devdaily-ai 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/standup.ts","../src/core/git-analyzer.ts","../src/core/copilot.ts","../src/core/github.ts","../src/core/project-management.ts","../src/config/index.ts","../src/config/schema.ts","../src/core/pm-errors.ts","../src/core/context-analyzer.ts","../src/core/standup-context.ts","../src/core/pr-prompt.ts","../src/core/notifications.ts","../src/ui/renderer.ts","../src/ui/colors.ts","../src/ui/ascii.ts","../src/utils/helpers.ts","../src/utils/formatter.ts","../src/core/work-journal.ts","../src/core/snapshot-builder.ts","../src/core/auto-snapshot.ts","../src/commands/pr.ts","../src/core/pr-template.ts","../src/core/github-repo.ts","../src/utils/commitlint.ts","../src/commands/week.ts","../src/commands/context.ts","../src/commands/snapshot.ts","../src/commands/recall.ts","../src/commands/init.ts","../src/commands/config.ts","../src/commands/dash.ts","../src/ui/keyboard.ts","../src/ui/dashboard.ts","../src/commands/doctor.ts","../src/commands/connect.ts","../src/ui/help.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { createRequire } from 'module';\nimport { standupCommand } from './commands/standup.js';\nimport { prCommand } from './commands/pr.js';\nimport { weekCommand } from './commands/week.js';\nimport { contextCommand } from './commands/context.js';\nimport { snapshotCommand } from './commands/snapshot.js';\nimport { recallCommand } from './commands/recall.js';\nimport { initCommand } from './commands/init.js';\nimport { configCommand } from './commands/config.js';\nimport { dashCommand } from './commands/dash.js';\nimport { doctorCommand } from './commands/doctor.js';\nimport { connectCommand } from './commands/connect.js';\nimport { renderMainHelp } from './ui/help.js';\nimport UI from './ui/renderer.js';\n\nconst { colors } = UI;\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../package.json');\n\nconst program = new Command();\n\n// Configure program\nprogram\n .name('devdaily')\n .description('Your AI-powered developer memory')\n .version(pkg.version, '-v, --version', 'Show version number')\n .configureHelp({\n sortSubcommands: true,\n sortOptions: true,\n })\n .addHelpText('beforeAll', () => {\n return renderMainHelp();\n })\n .showHelpAfterError('Run `devdaily --help` for usage information');\n\n// Register commands\nprogram.addCommand(standupCommand);\nprogram.addCommand(prCommand);\nprogram.addCommand(weekCommand);\nprogram.addCommand(contextCommand);\nprogram.addCommand(snapshotCommand);\nprogram.addCommand(recallCommand);\nprogram.addCommand(initCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(dashCommand);\nprogram.addCommand(doctorCommand);\nprogram.addCommand(connectCommand);\n\n// Add aliases\nstandupCommand.alias('s').alias('su').alias('daily');\nprCommand.alias('p').alias('pull');\nweekCommand.alias('w').alias('weekly');\ncontextCommand.alias('ctx').alias('resume');\nsnapshotCommand.alias('snap').alias('save');\nrecallCommand.alias('search').alias('find');\ndoctorCommand.alias('check').alias('setup');\nconnectCommand.alias('pm').alias('link');\n\n// Default action (no command) - show help\nprogram.action(async () => {\n console.log(renderMainHelp());\n});\n\n// Error handling\nprogram.exitOverride((err) => {\n if (err.code === 'commander.unknownCommand') {\n console.log('');\n console.log(UI.error(`Unknown command`));\n console.log(UI.info('Run `devdaily --help` to see available commands'));\n process.exit(1);\n }\n // Don't throw for help - just exit cleanly\n if (err.code === 'commander.helpDisplayed' || err.code === 'commander.help') {\n process.exit(0);\n }\n throw err;\n});\n\n// Graceful shutdown\nprocess.on('SIGINT', () => {\n console.log('');\n console.log(UI.info('Interrupted'));\n process.exit(0);\n});\n\nprocess.on('uncaughtException', (error) => {\n console.log('');\n console.log(UI.error('An unexpected error occurred'));\n console.log(colors.muted(error.message));\n process.exit(1);\n});\n\n// Parse and execute\nprogram.parse();\n","import { Command } from 'commander';\nimport { GitAnalyzer } from '../core/git-analyzer.js';\nimport { CopilotClient } from '../core/copilot.js';\nimport {\n StandupContextBuilder,\n type StandupContext,\n type StandupContextOptions,\n} from '../core/standup-context.js';\nimport { sendNotification, formatStandupNotification } from '../core/notifications.js';\nimport UI from '../ui/renderer.js';\nimport { copyToClipboard } from '../utils/helpers.js';\nimport { formatOutput, validateFormat } from '../utils/formatter.js';\nimport { getConfig } from '../config/index.js';\nimport { sideEffectSnapshot } from '../core/auto-snapshot.js';\n\nconst { colors } = UI;\n\nexport const standupCommand = new Command('standup')\n .description('Generate standup notes from your recent commits, PRs, and tickets')\n .option('-d, --days <number>', 'Number of days to look back', '1')\n .option('-f, --format <type>', 'Output format (markdown|slack|plain|json)', 'markdown')\n .option('-a, --author <email>', 'Filter by author email')\n .option('-t, --ticket <id...>', 'Include specific ticket/issue IDs for context')\n .option('--tone <type>', 'Output tone (engineering|mixed|business)', 'mixed')\n .option('--no-tickets', 'Skip fetching ticket/issue context')\n .option('--no-prs', 'Skip fetching PR context')\n .option('--no-copy', 'Do not copy to clipboard')\n .option('--debug', 'Show the full context and prompt sent to Copilot')\n .option('--preview', 'Show assembled context and ask for confirmation before generating')\n .option('--context', 'Show detailed work context analysis')\n .option('--raw-context', 'Output only the raw context block (no AI generation)')\n .option('--send', 'Send to configured notification channels (Slack/Discord)')\n .option('--slack', 'Send to Slack')\n .option('--discord', 'Send to Discord')\n .option('--test-webhook', 'Send a test message to configured Slack/Discord webhooks')\n .option('--no-journal', 'Skip auto-saving a snapshot to the journal')\n .action(async (options) => {\n const config = getConfig();\n\n // ── Test webhook mode ──────────────────────────────────────────────\n if (options.testWebhook) {\n console.log('');\n console.log(UI.section('Webhook Test'));\n console.log('');\n\n const testMessage = formatStandupNotification(\n '🧪 *Test message from DevDaily*\\n\\nIf you can see this, your webhook is configured correctly!\\n\\n• Slack: ✅ Connected\\n• Discord: ✅ Connected\\n• Timestamp: ' +\n new Date().toLocaleString(),\n [{ id: 'TEST-001', url: 'https://github.com', title: 'Sample ticket link' }]\n );\n\n const sendToSlack = options.slack || (!options.slack && !options.discord);\n const sendToDiscord = options.discord || (!options.slack && !options.discord);\n\n let anySuccess = false;\n let anyFailure = false;\n\n if (sendToSlack) {\n try {\n const result = await sendNotification(testMessage, { slack: true, discord: false });\n if (result.slack) {\n console.log(UI.success('Slack webhook test passed! Check your channel.'));\n anySuccess = true;\n } else if (result.slack === false) {\n console.log(UI.error('Slack webhook test failed. The request was rejected.'));\n anyFailure = true;\n }\n } catch (err) {\n console.log(UI.error(`Slack webhook test failed: ${(err as Error).message}`));\n anyFailure = true;\n }\n }\n\n if (sendToDiscord) {\n try {\n const result = await sendNotification(testMessage, { slack: false, discord: true });\n if (result.discord) {\n console.log(UI.success('Discord webhook test passed! Check your channel.'));\n anySuccess = true;\n } else if (result.discord === false) {\n console.log(UI.error('Discord webhook test failed. The request was rejected.'));\n anyFailure = true;\n }\n } catch (err) {\n console.log(UI.error(`Discord webhook test failed: ${(err as Error).message}`));\n anyFailure = true;\n }\n }\n\n if (!anySuccess && !anyFailure) {\n console.log(UI.warning('No webhooks configured. Run: devdaily init --notifications'));\n }\n\n console.log('');\n if (anyFailure) {\n console.log(UI.info('Troubleshooting:'));\n console.log(\n colors.muted(' 1. Check your webhook URL in .devdaily.secrets.json or config')\n );\n console.log(colors.muted(' 2. Slack: https://api.slack.com/apps → Incoming Webhooks'));\n console.log(colors.muted(' 3. Discord: Server Settings → Integrations → Webhooks'));\n console.log(colors.muted(' 4. Re-run: devdaily init --notifications'));\n }\n console.log('');\n return;\n }\n\n const git = new GitAnalyzer();\n const isDebug = options.debug || process.env.DEVD_DEBUG === '1';\n const copilot = new CopilotClient({ debug: isDebug });\n\n // Check if in git repo\n if (!(await git.isRepository())) {\n console.log(UI.error('Not a git repository'));\n console.log(UI.info('Run this command inside a git repository'));\n process.exit(1);\n }\n\n // Check if Copilot CLI is installed (unless raw-context mode)\n if (!options.rawContext && !(await copilot.isInstalled())) {\n console.log(UI.error('GitHub Copilot CLI not found'));\n console.log(UI.info('Install with: gh extension install github/gh-copilot'));\n process.exit(1);\n }\n\n const spinner = UI.spinner('Gathering work context...');\n spinner.start();\n\n try {\n const days = parseInt(options.days, 10) || config.standup.defaultDays;\n const tone = validateTone(options.tone);\n\n // ── Phase 1: Build rich context ──────────────────────────────────────\n spinner.text = 'Analyzing git history...';\n\n const contextBuilder = new StandupContextBuilder();\n const contextOptions: StandupContextOptions = {\n days,\n author: options.author,\n ticketIds: options.ticket,\n skipTickets: options.tickets === false,\n skipPRs: options.prs === false,\n baseBranch: config.git.defaultBranch,\n debug: isDebug,\n };\n\n // Update spinner as we gather data\n const originalBuild = contextBuilder.build.bind(contextBuilder);\n spinner.text = 'Fetching commits, PRs, and tickets...';\n\n const ctx: StandupContext = await originalBuild(contextOptions);\n\n // Check if we have any data\n if (ctx.commits.length === 0 && ctx.pullRequests.length === 0) {\n spinner.stop();\n console.log('');\n console.log(UI.warning(`No commits or PRs found in the last ${days} day(s)`));\n console.log(UI.info(`Try: devdaily standup --days=${days + 1}`));\n process.exit(0);\n }\n\n spinner.stop();\n\n // ── Debug mode: show full context ──────────────────────────────────\n if (isDebug) {\n console.log('');\n console.log(colors.accent('─── Debug: Assembled Context ───'));\n console.log(StandupContextBuilder.formatDebugSummary(ctx));\n console.log('');\n console.log(colors.accent('─── Debug: Full Prompt Context Block ───'));\n console.log(colors.muted(StandupContextBuilder.formatForPrompt(ctx)));\n console.log('');\n }\n\n // ── Context analysis mode ──────────────────────────────────────────\n if (options.context) {\n printContextAnalysis(ctx);\n }\n\n // ── Raw context mode: just output the context block ────────────────\n if (options.rawContext) {\n console.log('');\n console.log(StandupContextBuilder.formatForPrompt(ctx));\n return;\n }\n\n // ── Preview mode: show context and ask for confirmation ────────────\n if (options.preview) {\n console.log('');\n console.log(UI.section('Assembled Context'));\n console.log('');\n printContextSummary(ctx);\n console.log('');\n\n const { default: inquirer } = await import('inquirer');\n const { proceed } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'proceed',\n message: 'Generate standup from this context?',\n default: true,\n },\n ]);\n\n if (!proceed) {\n console.log(UI.info('Aborted. You can adjust with --days, --ticket, --author flags.'));\n return;\n }\n }\n\n // ── Phase 2: Generate standup with AI ──────────────────────────────\n const genSpinner = UI.spinner('Generating standup with Copilot CLI...');\n genSpinner.start();\n\n const rawStandup = await copilot.generateStandupFromContext(ctx, tone);\n\n genSpinner.stop();\n\n // ── Phase 2.5: Apply output format ─────────────────────────────────\n const outputFormat = validateFormat(options.format || config.output.format || 'markdown');\n const formatted = formatOutput(rawStandup, outputFormat, {\n title: days === 1 ? 'Daily Standup' : `Work Summary (${days} days)`,\n commits: ctx.commits.length,\n prs: ctx.pullRequests.length,\n tickets: ctx.tickets.length,\n days,\n branch: ctx.branch,\n repo: ctx.repo.name ?? undefined,\n });\n\n const standup = formatted.text;\n\n // ── Phase 3: Output ────────────────────────────────────────────────\n const title = days === 1 ? 'Your Standup' : `Your Work (Last ${days} Days)`;\n\n if (outputFormat === 'json') {\n // JSON format: print raw JSON without the box decoration\n console.log('');\n console.log(standup);\n } else {\n console.log('');\n console.log(UI.box(standup, title));\n }\n\n // Stats bar\n if (config.output.showStats) {\n const statItems: { label: string; value: string | number }[] = [\n { label: 'commits', value: ctx.commits.length },\n { label: 'days', value: days },\n ];\n if (ctx.pullRequests.length > 0) {\n statItems.push({ label: 'PRs', value: ctx.pullRequests.length });\n }\n if (ctx.tickets.length > 0) {\n statItems.push({ label: 'tickets', value: ctx.tickets.length });\n }\n if (ctx.categories.length > 0) {\n statItems.push({\n label: 'primary area',\n value: ctx.categories[0].name,\n });\n }\n if (ctx.diffStats) {\n statItems.push({\n label: 'changes',\n value: `+${ctx.diffStats.insertions}/-${ctx.diffStats.deletions}`,\n });\n }\n console.log(UI.stats(statItems));\n }\n console.log('');\n\n // ── Copy to clipboard ──────────────────────────────────────────────\n if (options.copy && config.output.copyToClipboard !== false) {\n await copyToClipboard(standup);\n const formatLabel = outputFormat !== 'markdown' ? ` (${outputFormat})` : '';\n console.log(UI.success(`Copied to clipboard${formatLabel}`));\n }\n\n // ── Send to notifications ──────────────────────────────────────────\n if (options.send || options.slack || options.discord) {\n const ticketLinks = ctx.tickets.map((t) => ({\n id: t.id,\n url: t.url,\n title: t.title,\n }));\n\n const notification = formatStandupNotification(standup, ticketLinks);\n\n const sendToSlack = options.slack || options.send;\n const sendToDiscord = options.discord || options.send;\n\n const results = await sendNotification(notification, {\n slack: sendToSlack,\n discord: sendToDiscord,\n });\n\n if (results.slack) {\n console.log(UI.success('Sent to Slack'));\n }\n if (results.discord) {\n console.log(UI.success('Sent to Discord'));\n }\n if (results.slack === false || results.discord === false) {\n console.log(\n UI.warning('Some notifications failed to send. Check your webhook configuration.')\n );\n }\n }\n\n // ── Auto-snapshot side-effect ──────────────────────────────────────\n if (options.journal !== false) {\n await sideEffectSnapshot({\n source: 'standup',\n note: `Standup generated (${ctx.commits.length} commits, ${days} day${days !== 1 ? 's' : ''})`,\n debug: isDebug,\n });\n }\n } catch (error) {\n spinner.stop();\n console.log('');\n console.log(UI.error('Failed to generate standup'));\n console.log(colors.muted((error as Error).message));\n\n if (isDebug && error instanceof Error && error.stack) {\n console.log('');\n console.log(colors.muted('Stack trace:'));\n console.log(colors.muted(error.stack));\n }\n\n process.exit(1);\n }\n });\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction validateTone(tone: string): 'engineering' | 'mixed' | 'business' {\n const valid = ['engineering', 'mixed', 'business'];\n if (valid.includes(tone)) {\n return tone as 'engineering' | 'mixed' | 'business';\n }\n console.log(UI.warning(`Invalid tone \"${tone}\". Using \"mixed\". Options: ${valid.join(', ')}`));\n return 'mixed';\n}\n\n/**\n * Print a compact summary of the assembled context\n */\nfunction printContextSummary(ctx: StandupContext): void {\n // Commits\n console.log(` ${colors.accent('Commits:')} ${ctx.commits.length}`);\n for (const c of ctx.commits.slice(0, 8)) {\n console.log(` ${colors.muted(`[${c.shortHash}]`)} ${c.message.slice(0, 70)}`);\n }\n if (ctx.commits.length > 8) {\n console.log(` ${colors.muted(`... and ${ctx.commits.length - 8} more`)}`);\n }\n\n // PRs\n if (ctx.pullRequests.length > 0) {\n console.log('');\n console.log(` ${colors.accent('Pull Requests:')} ${ctx.pullRequests.length}`);\n for (const pr of ctx.pullRequests) {\n const state = pr.state === 'open' ? colors.success('open') : colors.muted(pr.state);\n console.log(` PR #${pr.number} ${pr.title.slice(0, 55)} (${state})`);\n }\n }\n\n // Tickets\n if (ctx.tickets.length > 0) {\n console.log('');\n console.log(` ${colors.accent('Tickets:')} ${ctx.tickets.length}`);\n for (const t of ctx.tickets) {\n console.log(` ${t.id}: ${t.title.slice(0, 55)} [${t.status}]`);\n }\n } else if (ctx.ticketIds.length > 0) {\n console.log('');\n console.log(` ${colors.accent('Ticket IDs found:')} ${ctx.ticketIds.join(', ')}`);\n console.log(` ${colors.muted('(details not fetched — PM tool may not be configured)')}`);\n }\n\n // Diff stats\n if (ctx.diffStats) {\n console.log('');\n console.log(\n ` ${colors.accent('Changes:')} ${ctx.diffStats.filesChanged} files, ` +\n `${colors.success(`+${ctx.diffStats.insertions}`)} / ` +\n `${colors.error(`-${ctx.diffStats.deletions}`)}`\n );\n }\n\n // Top files\n if (ctx.topChangedFiles.length > 0) {\n console.log('');\n console.log(` ${colors.accent('Top changed files:')}`);\n for (const f of ctx.topChangedFiles.slice(0, 5)) {\n const freq = f.frequency > 1 ? ` ${colors.muted(`(${f.frequency}x)`)}` : '';\n console.log(` ${f.path}${freq}`);\n }\n }\n}\n\n/**\n * Print full context analysis (--context flag)\n */\nfunction printContextAnalysis(ctx: StandupContext): void {\n console.log('');\n console.log(UI.section('Work Context Analysis'));\n console.log('');\n\n // Branch & repo\n if (ctx.repo.name) {\n console.log(` ${colors.accent('Repository:')} ${ctx.repo.name}`);\n }\n console.log(` ${colors.accent('Branch:')} ${ctx.branch}`);\n console.log(\n ` ${colors.accent('Period:')} ${ctx.timeRange.since.toLocaleDateString()} → ${ctx.timeRange.until.toLocaleDateString()} (${ctx.timeRange.durationHours}h)`\n );\n console.log('');\n\n // Commits\n console.log(` ${colors.accent('Commits:')} ${ctx.commits.length}`);\n for (const c of ctx.commits) {\n const files = c.filesChanged ? ` (${c.filesChanged.length} files)` : '';\n console.log(` ${colors.muted(c.shortHash)} ${c.message}${colors.muted(files)}`);\n }\n console.log('');\n\n // PRs\n if (ctx.pullRequests.length > 0) {\n console.log(` ${colors.accent('Pull Requests:')} ${ctx.pullRequests.length}`);\n for (const pr of ctx.pullRequests) {\n console.log(` #${pr.number} ${pr.title} (${pr.state}) → ${pr.baseBranch}`);\n if (pr.linkedTickets.length > 0) {\n console.log(` ${colors.muted(`Linked: ${pr.linkedTickets.join(', ')}`)}`);\n }\n }\n console.log('');\n }\n\n // Tickets\n if (ctx.tickets.length > 0) {\n console.log(` ${colors.accent('Tickets:')}`);\n for (const t of ctx.tickets) {\n const priority = t.priority ? ` [${t.priority}]` : '';\n console.log(` ${t.id}: ${t.title} (${t.type}, ${t.status}${priority})`);\n }\n console.log('');\n }\n\n // Work categories\n if (ctx.categories.length > 0) {\n console.log(` ${colors.accent('Work Categories:')}`);\n for (const cat of ctx.categories.slice(0, 5)) {\n const barFilled = Math.round(cat.percentage / 5);\n const barEmpty = 20 - barFilled;\n const bar = '█'.repeat(barFilled) + '░'.repeat(barEmpty);\n console.log(` ${cat.name.padEnd(14)} ${bar} ${cat.percentage}%`);\n }\n console.log('');\n }\n\n // Diff stats\n if (ctx.diffStats) {\n console.log(\n ` ${colors.accent('Diff Stats:')} ${ctx.diffStats.filesChanged} files, ` +\n `+${ctx.diffStats.insertions}/-${ctx.diffStats.deletions} lines`\n );\n console.log('');\n }\n\n // Top changed files\n if (ctx.topChangedFiles.length > 0) {\n console.log(` ${colors.accent('Top Changed Files:')}`);\n for (const f of ctx.topChangedFiles.slice(0, 10)) {\n const freq = f.frequency > 1 ? ` ${colors.muted(`(touched in ${f.frequency} commits)`)}` : '';\n console.log(` ${f.path}${freq}`);\n }\n console.log('');\n }\n}\n","import simpleGit, { SimpleGit } from 'simple-git';\nimport { Commit, CommitOptions, DiffStats } from '../types';\n\nexport class GitAnalyzer {\n private git: SimpleGit;\n\n constructor(repoPath?: string) {\n this.git = simpleGit(repoPath || process.cwd());\n }\n\n /**\n * Get files changed in a specific commit by hash\n */\n async getCommitFiles(commitHash: string): Promise<string[]> {\n try {\n const result = await this.git.raw([\n 'diff-tree',\n '--no-commit-id',\n '--name-only',\n '-r',\n commitHash,\n ]);\n return result.split('\\n').filter(Boolean);\n } catch {\n return [];\n }\n }\n\n async isRepository(): Promise<boolean> {\n try {\n await this.git.revparse(['--is-inside-work-tree']);\n return true;\n } catch {\n return false;\n }\n }\n\n async getCurrentBranch(): Promise<string> {\n const branch = await this.git.revparse(['--abbrev-ref', 'HEAD']);\n return branch.trim();\n }\n\n async getCommits(options: CommitOptions = {}): Promise<Commit[]> {\n const args: string[] = ['log'];\n\n if (options.since) {\n args.push(`--since=${options.since.toISOString()}`);\n }\n\n if (options.until) {\n args.push(`--until=${options.until.toISOString()}`);\n }\n\n if (options.author) {\n args.push(`--author=${options.author}`);\n }\n\n // Use unique delimiters for field and record separation\n // Body (%b) is last to handle multi-line content\n const FIELD_SEP = '<<<DD_FIELD>>>';\n const RECORD_SEP = '<<<DD_RECORD>>>';\n args.push(\n `--format=${RECORD_SEP}%H${FIELD_SEP}%s${FIELD_SEP}%an${FIELD_SEP}%ae${FIELD_SEP}%ai${FIELD_SEP}%b`\n );\n\n const result = await this.git.raw(args);\n\n if (!result || !result.trim()) {\n return [];\n }\n\n const commits = result\n .split(RECORD_SEP)\n .filter(Boolean)\n .map((record) => {\n const parts = record.trim().split(FIELD_SEP);\n if (parts.length < 5) {\n return null;\n }\n const [hash, message, author, _authorEmail, date, ...bodyParts] = parts;\n // Body might contain our delimiter if it has special content\n const body = bodyParts.join(FIELD_SEP).trim();\n return {\n hash: hash || '',\n message: message || '',\n author: author || '',\n date: new Date(date || Date.now()),\n body: body || undefined,\n } as Commit;\n })\n .filter((c): c is Commit => c !== null && !!c.message);\n\n return commits;\n }\n\n async getDiff(base: string = 'main', head: string = 'HEAD'): Promise<string> {\n const diff = await this.git.diff([`${base}...${head}`]);\n return diff;\n }\n\n async getDiffStats(base: string = 'main', head: string = 'HEAD'): Promise<DiffStats> {\n const diffSummary = await this.git.diffSummary([`${base}...${head}`]);\n\n return {\n filesChanged: diffSummary.files.length,\n insertions: diffSummary.insertions,\n deletions: diffSummary.deletions,\n };\n }\n\n async getChangedFiles(base: string = 'main', head: string = 'HEAD'): Promise<string[]> {\n const diff = await this.git.diff([`${base}...${head}`, '--name-only']);\n return diff.split('\\n').filter(Boolean);\n }\n\n /**\n * Get files changed in recent commits (fallback when diff fails)\n */\n async getFilesFromCommits(options: CommitOptions = {}): Promise<string[]> {\n const args: string[] = ['log', '--name-only', '--pretty=format:'];\n\n if (options.since) {\n args.push(`--since=${options.since.toISOString()}`);\n }\n\n if (options.until) {\n args.push(`--until=${options.until.toISOString()}`);\n }\n\n if (options.author) {\n args.push(`--author=${options.author}`);\n }\n\n const result = await this.git.raw(args);\n const files = result\n .split('\\n')\n .filter(Boolean)\n .filter((f) => !f.startsWith('commit '));\n\n // Deduplicate\n return [...new Set(files)];\n }\n\n async getCurrentUser(): Promise<{ name: string; email: string }> {\n const name = await this.git.getConfig('user.name');\n const email = await this.git.getConfig('user.email');\n\n return {\n name: name.value || '',\n email: email.value || '',\n };\n }\n\n async getStatus(): Promise<{ modified: string[]; untracked: string[] }> {\n const status = await this.git.status();\n\n return {\n modified: status.modified,\n untracked: status.not_added,\n };\n }\n\n async hasUncommittedChanges(): Promise<boolean> {\n const status = await this.git.status();\n return !status.isClean();\n }\n\n async getRepoRoot(): Promise<string> {\n const root = await this.git.revparse(['--show-toplevel']);\n return root.trim();\n }\n\n /**\n * Get a truncated diff suitable for AI context.\n *\n * Returns the full `git diff --stat` plus a truncated unified diff\n * (capped at `maxLines` lines) so the AI can see WHAT actually changed,\n * not just filenames.\n */\n async getDiffForAI(\n base: string = 'main',\n head: string = 'HEAD',\n maxLines: number = 200\n ): Promise<{ stat: string; diff: string; truncated: boolean }> {\n // 1. diff --stat (always short)\n let stat = '';\n try {\n stat = await this.git.raw(['diff', '--stat', `${base}...${head}`]);\n } catch {\n stat = '';\n }\n\n // 2. unified diff (may be huge — truncate)\n let rawDiff = '';\n let truncated = false;\n try {\n rawDiff = await this.git.raw(['diff', `${base}...${head}`]);\n } catch {\n rawDiff = '';\n }\n\n const lines = rawDiff.split('\\n');\n if (lines.length > maxLines) {\n truncated = true;\n rawDiff =\n lines.slice(0, maxLines).join('\\n') +\n `\\n\\n... (diff truncated — ${lines.length - maxLines} more lines)`;\n }\n\n return { stat: stat.trim(), diff: rawDiff.trim(), truncated };\n }\n\n /**\n * Auto-detect the repository's default branch.\n *\n * Strategy (in order of precedence):\n * 1. `git symbolic-ref refs/remotes/origin/HEAD` — works when the\n * remote HEAD has been fetched (most reliable for cloned repos).\n * 2. `gh repo view --json defaultBranchRef` — queries GitHub API via\n * the gh CLI (requires auth but always returns the correct value).\n * 3. Probe for common branch names (`main`, `master`, `develop`) by\n * checking if the remote-tracking ref exists.\n * 4. Fall back to `\"main\"` as a last resort.\n */\n async getDefaultBranch(): Promise<string> {\n // Strategy 1: git symbolic-ref\n try {\n const ref = await this.git.raw(['symbolic-ref', 'refs/remotes/origin/HEAD']);\n const branch = ref.trim().replace('refs/remotes/origin/', '');\n if (branch) return branch;\n } catch {\n // origin/HEAD not set — continue\n }\n\n // Strategy 2: gh CLI (GitHub only)\n try {\n const { execa } = await import('execa');\n const { stdout } = await execa('gh', ['repo', 'view', '--json', 'defaultBranchRef'], {\n timeout: 10000,\n });\n const data = JSON.parse(stdout);\n const branch = data?.defaultBranchRef?.name;\n if (branch) return branch;\n } catch {\n // gh not installed or not a GitHub repo — continue\n }\n\n // Strategy 3: probe common branch names on the remote\n const candidates = ['main', 'master', 'develop'];\n for (const candidate of candidates) {\n try {\n await this.git.raw(['rev-parse', '--verify', `refs/remotes/origin/${candidate}`]);\n return candidate;\n } catch {\n // branch doesn't exist on remote — try next\n }\n }\n\n // Strategy 4: ultimate fallback\n return 'main';\n }\n}\n","import { execa } from 'execa';\nimport { type Ticket } from './project-management.js';\nimport { type WorkContext } from './context-analyzer.js';\nimport { type StandupContext, StandupContextBuilder } from './standup-context.js';\nimport { type PRPromptConfig, formatPRPromptForAI } from './pr-prompt.js';\n\nexport interface IssueContext {\n number: number;\n title: string;\n type: string; // bug, feature, etc.\n description: string;\n}\n\nexport class CopilotClient {\n private copilotTypeCache: 'new' | 'legacy' | null | undefined = undefined;\n private debugMode: boolean;\n\n constructor(options?: { debug?: boolean }) {\n this.debugMode = options?.debug ?? process.env.DEVD_DEBUG === '1';\n }\n\n /**\n * Check if the new GitHub Copilot CLI is installed\n */\n async isInstalled(): Promise<boolean> {\n try {\n // Check for the new copilot CLI first\n await execa('copilot', ['--version']);\n return true;\n } catch {\n // Fallback: check for gh copilot extension (deprecated)\n try {\n await execa('gh', ['copilot', '--version']);\n return true;\n } catch {\n return false;\n }\n }\n }\n\n /**\n * Check which Copilot CLI is available\n */\n private async getCopilotType(): Promise<'new' | 'legacy' | null> {\n if (this.copilotTypeCache !== undefined) {\n return this.copilotTypeCache;\n }\n\n try {\n await execa('copilot', ['--version']);\n this.copilotTypeCache = 'new';\n } catch {\n try {\n await execa('gh', ['copilot', '--version']);\n this.copilotTypeCache = 'legacy';\n } catch {\n this.copilotTypeCache = null;\n }\n }\n\n return this.copilotTypeCache;\n }\n\n /**\n * Execute a prompt using the new Copilot CLI (non-interactive mode)\n */\n private async executeNewCopilot(prompt: string): Promise<string> {\n try {\n const { stdout } = await execa(\n 'copilot',\n ['-p', prompt, '--silent', '--no-ask-user', '--model', 'claude-sonnet-4'],\n {\n timeout: 120000, // 2 minute timeout\n env: {\n ...process.env,\n NO_COLOR: '1', // Disable color output for cleaner parsing\n },\n }\n );\n\n return this.parseOutput(stdout);\n } catch (error) {\n throw new Error(`Copilot CLI error: ${error}`);\n }\n }\n\n /**\n * Execute using the legacy gh copilot extension\n */\n private async executeLegacyCopilot(prompt: string): Promise<string> {\n try {\n const { stdout } = await execa('gh', ['copilot', 'suggest', '-t', 'shell', prompt]);\n return this.parseOutput(stdout);\n } catch (error) {\n throw new Error(`Legacy Copilot CLI error: ${error}`);\n }\n }\n\n async suggest(prompt: string): Promise<string> {\n if (this.debugMode) {\n console.log('\\n┌─── DEBUG: Prompt sent to Copilot ───────────────────┐');\n console.log(prompt);\n console.log('└─── END Prompt ──────────────────────────────────────┘\\n');\n }\n\n const copilotType = await this.getCopilotType();\n\n let result: string;\n if (copilotType === 'new') {\n result = await this.executeNewCopilot(prompt);\n } else if (copilotType === 'legacy') {\n result = await this.executeLegacyCopilot(prompt);\n } else {\n throw new Error(\n 'GitHub Copilot CLI is not installed. Install it with: brew install copilot-cli'\n );\n }\n\n if (this.debugMode) {\n console.log('\\n┌─── DEBUG: Raw Copilot response ─────────────────────┐');\n console.log(result);\n console.log('└─── END Response ───────────────────────────────────┘\\n');\n }\n\n return result;\n }\n\n async explain(code: string): Promise<string> {\n const copilotType = await this.getCopilotType();\n\n if (copilotType === 'new') {\n return this.executeNewCopilot(`Explain this code:\\n\\n${code}`);\n } else if (copilotType === 'legacy') {\n try {\n const { stdout } = await execa('gh', ['copilot', 'explain', code]);\n return this.parseOutput(stdout);\n } catch (error) {\n throw new Error(`Copilot CLI error: ${error}`);\n }\n } else {\n throw new Error(\n 'GitHub Copilot CLI is not installed. Install it with: brew install copilot-cli'\n );\n }\n }\n\n private parseOutput(raw: string): string {\n // Remove ANSI codes\n\n // eslint-disable-next-line no-control-regex\n const cleaned = raw.replace(/\\x1B\\[[0-9;]*[a-zA-Z]/g, '');\n\n // For the new Copilot CLI in silent mode, output is cleaner\n // Just trim and return\n const lines = cleaned.split('\\n');\n const relevantLines = lines.filter(\n (line) =>\n line.trim() &&\n !line.includes('Suggestion:') &&\n !line.includes('Explain command:') &&\n !line.includes('?') &&\n !line.startsWith('Session:') &&\n !line.startsWith('Model:') &&\n !line.startsWith('Duration:')\n );\n\n return relevantLines.join('\\n').trim();\n }\n\n /**\n * Format tickets into context string for AI\n */\n private formatTicketContext(tickets: Ticket[]): string {\n if (tickets.length === 0) return '';\n\n const ticketContexts = tickets.map((ticket) => {\n const raw =\n typeof ticket.description === 'string'\n ? ticket.description\n : ticket.description\n ? String(ticket.description)\n : '';\n const description = raw.slice(0, 200) || 'No description';\n const priority = ticket.priority ? ` (${ticket.priority})` : '';\n\n return ` - ${ticket.id} [${ticket.type}${priority}]: ${ticket.title}\\n Context: ${description}`;\n });\n\n return `\\nRelated Tickets/Tasks (for context on WHY these changes were made):\\n${ticketContexts.join('\\n')}`;\n }\n\n /**\n * Format work context into prompt context\n */\n private formatWorkContext(context?: Partial<WorkContext>): string {\n if (!context) return '';\n\n const lines: string[] = ['Work Context:'];\n\n if (context.tickets && context.tickets.length > 0) {\n lines.push(` Tickets: ${context.tickets.map((t) => t.id).join(', ')}`);\n }\n\n if (context.categories && context.categories.length > 0) {\n const cats = context.categories.slice(0, 3).map((c) => `${c.name} (${c.percentage}%)`);\n lines.push(` Work areas: ${cats.join(', ')}`);\n }\n\n if (context.filesChanged) {\n lines.push(` Files changed: ${context.filesChanged.length}`);\n }\n\n if (context.branch) {\n lines.push(` Branch: ${context.branch}`);\n }\n\n if (context.authors && context.authors.length > 1) {\n lines.push(` Contributors: ${context.authors.join(', ')}`);\n }\n\n if (context.timeRange) {\n lines.push(` Duration: ${context.timeRange.durationHours} hours`);\n }\n\n return '\\n' + lines.join('\\n');\n }\n\n /**\n * Generate standup from rich structured context (new approach).\n * Uses StandupContextBuilder's factual prompt instead of loose commit messages.\n */\n async generateStandupFromContext(\n ctx: StandupContext,\n tone: 'engineering' | 'mixed' | 'business' = 'mixed'\n ): Promise<string> {\n const prompt = StandupContextBuilder.buildStandupPrompt(ctx, tone);\n return this.suggest(prompt);\n }\n\n /**\n * Generate weekly summary from rich structured context (new approach).\n */\n async generateWeeklyFromContext(ctx: StandupContext): Promise<string> {\n const prompt = StandupContextBuilder.buildWeeklyPrompt(ctx);\n return this.suggest(prompt);\n }\n\n /**\n * Generate output from a pre-built prompt string.\n * Useful for custom prompt flows (debug, preview, etc.).\n */\n async generateFromPrompt(prompt: string): Promise<string> {\n return this.suggest(prompt);\n }\n\n /**\n * @deprecated Use generateStandupFromContext() for accurate results.\n * Kept for backwards compatibility.\n */\n async summarizeCommits(\n commits: string[],\n tickets: Ticket[] = [],\n workContext?: WorkContext\n ): Promise<string> {\n const ticketContext = this.formatTicketContext(tickets);\n const contextInfo = this.formatWorkContext(workContext);\n\n // Extract ticket IDs from work context to ensure they're mentioned\n const ticketIds =\n workContext?.tickets.map((t) => t.id).join(', ') ||\n (tickets.length > 0 ? tickets.map((t) => t.id).join(', ') : '');\n\n // Build work areas string\n const workAreas =\n workContext?.categories\n .slice(0, 2)\n .map((c) => c.name)\n .join(', ') || '';\n\n const prompt = `\nYou are helping a developer write their daily standup update for a team meeting.\nThis will be shared with both technical and non-technical team members (managers, PMs, stakeholders).\n\nHere are their git commits from yesterday:\n${commits.map((c, i) => `${i + 1}. ${c}`).join('\\n')}\n${ticketContext}\n${contextInfo}\n\nWrite a friendly, conversational standup update that anyone can understand.\n\nFormat:\nYesterday I worked on:\n• [what you accomplished in plain language]${ticketIds ? ` (include ticket references like ${ticketIds})` : ''}\n• [another accomplishment - focus on the outcome/value, not technical details]\n• [if relevant, mention any collaboration or team impact]\n\nToday I'm planning to:\n• [what you'll be focusing on]\n• [any continuation of work or new items]\n\nBlockers: None (or describe any challenges)\n\nGuidelines:\n- Write in a warm, natural tone - like you're talking to a colleague\n- Explain technical work in terms of user impact or business value\n - Instead of \"Fixed null pointer exception in auth module\"\n - Say \"Fixed a login issue that was causing some users to get stuck\"\n- Instead of \"Implemented REST API endpoint for user preferences\"\n - Say \"Built the backend so users can now save their settings\"\n- Skip jargon like \"refactoring\", \"debugging\", \"endpoints\", \"modules\"\n- Focus on WHAT changed for users or the team, not HOW you coded it\n- Keep it brief and scannable (2-4 bullets per section)\n- Use the ticket context to explain the business purpose if available\n- Sound human and approachable, not robotic\n${ticketIds ? `- IMPORTANT: Reference these ticket IDs in your bullet points: ${ticketIds}` : ''}\n${workAreas ? `- The work was primarily in: ${workAreas}` : ''}\n`;\n\n return this.suggest(prompt);\n }\n\n async generatePRDescription(data: {\n branch: string;\n commits: string[];\n files: string[];\n issues: string[];\n ticketDetails?: Ticket[];\n /** git diff --stat output */\n diffStat?: string;\n /** Truncated unified diff for AI context */\n diff?: string;\n /** Raw PR template content for the AI to follow */\n templateContent?: string;\n /** Custom PR description prompt / team guidelines */\n promptConfig?: PRPromptConfig | null;\n }): Promise<string> {\n // Build ticket context\n let ticketContext = '';\n if (data.ticketDetails && data.ticketDetails.length > 0) {\n ticketContext = this.formatTicketContext(data.ticketDetails);\n }\n\n // Build ticket link references for the description footer\n const ticketLinks = this.buildTicketLinks(data.ticketDetails || [], data.issues);\n\n // Build diff context block\n const diffBlock = this.buildDiffBlock(data.diffStat, data.diff);\n\n // Build team guidelines block\n const guidelinesBlock = data.promptConfig ? formatPRPromptForAI(data.promptConfig) : '';\n\n // Build template guidance block\n const templateBlock = data.templateContent\n ? `\\n=== PR TEMPLATE (follow this structure) ===\\n${data.templateContent}\\n=== END PR TEMPLATE ===\\n`\n : '';\n\n const prompt = `\nYou are an expert developer helping create a Pull Request description.\nYour job is to write a clear, accurate, reviewer-friendly PR description.\n\nBranch: ${data.branch}\n\nCommits:\n${data.commits.map((c, i) => `${i + 1}. ${c}`).join('\\n')}\n\nFiles changed:\n${data.files.slice(0, 40).join('\\n')}${data.files.length > 40 ? `\\n... and ${data.files.length - 40} more files` : ''}\n${diffBlock}\nRelated tickets: ${data.issues.length > 0 ? data.issues.join(', ') : 'None'}\n${ticketContext}\n${templateBlock}\n${guidelinesBlock}\nGenerate a comprehensive PR description. ${data.templateContent ? 'Follow the PR template structure above.' : 'Use this structure:'}\n\n${\n !data.templateContent\n ? `## What Changed\n- [specific bullet points based on the ACTUAL diff and commits — do NOT invent changes]\n\n## Why\n[Business or technical reason — USE ticket context if available to explain the real value]\n\n## How to Test\n1. [concrete testing step]\n2. [another step]\n3. [verification step]`\n : ''\n}\n\n${ticketLinks ? `\\nInclude these ticket references at the end of the description:\\n${ticketLinks}` : ''}\n\nRequirements:\n- Be specific and technical — reference actual files, functions, and changes from the diff\n- NEVER invent or hallucinate changes that are not in the commits or diff\n- Use ticket descriptions to explain the WHY (business value)\n- Focus on value for code reviewers — what should they pay attention to?\n- Keep it clear and concise\n- No emojis in the body text\n`;\n\n return this.suggest(prompt);\n }\n\n /**\n * Generate structured PR content for filling templates\n */\n async generatePRContent(data: {\n branch: string;\n commits: string[];\n files: string[];\n issues: string[];\n ticketDetails?: Ticket[];\n templateSections?: string[];\n /** git diff --stat output */\n diffStat?: string;\n /** Truncated unified diff for AI context */\n diff?: string;\n /** Raw PR template content for the AI to understand section expectations */\n templateContent?: string;\n /** Custom PR description prompt / team guidelines */\n promptConfig?: PRPromptConfig | null;\n }): Promise<{\n title: string;\n description: string;\n type: string;\n impact: string;\n testing: string;\n breakingChanges: string;\n additionalInfo: string;\n }> {\n // Build ticket context\n let ticketContext = '';\n if (data.ticketDetails && data.ticketDetails.length > 0) {\n ticketContext = this.formatTicketContext(data.ticketDetails);\n }\n\n // Build diff context block\n const diffBlock = this.buildDiffBlock(data.diffStat, data.diff);\n\n // Build team guidelines block\n const guidelinesBlock = data.promptConfig ? formatPRPromptForAI(data.promptConfig) : '';\n\n // Build template guidance block\n const templateBlock = data.templateContent\n ? `\\nThe PR template used by this repo is:\\n---\\n${data.templateContent}\\n---\\nFill content that matches each section of this template.\\n`\n : '';\n\n // Build ticket link references\n const ticketLinks = this.buildTicketLinks(data.ticketDetails || [], data.issues);\n\n const prompt = `\nYou are an expert developer helping create a Pull Request. Analyze the ACTUAL changes and generate content.\n\nBranch: ${data.branch}\n\nCommits:\n${data.commits.map((c, i) => `${i + 1}. ${c}`).join('\\n')}\n\nFiles changed:\n${data.files.slice(0, 40).join('\\n')}${data.files.length > 40 ? `\\n... and ${data.files.length - 40} more files` : ''}\n${diffBlock}\nRelated tickets: ${data.issues.length > 0 ? data.issues.join(', ') : 'None'}\n${ticketContext}\n${templateBlock}\n${guidelinesBlock}\n${data.templateSections ? `Template sections to fill: ${data.templateSections.join(', ')}` : ''}\n\nGenerate a JSON object with the following fields (respond with ONLY the JSON, no markdown):\n\n{\n \"title\": \"A concise PR title following conventional commit format (e.g., 'feat: add user authentication')\",\n \"description\": \"2-4 bullet points describing WHAT changed — be specific, reference actual files/functions from the diff. NEVER invent changes.${ticketLinks ? ` Include ticket references: ${ticketLinks}` : ''}\",\n \"type\": \"One of: feat, fix, docs, refactor, test, chore, hotfix, security, style\",\n \"impact\": \"1-2 sentences about the impact of these changes. Use ticket context for business value if available.\",\n \"testing\": \"2-3 numbered steps on how to test these changes — be specific about what to verify\",\n \"breakingChanges\": \"Description of breaking changes, or 'None'\",\n \"additionalInfo\": \"Any additional context reviewers should know, or 'None'\"\n}\n\nIMPORTANT:\n- Base your output strictly on the commits, files, and diff provided. Do NOT hallucinate.\n- Reference actual file paths and function names where relevant.\n- Use ticket context to explain the business WHY, not just the technical WHAT.\n`;\n\n const response = await this.suggest(prompt);\n\n // Parse JSON from response\n try {\n // Try to extract JSON from the response\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n return JSON.parse(jsonMatch[0]);\n }\n } catch {\n // If parsing fails, return default structure\n }\n\n // Fallback: generate simple content\n return {\n title: this.generateSimpleTitle(data.commits),\n description: data.commits\n .slice(0, 5)\n .map((c) => `- ${c}`)\n .join('\\n'),\n type: this.detectPRType(data.commits),\n impact: 'See commit messages for details.',\n testing: '1. Pull the branch\\n2. Run tests\\n3. Manual verification',\n breakingChanges: 'None',\n additionalInfo: 'None',\n };\n }\n\n /**\n * Build a diff context block for the AI prompt.\n * Includes both the --stat summary and truncated unified diff.\n */\n private buildDiffBlock(diffStat?: string, diff?: string): string {\n if (!diffStat && !diff) return '';\n\n const parts: string[] = [''];\n\n if (diffStat) {\n parts.push('Diff summary (git diff --stat):');\n parts.push(diffStat);\n parts.push('');\n }\n\n if (diff) {\n parts.push('Code changes (unified diff — use this to understand WHAT actually changed):');\n parts.push(diff);\n parts.push('');\n }\n\n return parts.join('\\n');\n }\n\n /**\n * Build ticket link references for inclusion in the PR description.\n * Generates \"Closes #ID\" for GitHub or full URLs for Jira/Linear.\n */\n private buildTicketLinks(tickets: Ticket[], issueIds: string[]): string {\n if (tickets.length === 0 && issueIds.length === 0) return '';\n\n const links: string[] = [];\n\n for (const ticket of tickets) {\n if (ticket.source === 'github') {\n links.push(`Closes ${ticket.id}`);\n } else if (ticket.url) {\n links.push(`Relates to [${ticket.id}](${ticket.url})`);\n } else {\n links.push(`Relates to ${ticket.id}`);\n }\n }\n\n // Add any issue IDs that didn't have a matching ticket object\n const ticketIdsFromObjects = new Set(tickets.map((t) => t.id));\n for (const id of issueIds) {\n if (!ticketIdsFromObjects.has(id)) {\n if (id.startsWith('#')) {\n links.push(`Closes ${id}`);\n } else {\n links.push(`Relates to ${id}`);\n }\n }\n }\n\n return links.join('\\n');\n }\n\n /**\n * Generate a simple title from commits\n */\n private generateSimpleTitle(commits: string[]): string {\n if (commits.length === 0) return 'Update';\n\n // Use the most recent commit as base\n const firstCommit = commits[0];\n\n // Extract conventional commit type and message\n const match = firstCommit.match(/^(\\w+)(?:\\([^)]+\\))?:\\s*(.+)/);\n if (match) {\n const [, type, message] = match;\n return `${type}: ${message}`;\n }\n\n return firstCommit.length > 60 ? firstCommit.slice(0, 57) + '...' : firstCommit;\n }\n\n /**\n * Detect PR type from commits\n */\n private detectPRType(commits: string[]): string {\n const types = commits.map((c) => {\n const match = c.match(/^(\\w+)(?:\\([^)]+\\))?:/);\n return match ? match[1] : 'chore';\n });\n\n // Return most common type\n const counts = types.reduce(\n (acc, type) => {\n acc[type] = (acc[type] || 0) + 1;\n return acc;\n },\n {} as Record<string, number>\n );\n\n return Object.entries(counts).sort((a, b) => b[1] - a[1])[0]?.[0] || 'chore';\n }\n\n /**\n * @deprecated Use generateWeeklyFromContext() for accurate results.\n * Kept for backwards compatibility.\n */\n async generateWeeklySummary(data: {\n commits: string[];\n stats: {\n commits: number;\n linesAdded: number;\n linesRemoved: number;\n };\n closedTickets?: Ticket[];\n }): Promise<string> {\n // Include closed tickets for better context\n let ticketContext = '';\n if (data.closedTickets && data.closedTickets.length > 0) {\n ticketContext = `\\nTickets/Tasks Completed This Week:\\n${data.closedTickets.map((t) => ` - ${t.id}: ${t.title} [${t.type}]`).join('\\n')}`;\n }\n\n const prompt = `\nYou are helping a developer create their weekly work summary.\n\nThis week's commits:\n${data.commits.map((c, i) => `${i + 1}. ${c}`).join('\\n')}\n${ticketContext}\n\nStatistics:\n- ${data.stats.commits} commits\n- ${data.stats.linesAdded} lines added\n- ${data.stats.linesRemoved} lines removed\n\nGenerate a professional weekly summary following this format:\n\nKey Accomplishments:\n1. [Major accomplishment with impact - reference ticket if relevant]\n2. [Second accomplishment]\n3. [Third accomplishment]\n4. [Fourth accomplishment]\n5. [Fifth accomplishment]\n\nTop Achievement:\n[Single sentence highlighting the most impactful work]\n\nRequirements:\n- Focus on business value and impact\n- Use ticket titles to give context on WHAT and WHY\n- Be suitable for sharing with manager or team\n- Highlight 3-5 key accomplishments\n- Keep it professional\n- No emojis\n`;\n\n return this.suggest(prompt);\n }\n\n /**\n * Check if debug mode is enabled\n */\n isDebugEnabled(): boolean {\n return this.debugMode;\n }\n}\n","import { execa } from 'execa';\n\nexport interface GitHubIssue {\n number: number;\n title: string;\n body: string;\n state: 'open' | 'closed';\n labels: string[];\n assignees: string[];\n milestone?: string;\n url: string;\n createdAt: string;\n closedAt?: string;\n}\n\nexport interface GitHubPR {\n number: number;\n title: string;\n body: string;\n state: 'open' | 'closed' | 'merged';\n labels: string[];\n url: string;\n baseBranch: string;\n headBranch: string;\n}\n\n/**\n * GitHub integration using the gh CLI\n * Fetches issues, PRs, and project context\n */\nexport class GitHubClient {\n /**\n * Check if we're in a GitHub repository\n */\n async isGitHubRepo(): Promise<boolean> {\n try {\n await execa('gh', ['repo', 'view', '--json', 'name,owner']);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get repository info\n */\n async getRepoInfo(): Promise<{ owner: string; name: string; url: string } | null> {\n try {\n const { stdout } = await execa('gh', ['repo', 'view', '--json', 'name,owner,url']);\n const data = JSON.parse(stdout);\n return {\n owner: data.owner.login,\n name: data.name,\n url: data.url,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Fetch issue details by number\n */\n async getIssue(issueNumber: number): Promise<GitHubIssue | null> {\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'view',\n String(issueNumber),\n '--json',\n 'number,title,body,state,labels,assignees,milestone,url,createdAt,closedAt',\n ]);\n\n const data = JSON.parse(stdout);\n\n return {\n number: data.number,\n title: data.title,\n body: data.body || '',\n state: data.state.toLowerCase(),\n labels: data.labels?.map((l: { name: string }) => l.name) || [],\n assignees: data.assignees?.map((a: { login: string }) => a.login) || [],\n milestone: data.milestone?.title,\n url: data.url,\n createdAt: data.createdAt,\n closedAt: data.closedAt,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Fetch multiple issues by numbers\n */\n async getIssues(issueNumbers: number[]): Promise<GitHubIssue[]> {\n const issues: GitHubIssue[] = [];\n\n // Fetch in parallel but limit concurrency\n const batchSize = 5;\n for (let i = 0; i < issueNumbers.length; i += batchSize) {\n const batch = issueNumbers.slice(i, i + batchSize);\n const results = await Promise.all(batch.map((n) => this.getIssue(n)));\n issues.push(...results.filter((r): r is GitHubIssue => r !== null));\n }\n\n return issues;\n }\n\n /**\n * Get recent issues assigned to the current user\n */\n async getMyRecentIssues(limit: number = 10): Promise<GitHubIssue[]> {\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'list',\n '--assignee',\n '@me',\n '--limit',\n String(limit),\n '--json',\n 'number,title,body,state,labels,url,createdAt',\n ]);\n\n const data = JSON.parse(stdout);\n\n return data.map((issue: Record<string, unknown>) => ({\n number: issue.number,\n title: issue.title,\n body: issue.body || '',\n state: (issue.state as string).toLowerCase(),\n labels: ((issue.labels as Array<{ name: string }>) || []).map((l) => l.name),\n assignees: [],\n url: issue.url,\n createdAt: issue.createdAt,\n }));\n } catch {\n return [];\n }\n }\n\n /**\n * Get issues closed in the last N days\n */\n async getRecentlyClosedIssues(days: number = 7): Promise<GitHubIssue[]> {\n try {\n const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const sinceStr = since.toISOString().split('T')[0];\n\n const { stdout } = await execa('gh', [\n 'issue',\n 'list',\n '--state',\n 'closed',\n '--assignee',\n '@me',\n '--search',\n `closed:>=${sinceStr}`,\n '--json',\n 'number,title,body,state,labels,url,createdAt,closedAt',\n ]);\n\n const data = JSON.parse(stdout);\n\n return data.map((issue: Record<string, unknown>) => ({\n number: issue.number,\n title: issue.title,\n body: issue.body || '',\n state: 'closed',\n labels: ((issue.labels as Array<{ name: string }>) || []).map((l) => l.name),\n assignees: [],\n url: issue.url,\n createdAt: issue.createdAt,\n closedAt: issue.closedAt,\n }));\n } catch {\n return [];\n }\n }\n\n /**\n * Get PR details by number\n */\n async getPR(prNumber: number): Promise<GitHubPR | null> {\n try {\n const { stdout } = await execa('gh', [\n 'pr',\n 'view',\n String(prNumber),\n '--json',\n 'number,title,body,state,labels,url,baseRefName,headRefName',\n ]);\n\n const data = JSON.parse(stdout);\n\n return {\n number: data.number,\n title: data.title,\n body: data.body || '',\n state: data.state.toLowerCase(),\n labels: data.labels?.map((l: { name: string }) => l.name) || [],\n url: data.url,\n baseBranch: data.baseRefName,\n headBranch: data.headRefName,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Search issues by query\n */\n async searchIssues(query: string, limit: number = 10): Promise<GitHubIssue[]> {\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'list',\n '--search',\n query,\n '--limit',\n String(limit),\n '--json',\n 'number,title,body,state,labels,url,createdAt',\n ]);\n\n const data = JSON.parse(stdout);\n\n return data.map((issue: Record<string, unknown>) => ({\n number: issue.number,\n title: issue.title,\n body: issue.body || '',\n state: (issue.state as string).toLowerCase(),\n labels: ((issue.labels as Array<{ name: string }>) || []).map((l) => l.name),\n assignees: [],\n url: issue.url,\n createdAt: issue.createdAt,\n }));\n } catch {\n return [];\n }\n }\n\n /**\n * Format issue for display\n */\n formatIssue(issue: GitHubIssue): string {\n const lines: string[] = [];\n\n lines.push(`#${issue.number}: ${issue.title}`);\n\n if (issue.labels.length > 0) {\n lines.push(`Labels: ${issue.labels.join(', ')}`);\n }\n\n if (issue.body) {\n // Truncate body if too long\n const body = issue.body.length > 500 ? issue.body.slice(0, 500) + '...' : issue.body;\n lines.push('');\n lines.push(body);\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Format issue summary for AI context\n */\n formatIssueForContext(issue: GitHubIssue): string {\n const parts: string[] = [];\n\n parts.push(`Issue #${issue.number}: ${issue.title}`);\n\n if (issue.labels.length > 0) {\n const labelTypes = issue.labels.join(', ');\n parts.push(`Type: ${labelTypes}`);\n }\n\n if (issue.body) {\n // Extract first paragraph or acceptance criteria\n const body = issue.body;\n const firstParagraph = body.split('\\n\\n')[0].slice(0, 300);\n parts.push(`Description: ${firstParagraph}`);\n\n // Look for acceptance criteria\n const acMatch = body.match(/acceptance criteria[:\\s]*\\n([\\s\\S]*?)(?=\\n#|$)/i);\n if (acMatch) {\n parts.push(`Acceptance Criteria: ${acMatch[1].trim().slice(0, 200)}`);\n }\n }\n\n return parts.join('\\n');\n }\n}\n\n// Export singleton\nexport const github = new GitHubClient();\n","import { execa } from 'execa';\nimport { getConfig, getSecrets } from '../config/index.js';\nimport {\n PMAuthError,\n PMConfigError,\n PMConnectionError,\n PMNotFoundError,\n PMRateLimitError,\n PMResponseError,\n type PMConnectionTestResult,\n type PMTool,\n successResult,\n failureResult,\n} from './pm-errors.js';\n\n/**\n * Extract plain text from a Jira ADF (Atlassian Document Format) object.\n * Jira REST API v3 returns `description` as an ADF object, not a string.\n * This recursively walks the ADF tree and concatenates text nodes.\n */\nfunction extractAdfText(node: unknown): string {\n if (node == null) return '';\n if (typeof node === 'string') return node;\n if (typeof node !== 'object') return String(node);\n\n const obj = node as Record<string, unknown>;\n\n // Text node — return its text value\n if (obj.type === 'text' && typeof obj.text === 'string') {\n return obj.text;\n }\n\n // Container node — recurse into content array\n if (Array.isArray(obj.content)) {\n const parts: string[] = [];\n for (const child of obj.content) {\n parts.push(extractAdfText(child));\n }\n // Join paragraphs / blocks with newlines, inline text without separator\n const isBlock =\n obj.type === 'doc' ||\n obj.type === 'paragraph' ||\n obj.type === 'bulletList' ||\n obj.type === 'orderedList' ||\n obj.type === 'listItem' ||\n obj.type === 'blockquote' ||\n obj.type === 'codeBlock' ||\n obj.type === 'heading';\n return parts.join(isBlock ? '\\n' : '');\n }\n\n return '';\n}\n\n/**\n * Common interface for tickets/issues across different tools\n */\nexport interface Ticket {\n id: string; // e.g., \"PROJ-123\", \"ENG-456\"\n title: string;\n description: string;\n status: string;\n type: 'bug' | 'feature' | 'task' | 'story' | 'epic' | 'other';\n priority?: 'low' | 'medium' | 'high' | 'critical';\n assignee?: string;\n labels: string[];\n url: string;\n source: 'github' | 'jira' | 'linear' | 'notion';\n}\n\n/**\n * Default ticket patterns for different tools\n */\nconst TICKET_PATTERNS: Record<string, RegExp> = {\n // JIRA: PROJ-123, ABC-1\n jira: /\\b([A-Z][A-Z0-9]+-\\d+)\\b/gi,\n // Linear: ENG-123, DEV-1 (same format as Jira)\n linear: /\\b([A-Z][A-Z0-9]+-\\d+)\\b/gi,\n // GitHub: #123, gh-123\n github: /#(\\d+)\\b/g,\n // Notion: Uses UUIDs, harder to extract - typically linked\n notion: /\\b([a-f0-9]{32}|[a-f0-9-]{36})\\b/gi,\n};\n\n/**\n * Common branch naming patterns that contain ticket IDs\n */\nconst BRANCH_PATTERNS = [\n // feature/PROJ-123-description\n /^(?:feature|fix|bugfix|hotfix|chore|refactor|docs)\\/([A-Z][A-Z0-9]+-\\d+)/i,\n // PROJ-123/description or PROJ-123-description\n /^([A-Z][A-Z0-9]+-\\d+)[-/]/i,\n // feature/123-description (just number)\n /^(?:feature|fix|bugfix|hotfix|chore|refactor|docs)\\/(\\d+)[-/]/i,\n // user/PROJ-123-description\n /^[a-z0-9_-]+\\/([A-Z][A-Z0-9]+-\\d+)/i,\n];\n\n/**\n * Extract ticket IDs from text (branch name, commit message, etc.)\n */\nexport function extractTicketIds(\n text: string,\n options: {\n tool?: 'github' | 'jira' | 'linear' | 'notion';\n prefix?: string;\n customPattern?: string;\n } = {}\n): string[] {\n const config = getConfig();\n const tool = options.tool || config.projectManagement.tool;\n const prefix = options.prefix || config.projectManagement.ticketPrefix;\n const customPattern = options.customPattern || config.projectManagement.ticketPattern;\n\n const tickets = new Set<string>();\n\n // Use custom pattern if provided\n if (customPattern) {\n try {\n const regex = new RegExp(customPattern, 'gi');\n const matches = text.matchAll(regex);\n for (const match of matches) {\n tickets.add(match[1] || match[0]);\n }\n } catch {\n // Invalid regex, fall through to defaults\n }\n }\n\n // Use prefix-based pattern if provided\n if (prefix) {\n const prefixPattern = new RegExp(`\\\\b(${prefix}-\\\\d+)\\\\b`, 'gi');\n const matches = text.matchAll(prefixPattern);\n for (const match of matches) {\n tickets.add(match[1].toUpperCase());\n }\n }\n\n // Use tool-specific pattern\n if (tool && tool !== 'none' && TICKET_PATTERNS[tool]) {\n const pattern = TICKET_PATTERNS[tool];\n const matches = text.matchAll(pattern);\n for (const match of matches) {\n const ticketId = tool === 'github' ? `#${match[1]}` : match[1].toUpperCase();\n tickets.add(ticketId);\n }\n }\n\n return Array.from(tickets);\n}\n\n/**\n * Extract ticket ID from a branch name\n */\nexport function extractTicketFromBranch(branchName: string): string | null {\n const config = getConfig();\n const prefix = config.projectManagement.ticketPrefix;\n\n // First, try prefix-based extraction if configured\n if (prefix) {\n const prefixPattern = new RegExp(`(${prefix}-\\\\d+)`, 'i');\n const match = branchName.match(prefixPattern);\n if (match) {\n return match[1].toUpperCase();\n }\n }\n\n // Try common branch patterns\n for (const pattern of BRANCH_PATTERNS) {\n const match = branchName.match(pattern);\n if (match) {\n const ticketId = match[1];\n // If it's just a number and we have a prefix, combine them\n if (/^\\d+$/.test(ticketId) && prefix) {\n return `${prefix}-${ticketId}`;\n }\n return ticketId.toUpperCase();\n }\n }\n\n return null;\n}\n\n// ─── Helpers for fetch-based API calls ────────────────────────────────────────\n\n/**\n * Interpret an HTTP response and throw the appropriate PMError\n * if the status code indicates a problem.\n */\nfunction handleHttpStatus(tool: PMTool, response: Response, resourceId?: string): void {\n if (response.ok) return; // 2xx – nothing to do\n\n switch (response.status) {\n case 401:\n case 403:\n throw new PMAuthError(tool, `${tool} returned ${response.status}: ${response.statusText}`);\n case 404:\n if (resourceId) {\n throw new PMNotFoundError(tool, resourceId);\n }\n throw new PMConnectionError(tool, `Resource not found (404) on ${tool}`, 404);\n case 429: {\n const retryAfter = response.headers.get('retry-after');\n const retryMs = retryAfter ? parseInt(retryAfter, 10) * 1000 : undefined;\n throw new PMRateLimitError(tool, retryMs);\n }\n default:\n if (response.status >= 500) {\n throw new PMConnectionError(\n tool,\n `${tool} server error: ${response.status} ${response.statusText}`,\n response.status\n );\n }\n throw new PMResponseError(\n tool,\n `${tool} API returned unexpected status ${response.status}: ${response.statusText}`\n );\n }\n}\n\n/**\n * Safely parse JSON from a Response, wrapping parse errors in PMResponseError\n */\nasync function safeParseJson(tool: PMTool, response: Response): Promise<unknown> {\n const text = await response.text();\n try {\n return JSON.parse(text);\n } catch (err) {\n throw new PMResponseError(tool, `Failed to parse ${tool} API response as JSON`, err);\n }\n}\n\n// ─── Abstract base class ──────────────────────────────────────────────────────\n\n/**\n * Abstract PM client with common helpers\n */\nexport abstract class ProjectManagementClient {\n abstract readonly tool: 'github' | 'jira' | 'linear' | 'notion';\n\n abstract isConfigured(): Promise<boolean>;\n abstract getTicket(ticketId: string): Promise<Ticket | null>;\n abstract getTickets(ticketIds: string[]): Promise<Ticket[]>;\n abstract searchTickets(query: string, limit?: number): Promise<Ticket[]>;\n abstract getMyTickets(limit?: number): Promise<Ticket[]>;\n abstract getRecentlyClosedTickets(days?: number): Promise<Ticket[]>;\n\n /**\n * Test the connection to the PM tool.\n * Validates credentials, reachability, and authentication in one call.\n */\n abstract testConnection(): Promise<PMConnectionTestResult>;\n\n /**\n * Get a list of missing configuration fields for this tool.\n * Returns an empty array when fully configured.\n */\n abstract getMissingConfig(): string[];\n\n /**\n * Format ticket for AI context\n */\n formatTicketForContext(ticket: Ticket): string {\n const lines = [\n `[${ticket.id}] ${ticket.title}`,\n ` Type: ${ticket.type} | Status: ${ticket.status}`,\n ];\n\n if (ticket.priority) {\n lines[1] += ` | Priority: ${ticket.priority}`;\n }\n\n if (ticket.description) {\n // Truncate description to first 200 chars\n const raw =\n typeof ticket.description === 'string' ? ticket.description : String(ticket.description);\n const desc = raw.slice(0, 200).replace(/\\n/g, ' ');\n if (desc) {\n lines.push(` ${desc}${raw.length > 200 ? '...' : ''}`);\n }\n }\n\n return lines.join('\\n');\n }\n}\n\n// ─── Jira Client ──────────────────────────────────────────────────────────────\n\n/**\n * Jira integration using native fetch (REST API v3)\n */\nexport class JiraClient extends ProjectManagementClient {\n readonly tool = 'jira' as const;\n\n // --- configuration helpers (public for testing) ---\n\n getBaseUrl(): string {\n const config = getConfig();\n const secrets = getSecrets();\n return (\n secrets.jira?.baseUrl ||\n config.projectManagement.jira.baseUrl ||\n process.env.JIRA_BASE_URL ||\n ''\n );\n }\n\n getAuth(): { email: string; token: string } | null {\n const secrets = getSecrets();\n const email = secrets.jira?.email || process.env.JIRA_EMAIL;\n const token = secrets.jira?.apiToken || process.env.JIRA_API_TOKEN;\n if (!email || !token) return null;\n return { email, token };\n }\n\n private authHeader(): string {\n const auth = this.getAuth();\n if (!auth) throw new PMConfigError('jira', this.getMissingConfig());\n return 'Basic ' + Buffer.from(`${auth.email}:${auth.token}`).toString('base64');\n }\n\n getMissingConfig(): string[] {\n const missing: string[] = [];\n if (!this.getBaseUrl()) missing.push('baseUrl');\n const secrets = getSecrets();\n const email = secrets.jira?.email || process.env.JIRA_EMAIL;\n const token = secrets.jira?.apiToken || process.env.JIRA_API_TOKEN;\n if (!email) missing.push('email');\n if (!token) missing.push('apiToken');\n return missing;\n }\n\n async isConfigured(): Promise<boolean> {\n return this.getMissingConfig().length === 0;\n }\n\n // --- fetch helper ---\n\n private async jiraFetch(\n path: string,\n options: RequestInit = {},\n resourceId?: string\n ): Promise<unknown> {\n const baseUrl = this.getBaseUrl();\n if (!baseUrl) throw new PMConfigError('jira', ['baseUrl']);\n\n const url = `${baseUrl}${path}`;\n let response: Response;\n try {\n response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n Authorization: this.authHeader(),\n ...(options.headers as Record<string, string> | undefined),\n },\n });\n } catch (err) {\n throw new PMConnectionError(\n 'jira',\n `Could not reach Jira at ${baseUrl} — check network and base URL`,\n undefined,\n err\n );\n }\n\n handleHttpStatus('jira', response, resourceId);\n return safeParseJson('jira', response);\n }\n\n // --- public API ---\n\n async testConnection(): Promise<PMConnectionTestResult> {\n const missing = this.getMissingConfig();\n if (missing.length > 0) {\n return failureResult('jira', new PMConfigError('jira', missing));\n }\n\n const start = Date.now();\n try {\n const data = (await this.jiraFetch('/rest/api/3/myself')) as Record<string, unknown>;\n const elapsed = Date.now() - start;\n const displayName = (data.displayName as string) || (data.emailAddress as string) || '';\n return successResult(\n 'jira',\n displayName ? `Authenticated as ${displayName}` : undefined,\n elapsed\n );\n } catch (err) {\n if (\n err instanceof PMAuthError ||\n err instanceof PMConnectionError ||\n err instanceof PMConfigError\n ) {\n return failureResult('jira', err);\n }\n return failureResult(\n 'jira',\n new PMConnectionError('jira', (err as Error).message, undefined, err)\n );\n }\n }\n\n async getTicket(ticketId: string): Promise<Ticket | null> {\n if (!(await this.isConfigured())) return null;\n try {\n const data = (await this.jiraFetch(\n `/rest/api/3/issue/${encodeURIComponent(ticketId)}`,\n {},\n ticketId\n )) as Record<string, unknown>;\n if ((data as Record<string, unknown>).errorMessages) return null;\n return this.parseJiraIssue(data, this.getBaseUrl());\n } catch {\n return null;\n }\n }\n\n async getTickets(ticketIds: string[]): Promise<Ticket[]> {\n const results = await Promise.all(ticketIds.map((id) => this.getTicket(id)));\n return results.filter((t): t is Ticket => t !== null);\n }\n\n async searchTickets(query: string, limit = 10): Promise<Ticket[]> {\n if (!(await this.isConfigured())) return [];\n const config = getConfig();\n const projectKey = config.projectManagement.jira.projectKey;\n\n try {\n const jql = projectKey\n ? `project = ${projectKey} AND text ~ \"${query}\" ORDER BY updated DESC`\n : `text ~ \"${query}\" ORDER BY updated DESC`;\n\n const params = new URLSearchParams({ jql, maxResults: String(limit) });\n const data = (await this.jiraFetch(`/rest/api/3/search?${params.toString()}`)) as Record<\n string,\n unknown\n >;\n return ((data.issues as unknown[]) || []).map((issue) =>\n this.parseJiraIssue(issue as Record<string, unknown>, this.getBaseUrl())\n );\n } catch {\n return [];\n }\n }\n\n async getMyTickets(limit = 10): Promise<Ticket[]> {\n if (!(await this.isConfigured())) return [];\n try {\n const jql = 'assignee = currentUser() AND status != Done ORDER BY updated DESC';\n const params = new URLSearchParams({ jql, maxResults: String(limit) });\n const data = (await this.jiraFetch(`/rest/api/3/search?${params.toString()}`)) as Record<\n string,\n unknown\n >;\n return ((data.issues as unknown[]) || []).map((issue) =>\n this.parseJiraIssue(issue as Record<string, unknown>, this.getBaseUrl())\n );\n } catch {\n return [];\n }\n }\n\n async getRecentlyClosedTickets(days = 7): Promise<Ticket[]> {\n if (!(await this.isConfigured())) return [];\n try {\n const jql = `assignee = currentUser() AND status = Done AND resolved >= -${days}d ORDER BY resolved DESC`;\n const params = new URLSearchParams({ jql });\n const data = (await this.jiraFetch(`/rest/api/3/search?${params.toString()}`)) as Record<\n string,\n unknown\n >;\n return ((data.issues as unknown[]) || []).map((issue) =>\n this.parseJiraIssue(issue as Record<string, unknown>, this.getBaseUrl())\n );\n } catch {\n return [];\n }\n }\n\n // --- parsing helpers (public for testing) ---\n\n parseJiraIssue(issue: Record<string, unknown>, baseUrl: string): Ticket {\n const fields = issue.fields as Record<string, unknown>;\n const issueType = fields.issuetype as Record<string, unknown>;\n const priority = fields.priority as Record<string, unknown> | null;\n const assignee = fields.assignee as Record<string, unknown> | null;\n const status = fields.status as Record<string, unknown>;\n const labels = fields.labels as string[];\n\n return {\n id: issue.key as string,\n title: fields.summary as string,\n description: extractAdfText(fields.description),\n status: (status?.name as string) || 'unknown',\n type: this.mapJiraType((issueType?.name as string) || ''),\n priority: priority ? this.mapJiraPriority(priority.name as string) : undefined,\n assignee: assignee ? (assignee.displayName as string) : undefined,\n labels: labels || [],\n url: `${baseUrl}/browse/${issue.key}`,\n source: 'jira',\n };\n }\n\n mapJiraType(type: string): 'bug' | 'feature' | 'task' | 'story' | 'epic' | 'other' {\n const lower = type.toLowerCase();\n if (lower.includes('bug')) return 'bug';\n if (lower.includes('feature')) return 'feature';\n if (lower.includes('story')) return 'story';\n if (lower.includes('epic')) return 'epic';\n if (lower.includes('task')) return 'task';\n return 'other';\n }\n\n mapJiraPriority(priority: string): 'low' | 'medium' | 'high' | 'critical' | undefined {\n const lower = priority.toLowerCase();\n if (lower.includes('critical') || lower.includes('blocker')) return 'critical';\n if (lower.includes('high')) return 'high';\n if (lower.includes('medium') || lower.includes('normal')) return 'medium';\n if (lower.includes('low')) return 'low';\n return undefined;\n }\n}\n\n// ─── Linear Client ────────────────────────────────────────────────────────────\n\n/**\n * Linear integration using native fetch (GraphQL API)\n */\nexport class LinearClient extends ProjectManagementClient {\n readonly tool = 'linear' as const;\n\n private static readonly API_URL = 'https://api.linear.app/graphql';\n\n getApiKey(): string | null {\n const secrets = getSecrets();\n return secrets.linear?.apiKey || process.env.LINEAR_API_KEY || null;\n }\n\n getMissingConfig(): string[] {\n return this.getApiKey() ? [] : ['apiKey'];\n }\n\n async isConfigured(): Promise<boolean> {\n return !!this.getApiKey();\n }\n\n // --- fetch helper ---\n\n private async graphql(query: string, variables: Record<string, unknown> = {}): Promise<unknown> {\n const apiKey = this.getApiKey();\n if (!apiKey) throw new PMConfigError('linear', ['apiKey']);\n\n let response: Response;\n try {\n response = await fetch(LinearClient.API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: apiKey,\n },\n body: JSON.stringify({ query, variables }),\n });\n } catch (err) {\n throw new PMConnectionError(\n 'linear',\n 'Could not reach Linear API — check your network connection',\n undefined,\n err\n );\n }\n\n handleHttpStatus('linear', response);\n\n const data = (await safeParseJson('linear', response)) as Record<string, unknown>;\n const errors = data.errors as Array<{ message: string }> | undefined;\n if (errors && errors.length > 0) {\n const msg = errors[0].message;\n if (\n msg.toLowerCase().includes('authentication') ||\n msg.toLowerCase().includes('unauthorized')\n ) {\n throw new PMAuthError('linear', `Linear GraphQL error: ${msg}`);\n }\n throw new PMResponseError('linear', `Linear GraphQL error: ${msg}`);\n }\n return data.data;\n }\n\n // --- public API ---\n\n async testConnection(): Promise<PMConnectionTestResult> {\n const missing = this.getMissingConfig();\n if (missing.length > 0) {\n return failureResult('linear', new PMConfigError('linear', missing));\n }\n\n const start = Date.now();\n try {\n const data = (await this.graphql('query { viewer { id name email } }')) as Record<\n string,\n unknown\n >;\n const elapsed = Date.now() - start;\n const viewer = data.viewer as Record<string, unknown>;\n const name = (viewer?.name as string) || (viewer?.email as string) || '';\n return successResult('linear', name ? `Authenticated as ${name}` : undefined, elapsed);\n } catch (err) {\n if (\n err instanceof PMAuthError ||\n err instanceof PMConnectionError ||\n err instanceof PMConfigError\n ) {\n return failureResult('linear', err);\n }\n return failureResult(\n 'linear',\n new PMConnectionError('linear', (err as Error).message, undefined, err)\n );\n }\n }\n\n async getTicket(ticketId: string): Promise<Ticket | null> {\n try {\n const query = `\n query GetIssue($id: String!) {\n issue(id: $id) {\n id\n identifier\n title\n description\n state { name }\n priority\n assignee { name }\n labels { nodes { name } }\n url\n }\n }\n `;\n\n // Linear uses identifier (e.g., \"ENG-123\") for lookup\n const data = (await this.graphql(query, { id: ticketId })) as Record<string, unknown>;\n const issue = data.issue as Record<string, unknown>;\n if (!issue) return null;\n\n return this.parseLinearIssue(issue);\n } catch {\n return null;\n }\n }\n\n async getTickets(ticketIds: string[]): Promise<Ticket[]> {\n const results = await Promise.all(ticketIds.map((id) => this.getTicket(id)));\n return results.filter((t): t is Ticket => t !== null);\n }\n\n async searchTickets(query: string, limit = 10): Promise<Ticket[]> {\n try {\n const graphqlQuery = `\n query SearchIssues($query: String!, $first: Int!) {\n issueSearch(query: $query, first: $first) {\n nodes {\n id\n identifier\n title\n description\n state { name }\n priority\n assignee { name }\n labels { nodes { name } }\n url\n }\n }\n }\n `;\n\n const data = (await this.graphql(graphqlQuery, { query, first: limit })) as Record<\n string,\n unknown\n >;\n const search = data.issueSearch as Record<string, unknown>;\n const nodes = (search?.nodes as unknown[]) || [];\n return nodes.map((issue) => this.parseLinearIssue(issue as Record<string, unknown>));\n } catch {\n return [];\n }\n }\n\n async getMyTickets(limit = 10): Promise<Ticket[]> {\n try {\n const query = `\n query MyIssues($first: Int!) {\n viewer {\n assignedIssues(first: $first, filter: { state: { type: { nin: [\"completed\", \"canceled\"] } } }) {\n nodes {\n id\n identifier\n title\n description\n state { name }\n priority\n assignee { name }\n labels { nodes { name } }\n url\n }\n }\n }\n }\n `;\n\n const data = (await this.graphql(query, { first: limit })) as Record<string, unknown>;\n const viewer = data.viewer as Record<string, unknown>;\n const assignedIssues = viewer?.assignedIssues as Record<string, unknown>;\n const nodes = (assignedIssues?.nodes as unknown[]) || [];\n return nodes.map((issue) => this.parseLinearIssue(issue as Record<string, unknown>));\n } catch {\n return [];\n }\n }\n\n async getRecentlyClosedTickets(days = 7): Promise<Ticket[]> {\n try {\n const since = new Date();\n since.setDate(since.getDate() - days);\n\n const query = `\n query ClosedIssues($first: Int!, $since: DateTime!) {\n viewer {\n assignedIssues(first: $first, filter: { state: { type: { eq: \"completed\" } }, completedAt: { gte: $since } }) {\n nodes {\n id\n identifier\n title\n description\n state { name }\n priority\n assignee { name }\n labels { nodes { name } }\n url\n }\n }\n }\n }\n `;\n\n const data = (await this.graphql(query, {\n first: 50,\n since: since.toISOString(),\n })) as Record<string, unknown>;\n const viewer = data.viewer as Record<string, unknown>;\n const assignedIssues = viewer?.assignedIssues as Record<string, unknown>;\n const nodes = (assignedIssues?.nodes as unknown[]) || [];\n return nodes.map((issue) => this.parseLinearIssue(issue as Record<string, unknown>));\n } catch {\n return [];\n }\n }\n\n // --- parsing helpers (public for testing) ---\n\n parseLinearIssue(issue: Record<string, unknown>): Ticket {\n const state = issue.state as Record<string, unknown>;\n const assignee = issue.assignee as Record<string, unknown> | null;\n const labelsObj = issue.labels as Record<string, unknown>;\n const labelNodes = (labelsObj?.nodes as Array<{ name: string }>) || [];\n\n return {\n id: issue.identifier as string,\n title: issue.title as string,\n description: (issue.description as string) || '',\n status: (state?.name as string) || 'unknown',\n type: this.inferTypeFromLabels(labelNodes.map((l) => l.name)),\n priority: this.mapLinearPriority(issue.priority as number),\n assignee: assignee ? (assignee.name as string) : undefined,\n labels: labelNodes.map((l) => l.name),\n url: issue.url as string,\n source: 'linear',\n };\n }\n\n inferTypeFromLabels(labels: string[]): 'bug' | 'feature' | 'task' | 'story' | 'epic' | 'other' {\n const joined = labels.join(' ').toLowerCase();\n if (joined.includes('bug')) return 'bug';\n if (joined.includes('feature')) return 'feature';\n if (joined.includes('epic')) return 'epic';\n return 'task';\n }\n\n mapLinearPriority(priority: number): 'low' | 'medium' | 'high' | 'critical' | undefined {\n // Linear uses 0-4: 0=no priority, 1=urgent, 2=high, 3=medium, 4=low\n switch (priority) {\n case 1:\n return 'critical';\n case 2:\n return 'high';\n case 3:\n return 'medium';\n case 4:\n return 'low';\n default:\n return undefined;\n }\n }\n}\n\n// ─── Notion Client ────────────────────────────────────────────────────────────\n\n/**\n * Notion integration using native fetch (REST API, version 2022-06-28)\n */\nexport class NotionClient extends ProjectManagementClient {\n readonly tool = 'notion' as const;\n\n private static readonly API_BASE = 'https://api.notion.com/v1';\n private static readonly API_VERSION = '2022-06-28';\n\n getApiKey(): string | null {\n const secrets = getSecrets();\n return secrets.notion?.apiKey || process.env.NOTION_API_KEY || null;\n }\n\n getDatabaseId(): string | null {\n const config = getConfig();\n const secrets = getSecrets();\n return (\n secrets.notion?.databaseId ||\n config.projectManagement.notion.databaseId ||\n process.env.NOTION_DATABASE_ID ||\n null\n );\n }\n\n getMissingConfig(): string[] {\n const missing: string[] = [];\n if (!this.getApiKey()) missing.push('apiKey');\n if (!this.getDatabaseId()) missing.push('databaseId');\n return missing;\n }\n\n async isConfigured(): Promise<boolean> {\n return this.getMissingConfig().length === 0;\n }\n\n // --- fetch helper ---\n\n private async notionFetch(\n endpoint: string,\n method = 'GET',\n body?: Record<string, unknown>,\n resourceId?: string\n ): Promise<unknown> {\n const apiKey = this.getApiKey();\n if (!apiKey) throw new PMConfigError('notion', ['apiKey']);\n\n const url = `${NotionClient.API_BASE}${endpoint}`;\n const init: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n 'Notion-Version': NotionClient.API_VERSION,\n },\n };\n\n if (body) {\n init.body = JSON.stringify(body);\n }\n\n let response: Response;\n try {\n response = await fetch(url, init);\n } catch (err) {\n throw new PMConnectionError(\n 'notion',\n 'Could not reach Notion API — check your network connection',\n undefined,\n err\n );\n }\n\n handleHttpStatus('notion', response, resourceId);\n return safeParseJson('notion', response);\n }\n\n // --- public API ---\n\n async testConnection(): Promise<PMConnectionTestResult> {\n const missing = this.getMissingConfig();\n if (missing.length > 0) {\n return failureResult('notion', new PMConfigError('notion', missing));\n }\n\n const start = Date.now();\n try {\n // Test 1: check authentication via /users/me\n const user = (await this.notionFetch('/users/me')) as Record<string, unknown>;\n const elapsed = Date.now() - start;\n const name = (user.name as string) || '';\n\n // Test 2: verify database access\n const databaseId = this.getDatabaseId();\n if (databaseId) {\n try {\n await this.notionFetch(`/databases/${databaseId}`, 'GET', undefined, databaseId);\n } catch (err) {\n if (err instanceof PMNotFoundError) {\n return failureResult('notion', new PMNotFoundError('notion', databaseId, 'database'));\n }\n // Auth succeeded but database check failed for another reason – still report\n return failureResult(\n 'notion',\n new PMConnectionError(\n 'notion',\n `Authenticated but could not access database ${databaseId}`\n )\n );\n }\n }\n\n return successResult('notion', name ? `Authenticated as ${name}` : undefined, elapsed);\n } catch (err) {\n if (\n err instanceof PMAuthError ||\n err instanceof PMConnectionError ||\n err instanceof PMConfigError\n ) {\n return failureResult('notion', err);\n }\n return failureResult(\n 'notion',\n new PMConnectionError('notion', (err as Error).message, undefined, err)\n );\n }\n }\n\n async getTicket(ticketId: string): Promise<Ticket | null> {\n try {\n const page = (await this.notionFetch(\n `/pages/${ticketId}`,\n 'GET',\n undefined,\n ticketId\n )) as Record<string, unknown>;\n return this.parseNotionPage(page);\n } catch {\n return null;\n }\n }\n\n async getTickets(ticketIds: string[]): Promise<Ticket[]> {\n const results = await Promise.all(ticketIds.map((id) => this.getTicket(id)));\n return results.filter((t): t is Ticket => t !== null);\n }\n\n async searchTickets(query: string, limit = 10): Promise<Ticket[]> {\n const databaseId = this.getDatabaseId();\n if (!databaseId) return [];\n\n try {\n const response = (await this.notionFetch(`/databases/${databaseId}/query`, 'POST', {\n filter: {\n property: 'Name',\n title: {\n contains: query,\n },\n },\n page_size: limit,\n })) as Record<string, unknown>;\n\n const results = (response.results as unknown[]) || [];\n return results.map((page) => this.parseNotionPage(page as Record<string, unknown>));\n } catch {\n return [];\n }\n }\n\n async getMyTickets(_limit = 10): Promise<Ticket[]> {\n // Notion doesn't have a built-in \"assigned to me\" concept\n // This would need to be customized based on the database schema\n return [];\n }\n\n async getRecentlyClosedTickets(_days = 7): Promise<Ticket[]> {\n // Would need to know the status property name\n return [];\n }\n\n // --- parsing helpers (public for testing) ---\n\n parseNotionPage(page: Record<string, unknown>): Ticket {\n const properties = page.properties as Record<string, unknown>;\n\n // Try to extract title - Notion uses different property names\n let title = 'Untitled';\n const nameProperty = properties.Name || properties.Title || properties.title;\n if (nameProperty) {\n const propObj = nameProperty as Record<string, unknown>;\n const titleArray = propObj.title as Array<{ plain_text: string }>;\n if (titleArray?.[0]) {\n title = titleArray[0].plain_text;\n }\n }\n\n // Try to extract status\n let status = 'unknown';\n const statusProperty = properties.Status || properties.status;\n if (statusProperty) {\n const propObj = statusProperty as Record<string, unknown>;\n const selectObj = propObj.select as Record<string, unknown>;\n if (selectObj) {\n status = selectObj.name as string;\n }\n }\n\n return {\n id: page.id as string,\n title,\n description: '',\n status,\n type: 'task',\n labels: [],\n url: page.url as string,\n source: 'notion',\n };\n }\n}\n\n// ─── GitHub Issues Client ─────────────────────────────────────────────────────\n\n/**\n * GitHub Issues integration using the `gh` CLI.\n *\n * Unlike the other PM clients, this one keeps using `gh` CLI via execa because:\n * - gh CLI handles OAuth/token management automatically\n * - It respects the user's `gh auth` session\n * - No separate API token needed\n */\nexport class GitHubIssueClient extends ProjectManagementClient {\n readonly tool = 'github' as const;\n\n getMissingConfig(): string[] {\n // GitHub uses gh CLI auth – we detect this dynamically in testConnection\n return [];\n }\n\n async isConfigured(): Promise<boolean> {\n try {\n await execa('gh', ['auth', 'status']);\n return true;\n } catch {\n return false;\n }\n }\n\n async testConnection(): Promise<PMConnectionTestResult> {\n const start = Date.now();\n try {\n // Check gh CLI is installed\n try {\n await execa('gh', ['--version']);\n } catch {\n return failureResult('github', new PMConfigError('github', ['gh CLI not installed']));\n }\n\n // Check auth status\n const { stdout: authStatus } = await execa('gh', ['auth', 'status']);\n const elapsed = Date.now() - start;\n\n // Extract account info from auth status output\n const accountMatch = authStatus.match(/Logged in to .+ as (\\S+)/);\n const account = accountMatch ? accountMatch[1] : undefined;\n\n // Verify repo access\n let repoInfo: string | undefined;\n try {\n const { stdout: repoJson } = await execa('gh', ['repo', 'view', '--json', 'nameWithOwner']);\n const repo = JSON.parse(repoJson);\n repoInfo = repo.nameWithOwner;\n } catch {\n // Not in a GitHub repo, but auth works – that's still a success\n }\n\n const info = [\n account ? `Authenticated as ${account}` : 'Authenticated',\n repoInfo ? `repo: ${repoInfo}` : null,\n ]\n .filter(Boolean)\n .join(', ');\n\n return successResult('github', info, elapsed);\n } catch (err) {\n const msg = (err as Error).message || '';\n if (msg.includes('not logged') || msg.includes('auth login')) {\n return failureResult(\n 'github',\n new PMAuthError('github', 'Not authenticated — run `gh auth login`')\n );\n }\n return failureResult('github', new PMConnectionError('github', msg, undefined, err));\n }\n }\n\n async getTicket(ticketId: string): Promise<Ticket | null> {\n const issueNumber = ticketId.replace('#', '');\n\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'view',\n issueNumber,\n '--json',\n 'number,title,body,state,labels,assignees,url',\n ]);\n\n const data = JSON.parse(stdout);\n return this.parseGitHubIssue(data);\n } catch {\n return null;\n }\n }\n\n async getTickets(ticketIds: string[]): Promise<Ticket[]> {\n const results = await Promise.all(ticketIds.map((id) => this.getTicket(id)));\n return results.filter((t): t is Ticket => t !== null);\n }\n\n async searchTickets(query: string, limit = 10): Promise<Ticket[]> {\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'list',\n '--search',\n query,\n '--limit',\n String(limit),\n '--json',\n 'number,title,body,state,labels,assignees,url',\n ]);\n\n const issues = JSON.parse(stdout);\n return issues.map((issue: unknown) =>\n this.parseGitHubIssue(issue as Record<string, unknown>)\n );\n } catch {\n return [];\n }\n }\n\n async getMyTickets(limit = 10): Promise<Ticket[]> {\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'list',\n '--assignee',\n '@me',\n '--limit',\n String(limit),\n '--json',\n 'number,title,body,state,labels,assignees,url',\n ]);\n\n const issues = JSON.parse(stdout);\n return issues.map((issue: unknown) =>\n this.parseGitHubIssue(issue as Record<string, unknown>)\n );\n } catch {\n return [];\n }\n }\n\n async getRecentlyClosedTickets(days = 7): Promise<Ticket[]> {\n const since = new Date();\n since.setDate(since.getDate() - days);\n\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'list',\n '--state',\n 'closed',\n '--assignee',\n '@me',\n '--search',\n `closed:>=${since.toISOString().split('T')[0]}`,\n '--json',\n 'number,title,body,state,labels,assignees,url',\n ]);\n\n const issues = JSON.parse(stdout);\n return issues.map((issue: unknown) =>\n this.parseGitHubIssue(issue as Record<string, unknown>)\n );\n } catch {\n return [];\n }\n }\n\n // --- parsing helpers (public for testing) ---\n\n parseGitHubIssue(issue: Record<string, unknown>): Ticket {\n const labels = (issue.labels as Array<{ name: string }>) || [];\n const assignees = (issue.assignees as Array<{ login: string }>) || [];\n\n return {\n id: `#${issue.number}`,\n title: issue.title as string,\n description: (issue.body as string) || '',\n status: (issue.state as string) === 'OPEN' ? 'open' : 'closed',\n type: this.inferTypeFromLabels(labels.map((l) => l.name)),\n assignee: assignees[0]?.login,\n labels: labels.map((l) => l.name),\n url: issue.url as string,\n source: 'github',\n };\n }\n\n inferTypeFromLabels(labels: string[]): 'bug' | 'feature' | 'task' | 'story' | 'epic' | 'other' {\n const joined = labels.join(' ').toLowerCase();\n if (joined.includes('bug')) return 'bug';\n if (joined.includes('feature') || joined.includes('enhancement')) return 'feature';\n if (joined.includes('epic')) return 'epic';\n return 'task';\n }\n}\n\n// ─── Factory ──────────────────────────────────────────────────────────────────\n\n/**\n * Factory function to get the appropriate project management client\n */\nexport function getProjectManagementClient(): ProjectManagementClient {\n const config = getConfig();\n const tool = config.projectManagement.tool;\n\n switch (tool) {\n case 'jira':\n return new JiraClient();\n case 'linear':\n return new LinearClient();\n case 'notion':\n return new NotionClient();\n case 'github':\n default:\n return new GitHubIssueClient();\n }\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync, appendFileSync } from 'fs';\nimport { homedir } from 'os';\nimport { join, dirname } from 'path';\nimport { Config, ConfigSchema } from './schema.js';\n\n// Config file names\nconst LOCAL_CONFIG_FILENAME = '.devdaily.json';\nconst LOCAL_SECRETS_FILENAME = '.devdaily.secrets.json';\nconst GLOBAL_CONFIG_DIR = join(homedir(), '.config', 'devdaily');\nconst GLOBAL_CONFIG_PATH = join(GLOBAL_CONFIG_DIR, 'config.json');\nconst GLOBAL_SECRETS_PATH = join(GLOBAL_CONFIG_DIR, 'secrets.json');\n\n// Secrets interface (API tokens, emails, etc.)\nexport interface Secrets {\n jira?: {\n email?: string;\n apiToken?: string;\n baseUrl?: string;\n };\n linear?: {\n apiKey?: string;\n };\n notion?: {\n apiKey?: string;\n databaseId?: string;\n };\n slack?: {\n webhookUrl?: string;\n };\n discord?: {\n webhookUrl?: string;\n };\n}\n\nexport class ConfigManager {\n private static instance: ConfigManager;\n private config: Config;\n private secrets: Secrets;\n private configPath: string;\n\n private constructor() {\n this.secrets = this.loadSecrets();\n this.config = this.loadConfig();\n this.configPath = this.findConfigPath();\n }\n\n static getInstance(): ConfigManager {\n if (!ConfigManager.instance) {\n ConfigManager.instance = new ConfigManager();\n }\n return ConfigManager.instance;\n }\n\n private findConfigPath(): string {\n // 1. Check local .devdaily.json\n const localConfig = join(process.cwd(), LOCAL_CONFIG_FILENAME);\n if (existsSync(localConfig)) {\n return localConfig;\n }\n\n // 2. Check global config\n if (existsSync(GLOBAL_CONFIG_PATH)) {\n return GLOBAL_CONFIG_PATH;\n }\n\n // 3. Default to local (will be created on save)\n return localConfig;\n }\n\n private loadSecrets(): Secrets {\n const secrets: Secrets = {};\n\n // Load global secrets first\n if (existsSync(GLOBAL_SECRETS_PATH)) {\n try {\n const content = readFileSync(GLOBAL_SECRETS_PATH, 'utf-8');\n Object.assign(secrets, JSON.parse(content));\n } catch {\n // Invalid secrets file\n }\n }\n\n // Override with local secrets\n const localSecrets = join(process.cwd(), LOCAL_SECRETS_FILENAME);\n if (existsSync(localSecrets)) {\n try {\n const content = readFileSync(localSecrets, 'utf-8');\n const local = JSON.parse(content);\n // Deep merge\n if (local.jira) secrets.jira = { ...secrets.jira, ...local.jira };\n if (local.linear) secrets.linear = { ...secrets.linear, ...local.linear };\n if (local.notion) secrets.notion = { ...secrets.notion, ...local.notion };\n } catch {\n // Invalid secrets file\n }\n }\n\n // Also check environment variables as fallback\n if (process.env.JIRA_EMAIL || process.env.JIRA_API_TOKEN || process.env.JIRA_BASE_URL) {\n secrets.jira = {\n ...secrets.jira,\n email: process.env.JIRA_EMAIL || secrets.jira?.email,\n apiToken: process.env.JIRA_API_TOKEN || secrets.jira?.apiToken,\n baseUrl: process.env.JIRA_BASE_URL || secrets.jira?.baseUrl,\n };\n }\n\n if (process.env.LINEAR_API_KEY) {\n secrets.linear = {\n ...secrets.linear,\n apiKey: process.env.LINEAR_API_KEY || secrets.linear?.apiKey,\n };\n }\n\n if (process.env.NOTION_API_KEY || process.env.NOTION_DATABASE_ID) {\n secrets.notion = {\n ...secrets.notion,\n apiKey: process.env.NOTION_API_KEY || secrets.notion?.apiKey,\n databaseId: process.env.NOTION_DATABASE_ID || secrets.notion?.databaseId,\n };\n }\n\n return secrets;\n }\n\n private loadConfig(): Config {\n let globalConfig: Partial<Config> = {};\n let localConfig: Partial<Config> = {};\n\n // Load global config first\n if (existsSync(GLOBAL_CONFIG_PATH)) {\n try {\n const content = readFileSync(GLOBAL_CONFIG_PATH, 'utf-8');\n globalConfig = JSON.parse(content);\n } catch {\n // Invalid config\n }\n }\n\n // Load local config (overrides global)\n const localConfigPath = join(process.cwd(), LOCAL_CONFIG_FILENAME);\n if (existsSync(localConfigPath)) {\n try {\n const content = readFileSync(localConfigPath, 'utf-8');\n localConfig = JSON.parse(content);\n } catch {\n // Invalid config\n }\n }\n\n // Merge: global defaults < global config < local config\n const merged = this.deepMerge(globalConfig, localConfig);\n\n return ConfigSchema.parse(merged);\n }\n\n private deepMerge(\n target: Record<string, unknown>,\n source: Record<string, unknown>\n ): Record<string, unknown> {\n const result = { ...target };\n\n for (const key of Object.keys(source)) {\n if (\n source[key] &&\n typeof source[key] === 'object' &&\n !Array.isArray(source[key]) &&\n target[key] &&\n typeof target[key] === 'object'\n ) {\n result[key] = this.deepMerge(\n target[key] as Record<string, unknown>,\n source[key] as Record<string, unknown>\n );\n } else {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n get(): Config {\n return this.config;\n }\n\n getSecrets(): Secrets {\n return this.secrets;\n }\n\n set<K extends keyof Config>(key: K, value: Config[K]): void {\n this.config[key] = value;\n this.save();\n }\n\n update(partial: Partial<Config>): void {\n this.config = ConfigSchema.parse({ ...this.config, ...partial });\n this.save();\n }\n\n private save(): void {\n const dir = dirname(this.configPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(this.configPath, JSON.stringify(this.config, null, 2));\n }\n\n saveGlobal(): void {\n if (!existsSync(GLOBAL_CONFIG_DIR)) {\n mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });\n }\n writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(this.config, null, 2));\n }\n\n saveLocal(config?: Partial<Config>): void {\n const localPath = join(process.cwd(), LOCAL_CONFIG_FILENAME);\n const toSave = config ? ConfigSchema.parse({ ...this.config, ...config }) : this.config;\n // Add JSON schema reference for IDE autocomplete\n const withSchema = {\n $schema:\n 'https://raw.githubusercontent.com/hempun10/devdaily/main/schemas/devdaily.schema.json',\n ...toSave,\n };\n writeFileSync(localPath, JSON.stringify(withSchema, null, 2));\n }\n\n saveSecrets(secrets: Secrets, global = false): void {\n if (global) {\n if (!existsSync(GLOBAL_CONFIG_DIR)) {\n mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });\n }\n writeFileSync(GLOBAL_SECRETS_PATH, JSON.stringify(secrets, null, 2));\n } else {\n const localPath = join(process.cwd(), LOCAL_SECRETS_FILENAME);\n writeFileSync(localPath, JSON.stringify(secrets, null, 2));\n }\n\n // Merge into current secrets\n this.secrets = { ...this.secrets, ...secrets };\n }\n\n /**\n * Add secrets file to .gitignore\n */\n addSecretsToGitignore(): boolean {\n const gitignorePath = join(process.cwd(), '.gitignore');\n const secretsEntry = LOCAL_SECRETS_FILENAME;\n\n if (existsSync(gitignorePath)) {\n const content = readFileSync(gitignorePath, 'utf-8');\n if (content.includes(secretsEntry)) {\n return false; // Already in gitignore\n }\n appendFileSync(gitignorePath, `\\n# DevDaily secrets (API tokens)\\n${secretsEntry}\\n`);\n } else {\n writeFileSync(gitignorePath, `# DevDaily secrets (API tokens)\\n${secretsEntry}\\n`);\n }\n\n return true;\n }\n\n reset(): void {\n this.config = ConfigSchema.parse({});\n this.save();\n }\n\n getConfigPath(): string {\n return this.configPath;\n }\n\n isUsingLocalConfig(): boolean {\n return this.configPath === join(process.cwd(), LOCAL_CONFIG_FILENAME);\n }\n\n static getGlobalConfigPath(): string {\n return GLOBAL_CONFIG_PATH;\n }\n\n static getLocalConfigPath(): string {\n return join(process.cwd(), LOCAL_CONFIG_FILENAME);\n }\n\n static getLocalSecretsPath(): string {\n return join(process.cwd(), LOCAL_SECRETS_FILENAME);\n }\n}\n\n// Export singleton getter\nexport const getConfig = () => ConfigManager.getInstance().get();\nexport const getSecrets = () => ConfigManager.getInstance().getSecrets();\nexport const config = ConfigManager.getInstance();\n","import { z } from 'zod';\n\n// Theme configuration\nexport const ThemeSchema = z.object({\n primary: z.string().default('blue'),\n success: z.string().default('green'),\n warning: z.string().default('yellow'),\n error: z.string().default('red'),\n accent: z.string().default('cyan'),\n muted: z.string().default('gray'),\n});\n\n// Aliases configuration\nexport const AliasesSchema = z.object({\n standup: z.array(z.string()).default(['s', 'su', 'daily']),\n pr: z.array(z.string()).default(['p', 'pull']),\n week: z.array(z.string()).default(['w', 'weekly']),\n dash: z.array(z.string()).default(['d', 'dashboard']),\n});\n\n// Output defaults\nexport const OutputSchema = z.object({\n format: z.enum(['markdown', 'slack', 'plain', 'json']).default('markdown'),\n copyToClipboard: z.boolean().default(true),\n showStats: z.boolean().default(true),\n verbose: z.boolean().default(false),\n});\n\n// Git configuration\nexport const GitSchema = z.object({\n defaultBranch: z.string().default('main'),\n excludeAuthors: z.array(z.string()).default([]),\n excludePatterns: z.array(z.string()).default(['merge commit', 'Merge branch']),\n});\n\n// Project configuration (for multi-project support)\nexport const ProjectSchema = z.object({\n name: z.string(),\n path: z.string(),\n defaultBranch: z.string().optional(),\n team: z.array(z.string()).optional(),\n});\n\n// Shortcuts configuration\nexport const ShortcutsSchema = z.object({\n quit: z.string().default('q'),\n help: z.string().default('?'),\n refresh: z.string().default('r'),\n copy: z.string().default('c'),\n create: z.string().default('enter'),\n back: z.string().default('esc'),\n nextProject: z.string().default('tab'),\n prevProject: z.string().default('shift+tab'),\n});\n\n// Project Management Tool configuration\nexport const ProjectManagementSchema = z.object({\n // Which tool to use: github, jira, linear, notion, or none\n tool: z.enum(['github', 'jira', 'linear', 'notion', 'none']).default('github'),\n\n // Ticket/Issue prefix pattern (e.g., \"PROJ\", \"ENG\", \"DEV\")\n // Used to extract ticket numbers from branch names and commits\n ticketPrefix: z.string().optional(),\n\n // Custom regex pattern for ticket extraction (advanced)\n // Default patterns are provided for each tool\n ticketPattern: z.string().optional(),\n\n // Jira-specific settings\n jira: z\n .object({\n // Jira instance URL (e.g., \"https://yourcompany.atlassian.net\")\n baseUrl: z.string().optional(),\n // API token (stored separately for security, this is just a flag)\n // Actual token should be in JIRA_API_TOKEN env var\n useApiToken: z.boolean().default(true),\n // Default project key\n projectKey: z.string().optional(),\n })\n .default({}),\n\n // Linear-specific settings\n linear: z\n .object({\n // Team key (e.g., \"ENG\", \"DEV\")\n teamKey: z.string().optional(),\n // Use Linear CLI or API\n // Actual token should be in LINEAR_API_KEY env var\n useApi: z.boolean().default(true),\n })\n .default({}),\n\n // Notion-specific settings\n notion: z\n .object({\n // Database ID for tasks/issues\n databaseId: z.string().optional(),\n // Use Notion API\n // Actual token should be in NOTION_API_KEY env var\n useApi: z.boolean().default(true),\n })\n .default({}),\n});\n\n// Journal / snapshot automation\nexport const JournalSchema = z.object({\n // Automatically take a light snapshot when running standup, pr, week commands\n autoSnapshot: z.boolean().default(true),\n\n // Install git hooks (post-commit, post-checkout) to capture snapshots automatically\n gitHooks: z.boolean().default(false),\n\n // Which git hooks to install when gitHooks is enabled\n hooks: z\n .object({\n postCommit: z.boolean().default(true),\n postCheckout: z.boolean().default(true),\n })\n .default({}),\n\n // Maximum age in days before journal entries are auto-pruned (0 = never)\n autoPromptDays: z.number().default(0),\n\n // Quiet mode — suppress snapshot side-effect messages in other commands\n quiet: z.boolean().default(true),\n});\n\n// Full configuration schema\nexport const ConfigSchema = z.object({\n // Version for config migrations\n version: z.number().default(1),\n\n // Display settings\n theme: ThemeSchema.default({}),\n ascii: z.boolean().default(true),\n animations: z.boolean().default(true),\n compactMode: z.boolean().default(false),\n\n // Command aliases\n aliases: AliasesSchema.default({}),\n\n // Output preferences\n output: OutputSchema.default({}),\n\n // Git settings\n git: GitSchema.default({}),\n\n // Multi-project support\n projects: z.array(ProjectSchema).default([]),\n activeProject: z.string().optional(),\n\n // Keyboard shortcuts\n shortcuts: ShortcutsSchema.default({}),\n\n // Project management integration\n projectManagement: ProjectManagementSchema.default({}),\n\n // Notifications (Slack/Discord webhooks)\n notifications: z\n .object({\n slack: z\n .object({\n enabled: z.boolean().default(false),\n webhookUrl: z.string().optional(),\n channel: z.string().optional(),\n })\n .default({}),\n discord: z\n .object({\n enabled: z.boolean().default(false),\n webhookUrl: z.string().optional(),\n })\n .default({}),\n // Schedule for auto-standup (e.g., \"0 8 * * 1-5\" = 8am weekdays)\n standupSchedule: z.string().optional(),\n standupTimezone: z.string().default('America/New_York'),\n })\n .default({}),\n\n // Journal / snapshot automation\n journal: JournalSchema.default({}),\n\n // AI/Copilot settings\n copilot: z\n .object({\n timeout: z.number().default(30000),\n retries: z.number().default(2),\n })\n .default({}),\n\n // Standup defaults\n standup: z\n .object({\n defaultDays: z.number().default(1),\n includeWIP: z.boolean().default(false),\n template: z.string().optional(),\n sections: z\n .array(z.enum(['completed', 'in-progress', 'blockers', 'tickets', 'stats']))\n .default(['completed', 'in-progress', 'blockers']),\n groupBy: z.enum(['ticket', 'category', 'time', 'none']).default('none'),\n includeTicketLinks: z.boolean().default(true),\n scheduleTime: z.string().optional(),\n scheduleDays: z\n .array(\n z.enum(['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'])\n )\n .default(['monday', 'tuesday', 'wednesday', 'thursday', 'friday']),\n })\n .default({}),\n\n // PR defaults\n pr: z\n .object({\n defaultBase: z.string().default('main'),\n template: z.string().optional(),\n autoLabels: z.boolean().default(true),\n defaultLabels: z.array(z.string()).default([]),\n defaultReviewers: z.array(z.string()).default([]),\n defaultAssignees: z.array(z.string()).default([]),\n titleFormat: z.enum(['conventional', 'ticket-first', 'plain']).default('conventional'),\n includeTicketInTitle: z.boolean().default(true),\n // Path to a custom PR description prompt file (like CLAUDE.md for PRs)\n // Searched automatically in: .devdaily-pr-prompt.md, .github/devdaily-pr-prompt.md, etc.\n promptFile: z.string().optional(),\n // Whether to include diff summary in the AI prompt for richer descriptions\n includeDiff: z.boolean().default(true),\n // Max lines of diff to include in the AI prompt (to avoid token limits)\n maxDiffLines: z.number().default(200),\n })\n .default({}),\n\n // Week defaults\n week: z\n .object({\n startDay: z.enum(['sunday', 'monday']).default('monday'),\n includeWeekends: z.boolean().default(false),\n })\n .default({}),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\nexport type Theme = z.infer<typeof ThemeSchema>;\nexport type Shortcuts = z.infer<typeof ShortcutsSchema>;\nexport type Project = z.infer<typeof ProjectSchema>;\nexport type ProjectManagement = z.infer<typeof ProjectManagementSchema>;\nexport type Journal = z.infer<typeof JournalSchema>;\n","/**\n * PM Error Types - Structured error handling for project management integrations\n *\n * Provides actionable error messages so users know exactly what went wrong\n * and how to fix it, rather than silent failures.\n */\n\nexport type PMTool = 'github' | 'jira' | 'linear' | 'notion';\n\n/**\n * Base error for all PM integration failures\n */\nexport class PMError extends Error {\n readonly tool: PMTool;\n readonly hint: string;\n\n constructor(tool: PMTool, message: string, hint: string, cause?: unknown) {\n super(message);\n this.name = 'PMError';\n this.tool = tool;\n this.hint = hint;\n if (cause) this.cause = cause;\n }\n\n /**\n * Format for user-facing display (CLI output)\n */\n toUserMessage(): string {\n return `[${this.tool.toUpperCase()}] ${this.message}\\n → ${this.hint}`;\n }\n}\n\n/**\n * Authentication/authorization failures\n * Examples: invalid API token, expired credentials, missing permissions\n */\nexport class PMAuthError extends PMError {\n constructor(tool: PMTool, details?: string, cause?: unknown) {\n const message = details || `Authentication failed for ${tool}`;\n const hints: Record<PMTool, string> = {\n jira: 'Check JIRA_API_TOKEN and JIRA_EMAIL env vars, or run `devdaily init --pm` to reconfigure',\n linear: 'Check LINEAR_API_KEY env var, or generate a new key at Linear Settings → API',\n notion: 'Check NOTION_API_KEY env var, or create an integration at notion.so/my-integrations',\n github: 'Run `gh auth login` to authenticate with GitHub CLI',\n };\n super(tool, message, hints[tool], cause);\n this.name = 'PMAuthError';\n }\n}\n\n/**\n * Connection/network failures\n * Examples: DNS resolution failed, timeout, unreachable host\n */\nexport class PMConnectionError extends PMError {\n readonly statusCode?: number;\n\n constructor(tool: PMTool, details?: string, statusCode?: number, cause?: unknown) {\n const message = details || `Could not connect to ${tool}`;\n const hints: Record<PMTool, string> = {\n jira: 'Verify your Jira base URL (e.g., https://yourcompany.atlassian.net) and network connection',\n linear: 'Check your network connection — Linear API endpoint: https://api.linear.app/graphql',\n notion: 'Check your network connection — Notion API endpoint: https://api.notion.com',\n github: 'Check your network connection and verify `gh` CLI is working: `gh auth status`',\n };\n super(tool, message, hints[tool], cause);\n this.name = 'PMConnectionError';\n this.statusCode = statusCode;\n }\n}\n\n/**\n * Resource not found\n * Examples: ticket ID doesn't exist, project key is wrong, database not found\n */\nexport class PMNotFoundError extends PMError {\n readonly resourceId: string;\n\n constructor(tool: PMTool, resourceId: string, resourceType = 'ticket', cause?: unknown) {\n const message = `${resourceType} \"${resourceId}\" not found in ${tool}`;\n const hints: Record<PMTool, string> = {\n jira: `Verify the ticket ID format (e.g., PROJ-123) and that it exists in your Jira instance`,\n linear: `Verify the issue identifier (e.g., ENG-123) and that you have access to the team`,\n notion: `Verify the page/database ID and that your integration has access to it`,\n github: `Verify the issue number exists in this repository: gh issue view ${resourceId}`,\n };\n super(tool, message, hints[tool], cause);\n this.name = 'PMNotFoundError';\n this.resourceId = resourceId;\n }\n}\n\n/**\n * Rate limiting\n */\nexport class PMRateLimitError extends PMError {\n readonly retryAfterMs?: number;\n\n constructor(tool: PMTool, retryAfterMs?: number, cause?: unknown) {\n const retryStr = retryAfterMs ? ` Retry after ${Math.ceil(retryAfterMs / 1000)} seconds.` : '';\n const message = `Rate limited by ${tool} API.${retryStr}`;\n super(tool, message, 'Wait a moment and try again, or reduce request frequency', cause);\n this.name = 'PMRateLimitError';\n this.retryAfterMs = retryAfterMs;\n }\n}\n\n/**\n * Configuration missing or invalid\n * Examples: no base URL set, no API key configured, invalid project key\n */\nexport class PMConfigError extends PMError {\n readonly missingFields: string[];\n\n constructor(tool: PMTool, missingFields: string[], cause?: unknown) {\n const fieldStr = missingFields.join(', ');\n const message = `${tool} integration is not fully configured — missing: ${fieldStr}`;\n const hints: Record<PMTool, string> = {\n jira: `Run \\`devdaily init --pm\\` or set env vars: ${missingFields.map((f) => jiraFieldToEnv(f)).join(', ')}`,\n linear: `Run \\`devdaily init --pm\\` or set env var: LINEAR_API_KEY`,\n notion: `Run \\`devdaily init --pm\\` or set env vars: ${missingFields.map((f) => notionFieldToEnv(f)).join(', ')}`,\n github: `Run \\`gh auth login\\` to authenticate with GitHub CLI`,\n };\n super(tool, message, hints[tool], cause);\n this.name = 'PMConfigError';\n this.missingFields = missingFields;\n }\n}\n\n/**\n * Invalid API response (unexpected shape, parse error)\n */\nexport class PMResponseError extends PMError {\n constructor(tool: PMTool, details?: string, cause?: unknown) {\n const message = details || `Unexpected response from ${tool} API`;\n super(\n tool,\n message,\n 'This may indicate an API version mismatch or a temporary service issue. Try again or check the API status page.',\n cause\n );\n this.name = 'PMResponseError';\n }\n}\n\n// --- Helper mappings for env var hints ---\n\nfunction jiraFieldToEnv(field: string): string {\n const map: Record<string, string> = {\n baseUrl: 'JIRA_BASE_URL',\n email: 'JIRA_EMAIL',\n apiToken: 'JIRA_API_TOKEN',\n projectKey: 'projectManagement.jira.projectKey in .devdaily.json',\n };\n return map[field] || field;\n}\n\nfunction notionFieldToEnv(field: string): string {\n const map: Record<string, string> = {\n apiKey: 'NOTION_API_KEY',\n databaseId: 'NOTION_DATABASE_ID',\n };\n return map[field] || field;\n}\n\n// --- Connection test result type ---\n\nexport interface PMConnectionTestResult {\n tool: PMTool;\n success: boolean;\n message: string;\n details: {\n /** Whether required credentials are present */\n credentialsFound: boolean;\n /** Whether the API responded successfully */\n apiReachable: boolean;\n /** Whether the credentials are valid (authenticated successfully) */\n authenticated: boolean;\n /** Detected project/team info (e.g., Jira project key, Linear team) */\n projectInfo?: string;\n /** Response time in milliseconds */\n responseTimeMs?: number;\n };\n error?: PMError;\n}\n\n/**\n * Create a successful connection test result\n */\nexport function successResult(\n tool: PMTool,\n projectInfo?: string,\n responseTimeMs?: number\n): PMConnectionTestResult {\n return {\n tool,\n success: true,\n message: `Successfully connected to ${tool}${projectInfo ? ` (${projectInfo})` : ''}`,\n details: {\n credentialsFound: true,\n apiReachable: true,\n authenticated: true,\n projectInfo,\n responseTimeMs,\n },\n };\n}\n\n/**\n * Create a failed connection test result from a PMError\n */\nexport function failureResult(tool: PMTool, error: PMError): PMConnectionTestResult {\n const isAuthError = error instanceof PMAuthError;\n const isConfigError = error instanceof PMConfigError;\n const isConnectionError = error instanceof PMConnectionError;\n\n return {\n tool,\n success: false,\n message: error.message,\n details: {\n credentialsFound: !isConfigError,\n apiReachable: !isConnectionError,\n authenticated: !isAuthError,\n },\n error,\n };\n}\n","/**\n * Context Analyzer - Extract rich context from git activity\n *\n * Features:\n * - Branch → Ticket correlation (JIRA-123, #123, LINEAR-123)\n * - Work categorization (frontend, backend, infra, docs)\n * - Commit message analysis\n * - Time-based work session tracking\n */\n\nimport { GitAnalyzer } from './git-analyzer.js';\nimport { Commit } from '../types/index.js';\n\n// Ticket patterns for different PM tools\nconst TICKET_PATTERNS = {\n jira: /([A-Z]{2,10}-\\d+)/gi,\n linear: /([A-Z]{2,5}-\\d+)/gi,\n github: /#(\\d+)/g,\n notion: /([a-f0-9]{32})/gi,\n};\n\n// File patterns for work categorization\nconst WORK_CATEGORIES = {\n frontend: [\n /\\.tsx?$/,\n /\\.jsx?$/,\n /\\.vue$/,\n /\\.svelte$/,\n /\\.css$/,\n /\\.scss$/,\n /\\.less$/,\n /components\\//,\n /pages\\//,\n /views\\//,\n /ui\\//,\n /styles\\//,\n ],\n backend: [\n /\\.go$/,\n /\\.py$/,\n /\\.rb$/,\n /\\.java$/,\n /\\.rs$/,\n /\\.php$/,\n /api\\//,\n /server\\//,\n /services\\//,\n /handlers\\//,\n /controllers\\//,\n /routes\\//,\n ],\n infrastructure: [\n /Dockerfile/,\n /docker-compose/,\n /\\.ya?ml$/,\n /\\.tf$/,\n /\\.hcl$/,\n /k8s\\//,\n /kubernetes\\//,\n /\\.github\\/workflows\\//,\n /\\.circleci\\//,\n /infra\\//,\n /deploy\\//,\n ],\n database: [/\\.sql$/, /migrations\\//, /prisma\\//, /schema\\./, /models\\//, /entities\\//],\n tests: [/\\.test\\./, /\\.spec\\./, /__tests__\\//, /tests?\\//, /cypress\\//, /e2e\\//],\n docs: [/\\.md$/, /\\.mdx$/, /docs?\\//, /README/, /CHANGELOG/, /CONTRIBUTING/],\n config: [\n /\\.json$/,\n /\\.ya?ml$/,\n /\\.toml$/,\n /\\.env/,\n /config\\//,\n /\\.config\\./,\n /tsconfig/,\n /package\\.json/,\n ],\n};\n\nexport interface TicketInfo {\n id: string;\n type: 'jira' | 'linear' | 'github' | 'notion' | 'unknown';\n url?: string;\n}\n\nexport interface WorkCategory {\n name: string;\n files: string[];\n percentage: number;\n}\n\nexport interface WorkContext {\n branch: string;\n tickets: TicketInfo[];\n categories: WorkCategory[];\n commitCount: number;\n filesChanged: string[];\n authors: string[];\n timeRange: {\n start: Date;\n end: Date;\n durationHours: number;\n };\n summary: {\n primaryCategory: string;\n ticketSummary: string;\n workDescription: string;\n };\n}\n\nexport class ContextAnalyzer {\n private git: GitAnalyzer;\n private ticketPrefix?: string;\n private pmTool: 'github' | 'jira' | 'linear' | 'notion' | 'none';\n\n constructor(\n repoPath?: string,\n pmTool: 'github' | 'jira' | 'linear' | 'notion' | 'none' = 'github',\n ticketPrefix?: string\n ) {\n this.git = new GitAnalyzer(repoPath);\n this.pmTool = pmTool;\n this.ticketPrefix = ticketPrefix;\n }\n\n /**\n * Extract ticket IDs from branch name\n */\n extractTicketsFromBranch(branchName: string): TicketInfo[] {\n const tickets: TicketInfo[] = [];\n\n // Try PM-specific pattern first\n if (this.ticketPrefix) {\n const prefixPattern = new RegExp(`(${this.ticketPrefix}-\\\\d+)`, 'gi');\n const matches = branchName.match(prefixPattern);\n if (matches) {\n for (const match of matches) {\n tickets.push({\n id: match.toUpperCase(),\n type: this.pmTool === 'none' ? 'unknown' : this.pmTool,\n });\n }\n }\n }\n\n // Try all patterns\n for (const [type, pattern] of Object.entries(TICKET_PATTERNS)) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(branchName)) !== null) {\n const id = type === 'github' ? `#${match[1]}` : match[1].toUpperCase();\n if (!tickets.find((t) => t.id === id)) {\n tickets.push({\n id,\n type: type as TicketInfo['type'],\n });\n }\n }\n }\n\n return tickets;\n }\n\n /**\n * Extract ticket IDs from commit messages\n */\n extractTicketsFromCommits(commits: Commit[]): TicketInfo[] {\n const tickets: TicketInfo[] = [];\n const seen = new Set<string>();\n\n for (const commit of commits) {\n const text = `${commit.message} ${commit.body || ''}`;\n\n // Try PM-specific pattern first\n if (this.ticketPrefix) {\n const prefixPattern = new RegExp(`(${this.ticketPrefix}-\\\\d+)`, 'gi');\n const matches = text.match(prefixPattern);\n if (matches) {\n for (const match of matches) {\n const id = match.toUpperCase();\n if (!seen.has(id)) {\n seen.add(id);\n tickets.push({\n id,\n type: this.pmTool === 'none' ? 'unknown' : this.pmTool,\n });\n }\n }\n }\n }\n\n // Try all patterns\n for (const [type, pattern] of Object.entries(TICKET_PATTERNS)) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(text)) !== null) {\n const id = type === 'github' ? `#${match[1]}` : match[1].toUpperCase();\n if (!seen.has(id)) {\n seen.add(id);\n tickets.push({\n id,\n type: type as TicketInfo['type'],\n });\n }\n }\n }\n }\n\n return tickets;\n }\n\n /**\n * Categorize files by work type\n */\n categorizeFiles(files: string[]): WorkCategory[] {\n const categoryCounts: Record<string, string[]> = {};\n\n for (const category of Object.keys(WORK_CATEGORIES)) {\n categoryCounts[category] = [];\n }\n\n for (const file of files) {\n let categorized = false;\n\n for (const [category, patterns] of Object.entries(WORK_CATEGORIES)) {\n for (const pattern of patterns) {\n if (pattern.test(file)) {\n categoryCounts[category].push(file);\n categorized = true;\n break;\n }\n }\n if (categorized) break;\n }\n\n if (!categorized) {\n if (!categoryCounts['other']) {\n categoryCounts['other'] = [];\n }\n categoryCounts['other'].push(file);\n }\n }\n\n const total = files.length || 1;\n const categories: WorkCategory[] = [];\n\n for (const [name, categoryFiles] of Object.entries(categoryCounts)) {\n if (categoryFiles.length > 0) {\n categories.push({\n name,\n files: categoryFiles,\n percentage: Math.round((categoryFiles.length / total) * 100),\n });\n }\n }\n\n // Sort by percentage descending\n categories.sort((a, b) => b.percentage - a.percentage);\n\n return categories;\n }\n\n /**\n * Get comprehensive work context\n */\n async getWorkContext(\n options: {\n since?: Date;\n until?: Date;\n base?: string;\n } = {}\n ): Promise<WorkContext> {\n const branch = await this.git.getCurrentBranch();\n const commits = await this.git.getCommits({\n since: options.since,\n until: options.until,\n });\n\n let filesChanged: string[] = [];\n\n // Try git diff first (works best on feature branches)\n try {\n filesChanged = await this.git.getChangedFiles(options.base || 'main', 'HEAD');\n } catch {\n // Expected: fails when base branch doesn't exist locally, or when on main branch\n // with no upstream. Falls through to commit-based file detection below.\n }\n\n // Fallback: get files from commit history if diff returned nothing\n if (filesChanged.length === 0 && commits.length > 0) {\n try {\n filesChanged = await this.git.getFilesFromCommits({\n since: options.since,\n until: options.until,\n });\n } catch {\n // Expected: may fail in shallow clones or repos with no commit history.\n // Proceed with empty filesChanged — categorization will just be skipped.\n }\n }\n\n // Extract tickets from branch and commits\n const branchTickets = this.extractTicketsFromBranch(branch);\n const commitTickets = this.extractTicketsFromCommits(commits);\n\n // Deduplicate tickets\n const ticketMap = new Map<string, TicketInfo>();\n for (const ticket of [...branchTickets, ...commitTickets]) {\n ticketMap.set(ticket.id, ticket);\n }\n const tickets = Array.from(ticketMap.values());\n\n // Categorize files\n const categories = this.categorizeFiles(filesChanged);\n\n // Get unique authors\n const authors = [...new Set(commits.map((c) => c.author))];\n\n // Calculate time range\n const dates = commits.map((c) => c.date);\n const start =\n dates.length > 0 ? new Date(Math.min(...dates.map((d) => d.getTime()))) : new Date();\n const end =\n dates.length > 0 ? new Date(Math.max(...dates.map((d) => d.getTime()))) : new Date();\n const durationHours = (end.getTime() - start.getTime()) / (1000 * 60 * 60);\n\n // Generate summary\n const primaryCategory = categories.length > 0 ? categories[0].name : 'general';\n const ticketSummary =\n tickets.length > 0\n ? `Working on ${tickets.map((t) => t.id).join(', ')}`\n : 'No tickets linked';\n const workDescription = this.generateWorkDescription(categories, commits);\n\n return {\n branch,\n tickets,\n categories,\n commitCount: commits.length,\n filesChanged,\n authors,\n timeRange: {\n start,\n end,\n durationHours: Math.round(durationHours * 10) / 10,\n },\n summary: {\n primaryCategory,\n ticketSummary,\n workDescription,\n },\n };\n }\n\n /**\n * Generate human-readable work description\n */\n private generateWorkDescription(categories: WorkCategory[], commits: Commit[]): string {\n const parts: string[] = [];\n\n // Top 2 categories\n const topCategories = categories.slice(0, 2);\n if (topCategories.length > 0) {\n const categoryNames = topCategories.map((c) => c.name).join(' and ');\n parts.push(`${categoryNames} work`);\n }\n\n // Commit types\n const commitTypes = this.analyzeCommitTypes(commits);\n if (commitTypes.length > 0) {\n parts.push(`(${commitTypes.join(', ')})`);\n }\n\n return parts.join(' ') || 'Development work';\n }\n\n /**\n * Analyze commit message types\n */\n private analyzeCommitTypes(commits: Commit[]): string[] {\n const types: Record<string, number> = {};\n\n for (const commit of commits) {\n const match = commit.message.match(/^(\\w+)[(:]/);\n if (match) {\n const type = match[1].toLowerCase();\n types[type] = (types[type] || 0) + 1;\n }\n }\n\n // Return top 3 types\n return Object.entries(types)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 3)\n .map(([type]) => type);\n }\n\n /**\n * Format context for AI prompt\n */\n formatContextForAI(context: WorkContext): string {\n const lines: string[] = [];\n\n lines.push(`Branch: ${context.branch}`);\n\n if (context.tickets.length > 0) {\n lines.push(`Tickets: ${context.tickets.map((t) => `${t.id} (${t.type})`).join(', ')}`);\n }\n\n if (context.categories.length > 0) {\n const categoryStr = context.categories\n .slice(0, 3)\n .map((c) => `${c.name}: ${c.percentage}%`)\n .join(', ');\n lines.push(`Work categories: ${categoryStr}`);\n }\n\n lines.push(`Commits: ${context.commitCount}`);\n lines.push(`Files changed: ${context.filesChanged.length}`);\n lines.push(`Time span: ${context.timeRange.durationHours} hours`);\n\n if (context.authors.length > 1) {\n lines.push(`Contributors: ${context.authors.join(', ')}`);\n }\n\n return lines.join('\\n');\n }\n}\n","/**\n * Standup Context Builder\n *\n * Assembles rich, factual context from multiple sources for accurate standup generation.\n * Instead of sending loose commit messages to the AI, this builds a structured data block\n * that includes:\n * - Exact git commits (hash, message, body, files)\n * - PR metadata (title, body, linked issues, review status)\n * - Ticket details from PM tools (Jira, Linear, GitHub Issues)\n * - Diff statistics (files changed, insertions, deletions)\n * - Branch and ticket correlations\n *\n * The goal: give the AI factual, structured data so it summarizes accurately\n * instead of hallucinating \"business-friendly\" rewrites.\n */\n\nimport { GitAnalyzer } from './git-analyzer.js';\nimport { GitHubClient } from './github.js';\nimport {\n getProjectManagementClient,\n extractTicketIds,\n extractTicketFromBranch,\n type Ticket,\n type ProjectManagementClient,\n} from './project-management.js';\nimport { ContextAnalyzer, type WorkContext, type WorkCategory } from './context-analyzer.js';\nimport { getConfig } from '../config/index.js';\nimport type { Commit, DiffStats } from '../types/index.js';\nimport { execa } from 'execa';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface PRInfo {\n number: number;\n title: string;\n body: string;\n state: string;\n labels: string[];\n url: string;\n baseBranch: string;\n headBranch: string;\n linkedTickets: string[];\n}\n\nexport interface CommitDetail {\n hash: string;\n shortHash: string;\n message: string;\n body?: string;\n author: string;\n date: Date;\n filesChanged?: string[];\n}\n\nexport interface StandupContext {\n /** Current branch name */\n branch: string;\n\n /** Exact git commits with full details */\n commits: CommitDetail[];\n\n /** PRs created/merged in the time window */\n pullRequests: PRInfo[];\n\n /** Tickets fetched from PM tool with full metadata */\n tickets: Ticket[];\n\n /** Diff statistics */\n diffStats: DiffStats | null;\n\n /** Top changed files with change counts */\n topChangedFiles: FileChange[];\n\n /** Work categories from file analysis */\n categories: WorkCategory[];\n\n /** All extracted ticket IDs (from branch, commits, PRs) */\n ticketIds: string[];\n\n /** Time range of the work */\n timeRange: {\n since: Date;\n until: Date;\n durationHours: number;\n };\n\n /** Repository info */\n repo: {\n name: string | null;\n defaultBranch: string;\n };\n\n /** Raw work context from context analyzer */\n workContext: WorkContext;\n}\n\nexport interface FileChange {\n path: string;\n /** Number of times this file appears across commits */\n frequency: number;\n}\n\nexport interface StandupContextOptions {\n /** Number of days to look back */\n days: number;\n /** Filter by author email */\n author?: string;\n /** Specific ticket IDs to include */\n ticketIds?: string[];\n /** Skip PM tool integration */\n skipTickets?: boolean;\n /** Skip PR fetching */\n skipPRs?: boolean;\n /** Base branch for diff */\n baseBranch?: string;\n /** Enable debug logging for ticket fetching and context assembly */\n debug?: boolean;\n}\n\n// ─── Context Builder ──────────────────────────────────────────────────────────\n\nexport class StandupContextBuilder {\n private git: GitAnalyzer;\n private github: GitHubClient;\n private pmClient: ProjectManagementClient;\n private contextAnalyzer: ContextAnalyzer;\n private config = getConfig();\n\n constructor(repoPath?: string) {\n this.git = new GitAnalyzer(repoPath);\n this.github = new GitHubClient();\n this.pmClient = getProjectManagementClient();\n this.contextAnalyzer = new ContextAnalyzer(\n repoPath,\n this.config.projectManagement.tool,\n this.config.projectManagement.ticketPrefix\n );\n }\n\n /**\n * Build comprehensive standup context from all available sources\n */\n async build(options: StandupContextOptions): Promise<StandupContext> {\n const since = new Date();\n since.setDate(since.getDate() - options.days);\n const until = new Date();\n\n const baseBranch = options.baseBranch || this.config.git.defaultBranch;\n\n // Phase 1: Gather data from independent sources in parallel\n const [branch, commits, workContext, diffStats, repoName] = await Promise.all([\n this.git.getCurrentBranch(),\n this.git.getCommits({ since, until, author: options.author }),\n this.contextAnalyzer.getWorkContext({ since, until, base: baseBranch }),\n this.safeDiffStats(baseBranch),\n this.safeRepoName(),\n ]);\n\n // Phase 2: Enrich commits with file change info\n const commitDetails = await this.enrichCommits(commits);\n\n // Phase 3: Fetch PRs (depends on nothing, but we do it here for clarity)\n let pullRequests: PRInfo[] = [];\n if (!options.skipPRs) {\n pullRequests = await this.fetchRecentPRs(since, options.author);\n }\n\n // Phase 4: Extract ALL ticket IDs from every source\n const ticketIds = this.extractAllTicketIds(branch, commits, pullRequests, options.ticketIds);\n\n // Phase 5: Fetch ticket details from PM tool\n let tickets: Ticket[] = [];\n if (!options.skipTickets && ticketIds.length > 0) {\n tickets = await this.fetchTickets(ticketIds, options.debug);\n }\n\n // Phase 6: Compute top changed files\n const topChangedFiles = this.computeTopChangedFiles(commitDetails);\n\n // Compute duration\n const dates = commits.map((c) => c.date.getTime());\n const earliest = dates.length > 0 ? Math.min(...dates) : since.getTime();\n const latest = dates.length > 0 ? Math.max(...dates) : until.getTime();\n const durationHours = Math.round(((latest - earliest) / (1000 * 60 * 60)) * 10) / 10;\n\n return {\n branch,\n commits: commitDetails,\n pullRequests,\n tickets,\n diffStats,\n topChangedFiles,\n categories: workContext.categories,\n ticketIds,\n timeRange: {\n since,\n until,\n durationHours,\n },\n repo: {\n name: repoName,\n defaultBranch: baseBranch,\n },\n workContext,\n };\n }\n\n // ─── Data Gathering ───────────────────────────────────────────────────────\n\n /**\n * Enrich commits with per-commit file changes\n */\n private async enrichCommits(commits: Commit[]): Promise<CommitDetail[]> {\n const details: CommitDetail[] = [];\n\n for (const commit of commits) {\n const filesChanged = await this.git.getCommitFiles(commit.hash);\n\n details.push({\n hash: commit.hash,\n shortHash: commit.hash.slice(0, 7),\n message: commit.message,\n body: commit.body,\n author: commit.author,\n date: commit.date,\n filesChanged: filesChanged.length > 0 ? filesChanged : undefined,\n });\n }\n\n return details;\n }\n\n /**\n * Fetch recent PRs created or merged by the user\n */\n private async fetchRecentPRs(since: Date, _author?: string): Promise<PRInfo[]> {\n const prs: PRInfo[] = [];\n\n try {\n // Check if we're in a GitHub repo\n const isGH = await this.github.isGitHubRepo();\n if (!isGH) return [];\n\n // Fetch merged PRs by current user in the time window\n const sinceStr = since.toISOString().split('T')[0];\n\n // Fetch open PRs by current user\n const openPRs = await this.fetchPRsFromGH('open');\n prs.push(...openPRs);\n\n // Fetch recently merged PRs\n const mergedPRs = await this.fetchMergedPRsFromGH(sinceStr);\n prs.push(...mergedPRs);\n\n // Deduplicate by PR number\n const seen = new Set<number>();\n const unique: PRInfo[] = [];\n for (const pr of prs) {\n if (!seen.has(pr.number)) {\n seen.add(pr.number);\n unique.push(pr);\n }\n }\n\n return unique;\n } catch {\n // PR fetching is best-effort - don't fail standup because of it\n return [];\n }\n }\n\n /**\n * Fetch PRs from GitHub CLI with a specific state\n */\n private async fetchPRsFromGH(state: 'open' | 'closed' | 'merged'): Promise<PRInfo[]> {\n try {\n const args = [\n 'pr',\n 'list',\n '--author',\n '@me',\n '--state',\n state === 'merged' ? 'closed' : state,\n '--json',\n 'number,title,body,state,labels,url,baseRefName,headRefName',\n '--limit',\n '20',\n ];\n\n const { stdout } = await execa('gh', args);\n const data = JSON.parse(stdout);\n\n return (data as Array<Record<string, unknown>>).map((pr) => this.parsePR(pr));\n } catch {\n return [];\n }\n }\n\n /**\n * Fetch merged PRs since a given date\n */\n private async fetchMergedPRsFromGH(sinceDate: string): Promise<PRInfo[]> {\n try {\n const { stdout } = await execa('gh', [\n 'pr',\n 'list',\n '--author',\n '@me',\n '--state',\n 'merged',\n '--search',\n `merged:>=${sinceDate}`,\n '--json',\n 'number,title,body,state,labels,url,baseRefName,headRefName',\n '--limit',\n '20',\n ]);\n\n const data = JSON.parse(stdout);\n return (data as Array<Record<string, unknown>>).map((pr) => this.parsePR(pr));\n } catch {\n return [];\n }\n }\n\n /**\n * Parse a raw GitHub PR JSON object into PRInfo\n */\n private parsePR(raw: Record<string, unknown>): PRInfo {\n const body = (raw.body as string) || '';\n const title = (raw.title as string) || '';\n\n // Extract ticket IDs from PR title and body\n const linkedTickets = extractTicketIds(`${title} ${body}`);\n\n return {\n number: raw.number as number,\n title,\n body: body.slice(0, 1000), // Cap body length\n state: ((raw.state as string) || '').toLowerCase(),\n labels: ((raw.labels as Array<{ name: string }>) || []).map((l) => l.name),\n url: (raw.url as string) || '',\n baseBranch: (raw.baseRefName as string) || '',\n headBranch: (raw.headRefName as string) || '',\n linkedTickets,\n };\n }\n\n /**\n * Extract ticket IDs from all sources\n */\n private extractAllTicketIds(\n branch: string,\n commits: Commit[],\n prs: PRInfo[],\n userTickets?: string[]\n ): string[] {\n const ids = new Set<string>();\n\n // From user-provided tickets\n if (userTickets) {\n for (const id of userTickets) {\n ids.add(id);\n }\n }\n\n // From branch name\n const branchTicket = extractTicketFromBranch(branch);\n if (branchTicket) {\n ids.add(branchTicket);\n }\n\n // From commit messages (including body)\n for (const commit of commits) {\n const text = `${commit.message} ${commit.body || ''}`;\n const commitTickets = extractTicketIds(text);\n for (const id of commitTickets) {\n ids.add(id);\n }\n }\n\n // From PR titles and bodies\n for (const pr of prs) {\n for (const id of pr.linkedTickets) {\n ids.add(id);\n }\n }\n\n return Array.from(ids);\n }\n\n /**\n * Fetch ticket details from PM tool, with graceful error handling\n */\n private async fetchTickets(ticketIds: string[], debug = false): Promise<Ticket[]> {\n try {\n const isConfigured = await this.pmClient.isConfigured();\n if (!isConfigured) {\n if (debug) {\n console.error(`[fetchTickets] PM client (${this.pmClient.tool}) is not configured`);\n }\n return [];\n }\n\n if (debug) {\n console.error(\n `[fetchTickets] Fetching ${ticketIds.length} tickets via ${this.pmClient.tool}: ${ticketIds.join(', ')}`\n );\n }\n\n const tickets = await this.pmClient.getTickets(ticketIds);\n\n if (debug) {\n console.error(`[fetchTickets] Fetched ${tickets.length}/${ticketIds.length} tickets`);\n }\n\n return tickets;\n } catch (err) {\n // PM tool errors shouldn't break standup generation, but log in debug mode\n if (debug) {\n console.error(`[fetchTickets] Error fetching tickets:`, err);\n }\n return [];\n }\n }\n\n /**\n * Get diff stats safely (may fail on main branch or shallow clones)\n */\n private async safeDiffStats(baseBranch: string): Promise<DiffStats | null> {\n try {\n return await this.git.getDiffStats(baseBranch, 'HEAD');\n } catch {\n return null;\n }\n }\n\n /**\n * Get repo name safely\n */\n private async safeRepoName(): Promise<string | null> {\n try {\n const info = await this.github.getRepoInfo();\n return info ? `${info.owner}/${info.name}` : null;\n } catch {\n return null;\n }\n }\n\n /**\n * Compute most frequently changed files across commits\n */\n private computeTopChangedFiles(commits: CommitDetail[]): FileChange[] {\n const fileCounts = new Map<string, number>();\n\n for (const commit of commits) {\n if (commit.filesChanged) {\n for (const file of commit.filesChanged) {\n fileCounts.set(file, (fileCounts.get(file) || 0) + 1);\n }\n }\n }\n\n return Array.from(fileCounts.entries())\n .map(([path, frequency]) => ({ path, frequency }))\n .sort((a, b) => b.frequency - a.frequency)\n .slice(0, 15); // Top 15 files\n }\n\n // ─── Context Formatting ─────────────────────────────────────────────────────\n\n /**\n * Format the full context into a structured text block for the AI prompt.\n * This is the critical piece - it must be factual and structured so the AI\n * doesn't hallucinate or over-generalize.\n */\n static formatForPrompt(ctx: StandupContext): string {\n const sections: string[] = [];\n\n // ── Header\n sections.push('=== STANDUP CONTEXT (factual data — do NOT invent details) ===');\n sections.push('');\n\n // ── Repository info\n if (ctx.repo.name) {\n sections.push(`Repository: ${ctx.repo.name}`);\n }\n sections.push(`Branch: ${ctx.branch}`);\n sections.push(\n `Period: ${ctx.timeRange.since.toLocaleDateString()} to ${ctx.timeRange.until.toLocaleDateString()}`\n );\n sections.push('');\n\n // ── Commits (exact, unmodified)\n sections.push(`--- GIT COMMITS (${ctx.commits.length} total) ---`);\n if (ctx.commits.length === 0) {\n sections.push('(no commits in this period)');\n } else {\n for (const commit of ctx.commits) {\n const dateStr = commit.date.toLocaleString();\n sections.push(`[${commit.shortHash}] ${commit.message}`);\n if (commit.body) {\n // Include commit body but trim to reasonable length\n const body = commit.body.trim().slice(0, 300);\n sections.push(` Body: ${body}`);\n }\n if (commit.filesChanged && commit.filesChanged.length > 0) {\n const fileList = commit.filesChanged.slice(0, 5).join(', ');\n const more =\n commit.filesChanged.length > 5 ? ` (+${commit.filesChanged.length - 5} more)` : '';\n sections.push(` Files: ${fileList}${more}`);\n }\n sections.push(` Author: ${commit.author} | Date: ${dateStr}`);\n }\n }\n sections.push('');\n\n // ── Pull Requests\n if (ctx.pullRequests.length > 0) {\n sections.push(`--- PULL REQUESTS (${ctx.pullRequests.length}) ---`);\n for (const pr of ctx.pullRequests) {\n const labels = pr.labels.length > 0 ? ` [${pr.labels.join(', ')}]` : '';\n sections.push(`PR #${pr.number}: ${pr.title} (${pr.state})${labels}`);\n sections.push(` Branch: ${pr.headBranch} → ${pr.baseBranch}`);\n if (pr.body) {\n // Include first ~300 chars of PR body\n const bodyPreview = pr.body.trim().replace(/\\n/g, ' ').slice(0, 300);\n sections.push(` Description: ${bodyPreview}`);\n }\n if (pr.linkedTickets.length > 0) {\n sections.push(` Linked tickets: ${pr.linkedTickets.join(', ')}`);\n }\n sections.push(` URL: ${pr.url}`);\n }\n sections.push('');\n }\n\n // ── Tickets from PM tool\n if (ctx.tickets.length > 0) {\n sections.push(`--- TICKETS/ISSUES (${ctx.tickets.length}) ---`);\n for (const ticket of ctx.tickets) {\n const priority = ticket.priority ? ` | Priority: ${ticket.priority}` : '';\n sections.push(`${ticket.id}: ${ticket.title}`);\n sections.push(` Type: ${ticket.type} | Status: ${ticket.status}${priority}`);\n if (ticket.description) {\n const raw =\n typeof ticket.description === 'string'\n ? ticket.description\n : String(ticket.description);\n const desc = raw.trim().replace(/\\n/g, ' ').slice(0, 200);\n if (desc) {\n sections.push(` Description: ${desc}`);\n }\n }\n if (ticket.url) {\n sections.push(` URL: ${ticket.url}`);\n }\n }\n sections.push('');\n } else if (ctx.ticketIds.length > 0) {\n // We have ticket IDs but couldn't fetch details\n sections.push(`--- TICKET REFERENCES (not fetched) ---`);\n sections.push(`Ticket IDs found: ${ctx.ticketIds.join(', ')}`);\n sections.push('');\n }\n\n // ── Diff Statistics\n if (ctx.diffStats) {\n sections.push('--- DIFF STATISTICS ---');\n sections.push(`Files changed: ${ctx.diffStats.filesChanged}`);\n sections.push(`Lines added: +${ctx.diffStats.insertions}`);\n sections.push(`Lines removed: -${ctx.diffStats.deletions}`);\n sections.push('');\n }\n\n // ── Top Changed Files\n if (ctx.topChangedFiles.length > 0) {\n sections.push('--- TOP CHANGED FILES ---');\n for (const file of ctx.topChangedFiles.slice(0, 10)) {\n const freq = file.frequency > 1 ? ` (${file.frequency} commits)` : '';\n sections.push(` ${file.path}${freq}`);\n }\n sections.push('');\n }\n\n // ── Work Categories\n if (ctx.categories.length > 0) {\n sections.push('--- WORK AREAS ---');\n for (const cat of ctx.categories.slice(0, 5)) {\n sections.push(` ${cat.name}: ${cat.percentage}% (${cat.files.length} files)`);\n }\n sections.push('');\n }\n\n sections.push('=== END CONTEXT ===');\n\n return sections.join('\\n');\n }\n\n /**\n * Format a compact debug view of the context for terminal display\n */\n static formatDebugSummary(ctx: StandupContext): string {\n const lines: string[] = [];\n\n lines.push('┌─────────────────────────────────────────────┐');\n lines.push('│ STANDUP CONTEXT (debug) │');\n lines.push('├─────────────────────────────────────────────┤');\n\n // Basic info\n if (ctx.repo.name) {\n lines.push(`│ Repo: ${ctx.repo.name}`);\n }\n lines.push(`│ Branch: ${ctx.branch}`);\n lines.push(\n `│ Period: ${ctx.timeRange.since.toLocaleDateString()} → ${ctx.timeRange.until.toLocaleDateString()}`\n );\n lines.push(`│ Duration: ${ctx.timeRange.durationHours}h`);\n lines.push('│');\n\n // Commits\n lines.push(`│ Commits: ${ctx.commits.length}`);\n for (const c of ctx.commits.slice(0, 10)) {\n lines.push(`│ [${c.shortHash}] ${c.message.slice(0, 60)}`);\n }\n if (ctx.commits.length > 10) {\n lines.push(`│ ... and ${ctx.commits.length - 10} more`);\n }\n lines.push('│');\n\n // PRs\n lines.push(`│ PRs: ${ctx.pullRequests.length}`);\n for (const pr of ctx.pullRequests) {\n lines.push(`│ #${pr.number} ${pr.title.slice(0, 55)} (${pr.state})`);\n }\n lines.push('│');\n\n // Tickets\n lines.push(`│ Tickets: ${ctx.tickets.length} fetched, ${ctx.ticketIds.length} IDs found`);\n for (const t of ctx.tickets) {\n lines.push(`│ ${t.id}: ${t.title.slice(0, 50)} [${t.status}]`);\n }\n if (ctx.ticketIds.length > ctx.tickets.length) {\n const unfetched = ctx.ticketIds.filter((id) => !ctx.tickets.find((t) => t.id === id));\n if (unfetched.length > 0) {\n lines.push(`│ (unfetched: ${unfetched.join(', ')})`);\n }\n }\n lines.push('│');\n\n // Diff stats\n if (ctx.diffStats) {\n lines.push(\n `│ Diff: ${ctx.diffStats.filesChanged} files, +${ctx.diffStats.insertions}/-${ctx.diffStats.deletions}`\n );\n } else {\n lines.push(`│ Diff: (not available)`);\n }\n\n // Categories\n if (ctx.categories.length > 0) {\n const cats = ctx.categories\n .slice(0, 3)\n .map((c) => `${c.name}(${c.percentage}%)`)\n .join(', ');\n lines.push(`│ Areas: ${cats}`);\n }\n\n // Top files\n if (ctx.topChangedFiles.length > 0) {\n lines.push(`│ Top files:`);\n for (const f of ctx.topChangedFiles.slice(0, 5)) {\n lines.push(`│ ${f.path}`);\n }\n }\n\n lines.push('└─────────────────────────────────────────────┘');\n\n return lines.join('\\n');\n }\n\n /**\n * Build the full AI prompt for standup generation using the assembled context.\n * This prompt is designed to produce ACCURATE output, not creative rewrites.\n */\n static buildStandupPrompt(\n ctx: StandupContext,\n tone: 'engineering' | 'mixed' | 'business' = 'mixed'\n ): string {\n const contextBlock = StandupContextBuilder.formatForPrompt(ctx);\n\n const toneInstructions: Record<string, string> = {\n engineering: `- Use precise technical language (mention file names, modules, APIs where relevant)\n- Keep descriptions accurate to the actual commit messages and PR descriptions\n- Include ticket IDs inline where applicable\n- This is for an engineering audience — be specific about what code changed`,\n\n mixed: `- Write clearly for both technical and non-technical readers\n- Keep descriptions accurate and grounded in the actual commits/PRs\n- Mention ticket IDs inline where applicable\n- Describe the PURPOSE of changes (from ticket/PR context) alongside WHAT changed\n- Do NOT invent impacts or user-facing benefits that aren't evident from the data`,\n\n business: `- Describe work in terms of features, fixes, and improvements\n- Reference ticket IDs where available\n- Focus on outcomes and deliverables\n- Keep it grounded — only mention impacts that are clearly implied by the ticket/PR descriptions\n- Do NOT fabricate user-facing benefits unless the ticket description explicitly mentions them`,\n };\n\n const prompt = `You are generating a daily standup update from REAL git and project data.\n\nCRITICAL RULES:\n1. ONLY describe work that appears in the context data below. Do NOT invent or embellish.\n2. Use the EXACT commit messages, PR titles, and ticket titles as your source of truth.\n3. If a ticket has a description, use it to understand the PURPOSE, but don't fabricate details.\n4. If something is unclear from the data, say what the commit/PR says literally.\n5. Do NOT add generic filler like \"improving user experience\" unless a ticket explicitly says that.\n6. Keep it concise — 3-6 bullet points for completed work, not more.\n\n${contextBlock}\n\nNow write a standup update in this format:\n\n**Yesterday/Recently:**\n• [Accurate description of what was done — grounded in the commits/PRs/tickets above]\n• [Another item — reference ticket IDs like PROJ-123 or #123 where they exist]\n• [Continue for significant items only — group related commits together]\n\n**Today/Next:**\n• [Based on any open PRs or in-progress tickets, suggest what's next]\n• [If no signals, write \"Continue current work\" or \"Review and merge open PRs\"]\n\n**Blockers:** None (or describe if evident from the data)\n\nTone guidelines:\n${toneInstructions[tone]}\n\nAdditional rules:\n- Group related commits into single bullet points (e.g., multiple commits on the same feature = 1 bullet)\n- Reference PR numbers as \"PR #N\" and ticket IDs as-is\n- If there are both commits and matching PRs, prefer the PR title as it's usually more descriptive\n- Do NOT start bullets with \"Worked on\" repeatedly — vary the language naturally\n- Do NOT add emoji\n- Keep the total output under 300 words\n`;\n\n return prompt;\n }\n\n /**\n * Build prompt for weekly summary using the same structured approach\n */\n static buildWeeklyPrompt(ctx: StandupContext): string {\n const contextBlock = StandupContextBuilder.formatForPrompt(ctx);\n\n return `You are generating a weekly work summary from REAL git and project data.\n\nCRITICAL RULES:\n1. ONLY describe work that appears in the context data below. Do NOT invent or embellish.\n2. Use the EXACT commit messages, PR titles, and ticket titles as your source of truth.\n3. Group related work into themes/features — don't list every commit individually.\n\n${contextBlock}\n\nWrite a weekly summary in this format:\n\n**Key Accomplishments:**\n1. [Major accomplishment — reference tickets/PRs]\n2. [Second accomplishment]\n3. [Third accomplishment]\n(3-5 items max)\n\n**Stats:** X commits, Y PRs, Z tickets addressed\n\n**Top Achievement:** [Single sentence highlighting the most impactful work]\n\nRules:\n- Be factual and grounded in the data\n- Reference ticket IDs and PR numbers\n- Suitable for sharing with a manager or in a team meeting\n- Under 200 words total\n- No emoji\n`;\n }\n}\n","/**\n * Custom PR Description Prompt Loader\n *\n * Loads a custom prompt file (like CLAUDE.md but for PR descriptions)\n * that teams can use to customize how AI generates PR descriptions.\n *\n * Search order:\n * 1. Path specified in config (`pr.promptFile`)\n * 2. `.devdaily-pr-prompt.md` in repo root\n * 3. `.github/devdaily-pr-prompt.md`\n * 4. `.github/PR_DESCRIPTION_PROMPT.md`\n * 5. `docs/devdaily-pr-prompt.md`\n *\n * The file content is injected into the AI prompt as \"team guidelines\"\n * so the AI follows repo-specific rules for tone, format, sections, etc.\n */\n\nimport { readFile, access } from 'fs/promises';\nimport { join } from 'path';\nimport { getConfig } from '../config/index.js';\n\nexport interface PRPromptConfig {\n /** The raw markdown content of the prompt file */\n raw: string;\n /** The path where the prompt file was found */\n path: string;\n /** Parsed guidelines (if structured with headings) */\n guidelines: PRGuideline[];\n}\n\nexport interface PRGuideline {\n /** Section heading */\n heading: string;\n /** Section content */\n content: string;\n}\n\n/**\n * Common prompt file locations (in order of precedence)\n */\nconst PROMPT_FILE_PATHS = [\n '.devdaily-pr-prompt.md',\n '.github/devdaily-pr-prompt.md',\n '.github/PR_DESCRIPTION_PROMPT.md',\n 'docs/devdaily-pr-prompt.md',\n];\n\n/**\n * Check if a file exists\n */\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Find the PR prompt file in the repository\n */\nexport async function findPRPromptFile(repoRoot: string): Promise<string | null> {\n const config = getConfig();\n\n // 1. Check config-specified path first\n const configPath = config.pr.promptFile;\n if (configPath) {\n const fullPath = configPath.startsWith('/') ? configPath : join(repoRoot, configPath);\n if (await fileExists(fullPath)) {\n return fullPath;\n }\n }\n\n // 2. Check standard locations\n for (const promptPath of PROMPT_FILE_PATHS) {\n const fullPath = join(repoRoot, promptPath);\n if (await fileExists(fullPath)) {\n return fullPath;\n }\n }\n\n return null;\n}\n\n/**\n * Parse the prompt file into structured guidelines\n */\nexport function parsePRPrompt(content: string): PRGuideline[] {\n const guidelines: PRGuideline[] = [];\n\n // Normalize line endings (Windows \\r\\n → \\n)\n const normalized = content.replace(/\\r\\n/g, '\\n');\n const lines = normalized.split('\\n');\n\n let currentHeading: string | null = null;\n let currentContent: string[] = [];\n let insideCodeBlock = false;\n\n for (const line of lines) {\n // Track fenced code blocks so we don't treat headings inside them as real headings\n if (line.trimEnd().startsWith('```')) {\n insideCodeBlock = !insideCodeBlock;\n if (currentHeading !== null) {\n currentContent.push(line);\n }\n continue;\n }\n\n // Only match headings (h1–h3) when NOT inside a code block\n const headingMatch = !insideCodeBlock ? line.match(/^#{1,3}\\s+(.+)$/) : null;\n\n if (headingMatch) {\n // Save previous section\n if (currentHeading !== null) {\n guidelines.push({\n heading: currentHeading,\n content: currentContent.join('\\n').trim(),\n });\n }\n currentHeading = headingMatch[1].trim();\n currentContent = [];\n } else if (currentHeading !== null) {\n currentContent.push(line);\n } else {\n // Content before any heading — treat as a \"General\" section\n if (line.trim()) {\n if (!currentHeading) {\n currentHeading = 'General';\n }\n currentContent.push(line);\n }\n }\n }\n\n // Don't forget the last section\n if (currentHeading !== null) {\n guidelines.push({\n heading: currentHeading,\n content: currentContent.join('\\n').trim(),\n });\n }\n\n return guidelines;\n}\n\n/**\n * Load and parse the PR prompt file\n */\nexport async function loadPRPrompt(repoRoot: string): Promise<PRPromptConfig | null> {\n const promptPath = await findPRPromptFile(repoRoot);\n\n if (!promptPath) {\n return null;\n }\n\n try {\n const content = await readFile(promptPath, 'utf-8');\n const guidelines = parsePRPrompt(content);\n\n return {\n raw: content,\n path: promptPath,\n guidelines,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Format the PR prompt config into a string suitable for injection into the AI prompt.\n * This produces a clearly delineated block that tells the AI to follow these rules.\n */\nexport function formatPRPromptForAI(promptConfig: PRPromptConfig): string {\n const lines: string[] = [\n '',\n '=== TEAM PR DESCRIPTION GUIDELINES (follow these strictly) ===',\n '',\n ];\n\n if (promptConfig.guidelines.length > 0) {\n for (const guideline of promptConfig.guidelines) {\n lines.push(`### ${guideline.heading}`);\n if (guideline.content) {\n lines.push(guideline.content);\n }\n lines.push('');\n }\n } else {\n // No structured guidelines — just include the raw content\n lines.push(promptConfig.raw);\n lines.push('');\n }\n\n lines.push('=== END TEAM GUIDELINES ===');\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * Generate a sample PR prompt file that teams can customize\n */\nexport function generateSamplePRPrompt(): string {\n return `# PR Description Guidelines\n\nThese guidelines tell DevDaily AI how to generate PR descriptions for your team.\nCustomize this file to match your team's conventions.\n\n## Tone & Style\n\n- Write in a professional but approachable tone\n- Be concise — aim for clarity over verbosity\n- Use bullet points for lists of changes\n- Avoid jargon unless it's well-known in the team\n- No emojis in the description body (section headers are fine)\n\n## Description Format\n\n- Start with a one-sentence summary of what the PR does\n- Follow with bullet points of specific changes\n- Group related changes together\n- Mention any architectural decisions or trade-offs\n\n## Ticket References\n\n- Always include ticket IDs (e.g., PROJ-123) when available\n- Link to the ticket URL when possible\n- Explain how the changes relate to the ticket's acceptance criteria\n\n## Testing Instructions\n\n- Provide step-by-step instructions for reviewers to test\n- Include any required environment setup\n- Mention edge cases that should be verified\n- Include expected vs actual behavior for bug fixes\n\n## Breaking Changes\n\n- Clearly call out any breaking changes\n- Explain migration steps if applicable\n- Tag breaking changes with a warning\n\n## What NOT to Include\n\n- Don't list every file changed (that's in the diff)\n- Don't repeat commit messages verbatim\n- Don't include implementation details that are obvious from the code\n- Don't include TODOs — create follow-up tickets instead\n`;\n}\n\n/**\n * Get the default path where a new PR prompt file should be created\n */\nexport function getDefaultPRPromptPath(repoRoot: string): string {\n return join(repoRoot, '.devdaily-pr-prompt.md');\n}\n","/**\n * Notification integrations for Slack and Discord\n * Sends standup updates, PR notifications, etc. via webhooks\n */\n\nimport { getConfig, getSecrets } from '../config/index.js';\n\nexport interface NotificationMessage {\n title?: string;\n text: string;\n type?: 'standup' | 'pr' | 'weekly' | 'info';\n ticketLinks?: { id: string; url: string; title?: string }[];\n footer?: string;\n}\n\n/**\n * Slack webhook message format\n */\ninterface SlackMessage {\n text?: string;\n blocks?: SlackBlock[];\n attachments?: SlackAttachment[];\n}\n\ninterface SlackBlock {\n type: string;\n text?: {\n type: string;\n text: string;\n emoji?: boolean;\n };\n elements?: Array<{\n type: string;\n text?: string;\n url?: string;\n style?: string;\n }>;\n}\n\ninterface SlackAttachment {\n color?: string;\n blocks?: SlackBlock[];\n}\n\n/**\n * Discord webhook message format\n */\ninterface DiscordMessage {\n content?: string;\n embeds?: DiscordEmbed[];\n username?: string;\n avatar_url?: string;\n}\n\ninterface DiscordEmbed {\n title?: string;\n description?: string;\n color?: number;\n fields?: Array<{\n name: string;\n value: string;\n inline?: boolean;\n }>;\n footer?: {\n text: string;\n };\n timestamp?: string;\n}\n\n/**\n * Get notification emoji based on type\n */\nfunction getTypeEmoji(type?: string): string {\n switch (type) {\n case 'standup':\n return '☀️';\n case 'pr':\n return '🔀';\n case 'weekly':\n return '📊';\n default:\n return '📝';\n }\n}\n\n/**\n * Get notification color based on type (for Discord embed)\n */\nfunction getTypeColor(type?: string): number {\n switch (type) {\n case 'standup':\n return 0x4ade80; // Green\n case 'pr':\n return 0x60a5fa; // Blue\n case 'weekly':\n return 0xa78bfa; // Purple\n default:\n return 0x94a3b8; // Gray\n }\n}\n\n/**\n * Format a message for Slack\n */\nfunction formatSlackMessage(message: NotificationMessage): SlackMessage {\n const emoji = getTypeEmoji(message.type);\n const blocks: SlackBlock[] = [];\n\n // Header\n if (message.title) {\n blocks.push({\n type: 'header',\n text: {\n type: 'plain_text',\n text: `${emoji} ${message.title}`,\n emoji: true,\n },\n });\n }\n\n // Main content\n blocks.push({\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: message.text,\n },\n });\n\n // Ticket links\n if (message.ticketLinks && message.ticketLinks.length > 0) {\n const ticketText = message.ticketLinks\n .map((t) => `• <${t.url}|${t.id}>${t.title ? `: ${t.title}` : ''}`)\n .join('\\n');\n\n blocks.push({\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: `*Related Tickets:*\\n${ticketText}`,\n },\n });\n }\n\n // Divider\n blocks.push({ type: 'divider' });\n\n // Footer\n if (message.footer) {\n blocks.push({\n type: 'context',\n elements: [\n {\n type: 'mrkdwn',\n text: message.footer,\n },\n ],\n });\n } else {\n blocks.push({\n type: 'context',\n elements: [\n {\n type: 'mrkdwn',\n text: `Sent via DevDaily · ${new Date().toLocaleString()}`,\n },\n ],\n });\n }\n\n return { blocks };\n}\n\n/**\n * Format a message for Discord\n */\nfunction formatDiscordMessage(message: NotificationMessage): DiscordMessage {\n const emoji = getTypeEmoji(message.type);\n const color = getTypeColor(message.type);\n\n const embed: DiscordEmbed = {\n title: message.title ? `${emoji} ${message.title}` : undefined,\n description: message.text,\n color,\n timestamp: new Date().toISOString(),\n footer: {\n text: message.footer || 'Sent via DevDaily',\n },\n };\n\n // Add ticket links as fields\n if (message.ticketLinks && message.ticketLinks.length > 0) {\n embed.fields = message.ticketLinks.map((t) => ({\n name: t.id,\n value: t.title ? `[${t.title}](${t.url})` : `[View Ticket](${t.url})`,\n inline: true,\n }));\n }\n\n return {\n embeds: [embed],\n username: 'DevDaily',\n };\n}\n\n/**\n * Send a notification to Slack\n */\nexport async function sendToSlack(\n message: NotificationMessage,\n webhookUrl?: string\n): Promise<boolean> {\n const config = getConfig();\n const secrets = getSecrets();\n\n const url = webhookUrl || secrets.slack?.webhookUrl || config.notifications?.slack?.webhookUrl;\n\n if (!url) {\n throw new Error('Slack webhook URL not configured. Run: devdaily init --notifications');\n }\n\n const payload = formatSlackMessage(message);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n throw new Error(`Slack API error: ${response.status} ${response.statusText}`);\n }\n\n return true;\n } catch (error) {\n throw new Error(`Failed to send Slack message: ${(error as Error).message}`);\n }\n}\n\n/**\n * Send a notification to Discord\n */\nexport async function sendToDiscord(\n message: NotificationMessage,\n webhookUrl?: string\n): Promise<boolean> {\n const config = getConfig();\n const secrets = getSecrets();\n\n const url =\n webhookUrl || secrets.discord?.webhookUrl || config.notifications?.discord?.webhookUrl;\n\n if (!url) {\n throw new Error('Discord webhook URL not configured. Run: devdaily init --notifications');\n }\n\n const payload = formatDiscordMessage(message);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n throw new Error(`Discord API error: ${response.status} ${response.statusText}`);\n }\n\n return true;\n } catch (error) {\n throw new Error(`Failed to send Discord message: ${(error as Error).message}`);\n }\n}\n\n/**\n * Send notification to configured channels\n */\nexport async function sendNotification(\n message: NotificationMessage,\n options?: {\n slack?: boolean;\n discord?: boolean;\n }\n): Promise<{ slack?: boolean; discord?: boolean }> {\n const config = getConfig();\n const results: { slack?: boolean; discord?: boolean } = {};\n\n const sendSlack = options?.slack ?? config.notifications?.slack?.enabled;\n const sendDiscord = options?.discord ?? config.notifications?.discord?.enabled;\n\n if (sendSlack) {\n try {\n results.slack = await sendToSlack(message);\n } catch {\n results.slack = false;\n }\n }\n\n if (sendDiscord) {\n try {\n results.discord = await sendToDiscord(message);\n } catch {\n results.discord = false;\n }\n }\n\n return results;\n}\n\n/**\n * Format standup for notification\n */\nexport function formatStandupNotification(\n standupText: string,\n tickets?: { id: string; url: string; title?: string }[]\n): NotificationMessage {\n return {\n title: 'Daily Standup',\n text: standupText,\n type: 'standup',\n ticketLinks: tickets,\n };\n}\n\n/**\n * Format PR notification\n */\nexport function formatPRNotification(\n title: string,\n url: string,\n description: string\n): NotificationMessage {\n return {\n title: `New PR: ${title}`,\n text: `${description}\\n\\n🔗 <${url}|View Pull Request>`,\n type: 'pr',\n };\n}\n\n/**\n * Format weekly summary notification\n */\nexport function formatWeeklyNotification(\n summaryText: string,\n stats?: { commits: number; prs?: number }\n): NotificationMessage {\n const footer = stats\n ? `📊 ${stats.commits} commits${stats.prs ? ` · ${stats.prs} PRs` : ''} this week`\n : undefined;\n\n return {\n title: 'Weekly Summary',\n text: summaryText,\n type: 'weekly',\n footer,\n };\n}\n","import boxen from 'boxen';\nimport ora, { Ora } from 'ora';\nimport { colors, chalk } from './colors.js';\nimport { ASCII, drawBox, divider, progressBar, table } from './ascii.js';\nimport { getConfig } from '../config/index.js';\n\n// Terminal width helper\nconst getTerminalWidth = (): number => {\n return process.stdout.columns || 80;\n};\n\n/**\n * Render the DevDaily header/banner\n */\nexport const renderHeader = (subtitle?: string): string => {\n const config = getConfig();\n\n if (!config.ascii) {\n return colors.gradient('◆ devdaily') + (subtitle ? colors.muted(` ${subtitle}`) : '');\n }\n\n if (config.compactMode) {\n return colors.gradient(ASCII.logoMini) + (subtitle ? colors.muted(` · ${subtitle}`) : '');\n }\n\n const logo = colors.gradient(ASCII.logoSmall.trim(), ['cyan', 'blue']);\n const sub = subtitle ? `\\n${colors.muted(subtitle)}` : '';\n\n return `${logo}${sub}`;\n};\n\n/**\n * Render a section header\n */\nexport const renderSection = (title: string, icon?: string): string => {\n const iconStr = icon ? `${icon} ` : '';\n return `\\n${colors.primary.bold(`${iconStr}${title}`)}\\n${colors.muted(divider(40))}`;\n};\n\n/**\n * Render a success message\n */\nexport const renderSuccess = (message: string): string => {\n return colors.success(`${ASCII.status.success} ${message}`);\n};\n\n/**\n * Render an error message\n */\nexport const renderError = (message: string, detail?: string): string => {\n const main = colors.error(`${ASCII.status.error} ${message}`);\n const detailStr = detail ? `\\n ${colors.muted(detail)}` : '';\n return main + detailStr;\n};\n\n/**\n * Render a warning message\n */\nexport const renderWarning = (message: string): string => {\n return colors.warning(`${ASCII.status.warning} ${message}`);\n};\n\n/**\n * Render an info message\n */\nexport const renderInfo = (message: string): string => {\n return colors.muted(`${ASCII.status.info} ${message}`);\n};\n\n/**\n * Render a boxed content area\n */\nexport const renderBox = (\n content: string,\n title?: string,\n options: { style?: 'round' | 'single' | 'double' } = {}\n): string => {\n const width = Math.min(getTerminalWidth() - 4, 70);\n\n return boxen(content, {\n padding: 1,\n margin: { top: 1, bottom: 1, left: 0, right: 0 },\n borderStyle: options.style || 'round',\n borderColor: 'blue',\n title: title,\n titleAlignment: 'left',\n width,\n });\n};\n\n/**\n * Render a key-value pair\n */\nexport const renderKeyValue = (key: string, value: string, keyWidth: number = 15): string => {\n const paddedKey = key.padEnd(keyWidth);\n return `${colors.muted(paddedKey)} ${value}`;\n};\n\n/**\n * Render a list of items\n */\nexport const renderList = (\n items: string[],\n options: { bullet?: string; indent?: number } = {}\n): string => {\n const { bullet = ASCII.status.bullet, indent = 2 } = options;\n const indentStr = ' '.repeat(indent);\n return items.map((item) => `${indentStr}${colors.accent(bullet)} ${item}`).join('\\n');\n};\n\n/**\n * Render a numbered list\n */\nexport const renderNumberedList = (items: string[], options: { indent?: number } = {}): string => {\n const { indent = 2 } = options;\n const indentStr = ' '.repeat(indent);\n return items.map((item, i) => `${indentStr}${colors.accent(`${i + 1}.`)} ${item}`).join('\\n');\n};\n\n/**\n * Render stats/metrics\n */\nexport const renderStats = (\n stats: Array<{ label: string; value: string | number; color?: string }>\n): string => {\n return stats\n .map(({ label, value, color }) => {\n const colorFn = color\n ? (chalk as unknown as Record<string, (s: string) => string>)[color] || colors.primary\n : colors.primary;\n return `${colorFn(String(value))} ${colors.muted(label)}`;\n })\n .join(colors.muted(' · '));\n};\n\n/**\n * Render a progress indicator\n */\nexport const renderProgress = (progress: number, label?: string): string => {\n const bar = progressBar(progress, 30);\n const labelStr = label ? `${colors.muted(label)} ` : '';\n return `${labelStr}${colors.primary(bar)}`;\n};\n\n/**\n * Render a table\n */\nexport const renderTable = (headers: string[], rows: string[][]): string => {\n return table(headers, rows, {\n columnWidth: 20,\n headerStyle: (s) => colors.bold(s),\n });\n};\n\n/**\n * Render command help\n */\nexport const renderCommandHelp = (\n command: string,\n description: string,\n options: Array<{ flag: string; description: string; default?: string }>,\n examples: string[]\n): string => {\n const sections: string[] = [];\n\n // Command header\n sections.push(colors.bold(colors.primary(`${command}`)) + colors.muted(` - ${description}`));\n sections.push('');\n\n // Options\n if (options.length > 0) {\n sections.push(colors.bold('OPTIONS'));\n sections.push('');\n options.forEach(({ flag, description, default: defaultVal }) => {\n const defaultStr = defaultVal ? colors.muted(` (default: ${defaultVal})`) : '';\n sections.push(` ${colors.accent(flag.padEnd(20))} ${description}${defaultStr}`);\n });\n sections.push('');\n }\n\n // Examples\n if (examples.length > 0) {\n sections.push(colors.bold('EXAMPLES'));\n sections.push('');\n examples.forEach((ex) => {\n sections.push(` ${colors.muted('$')} ${colors.primary(ex)}`);\n });\n }\n\n return sections.join('\\n');\n};\n\n/**\n * Render keyboard shortcuts\n */\nexport const renderShortcuts = (shortcuts: Array<{ key: string; action: string }>): string => {\n const maxKeyLen = Math.max(...shortcuts.map((s) => s.key.length));\n\n return shortcuts\n .map(({ key, action }) => {\n const keyStr = colors.accent.bold(`[${key}]`.padEnd(maxKeyLen + 3));\n return ` ${keyStr} ${colors.muted(action)}`;\n })\n .join('\\n');\n};\n\n/**\n * Create a spinner with custom styling\n */\nexport const createSpinner = (text: string): Ora => {\n return ora({\n text,\n spinner: 'dots',\n color: 'cyan',\n });\n};\n\n/**\n * Render a divider line\n */\nexport const renderDivider = (width?: number): string => {\n return colors.muted(divider(width || Math.min(getTerminalWidth() - 10, 60)));\n};\n\n/**\n * Clear screen and move cursor to top\n */\nexport const clearScreen = (): void => {\n process.stdout.write('\\x1B[2J\\x1B[0f');\n};\n\n/**\n * Move cursor up N lines\n */\nexport const cursorUp = (n: number): void => {\n process.stdout.write(`\\x1B[${n}A`);\n};\n\n/**\n * Hide cursor\n */\nexport const hideCursor = (): void => {\n process.stdout.write('\\x1B[?25l');\n};\n\n/**\n * Show cursor\n */\nexport const showCursor = (): void => {\n process.stdout.write('\\x1B[?25h');\n};\n\n// Export everything\nexport const UI = {\n // Rendering\n header: renderHeader,\n section: renderSection,\n box: renderBox,\n success: renderSuccess,\n error: renderError,\n warning: renderWarning,\n info: renderInfo,\n keyValue: renderKeyValue,\n list: renderList,\n numberedList: renderNumberedList,\n stats: renderStats,\n progress: renderProgress,\n table: renderTable,\n commandHelp: renderCommandHelp,\n shortcuts: renderShortcuts,\n divider: renderDivider,\n\n // Utilities\n spinner: createSpinner,\n clear: clearScreen,\n cursorUp,\n hideCursor,\n showCursor,\n\n // Re-exports\n colors,\n chalk,\n ASCII,\n drawBox,\n};\n\nexport default UI;\n","import chalk, { ChalkInstance } from 'chalk';\nimport { getConfig } from '../config/index.js';\nimport { Theme } from '../config/schema.js';\n\n// Dynamic theme colors based on config\nconst getThemeColor = (colorName: string): ChalkInstance => {\n const colorMap: Record<string, ChalkInstance> = {\n blue: chalk.blue,\n green: chalk.green,\n yellow: chalk.yellow,\n red: chalk.red,\n cyan: chalk.cyan,\n magenta: chalk.magenta,\n white: chalk.white,\n gray: chalk.gray,\n // Bright variants\n brightBlue: chalk.blueBright,\n brightGreen: chalk.greenBright,\n brightYellow: chalk.yellowBright,\n brightRed: chalk.redBright,\n brightCyan: chalk.cyanBright,\n brightMagenta: chalk.magentaBright,\n };\n return colorMap[colorName] || chalk.white;\n};\n\nexport class Colors {\n private theme: Theme;\n\n constructor() {\n this.theme = getConfig().theme;\n }\n\n get primary(): ChalkInstance {\n return getThemeColor(this.theme.primary);\n }\n\n get success(): ChalkInstance {\n return getThemeColor(this.theme.success);\n }\n\n get warning(): ChalkInstance {\n return getThemeColor(this.theme.warning);\n }\n\n get error(): ChalkInstance {\n return getThemeColor(this.theme.error);\n }\n\n get accent(): ChalkInstance {\n return getThemeColor(this.theme.accent);\n }\n\n get muted(): ChalkInstance {\n return getThemeColor(this.theme.muted);\n }\n\n get bold(): ChalkInstance {\n return chalk.bold;\n }\n\n get dim(): ChalkInstance {\n return chalk.dim;\n }\n\n get italic(): ChalkInstance {\n return chalk.italic;\n }\n\n get underline(): ChalkInstance {\n return chalk.underline;\n }\n\n get inverse(): ChalkInstance {\n return chalk.inverse;\n }\n\n // Gradient text (for headers)\n gradient(text: string, colors: string[] = ['cyan', 'blue', 'magenta']): string {\n const chars = text.split('');\n const colorFns = colors.map((c) => getThemeColor(c));\n return chars\n .map((char, i) => {\n const colorIndex = Math.floor((i / chars.length) * colorFns.length);\n return colorFns[colorIndex](char);\n })\n .join('');\n }\n\n // Rainbow text\n rainbow(text: string): string {\n const colors = ['red', 'yellow', 'green', 'cyan', 'blue', 'magenta'];\n return text\n .split('')\n .map((char, i) => getThemeColor(colors[i % colors.length])(char))\n .join('');\n }\n}\n\n// Export singleton\nexport const colors = new Colors();\n\n// Static chalk exports for simple usage\nexport { chalk };\n","// ASCII Art and Symbols for DevDaily\n// Clean, modern aesthetic\n\nexport const ASCII = {\n // Main logo - compact and modern\n logo: `\n ██████╗ ███████╗██╗ ██╗██████╗ █████╗ ██╗██╗ ██╗ ██╗\n ██╔══██╗██╔════╝██║ ██║██╔══██╗██╔══██╗██║██║ ╚██╗ ██╔╝\n ██║ ██║█████╗ ██║ ██║██║ ██║███████║██║██║ ╚████╔╝ \n ██║ ██║██╔══╝ ╚██╗ ██╔╝██║ ██║██╔══██║██║██║ ╚██╔╝ \n ██████╔╝███████╗ ╚████╔╝ ██████╔╝██║ ██║██║███████╗██║ \n ╚═════╝ ╚══════╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝ \n`,\n\n // Smaller logo for compact displays\n logoSmall: `\n ╔═══════════════════════════════╗\n ║ D E V D A I L Y . A I ║\n ╚═══════════════════════════════╝\n`,\n\n // Minimal logo\n logoMini: `◆ devdaily`,\n\n // Command icons\n icons: {\n standup: '◈',\n pr: '◉',\n week: '◎',\n dash: '◐',\n config: '◇',\n init: '◆',\n help: '?',\n },\n\n // Status symbols\n status: {\n success: '✓',\n error: '✗',\n warning: '!',\n info: 'i',\n pending: '○',\n active: '●',\n arrow: '→',\n arrowRight: '▶',\n arrowDown: '▼',\n bullet: '•',\n dot: '·',\n star: '★',\n check: '✔',\n cross: '✖',\n },\n\n // Box drawing characters\n box: {\n topLeft: '╭',\n topRight: '╮',\n bottomLeft: '╰',\n bottomRight: '╯',\n horizontal: '─',\n vertical: '│',\n cross: '┼',\n teeRight: '├',\n teeLeft: '┤',\n teeDown: '┬',\n teeUp: '┴',\n },\n\n // Progress indicators\n progress: {\n filled: '█',\n empty: '░',\n half: '▒',\n },\n\n // Spinners frames\n spinners: {\n dots: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],\n line: ['|', '/', '-', '\\\\'],\n arc: ['◜', '◠', '◝', '◞', '◡', '◟'],\n circle: ['◐', '◓', '◑', '◒'],\n square: ['◰', '◳', '◲', '◱'],\n },\n\n // Decorative elements\n decorations: {\n wave: '~~~~~',\n sparkle: '✦',\n diamond: '◇',\n heart: '♥',\n thunder: '⚡',\n },\n};\n\n// Box drawing helper\nexport const drawBox = (\n content: string,\n options: {\n title?: string;\n width?: number;\n padding?: number;\n style?: 'single' | 'double' | 'round';\n } = {}\n): string => {\n const { title, width = 60, padding = 1, style = 'round' } = options;\n\n const chars =\n style === 'round'\n ? { tl: '╭', tr: '╮', bl: '╰', br: '╯', h: '─', v: '│' }\n : style === 'double'\n ? { tl: '╔', tr: '╗', bl: '╚', br: '╝', h: '═', v: '║' }\n : { tl: '┌', tr: '┐', bl: '└', br: '┘', h: '─', v: '│' };\n\n const lines = content.split('\\n');\n const maxLineLength = Math.max(...lines.map((l) => stripAnsi(l).length));\n const innerWidth = Math.max(width - 2, maxLineLength + padding * 2);\n\n const padLine = (line: string): string => {\n const visibleLength = stripAnsi(line).length;\n const leftPad = ' '.repeat(padding);\n const rightPad = ' '.repeat(innerWidth - visibleLength - padding);\n return `${chars.v}${leftPad}${line}${rightPad}${chars.v}`;\n };\n\n const topBorder = title\n ? `${chars.tl}${chars.h} ${title} ${chars.h.repeat(innerWidth - title.length - 3)}${chars.tr}`\n : `${chars.tl}${chars.h.repeat(innerWidth)}${chars.tr}`;\n\n const bottomBorder = `${chars.bl}${chars.h.repeat(innerWidth)}${chars.br}`;\n\n const paddedContent = [\n ...Array(padding).fill(`${chars.v}${' '.repeat(innerWidth)}${chars.v}`),\n ...lines.map(padLine),\n ...Array(padding).fill(`${chars.v}${' '.repeat(innerWidth)}${chars.v}`),\n ];\n\n return [topBorder, ...paddedContent, bottomBorder].join('\\n');\n};\n\n// Strip ANSI codes for length calculation\nconst stripAnsi = (str: string): string => {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1B\\[[0-9;]*[a-zA-Z]/g, '');\n};\n\n// Create a horizontal divider\nexport const divider = (width: number = 50, char: string = '─'): string => {\n return char.repeat(width);\n};\n\n// Create a progress bar\nexport const progressBar = (\n progress: number,\n width: number = 30,\n options: { filled?: string; empty?: string; showPercent?: boolean } = {}\n): string => {\n const {\n filled = ASCII.progress.filled,\n empty = ASCII.progress.empty,\n showPercent = true,\n } = options;\n\n const clampedProgress = Math.max(0, Math.min(1, progress));\n const filledCount = Math.round(clampedProgress * width);\n const emptyCount = width - filledCount;\n\n const bar = filled.repeat(filledCount) + empty.repeat(emptyCount);\n const percent = showPercent ? ` ${Math.round(clampedProgress * 100)}%` : '';\n\n return `[${bar}]${percent}`;\n};\n\n// Create a table\nexport const table = (\n headers: string[],\n rows: string[][],\n options: { columnWidth?: number; headerStyle?: (s: string) => string } = {}\n): string => {\n const { columnWidth = 15, headerStyle = (s: string) => s } = options;\n\n const formatCell = (cell: string, width: number): string => {\n const visibleLength = stripAnsi(cell).length;\n if (visibleLength >= width) {\n return cell.slice(0, width - 1) + '…';\n }\n return cell + ' '.repeat(width - visibleLength);\n };\n\n const headerRow = headers.map((h) => headerStyle(formatCell(h, columnWidth))).join(' │ ');\n\n const separator = headers.map(() => '─'.repeat(columnWidth)).join('─┼─');\n\n const dataRows = rows\n .map((row) => row.map((cell) => formatCell(cell, columnWidth)).join(' │ '))\n .join('\\n');\n\n return `${headerRow}\\n${separator}\\n${dataRows}`;\n};\n","import clipboard from 'clipboardy';\n\nexport async function copyToClipboard(text: string): Promise<void> {\n try {\n await clipboard.write(text);\n } catch {\n // Silently fail - let caller handle messaging\n throw new Error('Failed to copy to clipboard');\n }\n}\n\nexport function formatDate(date: Date): string {\n return date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n });\n}\n\nexport function formatDateRange(start: Date, end: Date): string {\n return `${formatDate(start)} - ${formatDate(end)}`;\n}\n\nexport function getWeekStart(weeksAgo: number = 0): Date {\n const now = new Date();\n const dayOfWeek = now.getDay();\n const monday = new Date(now);\n monday.setDate(now.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1));\n monday.setDate(monday.getDate() - weeksAgo * 7);\n monday.setHours(0, 0, 0, 0);\n return monday;\n}\n\nexport function getWeekEnd(weeksAgo: number = 0): Date {\n const start = getWeekStart(weeksAgo);\n const end = new Date(start);\n end.setDate(start.getDate() + 6);\n end.setHours(23, 59, 59, 999);\n return end;\n}\n\nexport function getDaysAgo(days: number): Date {\n const date = new Date();\n date.setDate(date.getDate() - days);\n date.setHours(0, 0, 0, 0);\n return date;\n}\n","/**\n * Output formatter — converts AI-generated markdown to other output formats.\n *\n * Supported formats:\n * - markdown (passthrough)\n * - plain (strip all markdown syntax)\n * - slack (convert to Slack mrkdwn)\n * - json (structured JSON object)\n */\n\nexport type OutputFormat = 'markdown' | 'slack' | 'plain' | 'json';\n\nexport interface FormattedOutput {\n /** The transformed text ready for display / clipboard */\n text: string;\n /** The original markdown (always kept) */\n raw: string;\n /** Which format was applied */\n format: OutputFormat;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Format standup / PR / weekly text into the requested output format.\n */\nexport function formatOutput(\n markdown: string,\n format: OutputFormat = 'markdown',\n meta?: {\n title?: string;\n commits?: number;\n prs?: number;\n tickets?: number;\n days?: number;\n branch?: string;\n repo?: string;\n }\n): FormattedOutput {\n switch (format) {\n case 'plain':\n return { text: toPlain(markdown), raw: markdown, format };\n case 'slack':\n return { text: toSlack(markdown), raw: markdown, format };\n case 'json':\n return { text: toJSON(markdown, meta), raw: markdown, format };\n case 'markdown':\n default:\n return { text: markdown, raw: markdown, format };\n }\n}\n\n/**\n * Validate that a string is a supported output format.\n * Returns the validated format or the fallback.\n */\nexport function validateFormat(value: string, fallback: OutputFormat = 'markdown'): OutputFormat {\n const valid: OutputFormat[] = ['markdown', 'slack', 'plain', 'json'];\n if (valid.includes(value as OutputFormat)) {\n return value as OutputFormat;\n }\n return fallback;\n}\n\n// ─── Converters ───────────────────────────────────────────────────────────────\n\n/**\n * Strip markdown syntax and return plain text.\n */\nfunction toPlain(md: string): string {\n let text = md;\n\n // Remove horizontal rules (---, ***, ___)\n text = text.replace(/^[ \\t]*([-*_]){3,}[ \\t]*$/gm, '');\n\n // Convert headers to plain text with a colon suffix\n // e.g. \"## In Progress\" → \"In Progress:\"\n text = text.replace(/^#{1,6}\\s+(.+)$/gm, (_match, heading: string) => {\n const cleaned = heading.trim();\n // Don't add colon if it already ends with punctuation\n if (/[.:!?]$/.test(cleaned)) {\n return cleaned;\n }\n return `${cleaned}:`;\n });\n\n // Bold: **text** or __text__ → text\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, '$1');\n text = text.replace(/__(.+?)__/g, '$1');\n\n // Italic: *text* or _text_ → text\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, '$1');\n text = text.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, '$1');\n\n // Strikethrough: ~~text~~ → text\n text = text.replace(/~~(.+?)~~/g, '$1');\n\n // Inline code: `code` → code\n text = text.replace(/`([^`]+)`/g, '$1');\n\n // Code blocks: ```lang\\ncode\\n``` → code\n text = text.replace(/```[\\s\\S]*?\\n([\\s\\S]*?)```/g, '$1');\n\n // Links: [text](url) → text (url)\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '$1 ($2)');\n\n // Images: ![alt](url) → [Image: alt]\n text = text.replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, '[Image: $1]');\n\n // Unordered list markers: - item or * item → • item\n text = text.replace(/^[ \\t]*[-*]\\s+/gm, '• ');\n\n // Ordered list markers are fine as-is (1. item)\n\n // Blockquotes: > text → text\n text = text.replace(/^>+\\s?/gm, '');\n\n // Collapse multiple blank lines\n text = text.replace(/\\n{3,}/g, '\\n\\n');\n\n return text.trim();\n}\n\n/**\n * Convert markdown to Slack mrkdwn format.\n *\n * Key differences from standard markdown:\n * - Bold: **text** → *text*\n * - Italic: *text* → _text_\n * - Strike: ~~text~~ → ~text~\n * - Links: [t](url) → <url|t>\n * - Headers: ## Foo → *Foo*\n * - Code block: ``` → ``` (same, but no language tag)\n * - Lists: - item → • item\n */\nfunction toSlack(md: string): string {\n let text = md;\n\n // Use Unicode private-use area chars as safe placeholder delimiters\n // so they won't be matched by bold/italic/underscore regexes.\n const PH_START = '\\uE000';\n const PH_END = '\\uE001';\n\n // Code blocks first (protect from other transforms).\n // Strip the language identifier after ```.\n const codeBlocks: string[] = [];\n text = text.replace(/```\\w*\\n([\\s\\S]*?)```/g, (_match, code: string) => {\n const placeholder = `${PH_START}CB${codeBlocks.length}${PH_END}`;\n codeBlocks.push('```\\n' + code + '```');\n return placeholder;\n });\n\n // Inline code — leave as-is (Slack supports `code`)\n const inlineCodes: string[] = [];\n text = text.replace(/`([^`]+)`/g, (_match, code: string) => {\n const placeholder = `${PH_START}IC${inlineCodes.length}${PH_END}`;\n inlineCodes.push('`' + code + '`');\n return placeholder;\n });\n\n // Images → just the URL\n text = text.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '<$2|$1>');\n\n // Links: [text](url) → <url|text>\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<$2|$1>');\n\n // Italic first: convert single *text* → _text_ BEFORE we collapse **text**\n // This way, double-asterisk bold won't be partially eaten by the italic pass.\n // Match single asterisks that are NOT adjacent to another asterisk.\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, '_$1_');\n\n // Bold: **text** → *text* (Slack uses single asterisk for bold)\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, '*$1*');\n\n // __text__ bold (underscore variant) — also convert to Slack bold *text*\n // Use a regex that won't match our safe placeholders (which use PH_START/PH_END)\n text = text.replace(/(?<!\\uE000)__(.+?)__(?!\\uE001)/g, '*$1*');\n\n // Headers → bold in Slack (## Foo → *Foo*)\n text = text.replace(/^#{1,6}\\s+(.+)$/gm, '*$1*');\n\n // Strikethrough: ~~text~~ → ~text~\n text = text.replace(/~~(.+?)~~/g, '~$1~');\n\n // Unordered list markers\n text = text.replace(/^[ \\t]*[-*]\\s+/gm, '• ');\n\n // Blockquotes: > text → > text (Slack supports this natively)\n // Leave as-is\n\n // Horizontal rules → divider-like text\n text = text.replace(/^[ \\t]*([-*_]){3,}[ \\t]*$/gm, '───────────────────────');\n\n // Restore code blocks\n for (let i = 0; i < codeBlocks.length; i++) {\n text = text.replace(`${PH_START}CB${i}${PH_END}`, codeBlocks[i]);\n }\n\n // Restore inline code\n for (let i = 0; i < inlineCodes.length; i++) {\n text = text.replace(`${PH_START}IC${i}${PH_END}`, inlineCodes[i]);\n }\n\n // Collapse multiple blank lines\n text = text.replace(/\\n{3,}/g, '\\n\\n');\n\n return text.trim();\n}\n\n/**\n * Convert markdown standup to a structured JSON string.\n */\nfunction toJSON(\n md: string,\n meta?: {\n title?: string;\n commits?: number;\n prs?: number;\n tickets?: number;\n days?: number;\n branch?: string;\n repo?: string;\n }\n): string {\n const sections = parseSections(md);\n\n const output: Record<string, unknown> = {\n generatedAt: new Date().toISOString(),\n };\n\n if (meta) {\n output.meta = { ...meta };\n }\n\n output.sections = sections;\n output.raw = md;\n\n return JSON.stringify(output, null, 2);\n}\n\n// ─── Section parser ───────────────────────────────────────────────────────────\n\ninterface Section {\n heading: string;\n level: number;\n items: string[];\n body: string;\n}\n\n/**\n * Parse markdown into sections keyed by heading.\n */\nfunction parseSections(md: string): Section[] {\n const lines = md.split('\\n');\n const sections: Section[] = [];\n let current: Section | null = null;\n let bodyLines: string[] = [];\n\n const flushCurrent = () => {\n if (current) {\n current.body = bodyLines.join('\\n').trim();\n current.items = extractListItems(current.body);\n sections.push(current);\n }\n };\n\n for (const line of lines) {\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (headingMatch) {\n flushCurrent();\n current = {\n heading: headingMatch[2].trim(),\n level: headingMatch[1].length,\n items: [],\n body: '',\n };\n bodyLines = [];\n } else {\n bodyLines.push(line);\n }\n }\n\n // Flush last section\n flushCurrent();\n\n // If there were no headings at all, treat the whole thing as one section\n if (sections.length === 0 && md.trim().length > 0) {\n const body = md.trim();\n sections.push({\n heading: 'Content',\n level: 0,\n items: extractListItems(body),\n body,\n });\n }\n\n return sections;\n}\n\n/**\n * Extract bullet / numbered list items from a body of text.\n */\nfunction extractListItems(body: string): string[] {\n const items: string[] = [];\n for (const line of body.split('\\n')) {\n const match = line.match(/^[ \\t]*(?:[-*]|\\d+[.)]) \\s*(.+)$/);\n if (match) {\n items.push(match[1].trim());\n }\n }\n return items;\n}\n","/**\n * Work Journal - Persistent local activity snapshots\n *\n * Stores daily work snapshots locally so you can recall what you were doing\n * on any date, across any project. This is the \"memory\" layer that powers\n * context recovery, smart recall, and cross-project weekly summaries.\n *\n * Storage layout:\n * ~/.config/devdaily/journal/\n * ├── index.json # project registry + metadata\n * ├── 2024-01-15/\n * │ ├── my-project.json # snapshot for that project on that day\n * │ └── other-project.json\n * └── 2024-01-16/\n * └── my-project.json\n */\n\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n readdirSync,\n statSync,\n unlinkSync,\n rmdirSync,\n} from 'fs';\nimport { homedir } from 'os';\nimport { join, basename } from 'path';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface JournalCommit {\n hash: string;\n shortHash: string;\n message: string;\n author: string;\n date: string; // ISO string for serialization\n filesChanged?: string[];\n}\n\nexport interface JournalBranchSnapshot {\n name: string;\n lastCommitHash: string;\n lastCommitMessage: string;\n lastCommitDate: string;\n hasUncommittedChanges: boolean;\n aheadOfBase: number;\n /** Files with uncommitted modifications at snapshot time */\n uncommittedFiles: string[];\n}\n\nexport interface JournalPRSnapshot {\n number: number;\n title: string;\n state: string; // open, merged, closed\n url: string;\n baseBranch: string;\n headBranch: string;\n labels: string[];\n}\n\nexport interface JournalTicketSnapshot {\n id: string;\n title: string;\n status: string;\n type: string;\n priority?: string;\n url?: string;\n}\n\nexport interface WorkSnapshot {\n /** ISO date string (YYYY-MM-DD) */\n date: string;\n\n /** ISO timestamp of when this snapshot was taken */\n takenAt: string;\n\n /** Project identifier (sanitized repo name or directory name) */\n projectId: string;\n\n /** Absolute path to the repo root */\n repoPath: string;\n\n /** Remote URL if available */\n remoteUrl?: string;\n\n /** Current branch at snapshot time */\n currentBranch: string;\n\n /** All active (non-merged) local branches with status */\n activeBranches: JournalBranchSnapshot[];\n\n /** Commits made today (on the snapshot date) */\n todayCommits: JournalCommit[];\n\n /** Commits made in the last 7 days (for context) */\n recentCommits: JournalCommit[];\n\n /** Open/recently merged PRs */\n pullRequests: JournalPRSnapshot[];\n\n /** Active/recently touched tickets */\n tickets: JournalTicketSnapshot[];\n\n /** Work categories breakdown */\n categories: { name: string; percentage: number }[];\n\n /** Top changed files (today) */\n topChangedFiles: { path: string; frequency: number }[];\n\n /** Diff stats for today's work */\n diffStats: { filesChanged: number; insertions: number; deletions: number } | null;\n\n /** Free-form notes the user can attach */\n notes?: string;\n\n /** AI-generated \"what I was working on\" summary (if available) */\n aiSummary?: string;\n\n /** Tags for search (auto-extracted + user-supplied) */\n tags: string[];\n}\n\nexport interface ProjectRegistryEntry {\n projectId: string;\n repoPath: string;\n remoteUrl?: string;\n lastSnapshotDate: string;\n snapshotCount: number;\n /** First snapshot date */\n firstSeen: string;\n}\n\nexport interface JournalIndex {\n version: number;\n projects: ProjectRegistryEntry[];\n lastUpdated: string;\n}\n\nexport interface JournalSearchResult {\n snapshot: WorkSnapshot;\n /** Why this result matched (which fields) */\n matchReasons: string[];\n /** Relevance score (higher = more relevant) */\n score: number;\n}\n\nexport interface JournalQueryOptions {\n /** Filter by project ID */\n projectId?: string;\n /** Start date (inclusive, YYYY-MM-DD) */\n from?: string;\n /** End date (inclusive, YYYY-MM-DD) */\n to?: string;\n /** Text search query (searches commits, branches, tags, notes) */\n query?: string;\n /** Filter by tags */\n tags?: string[];\n /** Max results to return */\n limit?: number;\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst JOURNAL_DIR = join(homedir(), '.config', 'devdaily', 'journal');\nconst INDEX_PATH = join(JOURNAL_DIR, 'index.json');\nconst JOURNAL_VERSION = 1;\n\n// ─── Work Journal ─────────────────────────────────────────────────────────────\n\nexport class WorkJournal {\n private journalDir: string;\n private indexPath: string;\n\n constructor(journalDir?: string) {\n this.journalDir = journalDir || JOURNAL_DIR;\n this.indexPath = journalDir ? join(journalDir, 'index.json') : INDEX_PATH;\n this.ensureDirectoryExists();\n }\n\n // ─── Write Operations ───────────────────────────────────────────────────\n\n /**\n * Save a work snapshot for a given date and project.\n * If a snapshot already exists for that date+project, it is merged/updated\n * (newer commits appended, metadata refreshed).\n */\n saveSnapshot(snapshot: WorkSnapshot): void {\n const dateDir = join(this.journalDir, snapshot.date);\n if (!existsSync(dateDir)) {\n mkdirSync(dateDir, { recursive: true });\n }\n\n const filePath = join(dateDir, `${snapshot.projectId}.json`);\n\n // If a snapshot already exists, merge it\n let finalSnapshot = snapshot;\n if (existsSync(filePath)) {\n try {\n const existing = JSON.parse(readFileSync(filePath, 'utf-8')) as WorkSnapshot;\n finalSnapshot = this.mergeSnapshots(existing, snapshot);\n } catch {\n // Corrupted file — overwrite\n }\n }\n\n writeFileSync(filePath, JSON.stringify(finalSnapshot, null, 2), 'utf-8');\n\n // Update the index\n this.updateIndex(finalSnapshot);\n }\n\n /**\n * Add a user note to today's snapshot for a project.\n */\n addNote(projectId: string, note: string, date?: string): void {\n const targetDate = date || this.todayString();\n const snapshot = this.getSnapshot(targetDate, projectId);\n if (!snapshot) {\n // Create a minimal snapshot just for the note\n const minimal: WorkSnapshot = {\n date: targetDate,\n takenAt: new Date().toISOString(),\n projectId,\n repoPath: process.cwd(),\n currentBranch: '',\n activeBranches: [],\n todayCommits: [],\n recentCommits: [],\n pullRequests: [],\n tickets: [],\n categories: [],\n topChangedFiles: [],\n diffStats: null,\n notes: note,\n tags: [],\n };\n this.saveSnapshot(minimal);\n return;\n }\n\n snapshot.notes = snapshot.notes ? `${snapshot.notes}\\n\\n${note}` : note;\n snapshot.takenAt = new Date().toISOString();\n const filePath = join(this.journalDir, targetDate, `${projectId}.json`);\n writeFileSync(filePath, JSON.stringify(snapshot, null, 2), 'utf-8');\n }\n\n /**\n * Add an AI-generated summary to a snapshot.\n */\n setAISummary(projectId: string, summary: string, date?: string): void {\n const targetDate = date || this.todayString();\n const snapshot = this.getSnapshot(targetDate, projectId);\n if (!snapshot) return;\n\n snapshot.aiSummary = summary;\n snapshot.takenAt = new Date().toISOString();\n const filePath = join(this.journalDir, targetDate, `${projectId}.json`);\n writeFileSync(filePath, JSON.stringify(snapshot, null, 2), 'utf-8');\n }\n\n /**\n * Add tags to a snapshot.\n */\n addTags(projectId: string, tags: string[], date?: string): void {\n const targetDate = date || this.todayString();\n const snapshot = this.getSnapshot(targetDate, projectId);\n if (!snapshot) return;\n\n const allTags = new Set([...snapshot.tags, ...tags]);\n snapshot.tags = Array.from(allTags);\n snapshot.takenAt = new Date().toISOString();\n const filePath = join(this.journalDir, targetDate, `${projectId}.json`);\n writeFileSync(filePath, JSON.stringify(snapshot, null, 2), 'utf-8');\n }\n\n // ─── Read Operations ────────────────────────────────────────────────────\n\n /**\n * Get a specific snapshot by date and project.\n */\n getSnapshot(date: string, projectId: string): WorkSnapshot | null {\n const filePath = join(this.journalDir, date, `${projectId}.json`);\n if (!existsSync(filePath)) return null;\n\n try {\n return JSON.parse(readFileSync(filePath, 'utf-8')) as WorkSnapshot;\n } catch {\n return null;\n }\n }\n\n /**\n * Get all snapshots for a specific date (across all projects).\n */\n getSnapshotsForDate(date: string): WorkSnapshot[] {\n const dateDir = join(this.journalDir, date);\n if (!existsSync(dateDir)) return [];\n\n const snapshots: WorkSnapshot[] = [];\n try {\n const files = readdirSync(dateDir).filter((f) => f.endsWith('.json'));\n for (const file of files) {\n try {\n const content = readFileSync(join(dateDir, file), 'utf-8');\n snapshots.push(JSON.parse(content) as WorkSnapshot);\n } catch {\n // Skip corrupted files\n }\n }\n } catch {\n return [];\n }\n\n return snapshots;\n }\n\n /**\n * Get all snapshots for a project within a date range.\n */\n getSnapshotsForRange(projectId: string | null, from: string, to: string): WorkSnapshot[] {\n const snapshots: WorkSnapshot[] = [];\n const dates = this.getDateDirsInRange(from, to);\n\n for (const date of dates) {\n if (projectId) {\n const snapshot = this.getSnapshot(date, projectId);\n if (snapshot) snapshots.push(snapshot);\n } else {\n snapshots.push(...this.getSnapshotsForDate(date));\n }\n }\n\n return snapshots.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());\n }\n\n /**\n * Get the most recent snapshot for a project (regardless of date).\n */\n getLatestSnapshot(projectId: string): WorkSnapshot | null {\n const index = this.getIndex();\n const project = index.projects.find((p) => p.projectId === projectId);\n if (!project) return null;\n\n return this.getSnapshot(project.lastSnapshotDate, projectId);\n }\n\n /**\n * Get all snapshots across all projects for the last N days.\n */\n getRecentActivity(days: number = 7): WorkSnapshot[] {\n const to = this.todayString();\n const fromDate = new Date();\n fromDate.setDate(fromDate.getDate() - days);\n const from = this.dateToString(fromDate);\n\n return this.getSnapshotsForRange(null, from, to);\n }\n\n /**\n * Get all known projects from the index.\n */\n getProjects(): ProjectRegistryEntry[] {\n return this.getIndex().projects;\n }\n\n /**\n * Check if a snapshot exists for today for a given project.\n */\n hasTodaySnapshot(projectId: string): boolean {\n return this.getSnapshot(this.todayString(), projectId) !== null;\n }\n\n // ─── Search ─────────────────────────────────────────────────────────────\n\n /**\n * Search snapshots using a text query.\n * Searches across: commit messages, branch names, file paths, tags, notes, AI summaries.\n */\n search(options: JournalQueryOptions): JournalSearchResult[] {\n const { projectId, from, to, query, tags, limit = 20 } = options;\n\n const startDate = from || this.getEarliestDate();\n const endDate = to || this.todayString();\n\n if (!startDate) return [];\n\n const allSnapshots = this.getSnapshotsForRange(projectId || null, startDate, endDate);\n let results: JournalSearchResult[] = [];\n\n for (const snapshot of allSnapshots) {\n const matchResult = this.matchSnapshot(snapshot, query, tags);\n if (matchResult.score > 0) {\n results.push({\n snapshot,\n matchReasons: matchResult.reasons,\n score: matchResult.score,\n });\n }\n }\n\n // Sort by score descending, then by date descending\n results.sort((a, b) => {\n if (b.score !== a.score) return b.score - a.score;\n return new Date(b.snapshot.date).getTime() - new Date(a.snapshot.date).getTime();\n });\n\n if (limit > 0) {\n results = results.slice(0, limit);\n }\n\n return results;\n }\n\n /**\n * Find when a specific file was last worked on.\n */\n findFileHistory(\n filePath: string,\n projectId?: string,\n maxDays: number = 90\n ): { date: string; commits: JournalCommit[] }[] {\n const to = this.todayString();\n const fromDate = new Date();\n fromDate.setDate(fromDate.getDate() - maxDays);\n const from = this.dateToString(fromDate);\n\n const allSnapshots = this.getSnapshotsForRange(projectId || null, from, to);\n const results: { date: string; commits: JournalCommit[] }[] = [];\n\n const normalizedPath = filePath.toLowerCase();\n\n for (const snapshot of allSnapshots) {\n const matchingCommits = snapshot.todayCommits.filter((c) =>\n c.filesChanged?.some((f) => f.toLowerCase().includes(normalizedPath))\n );\n\n if (matchingCommits.length > 0) {\n results.push({ date: snapshot.date, commits: matchingCommits });\n }\n }\n\n return results;\n }\n\n /**\n * Get a cross-project summary for a date range.\n * Groups activity by project and provides aggregate stats.\n */\n getCrossProjectSummary(\n from: string,\n to: string\n ): {\n projects: {\n projectId: string;\n repoPath: string;\n totalCommits: number;\n activeDays: number;\n branches: string[];\n topFiles: string[];\n categories: { name: string; percentage: number }[];\n diffStats: { filesChanged: number; insertions: number; deletions: number };\n }[];\n totalCommits: number;\n totalActiveDays: number;\n dateRange: { from: string; to: string };\n } {\n const allSnapshots = this.getSnapshotsForRange(null, from, to);\n\n // Group by project\n const projectMap = new Map<\n string,\n {\n repoPath: string;\n snapshots: WorkSnapshot[];\n }\n >();\n\n for (const snapshot of allSnapshots) {\n const existing = projectMap.get(snapshot.projectId);\n if (existing) {\n existing.snapshots.push(snapshot);\n } else {\n projectMap.set(snapshot.projectId, {\n repoPath: snapshot.repoPath,\n snapshots: [snapshot],\n });\n }\n }\n\n const projects = Array.from(projectMap.entries()).map(([projectId, data]) => {\n const allCommits = data.snapshots.flatMap((s) => s.todayCommits);\n const allBranches = new Set(data.snapshots.map((s) => s.currentBranch));\n const allFiles = data.snapshots.flatMap((s) => s.topChangedFiles.map((f) => f.path));\n const fileFreq = new Map<string, number>();\n for (const f of allFiles) {\n fileFreq.set(f, (fileFreq.get(f) || 0) + 1);\n }\n const topFiles = Array.from(fileFreq.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([path]) => path);\n\n // Aggregate categories\n const catMap = new Map<string, number[]>();\n for (const snapshot of data.snapshots) {\n for (const cat of snapshot.categories) {\n const existing = catMap.get(cat.name);\n if (existing) {\n existing.push(cat.percentage);\n } else {\n catMap.set(cat.name, [cat.percentage]);\n }\n }\n }\n const categories = Array.from(catMap.entries())\n .map(([name, percentages]) => ({\n name,\n percentage: Math.round(percentages.reduce((a, b) => a + b, 0) / percentages.length),\n }))\n .sort((a, b) => b.percentage - a.percentage);\n\n // Aggregate diff stats\n const diffStats = {\n filesChanged: 0,\n insertions: 0,\n deletions: 0,\n };\n for (const snapshot of data.snapshots) {\n if (snapshot.diffStats) {\n diffStats.filesChanged += snapshot.diffStats.filesChanged;\n diffStats.insertions += snapshot.diffStats.insertions;\n diffStats.deletions += snapshot.diffStats.deletions;\n }\n }\n\n return {\n projectId,\n repoPath: data.repoPath,\n totalCommits: allCommits.length,\n activeDays: data.snapshots.length,\n branches: Array.from(allBranches),\n topFiles,\n categories,\n diffStats,\n };\n });\n\n const activeDates = new Set(allSnapshots.map((s) => s.date));\n\n return {\n projects: projects.sort((a, b) => b.totalCommits - a.totalCommits),\n totalCommits: projects.reduce((sum, p) => sum + p.totalCommits, 0),\n totalActiveDays: activeDates.size,\n dateRange: { from, to },\n };\n }\n\n // ─── Formatting for AI ──────────────────────────────────────────────────\n\n /**\n * Format snapshots into a context block suitable for AI prompts.\n */\n static formatSnapshotsForAI(snapshots: WorkSnapshot[]): string {\n if (snapshots.length === 0) return '[No journal entries found]';\n\n const sections: string[] = [];\n\n // Group by project\n const byProject = new Map<string, WorkSnapshot[]>();\n for (const s of snapshots) {\n const existing = byProject.get(s.projectId);\n if (existing) {\n existing.push(s);\n } else {\n byProject.set(s.projectId, [s]);\n }\n }\n\n for (const [projectId, projectSnapshots] of byProject) {\n const lines: string[] = [];\n lines.push(`## Project: ${projectId}`);\n lines.push(`Path: ${projectSnapshots[0].repoPath}`);\n lines.push('');\n\n for (const snapshot of projectSnapshots) {\n lines.push(`### ${snapshot.date}`);\n lines.push(`Branch: ${snapshot.currentBranch}`);\n\n if (snapshot.todayCommits.length > 0) {\n lines.push(`Commits (${snapshot.todayCommits.length}):`);\n for (const c of snapshot.todayCommits.slice(0, 15)) {\n const files = c.filesChanged\n ? ` [${c.filesChanged.slice(0, 3).join(', ')}${c.filesChanged.length > 3 ? '...' : ''}]`\n : '';\n lines.push(` - ${c.shortHash} ${c.message}${files}`);\n }\n if (snapshot.todayCommits.length > 15) {\n lines.push(` ... and ${snapshot.todayCommits.length - 15} more commits`);\n }\n }\n\n if (snapshot.pullRequests.length > 0) {\n lines.push(`PRs:`);\n for (const pr of snapshot.pullRequests) {\n lines.push(` - #${pr.number} ${pr.title} (${pr.state})`);\n }\n }\n\n if (snapshot.tickets.length > 0) {\n lines.push(`Tickets:`);\n for (const t of snapshot.tickets) {\n lines.push(` - ${t.id}: ${t.title} [${t.status}]`);\n }\n }\n\n if (snapshot.categories.length > 0) {\n const cats = snapshot.categories\n .slice(0, 3)\n .map((c) => `${c.name}(${c.percentage}%)`)\n .join(', ');\n lines.push(`Work areas: ${cats}`);\n }\n\n if (snapshot.diffStats) {\n lines.push(\n `Changes: ${snapshot.diffStats.filesChanged} files, +${snapshot.diffStats.insertions}/-${snapshot.diffStats.deletions}`\n );\n }\n\n if (snapshot.notes) {\n lines.push(`Notes: ${snapshot.notes}`);\n }\n\n if (snapshot.aiSummary) {\n lines.push(`Summary: ${snapshot.aiSummary}`);\n }\n\n lines.push('');\n }\n\n sections.push(lines.join('\\n'));\n }\n\n return sections.join('\\n---\\n');\n }\n\n /**\n * Format a single snapshot into a human-readable summary.\n */\n static formatSnapshotSummary(snapshot: WorkSnapshot): string {\n const lines: string[] = [];\n\n lines.push(`📅 ${snapshot.date} — ${snapshot.projectId}`);\n lines.push(`🌿 Branch: ${snapshot.currentBranch}`);\n\n if (snapshot.todayCommits.length > 0) {\n lines.push(`📝 ${snapshot.todayCommits.length} commit(s)`);\n for (const c of snapshot.todayCommits.slice(0, 5)) {\n lines.push(` ${c.shortHash} ${c.message}`);\n }\n if (snapshot.todayCommits.length > 5) {\n lines.push(` ... and ${snapshot.todayCommits.length - 5} more`);\n }\n }\n\n if (snapshot.activeBranches.length > 1) {\n const otherBranches = snapshot.activeBranches\n .filter((b) => b.name !== snapshot.currentBranch)\n .slice(0, 5);\n if (otherBranches.length > 0) {\n lines.push(`🔀 Other active branches: ${otherBranches.map((b) => b.name).join(', ')}`);\n }\n }\n\n if (snapshot.pullRequests.length > 0) {\n lines.push(\n `🔄 PRs: ${snapshot.pullRequests.map((pr) => `#${pr.number} (${pr.state})`).join(', ')}`\n );\n }\n\n if (snapshot.diffStats) {\n lines.push(\n `📊 +${snapshot.diffStats.insertions}/-${snapshot.diffStats.deletions} across ${snapshot.diffStats.filesChanged} files`\n );\n }\n\n if (snapshot.notes) {\n lines.push(`📌 Notes: ${snapshot.notes}`);\n }\n\n if (snapshot.aiSummary) {\n lines.push(`🤖 ${snapshot.aiSummary}`);\n }\n\n return lines.join('\\n');\n }\n\n // ─── Maintenance ────────────────────────────────────────────────────────\n\n /**\n * Prune journal entries older than a given number of days.\n */\n prune(maxAgeDays: number = 365): { removedDates: string[]; removedSnapshots: number } {\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - maxAgeDays);\n const cutoffStr = this.dateToString(cutoffDate);\n\n const removedDates: string[] = [];\n let removedSnapshots = 0;\n\n try {\n const entries = readdirSync(this.journalDir);\n for (const entry of entries) {\n // Only process date directories (YYYY-MM-DD format)\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(entry)) continue;\n if (entry < cutoffStr) {\n const dateDir = join(this.journalDir, entry);\n const stat = statSync(dateDir);\n if (stat.isDirectory()) {\n const files = readdirSync(dateDir).filter((f) => f.endsWith('.json'));\n removedSnapshots += files.length;\n // Remove files then directory\n for (const file of files) {\n const filePath = join(dateDir, file);\n try {\n unlinkSync(filePath);\n } catch {\n // Skip if can't delete\n }\n }\n try {\n rmdirSync(dateDir);\n } catch {\n // Skip if can't delete (not empty)\n }\n removedDates.push(entry);\n }\n }\n }\n } catch {\n // Journal directory doesn't exist yet\n }\n\n // Rebuild index after pruning\n if (removedDates.length > 0) {\n this.rebuildIndex();\n }\n\n return { removedDates, removedSnapshots };\n }\n\n /**\n * Get journal storage stats.\n */\n getStats(): {\n totalSnapshots: number;\n totalDates: number;\n totalProjects: number;\n oldestEntry: string | null;\n newestEntry: string | null;\n storageBytes: number;\n } {\n const index = this.getIndex();\n let totalSnapshots = 0;\n let storageBytes = 0;\n\n const dates = this.getAllDateDirs();\n\n for (const date of dates) {\n const dateDir = join(this.journalDir, date);\n try {\n const files = readdirSync(dateDir).filter((f) => f.endsWith('.json'));\n totalSnapshots += files.length;\n for (const file of files) {\n try {\n const stat = statSync(join(dateDir, file));\n storageBytes += stat.size;\n } catch {\n // Skip\n }\n }\n } catch {\n // Skip\n }\n }\n\n return {\n totalSnapshots,\n totalDates: dates.length,\n totalProjects: index.projects.length,\n oldestEntry: dates.length > 0 ? dates[0] : null,\n newestEntry: dates.length > 0 ? dates[dates.length - 1] : null,\n storageBytes,\n };\n }\n\n // ─── Auto-tagging ──────────────────────────────────────────────────────\n\n /**\n * Auto-extract tags from a snapshot's content.\n * Used to make snapshots searchable by topic.\n */\n static autoTag(snapshot: WorkSnapshot): string[] {\n const tags = new Set<string>();\n\n // Extract from branch name\n const branch = snapshot.currentBranch;\n if (branch.startsWith('feature/')) tags.add('feature');\n if (branch.startsWith('fix/') || branch.startsWith('bugfix/')) tags.add('bugfix');\n if (branch.startsWith('hotfix/')) tags.add('hotfix');\n if (branch.startsWith('chore/')) tags.add('chore');\n if (branch.startsWith('refactor/')) tags.add('refactor');\n if (branch.startsWith('docs/')) tags.add('docs');\n if (branch.startsWith('test/')) tags.add('test');\n if (branch.startsWith('release/')) tags.add('release');\n\n // Extract from commit types (conventional commits)\n for (const commit of snapshot.todayCommits) {\n const match = commit.message.match(/^(\\w+)[(:]/);\n if (match) {\n const type = match[1].toLowerCase();\n if (\n [\n 'feat',\n 'fix',\n 'docs',\n 'style',\n 'refactor',\n 'test',\n 'chore',\n 'perf',\n 'ci',\n 'build',\n ].includes(type)\n ) {\n tags.add(type);\n }\n }\n\n // Extract ticket IDs as tags\n const ticketMatches = commit.message.match(/([A-Z]{2,10}-\\d+)/g);\n if (ticketMatches) {\n for (const t of ticketMatches) {\n tags.add(t.toUpperCase());\n }\n }\n\n const ghIssueMatches = commit.message.match(/#(\\d+)/g);\n if (ghIssueMatches) {\n for (const t of ghIssueMatches) {\n tags.add(t);\n }\n }\n }\n\n // Extract from categories\n for (const cat of snapshot.categories) {\n if (cat.percentage >= 20) {\n tags.add(cat.name);\n }\n }\n\n // Extract from PR labels\n for (const pr of snapshot.pullRequests) {\n for (const label of pr.labels) {\n tags.add(label.toLowerCase());\n }\n }\n\n return Array.from(tags);\n }\n\n // ─── Private Helpers ────────────────────────────────────────────────────\n\n private ensureDirectoryExists(): void {\n if (!existsSync(this.journalDir)) {\n mkdirSync(this.journalDir, { recursive: true });\n }\n }\n\n private getIndex(): JournalIndex {\n if (!existsSync(this.indexPath)) {\n return { version: JOURNAL_VERSION, projects: [], lastUpdated: new Date().toISOString() };\n }\n\n try {\n return JSON.parse(readFileSync(this.indexPath, 'utf-8')) as JournalIndex;\n } catch {\n return { version: JOURNAL_VERSION, projects: [], lastUpdated: new Date().toISOString() };\n }\n }\n\n private saveIndex(index: JournalIndex): void {\n index.lastUpdated = new Date().toISOString();\n writeFileSync(this.indexPath, JSON.stringify(index, null, 2), 'utf-8');\n }\n\n private updateIndex(snapshot: WorkSnapshot): void {\n const index = this.getIndex();\n const existing = index.projects.find((p) => p.projectId === snapshot.projectId);\n\n if (existing) {\n existing.lastSnapshotDate = snapshot.date;\n existing.repoPath = snapshot.repoPath;\n existing.remoteUrl = snapshot.remoteUrl;\n existing.snapshotCount += 1;\n if (snapshot.date < existing.firstSeen) {\n existing.firstSeen = snapshot.date;\n }\n } else {\n index.projects.push({\n projectId: snapshot.projectId,\n repoPath: snapshot.repoPath,\n remoteUrl: snapshot.remoteUrl,\n lastSnapshotDate: snapshot.date,\n snapshotCount: 1,\n firstSeen: snapshot.date,\n });\n }\n\n this.saveIndex(index);\n }\n\n private rebuildIndex(): void {\n const index: JournalIndex = {\n version: JOURNAL_VERSION,\n projects: [],\n lastUpdated: new Date().toISOString(),\n };\n\n const projectMap = new Map<\n string,\n { repoPath: string; remoteUrl?: string; dates: string[]; count: number }\n >();\n\n const dates = this.getAllDateDirs();\n for (const date of dates) {\n const dateDir = join(this.journalDir, date);\n try {\n const files = readdirSync(dateDir).filter((f) => f.endsWith('.json'));\n for (const file of files) {\n try {\n const content = JSON.parse(readFileSync(join(dateDir, file), 'utf-8')) as WorkSnapshot;\n const projectId = content.projectId || basename(file, '.json');\n const existing = projectMap.get(projectId);\n if (existing) {\n existing.dates.push(date);\n existing.count += 1;\n } else {\n projectMap.set(projectId, {\n repoPath: content.repoPath || '',\n remoteUrl: content.remoteUrl,\n dates: [date],\n count: 1,\n });\n }\n } catch {\n // Skip corrupted files\n }\n }\n } catch {\n // Skip\n }\n }\n\n for (const [projectId, data] of projectMap) {\n data.dates.sort();\n index.projects.push({\n projectId,\n repoPath: data.repoPath,\n remoteUrl: data.remoteUrl,\n lastSnapshotDate: data.dates[data.dates.length - 1],\n snapshotCount: data.count,\n firstSeen: data.dates[0],\n });\n }\n\n this.saveIndex(index);\n }\n\n /**\n * Merge two snapshots for the same date+project.\n * The newer snapshot's metadata wins, but commits are deduplicated and merged.\n */\n private mergeSnapshots(existing: WorkSnapshot, incoming: WorkSnapshot): WorkSnapshot {\n // Deduplicate commits by hash\n const commitMap = new Map<string, JournalCommit>();\n for (const c of existing.todayCommits) {\n commitMap.set(c.hash, c);\n }\n for (const c of incoming.todayCommits) {\n commitMap.set(c.hash, c); // Incoming wins on duplicates\n }\n\n const recentMap = new Map<string, JournalCommit>();\n for (const c of existing.recentCommits) {\n recentMap.set(c.hash, c);\n }\n for (const c of incoming.recentCommits) {\n recentMap.set(c.hash, c);\n }\n\n // Merge branches\n const branchMap = new Map<string, JournalBranchSnapshot>();\n for (const b of existing.activeBranches) {\n branchMap.set(b.name, b);\n }\n for (const b of incoming.activeBranches) {\n branchMap.set(b.name, b); // Incoming wins\n }\n\n // Merge PRs\n const prMap = new Map<number, JournalPRSnapshot>();\n for (const pr of existing.pullRequests) {\n prMap.set(pr.number, pr);\n }\n for (const pr of incoming.pullRequests) {\n prMap.set(pr.number, pr);\n }\n\n // Merge tags\n const allTags = new Set([...existing.tags, ...incoming.tags]);\n\n return {\n ...incoming,\n takenAt: new Date().toISOString(),\n todayCommits: Array.from(commitMap.values()).sort(\n (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()\n ),\n recentCommits: Array.from(recentMap.values()).sort(\n (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()\n ),\n activeBranches: Array.from(branchMap.values()),\n pullRequests: Array.from(prMap.values()),\n notes: existing.notes\n ? incoming.notes\n ? `${existing.notes}\\n\\n${incoming.notes}`\n : existing.notes\n : incoming.notes,\n aiSummary: incoming.aiSummary || existing.aiSummary,\n tags: Array.from(allTags),\n };\n }\n\n /**\n * Match a snapshot against search criteria and compute a relevance score.\n */\n private matchSnapshot(\n snapshot: WorkSnapshot,\n query?: string,\n tags?: string[]\n ): { score: number; reasons: string[] } {\n let score = 0;\n const reasons: string[] = [];\n\n // If no query and no tags, match everything with base score\n if (!query && (!tags || tags.length === 0)) {\n return { score: 1, reasons: ['date match'] };\n }\n\n // Tag matching\n if (tags && tags.length > 0) {\n const snapshotTags = new Set(snapshot.tags.map((t) => t.toLowerCase()));\n for (const tag of tags) {\n if (snapshotTags.has(tag.toLowerCase())) {\n score += 5;\n reasons.push(`tag: ${tag}`);\n }\n }\n }\n\n // Text query matching\n if (query) {\n const q = query.toLowerCase();\n\n // Branch name match (high value — directly relevant)\n if (snapshot.currentBranch.toLowerCase().includes(q)) {\n score += 10;\n reasons.push(`branch: ${snapshot.currentBranch}`);\n }\n\n // Active branch match\n for (const b of snapshot.activeBranches) {\n if (b.name.toLowerCase().includes(q)) {\n score += 5;\n reasons.push(`active branch: ${b.name}`);\n }\n }\n\n // Commit message match\n for (const c of snapshot.todayCommits) {\n if (c.message.toLowerCase().includes(q)) {\n score += 3;\n reasons.push(`commit: ${c.shortHash} ${c.message.slice(0, 50)}`);\n }\n // File path match within commits\n if (c.filesChanged) {\n for (const f of c.filesChanged) {\n if (f.toLowerCase().includes(q)) {\n score += 2;\n reasons.push(`file: ${f}`);\n }\n }\n }\n }\n\n // Recent commit match (lower weight)\n for (const c of snapshot.recentCommits) {\n if (c.message.toLowerCase().includes(q)) {\n score += 1;\n reasons.push(`recent commit: ${c.shortHash} ${c.message.slice(0, 50)}`);\n }\n }\n\n // PR title match\n for (const pr of snapshot.pullRequests) {\n if (pr.title.toLowerCase().includes(q)) {\n score += 5;\n reasons.push(`PR: #${pr.number} ${pr.title.slice(0, 50)}`);\n }\n }\n\n // Ticket match\n for (const t of snapshot.tickets) {\n if (t.id.toLowerCase().includes(q) || t.title.toLowerCase().includes(q)) {\n score += 5;\n reasons.push(`ticket: ${t.id}`);\n }\n }\n\n // Notes match\n if (snapshot.notes && snapshot.notes.toLowerCase().includes(q)) {\n score += 4;\n reasons.push('notes');\n }\n\n // AI summary match\n if (snapshot.aiSummary && snapshot.aiSummary.toLowerCase().includes(q)) {\n score += 3;\n reasons.push('AI summary');\n }\n\n // Tag match (via text, in case user doesn't use --tags flag)\n for (const tag of snapshot.tags) {\n if (tag.toLowerCase().includes(q)) {\n score += 2;\n reasons.push(`tag: ${tag}`);\n }\n }\n\n // Top files match\n for (const f of snapshot.topChangedFiles) {\n if (f.path.toLowerCase().includes(q)) {\n score += 2;\n reasons.push(`changed file: ${f.path}`);\n }\n }\n\n // Project ID match\n if (snapshot.projectId.toLowerCase().includes(q)) {\n score += 3;\n reasons.push(`project: ${snapshot.projectId}`);\n }\n }\n\n // Deduplicate reasons\n const uniqueReasons = [...new Set(reasons)];\n\n return { score, reasons: uniqueReasons };\n }\n\n /**\n * Get all date directories sorted chronologically.\n */\n private getAllDateDirs(): string[] {\n try {\n const entries = readdirSync(this.journalDir);\n return entries\n .filter((e) => /^\\d{4}-\\d{2}-\\d{2}$/.test(e))\n .filter((e) => {\n try {\n return statSync(join(this.journalDir, e)).isDirectory();\n } catch {\n return false;\n }\n })\n .sort();\n } catch {\n return [];\n }\n }\n\n /**\n * Get date directories within a range (inclusive).\n */\n private getDateDirsInRange(from: string, to: string): string[] {\n return this.getAllDateDirs().filter((d) => d >= from && d <= to);\n }\n\n /**\n * Get the earliest date directory in the journal.\n */\n private getEarliestDate(): string | null {\n const dirs = this.getAllDateDirs();\n return dirs.length > 0 ? dirs[0] : null;\n }\n\n /**\n * Get today's date as YYYY-MM-DD string.\n */\n todayString(): string {\n return this.dateToString(new Date());\n }\n\n /**\n * Convert a Date to YYYY-MM-DD string.\n */\n dateToString(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n }\n\n /**\n * Sanitize a project name for use as a filename.\n */\n static sanitizeProjectId(name: string): string {\n return name\n .replace(/[/\\\\:*?\"<>|]/g, '-')\n .replace(/^\\.+/, '')\n .replace(/\\s+/g, '-')\n .toLowerCase()\n .slice(0, 100);\n }\n}\n","/**\n * Snapshot Builder - Captures current project state into a WorkSnapshot\n *\n * Uses the existing GitAnalyzer, ContextAnalyzer, StandupContextBuilder,\n * and GitHub client to gather all relevant project state and produce a\n * WorkSnapshot that the WorkJournal can persist.\n *\n * This is the bridge between the real-time analysis layer (git, PRs, tickets)\n * and the persistent memory layer (WorkJournal).\n */\n\nimport { GitAnalyzer } from './git-analyzer.js';\nimport { ContextAnalyzer } from './context-analyzer.js';\nimport {\n WorkJournal,\n type WorkSnapshot,\n type JournalCommit,\n type JournalBranchSnapshot,\n type JournalPRSnapshot,\n type JournalTicketSnapshot,\n} from './work-journal.js';\nimport { getConfig } from '../config/index.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface SnapshotOptions {\n /** Override the date for the snapshot (default: today) */\n date?: string;\n\n /** Override the project ID (default: auto-detected from repo name / directory) */\n projectId?: string;\n\n /** Number of days to look back for \"recent\" commits context (default: 7) */\n recentDays?: number;\n\n /** Skip fetching PR data */\n skipPRs?: boolean;\n\n /** Skip fetching ticket data */\n skipTickets?: boolean;\n\n /** Include active branch listing (default: true) */\n includeBranches?: boolean;\n\n /** Include uncommitted changes info (default: true) */\n includeUncommitted?: boolean;\n\n /** Auto-generate AI summary after snapshot (default: false) */\n generateSummary?: boolean;\n\n /** Debug mode — log extra info */\n debug?: boolean;\n\n /** Optional note to attach to the snapshot */\n note?: string;\n\n /** Optional extra tags */\n tags?: string[];\n}\n\nexport interface SnapshotResult {\n snapshot: WorkSnapshot;\n /** Whether this snapshot was merged with an existing one for the same date */\n merged: boolean;\n /** Warnings encountered during snapshot (non-fatal issues) */\n warnings: string[];\n /** Time taken in milliseconds */\n durationMs: number;\n}\n\n// ─── Snapshot Builder ─────────────────────────────────────────────────────────\n\nexport class SnapshotBuilder {\n private git: GitAnalyzer;\n private contextAnalyzer: ContextAnalyzer;\n private config = getConfig();\n private debug: boolean;\n\n constructor(repoPath?: string, debug: boolean = false) {\n this.git = new GitAnalyzer(repoPath);\n this.contextAnalyzer = new ContextAnalyzer(\n repoPath,\n this.config.projectManagement.tool,\n this.config.projectManagement.ticketPrefix\n );\n this.debug = debug;\n }\n\n /**\n * Take a full snapshot of the current project state.\n *\n * This gathers:\n * - Current branch and all active local branches\n * - Today's commits (with file change details)\n * - Recent commits (last N days, for context)\n * - Open / recently merged PRs\n * - Active tickets (extracted from branch names, commits, PRs)\n * - Work category breakdown (frontend, backend, infra, etc.)\n * - Diff stats\n * - Top changed files\n * - Uncommitted changes\n *\n * The snapshot is ready to be saved by WorkJournal.saveSnapshot().\n */\n async takeSnapshot(options: SnapshotOptions = {}): Promise<SnapshotResult> {\n const startTime = Date.now();\n const warnings: string[] = [];\n const journal = new WorkJournal();\n\n const {\n date,\n projectId: overrideProjectId,\n recentDays = 7,\n skipPRs = false,\n skipTickets = false,\n includeBranches = true,\n includeUncommitted = true,\n note,\n tags: extraTags = [],\n } = options;\n\n const snapshotDate = date || journal.todayString();\n\n // ── Step 1: Detect project identity ──────────────────────────────────\n\n const projectId = overrideProjectId || (await this.detectProjectId());\n const repoPath = await this.safeRepoRoot();\n const remoteUrl = await this.safeRemoteUrl();\n\n this.log('Project ID:', projectId);\n this.log('Repo path:', repoPath);\n\n // ── Step 2: Get current branch ───────────────────────────────────────\n\n const currentBranch = await this.safeCurrentBranch();\n this.log('Current branch:', currentBranch);\n\n // ── Step 3: Get today's commits ──────────────────────────────────────\n\n const todaySince = this.parseDateStart(snapshotDate);\n const todayUntil = this.parseDateEnd(snapshotDate);\n\n const todayCommits = await this.getCommitsInRange(todaySince, todayUntil);\n this.log(`Today's commits: ${todayCommits.length}`);\n\n // ── Step 4: Get recent commits (for context) ─────────────────────────\n\n const recentSince = new Date();\n recentSince.setDate(recentSince.getDate() - recentDays);\n recentSince.setHours(0, 0, 0, 0);\n\n const recentCommits = await this.getCommitsInRange(recentSince, todayUntil);\n this.log(`Recent commits (${recentDays}d): ${recentCommits.length}`);\n\n // ── Step 5: Get active branches ──────────────────────────────────────\n\n let activeBranches: JournalBranchSnapshot[] = [];\n if (includeBranches) {\n try {\n activeBranches = await this.getActiveBranches(currentBranch, includeUncommitted);\n this.log(`Active branches: ${activeBranches.length}`);\n } catch (err) {\n warnings.push(`Could not list branches: ${(err as Error).message}`);\n }\n }\n\n // ── Step 6: Get work context (categories, files, diff stats) ─────────\n\n const baseBranch = this.config.git.defaultBranch || 'main';\n let categories: { name: string; percentage: number }[] = [];\n let diffStats: { filesChanged: number; insertions: number; deletions: number } | null = null;\n let topChangedFiles: { path: string; frequency: number }[] = [];\n\n try {\n const workContext = await this.contextAnalyzer.getWorkContext({\n since: todaySince,\n until: todayUntil,\n base: baseBranch,\n });\n\n categories = workContext.categories.map((c) => ({\n name: c.name,\n percentage: c.percentage,\n }));\n\n topChangedFiles = workContext.filesChanged\n .reduce(\n (acc, file) => {\n const existing = acc.find((f) => f.path === file);\n if (existing) {\n existing.frequency += 1;\n } else {\n acc.push({ path: file, frequency: 1 });\n }\n return acc;\n },\n [] as { path: string; frequency: number }[]\n )\n .sort((a, b) => b.frequency - a.frequency)\n .slice(0, 20);\n } catch (err) {\n warnings.push(`Could not analyze work context: ${(err as Error).message}`);\n }\n\n // Try to get diff stats separately (more targeted)\n try {\n const stats = await this.git.getDiffStats(baseBranch, 'HEAD');\n diffStats = stats;\n } catch {\n // Not on a feature branch or base doesn't exist — try commit-based stats\n if (todayCommits.length > 0) {\n const filesChanged = new Set<string>();\n for (const c of todayCommits) {\n if (c.filesChanged) {\n for (const f of c.filesChanged) {\n filesChanged.add(f);\n }\n }\n }\n diffStats = {\n filesChanged: filesChanged.size,\n insertions: 0,\n deletions: 0,\n };\n }\n }\n\n // ── Step 7: Get PRs ──────────────────────────────────────────────────\n\n let pullRequests: JournalPRSnapshot[] = [];\n if (!skipPRs) {\n try {\n pullRequests = await this.getRecentPRs(recentSince);\n this.log(`PRs found: ${pullRequests.length}`);\n } catch (err) {\n warnings.push(`Could not fetch PRs: ${(err as Error).message}`);\n }\n }\n\n // ── Step 8: Get tickets ──────────────────────────────────────────────\n\n let tickets: JournalTicketSnapshot[] = [];\n if (!skipTickets) {\n try {\n tickets = await this.extractTickets(\n currentBranch,\n todayCommits,\n recentCommits,\n pullRequests\n );\n this.log(`Tickets found: ${tickets.length}`);\n } catch (err) {\n warnings.push(`Could not extract tickets: ${(err as Error).message}`);\n }\n }\n\n // ── Step 9: Auto-tag ─────────────────────────────────────────────────\n\n // Build preliminary snapshot for auto-tagging\n const snapshot: WorkSnapshot = {\n date: snapshotDate,\n takenAt: new Date().toISOString(),\n projectId,\n repoPath: repoPath || process.cwd(),\n remoteUrl: remoteUrl || undefined,\n currentBranch,\n activeBranches,\n todayCommits,\n recentCommits,\n pullRequests,\n tickets,\n categories,\n topChangedFiles,\n diffStats,\n notes: note,\n tags: [],\n };\n\n // Auto-tag + merge with user-supplied tags\n const autoTags = WorkJournal.autoTag(snapshot);\n const allTags = new Set([...autoTags, ...extraTags]);\n snapshot.tags = Array.from(allTags);\n\n // ── Step 10: Check if this is a merge with existing snapshot ──────────\n\n const existing = journal.getSnapshot(snapshotDate, projectId);\n const merged = existing !== null;\n\n // ── Done ─────────────────────────────────────────────────────────────\n\n const durationMs = Date.now() - startTime;\n this.log(`Snapshot built in ${durationMs}ms (${warnings.length} warnings)`);\n\n return {\n snapshot,\n merged,\n warnings,\n durationMs,\n };\n }\n\n /**\n * Take a snapshot and immediately save it to the journal.\n * Returns the saved snapshot and metadata.\n */\n async takeAndSave(options: SnapshotOptions = {}): Promise<SnapshotResult> {\n const result = await this.takeSnapshot(options);\n const journal = new WorkJournal();\n journal.saveSnapshot(result.snapshot);\n return result;\n }\n\n /**\n * Take a lightweight snapshot — only commits and branch info, no PRs/tickets.\n * Useful for quick saves (e.g., on branch switch via git hook).\n */\n async takeLightSnapshot(options: SnapshotOptions = {}): Promise<SnapshotResult> {\n return this.takeSnapshot({\n ...options,\n skipPRs: true,\n skipTickets: true,\n includeBranches: true,\n includeUncommitted: true,\n });\n }\n\n // ─── Data Gathering Helpers ─────────────────────────────────────────────\n\n /**\n * Detect a stable project identifier from the repo.\n * Priority: remote origin name > directory name.\n */\n private async detectProjectId(): Promise<string> {\n // Try to get the repo name from remote origin\n try {\n const remoteUrl = await this.safeRemoteUrl();\n if (remoteUrl) {\n // Extract owner/repo from various URL formats\n // git@github.com:owner/repo.git\n // https://github.com/owner/repo.git\n const sshMatch = remoteUrl.match(/[:/]([^/]+\\/[^/]+?)(?:\\.git)?$/);\n if (sshMatch) {\n return WorkJournal.sanitizeProjectId(sshMatch[1]);\n }\n }\n } catch {\n // Fall through to directory name\n }\n\n // Fallback: use the directory name of the repo root\n try {\n const root = await this.git.getRepoRoot();\n const dirName = root.split('/').pop() || root.split('\\\\').pop() || 'unknown';\n return WorkJournal.sanitizeProjectId(dirName);\n } catch {\n return WorkJournal.sanitizeProjectId(process.cwd().split('/').pop() || 'unknown');\n }\n }\n\n /**\n * Get commits in a date range, enriched with file change info.\n */\n private async getCommitsInRange(since: Date, until: Date): Promise<JournalCommit[]> {\n try {\n const rawCommits = await this.git.getCommits({ since, until });\n const enriched: JournalCommit[] = [];\n\n for (const commit of rawCommits) {\n let filesChanged: string[] | undefined;\n try {\n filesChanged = await this.git.getCommitFiles(commit.hash);\n } catch {\n // Non-critical — just skip file info for this commit\n }\n\n enriched.push({\n hash: commit.hash,\n shortHash: commit.hash.slice(0, 7),\n message: commit.message,\n author: commit.author,\n date: commit.date.toISOString(),\n filesChanged,\n });\n }\n\n return enriched;\n } catch {\n return [];\n }\n }\n\n /**\n * Get all active local branches with their status.\n */\n private async getActiveBranches(\n currentBranch: string,\n includeUncommitted: boolean\n ): Promise<JournalBranchSnapshot[]> {\n const branches: JournalBranchSnapshot[] = [];\n\n try {\n // Get all local branches with last commit info\n const result = await this.git['git'].raw([\n 'branch',\n '--format=%(refname:short)|||%(objectname:short)|||%(subject)|||%(committerdate:iso)',\n '--sort=-committerdate',\n ]);\n\n const lines = result.split('\\n').filter(Boolean);\n const baseBranch = this.config.git.defaultBranch || 'main';\n\n for (const line of lines.slice(0, 30)) {\n // Cap at 30 branches\n const parts = line.split('|||');\n if (parts.length < 4) continue;\n\n const [name, commitHash, commitMessage, commitDate] = parts;\n const trimmedName = name.trim();\n\n // Skip the base branch itself in the listing\n if (trimmedName === baseBranch) continue;\n\n // Compute ahead count (how many commits ahead of base)\n let aheadOfBase = 0;\n try {\n const countResult = await this.git['git'].raw([\n 'rev-list',\n '--count',\n `${baseBranch}..${trimmedName}`,\n ]);\n aheadOfBase = parseInt(countResult.trim(), 10) || 0;\n } catch {\n // Base branch might not exist — that's fine\n }\n\n // Check uncommitted changes only for the current branch\n let hasUncommittedChanges = false;\n let uncommittedFiles: string[] = [];\n\n if (includeUncommitted && trimmedName === currentBranch) {\n try {\n const status = await this.git.getStatus();\n uncommittedFiles = [...status.modified, ...status.untracked];\n hasUncommittedChanges = uncommittedFiles.length > 0;\n } catch {\n // Non-critical\n }\n }\n\n branches.push({\n name: trimmedName,\n lastCommitHash: commitHash.trim(),\n lastCommitMessage: commitMessage.trim(),\n lastCommitDate: new Date(commitDate.trim()).toISOString(),\n hasUncommittedChanges,\n aheadOfBase,\n uncommittedFiles,\n });\n }\n } catch {\n // If branch listing fails entirely, at least record the current branch\n branches.push({\n name: currentBranch,\n lastCommitHash: '',\n lastCommitMessage: '',\n lastCommitDate: new Date().toISOString(),\n hasUncommittedChanges: false,\n aheadOfBase: 0,\n uncommittedFiles: [],\n });\n }\n\n return branches;\n }\n\n /**\n * Fetch recent PRs and map them to the journal format.\n */\n private async getRecentPRs(since: Date): Promise<JournalPRSnapshot[]> {\n const prs: JournalPRSnapshot[] = [];\n\n try {\n const { execa } = await import('execa');\n\n // Fetch open PRs authored by current user\n try {\n const { stdout: openStdout } = await execa(\n 'gh',\n [\n 'pr',\n 'list',\n '--author',\n '@me',\n '--state',\n 'open',\n '--json',\n 'number,title,state,url,baseRefName,headRefName,labels',\n '--limit',\n '20',\n ],\n { timeout: 15000 }\n );\n\n const openPRs = JSON.parse(openStdout || '[]');\n for (const pr of openPRs) {\n prs.push(this.mapPR(pr));\n }\n } catch {\n // gh not available or not a GitHub repo\n }\n\n // Fetch recently merged PRs\n try {\n const { stdout: mergedStdout } = await execa(\n 'gh',\n [\n 'pr',\n 'list',\n '--author',\n '@me',\n '--state',\n 'merged',\n '--json',\n 'number,title,state,url,baseRefName,headRefName,labels,mergedAt',\n '--limit',\n '10',\n ],\n { timeout: 15000 }\n );\n\n const mergedPRs = JSON.parse(mergedStdout || '[]');\n for (const pr of mergedPRs) {\n // Only include if merged after `since`\n if (pr.mergedAt && new Date(pr.mergedAt) >= since) {\n prs.push(this.mapPR(pr));\n }\n }\n } catch {\n // Non-critical\n }\n } catch {\n // execa not available — skip PR fetching\n }\n\n // Deduplicate by PR number\n const seen = new Set<number>();\n return prs.filter((pr) => {\n if (seen.has(pr.number)) return false;\n seen.add(pr.number);\n return true;\n });\n }\n\n /**\n * Map a raw GH CLI PR object to JournalPRSnapshot.\n */\n private mapPR(pr: Record<string, unknown>): JournalPRSnapshot {\n return {\n number: (pr.number as number) || 0,\n title: (pr.title as string) || '',\n state: (pr.state as string) || 'unknown',\n url: (pr.url as string) || '',\n baseBranch: (pr.baseRefName as string) || '',\n headBranch: (pr.headRefName as string) || '',\n labels: Array.isArray(pr.labels)\n ? (pr.labels as { name: string }[]).map((l) => l.name || '')\n : [],\n };\n }\n\n /**\n * Extract ticket IDs from various sources and map to journal format.\n */\n private async extractTickets(\n currentBranch: string,\n todayCommits: JournalCommit[],\n recentCommits: JournalCommit[],\n pullRequests: JournalPRSnapshot[]\n ): Promise<JournalTicketSnapshot[]> {\n const ticketIds = new Set<string>();\n\n // From branch name\n const branchTickets = this.contextAnalyzer.extractTicketsFromBranch(currentBranch);\n for (const t of branchTickets) {\n ticketIds.add(t.id);\n }\n\n // From commit messages (convert JournalCommit to Commit format)\n const commitLikeObjects = [...todayCommits, ...recentCommits].map((c) => ({\n hash: c.hash,\n message: c.message,\n author: c.author,\n date: new Date(c.date),\n body: undefined,\n }));\n const commitTickets = this.contextAnalyzer.extractTicketsFromCommits(commitLikeObjects);\n for (const t of commitTickets) {\n ticketIds.add(t.id);\n }\n\n // From PR titles\n for (const pr of pullRequests) {\n const prTickets = this.contextAnalyzer.extractTicketsFromCommits([\n { hash: '', message: pr.title, author: '', date: new Date() },\n ]);\n for (const t of prTickets) {\n ticketIds.add(t.id);\n }\n }\n\n // Map to JournalTicketSnapshot (basic — no PM API lookup in snapshot builder)\n const tickets: JournalTicketSnapshot[] = [];\n for (const id of ticketIds) {\n tickets.push({\n id,\n title: '', // Would need PM API to get full title\n status: 'unknown',\n type: 'unknown',\n });\n }\n\n return tickets;\n }\n\n // ─── Safe Git Helpers (never throw) ─────────────────────────────────────\n\n private async safeCurrentBranch(): Promise<string> {\n try {\n return await this.git.getCurrentBranch();\n } catch {\n return 'unknown';\n }\n }\n\n private async safeRepoRoot(): Promise<string | null> {\n try {\n return await this.git.getRepoRoot();\n } catch {\n return null;\n }\n }\n\n private async safeRemoteUrl(): Promise<string | null> {\n try {\n const result = await this.git['git'].raw(['remote', 'get-url', 'origin']);\n return result.trim() || null;\n } catch {\n return null;\n }\n }\n\n // ─── Date Helpers ───────────────────────────────────────────────────────\n\n /**\n * Parse a YYYY-MM-DD string into a Date at 00:00:00 local time.\n */\n private parseDateStart(dateStr: string): Date {\n const [year, month, day] = dateStr.split('-').map(Number);\n const d = new Date(year, month - 1, day, 0, 0, 0, 0);\n return d;\n }\n\n /**\n * Parse a YYYY-MM-DD string into a Date at 23:59:59 local time.\n */\n private parseDateEnd(dateStr: string): Date {\n const [year, month, day] = dateStr.split('-').map(Number);\n const d = new Date(year, month - 1, day, 23, 59, 59, 999);\n return d;\n }\n\n // ─── Debug Logging ──────────────────────────────────────────────────────\n\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log('[snapshot]', ...args);\n }\n }\n}\n\n// ─── Convenience Functions ────────────────────────────────────────────────────\n\n/**\n * Quick helper: take a snapshot of the current project and save it.\n * Ideal for use in git hooks or cron jobs.\n */\nexport async function autoSnapshot(options: SnapshotOptions = {}): Promise<SnapshotResult> {\n const builder = new SnapshotBuilder(undefined, options.debug);\n return builder.takeAndSave(options);\n}\n\n/**\n * Quick helper: take a light snapshot (no PRs/tickets) and save it.\n * Ideal for branch-switch hooks where speed matters.\n */\nexport async function quickSnapshot(options: SnapshotOptions = {}): Promise<SnapshotResult> {\n const builder = new SnapshotBuilder(undefined, options.debug);\n const result = await builder.takeLightSnapshot(options);\n const journal = new WorkJournal();\n journal.saveSnapshot(result.snapshot);\n return result;\n}\n","/**\n * Auto-Snapshot — Silent side-effect snapshots for existing commands\n *\n * This module provides a fire-and-forget snapshot mechanism that:\n * - Runs in the background without blocking the main command\n * - Never throws or crashes the parent command\n * - Respects the `journal.autoSnapshot` config flag\n * - Takes a \"light\" snapshot (no PRs/tickets) for speed\n * - Logs quietly (or not at all) depending on `journal.quiet`\n *\n * Usage in any command:\n * import { sideEffectSnapshot } from '../core/auto-snapshot.js';\n * // At the end of your command's action:\n * await sideEffectSnapshot({ source: 'standup' });\n */\n\nimport { getConfig } from '../config/index.js';\nimport { SnapshotBuilder, type SnapshotOptions, type SnapshotResult } from './snapshot-builder.js';\nimport { WorkJournal } from './work-journal.js';\nimport { GitAnalyzer } from './git-analyzer.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface SideEffectSnapshotOptions {\n /** Which command triggered this snapshot (used as a tag) */\n source: 'standup' | 'pr' | 'week' | 'context' | 'recall' | 'post-commit' | 'post-checkout';\n\n /** Optional note to attach */\n note?: string;\n\n /** Extra tags beyond the auto-generated ones */\n tags?: string[];\n\n /** Override project ID */\n projectId?: string;\n\n /** Override date */\n date?: string;\n\n /** Force snapshot even if autoSnapshot config is false */\n force?: boolean;\n\n /** Show a message when snapshot is saved (overrides journal.quiet) */\n verbose?: boolean;\n\n /** Debug mode */\n debug?: boolean;\n}\n\nexport interface SideEffectResult {\n /** Whether a snapshot was actually taken */\n taken: boolean;\n /** Reason it was skipped (if not taken) */\n skipReason?: string;\n /** The snapshot result (if taken) */\n result?: SnapshotResult;\n}\n\n// ─── Main API ─────────────────────────────────────────────────────────────────\n\n/**\n * Take a silent, non-blocking snapshot as a side-effect of another command.\n *\n * This is the primary function commands should call. It:\n * 1. Checks if auto-snapshot is enabled in config\n * 2. Checks if we're in a git repo\n * 3. Takes a light snapshot (fast — no PR/ticket fetching)\n * 4. Saves it to the journal with a source tag\n * 5. Never throws — returns a result indicating what happened\n */\nexport async function sideEffectSnapshot(\n options: SideEffectSnapshotOptions\n): Promise<SideEffectResult> {\n try {\n const config = getConfig();\n const journalConfig = config.journal ?? { autoSnapshot: true, quiet: true };\n\n // Check if auto-snapshot is enabled (unless forced)\n if (!options.force && !journalConfig.autoSnapshot) {\n return { taken: false, skipReason: 'autoSnapshot disabled in config' };\n }\n\n // Check if we're in a git repo\n const git = new GitAnalyzer();\n if (!(await git.isRepository())) {\n return { taken: false, skipReason: 'not a git repository' };\n }\n\n // Build snapshot options — always use light mode for speed\n const snapshotOpts: SnapshotOptions = {\n date: options.date,\n projectId: options.projectId,\n skipPRs: true,\n skipTickets: true,\n includeBranches: false,\n includeUncommitted: true,\n debug: options.debug,\n note: options.note,\n tags: [...(options.tags ?? []), `auto:${options.source}`],\n };\n\n const builder = new SnapshotBuilder(undefined, options.debug ?? false);\n const result = await builder.takeLightSnapshot(snapshotOpts);\n\n // Save to journal\n const journal = new WorkJournal();\n journal.saveSnapshot(result.snapshot);\n\n // Log if not quiet\n const quiet = options.verbose !== undefined ? !options.verbose : journalConfig.quiet;\n if (!quiet && process.env.DEVD_QUIET !== '1') {\n const tag = options.source;\n // Use stderr so it doesn't interfere with piped output\n process.stderr.write(`\\x1b[2m📸 Snapshot saved (via ${tag})\\x1b[0m\\n`);\n }\n\n return { taken: true, result };\n } catch {\n // Never crash the parent command\n if (options.debug) {\n process.stderr.write(`\\x1b[2m⚠ Auto-snapshot failed (non-fatal)\\x1b[0m\\n`);\n }\n return { taken: false, skipReason: 'snapshot failed (non-fatal)' };\n }\n}\n\n/**\n * Fire-and-forget variant — doesn't even await the result.\n *\n * Use this when you absolutely don't want to add any latency to the command.\n * The snapshot runs in the background and errors are silently swallowed.\n */\nexport function fireAndForgetSnapshot(options: SideEffectSnapshotOptions): void {\n sideEffectSnapshot(options).catch(() => {\n // Intentionally swallowed — fire and forget\n });\n}\n\n// ─── Git Hook Helpers ─────────────────────────────────────────────────────────\n\n/**\n * Generate the content for a post-commit git hook that triggers a snapshot.\n */\nexport function generatePostCommitHook(): string {\n return `#!/bin/sh\n# DevDaily auto-snapshot — captures work state after each commit\n# Installed by: devdaily init --git-hooks\n# Remove this file to disable post-commit snapshots\n\n# Only run if devdaily is installed\nif ! command -v devdaily >/dev/null 2>&1; then\n exit 0\nfi\n\n# Run snapshot in background so it doesn't slow down commits\n(devdaily snapshot --light --tag auto:post-commit 2>/dev/null &)\n\nexit 0\n`;\n}\n\n/**\n * Generate the content for a post-checkout git hook that triggers a snapshot.\n */\nexport function generatePostCheckoutHook(): string {\n return `#!/bin/sh\n# DevDaily auto-snapshot — captures work state when switching branches\n# Installed by: devdaily init --git-hooks\n# Remove this file to disable post-checkout snapshots\n#\n# Arguments from git:\n# $1 = previous HEAD ref\n# $2 = new HEAD ref\n# $3 = 1 if branch checkout, 0 if file checkout\n\nPREV_REF=\"$1\"\nNEW_REF=\"$2\"\nIS_BRANCH_CHECKOUT=\"$3\"\n\n# Only run on branch checkouts (not file checkouts)\nif [ \"$IS_BRANCH_CHECKOUT\" != \"1\" ]; then\n exit 0\nfi\n\n# Skip if refs are the same (no actual branch change)\nif [ \"$PREV_REF\" = \"$NEW_REF\" ]; then\n exit 0\nfi\n\n# Only run if devdaily is installed\nif ! command -v devdaily >/dev/null 2>&1; then\n exit 0\nfi\n\n# Run snapshot in background so it doesn't slow down checkout\n(devdaily snapshot --light --tag auto:post-checkout --note \"Switched branch\" 2>/dev/null &)\n\nexit 0\n`;\n}\n\n/**\n * Install git hooks into the current repository.\n *\n * Returns an object describing what was installed and what was skipped.\n * Respects existing hooks — if a hook already exists and isn't ours, it\n * appends a call to devdaily instead of overwriting.\n */\nexport async function installGitHooks(options?: {\n postCommit?: boolean;\n postCheckout?: boolean;\n force?: boolean;\n}): Promise<{\n installed: string[];\n skipped: string[];\n warnings: string[];\n}> {\n const { existsSync, writeFileSync, readFileSync, chmodSync, mkdirSync } = await import('fs');\n const { join } = await import('path');\n\n const git = new GitAnalyzer();\n const installed: string[] = [];\n const skipped: string[] = [];\n const warnings: string[] = [];\n\n if (!(await git.isRepository())) {\n warnings.push('Not a git repository — cannot install hooks');\n return { installed, skipped, warnings };\n }\n\n let repoRoot: string;\n try {\n repoRoot = await git.getRepoRoot();\n } catch {\n warnings.push('Could not determine repository root');\n return { installed, skipped, warnings };\n }\n\n // Determine hooks directory (respects core.hooksPath config)\n let hooksDir: string;\n try {\n const { execSync } = await import('child_process');\n const customPath = execSync('git config core.hooksPath', {\n cwd: repoRoot,\n encoding: 'utf-8',\n }).trim();\n hooksDir = customPath.startsWith('/') ? customPath : join(repoRoot, customPath);\n } catch {\n hooksDir = join(repoRoot, '.git', 'hooks');\n }\n\n // Ensure hooks directory exists\n if (!existsSync(hooksDir)) {\n mkdirSync(hooksDir, { recursive: true });\n }\n\n const DEVDAILY_MARKER = '# DevDaily auto-snapshot';\n\n const installHook = (name: string, content: string, enabled: boolean): void => {\n if (!enabled) {\n skipped.push(name);\n return;\n }\n\n const hookPath = join(hooksDir, name);\n\n if (existsSync(hookPath)) {\n const existing = readFileSync(hookPath, 'utf-8');\n\n // If it's already our hook, skip or overwrite\n if (existing.includes(DEVDAILY_MARKER)) {\n if (options?.force) {\n writeFileSync(hookPath, content);\n chmodSync(hookPath, 0o755);\n installed.push(`${name} (overwritten)`);\n } else {\n skipped.push(`${name} (already installed)`);\n }\n return;\n }\n\n // There's an existing hook that isn't ours — append\n const appendSnippet =\n name === 'post-commit'\n ? `\\n\\n${DEVDAILY_MARKER}\\nif command -v devdaily >/dev/null 2>&1; then\\n (devdaily snapshot --light --tag auto:post-commit 2>/dev/null &)\\nfi\\n`\n : `\\n\\n${DEVDAILY_MARKER}\\nif [ \"$3\" = \"1\" ] && command -v devdaily >/dev/null 2>&1; then\\n (devdaily snapshot --light --tag auto:post-checkout --note \"Switched branch\" 2>/dev/null &)\\nfi\\n`;\n\n writeFileSync(hookPath, existing + appendSnippet);\n chmodSync(hookPath, 0o755);\n installed.push(`${name} (appended to existing hook)`);\n warnings.push(\n `${name}: Existing hook found — appended devdaily call. Review ${hookPath} to verify.`\n );\n return;\n }\n\n // No existing hook — write fresh\n writeFileSync(hookPath, content);\n chmodSync(hookPath, 0o755);\n installed.push(name);\n };\n\n const doPostCommit = options?.postCommit ?? true;\n const doPostCheckout = options?.postCheckout ?? true;\n\n installHook('post-commit', generatePostCommitHook(), doPostCommit);\n installHook('post-checkout', generatePostCheckoutHook(), doPostCheckout);\n\n return { installed, skipped, warnings };\n}\n\n/**\n * Remove devdaily git hooks from the current repository.\n */\nexport async function removeGitHooks(): Promise<{\n removed: string[];\n warnings: string[];\n}> {\n const { existsSync, readFileSync, writeFileSync, unlinkSync } = await import('fs');\n const { join } = await import('path');\n\n const git = new GitAnalyzer();\n const removed: string[] = [];\n const warnings: string[] = [];\n\n if (!(await git.isRepository())) {\n warnings.push('Not a git repository');\n return { removed, warnings };\n }\n\n let repoRoot: string;\n try {\n repoRoot = await git.getRepoRoot();\n } catch {\n warnings.push('Could not determine repository root');\n return { removed, warnings };\n }\n\n let hooksDir: string;\n try {\n const { execSync } = await import('child_process');\n const customPath = execSync('git config core.hooksPath', {\n cwd: repoRoot,\n encoding: 'utf-8',\n }).trim();\n hooksDir = customPath.startsWith('/') ? customPath : join(repoRoot, customPath);\n } catch {\n hooksDir = join(repoRoot, '.git', 'hooks');\n }\n\n const DEVDAILY_MARKER = '# DevDaily auto-snapshot';\n\n for (const hookName of ['post-commit', 'post-checkout']) {\n const hookPath = join(hooksDir, hookName);\n\n if (!existsSync(hookPath)) {\n continue;\n }\n\n const content = readFileSync(hookPath, 'utf-8');\n if (!content.includes(DEVDAILY_MARKER)) {\n continue;\n }\n\n // Check if the entire file is our hook (starts with our marker after shebang)\n const lines = content.split('\\n');\n const isOurHook =\n lines[0].startsWith('#!/') && lines.some((l) => l.includes('Installed by: devdaily init'));\n\n if (isOurHook) {\n // Entire hook is ours — remove the file\n unlinkSync(hookPath);\n removed.push(hookName);\n } else {\n // Mixed hook — remove only our appended section\n const markerIndex = content.indexOf(`\\n\\n${DEVDAILY_MARKER}`);\n if (markerIndex !== -1) {\n // Find the end of our section (next double newline or end of file)\n const afterMarker = content.substring(markerIndex + 2);\n const fiEnd = afterMarker.indexOf('\\nfi\\n');\n const endIndex = fiEnd !== -1 ? markerIndex + 2 + fiEnd + 4 : content.length;\n\n const cleaned = content.substring(0, markerIndex) + content.substring(endIndex);\n writeFileSync(hookPath, cleaned);\n removed.push(`${hookName} (removed appended section)`);\n }\n }\n }\n\n return { removed, warnings };\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport { GitAnalyzer } from '../core/git-analyzer.js';\nimport { CopilotClient } from '../core/copilot.js';\nimport {\n getProjectManagementClient,\n extractTicketIds,\n extractTicketFromBranch,\n type Ticket,\n} from '../core/project-management.js';\nimport { loadPRTemplate, fillTemplate, type PRTemplate } from '../core/pr-template.js';\nimport { loadPRPrompt, type PRPromptConfig } from '../core/pr-prompt.js';\nimport {\n getRepoMetadata,\n getRepoInfo,\n createPR,\n getPRPreviewUrl,\n type GitHubLabel,\n type GitHubUser,\n} from '../core/github-repo.js';\nimport UI from '../ui/renderer.js';\nimport { ASCII } from '../ui/ascii.js';\nimport { copyToClipboard } from '../utils/helpers.js';\nimport { generatePRTitle, categorizePRType } from '../utils/commitlint.js';\nimport { getConfig } from '../config/index.js';\nimport { sideEffectSnapshot } from '../core/auto-snapshot.js';\n\nconst { colors } = UI;\n\n/**\n * Render a PR preview in the terminal\n */\nfunction renderPRPreview(\n title: string,\n body: string,\n metadata: {\n branch: string;\n base: string;\n labels?: string[];\n assignees?: string[];\n reviewers?: string[];\n isDraft?: boolean;\n }\n): void {\n console.log('');\n\n // Header\n console.log(\n colors.muted('┌─────────────────────────────────────────────────────────────────────┐')\n );\n console.log(\n colors.muted('│') + ' ' + colors.bold('PR Preview') + ' '.repeat(58) + colors.muted('│')\n );\n console.log(\n colors.muted('├─────────────────────────────────────────────────────────────────────┤')\n );\n\n // Title\n console.log(colors.muted('│'));\n console.log(colors.muted('│ ') + colors.accent('⬤') + ' ' + colors.bold(title));\n console.log(colors.muted('│'));\n\n // Branch info\n console.log(\n colors.muted('│ ') +\n colors.primary(metadata.branch) +\n colors.muted(' → ') +\n colors.accent(metadata.base)\n );\n\n // Metadata badges\n if (metadata.isDraft) {\n console.log(colors.muted('│ ') + colors.warning('◉ Draft'));\n }\n\n if (metadata.labels && metadata.labels.length > 0) {\n console.log(\n colors.muted('│ ') + '🏷️ ' + metadata.labels.map((l) => colors.accent(l)).join(' ')\n );\n }\n\n if (metadata.assignees && metadata.assignees.length > 0) {\n console.log(colors.muted('│ ') + '👤 Assignees: ' + metadata.assignees.join(', '));\n }\n\n if (metadata.reviewers && metadata.reviewers.length > 0) {\n console.log(colors.muted('│ ') + '👁️ Reviewers: ' + metadata.reviewers.join(', '));\n }\n\n console.log(colors.muted('│'));\n console.log(\n colors.muted('├─────────────────────────────────────────────────────────────────────┤')\n );\n\n // Body preview\n const lines = body.split('\\n').slice(0, 25); // First 25 lines\n for (const line of lines) {\n // Render markdown-like formatting\n if (line.startsWith('## ')) {\n console.log(colors.muted('│ ') + colors.bold(colors.primary(line.replace('## ', '▸ '))));\n } else if (line.startsWith('- [ ]')) {\n console.log(colors.muted('│ ') + ' ☐ ' + line.replace('- [ ] ', ''));\n } else if (line.startsWith('- [x]')) {\n console.log(\n colors.muted('│ ') + ' ' + colors.success('☑') + ' ' + line.replace('- [x] ', '')\n );\n } else if (line.startsWith('- ')) {\n console.log(colors.muted('│ ') + ' • ' + line.replace('- ', ''));\n } else if (line.match(/^\\d+\\./)) {\n console.log(colors.muted('│ ') + ' ' + line);\n } else {\n console.log(colors.muted('│ ') + line);\n }\n }\n\n if (body.split('\\n').length > 25) {\n console.log(\n colors.muted('│ ') + colors.muted(`... ${body.split('\\n').length - 25} more lines`)\n );\n }\n\n console.log(colors.muted('│'));\n console.log(\n colors.muted('└─────────────────────────────────────────────────────────────────────┘')\n );\n console.log('');\n}\n\n/**\n * Interactive label selection\n */\nasync function selectLabels(availableLabels: GitHubLabel[]): Promise<string[]> {\n if (availableLabels.length === 0) {\n return [];\n }\n\n const { selectedLabels } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'selectedLabels',\n message: 'Select labels:',\n choices: availableLabels.map((label) => ({\n name: `${label.name}${label.description ? ` - ${colors.muted(label.description)}` : ''}`,\n value: label.name,\n })),\n pageSize: 10,\n },\n ]);\n\n return selectedLabels;\n}\n\n/**\n * Interactive reviewer/assignee selection\n */\nasync function selectUsers(\n availableUsers: GitHubUser[],\n type: 'reviewers' | 'assignees'\n): Promise<string[]> {\n if (availableUsers.length === 0) {\n return [];\n }\n\n const { selectedUsers } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'selectedUsers',\n message: `Select ${type}:`,\n choices: availableUsers.map((user) => ({\n name: `@${user.login}${user.name ? ` (${user.name})` : ''}`,\n value: user.login,\n })),\n pageSize: 10,\n },\n ]);\n\n return selectedUsers;\n}\n\nexport const prCommand = new Command('pr')\n .description('Generate PR description from current branch')\n .option('-b, --base <branch>', 'Base branch to compare against')\n .option('-c, --create', 'Create PR on GitHub')\n .option('-d, --draft', 'Create as draft PR')\n .option('-p, --preview', 'Show preview before creating')\n .option('-t, --ticket <id>', 'Include specific ticket/issue for context')\n .option('--no-tickets', 'Skip fetching ticket/issue context')\n .option('--no-copy', 'Do not copy to clipboard')\n .option('--no-template', 'Ignore PR template, use default format')\n .option('--no-diff', 'Skip including diff context in AI prompt')\n .option('--no-prompt-file', 'Ignore custom PR prompt file')\n .option('-i, --interactive', 'Interactive mode for labels, reviewers, assignees')\n .option('--no-journal', 'Skip auto-saving a snapshot to the journal')\n .option('--debug', 'Show debug information (prompts, raw AI input)')\n .action(async (options) => {\n const config = getConfig();\n const git = new GitAnalyzer();\n const copilot = new CopilotClient({ debug: options.debug });\n const pmClient = getProjectManagementClient();\n\n // Check if in git repo\n if (!(await git.isRepository())) {\n console.log(UI.error('Not a git repository'));\n process.exit(1);\n }\n\n // Check if Copilot CLI is installed\n if (!(await copilot.isInstalled())) {\n console.log(UI.error('GitHub Copilot CLI not found'));\n console.log(UI.info('Install with: brew install copilot-cli'));\n process.exit(1);\n }\n\n // Resolve the base branch: CLI flag → config → auto-detect → fallback\n let base: string;\n if (options.base) {\n base = options.base;\n } else if (config.pr.defaultBase && config.pr.defaultBase !== 'main') {\n // User has explicitly configured a non-default base\n base = config.pr.defaultBase;\n } else {\n // Auto-detect from the repo\n try {\n base = await git.getDefaultBranch();\n } catch {\n base = config.pr.defaultBase || 'main';\n }\n }\n\n const spinner = UI.spinner('Analyzing branch...');\n spinner.start();\n\n try {\n // Get repo root\n const repoRoot = await git.getRepoRoot();\n\n // Get current branch\n const currentBranch = await git.getCurrentBranch();\n\n if (currentBranch === base) {\n spinner.stop();\n console.log('');\n console.log(UI.error(`Cannot create PR from ${base} branch`));\n console.log(UI.info('Switch to a feature branch first'));\n process.exit(1);\n }\n\n // Get commits on this branch\n const commits = await git.getCommits();\n\n if (commits.length === 0) {\n spinner.stop();\n console.log('');\n console.log(UI.warning('No commits on this branch'));\n process.exit(0);\n }\n\n // Get changed files\n const files = await git.getChangedFiles(base);\n\n // Extract ticket IDs from various sources\n const commitMessages = commits.map((c) => c.message);\n const ticketIds = new Set<string>();\n\n // From user-provided ticket\n if (options.ticket) {\n ticketIds.add(options.ticket);\n }\n\n // From branch name\n const branchTicket = extractTicketFromBranch(currentBranch);\n if (branchTicket) {\n ticketIds.add(branchTicket);\n }\n\n // From commit messages\n const commitTickets = extractTicketIds(commitMessages.join(' '));\n commitTickets.forEach((id) => ticketIds.add(id));\n\n // Fetch ticket details\n let tickets: Ticket[] = [];\n if (options.tickets !== false && ticketIds.size > 0) {\n spinner.text = `Fetching ${config.projectManagement.tool} ticket context...`;\n if (await pmClient.isConfigured()) {\n tickets = await pmClient.getTickets(Array.from(ticketIds));\n }\n }\n\n // Check for PR template\n spinner.text = 'Looking for PR template...';\n let template: PRTemplate | null = null;\n let usingTemplate = false;\n\n if (options.template !== false) {\n template = await loadPRTemplate(repoRoot);\n if (template) {\n usingTemplate = true;\n spinner.text = `Found template: ${template.path}`;\n }\n }\n\n // Load custom PR prompt file (team guidelines)\n spinner.text = 'Checking for PR description guidelines...';\n let promptConfig: PRPromptConfig | null = null;\n\n if (options.promptFile !== false) {\n promptConfig = await loadPRPrompt(repoRoot);\n if (promptConfig) {\n spinner.text = `Found PR prompt: ${promptConfig.path}`;\n }\n }\n\n // Get diff context for richer AI descriptions\n spinner.text = 'Gathering diff context...';\n let diffStat = '';\n let diffContent = '';\n\n const shouldIncludeDiff = options.diff !== false && config.pr.includeDiff !== false;\n if (shouldIncludeDiff) {\n try {\n const diffData = await git.getDiffForAI(base, 'HEAD', config.pr.maxDiffLines || 200);\n diffStat = diffData.stat;\n diffContent = diffData.diff;\n if (diffData.truncated) {\n spinner.text = 'Diff truncated to fit AI context window...';\n }\n } catch {\n // Diff failed — continue without it (filenames still available)\n }\n }\n\n // Generate PR content\n spinner.text = 'Generating PR description with Copilot CLI...';\n\n let prTitle: string;\n let prBody: string;\n let prType: string;\n\n if (usingTemplate && template) {\n // Generate structured content for template\n const content = await copilot.generatePRContent({\n branch: currentBranch,\n commits: commitMessages,\n files,\n issues: Array.from(ticketIds),\n ticketDetails: tickets,\n templateSections: template.sections.map((s) => s.name),\n diffStat,\n diff: diffContent,\n templateContent: template.raw,\n promptConfig,\n });\n\n prTitle = content.title;\n prType = content.type;\n\n // Build ticket links\n const ticketLinks = tickets.map((t) => ({ id: t.id, url: t.url }));\n\n // Fill the template\n prBody = fillTemplate(template, {\n title: content.title,\n description: content.description,\n type: content.type,\n impact: content.impact,\n testing: content.testing,\n ticketIds: Array.from(ticketIds),\n ticketLinks,\n breakingChanges: content.breakingChanges,\n additionalInfo: content.additionalInfo,\n });\n } else {\n // Use default format\n prTitle = generatePRTitle(commitMessages);\n prType = categorizePRType(commitMessages);\n prBody = await copilot.generatePRDescription({\n branch: currentBranch,\n commits: commitMessages,\n files,\n issues: Array.from(ticketIds),\n ticketDetails: tickets,\n diffStat,\n diff: diffContent,\n templateContent: template?.raw,\n promptConfig,\n });\n }\n\n spinner.stop();\n\n // Fetch repo metadata for interactive mode\n let repoMeta: Awaited<ReturnType<typeof getRepoMetadata>> = null;\n let selectedLabels: string[] = [];\n let selectedReviewers: string[] = [];\n let selectedAssignees: string[] = [];\n\n if (options.interactive) {\n const metaSpinner = UI.spinner('Fetching repository metadata...');\n metaSpinner.start();\n repoMeta = await getRepoMetadata();\n metaSpinner.stop();\n }\n\n // Show info about what was used\n console.log('');\n console.log(UI.info(`Base branch: ${colors.accent(base)}`));\n if (usingTemplate && template) {\n console.log(UI.info(`PR template: ${colors.accent(template.path)}`));\n } else {\n console.log(UI.info('Using default PR format (no template found)'));\n }\n if (promptConfig) {\n console.log(UI.info(`PR guidelines: ${colors.accent(promptConfig.path)}`));\n }\n if (shouldIncludeDiff && diffStat) {\n console.log(\n UI.info(\n `Diff context: ${colors.accent('included')} (${diffContent.split('\\n').length} lines)`\n )\n );\n }\n\n // Interactive selection\n if (options.interactive && repoMeta) {\n console.log('');\n console.log(UI.section('Configure PR', '⚙️'));\n console.log('');\n\n // Select labels\n if (repoMeta.labels.length > 0) {\n selectedLabels = await selectLabels(repoMeta.labels);\n }\n\n // Select reviewers\n if (repoMeta.collaborators.length > 0) {\n selectedReviewers = await selectUsers(repoMeta.collaborators, 'reviewers');\n }\n\n // Select assignees\n if (repoMeta.collaborators.length > 0) {\n selectedAssignees = await selectUsers(repoMeta.collaborators, 'assignees');\n }\n }\n\n // Show preview\n const isDraft = options.draft;\n\n if (options.preview || options.interactive) {\n renderPRPreview(prTitle, prBody, {\n branch: currentBranch,\n base,\n labels: selectedLabels,\n assignees: selectedAssignees,\n reviewers: selectedReviewers,\n isDraft,\n });\n } else {\n // Simple display\n console.log('');\n console.log(\n UI.box(`${colors.bold(prTitle)}\\n\\n${prBody}`, `${ASCII.icons.pr} PR: ${currentBranch}`)\n );\n }\n\n // Stats\n if (config.output.showStats) {\n const statItems: { label: string; value: string | number }[] = [\n { label: 'commits', value: commits.length },\n { label: 'files changed', value: files.length },\n { label: 'type', value: prType },\n ];\n if (tickets.length > 0) {\n statItems.push({ label: 'tickets linked', value: tickets.length });\n }\n if (usingTemplate) {\n statItems.push({ label: 'template', value: '✓' });\n }\n console.log(UI.stats(statItems));\n }\n console.log('');\n\n // Action menu\n const choices = [\n { name: `${ASCII.status.bullet} Copy to clipboard`, value: 'copy' },\n { name: `${ASCII.status.arrowRight} Create PR on GitHub`, value: 'create' },\n { name: `${ASCII.status.bullet} Create draft PR`, value: 'draft' },\n ];\n\n // Add preview in browser option\n const repoInfo = await getRepoInfo();\n if (repoInfo) {\n choices.push({\n name: `${ASCII.status.bullet} Preview in browser`,\n value: 'browser',\n });\n }\n\n if (!options.interactive && repoMeta === null) {\n choices.push({\n name: `${ASCII.status.bullet} Configure labels & reviewers`,\n value: 'configure',\n });\n }\n\n choices.push(\n // @ts-expect-error - inquirer separator type\n new inquirer.Separator(),\n { name: `${ASCII.status.cross} Exit`, value: 'exit' }\n );\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: colors.primary('What would you like to do?'),\n choices,\n },\n ]);\n\n if (action === 'copy') {\n await copyToClipboard(`${prTitle}\\n\\n${prBody}`);\n console.log(UI.success('Copied to clipboard!'));\n } else if (action === 'browser' && repoInfo) {\n const previewUrl = getPRPreviewUrl(repoInfo.owner, repoInfo.name, base, currentBranch);\n const { execa } = await import('execa');\n await execa('open', [previewUrl]);\n console.log(UI.success('Opened in browser!'));\n } else if (action === 'configure') {\n // Fetch metadata and let user configure\n const metaSpinner = UI.spinner('Fetching repository metadata...');\n metaSpinner.start();\n repoMeta = await getRepoMetadata();\n metaSpinner.stop();\n\n if (repoMeta) {\n console.log('');\n if (repoMeta.labels.length > 0) {\n selectedLabels = await selectLabels(repoMeta.labels);\n }\n if (repoMeta.collaborators.length > 0) {\n selectedReviewers = await selectUsers(repoMeta.collaborators, 'reviewers');\n }\n if (repoMeta.collaborators.length > 0) {\n selectedAssignees = await selectUsers(repoMeta.collaborators, 'assignees');\n }\n\n // Show updated preview\n renderPRPreview(prTitle, prBody, {\n branch: currentBranch,\n base,\n labels: selectedLabels,\n assignees: selectedAssignees,\n reviewers: selectedReviewers,\n isDraft,\n });\n\n // Ask to create\n const { confirmCreate } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmCreate',\n message: 'Create this PR?',\n default: true,\n },\n ]);\n\n if (confirmCreate) {\n await doCreatePR(\n prTitle,\n prBody,\n base,\n selectedLabels,\n selectedAssignees,\n selectedReviewers,\n false\n );\n }\n }\n } else if (action === 'create' || action === 'draft') {\n const createDraft = action === 'draft' || options.draft;\n await doCreatePR(\n prTitle,\n prBody,\n base,\n selectedLabels,\n selectedAssignees,\n selectedReviewers,\n createDraft\n );\n }\n // ── Auto-snapshot side-effect ──────────────────────────────────────\n if (options.journal !== false) {\n const isDebug = options.debug || process.env.DEVD_DEBUG === '1';\n await sideEffectSnapshot({\n source: 'pr',\n note: `PR generated for branch ${currentBranch} → ${base}`,\n tags: prTitle ? [`pr:${prTitle.slice(0, 50)}`] : [],\n debug: isDebug,\n });\n }\n } catch (error) {\n spinner.stop();\n console.log('');\n console.log(UI.error('Failed to generate PR description'));\n console.log(colors.muted((error as Error).message));\n process.exit(1);\n }\n });\n\n/**\n * Create the PR on GitHub\n */\nasync function doCreatePR(\n title: string,\n body: string,\n base: string,\n labels: string[],\n assignees: string[],\n reviewers: string[],\n isDraft: boolean\n): Promise<void> {\n const createSpinner = UI.spinner(`Creating ${isDraft ? 'draft ' : ''}PR...`);\n createSpinner.start();\n\n try {\n const result = await createPR({\n title,\n body,\n base,\n draft: isDraft,\n labels: labels.length > 0 ? labels : undefined,\n assignees: assignees.length > 0 ? assignees : undefined,\n reviewers: reviewers.length > 0 ? reviewers : undefined,\n });\n\n createSpinner.stop();\n console.log('');\n console.log(UI.success('PR created successfully'));\n console.log(colors.accent(result.url));\n } catch (error) {\n createSpinner.stop();\n console.log('');\n console.log(UI.error('Failed to create PR'));\n console.log(colors.muted((error as Error).message));\n }\n}\n","/**\n * PR Template Detection and Parsing\n * Finds and parses GitHub PR templates to provide structured PR descriptions\n */\n\nimport { readFile, access } from 'fs/promises';\nimport { join } from 'path';\n\nexport interface PRTemplateSection {\n name: string;\n header: string;\n content: string;\n type: 'heading' | 'checklist' | 'list' | 'text';\n required: boolean;\n}\n\nexport interface PRTemplate {\n path: string;\n raw: string;\n title?: string;\n sections: PRTemplateSection[];\n}\n\n/**\n * Common PR template locations (in order of precedence)\n */\nconst TEMPLATE_PATHS = [\n '.github/PULL_REQUEST_TEMPLATE.md',\n '.github/pull_request_template.md',\n '.github/PULL_REQUEST_TEMPLATE/default.md',\n 'docs/PULL_REQUEST_TEMPLATE.md',\n 'PULL_REQUEST_TEMPLATE.md',\n 'pull_request_template.md',\n];\n\n/**\n * Check if a file exists\n */\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Find PR template in the repository\n */\nexport async function findPRTemplate(repoRoot: string): Promise<string | null> {\n for (const templatePath of TEMPLATE_PATHS) {\n const fullPath = join(repoRoot, templatePath);\n if (await fileExists(fullPath)) {\n return fullPath;\n }\n }\n return null;\n}\n\n/**\n * Parse a PR template into sections\n */\nexport function parsePRTemplate(content: string): PRTemplate {\n const sections: PRTemplateSection[] = [];\n const lines = content.split('\\n');\n\n let currentSection: PRTemplateSection | null = null;\n let titleLine: string | undefined;\n\n // Check for title in first line\n if (lines[0]?.startsWith('# ')) {\n titleLine = lines[0].replace(/^#\\s*/, '').trim();\n }\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Detect heading (## Section Name)\n const headingMatch = line.match(/^##\\s+(.+)$/);\n if (headingMatch) {\n // Save previous section\n if (currentSection) {\n currentSection.content = currentSection.content.trim();\n sections.push(currentSection);\n }\n\n // Start new section\n const sectionName = headingMatch[1].trim();\n currentSection = {\n name: normalizeSectionName(sectionName),\n header: sectionName,\n content: '',\n type: 'text',\n required: false,\n };\n continue;\n }\n\n // Detect section type and accumulate content\n if (currentSection) {\n // Check for checklist items\n if (line.match(/^-\\s*\\[[ x]\\]/i)) {\n currentSection.type = 'checklist';\n }\n // Check for bullet list\n else if (line.match(/^-\\s+[^[]/) && currentSection.type !== 'checklist') {\n currentSection.type = 'list';\n }\n\n currentSection.content += line + '\\n';\n }\n }\n\n // Don't forget the last section\n if (currentSection) {\n currentSection.content = currentSection.content.trim();\n sections.push(currentSection);\n }\n\n return {\n path: '',\n raw: content,\n title: titleLine,\n sections,\n };\n}\n\n/**\n * Normalize section names for matching\n */\nfunction normalizeSectionName(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, '')\n .replace(/\\s+/g, '_')\n .trim();\n}\n\n/**\n * Load and parse a PR template\n */\nexport async function loadPRTemplate(repoRoot: string): Promise<PRTemplate | null> {\n const templatePath = await findPRTemplate(repoRoot);\n\n if (!templatePath) {\n return null;\n }\n\n try {\n const content = await readFile(templatePath, 'utf-8');\n const template = parsePRTemplate(content);\n template.path = templatePath;\n return template;\n } catch {\n return null;\n }\n}\n\n/**\n * Section mappings for AI to fill\n */\nexport interface PRSectionMappings {\n description?: string;\n type_of_change?: string;\n impact?: string;\n testing?: string;\n additional?: string;\n jira_ticket?: string;\n breaking_changes?: string;\n screenshots?: string;\n checklist?: string[];\n}\n\n/**\n * Fill a template with AI-generated content\n */\nexport function fillTemplate(\n template: PRTemplate,\n content: {\n title: string;\n description: string;\n type: string;\n impact: string;\n testing: string;\n ticketIds: string[];\n ticketLinks: { id: string; url: string }[];\n breakingChanges?: string;\n additionalInfo?: string;\n }\n): string {\n let result = '';\n\n // Add title if template has one\n if (template.title) {\n result += `# ${content.title}\\n\\n`;\n }\n\n for (const section of template.sections) {\n result += `## ${section.header}\\n\\n`;\n\n const sectionKey = section.name.toLowerCase();\n\n // Match section to content\n if (sectionKey.includes('description') || sectionKey.includes('what')) {\n result += content.description + '\\n\\n';\n } else if (sectionKey.includes('type') || sectionKey.includes('change')) {\n result += formatTypeOfChange(content.type, section.content) + '\\n\\n';\n } else if (\n sectionKey.includes('jira') ||\n sectionKey.includes('ticket') ||\n sectionKey.includes('issue')\n ) {\n result += formatTicketSection(content.ticketIds, content.ticketLinks) + '\\n\\n';\n } else if (sectionKey.includes('impact')) {\n result += content.impact + '\\n\\n';\n } else if (sectionKey.includes('test') || sectionKey.includes('how_to')) {\n result += content.testing + '\\n\\n';\n } else if (sectionKey.includes('breaking')) {\n result += (content.breakingChanges || 'No breaking changes.') + '\\n\\n';\n } else if (sectionKey.includes('additional') || sectionKey.includes('notes')) {\n result += (content.additionalInfo || 'No additional information.') + '\\n\\n';\n } else if (sectionKey.includes('screenshot')) {\n result += '_Screenshots will be added if applicable._\\n\\n';\n } else if (section.type === 'checklist') {\n // Keep checklist as-is\n result += section.content + '\\n\\n';\n } else {\n // For unknown sections, keep original content or add placeholder\n result += section.content || '_To be filled._\\n\\n';\n }\n }\n\n return result.trim();\n}\n\n/**\n * Format type of change section with checkmarks\n */\nfunction formatTypeOfChange(type: string, originalContent: string): string {\n const typeMap: Record<string, string[]> = {\n feat: ['feature', 'new feature', '🚀'],\n fix: ['bug', 'bug fix', '🪲'],\n docs: ['documentation', 'doc', '📈'],\n refactor: ['refactor', '🛠️'],\n hotfix: ['hotfix', '🐦‍🔥'],\n security: ['security', '🔐'],\n style: ['ui', 'ux', '✨', 'style'],\n chore: ['chore', 'maintenance'],\n test: ['test', 'testing'],\n };\n\n // Find matching keywords for the type\n const keywords = typeMap[type.toLowerCase()] || [];\n\n // Parse original checklist and mark the appropriate one\n const lines = originalContent.split('\\n');\n const result = lines.map((line) => {\n const isChecklist = line.match(/^-\\s*\\[[ x]\\]/i);\n if (!isChecklist) return line;\n\n const lineContent = line.toLowerCase();\n const shouldCheck = keywords.some((kw) => lineContent.includes(kw.toLowerCase()));\n\n if (shouldCheck) {\n return line.replace(/\\[[ ]\\]/, '[x]');\n }\n return line.replace(/\\[x\\]/i, '[ ]');\n });\n\n return result.join('\\n');\n}\n\n/**\n * Format ticket section\n */\nfunction formatTicketSection(\n ticketIds: string[],\n ticketLinks: { id: string; url: string }[]\n): string {\n if (ticketIds.length === 0) {\n return '**Ticket No:** N/A\\n\\n**Ticket link:** N/A';\n }\n\n const lines: string[] = [];\n\n for (const id of ticketIds) {\n const link = ticketLinks.find((t) => t.id === id);\n if (link) {\n lines.push(`**Ticket No:** ${id}`);\n lines.push(`**Ticket link:** ${link.url}`);\n } else {\n lines.push(`**Ticket No:** ${id}`);\n }\n }\n\n return lines.join('\\n\\n');\n}\n\n/**\n * Get default PR template (used when no template exists)\n */\nexport function getDefaultTemplate(): string {\n return `## What Changed\n\n[Description of changes]\n\n## Why\n\n[Business or technical reason for these changes]\n\n## How to Test\n\n1. [Testing step 1]\n2. [Testing step 2]\n\n## Checklist\n\n- [ ] My code follows the project's style guidelines\n- [ ] I have performed a self-review of my code\n- [ ] I have added tests that prove my fix/feature works\n- [ ] New and existing tests pass locally\n`;\n}\n","/**\n * GitHub Repository Helpers\n * Functions for interacting with GitHub API via gh CLI\n */\n\nimport { execa } from 'execa';\n\nexport interface GitHubLabel {\n name: string;\n color: string;\n description?: string;\n}\n\nexport interface GitHubUser {\n login: string;\n name?: string;\n}\n\nexport interface GitHubTeam {\n slug: string;\n name: string;\n}\n\nexport interface RepoMetadata {\n owner: string;\n name: string;\n defaultBranch: string;\n labels: GitHubLabel[];\n collaborators: GitHubUser[];\n teams: GitHubTeam[];\n}\n\n/**\n * Get the current repository's owner and name\n */\nexport async function getRepoInfo(): Promise<{ owner: string; name: string } | null> {\n try {\n const { stdout } = await execa('gh', ['repo', 'view', '--json', 'owner,name']);\n const data = JSON.parse(stdout);\n return {\n owner: data.owner?.login || data.owner,\n name: data.name,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Get repository labels\n */\nexport async function getRepoLabels(): Promise<GitHubLabel[]> {\n try {\n const { stdout } = await execa('gh', ['label', 'list', '--json', 'name,color,description']);\n return JSON.parse(stdout);\n } catch {\n return [];\n }\n}\n\n/**\n * Get repository collaborators (people who can be assigned)\n */\nexport async function getRepoCollaborators(): Promise<GitHubUser[]> {\n try {\n const { stdout } = await execa('gh', [\n 'api',\n 'repos/{owner}/{repo}/collaborators',\n '--jq',\n '.[].login',\n ]);\n const logins = stdout.trim().split('\\n').filter(Boolean);\n return logins.map((login) => ({ login }));\n } catch {\n return [];\n }\n}\n\n/**\n * Get assignable users for the repository\n */\nexport async function getAssignableUsers(): Promise<GitHubUser[]> {\n try {\n const { stdout } = await execa('gh', [\n 'api',\n 'repos/{owner}/{repo}/assignees',\n '--jq',\n '.[].login',\n ]);\n const logins = stdout.trim().split('\\n').filter(Boolean);\n return logins.map((login) => ({ login }));\n } catch {\n return [];\n }\n}\n\n/**\n * Get the current user's login\n */\nexport async function getCurrentUser(): Promise<string | null> {\n try {\n const { stdout } = await execa('gh', ['api', 'user', '--jq', '.login']);\n return stdout.trim();\n } catch {\n return null;\n }\n}\n\n/**\n * Get team members who can review PRs\n */\nexport async function getTeamReviewers(): Promise<GitHubTeam[]> {\n try {\n const { stdout } = await execa('gh', [\n 'api',\n 'repos/{owner}/{repo}/teams',\n '--jq',\n '.[] | {slug: .slug, name: .name}',\n ]);\n // Parse JSON lines\n const lines = stdout.trim().split('\\n').filter(Boolean);\n return lines.map((line) => JSON.parse(line));\n } catch {\n return [];\n }\n}\n\n/**\n * Fetch all repository metadata in parallel\n */\nexport async function getRepoMetadata(): Promise<RepoMetadata | null> {\n const repoInfo = await getRepoInfo();\n if (!repoInfo) return null;\n\n const [labels, collaborators, teams] = await Promise.all([\n getRepoLabels(),\n getAssignableUsers(),\n getTeamReviewers(),\n ]);\n\n // Get default branch\n let defaultBranch = 'main';\n try {\n const { stdout } = await execa('gh', ['repo', 'view', '--json', 'defaultBranchRef']);\n const data = JSON.parse(stdout);\n defaultBranch = data.defaultBranchRef?.name || 'main';\n } catch {\n // Keep default\n }\n\n return {\n owner: repoInfo.owner,\n name: repoInfo.name,\n defaultBranch,\n labels,\n collaborators,\n teams,\n };\n}\n\n/**\n * Create a PR with full options\n */\nexport interface CreatePROptions {\n title: string;\n body: string;\n base: string;\n head?: string;\n draft?: boolean;\n labels?: string[];\n assignees?: string[];\n reviewers?: string[];\n teamReviewers?: string[];\n milestone?: string;\n project?: string;\n}\n\nexport async function createPR(options: CreatePROptions): Promise<{ url: string; number: number }> {\n const args = [\n 'pr',\n 'create',\n '--title',\n options.title,\n '--body',\n options.body,\n '--base',\n options.base,\n ];\n\n if (options.head) {\n args.push('--head', options.head);\n }\n\n if (options.draft) {\n args.push('--draft');\n }\n\n if (options.labels && options.labels.length > 0) {\n args.push('--label', options.labels.join(','));\n }\n\n if (options.assignees && options.assignees.length > 0) {\n args.push('--assignee', options.assignees.join(','));\n }\n\n if (options.reviewers && options.reviewers.length > 0) {\n args.push('--reviewer', options.reviewers.join(','));\n }\n\n // Note: team reviewers need special handling in gh cli\n\n const { stdout } = await execa('gh', args);\n\n // Parse PR URL and number from output\n const urlMatch = stdout.match(/https:\\/\\/github\\.com\\/[^\\s]+\\/pull\\/(\\d+)/);\n\n return {\n url: stdout.trim(),\n number: urlMatch ? parseInt(urlMatch[1], 10) : 0,\n };\n}\n\n/**\n * Get PR preview URL (for opening in browser)\n */\nexport function getPRPreviewUrl(owner: string, repo: string, base: string, head: string): string {\n return `https://github.com/${owner}/${repo}/compare/${base}...${head}?expand=1`;\n}\n","import type { ConventionalCommit } from '../types/index.js';\n\nconst COMMIT_PATTERN =\n // eslint-disable-next-line no-useless-escape\n /^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\\([^\\)]+\\))?(!)?:\\s*(.+)$/;\n\nexport function parseConventionalCommit(message: string): ConventionalCommit | null {\n const match = message.match(COMMIT_PATTERN);\n\n if (!match) {\n return null;\n }\n\n const [, type, scope, breaking, subject] = match;\n\n return {\n type: type as ConventionalCommit['type'],\n scope: scope?.replace(/[()]/g, ''),\n subject: subject.trim(),\n breaking: breaking === '!',\n };\n}\n\nexport function extractIssueNumbers(text: string): string[] {\n const issuePattern = /#(\\d+)/g;\n const matches = text.matchAll(issuePattern);\n return Array.from(matches, (m) => `#${m[1]}`);\n}\n\nexport function generatePRTitle(commits: string[]): string {\n // Try to parse conventional commits\n const parsed = commits\n .map(parseConventionalCommit)\n .filter((c): c is ConventionalCommit => c !== null);\n\n if (parsed.length === 0) {\n // Fallback: use first commit message\n return commits[0] || 'Update';\n }\n\n // Group by type\n const features = parsed.filter((c) => c.type === 'feat');\n const fixes = parsed.filter((c) => c.type === 'fix');\n\n if (features.length > 0) {\n return features[0].subject;\n }\n\n if (fixes.length > 0) {\n return `Fix: ${fixes[0].subject}`;\n }\n\n return parsed[0].subject;\n}\n\nexport function categorizePRType(commits: string[]): string {\n const parsed = commits\n .map(parseConventionalCommit)\n .filter((c): c is ConventionalCommit => c !== null);\n\n const hasFeatures = parsed.some((c) => c.type === 'feat');\n const hasFixes = parsed.some((c) => c.type === 'fix');\n const hasBreaking = parsed.some((c) => c.breaking);\n\n if (hasBreaking) return 'breaking';\n if (hasFeatures) return 'feature';\n if (hasFixes) return 'bugfix';\n return 'chore';\n}\n","import { Command } from 'commander';\nimport { GitAnalyzer } from '../core/git-analyzer.js';\nimport { CopilotClient } from '../core/copilot.js';\nimport { StandupContextBuilder } from '../core/standup-context.js';\nimport { WorkJournal } from '../core/work-journal.js';\nimport UI from '../ui/renderer.js';\nimport { ASCII } from '../ui/ascii.js';\nimport { copyToClipboard, getWeekStart, getWeekEnd, formatDateRange } from '../utils/helpers.js';\nimport { getConfig } from '../config/index.js';\nimport { sideEffectSnapshot } from '../core/auto-snapshot.js';\n\nconst { colors } = UI;\n\nexport const weekCommand = new Command('week')\n .description('Generate weekly work summary from commits, PRs, tickets, and journal history')\n .option('-l, --last', 'Last week instead of current week')\n .option('-s, --start <date>', 'Custom start date (YYYY-MM-DD)')\n .option('--from <date>', 'Start date for custom range (YYYY-MM-DD)')\n .option('--to <date>', 'End date for custom range (YYYY-MM-DD)')\n .option('-w, --weeks-ago <number>', 'Number of weeks ago (e.g., 2 = two weeks back)')\n .option('--all-projects', 'Include all tracked projects from journal (cross-project summary)')\n .option('-p, --project <id>', 'Filter by specific project identifier')\n .option('--no-tickets', 'Skip fetching closed tickets/issues')\n .option('--no-prs', 'Skip fetching PR context')\n .option('--no-journal', 'Skip journal data (use only live git data)')\n .option('--no-auto-snapshot', 'Skip auto-saving a snapshot to the journal')\n .option('--no-copy', 'Do not copy to clipboard')\n .option('--save', 'Save the generated summary to the journal as an AI summary')\n .option('--debug', 'Show the full context and prompt sent to Copilot')\n .option('--raw-context', 'Output only the raw context block (no AI generation)')\n .option('--json', 'Output stats as JSON (no AI generation)')\n .action(async (options) => {\n const config = getConfig();\n const git = new GitAnalyzer();\n const isDebug = options.debug || process.env.DEVD_DEBUG === '1';\n const copilot = new CopilotClient({ debug: isDebug });\n const journal = new WorkJournal();\n\n // Check if in git repo (unless doing cross-project from journal)\n const isRepo = await git.isRepository();\n if (!isRepo && !options.allProjects) {\n console.log(UI.error('Not a git repository'));\n console.log(\n UI.info('Use --all-projects to generate a cross-project summary from your journal')\n );\n process.exit(1);\n }\n\n // Check if Copilot CLI is installed (unless raw-context or json mode)\n if (!options.rawContext && !options.json && !(await copilot.isInstalled())) {\n console.log(UI.error('GitHub Copilot CLI not found'));\n console.log(UI.info('Install with: gh extension install github/gh-copilot'));\n process.exit(1);\n }\n\n const spinner = UI.spinner('Gathering weekly work context...');\n spinner.start();\n\n try {\n // ── Determine date range ─────────────────────────────────────────────\n let start: Date;\n let end: Date;\n\n if (options.from || options.to) {\n // Custom range mode\n const today = new Date();\n start = options.from ? new Date(options.from) : getWeekStart(0);\n end = options.to ? new Date(options.to) : today;\n // Normalize end to end-of-day\n end.setHours(23, 59, 59, 999);\n } else if (options.start) {\n start = new Date(options.start);\n end = new Date(start.getTime() + 7 * 24 * 60 * 60 * 1000);\n } else if (options.weeksAgo) {\n const weeksAgo = parseInt(options.weeksAgo, 10) || 1;\n start = getWeekStart(weeksAgo);\n end = getWeekEnd(weeksAgo);\n } else {\n const weeksAgo = options.last ? 1 : 0;\n start = getWeekStart(weeksAgo);\n end = getWeekEnd(weeksAgo);\n }\n\n const startStr = dateToString(start);\n const endStr = dateToString(end);\n\n // Calculate days for the context builder\n const now = new Date();\n const daysSinceStart = Math.ceil((now.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));\n\n // ── Cross-project mode (journal-based) ───────────────────────────────\n if (options.allProjects) {\n spinner.text = 'Gathering cross-project journal data...';\n\n const crossProjectSummary = journal.getCrossProjectSummary(startStr, endStr);\n const allSnapshots = journal.getSnapshotsForRange(null, startStr, endStr);\n\n spinner.stop();\n\n if (crossProjectSummary.projects.length === 0) {\n console.log('');\n console.log(UI.warning('No journal entries found for this period across any project'));\n console.log(UI.info('Take snapshots with: devdaily snapshot'));\n console.log(UI.info('Or run without --all-projects to use live git data for this repo'));\n process.exit(0);\n }\n\n // ── JSON mode for cross-project ──────────────────────────────────\n if (options.json) {\n console.log(JSON.stringify(crossProjectSummary, null, 2));\n return;\n }\n\n // ── Raw context mode for cross-project ───────────────────────────\n if (options.rawContext) {\n console.log('');\n console.log(WorkJournal.formatSnapshotsForAI(allSnapshots));\n return;\n }\n\n // ── Debug mode ───────────────────────────────────────────────────\n if (isDebug) {\n console.log('');\n console.log(colors.accent('─── Debug: Cross-Project Summary ───'));\n console.log(JSON.stringify(crossProjectSummary, null, 2));\n console.log('');\n console.log(colors.accent('─── Debug: Full Prompt Context Block ───'));\n console.log(colors.muted(WorkJournal.formatSnapshotsForAI(allSnapshots)));\n console.log('');\n }\n\n // ── Generate AI summary for cross-project ────────────────────────\n const genSpinner = UI.spinner(\n 'Generating cross-project weekly summary with Copilot CLI...'\n );\n genSpinner.start();\n\n const contextBlock = WorkJournal.formatSnapshotsForAI(allSnapshots);\n const prompt = buildCrossProjectWeeklyPrompt(\n contextBlock,\n startStr,\n endStr,\n crossProjectSummary\n );\n const summary = await copilot.generateFromPrompt(prompt);\n\n genSpinner.stop();\n\n // ── Output cross-project summary ─────────────────────────────────\n const title = `${ASCII.icons.week} Cross-Project Week in Review (${formatDateRange(start, end)})`;\n\n console.log('');\n console.log(UI.box(summary, title));\n\n // Stats bar\n if (config.output.showStats) {\n const statItems: { label: string; value: string | number; color?: string }[] = [\n { label: 'projects', value: crossProjectSummary.projects.length },\n { label: 'active days', value: crossProjectSummary.totalActiveDays },\n { label: 'total commits', value: crossProjectSummary.totalCommits },\n ];\n\n // Aggregate diff stats\n const totalInsertions = crossProjectSummary.projects.reduce(\n (sum, p) => sum + p.diffStats.insertions,\n 0\n );\n const totalDeletions = crossProjectSummary.projects.reduce(\n (sum, p) => sum + p.diffStats.deletions,\n 0\n );\n if (totalInsertions > 0 || totalDeletions > 0) {\n statItems.push(\n { label: 'lines added', value: `+${totalInsertions}`, color: 'green' },\n { label: 'lines removed', value: `-${totalDeletions}`, color: 'red' }\n );\n }\n\n console.log(UI.stats(statItems));\n }\n\n // Per-project breakdown\n console.log('');\n console.log(UI.section('📂 Per-Project Breakdown'));\n console.log('');\n\n for (const project of crossProjectSummary.projects) {\n const diffInfo =\n project.diffStats.insertions + project.diffStats.deletions > 0\n ? ` ${colors.success(`+${project.diffStats.insertions}`)}/${colors.error(`-${project.diffStats.deletions}`)}`\n : '';\n\n console.log(\n ` ${colors.accent(project.projectId.padEnd(30))} ${project.totalCommits} commit${project.totalCommits !== 1 ? 's' : ''} · ${project.activeDays} day${project.activeDays !== 1 ? 's' : ''}${diffInfo}`\n );\n\n if (project.branches.length > 0) {\n console.log(\n ` ${colors.muted('Branches:')} ${project.branches.slice(0, 5).join(', ')}${project.branches.length > 5 ? ` +${project.branches.length - 5} more` : ''}`\n );\n }\n\n if (project.categories.length > 0) {\n const cats = project.categories\n .slice(0, 3)\n .map((c) => `${c.name}(${c.percentage}%)`)\n .join(', ');\n console.log(` ${colors.muted('Areas:')} ${cats}`);\n }\n\n console.log('');\n }\n\n // Copy to clipboard\n if (options.copy && config.output.copyToClipboard !== false) {\n await copyToClipboard(summary);\n console.log(UI.success('Copied to clipboard'));\n }\n\n // Save to journal\n if (options.save) {\n for (const project of crossProjectSummary.projects) {\n const latestDate = endStr;\n journal.setAISummary(project.projectId, summary, latestDate);\n }\n console.log(UI.success('Summary saved to journal'));\n }\n\n console.log('');\n return;\n }\n\n // ── Single-project mode (live git + optional journal enrichment) ─────\n\n // Phase 1: Build rich context using StandupContextBuilder (live data)\n spinner.text = 'Analyzing git history, PRs, and tickets...';\n\n const contextBuilder = new StandupContextBuilder();\n const ctx = await contextBuilder.build({\n days: daysSinceStart,\n skipTickets: options.tickets === false,\n skipPRs: options.prs === false,\n baseBranch: config.git.defaultBranch,\n debug: isDebug,\n });\n\n // Phase 1b: Enrich with journal data if available\n let journalSnapshots = null;\n let journalContext = '';\n\n if (options.journal !== false) {\n const projectId = options.project || null;\n const snapshots = journal.getSnapshotsForRange(projectId, startStr, endStr);\n\n if (snapshots.length > 0) {\n journalSnapshots = snapshots;\n journalContext = WorkJournal.formatSnapshotsForAI(snapshots);\n\n if (isDebug) {\n console.log('');\n console.log(colors.accent(`─── Debug: Journal Entries (${snapshots.length}) ───`));\n console.log(colors.muted(journalContext.slice(0, 2000)));\n if (journalContext.length > 2000) {\n console.log(colors.muted(`... (${journalContext.length - 2000} more chars)`));\n }\n console.log('');\n }\n }\n }\n\n if (ctx.commits.length === 0 && ctx.pullRequests.length === 0 && !journalSnapshots) {\n spinner.stop();\n console.log('');\n console.log(UI.warning('No commits, PRs, or journal entries found for this week'));\n console.log(\n UI.info(\n 'Try a different date range with --from / --to, or take snapshots with: devdaily snapshot'\n )\n );\n process.exit(0);\n }\n\n spinner.stop();\n\n // ── Debug mode: show full context ──────────────────────────────────\n if (isDebug) {\n console.log('');\n console.log(colors.accent('─── Debug: Assembled Context ───'));\n console.log(StandupContextBuilder.formatDebugSummary(ctx));\n console.log('');\n console.log(colors.accent('─── Debug: Full Prompt Context Block ───'));\n console.log(colors.muted(StandupContextBuilder.formatForPrompt(ctx)));\n console.log('');\n }\n\n // ── JSON mode ──────────────────────────────────────────────────────\n if (options.json) {\n const jsonData = {\n dateRange: { from: startStr, to: endStr },\n commits: ctx.commits.length,\n pullRequests: ctx.pullRequests.length,\n tickets: ctx.tickets.length,\n diffStats: ctx.diffStats,\n categories: ctx.categories,\n topChangedFiles: ctx.topChangedFiles,\n branch: ctx.branch,\n journalEntries: journalSnapshots?.length || 0,\n };\n console.log(JSON.stringify(jsonData, null, 2));\n return;\n }\n\n // ── Raw context mode: just output the context block ────────────────\n if (options.rawContext) {\n console.log('');\n console.log(StandupContextBuilder.formatForPrompt(ctx));\n if (journalContext) {\n console.log('');\n console.log('--- JOURNAL HISTORY ---');\n console.log(journalContext);\n }\n return;\n }\n\n // ── Phase 2: Generate weekly summary with AI ───────────────────────\n const genSpinner = UI.spinner('Generating weekly summary with Copilot CLI...');\n genSpinner.start();\n\n let summary: string;\n\n if (journalContext) {\n // Enhanced prompt with journal context\n const contextBlock = StandupContextBuilder.formatForPrompt(ctx);\n const prompt = buildEnhancedWeeklyPrompt(contextBlock, journalContext, startStr, endStr);\n summary = await copilot.generateFromPrompt(prompt);\n } else {\n summary = await copilot.generateWeeklyFromContext(ctx);\n }\n\n genSpinner.stop();\n\n // ── Phase 3: Output ────────────────────────────────────────────────\n const title = `${ASCII.icons.week} Week in Review (${formatDateRange(start, end)})`;\n\n console.log('');\n console.log(UI.box(summary, title));\n\n // Stats bar\n if (config.output.showStats) {\n const statItems: { label: string; value: string | number; color?: string }[] = [\n { label: 'commits', value: ctx.commits.length },\n ];\n if (ctx.diffStats) {\n statItems.push(\n { label: 'lines added', value: `+${ctx.diffStats.insertions}`, color: 'green' },\n { label: 'lines removed', value: `-${ctx.diffStats.deletions}`, color: 'red' }\n );\n }\n if (ctx.pullRequests.length > 0) {\n statItems.push({ label: 'PRs', value: ctx.pullRequests.length });\n }\n if (ctx.tickets.length > 0) {\n statItems.push({ label: 'tickets', value: ctx.tickets.length });\n }\n if (ctx.categories.length > 0) {\n statItems.push({ label: 'primary area', value: ctx.categories[0].name });\n }\n if (journalSnapshots) {\n statItems.push({ label: 'journal days', value: journalSnapshots.length });\n }\n console.log(UI.stats(statItems));\n }\n console.log('');\n\n // Copy to clipboard\n if (options.copy && config.output.copyToClipboard !== false) {\n await copyToClipboard(summary);\n console.log(UI.success('Copied to clipboard'));\n }\n\n // Save to journal\n if (options.save) {\n try {\n // Detect project ID for saving\n let projectIdForSave = options.project;\n if (!projectIdForSave && journalSnapshots && journalSnapshots.length > 0) {\n projectIdForSave = journalSnapshots[0].projectId;\n }\n if (!projectIdForSave) {\n projectIdForSave = WorkJournal.sanitizeProjectId(\n ctx.repo.name || process.cwd().split('/').pop() || 'unknown'\n );\n }\n\n journal.setAISummary(projectIdForSave, summary, endStr);\n console.log(UI.success('Summary saved to journal'));\n } catch (err) {\n console.log(UI.warning(`Could not save to journal: ${(err as Error).message}`));\n }\n }\n\n // ── Auto-snapshot side-effect ──────────────────────────────────────\n if (options.autoSnapshot !== false) {\n await sideEffectSnapshot({\n source: 'week',\n note: `Weekly summary generated (${startStr} → ${endStr})`,\n debug: isDebug,\n });\n }\n } catch (error) {\n spinner.stop();\n console.log('');\n console.log(UI.error('Failed to generate weekly summary'));\n console.log(colors.muted((error as Error).message));\n\n if (isDebug && error instanceof Error && error.stack) {\n console.log('');\n console.log(colors.muted('Stack trace:'));\n console.log(colors.muted(error.stack));\n }\n\n process.exit(1);\n }\n });\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction dateToString(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n}\n\nfunction buildEnhancedWeeklyPrompt(\n liveContext: string,\n journalContext: string,\n fromDate: string,\n toDate: string\n): string {\n return `You are a developer assistant generating a weekly work summary for the period ${fromDate} to ${toDate}.\n\nYou have TWO sources of data:\n1. LIVE GIT DATA — commits, PRs, tickets from the current repo (most accurate for current state)\n2. JOURNAL HISTORY — saved snapshots from previous days (provides historical context and continuity)\n\nGenerate a clear, well-structured weekly summary with these sections:\n\n## Accomplishments\n- List the key things completed this week\n- Group related commits into logical accomplishments\n- Reference PR numbers and ticket IDs where available\n\n## In Progress\n- Work that's started but not yet complete\n- Open PRs, active branches, pending reviews\n\n## Key Metrics\n- Lines changed, files touched, PRs merged\n- Work area breakdown (frontend, backend, etc.)\n\n## Notable Items\n- Any breaking changes, new features, or significant refactors\n- Cross-cutting concerns or patterns you notice\n\nRules:\n- Be concise but comprehensive\n- Use bullet points\n- Reference specific PR numbers (#N), ticket IDs, and branch names\n- Don't hallucinate — only use information from the provided data\n- If journal data shows work on multiple days, show the progression\n- Highlight continuity: work that spans multiple days or builds on earlier work\n\n---\nLIVE GIT DATA:\n${liveContext}\n\n---\nJOURNAL HISTORY:\n${journalContext}\n\n---\nGenerate the weekly summary now:`;\n}\n\nfunction buildCrossProjectWeeklyPrompt(\n journalContext: string,\n fromDate: string,\n toDate: string,\n crossProjectSummary: {\n projects: {\n projectId: string;\n totalCommits: number;\n activeDays: number;\n branches: string[];\n categories: { name: string; percentage: number }[];\n diffStats: { filesChanged: number; insertions: number; deletions: number };\n }[];\n totalCommits: number;\n totalActiveDays: number;\n }\n): string {\n const projectList = crossProjectSummary.projects\n .map(\n (p) =>\n `- ${p.projectId}: ${p.totalCommits} commits across ${p.activeDays} days, branches: ${p.branches.slice(0, 5).join(', ')}`\n )\n .join('\\n');\n\n return `You are a developer assistant generating a CROSS-PROJECT weekly summary for ${fromDate} to ${toDate}.\n\nThis developer worked on ${crossProjectSummary.projects.length} project(s) this week with ${crossProjectSummary.totalCommits} total commits across ${crossProjectSummary.totalActiveDays} active days.\n\nProjects overview:\n${projectList}\n\nGenerate a summary that:\n\n## Week Overview\n- High-level: what was this week about? What were the main themes across all projects?\n- How was time split between projects?\n\n## Per-Project Highlights\n- For each project, summarize the key accomplishments (2-3 bullets each)\n- Reference specific branches, PRs, and tickets\n\n## Cross-Cutting Themes\n- Any patterns across projects (e.g., \"infrastructure week\", \"bug-fix sprint\")\n- Context switching patterns — how many projects were touched per day?\n\n## This Week in Numbers\n- Commits, PRs, files changed across all projects\n- Most active project and most active day\n\nRules:\n- Be concise — this is a high-level view, not a detailed log\n- Organize by project, then highlight cross-project themes\n- Don't hallucinate — only use information from the data\n- Reference specific branch names and commit messages when they tell a story\n- If a project had no activity, don't mention it\n\n---\nJOURNAL DATA:\n${journalContext}\n\n---\nGenerate the cross-project weekly summary now:`;\n}\n","import { Command } from 'commander';\nimport { SnapshotBuilder } from '../core/snapshot-builder.js';\nimport { WorkJournal } from '../core/work-journal.js';\nimport { GitAnalyzer } from '../core/git-analyzer.js';\nimport { CopilotClient } from '../core/copilot.js';\nimport UI from '../ui/renderer.js';\nimport { copyToClipboard } from '../utils/helpers.js';\nimport { getConfig } from '../config/index.js';\n\nconst { colors } = UI;\n\nexport const contextCommand = new Command('context')\n .description('Recover what you were working on — fight context switching amnesia')\n .option('-d, --days <number>', 'Number of days to look back', '7')\n .option('-p, --project <id>', 'Filter by project identifier')\n .option('--all-projects', 'Show context across all tracked projects')\n .option('--date <date>', 'Show context for a specific date (YYYY-MM-DD)')\n .option('--from <date>', 'Start date for range (YYYY-MM-DD)')\n .option('--to <date>', 'End date for range (YYYY-MM-DD)')\n .option('--ai', 'Generate an AI-powered \"where did I leave off?\" summary')\n .option('--branches', 'Show detailed active branch status')\n .option('--no-copy', 'Do not copy to clipboard')\n .option('--raw', 'Output raw context data (no formatting)')\n .option('--debug', 'Show debug output')\n .action(async (options) => {\n const config = getConfig();\n const git = new GitAnalyzer();\n const isDebug = options.debug || process.env.DEVD_DEBUG === '1';\n const journal = new WorkJournal();\n\n // ── Determine date range ───────────────────────────────────────────────\n let fromDate: string;\n let toDate: string;\n\n if (options.date) {\n fromDate = options.date;\n toDate = options.date;\n } else if (options.from || options.to) {\n const today = journal.todayString();\n fromDate = options.from || today;\n toDate = options.to || today;\n } else {\n const days = parseInt(options.days, 10) || 7;\n const from = new Date();\n from.setDate(from.getDate() - days);\n fromDate = journal.dateToString(from);\n toDate = journal.todayString();\n }\n\n // ── Check if we have journal data ──────────────────────────────────────\n const projectId = options.project || null;\n const snapshots = journal.getSnapshotsForRange(\n options.allProjects ? null : projectId,\n fromDate,\n toDate\n );\n\n // If no journal data, try to take a live snapshot first\n if (snapshots.length === 0 && !options.allProjects) {\n if (await git.isRepository()) {\n console.log('');\n console.log(\n UI.info('No journal entries found. Taking a live snapshot of your current project...')\n );\n console.log('');\n\n const spinner = UI.spinner('Analyzing current project state...');\n spinner.start();\n\n try {\n const builder = new SnapshotBuilder(undefined, isDebug);\n const result = await builder.takeAndSave({ debug: isDebug });\n snapshots.push(result.snapshot);\n spinner.stop();\n console.log(\n UI.success(\n `Snapshot saved for ${result.snapshot.projectId}. Future runs will have history.`\n )\n );\n console.log('');\n } catch (err) {\n spinner.stop();\n console.log(UI.warning(`Could not take snapshot: ${(err as Error).message}`));\n console.log('');\n }\n }\n }\n\n if (snapshots.length === 0) {\n console.log('');\n console.log(UI.warning('No work context found for the specified period.'));\n console.log('');\n console.log(UI.info('To start building your work journal:'));\n console.log(` ${colors.accent('devdaily snapshot')} Take a snapshot now`);\n console.log(` ${colors.accent('devdaily snapshot --list')} View your journal entries`);\n console.log(` ${colors.accent('devdaily context --days=14')} Look further back`);\n console.log('');\n return;\n }\n\n // ── Group snapshots by project ─────────────────────────────────────────\n const byProject = new Map<string, typeof snapshots>();\n for (const s of snapshots) {\n const existing = byProject.get(s.projectId);\n if (existing) {\n existing.push(s);\n } else {\n byProject.set(s.projectId, [s]);\n }\n }\n\n // ── Raw mode ───────────────────────────────────────────────────────────\n if (options.raw) {\n console.log(WorkJournal.formatSnapshotsForAI(snapshots));\n return;\n }\n\n // ── Render context recovery ────────────────────────────────────────────\n console.log('');\n\n const dateRangeLabel = fromDate === toDate ? fromDate : `${fromDate} → ${toDate}`;\n\n console.log(UI.section(`🧠 Context Recovery — ${dateRangeLabel}`));\n console.log('');\n\n for (const [pid, projectSnapshots] of byProject) {\n const sortedSnapshots = projectSnapshots.sort(\n (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()\n );\n\n const latestSnapshot = sortedSnapshots[0];\n const totalCommits = sortedSnapshots.reduce((sum, s) => sum + s.todayCommits.length, 0);\n const activeDays = sortedSnapshots.length;\n\n // ── Project header ───────────────────────────────────────────────\n console.log(` ${colors.accent('━━━')} 📂 ${colors.accent(pid)} ${colors.accent('━━━')}`);\n console.log(` ${colors.muted(latestSnapshot.repoPath)}`);\n console.log(\n ` ${activeDays} active day${activeDays !== 1 ? 's' : ''} · ${totalCommits} commit${totalCommits !== 1 ? 's' : ''}`\n );\n console.log('');\n\n // ── Current state (from most recent snapshot) ────────────────────\n console.log(` ${colors.accent('Current branch:')} ${latestSnapshot.currentBranch}`);\n\n if (latestSnapshot.activeBranches.length > 0) {\n // Find branches with work-in-progress\n const wipBranches = latestSnapshot.activeBranches.filter(\n (b) => b.aheadOfBase > 0 || b.hasUncommittedChanges\n );\n\n if (wipBranches.length > 0 || options.branches) {\n const branchesToShow = options.branches ? latestSnapshot.activeBranches : wipBranches;\n\n console.log('');\n console.log(\n ` ${colors.accent('Active branches')} ${colors.muted(`(${branchesToShow.length}):`)}`\n );\n\n for (const branch of branchesToShow.slice(0, 15)) {\n const isCurrent = branch.name === latestSnapshot.currentBranch;\n const marker = isCurrent ? colors.success(' ← you are here') : '';\n let status = '';\n\n if (branch.aheadOfBase > 0) {\n status += colors.warning(` ↑${branch.aheadOfBase} ahead`);\n }\n if (branch.hasUncommittedChanges) {\n status += colors.error(' ● uncommitted changes');\n }\n\n console.log(\n ` ${isCurrent ? colors.accent('▸') : ' '} ${branch.name}${marker}${status}`\n );\n if (branch.lastCommitMessage) {\n console.log(\n ` ${colors.muted(`Last: ${branch.lastCommitMessage.slice(0, 60)}`)}`\n );\n }\n if (branch.hasUncommittedChanges && branch.uncommittedFiles.length > 0) {\n const fileList = branch.uncommittedFiles.slice(0, 5).join(', ');\n const more =\n branch.uncommittedFiles.length > 5\n ? ` +${branch.uncommittedFiles.length - 5} more`\n : '';\n console.log(` ${colors.muted(`Modified: ${fileList}${more}`)}`);\n }\n }\n\n if (branchesToShow.length > 15) {\n console.log(\n ` ${colors.muted(`... and ${branchesToShow.length - 15} more branches`)}`\n );\n }\n }\n }\n\n // ── Recent activity timeline ─────────────────────────────────────\n console.log('');\n console.log(` ${colors.accent('Activity timeline:')}`);\n\n for (const snapshot of sortedSnapshots.slice(0, 10)) {\n const isToday = snapshot.date === journal.todayString();\n const dateLabel = isToday ? `${snapshot.date} ${colors.success('(today)')}` : snapshot.date;\n\n const commitCount = snapshot.todayCommits.length;\n const prInfo =\n snapshot.pullRequests.length > 0\n ? ` · ${snapshot.pullRequests.length} PR${snapshot.pullRequests.length !== 1 ? 's' : ''}`\n : '';\n\n const diffInfo = snapshot.diffStats\n ? ` · ${colors.success(`+${snapshot.diffStats.insertions}`)}/${colors.error(`-${snapshot.diffStats.deletions}`)}`\n : '';\n\n console.log(\n ` ${colors.accent('│')} ${dateLabel} 🌿 ${snapshot.currentBranch} 📝 ${commitCount}${prInfo}${diffInfo}`\n );\n\n // Show top commits for each day\n for (const commit of snapshot.todayCommits.slice(0, 3)) {\n console.log(\n ` ${colors.accent('│')} ${colors.muted(commit.shortHash)} ${commit.message.slice(0, 55)}`\n );\n }\n if (snapshot.todayCommits.length > 3) {\n console.log(\n ` ${colors.accent('│')} ${colors.muted(`... +${snapshot.todayCommits.length - 3} more commits`)}`\n );\n }\n\n // Show notes if present\n if (snapshot.notes) {\n console.log(\n ` ${colors.accent('│')} ${colors.warning('📌')} ${snapshot.notes.split('\\n')[0].slice(0, 55)}`\n );\n }\n }\n\n if (sortedSnapshots.length > 10) {\n console.log(\n ` ${colors.accent('│')} ${colors.muted(`... ${sortedSnapshots.length - 10} more days`)}`\n );\n }\n console.log(` ${colors.accent('╵')}`);\n\n // ── PRs ──────────────────────────────────────────────────────────\n const allPRs = new Map<number, (typeof latestSnapshot.pullRequests)[0]>();\n for (const s of sortedSnapshots) {\n for (const pr of s.pullRequests) {\n allPRs.set(pr.number, pr);\n }\n }\n\n if (allPRs.size > 0) {\n console.log('');\n console.log(` ${colors.accent('Pull Requests:')}`);\n for (const pr of allPRs.values()) {\n const stateIcon =\n pr.state === 'open'\n ? colors.success('○')\n : pr.state === 'merged'\n ? colors.accent('●')\n : colors.muted('✕');\n console.log(` ${stateIcon} #${pr.number} ${pr.title.slice(0, 55)} (${pr.state})`);\n }\n }\n\n // ── Tickets ──────────────────────────────────────────────────────\n const allTickets = new Map<string, (typeof latestSnapshot.tickets)[0]>();\n for (const s of sortedSnapshots) {\n for (const t of s.tickets) {\n allTickets.set(t.id, t);\n }\n }\n\n if (allTickets.size > 0) {\n console.log('');\n console.log(` ${colors.accent('Tickets:')}`);\n for (const ticket of allTickets.values()) {\n const titlePart = ticket.title ? `: ${ticket.title.slice(0, 50)}` : '';\n console.log(` ${ticket.id}${titlePart} ${colors.muted(`[${ticket.status}]`)}`);\n }\n }\n\n // ── Work areas ───────────────────────────────────────────────────\n const catMap = new Map<string, number[]>();\n for (const s of sortedSnapshots) {\n for (const cat of s.categories) {\n const existing = catMap.get(cat.name);\n if (existing) {\n existing.push(cat.percentage);\n } else {\n catMap.set(cat.name, [cat.percentage]);\n }\n }\n }\n\n if (catMap.size > 0) {\n console.log('');\n console.log(` ${colors.accent('Work areas:')}`);\n const categories = Array.from(catMap.entries())\n .map(([name, percentages]) => ({\n name,\n avgPercentage: Math.round(percentages.reduce((a, b) => a + b, 0) / percentages.length),\n }))\n .sort((a, b) => b.avgPercentage - a.avgPercentage)\n .slice(0, 5);\n\n for (const cat of categories) {\n const barFilled = Math.round(cat.avgPercentage / 5);\n const barEmpty = 20 - barFilled;\n const bar = '█'.repeat(barFilled) + '░'.repeat(barEmpty);\n console.log(` ${cat.name.padEnd(14)} ${bar} ${cat.avgPercentage}%`);\n }\n }\n\n console.log('');\n }\n\n // ── AI-powered summary ─────────────────────────────────────────────────\n if (options.ai) {\n const copilot = new CopilotClient({ debug: isDebug });\n\n if (!(await copilot.isInstalled())) {\n console.log(\n UI.warning(\n 'GitHub Copilot CLI not found — skipping AI summary. Install with: gh extension install github/gh-copilot'\n )\n );\n } else {\n const genSpinner = UI.spinner('Generating \"where did I leave off?\" summary with AI...');\n genSpinner.start();\n\n try {\n const contextBlock = WorkJournal.formatSnapshotsForAI(snapshots);\n\n const prompt = buildContextRecoveryPrompt(contextBlock, fromDate, toDate);\n const summary = await copilot.generateFromPrompt(prompt);\n\n genSpinner.stop();\n\n console.log(UI.box(summary, '🧠 Where You Left Off'));\n console.log('');\n\n // Copy to clipboard\n if (options.copy !== false && config.output.copyToClipboard !== false) {\n await copyToClipboard(summary);\n console.log(UI.success('Copied to clipboard'));\n console.log('');\n }\n } catch (err) {\n genSpinner.stop();\n console.log(UI.warning(`AI summary failed: ${(err as Error).message}`));\n console.log('');\n }\n }\n }\n\n // ── Helpful tips ───────────────────────────────────────────────────────\n if (!options.ai) {\n console.log(\n colors.muted(\n ` Tip: Add ${colors.accent('--ai')} for an AI-powered \"where did I leave off?\" summary`\n )\n );\n console.log(\n colors.muted(` Add ${colors.accent('--branches')} for detailed branch status`)\n );\n console.log('');\n }\n });\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction buildContextRecoveryPrompt(\n contextBlock: string,\n fromDate: string,\n toDate: string\n): string {\n return `You are a developer assistant helping me recover my work context after time away or context switching.\n\nBelow is a journal of my recent development activity from ${fromDate} to ${toDate}, including commits, branches, PRs, tickets, and file changes.\n\nYour job is to give me a concise, actionable \"where I left off\" briefing. Structure it as:\n\n1. **What I was working on** — The main themes/features/tasks (2-3 sentences max)\n2. **Current state** — What's in progress, what's done, what's pending\n3. **Open threads** — Branches with uncommitted work, open PRs needing attention, unfinished tasks\n4. **Suggested next steps** — What I should probably pick up first based on the activity pattern\n\nRules:\n- Be concise and practical — this is for getting back up to speed quickly\n- Reference specific branch names, PR numbers, and ticket IDs when available\n- Don't invent or hallucinate details that aren't in the data\n- If multiple projects are present, organize by project\n- Use bullet points for readability\n\n---\nWORK JOURNAL DATA:\n${contextBlock}\n---\n\nGenerate the context recovery briefing now:`;\n}\n","import { Command } from 'commander';\nimport { SnapshotBuilder } from '../core/snapshot-builder.js';\nimport { WorkJournal } from '../core/work-journal.js';\nimport { GitAnalyzer } from '../core/git-analyzer.js';\nimport UI from '../ui/renderer.js';\n\nconst { colors } = UI;\n\nexport const snapshotCommand = new Command('snapshot')\n .description('Save a snapshot of your current work state to your local journal')\n .option('-d, --date <date>', 'Snapshot date (YYYY-MM-DD, default: today)')\n .option('-p, --project <id>', 'Override project identifier')\n .option('-n, --note <text>', 'Attach a note to this snapshot')\n .option('-t, --tag <tags...>', 'Add custom tags to the snapshot')\n .option('--no-prs', 'Skip fetching PR data')\n .option('--no-tickets', 'Skip fetching ticket data')\n .option('--no-branches', 'Skip listing active branches')\n .option('--light', 'Quick snapshot — commits and branch info only (no PRs/tickets)')\n .option('--debug', 'Show detailed debug output')\n .option('--stats', 'Show journal storage stats instead of taking a snapshot')\n .option('--list [days]', 'List recent snapshots (default: 7 days)')\n .option('--prune <days>', 'Remove journal entries older than N days')\n .action(async (options) => {\n const git = new GitAnalyzer();\n const isDebug = options.debug || process.env.DEVD_DEBUG === '1';\n\n // ── Stats mode ─────────────────────────────────────────────────────────\n if (options.stats) {\n const journal = new WorkJournal();\n const stats = journal.getStats();\n\n console.log('');\n console.log(UI.section('📓 Journal Stats'));\n console.log('');\n console.log(` ${colors.accent('Total snapshots:')} ${stats.totalSnapshots}`);\n console.log(` ${colors.accent('Active dates:')} ${stats.totalDates}`);\n console.log(` ${colors.accent('Projects tracked:')} ${stats.totalProjects}`);\n console.log(\n ` ${colors.accent('Oldest entry:')} ${stats.oldestEntry || colors.muted('none')}`\n );\n console.log(\n ` ${colors.accent('Newest entry:')} ${stats.newestEntry || colors.muted('none')}`\n );\n console.log(` ${colors.accent('Storage used:')} ${formatBytes(stats.storageBytes)}`);\n console.log('');\n\n const projects = journal.getProjects();\n if (projects.length > 0) {\n console.log(UI.section('📂 Tracked Projects'));\n console.log('');\n for (const project of projects) {\n const lastSeen = project.lastSnapshotDate;\n const daysAgo = daysBetween(lastSeen, new Date().toISOString().split('T')[0]);\n const freshness =\n daysAgo === 0\n ? colors.success('today')\n : daysAgo <= 3\n ? colors.warning(`${daysAgo}d ago`)\n : colors.muted(`${daysAgo}d ago`);\n\n console.log(\n ` ${colors.accent(project.projectId.padEnd(30))} ${freshness} (${project.snapshotCount} snapshots)`\n );\n console.log(` ${colors.muted(project.repoPath)}`);\n }\n console.log('');\n }\n\n return;\n }\n\n // ── List mode ──────────────────────────────────────────────────────────\n if (options.list !== undefined) {\n const days = typeof options.list === 'string' ? parseInt(options.list, 10) : 7;\n const journal = new WorkJournal();\n const recent = journal.getRecentActivity(isNaN(days) ? 7 : days);\n\n if (recent.length === 0) {\n console.log('');\n console.log(UI.warning('No journal entries found'));\n console.log(UI.info('Take your first snapshot with: devdaily snapshot'));\n console.log('');\n return;\n }\n\n console.log('');\n console.log(UI.section(`📓 Recent Activity (last ${isNaN(days) ? 7 : days} days)`));\n console.log('');\n\n // Group by date\n const byDate = new Map<string, typeof recent>();\n for (const snapshot of recent) {\n const existing = byDate.get(snapshot.date);\n if (existing) {\n existing.push(snapshot);\n } else {\n byDate.set(snapshot.date, [snapshot]);\n }\n }\n\n for (const [date, snapshots] of byDate) {\n const isToday = date === journal.todayString();\n const dateLabel = isToday ? `${date} ${colors.success('(today)')}` : date;\n console.log(` ${colors.accent('━━━')} ${dateLabel} ${colors.accent('━━━')}`);\n\n for (const snapshot of snapshots) {\n const commitCount = snapshot.todayCommits.length;\n const branch = snapshot.currentBranch;\n const prCount = snapshot.pullRequests.length;\n\n let line = ` ${colors.accent(snapshot.projectId)}`;\n line += ` 🌿 ${branch}`;\n if (commitCount > 0) {\n line += ` 📝 ${commitCount} commit${commitCount !== 1 ? 's' : ''}`;\n }\n if (prCount > 0) {\n line += ` 🔄 ${prCount} PR${prCount !== 1 ? 's' : ''}`;\n }\n if (snapshot.diffStats) {\n line += ` ${colors.success(`+${snapshot.diffStats.insertions}`)}/${colors.error(`-${snapshot.diffStats.deletions}`)}`;\n }\n console.log(line);\n\n // Show top commits\n for (const commit of snapshot.todayCommits.slice(0, 3)) {\n console.log(` ${colors.muted(commit.shortHash)} ${commit.message.slice(0, 60)}`);\n }\n if (snapshot.todayCommits.length > 3) {\n console.log(\n ` ${colors.muted(`... and ${snapshot.todayCommits.length - 3} more`)}`\n );\n }\n\n if (snapshot.notes) {\n console.log(\n ` ${colors.warning('📌')} ${snapshot.notes.split('\\n')[0].slice(0, 60)}`\n );\n }\n\n if (snapshot.tags.length > 0) {\n console.log(\n ` ${colors.muted('tags:')} ${snapshot.tags.slice(0, 8).join(', ')}${snapshot.tags.length > 8 ? '...' : ''}`\n );\n }\n }\n console.log('');\n }\n\n return;\n }\n\n // ── Prune mode ─────────────────────────────────────────────────────────\n if (options.prune) {\n const maxAgeDays = parseInt(options.prune, 10);\n if (isNaN(maxAgeDays) || maxAgeDays < 1) {\n console.log(UI.error('Invalid prune age. Use a positive number of days.'));\n process.exit(1);\n }\n\n const journal = new WorkJournal();\n const { removedDates, removedSnapshots } = journal.prune(maxAgeDays);\n\n if (removedDates.length === 0) {\n console.log(UI.info(`No journal entries older than ${maxAgeDays} days.`));\n } else {\n console.log(\n UI.success(\n `Pruned ${removedSnapshots} snapshot(s) across ${removedDates.length} date(s) older than ${maxAgeDays} days.`\n )\n );\n }\n return;\n }\n\n // ── Take snapshot ──────────────────────────────────────────────────────\n if (!(await git.isRepository())) {\n console.log(UI.error('Not a git repository'));\n console.log(UI.info('Run this command inside a git repository'));\n process.exit(1);\n }\n\n const spinner = UI.spinner('Taking snapshot of your work state...');\n spinner.start();\n\n try {\n const builder = new SnapshotBuilder(undefined, isDebug);\n const isLight = options.light;\n\n const result = isLight\n ? await (async () => {\n const r = await builder.takeLightSnapshot({\n date: options.date,\n projectId: options.project,\n note: options.note,\n tags: options.tag,\n debug: isDebug,\n });\n const journal = new WorkJournal();\n journal.saveSnapshot(r.snapshot);\n return r;\n })()\n : await builder.takeAndSave({\n date: options.date,\n projectId: options.project,\n skipPRs: options.prs === false,\n skipTickets: options.tickets === false,\n includeBranches: options.branches !== false,\n note: options.note,\n tags: options.tag,\n debug: isDebug,\n });\n\n spinner.stop();\n\n const { snapshot, merged, warnings, durationMs } = result;\n\n // ── Output ─────────────────────────────────────────────────────────\n console.log('');\n\n const action = merged ? 'Updated' : 'Saved';\n const title = `📸 ${action} snapshot for ${snapshot.projectId}`;\n\n const summaryLines: string[] = [];\n summaryLines.push(`📅 Date: ${snapshot.date}`);\n summaryLines.push(`🌿 Branch: ${snapshot.currentBranch}`);\n summaryLines.push(`📝 Commits: ${snapshot.todayCommits.length} today`);\n\n if (snapshot.activeBranches.length > 0) {\n summaryLines.push(`🔀 Active branches: ${snapshot.activeBranches.length}`);\n }\n\n if (snapshot.pullRequests.length > 0) {\n summaryLines.push(\n `🔄 PRs: ${snapshot.pullRequests.map((pr) => `#${pr.number} (${pr.state})`).join(', ')}`\n );\n }\n\n if (snapshot.diffStats) {\n summaryLines.push(\n `📊 Changes: ${snapshot.diffStats.filesChanged} files, +${snapshot.diffStats.insertions}/-${snapshot.diffStats.deletions}`\n );\n }\n\n if (snapshot.tags.length > 0) {\n summaryLines.push(`🏷️ Tags: ${snapshot.tags.join(', ')}`);\n }\n\n if (snapshot.notes) {\n summaryLines.push(`📌 Note: ${snapshot.notes}`);\n }\n\n console.log(UI.box(summaryLines.join('\\n'), title));\n\n // Show top commits\n if (snapshot.todayCommits.length > 0) {\n console.log('');\n console.log(` ${colors.accent(\"Today's commits:\")}`);\n for (const commit of snapshot.todayCommits.slice(0, 8)) {\n console.log(` ${colors.muted(commit.shortHash)} ${commit.message.slice(0, 70)}`);\n }\n if (snapshot.todayCommits.length > 8) {\n console.log(` ${colors.muted(`... and ${snapshot.todayCommits.length - 8} more`)}`);\n }\n }\n\n // Show active branches (if any have WIP)\n const wipBranches = snapshot.activeBranches.filter(\n (b) => b.hasUncommittedChanges || b.aheadOfBase > 0\n );\n if (wipBranches.length > 0) {\n console.log('');\n console.log(` ${colors.accent('Active work:')}`);\n for (const branch of wipBranches.slice(0, 10)) {\n let status = '';\n if (branch.aheadOfBase > 0) {\n status += colors.warning(`↑${branch.aheadOfBase}`);\n }\n if (branch.hasUncommittedChanges) {\n status += ` ${colors.error('●')} uncommitted`;\n }\n const current = branch.name === snapshot.currentBranch ? ' ←' : '';\n console.log(\n ` ${branch.name}${colors.accent(current)} ${status} ${colors.muted(branch.lastCommitMessage.slice(0, 40))}`\n );\n }\n }\n\n // Warnings\n if (warnings.length > 0) {\n console.log('');\n for (const w of warnings) {\n console.log(UI.warning(w));\n }\n }\n\n // Stats bar\n const statItems: { label: string; value: string | number }[] = [\n { label: 'time', value: `${durationMs}ms` },\n { label: 'commits', value: snapshot.todayCommits.length },\n ];\n if (snapshot.activeBranches.length > 0) {\n statItems.push({ label: 'branches', value: snapshot.activeBranches.length });\n }\n if (isLight) {\n statItems.push({ label: 'mode', value: 'light' });\n }\n console.log('');\n console.log(UI.stats(statItems));\n\n console.log('');\n console.log(\n UI.info(\n `Snapshot saved to journal. Use ${colors.accent('devdaily snapshot --list')} to see history.`\n )\n );\n console.log('');\n } catch (error) {\n spinner.stop();\n console.log('');\n console.log(UI.error('Failed to take snapshot'));\n console.log(colors.muted((error as Error).message));\n\n if (isDebug && error instanceof Error && error.stack) {\n console.log('');\n console.log(colors.muted('Stack trace:'));\n console.log(colors.muted(error.stack));\n }\n\n process.exit(1);\n }\n });\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const units = ['B', 'KB', 'MB', 'GB'];\n const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);\n const value = bytes / Math.pow(1024, i);\n return `${value.toFixed(i === 0 ? 0 : 1)} ${units[i]}`;\n}\n\nfunction daysBetween(dateStr: string, todayStr: string): number {\n const d1 = new Date(dateStr);\n const d2 = new Date(todayStr);\n return Math.round(Math.abs(d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24));\n}\n","import { Command } from 'commander';\nimport { WorkJournal } from '../core/work-journal.js';\nimport { CopilotClient } from '../core/copilot.js';\nimport UI from '../ui/renderer.js';\nimport { copyToClipboard } from '../utils/helpers.js';\nimport { getConfig } from '../config/index.js';\n\nconst { colors } = UI;\n\nexport const recallCommand = new Command('recall')\n .description('Search your work history — \"when did I last work on X?\"')\n .argument('[query...]', 'Search query (e.g., \"auth\", \"login page\", \"PROJ-123\")')\n .option('-p, --project <id>', 'Filter by project identifier')\n .option('--from <date>', 'Start date for search range (YYYY-MM-DD)')\n .option('--to <date>', 'End date for search range (YYYY-MM-DD)')\n .option('-d, --days <number>', 'Search last N days (default: 90)', '90')\n .option('-t, --tag <tags...>', 'Filter by tags')\n .option('-f, --file <path>', 'Search for a specific file path')\n .option('-l, --limit <number>', 'Max results to show (default: 10)', '10')\n .option('--ai', 'Generate an AI-powered summary of the search results')\n .option('--no-copy', 'Do not copy to clipboard')\n .option('--json', 'Output results as JSON')\n .option('--debug', 'Show debug output')\n .action(async (queryParts, options) => {\n const config = getConfig();\n const journal = new WorkJournal();\n const isDebug = options.debug || process.env.DEVD_DEBUG === '1';\n\n const query = queryParts.join(' ').trim();\n\n // ── Validate input ───────────────────────────────────────────────────\n if (!query && !options.tag && !options.file) {\n console.log('');\n console.log(UI.section('🔍 Recall — Search Your Work History'));\n console.log('');\n console.log(' Search across all your journal snapshots to find when you');\n console.log(' last worked on something, touched a file, or used a branch.');\n console.log('');\n console.log(` ${colors.accent('Usage:')}`);\n console.log(` devdaily recall <query> Search by keyword`);\n console.log(` devdaily recall \"auth feature\" Search for a phrase`);\n console.log(` devdaily recall PROJ-123 Search for a ticket`);\n console.log(` devdaily recall --file src/auth.ts Search for a file`);\n console.log(` devdaily recall --tag bugfix Search by tag`);\n console.log(` devdaily recall login --ai Get AI summary of results`);\n console.log('');\n console.log(` ${colors.accent('Options:')}`);\n console.log(` --from / --to Date range (YYYY-MM-DD)`);\n console.log(` --days <N> Search last N days (default: 90)`);\n console.log(` --project <id> Filter by project`);\n console.log(` --limit <N> Max results (default: 10)`);\n console.log('');\n\n // Show quick stats\n const stats = journal.getStats();\n if (stats.totalSnapshots > 0) {\n console.log(\n ` ${colors.muted('Your journal:')} ${stats.totalSnapshots} snapshots across ${stats.totalProjects} project(s), ${stats.totalDates} day(s)`\n );\n if (stats.oldestEntry && stats.newestEntry) {\n console.log(` ${colors.muted('Range:')} ${stats.oldestEntry} → ${stats.newestEntry}`);\n }\n } else {\n console.log(\n ` ${colors.muted('Your journal is empty. Run')} ${colors.accent('devdaily snapshot')} ${colors.muted('to start tracking.')}`\n );\n }\n console.log('');\n return;\n }\n\n // ── File search mode ───────────────────────────────────────────────────\n if (options.file) {\n const fileResults = journal.findFileHistory(\n options.file,\n options.project,\n parseInt(options.days, 10) || 90\n );\n\n if (fileResults.length === 0) {\n console.log('');\n console.log(UI.warning(`No history found for file: ${options.file}`));\n console.log(UI.info('Try broadening your search with a partial path or more --days'));\n console.log('');\n return;\n }\n\n console.log('');\n console.log(UI.section(`📄 File History: ${options.file}`));\n console.log('');\n\n const limit = parseInt(options.limit, 10) || 10;\n const toShow = fileResults.slice(-limit).reverse(); // Most recent first\n\n for (const entry of toShow) {\n const isToday = entry.date === journal.todayString();\n const dateLabel = isToday ? `${entry.date} ${colors.success('(today)')}` : entry.date;\n\n console.log(` ${colors.accent('│')} ${dateLabel}`);\n for (const commit of entry.commits.slice(0, 5)) {\n const files = commit.filesChanged\n ? commit.filesChanged.filter((f) =>\n f.toLowerCase().includes(options.file.toLowerCase())\n )\n : [];\n const fileNote = files.length > 0 ? colors.muted(` [${files.join(', ')}]`) : '';\n console.log(\n ` ${colors.accent('│')} ${colors.muted(commit.shortHash)} ${commit.message.slice(0, 55)}${fileNote}`\n );\n }\n if (entry.commits.length > 5) {\n console.log(\n ` ${colors.accent('│')} ${colors.muted(`... +${entry.commits.length - 5} more commits`)}`\n );\n }\n }\n console.log(` ${colors.accent('╵')}`);\n\n if (fileResults.length > limit) {\n console.log('');\n console.log(\n colors.muted(` Showing ${limit} of ${fileResults.length} days. Use --limit to see more.`)\n );\n }\n\n console.log('');\n return;\n }\n\n // ── Text / tag search mode ─────────────────────────────────────────────\n const spinner = UI.spinner(`Searching journal for \"${query || options.tag?.join(', ')}\"...`);\n spinner.start();\n\n // Determine date range\n let fromDate: string | undefined;\n let toDate: string | undefined;\n\n if (options.from || options.to) {\n fromDate = options.from;\n toDate = options.to;\n } else {\n const days = parseInt(options.days, 10) || 90;\n const from = new Date();\n from.setDate(from.getDate() - days);\n fromDate = journal.dateToString(from);\n toDate = journal.todayString();\n }\n\n const limit = parseInt(options.limit, 10) || 10;\n\n const results = journal.search({\n projectId: options.project,\n from: fromDate,\n to: toDate,\n query: query || undefined,\n tags: options.tag,\n limit,\n });\n\n spinner.stop();\n\n // ── JSON output ────────────────────────────────────────────────────────\n if (options.json) {\n const jsonOutput = results.map((r) => ({\n date: r.snapshot.date,\n projectId: r.snapshot.projectId,\n branch: r.snapshot.currentBranch,\n score: r.score,\n matchReasons: r.matchReasons,\n commits: r.snapshot.todayCommits.length,\n prs: r.snapshot.pullRequests.length,\n tags: r.snapshot.tags,\n notes: r.snapshot.notes || null,\n }));\n console.log(JSON.stringify(jsonOutput, null, 2));\n return;\n }\n\n // ── No results ─────────────────────────────────────────────────────────\n if (results.length === 0) {\n console.log('');\n const searchTerm = query || (options.tag ? `tags: ${options.tag.join(', ')}` : 'unknown');\n console.log(UI.warning(`No matches found for \"${searchTerm}\"`));\n console.log('');\n console.log(UI.info('Tips:'));\n console.log(` • Try a broader search term`);\n console.log(` • Increase the lookback window with ${colors.accent('--days 180')}`);\n console.log(` • Search across all projects with no ${colors.accent('--project')} filter`);\n console.log(\n ` • Make sure you've been taking snapshots (${colors.accent('devdaily snapshot')})`\n );\n console.log('');\n return;\n }\n\n // ── Render results ─────────────────────────────────────────────────────\n console.log('');\n\n const searchLabel = query\n ? `\"${query}\"`\n : options.tag\n ? `tags: ${options.tag.join(', ')}`\n : 'all';\n console.log(UI.section(`🔍 Recall — ${results.length} result(s) for ${searchLabel}`));\n console.log('');\n\n for (let i = 0; i < results.length; i++) {\n const { snapshot, matchReasons, score } = results[i];\n const isToday = snapshot.date === journal.todayString();\n const dateLabel = isToday ? `${snapshot.date} ${colors.success('(today)')}` : snapshot.date;\n\n // Result header\n const scoreBar = '●'.repeat(Math.min(score, 10)) + '○'.repeat(Math.max(0, 10 - score));\n console.log(\n ` ${colors.accent(`${i + 1}.`)} ${dateLabel} 📂 ${colors.accent(snapshot.projectId)} 🌿 ${snapshot.currentBranch} ${colors.muted(scoreBar)}`\n );\n\n // Match reasons\n if (matchReasons.length > 0) {\n const reasonsStr = matchReasons.slice(0, 5).join(', ');\n const more = matchReasons.length > 5 ? ` +${matchReasons.length - 5} more` : '';\n console.log(` ${colors.muted(`Matched: ${reasonsStr}${more}`)}`);\n }\n\n // Commits\n if (snapshot.todayCommits.length > 0) {\n const relevantCommits = query\n ? snapshot.todayCommits.filter(\n (c) =>\n c.message.toLowerCase().includes(query.toLowerCase()) ||\n c.filesChanged?.some((f) => f.toLowerCase().includes(query.toLowerCase()))\n )\n : [];\n\n const commitsToShow =\n relevantCommits.length > 0\n ? relevantCommits.slice(0, 3)\n : snapshot.todayCommits.slice(0, 2);\n\n for (const commit of commitsToShow) {\n // Highlight matching text in commit message\n const msg = query\n ? highlightMatch(commit.message.slice(0, 60), query)\n : commit.message.slice(0, 60);\n console.log(` ${colors.muted(commit.shortHash)} ${msg}`);\n }\n\n const remaining = snapshot.todayCommits.length - commitsToShow.length;\n if (remaining > 0) {\n console.log(` ${colors.muted(`... +${remaining} more commit(s)`)}`);\n }\n }\n\n // PRs (if relevant)\n if (snapshot.pullRequests.length > 0) {\n const relevantPRs = query\n ? snapshot.pullRequests.filter((pr) =>\n pr.title.toLowerCase().includes(query.toLowerCase())\n )\n : snapshot.pullRequests;\n\n if (relevantPRs.length > 0) {\n for (const pr of relevantPRs.slice(0, 2)) {\n const stateIcon =\n pr.state === 'open'\n ? colors.success('○')\n : pr.state === 'merged'\n ? colors.accent('●')\n : colors.muted('✕');\n const title = query\n ? highlightMatch(pr.title.slice(0, 50), query)\n : pr.title.slice(0, 50);\n console.log(` ${stateIcon} PR #${pr.number} ${title}`);\n }\n }\n }\n\n // Notes\n if (snapshot.notes) {\n const notePreview = snapshot.notes.split('\\n')[0].slice(0, 55);\n const highlighted = query ? highlightMatch(notePreview, query) : notePreview;\n console.log(` ${colors.warning('📌')} ${highlighted}`);\n }\n\n // Diff stats\n if (snapshot.diffStats && snapshot.diffStats.insertions + snapshot.diffStats.deletions > 0) {\n console.log(\n ` ${colors.muted(`${snapshot.diffStats.filesChanged} files`)} ${colors.success(`+${snapshot.diffStats.insertions}`)}/${colors.error(`-${snapshot.diffStats.deletions}`)}`\n );\n }\n\n // Tags\n if (snapshot.tags.length > 0) {\n const relevantTags = query\n ? snapshot.tags.filter((t) => t.toLowerCase().includes(query.toLowerCase()))\n : [];\n\n if (relevantTags.length > 0) {\n console.log(` ${colors.muted('tags:')} ${relevantTags.join(', ')}`);\n }\n }\n\n console.log('');\n }\n\n // ── Search metadata ────────────────────────────────────────────────────\n const stats = journal.getStats();\n console.log(\n colors.muted(\n ` Searched ${stats.totalSnapshots} snapshots across ${stats.totalProjects} project(s) from ${fromDate} to ${toDate}`\n )\n );\n console.log('');\n\n // ── AI summary of search results ───────────────────────────────────────\n if (options.ai) {\n const copilot = new CopilotClient({ debug: isDebug });\n\n if (!(await copilot.isInstalled())) {\n console.log(\n UI.warning(\n 'GitHub Copilot CLI not found — skipping AI summary. Install with: gh extension install github/gh-copilot'\n )\n );\n } else {\n const genSpinner = UI.spinner('Generating AI summary of search results...');\n genSpinner.start();\n\n try {\n const snapshotsForAI = results.map((r) => r.snapshot);\n const contextBlock = WorkJournal.formatSnapshotsForAI(snapshotsForAI);\n\n const prompt = buildRecallSummaryPrompt(query, contextBlock, fromDate!, toDate!);\n const summary = await copilot.generateFromPrompt(prompt);\n\n genSpinner.stop();\n\n console.log(UI.box(summary, `🔍 AI Summary: \"${query}\"`));\n console.log('');\n\n // Copy to clipboard\n if (options.copy !== false && config.output.copyToClipboard !== false) {\n await copyToClipboard(summary);\n console.log(UI.success('Copied to clipboard'));\n console.log('');\n }\n } catch (err) {\n genSpinner.stop();\n console.log(UI.warning(`AI summary failed: ${(err as Error).message}`));\n console.log('');\n }\n }\n } else if (results.length > 0) {\n console.log(\n colors.muted(\n ` Tip: Add ${colors.accent('--ai')} for an AI-powered summary of these results`\n )\n );\n console.log('');\n }\n });\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/**\n * Highlight matching substring in text using accent color.\n */\nfunction highlightMatch(text: string, query: string): string {\n if (!query) return text;\n\n const lowerText = text.toLowerCase();\n const lowerQuery = query.toLowerCase();\n const index = lowerText.indexOf(lowerQuery);\n\n if (index === -1) return text;\n\n const before = text.slice(0, index);\n const match = text.slice(index, index + query.length);\n const after = text.slice(index + query.length);\n\n return `${before}${colors.accent(match)}${after}`;\n}\n\n/**\n * Build an AI prompt for summarizing recall search results.\n */\nfunction buildRecallSummaryPrompt(\n query: string,\n contextBlock: string,\n fromDate: string,\n toDate: string\n): string {\n return `You are a developer assistant helping me recall past work.\n\nI searched my work journal for \"${query}\" and found the matching entries below (from ${fromDate} to ${toDate}).\n\nYour job is to give me a concise summary that answers: \"What did I do related to '${query}'?\"\n\nStructure your response as:\n1. **Summary** — What the work related to \"${query}\" was about (2-3 sentences)\n2. **Timeline** — When the key activities happened (brief chronological list)\n3. **Key details** — Specific branches, PRs, files, or tickets that are most relevant\n4. **Current state** — Is this work done, still in progress, or abandoned?\n\nRules:\n- Be concise and factual — only use information from the data\n- Reference specific commit hashes, branch names, PR numbers when helpful\n- If the query matches across multiple projects, organize by project\n- Don't hallucinate or invent details\n\n---\nMATCHING JOURNAL ENTRIES:\n${contextBlock}\n---\n\nGenerate the recall summary now:`;\n}\n","import { Command } from 'commander';\nimport { existsSync, readFileSync, appendFileSync, writeFileSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport inquirer from 'inquirer';\nimport UI from '../ui/renderer.js';\nimport { ASCII } from '../ui/ascii.js';\nimport { ConfigManager, type Secrets } from '../config/index.js';\nimport { GitAnalyzer } from '../core/git-analyzer.js';\nimport { generateSamplePRPrompt, findPRPromptFile } from '../core/pr-prompt.js';\nimport { installGitHooks, removeGitHooks } from '../core/auto-snapshot.js';\n\nconst { colors } = UI;\n\n// Shell config file paths\nconst SHELL_CONFIGS = {\n zsh: join(homedir(), '.zshrc'),\n bash: join(homedir(), '.bashrc'),\n fish: join(homedir(), '.config', 'fish', 'config.fish'),\n};\n\n// Alias to add\nconst ALIAS_LINE = {\n zsh: `\\n# DevDaily AI alias\\nalias dd='devdaily'\\n`,\n bash: `\\n# DevDaily AI alias\\nalias dd='devdaily'\\n`,\n fish: `\\n# DevDaily AI alias\\nalias dd 'devdaily'\\n`,\n};\n\n// Shell completions\nconst COMPLETIONS = {\n zsh: `\n# DevDaily AI completions\n_devdaily() {\n local commands=\"standup pr week dash config init help\"\n local standup_opts=\"--days --format --no-copy\"\n local pr_opts=\"--base --create --draft --no-copy\"\n local week_opts=\"--last --start --no-copy\"\n\n _arguments \\\\\n '1:command:($commands)' \\\\\n '*::arg:->args'\n\n case $words[1] in\n standup|s|su)\n _arguments $standup_opts\n ;;\n pr|p)\n _arguments $pr_opts\n ;;\n week|w)\n _arguments $week_opts\n ;;\n esac\n}\ncompdef _devdaily devdaily\ncompdef _devdaily dd\n`,\n bash: `\n# DevDaily AI completions\n_devdaily_completions() {\n local cur=\"\\${COMP_WORDS[COMP_CWORD]}\"\n local commands=\"standup pr week dash config init help\"\n\n if [ \\${COMP_CWORD} -eq 1 ]; then\n COMPREPLY=( $(compgen -W \"\\${commands}\" -- \\${cur}) )\n fi\n}\ncomplete -F _devdaily_completions devdaily\ncomplete -F _devdaily_completions dd\n`,\n fish: `\n# DevDaily AI completions\ncomplete -c devdaily -n __fish_use_subcommand -a standup -d 'Generate standup notes'\ncomplete -c devdaily -n __fish_use_subcommand -a pr -d 'Generate PR description'\ncomplete -c devdaily -n __fish_use_subcommand -a week -d 'Generate weekly summary'\ncomplete -c devdaily -n __fish_use_subcommand -a dash -d 'Open dashboard'\ncomplete -c devdaily -n __fish_use_subcommand -a config -d 'Manage configuration'\ncomplete -c devdaily -n __fish_use_subcommand -a init -d 'Initialize DevDaily'\ncomplete -c dd -w devdaily\n`,\n};\n\n/**\n * Detect current shell\n */\nconst detectShell = (): 'zsh' | 'bash' | 'fish' => {\n const shell = process.env.SHELL || '';\n\n if (shell.includes('zsh')) return 'zsh';\n if (shell.includes('fish')) return 'fish';\n return 'bash';\n};\n\n/**\n * Check if alias already exists\n */\nconst hasAlias = (shell: 'zsh' | 'bash' | 'fish'): boolean => {\n const configPath = SHELL_CONFIGS[shell];\n\n if (!existsSync(configPath)) return false;\n\n const content = readFileSync(configPath, 'utf-8');\n return content.includes(\"alias dd='devdaily'\") || content.includes(\"alias dd 'devdaily'\");\n};\n\n/**\n * Add alias to shell config\n */\nconst addAlias = (shell: 'zsh' | 'bash' | 'fish'): void => {\n const configPath = SHELL_CONFIGS[shell];\n const aliasLine = ALIAS_LINE[shell];\n\n appendFileSync(configPath, aliasLine);\n};\n\n/**\n * Add completions to shell config\n */\nconst addCompletions = (shell: 'zsh' | 'bash' | 'fish'): void => {\n const configPath = SHELL_CONFIGS[shell];\n const completions = COMPLETIONS[shell];\n\n appendFileSync(configPath, completions);\n};\n\n/**\n * Check if completions already exist\n */\nconst hasCompletions = (shell: 'zsh' | 'bash' | 'fish'): boolean => {\n const configPath = SHELL_CONFIGS[shell];\n\n if (!existsSync(configPath)) return false;\n\n const content = readFileSync(configPath, 'utf-8');\n return content.includes('DevDaily AI completions');\n};\n\nexport const initCommand = new Command('init')\n .description('Set up DevDaily (aliases, shell completions, config)')\n .option('-g, --global', 'Set up globally for all projects')\n .option('--alias', 'Only set up shell alias (dd)')\n .option('--completions', 'Only set up shell completions')\n .option('--config', 'Only create config file')\n .option('--pm', 'Only set up project management integration')\n .option('--notifications', 'Only set up Slack/Discord notifications')\n .option('--git-hooks', 'Install git hooks for automatic snapshots (post-commit, post-checkout)')\n .option('--remove-hooks', 'Remove previously installed devdaily git hooks')\n .action(async (options) => {\n console.log('');\n console.log(UI.header('DevDaily Setup'));\n console.log('');\n\n const shell = detectShell();\n console.log(UI.info(`Detected shell: ${shell}`));\n console.log('');\n\n const tasks: Array<{ name: string; done: boolean; skipped: boolean }> = [];\n\n // Auto-detect default branch\n let detectedDefaultBranch = 'main';\n const git = new GitAnalyzer();\n const isRepo = await git.isRepository();\n\n if (isRepo) {\n const branchSpinner = UI.spinner('Detecting default branch...');\n branchSpinner.start();\n try {\n detectedDefaultBranch = await git.getDefaultBranch();\n branchSpinner.stop();\n console.log(UI.info(`Detected default branch: ${colors.accent(detectedDefaultBranch)}`));\n } catch {\n branchSpinner.stop();\n console.log(colors.muted(' Could not auto-detect default branch, using \"main\"'));\n }\n }\n\n // Check for existing PR prompt file\n let hasPRPrompt = false;\n if (isRepo) {\n try {\n const repoRoot = await git.getRepoRoot();\n hasPRPrompt = (await findPRPromptFile(repoRoot)) !== null;\n } catch {\n // ignore\n }\n }\n\n console.log('');\n\n // Interactive setup if no specific options\n // Handle --remove-hooks early\n if (options.removeHooks) {\n console.log(colors.bold('📸 Removing DevDaily Git Hooks'));\n console.log('');\n const removeResult = await removeGitHooks();\n if (removeResult.removed.length > 0) {\n for (const name of removeResult.removed) {\n console.log(UI.success(`Removed: ${name}`));\n }\n } else {\n console.log(UI.info('No devdaily git hooks found to remove.'));\n }\n for (const w of removeResult.warnings) {\n console.log(UI.warning(w));\n }\n console.log('');\n return;\n }\n\n const hasSpecificOption =\n options.alias ||\n options.completions ||\n options.config ||\n options.pm ||\n options.notifications ||\n options.gitHooks ||\n options.git_hooks;\n\n if (!hasSpecificOption) {\n const { features } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'features',\n message: 'What would you like to set up?',\n choices: [\n {\n name: `Shell alias (${colors.accent('dd')} → ${colors.primary('devdaily')})`,\n value: 'alias',\n checked: !hasAlias(shell),\n },\n {\n name: 'Shell completions (tab completion)',\n value: 'completions',\n checked: !hasCompletions(shell),\n },\n {\n name: `Create ${options.global ? 'global' : 'project'} config file`,\n value: 'config',\n checked: true,\n },\n {\n name: `${colors.accent('🎫')} Project management integration (Jira/Linear/Notion)`,\n value: 'pm',\n checked: true,\n },\n {\n name: `${colors.accent('🔀')} Default branch & PR settings`,\n value: 'branch',\n checked: true,\n },\n {\n name: `${colors.accent('📝')} PR description prompt file (.devdaily-pr-prompt.md)`,\n value: 'pr_prompt',\n checked: !hasPRPrompt,\n },\n {\n name: `${colors.accent('🔔')} Notifications (Slack/Discord webhooks)`,\n value: 'notifications',\n checked: false,\n },\n {\n name: `${colors.accent('📸')} Git hooks for automatic snapshots (post-commit, post-checkout)`,\n value: 'git_hooks',\n checked: false,\n },\n ],\n },\n ]);\n\n options.alias = features.includes('alias');\n options.completions = features.includes('completions');\n options.config = features.includes('config');\n options.pm = features.includes('pm');\n options.branch = features.includes('branch');\n options.pr_prompt = features.includes('pr_prompt');\n options.notifications = features.includes('notifications');\n options.git_hooks = options.gitHooks || features.includes('git_hooks');\n }\n\n console.log('');\n\n // Set up alias\n if (options.alias) {\n if (hasAlias(shell)) {\n console.log(colors.muted(`${ASCII.status.check} Shell alias already exists`));\n tasks.push({ name: 'Shell alias', done: false, skipped: true });\n } else {\n try {\n addAlias(shell);\n console.log(UI.success(`Added shell alias: ${colors.accent('dd')} → devdaily`));\n tasks.push({ name: 'Shell alias', done: true, skipped: false });\n } catch {\n console.log(UI.error('Failed to add shell alias'));\n tasks.push({ name: 'Shell alias', done: false, skipped: false });\n }\n }\n }\n\n // Set up completions\n if (options.completions) {\n if (hasCompletions(shell)) {\n console.log(colors.muted(`${ASCII.status.check} Shell completions already exist`));\n tasks.push({ name: 'Completions', done: false, skipped: true });\n } else {\n try {\n addCompletions(shell);\n console.log(UI.success('Added shell completions'));\n tasks.push({ name: 'Completions', done: true, skipped: false });\n } catch {\n console.log(UI.error('Failed to add completions'));\n tasks.push({ name: 'Completions', done: false, skipped: false });\n }\n }\n }\n\n // Set up project management\n if (options.pm) {\n console.log('');\n console.log(UI.divider());\n console.log('');\n console.log(colors.bold('🎫 Project Management Setup'));\n console.log(colors.muted(' Link your ticket system for richer AI context'));\n console.log('');\n\n const { pmTool } = await inquirer.prompt([\n {\n type: 'list',\n name: 'pmTool',\n message: 'Which project management tool do you use?',\n choices: [\n { name: '🐙 GitHub Issues (default, uses gh CLI)', value: 'github' },\n { name: '🔷 Jira', value: 'jira' },\n { name: '📐 Linear', value: 'linear' },\n { name: '📝 Notion', value: 'notion' },\n { name: '⏭️ Skip for now', value: 'none' },\n ],\n },\n ]);\n\n const configManager = ConfigManager.getInstance();\n const secrets: Secrets = {};\n let ticketPrefix = '';\n\n if (pmTool !== 'none' && pmTool !== 'github') {\n // Ask for ticket prefix\n const { prefix } = await inquirer.prompt([\n {\n type: 'input',\n name: 'prefix',\n message: 'Ticket prefix (e.g., PROJ, ENG, DEV):',\n default: '',\n validate: (input: string) => {\n if (!input) return true; // Optional\n if (/^[A-Z][A-Z0-9]*$/i.test(input)) return true;\n return 'Prefix should be letters/numbers (e.g., PROJ, ENG-1)';\n },\n },\n ]);\n ticketPrefix = prefix.toUpperCase();\n }\n\n // Tool-specific setup\n if (pmTool === 'jira') {\n console.log('');\n console.log(\n colors.muted(' Jira API credentials will be stored in .devdaily.secrets.json')\n );\n console.log(colors.muted(' This file will be added to .gitignore'));\n console.log('');\n\n const jiraAnswers = await inquirer.prompt([\n {\n type: 'input',\n name: 'baseUrl',\n message: 'Jira base URL:',\n default: 'https://yourcompany.atlassian.net',\n validate: (input: string) => input.startsWith('http') || 'Must be a valid URL',\n },\n {\n type: 'input',\n name: 'email',\n message: 'Your Jira email:',\n },\n {\n type: 'password',\n name: 'apiToken',\n message: 'Jira API token:',\n mask: '*',\n },\n ]);\n\n secrets.jira = {\n baseUrl: jiraAnswers.baseUrl,\n email: jiraAnswers.email,\n apiToken: jiraAnswers.apiToken,\n };\n } else if (pmTool === 'linear') {\n console.log('');\n console.log(colors.muted(' Get your API key from Linear Settings → API'));\n console.log('');\n\n const linearAnswers = await inquirer.prompt([\n {\n type: 'password',\n name: 'apiKey',\n message: 'Linear API key:',\n mask: '*',\n },\n ]);\n\n secrets.linear = {\n apiKey: linearAnswers.apiKey,\n };\n } else if (pmTool === 'notion') {\n console.log('');\n console.log(colors.muted(' Create an integration at notion.so/my-integrations'));\n console.log('');\n\n const notionAnswers = await inquirer.prompt([\n {\n type: 'password',\n name: 'apiKey',\n message: 'Notion API key:',\n mask: '*',\n },\n {\n type: 'input',\n name: 'databaseId',\n message: 'Notion database ID (for tasks):',\n },\n ]);\n\n secrets.notion = {\n apiKey: notionAnswers.apiKey,\n databaseId: notionAnswers.databaseId,\n };\n }\n\n // Save PM config\n if (pmTool !== 'none') {\n // Use type assertion since we're doing a partial update\n const pmConfig = {\n projectManagement: {\n tool: pmTool,\n ticketPrefix: ticketPrefix || undefined,\n jira: {},\n linear: {},\n notion: {},\n },\n } as Parameters<typeof configManager.update>[0];\n\n if (options.global) {\n configManager.update(pmConfig);\n configManager.saveGlobal();\n } else {\n configManager.saveLocal(pmConfig as Parameters<typeof configManager.saveLocal>[0]);\n }\n\n // Save secrets if any\n if (Object.keys(secrets).length > 0) {\n configManager.saveSecrets(secrets, options.global);\n\n // Add to gitignore\n if (!options.global) {\n const added = configManager.addSecretsToGitignore();\n if (added) {\n console.log(UI.success('Added .devdaily.secrets.json to .gitignore'));\n }\n }\n }\n\n console.log(UI.success(`Configured ${pmTool} integration`));\n tasks.push({ name: 'PM integration', done: true, skipped: false });\n } else {\n tasks.push({ name: 'PM integration', done: false, skipped: true });\n }\n }\n\n // Set up notifications\n if (options.notifications) {\n console.log('');\n console.log(UI.divider());\n console.log('');\n console.log(colors.bold('🔔 Notification Setup'));\n console.log(colors.muted(' Send standups to Slack or Discord automatically'));\n console.log('');\n\n const { notificationChannels } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'notificationChannels',\n message: 'Which notification channels do you want to set up?',\n choices: [\n { name: '💬 Slack (webhook)', value: 'slack' },\n { name: '🎮 Discord (webhook)', value: 'discord' },\n ],\n },\n ]);\n\n const configManager = ConfigManager.getInstance();\n const secrets: Secrets = {};\n const notificationConfig: {\n slack?: { enabled: boolean };\n discord?: { enabled: boolean };\n } = {};\n\n if (notificationChannels.includes('slack')) {\n console.log('');\n console.log(colors.muted(' Create a Slack webhook at: api.slack.com/apps'));\n console.log(colors.muted(' → Create App → Incoming Webhooks → Add New Webhook'));\n console.log('');\n\n const slackAnswers = await inquirer.prompt([\n {\n type: 'password',\n name: 'webhookUrl',\n message: 'Slack webhook URL:',\n mask: '*',\n validate: (input: string) =>\n input.startsWith('https://hooks.slack.com/') || 'Must be a valid Slack webhook URL',\n },\n ]);\n\n secrets.slack = {\n webhookUrl: slackAnswers.webhookUrl,\n };\n\n notificationConfig.slack = {\n enabled: true,\n };\n\n console.log(UI.success('Slack configured!'));\n }\n\n if (notificationChannels.includes('discord')) {\n console.log('');\n console.log(colors.muted(' Create a Discord webhook:'));\n console.log(colors.muted(' → Server Settings → Integrations → Webhooks → New Webhook'));\n console.log('');\n\n const discordAnswers = await inquirer.prompt([\n {\n type: 'password',\n name: 'webhookUrl',\n message: 'Discord webhook URL:',\n mask: '*',\n validate: (input: string) =>\n input.startsWith('https://discord.com/api/webhooks/') ||\n 'Must be a valid Discord webhook URL',\n },\n ]);\n\n secrets.discord = {\n webhookUrl: discordAnswers.webhookUrl,\n };\n\n notificationConfig.discord = {\n enabled: true,\n };\n\n console.log(UI.success('Discord configured!'));\n }\n\n if (notificationChannels.length > 0) {\n // Save notification config - use type assertion for partial update\n const config = {\n notifications: {\n slack: { enabled: false, ...notificationConfig.slack },\n discord: { enabled: false, ...notificationConfig.discord },\n standupTimezone: 'America/New_York',\n },\n } as Parameters<typeof configManager.update>[0];\n\n if (options.global) {\n configManager.update(config);\n configManager.saveGlobal();\n } else {\n configManager.saveLocal(config as Parameters<typeof configManager.saveLocal>[0]);\n }\n\n // Save secrets\n if (Object.keys(secrets).length > 0) {\n configManager.saveSecrets(secrets, options.global);\n\n if (!options.global) {\n const added = configManager.addSecretsToGitignore();\n if (added) {\n console.log(UI.success('Added .devdaily.secrets.json to .gitignore'));\n }\n }\n }\n\n console.log('');\n console.log(colors.muted(' Usage:'));\n console.log(\n ` ${colors.primary('devdaily standup --send')} ${colors.muted('# Send to all channels')}`\n );\n console.log(\n ` ${colors.primary('devdaily standup --slack')} ${colors.muted('# Send to Slack only')}`\n );\n console.log(\n ` ${colors.primary('devdaily standup --discord')} ${colors.muted('# Send to Discord only')}`\n );\n\n tasks.push({ name: 'Notifications', done: true, skipped: false });\n } else {\n tasks.push({ name: 'Notifications', done: false, skipped: true });\n }\n }\n\n // Default branch & PR settings\n if (options.branch) {\n console.log('');\n console.log(UI.divider());\n console.log('');\n console.log(colors.bold('🔀 Default Branch & PR Settings'));\n console.log(colors.muted(' Configure the base branch for PRs and git comparisons'));\n console.log('');\n\n const branchAnswers = await inquirer.prompt([\n {\n type: 'input',\n name: 'defaultBranch',\n message: 'Default base branch (for PRs, diffs, standups):',\n default: detectedDefaultBranch,\n },\n {\n type: 'confirm',\n name: 'includeDiff',\n message: 'Include code diff in AI prompt for richer PR descriptions?',\n default: true,\n },\n {\n type: 'number',\n name: 'maxDiffLines',\n message: 'Max diff lines to send to AI (to avoid token limits):',\n default: 200,\n when: (answers: Record<string, unknown>) => Boolean(answers.includeDiff),\n },\n ]);\n\n const configManager = ConfigManager.getInstance();\n const prConfig = {\n pr: {\n defaultBase: branchAnswers.defaultBranch,\n includeDiff: branchAnswers.includeDiff,\n maxDiffLines: branchAnswers.maxDiffLines || 200,\n },\n git: {\n defaultBranch: branchAnswers.defaultBranch,\n },\n } as Parameters<typeof configManager.update>[0];\n\n if (options.global) {\n configManager.update(prConfig);\n configManager.saveGlobal();\n } else {\n configManager.saveLocal(prConfig as Parameters<typeof configManager.saveLocal>[0]);\n }\n\n console.log(\n UI.success(`Default branch set to ${colors.accent(branchAnswers.defaultBranch)}`)\n );\n tasks.push({ name: 'Branch & PR settings', done: true, skipped: false });\n }\n\n // PR description prompt file\n if (options.pr_prompt) {\n console.log('');\n console.log(UI.divider());\n console.log('');\n console.log(colors.bold('📝 PR Description Prompt'));\n console.log(\n colors.muted(\n ' Create a .devdaily-pr-prompt.md file to customize how AI generates PR descriptions'\n )\n );\n console.log(\n colors.muted(' Think of it like CLAUDE.md — but specifically for PR descriptions')\n );\n console.log('');\n\n if (hasPRPrompt) {\n console.log(colors.muted(` ${ASCII.status.check} PR prompt file already exists`));\n tasks.push({ name: 'PR prompt file', done: false, skipped: true });\n } else {\n const { createPrompt } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'createPrompt',\n message: 'Create a .devdaily-pr-prompt.md with sample guidelines you can customize?',\n default: true,\n },\n ]);\n\n if (createPrompt) {\n try {\n const repoRoot = isRepo ? await git.getRepoRoot() : process.cwd();\n const promptPath = join(repoRoot, '.devdaily-pr-prompt.md');\n writeFileSync(promptPath, generateSamplePRPrompt());\n console.log(\n UI.success(\n `Created ${colors.accent('.devdaily-pr-prompt.md')} — customize it for your team!`\n )\n );\n tasks.push({ name: 'PR prompt file', done: true, skipped: false });\n } catch {\n console.log(UI.error('Failed to create PR prompt file'));\n tasks.push({ name: 'PR prompt file', done: false, skipped: false });\n }\n } else {\n tasks.push({ name: 'PR prompt file', done: false, skipped: true });\n }\n }\n }\n\n // Create config (if not already done by PM setup)\n if (options.config && !options.pm) {\n try {\n const configManager = ConfigManager.getInstance();\n\n if (options.global) {\n configManager.saveGlobal();\n console.log(UI.success(`Created global config: ${ConfigManager.getGlobalConfigPath()}`));\n } else {\n configManager.saveLocal();\n console.log(UI.success(`Created local config: ${ConfigManager.getLocalConfigPath()}`));\n }\n tasks.push({ name: 'Config file', done: true, skipped: false });\n } catch {\n console.log(UI.error('Failed to create config'));\n tasks.push({ name: 'Config file', done: false, skipped: false });\n }\n }\n\n console.log('');\n console.log(UI.divider());\n console.log('');\n\n // Summary\n // Git hooks for automatic snapshots\n if (options.git_hooks || options.gitHooks) {\n console.log('');\n console.log(UI.divider());\n console.log('');\n console.log(colors.bold('📸 Git Hooks for Automatic Snapshots'));\n console.log(\n colors.muted(\n ' Install hooks that automatically capture your work state on commit and branch switch'\n )\n );\n console.log(\n colors.muted(' Snapshots are lightweight, local-only, and run in the background')\n );\n console.log('');\n\n if (!isRepo) {\n console.log(UI.warning('Not a git repository — skipping git hooks'));\n tasks.push({ name: 'Git hooks', done: false, skipped: true });\n } else {\n const { hookChoices } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'hookChoices',\n message: 'Which hooks would you like to install?',\n choices: [\n {\n name: `post-commit — snapshot after each commit`,\n value: 'post-commit',\n checked: true,\n },\n {\n name: `post-checkout — snapshot when switching branches`,\n value: 'post-checkout',\n checked: true,\n },\n ],\n },\n ]);\n\n if (hookChoices.length === 0) {\n console.log(colors.muted(' No hooks selected'));\n tasks.push({ name: 'Git hooks', done: false, skipped: true });\n } else {\n const hookResult = await installGitHooks({\n postCommit: hookChoices.includes('post-commit'),\n postCheckout: hookChoices.includes('post-checkout'),\n });\n\n if (hookResult.installed.length > 0) {\n for (const name of hookResult.installed) {\n console.log(UI.success(`Installed: ${name}`));\n }\n\n // Update config to reflect git hooks are enabled\n try {\n const configManager = ConfigManager.getInstance();\n const currentConfig = configManager.get();\n configManager.update({\n ...currentConfig,\n journal: {\n ...currentConfig.journal,\n autoSnapshot: true,\n gitHooks: true,\n hooks: {\n postCommit: hookChoices.includes('post-commit'),\n postCheckout: hookChoices.includes('post-checkout'),\n },\n },\n });\n if (options.global) {\n configManager.saveGlobal();\n } else {\n configManager.saveLocal();\n }\n } catch {\n // Non-fatal — hooks are installed even if config update fails\n }\n\n tasks.push({ name: 'Git hooks', done: true, skipped: false });\n }\n\n for (const name of hookResult.skipped) {\n console.log(colors.muted(` ${ASCII.status.check} ${name}`));\n }\n\n for (const w of hookResult.warnings) {\n console.log(UI.warning(w));\n }\n }\n }\n }\n\n const completed = tasks.filter((t) => t.done).length;\n const skipped = tasks.filter((t) => t.skipped).length;\n\n if (completed > 0) {\n console.log(UI.success(`Setup complete! (${completed} task${completed > 1 ? 's' : ''})`));\n console.log('');\n console.log(colors.muted('To apply changes, restart your terminal or run:'));\n console.log(\n ` ${colors.primary(`source ~/${shell === 'fish' ? '.config/fish/config.fish' : `.${shell}rc`}`)}`\n );\n } else if (skipped === tasks.length) {\n console.log(UI.info('Everything is already set up!'));\n }\n\n console.log('');\n console.log(colors.muted('Quick start:'));\n console.log(` ${colors.primary('dd standup')} ${colors.muted('# Generate standup notes')}`);\n console.log(\n ` ${colors.primary('dd pr')} ${colors.muted('# Generate PR description')}`\n );\n console.log(\n ` ${colors.primary('dd dash')} ${colors.muted('# Open interactive dashboard')}`\n );\n console.log(\n ` ${colors.primary('dd context')} ${colors.muted('# Resume where you left off')}`\n );\n console.log('');\n });\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport { ConfigManager, getConfig } from '../config/index.js';\nimport UI from '../ui/renderer.js';\nimport { ASCII } from '../ui/ascii.js';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nconst execAsync = promisify(exec);\n\nexport const configCommand = new Command('config')\n .description('Manage DevDaily configuration')\n .option('-e, --edit', 'Open config in editor')\n .option('--reset', 'Reset to defaults')\n .option('--path', 'Show config file path')\n .option('--show', 'Show current configuration')\n .action(async (options) => {\n const configManager = ConfigManager.getInstance();\n const config = getConfig();\n\n if (options.path) {\n console.log('');\n console.log(UI.keyValue('Config path', configManager.getConfigPath()));\n console.log(UI.keyValue('Global config', ConfigManager.getGlobalConfigPath()));\n console.log(UI.keyValue('Local config', ConfigManager.getLocalConfigPath()));\n console.log('');\n return;\n }\n\n if (options.reset) {\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Reset configuration to defaults?',\n default: false,\n },\n ]);\n\n if (confirm) {\n configManager.reset();\n console.log(UI.success('Configuration reset to defaults'));\n }\n return;\n }\n\n if (options.edit) {\n const editor = process.env.EDITOR || 'code';\n const configPath = configManager.getConfigPath();\n\n console.log(UI.info(`Opening ${configPath} in ${editor}...`));\n\n try {\n await execAsync(`${editor} \"${configPath}\"`);\n } catch {\n console.log(UI.error(`Failed to open editor. Config path: ${configPath}`));\n }\n return;\n }\n\n if (options.show) {\n console.log('');\n console.log(UI.section('Current Configuration', ASCII.icons.config));\n console.log('');\n console.log(JSON.stringify(config, null, 2));\n console.log('');\n return;\n }\n\n // Interactive configuration\n console.log('');\n console.log(UI.header('Configuration'));\n console.log('');\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What would you like to configure?',\n choices: [\n { name: `${ASCII.icons.standup} Theme & Appearance`, value: 'theme' },\n { name: `${ASCII.icons.pr} Default Settings`, value: 'defaults' },\n { name: `${ASCII.icons.week} Output Preferences`, value: 'output' },\n new inquirer.Separator(),\n { name: 'Show current config', value: 'show' },\n { name: 'Open in editor', value: 'edit' },\n { name: 'Reset to defaults', value: 'reset' },\n new inquirer.Separator(),\n { name: 'Exit', value: 'exit' },\n ],\n },\n ]);\n\n switch (action) {\n case 'theme':\n await configureTheme(configManager);\n break;\n case 'defaults':\n await configureDefaults(configManager);\n break;\n case 'output':\n await configureOutput(configManager);\n break;\n case 'show':\n console.log('');\n console.log(JSON.stringify(config, null, 2));\n console.log('');\n break;\n case 'edit': {\n const editor = process.env.EDITOR || 'code';\n try {\n await execAsync(`${editor} \"${configManager.getConfigPath()}\"`);\n } catch {\n console.log(UI.error('Failed to open editor'));\n }\n break;\n }\n case 'reset':\n configManager.reset();\n console.log(UI.success('Configuration reset'));\n break;\n }\n });\n\nasync function configureTheme(configManager: ConfigManager): Promise<void> {\n const config = configManager.get();\n\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'primary',\n message: 'Primary color:',\n choices: ['blue', 'cyan', 'green', 'magenta', 'yellow', 'red'],\n default: config.theme.primary,\n },\n {\n type: 'confirm',\n name: 'ascii',\n message: 'Show ASCII art logo?',\n default: config.ascii,\n },\n {\n type: 'confirm',\n name: 'compactMode',\n message: 'Use compact mode?',\n default: config.compactMode,\n },\n ]);\n\n configManager.update({\n theme: { ...config.theme, primary: answers.primary },\n ascii: answers.ascii,\n compactMode: answers.compactMode,\n });\n\n console.log(UI.success('Theme updated'));\n}\n\nasync function configureDefaults(configManager: ConfigManager): Promise<void> {\n const config = configManager.get();\n\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'defaultBranch',\n message: 'Default base branch for PRs:',\n default: config.pr.defaultBase,\n },\n {\n type: 'number',\n name: 'standupDays',\n message: 'Default days for standup:',\n default: config.standup.defaultDays,\n },\n {\n type: 'list',\n name: 'weekStart',\n message: 'Week starts on:',\n choices: ['monday', 'sunday'],\n default: config.week.startDay,\n },\n ]);\n\n configManager.update({\n pr: { ...config.pr, defaultBase: answers.defaultBranch },\n standup: { ...config.standup, defaultDays: answers.standupDays },\n week: { ...config.week, startDay: answers.weekStart },\n });\n\n console.log(UI.success('Defaults updated'));\n}\n\nasync function configureOutput(configManager: ConfigManager): Promise<void> {\n const config = configManager.get();\n\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'format',\n message: 'Default output format:',\n choices: ['markdown', 'slack', 'plain', 'json'],\n default: config.output.format,\n },\n {\n type: 'confirm',\n name: 'copyToClipboard',\n message: 'Auto-copy to clipboard?',\n default: config.output.copyToClipboard,\n },\n {\n type: 'confirm',\n name: 'showStats',\n message: 'Show statistics?',\n default: config.output.showStats,\n },\n ]);\n\n configManager.update({\n output: {\n ...config.output,\n format: answers.format,\n copyToClipboard: answers.copyToClipboard,\n showStats: answers.showStats,\n },\n });\n\n console.log(UI.success('Output preferences updated'));\n}\n","import { Command } from 'commander';\nimport { startDashboard } from '../ui/dashboard.js';\n\nexport const dashCommand = new Command('dash')\n .alias('d')\n .alias('dashboard')\n .description('Open interactive dashboard')\n .action(async () => {\n await startDashboard();\n });\n","import { EventEmitter } from 'events';\nimport { getConfig } from '../config/index.js';\n\nexport interface KeyEvent {\n name: string;\n ctrl: boolean;\n meta: boolean;\n shift: boolean;\n sequence: string;\n}\n\nexport type KeyHandler = (key: KeyEvent) => void | Promise<void>;\n\n/**\n * Keyboard input handler for interactive modes\n */\nexport class KeyboardHandler extends EventEmitter {\n private handlers: Map<string, KeyHandler> = new Map();\n private isListening = false;\n\n constructor() {\n super();\n }\n\n /**\n * Start listening for keyboard input\n */\n start(): void {\n if (this.isListening) return;\n\n // Enable raw mode for character-by-character input\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n process.stdin.resume();\n process.stdin.setEncoding('utf8');\n\n process.stdin.on('data', this.handleInput.bind(this));\n this.isListening = true;\n }\n\n /**\n * Stop listening for keyboard input\n */\n stop(): void {\n if (!this.isListening) return;\n\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n process.stdin.removeAllListeners('data');\n this.isListening = false;\n }\n\n /**\n * Register a key handler\n */\n on(key: string, handler: KeyHandler): this {\n this.handlers.set(key.toLowerCase(), handler);\n return this;\n }\n\n /**\n * Remove a key handler\n */\n off(key: string): this {\n this.handlers.delete(key.toLowerCase());\n return this;\n }\n\n /**\n * Handle raw input\n */\n private handleInput(data: string): void {\n const key = this.parseKey(data);\n this.emit('key', key);\n\n // Check for specific handlers\n const keyName = this.getKeyName(key);\n const handler = this.handlers.get(keyName);\n\n if (handler) {\n handler(key);\n }\n\n // Always emit the raw key name\n this.emit(keyName, key);\n }\n\n /**\n * Parse raw input into a KeyEvent\n */\n private parseKey(data: string): KeyEvent {\n const key: KeyEvent = {\n name: '',\n ctrl: false,\n meta: false,\n shift: false,\n sequence: data,\n };\n\n // Handle special sequences\n if (data === '\\x03') {\n key.name = 'c';\n key.ctrl = true;\n } else if (data === '\\x1B') {\n key.name = 'escape';\n } else if (data === '\\r' || data === '\\n') {\n key.name = 'return';\n } else if (data === '\\t') {\n key.name = 'tab';\n } else if (data === '\\x7F') {\n key.name = 'backspace';\n } else if (data === ' ') {\n key.name = 'space';\n } else if (data === '\\x1B[A') {\n key.name = 'up';\n } else if (data === '\\x1B[B') {\n key.name = 'down';\n } else if (data === '\\x1B[C') {\n key.name = 'right';\n } else if (data === '\\x1B[D') {\n key.name = 'left';\n } else if (data === '\\x1B[Z') {\n key.name = 'tab';\n key.shift = true;\n } else if (data.length === 1) {\n key.name = data.toLowerCase();\n key.shift = data !== data.toLowerCase();\n\n // Check for ctrl+letter\n const code = data.charCodeAt(0);\n if (code >= 1 && code <= 26) {\n key.ctrl = true;\n key.name = String.fromCharCode(code + 96);\n }\n } else {\n key.name = data;\n }\n\n return key;\n }\n\n /**\n * Get a normalized key name for handler lookup\n */\n private getKeyName(key: KeyEvent): string {\n let name = '';\n\n if (key.ctrl) name += 'ctrl+';\n if (key.meta) name += 'meta+';\n if (key.shift) name += 'shift+';\n\n name += key.name;\n\n return name.toLowerCase();\n }\n}\n\n/**\n * Create shortcuts help text from config\n */\nexport const getShortcutsHelp = (): Array<{ key: string; action: string }> => {\n const shortcuts = getConfig().shortcuts;\n\n return [\n { key: shortcuts.quit, action: 'Quit' },\n { key: shortcuts.help, action: 'Help' },\n { key: shortcuts.refresh, action: 'Refresh' },\n { key: shortcuts.copy, action: 'Copy to clipboard' },\n { key: shortcuts.create, action: 'Create/Select' },\n { key: shortcuts.back, action: 'Back' },\n { key: '↑/↓', action: 'Navigate' },\n { key: shortcuts.nextProject, action: 'Next project' },\n ];\n};\n\n// Export singleton\nexport const keyboard = new KeyboardHandler();\n","import { GitAnalyzer } from '../core/git-analyzer.js';\nimport { CopilotClient } from '../core/copilot.js';\nimport UI from './renderer.js';\nimport { ASCII } from './ascii.js';\nimport { KeyboardHandler } from './keyboard.js';\nimport { getConfig } from '../config/index.js';\nimport { copyToClipboard } from '../utils/helpers.js';\nimport inquirer from 'inquirer';\n\nconst { colors } = UI;\n\ninterface DashboardState {\n currentView: 'main' | 'standup' | 'pr' | 'week' | 'settings';\n selectedIndex: number;\n isLoading: boolean;\n lastOutput: string | null;\n commits: Array<{ message: string; date: Date }>;\n branch: string;\n stats: { commits: number; files: number; insertions: number; deletions: number };\n}\n\n/**\n * Interactive Dashboard for DevDaily\n */\nexport class Dashboard {\n private git: GitAnalyzer;\n private copilot: CopilotClient;\n private keyboard: KeyboardHandler;\n private state: DashboardState;\n private isRunning = false;\n\n constructor() {\n this.git = new GitAnalyzer();\n this.copilot = new CopilotClient();\n this.keyboard = new KeyboardHandler();\n this.state = {\n currentView: 'main',\n selectedIndex: 0,\n isLoading: false,\n lastOutput: null,\n commits: [],\n branch: '',\n stats: { commits: 0, files: 0, insertions: 0, deletions: 0 },\n };\n }\n\n /**\n * Start the dashboard\n */\n async start(): Promise<void> {\n // Check prerequisites\n if (!(await this.git.isRepository())) {\n console.log(UI.error('Not in a git repository'));\n process.exit(1);\n }\n\n if (!(await this.copilot.isInstalled())) {\n console.log(UI.error('GitHub Copilot CLI not installed'));\n console.log(UI.info('Install with: gh extension install github/gh-copilot'));\n process.exit(1);\n }\n\n this.isRunning = true;\n\n // Load initial data\n await this.loadData();\n\n // Render initial view\n this.render();\n\n // Run main menu loop\n await this.mainMenu();\n }\n\n /**\n * Load git data\n */\n private async loadData(): Promise<void> {\n try {\n this.state.branch = await this.git.getCurrentBranch();\n\n const commits = await this.git.getCommits({\n since: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),\n });\n this.state.commits = commits;\n\n const diffStats = await this.git.getDiffStats();\n this.state.stats = {\n commits: commits.length,\n files: diffStats.filesChanged,\n insertions: diffStats.insertions,\n deletions: diffStats.deletions,\n };\n } catch {\n // Expected: may fail if not in a git repo or no commits exist yet.\n // Dashboard will render with default/empty state values.\n }\n }\n\n /**\n * Render the current view\n */\n private render(): void {\n UI.clear();\n console.log(this.renderMainView());\n }\n\n /**\n * Render the main dashboard view\n */\n private renderMainView(): string {\n const lines: string[] = [];\n\n // Header\n lines.push(UI.header('Dashboard'));\n lines.push('');\n\n // Git status\n lines.push(UI.section('Git Status', ASCII.icons.standup));\n lines.push('');\n lines.push(` ${colors.accent('Branch:')} ${colors.primary(this.state.branch)}`);\n lines.push(\n ` ${colors.accent('Week:')} ${UI.stats([\n { label: 'commits', value: this.state.stats.commits },\n { label: 'files changed', value: this.state.stats.files },\n { label: 'insertions', value: `+${this.state.stats.insertions}`, color: 'green' },\n { label: 'deletions', value: `-${this.state.stats.deletions}`, color: 'red' },\n ])}`\n );\n lines.push('');\n\n // Recent commits\n if (this.state.commits.length > 0) {\n lines.push(colors.bold(' Recent Commits'));\n lines.push('');\n this.state.commits.slice(0, 5).forEach((commit) => {\n const msg =\n commit.message.length > 50 ? commit.message.slice(0, 47) + '...' : commit.message;\n lines.push(` ${colors.muted(ASCII.status.bullet)} ${msg}`);\n });\n lines.push('');\n }\n\n // Shortcuts\n lines.push(UI.divider());\n lines.push('');\n lines.push(\n UI.shortcuts([\n { key: 's', action: 'Standup' },\n { key: 'p', action: 'PR Description' },\n { key: 'w', action: 'Week Summary' },\n { key: 'c', action: 'Config' },\n { key: 'q', action: 'Quit' },\n ])\n );\n lines.push('');\n\n return lines.join('\\n');\n }\n\n /**\n * Main menu loop\n */\n private async mainMenu(): Promise<void> {\n while (this.isRunning) {\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: colors.primary('What would you like to do?'),\n choices: [\n { name: `${ASCII.icons.standup} Generate Standup Notes`, value: 'standup' },\n { name: `${ASCII.icons.pr} Generate PR Description`, value: 'pr' },\n { name: `${ASCII.icons.week} Generate Weekly Summary`, value: 'week' },\n new inquirer.Separator(),\n { name: `${ASCII.icons.config} Configuration`, value: 'config' },\n { name: `${ASCII.status.info} Refresh Data`, value: 'refresh' },\n new inquirer.Separator(),\n { name: `${ASCII.status.cross} Exit`, value: 'exit' },\n ],\n pageSize: 10,\n },\n ]);\n\n switch (action) {\n case 'standup':\n await this.generateStandup();\n break;\n case 'pr':\n await this.generatePR();\n break;\n case 'week':\n await this.generateWeek();\n break;\n case 'config':\n await this.showConfig();\n break;\n case 'refresh':\n await this.refresh();\n break;\n case 'exit':\n this.stop();\n break;\n }\n }\n }\n\n /**\n * Generate standup notes\n */\n private async generateStandup(): Promise<void> {\n const { days } = await inquirer.prompt([\n {\n type: 'list',\n name: 'days',\n message: 'Time range:',\n choices: [\n { name: 'Yesterday (1 day)', value: 1 },\n { name: 'Last 2 days', value: 2 },\n { name: 'Last 3 days', value: 3 },\n { name: 'Last week', value: 7 },\n ],\n },\n ]);\n\n const spinner = UI.spinner('Generating standup notes...');\n spinner.start();\n\n try {\n const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const commits = await this.git.getCommits({ since });\n\n if (commits.length === 0) {\n spinner.stop();\n console.log(UI.warning(`No commits found in the last ${days} day(s)`));\n return;\n }\n\n const messages = commits.map((c) => c.message);\n const standup = await this.copilot.summarizeCommits(messages);\n\n spinner.stop();\n\n console.log('');\n console.log(UI.box(standup, 'Your Standup'));\n console.log(UI.stats([{ label: 'commits analyzed', value: commits.length }]));\n console.log('');\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What next?',\n choices: [\n { name: 'Copy to clipboard', value: 'copy' },\n { name: 'Back to dashboard', value: 'back' },\n ],\n },\n ]);\n\n if (action === 'copy') {\n await copyToClipboard(standup);\n console.log(UI.success('Copied to clipboard!'));\n }\n } catch (error) {\n spinner.stop();\n console.log(UI.error('Failed to generate standup'));\n console.log(colors.muted((error as Error).message));\n }\n }\n\n /**\n * Generate PR description\n */\n private async generatePR(): Promise<void> {\n const config = getConfig();\n\n const { base } = await inquirer.prompt([\n {\n type: 'input',\n name: 'base',\n message: 'Base branch:',\n default: config.pr.defaultBase,\n },\n ]);\n\n const spinner = UI.spinner('Analyzing branch...');\n spinner.start();\n\n try {\n const currentBranch = await this.git.getCurrentBranch();\n\n if (currentBranch === base) {\n spinner.stop();\n console.log(UI.error(`Cannot create PR from ${base} to ${base}`));\n return;\n }\n\n const commits = await this.git.getCommits();\n const files = await this.git.getChangedFiles(base);\n\n spinner.text = 'Generating PR description...';\n\n const description = await this.copilot.generatePRDescription({\n branch: currentBranch,\n commits: commits.map((c) => c.message),\n files,\n issues: [],\n });\n\n spinner.stop();\n\n console.log('');\n console.log(UI.box(description, `PR: ${currentBranch}`));\n console.log(\n UI.stats([\n { label: 'commits', value: commits.length },\n { label: 'files changed', value: files.length },\n ])\n );\n console.log('');\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What next?',\n choices: [\n { name: 'Copy to clipboard', value: 'copy' },\n { name: 'Back to dashboard', value: 'back' },\n ],\n },\n ]);\n\n if (action === 'copy') {\n await copyToClipboard(description);\n console.log(UI.success('Copied to clipboard!'));\n console.log(UI.info('Tip: Use `devdaily pr --create` to create PRs directly'));\n }\n } catch (error) {\n spinner.stop();\n console.log(UI.error('Failed to generate PR description'));\n console.log(colors.muted((error as Error).message));\n }\n }\n\n /**\n * Generate weekly summary\n */\n private async generateWeek(): Promise<void> {\n const spinner = UI.spinner('Generating weekly summary...');\n spinner.start();\n\n try {\n const since = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);\n const commits = await this.git.getCommits({ since });\n\n if (commits.length === 0) {\n spinner.stop();\n console.log(UI.warning('No commits found this week'));\n return;\n }\n\n const stats = await this.git.getDiffStats();\n const messages = commits.map((c) => c.message);\n\n const summary = await this.copilot.generateWeeklySummary({\n commits: messages,\n stats: {\n commits: commits.length,\n linesAdded: stats.insertions,\n linesRemoved: stats.deletions,\n },\n });\n\n spinner.stop();\n\n console.log('');\n console.log(UI.box(summary, 'Weekly Summary'));\n console.log(\n UI.stats([\n { label: 'commits', value: commits.length },\n { label: 'lines added', value: `+${stats.insertions}`, color: 'green' },\n { label: 'lines removed', value: `-${stats.deletions}`, color: 'red' },\n ])\n );\n console.log('');\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What next?',\n choices: [\n { name: 'Copy to clipboard', value: 'copy' },\n { name: 'Back to dashboard', value: 'back' },\n ],\n },\n ]);\n\n if (action === 'copy') {\n await copyToClipboard(summary);\n console.log(UI.success('Copied to clipboard!'));\n }\n } catch (error) {\n spinner.stop();\n console.log(UI.error('Failed to generate weekly summary'));\n console.log(colors.muted((error as Error).message));\n }\n }\n\n /**\n * Show configuration\n */\n private async showConfig(): Promise<void> {\n const config = getConfig();\n\n console.log('');\n console.log(UI.section('Configuration', ASCII.icons.config));\n console.log('');\n console.log(UI.keyValue('Theme', config.theme.primary));\n console.log(UI.keyValue('Default format', config.output.format));\n console.log(UI.keyValue('Copy to clipboard', config.output.copyToClipboard ? 'Yes' : 'No'));\n console.log(UI.keyValue('Default branch', config.pr.defaultBase));\n console.log(UI.keyValue('Week starts', config.week.startDay));\n console.log('');\n\n await inquirer.prompt([\n {\n type: 'input',\n name: 'continue',\n message: 'Press Enter to continue...',\n },\n ]);\n }\n\n /**\n * Refresh data\n */\n private async refresh(): Promise<void> {\n const spinner = UI.spinner('Refreshing...');\n spinner.start();\n\n await this.loadData();\n\n spinner.stop();\n this.render();\n\n console.log(UI.success('Data refreshed'));\n }\n\n /**\n * Stop the dashboard\n */\n stop(): void {\n this.isRunning = false;\n this.keyboard.stop();\n console.log('');\n console.log(UI.info('Goodbye!'));\n }\n}\n\n/**\n * Start the dashboard\n */\nexport const startDashboard = async (): Promise<void> => {\n const dashboard = new Dashboard();\n await dashboard.start();\n};\n","import { Command } from 'commander';\nimport { execa } from 'execa';\nimport UI from '../ui/renderer.js';\nimport { ASCII } from '../ui/ascii.js';\n\nconst { colors } = UI;\n\ninterface CheckResult {\n name: string;\n status: 'ok' | 'warning' | 'error';\n message: string;\n fix?: string;\n}\n\n/**\n * Check if a command exists\n */\nasync function commandExists(cmd: string): Promise<boolean> {\n try {\n await execa('which', [cmd]);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get version of a command\n */\nasync function getVersion(cmd: string, args: string[] = ['--version']): Promise<string | null> {\n try {\n const { stdout } = await execa(cmd, args);\n return stdout.trim().split('\\n')[0];\n } catch {\n return null;\n }\n}\n\n/**\n * Check if gh is authenticated\n */\nasync function isGhAuthenticated(): Promise<boolean> {\n try {\n await execa('gh', ['auth', 'status']);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check which Copilot CLI is installed\n * Returns: 'new' for copilot CLI, 'legacy' for gh copilot extension, null if neither\n */\nasync function getCopilotStatus(): Promise<{ type: 'new' | 'legacy' | null; version?: string }> {\n // Check for new Copilot CLI first (preferred)\n try {\n const { stdout } = await execa('copilot', ['--version']);\n return { type: 'new', version: stdout.trim().split('\\n')[0] };\n } catch {\n // Fallback to legacy gh copilot extension\n try {\n const { stdout } = await execa('gh', ['extension', 'list']);\n if (stdout.includes('copilot')) {\n return { type: 'legacy', version: 'gh extension' };\n }\n } catch {\n // Ignore\n }\n return { type: null };\n }\n}\n\n/**\n * Run all diagnostic checks\n */\nasync function runChecks(): Promise<CheckResult[]> {\n const checks: CheckResult[] = [];\n\n // Check Node.js\n const nodeVersion = await getVersion('node');\n if (nodeVersion) {\n const major = parseInt(nodeVersion.replace('v', '').split('.')[0]);\n if (major >= 18) {\n checks.push({\n name: 'Node.js',\n status: 'ok',\n message: nodeVersion,\n });\n } else {\n checks.push({\n name: 'Node.js',\n status: 'error',\n message: `${nodeVersion} (requires >= 18)`,\n fix: 'Install Node.js 18+ from https://nodejs.org',\n });\n }\n } else {\n checks.push({\n name: 'Node.js',\n status: 'error',\n message: 'Not found',\n fix: 'Install Node.js from https://nodejs.org',\n });\n }\n\n // Check Git\n const gitVersion = await getVersion('git');\n if (gitVersion) {\n checks.push({\n name: 'Git',\n status: 'ok',\n message: gitVersion,\n });\n } else {\n checks.push({\n name: 'Git',\n status: 'error',\n message: 'Not found',\n fix: 'Install Git from https://git-scm.com',\n });\n }\n\n // Check GitHub CLI\n if (await commandExists('gh')) {\n const ghVersion = await getVersion('gh');\n checks.push({\n name: 'GitHub CLI',\n status: 'ok',\n message: ghVersion || 'Installed',\n });\n\n // Check gh auth\n if (await isGhAuthenticated()) {\n checks.push({\n name: 'GitHub Auth',\n status: 'ok',\n message: 'Authenticated',\n });\n } else {\n checks.push({\n name: 'GitHub Auth',\n status: 'error',\n message: 'Not authenticated',\n fix: 'Run: gh auth login',\n });\n }\n\n // Check Copilot CLI (new or legacy)\n const copilotStatus = await getCopilotStatus();\n if (copilotStatus.type === 'new') {\n checks.push({\n name: 'Copilot CLI',\n status: 'ok',\n message: copilotStatus.version || 'Installed',\n });\n } else if (copilotStatus.type === 'legacy') {\n checks.push({\n name: 'Copilot CLI',\n status: 'warning',\n message: 'Using deprecated gh extension. Upgrade to new CLI.',\n fix: 'Run: brew install copilot-cli',\n });\n } else {\n checks.push({\n name: 'Copilot CLI',\n status: 'error',\n message: 'Not found',\n fix: 'Run: brew install copilot-cli',\n });\n }\n } else {\n checks.push({\n name: 'GitHub CLI',\n status: 'error',\n message: 'Not found',\n fix: 'Install from https://cli.github.com',\n });\n checks.push({\n name: 'GitHub Auth',\n status: 'warning',\n message: 'Requires GitHub CLI',\n });\n checks.push({\n name: 'Copilot CLI',\n status: 'warning',\n message: 'Requires GitHub CLI',\n });\n }\n\n return checks;\n}\n\nexport const doctorCommand = new Command('doctor')\n .description('Check system setup and diagnose issues')\n .option('--fix', 'Attempt to fix issues automatically')\n .action(async (options) => {\n console.log('');\n console.log(UI.header('System Check'));\n console.log('');\n\n const spinner = UI.spinner('Running diagnostics...');\n spinner.start();\n\n const checks = await runChecks();\n\n spinner.stop();\n\n // Display results\n console.log(UI.section('Prerequisites', '🔍'));\n console.log('');\n\n const statusIcon = {\n ok: colors.success(ASCII.status.check),\n warning: colors.warning(ASCII.status.warning),\n error: colors.error(ASCII.status.cross),\n };\n\n for (const check of checks) {\n const icon = statusIcon[check.status];\n const name = check.name.padEnd(15);\n const message =\n check.status === 'ok'\n ? colors.muted(check.message)\n : check.status === 'error'\n ? colors.error(check.message)\n : colors.warning(check.message);\n\n console.log(` ${icon} ${name} ${message}`);\n\n if (check.fix && check.status === 'error') {\n console.log(` ${colors.muted('Fix:')} ${colors.accent(check.fix)}`);\n }\n }\n\n console.log('');\n\n // Summary\n const errors = checks.filter((c) => c.status === 'error');\n\n if (errors.length === 0) {\n console.log(UI.success('All checks passed! DevDaily is ready to use.'));\n } else {\n console.log(UI.error(`${errors.length} issue(s) found`));\n console.log('');\n\n if (options.fix) {\n console.log(UI.info('Attempting automatic fixes...'));\n console.log('');\n\n for (const check of errors) {\n if (check.name === 'GitHub Auth') {\n console.log(` ${colors.accent('→')} Running: gh auth login`);\n try {\n await execa('gh', ['auth', 'login'], { stdio: 'inherit' });\n console.log(UI.success('Authenticated successfully'));\n } catch {\n console.log(UI.error('Authentication failed'));\n }\n } else if (check.name === 'Copilot CLI') {\n console.log(` ${colors.accent('→')} Running: brew install copilot-cli`);\n try {\n await execa('brew', ['install', 'copilot-cli'], { stdio: 'inherit' });\n console.log(UI.success('Copilot CLI installed'));\n } catch {\n console.log(UI.error('Installation failed. Try manually: brew install copilot-cli'));\n }\n }\n }\n } else {\n console.log(UI.info('Run `devdaily doctor --fix` to attempt automatic fixes'));\n }\n }\n\n console.log('');\n\n // Quick setup guide if issues found\n if (errors.length > 0) {\n console.log(UI.section('Quick Setup Guide', '📋'));\n console.log('');\n console.log(\n ' ' + colors.muted('1.') + ' Install GitHub CLI: ' + colors.accent('brew install gh')\n );\n console.log(' ' + colors.muted('2.') + ' Authenticate: ' + colors.accent('gh auth login'));\n console.log(\n ' ' +\n colors.muted('3.') +\n ' Install Copilot CLI: ' +\n colors.accent('brew install copilot-cli')\n );\n console.log(\n ' ' + colors.muted('4.') + ' Set up DevDaily: ' + colors.accent('devdaily init')\n );\n console.log('');\n }\n });\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport UI from '../ui/renderer.js';\nimport { ASCII } from '../ui/ascii.js';\nimport { getConfig, getSecrets, ConfigManager } from '../config/index.js';\nimport {\n getProjectManagementClient,\n extractTicketIds,\n JiraClient,\n LinearClient,\n GitHubIssueClient,\n} from '../core/project-management.js';\nimport { type PMConnectionTestResult, type PMTool } from '../core/pm-errors.js';\n\nconst { colors } = UI;\n\n// ─── Helper: render a connection test result ──────────────────────────────────\n\nfunction renderTestResult(result: PMConnectionTestResult): void {\n const icon = result.success\n ? colors.success(ASCII.status.check)\n : colors.error(ASCII.status.cross);\n\n console.log(` ${icon} ${result.message}`);\n\n if (result.details.responseTimeMs !== undefined) {\n console.log(\n ` ${colors.muted('Response time:')} ${colors.accent(`${result.details.responseTimeMs}ms`)}`\n );\n }\n\n if (!result.success && result.error) {\n console.log(` ${colors.muted('Hint:')} ${colors.warning(result.error.hint)}`);\n }\n}\n\n// ─── Helper: show credential status ───────────────────────────────────────────\n\nfunction showCredentialStatus(tool: PMTool): void {\n const secrets = getSecrets();\n const config = getConfig();\n\n console.log('');\n console.log(UI.section('Credential Status', '🔑'));\n console.log('');\n\n if (tool === 'jira') {\n const baseUrl =\n secrets.jira?.baseUrl ||\n config.projectManagement.jira.baseUrl ||\n process.env.JIRA_BASE_URL ||\n '';\n const email = secrets.jira?.email || process.env.JIRA_EMAIL || '';\n const token = secrets.jira?.apiToken || process.env.JIRA_API_TOKEN || '';\n const projectKey = config.projectManagement.jira.projectKey || '';\n const prefix = config.projectManagement.ticketPrefix || '';\n\n showField('Base URL', baseUrl, 'JIRA_BASE_URL');\n showField('Email', email, 'JIRA_EMAIL');\n showField('API Token', token ? maskSecret(token) : '', 'JIRA_API_TOKEN');\n showField('Project Key', projectKey, '.devdaily.json → projectManagement.jira.projectKey');\n showField('Ticket Prefix', prefix, '.devdaily.json → projectManagement.ticketPrefix');\n } else if (tool === 'linear') {\n const apiKey = secrets.linear?.apiKey || process.env.LINEAR_API_KEY || '';\n const teamKey = config.projectManagement.linear.teamKey || '';\n const prefix = config.projectManagement.ticketPrefix || '';\n\n showField('API Key', apiKey ? maskSecret(apiKey) : '', 'LINEAR_API_KEY');\n showField('Team Key', teamKey, '.devdaily.json → projectManagement.linear.teamKey');\n showField('Ticket Prefix', prefix, '.devdaily.json → projectManagement.ticketPrefix');\n } else if (tool === 'github') {\n showField('Auth', '(managed by gh CLI)', 'gh auth login');\n const prefix = config.projectManagement.ticketPrefix || '';\n showField('Ticket Prefix', prefix, '.devdaily.json → projectManagement.ticketPrefix');\n }\n}\n\nfunction showField(label: string, value: string, source: string): void {\n const icon = value ? colors.success(ASCII.status.check) : colors.error(ASCII.status.cross);\n const displayValue = value || colors.muted('not set');\n console.log(` ${icon} ${label.padEnd(16)} ${displayValue}`);\n if (!value) {\n console.log(` ${colors.muted('Set via:')} ${colors.accent(source)}`);\n }\n}\n\nfunction maskSecret(secret: string): string {\n if (secret.length <= 8) return '••••••••';\n return secret.slice(0, 4) + '••••' + secret.slice(-4);\n}\n\n// ─── Helper: fetch a sample ticket to prove it works ──────────────────────────\n\nasync function trySampleTicket(tool: PMTool): Promise<void> {\n const client = getProjectManagementClient();\n\n console.log('');\n console.log(UI.section('Live Ticket Test', '🎫'));\n console.log('');\n\n // Ask user for a ticket ID\n const config = getConfig();\n const prefix = config.projectManagement.ticketPrefix;\n\n let placeholder = '';\n if (tool === 'jira') placeholder = prefix ? `${prefix}-123` : 'PROJ-123';\n else if (tool === 'linear') placeholder = prefix ? `${prefix}-42` : 'ENG-42';\n else if (tool === 'github') placeholder = '#1';\n\n const { ticketId } = await inquirer.prompt([\n {\n type: 'input',\n name: 'ticketId',\n message: `Enter a ticket ID to fetch (e.g. ${placeholder}):`,\n validate: (input: string) => {\n if (!input.trim()) return 'Please enter a ticket ID';\n return true;\n },\n },\n ]);\n\n const spinner = UI.spinner(`Fetching ${ticketId} from ${tool}...`);\n spinner.start();\n\n try {\n const ticket = await client.getTicket(ticketId.trim());\n spinner.stop();\n\n if (ticket) {\n console.log('');\n console.log(colors.success(` ${ASCII.status.check} Ticket found!`));\n console.log('');\n console.log(` ${colors.accent('ID:')} ${ticket.id}`);\n console.log(` ${colors.accent('Title:')} ${ticket.title}`);\n console.log(` ${colors.accent('Status:')} ${ticket.status}`);\n console.log(` ${colors.accent('Type:')} ${ticket.type}`);\n if (ticket.priority) {\n console.log(` ${colors.accent('Priority:')} ${ticket.priority}`);\n }\n if (ticket.assignee) {\n console.log(` ${colors.accent('Assignee:')} ${ticket.assignee}`);\n }\n if (ticket.labels.length > 0) {\n console.log(` ${colors.accent('Labels:')} ${ticket.labels.join(', ')}`);\n }\n if (ticket.url) {\n console.log(` ${colors.accent('URL:')} ${colors.muted(ticket.url)}`);\n }\n\n // Show how it looks as AI context\n console.log('');\n console.log(colors.muted(' This is how DevDaily will present it to Copilot:'));\n console.log('');\n const context = client.formatTicketForContext(ticket);\n for (const line of context.split('\\n')) {\n console.log(` ${colors.muted('│')} ${line}`);\n }\n } else {\n console.log('');\n console.log(colors.warning(` ${ASCII.status.warning} Ticket \"${ticketId}\" not found`));\n console.log(colors.muted(` Make sure the ID is correct and you have access`));\n }\n } catch (err) {\n spinner.stop();\n console.log('');\n console.log(\n colors.error(` ${ASCII.status.cross} Failed to fetch ticket: ${(err as Error).message}`)\n );\n }\n}\n\n// ─── Helper: test ticket extraction from branch/commit ────────────────────────\n\nfunction testTicketExtraction(): void {\n const config = getConfig();\n const tool = config.projectManagement.tool;\n const prefix = config.projectManagement.ticketPrefix;\n\n console.log('');\n console.log(UI.section('Ticket Pattern Matching', '🔍'));\n console.log('');\n\n // Show current config\n console.log(` ${colors.accent('Tool:')} ${tool}`);\n console.log(` ${colors.accent('Prefix:')} ${prefix || colors.muted('(none)')}`);\n console.log('');\n\n // Test against common patterns\n interface PatternTest {\n input: string;\n label: string;\n }\n\n const testCases: PatternTest[] = [];\n\n if (tool === 'jira' || tool === 'linear') {\n const p = prefix || 'PROJ';\n testCases.push(\n { input: `feature/${p}-123-add-login`, label: 'Branch name' },\n { input: `fix: resolve ${p}-456 validation bug`, label: 'Commit msg' },\n { input: `${p}-789/implement-oauth`, label: 'Branch name' },\n { input: `chore: update deps, refs ${p}-10 ${p}-11`, label: 'Multi-ticket' }\n );\n } else if (tool === 'github') {\n testCases.push(\n { input: 'fix/#42-button-color', label: 'Branch name' },\n { input: 'fix: resolve #123 login issue', label: 'Commit msg' },\n { input: 'feat: implements #10 and closes #11', label: 'Multi-ticket' },\n { input: 'feature/add-login-page', label: 'No ticket' }\n );\n }\n\n for (const tc of testCases) {\n const ids = extractTicketIds(tc.input);\n const icon =\n ids.length > 0 ? colors.success(ASCII.status.check) : colors.muted(ASCII.status.pending);\n const found = ids.length > 0 ? colors.success(ids.join(', ')) : colors.muted('(none)');\n\n console.log(\n ` ${icon} ${tc.label.padEnd(14)} ${colors.muted('\"')}${tc.input}${colors.muted('\"')}`\n );\n console.log(` ${colors.muted('→ Extracted:')} ${found}`);\n }\n}\n\n// ─── Helper: interactive quick setup for a tool ───────────────────────────────\n\nasync function quickSetup(tool: PMTool): Promise<boolean> {\n console.log('');\n console.log(UI.section('Quick Setup', '⚙️'));\n console.log('');\n\n if (tool === 'jira') {\n console.log(colors.muted(' Your Jira API token can be created at:'));\n console.log(colors.accent(' https://id.atlassian.com/manage-profile/security/api-tokens'));\n console.log('');\n\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'baseUrl',\n message: 'Jira base URL:',\n default: 'https://yourcompany.atlassian.net',\n validate: (input: string) => input.startsWith('http') || 'Must be a valid URL',\n },\n {\n type: 'input',\n name: 'email',\n message: 'Your Jira email:',\n validate: (input: string) => input.includes('@') || 'Must be a valid email',\n },\n {\n type: 'password',\n name: 'apiToken',\n message: 'Jira API token:',\n mask: '*',\n validate: (input: string) => input.length > 0 || 'API token is required',\n },\n {\n type: 'input',\n name: 'projectKey',\n message: 'Default project key (optional, e.g. PROJ):',\n },\n {\n type: 'input',\n name: 'ticketPrefix',\n message: 'Ticket prefix for extraction (optional, e.g. PROJ):',\n },\n ]);\n\n // Save secrets\n const configManager = ConfigManager.getInstance();\n configManager.saveSecrets(\n {\n jira: {\n baseUrl: answers.baseUrl,\n email: answers.email,\n apiToken: answers.apiToken,\n },\n },\n false\n );\n\n // Update config\n const currentConfig = getConfig();\n configManager.saveLocal({\n ...currentConfig,\n projectManagement: {\n ...currentConfig.projectManagement,\n tool: 'jira',\n ticketPrefix: answers.ticketPrefix || currentConfig.projectManagement.ticketPrefix,\n jira: {\n ...currentConfig.projectManagement.jira,\n projectKey: answers.projectKey || undefined,\n baseUrl: answers.baseUrl,\n },\n },\n });\n\n // Add secrets to gitignore\n configManager.addSecretsToGitignore();\n\n console.log('');\n console.log(UI.success('Jira credentials saved'));\n console.log(colors.muted(' Secrets stored in .devdaily.secrets.json'));\n console.log(colors.muted(' Added to .gitignore'));\n return true;\n } else if (tool === 'linear') {\n console.log(colors.muted(' Get your API key from Linear:'));\n console.log(colors.accent(' Settings → Account → API → Personal API keys'));\n console.log('');\n\n const answers = await inquirer.prompt([\n {\n type: 'password',\n name: 'apiKey',\n message: 'Linear API key:',\n mask: '*',\n validate: (input: string) => input.length > 0 || 'API key is required',\n },\n {\n type: 'input',\n name: 'teamKey',\n message: 'Team key (optional, e.g. ENG):',\n },\n {\n type: 'input',\n name: 'ticketPrefix',\n message: 'Ticket prefix for extraction (optional, e.g. ENG):',\n },\n ]);\n\n // Save secrets\n const configManager = ConfigManager.getInstance();\n configManager.saveSecrets(\n {\n linear: {\n apiKey: answers.apiKey,\n },\n },\n false\n );\n\n // Update config\n const currentConfig = getConfig();\n configManager.saveLocal({\n ...currentConfig,\n projectManagement: {\n ...currentConfig.projectManagement,\n tool: 'linear',\n ticketPrefix: answers.ticketPrefix || currentConfig.projectManagement.ticketPrefix,\n linear: {\n ...currentConfig.projectManagement.linear,\n teamKey: answers.teamKey || undefined,\n },\n },\n });\n\n // Add secrets to gitignore\n configManager.addSecretsToGitignore();\n\n console.log('');\n console.log(UI.success('Linear credentials saved'));\n console.log(colors.muted(' Secrets stored in .devdaily.secrets.json'));\n console.log(colors.muted(' Added to .gitignore'));\n return true;\n } else if (tool === 'github') {\n console.log(colors.muted(' GitHub uses the gh CLI for authentication.'));\n console.log(colors.muted(' If you are not logged in, run: gh auth login'));\n console.log('');\n\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'ticketPrefix',\n message: 'Ticket prefix for extraction (optional):',\n },\n ]);\n\n if (answers.ticketPrefix) {\n const configManager = ConfigManager.getInstance();\n const currentConfig = getConfig();\n configManager.saveLocal({\n ...currentConfig,\n projectManagement: {\n ...currentConfig.projectManagement,\n tool: 'github',\n ticketPrefix: answers.ticketPrefix,\n },\n });\n }\n\n console.log('');\n console.log(UI.success('GitHub configuration saved'));\n return true;\n }\n\n return false;\n}\n\n// ─── Main Command ─────────────────────────────────────────────────────────────\n\nexport const connectCommand = new Command('connect')\n .description('Test and configure PM tool connections (Jira, Linear, GitHub)')\n .option('--tool <tool>', 'PM tool to test (jira, linear, github)')\n .option('--test', 'Run connection test only (non-interactive)')\n .option('--setup', 'Run interactive setup for the selected tool')\n .option('--ticket <id>', 'Fetch a specific ticket to verify')\n .option('--status', 'Show current credential status only')\n .action(async (options) => {\n console.log('');\n console.log(UI.header('PM Connection Manager'));\n console.log('');\n\n // Determine which tool to use\n let tool: PMTool;\n\n if (options.tool) {\n if (!['jira', 'linear', 'github'].includes(options.tool)) {\n console.log(UI.error(`Unsupported tool: ${options.tool}. Use jira, linear, or github.`));\n process.exit(1);\n }\n tool = options.tool as PMTool;\n } else if (options.test || options.status) {\n // Use configured tool for non-interactive modes\n const config = getConfig();\n tool =\n config.projectManagement.tool === 'none'\n ? 'github'\n : (config.projectManagement.tool as PMTool);\n } else {\n // Interactive: ask user\n const { selectedTool } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedTool',\n message: 'Which PM tool do you want to connect?',\n choices: [\n {\n name: `${colors.accent('🐙')} GitHub Issues (uses gh CLI)`,\n value: 'github',\n },\n {\n name: `${colors.accent('🔷')} Jira (REST API)`,\n value: 'jira',\n },\n {\n name: `${colors.accent('📐')} Linear (GraphQL API)`,\n value: 'linear',\n },\n ],\n },\n ]);\n tool = selectedTool;\n }\n\n console.log(` ${colors.accent('Tool:')} ${tool.charAt(0).toUpperCase() + tool.slice(1)}`);\n\n // ── Status-only mode ────────────────────────────────────────────────\n if (options.status) {\n showCredentialStatus(tool);\n console.log('');\n return;\n }\n\n // ── Setup mode ──────────────────────────────────────────────────────\n if (options.setup) {\n await quickSetup(tool);\n console.log('');\n return;\n }\n\n // ── Non-interactive test mode ───────────────────────────────────────\n if (options.test) {\n showCredentialStatus(tool);\n\n console.log('');\n console.log(UI.section('Connection Test', '🔌'));\n console.log('');\n\n const client = getProjectManagementClient();\n const result = await client.testConnection();\n renderTestResult(result);\n\n if (result.success) {\n testTicketExtraction();\n }\n\n // Fetch specific ticket if requested\n if (options.ticket && result.success) {\n const spinner = UI.spinner(`Fetching ${options.ticket} from ${tool}...`);\n spinner.start();\n try {\n const ticket = await client.getTicket(options.ticket);\n spinner.stop();\n if (ticket) {\n console.log('');\n console.log(\n colors.success(` ${ASCII.status.check} Ticket found: [${ticket.id}] ${ticket.title}`)\n );\n } else {\n console.log('');\n console.log(\n colors.warning(` ${ASCII.status.warning} Ticket \"${options.ticket}\" not found`)\n );\n }\n } catch (err) {\n spinner.stop();\n console.log(colors.error(` ${ASCII.status.cross} Error: ${(err as Error).message}`));\n }\n }\n\n console.log('');\n process.exit(result.success ? 0 : 1);\n }\n\n // ── Full interactive mode ───────────────────────────────────────────\n\n // Step 1: Show credential status\n showCredentialStatus(tool);\n\n // Step 2: Check if setup is needed\n const missingFields =\n tool === 'github'\n ? []\n : tool === 'jira'\n ? new JiraClient().getMissingConfig()\n : new LinearClient().getMissingConfig();\n\n if (missingFields.length > 0) {\n console.log('');\n console.log(UI.warning(`Missing configuration: ${missingFields.join(', ')}`));\n\n const { wantSetup } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'wantSetup',\n message: 'Would you like to set up credentials now?',\n default: true,\n },\n ]);\n\n if (wantSetup) {\n const didSetup = await quickSetup(tool);\n if (!didSetup) {\n console.log('');\n return;\n }\n } else {\n console.log('');\n console.log(UI.info('Skipping setup. Run `devdaily connect --setup` later.'));\n console.log('');\n return;\n }\n }\n\n // Step 3: Test connection\n console.log('');\n console.log(UI.section('Connection Test', '🔌'));\n console.log('');\n\n const spinner = UI.spinner(`Testing ${tool} connection...`);\n spinner.start();\n\n // Re-create client to pick up any newly saved credentials\n // ConfigManager is a singleton so we need to get a fresh client\n const freshClient =\n tool === 'jira'\n ? new JiraClient()\n : tool === 'linear'\n ? new LinearClient()\n : new GitHubIssueClient();\n\n const result = await freshClient.testConnection();\n spinner.stop();\n\n renderTestResult(result);\n\n if (!result.success) {\n console.log('');\n console.log(UI.info('Fix the issue above and run `devdaily connect` again.'));\n console.log('');\n return;\n }\n\n // Step 4: Test ticket extraction patterns\n testTicketExtraction();\n\n // Step 5: Offer to fetch a sample ticket\n console.log('');\n const { wantTicketTest } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'wantTicketTest',\n message: 'Would you like to fetch a real ticket to verify?',\n default: true,\n },\n ]);\n\n if (wantTicketTest) {\n await trySampleTicket(tool);\n }\n\n // Step 6: Summary\n console.log('');\n console.log(UI.section('Summary', '📋'));\n console.log('');\n console.log(\n ` ${colors.success(ASCII.status.check)} ${tool.charAt(0).toUpperCase() + tool.slice(1)} integration is ${colors.success('ready')}`\n );\n console.log('');\n console.log(colors.muted(' DevDaily will now:'));\n console.log(colors.muted(' • Extract ticket IDs from your branches and commits'));\n console.log(colors.muted(' • Fetch ticket details to enrich standup & PR context'));\n console.log(colors.muted(' • Pass ticket info to Copilot for smarter summaries'));\n console.log('');\n console.log(\n colors.muted(' Try it:') +\n ` ${colors.accent('devdaily standup')} or ${colors.accent('devdaily pr')}`\n );\n console.log('');\n });\n","import { UI } from './renderer.js';\nimport { ASCII } from './ascii.js';\nimport { getConfig } from '../config/index.js';\n\nconst { colors } = UI;\n\ninterface CommandDef {\n name: string;\n aliases: string[];\n description: string;\n icon: string;\n options: Array<{\n flag: string;\n short?: string;\n description: string;\n default?: string;\n }>;\n examples: string[];\n}\n\nconst COMMANDS: CommandDef[] = [\n {\n name: 'standup',\n aliases: ['s', 'su', 'daily'],\n description: 'Generate standup notes from your recent commits',\n icon: ASCII.icons.standup,\n options: [\n { flag: '--days', short: '-d', description: 'Number of days to look back', default: '1' },\n {\n flag: '--format',\n short: '-f',\n description: 'Output format (markdown|slack|plain|json)',\n default: 'markdown',\n },\n { flag: '--ticket', short: '-t', description: 'Include specific ticket for context' },\n { flag: '--no-tickets', description: 'Skip fetching ticket context' },\n { flag: '--no-copy', description: 'Do not copy to clipboard' },\n { flag: '--author', short: '-a', description: 'Filter by author email' },\n ],\n examples: [\n 'devdaily standup',\n 'devdaily s -d 3',\n 'devdaily standup --ticket=PROJ-123',\n 'dd s # using alias',\n ],\n },\n {\n name: 'pr',\n aliases: ['p', 'pull'],\n description: 'Generate PR description from current branch',\n icon: ASCII.icons.pr,\n options: [\n {\n flag: '--base',\n short: '-b',\n description: 'Base branch to compare against',\n default: 'main',\n },\n { flag: '--create', short: '-c', description: 'Create PR on GitHub immediately' },\n { flag: '--draft', short: '-d', description: 'Create as draft PR' },\n { flag: '--ticket', short: '-t', description: 'Include specific ticket for context' },\n { flag: '--no-tickets', description: 'Skip fetching ticket context' },\n { flag: '--no-copy', description: 'Do not copy to clipboard' },\n ],\n examples: [\n 'devdaily pr',\n 'devdaily p --base=develop',\n 'devdaily pr --ticket=PROJ-123',\n 'devdaily pr -c -d # create draft PR',\n ],\n },\n {\n name: 'week',\n aliases: ['w', 'weekly'],\n description: 'Generate weekly work summary',\n icon: ASCII.icons.week,\n options: [\n { flag: '--last', short: '-l', description: 'Show last week instead of current week' },\n { flag: '--start', short: '-s', description: 'Custom start date (YYYY-MM-DD)' },\n { flag: '--no-tickets', description: 'Skip fetching closed tickets' },\n { flag: '--no-copy', description: 'Do not copy to clipboard' },\n ],\n examples: ['devdaily week', 'devdaily w --last', 'devdaily week --start=2026-02-01'],\n },\n {\n name: 'dash',\n aliases: ['d', 'dashboard'],\n description: 'Open interactive dashboard',\n icon: ASCII.icons.dash,\n options: [],\n examples: ['devdaily dash', 'devdaily d', 'dd # with alias'],\n },\n {\n name: 'init',\n aliases: [],\n description: 'Set up DevDaily (aliases, shell completions)',\n icon: ASCII.icons.init,\n options: [\n { flag: '--global', short: '-g', description: 'Install globally for all projects' },\n { flag: '--alias', description: 'Only set up shell alias (dd)' },\n { flag: '--completions', description: 'Only set up shell completions' },\n ],\n examples: ['devdaily init', 'devdaily init --global', 'devdaily init --alias'],\n },\n {\n name: 'config',\n aliases: ['cfg'],\n description: 'Manage configuration',\n icon: ASCII.icons.config,\n options: [\n { flag: '--edit', short: '-e', description: 'Open config in editor' },\n { flag: '--reset', description: 'Reset to defaults' },\n { flag: '--path', description: 'Show config file path' },\n ],\n examples: ['devdaily config', 'devdaily config --edit', 'devdaily config --path'],\n },\n {\n name: 'doctor',\n aliases: ['check', 'setup'],\n description: 'Check system requirements and fix issues',\n icon: '🩺',\n options: [{ flag: '--fix', description: 'Attempt to automatically fix issues' }],\n examples: ['devdaily doctor', 'devdaily doctor --fix', 'devdaily check'],\n },\n];\n\n/**\n * Render the main help screen\n */\nexport const renderMainHelp = (): string => {\n const lines: string[] = [];\n const config = getConfig();\n\n // Header\n if (config.ascii) {\n lines.push(colors.gradient(ASCII.logoSmall.trim(), ['cyan', 'blue', 'magenta']));\n } else {\n lines.push(colors.gradient('◆ devdaily', ['cyan', 'blue']));\n }\n lines.push('');\n lines.push(colors.muted(' Your AI-powered developer memory'));\n lines.push(colors.muted(' Auto-generate standup notes, PR descriptions, and weekly summaries'));\n lines.push('');\n\n // Usage\n lines.push(colors.bold('USAGE'));\n lines.push('');\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('devdaily')} ${colors.accent('<command>')} ${colors.muted('[options]')}`\n );\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('dd')} ${colors.accent('<command>')} ${colors.muted('[options]')} ${colors.muted('# with alias')}`\n );\n lines.push('');\n\n // Commands\n lines.push(colors.bold('COMMANDS'));\n lines.push('');\n\n COMMANDS.forEach((cmd) => {\n const aliases = cmd.aliases.length > 0 ? colors.muted(` (${cmd.aliases.join(', ')})`) : '';\n const icon = colors.accent(cmd.icon);\n const name = colors.primary(cmd.name.padEnd(12));\n lines.push(` ${icon} ${name}${cmd.description}${aliases}`);\n });\n\n lines.push('');\n\n // Quick start\n lines.push(colors.bold('QUICK START'));\n lines.push('');\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('devdaily init')} ${colors.muted('# Set up aliases & completions')}`\n );\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('devdaily standup')} ${colors.muted(\"# Generate today's standup\")}`\n );\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('devdaily pr')} ${colors.muted('# Generate PR description')}`\n );\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('devdaily dash')} ${colors.muted('# Open interactive dashboard')}`\n );\n lines.push('');\n\n // Shortcuts hint\n lines.push(colors.bold('SHORTCUTS'));\n lines.push('');\n lines.push(\n ` ${colors.accent('[q]')} quit ${colors.accent('[?]')} help ${colors.accent('[r]')} refresh ${colors.accent('[c]')} copy ${colors.accent('[↵]')} select`\n );\n lines.push('');\n\n // Footer\n lines.push(colors.muted('─'.repeat(60)));\n lines.push('');\n lines.push(\n ` ${colors.muted('Run')} ${colors.primary('devdaily <command> --help')} ${colors.muted('for detailed command help')}`\n );\n lines.push(\n ` ${colors.muted('Docs:')} ${colors.accent.underline('https://github.com/hempun10/devdaily')}`\n );\n lines.push('');\n\n return lines.join('\\n');\n};\n\n/**\n * Render help for a specific command\n */\nexport const renderCommandHelp = (commandName: string): string | null => {\n const cmd = COMMANDS.find((c) => c.name === commandName || c.aliases.includes(commandName));\n\n if (!cmd) {\n return null;\n }\n\n const lines: string[] = [];\n\n // Header\n lines.push('');\n lines.push(`${colors.accent(cmd.icon)} ${colors.bold(colors.primary(cmd.name))}`);\n lines.push(colors.muted(cmd.description));\n lines.push('');\n\n // Aliases\n if (cmd.aliases.length > 0) {\n lines.push(colors.bold('ALIASES'));\n lines.push('');\n lines.push(` ${cmd.aliases.map((a) => colors.accent(a)).join(', ')}`);\n lines.push('');\n }\n\n // Usage\n lines.push(colors.bold('USAGE'));\n lines.push('');\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('devdaily')} ${colors.accent(cmd.name)} ${colors.muted('[options]')}`\n );\n lines.push('');\n\n // Options\n if (cmd.options.length > 0) {\n lines.push(colors.bold('OPTIONS'));\n lines.push('');\n\n cmd.options.forEach((opt) => {\n const shortStr = opt.short ? `${colors.accent(opt.short)}, ` : ' ';\n const flagStr = colors.accent(opt.flag.padEnd(16));\n const defaultStr = opt.default ? colors.muted(` [default: ${opt.default}]`) : '';\n lines.push(` ${shortStr}${flagStr} ${opt.description}${defaultStr}`);\n });\n lines.push('');\n }\n\n // Examples\n if (cmd.examples.length > 0) {\n lines.push(colors.bold('EXAMPLES'));\n lines.push('');\n cmd.examples.forEach((ex) => {\n lines.push(` ${colors.muted('$')} ${colors.primary(ex)}`);\n });\n lines.push('');\n }\n\n return lines.join('\\n');\n};\n\n/**\n * Get all command names and aliases for validation\n */\nexport const getAllCommandNames = (): string[] => {\n return COMMANDS.flatMap((cmd) => [cmd.name, ...cmd.aliases]);\n};\n\n/**\n * Get command definition\n */\nexport const getCommand = (name: string): CommandDef | undefined => {\n return COMMANDS.find((c) => c.name === name || c.aliases.includes(name));\n};\n\nexport { COMMANDS };\n"],"mappings":"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","names":["Command","execa","execa","execa","config","config","execa","TICKET_PATTERNS","execa","join","config","join","execa","config","colors","config","description","existsSync","readFileSync","writeFileSync","mkdirSync","homedir","join","existing","execa","config","existsSync","writeFileSync","readFileSync","mkdirSync","join","unlinkSync","colors","config","sendToSlack","sendToDiscord","inquirer","Command","readFile","access","join","fileExists","execa","execa","execa","colors","Command","config","execa","createSpinner","Command","colors","Command","config","genSpinner","summary","title","Command","colors","Command","config","Command","colors","Command","Command","colors","Command","config","stats","limit","Command","existsSync","readFileSync","appendFileSync","writeFileSync","homedir","join","inquirer","colors","join","homedir","existsSync","readFileSync","appendFileSync","Command","inquirer","config","writeFileSync","Command","inquirer","Command","config","inquirer","Command","inquirer","colors","config","Command","Command","execa","colors","execa","Command","Command","inquirer","colors","config","inquirer","Command","result","spinner","colors","config","colors","require","Command"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/standup.ts","../src/core/git-analyzer.ts","../src/core/copilot.ts","../src/core/github.ts","../src/core/project-management.ts","../src/config/index.ts","../src/config/schema.ts","../src/core/pm-errors.ts","../src/core/context-analyzer.ts","../src/core/standup-context.ts","../src/core/pr-prompt.ts","../src/utils/formatter.ts","../src/core/notifications.ts","../src/ui/renderer.ts","../src/ui/colors.ts","../src/ui/ascii.ts","../src/utils/helpers.ts","../src/core/work-journal.ts","../src/core/snapshot-builder.ts","../src/core/auto-snapshot.ts","../src/commands/pr.ts","../src/core/pr-template.ts","../src/core/github-repo.ts","../src/utils/commitlint.ts","../src/commands/week.ts","../src/commands/context.ts","../src/commands/snapshot.ts","../src/commands/recall.ts","../src/commands/init.ts","../src/commands/config.ts","../src/commands/dash.ts","../src/ui/keyboard.ts","../src/ui/dashboard.ts","../src/commands/doctor.ts","../src/commands/connect.ts","../src/ui/help.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { createRequire } from 'module';\nimport { standupCommand } from './commands/standup.js';\nimport { prCommand } from './commands/pr.js';\nimport { weekCommand } from './commands/week.js';\nimport { contextCommand } from './commands/context.js';\nimport { snapshotCommand } from './commands/snapshot.js';\nimport { recallCommand } from './commands/recall.js';\nimport { initCommand } from './commands/init.js';\nimport { configCommand } from './commands/config.js';\nimport { dashCommand } from './commands/dash.js';\nimport { doctorCommand } from './commands/doctor.js';\nimport { connectCommand } from './commands/connect.js';\nimport { renderMainHelp } from './ui/help.js';\nimport UI from './ui/renderer.js';\n\nconst { colors } = UI;\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../package.json');\n\nconst program = new Command();\n\n// Configure program\nprogram\n .name('devdaily')\n .description('Your AI-powered developer memory')\n .version(pkg.version, '-v, --version', 'Show version number')\n .configureHelp({\n sortSubcommands: true,\n sortOptions: true,\n })\n .addHelpText('beforeAll', () => {\n return renderMainHelp();\n })\n .showHelpAfterError('Run `devdaily --help` for usage information');\n\n// Register commands\nprogram.addCommand(standupCommand);\nprogram.addCommand(prCommand);\nprogram.addCommand(weekCommand);\nprogram.addCommand(contextCommand);\nprogram.addCommand(snapshotCommand);\nprogram.addCommand(recallCommand);\nprogram.addCommand(initCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(dashCommand);\nprogram.addCommand(doctorCommand);\nprogram.addCommand(connectCommand);\n\n// Add aliases\nstandupCommand.alias('s').alias('su').alias('daily');\nprCommand.alias('p').alias('pull');\nweekCommand.alias('w').alias('weekly');\ncontextCommand.alias('ctx').alias('resume');\nsnapshotCommand.alias('snap').alias('save');\nrecallCommand.alias('search').alias('find');\ndoctorCommand.alias('check').alias('setup');\nconnectCommand.alias('pm').alias('link');\n\n// Default action (no command) - show help\nprogram.action(async () => {\n console.log(renderMainHelp());\n});\n\n// Error handling\nprogram.exitOverride((err) => {\n if (err.code === 'commander.unknownCommand') {\n console.log('');\n console.log(UI.error(`Unknown command`));\n console.log(UI.info('Run `devdaily --help` to see available commands'));\n process.exit(1);\n }\n // Don't throw for help - just exit cleanly\n if (err.code === 'commander.helpDisplayed' || err.code === 'commander.help') {\n process.exit(0);\n }\n throw err;\n});\n\n// Graceful shutdown\nprocess.on('SIGINT', () => {\n console.log('');\n console.log(UI.info('Interrupted'));\n process.exit(0);\n});\n\nprocess.on('uncaughtException', (error) => {\n console.log('');\n console.log(UI.error('An unexpected error occurred'));\n console.log(colors.muted(error.message));\n process.exit(1);\n});\n\n// Parse and execute\nprogram.parse();\n","import { Command } from 'commander';\nimport { GitAnalyzer } from '../core/git-analyzer.js';\nimport { CopilotClient } from '../core/copilot.js';\nimport {\n StandupContextBuilder,\n type StandupContext,\n type StandupContextOptions,\n} from '../core/standup-context.js';\nimport { sendNotification, formatStandupNotification } from '../core/notifications.js';\nimport UI from '../ui/renderer.js';\nimport { copyToClipboard } from '../utils/helpers.js';\nimport { formatOutput, validateFormat } from '../utils/formatter.js';\nimport { getConfig } from '../config/index.js';\nimport { sideEffectSnapshot } from '../core/auto-snapshot.js';\n\nconst { colors } = UI;\n\nexport const standupCommand = new Command('standup')\n .description('Generate standup notes from your recent commits, PRs, and tickets')\n .option('-d, --days <number>', 'Number of days to look back', '1')\n .option('-f, --format <type>', 'Output format (markdown|slack|plain|json)', 'markdown')\n .option('-a, --author <email>', 'Filter by author email')\n .option('-t, --ticket <id...>', 'Include specific ticket/issue IDs for context')\n .option('--tone <type>', 'Output tone (engineering|mixed|business)', 'mixed')\n .option('--no-tickets', 'Skip fetching ticket/issue context')\n .option('--no-prs', 'Skip fetching PR context')\n .option('--no-copy', 'Do not copy to clipboard')\n .option('--debug', 'Show the full context and prompt sent to Copilot')\n .option('--preview', 'Show assembled context and ask for confirmation before generating')\n .option('--context', 'Show detailed work context analysis')\n .option('--raw-context', 'Output only the raw context block (no AI generation)')\n .option('--send', 'Send to configured notification channels (Slack/Discord)')\n .option('--slack', 'Send to Slack')\n .option('--discord', 'Send to Discord')\n .option('--test-webhook', 'Send a test message to configured Slack/Discord webhooks')\n .option('--no-journal', 'Skip auto-saving a snapshot to the journal')\n .action(async (options) => {\n const config = getConfig();\n\n // ── Test webhook mode ──────────────────────────────────────────────\n if (options.testWebhook) {\n console.log('');\n console.log(UI.section('Webhook Test'));\n console.log('');\n\n const testMessage = formatStandupNotification(\n '🧪 *Test message from DevDaily*\\n\\nIf you can see this, your webhook is configured correctly!\\n\\n• Slack: ✅ Connected\\n• Discord: ✅ Connected\\n• Timestamp: ' +\n new Date().toLocaleString(),\n [{ id: 'TEST-001', url: 'https://github.com', title: 'Sample ticket link' }]\n );\n\n const sendToSlack = options.slack || (!options.slack && !options.discord);\n const sendToDiscord = options.discord || (!options.slack && !options.discord);\n\n let anySuccess = false;\n let anyFailure = false;\n\n if (sendToSlack) {\n try {\n const result = await sendNotification(testMessage, { slack: true, discord: false });\n if (result.slack) {\n console.log(UI.success('Slack webhook test passed! Check your channel.'));\n anySuccess = true;\n } else if (result.slack === false) {\n console.log(UI.error('Slack webhook test failed. The request was rejected.'));\n anyFailure = true;\n }\n } catch (err) {\n console.log(UI.error(`Slack webhook test failed: ${(err as Error).message}`));\n anyFailure = true;\n }\n }\n\n if (sendToDiscord) {\n try {\n const result = await sendNotification(testMessage, { slack: false, discord: true });\n if (result.discord) {\n console.log(UI.success('Discord webhook test passed! Check your channel.'));\n anySuccess = true;\n } else if (result.discord === false) {\n console.log(UI.error('Discord webhook test failed. The request was rejected.'));\n anyFailure = true;\n }\n } catch (err) {\n console.log(UI.error(`Discord webhook test failed: ${(err as Error).message}`));\n anyFailure = true;\n }\n }\n\n if (!anySuccess && !anyFailure) {\n console.log(UI.warning('No webhooks configured. Run: devdaily init --notifications'));\n }\n\n console.log('');\n if (anyFailure) {\n console.log(UI.info('Troubleshooting:'));\n console.log(\n colors.muted(' 1. Check your webhook URL in .devdaily.secrets.json or config')\n );\n console.log(colors.muted(' 2. Slack: https://api.slack.com/apps → Incoming Webhooks'));\n console.log(colors.muted(' 3. Discord: Server Settings → Integrations → Webhooks'));\n console.log(colors.muted(' 4. Re-run: devdaily init --notifications'));\n }\n console.log('');\n return;\n }\n\n const git = new GitAnalyzer();\n const isDebug = options.debug || process.env.DEVD_DEBUG === '1';\n const copilot = new CopilotClient({ debug: isDebug });\n\n // Check if in git repo\n if (!(await git.isRepository())) {\n console.log(UI.error('Not a git repository'));\n console.log(UI.info('Run this command inside a git repository'));\n process.exit(1);\n }\n\n // Check if Copilot CLI is installed (unless raw-context mode)\n if (!options.rawContext && !(await copilot.isInstalled())) {\n console.log(UI.error('GitHub Copilot CLI not found'));\n console.log(UI.info('Install with: gh extension install github/gh-copilot'));\n process.exit(1);\n }\n\n const spinner = UI.spinner('Gathering work context...');\n spinner.start();\n\n try {\n const days = parseInt(options.days, 10) || config.standup.defaultDays;\n const tone = validateTone(options.tone);\n\n // ── Phase 1: Build rich context ──────────────────────────────────────\n spinner.text = 'Analyzing git history...';\n\n const contextBuilder = new StandupContextBuilder();\n const contextOptions: StandupContextOptions = {\n days,\n author: options.author,\n ticketIds: options.ticket,\n skipTickets: options.tickets === false,\n skipPRs: options.prs === false,\n baseBranch: config.git.defaultBranch,\n debug: isDebug,\n };\n\n // Update spinner as we gather data\n const originalBuild = contextBuilder.build.bind(contextBuilder);\n spinner.text = 'Fetching commits, PRs, and tickets...';\n\n const ctx: StandupContext = await originalBuild(contextOptions);\n\n // Check if we have any data\n if (ctx.commits.length === 0 && ctx.pullRequests.length === 0) {\n spinner.stop();\n console.log('');\n console.log(UI.warning(`No commits or PRs found in the last ${days} day(s)`));\n console.log(UI.info(`Try: devdaily standup --days=${days + 1}`));\n process.exit(0);\n }\n\n spinner.stop();\n\n // ── Debug mode: show full context ──────────────────────────────────\n if (isDebug) {\n console.log('');\n console.log(colors.accent('─── Debug: Assembled Context ───'));\n console.log(StandupContextBuilder.formatDebugSummary(ctx));\n console.log('');\n console.log(colors.accent('─── Debug: Full Prompt Context Block ───'));\n console.log(colors.muted(StandupContextBuilder.formatForPrompt(ctx)));\n console.log('');\n }\n\n // ── Context analysis mode ──────────────────────────────────────────\n if (options.context) {\n printContextAnalysis(ctx);\n }\n\n // ── Raw context mode: just output the context block ────────────────\n if (options.rawContext) {\n console.log('');\n console.log(StandupContextBuilder.formatForPrompt(ctx));\n return;\n }\n\n // ── Preview mode: show context and ask for confirmation ────────────\n if (options.preview) {\n console.log('');\n console.log(UI.section('Assembled Context'));\n console.log('');\n printContextSummary(ctx);\n console.log('');\n\n const { default: inquirer } = await import('inquirer');\n const { proceed } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'proceed',\n message: 'Generate standup from this context?',\n default: true,\n },\n ]);\n\n if (!proceed) {\n console.log(UI.info('Aborted. You can adjust with --days, --ticket, --author flags.'));\n return;\n }\n }\n\n // ── Phase 2: Generate standup with AI ──────────────────────────────\n const genSpinner = UI.spinner('Generating standup with Copilot CLI...');\n genSpinner.start();\n\n const rawStandup = await copilot.generateStandupFromContext(ctx, tone);\n\n genSpinner.stop();\n\n // ── Phase 2.5: Apply output format ─────────────────────────────────\n const outputFormat = validateFormat(options.format || config.output.format || 'markdown');\n const formatted = formatOutput(rawStandup, outputFormat, {\n title: days === 1 ? 'Daily Standup' : `Work Summary (${days} days)`,\n commits: ctx.commits.length,\n prs: ctx.pullRequests.length,\n tickets: ctx.tickets.length,\n days,\n branch: ctx.branch,\n repo: ctx.repo.name ?? undefined,\n });\n\n const standup = formatted.text;\n\n // ── Phase 3: Output ────────────────────────────────────────────────\n const title = days === 1 ? 'Your Standup' : `Your Work (Last ${days} Days)`;\n\n if (outputFormat === 'json') {\n // JSON format: print raw JSON without the box decoration\n console.log('');\n console.log(standup);\n } else {\n console.log('');\n console.log(UI.box(standup, title));\n }\n\n // Stats bar\n if (config.output.showStats) {\n const statItems: { label: string; value: string | number }[] = [\n { label: 'commits', value: ctx.commits.length },\n { label: 'days', value: days },\n ];\n if (ctx.pullRequests.length > 0) {\n statItems.push({ label: 'PRs', value: ctx.pullRequests.length });\n }\n if (ctx.tickets.length > 0) {\n statItems.push({ label: 'tickets', value: ctx.tickets.length });\n }\n if (ctx.categories.length > 0) {\n statItems.push({\n label: 'primary area',\n value: ctx.categories[0].name,\n });\n }\n if (ctx.diffStats) {\n statItems.push({\n label: 'changes',\n value: `+${ctx.diffStats.insertions}/-${ctx.diffStats.deletions}`,\n });\n }\n console.log(UI.stats(statItems));\n }\n console.log('');\n\n // ── Copy to clipboard ──────────────────────────────────────────────\n if (options.copy && config.output.copyToClipboard !== false) {\n await copyToClipboard(standup);\n const formatLabel = outputFormat !== 'markdown' ? ` (${outputFormat})` : '';\n console.log(UI.success(`Copied to clipboard${formatLabel}`));\n }\n\n // ── Send to notifications ──────────────────────────────────────────\n if (options.send || options.slack || options.discord) {\n const ticketLinks = ctx.tickets.map((t) => ({\n id: t.id,\n url: t.url,\n title: t.title,\n }));\n\n const notification = formatStandupNotification(standup, ticketLinks);\n\n const sendToSlack = options.slack || options.send;\n const sendToDiscord = options.discord || options.send;\n\n const results = await sendNotification(notification, {\n slack: sendToSlack,\n discord: sendToDiscord,\n });\n\n if (results.slack) {\n console.log(UI.success('Sent to Slack'));\n }\n if (results.discord) {\n console.log(UI.success('Sent to Discord'));\n }\n if (results.slack === false || results.discord === false) {\n console.log(\n UI.warning('Some notifications failed to send. Check your webhook configuration.')\n );\n }\n }\n\n // ── Auto-snapshot side-effect ──────────────────────────────────────\n if (options.journal !== false) {\n await sideEffectSnapshot({\n source: 'standup',\n note: `Standup generated (${ctx.commits.length} commits, ${days} day${days !== 1 ? 's' : ''})`,\n debug: isDebug,\n });\n }\n } catch (error) {\n spinner.stop();\n console.log('');\n console.log(UI.error('Failed to generate standup'));\n console.log(colors.muted((error as Error).message));\n\n if (isDebug && error instanceof Error && error.stack) {\n console.log('');\n console.log(colors.muted('Stack trace:'));\n console.log(colors.muted(error.stack));\n }\n\n process.exit(1);\n }\n });\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction validateTone(tone: string): 'engineering' | 'mixed' | 'business' {\n const valid = ['engineering', 'mixed', 'business'];\n if (valid.includes(tone)) {\n return tone as 'engineering' | 'mixed' | 'business';\n }\n console.log(UI.warning(`Invalid tone \"${tone}\". Using \"mixed\". Options: ${valid.join(', ')}`));\n return 'mixed';\n}\n\n/**\n * Print a compact summary of the assembled context\n */\nfunction printContextSummary(ctx: StandupContext): void {\n // Commits\n console.log(` ${colors.accent('Commits:')} ${ctx.commits.length}`);\n for (const c of ctx.commits.slice(0, 8)) {\n console.log(` ${colors.muted(`[${c.shortHash}]`)} ${c.message.slice(0, 70)}`);\n }\n if (ctx.commits.length > 8) {\n console.log(` ${colors.muted(`... and ${ctx.commits.length - 8} more`)}`);\n }\n\n // PRs\n if (ctx.pullRequests.length > 0) {\n console.log('');\n console.log(` ${colors.accent('Pull Requests:')} ${ctx.pullRequests.length}`);\n for (const pr of ctx.pullRequests) {\n const state = pr.state === 'open' ? colors.success('open') : colors.muted(pr.state);\n console.log(` PR #${pr.number} ${pr.title.slice(0, 55)} (${state})`);\n }\n }\n\n // Tickets\n if (ctx.tickets.length > 0) {\n console.log('');\n console.log(` ${colors.accent('Tickets:')} ${ctx.tickets.length}`);\n for (const t of ctx.tickets) {\n console.log(` ${t.id}: ${t.title.slice(0, 55)} [${t.status}]`);\n }\n } else if (ctx.ticketIds.length > 0) {\n console.log('');\n console.log(` ${colors.accent('Ticket IDs found:')} ${ctx.ticketIds.join(', ')}`);\n console.log(` ${colors.muted('(details not fetched — PM tool may not be configured)')}`);\n }\n\n // Diff stats\n if (ctx.diffStats) {\n console.log('');\n console.log(\n ` ${colors.accent('Changes:')} ${ctx.diffStats.filesChanged} files, ` +\n `${colors.success(`+${ctx.diffStats.insertions}`)} / ` +\n `${colors.error(`-${ctx.diffStats.deletions}`)}`\n );\n }\n\n // Top files\n if (ctx.topChangedFiles.length > 0) {\n console.log('');\n console.log(` ${colors.accent('Top changed files:')}`);\n for (const f of ctx.topChangedFiles.slice(0, 5)) {\n const freq = f.frequency > 1 ? ` ${colors.muted(`(${f.frequency}x)`)}` : '';\n console.log(` ${f.path}${freq}`);\n }\n }\n}\n\n/**\n * Print full context analysis (--context flag)\n */\nfunction printContextAnalysis(ctx: StandupContext): void {\n console.log('');\n console.log(UI.section('Work Context Analysis'));\n console.log('');\n\n // Branch & repo\n if (ctx.repo.name) {\n console.log(` ${colors.accent('Repository:')} ${ctx.repo.name}`);\n }\n console.log(` ${colors.accent('Branch:')} ${ctx.branch}`);\n console.log(\n ` ${colors.accent('Period:')} ${ctx.timeRange.since.toLocaleDateString()} → ${ctx.timeRange.until.toLocaleDateString()} (${ctx.timeRange.durationHours}h)`\n );\n console.log('');\n\n // Commits\n console.log(` ${colors.accent('Commits:')} ${ctx.commits.length}`);\n for (const c of ctx.commits) {\n const files = c.filesChanged ? ` (${c.filesChanged.length} files)` : '';\n console.log(` ${colors.muted(c.shortHash)} ${c.message}${colors.muted(files)}`);\n }\n console.log('');\n\n // PRs\n if (ctx.pullRequests.length > 0) {\n console.log(` ${colors.accent('Pull Requests:')} ${ctx.pullRequests.length}`);\n for (const pr of ctx.pullRequests) {\n console.log(` #${pr.number} ${pr.title} (${pr.state}) → ${pr.baseBranch}`);\n if (pr.linkedTickets.length > 0) {\n console.log(` ${colors.muted(`Linked: ${pr.linkedTickets.join(', ')}`)}`);\n }\n }\n console.log('');\n }\n\n // Tickets\n if (ctx.tickets.length > 0) {\n console.log(` ${colors.accent('Tickets:')}`);\n for (const t of ctx.tickets) {\n const priority = t.priority ? ` [${t.priority}]` : '';\n console.log(` ${t.id}: ${t.title} (${t.type}, ${t.status}${priority})`);\n }\n console.log('');\n }\n\n // Work categories\n if (ctx.categories.length > 0) {\n console.log(` ${colors.accent('Work Categories:')}`);\n for (const cat of ctx.categories.slice(0, 5)) {\n const barFilled = Math.round(cat.percentage / 5);\n const barEmpty = 20 - barFilled;\n const bar = '█'.repeat(barFilled) + '░'.repeat(barEmpty);\n console.log(` ${cat.name.padEnd(14)} ${bar} ${cat.percentage}%`);\n }\n console.log('');\n }\n\n // Diff stats\n if (ctx.diffStats) {\n console.log(\n ` ${colors.accent('Diff Stats:')} ${ctx.diffStats.filesChanged} files, ` +\n `+${ctx.diffStats.insertions}/-${ctx.diffStats.deletions} lines`\n );\n console.log('');\n }\n\n // Top changed files\n if (ctx.topChangedFiles.length > 0) {\n console.log(` ${colors.accent('Top Changed Files:')}`);\n for (const f of ctx.topChangedFiles.slice(0, 10)) {\n const freq = f.frequency > 1 ? ` ${colors.muted(`(touched in ${f.frequency} commits)`)}` : '';\n console.log(` ${f.path}${freq}`);\n }\n console.log('');\n }\n}\n","import simpleGit, { SimpleGit } from 'simple-git';\nimport { Commit, CommitOptions, DiffStats } from '../types';\n\nexport class GitAnalyzer {\n private git: SimpleGit;\n\n constructor(repoPath?: string) {\n this.git = simpleGit(repoPath || process.cwd());\n }\n\n /**\n * Get files changed in a specific commit by hash\n */\n async getCommitFiles(commitHash: string): Promise<string[]> {\n try {\n const result = await this.git.raw([\n 'diff-tree',\n '--no-commit-id',\n '--name-only',\n '-r',\n commitHash,\n ]);\n return result.split('\\n').filter(Boolean);\n } catch {\n return [];\n }\n }\n\n async isRepository(): Promise<boolean> {\n try {\n await this.git.revparse(['--is-inside-work-tree']);\n return true;\n } catch {\n return false;\n }\n }\n\n async getCurrentBranch(): Promise<string> {\n const branch = await this.git.revparse(['--abbrev-ref', 'HEAD']);\n return branch.trim();\n }\n\n async getCommits(options: CommitOptions = {}): Promise<Commit[]> {\n const args: string[] = ['log'];\n\n if (options.since) {\n args.push(`--since=${options.since.toISOString()}`);\n }\n\n if (options.until) {\n args.push(`--until=${options.until.toISOString()}`);\n }\n\n if (options.author) {\n args.push(`--author=${options.author}`);\n }\n\n // Use unique delimiters for field and record separation\n // Body (%b) is last to handle multi-line content\n const FIELD_SEP = '<<<DD_FIELD>>>';\n const RECORD_SEP = '<<<DD_RECORD>>>';\n args.push(\n `--format=${RECORD_SEP}%H${FIELD_SEP}%s${FIELD_SEP}%an${FIELD_SEP}%ae${FIELD_SEP}%ai${FIELD_SEP}%b`\n );\n\n const result = await this.git.raw(args);\n\n if (!result || !result.trim()) {\n return [];\n }\n\n const commits = result\n .split(RECORD_SEP)\n .filter(Boolean)\n .map((record) => {\n const parts = record.trim().split(FIELD_SEP);\n if (parts.length < 5) {\n return null;\n }\n const [hash, message, author, _authorEmail, date, ...bodyParts] = parts;\n // Body might contain our delimiter if it has special content\n const body = bodyParts.join(FIELD_SEP).trim();\n return {\n hash: hash || '',\n message: message || '',\n author: author || '',\n date: new Date(date || Date.now()),\n body: body || undefined,\n } as Commit;\n })\n .filter((c): c is Commit => c !== null && !!c.message);\n\n return commits;\n }\n\n async getDiff(base: string = 'main', head: string = 'HEAD'): Promise<string> {\n const diff = await this.git.diff([`${base}...${head}`]);\n return diff;\n }\n\n async getDiffStats(base: string = 'main', head: string = 'HEAD'): Promise<DiffStats> {\n const diffSummary = await this.git.diffSummary([`${base}...${head}`]);\n\n return {\n filesChanged: diffSummary.files.length,\n insertions: diffSummary.insertions,\n deletions: diffSummary.deletions,\n };\n }\n\n async getChangedFiles(base: string = 'main', head: string = 'HEAD'): Promise<string[]> {\n const diff = await this.git.diff([`${base}...${head}`, '--name-only']);\n return diff.split('\\n').filter(Boolean);\n }\n\n /**\n * Get files changed in recent commits (fallback when diff fails)\n */\n async getFilesFromCommits(options: CommitOptions = {}): Promise<string[]> {\n const args: string[] = ['log', '--name-only', '--pretty=format:'];\n\n if (options.since) {\n args.push(`--since=${options.since.toISOString()}`);\n }\n\n if (options.until) {\n args.push(`--until=${options.until.toISOString()}`);\n }\n\n if (options.author) {\n args.push(`--author=${options.author}`);\n }\n\n const result = await this.git.raw(args);\n const files = result\n .split('\\n')\n .filter(Boolean)\n .filter((f) => !f.startsWith('commit '));\n\n // Deduplicate\n return [...new Set(files)];\n }\n\n async getCurrentUser(): Promise<{ name: string; email: string }> {\n const name = await this.git.getConfig('user.name');\n const email = await this.git.getConfig('user.email');\n\n return {\n name: name.value || '',\n email: email.value || '',\n };\n }\n\n async getStatus(): Promise<{ modified: string[]; untracked: string[] }> {\n const status = await this.git.status();\n\n return {\n modified: status.modified,\n untracked: status.not_added,\n };\n }\n\n async hasUncommittedChanges(): Promise<boolean> {\n const status = await this.git.status();\n return !status.isClean();\n }\n\n async getRepoRoot(): Promise<string> {\n const root = await this.git.revparse(['--show-toplevel']);\n return root.trim();\n }\n\n /**\n * Get a truncated diff suitable for AI context.\n *\n * Returns the full `git diff --stat` plus a truncated unified diff\n * (capped at `maxLines` lines) so the AI can see WHAT actually changed,\n * not just filenames.\n */\n async getDiffForAI(\n base: string = 'main',\n head: string = 'HEAD',\n maxLines: number = 200\n ): Promise<{ stat: string; diff: string; truncated: boolean }> {\n // 1. diff --stat (always short)\n let stat = '';\n try {\n stat = await this.git.raw(['diff', '--stat', `${base}...${head}`]);\n } catch {\n stat = '';\n }\n\n // 2. unified diff (may be huge — truncate)\n let rawDiff = '';\n let truncated = false;\n try {\n rawDiff = await this.git.raw(['diff', `${base}...${head}`]);\n } catch {\n rawDiff = '';\n }\n\n const lines = rawDiff.split('\\n');\n if (lines.length > maxLines) {\n truncated = true;\n rawDiff =\n lines.slice(0, maxLines).join('\\n') +\n `\\n\\n... (diff truncated — ${lines.length - maxLines} more lines)`;\n }\n\n return { stat: stat.trim(), diff: rawDiff.trim(), truncated };\n }\n\n /**\n * Auto-detect the repository's default branch.\n *\n * Strategy (in order of precedence):\n * 1. `git symbolic-ref refs/remotes/origin/HEAD` — works when the\n * remote HEAD has been fetched (most reliable for cloned repos).\n * 2. `gh repo view --json defaultBranchRef` — queries GitHub API via\n * the gh CLI (requires auth but always returns the correct value).\n * 3. Probe for common branch names (`main`, `master`, `develop`) by\n * checking if the remote-tracking ref exists.\n * 4. Fall back to `\"main\"` as a last resort.\n */\n async getDefaultBranch(): Promise<string> {\n // Strategy 1: git symbolic-ref\n try {\n const ref = await this.git.raw(['symbolic-ref', 'refs/remotes/origin/HEAD']);\n const branch = ref.trim().replace('refs/remotes/origin/', '');\n if (branch) return branch;\n } catch {\n // origin/HEAD not set — continue\n }\n\n // Strategy 2: gh CLI (GitHub only)\n try {\n const { execa } = await import('execa');\n const { stdout } = await execa('gh', ['repo', 'view', '--json', 'defaultBranchRef'], {\n timeout: 10000,\n });\n const data = JSON.parse(stdout);\n const branch = data?.defaultBranchRef?.name;\n if (branch) return branch;\n } catch {\n // gh not installed or not a GitHub repo — continue\n }\n\n // Strategy 3: probe common branch names on the remote\n const candidates = ['main', 'master', 'develop'];\n for (const candidate of candidates) {\n try {\n await this.git.raw(['rev-parse', '--verify', `refs/remotes/origin/${candidate}`]);\n return candidate;\n } catch {\n // branch doesn't exist on remote — try next\n }\n }\n\n // Strategy 4: ultimate fallback\n return 'main';\n }\n}\n","import { execa } from 'execa';\nimport { type Ticket } from './project-management.js';\nimport { type WorkContext } from './context-analyzer.js';\nimport { type StandupContext, StandupContextBuilder } from './standup-context.js';\nimport { type PRPromptConfig, formatPRPromptForAI } from './pr-prompt.js';\n\nexport interface IssueContext {\n number: number;\n title: string;\n type: string; // bug, feature, etc.\n description: string;\n}\n\nexport class CopilotClient {\n private copilotTypeCache: 'new' | 'legacy' | null | undefined = undefined;\n private debugMode: boolean;\n\n constructor(options?: { debug?: boolean }) {\n this.debugMode = options?.debug ?? process.env.DEVD_DEBUG === '1';\n }\n\n /**\n * Check if the new GitHub Copilot CLI is installed\n */\n async isInstalled(): Promise<boolean> {\n try {\n // Check for the new copilot CLI first\n await execa('copilot', ['--version']);\n return true;\n } catch {\n // Fallback: check for gh copilot extension (deprecated)\n try {\n await execa('gh', ['copilot', '--version']);\n return true;\n } catch {\n return false;\n }\n }\n }\n\n /**\n * Check which Copilot CLI is available\n */\n private async getCopilotType(): Promise<'new' | 'legacy' | null> {\n if (this.copilotTypeCache !== undefined) {\n return this.copilotTypeCache;\n }\n\n try {\n await execa('copilot', ['--version']);\n this.copilotTypeCache = 'new';\n } catch {\n try {\n await execa('gh', ['copilot', '--version']);\n this.copilotTypeCache = 'legacy';\n } catch {\n this.copilotTypeCache = null;\n }\n }\n\n return this.copilotTypeCache;\n }\n\n /**\n * Execute a prompt using the new Copilot CLI (non-interactive mode)\n */\n private async executeNewCopilot(prompt: string): Promise<string> {\n try {\n const { stdout } = await execa(\n 'copilot',\n ['-p', prompt, '--silent', '--no-ask-user', '--model', 'claude-sonnet-4'],\n {\n timeout: 120000, // 2 minute timeout\n env: {\n ...process.env,\n NO_COLOR: '1', // Disable color output for cleaner parsing\n },\n }\n );\n\n return this.parseOutput(stdout);\n } catch (error) {\n throw new Error(`Copilot CLI error: ${error}`);\n }\n }\n\n /**\n * Execute using the legacy gh copilot extension\n */\n private async executeLegacyCopilot(prompt: string): Promise<string> {\n try {\n const { stdout } = await execa('gh', ['copilot', 'suggest', '-t', 'shell', prompt]);\n return this.parseOutput(stdout);\n } catch (error) {\n throw new Error(`Legacy Copilot CLI error: ${error}`);\n }\n }\n\n async suggest(prompt: string): Promise<string> {\n if (this.debugMode) {\n console.log('\\n┌─── DEBUG: Prompt sent to Copilot ───────────────────┐');\n console.log(prompt);\n console.log('└─── END Prompt ──────────────────────────────────────┘\\n');\n }\n\n const copilotType = await this.getCopilotType();\n\n let result: string;\n if (copilotType === 'new') {\n result = await this.executeNewCopilot(prompt);\n } else if (copilotType === 'legacy') {\n result = await this.executeLegacyCopilot(prompt);\n } else {\n throw new Error(\n 'GitHub Copilot CLI is not installed. Install it with: brew install copilot-cli'\n );\n }\n\n if (this.debugMode) {\n console.log('\\n┌─── DEBUG: Raw Copilot response ─────────────────────┐');\n console.log(result);\n console.log('└─── END Response ───────────────────────────────────┘\\n');\n }\n\n return result;\n }\n\n async explain(code: string): Promise<string> {\n const copilotType = await this.getCopilotType();\n\n if (copilotType === 'new') {\n return this.executeNewCopilot(`Explain this code:\\n\\n${code}`);\n } else if (copilotType === 'legacy') {\n try {\n const { stdout } = await execa('gh', ['copilot', 'explain', code]);\n return this.parseOutput(stdout);\n } catch (error) {\n throw new Error(`Copilot CLI error: ${error}`);\n }\n } else {\n throw new Error(\n 'GitHub Copilot CLI is not installed. Install it with: brew install copilot-cli'\n );\n }\n }\n\n private parseOutput(raw: string): string {\n // Remove ANSI codes\n\n // eslint-disable-next-line no-control-regex\n const cleaned = raw.replace(/\\x1B\\[[0-9;]*[a-zA-Z]/g, '');\n\n // For the new Copilot CLI in silent mode, output is cleaner\n // Just trim and return\n const lines = cleaned.split('\\n');\n const relevantLines = lines.filter(\n (line) =>\n line.trim() &&\n !line.includes('Suggestion:') &&\n !line.includes('Explain command:') &&\n !line.includes('?') &&\n !line.startsWith('Session:') &&\n !line.startsWith('Model:') &&\n !line.startsWith('Duration:')\n );\n\n return relevantLines.join('\\n').trim();\n }\n\n /**\n * Format tickets into context string for AI\n */\n private formatTicketContext(tickets: Ticket[]): string {\n if (tickets.length === 0) return '';\n\n const ticketContexts = tickets.map((ticket) => {\n const raw =\n typeof ticket.description === 'string'\n ? ticket.description\n : ticket.description\n ? String(ticket.description)\n : '';\n const description = raw.slice(0, 200) || 'No description';\n const priority = ticket.priority ? ` (${ticket.priority})` : '';\n\n return ` - ${ticket.id} [${ticket.type}${priority}]: ${ticket.title}\\n Context: ${description}`;\n });\n\n return `\\nRelated Tickets/Tasks (for context on WHY these changes were made):\\n${ticketContexts.join('\\n')}`;\n }\n\n /**\n * Format work context into prompt context\n */\n private formatWorkContext(context?: Partial<WorkContext>): string {\n if (!context) return '';\n\n const lines: string[] = ['Work Context:'];\n\n if (context.tickets && context.tickets.length > 0) {\n lines.push(` Tickets: ${context.tickets.map((t) => t.id).join(', ')}`);\n }\n\n if (context.categories && context.categories.length > 0) {\n const cats = context.categories.slice(0, 3).map((c) => `${c.name} (${c.percentage}%)`);\n lines.push(` Work areas: ${cats.join(', ')}`);\n }\n\n if (context.filesChanged) {\n lines.push(` Files changed: ${context.filesChanged.length}`);\n }\n\n if (context.branch) {\n lines.push(` Branch: ${context.branch}`);\n }\n\n if (context.authors && context.authors.length > 1) {\n lines.push(` Contributors: ${context.authors.join(', ')}`);\n }\n\n if (context.timeRange) {\n lines.push(` Duration: ${context.timeRange.durationHours} hours`);\n }\n\n return '\\n' + lines.join('\\n');\n }\n\n /**\n * Generate standup from rich structured context (new approach).\n * Uses StandupContextBuilder's factual prompt instead of loose commit messages.\n */\n async generateStandupFromContext(\n ctx: StandupContext,\n tone: 'engineering' | 'mixed' | 'business' = 'mixed'\n ): Promise<string> {\n const prompt = StandupContextBuilder.buildStandupPrompt(ctx, tone);\n return this.suggest(prompt);\n }\n\n /**\n * Generate weekly summary from rich structured context (new approach).\n */\n async generateWeeklyFromContext(ctx: StandupContext): Promise<string> {\n const prompt = StandupContextBuilder.buildWeeklyPrompt(ctx);\n return this.suggest(prompt);\n }\n\n /**\n * Generate output from a pre-built prompt string.\n * Useful for custom prompt flows (debug, preview, etc.).\n */\n async generateFromPrompt(prompt: string): Promise<string> {\n return this.suggest(prompt);\n }\n\n /**\n * @deprecated Use generateStandupFromContext() for accurate results.\n * Kept for backwards compatibility.\n */\n async summarizeCommits(\n commits: string[],\n tickets: Ticket[] = [],\n workContext?: WorkContext\n ): Promise<string> {\n const ticketContext = this.formatTicketContext(tickets);\n const contextInfo = this.formatWorkContext(workContext);\n\n // Extract ticket IDs from work context to ensure they're mentioned\n const ticketIds =\n workContext?.tickets.map((t) => t.id).join(', ') ||\n (tickets.length > 0 ? tickets.map((t) => t.id).join(', ') : '');\n\n // Build work areas string\n const workAreas =\n workContext?.categories\n .slice(0, 2)\n .map((c) => c.name)\n .join(', ') || '';\n\n const prompt = `\nYou are helping a developer write their daily standup update for a team meeting.\nThis will be shared with both technical and non-technical team members (managers, PMs, stakeholders).\n\nHere are their git commits from yesterday:\n${commits.map((c, i) => `${i + 1}. ${c}`).join('\\n')}\n${ticketContext}\n${contextInfo}\n\nWrite a friendly, conversational standup update that anyone can understand.\n\nFormat:\nYesterday I worked on:\n• [what you accomplished in plain language]${ticketIds ? ` (include ticket references like ${ticketIds})` : ''}\n• [another accomplishment - focus on the outcome/value, not technical details]\n• [if relevant, mention any collaboration or team impact]\n\nToday I'm planning to:\n• [what you'll be focusing on]\n• [any continuation of work or new items]\n\nBlockers: None (or describe any challenges)\n\nGuidelines:\n- Write in a warm, natural tone - like you're talking to a colleague\n- Explain technical work in terms of user impact or business value\n - Instead of \"Fixed null pointer exception in auth module\"\n - Say \"Fixed a login issue that was causing some users to get stuck\"\n- Instead of \"Implemented REST API endpoint for user preferences\"\n - Say \"Built the backend so users can now save their settings\"\n- Skip jargon like \"refactoring\", \"debugging\", \"endpoints\", \"modules\"\n- Focus on WHAT changed for users or the team, not HOW you coded it\n- Keep it brief and scannable (2-4 bullets per section)\n- Use the ticket context to explain the business purpose if available\n- Sound human and approachable, not robotic\n${ticketIds ? `- IMPORTANT: Reference these ticket IDs in your bullet points: ${ticketIds}` : ''}\n${workAreas ? `- The work was primarily in: ${workAreas}` : ''}\n`;\n\n return this.suggest(prompt);\n }\n\n async generatePRDescription(data: {\n branch: string;\n commits: string[];\n files: string[];\n issues: string[];\n ticketDetails?: Ticket[];\n /** git diff --stat output */\n diffStat?: string;\n /** Truncated unified diff for AI context */\n diff?: string;\n /** Raw PR template content for the AI to follow */\n templateContent?: string;\n /** Custom PR description prompt / team guidelines */\n promptConfig?: PRPromptConfig | null;\n }): Promise<string> {\n // Build ticket context\n let ticketContext = '';\n if (data.ticketDetails && data.ticketDetails.length > 0) {\n ticketContext = this.formatTicketContext(data.ticketDetails);\n }\n\n // Build ticket link references for the description footer\n const ticketLinks = this.buildTicketLinks(data.ticketDetails || [], data.issues);\n\n // Build diff context block\n const diffBlock = this.buildDiffBlock(data.diffStat, data.diff);\n\n // Build team guidelines block\n const guidelinesBlock = data.promptConfig ? formatPRPromptForAI(data.promptConfig) : '';\n\n // Build template guidance block\n const templateBlock = data.templateContent\n ? `\\n=== PR TEMPLATE (follow this structure) ===\\n${data.templateContent}\\n=== END PR TEMPLATE ===\\n`\n : '';\n\n const prompt = `\nYou are an expert developer helping create a Pull Request description.\nYour job is to write a clear, accurate, reviewer-friendly PR description.\n\nBranch: ${data.branch}\n\nCommits:\n${data.commits.map((c, i) => `${i + 1}. ${c}`).join('\\n')}\n\nFiles changed:\n${data.files.slice(0, 40).join('\\n')}${data.files.length > 40 ? `\\n... and ${data.files.length - 40} more files` : ''}\n${diffBlock}\nRelated tickets: ${data.issues.length > 0 ? data.issues.join(', ') : 'None'}\n${ticketContext}\n${templateBlock}\n${guidelinesBlock}\nGenerate a comprehensive PR description. ${data.templateContent ? 'Follow the PR template structure above.' : 'Use this structure:'}\n\n${\n !data.templateContent\n ? `## What Changed\n- [specific bullet points based on the ACTUAL diff and commits — do NOT invent changes]\n\n## Why\n[Business or technical reason — USE ticket context if available to explain the real value]\n\n## How to Test\n1. [concrete testing step]\n2. [another step]\n3. [verification step]`\n : ''\n}\n\n${ticketLinks ? `\\nInclude these ticket references at the end of the description:\\n${ticketLinks}` : ''}\n\nRequirements:\n- Be specific and technical — reference actual files, functions, and changes from the diff\n- NEVER invent or hallucinate changes that are not in the commits or diff\n- Use ticket descriptions to explain the WHY (business value)\n- Focus on value for code reviewers — what should they pay attention to?\n- Keep it clear and concise\n- No emojis in the body text\n`;\n\n return this.suggest(prompt);\n }\n\n /**\n * Generate structured PR content for filling templates\n */\n async generatePRContent(data: {\n branch: string;\n commits: string[];\n files: string[];\n issues: string[];\n ticketDetails?: Ticket[];\n templateSections?: string[];\n /** git diff --stat output */\n diffStat?: string;\n /** Truncated unified diff for AI context */\n diff?: string;\n /** Raw PR template content for the AI to understand section expectations */\n templateContent?: string;\n /** Custom PR description prompt / team guidelines */\n promptConfig?: PRPromptConfig | null;\n }): Promise<{\n title: string;\n description: string;\n type: string;\n impact: string;\n testing: string;\n breakingChanges: string;\n additionalInfo: string;\n }> {\n // Build ticket context\n let ticketContext = '';\n if (data.ticketDetails && data.ticketDetails.length > 0) {\n ticketContext = this.formatTicketContext(data.ticketDetails);\n }\n\n // Build diff context block\n const diffBlock = this.buildDiffBlock(data.diffStat, data.diff);\n\n // Build team guidelines block\n const guidelinesBlock = data.promptConfig ? formatPRPromptForAI(data.promptConfig) : '';\n\n // Build template guidance block\n const templateBlock = data.templateContent\n ? `\\nThe PR template used by this repo is:\\n---\\n${data.templateContent}\\n---\\nFill content that matches each section of this template.\\n`\n : '';\n\n // Build ticket link references\n const ticketLinks = this.buildTicketLinks(data.ticketDetails || [], data.issues);\n\n const prompt = `\nYou are an expert developer helping create a Pull Request. Analyze the ACTUAL changes and generate content.\n\nBranch: ${data.branch}\n\nCommits:\n${data.commits.map((c, i) => `${i + 1}. ${c}`).join('\\n')}\n\nFiles changed:\n${data.files.slice(0, 40).join('\\n')}${data.files.length > 40 ? `\\n... and ${data.files.length - 40} more files` : ''}\n${diffBlock}\nRelated tickets: ${data.issues.length > 0 ? data.issues.join(', ') : 'None'}\n${ticketContext}\n${templateBlock}\n${guidelinesBlock}\n${data.templateSections ? `Template sections to fill: ${data.templateSections.join(', ')}` : ''}\n\nGenerate a JSON object with the following fields (respond with ONLY the JSON, no markdown):\n\n{\n \"title\": \"A concise PR title following conventional commit format (e.g., 'feat: add user authentication')\",\n \"description\": \"2-4 bullet points describing WHAT changed — be specific, reference actual files/functions from the diff. NEVER invent changes.${ticketLinks ? ` Include ticket references: ${ticketLinks}` : ''}\",\n \"type\": \"One of: feat, fix, docs, refactor, test, chore, hotfix, security, style\",\n \"impact\": \"1-2 sentences about the impact of these changes. Use ticket context for business value if available.\",\n \"testing\": \"2-3 numbered steps on how to test these changes — be specific about what to verify\",\n \"breakingChanges\": \"Description of breaking changes, or 'None'\",\n \"additionalInfo\": \"Any additional context reviewers should know, or 'None'\"\n}\n\nIMPORTANT:\n- Base your output strictly on the commits, files, and diff provided. Do NOT hallucinate.\n- Reference actual file paths and function names where relevant.\n- Use ticket context to explain the business WHY, not just the technical WHAT.\n`;\n\n const response = await this.suggest(prompt);\n\n // Parse JSON from response\n try {\n // Try to extract JSON from the response\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n return JSON.parse(jsonMatch[0]);\n }\n } catch {\n // If parsing fails, return default structure\n }\n\n // Fallback: generate simple content\n return {\n title: this.generateSimpleTitle(data.commits),\n description: data.commits\n .slice(0, 5)\n .map((c) => `- ${c}`)\n .join('\\n'),\n type: this.detectPRType(data.commits),\n impact: 'See commit messages for details.',\n testing: '1. Pull the branch\\n2. Run tests\\n3. Manual verification',\n breakingChanges: 'None',\n additionalInfo: 'None',\n };\n }\n\n /**\n * Build a diff context block for the AI prompt.\n * Includes both the --stat summary and truncated unified diff.\n */\n private buildDiffBlock(diffStat?: string, diff?: string): string {\n if (!diffStat && !diff) return '';\n\n const parts: string[] = [''];\n\n if (diffStat) {\n parts.push('Diff summary (git diff --stat):');\n parts.push(diffStat);\n parts.push('');\n }\n\n if (diff) {\n parts.push('Code changes (unified diff — use this to understand WHAT actually changed):');\n parts.push(diff);\n parts.push('');\n }\n\n return parts.join('\\n');\n }\n\n /**\n * Build ticket link references for inclusion in the PR description.\n * Generates \"Closes #ID\" for GitHub or full URLs for Jira/Linear.\n */\n private buildTicketLinks(tickets: Ticket[], issueIds: string[]): string {\n if (tickets.length === 0 && issueIds.length === 0) return '';\n\n const links: string[] = [];\n\n for (const ticket of tickets) {\n if (ticket.source === 'github') {\n links.push(`Closes ${ticket.id}`);\n } else if (ticket.url) {\n links.push(`Relates to [${ticket.id}](${ticket.url})`);\n } else {\n links.push(`Relates to ${ticket.id}`);\n }\n }\n\n // Add any issue IDs that didn't have a matching ticket object\n const ticketIdsFromObjects = new Set(tickets.map((t) => t.id));\n for (const id of issueIds) {\n if (!ticketIdsFromObjects.has(id)) {\n if (id.startsWith('#')) {\n links.push(`Closes ${id}`);\n } else {\n links.push(`Relates to ${id}`);\n }\n }\n }\n\n return links.join('\\n');\n }\n\n /**\n * Generate a simple title from commits\n */\n private generateSimpleTitle(commits: string[]): string {\n if (commits.length === 0) return 'Update';\n\n // Use the most recent commit as base\n const firstCommit = commits[0];\n\n // Extract conventional commit type and message\n const match = firstCommit.match(/^(\\w+)(?:\\([^)]+\\))?:\\s*(.+)/);\n if (match) {\n const [, type, message] = match;\n return `${type}: ${message}`;\n }\n\n return firstCommit.length > 60 ? firstCommit.slice(0, 57) + '...' : firstCommit;\n }\n\n /**\n * Detect PR type from commits\n */\n private detectPRType(commits: string[]): string {\n const types = commits.map((c) => {\n const match = c.match(/^(\\w+)(?:\\([^)]+\\))?:/);\n return match ? match[1] : 'chore';\n });\n\n // Return most common type\n const counts = types.reduce(\n (acc, type) => {\n acc[type] = (acc[type] || 0) + 1;\n return acc;\n },\n {} as Record<string, number>\n );\n\n return Object.entries(counts).sort((a, b) => b[1] - a[1])[0]?.[0] || 'chore';\n }\n\n /**\n * @deprecated Use generateWeeklyFromContext() for accurate results.\n * Kept for backwards compatibility.\n */\n async generateWeeklySummary(data: {\n commits: string[];\n stats: {\n commits: number;\n linesAdded: number;\n linesRemoved: number;\n };\n closedTickets?: Ticket[];\n }): Promise<string> {\n // Include closed tickets for better context\n let ticketContext = '';\n if (data.closedTickets && data.closedTickets.length > 0) {\n ticketContext = `\\nTickets/Tasks Completed This Week:\\n${data.closedTickets.map((t) => ` - ${t.id}: ${t.title} [${t.type}]`).join('\\n')}`;\n }\n\n const prompt = `\nYou are helping a developer create their weekly work summary.\n\nThis week's commits:\n${data.commits.map((c, i) => `${i + 1}. ${c}`).join('\\n')}\n${ticketContext}\n\nStatistics:\n- ${data.stats.commits} commits\n- ${data.stats.linesAdded} lines added\n- ${data.stats.linesRemoved} lines removed\n\nGenerate a professional weekly summary following this format:\n\nKey Accomplishments:\n1. [Major accomplishment with impact - reference ticket if relevant]\n2. [Second accomplishment]\n3. [Third accomplishment]\n4. [Fourth accomplishment]\n5. [Fifth accomplishment]\n\nTop Achievement:\n[Single sentence highlighting the most impactful work]\n\nRequirements:\n- Focus on business value and impact\n- Use ticket titles to give context on WHAT and WHY\n- Be suitable for sharing with manager or team\n- Highlight 3-5 key accomplishments\n- Keep it professional\n- No emojis\n`;\n\n return this.suggest(prompt);\n }\n\n /**\n * Check if debug mode is enabled\n */\n isDebugEnabled(): boolean {\n return this.debugMode;\n }\n}\n","import { execa } from 'execa';\n\nexport interface GitHubIssue {\n number: number;\n title: string;\n body: string;\n state: 'open' | 'closed';\n labels: string[];\n assignees: string[];\n milestone?: string;\n url: string;\n createdAt: string;\n closedAt?: string;\n}\n\nexport interface GitHubPR {\n number: number;\n title: string;\n body: string;\n state: 'open' | 'closed' | 'merged';\n labels: string[];\n url: string;\n baseBranch: string;\n headBranch: string;\n}\n\n/**\n * GitHub integration using the gh CLI\n * Fetches issues, PRs, and project context\n */\nexport class GitHubClient {\n /**\n * Check if we're in a GitHub repository\n */\n async isGitHubRepo(): Promise<boolean> {\n try {\n await execa('gh', ['repo', 'view', '--json', 'name,owner']);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Get repository info\n */\n async getRepoInfo(): Promise<{ owner: string; name: string; url: string } | null> {\n try {\n const { stdout } = await execa('gh', ['repo', 'view', '--json', 'name,owner,url']);\n const data = JSON.parse(stdout);\n return {\n owner: data.owner.login,\n name: data.name,\n url: data.url,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Fetch issue details by number\n */\n async getIssue(issueNumber: number): Promise<GitHubIssue | null> {\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'view',\n String(issueNumber),\n '--json',\n 'number,title,body,state,labels,assignees,milestone,url,createdAt,closedAt',\n ]);\n\n const data = JSON.parse(stdout);\n\n return {\n number: data.number,\n title: data.title,\n body: data.body || '',\n state: data.state.toLowerCase(),\n labels: data.labels?.map((l: { name: string }) => l.name) || [],\n assignees: data.assignees?.map((a: { login: string }) => a.login) || [],\n milestone: data.milestone?.title,\n url: data.url,\n createdAt: data.createdAt,\n closedAt: data.closedAt,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Fetch multiple issues by numbers\n */\n async getIssues(issueNumbers: number[]): Promise<GitHubIssue[]> {\n const issues: GitHubIssue[] = [];\n\n // Fetch in parallel but limit concurrency\n const batchSize = 5;\n for (let i = 0; i < issueNumbers.length; i += batchSize) {\n const batch = issueNumbers.slice(i, i + batchSize);\n const results = await Promise.all(batch.map((n) => this.getIssue(n)));\n issues.push(...results.filter((r): r is GitHubIssue => r !== null));\n }\n\n return issues;\n }\n\n /**\n * Get recent issues assigned to the current user\n */\n async getMyRecentIssues(limit: number = 10): Promise<GitHubIssue[]> {\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'list',\n '--assignee',\n '@me',\n '--limit',\n String(limit),\n '--json',\n 'number,title,body,state,labels,url,createdAt',\n ]);\n\n const data = JSON.parse(stdout);\n\n return data.map((issue: Record<string, unknown>) => ({\n number: issue.number,\n title: issue.title,\n body: issue.body || '',\n state: (issue.state as string).toLowerCase(),\n labels: ((issue.labels as Array<{ name: string }>) || []).map((l) => l.name),\n assignees: [],\n url: issue.url,\n createdAt: issue.createdAt,\n }));\n } catch {\n return [];\n }\n }\n\n /**\n * Get issues closed in the last N days\n */\n async getRecentlyClosedIssues(days: number = 7): Promise<GitHubIssue[]> {\n try {\n const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const sinceStr = since.toISOString().split('T')[0];\n\n const { stdout } = await execa('gh', [\n 'issue',\n 'list',\n '--state',\n 'closed',\n '--assignee',\n '@me',\n '--search',\n `closed:>=${sinceStr}`,\n '--json',\n 'number,title,body,state,labels,url,createdAt,closedAt',\n ]);\n\n const data = JSON.parse(stdout);\n\n return data.map((issue: Record<string, unknown>) => ({\n number: issue.number,\n title: issue.title,\n body: issue.body || '',\n state: 'closed',\n labels: ((issue.labels as Array<{ name: string }>) || []).map((l) => l.name),\n assignees: [],\n url: issue.url,\n createdAt: issue.createdAt,\n closedAt: issue.closedAt,\n }));\n } catch {\n return [];\n }\n }\n\n /**\n * Get PR details by number\n */\n async getPR(prNumber: number): Promise<GitHubPR | null> {\n try {\n const { stdout } = await execa('gh', [\n 'pr',\n 'view',\n String(prNumber),\n '--json',\n 'number,title,body,state,labels,url,baseRefName,headRefName',\n ]);\n\n const data = JSON.parse(stdout);\n\n return {\n number: data.number,\n title: data.title,\n body: data.body || '',\n state: data.state.toLowerCase(),\n labels: data.labels?.map((l: { name: string }) => l.name) || [],\n url: data.url,\n baseBranch: data.baseRefName,\n headBranch: data.headRefName,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Search issues by query\n */\n async searchIssues(query: string, limit: number = 10): Promise<GitHubIssue[]> {\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'list',\n '--search',\n query,\n '--limit',\n String(limit),\n '--json',\n 'number,title,body,state,labels,url,createdAt',\n ]);\n\n const data = JSON.parse(stdout);\n\n return data.map((issue: Record<string, unknown>) => ({\n number: issue.number,\n title: issue.title,\n body: issue.body || '',\n state: (issue.state as string).toLowerCase(),\n labels: ((issue.labels as Array<{ name: string }>) || []).map((l) => l.name),\n assignees: [],\n url: issue.url,\n createdAt: issue.createdAt,\n }));\n } catch {\n return [];\n }\n }\n\n /**\n * Format issue for display\n */\n formatIssue(issue: GitHubIssue): string {\n const lines: string[] = [];\n\n lines.push(`#${issue.number}: ${issue.title}`);\n\n if (issue.labels.length > 0) {\n lines.push(`Labels: ${issue.labels.join(', ')}`);\n }\n\n if (issue.body) {\n // Truncate body if too long\n const body = issue.body.length > 500 ? issue.body.slice(0, 500) + '...' : issue.body;\n lines.push('');\n lines.push(body);\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Format issue summary for AI context\n */\n formatIssueForContext(issue: GitHubIssue): string {\n const parts: string[] = [];\n\n parts.push(`Issue #${issue.number}: ${issue.title}`);\n\n if (issue.labels.length > 0) {\n const labelTypes = issue.labels.join(', ');\n parts.push(`Type: ${labelTypes}`);\n }\n\n if (issue.body) {\n // Extract first paragraph or acceptance criteria\n const body = issue.body;\n const firstParagraph = body.split('\\n\\n')[0].slice(0, 300);\n parts.push(`Description: ${firstParagraph}`);\n\n // Look for acceptance criteria\n const acMatch = body.match(/acceptance criteria[:\\s]*\\n([\\s\\S]*?)(?=\\n#|$)/i);\n if (acMatch) {\n parts.push(`Acceptance Criteria: ${acMatch[1].trim().slice(0, 200)}`);\n }\n }\n\n return parts.join('\\n');\n }\n}\n\n// Export singleton\nexport const github = new GitHubClient();\n","import { execa } from 'execa';\nimport { getConfig, getSecrets } from '../config/index.js';\nimport {\n PMAuthError,\n PMConfigError,\n PMConnectionError,\n PMNotFoundError,\n PMRateLimitError,\n PMResponseError,\n type PMConnectionTestResult,\n type PMTool,\n successResult,\n failureResult,\n} from './pm-errors.js';\n\n/**\n * Extract plain text from a Jira ADF (Atlassian Document Format) object.\n * Jira REST API v3 returns `description` as an ADF object, not a string.\n * This recursively walks the ADF tree and concatenates text nodes.\n */\nfunction extractAdfText(node: unknown): string {\n if (node == null) return '';\n if (typeof node === 'string') return node;\n if (typeof node !== 'object') return String(node);\n\n const obj = node as Record<string, unknown>;\n\n // Text node — return its text value\n if (obj.type === 'text' && typeof obj.text === 'string') {\n return obj.text;\n }\n\n // Container node — recurse into content array\n if (Array.isArray(obj.content)) {\n const parts: string[] = [];\n for (const child of obj.content) {\n parts.push(extractAdfText(child));\n }\n // Join paragraphs / blocks with newlines, inline text without separator\n const isBlock =\n obj.type === 'doc' ||\n obj.type === 'paragraph' ||\n obj.type === 'bulletList' ||\n obj.type === 'orderedList' ||\n obj.type === 'listItem' ||\n obj.type === 'blockquote' ||\n obj.type === 'codeBlock' ||\n obj.type === 'heading';\n return parts.join(isBlock ? '\\n' : '');\n }\n\n return '';\n}\n\n/**\n * Common interface for tickets/issues across different tools\n */\nexport interface Ticket {\n id: string; // e.g., \"PROJ-123\", \"ENG-456\"\n title: string;\n description: string;\n status: string;\n type: 'bug' | 'feature' | 'task' | 'story' | 'epic' | 'other';\n priority?: 'low' | 'medium' | 'high' | 'critical';\n assignee?: string;\n labels: string[];\n url: string;\n source: 'github' | 'jira' | 'linear' | 'notion';\n}\n\n/**\n * Default ticket patterns for different tools\n */\nconst TICKET_PATTERNS: Record<string, RegExp> = {\n // JIRA: PROJ-123, ABC-1\n jira: /\\b([A-Z][A-Z0-9]+-\\d+)\\b/gi,\n // Linear: ENG-123, DEV-1 (same format as Jira)\n linear: /\\b([A-Z][A-Z0-9]+-\\d+)\\b/gi,\n // GitHub: #123, gh-123\n github: /#(\\d+)\\b/g,\n // Notion: Uses UUIDs, harder to extract - typically linked\n notion: /\\b([a-f0-9]{32}|[a-f0-9-]{36})\\b/gi,\n};\n\n/**\n * Common branch naming patterns that contain ticket IDs\n */\nconst BRANCH_PATTERNS = [\n // feature/PROJ-123-description\n /^(?:feature|fix|bugfix|hotfix|chore|refactor|docs)\\/([A-Z][A-Z0-9]+-\\d+)/i,\n // PROJ-123/description or PROJ-123-description\n /^([A-Z][A-Z0-9]+-\\d+)[-/]/i,\n // feature/123-description (just number)\n /^(?:feature|fix|bugfix|hotfix|chore|refactor|docs)\\/(\\d+)[-/]/i,\n // user/PROJ-123-description\n /^[a-z0-9_-]+\\/([A-Z][A-Z0-9]+-\\d+)/i,\n];\n\n/**\n * Extract ticket IDs from text (branch name, commit message, etc.)\n */\nexport function extractTicketIds(\n text: string,\n options: {\n tool?: 'github' | 'jira' | 'linear' | 'notion';\n prefix?: string;\n customPattern?: string;\n } = {}\n): string[] {\n const config = getConfig();\n const tool = options.tool || config.projectManagement.tool;\n const prefix = options.prefix || config.projectManagement.ticketPrefix;\n const customPattern = options.customPattern || config.projectManagement.ticketPattern;\n\n const tickets = new Set<string>();\n\n // Use custom pattern if provided\n if (customPattern) {\n try {\n const regex = new RegExp(customPattern, 'gi');\n const matches = text.matchAll(regex);\n for (const match of matches) {\n tickets.add(match[1] || match[0]);\n }\n } catch {\n // Invalid regex, fall through to defaults\n }\n }\n\n // Use prefix-based pattern if provided\n if (prefix) {\n const prefixPattern = new RegExp(`\\\\b(${prefix}-\\\\d+)\\\\b`, 'gi');\n const matches = text.matchAll(prefixPattern);\n for (const match of matches) {\n tickets.add(match[1].toUpperCase());\n }\n }\n\n // Use tool-specific pattern\n if (tool && tool !== 'none' && TICKET_PATTERNS[tool]) {\n const pattern = TICKET_PATTERNS[tool];\n const matches = text.matchAll(pattern);\n for (const match of matches) {\n const ticketId = tool === 'github' ? `#${match[1]}` : match[1].toUpperCase();\n tickets.add(ticketId);\n }\n }\n\n return Array.from(tickets);\n}\n\n/**\n * Extract ticket ID from a branch name\n */\nexport function extractTicketFromBranch(branchName: string): string | null {\n const config = getConfig();\n const prefix = config.projectManagement.ticketPrefix;\n\n // First, try prefix-based extraction if configured\n if (prefix) {\n const prefixPattern = new RegExp(`(${prefix}-\\\\d+)`, 'i');\n const match = branchName.match(prefixPattern);\n if (match) {\n return match[1].toUpperCase();\n }\n }\n\n // Try common branch patterns\n for (const pattern of BRANCH_PATTERNS) {\n const match = branchName.match(pattern);\n if (match) {\n const ticketId = match[1];\n // If it's just a number and we have a prefix, combine them\n if (/^\\d+$/.test(ticketId) && prefix) {\n return `${prefix}-${ticketId}`;\n }\n return ticketId.toUpperCase();\n }\n }\n\n return null;\n}\n\n// ─── Helpers for fetch-based API calls ────────────────────────────────────────\n\n/**\n * Interpret an HTTP response and throw the appropriate PMError\n * if the status code indicates a problem.\n */\nfunction handleHttpStatus(tool: PMTool, response: Response, resourceId?: string): void {\n if (response.ok) return; // 2xx – nothing to do\n\n switch (response.status) {\n case 401:\n case 403:\n throw new PMAuthError(tool, `${tool} returned ${response.status}: ${response.statusText}`);\n case 404:\n if (resourceId) {\n throw new PMNotFoundError(tool, resourceId);\n }\n throw new PMConnectionError(tool, `Resource not found (404) on ${tool}`, 404);\n case 429: {\n const retryAfter = response.headers.get('retry-after');\n const retryMs = retryAfter ? parseInt(retryAfter, 10) * 1000 : undefined;\n throw new PMRateLimitError(tool, retryMs);\n }\n default:\n if (response.status >= 500) {\n throw new PMConnectionError(\n tool,\n `${tool} server error: ${response.status} ${response.statusText}`,\n response.status\n );\n }\n throw new PMResponseError(\n tool,\n `${tool} API returned unexpected status ${response.status}: ${response.statusText}`\n );\n }\n}\n\n/**\n * Safely parse JSON from a Response, wrapping parse errors in PMResponseError\n */\nasync function safeParseJson(tool: PMTool, response: Response): Promise<unknown> {\n const text = await response.text();\n try {\n return JSON.parse(text);\n } catch (err) {\n throw new PMResponseError(tool, `Failed to parse ${tool} API response as JSON`, err);\n }\n}\n\n// ─── Abstract base class ──────────────────────────────────────────────────────\n\n/**\n * Abstract PM client with common helpers\n */\nexport abstract class ProjectManagementClient {\n abstract readonly tool: 'github' | 'jira' | 'linear' | 'notion';\n\n abstract isConfigured(): Promise<boolean>;\n abstract getTicket(ticketId: string): Promise<Ticket | null>;\n abstract getTickets(ticketIds: string[]): Promise<Ticket[]>;\n abstract searchTickets(query: string, limit?: number): Promise<Ticket[]>;\n abstract getMyTickets(limit?: number): Promise<Ticket[]>;\n abstract getRecentlyClosedTickets(days?: number): Promise<Ticket[]>;\n\n /**\n * Test the connection to the PM tool.\n * Validates credentials, reachability, and authentication in one call.\n */\n abstract testConnection(): Promise<PMConnectionTestResult>;\n\n /**\n * Get a list of missing configuration fields for this tool.\n * Returns an empty array when fully configured.\n */\n abstract getMissingConfig(): string[];\n\n /**\n * Format ticket for AI context\n */\n formatTicketForContext(ticket: Ticket): string {\n const lines = [\n `[${ticket.id}] ${ticket.title}`,\n ` Type: ${ticket.type} | Status: ${ticket.status}`,\n ];\n\n if (ticket.priority) {\n lines[1] += ` | Priority: ${ticket.priority}`;\n }\n\n if (ticket.description) {\n // Truncate description to first 200 chars\n const raw =\n typeof ticket.description === 'string' ? ticket.description : String(ticket.description);\n const desc = raw.slice(0, 200).replace(/\\n/g, ' ');\n if (desc) {\n lines.push(` ${desc}${raw.length > 200 ? '...' : ''}`);\n }\n }\n\n return lines.join('\\n');\n }\n}\n\n// ─── Jira Client ──────────────────────────────────────────────────────────────\n\n/**\n * Jira integration using native fetch (REST API v3)\n */\nexport class JiraClient extends ProjectManagementClient {\n readonly tool = 'jira' as const;\n\n // --- configuration helpers (public for testing) ---\n\n getBaseUrl(): string {\n const config = getConfig();\n const secrets = getSecrets();\n return (\n secrets.jira?.baseUrl ||\n config.projectManagement.jira.baseUrl ||\n process.env.JIRA_BASE_URL ||\n ''\n );\n }\n\n getAuth(): { email: string; token: string } | null {\n const secrets = getSecrets();\n const email = secrets.jira?.email || process.env.JIRA_EMAIL;\n const token = secrets.jira?.apiToken || process.env.JIRA_API_TOKEN;\n if (!email || !token) return null;\n return { email, token };\n }\n\n private authHeader(): string {\n const auth = this.getAuth();\n if (!auth) throw new PMConfigError('jira', this.getMissingConfig());\n return 'Basic ' + Buffer.from(`${auth.email}:${auth.token}`).toString('base64');\n }\n\n getMissingConfig(): string[] {\n const missing: string[] = [];\n if (!this.getBaseUrl()) missing.push('baseUrl');\n const secrets = getSecrets();\n const email = secrets.jira?.email || process.env.JIRA_EMAIL;\n const token = secrets.jira?.apiToken || process.env.JIRA_API_TOKEN;\n if (!email) missing.push('email');\n if (!token) missing.push('apiToken');\n return missing;\n }\n\n async isConfigured(): Promise<boolean> {\n return this.getMissingConfig().length === 0;\n }\n\n // --- fetch helper ---\n\n private async jiraFetch(\n path: string,\n options: RequestInit = {},\n resourceId?: string\n ): Promise<unknown> {\n const baseUrl = this.getBaseUrl();\n if (!baseUrl) throw new PMConfigError('jira', ['baseUrl']);\n\n const url = `${baseUrl}${path}`;\n let response: Response;\n try {\n response = await fetch(url, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n Authorization: this.authHeader(),\n ...(options.headers as Record<string, string> | undefined),\n },\n });\n } catch (err) {\n throw new PMConnectionError(\n 'jira',\n `Could not reach Jira at ${baseUrl} — check network and base URL`,\n undefined,\n err\n );\n }\n\n handleHttpStatus('jira', response, resourceId);\n return safeParseJson('jira', response);\n }\n\n // --- public API ---\n\n async testConnection(): Promise<PMConnectionTestResult> {\n const missing = this.getMissingConfig();\n if (missing.length > 0) {\n return failureResult('jira', new PMConfigError('jira', missing));\n }\n\n const start = Date.now();\n try {\n const data = (await this.jiraFetch('/rest/api/3/myself')) as Record<string, unknown>;\n const elapsed = Date.now() - start;\n const displayName = (data.displayName as string) || (data.emailAddress as string) || '';\n return successResult(\n 'jira',\n displayName ? `Authenticated as ${displayName}` : undefined,\n elapsed\n );\n } catch (err) {\n if (\n err instanceof PMAuthError ||\n err instanceof PMConnectionError ||\n err instanceof PMConfigError\n ) {\n return failureResult('jira', err);\n }\n return failureResult(\n 'jira',\n new PMConnectionError('jira', (err as Error).message, undefined, err)\n );\n }\n }\n\n async getTicket(ticketId: string): Promise<Ticket | null> {\n if (!(await this.isConfigured())) return null;\n try {\n const data = (await this.jiraFetch(\n `/rest/api/3/issue/${encodeURIComponent(ticketId)}`,\n {},\n ticketId\n )) as Record<string, unknown>;\n if ((data as Record<string, unknown>).errorMessages) return null;\n return this.parseJiraIssue(data, this.getBaseUrl());\n } catch {\n return null;\n }\n }\n\n async getTickets(ticketIds: string[]): Promise<Ticket[]> {\n const results = await Promise.all(ticketIds.map((id) => this.getTicket(id)));\n return results.filter((t): t is Ticket => t !== null);\n }\n\n async searchTickets(query: string, limit = 10): Promise<Ticket[]> {\n if (!(await this.isConfigured())) return [];\n const config = getConfig();\n const projectKey = config.projectManagement.jira.projectKey;\n\n try {\n const jql = projectKey\n ? `project = ${projectKey} AND text ~ \"${query}\" ORDER BY updated DESC`\n : `text ~ \"${query}\" ORDER BY updated DESC`;\n\n const params = new URLSearchParams({ jql, maxResults: String(limit) });\n const data = (await this.jiraFetch(`/rest/api/3/search?${params.toString()}`)) as Record<\n string,\n unknown\n >;\n return ((data.issues as unknown[]) || []).map((issue) =>\n this.parseJiraIssue(issue as Record<string, unknown>, this.getBaseUrl())\n );\n } catch {\n return [];\n }\n }\n\n async getMyTickets(limit = 10): Promise<Ticket[]> {\n if (!(await this.isConfigured())) return [];\n try {\n const jql = 'assignee = currentUser() AND status != Done ORDER BY updated DESC';\n const params = new URLSearchParams({ jql, maxResults: String(limit) });\n const data = (await this.jiraFetch(`/rest/api/3/search?${params.toString()}`)) as Record<\n string,\n unknown\n >;\n return ((data.issues as unknown[]) || []).map((issue) =>\n this.parseJiraIssue(issue as Record<string, unknown>, this.getBaseUrl())\n );\n } catch {\n return [];\n }\n }\n\n async getRecentlyClosedTickets(days = 7): Promise<Ticket[]> {\n if (!(await this.isConfigured())) return [];\n try {\n const jql = `assignee = currentUser() AND status = Done AND resolved >= -${days}d ORDER BY resolved DESC`;\n const params = new URLSearchParams({ jql });\n const data = (await this.jiraFetch(`/rest/api/3/search?${params.toString()}`)) as Record<\n string,\n unknown\n >;\n return ((data.issues as unknown[]) || []).map((issue) =>\n this.parseJiraIssue(issue as Record<string, unknown>, this.getBaseUrl())\n );\n } catch {\n return [];\n }\n }\n\n // --- parsing helpers (public for testing) ---\n\n parseJiraIssue(issue: Record<string, unknown>, baseUrl: string): Ticket {\n const fields = issue.fields as Record<string, unknown>;\n const issueType = fields.issuetype as Record<string, unknown>;\n const priority = fields.priority as Record<string, unknown> | null;\n const assignee = fields.assignee as Record<string, unknown> | null;\n const status = fields.status as Record<string, unknown>;\n const labels = fields.labels as string[];\n\n return {\n id: issue.key as string,\n title: fields.summary as string,\n description: extractAdfText(fields.description),\n status: (status?.name as string) || 'unknown',\n type: this.mapJiraType((issueType?.name as string) || ''),\n priority: priority ? this.mapJiraPriority(priority.name as string) : undefined,\n assignee: assignee ? (assignee.displayName as string) : undefined,\n labels: labels || [],\n url: `${baseUrl}/browse/${issue.key}`,\n source: 'jira',\n };\n }\n\n mapJiraType(type: string): 'bug' | 'feature' | 'task' | 'story' | 'epic' | 'other' {\n const lower = type.toLowerCase();\n if (lower.includes('bug')) return 'bug';\n if (lower.includes('feature')) return 'feature';\n if (lower.includes('story')) return 'story';\n if (lower.includes('epic')) return 'epic';\n if (lower.includes('task')) return 'task';\n return 'other';\n }\n\n mapJiraPriority(priority: string): 'low' | 'medium' | 'high' | 'critical' | undefined {\n const lower = priority.toLowerCase();\n if (lower.includes('critical') || lower.includes('blocker')) return 'critical';\n if (lower.includes('high')) return 'high';\n if (lower.includes('medium') || lower.includes('normal')) return 'medium';\n if (lower.includes('low')) return 'low';\n return undefined;\n }\n}\n\n// ─── Linear Client ────────────────────────────────────────────────────────────\n\n/**\n * Linear integration using native fetch (GraphQL API)\n */\nexport class LinearClient extends ProjectManagementClient {\n readonly tool = 'linear' as const;\n\n private static readonly API_URL = 'https://api.linear.app/graphql';\n\n getApiKey(): string | null {\n const secrets = getSecrets();\n return secrets.linear?.apiKey || process.env.LINEAR_API_KEY || null;\n }\n\n getMissingConfig(): string[] {\n return this.getApiKey() ? [] : ['apiKey'];\n }\n\n async isConfigured(): Promise<boolean> {\n return !!this.getApiKey();\n }\n\n // --- fetch helper ---\n\n private async graphql(query: string, variables: Record<string, unknown> = {}): Promise<unknown> {\n const apiKey = this.getApiKey();\n if (!apiKey) throw new PMConfigError('linear', ['apiKey']);\n\n let response: Response;\n try {\n response = await fetch(LinearClient.API_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: apiKey,\n },\n body: JSON.stringify({ query, variables }),\n });\n } catch (err) {\n throw new PMConnectionError(\n 'linear',\n 'Could not reach Linear API — check your network connection',\n undefined,\n err\n );\n }\n\n handleHttpStatus('linear', response);\n\n const data = (await safeParseJson('linear', response)) as Record<string, unknown>;\n const errors = data.errors as Array<{ message: string }> | undefined;\n if (errors && errors.length > 0) {\n const msg = errors[0].message;\n if (\n msg.toLowerCase().includes('authentication') ||\n msg.toLowerCase().includes('unauthorized')\n ) {\n throw new PMAuthError('linear', `Linear GraphQL error: ${msg}`);\n }\n throw new PMResponseError('linear', `Linear GraphQL error: ${msg}`);\n }\n return data.data;\n }\n\n // --- public API ---\n\n async testConnection(): Promise<PMConnectionTestResult> {\n const missing = this.getMissingConfig();\n if (missing.length > 0) {\n return failureResult('linear', new PMConfigError('linear', missing));\n }\n\n const start = Date.now();\n try {\n const data = (await this.graphql('query { viewer { id name email } }')) as Record<\n string,\n unknown\n >;\n const elapsed = Date.now() - start;\n const viewer = data.viewer as Record<string, unknown>;\n const name = (viewer?.name as string) || (viewer?.email as string) || '';\n return successResult('linear', name ? `Authenticated as ${name}` : undefined, elapsed);\n } catch (err) {\n if (\n err instanceof PMAuthError ||\n err instanceof PMConnectionError ||\n err instanceof PMConfigError\n ) {\n return failureResult('linear', err);\n }\n return failureResult(\n 'linear',\n new PMConnectionError('linear', (err as Error).message, undefined, err)\n );\n }\n }\n\n async getTicket(ticketId: string): Promise<Ticket | null> {\n try {\n const query = `\n query GetIssue($id: String!) {\n issue(id: $id) {\n id\n identifier\n title\n description\n state { name }\n priority\n assignee { name }\n labels { nodes { name } }\n url\n }\n }\n `;\n\n // Linear uses identifier (e.g., \"ENG-123\") for lookup\n const data = (await this.graphql(query, { id: ticketId })) as Record<string, unknown>;\n const issue = data.issue as Record<string, unknown>;\n if (!issue) return null;\n\n return this.parseLinearIssue(issue);\n } catch {\n return null;\n }\n }\n\n async getTickets(ticketIds: string[]): Promise<Ticket[]> {\n const results = await Promise.all(ticketIds.map((id) => this.getTicket(id)));\n return results.filter((t): t is Ticket => t !== null);\n }\n\n async searchTickets(query: string, limit = 10): Promise<Ticket[]> {\n try {\n const graphqlQuery = `\n query SearchIssues($query: String!, $first: Int!) {\n issueSearch(query: $query, first: $first) {\n nodes {\n id\n identifier\n title\n description\n state { name }\n priority\n assignee { name }\n labels { nodes { name } }\n url\n }\n }\n }\n `;\n\n const data = (await this.graphql(graphqlQuery, { query, first: limit })) as Record<\n string,\n unknown\n >;\n const search = data.issueSearch as Record<string, unknown>;\n const nodes = (search?.nodes as unknown[]) || [];\n return nodes.map((issue) => this.parseLinearIssue(issue as Record<string, unknown>));\n } catch {\n return [];\n }\n }\n\n async getMyTickets(limit = 10): Promise<Ticket[]> {\n try {\n const query = `\n query MyIssues($first: Int!) {\n viewer {\n assignedIssues(first: $first, filter: { state: { type: { nin: [\"completed\", \"canceled\"] } } }) {\n nodes {\n id\n identifier\n title\n description\n state { name }\n priority\n assignee { name }\n labels { nodes { name } }\n url\n }\n }\n }\n }\n `;\n\n const data = (await this.graphql(query, { first: limit })) as Record<string, unknown>;\n const viewer = data.viewer as Record<string, unknown>;\n const assignedIssues = viewer?.assignedIssues as Record<string, unknown>;\n const nodes = (assignedIssues?.nodes as unknown[]) || [];\n return nodes.map((issue) => this.parseLinearIssue(issue as Record<string, unknown>));\n } catch {\n return [];\n }\n }\n\n async getRecentlyClosedTickets(days = 7): Promise<Ticket[]> {\n try {\n const since = new Date();\n since.setDate(since.getDate() - days);\n\n const query = `\n query ClosedIssues($first: Int!, $since: DateTime!) {\n viewer {\n assignedIssues(first: $first, filter: { state: { type: { eq: \"completed\" } }, completedAt: { gte: $since } }) {\n nodes {\n id\n identifier\n title\n description\n state { name }\n priority\n assignee { name }\n labels { nodes { name } }\n url\n }\n }\n }\n }\n `;\n\n const data = (await this.graphql(query, {\n first: 50,\n since: since.toISOString(),\n })) as Record<string, unknown>;\n const viewer = data.viewer as Record<string, unknown>;\n const assignedIssues = viewer?.assignedIssues as Record<string, unknown>;\n const nodes = (assignedIssues?.nodes as unknown[]) || [];\n return nodes.map((issue) => this.parseLinearIssue(issue as Record<string, unknown>));\n } catch {\n return [];\n }\n }\n\n // --- parsing helpers (public for testing) ---\n\n parseLinearIssue(issue: Record<string, unknown>): Ticket {\n const state = issue.state as Record<string, unknown>;\n const assignee = issue.assignee as Record<string, unknown> | null;\n const labelsObj = issue.labels as Record<string, unknown>;\n const labelNodes = (labelsObj?.nodes as Array<{ name: string }>) || [];\n\n return {\n id: issue.identifier as string,\n title: issue.title as string,\n description: (issue.description as string) || '',\n status: (state?.name as string) || 'unknown',\n type: this.inferTypeFromLabels(labelNodes.map((l) => l.name)),\n priority: this.mapLinearPriority(issue.priority as number),\n assignee: assignee ? (assignee.name as string) : undefined,\n labels: labelNodes.map((l) => l.name),\n url: issue.url as string,\n source: 'linear',\n };\n }\n\n inferTypeFromLabels(labels: string[]): 'bug' | 'feature' | 'task' | 'story' | 'epic' | 'other' {\n const joined = labels.join(' ').toLowerCase();\n if (joined.includes('bug')) return 'bug';\n if (joined.includes('feature')) return 'feature';\n if (joined.includes('epic')) return 'epic';\n return 'task';\n }\n\n mapLinearPriority(priority: number): 'low' | 'medium' | 'high' | 'critical' | undefined {\n // Linear uses 0-4: 0=no priority, 1=urgent, 2=high, 3=medium, 4=low\n switch (priority) {\n case 1:\n return 'critical';\n case 2:\n return 'high';\n case 3:\n return 'medium';\n case 4:\n return 'low';\n default:\n return undefined;\n }\n }\n}\n\n// ─── Notion Client ────────────────────────────────────────────────────────────\n\n/**\n * Notion integration using native fetch (REST API, version 2022-06-28)\n */\nexport class NotionClient extends ProjectManagementClient {\n readonly tool = 'notion' as const;\n\n private static readonly API_BASE = 'https://api.notion.com/v1';\n private static readonly API_VERSION = '2022-06-28';\n\n getApiKey(): string | null {\n const secrets = getSecrets();\n return secrets.notion?.apiKey || process.env.NOTION_API_KEY || null;\n }\n\n getDatabaseId(): string | null {\n const config = getConfig();\n const secrets = getSecrets();\n return (\n secrets.notion?.databaseId ||\n config.projectManagement.notion.databaseId ||\n process.env.NOTION_DATABASE_ID ||\n null\n );\n }\n\n getMissingConfig(): string[] {\n const missing: string[] = [];\n if (!this.getApiKey()) missing.push('apiKey');\n if (!this.getDatabaseId()) missing.push('databaseId');\n return missing;\n }\n\n async isConfigured(): Promise<boolean> {\n return this.getMissingConfig().length === 0;\n }\n\n // --- fetch helper ---\n\n private async notionFetch(\n endpoint: string,\n method = 'GET',\n body?: Record<string, unknown>,\n resourceId?: string\n ): Promise<unknown> {\n const apiKey = this.getApiKey();\n if (!apiKey) throw new PMConfigError('notion', ['apiKey']);\n\n const url = `${NotionClient.API_BASE}${endpoint}`;\n const init: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n 'Notion-Version': NotionClient.API_VERSION,\n },\n };\n\n if (body) {\n init.body = JSON.stringify(body);\n }\n\n let response: Response;\n try {\n response = await fetch(url, init);\n } catch (err) {\n throw new PMConnectionError(\n 'notion',\n 'Could not reach Notion API — check your network connection',\n undefined,\n err\n );\n }\n\n handleHttpStatus('notion', response, resourceId);\n return safeParseJson('notion', response);\n }\n\n // --- public API ---\n\n async testConnection(): Promise<PMConnectionTestResult> {\n const missing = this.getMissingConfig();\n if (missing.length > 0) {\n return failureResult('notion', new PMConfigError('notion', missing));\n }\n\n const start = Date.now();\n try {\n // Test 1: check authentication via /users/me\n const user = (await this.notionFetch('/users/me')) as Record<string, unknown>;\n const elapsed = Date.now() - start;\n const name = (user.name as string) || '';\n\n // Test 2: verify database access\n const databaseId = this.getDatabaseId();\n if (databaseId) {\n try {\n await this.notionFetch(`/databases/${databaseId}`, 'GET', undefined, databaseId);\n } catch (err) {\n if (err instanceof PMNotFoundError) {\n return failureResult('notion', new PMNotFoundError('notion', databaseId, 'database'));\n }\n // Auth succeeded but database check failed for another reason – still report\n return failureResult(\n 'notion',\n new PMConnectionError(\n 'notion',\n `Authenticated but could not access database ${databaseId}`\n )\n );\n }\n }\n\n return successResult('notion', name ? `Authenticated as ${name}` : undefined, elapsed);\n } catch (err) {\n if (\n err instanceof PMAuthError ||\n err instanceof PMConnectionError ||\n err instanceof PMConfigError\n ) {\n return failureResult('notion', err);\n }\n return failureResult(\n 'notion',\n new PMConnectionError('notion', (err as Error).message, undefined, err)\n );\n }\n }\n\n async getTicket(ticketId: string): Promise<Ticket | null> {\n try {\n const page = (await this.notionFetch(\n `/pages/${ticketId}`,\n 'GET',\n undefined,\n ticketId\n )) as Record<string, unknown>;\n return this.parseNotionPage(page);\n } catch {\n return null;\n }\n }\n\n async getTickets(ticketIds: string[]): Promise<Ticket[]> {\n const results = await Promise.all(ticketIds.map((id) => this.getTicket(id)));\n return results.filter((t): t is Ticket => t !== null);\n }\n\n async searchTickets(query: string, limit = 10): Promise<Ticket[]> {\n const databaseId = this.getDatabaseId();\n if (!databaseId) return [];\n\n try {\n const response = (await this.notionFetch(`/databases/${databaseId}/query`, 'POST', {\n filter: {\n property: 'Name',\n title: {\n contains: query,\n },\n },\n page_size: limit,\n })) as Record<string, unknown>;\n\n const results = (response.results as unknown[]) || [];\n return results.map((page) => this.parseNotionPage(page as Record<string, unknown>));\n } catch {\n return [];\n }\n }\n\n async getMyTickets(_limit = 10): Promise<Ticket[]> {\n // Notion doesn't have a built-in \"assigned to me\" concept\n // This would need to be customized based on the database schema\n return [];\n }\n\n async getRecentlyClosedTickets(_days = 7): Promise<Ticket[]> {\n // Would need to know the status property name\n return [];\n }\n\n // --- parsing helpers (public for testing) ---\n\n parseNotionPage(page: Record<string, unknown>): Ticket {\n const properties = page.properties as Record<string, unknown>;\n\n // Try to extract title - Notion uses different property names\n let title = 'Untitled';\n const nameProperty = properties.Name || properties.Title || properties.title;\n if (nameProperty) {\n const propObj = nameProperty as Record<string, unknown>;\n const titleArray = propObj.title as Array<{ plain_text: string }>;\n if (titleArray?.[0]) {\n title = titleArray[0].plain_text;\n }\n }\n\n // Try to extract status\n let status = 'unknown';\n const statusProperty = properties.Status || properties.status;\n if (statusProperty) {\n const propObj = statusProperty as Record<string, unknown>;\n const selectObj = propObj.select as Record<string, unknown>;\n if (selectObj) {\n status = selectObj.name as string;\n }\n }\n\n return {\n id: page.id as string,\n title,\n description: '',\n status,\n type: 'task',\n labels: [],\n url: page.url as string,\n source: 'notion',\n };\n }\n}\n\n// ─── GitHub Issues Client ─────────────────────────────────────────────────────\n\n/**\n * GitHub Issues integration using the `gh` CLI.\n *\n * Unlike the other PM clients, this one keeps using `gh` CLI via execa because:\n * - gh CLI handles OAuth/token management automatically\n * - It respects the user's `gh auth` session\n * - No separate API token needed\n */\nexport class GitHubIssueClient extends ProjectManagementClient {\n readonly tool = 'github' as const;\n\n getMissingConfig(): string[] {\n // GitHub uses gh CLI auth – we detect this dynamically in testConnection\n return [];\n }\n\n async isConfigured(): Promise<boolean> {\n try {\n await execa('gh', ['auth', 'status']);\n return true;\n } catch {\n return false;\n }\n }\n\n async testConnection(): Promise<PMConnectionTestResult> {\n const start = Date.now();\n try {\n // Check gh CLI is installed\n try {\n await execa('gh', ['--version']);\n } catch {\n return failureResult('github', new PMConfigError('github', ['gh CLI not installed']));\n }\n\n // Check auth status\n const { stdout: authStatus } = await execa('gh', ['auth', 'status']);\n const elapsed = Date.now() - start;\n\n // Extract account info from auth status output\n const accountMatch = authStatus.match(/Logged in to .+ as (\\S+)/);\n const account = accountMatch ? accountMatch[1] : undefined;\n\n // Verify repo access\n let repoInfo: string | undefined;\n try {\n const { stdout: repoJson } = await execa('gh', ['repo', 'view', '--json', 'nameWithOwner']);\n const repo = JSON.parse(repoJson);\n repoInfo = repo.nameWithOwner;\n } catch {\n // Not in a GitHub repo, but auth works – that's still a success\n }\n\n const info = [\n account ? `Authenticated as ${account}` : 'Authenticated',\n repoInfo ? `repo: ${repoInfo}` : null,\n ]\n .filter(Boolean)\n .join(', ');\n\n return successResult('github', info, elapsed);\n } catch (err) {\n const msg = (err as Error).message || '';\n if (msg.includes('not logged') || msg.includes('auth login')) {\n return failureResult(\n 'github',\n new PMAuthError('github', 'Not authenticated — run `gh auth login`')\n );\n }\n return failureResult('github', new PMConnectionError('github', msg, undefined, err));\n }\n }\n\n async getTicket(ticketId: string): Promise<Ticket | null> {\n const issueNumber = ticketId.replace('#', '');\n\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'view',\n issueNumber,\n '--json',\n 'number,title,body,state,labels,assignees,url',\n ]);\n\n const data = JSON.parse(stdout);\n return this.parseGitHubIssue(data);\n } catch {\n return null;\n }\n }\n\n async getTickets(ticketIds: string[]): Promise<Ticket[]> {\n const results = await Promise.all(ticketIds.map((id) => this.getTicket(id)));\n return results.filter((t): t is Ticket => t !== null);\n }\n\n async searchTickets(query: string, limit = 10): Promise<Ticket[]> {\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'list',\n '--search',\n query,\n '--limit',\n String(limit),\n '--json',\n 'number,title,body,state,labels,assignees,url',\n ]);\n\n const issues = JSON.parse(stdout);\n return issues.map((issue: unknown) =>\n this.parseGitHubIssue(issue as Record<string, unknown>)\n );\n } catch {\n return [];\n }\n }\n\n async getMyTickets(limit = 10): Promise<Ticket[]> {\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'list',\n '--assignee',\n '@me',\n '--limit',\n String(limit),\n '--json',\n 'number,title,body,state,labels,assignees,url',\n ]);\n\n const issues = JSON.parse(stdout);\n return issues.map((issue: unknown) =>\n this.parseGitHubIssue(issue as Record<string, unknown>)\n );\n } catch {\n return [];\n }\n }\n\n async getRecentlyClosedTickets(days = 7): Promise<Ticket[]> {\n const since = new Date();\n since.setDate(since.getDate() - days);\n\n try {\n const { stdout } = await execa('gh', [\n 'issue',\n 'list',\n '--state',\n 'closed',\n '--assignee',\n '@me',\n '--search',\n `closed:>=${since.toISOString().split('T')[0]}`,\n '--json',\n 'number,title,body,state,labels,assignees,url',\n ]);\n\n const issues = JSON.parse(stdout);\n return issues.map((issue: unknown) =>\n this.parseGitHubIssue(issue as Record<string, unknown>)\n );\n } catch {\n return [];\n }\n }\n\n // --- parsing helpers (public for testing) ---\n\n parseGitHubIssue(issue: Record<string, unknown>): Ticket {\n const labels = (issue.labels as Array<{ name: string }>) || [];\n const assignees = (issue.assignees as Array<{ login: string }>) || [];\n\n return {\n id: `#${issue.number}`,\n title: issue.title as string,\n description: (issue.body as string) || '',\n status: (issue.state as string) === 'OPEN' ? 'open' : 'closed',\n type: this.inferTypeFromLabels(labels.map((l) => l.name)),\n assignee: assignees[0]?.login,\n labels: labels.map((l) => l.name),\n url: issue.url as string,\n source: 'github',\n };\n }\n\n inferTypeFromLabels(labels: string[]): 'bug' | 'feature' | 'task' | 'story' | 'epic' | 'other' {\n const joined = labels.join(' ').toLowerCase();\n if (joined.includes('bug')) return 'bug';\n if (joined.includes('feature') || joined.includes('enhancement')) return 'feature';\n if (joined.includes('epic')) return 'epic';\n return 'task';\n }\n}\n\n// ─── Factory ──────────────────────────────────────────────────────────────────\n\n/**\n * Factory function to get the appropriate project management client\n */\nexport function getProjectManagementClient(): ProjectManagementClient {\n const config = getConfig();\n const tool = config.projectManagement.tool;\n\n switch (tool) {\n case 'jira':\n return new JiraClient();\n case 'linear':\n return new LinearClient();\n case 'notion':\n return new NotionClient();\n case 'github':\n default:\n return new GitHubIssueClient();\n }\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync, appendFileSync } from 'fs';\nimport { homedir } from 'os';\nimport { join, dirname } from 'path';\nimport { Config, ConfigSchema } from './schema.js';\n\n// Config file names\nconst LOCAL_CONFIG_FILENAME = '.devdaily.json';\nconst LOCAL_SECRETS_FILENAME = '.devdaily.secrets.json';\nconst GLOBAL_CONFIG_DIR = join(homedir(), '.config', 'devdaily');\nconst GLOBAL_CONFIG_PATH = join(GLOBAL_CONFIG_DIR, 'config.json');\nconst GLOBAL_SECRETS_PATH = join(GLOBAL_CONFIG_DIR, 'secrets.json');\n\n// Secrets interface (API tokens, emails, etc.)\nexport interface Secrets {\n jira?: {\n email?: string;\n apiToken?: string;\n baseUrl?: string;\n };\n linear?: {\n apiKey?: string;\n };\n notion?: {\n apiKey?: string;\n databaseId?: string;\n };\n slack?: {\n webhookUrl?: string;\n };\n discord?: {\n webhookUrl?: string;\n };\n}\n\nexport class ConfigManager {\n private static instance: ConfigManager;\n private config: Config;\n private secrets: Secrets;\n private configPath: string;\n\n private constructor() {\n this.secrets = this.loadSecrets();\n this.config = this.loadConfig();\n this.configPath = this.findConfigPath();\n }\n\n static getInstance(): ConfigManager {\n if (!ConfigManager.instance) {\n ConfigManager.instance = new ConfigManager();\n }\n return ConfigManager.instance;\n }\n\n private findConfigPath(): string {\n // 1. Check local .devdaily.json\n const localConfig = join(process.cwd(), LOCAL_CONFIG_FILENAME);\n if (existsSync(localConfig)) {\n return localConfig;\n }\n\n // 2. Check global config\n if (existsSync(GLOBAL_CONFIG_PATH)) {\n return GLOBAL_CONFIG_PATH;\n }\n\n // 3. Default to local (will be created on save)\n return localConfig;\n }\n\n private loadSecrets(): Secrets {\n const secrets: Secrets = {};\n\n // Load global secrets first\n if (existsSync(GLOBAL_SECRETS_PATH)) {\n try {\n const content = readFileSync(GLOBAL_SECRETS_PATH, 'utf-8');\n Object.assign(secrets, JSON.parse(content));\n } catch {\n // Invalid secrets file\n }\n }\n\n // Override with local secrets\n const localSecrets = join(process.cwd(), LOCAL_SECRETS_FILENAME);\n if (existsSync(localSecrets)) {\n try {\n const content = readFileSync(localSecrets, 'utf-8');\n const local = JSON.parse(content);\n // Deep merge\n if (local.jira) secrets.jira = { ...secrets.jira, ...local.jira };\n if (local.linear) secrets.linear = { ...secrets.linear, ...local.linear };\n if (local.notion) secrets.notion = { ...secrets.notion, ...local.notion };\n } catch {\n // Invalid secrets file\n }\n }\n\n // Also check environment variables as fallback\n if (process.env.JIRA_EMAIL || process.env.JIRA_API_TOKEN || process.env.JIRA_BASE_URL) {\n secrets.jira = {\n ...secrets.jira,\n email: process.env.JIRA_EMAIL || secrets.jira?.email,\n apiToken: process.env.JIRA_API_TOKEN || secrets.jira?.apiToken,\n baseUrl: process.env.JIRA_BASE_URL || secrets.jira?.baseUrl,\n };\n }\n\n if (process.env.LINEAR_API_KEY) {\n secrets.linear = {\n ...secrets.linear,\n apiKey: process.env.LINEAR_API_KEY || secrets.linear?.apiKey,\n };\n }\n\n if (process.env.NOTION_API_KEY || process.env.NOTION_DATABASE_ID) {\n secrets.notion = {\n ...secrets.notion,\n apiKey: process.env.NOTION_API_KEY || secrets.notion?.apiKey,\n databaseId: process.env.NOTION_DATABASE_ID || secrets.notion?.databaseId,\n };\n }\n\n return secrets;\n }\n\n private loadConfig(): Config {\n let globalConfig: Partial<Config> = {};\n let localConfig: Partial<Config> = {};\n\n // Load global config first\n if (existsSync(GLOBAL_CONFIG_PATH)) {\n try {\n const content = readFileSync(GLOBAL_CONFIG_PATH, 'utf-8');\n globalConfig = JSON.parse(content);\n } catch {\n // Invalid config\n }\n }\n\n // Load local config (overrides global)\n const localConfigPath = join(process.cwd(), LOCAL_CONFIG_FILENAME);\n if (existsSync(localConfigPath)) {\n try {\n const content = readFileSync(localConfigPath, 'utf-8');\n localConfig = JSON.parse(content);\n } catch {\n // Invalid config\n }\n }\n\n // Merge: global defaults < global config < local config\n const merged = this.deepMerge(globalConfig, localConfig);\n\n return ConfigSchema.parse(merged);\n }\n\n private deepMerge(\n target: Record<string, unknown>,\n source: Record<string, unknown>\n ): Record<string, unknown> {\n const result = { ...target };\n\n for (const key of Object.keys(source)) {\n if (\n source[key] &&\n typeof source[key] === 'object' &&\n !Array.isArray(source[key]) &&\n target[key] &&\n typeof target[key] === 'object'\n ) {\n result[key] = this.deepMerge(\n target[key] as Record<string, unknown>,\n source[key] as Record<string, unknown>\n );\n } else {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n get(): Config {\n return this.config;\n }\n\n getSecrets(): Secrets {\n return this.secrets;\n }\n\n set<K extends keyof Config>(key: K, value: Config[K]): void {\n this.config[key] = value;\n this.save();\n }\n\n update(partial: Partial<Config>): void {\n this.config = ConfigSchema.parse({ ...this.config, ...partial });\n this.save();\n }\n\n private save(): void {\n const dir = dirname(this.configPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(this.configPath, JSON.stringify(this.config, null, 2));\n }\n\n saveGlobal(): void {\n if (!existsSync(GLOBAL_CONFIG_DIR)) {\n mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });\n }\n writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(this.config, null, 2));\n }\n\n saveLocal(config?: Partial<Config>): void {\n const localPath = join(process.cwd(), LOCAL_CONFIG_FILENAME);\n const toSave = config ? ConfigSchema.parse({ ...this.config, ...config }) : this.config;\n // Add JSON schema reference for IDE autocomplete\n const withSchema = {\n $schema:\n 'https://raw.githubusercontent.com/hempun10/devdaily/main/schemas/devdaily.schema.json',\n ...toSave,\n };\n writeFileSync(localPath, JSON.stringify(withSchema, null, 2));\n }\n\n saveSecrets(secrets: Secrets, global = false): void {\n if (global) {\n if (!existsSync(GLOBAL_CONFIG_DIR)) {\n mkdirSync(GLOBAL_CONFIG_DIR, { recursive: true });\n }\n writeFileSync(GLOBAL_SECRETS_PATH, JSON.stringify(secrets, null, 2));\n } else {\n const localPath = join(process.cwd(), LOCAL_SECRETS_FILENAME);\n writeFileSync(localPath, JSON.stringify(secrets, null, 2));\n }\n\n // Merge into current secrets\n this.secrets = { ...this.secrets, ...secrets };\n }\n\n /**\n * Add secrets file to .gitignore\n */\n addSecretsToGitignore(): boolean {\n const gitignorePath = join(process.cwd(), '.gitignore');\n const secretsEntry = LOCAL_SECRETS_FILENAME;\n\n if (existsSync(gitignorePath)) {\n const content = readFileSync(gitignorePath, 'utf-8');\n if (content.includes(secretsEntry)) {\n return false; // Already in gitignore\n }\n appendFileSync(gitignorePath, `\\n# DevDaily secrets (API tokens)\\n${secretsEntry}\\n`);\n } else {\n writeFileSync(gitignorePath, `# DevDaily secrets (API tokens)\\n${secretsEntry}\\n`);\n }\n\n return true;\n }\n\n reset(): void {\n this.config = ConfigSchema.parse({});\n this.save();\n }\n\n getConfigPath(): string {\n return this.configPath;\n }\n\n isUsingLocalConfig(): boolean {\n return this.configPath === join(process.cwd(), LOCAL_CONFIG_FILENAME);\n }\n\n static getGlobalConfigPath(): string {\n return GLOBAL_CONFIG_PATH;\n }\n\n static getLocalConfigPath(): string {\n return join(process.cwd(), LOCAL_CONFIG_FILENAME);\n }\n\n static getLocalSecretsPath(): string {\n return join(process.cwd(), LOCAL_SECRETS_FILENAME);\n }\n}\n\n// Export singleton getter\nexport const getConfig = () => ConfigManager.getInstance().get();\nexport const getSecrets = () => ConfigManager.getInstance().getSecrets();\nexport const config = ConfigManager.getInstance();\n","import { z } from 'zod';\n\n// Theme configuration\nexport const ThemeSchema = z.object({\n primary: z.string().default('blue'),\n success: z.string().default('green'),\n warning: z.string().default('yellow'),\n error: z.string().default('red'),\n accent: z.string().default('cyan'),\n muted: z.string().default('gray'),\n});\n\n// Aliases configuration\nexport const AliasesSchema = z.object({\n standup: z.array(z.string()).default(['s', 'su', 'daily']),\n pr: z.array(z.string()).default(['p', 'pull']),\n week: z.array(z.string()).default(['w', 'weekly']),\n dash: z.array(z.string()).default(['d', 'dashboard']),\n});\n\n// Output defaults\nexport const OutputSchema = z.object({\n format: z.enum(['markdown', 'slack', 'plain', 'json']).default('markdown'),\n copyToClipboard: z.boolean().default(true),\n showStats: z.boolean().default(true),\n verbose: z.boolean().default(false),\n});\n\n// Git configuration\nexport const GitSchema = z.object({\n defaultBranch: z.string().default('main'),\n excludeAuthors: z.array(z.string()).default([]),\n excludePatterns: z.array(z.string()).default(['merge commit', 'Merge branch']),\n});\n\n// Project configuration (for multi-project support)\nexport const ProjectSchema = z.object({\n name: z.string(),\n path: z.string(),\n defaultBranch: z.string().optional(),\n team: z.array(z.string()).optional(),\n});\n\n// Shortcuts configuration\nexport const ShortcutsSchema = z.object({\n quit: z.string().default('q'),\n help: z.string().default('?'),\n refresh: z.string().default('r'),\n copy: z.string().default('c'),\n create: z.string().default('enter'),\n back: z.string().default('esc'),\n nextProject: z.string().default('tab'),\n prevProject: z.string().default('shift+tab'),\n});\n\n// Project Management Tool configuration\nexport const ProjectManagementSchema = z.object({\n // Which tool to use: github, jira, linear, notion, or none\n tool: z.enum(['github', 'jira', 'linear', 'notion', 'none']).default('github'),\n\n // Ticket/Issue prefix pattern (e.g., \"PROJ\", \"ENG\", \"DEV\")\n // Used to extract ticket numbers from branch names and commits\n ticketPrefix: z.string().optional(),\n\n // Custom regex pattern for ticket extraction (advanced)\n // Default patterns are provided for each tool\n ticketPattern: z.string().optional(),\n\n // Jira-specific settings\n jira: z\n .object({\n // Jira instance URL (e.g., \"https://yourcompany.atlassian.net\")\n baseUrl: z.string().optional(),\n // API token (stored separately for security, this is just a flag)\n // Actual token should be in JIRA_API_TOKEN env var\n useApiToken: z.boolean().default(true),\n // Default project key\n projectKey: z.string().optional(),\n })\n .default({}),\n\n // Linear-specific settings\n linear: z\n .object({\n // Team key (e.g., \"ENG\", \"DEV\")\n teamKey: z.string().optional(),\n // Use Linear CLI or API\n // Actual token should be in LINEAR_API_KEY env var\n useApi: z.boolean().default(true),\n })\n .default({}),\n\n // Notion-specific settings\n notion: z\n .object({\n // Database ID for tasks/issues\n databaseId: z.string().optional(),\n // Use Notion API\n // Actual token should be in NOTION_API_KEY env var\n useApi: z.boolean().default(true),\n })\n .default({}),\n});\n\n// Journal / snapshot automation\nexport const JournalSchema = z.object({\n // Automatically take a light snapshot when running standup, pr, week commands\n autoSnapshot: z.boolean().default(true),\n\n // Install git hooks (post-commit, post-checkout) to capture snapshots automatically\n gitHooks: z.boolean().default(false),\n\n // Which git hooks to install when gitHooks is enabled\n hooks: z\n .object({\n postCommit: z.boolean().default(true),\n postCheckout: z.boolean().default(true),\n })\n .default({}),\n\n // Maximum age in days before journal entries are auto-pruned (0 = never)\n autoPromptDays: z.number().default(0),\n\n // Quiet mode — suppress snapshot side-effect messages in other commands\n quiet: z.boolean().default(true),\n});\n\n// Full configuration schema\nexport const ConfigSchema = z.object({\n // Version for config migrations\n version: z.number().default(1),\n\n // Display settings\n theme: ThemeSchema.default({}),\n ascii: z.boolean().default(true),\n animations: z.boolean().default(true),\n compactMode: z.boolean().default(false),\n\n // Command aliases\n aliases: AliasesSchema.default({}),\n\n // Output preferences\n output: OutputSchema.default({}),\n\n // Git settings\n git: GitSchema.default({}),\n\n // Multi-project support\n projects: z.array(ProjectSchema).default([]),\n activeProject: z.string().optional(),\n\n // Keyboard shortcuts\n shortcuts: ShortcutsSchema.default({}),\n\n // Project management integration\n projectManagement: ProjectManagementSchema.default({}),\n\n // Notifications (Slack/Discord webhooks)\n notifications: z\n .object({\n slack: z\n .object({\n enabled: z.boolean().default(false),\n webhookUrl: z.string().optional(),\n channel: z.string().optional(),\n })\n .default({}),\n discord: z\n .object({\n enabled: z.boolean().default(false),\n webhookUrl: z.string().optional(),\n })\n .default({}),\n // Schedule for auto-standup (e.g., \"0 8 * * 1-5\" = 8am weekdays)\n standupSchedule: z.string().optional(),\n standupTimezone: z.string().default('America/New_York'),\n })\n .default({}),\n\n // Journal / snapshot automation\n journal: JournalSchema.default({}),\n\n // AI/Copilot settings\n copilot: z\n .object({\n timeout: z.number().default(30000),\n retries: z.number().default(2),\n })\n .default({}),\n\n // Standup defaults\n standup: z\n .object({\n defaultDays: z.number().default(1),\n includeWIP: z.boolean().default(false),\n template: z.string().optional(),\n sections: z\n .array(z.enum(['completed', 'in-progress', 'blockers', 'tickets', 'stats']))\n .default(['completed', 'in-progress', 'blockers']),\n groupBy: z.enum(['ticket', 'category', 'time', 'none']).default('none'),\n includeTicketLinks: z.boolean().default(true),\n scheduleTime: z.string().optional(),\n scheduleDays: z\n .array(\n z.enum(['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'])\n )\n .default(['monday', 'tuesday', 'wednesday', 'thursday', 'friday']),\n })\n .default({}),\n\n // PR defaults\n pr: z\n .object({\n defaultBase: z.string().default('main'),\n template: z.string().optional(),\n autoLabels: z.boolean().default(true),\n defaultLabels: z.array(z.string()).default([]),\n defaultReviewers: z.array(z.string()).default([]),\n defaultAssignees: z.array(z.string()).default([]),\n titleFormat: z.enum(['conventional', 'ticket-first', 'plain']).default('conventional'),\n includeTicketInTitle: z.boolean().default(true),\n // Path to a custom PR description prompt file (like CLAUDE.md for PRs)\n // Searched automatically in: .devdaily-pr-prompt.md, .github/devdaily-pr-prompt.md, etc.\n promptFile: z.string().optional(),\n // Whether to include diff summary in the AI prompt for richer descriptions\n includeDiff: z.boolean().default(true),\n // Max lines of diff to include in the AI prompt (to avoid token limits)\n maxDiffLines: z.number().default(200),\n })\n .default({}),\n\n // Week defaults\n week: z\n .object({\n startDay: z.enum(['sunday', 'monday']).default('monday'),\n includeWeekends: z.boolean().default(false),\n })\n .default({}),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\nexport type Theme = z.infer<typeof ThemeSchema>;\nexport type Shortcuts = z.infer<typeof ShortcutsSchema>;\nexport type Project = z.infer<typeof ProjectSchema>;\nexport type ProjectManagement = z.infer<typeof ProjectManagementSchema>;\nexport type Journal = z.infer<typeof JournalSchema>;\n","/**\n * PM Error Types - Structured error handling for project management integrations\n *\n * Provides actionable error messages so users know exactly what went wrong\n * and how to fix it, rather than silent failures.\n */\n\nexport type PMTool = 'github' | 'jira' | 'linear' | 'notion';\n\n/**\n * Base error for all PM integration failures\n */\nexport class PMError extends Error {\n readonly tool: PMTool;\n readonly hint: string;\n\n constructor(tool: PMTool, message: string, hint: string, cause?: unknown) {\n super(message);\n this.name = 'PMError';\n this.tool = tool;\n this.hint = hint;\n if (cause) this.cause = cause;\n }\n\n /**\n * Format for user-facing display (CLI output)\n */\n toUserMessage(): string {\n return `[${this.tool.toUpperCase()}] ${this.message}\\n → ${this.hint}`;\n }\n}\n\n/**\n * Authentication/authorization failures\n * Examples: invalid API token, expired credentials, missing permissions\n */\nexport class PMAuthError extends PMError {\n constructor(tool: PMTool, details?: string, cause?: unknown) {\n const message = details || `Authentication failed for ${tool}`;\n const hints: Record<PMTool, string> = {\n jira: 'Check JIRA_API_TOKEN and JIRA_EMAIL env vars, or run `devdaily init --pm` to reconfigure',\n linear: 'Check LINEAR_API_KEY env var, or generate a new key at Linear Settings → API',\n notion: 'Check NOTION_API_KEY env var, or create an integration at notion.so/my-integrations',\n github: 'Run `gh auth login` to authenticate with GitHub CLI',\n };\n super(tool, message, hints[tool], cause);\n this.name = 'PMAuthError';\n }\n}\n\n/**\n * Connection/network failures\n * Examples: DNS resolution failed, timeout, unreachable host\n */\nexport class PMConnectionError extends PMError {\n readonly statusCode?: number;\n\n constructor(tool: PMTool, details?: string, statusCode?: number, cause?: unknown) {\n const message = details || `Could not connect to ${tool}`;\n const hints: Record<PMTool, string> = {\n jira: 'Verify your Jira base URL (e.g., https://yourcompany.atlassian.net) and network connection',\n linear: 'Check your network connection — Linear API endpoint: https://api.linear.app/graphql',\n notion: 'Check your network connection — Notion API endpoint: https://api.notion.com',\n github: 'Check your network connection and verify `gh` CLI is working: `gh auth status`',\n };\n super(tool, message, hints[tool], cause);\n this.name = 'PMConnectionError';\n this.statusCode = statusCode;\n }\n}\n\n/**\n * Resource not found\n * Examples: ticket ID doesn't exist, project key is wrong, database not found\n */\nexport class PMNotFoundError extends PMError {\n readonly resourceId: string;\n\n constructor(tool: PMTool, resourceId: string, resourceType = 'ticket', cause?: unknown) {\n const message = `${resourceType} \"${resourceId}\" not found in ${tool}`;\n const hints: Record<PMTool, string> = {\n jira: `Verify the ticket ID format (e.g., PROJ-123) and that it exists in your Jira instance`,\n linear: `Verify the issue identifier (e.g., ENG-123) and that you have access to the team`,\n notion: `Verify the page/database ID and that your integration has access to it`,\n github: `Verify the issue number exists in this repository: gh issue view ${resourceId}`,\n };\n super(tool, message, hints[tool], cause);\n this.name = 'PMNotFoundError';\n this.resourceId = resourceId;\n }\n}\n\n/**\n * Rate limiting\n */\nexport class PMRateLimitError extends PMError {\n readonly retryAfterMs?: number;\n\n constructor(tool: PMTool, retryAfterMs?: number, cause?: unknown) {\n const retryStr = retryAfterMs ? ` Retry after ${Math.ceil(retryAfterMs / 1000)} seconds.` : '';\n const message = `Rate limited by ${tool} API.${retryStr}`;\n super(tool, message, 'Wait a moment and try again, or reduce request frequency', cause);\n this.name = 'PMRateLimitError';\n this.retryAfterMs = retryAfterMs;\n }\n}\n\n/**\n * Configuration missing or invalid\n * Examples: no base URL set, no API key configured, invalid project key\n */\nexport class PMConfigError extends PMError {\n readonly missingFields: string[];\n\n constructor(tool: PMTool, missingFields: string[], cause?: unknown) {\n const fieldStr = missingFields.join(', ');\n const message = `${tool} integration is not fully configured — missing: ${fieldStr}`;\n const hints: Record<PMTool, string> = {\n jira: `Run \\`devdaily init --pm\\` or set env vars: ${missingFields.map((f) => jiraFieldToEnv(f)).join(', ')}`,\n linear: `Run \\`devdaily init --pm\\` or set env var: LINEAR_API_KEY`,\n notion: `Run \\`devdaily init --pm\\` or set env vars: ${missingFields.map((f) => notionFieldToEnv(f)).join(', ')}`,\n github: `Run \\`gh auth login\\` to authenticate with GitHub CLI`,\n };\n super(tool, message, hints[tool], cause);\n this.name = 'PMConfigError';\n this.missingFields = missingFields;\n }\n}\n\n/**\n * Invalid API response (unexpected shape, parse error)\n */\nexport class PMResponseError extends PMError {\n constructor(tool: PMTool, details?: string, cause?: unknown) {\n const message = details || `Unexpected response from ${tool} API`;\n super(\n tool,\n message,\n 'This may indicate an API version mismatch or a temporary service issue. Try again or check the API status page.',\n cause\n );\n this.name = 'PMResponseError';\n }\n}\n\n// --- Helper mappings for env var hints ---\n\nfunction jiraFieldToEnv(field: string): string {\n const map: Record<string, string> = {\n baseUrl: 'JIRA_BASE_URL',\n email: 'JIRA_EMAIL',\n apiToken: 'JIRA_API_TOKEN',\n projectKey: 'projectManagement.jira.projectKey in .devdaily.json',\n };\n return map[field] || field;\n}\n\nfunction notionFieldToEnv(field: string): string {\n const map: Record<string, string> = {\n apiKey: 'NOTION_API_KEY',\n databaseId: 'NOTION_DATABASE_ID',\n };\n return map[field] || field;\n}\n\n// --- Connection test result type ---\n\nexport interface PMConnectionTestResult {\n tool: PMTool;\n success: boolean;\n message: string;\n details: {\n /** Whether required credentials are present */\n credentialsFound: boolean;\n /** Whether the API responded successfully */\n apiReachable: boolean;\n /** Whether the credentials are valid (authenticated successfully) */\n authenticated: boolean;\n /** Detected project/team info (e.g., Jira project key, Linear team) */\n projectInfo?: string;\n /** Response time in milliseconds */\n responseTimeMs?: number;\n };\n error?: PMError;\n}\n\n/**\n * Create a successful connection test result\n */\nexport function successResult(\n tool: PMTool,\n projectInfo?: string,\n responseTimeMs?: number\n): PMConnectionTestResult {\n return {\n tool,\n success: true,\n message: `Successfully connected to ${tool}${projectInfo ? ` (${projectInfo})` : ''}`,\n details: {\n credentialsFound: true,\n apiReachable: true,\n authenticated: true,\n projectInfo,\n responseTimeMs,\n },\n };\n}\n\n/**\n * Create a failed connection test result from a PMError\n */\nexport function failureResult(tool: PMTool, error: PMError): PMConnectionTestResult {\n const isAuthError = error instanceof PMAuthError;\n const isConfigError = error instanceof PMConfigError;\n const isConnectionError = error instanceof PMConnectionError;\n\n return {\n tool,\n success: false,\n message: error.message,\n details: {\n credentialsFound: !isConfigError,\n apiReachable: !isConnectionError,\n authenticated: !isAuthError,\n },\n error,\n };\n}\n","/**\n * Context Analyzer - Extract rich context from git activity\n *\n * Features:\n * - Branch → Ticket correlation (JIRA-123, #123, LINEAR-123)\n * - Work categorization (frontend, backend, infra, docs)\n * - Commit message analysis\n * - Time-based work session tracking\n */\n\nimport { GitAnalyzer } from './git-analyzer.js';\nimport { Commit } from '../types/index.js';\n\n// Ticket patterns for different PM tools\nconst TICKET_PATTERNS = {\n jira: /([A-Z]{2,10}-\\d+)/gi,\n linear: /([A-Z]{2,5}-\\d+)/gi,\n github: /#(\\d+)/g,\n notion: /([a-f0-9]{32})/gi,\n};\n\n// File patterns for work categorization\nconst WORK_CATEGORIES = {\n frontend: [\n /\\.tsx?$/,\n /\\.jsx?$/,\n /\\.vue$/,\n /\\.svelte$/,\n /\\.css$/,\n /\\.scss$/,\n /\\.less$/,\n /components\\//,\n /pages\\//,\n /views\\//,\n /ui\\//,\n /styles\\//,\n ],\n backend: [\n /\\.go$/,\n /\\.py$/,\n /\\.rb$/,\n /\\.java$/,\n /\\.rs$/,\n /\\.php$/,\n /api\\//,\n /server\\//,\n /services\\//,\n /handlers\\//,\n /controllers\\//,\n /routes\\//,\n ],\n infrastructure: [\n /Dockerfile/,\n /docker-compose/,\n /\\.ya?ml$/,\n /\\.tf$/,\n /\\.hcl$/,\n /k8s\\//,\n /kubernetes\\//,\n /\\.github\\/workflows\\//,\n /\\.circleci\\//,\n /infra\\//,\n /deploy\\//,\n ],\n database: [/\\.sql$/, /migrations\\//, /prisma\\//, /schema\\./, /models\\//, /entities\\//],\n tests: [/\\.test\\./, /\\.spec\\./, /__tests__\\//, /tests?\\//, /cypress\\//, /e2e\\//],\n docs: [/\\.md$/, /\\.mdx$/, /docs?\\//, /README/, /CHANGELOG/, /CONTRIBUTING/],\n config: [\n /\\.json$/,\n /\\.ya?ml$/,\n /\\.toml$/,\n /\\.env/,\n /config\\//,\n /\\.config\\./,\n /tsconfig/,\n /package\\.json/,\n ],\n};\n\nexport interface TicketInfo {\n id: string;\n type: 'jira' | 'linear' | 'github' | 'notion' | 'unknown';\n url?: string;\n}\n\nexport interface WorkCategory {\n name: string;\n files: string[];\n percentage: number;\n}\n\nexport interface WorkContext {\n branch: string;\n tickets: TicketInfo[];\n categories: WorkCategory[];\n commitCount: number;\n filesChanged: string[];\n authors: string[];\n timeRange: {\n start: Date;\n end: Date;\n durationHours: number;\n };\n summary: {\n primaryCategory: string;\n ticketSummary: string;\n workDescription: string;\n };\n}\n\nexport class ContextAnalyzer {\n private git: GitAnalyzer;\n private ticketPrefix?: string;\n private pmTool: 'github' | 'jira' | 'linear' | 'notion' | 'none';\n\n constructor(\n repoPath?: string,\n pmTool: 'github' | 'jira' | 'linear' | 'notion' | 'none' = 'github',\n ticketPrefix?: string\n ) {\n this.git = new GitAnalyzer(repoPath);\n this.pmTool = pmTool;\n this.ticketPrefix = ticketPrefix;\n }\n\n /**\n * Extract ticket IDs from branch name\n */\n extractTicketsFromBranch(branchName: string): TicketInfo[] {\n const tickets: TicketInfo[] = [];\n\n // Try PM-specific pattern first\n if (this.ticketPrefix) {\n const prefixPattern = new RegExp(`(${this.ticketPrefix}-\\\\d+)`, 'gi');\n const matches = branchName.match(prefixPattern);\n if (matches) {\n for (const match of matches) {\n tickets.push({\n id: match.toUpperCase(),\n type: this.pmTool === 'none' ? 'unknown' : this.pmTool,\n });\n }\n }\n }\n\n // Try all patterns\n for (const [type, pattern] of Object.entries(TICKET_PATTERNS)) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(branchName)) !== null) {\n const id = type === 'github' ? `#${match[1]}` : match[1].toUpperCase();\n if (!tickets.find((t) => t.id === id)) {\n tickets.push({\n id,\n type: type as TicketInfo['type'],\n });\n }\n }\n }\n\n return tickets;\n }\n\n /**\n * Extract ticket IDs from commit messages\n */\n extractTicketsFromCommits(commits: Commit[]): TicketInfo[] {\n const tickets: TicketInfo[] = [];\n const seen = new Set<string>();\n\n for (const commit of commits) {\n const text = `${commit.message} ${commit.body || ''}`;\n\n // Try PM-specific pattern first\n if (this.ticketPrefix) {\n const prefixPattern = new RegExp(`(${this.ticketPrefix}-\\\\d+)`, 'gi');\n const matches = text.match(prefixPattern);\n if (matches) {\n for (const match of matches) {\n const id = match.toUpperCase();\n if (!seen.has(id)) {\n seen.add(id);\n tickets.push({\n id,\n type: this.pmTool === 'none' ? 'unknown' : this.pmTool,\n });\n }\n }\n }\n }\n\n // Try all patterns\n for (const [type, pattern] of Object.entries(TICKET_PATTERNS)) {\n const regex = new RegExp(pattern.source, pattern.flags);\n let match;\n while ((match = regex.exec(text)) !== null) {\n const id = type === 'github' ? `#${match[1]}` : match[1].toUpperCase();\n if (!seen.has(id)) {\n seen.add(id);\n tickets.push({\n id,\n type: type as TicketInfo['type'],\n });\n }\n }\n }\n }\n\n return tickets;\n }\n\n /**\n * Categorize files by work type\n */\n categorizeFiles(files: string[]): WorkCategory[] {\n const categoryCounts: Record<string, string[]> = {};\n\n for (const category of Object.keys(WORK_CATEGORIES)) {\n categoryCounts[category] = [];\n }\n\n for (const file of files) {\n let categorized = false;\n\n for (const [category, patterns] of Object.entries(WORK_CATEGORIES)) {\n for (const pattern of patterns) {\n if (pattern.test(file)) {\n categoryCounts[category].push(file);\n categorized = true;\n break;\n }\n }\n if (categorized) break;\n }\n\n if (!categorized) {\n if (!categoryCounts['other']) {\n categoryCounts['other'] = [];\n }\n categoryCounts['other'].push(file);\n }\n }\n\n const total = files.length || 1;\n const categories: WorkCategory[] = [];\n\n for (const [name, categoryFiles] of Object.entries(categoryCounts)) {\n if (categoryFiles.length > 0) {\n categories.push({\n name,\n files: categoryFiles,\n percentage: Math.round((categoryFiles.length / total) * 100),\n });\n }\n }\n\n // Sort by percentage descending\n categories.sort((a, b) => b.percentage - a.percentage);\n\n return categories;\n }\n\n /**\n * Get comprehensive work context\n */\n async getWorkContext(\n options: {\n since?: Date;\n until?: Date;\n base?: string;\n } = {}\n ): Promise<WorkContext> {\n const branch = await this.git.getCurrentBranch();\n const commits = await this.git.getCommits({\n since: options.since,\n until: options.until,\n });\n\n let filesChanged: string[] = [];\n\n // Try git diff first (works best on feature branches)\n try {\n filesChanged = await this.git.getChangedFiles(options.base || 'main', 'HEAD');\n } catch {\n // Expected: fails when base branch doesn't exist locally, or when on main branch\n // with no upstream. Falls through to commit-based file detection below.\n }\n\n // Fallback: get files from commit history if diff returned nothing\n if (filesChanged.length === 0 && commits.length > 0) {\n try {\n filesChanged = await this.git.getFilesFromCommits({\n since: options.since,\n until: options.until,\n });\n } catch {\n // Expected: may fail in shallow clones or repos with no commit history.\n // Proceed with empty filesChanged — categorization will just be skipped.\n }\n }\n\n // Extract tickets from branch and commits\n const branchTickets = this.extractTicketsFromBranch(branch);\n const commitTickets = this.extractTicketsFromCommits(commits);\n\n // Deduplicate tickets\n const ticketMap = new Map<string, TicketInfo>();\n for (const ticket of [...branchTickets, ...commitTickets]) {\n ticketMap.set(ticket.id, ticket);\n }\n const tickets = Array.from(ticketMap.values());\n\n // Categorize files\n const categories = this.categorizeFiles(filesChanged);\n\n // Get unique authors\n const authors = [...new Set(commits.map((c) => c.author))];\n\n // Calculate time range\n const dates = commits.map((c) => c.date);\n const start =\n dates.length > 0 ? new Date(Math.min(...dates.map((d) => d.getTime()))) : new Date();\n const end =\n dates.length > 0 ? new Date(Math.max(...dates.map((d) => d.getTime()))) : new Date();\n const durationHours = (end.getTime() - start.getTime()) / (1000 * 60 * 60);\n\n // Generate summary\n const primaryCategory = categories.length > 0 ? categories[0].name : 'general';\n const ticketSummary =\n tickets.length > 0\n ? `Working on ${tickets.map((t) => t.id).join(', ')}`\n : 'No tickets linked';\n const workDescription = this.generateWorkDescription(categories, commits);\n\n return {\n branch,\n tickets,\n categories,\n commitCount: commits.length,\n filesChanged,\n authors,\n timeRange: {\n start,\n end,\n durationHours: Math.round(durationHours * 10) / 10,\n },\n summary: {\n primaryCategory,\n ticketSummary,\n workDescription,\n },\n };\n }\n\n /**\n * Generate human-readable work description\n */\n private generateWorkDescription(categories: WorkCategory[], commits: Commit[]): string {\n const parts: string[] = [];\n\n // Top 2 categories\n const topCategories = categories.slice(0, 2);\n if (topCategories.length > 0) {\n const categoryNames = topCategories.map((c) => c.name).join(' and ');\n parts.push(`${categoryNames} work`);\n }\n\n // Commit types\n const commitTypes = this.analyzeCommitTypes(commits);\n if (commitTypes.length > 0) {\n parts.push(`(${commitTypes.join(', ')})`);\n }\n\n return parts.join(' ') || 'Development work';\n }\n\n /**\n * Analyze commit message types\n */\n private analyzeCommitTypes(commits: Commit[]): string[] {\n const types: Record<string, number> = {};\n\n for (const commit of commits) {\n const match = commit.message.match(/^(\\w+)[(:]/);\n if (match) {\n const type = match[1].toLowerCase();\n types[type] = (types[type] || 0) + 1;\n }\n }\n\n // Return top 3 types\n return Object.entries(types)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 3)\n .map(([type]) => type);\n }\n\n /**\n * Format context for AI prompt\n */\n formatContextForAI(context: WorkContext): string {\n const lines: string[] = [];\n\n lines.push(`Branch: ${context.branch}`);\n\n if (context.tickets.length > 0) {\n lines.push(`Tickets: ${context.tickets.map((t) => `${t.id} (${t.type})`).join(', ')}`);\n }\n\n if (context.categories.length > 0) {\n const categoryStr = context.categories\n .slice(0, 3)\n .map((c) => `${c.name}: ${c.percentage}%`)\n .join(', ');\n lines.push(`Work categories: ${categoryStr}`);\n }\n\n lines.push(`Commits: ${context.commitCount}`);\n lines.push(`Files changed: ${context.filesChanged.length}`);\n lines.push(`Time span: ${context.timeRange.durationHours} hours`);\n\n if (context.authors.length > 1) {\n lines.push(`Contributors: ${context.authors.join(', ')}`);\n }\n\n return lines.join('\\n');\n }\n}\n","/**\n * Standup Context Builder\n *\n * Assembles rich, factual context from multiple sources for accurate standup generation.\n * Instead of sending loose commit messages to the AI, this builds a structured data block\n * that includes:\n * - Exact git commits (hash, message, body, files)\n * - PR metadata (title, body, linked issues, review status)\n * - Ticket details from PM tools (Jira, Linear, GitHub Issues)\n * - Diff statistics (files changed, insertions, deletions)\n * - Branch and ticket correlations\n *\n * The goal: give the AI factual, structured data so it summarizes accurately\n * instead of hallucinating \"business-friendly\" rewrites.\n */\n\nimport { GitAnalyzer } from './git-analyzer.js';\nimport { GitHubClient } from './github.js';\nimport {\n getProjectManagementClient,\n extractTicketIds,\n extractTicketFromBranch,\n type Ticket,\n type ProjectManagementClient,\n} from './project-management.js';\nimport { ContextAnalyzer, type WorkContext, type WorkCategory } from './context-analyzer.js';\nimport { getConfig } from '../config/index.js';\nimport type { Commit, DiffStats } from '../types/index.js';\nimport { execa } from 'execa';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface PRInfo {\n number: number;\n title: string;\n body: string;\n state: string;\n labels: string[];\n url: string;\n baseBranch: string;\n headBranch: string;\n linkedTickets: string[];\n}\n\nexport interface CommitDetail {\n hash: string;\n shortHash: string;\n message: string;\n body?: string;\n author: string;\n date: Date;\n filesChanged?: string[];\n}\n\nexport interface StandupContext {\n /** Current branch name */\n branch: string;\n\n /** Exact git commits with full details */\n commits: CommitDetail[];\n\n /** PRs created/merged in the time window */\n pullRequests: PRInfo[];\n\n /** Tickets fetched from PM tool with full metadata */\n tickets: Ticket[];\n\n /** Diff statistics */\n diffStats: DiffStats | null;\n\n /** Top changed files with change counts */\n topChangedFiles: FileChange[];\n\n /** Work categories from file analysis */\n categories: WorkCategory[];\n\n /** All extracted ticket IDs (from branch, commits, PRs) */\n ticketIds: string[];\n\n /** Time range of the work */\n timeRange: {\n since: Date;\n until: Date;\n durationHours: number;\n };\n\n /** Repository info */\n repo: {\n name: string | null;\n defaultBranch: string;\n };\n\n /** Raw work context from context analyzer */\n workContext: WorkContext;\n}\n\nexport interface FileChange {\n path: string;\n /** Number of times this file appears across commits */\n frequency: number;\n}\n\nexport interface StandupContextOptions {\n /** Number of days to look back */\n days: number;\n /** Filter by author email */\n author?: string;\n /** Specific ticket IDs to include */\n ticketIds?: string[];\n /** Skip PM tool integration */\n skipTickets?: boolean;\n /** Skip PR fetching */\n skipPRs?: boolean;\n /** Base branch for diff */\n baseBranch?: string;\n /** Enable debug logging for ticket fetching and context assembly */\n debug?: boolean;\n}\n\n// ─── Context Builder ──────────────────────────────────────────────────────────\n\nexport class StandupContextBuilder {\n private git: GitAnalyzer;\n private github: GitHubClient;\n private pmClient: ProjectManagementClient;\n private contextAnalyzer: ContextAnalyzer;\n private config = getConfig();\n\n constructor(repoPath?: string) {\n this.git = new GitAnalyzer(repoPath);\n this.github = new GitHubClient();\n this.pmClient = getProjectManagementClient();\n this.contextAnalyzer = new ContextAnalyzer(\n repoPath,\n this.config.projectManagement.tool,\n this.config.projectManagement.ticketPrefix\n );\n }\n\n /**\n * Build comprehensive standup context from all available sources\n */\n async build(options: StandupContextOptions): Promise<StandupContext> {\n const since = new Date();\n since.setDate(since.getDate() - options.days);\n const until = new Date();\n\n const baseBranch = options.baseBranch || this.config.git.defaultBranch;\n\n // Phase 1: Gather data from independent sources in parallel\n const [branch, commits, workContext, diffStats, repoName] = await Promise.all([\n this.git.getCurrentBranch(),\n this.git.getCommits({ since, until, author: options.author }),\n this.contextAnalyzer.getWorkContext({ since, until, base: baseBranch }),\n this.safeDiffStats(baseBranch),\n this.safeRepoName(),\n ]);\n\n // Phase 2: Enrich commits with file change info\n const commitDetails = await this.enrichCommits(commits);\n\n // Phase 3: Fetch PRs (depends on nothing, but we do it here for clarity)\n let pullRequests: PRInfo[] = [];\n if (!options.skipPRs) {\n pullRequests = await this.fetchRecentPRs(since, options.author);\n }\n\n // Phase 4: Extract ALL ticket IDs from every source\n const ticketIds = this.extractAllTicketIds(branch, commits, pullRequests, options.ticketIds);\n\n // Phase 5: Fetch ticket details from PM tool\n let tickets: Ticket[] = [];\n if (!options.skipTickets && ticketIds.length > 0) {\n tickets = await this.fetchTickets(ticketIds, options.debug);\n }\n\n // Phase 6: Compute top changed files\n const topChangedFiles = this.computeTopChangedFiles(commitDetails);\n\n // Compute duration\n const dates = commits.map((c) => c.date.getTime());\n const earliest = dates.length > 0 ? Math.min(...dates) : since.getTime();\n const latest = dates.length > 0 ? Math.max(...dates) : until.getTime();\n const durationHours = Math.round(((latest - earliest) / (1000 * 60 * 60)) * 10) / 10;\n\n return {\n branch,\n commits: commitDetails,\n pullRequests,\n tickets,\n diffStats,\n topChangedFiles,\n categories: workContext.categories,\n ticketIds,\n timeRange: {\n since,\n until,\n durationHours,\n },\n repo: {\n name: repoName,\n defaultBranch: baseBranch,\n },\n workContext,\n };\n }\n\n // ─── Data Gathering ───────────────────────────────────────────────────────\n\n /**\n * Enrich commits with per-commit file changes\n */\n private async enrichCommits(commits: Commit[]): Promise<CommitDetail[]> {\n const details: CommitDetail[] = [];\n\n for (const commit of commits) {\n const filesChanged = await this.git.getCommitFiles(commit.hash);\n\n details.push({\n hash: commit.hash,\n shortHash: commit.hash.slice(0, 7),\n message: commit.message,\n body: commit.body,\n author: commit.author,\n date: commit.date,\n filesChanged: filesChanged.length > 0 ? filesChanged : undefined,\n });\n }\n\n return details;\n }\n\n /**\n * Fetch recent PRs created or merged by the user\n */\n private async fetchRecentPRs(since: Date, _author?: string): Promise<PRInfo[]> {\n const prs: PRInfo[] = [];\n\n try {\n // Check if we're in a GitHub repo\n const isGH = await this.github.isGitHubRepo();\n if (!isGH) return [];\n\n // Fetch merged PRs by current user in the time window\n const sinceStr = since.toISOString().split('T')[0];\n\n // Fetch open PRs by current user\n const openPRs = await this.fetchPRsFromGH('open');\n prs.push(...openPRs);\n\n // Fetch recently merged PRs\n const mergedPRs = await this.fetchMergedPRsFromGH(sinceStr);\n prs.push(...mergedPRs);\n\n // Deduplicate by PR number\n const seen = new Set<number>();\n const unique: PRInfo[] = [];\n for (const pr of prs) {\n if (!seen.has(pr.number)) {\n seen.add(pr.number);\n unique.push(pr);\n }\n }\n\n return unique;\n } catch {\n // PR fetching is best-effort - don't fail standup because of it\n return [];\n }\n }\n\n /**\n * Fetch PRs from GitHub CLI with a specific state\n */\n private async fetchPRsFromGH(state: 'open' | 'closed' | 'merged'): Promise<PRInfo[]> {\n try {\n const args = [\n 'pr',\n 'list',\n '--author',\n '@me',\n '--state',\n state === 'merged' ? 'closed' : state,\n '--json',\n 'number,title,body,state,labels,url,baseRefName,headRefName',\n '--limit',\n '20',\n ];\n\n const { stdout } = await execa('gh', args);\n const data = JSON.parse(stdout);\n\n return (data as Array<Record<string, unknown>>).map((pr) => this.parsePR(pr));\n } catch {\n return [];\n }\n }\n\n /**\n * Fetch merged PRs since a given date\n */\n private async fetchMergedPRsFromGH(sinceDate: string): Promise<PRInfo[]> {\n try {\n const { stdout } = await execa('gh', [\n 'pr',\n 'list',\n '--author',\n '@me',\n '--state',\n 'merged',\n '--search',\n `merged:>=${sinceDate}`,\n '--json',\n 'number,title,body,state,labels,url,baseRefName,headRefName',\n '--limit',\n '20',\n ]);\n\n const data = JSON.parse(stdout);\n return (data as Array<Record<string, unknown>>).map((pr) => this.parsePR(pr));\n } catch {\n return [];\n }\n }\n\n /**\n * Parse a raw GitHub PR JSON object into PRInfo\n */\n private parsePR(raw: Record<string, unknown>): PRInfo {\n const body = (raw.body as string) || '';\n const title = (raw.title as string) || '';\n\n // Extract ticket IDs from PR title and body\n const linkedTickets = extractTicketIds(`${title} ${body}`);\n\n return {\n number: raw.number as number,\n title,\n body: body.slice(0, 1000), // Cap body length\n state: ((raw.state as string) || '').toLowerCase(),\n labels: ((raw.labels as Array<{ name: string }>) || []).map((l) => l.name),\n url: (raw.url as string) || '',\n baseBranch: (raw.baseRefName as string) || '',\n headBranch: (raw.headRefName as string) || '',\n linkedTickets,\n };\n }\n\n /**\n * Extract ticket IDs from all sources\n */\n private extractAllTicketIds(\n branch: string,\n commits: Commit[],\n prs: PRInfo[],\n userTickets?: string[]\n ): string[] {\n const ids = new Set<string>();\n\n // From user-provided tickets\n if (userTickets) {\n for (const id of userTickets) {\n ids.add(id);\n }\n }\n\n // From branch name\n const branchTicket = extractTicketFromBranch(branch);\n if (branchTicket) {\n ids.add(branchTicket);\n }\n\n // From commit messages (including body)\n for (const commit of commits) {\n const text = `${commit.message} ${commit.body || ''}`;\n const commitTickets = extractTicketIds(text);\n for (const id of commitTickets) {\n ids.add(id);\n }\n }\n\n // From PR titles and bodies\n for (const pr of prs) {\n for (const id of pr.linkedTickets) {\n ids.add(id);\n }\n }\n\n return Array.from(ids);\n }\n\n /**\n * Fetch ticket details from PM tool, with graceful error handling\n */\n private async fetchTickets(ticketIds: string[], debug = false): Promise<Ticket[]> {\n try {\n const isConfigured = await this.pmClient.isConfigured();\n if (!isConfigured) {\n if (debug) {\n console.error(`[fetchTickets] PM client (${this.pmClient.tool}) is not configured`);\n }\n return [];\n }\n\n if (debug) {\n console.error(\n `[fetchTickets] Fetching ${ticketIds.length} tickets via ${this.pmClient.tool}: ${ticketIds.join(', ')}`\n );\n }\n\n const tickets = await this.pmClient.getTickets(ticketIds);\n\n if (debug) {\n console.error(`[fetchTickets] Fetched ${tickets.length}/${ticketIds.length} tickets`);\n }\n\n return tickets;\n } catch (err) {\n // PM tool errors shouldn't break standup generation, but log in debug mode\n if (debug) {\n console.error(`[fetchTickets] Error fetching tickets:`, err);\n }\n return [];\n }\n }\n\n /**\n * Get diff stats safely (may fail on main branch or shallow clones)\n */\n private async safeDiffStats(baseBranch: string): Promise<DiffStats | null> {\n try {\n return await this.git.getDiffStats(baseBranch, 'HEAD');\n } catch {\n return null;\n }\n }\n\n /**\n * Get repo name safely\n */\n private async safeRepoName(): Promise<string | null> {\n try {\n const info = await this.github.getRepoInfo();\n return info ? `${info.owner}/${info.name}` : null;\n } catch {\n return null;\n }\n }\n\n /**\n * Compute most frequently changed files across commits\n */\n private computeTopChangedFiles(commits: CommitDetail[]): FileChange[] {\n const fileCounts = new Map<string, number>();\n\n for (const commit of commits) {\n if (commit.filesChanged) {\n for (const file of commit.filesChanged) {\n fileCounts.set(file, (fileCounts.get(file) || 0) + 1);\n }\n }\n }\n\n return Array.from(fileCounts.entries())\n .map(([path, frequency]) => ({ path, frequency }))\n .sort((a, b) => b.frequency - a.frequency)\n .slice(0, 15); // Top 15 files\n }\n\n // ─── Context Formatting ─────────────────────────────────────────────────────\n\n /**\n * Format the full context into a structured text block for the AI prompt.\n * This is the critical piece - it must be factual and structured so the AI\n * doesn't hallucinate or over-generalize.\n */\n static formatForPrompt(ctx: StandupContext): string {\n const sections: string[] = [];\n\n // ── Header\n sections.push('=== STANDUP CONTEXT (factual data — do NOT invent details) ===');\n sections.push('');\n\n // ── Repository info\n if (ctx.repo.name) {\n sections.push(`Repository: ${ctx.repo.name}`);\n }\n sections.push(`Branch: ${ctx.branch}`);\n sections.push(\n `Period: ${ctx.timeRange.since.toLocaleDateString()} to ${ctx.timeRange.until.toLocaleDateString()}`\n );\n sections.push('');\n\n // ── Commits (exact, unmodified)\n sections.push(`--- GIT COMMITS (${ctx.commits.length} total) ---`);\n if (ctx.commits.length === 0) {\n sections.push('(no commits in this period)');\n } else {\n for (const commit of ctx.commits) {\n const dateStr = commit.date.toLocaleString();\n sections.push(`[${commit.shortHash}] ${commit.message}`);\n if (commit.body) {\n // Include commit body but trim to reasonable length\n const body = commit.body.trim().slice(0, 300);\n sections.push(` Body: ${body}`);\n }\n if (commit.filesChanged && commit.filesChanged.length > 0) {\n const fileList = commit.filesChanged.slice(0, 5).join(', ');\n const more =\n commit.filesChanged.length > 5 ? ` (+${commit.filesChanged.length - 5} more)` : '';\n sections.push(` Files: ${fileList}${more}`);\n }\n sections.push(` Author: ${commit.author} | Date: ${dateStr}`);\n }\n }\n sections.push('');\n\n // ── Pull Requests\n if (ctx.pullRequests.length > 0) {\n sections.push(`--- PULL REQUESTS (${ctx.pullRequests.length}) ---`);\n for (const pr of ctx.pullRequests) {\n const labels = pr.labels.length > 0 ? ` [${pr.labels.join(', ')}]` : '';\n sections.push(`PR #${pr.number}: ${pr.title} (${pr.state})${labels}`);\n sections.push(` Branch: ${pr.headBranch} → ${pr.baseBranch}`);\n if (pr.body) {\n // Include first ~300 chars of PR body\n const bodyPreview = pr.body.trim().replace(/\\n/g, ' ').slice(0, 300);\n sections.push(` Description: ${bodyPreview}`);\n }\n if (pr.linkedTickets.length > 0) {\n sections.push(` Linked tickets: ${pr.linkedTickets.join(', ')}`);\n }\n sections.push(` URL: ${pr.url}`);\n }\n sections.push('');\n }\n\n // ── Tickets from PM tool\n if (ctx.tickets.length > 0) {\n sections.push(`--- TICKETS/ISSUES (${ctx.tickets.length}) ---`);\n for (const ticket of ctx.tickets) {\n const priority = ticket.priority ? ` | Priority: ${ticket.priority}` : '';\n sections.push(`${ticket.id}: ${ticket.title}`);\n sections.push(` Type: ${ticket.type} | Status: ${ticket.status}${priority}`);\n if (ticket.description) {\n const raw =\n typeof ticket.description === 'string'\n ? ticket.description\n : String(ticket.description);\n const desc = raw.trim().replace(/\\n/g, ' ').slice(0, 200);\n if (desc) {\n sections.push(` Description: ${desc}`);\n }\n }\n if (ticket.url) {\n sections.push(` URL: ${ticket.url}`);\n }\n }\n sections.push('');\n } else if (ctx.ticketIds.length > 0) {\n // We have ticket IDs but couldn't fetch details\n sections.push(`--- TICKET REFERENCES (not fetched) ---`);\n sections.push(`Ticket IDs found: ${ctx.ticketIds.join(', ')}`);\n sections.push('');\n }\n\n // ── Diff Statistics\n if (ctx.diffStats) {\n sections.push('--- DIFF STATISTICS ---');\n sections.push(`Files changed: ${ctx.diffStats.filesChanged}`);\n sections.push(`Lines added: +${ctx.diffStats.insertions}`);\n sections.push(`Lines removed: -${ctx.diffStats.deletions}`);\n sections.push('');\n }\n\n // ── Top Changed Files\n if (ctx.topChangedFiles.length > 0) {\n sections.push('--- TOP CHANGED FILES ---');\n for (const file of ctx.topChangedFiles.slice(0, 10)) {\n const freq = file.frequency > 1 ? ` (${file.frequency} commits)` : '';\n sections.push(` ${file.path}${freq}`);\n }\n sections.push('');\n }\n\n // ── Work Categories\n if (ctx.categories.length > 0) {\n sections.push('--- WORK AREAS ---');\n for (const cat of ctx.categories.slice(0, 5)) {\n sections.push(` ${cat.name}: ${cat.percentage}% (${cat.files.length} files)`);\n }\n sections.push('');\n }\n\n sections.push('=== END CONTEXT ===');\n\n return sections.join('\\n');\n }\n\n /**\n * Format a compact debug view of the context for terminal display\n */\n static formatDebugSummary(ctx: StandupContext): string {\n const lines: string[] = [];\n\n lines.push('┌─────────────────────────────────────────────┐');\n lines.push('│ STANDUP CONTEXT (debug) │');\n lines.push('├─────────────────────────────────────────────┤');\n\n // Basic info\n if (ctx.repo.name) {\n lines.push(`│ Repo: ${ctx.repo.name}`);\n }\n lines.push(`│ Branch: ${ctx.branch}`);\n lines.push(\n `│ Period: ${ctx.timeRange.since.toLocaleDateString()} → ${ctx.timeRange.until.toLocaleDateString()}`\n );\n lines.push(`│ Duration: ${ctx.timeRange.durationHours}h`);\n lines.push('│');\n\n // Commits\n lines.push(`│ Commits: ${ctx.commits.length}`);\n for (const c of ctx.commits.slice(0, 10)) {\n lines.push(`│ [${c.shortHash}] ${c.message.slice(0, 60)}`);\n }\n if (ctx.commits.length > 10) {\n lines.push(`│ ... and ${ctx.commits.length - 10} more`);\n }\n lines.push('│');\n\n // PRs\n lines.push(`│ PRs: ${ctx.pullRequests.length}`);\n for (const pr of ctx.pullRequests) {\n lines.push(`│ #${pr.number} ${pr.title.slice(0, 55)} (${pr.state})`);\n }\n lines.push('│');\n\n // Tickets\n lines.push(`│ Tickets: ${ctx.tickets.length} fetched, ${ctx.ticketIds.length} IDs found`);\n for (const t of ctx.tickets) {\n lines.push(`│ ${t.id}: ${t.title.slice(0, 50)} [${t.status}]`);\n }\n if (ctx.ticketIds.length > ctx.tickets.length) {\n const unfetched = ctx.ticketIds.filter((id) => !ctx.tickets.find((t) => t.id === id));\n if (unfetched.length > 0) {\n lines.push(`│ (unfetched: ${unfetched.join(', ')})`);\n }\n }\n lines.push('│');\n\n // Diff stats\n if (ctx.diffStats) {\n lines.push(\n `│ Diff: ${ctx.diffStats.filesChanged} files, +${ctx.diffStats.insertions}/-${ctx.diffStats.deletions}`\n );\n } else {\n lines.push(`│ Diff: (not available)`);\n }\n\n // Categories\n if (ctx.categories.length > 0) {\n const cats = ctx.categories\n .slice(0, 3)\n .map((c) => `${c.name}(${c.percentage}%)`)\n .join(', ');\n lines.push(`│ Areas: ${cats}`);\n }\n\n // Top files\n if (ctx.topChangedFiles.length > 0) {\n lines.push(`│ Top files:`);\n for (const f of ctx.topChangedFiles.slice(0, 5)) {\n lines.push(`│ ${f.path}`);\n }\n }\n\n lines.push('└─────────────────────────────────────────────┘');\n\n return lines.join('\\n');\n }\n\n /**\n * Build the full AI prompt for standup generation using the assembled context.\n * This prompt is designed to produce ACCURATE output, not creative rewrites.\n */\n static buildStandupPrompt(\n ctx: StandupContext,\n tone: 'engineering' | 'mixed' | 'business' = 'mixed'\n ): string {\n const contextBlock = StandupContextBuilder.formatForPrompt(ctx);\n\n const toneInstructions: Record<string, string> = {\n engineering: `- Use precise technical language (mention file names, modules, APIs where relevant)\n- Keep descriptions accurate to the actual commit messages and PR descriptions\n- Include ticket IDs inline where applicable\n- This is for an engineering audience — be specific about what code changed`,\n\n mixed: `- Write clearly for both technical and non-technical readers\n- Keep descriptions accurate and grounded in the actual commits/PRs\n- Mention ticket IDs inline where applicable\n- Describe the PURPOSE of changes (from ticket/PR context) alongside WHAT changed\n- Do NOT invent impacts or user-facing benefits that aren't evident from the data`,\n\n business: `- Describe work in terms of features, fixes, and improvements\n- Reference ticket IDs where available\n- Focus on outcomes and deliverables\n- Keep it grounded — only mention impacts that are clearly implied by the ticket/PR descriptions\n- Do NOT fabricate user-facing benefits unless the ticket description explicitly mentions them`,\n };\n\n const prompt = `You are generating a daily standup update from REAL git and project data.\n\nCRITICAL RULES:\n1. ONLY describe work that appears in the context data below. Do NOT invent or embellish.\n2. Use the EXACT commit messages, PR titles, and ticket titles as your source of truth.\n3. If a ticket has a description, use it to understand the PURPOSE, but don't fabricate details.\n4. If something is unclear from the data, say what the commit/PR says literally.\n5. Do NOT add generic filler like \"improving user experience\" unless a ticket explicitly says that.\n6. Keep it concise — 3-6 bullet points for completed work, not more.\n\n${contextBlock}\n\nNow write a standup update in this format:\n\n**Yesterday/Recently:**\n• [Accurate description of what was done — grounded in the commits/PRs/tickets above]\n• [Another item — reference ticket IDs like PROJ-123 or #123 where they exist]\n• [Continue for significant items only — group related commits together]\n\n**Today/Next:**\n• [Based on any open PRs or in-progress tickets, suggest what's next]\n• [If no signals, write \"Continue current work\" or \"Review and merge open PRs\"]\n\n**Blockers:** None (or describe if evident from the data)\n\nTone guidelines:\n${toneInstructions[tone]}\n\nAdditional rules:\n- Group related commits into single bullet points (e.g., multiple commits on the same feature = 1 bullet)\n- Reference PR numbers as \"PR #N\" and ticket IDs as-is\n- If there are both commits and matching PRs, prefer the PR title as it's usually more descriptive\n- Do NOT start bullets with \"Worked on\" repeatedly — vary the language naturally\n- Do NOT add emoji\n- Keep the total output under 300 words\n`;\n\n return prompt;\n }\n\n /**\n * Build prompt for weekly summary using the same structured approach\n */\n static buildWeeklyPrompt(ctx: StandupContext): string {\n const contextBlock = StandupContextBuilder.formatForPrompt(ctx);\n\n return `You are generating a weekly work summary from REAL git and project data.\n\nCRITICAL RULES:\n1. ONLY describe work that appears in the context data below. Do NOT invent or embellish.\n2. Use the EXACT commit messages, PR titles, and ticket titles as your source of truth.\n3. Group related work into themes/features — don't list every commit individually.\n\n${contextBlock}\n\nWrite a weekly summary in this format:\n\n**Key Accomplishments:**\n1. [Major accomplishment — reference tickets/PRs]\n2. [Second accomplishment]\n3. [Third accomplishment]\n(3-5 items max)\n\n**Stats:** X commits, Y PRs, Z tickets addressed\n\n**Top Achievement:** [Single sentence highlighting the most impactful work]\n\nRules:\n- Be factual and grounded in the data\n- Reference ticket IDs and PR numbers\n- Suitable for sharing with a manager or in a team meeting\n- Under 200 words total\n- No emoji\n`;\n }\n}\n","/**\n * Custom PR Description Prompt Loader\n *\n * Loads a custom prompt file (like CLAUDE.md but for PR descriptions)\n * that teams can use to customize how AI generates PR descriptions.\n *\n * Search order:\n * 1. Path specified in config (`pr.promptFile`)\n * 2. `.devdaily-pr-prompt.md` in repo root\n * 3. `.github/devdaily-pr-prompt.md`\n * 4. `.github/PR_DESCRIPTION_PROMPT.md`\n * 5. `docs/devdaily-pr-prompt.md`\n *\n * The file content is injected into the AI prompt as \"team guidelines\"\n * so the AI follows repo-specific rules for tone, format, sections, etc.\n */\n\nimport { readFile, access } from 'fs/promises';\nimport { join } from 'path';\nimport { getConfig } from '../config/index.js';\n\nexport interface PRPromptConfig {\n /** The raw markdown content of the prompt file */\n raw: string;\n /** The path where the prompt file was found */\n path: string;\n /** Parsed guidelines (if structured with headings) */\n guidelines: PRGuideline[];\n}\n\nexport interface PRGuideline {\n /** Section heading */\n heading: string;\n /** Section content */\n content: string;\n}\n\n/**\n * Common prompt file locations (in order of precedence)\n */\nconst PROMPT_FILE_PATHS = [\n '.devdaily-pr-prompt.md',\n '.github/devdaily-pr-prompt.md',\n '.github/PR_DESCRIPTION_PROMPT.md',\n 'docs/devdaily-pr-prompt.md',\n];\n\n/**\n * Check if a file exists\n */\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Find the PR prompt file in the repository\n */\nexport async function findPRPromptFile(repoRoot: string): Promise<string | null> {\n const config = getConfig();\n\n // 1. Check config-specified path first\n const configPath = config.pr.promptFile;\n if (configPath) {\n const fullPath = configPath.startsWith('/') ? configPath : join(repoRoot, configPath);\n if (await fileExists(fullPath)) {\n return fullPath;\n }\n }\n\n // 2. Check standard locations\n for (const promptPath of PROMPT_FILE_PATHS) {\n const fullPath = join(repoRoot, promptPath);\n if (await fileExists(fullPath)) {\n return fullPath;\n }\n }\n\n return null;\n}\n\n/**\n * Parse the prompt file into structured guidelines\n */\nexport function parsePRPrompt(content: string): PRGuideline[] {\n const guidelines: PRGuideline[] = [];\n\n // Normalize line endings (Windows \\r\\n → \\n)\n const normalized = content.replace(/\\r\\n/g, '\\n');\n const lines = normalized.split('\\n');\n\n let currentHeading: string | null = null;\n let currentContent: string[] = [];\n let insideCodeBlock = false;\n\n for (const line of lines) {\n // Track fenced code blocks so we don't treat headings inside them as real headings\n if (line.trimEnd().startsWith('```')) {\n insideCodeBlock = !insideCodeBlock;\n if (currentHeading !== null) {\n currentContent.push(line);\n }\n continue;\n }\n\n // Only match headings (h1–h3) when NOT inside a code block\n const headingMatch = !insideCodeBlock ? line.match(/^#{1,3}\\s+(.+)$/) : null;\n\n if (headingMatch) {\n // Save previous section\n if (currentHeading !== null) {\n guidelines.push({\n heading: currentHeading,\n content: currentContent.join('\\n').trim(),\n });\n }\n currentHeading = headingMatch[1].trim();\n currentContent = [];\n } else if (currentHeading !== null) {\n currentContent.push(line);\n } else {\n // Content before any heading — treat as a \"General\" section\n if (line.trim()) {\n if (!currentHeading) {\n currentHeading = 'General';\n }\n currentContent.push(line);\n }\n }\n }\n\n // Don't forget the last section\n if (currentHeading !== null) {\n guidelines.push({\n heading: currentHeading,\n content: currentContent.join('\\n').trim(),\n });\n }\n\n return guidelines;\n}\n\n/**\n * Load and parse the PR prompt file\n */\nexport async function loadPRPrompt(repoRoot: string): Promise<PRPromptConfig | null> {\n const promptPath = await findPRPromptFile(repoRoot);\n\n if (!promptPath) {\n return null;\n }\n\n try {\n const content = await readFile(promptPath, 'utf-8');\n const guidelines = parsePRPrompt(content);\n\n return {\n raw: content,\n path: promptPath,\n guidelines,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Format the PR prompt config into a string suitable for injection into the AI prompt.\n * This produces a clearly delineated block that tells the AI to follow these rules.\n */\nexport function formatPRPromptForAI(promptConfig: PRPromptConfig): string {\n const lines: string[] = [\n '',\n '=== TEAM PR DESCRIPTION GUIDELINES (follow these strictly) ===',\n '',\n ];\n\n if (promptConfig.guidelines.length > 0) {\n for (const guideline of promptConfig.guidelines) {\n lines.push(`### ${guideline.heading}`);\n if (guideline.content) {\n lines.push(guideline.content);\n }\n lines.push('');\n }\n } else {\n // No structured guidelines — just include the raw content\n lines.push(promptConfig.raw);\n lines.push('');\n }\n\n lines.push('=== END TEAM GUIDELINES ===');\n lines.push('');\n\n return lines.join('\\n');\n}\n\n/**\n * Generate a sample PR prompt file that teams can customize\n */\nexport function generateSamplePRPrompt(): string {\n return `# PR Description Guidelines\n\nThese guidelines tell DevDaily AI how to generate PR descriptions for your team.\nCustomize this file to match your team's conventions.\n\n## Tone & Style\n\n- Write in a professional but approachable tone\n- Be concise — aim for clarity over verbosity\n- Use bullet points for lists of changes\n- Avoid jargon unless it's well-known in the team\n- No emojis in the description body (section headers are fine)\n\n## Description Format\n\n- Start with a one-sentence summary of what the PR does\n- Follow with bullet points of specific changes\n- Group related changes together\n- Mention any architectural decisions or trade-offs\n\n## Ticket References\n\n- Always include ticket IDs (e.g., PROJ-123) when available\n- Link to the ticket URL when possible\n- Explain how the changes relate to the ticket's acceptance criteria\n\n## Testing Instructions\n\n- Provide step-by-step instructions for reviewers to test\n- Include any required environment setup\n- Mention edge cases that should be verified\n- Include expected vs actual behavior for bug fixes\n\n## Breaking Changes\n\n- Clearly call out any breaking changes\n- Explain migration steps if applicable\n- Tag breaking changes with a warning\n\n## What NOT to Include\n\n- Don't list every file changed (that's in the diff)\n- Don't repeat commit messages verbatim\n- Don't include implementation details that are obvious from the code\n- Don't include TODOs — create follow-up tickets instead\n`;\n}\n\n/**\n * Get the default path where a new PR prompt file should be created\n */\nexport function getDefaultPRPromptPath(repoRoot: string): string {\n return join(repoRoot, '.devdaily-pr-prompt.md');\n}\n","/**\n * Output formatter — converts AI-generated markdown to other output formats.\n *\n * Supported formats:\n * - markdown (passthrough)\n * - plain (strip all markdown syntax)\n * - slack (convert to Slack mrkdwn)\n * - json (structured JSON object)\n */\n\nexport type OutputFormat = 'markdown' | 'slack' | 'plain' | 'json';\n\nexport interface FormattedOutput {\n /** The transformed text ready for display / clipboard */\n text: string;\n /** The original markdown (always kept) */\n raw: string;\n /** Which format was applied */\n format: OutputFormat;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Format standup / PR / weekly text into the requested output format.\n */\nexport function formatOutput(\n markdown: string,\n format: OutputFormat = 'markdown',\n meta?: {\n title?: string;\n commits?: number;\n prs?: number;\n tickets?: number;\n days?: number;\n branch?: string;\n repo?: string;\n }\n): FormattedOutput {\n switch (format) {\n case 'plain':\n return { text: toPlain(markdown), raw: markdown, format };\n case 'slack':\n return { text: toSlack(markdown), raw: markdown, format };\n case 'json':\n return { text: toJSON(markdown, meta), raw: markdown, format };\n case 'markdown':\n default:\n return { text: markdown, raw: markdown, format };\n }\n}\n\n/**\n * Validate that a string is a supported output format.\n * Returns the validated format or the fallback.\n */\nexport function validateFormat(value: string, fallback: OutputFormat = 'markdown'): OutputFormat {\n const valid: OutputFormat[] = ['markdown', 'slack', 'plain', 'json'];\n if (valid.includes(value as OutputFormat)) {\n return value as OutputFormat;\n }\n return fallback;\n}\n\n// ─── Converters ───────────────────────────────────────────────────────────────\n\n/**\n * Strip markdown syntax and return plain text.\n */\nfunction toPlain(md: string): string {\n let text = md;\n\n // Remove horizontal rules (---, ***, ___)\n text = text.replace(/^[ \\t]*([-*_]){3,}[ \\t]*$/gm, '');\n\n // Convert headers to plain text with a colon suffix\n // e.g. \"## In Progress\" → \"In Progress:\"\n text = text.replace(/^#{1,6}\\s+(.+)$/gm, (_match, heading: string) => {\n const cleaned = heading.trim();\n // Don't add colon if it already ends with punctuation\n if (/[.:!?]$/.test(cleaned)) {\n return cleaned;\n }\n return `${cleaned}:`;\n });\n\n // Bold: **text** or __text__ → text\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, '$1');\n text = text.replace(/__(.+?)__/g, '$1');\n\n // Italic: *text* or _text_ → text\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, '$1');\n text = text.replace(/(?<!_)_(?!_)(.+?)(?<!_)_(?!_)/g, '$1');\n\n // Strikethrough: ~~text~~ → text\n text = text.replace(/~~(.+?)~~/g, '$1');\n\n // Inline code: `code` → code\n text = text.replace(/`([^`]+)`/g, '$1');\n\n // Code blocks: ```lang\\ncode\\n``` → code\n text = text.replace(/```[\\s\\S]*?\\n([\\s\\S]*?)```/g, '$1');\n\n // Links: [text](url) → text (url)\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '$1 ($2)');\n\n // Images: ![alt](url) → [Image: alt]\n text = text.replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, '[Image: $1]');\n\n // Unordered list markers: - item or * item → • item\n text = text.replace(/^[ \\t]*[-*]\\s+/gm, '• ');\n\n // Ordered list markers are fine as-is (1. item)\n\n // Blockquotes: > text → text\n text = text.replace(/^>+\\s?/gm, '');\n\n // Collapse multiple blank lines\n text = text.replace(/\\n{3,}/g, '\\n\\n');\n\n return text.trim();\n}\n\n/**\n * Convert markdown to Slack mrkdwn format.\n *\n * Key differences from standard markdown:\n * - Bold: **text** → *text*\n * - Italic: *text* → _text_\n * - Strike: ~~text~~ → ~text~\n * - Links: [t](url) → <url|t>\n * - Headers: ## Foo → *Foo*\n * - Code block: ``` → ``` (same, but no language tag)\n * - Lists: - item → • item\n */\nfunction toSlack(md: string): string {\n let text = md;\n\n // Use Unicode private-use area chars as safe placeholder delimiters\n // so they won't be matched by bold/italic/underscore regexes.\n const PH_START = '\\uE000';\n const PH_END = '\\uE001';\n\n // Code blocks first (protect from other transforms).\n // Strip the language identifier after ```.\n const codeBlocks: string[] = [];\n text = text.replace(/```\\w*\\n([\\s\\S]*?)```/g, (_match, code: string) => {\n const placeholder = `${PH_START}CB${codeBlocks.length}${PH_END}`;\n codeBlocks.push('```\\n' + code + '```');\n return placeholder;\n });\n\n // Inline code — leave as-is (Slack supports `code`)\n const inlineCodes: string[] = [];\n text = text.replace(/`([^`]+)`/g, (_match, code: string) => {\n const placeholder = `${PH_START}IC${inlineCodes.length}${PH_END}`;\n inlineCodes.push('`' + code + '`');\n return placeholder;\n });\n\n // Images → just the URL\n text = text.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '<$2|$1>');\n\n // Links: [text](url) → <url|text>\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<$2|$1>');\n\n // Italic first: convert single *text* → _text_ BEFORE we collapse **text**\n // This way, double-asterisk bold won't be partially eaten by the italic pass.\n // Match single asterisks that are NOT adjacent to another asterisk.\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, '_$1_');\n\n // Bold: **text** → *text* (Slack uses single asterisk for bold)\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, '*$1*');\n\n // __text__ bold (underscore variant) — also convert to Slack bold *text*\n // Use a regex that won't match our safe placeholders (which use PH_START/PH_END)\n text = text.replace(/(?<!\\uE000)__(.+?)__(?!\\uE001)/g, '*$1*');\n\n // Headers → bold in Slack (## Foo → *Foo*)\n text = text.replace(/^#{1,6}\\s+(.+)$/gm, '*$1*');\n\n // Strikethrough: ~~text~~ → ~text~\n text = text.replace(/~~(.+?)~~/g, '~$1~');\n\n // Unordered list markers\n text = text.replace(/^[ \\t]*[-*]\\s+/gm, '• ');\n\n // Blockquotes: > text → > text (Slack supports this natively)\n // Leave as-is\n\n // Horizontal rules → divider-like text\n text = text.replace(/^[ \\t]*([-*_]){3,}[ \\t]*$/gm, '───────────────────────');\n\n // Restore code blocks\n for (let i = 0; i < codeBlocks.length; i++) {\n text = text.replace(`${PH_START}CB${i}${PH_END}`, codeBlocks[i]);\n }\n\n // Restore inline code\n for (let i = 0; i < inlineCodes.length; i++) {\n text = text.replace(`${PH_START}IC${i}${PH_END}`, inlineCodes[i]);\n }\n\n // Collapse multiple blank lines\n text = text.replace(/\\n{3,}/g, '\\n\\n');\n\n return text.trim();\n}\n\n/**\n * Convert markdown standup to a structured JSON string.\n */\nfunction toJSON(\n md: string,\n meta?: {\n title?: string;\n commits?: number;\n prs?: number;\n tickets?: number;\n days?: number;\n branch?: string;\n repo?: string;\n }\n): string {\n const sections = parseSections(md);\n\n const output: Record<string, unknown> = {\n generatedAt: new Date().toISOString(),\n };\n\n if (meta) {\n output.meta = { ...meta };\n }\n\n output.sections = sections;\n output.raw = md;\n\n return JSON.stringify(output, null, 2);\n}\n\n// ─── Section parser ───────────────────────────────────────────────────────────\n\ninterface Section {\n heading: string;\n level: number;\n items: string[];\n body: string;\n}\n\n/**\n * Parse markdown into sections keyed by heading.\n */\nfunction parseSections(md: string): Section[] {\n const lines = md.split('\\n');\n const sections: Section[] = [];\n let current: Section | null = null;\n let bodyLines: string[] = [];\n\n const flushCurrent = () => {\n if (current) {\n current.body = bodyLines.join('\\n').trim();\n current.items = extractListItems(current.body);\n sections.push(current);\n }\n };\n\n for (const line of lines) {\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (headingMatch) {\n flushCurrent();\n current = {\n heading: headingMatch[2].trim(),\n level: headingMatch[1].length,\n items: [],\n body: '',\n };\n bodyLines = [];\n } else {\n bodyLines.push(line);\n }\n }\n\n // Flush last section\n flushCurrent();\n\n // If there were no headings at all, treat the whole thing as one section\n if (sections.length === 0 && md.trim().length > 0) {\n const body = md.trim();\n sections.push({\n heading: 'Content',\n level: 0,\n items: extractListItems(body),\n body,\n });\n }\n\n return sections;\n}\n\n/**\n * Extract bullet / numbered list items from a body of text.\n */\nfunction extractListItems(body: string): string[] {\n const items: string[] = [];\n for (const line of body.split('\\n')) {\n const match = line.match(/^[ \\t]*(?:[-*]|\\d+[.)]) \\s*(.+)$/);\n if (match) {\n items.push(match[1].trim());\n }\n }\n return items;\n}\n","/**\n * Notification integrations for Slack and Discord\n * Sends standup updates, PR notifications, etc. via webhooks\n */\n\nimport { getConfig, getSecrets } from '../config/index.js';\nimport { formatOutput } from '../utils/formatter.js';\n\nexport interface NotificationMessage {\n title?: string;\n text: string;\n type?: 'standup' | 'pr' | 'weekly' | 'info';\n ticketLinks?: { id: string; url: string; title?: string }[];\n footer?: string;\n}\n\n/**\n * Slack webhook message format\n */\ninterface SlackMessage {\n text?: string;\n blocks?: SlackBlock[];\n attachments?: SlackAttachment[];\n}\n\ninterface SlackBlock {\n type: string;\n text?: {\n type: string;\n text: string;\n emoji?: boolean;\n };\n elements?: Array<{\n type: string;\n text?: string;\n url?: string;\n style?: string;\n }>;\n}\n\ninterface SlackAttachment {\n color?: string;\n blocks?: SlackBlock[];\n}\n\n/**\n * Discord webhook message format\n */\ninterface DiscordMessage {\n content?: string;\n embeds?: DiscordEmbed[];\n username?: string;\n avatar_url?: string;\n}\n\ninterface DiscordEmbed {\n title?: string;\n description?: string;\n color?: number;\n fields?: Array<{\n name: string;\n value: string;\n inline?: boolean;\n }>;\n footer?: {\n text: string;\n };\n timestamp?: string;\n}\n\n/**\n * Get notification emoji based on type\n */\nfunction getTypeEmoji(type?: string): string {\n switch (type) {\n case 'standup':\n return '☀️';\n case 'pr':\n return '🔀';\n case 'weekly':\n return '📊';\n default:\n return '📝';\n }\n}\n\n/**\n * Get notification color based on type (for Discord embed)\n */\nfunction getTypeColor(type?: string): number {\n switch (type) {\n case 'standup':\n return 0x4ade80; // Green\n case 'pr':\n return 0x60a5fa; // Blue\n case 'weekly':\n return 0xa78bfa; // Purple\n default:\n return 0x94a3b8; // Gray\n }\n}\n\n/**\n * Format a message for Slack\n */\nfunction formatSlackMessage(message: NotificationMessage): SlackMessage {\n const emoji = getTypeEmoji(message.type);\n const blocks: SlackBlock[] = [];\n\n // Header\n if (message.title) {\n blocks.push({\n type: 'header',\n text: {\n type: 'plain_text',\n text: `${emoji} ${message.title}`,\n emoji: true,\n },\n });\n }\n\n // Main content — convert markdown to Slack mrkdwn format\n const slackText = formatOutput(message.text, 'slack').text;\n blocks.push({\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: slackText,\n },\n });\n\n // Ticket links\n if (message.ticketLinks && message.ticketLinks.length > 0) {\n const ticketText = message.ticketLinks\n .map((t) => `• <${t.url}|${t.id}>${t.title ? `: ${t.title}` : ''}`)\n .join('\\n');\n\n blocks.push({\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: `*Related Tickets:*\\n${ticketText}`,\n },\n });\n }\n\n // Divider\n blocks.push({ type: 'divider' });\n\n // Footer\n if (message.footer) {\n blocks.push({\n type: 'context',\n elements: [\n {\n type: 'mrkdwn',\n text: message.footer,\n },\n ],\n });\n } else {\n blocks.push({\n type: 'context',\n elements: [\n {\n type: 'mrkdwn',\n text: `Sent via DevDaily · ${new Date().toLocaleString()}`,\n },\n ],\n });\n }\n\n return { blocks };\n}\n\n/**\n * Format a message for Discord\n */\nfunction formatDiscordMessage(message: NotificationMessage): DiscordMessage {\n const emoji = getTypeEmoji(message.type);\n const color = getTypeColor(message.type);\n\n const embed: DiscordEmbed = {\n title: message.title ? `${emoji} ${message.title}` : undefined,\n description: message.text,\n color,\n timestamp: new Date().toISOString(),\n footer: {\n text: message.footer || 'Sent via DevDaily',\n },\n };\n\n // Add ticket links as fields\n if (message.ticketLinks && message.ticketLinks.length > 0) {\n embed.fields = message.ticketLinks.map((t) => ({\n name: t.id,\n value: t.title ? `[${t.title}](${t.url})` : `[View Ticket](${t.url})`,\n inline: true,\n }));\n }\n\n return {\n embeds: [embed],\n username: 'DevDaily',\n };\n}\n\n/**\n * Send a notification to Slack\n */\nexport async function sendToSlack(\n message: NotificationMessage,\n webhookUrl?: string\n): Promise<boolean> {\n const config = getConfig();\n const secrets = getSecrets();\n\n const url = webhookUrl || secrets.slack?.webhookUrl || config.notifications?.slack?.webhookUrl;\n\n if (!url) {\n throw new Error('Slack webhook URL not configured. Run: devdaily init --notifications');\n }\n\n const payload = formatSlackMessage(message);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n throw new Error(`Slack API error: ${response.status} ${response.statusText}`);\n }\n\n return true;\n } catch (error) {\n throw new Error(`Failed to send Slack message: ${(error as Error).message}`);\n }\n}\n\n/**\n * Send a notification to Discord\n */\nexport async function sendToDiscord(\n message: NotificationMessage,\n webhookUrl?: string\n): Promise<boolean> {\n const config = getConfig();\n const secrets = getSecrets();\n\n const url =\n webhookUrl || secrets.discord?.webhookUrl || config.notifications?.discord?.webhookUrl;\n\n if (!url) {\n throw new Error('Discord webhook URL not configured. Run: devdaily init --notifications');\n }\n\n const payload = formatDiscordMessage(message);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n throw new Error(`Discord API error: ${response.status} ${response.statusText}`);\n }\n\n return true;\n } catch (error) {\n throw new Error(`Failed to send Discord message: ${(error as Error).message}`);\n }\n}\n\n/**\n * Send notification to configured channels\n */\nexport async function sendNotification(\n message: NotificationMessage,\n options?: {\n slack?: boolean;\n discord?: boolean;\n }\n): Promise<{ slack?: boolean; discord?: boolean }> {\n const config = getConfig();\n const results: { slack?: boolean; discord?: boolean } = {};\n\n const sendSlack = options?.slack ?? config.notifications?.slack?.enabled;\n const sendDiscord = options?.discord ?? config.notifications?.discord?.enabled;\n\n if (sendSlack) {\n try {\n results.slack = await sendToSlack(message);\n } catch {\n results.slack = false;\n }\n }\n\n if (sendDiscord) {\n try {\n results.discord = await sendToDiscord(message);\n } catch {\n results.discord = false;\n }\n }\n\n return results;\n}\n\n/**\n * Format standup for notification\n */\nexport function formatStandupNotification(\n standupText: string,\n tickets?: { id: string; url: string; title?: string }[]\n): NotificationMessage {\n return {\n title: 'Daily Standup',\n text: standupText,\n type: 'standup',\n ticketLinks: tickets,\n };\n}\n\n/**\n * Format PR notification\n */\nexport function formatPRNotification(\n title: string,\n url: string,\n description: string\n): NotificationMessage {\n return {\n title: `New PR: ${title}`,\n text: `${description}\\n\\n🔗 <${url}|View Pull Request>`,\n type: 'pr',\n };\n}\n\n/**\n * Format weekly summary notification\n */\nexport function formatWeeklyNotification(\n summaryText: string,\n stats?: { commits: number; prs?: number }\n): NotificationMessage {\n const footer = stats\n ? `📊 ${stats.commits} commits${stats.prs ? ` · ${stats.prs} PRs` : ''} this week`\n : undefined;\n\n return {\n title: 'Weekly Summary',\n text: summaryText,\n type: 'weekly',\n footer,\n };\n}\n","import boxen from 'boxen';\nimport ora, { Ora } from 'ora';\nimport { colors, chalk } from './colors.js';\nimport { ASCII, drawBox, divider, progressBar, table } from './ascii.js';\nimport { getConfig } from '../config/index.js';\n\n// Terminal width helper\nconst getTerminalWidth = (): number => {\n return process.stdout.columns || 80;\n};\n\n/**\n * Render the DevDaily header/banner\n */\nexport const renderHeader = (subtitle?: string): string => {\n const config = getConfig();\n\n if (!config.ascii) {\n return colors.gradient('◆ devdaily') + (subtitle ? colors.muted(` ${subtitle}`) : '');\n }\n\n if (config.compactMode) {\n return colors.gradient(ASCII.logoMini) + (subtitle ? colors.muted(` · ${subtitle}`) : '');\n }\n\n const logo = colors.gradient(ASCII.logoSmall.trim(), ['cyan', 'blue']);\n const sub = subtitle ? `\\n${colors.muted(subtitle)}` : '';\n\n return `${logo}${sub}`;\n};\n\n/**\n * Render a section header\n */\nexport const renderSection = (title: string, icon?: string): string => {\n const iconStr = icon ? `${icon} ` : '';\n return `\\n${colors.primary.bold(`${iconStr}${title}`)}\\n${colors.muted(divider(40))}`;\n};\n\n/**\n * Render a success message\n */\nexport const renderSuccess = (message: string): string => {\n return colors.success(`${ASCII.status.success} ${message}`);\n};\n\n/**\n * Render an error message\n */\nexport const renderError = (message: string, detail?: string): string => {\n const main = colors.error(`${ASCII.status.error} ${message}`);\n const detailStr = detail ? `\\n ${colors.muted(detail)}` : '';\n return main + detailStr;\n};\n\n/**\n * Render a warning message\n */\nexport const renderWarning = (message: string): string => {\n return colors.warning(`${ASCII.status.warning} ${message}`);\n};\n\n/**\n * Render an info message\n */\nexport const renderInfo = (message: string): string => {\n return colors.muted(`${ASCII.status.info} ${message}`);\n};\n\n/**\n * Render a boxed content area\n */\nexport const renderBox = (\n content: string,\n title?: string,\n options: { style?: 'round' | 'single' | 'double' } = {}\n): string => {\n const width = Math.min(getTerminalWidth() - 4, 70);\n\n return boxen(content, {\n padding: 1,\n margin: { top: 1, bottom: 1, left: 0, right: 0 },\n borderStyle: options.style || 'round',\n borderColor: 'blue',\n title: title,\n titleAlignment: 'left',\n width,\n });\n};\n\n/**\n * Render a key-value pair\n */\nexport const renderKeyValue = (key: string, value: string, keyWidth: number = 15): string => {\n const paddedKey = key.padEnd(keyWidth);\n return `${colors.muted(paddedKey)} ${value}`;\n};\n\n/**\n * Render a list of items\n */\nexport const renderList = (\n items: string[],\n options: { bullet?: string; indent?: number } = {}\n): string => {\n const { bullet = ASCII.status.bullet, indent = 2 } = options;\n const indentStr = ' '.repeat(indent);\n return items.map((item) => `${indentStr}${colors.accent(bullet)} ${item}`).join('\\n');\n};\n\n/**\n * Render a numbered list\n */\nexport const renderNumberedList = (items: string[], options: { indent?: number } = {}): string => {\n const { indent = 2 } = options;\n const indentStr = ' '.repeat(indent);\n return items.map((item, i) => `${indentStr}${colors.accent(`${i + 1}.`)} ${item}`).join('\\n');\n};\n\n/**\n * Render stats/metrics\n */\nexport const renderStats = (\n stats: Array<{ label: string; value: string | number; color?: string }>\n): string => {\n return stats\n .map(({ label, value, color }) => {\n const colorFn = color\n ? (chalk as unknown as Record<string, (s: string) => string>)[color] || colors.primary\n : colors.primary;\n return `${colorFn(String(value))} ${colors.muted(label)}`;\n })\n .join(colors.muted(' · '));\n};\n\n/**\n * Render a progress indicator\n */\nexport const renderProgress = (progress: number, label?: string): string => {\n const bar = progressBar(progress, 30);\n const labelStr = label ? `${colors.muted(label)} ` : '';\n return `${labelStr}${colors.primary(bar)}`;\n};\n\n/**\n * Render a table\n */\nexport const renderTable = (headers: string[], rows: string[][]): string => {\n return table(headers, rows, {\n columnWidth: 20,\n headerStyle: (s) => colors.bold(s),\n });\n};\n\n/**\n * Render command help\n */\nexport const renderCommandHelp = (\n command: string,\n description: string,\n options: Array<{ flag: string; description: string; default?: string }>,\n examples: string[]\n): string => {\n const sections: string[] = [];\n\n // Command header\n sections.push(colors.bold(colors.primary(`${command}`)) + colors.muted(` - ${description}`));\n sections.push('');\n\n // Options\n if (options.length > 0) {\n sections.push(colors.bold('OPTIONS'));\n sections.push('');\n options.forEach(({ flag, description, default: defaultVal }) => {\n const defaultStr = defaultVal ? colors.muted(` (default: ${defaultVal})`) : '';\n sections.push(` ${colors.accent(flag.padEnd(20))} ${description}${defaultStr}`);\n });\n sections.push('');\n }\n\n // Examples\n if (examples.length > 0) {\n sections.push(colors.bold('EXAMPLES'));\n sections.push('');\n examples.forEach((ex) => {\n sections.push(` ${colors.muted('$')} ${colors.primary(ex)}`);\n });\n }\n\n return sections.join('\\n');\n};\n\n/**\n * Render keyboard shortcuts\n */\nexport const renderShortcuts = (shortcuts: Array<{ key: string; action: string }>): string => {\n const maxKeyLen = Math.max(...shortcuts.map((s) => s.key.length));\n\n return shortcuts\n .map(({ key, action }) => {\n const keyStr = colors.accent.bold(`[${key}]`.padEnd(maxKeyLen + 3));\n return ` ${keyStr} ${colors.muted(action)}`;\n })\n .join('\\n');\n};\n\n/**\n * Create a spinner with custom styling\n */\nexport const createSpinner = (text: string): Ora => {\n return ora({\n text,\n spinner: 'dots',\n color: 'cyan',\n });\n};\n\n/**\n * Render a divider line\n */\nexport const renderDivider = (width?: number): string => {\n return colors.muted(divider(width || Math.min(getTerminalWidth() - 10, 60)));\n};\n\n/**\n * Clear screen and move cursor to top\n */\nexport const clearScreen = (): void => {\n process.stdout.write('\\x1B[2J\\x1B[0f');\n};\n\n/**\n * Move cursor up N lines\n */\nexport const cursorUp = (n: number): void => {\n process.stdout.write(`\\x1B[${n}A`);\n};\n\n/**\n * Hide cursor\n */\nexport const hideCursor = (): void => {\n process.stdout.write('\\x1B[?25l');\n};\n\n/**\n * Show cursor\n */\nexport const showCursor = (): void => {\n process.stdout.write('\\x1B[?25h');\n};\n\n// Export everything\nexport const UI = {\n // Rendering\n header: renderHeader,\n section: renderSection,\n box: renderBox,\n success: renderSuccess,\n error: renderError,\n warning: renderWarning,\n info: renderInfo,\n keyValue: renderKeyValue,\n list: renderList,\n numberedList: renderNumberedList,\n stats: renderStats,\n progress: renderProgress,\n table: renderTable,\n commandHelp: renderCommandHelp,\n shortcuts: renderShortcuts,\n divider: renderDivider,\n\n // Utilities\n spinner: createSpinner,\n clear: clearScreen,\n cursorUp,\n hideCursor,\n showCursor,\n\n // Re-exports\n colors,\n chalk,\n ASCII,\n drawBox,\n};\n\nexport default UI;\n","import chalk, { ChalkInstance } from 'chalk';\nimport { getConfig } from '../config/index.js';\nimport { Theme } from '../config/schema.js';\n\n// Dynamic theme colors based on config\nconst getThemeColor = (colorName: string): ChalkInstance => {\n const colorMap: Record<string, ChalkInstance> = {\n blue: chalk.blue,\n green: chalk.green,\n yellow: chalk.yellow,\n red: chalk.red,\n cyan: chalk.cyan,\n magenta: chalk.magenta,\n white: chalk.white,\n gray: chalk.gray,\n // Bright variants\n brightBlue: chalk.blueBright,\n brightGreen: chalk.greenBright,\n brightYellow: chalk.yellowBright,\n brightRed: chalk.redBright,\n brightCyan: chalk.cyanBright,\n brightMagenta: chalk.magentaBright,\n };\n return colorMap[colorName] || chalk.white;\n};\n\nexport class Colors {\n private theme: Theme;\n\n constructor() {\n this.theme = getConfig().theme;\n }\n\n get primary(): ChalkInstance {\n return getThemeColor(this.theme.primary);\n }\n\n get success(): ChalkInstance {\n return getThemeColor(this.theme.success);\n }\n\n get warning(): ChalkInstance {\n return getThemeColor(this.theme.warning);\n }\n\n get error(): ChalkInstance {\n return getThemeColor(this.theme.error);\n }\n\n get accent(): ChalkInstance {\n return getThemeColor(this.theme.accent);\n }\n\n get muted(): ChalkInstance {\n return getThemeColor(this.theme.muted);\n }\n\n get bold(): ChalkInstance {\n return chalk.bold;\n }\n\n get dim(): ChalkInstance {\n return chalk.dim;\n }\n\n get italic(): ChalkInstance {\n return chalk.italic;\n }\n\n get underline(): ChalkInstance {\n return chalk.underline;\n }\n\n get inverse(): ChalkInstance {\n return chalk.inverse;\n }\n\n // Gradient text (for headers)\n gradient(text: string, colors: string[] = ['cyan', 'blue', 'magenta']): string {\n const chars = text.split('');\n const colorFns = colors.map((c) => getThemeColor(c));\n return chars\n .map((char, i) => {\n const colorIndex = Math.floor((i / chars.length) * colorFns.length);\n return colorFns[colorIndex](char);\n })\n .join('');\n }\n\n // Rainbow text\n rainbow(text: string): string {\n const colors = ['red', 'yellow', 'green', 'cyan', 'blue', 'magenta'];\n return text\n .split('')\n .map((char, i) => getThemeColor(colors[i % colors.length])(char))\n .join('');\n }\n}\n\n// Export singleton\nexport const colors = new Colors();\n\n// Static chalk exports for simple usage\nexport { chalk };\n","// ASCII Art and Symbols for DevDaily\n// Clean, modern aesthetic\n\nexport const ASCII = {\n // Main logo - compact and modern\n logo: `\n ██████╗ ███████╗██╗ ██╗██████╗ █████╗ ██╗██╗ ██╗ ██╗\n ██╔══██╗██╔════╝██║ ██║██╔══██╗██╔══██╗██║██║ ╚██╗ ██╔╝\n ██║ ██║█████╗ ██║ ██║██║ ██║███████║██║██║ ╚████╔╝ \n ██║ ██║██╔══╝ ╚██╗ ██╔╝██║ ██║██╔══██║██║██║ ╚██╔╝ \n ██████╔╝███████╗ ╚████╔╝ ██████╔╝██║ ██║██║███████╗██║ \n ╚═════╝ ╚══════╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝ \n`,\n\n // Smaller logo for compact displays\n logoSmall: `\n ╔═══════════════════════════════╗\n ║ D E V D A I L Y . A I ║\n ╚═══════════════════════════════╝\n`,\n\n // Minimal logo\n logoMini: `◆ devdaily`,\n\n // Command icons\n icons: {\n standup: '◈',\n pr: '◉',\n week: '◎',\n dash: '◐',\n config: '◇',\n init: '◆',\n help: '?',\n },\n\n // Status symbols\n status: {\n success: '✓',\n error: '✗',\n warning: '!',\n info: 'i',\n pending: '○',\n active: '●',\n arrow: '→',\n arrowRight: '▶',\n arrowDown: '▼',\n bullet: '•',\n dot: '·',\n star: '★',\n check: '✔',\n cross: '✖',\n },\n\n // Box drawing characters\n box: {\n topLeft: '╭',\n topRight: '╮',\n bottomLeft: '╰',\n bottomRight: '╯',\n horizontal: '─',\n vertical: '│',\n cross: '┼',\n teeRight: '├',\n teeLeft: '┤',\n teeDown: '┬',\n teeUp: '┴',\n },\n\n // Progress indicators\n progress: {\n filled: '█',\n empty: '░',\n half: '▒',\n },\n\n // Spinners frames\n spinners: {\n dots: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],\n line: ['|', '/', '-', '\\\\'],\n arc: ['◜', '◠', '◝', '◞', '◡', '◟'],\n circle: ['◐', '◓', '◑', '◒'],\n square: ['◰', '◳', '◲', '◱'],\n },\n\n // Decorative elements\n decorations: {\n wave: '~~~~~',\n sparkle: '✦',\n diamond: '◇',\n heart: '♥',\n thunder: '⚡',\n },\n};\n\n// Box drawing helper\nexport const drawBox = (\n content: string,\n options: {\n title?: string;\n width?: number;\n padding?: number;\n style?: 'single' | 'double' | 'round';\n } = {}\n): string => {\n const { title, width = 60, padding = 1, style = 'round' } = options;\n\n const chars =\n style === 'round'\n ? { tl: '╭', tr: '╮', bl: '╰', br: '╯', h: '─', v: '│' }\n : style === 'double'\n ? { tl: '╔', tr: '╗', bl: '╚', br: '╝', h: '═', v: '║' }\n : { tl: '┌', tr: '┐', bl: '└', br: '┘', h: '─', v: '│' };\n\n const lines = content.split('\\n');\n const maxLineLength = Math.max(...lines.map((l) => stripAnsi(l).length));\n const innerWidth = Math.max(width - 2, maxLineLength + padding * 2);\n\n const padLine = (line: string): string => {\n const visibleLength = stripAnsi(line).length;\n const leftPad = ' '.repeat(padding);\n const rightPad = ' '.repeat(innerWidth - visibleLength - padding);\n return `${chars.v}${leftPad}${line}${rightPad}${chars.v}`;\n };\n\n const topBorder = title\n ? `${chars.tl}${chars.h} ${title} ${chars.h.repeat(innerWidth - title.length - 3)}${chars.tr}`\n : `${chars.tl}${chars.h.repeat(innerWidth)}${chars.tr}`;\n\n const bottomBorder = `${chars.bl}${chars.h.repeat(innerWidth)}${chars.br}`;\n\n const paddedContent = [\n ...Array(padding).fill(`${chars.v}${' '.repeat(innerWidth)}${chars.v}`),\n ...lines.map(padLine),\n ...Array(padding).fill(`${chars.v}${' '.repeat(innerWidth)}${chars.v}`),\n ];\n\n return [topBorder, ...paddedContent, bottomBorder].join('\\n');\n};\n\n// Strip ANSI codes for length calculation\nconst stripAnsi = (str: string): string => {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1B\\[[0-9;]*[a-zA-Z]/g, '');\n};\n\n// Create a horizontal divider\nexport const divider = (width: number = 50, char: string = '─'): string => {\n return char.repeat(width);\n};\n\n// Create a progress bar\nexport const progressBar = (\n progress: number,\n width: number = 30,\n options: { filled?: string; empty?: string; showPercent?: boolean } = {}\n): string => {\n const {\n filled = ASCII.progress.filled,\n empty = ASCII.progress.empty,\n showPercent = true,\n } = options;\n\n const clampedProgress = Math.max(0, Math.min(1, progress));\n const filledCount = Math.round(clampedProgress * width);\n const emptyCount = width - filledCount;\n\n const bar = filled.repeat(filledCount) + empty.repeat(emptyCount);\n const percent = showPercent ? ` ${Math.round(clampedProgress * 100)}%` : '';\n\n return `[${bar}]${percent}`;\n};\n\n// Create a table\nexport const table = (\n headers: string[],\n rows: string[][],\n options: { columnWidth?: number; headerStyle?: (s: string) => string } = {}\n): string => {\n const { columnWidth = 15, headerStyle = (s: string) => s } = options;\n\n const formatCell = (cell: string, width: number): string => {\n const visibleLength = stripAnsi(cell).length;\n if (visibleLength >= width) {\n return cell.slice(0, width - 1) + '…';\n }\n return cell + ' '.repeat(width - visibleLength);\n };\n\n const headerRow = headers.map((h) => headerStyle(formatCell(h, columnWidth))).join(' │ ');\n\n const separator = headers.map(() => '─'.repeat(columnWidth)).join('─┼─');\n\n const dataRows = rows\n .map((row) => row.map((cell) => formatCell(cell, columnWidth)).join(' │ '))\n .join('\\n');\n\n return `${headerRow}\\n${separator}\\n${dataRows}`;\n};\n","import clipboard from 'clipboardy';\n\nexport async function copyToClipboard(text: string): Promise<void> {\n try {\n await clipboard.write(text);\n } catch {\n // Silently fail - let caller handle messaging\n throw new Error('Failed to copy to clipboard');\n }\n}\n\nexport function formatDate(date: Date): string {\n return date.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n });\n}\n\nexport function formatDateRange(start: Date, end: Date): string {\n return `${formatDate(start)} - ${formatDate(end)}`;\n}\n\nexport function getWeekStart(weeksAgo: number = 0): Date {\n const now = new Date();\n const dayOfWeek = now.getDay();\n const monday = new Date(now);\n monday.setDate(now.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1));\n monday.setDate(monday.getDate() - weeksAgo * 7);\n monday.setHours(0, 0, 0, 0);\n return monday;\n}\n\nexport function getWeekEnd(weeksAgo: number = 0): Date {\n const start = getWeekStart(weeksAgo);\n const end = new Date(start);\n end.setDate(start.getDate() + 6);\n end.setHours(23, 59, 59, 999);\n return end;\n}\n\nexport function getDaysAgo(days: number): Date {\n const date = new Date();\n date.setDate(date.getDate() - days);\n date.setHours(0, 0, 0, 0);\n return date;\n}\n","/**\n * Work Journal - Persistent local activity snapshots\n *\n * Stores daily work snapshots locally so you can recall what you were doing\n * on any date, across any project. This is the \"memory\" layer that powers\n * context recovery, smart recall, and cross-project weekly summaries.\n *\n * Storage layout:\n * ~/.config/devdaily/journal/\n * ├── index.json # project registry + metadata\n * ├── 2024-01-15/\n * │ ├── my-project.json # snapshot for that project on that day\n * │ └── other-project.json\n * └── 2024-01-16/\n * └── my-project.json\n */\n\nimport {\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n readdirSync,\n statSync,\n unlinkSync,\n rmdirSync,\n} from 'fs';\nimport { homedir } from 'os';\nimport { join, basename } from 'path';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface JournalCommit {\n hash: string;\n shortHash: string;\n message: string;\n author: string;\n date: string; // ISO string for serialization\n filesChanged?: string[];\n}\n\nexport interface JournalBranchSnapshot {\n name: string;\n lastCommitHash: string;\n lastCommitMessage: string;\n lastCommitDate: string;\n hasUncommittedChanges: boolean;\n aheadOfBase: number;\n /** Files with uncommitted modifications at snapshot time */\n uncommittedFiles: string[];\n}\n\nexport interface JournalPRSnapshot {\n number: number;\n title: string;\n state: string; // open, merged, closed\n url: string;\n baseBranch: string;\n headBranch: string;\n labels: string[];\n}\n\nexport interface JournalTicketSnapshot {\n id: string;\n title: string;\n status: string;\n type: string;\n priority?: string;\n url?: string;\n}\n\nexport interface WorkSnapshot {\n /** ISO date string (YYYY-MM-DD) */\n date: string;\n\n /** ISO timestamp of when this snapshot was taken */\n takenAt: string;\n\n /** Project identifier (sanitized repo name or directory name) */\n projectId: string;\n\n /** Absolute path to the repo root */\n repoPath: string;\n\n /** Remote URL if available */\n remoteUrl?: string;\n\n /** Current branch at snapshot time */\n currentBranch: string;\n\n /** All active (non-merged) local branches with status */\n activeBranches: JournalBranchSnapshot[];\n\n /** Commits made today (on the snapshot date) */\n todayCommits: JournalCommit[];\n\n /** Commits made in the last 7 days (for context) */\n recentCommits: JournalCommit[];\n\n /** Open/recently merged PRs */\n pullRequests: JournalPRSnapshot[];\n\n /** Active/recently touched tickets */\n tickets: JournalTicketSnapshot[];\n\n /** Work categories breakdown */\n categories: { name: string; percentage: number }[];\n\n /** Top changed files (today) */\n topChangedFiles: { path: string; frequency: number }[];\n\n /** Diff stats for today's work */\n diffStats: { filesChanged: number; insertions: number; deletions: number } | null;\n\n /** Free-form notes the user can attach */\n notes?: string;\n\n /** AI-generated \"what I was working on\" summary (if available) */\n aiSummary?: string;\n\n /** Tags for search (auto-extracted + user-supplied) */\n tags: string[];\n}\n\nexport interface ProjectRegistryEntry {\n projectId: string;\n repoPath: string;\n remoteUrl?: string;\n lastSnapshotDate: string;\n snapshotCount: number;\n /** First snapshot date */\n firstSeen: string;\n}\n\nexport interface JournalIndex {\n version: number;\n projects: ProjectRegistryEntry[];\n lastUpdated: string;\n}\n\nexport interface JournalSearchResult {\n snapshot: WorkSnapshot;\n /** Why this result matched (which fields) */\n matchReasons: string[];\n /** Relevance score (higher = more relevant) */\n score: number;\n}\n\nexport interface JournalQueryOptions {\n /** Filter by project ID */\n projectId?: string;\n /** Start date (inclusive, YYYY-MM-DD) */\n from?: string;\n /** End date (inclusive, YYYY-MM-DD) */\n to?: string;\n /** Text search query (searches commits, branches, tags, notes) */\n query?: string;\n /** Filter by tags */\n tags?: string[];\n /** Max results to return */\n limit?: number;\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst JOURNAL_DIR = join(homedir(), '.config', 'devdaily', 'journal');\nconst INDEX_PATH = join(JOURNAL_DIR, 'index.json');\nconst JOURNAL_VERSION = 1;\n\n// ─── Work Journal ─────────────────────────────────────────────────────────────\n\nexport class WorkJournal {\n private journalDir: string;\n private indexPath: string;\n\n constructor(journalDir?: string) {\n this.journalDir = journalDir || JOURNAL_DIR;\n this.indexPath = journalDir ? join(journalDir, 'index.json') : INDEX_PATH;\n this.ensureDirectoryExists();\n }\n\n // ─── Write Operations ───────────────────────────────────────────────────\n\n /**\n * Save a work snapshot for a given date and project.\n * If a snapshot already exists for that date+project, it is merged/updated\n * (newer commits appended, metadata refreshed).\n */\n saveSnapshot(snapshot: WorkSnapshot): void {\n const dateDir = join(this.journalDir, snapshot.date);\n if (!existsSync(dateDir)) {\n mkdirSync(dateDir, { recursive: true });\n }\n\n const filePath = join(dateDir, `${snapshot.projectId}.json`);\n\n // If a snapshot already exists, merge it\n let finalSnapshot = snapshot;\n if (existsSync(filePath)) {\n try {\n const existing = JSON.parse(readFileSync(filePath, 'utf-8')) as WorkSnapshot;\n finalSnapshot = this.mergeSnapshots(existing, snapshot);\n } catch {\n // Corrupted file — overwrite\n }\n }\n\n writeFileSync(filePath, JSON.stringify(finalSnapshot, null, 2), 'utf-8');\n\n // Update the index\n this.updateIndex(finalSnapshot);\n }\n\n /**\n * Add a user note to today's snapshot for a project.\n */\n addNote(projectId: string, note: string, date?: string): void {\n const targetDate = date || this.todayString();\n const snapshot = this.getSnapshot(targetDate, projectId);\n if (!snapshot) {\n // Create a minimal snapshot just for the note\n const minimal: WorkSnapshot = {\n date: targetDate,\n takenAt: new Date().toISOString(),\n projectId,\n repoPath: process.cwd(),\n currentBranch: '',\n activeBranches: [],\n todayCommits: [],\n recentCommits: [],\n pullRequests: [],\n tickets: [],\n categories: [],\n topChangedFiles: [],\n diffStats: null,\n notes: note,\n tags: [],\n };\n this.saveSnapshot(minimal);\n return;\n }\n\n snapshot.notes = snapshot.notes ? `${snapshot.notes}\\n\\n${note}` : note;\n snapshot.takenAt = new Date().toISOString();\n const filePath = join(this.journalDir, targetDate, `${projectId}.json`);\n writeFileSync(filePath, JSON.stringify(snapshot, null, 2), 'utf-8');\n }\n\n /**\n * Add an AI-generated summary to a snapshot.\n */\n setAISummary(projectId: string, summary: string, date?: string): void {\n const targetDate = date || this.todayString();\n const snapshot = this.getSnapshot(targetDate, projectId);\n if (!snapshot) return;\n\n snapshot.aiSummary = summary;\n snapshot.takenAt = new Date().toISOString();\n const filePath = join(this.journalDir, targetDate, `${projectId}.json`);\n writeFileSync(filePath, JSON.stringify(snapshot, null, 2), 'utf-8');\n }\n\n /**\n * Add tags to a snapshot.\n */\n addTags(projectId: string, tags: string[], date?: string): void {\n const targetDate = date || this.todayString();\n const snapshot = this.getSnapshot(targetDate, projectId);\n if (!snapshot) return;\n\n const allTags = new Set([...snapshot.tags, ...tags]);\n snapshot.tags = Array.from(allTags);\n snapshot.takenAt = new Date().toISOString();\n const filePath = join(this.journalDir, targetDate, `${projectId}.json`);\n writeFileSync(filePath, JSON.stringify(snapshot, null, 2), 'utf-8');\n }\n\n // ─── Read Operations ────────────────────────────────────────────────────\n\n /**\n * Get a specific snapshot by date and project.\n */\n getSnapshot(date: string, projectId: string): WorkSnapshot | null {\n const filePath = join(this.journalDir, date, `${projectId}.json`);\n if (!existsSync(filePath)) return null;\n\n try {\n return JSON.parse(readFileSync(filePath, 'utf-8')) as WorkSnapshot;\n } catch {\n return null;\n }\n }\n\n /**\n * Get all snapshots for a specific date (across all projects).\n */\n getSnapshotsForDate(date: string): WorkSnapshot[] {\n const dateDir = join(this.journalDir, date);\n if (!existsSync(dateDir)) return [];\n\n const snapshots: WorkSnapshot[] = [];\n try {\n const files = readdirSync(dateDir).filter((f) => f.endsWith('.json'));\n for (const file of files) {\n try {\n const content = readFileSync(join(dateDir, file), 'utf-8');\n snapshots.push(JSON.parse(content) as WorkSnapshot);\n } catch {\n // Skip corrupted files\n }\n }\n } catch {\n return [];\n }\n\n return snapshots;\n }\n\n /**\n * Get all snapshots for a project within a date range.\n */\n getSnapshotsForRange(projectId: string | null, from: string, to: string): WorkSnapshot[] {\n const snapshots: WorkSnapshot[] = [];\n const dates = this.getDateDirsInRange(from, to);\n\n for (const date of dates) {\n if (projectId) {\n const snapshot = this.getSnapshot(date, projectId);\n if (snapshot) snapshots.push(snapshot);\n } else {\n snapshots.push(...this.getSnapshotsForDate(date));\n }\n }\n\n return snapshots.sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());\n }\n\n /**\n * Get the most recent snapshot for a project (regardless of date).\n */\n getLatestSnapshot(projectId: string): WorkSnapshot | null {\n const index = this.getIndex();\n const project = index.projects.find((p) => p.projectId === projectId);\n if (!project) return null;\n\n return this.getSnapshot(project.lastSnapshotDate, projectId);\n }\n\n /**\n * Get all snapshots across all projects for the last N days.\n */\n getRecentActivity(days: number = 7): WorkSnapshot[] {\n const to = this.todayString();\n const fromDate = new Date();\n fromDate.setDate(fromDate.getDate() - days);\n const from = this.dateToString(fromDate);\n\n return this.getSnapshotsForRange(null, from, to);\n }\n\n /**\n * Get all known projects from the index.\n */\n getProjects(): ProjectRegistryEntry[] {\n return this.getIndex().projects;\n }\n\n /**\n * Check if a snapshot exists for today for a given project.\n */\n hasTodaySnapshot(projectId: string): boolean {\n return this.getSnapshot(this.todayString(), projectId) !== null;\n }\n\n // ─── Search ─────────────────────────────────────────────────────────────\n\n /**\n * Search snapshots using a text query.\n * Searches across: commit messages, branch names, file paths, tags, notes, AI summaries.\n */\n search(options: JournalQueryOptions): JournalSearchResult[] {\n const { projectId, from, to, query, tags, limit = 20 } = options;\n\n const startDate = from || this.getEarliestDate();\n const endDate = to || this.todayString();\n\n if (!startDate) return [];\n\n const allSnapshots = this.getSnapshotsForRange(projectId || null, startDate, endDate);\n let results: JournalSearchResult[] = [];\n\n for (const snapshot of allSnapshots) {\n const matchResult = this.matchSnapshot(snapshot, query, tags);\n if (matchResult.score > 0) {\n results.push({\n snapshot,\n matchReasons: matchResult.reasons,\n score: matchResult.score,\n });\n }\n }\n\n // Sort by score descending, then by date descending\n results.sort((a, b) => {\n if (b.score !== a.score) return b.score - a.score;\n return new Date(b.snapshot.date).getTime() - new Date(a.snapshot.date).getTime();\n });\n\n if (limit > 0) {\n results = results.slice(0, limit);\n }\n\n return results;\n }\n\n /**\n * Find when a specific file was last worked on.\n */\n findFileHistory(\n filePath: string,\n projectId?: string,\n maxDays: number = 90\n ): { date: string; commits: JournalCommit[] }[] {\n const to = this.todayString();\n const fromDate = new Date();\n fromDate.setDate(fromDate.getDate() - maxDays);\n const from = this.dateToString(fromDate);\n\n const allSnapshots = this.getSnapshotsForRange(projectId || null, from, to);\n const results: { date: string; commits: JournalCommit[] }[] = [];\n\n const normalizedPath = filePath.toLowerCase();\n\n for (const snapshot of allSnapshots) {\n const matchingCommits = snapshot.todayCommits.filter((c) =>\n c.filesChanged?.some((f) => f.toLowerCase().includes(normalizedPath))\n );\n\n if (matchingCommits.length > 0) {\n results.push({ date: snapshot.date, commits: matchingCommits });\n }\n }\n\n return results;\n }\n\n /**\n * Get a cross-project summary for a date range.\n * Groups activity by project and provides aggregate stats.\n */\n getCrossProjectSummary(\n from: string,\n to: string\n ): {\n projects: {\n projectId: string;\n repoPath: string;\n totalCommits: number;\n activeDays: number;\n branches: string[];\n topFiles: string[];\n categories: { name: string; percentage: number }[];\n diffStats: { filesChanged: number; insertions: number; deletions: number };\n }[];\n totalCommits: number;\n totalActiveDays: number;\n dateRange: { from: string; to: string };\n } {\n const allSnapshots = this.getSnapshotsForRange(null, from, to);\n\n // Group by project\n const projectMap = new Map<\n string,\n {\n repoPath: string;\n snapshots: WorkSnapshot[];\n }\n >();\n\n for (const snapshot of allSnapshots) {\n const existing = projectMap.get(snapshot.projectId);\n if (existing) {\n existing.snapshots.push(snapshot);\n } else {\n projectMap.set(snapshot.projectId, {\n repoPath: snapshot.repoPath,\n snapshots: [snapshot],\n });\n }\n }\n\n const projects = Array.from(projectMap.entries()).map(([projectId, data]) => {\n const allCommits = data.snapshots.flatMap((s) => s.todayCommits);\n const allBranches = new Set(data.snapshots.map((s) => s.currentBranch));\n const allFiles = data.snapshots.flatMap((s) => s.topChangedFiles.map((f) => f.path));\n const fileFreq = new Map<string, number>();\n for (const f of allFiles) {\n fileFreq.set(f, (fileFreq.get(f) || 0) + 1);\n }\n const topFiles = Array.from(fileFreq.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([path]) => path);\n\n // Aggregate categories\n const catMap = new Map<string, number[]>();\n for (const snapshot of data.snapshots) {\n for (const cat of snapshot.categories) {\n const existing = catMap.get(cat.name);\n if (existing) {\n existing.push(cat.percentage);\n } else {\n catMap.set(cat.name, [cat.percentage]);\n }\n }\n }\n const categories = Array.from(catMap.entries())\n .map(([name, percentages]) => ({\n name,\n percentage: Math.round(percentages.reduce((a, b) => a + b, 0) / percentages.length),\n }))\n .sort((a, b) => b.percentage - a.percentage);\n\n // Aggregate diff stats\n const diffStats = {\n filesChanged: 0,\n insertions: 0,\n deletions: 0,\n };\n for (const snapshot of data.snapshots) {\n if (snapshot.diffStats) {\n diffStats.filesChanged += snapshot.diffStats.filesChanged;\n diffStats.insertions += snapshot.diffStats.insertions;\n diffStats.deletions += snapshot.diffStats.deletions;\n }\n }\n\n return {\n projectId,\n repoPath: data.repoPath,\n totalCommits: allCommits.length,\n activeDays: data.snapshots.length,\n branches: Array.from(allBranches),\n topFiles,\n categories,\n diffStats,\n };\n });\n\n const activeDates = new Set(allSnapshots.map((s) => s.date));\n\n return {\n projects: projects.sort((a, b) => b.totalCommits - a.totalCommits),\n totalCommits: projects.reduce((sum, p) => sum + p.totalCommits, 0),\n totalActiveDays: activeDates.size,\n dateRange: { from, to },\n };\n }\n\n // ─── Formatting for AI ──────────────────────────────────────────────────\n\n /**\n * Format snapshots into a context block suitable for AI prompts.\n */\n static formatSnapshotsForAI(snapshots: WorkSnapshot[]): string {\n if (snapshots.length === 0) return '[No journal entries found]';\n\n const sections: string[] = [];\n\n // Group by project\n const byProject = new Map<string, WorkSnapshot[]>();\n for (const s of snapshots) {\n const existing = byProject.get(s.projectId);\n if (existing) {\n existing.push(s);\n } else {\n byProject.set(s.projectId, [s]);\n }\n }\n\n for (const [projectId, projectSnapshots] of byProject) {\n const lines: string[] = [];\n lines.push(`## Project: ${projectId}`);\n lines.push(`Path: ${projectSnapshots[0].repoPath}`);\n lines.push('');\n\n for (const snapshot of projectSnapshots) {\n lines.push(`### ${snapshot.date}`);\n lines.push(`Branch: ${snapshot.currentBranch}`);\n\n if (snapshot.todayCommits.length > 0) {\n lines.push(`Commits (${snapshot.todayCommits.length}):`);\n for (const c of snapshot.todayCommits.slice(0, 15)) {\n const files = c.filesChanged\n ? ` [${c.filesChanged.slice(0, 3).join(', ')}${c.filesChanged.length > 3 ? '...' : ''}]`\n : '';\n lines.push(` - ${c.shortHash} ${c.message}${files}`);\n }\n if (snapshot.todayCommits.length > 15) {\n lines.push(` ... and ${snapshot.todayCommits.length - 15} more commits`);\n }\n }\n\n if (snapshot.pullRequests.length > 0) {\n lines.push(`PRs:`);\n for (const pr of snapshot.pullRequests) {\n lines.push(` - #${pr.number} ${pr.title} (${pr.state})`);\n }\n }\n\n if (snapshot.tickets.length > 0) {\n lines.push(`Tickets:`);\n for (const t of snapshot.tickets) {\n lines.push(` - ${t.id}: ${t.title} [${t.status}]`);\n }\n }\n\n if (snapshot.categories.length > 0) {\n const cats = snapshot.categories\n .slice(0, 3)\n .map((c) => `${c.name}(${c.percentage}%)`)\n .join(', ');\n lines.push(`Work areas: ${cats}`);\n }\n\n if (snapshot.diffStats) {\n lines.push(\n `Changes: ${snapshot.diffStats.filesChanged} files, +${snapshot.diffStats.insertions}/-${snapshot.diffStats.deletions}`\n );\n }\n\n if (snapshot.notes) {\n lines.push(`Notes: ${snapshot.notes}`);\n }\n\n if (snapshot.aiSummary) {\n lines.push(`Summary: ${snapshot.aiSummary}`);\n }\n\n lines.push('');\n }\n\n sections.push(lines.join('\\n'));\n }\n\n return sections.join('\\n---\\n');\n }\n\n /**\n * Format a single snapshot into a human-readable summary.\n */\n static formatSnapshotSummary(snapshot: WorkSnapshot): string {\n const lines: string[] = [];\n\n lines.push(`📅 ${snapshot.date} — ${snapshot.projectId}`);\n lines.push(`🌿 Branch: ${snapshot.currentBranch}`);\n\n if (snapshot.todayCommits.length > 0) {\n lines.push(`📝 ${snapshot.todayCommits.length} commit(s)`);\n for (const c of snapshot.todayCommits.slice(0, 5)) {\n lines.push(` ${c.shortHash} ${c.message}`);\n }\n if (snapshot.todayCommits.length > 5) {\n lines.push(` ... and ${snapshot.todayCommits.length - 5} more`);\n }\n }\n\n if (snapshot.activeBranches.length > 1) {\n const otherBranches = snapshot.activeBranches\n .filter((b) => b.name !== snapshot.currentBranch)\n .slice(0, 5);\n if (otherBranches.length > 0) {\n lines.push(`🔀 Other active branches: ${otherBranches.map((b) => b.name).join(', ')}`);\n }\n }\n\n if (snapshot.pullRequests.length > 0) {\n lines.push(\n `🔄 PRs: ${snapshot.pullRequests.map((pr) => `#${pr.number} (${pr.state})`).join(', ')}`\n );\n }\n\n if (snapshot.diffStats) {\n lines.push(\n `📊 +${snapshot.diffStats.insertions}/-${snapshot.diffStats.deletions} across ${snapshot.diffStats.filesChanged} files`\n );\n }\n\n if (snapshot.notes) {\n lines.push(`📌 Notes: ${snapshot.notes}`);\n }\n\n if (snapshot.aiSummary) {\n lines.push(`🤖 ${snapshot.aiSummary}`);\n }\n\n return lines.join('\\n');\n }\n\n // ─── Maintenance ────────────────────────────────────────────────────────\n\n /**\n * Prune journal entries older than a given number of days.\n */\n prune(maxAgeDays: number = 365): { removedDates: string[]; removedSnapshots: number } {\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - maxAgeDays);\n const cutoffStr = this.dateToString(cutoffDate);\n\n const removedDates: string[] = [];\n let removedSnapshots = 0;\n\n try {\n const entries = readdirSync(this.journalDir);\n for (const entry of entries) {\n // Only process date directories (YYYY-MM-DD format)\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(entry)) continue;\n if (entry < cutoffStr) {\n const dateDir = join(this.journalDir, entry);\n const stat = statSync(dateDir);\n if (stat.isDirectory()) {\n const files = readdirSync(dateDir).filter((f) => f.endsWith('.json'));\n removedSnapshots += files.length;\n // Remove files then directory\n for (const file of files) {\n const filePath = join(dateDir, file);\n try {\n unlinkSync(filePath);\n } catch {\n // Skip if can't delete\n }\n }\n try {\n rmdirSync(dateDir);\n } catch {\n // Skip if can't delete (not empty)\n }\n removedDates.push(entry);\n }\n }\n }\n } catch {\n // Journal directory doesn't exist yet\n }\n\n // Rebuild index after pruning\n if (removedDates.length > 0) {\n this.rebuildIndex();\n }\n\n return { removedDates, removedSnapshots };\n }\n\n /**\n * Get journal storage stats.\n */\n getStats(): {\n totalSnapshots: number;\n totalDates: number;\n totalProjects: number;\n oldestEntry: string | null;\n newestEntry: string | null;\n storageBytes: number;\n } {\n const index = this.getIndex();\n let totalSnapshots = 0;\n let storageBytes = 0;\n\n const dates = this.getAllDateDirs();\n\n for (const date of dates) {\n const dateDir = join(this.journalDir, date);\n try {\n const files = readdirSync(dateDir).filter((f) => f.endsWith('.json'));\n totalSnapshots += files.length;\n for (const file of files) {\n try {\n const stat = statSync(join(dateDir, file));\n storageBytes += stat.size;\n } catch {\n // Skip\n }\n }\n } catch {\n // Skip\n }\n }\n\n return {\n totalSnapshots,\n totalDates: dates.length,\n totalProjects: index.projects.length,\n oldestEntry: dates.length > 0 ? dates[0] : null,\n newestEntry: dates.length > 0 ? dates[dates.length - 1] : null,\n storageBytes,\n };\n }\n\n // ─── Auto-tagging ──────────────────────────────────────────────────────\n\n /**\n * Auto-extract tags from a snapshot's content.\n * Used to make snapshots searchable by topic.\n */\n static autoTag(snapshot: WorkSnapshot): string[] {\n const tags = new Set<string>();\n\n // Extract from branch name\n const branch = snapshot.currentBranch;\n if (branch.startsWith('feature/')) tags.add('feature');\n if (branch.startsWith('fix/') || branch.startsWith('bugfix/')) tags.add('bugfix');\n if (branch.startsWith('hotfix/')) tags.add('hotfix');\n if (branch.startsWith('chore/')) tags.add('chore');\n if (branch.startsWith('refactor/')) tags.add('refactor');\n if (branch.startsWith('docs/')) tags.add('docs');\n if (branch.startsWith('test/')) tags.add('test');\n if (branch.startsWith('release/')) tags.add('release');\n\n // Extract from commit types (conventional commits)\n for (const commit of snapshot.todayCommits) {\n const match = commit.message.match(/^(\\w+)[(:]/);\n if (match) {\n const type = match[1].toLowerCase();\n if (\n [\n 'feat',\n 'fix',\n 'docs',\n 'style',\n 'refactor',\n 'test',\n 'chore',\n 'perf',\n 'ci',\n 'build',\n ].includes(type)\n ) {\n tags.add(type);\n }\n }\n\n // Extract ticket IDs as tags\n const ticketMatches = commit.message.match(/([A-Z]{2,10}-\\d+)/g);\n if (ticketMatches) {\n for (const t of ticketMatches) {\n tags.add(t.toUpperCase());\n }\n }\n\n const ghIssueMatches = commit.message.match(/#(\\d+)/g);\n if (ghIssueMatches) {\n for (const t of ghIssueMatches) {\n tags.add(t);\n }\n }\n }\n\n // Extract from categories\n for (const cat of snapshot.categories) {\n if (cat.percentage >= 20) {\n tags.add(cat.name);\n }\n }\n\n // Extract from PR labels\n for (const pr of snapshot.pullRequests) {\n for (const label of pr.labels) {\n tags.add(label.toLowerCase());\n }\n }\n\n return Array.from(tags);\n }\n\n // ─── Private Helpers ────────────────────────────────────────────────────\n\n private ensureDirectoryExists(): void {\n if (!existsSync(this.journalDir)) {\n mkdirSync(this.journalDir, { recursive: true });\n }\n }\n\n private getIndex(): JournalIndex {\n if (!existsSync(this.indexPath)) {\n return { version: JOURNAL_VERSION, projects: [], lastUpdated: new Date().toISOString() };\n }\n\n try {\n return JSON.parse(readFileSync(this.indexPath, 'utf-8')) as JournalIndex;\n } catch {\n return { version: JOURNAL_VERSION, projects: [], lastUpdated: new Date().toISOString() };\n }\n }\n\n private saveIndex(index: JournalIndex): void {\n index.lastUpdated = new Date().toISOString();\n writeFileSync(this.indexPath, JSON.stringify(index, null, 2), 'utf-8');\n }\n\n private updateIndex(snapshot: WorkSnapshot): void {\n const index = this.getIndex();\n const existing = index.projects.find((p) => p.projectId === snapshot.projectId);\n\n if (existing) {\n existing.lastSnapshotDate = snapshot.date;\n existing.repoPath = snapshot.repoPath;\n existing.remoteUrl = snapshot.remoteUrl;\n existing.snapshotCount += 1;\n if (snapshot.date < existing.firstSeen) {\n existing.firstSeen = snapshot.date;\n }\n } else {\n index.projects.push({\n projectId: snapshot.projectId,\n repoPath: snapshot.repoPath,\n remoteUrl: snapshot.remoteUrl,\n lastSnapshotDate: snapshot.date,\n snapshotCount: 1,\n firstSeen: snapshot.date,\n });\n }\n\n this.saveIndex(index);\n }\n\n private rebuildIndex(): void {\n const index: JournalIndex = {\n version: JOURNAL_VERSION,\n projects: [],\n lastUpdated: new Date().toISOString(),\n };\n\n const projectMap = new Map<\n string,\n { repoPath: string; remoteUrl?: string; dates: string[]; count: number }\n >();\n\n const dates = this.getAllDateDirs();\n for (const date of dates) {\n const dateDir = join(this.journalDir, date);\n try {\n const files = readdirSync(dateDir).filter((f) => f.endsWith('.json'));\n for (const file of files) {\n try {\n const content = JSON.parse(readFileSync(join(dateDir, file), 'utf-8')) as WorkSnapshot;\n const projectId = content.projectId || basename(file, '.json');\n const existing = projectMap.get(projectId);\n if (existing) {\n existing.dates.push(date);\n existing.count += 1;\n } else {\n projectMap.set(projectId, {\n repoPath: content.repoPath || '',\n remoteUrl: content.remoteUrl,\n dates: [date],\n count: 1,\n });\n }\n } catch {\n // Skip corrupted files\n }\n }\n } catch {\n // Skip\n }\n }\n\n for (const [projectId, data] of projectMap) {\n data.dates.sort();\n index.projects.push({\n projectId,\n repoPath: data.repoPath,\n remoteUrl: data.remoteUrl,\n lastSnapshotDate: data.dates[data.dates.length - 1],\n snapshotCount: data.count,\n firstSeen: data.dates[0],\n });\n }\n\n this.saveIndex(index);\n }\n\n /**\n * Merge two snapshots for the same date+project.\n * The newer snapshot's metadata wins, but commits are deduplicated and merged.\n */\n private mergeSnapshots(existing: WorkSnapshot, incoming: WorkSnapshot): WorkSnapshot {\n // Deduplicate commits by hash\n const commitMap = new Map<string, JournalCommit>();\n for (const c of existing.todayCommits) {\n commitMap.set(c.hash, c);\n }\n for (const c of incoming.todayCommits) {\n commitMap.set(c.hash, c); // Incoming wins on duplicates\n }\n\n const recentMap = new Map<string, JournalCommit>();\n for (const c of existing.recentCommits) {\n recentMap.set(c.hash, c);\n }\n for (const c of incoming.recentCommits) {\n recentMap.set(c.hash, c);\n }\n\n // Merge branches\n const branchMap = new Map<string, JournalBranchSnapshot>();\n for (const b of existing.activeBranches) {\n branchMap.set(b.name, b);\n }\n for (const b of incoming.activeBranches) {\n branchMap.set(b.name, b); // Incoming wins\n }\n\n // Merge PRs\n const prMap = new Map<number, JournalPRSnapshot>();\n for (const pr of existing.pullRequests) {\n prMap.set(pr.number, pr);\n }\n for (const pr of incoming.pullRequests) {\n prMap.set(pr.number, pr);\n }\n\n // Merge tags\n const allTags = new Set([...existing.tags, ...incoming.tags]);\n\n return {\n ...incoming,\n takenAt: new Date().toISOString(),\n todayCommits: Array.from(commitMap.values()).sort(\n (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()\n ),\n recentCommits: Array.from(recentMap.values()).sort(\n (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()\n ),\n activeBranches: Array.from(branchMap.values()),\n pullRequests: Array.from(prMap.values()),\n notes: existing.notes\n ? incoming.notes\n ? `${existing.notes}\\n\\n${incoming.notes}`\n : existing.notes\n : incoming.notes,\n aiSummary: incoming.aiSummary || existing.aiSummary,\n tags: Array.from(allTags),\n };\n }\n\n /**\n * Match a snapshot against search criteria and compute a relevance score.\n */\n private matchSnapshot(\n snapshot: WorkSnapshot,\n query?: string,\n tags?: string[]\n ): { score: number; reasons: string[] } {\n let score = 0;\n const reasons: string[] = [];\n\n // If no query and no tags, match everything with base score\n if (!query && (!tags || tags.length === 0)) {\n return { score: 1, reasons: ['date match'] };\n }\n\n // Tag matching\n if (tags && tags.length > 0) {\n const snapshotTags = new Set(snapshot.tags.map((t) => t.toLowerCase()));\n for (const tag of tags) {\n if (snapshotTags.has(tag.toLowerCase())) {\n score += 5;\n reasons.push(`tag: ${tag}`);\n }\n }\n }\n\n // Text query matching\n if (query) {\n const q = query.toLowerCase();\n\n // Branch name match (high value — directly relevant)\n if (snapshot.currentBranch.toLowerCase().includes(q)) {\n score += 10;\n reasons.push(`branch: ${snapshot.currentBranch}`);\n }\n\n // Active branch match\n for (const b of snapshot.activeBranches) {\n if (b.name.toLowerCase().includes(q)) {\n score += 5;\n reasons.push(`active branch: ${b.name}`);\n }\n }\n\n // Commit message match\n for (const c of snapshot.todayCommits) {\n if (c.message.toLowerCase().includes(q)) {\n score += 3;\n reasons.push(`commit: ${c.shortHash} ${c.message.slice(0, 50)}`);\n }\n // File path match within commits\n if (c.filesChanged) {\n for (const f of c.filesChanged) {\n if (f.toLowerCase().includes(q)) {\n score += 2;\n reasons.push(`file: ${f}`);\n }\n }\n }\n }\n\n // Recent commit match (lower weight)\n for (const c of snapshot.recentCommits) {\n if (c.message.toLowerCase().includes(q)) {\n score += 1;\n reasons.push(`recent commit: ${c.shortHash} ${c.message.slice(0, 50)}`);\n }\n }\n\n // PR title match\n for (const pr of snapshot.pullRequests) {\n if (pr.title.toLowerCase().includes(q)) {\n score += 5;\n reasons.push(`PR: #${pr.number} ${pr.title.slice(0, 50)}`);\n }\n }\n\n // Ticket match\n for (const t of snapshot.tickets) {\n if (t.id.toLowerCase().includes(q) || t.title.toLowerCase().includes(q)) {\n score += 5;\n reasons.push(`ticket: ${t.id}`);\n }\n }\n\n // Notes match\n if (snapshot.notes && snapshot.notes.toLowerCase().includes(q)) {\n score += 4;\n reasons.push('notes');\n }\n\n // AI summary match\n if (snapshot.aiSummary && snapshot.aiSummary.toLowerCase().includes(q)) {\n score += 3;\n reasons.push('AI summary');\n }\n\n // Tag match (via text, in case user doesn't use --tags flag)\n for (const tag of snapshot.tags) {\n if (tag.toLowerCase().includes(q)) {\n score += 2;\n reasons.push(`tag: ${tag}`);\n }\n }\n\n // Top files match\n for (const f of snapshot.topChangedFiles) {\n if (f.path.toLowerCase().includes(q)) {\n score += 2;\n reasons.push(`changed file: ${f.path}`);\n }\n }\n\n // Project ID match\n if (snapshot.projectId.toLowerCase().includes(q)) {\n score += 3;\n reasons.push(`project: ${snapshot.projectId}`);\n }\n }\n\n // Deduplicate reasons\n const uniqueReasons = [...new Set(reasons)];\n\n return { score, reasons: uniqueReasons };\n }\n\n /**\n * Get all date directories sorted chronologically.\n */\n private getAllDateDirs(): string[] {\n try {\n const entries = readdirSync(this.journalDir);\n return entries\n .filter((e) => /^\\d{4}-\\d{2}-\\d{2}$/.test(e))\n .filter((e) => {\n try {\n return statSync(join(this.journalDir, e)).isDirectory();\n } catch {\n return false;\n }\n })\n .sort();\n } catch {\n return [];\n }\n }\n\n /**\n * Get date directories within a range (inclusive).\n */\n private getDateDirsInRange(from: string, to: string): string[] {\n return this.getAllDateDirs().filter((d) => d >= from && d <= to);\n }\n\n /**\n * Get the earliest date directory in the journal.\n */\n private getEarliestDate(): string | null {\n const dirs = this.getAllDateDirs();\n return dirs.length > 0 ? dirs[0] : null;\n }\n\n /**\n * Get today's date as YYYY-MM-DD string.\n */\n todayString(): string {\n return this.dateToString(new Date());\n }\n\n /**\n * Convert a Date to YYYY-MM-DD string.\n */\n dateToString(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n }\n\n /**\n * Sanitize a project name for use as a filename.\n */\n static sanitizeProjectId(name: string): string {\n return name\n .replace(/[/\\\\:*?\"<>|]/g, '-')\n .replace(/^\\.+/, '')\n .replace(/\\s+/g, '-')\n .toLowerCase()\n .slice(0, 100);\n }\n}\n","/**\n * Snapshot Builder - Captures current project state into a WorkSnapshot\n *\n * Uses the existing GitAnalyzer, ContextAnalyzer, StandupContextBuilder,\n * and GitHub client to gather all relevant project state and produce a\n * WorkSnapshot that the WorkJournal can persist.\n *\n * This is the bridge between the real-time analysis layer (git, PRs, tickets)\n * and the persistent memory layer (WorkJournal).\n */\n\nimport { GitAnalyzer } from './git-analyzer.js';\nimport { ContextAnalyzer } from './context-analyzer.js';\nimport {\n WorkJournal,\n type WorkSnapshot,\n type JournalCommit,\n type JournalBranchSnapshot,\n type JournalPRSnapshot,\n type JournalTicketSnapshot,\n} from './work-journal.js';\nimport { getConfig } from '../config/index.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface SnapshotOptions {\n /** Override the date for the snapshot (default: today) */\n date?: string;\n\n /** Override the project ID (default: auto-detected from repo name / directory) */\n projectId?: string;\n\n /** Number of days to look back for \"recent\" commits context (default: 7) */\n recentDays?: number;\n\n /** Skip fetching PR data */\n skipPRs?: boolean;\n\n /** Skip fetching ticket data */\n skipTickets?: boolean;\n\n /** Include active branch listing (default: true) */\n includeBranches?: boolean;\n\n /** Include uncommitted changes info (default: true) */\n includeUncommitted?: boolean;\n\n /** Auto-generate AI summary after snapshot (default: false) */\n generateSummary?: boolean;\n\n /** Debug mode — log extra info */\n debug?: boolean;\n\n /** Optional note to attach to the snapshot */\n note?: string;\n\n /** Optional extra tags */\n tags?: string[];\n}\n\nexport interface SnapshotResult {\n snapshot: WorkSnapshot;\n /** Whether this snapshot was merged with an existing one for the same date */\n merged: boolean;\n /** Warnings encountered during snapshot (non-fatal issues) */\n warnings: string[];\n /** Time taken in milliseconds */\n durationMs: number;\n}\n\n// ─── Snapshot Builder ─────────────────────────────────────────────────────────\n\nexport class SnapshotBuilder {\n private git: GitAnalyzer;\n private contextAnalyzer: ContextAnalyzer;\n private config = getConfig();\n private debug: boolean;\n\n constructor(repoPath?: string, debug: boolean = false) {\n this.git = new GitAnalyzer(repoPath);\n this.contextAnalyzer = new ContextAnalyzer(\n repoPath,\n this.config.projectManagement.tool,\n this.config.projectManagement.ticketPrefix\n );\n this.debug = debug;\n }\n\n /**\n * Take a full snapshot of the current project state.\n *\n * This gathers:\n * - Current branch and all active local branches\n * - Today's commits (with file change details)\n * - Recent commits (last N days, for context)\n * - Open / recently merged PRs\n * - Active tickets (extracted from branch names, commits, PRs)\n * - Work category breakdown (frontend, backend, infra, etc.)\n * - Diff stats\n * - Top changed files\n * - Uncommitted changes\n *\n * The snapshot is ready to be saved by WorkJournal.saveSnapshot().\n */\n async takeSnapshot(options: SnapshotOptions = {}): Promise<SnapshotResult> {\n const startTime = Date.now();\n const warnings: string[] = [];\n const journal = new WorkJournal();\n\n const {\n date,\n projectId: overrideProjectId,\n recentDays = 7,\n skipPRs = false,\n skipTickets = false,\n includeBranches = true,\n includeUncommitted = true,\n note,\n tags: extraTags = [],\n } = options;\n\n const snapshotDate = date || journal.todayString();\n\n // ── Step 1: Detect project identity ──────────────────────────────────\n\n const projectId = overrideProjectId || (await this.detectProjectId());\n const repoPath = await this.safeRepoRoot();\n const remoteUrl = await this.safeRemoteUrl();\n\n this.log('Project ID:', projectId);\n this.log('Repo path:', repoPath);\n\n // ── Step 2: Get current branch ───────────────────────────────────────\n\n const currentBranch = await this.safeCurrentBranch();\n this.log('Current branch:', currentBranch);\n\n // ── Step 3: Get today's commits ──────────────────────────────────────\n\n const todaySince = this.parseDateStart(snapshotDate);\n const todayUntil = this.parseDateEnd(snapshotDate);\n\n const todayCommits = await this.getCommitsInRange(todaySince, todayUntil);\n this.log(`Today's commits: ${todayCommits.length}`);\n\n // ── Step 4: Get recent commits (for context) ─────────────────────────\n\n const recentSince = new Date();\n recentSince.setDate(recentSince.getDate() - recentDays);\n recentSince.setHours(0, 0, 0, 0);\n\n const recentCommits = await this.getCommitsInRange(recentSince, todayUntil);\n this.log(`Recent commits (${recentDays}d): ${recentCommits.length}`);\n\n // ── Step 5: Get active branches ──────────────────────────────────────\n\n let activeBranches: JournalBranchSnapshot[] = [];\n if (includeBranches) {\n try {\n activeBranches = await this.getActiveBranches(currentBranch, includeUncommitted);\n this.log(`Active branches: ${activeBranches.length}`);\n } catch (err) {\n warnings.push(`Could not list branches: ${(err as Error).message}`);\n }\n }\n\n // ── Step 6: Get work context (categories, files, diff stats) ─────────\n\n const baseBranch = this.config.git.defaultBranch || 'main';\n let categories: { name: string; percentage: number }[] = [];\n let diffStats: { filesChanged: number; insertions: number; deletions: number } | null = null;\n let topChangedFiles: { path: string; frequency: number }[] = [];\n\n try {\n const workContext = await this.contextAnalyzer.getWorkContext({\n since: todaySince,\n until: todayUntil,\n base: baseBranch,\n });\n\n categories = workContext.categories.map((c) => ({\n name: c.name,\n percentage: c.percentage,\n }));\n\n topChangedFiles = workContext.filesChanged\n .reduce(\n (acc, file) => {\n const existing = acc.find((f) => f.path === file);\n if (existing) {\n existing.frequency += 1;\n } else {\n acc.push({ path: file, frequency: 1 });\n }\n return acc;\n },\n [] as { path: string; frequency: number }[]\n )\n .sort((a, b) => b.frequency - a.frequency)\n .slice(0, 20);\n } catch (err) {\n warnings.push(`Could not analyze work context: ${(err as Error).message}`);\n }\n\n // Try to get diff stats separately (more targeted)\n try {\n const stats = await this.git.getDiffStats(baseBranch, 'HEAD');\n diffStats = stats;\n } catch {\n // Not on a feature branch or base doesn't exist — try commit-based stats\n if (todayCommits.length > 0) {\n const filesChanged = new Set<string>();\n for (const c of todayCommits) {\n if (c.filesChanged) {\n for (const f of c.filesChanged) {\n filesChanged.add(f);\n }\n }\n }\n diffStats = {\n filesChanged: filesChanged.size,\n insertions: 0,\n deletions: 0,\n };\n }\n }\n\n // ── Step 7: Get PRs ──────────────────────────────────────────────────\n\n let pullRequests: JournalPRSnapshot[] = [];\n if (!skipPRs) {\n try {\n pullRequests = await this.getRecentPRs(recentSince);\n this.log(`PRs found: ${pullRequests.length}`);\n } catch (err) {\n warnings.push(`Could not fetch PRs: ${(err as Error).message}`);\n }\n }\n\n // ── Step 8: Get tickets ──────────────────────────────────────────────\n\n let tickets: JournalTicketSnapshot[] = [];\n if (!skipTickets) {\n try {\n tickets = await this.extractTickets(\n currentBranch,\n todayCommits,\n recentCommits,\n pullRequests\n );\n this.log(`Tickets found: ${tickets.length}`);\n } catch (err) {\n warnings.push(`Could not extract tickets: ${(err as Error).message}`);\n }\n }\n\n // ── Step 9: Auto-tag ─────────────────────────────────────────────────\n\n // Build preliminary snapshot for auto-tagging\n const snapshot: WorkSnapshot = {\n date: snapshotDate,\n takenAt: new Date().toISOString(),\n projectId,\n repoPath: repoPath || process.cwd(),\n remoteUrl: remoteUrl || undefined,\n currentBranch,\n activeBranches,\n todayCommits,\n recentCommits,\n pullRequests,\n tickets,\n categories,\n topChangedFiles,\n diffStats,\n notes: note,\n tags: [],\n };\n\n // Auto-tag + merge with user-supplied tags\n const autoTags = WorkJournal.autoTag(snapshot);\n const allTags = new Set([...autoTags, ...extraTags]);\n snapshot.tags = Array.from(allTags);\n\n // ── Step 10: Check if this is a merge with existing snapshot ──────────\n\n const existing = journal.getSnapshot(snapshotDate, projectId);\n const merged = existing !== null;\n\n // ── Done ─────────────────────────────────────────────────────────────\n\n const durationMs = Date.now() - startTime;\n this.log(`Snapshot built in ${durationMs}ms (${warnings.length} warnings)`);\n\n return {\n snapshot,\n merged,\n warnings,\n durationMs,\n };\n }\n\n /**\n * Take a snapshot and immediately save it to the journal.\n * Returns the saved snapshot and metadata.\n */\n async takeAndSave(options: SnapshotOptions = {}): Promise<SnapshotResult> {\n const result = await this.takeSnapshot(options);\n const journal = new WorkJournal();\n journal.saveSnapshot(result.snapshot);\n return result;\n }\n\n /**\n * Take a lightweight snapshot — only commits and branch info, no PRs/tickets.\n * Useful for quick saves (e.g., on branch switch via git hook).\n */\n async takeLightSnapshot(options: SnapshotOptions = {}): Promise<SnapshotResult> {\n return this.takeSnapshot({\n ...options,\n skipPRs: true,\n skipTickets: true,\n includeBranches: true,\n includeUncommitted: true,\n });\n }\n\n // ─── Data Gathering Helpers ─────────────────────────────────────────────\n\n /**\n * Detect a stable project identifier from the repo.\n * Priority: remote origin name > directory name.\n */\n private async detectProjectId(): Promise<string> {\n // Try to get the repo name from remote origin\n try {\n const remoteUrl = await this.safeRemoteUrl();\n if (remoteUrl) {\n // Extract owner/repo from various URL formats\n // git@github.com:owner/repo.git\n // https://github.com/owner/repo.git\n const sshMatch = remoteUrl.match(/[:/]([^/]+\\/[^/]+?)(?:\\.git)?$/);\n if (sshMatch) {\n return WorkJournal.sanitizeProjectId(sshMatch[1]);\n }\n }\n } catch {\n // Fall through to directory name\n }\n\n // Fallback: use the directory name of the repo root\n try {\n const root = await this.git.getRepoRoot();\n const dirName = root.split('/').pop() || root.split('\\\\').pop() || 'unknown';\n return WorkJournal.sanitizeProjectId(dirName);\n } catch {\n return WorkJournal.sanitizeProjectId(process.cwd().split('/').pop() || 'unknown');\n }\n }\n\n /**\n * Get commits in a date range, enriched with file change info.\n */\n private async getCommitsInRange(since: Date, until: Date): Promise<JournalCommit[]> {\n try {\n const rawCommits = await this.git.getCommits({ since, until });\n const enriched: JournalCommit[] = [];\n\n for (const commit of rawCommits) {\n let filesChanged: string[] | undefined;\n try {\n filesChanged = await this.git.getCommitFiles(commit.hash);\n } catch {\n // Non-critical — just skip file info for this commit\n }\n\n enriched.push({\n hash: commit.hash,\n shortHash: commit.hash.slice(0, 7),\n message: commit.message,\n author: commit.author,\n date: commit.date.toISOString(),\n filesChanged,\n });\n }\n\n return enriched;\n } catch {\n return [];\n }\n }\n\n /**\n * Get all active local branches with their status.\n */\n private async getActiveBranches(\n currentBranch: string,\n includeUncommitted: boolean\n ): Promise<JournalBranchSnapshot[]> {\n const branches: JournalBranchSnapshot[] = [];\n\n try {\n // Get all local branches with last commit info\n const result = await this.git['git'].raw([\n 'branch',\n '--format=%(refname:short)|||%(objectname:short)|||%(subject)|||%(committerdate:iso)',\n '--sort=-committerdate',\n ]);\n\n const lines = result.split('\\n').filter(Boolean);\n const baseBranch = this.config.git.defaultBranch || 'main';\n\n for (const line of lines.slice(0, 30)) {\n // Cap at 30 branches\n const parts = line.split('|||');\n if (parts.length < 4) continue;\n\n const [name, commitHash, commitMessage, commitDate] = parts;\n const trimmedName = name.trim();\n\n // Skip the base branch itself in the listing\n if (trimmedName === baseBranch) continue;\n\n // Compute ahead count (how many commits ahead of base)\n let aheadOfBase = 0;\n try {\n const countResult = await this.git['git'].raw([\n 'rev-list',\n '--count',\n `${baseBranch}..${trimmedName}`,\n ]);\n aheadOfBase = parseInt(countResult.trim(), 10) || 0;\n } catch {\n // Base branch might not exist — that's fine\n }\n\n // Check uncommitted changes only for the current branch\n let hasUncommittedChanges = false;\n let uncommittedFiles: string[] = [];\n\n if (includeUncommitted && trimmedName === currentBranch) {\n try {\n const status = await this.git.getStatus();\n uncommittedFiles = [...status.modified, ...status.untracked];\n hasUncommittedChanges = uncommittedFiles.length > 0;\n } catch {\n // Non-critical\n }\n }\n\n branches.push({\n name: trimmedName,\n lastCommitHash: commitHash.trim(),\n lastCommitMessage: commitMessage.trim(),\n lastCommitDate: new Date(commitDate.trim()).toISOString(),\n hasUncommittedChanges,\n aheadOfBase,\n uncommittedFiles,\n });\n }\n } catch {\n // If branch listing fails entirely, at least record the current branch\n branches.push({\n name: currentBranch,\n lastCommitHash: '',\n lastCommitMessage: '',\n lastCommitDate: new Date().toISOString(),\n hasUncommittedChanges: false,\n aheadOfBase: 0,\n uncommittedFiles: [],\n });\n }\n\n return branches;\n }\n\n /**\n * Fetch recent PRs and map them to the journal format.\n */\n private async getRecentPRs(since: Date): Promise<JournalPRSnapshot[]> {\n const prs: JournalPRSnapshot[] = [];\n\n try {\n const { execa } = await import('execa');\n\n // Fetch open PRs authored by current user\n try {\n const { stdout: openStdout } = await execa(\n 'gh',\n [\n 'pr',\n 'list',\n '--author',\n '@me',\n '--state',\n 'open',\n '--json',\n 'number,title,state,url,baseRefName,headRefName,labels',\n '--limit',\n '20',\n ],\n { timeout: 15000 }\n );\n\n const openPRs = JSON.parse(openStdout || '[]');\n for (const pr of openPRs) {\n prs.push(this.mapPR(pr));\n }\n } catch {\n // gh not available or not a GitHub repo\n }\n\n // Fetch recently merged PRs\n try {\n const { stdout: mergedStdout } = await execa(\n 'gh',\n [\n 'pr',\n 'list',\n '--author',\n '@me',\n '--state',\n 'merged',\n '--json',\n 'number,title,state,url,baseRefName,headRefName,labels,mergedAt',\n '--limit',\n '10',\n ],\n { timeout: 15000 }\n );\n\n const mergedPRs = JSON.parse(mergedStdout || '[]');\n for (const pr of mergedPRs) {\n // Only include if merged after `since`\n if (pr.mergedAt && new Date(pr.mergedAt) >= since) {\n prs.push(this.mapPR(pr));\n }\n }\n } catch {\n // Non-critical\n }\n } catch {\n // execa not available — skip PR fetching\n }\n\n // Deduplicate by PR number\n const seen = new Set<number>();\n return prs.filter((pr) => {\n if (seen.has(pr.number)) return false;\n seen.add(pr.number);\n return true;\n });\n }\n\n /**\n * Map a raw GH CLI PR object to JournalPRSnapshot.\n */\n private mapPR(pr: Record<string, unknown>): JournalPRSnapshot {\n return {\n number: (pr.number as number) || 0,\n title: (pr.title as string) || '',\n state: (pr.state as string) || 'unknown',\n url: (pr.url as string) || '',\n baseBranch: (pr.baseRefName as string) || '',\n headBranch: (pr.headRefName as string) || '',\n labels: Array.isArray(pr.labels)\n ? (pr.labels as { name: string }[]).map((l) => l.name || '')\n : [],\n };\n }\n\n /**\n * Extract ticket IDs from various sources and map to journal format.\n */\n private async extractTickets(\n currentBranch: string,\n todayCommits: JournalCommit[],\n recentCommits: JournalCommit[],\n pullRequests: JournalPRSnapshot[]\n ): Promise<JournalTicketSnapshot[]> {\n const ticketIds = new Set<string>();\n\n // From branch name\n const branchTickets = this.contextAnalyzer.extractTicketsFromBranch(currentBranch);\n for (const t of branchTickets) {\n ticketIds.add(t.id);\n }\n\n // From commit messages (convert JournalCommit to Commit format)\n const commitLikeObjects = [...todayCommits, ...recentCommits].map((c) => ({\n hash: c.hash,\n message: c.message,\n author: c.author,\n date: new Date(c.date),\n body: undefined,\n }));\n const commitTickets = this.contextAnalyzer.extractTicketsFromCommits(commitLikeObjects);\n for (const t of commitTickets) {\n ticketIds.add(t.id);\n }\n\n // From PR titles\n for (const pr of pullRequests) {\n const prTickets = this.contextAnalyzer.extractTicketsFromCommits([\n { hash: '', message: pr.title, author: '', date: new Date() },\n ]);\n for (const t of prTickets) {\n ticketIds.add(t.id);\n }\n }\n\n // Map to JournalTicketSnapshot (basic — no PM API lookup in snapshot builder)\n const tickets: JournalTicketSnapshot[] = [];\n for (const id of ticketIds) {\n tickets.push({\n id,\n title: '', // Would need PM API to get full title\n status: 'unknown',\n type: 'unknown',\n });\n }\n\n return tickets;\n }\n\n // ─── Safe Git Helpers (never throw) ─────────────────────────────────────\n\n private async safeCurrentBranch(): Promise<string> {\n try {\n return await this.git.getCurrentBranch();\n } catch {\n return 'unknown';\n }\n }\n\n private async safeRepoRoot(): Promise<string | null> {\n try {\n return await this.git.getRepoRoot();\n } catch {\n return null;\n }\n }\n\n private async safeRemoteUrl(): Promise<string | null> {\n try {\n const result = await this.git['git'].raw(['remote', 'get-url', 'origin']);\n return result.trim() || null;\n } catch {\n return null;\n }\n }\n\n // ─── Date Helpers ───────────────────────────────────────────────────────\n\n /**\n * Parse a YYYY-MM-DD string into a Date at 00:00:00 local time.\n */\n private parseDateStart(dateStr: string): Date {\n const [year, month, day] = dateStr.split('-').map(Number);\n const d = new Date(year, month - 1, day, 0, 0, 0, 0);\n return d;\n }\n\n /**\n * Parse a YYYY-MM-DD string into a Date at 23:59:59 local time.\n */\n private parseDateEnd(dateStr: string): Date {\n const [year, month, day] = dateStr.split('-').map(Number);\n const d = new Date(year, month - 1, day, 23, 59, 59, 999);\n return d;\n }\n\n // ─── Debug Logging ──────────────────────────────────────────────────────\n\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log('[snapshot]', ...args);\n }\n }\n}\n\n// ─── Convenience Functions ────────────────────────────────────────────────────\n\n/**\n * Quick helper: take a snapshot of the current project and save it.\n * Ideal for use in git hooks or cron jobs.\n */\nexport async function autoSnapshot(options: SnapshotOptions = {}): Promise<SnapshotResult> {\n const builder = new SnapshotBuilder(undefined, options.debug);\n return builder.takeAndSave(options);\n}\n\n/**\n * Quick helper: take a light snapshot (no PRs/tickets) and save it.\n * Ideal for branch-switch hooks where speed matters.\n */\nexport async function quickSnapshot(options: SnapshotOptions = {}): Promise<SnapshotResult> {\n const builder = new SnapshotBuilder(undefined, options.debug);\n const result = await builder.takeLightSnapshot(options);\n const journal = new WorkJournal();\n journal.saveSnapshot(result.snapshot);\n return result;\n}\n","/**\n * Auto-Snapshot — Silent side-effect snapshots for existing commands\n *\n * This module provides a fire-and-forget snapshot mechanism that:\n * - Runs in the background without blocking the main command\n * - Never throws or crashes the parent command\n * - Respects the `journal.autoSnapshot` config flag\n * - Takes a \"light\" snapshot (no PRs/tickets) for speed\n * - Logs quietly (or not at all) depending on `journal.quiet`\n *\n * Usage in any command:\n * import { sideEffectSnapshot } from '../core/auto-snapshot.js';\n * // At the end of your command's action:\n * await sideEffectSnapshot({ source: 'standup' });\n */\n\nimport { getConfig } from '../config/index.js';\nimport { SnapshotBuilder, type SnapshotOptions, type SnapshotResult } from './snapshot-builder.js';\nimport { WorkJournal } from './work-journal.js';\nimport { GitAnalyzer } from './git-analyzer.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface SideEffectSnapshotOptions {\n /** Which command triggered this snapshot (used as a tag) */\n source: 'standup' | 'pr' | 'week' | 'context' | 'recall' | 'post-commit' | 'post-checkout';\n\n /** Optional note to attach */\n note?: string;\n\n /** Extra tags beyond the auto-generated ones */\n tags?: string[];\n\n /** Override project ID */\n projectId?: string;\n\n /** Override date */\n date?: string;\n\n /** Force snapshot even if autoSnapshot config is false */\n force?: boolean;\n\n /** Show a message when snapshot is saved (overrides journal.quiet) */\n verbose?: boolean;\n\n /** Debug mode */\n debug?: boolean;\n}\n\nexport interface SideEffectResult {\n /** Whether a snapshot was actually taken */\n taken: boolean;\n /** Reason it was skipped (if not taken) */\n skipReason?: string;\n /** The snapshot result (if taken) */\n result?: SnapshotResult;\n}\n\n// ─── Main API ─────────────────────────────────────────────────────────────────\n\n/**\n * Take a silent, non-blocking snapshot as a side-effect of another command.\n *\n * This is the primary function commands should call. It:\n * 1. Checks if auto-snapshot is enabled in config\n * 2. Checks if we're in a git repo\n * 3. Takes a light snapshot (fast — no PR/ticket fetching)\n * 4. Saves it to the journal with a source tag\n * 5. Never throws — returns a result indicating what happened\n */\nexport async function sideEffectSnapshot(\n options: SideEffectSnapshotOptions\n): Promise<SideEffectResult> {\n try {\n const config = getConfig();\n const journalConfig = config.journal ?? { autoSnapshot: true, quiet: true };\n\n // Check if auto-snapshot is enabled (unless forced)\n if (!options.force && !journalConfig.autoSnapshot) {\n return { taken: false, skipReason: 'autoSnapshot disabled in config' };\n }\n\n // Check if we're in a git repo\n const git = new GitAnalyzer();\n if (!(await git.isRepository())) {\n return { taken: false, skipReason: 'not a git repository' };\n }\n\n // Build snapshot options — always use light mode for speed\n const snapshotOpts: SnapshotOptions = {\n date: options.date,\n projectId: options.projectId,\n skipPRs: true,\n skipTickets: true,\n includeBranches: false,\n includeUncommitted: true,\n debug: options.debug,\n note: options.note,\n tags: [...(options.tags ?? []), `auto:${options.source}`],\n };\n\n const builder = new SnapshotBuilder(undefined, options.debug ?? false);\n const result = await builder.takeLightSnapshot(snapshotOpts);\n\n // Save to journal\n const journal = new WorkJournal();\n journal.saveSnapshot(result.snapshot);\n\n // Log if not quiet\n const quiet = options.verbose !== undefined ? !options.verbose : journalConfig.quiet;\n if (!quiet && process.env.DEVD_QUIET !== '1') {\n const tag = options.source;\n // Use stderr so it doesn't interfere with piped output\n process.stderr.write(`\\x1b[2m📸 Snapshot saved (via ${tag})\\x1b[0m\\n`);\n }\n\n return { taken: true, result };\n } catch {\n // Never crash the parent command\n if (options.debug) {\n process.stderr.write(`\\x1b[2m⚠ Auto-snapshot failed (non-fatal)\\x1b[0m\\n`);\n }\n return { taken: false, skipReason: 'snapshot failed (non-fatal)' };\n }\n}\n\n/**\n * Fire-and-forget variant — doesn't even await the result.\n *\n * Use this when you absolutely don't want to add any latency to the command.\n * The snapshot runs in the background and errors are silently swallowed.\n */\nexport function fireAndForgetSnapshot(options: SideEffectSnapshotOptions): void {\n sideEffectSnapshot(options).catch(() => {\n // Intentionally swallowed — fire and forget\n });\n}\n\n// ─── Git Hook Helpers ─────────────────────────────────────────────────────────\n\n/**\n * Generate the content for a post-commit git hook that triggers a snapshot.\n */\nexport function generatePostCommitHook(): string {\n return `#!/bin/sh\n# DevDaily auto-snapshot — captures work state after each commit\n# Installed by: devdaily init --git-hooks\n# Remove this file to disable post-commit snapshots\n\n# Only run if devdaily is installed\nif ! command -v devdaily >/dev/null 2>&1; then\n exit 0\nfi\n\n# Run snapshot in background so it doesn't slow down commits\n(devdaily snapshot --light --tag auto:post-commit 2>/dev/null &)\n\nexit 0\n`;\n}\n\n/**\n * Generate the content for a post-checkout git hook that triggers a snapshot.\n */\nexport function generatePostCheckoutHook(): string {\n return `#!/bin/sh\n# DevDaily auto-snapshot — captures work state when switching branches\n# Installed by: devdaily init --git-hooks\n# Remove this file to disable post-checkout snapshots\n#\n# Arguments from git:\n# $1 = previous HEAD ref\n# $2 = new HEAD ref\n# $3 = 1 if branch checkout, 0 if file checkout\n\nPREV_REF=\"$1\"\nNEW_REF=\"$2\"\nIS_BRANCH_CHECKOUT=\"$3\"\n\n# Only run on branch checkouts (not file checkouts)\nif [ \"$IS_BRANCH_CHECKOUT\" != \"1\" ]; then\n exit 0\nfi\n\n# Skip if refs are the same (no actual branch change)\nif [ \"$PREV_REF\" = \"$NEW_REF\" ]; then\n exit 0\nfi\n\n# Only run if devdaily is installed\nif ! command -v devdaily >/dev/null 2>&1; then\n exit 0\nfi\n\n# Run snapshot in background so it doesn't slow down checkout\n(devdaily snapshot --light --tag auto:post-checkout --note \"Switched branch\" 2>/dev/null &)\n\nexit 0\n`;\n}\n\n/**\n * Install git hooks into the current repository.\n *\n * Returns an object describing what was installed and what was skipped.\n * Respects existing hooks — if a hook already exists and isn't ours, it\n * appends a call to devdaily instead of overwriting.\n */\nexport async function installGitHooks(options?: {\n postCommit?: boolean;\n postCheckout?: boolean;\n force?: boolean;\n}): Promise<{\n installed: string[];\n skipped: string[];\n warnings: string[];\n}> {\n const { existsSync, writeFileSync, readFileSync, chmodSync, mkdirSync } = await import('fs');\n const { join } = await import('path');\n\n const git = new GitAnalyzer();\n const installed: string[] = [];\n const skipped: string[] = [];\n const warnings: string[] = [];\n\n if (!(await git.isRepository())) {\n warnings.push('Not a git repository — cannot install hooks');\n return { installed, skipped, warnings };\n }\n\n let repoRoot: string;\n try {\n repoRoot = await git.getRepoRoot();\n } catch {\n warnings.push('Could not determine repository root');\n return { installed, skipped, warnings };\n }\n\n // Determine hooks directory (respects core.hooksPath config)\n let hooksDir: string;\n try {\n const { execSync } = await import('child_process');\n const customPath = execSync('git config core.hooksPath', {\n cwd: repoRoot,\n encoding: 'utf-8',\n }).trim();\n hooksDir = customPath.startsWith('/') ? customPath : join(repoRoot, customPath);\n } catch {\n hooksDir = join(repoRoot, '.git', 'hooks');\n }\n\n // Ensure hooks directory exists\n if (!existsSync(hooksDir)) {\n mkdirSync(hooksDir, { recursive: true });\n }\n\n const DEVDAILY_MARKER = '# DevDaily auto-snapshot';\n\n const installHook = (name: string, content: string, enabled: boolean): void => {\n if (!enabled) {\n skipped.push(name);\n return;\n }\n\n const hookPath = join(hooksDir, name);\n\n if (existsSync(hookPath)) {\n const existing = readFileSync(hookPath, 'utf-8');\n\n // If it's already our hook, skip or overwrite\n if (existing.includes(DEVDAILY_MARKER)) {\n if (options?.force) {\n writeFileSync(hookPath, content);\n chmodSync(hookPath, 0o755);\n installed.push(`${name} (overwritten)`);\n } else {\n skipped.push(`${name} (already installed)`);\n }\n return;\n }\n\n // There's an existing hook that isn't ours — append\n const appendSnippet =\n name === 'post-commit'\n ? `\\n\\n${DEVDAILY_MARKER}\\nif command -v devdaily >/dev/null 2>&1; then\\n (devdaily snapshot --light --tag auto:post-commit 2>/dev/null &)\\nfi\\n`\n : `\\n\\n${DEVDAILY_MARKER}\\nif [ \"$3\" = \"1\" ] && command -v devdaily >/dev/null 2>&1; then\\n (devdaily snapshot --light --tag auto:post-checkout --note \"Switched branch\" 2>/dev/null &)\\nfi\\n`;\n\n writeFileSync(hookPath, existing + appendSnippet);\n chmodSync(hookPath, 0o755);\n installed.push(`${name} (appended to existing hook)`);\n warnings.push(\n `${name}: Existing hook found — appended devdaily call. Review ${hookPath} to verify.`\n );\n return;\n }\n\n // No existing hook — write fresh\n writeFileSync(hookPath, content);\n chmodSync(hookPath, 0o755);\n installed.push(name);\n };\n\n const doPostCommit = options?.postCommit ?? true;\n const doPostCheckout = options?.postCheckout ?? true;\n\n installHook('post-commit', generatePostCommitHook(), doPostCommit);\n installHook('post-checkout', generatePostCheckoutHook(), doPostCheckout);\n\n return { installed, skipped, warnings };\n}\n\n/**\n * Remove devdaily git hooks from the current repository.\n */\nexport async function removeGitHooks(): Promise<{\n removed: string[];\n warnings: string[];\n}> {\n const { existsSync, readFileSync, writeFileSync, unlinkSync } = await import('fs');\n const { join } = await import('path');\n\n const git = new GitAnalyzer();\n const removed: string[] = [];\n const warnings: string[] = [];\n\n if (!(await git.isRepository())) {\n warnings.push('Not a git repository');\n return { removed, warnings };\n }\n\n let repoRoot: string;\n try {\n repoRoot = await git.getRepoRoot();\n } catch {\n warnings.push('Could not determine repository root');\n return { removed, warnings };\n }\n\n let hooksDir: string;\n try {\n const { execSync } = await import('child_process');\n const customPath = execSync('git config core.hooksPath', {\n cwd: repoRoot,\n encoding: 'utf-8',\n }).trim();\n hooksDir = customPath.startsWith('/') ? customPath : join(repoRoot, customPath);\n } catch {\n hooksDir = join(repoRoot, '.git', 'hooks');\n }\n\n const DEVDAILY_MARKER = '# DevDaily auto-snapshot';\n\n for (const hookName of ['post-commit', 'post-checkout']) {\n const hookPath = join(hooksDir, hookName);\n\n if (!existsSync(hookPath)) {\n continue;\n }\n\n const content = readFileSync(hookPath, 'utf-8');\n if (!content.includes(DEVDAILY_MARKER)) {\n continue;\n }\n\n // Check if the entire file is our hook (starts with our marker after shebang)\n const lines = content.split('\\n');\n const isOurHook =\n lines[0].startsWith('#!/') && lines.some((l) => l.includes('Installed by: devdaily init'));\n\n if (isOurHook) {\n // Entire hook is ours — remove the file\n unlinkSync(hookPath);\n removed.push(hookName);\n } else {\n // Mixed hook — remove only our appended section\n const markerIndex = content.indexOf(`\\n\\n${DEVDAILY_MARKER}`);\n if (markerIndex !== -1) {\n // Find the end of our section (next double newline or end of file)\n const afterMarker = content.substring(markerIndex + 2);\n const fiEnd = afterMarker.indexOf('\\nfi\\n');\n const endIndex = fiEnd !== -1 ? markerIndex + 2 + fiEnd + 4 : content.length;\n\n const cleaned = content.substring(0, markerIndex) + content.substring(endIndex);\n writeFileSync(hookPath, cleaned);\n removed.push(`${hookName} (removed appended section)`);\n }\n }\n }\n\n return { removed, warnings };\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport { GitAnalyzer } from '../core/git-analyzer.js';\nimport { CopilotClient } from '../core/copilot.js';\nimport {\n getProjectManagementClient,\n extractTicketIds,\n extractTicketFromBranch,\n type Ticket,\n} from '../core/project-management.js';\nimport { loadPRTemplate, fillTemplate, type PRTemplate } from '../core/pr-template.js';\nimport { loadPRPrompt, type PRPromptConfig } from '../core/pr-prompt.js';\nimport {\n getRepoMetadata,\n getRepoInfo,\n createPR,\n getPRPreviewUrl,\n type GitHubLabel,\n type GitHubUser,\n} from '../core/github-repo.js';\nimport UI from '../ui/renderer.js';\nimport { ASCII } from '../ui/ascii.js';\nimport { copyToClipboard } from '../utils/helpers.js';\nimport { generatePRTitle, categorizePRType } from '../utils/commitlint.js';\nimport { getConfig } from '../config/index.js';\nimport { sideEffectSnapshot } from '../core/auto-snapshot.js';\n\nconst { colors } = UI;\n\n/**\n * Render a PR preview in the terminal\n */\nfunction renderPRPreview(\n title: string,\n body: string,\n metadata: {\n branch: string;\n base: string;\n labels?: string[];\n assignees?: string[];\n reviewers?: string[];\n isDraft?: boolean;\n }\n): void {\n console.log('');\n\n // Header\n console.log(\n colors.muted('┌─────────────────────────────────────────────────────────────────────┐')\n );\n console.log(\n colors.muted('│') + ' ' + colors.bold('PR Preview') + ' '.repeat(58) + colors.muted('│')\n );\n console.log(\n colors.muted('├─────────────────────────────────────────────────────────────────────┤')\n );\n\n // Title\n console.log(colors.muted('│'));\n console.log(colors.muted('│ ') + colors.accent('⬤') + ' ' + colors.bold(title));\n console.log(colors.muted('│'));\n\n // Branch info\n console.log(\n colors.muted('│ ') +\n colors.primary(metadata.branch) +\n colors.muted(' → ') +\n colors.accent(metadata.base)\n );\n\n // Metadata badges\n if (metadata.isDraft) {\n console.log(colors.muted('│ ') + colors.warning('◉ Draft'));\n }\n\n if (metadata.labels && metadata.labels.length > 0) {\n console.log(\n colors.muted('│ ') + '🏷️ ' + metadata.labels.map((l) => colors.accent(l)).join(' ')\n );\n }\n\n if (metadata.assignees && metadata.assignees.length > 0) {\n console.log(colors.muted('│ ') + '👤 Assignees: ' + metadata.assignees.join(', '));\n }\n\n if (metadata.reviewers && metadata.reviewers.length > 0) {\n console.log(colors.muted('│ ') + '👁️ Reviewers: ' + metadata.reviewers.join(', '));\n }\n\n console.log(colors.muted('│'));\n console.log(\n colors.muted('├─────────────────────────────────────────────────────────────────────┤')\n );\n\n // Body preview\n const lines = body.split('\\n').slice(0, 25); // First 25 lines\n for (const line of lines) {\n // Render markdown-like formatting\n if (line.startsWith('## ')) {\n console.log(colors.muted('│ ') + colors.bold(colors.primary(line.replace('## ', '▸ '))));\n } else if (line.startsWith('- [ ]')) {\n console.log(colors.muted('│ ') + ' ☐ ' + line.replace('- [ ] ', ''));\n } else if (line.startsWith('- [x]')) {\n console.log(\n colors.muted('│ ') + ' ' + colors.success('☑') + ' ' + line.replace('- [x] ', '')\n );\n } else if (line.startsWith('- ')) {\n console.log(colors.muted('│ ') + ' • ' + line.replace('- ', ''));\n } else if (line.match(/^\\d+\\./)) {\n console.log(colors.muted('│ ') + ' ' + line);\n } else {\n console.log(colors.muted('│ ') + line);\n }\n }\n\n if (body.split('\\n').length > 25) {\n console.log(\n colors.muted('│ ') + colors.muted(`... ${body.split('\\n').length - 25} more lines`)\n );\n }\n\n console.log(colors.muted('│'));\n console.log(\n colors.muted('└─────────────────────────────────────────────────────────────────────┘')\n );\n console.log('');\n}\n\n/**\n * Interactive label selection\n */\nasync function selectLabels(availableLabels: GitHubLabel[]): Promise<string[]> {\n if (availableLabels.length === 0) {\n return [];\n }\n\n const { selectedLabels } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'selectedLabels',\n message: 'Select labels:',\n choices: availableLabels.map((label) => ({\n name: `${label.name}${label.description ? ` - ${colors.muted(label.description)}` : ''}`,\n value: label.name,\n })),\n pageSize: 10,\n },\n ]);\n\n return selectedLabels;\n}\n\n/**\n * Interactive reviewer/assignee selection\n */\nasync function selectUsers(\n availableUsers: GitHubUser[],\n type: 'reviewers' | 'assignees'\n): Promise<string[]> {\n if (availableUsers.length === 0) {\n return [];\n }\n\n const { selectedUsers } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'selectedUsers',\n message: `Select ${type}:`,\n choices: availableUsers.map((user) => ({\n name: `@${user.login}${user.name ? ` (${user.name})` : ''}`,\n value: user.login,\n })),\n pageSize: 10,\n },\n ]);\n\n return selectedUsers;\n}\n\nexport const prCommand = new Command('pr')\n .description('Generate PR description from current branch')\n .option('-b, --base <branch>', 'Base branch to compare against')\n .option('-c, --create', 'Create PR on GitHub')\n .option('-d, --draft', 'Create as draft PR')\n .option('-p, --preview', 'Show preview before creating')\n .option('-t, --ticket <id>', 'Include specific ticket/issue for context')\n .option('--no-tickets', 'Skip fetching ticket/issue context')\n .option('--no-copy', 'Do not copy to clipboard')\n .option('--no-template', 'Ignore PR template, use default format')\n .option('--no-diff', 'Skip including diff context in AI prompt')\n .option('--no-prompt-file', 'Ignore custom PR prompt file')\n .option('-i, --interactive', 'Interactive mode for labels, reviewers, assignees')\n .option('--no-journal', 'Skip auto-saving a snapshot to the journal')\n .option('--debug', 'Show debug information (prompts, raw AI input)')\n .action(async (options) => {\n const config = getConfig();\n const git = new GitAnalyzer();\n const copilot = new CopilotClient({ debug: options.debug });\n const pmClient = getProjectManagementClient();\n\n // Check if in git repo\n if (!(await git.isRepository())) {\n console.log(UI.error('Not a git repository'));\n process.exit(1);\n }\n\n // Check if Copilot CLI is installed\n if (!(await copilot.isInstalled())) {\n console.log(UI.error('GitHub Copilot CLI not found'));\n console.log(UI.info('Install with: brew install copilot-cli'));\n process.exit(1);\n }\n\n // Resolve the base branch: CLI flag → config → auto-detect → fallback\n let base: string;\n if (options.base) {\n base = options.base;\n } else if (config.pr.defaultBase && config.pr.defaultBase !== 'main') {\n // User has explicitly configured a non-default base\n base = config.pr.defaultBase;\n } else {\n // Auto-detect from the repo\n try {\n base = await git.getDefaultBranch();\n } catch {\n base = config.pr.defaultBase || 'main';\n }\n }\n\n const spinner = UI.spinner('Analyzing branch...');\n spinner.start();\n\n try {\n // Get repo root\n const repoRoot = await git.getRepoRoot();\n\n // Get current branch\n const currentBranch = await git.getCurrentBranch();\n\n if (currentBranch === base) {\n spinner.stop();\n console.log('');\n console.log(UI.error(`Cannot create PR from ${base} branch`));\n console.log(UI.info('Switch to a feature branch first'));\n process.exit(1);\n }\n\n // Get commits on this branch\n const commits = await git.getCommits();\n\n if (commits.length === 0) {\n spinner.stop();\n console.log('');\n console.log(UI.warning('No commits on this branch'));\n process.exit(0);\n }\n\n // Get changed files\n const files = await git.getChangedFiles(base);\n\n // Extract ticket IDs from various sources\n const commitMessages = commits.map((c) => c.message);\n const ticketIds = new Set<string>();\n\n // From user-provided ticket\n if (options.ticket) {\n ticketIds.add(options.ticket);\n }\n\n // From branch name\n const branchTicket = extractTicketFromBranch(currentBranch);\n if (branchTicket) {\n ticketIds.add(branchTicket);\n }\n\n // From commit messages\n const commitTickets = extractTicketIds(commitMessages.join(' '));\n commitTickets.forEach((id) => ticketIds.add(id));\n\n // Fetch ticket details\n let tickets: Ticket[] = [];\n if (options.tickets !== false && ticketIds.size > 0) {\n spinner.text = `Fetching ${config.projectManagement.tool} ticket context...`;\n if (await pmClient.isConfigured()) {\n tickets = await pmClient.getTickets(Array.from(ticketIds));\n }\n }\n\n // Check for PR template\n spinner.text = 'Looking for PR template...';\n let template: PRTemplate | null = null;\n let usingTemplate = false;\n\n if (options.template !== false) {\n template = await loadPRTemplate(repoRoot);\n if (template) {\n usingTemplate = true;\n spinner.text = `Found template: ${template.path}`;\n }\n }\n\n // Load custom PR prompt file (team guidelines)\n spinner.text = 'Checking for PR description guidelines...';\n let promptConfig: PRPromptConfig | null = null;\n\n if (options.promptFile !== false) {\n promptConfig = await loadPRPrompt(repoRoot);\n if (promptConfig) {\n spinner.text = `Found PR prompt: ${promptConfig.path}`;\n }\n }\n\n // Get diff context for richer AI descriptions\n spinner.text = 'Gathering diff context...';\n let diffStat = '';\n let diffContent = '';\n\n const shouldIncludeDiff = options.diff !== false && config.pr.includeDiff !== false;\n if (shouldIncludeDiff) {\n try {\n const diffData = await git.getDiffForAI(base, 'HEAD', config.pr.maxDiffLines || 200);\n diffStat = diffData.stat;\n diffContent = diffData.diff;\n if (diffData.truncated) {\n spinner.text = 'Diff truncated to fit AI context window...';\n }\n } catch {\n // Diff failed — continue without it (filenames still available)\n }\n }\n\n // Generate PR content\n spinner.text = 'Generating PR description with Copilot CLI...';\n\n let prTitle: string;\n let prBody: string;\n let prType: string;\n\n if (usingTemplate && template) {\n // Generate structured content for template\n const content = await copilot.generatePRContent({\n branch: currentBranch,\n commits: commitMessages,\n files,\n issues: Array.from(ticketIds),\n ticketDetails: tickets,\n templateSections: template.sections.map((s) => s.name),\n diffStat,\n diff: diffContent,\n templateContent: template.raw,\n promptConfig,\n });\n\n prTitle = content.title;\n prType = content.type;\n\n // Build ticket links\n const ticketLinks = tickets.map((t) => ({ id: t.id, url: t.url }));\n\n // Fill the template\n prBody = fillTemplate(template, {\n title: content.title,\n description: content.description,\n type: content.type,\n impact: content.impact,\n testing: content.testing,\n ticketIds: Array.from(ticketIds),\n ticketLinks,\n breakingChanges: content.breakingChanges,\n additionalInfo: content.additionalInfo,\n });\n } else {\n // Use default format\n prTitle = generatePRTitle(commitMessages);\n prType = categorizePRType(commitMessages);\n prBody = await copilot.generatePRDescription({\n branch: currentBranch,\n commits: commitMessages,\n files,\n issues: Array.from(ticketIds),\n ticketDetails: tickets,\n diffStat,\n diff: diffContent,\n templateContent: template?.raw,\n promptConfig,\n });\n }\n\n spinner.stop();\n\n // Fetch repo metadata for interactive mode\n let repoMeta: Awaited<ReturnType<typeof getRepoMetadata>> = null;\n let selectedLabels: string[] = [];\n let selectedReviewers: string[] = [];\n let selectedAssignees: string[] = [];\n\n if (options.interactive) {\n const metaSpinner = UI.spinner('Fetching repository metadata...');\n metaSpinner.start();\n repoMeta = await getRepoMetadata();\n metaSpinner.stop();\n }\n\n // Show info about what was used\n console.log('');\n console.log(UI.info(`Base branch: ${colors.accent(base)}`));\n if (usingTemplate && template) {\n console.log(UI.info(`PR template: ${colors.accent(template.path)}`));\n } else {\n console.log(UI.info('Using default PR format (no template found)'));\n }\n if (promptConfig) {\n console.log(UI.info(`PR guidelines: ${colors.accent(promptConfig.path)}`));\n }\n if (shouldIncludeDiff && diffStat) {\n console.log(\n UI.info(\n `Diff context: ${colors.accent('included')} (${diffContent.split('\\n').length} lines)`\n )\n );\n }\n\n // Interactive selection\n if (options.interactive && repoMeta) {\n console.log('');\n console.log(UI.section('Configure PR', '⚙️'));\n console.log('');\n\n // Select labels\n if (repoMeta.labels.length > 0) {\n selectedLabels = await selectLabels(repoMeta.labels);\n }\n\n // Select reviewers\n if (repoMeta.collaborators.length > 0) {\n selectedReviewers = await selectUsers(repoMeta.collaborators, 'reviewers');\n }\n\n // Select assignees\n if (repoMeta.collaborators.length > 0) {\n selectedAssignees = await selectUsers(repoMeta.collaborators, 'assignees');\n }\n }\n\n // Show preview\n const isDraft = options.draft;\n\n if (options.preview || options.interactive) {\n renderPRPreview(prTitle, prBody, {\n branch: currentBranch,\n base,\n labels: selectedLabels,\n assignees: selectedAssignees,\n reviewers: selectedReviewers,\n isDraft,\n });\n } else {\n // Simple display\n console.log('');\n console.log(\n UI.box(`${colors.bold(prTitle)}\\n\\n${prBody}`, `${ASCII.icons.pr} PR: ${currentBranch}`)\n );\n }\n\n // Stats\n if (config.output.showStats) {\n const statItems: { label: string; value: string | number }[] = [\n { label: 'commits', value: commits.length },\n { label: 'files changed', value: files.length },\n { label: 'type', value: prType },\n ];\n if (tickets.length > 0) {\n statItems.push({ label: 'tickets linked', value: tickets.length });\n }\n if (usingTemplate) {\n statItems.push({ label: 'template', value: '✓' });\n }\n console.log(UI.stats(statItems));\n }\n console.log('');\n\n // Action menu\n const choices = [\n { name: `${ASCII.status.bullet} Copy to clipboard`, value: 'copy' },\n { name: `${ASCII.status.arrowRight} Create PR on GitHub`, value: 'create' },\n { name: `${ASCII.status.bullet} Create draft PR`, value: 'draft' },\n ];\n\n // Add preview in browser option\n const repoInfo = await getRepoInfo();\n if (repoInfo) {\n choices.push({\n name: `${ASCII.status.bullet} Preview in browser`,\n value: 'browser',\n });\n }\n\n if (!options.interactive && repoMeta === null) {\n choices.push({\n name: `${ASCII.status.bullet} Configure labels & reviewers`,\n value: 'configure',\n });\n }\n\n choices.push(\n // @ts-expect-error - inquirer separator type\n new inquirer.Separator(),\n { name: `${ASCII.status.cross} Exit`, value: 'exit' }\n );\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: colors.primary('What would you like to do?'),\n choices,\n },\n ]);\n\n if (action === 'copy') {\n await copyToClipboard(`${prTitle}\\n\\n${prBody}`);\n console.log(UI.success('Copied to clipboard!'));\n } else if (action === 'browser' && repoInfo) {\n const previewUrl = getPRPreviewUrl(repoInfo.owner, repoInfo.name, base, currentBranch);\n const { execa } = await import('execa');\n await execa('open', [previewUrl]);\n console.log(UI.success('Opened in browser!'));\n } else if (action === 'configure') {\n // Fetch metadata and let user configure\n const metaSpinner = UI.spinner('Fetching repository metadata...');\n metaSpinner.start();\n repoMeta = await getRepoMetadata();\n metaSpinner.stop();\n\n if (repoMeta) {\n console.log('');\n if (repoMeta.labels.length > 0) {\n selectedLabels = await selectLabels(repoMeta.labels);\n }\n if (repoMeta.collaborators.length > 0) {\n selectedReviewers = await selectUsers(repoMeta.collaborators, 'reviewers');\n }\n if (repoMeta.collaborators.length > 0) {\n selectedAssignees = await selectUsers(repoMeta.collaborators, 'assignees');\n }\n\n // Show updated preview\n renderPRPreview(prTitle, prBody, {\n branch: currentBranch,\n base,\n labels: selectedLabels,\n assignees: selectedAssignees,\n reviewers: selectedReviewers,\n isDraft,\n });\n\n // Ask to create\n const { confirmCreate } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirmCreate',\n message: 'Create this PR?',\n default: true,\n },\n ]);\n\n if (confirmCreate) {\n await doCreatePR(\n prTitle,\n prBody,\n base,\n selectedLabels,\n selectedAssignees,\n selectedReviewers,\n false\n );\n }\n }\n } else if (action === 'create' || action === 'draft') {\n const createDraft = action === 'draft' || options.draft;\n await doCreatePR(\n prTitle,\n prBody,\n base,\n selectedLabels,\n selectedAssignees,\n selectedReviewers,\n createDraft\n );\n }\n // ── Auto-snapshot side-effect ──────────────────────────────────────\n if (options.journal !== false) {\n const isDebug = options.debug || process.env.DEVD_DEBUG === '1';\n await sideEffectSnapshot({\n source: 'pr',\n note: `PR generated for branch ${currentBranch} → ${base}`,\n tags: prTitle ? [`pr:${prTitle.slice(0, 50)}`] : [],\n debug: isDebug,\n });\n }\n } catch (error) {\n spinner.stop();\n console.log('');\n console.log(UI.error('Failed to generate PR description'));\n console.log(colors.muted((error as Error).message));\n process.exit(1);\n }\n });\n\n/**\n * Create the PR on GitHub\n */\nasync function doCreatePR(\n title: string,\n body: string,\n base: string,\n labels: string[],\n assignees: string[],\n reviewers: string[],\n isDraft: boolean\n): Promise<void> {\n const createSpinner = UI.spinner(`Creating ${isDraft ? 'draft ' : ''}PR...`);\n createSpinner.start();\n\n try {\n const result = await createPR({\n title,\n body,\n base,\n draft: isDraft,\n labels: labels.length > 0 ? labels : undefined,\n assignees: assignees.length > 0 ? assignees : undefined,\n reviewers: reviewers.length > 0 ? reviewers : undefined,\n });\n\n createSpinner.stop();\n console.log('');\n console.log(UI.success('PR created successfully'));\n console.log(colors.accent(result.url));\n } catch (error) {\n createSpinner.stop();\n console.log('');\n console.log(UI.error('Failed to create PR'));\n console.log(colors.muted((error as Error).message));\n }\n}\n","/**\n * PR Template Detection and Parsing\n * Finds and parses GitHub PR templates to provide structured PR descriptions\n */\n\nimport { readFile, access } from 'fs/promises';\nimport { join } from 'path';\n\nexport interface PRTemplateSection {\n name: string;\n header: string;\n content: string;\n type: 'heading' | 'checklist' | 'list' | 'text';\n required: boolean;\n}\n\nexport interface PRTemplate {\n path: string;\n raw: string;\n title?: string;\n sections: PRTemplateSection[];\n}\n\n/**\n * Common PR template locations (in order of precedence)\n */\nconst TEMPLATE_PATHS = [\n '.github/PULL_REQUEST_TEMPLATE.md',\n '.github/pull_request_template.md',\n '.github/PULL_REQUEST_TEMPLATE/default.md',\n 'docs/PULL_REQUEST_TEMPLATE.md',\n 'PULL_REQUEST_TEMPLATE.md',\n 'pull_request_template.md',\n];\n\n/**\n * Check if a file exists\n */\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Find PR template in the repository\n */\nexport async function findPRTemplate(repoRoot: string): Promise<string | null> {\n for (const templatePath of TEMPLATE_PATHS) {\n const fullPath = join(repoRoot, templatePath);\n if (await fileExists(fullPath)) {\n return fullPath;\n }\n }\n return null;\n}\n\n/**\n * Parse a PR template into sections\n */\nexport function parsePRTemplate(content: string): PRTemplate {\n const sections: PRTemplateSection[] = [];\n const lines = content.split('\\n');\n\n let currentSection: PRTemplateSection | null = null;\n let titleLine: string | undefined;\n\n // Check for title in first line\n if (lines[0]?.startsWith('# ')) {\n titleLine = lines[0].replace(/^#\\s*/, '').trim();\n }\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Detect heading (## Section Name)\n const headingMatch = line.match(/^##\\s+(.+)$/);\n if (headingMatch) {\n // Save previous section\n if (currentSection) {\n currentSection.content = currentSection.content.trim();\n sections.push(currentSection);\n }\n\n // Start new section\n const sectionName = headingMatch[1].trim();\n currentSection = {\n name: normalizeSectionName(sectionName),\n header: sectionName,\n content: '',\n type: 'text',\n required: false,\n };\n continue;\n }\n\n // Detect section type and accumulate content\n if (currentSection) {\n // Check for checklist items\n if (line.match(/^-\\s*\\[[ x]\\]/i)) {\n currentSection.type = 'checklist';\n }\n // Check for bullet list\n else if (line.match(/^-\\s+[^[]/) && currentSection.type !== 'checklist') {\n currentSection.type = 'list';\n }\n\n currentSection.content += line + '\\n';\n }\n }\n\n // Don't forget the last section\n if (currentSection) {\n currentSection.content = currentSection.content.trim();\n sections.push(currentSection);\n }\n\n return {\n path: '',\n raw: content,\n title: titleLine,\n sections,\n };\n}\n\n/**\n * Normalize section names for matching\n */\nfunction normalizeSectionName(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, '')\n .replace(/\\s+/g, '_')\n .trim();\n}\n\n/**\n * Load and parse a PR template\n */\nexport async function loadPRTemplate(repoRoot: string): Promise<PRTemplate | null> {\n const templatePath = await findPRTemplate(repoRoot);\n\n if (!templatePath) {\n return null;\n }\n\n try {\n const content = await readFile(templatePath, 'utf-8');\n const template = parsePRTemplate(content);\n template.path = templatePath;\n return template;\n } catch {\n return null;\n }\n}\n\n/**\n * Section mappings for AI to fill\n */\nexport interface PRSectionMappings {\n description?: string;\n type_of_change?: string;\n impact?: string;\n testing?: string;\n additional?: string;\n jira_ticket?: string;\n breaking_changes?: string;\n screenshots?: string;\n checklist?: string[];\n}\n\n/**\n * Fill a template with AI-generated content\n */\nexport function fillTemplate(\n template: PRTemplate,\n content: {\n title: string;\n description: string;\n type: string;\n impact: string;\n testing: string;\n ticketIds: string[];\n ticketLinks: { id: string; url: string }[];\n breakingChanges?: string;\n additionalInfo?: string;\n }\n): string {\n let result = '';\n\n // Add title if template has one\n if (template.title) {\n result += `# ${content.title}\\n\\n`;\n }\n\n for (const section of template.sections) {\n result += `## ${section.header}\\n\\n`;\n\n const sectionKey = section.name.toLowerCase();\n\n // Match section to content\n if (sectionKey.includes('description') || sectionKey.includes('what')) {\n result += content.description + '\\n\\n';\n } else if (sectionKey.includes('type') || sectionKey.includes('change')) {\n result += formatTypeOfChange(content.type, section.content) + '\\n\\n';\n } else if (\n sectionKey.includes('jira') ||\n sectionKey.includes('ticket') ||\n sectionKey.includes('issue')\n ) {\n result += formatTicketSection(content.ticketIds, content.ticketLinks) + '\\n\\n';\n } else if (sectionKey.includes('impact')) {\n result += content.impact + '\\n\\n';\n } else if (sectionKey.includes('test') || sectionKey.includes('how_to')) {\n result += content.testing + '\\n\\n';\n } else if (sectionKey.includes('breaking')) {\n result += (content.breakingChanges || 'No breaking changes.') + '\\n\\n';\n } else if (sectionKey.includes('additional') || sectionKey.includes('notes')) {\n result += (content.additionalInfo || 'No additional information.') + '\\n\\n';\n } else if (sectionKey.includes('screenshot')) {\n result += '_Screenshots will be added if applicable._\\n\\n';\n } else if (section.type === 'checklist') {\n // Keep checklist as-is\n result += section.content + '\\n\\n';\n } else {\n // For unknown sections, keep original content or add placeholder\n result += section.content || '_To be filled._\\n\\n';\n }\n }\n\n return result.trim();\n}\n\n/**\n * Format type of change section with checkmarks\n */\nfunction formatTypeOfChange(type: string, originalContent: string): string {\n const typeMap: Record<string, string[]> = {\n feat: ['feature', 'new feature', '🚀'],\n fix: ['bug', 'bug fix', '🪲'],\n docs: ['documentation', 'doc', '📈'],\n refactor: ['refactor', '🛠️'],\n hotfix: ['hotfix', '🐦‍🔥'],\n security: ['security', '🔐'],\n style: ['ui', 'ux', '✨', 'style'],\n chore: ['chore', 'maintenance'],\n test: ['test', 'testing'],\n };\n\n // Find matching keywords for the type\n const keywords = typeMap[type.toLowerCase()] || [];\n\n // Parse original checklist and mark the appropriate one\n const lines = originalContent.split('\\n');\n const result = lines.map((line) => {\n const isChecklist = line.match(/^-\\s*\\[[ x]\\]/i);\n if (!isChecklist) return line;\n\n const lineContent = line.toLowerCase();\n const shouldCheck = keywords.some((kw) => lineContent.includes(kw.toLowerCase()));\n\n if (shouldCheck) {\n return line.replace(/\\[[ ]\\]/, '[x]');\n }\n return line.replace(/\\[x\\]/i, '[ ]');\n });\n\n return result.join('\\n');\n}\n\n/**\n * Format ticket section\n */\nfunction formatTicketSection(\n ticketIds: string[],\n ticketLinks: { id: string; url: string }[]\n): string {\n if (ticketIds.length === 0) {\n return '**Ticket No:** N/A\\n\\n**Ticket link:** N/A';\n }\n\n const lines: string[] = [];\n\n for (const id of ticketIds) {\n const link = ticketLinks.find((t) => t.id === id);\n if (link) {\n lines.push(`**Ticket No:** ${id}`);\n lines.push(`**Ticket link:** ${link.url}`);\n } else {\n lines.push(`**Ticket No:** ${id}`);\n }\n }\n\n return lines.join('\\n\\n');\n}\n\n/**\n * Get default PR template (used when no template exists)\n */\nexport function getDefaultTemplate(): string {\n return `## What Changed\n\n[Description of changes]\n\n## Why\n\n[Business or technical reason for these changes]\n\n## How to Test\n\n1. [Testing step 1]\n2. [Testing step 2]\n\n## Checklist\n\n- [ ] My code follows the project's style guidelines\n- [ ] I have performed a self-review of my code\n- [ ] I have added tests that prove my fix/feature works\n- [ ] New and existing tests pass locally\n`;\n}\n","/**\n * GitHub Repository Helpers\n * Functions for interacting with GitHub API via gh CLI\n */\n\nimport { execa } from 'execa';\n\nexport interface GitHubLabel {\n name: string;\n color: string;\n description?: string;\n}\n\nexport interface GitHubUser {\n login: string;\n name?: string;\n}\n\nexport interface GitHubTeam {\n slug: string;\n name: string;\n}\n\nexport interface RepoMetadata {\n owner: string;\n name: string;\n defaultBranch: string;\n labels: GitHubLabel[];\n collaborators: GitHubUser[];\n teams: GitHubTeam[];\n}\n\n/**\n * Get the current repository's owner and name\n */\nexport async function getRepoInfo(): Promise<{ owner: string; name: string } | null> {\n try {\n const { stdout } = await execa('gh', ['repo', 'view', '--json', 'owner,name']);\n const data = JSON.parse(stdout);\n return {\n owner: data.owner?.login || data.owner,\n name: data.name,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Get repository labels\n */\nexport async function getRepoLabels(): Promise<GitHubLabel[]> {\n try {\n const { stdout } = await execa('gh', ['label', 'list', '--json', 'name,color,description']);\n return JSON.parse(stdout);\n } catch {\n return [];\n }\n}\n\n/**\n * Get repository collaborators (people who can be assigned)\n */\nexport async function getRepoCollaborators(): Promise<GitHubUser[]> {\n try {\n const { stdout } = await execa('gh', [\n 'api',\n 'repos/{owner}/{repo}/collaborators',\n '--jq',\n '.[].login',\n ]);\n const logins = stdout.trim().split('\\n').filter(Boolean);\n return logins.map((login) => ({ login }));\n } catch {\n return [];\n }\n}\n\n/**\n * Get assignable users for the repository\n */\nexport async function getAssignableUsers(): Promise<GitHubUser[]> {\n try {\n const { stdout } = await execa('gh', [\n 'api',\n 'repos/{owner}/{repo}/assignees',\n '--jq',\n '.[].login',\n ]);\n const logins = stdout.trim().split('\\n').filter(Boolean);\n return logins.map((login) => ({ login }));\n } catch {\n return [];\n }\n}\n\n/**\n * Get the current user's login\n */\nexport async function getCurrentUser(): Promise<string | null> {\n try {\n const { stdout } = await execa('gh', ['api', 'user', '--jq', '.login']);\n return stdout.trim();\n } catch {\n return null;\n }\n}\n\n/**\n * Get team members who can review PRs\n */\nexport async function getTeamReviewers(): Promise<GitHubTeam[]> {\n try {\n const { stdout } = await execa('gh', [\n 'api',\n 'repos/{owner}/{repo}/teams',\n '--jq',\n '.[] | {slug: .slug, name: .name}',\n ]);\n // Parse JSON lines\n const lines = stdout.trim().split('\\n').filter(Boolean);\n return lines.map((line) => JSON.parse(line));\n } catch {\n return [];\n }\n}\n\n/**\n * Fetch all repository metadata in parallel\n */\nexport async function getRepoMetadata(): Promise<RepoMetadata | null> {\n const repoInfo = await getRepoInfo();\n if (!repoInfo) return null;\n\n const [labels, collaborators, teams] = await Promise.all([\n getRepoLabels(),\n getAssignableUsers(),\n getTeamReviewers(),\n ]);\n\n // Get default branch\n let defaultBranch = 'main';\n try {\n const { stdout } = await execa('gh', ['repo', 'view', '--json', 'defaultBranchRef']);\n const data = JSON.parse(stdout);\n defaultBranch = data.defaultBranchRef?.name || 'main';\n } catch {\n // Keep default\n }\n\n return {\n owner: repoInfo.owner,\n name: repoInfo.name,\n defaultBranch,\n labels,\n collaborators,\n teams,\n };\n}\n\n/**\n * Create a PR with full options\n */\nexport interface CreatePROptions {\n title: string;\n body: string;\n base: string;\n head?: string;\n draft?: boolean;\n labels?: string[];\n assignees?: string[];\n reviewers?: string[];\n teamReviewers?: string[];\n milestone?: string;\n project?: string;\n}\n\nexport async function createPR(options: CreatePROptions): Promise<{ url: string; number: number }> {\n const args = [\n 'pr',\n 'create',\n '--title',\n options.title,\n '--body',\n options.body,\n '--base',\n options.base,\n ];\n\n if (options.head) {\n args.push('--head', options.head);\n }\n\n if (options.draft) {\n args.push('--draft');\n }\n\n if (options.labels && options.labels.length > 0) {\n args.push('--label', options.labels.join(','));\n }\n\n if (options.assignees && options.assignees.length > 0) {\n args.push('--assignee', options.assignees.join(','));\n }\n\n if (options.reviewers && options.reviewers.length > 0) {\n args.push('--reviewer', options.reviewers.join(','));\n }\n\n // Note: team reviewers need special handling in gh cli\n\n const { stdout } = await execa('gh', args);\n\n // Parse PR URL and number from output\n const urlMatch = stdout.match(/https:\\/\\/github\\.com\\/[^\\s]+\\/pull\\/(\\d+)/);\n\n return {\n url: stdout.trim(),\n number: urlMatch ? parseInt(urlMatch[1], 10) : 0,\n };\n}\n\n/**\n * Get PR preview URL (for opening in browser)\n */\nexport function getPRPreviewUrl(owner: string, repo: string, base: string, head: string): string {\n return `https://github.com/${owner}/${repo}/compare/${base}...${head}?expand=1`;\n}\n","import type { ConventionalCommit } from '../types/index.js';\n\nconst COMMIT_PATTERN =\n // eslint-disable-next-line no-useless-escape\n /^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\\([^\\)]+\\))?(!)?:\\s*(.+)$/;\n\nexport function parseConventionalCommit(message: string): ConventionalCommit | null {\n const match = message.match(COMMIT_PATTERN);\n\n if (!match) {\n return null;\n }\n\n const [, type, scope, breaking, subject] = match;\n\n return {\n type: type as ConventionalCommit['type'],\n scope: scope?.replace(/[()]/g, ''),\n subject: subject.trim(),\n breaking: breaking === '!',\n };\n}\n\nexport function extractIssueNumbers(text: string): string[] {\n const issuePattern = /#(\\d+)/g;\n const matches = text.matchAll(issuePattern);\n return Array.from(matches, (m) => `#${m[1]}`);\n}\n\nexport function generatePRTitle(commits: string[]): string {\n // Try to parse conventional commits\n const parsed = commits\n .map(parseConventionalCommit)\n .filter((c): c is ConventionalCommit => c !== null);\n\n if (parsed.length === 0) {\n // Fallback: use first commit message\n return commits[0] || 'Update';\n }\n\n // Group by type\n const features = parsed.filter((c) => c.type === 'feat');\n const fixes = parsed.filter((c) => c.type === 'fix');\n\n if (features.length > 0) {\n return features[0].subject;\n }\n\n if (fixes.length > 0) {\n return `Fix: ${fixes[0].subject}`;\n }\n\n return parsed[0].subject;\n}\n\nexport function categorizePRType(commits: string[]): string {\n const parsed = commits\n .map(parseConventionalCommit)\n .filter((c): c is ConventionalCommit => c !== null);\n\n const hasFeatures = parsed.some((c) => c.type === 'feat');\n const hasFixes = parsed.some((c) => c.type === 'fix');\n const hasBreaking = parsed.some((c) => c.breaking);\n\n if (hasBreaking) return 'breaking';\n if (hasFeatures) return 'feature';\n if (hasFixes) return 'bugfix';\n return 'chore';\n}\n","import { Command } from 'commander';\nimport { GitAnalyzer } from '../core/git-analyzer.js';\nimport { CopilotClient } from '../core/copilot.js';\nimport { StandupContextBuilder } from '../core/standup-context.js';\nimport { WorkJournal } from '../core/work-journal.js';\nimport UI from '../ui/renderer.js';\nimport { ASCII } from '../ui/ascii.js';\nimport { copyToClipboard, getWeekStart, getWeekEnd, formatDateRange } from '../utils/helpers.js';\nimport { getConfig } from '../config/index.js';\nimport { sideEffectSnapshot } from '../core/auto-snapshot.js';\n\nconst { colors } = UI;\n\nexport const weekCommand = new Command('week')\n .description('Generate weekly work summary from commits, PRs, tickets, and journal history')\n .option('-l, --last', 'Last week instead of current week')\n .option('-s, --start <date>', 'Custom start date (YYYY-MM-DD)')\n .option('--from <date>', 'Start date for custom range (YYYY-MM-DD)')\n .option('--to <date>', 'End date for custom range (YYYY-MM-DD)')\n .option('-w, --weeks-ago <number>', 'Number of weeks ago (e.g., 2 = two weeks back)')\n .option('--all-projects', 'Include all tracked projects from journal (cross-project summary)')\n .option('-p, --project <id>', 'Filter by specific project identifier')\n .option('--no-tickets', 'Skip fetching closed tickets/issues')\n .option('--no-prs', 'Skip fetching PR context')\n .option('--no-journal', 'Skip journal data (use only live git data)')\n .option('--no-auto-snapshot', 'Skip auto-saving a snapshot to the journal')\n .option('--no-copy', 'Do not copy to clipboard')\n .option('--save', 'Save the generated summary to the journal as an AI summary')\n .option('--debug', 'Show the full context and prompt sent to Copilot')\n .option('--raw-context', 'Output only the raw context block (no AI generation)')\n .option('--json', 'Output stats as JSON (no AI generation)')\n .action(async (options) => {\n const config = getConfig();\n const git = new GitAnalyzer();\n const isDebug = options.debug || process.env.DEVD_DEBUG === '1';\n const copilot = new CopilotClient({ debug: isDebug });\n const journal = new WorkJournal();\n\n // Check if in git repo (unless doing cross-project from journal)\n const isRepo = await git.isRepository();\n if (!isRepo && !options.allProjects) {\n console.log(UI.error('Not a git repository'));\n console.log(\n UI.info('Use --all-projects to generate a cross-project summary from your journal')\n );\n process.exit(1);\n }\n\n // Check if Copilot CLI is installed (unless raw-context or json mode)\n if (!options.rawContext && !options.json && !(await copilot.isInstalled())) {\n console.log(UI.error('GitHub Copilot CLI not found'));\n console.log(UI.info('Install with: gh extension install github/gh-copilot'));\n process.exit(1);\n }\n\n const spinner = UI.spinner('Gathering weekly work context...');\n spinner.start();\n\n try {\n // ── Determine date range ─────────────────────────────────────────────\n let start: Date;\n let end: Date;\n\n if (options.from || options.to) {\n // Custom range mode\n const today = new Date();\n start = options.from ? new Date(options.from) : getWeekStart(0);\n end = options.to ? new Date(options.to) : today;\n // Normalize end to end-of-day\n end.setHours(23, 59, 59, 999);\n } else if (options.start) {\n start = new Date(options.start);\n end = new Date(start.getTime() + 7 * 24 * 60 * 60 * 1000);\n } else if (options.weeksAgo) {\n const weeksAgo = parseInt(options.weeksAgo, 10) || 1;\n start = getWeekStart(weeksAgo);\n end = getWeekEnd(weeksAgo);\n } else {\n const weeksAgo = options.last ? 1 : 0;\n start = getWeekStart(weeksAgo);\n end = getWeekEnd(weeksAgo);\n }\n\n const startStr = dateToString(start);\n const endStr = dateToString(end);\n\n // Calculate days for the context builder\n const now = new Date();\n const daysSinceStart = Math.ceil((now.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));\n\n // ── Cross-project mode (journal-based) ───────────────────────────────\n if (options.allProjects) {\n spinner.text = 'Gathering cross-project journal data...';\n\n const crossProjectSummary = journal.getCrossProjectSummary(startStr, endStr);\n const allSnapshots = journal.getSnapshotsForRange(null, startStr, endStr);\n\n spinner.stop();\n\n if (crossProjectSummary.projects.length === 0) {\n console.log('');\n console.log(UI.warning('No journal entries found for this period across any project'));\n console.log(UI.info('Take snapshots with: devdaily snapshot'));\n console.log(UI.info('Or run without --all-projects to use live git data for this repo'));\n process.exit(0);\n }\n\n // ── JSON mode for cross-project ──────────────────────────────────\n if (options.json) {\n console.log(JSON.stringify(crossProjectSummary, null, 2));\n return;\n }\n\n // ── Raw context mode for cross-project ───────────────────────────\n if (options.rawContext) {\n console.log('');\n console.log(WorkJournal.formatSnapshotsForAI(allSnapshots));\n return;\n }\n\n // ── Debug mode ───────────────────────────────────────────────────\n if (isDebug) {\n console.log('');\n console.log(colors.accent('─── Debug: Cross-Project Summary ───'));\n console.log(JSON.stringify(crossProjectSummary, null, 2));\n console.log('');\n console.log(colors.accent('─── Debug: Full Prompt Context Block ───'));\n console.log(colors.muted(WorkJournal.formatSnapshotsForAI(allSnapshots)));\n console.log('');\n }\n\n // ── Generate AI summary for cross-project ────────────────────────\n const genSpinner = UI.spinner(\n 'Generating cross-project weekly summary with Copilot CLI...'\n );\n genSpinner.start();\n\n const contextBlock = WorkJournal.formatSnapshotsForAI(allSnapshots);\n const prompt = buildCrossProjectWeeklyPrompt(\n contextBlock,\n startStr,\n endStr,\n crossProjectSummary\n );\n const summary = await copilot.generateFromPrompt(prompt);\n\n genSpinner.stop();\n\n // ── Output cross-project summary ─────────────────────────────────\n const title = `${ASCII.icons.week} Cross-Project Week in Review (${formatDateRange(start, end)})`;\n\n console.log('');\n console.log(UI.box(summary, title));\n\n // Stats bar\n if (config.output.showStats) {\n const statItems: { label: string; value: string | number; color?: string }[] = [\n { label: 'projects', value: crossProjectSummary.projects.length },\n { label: 'active days', value: crossProjectSummary.totalActiveDays },\n { label: 'total commits', value: crossProjectSummary.totalCommits },\n ];\n\n // Aggregate diff stats\n const totalInsertions = crossProjectSummary.projects.reduce(\n (sum, p) => sum + p.diffStats.insertions,\n 0\n );\n const totalDeletions = crossProjectSummary.projects.reduce(\n (sum, p) => sum + p.diffStats.deletions,\n 0\n );\n if (totalInsertions > 0 || totalDeletions > 0) {\n statItems.push(\n { label: 'lines added', value: `+${totalInsertions}`, color: 'green' },\n { label: 'lines removed', value: `-${totalDeletions}`, color: 'red' }\n );\n }\n\n console.log(UI.stats(statItems));\n }\n\n // Per-project breakdown\n console.log('');\n console.log(UI.section('📂 Per-Project Breakdown'));\n console.log('');\n\n for (const project of crossProjectSummary.projects) {\n const diffInfo =\n project.diffStats.insertions + project.diffStats.deletions > 0\n ? ` ${colors.success(`+${project.diffStats.insertions}`)}/${colors.error(`-${project.diffStats.deletions}`)}`\n : '';\n\n console.log(\n ` ${colors.accent(project.projectId.padEnd(30))} ${project.totalCommits} commit${project.totalCommits !== 1 ? 's' : ''} · ${project.activeDays} day${project.activeDays !== 1 ? 's' : ''}${diffInfo}`\n );\n\n if (project.branches.length > 0) {\n console.log(\n ` ${colors.muted('Branches:')} ${project.branches.slice(0, 5).join(', ')}${project.branches.length > 5 ? ` +${project.branches.length - 5} more` : ''}`\n );\n }\n\n if (project.categories.length > 0) {\n const cats = project.categories\n .slice(0, 3)\n .map((c) => `${c.name}(${c.percentage}%)`)\n .join(', ');\n console.log(` ${colors.muted('Areas:')} ${cats}`);\n }\n\n console.log('');\n }\n\n // Copy to clipboard\n if (options.copy && config.output.copyToClipboard !== false) {\n await copyToClipboard(summary);\n console.log(UI.success('Copied to clipboard'));\n }\n\n // Save to journal\n if (options.save) {\n for (const project of crossProjectSummary.projects) {\n const latestDate = endStr;\n journal.setAISummary(project.projectId, summary, latestDate);\n }\n console.log(UI.success('Summary saved to journal'));\n }\n\n console.log('');\n return;\n }\n\n // ── Single-project mode (live git + optional journal enrichment) ─────\n\n // Phase 1: Build rich context using StandupContextBuilder (live data)\n spinner.text = 'Analyzing git history, PRs, and tickets...';\n\n const contextBuilder = new StandupContextBuilder();\n const ctx = await contextBuilder.build({\n days: daysSinceStart,\n skipTickets: options.tickets === false,\n skipPRs: options.prs === false,\n baseBranch: config.git.defaultBranch,\n debug: isDebug,\n });\n\n // Phase 1b: Enrich with journal data if available\n let journalSnapshots = null;\n let journalContext = '';\n\n if (options.journal !== false) {\n const projectId = options.project || null;\n const snapshots = journal.getSnapshotsForRange(projectId, startStr, endStr);\n\n if (snapshots.length > 0) {\n journalSnapshots = snapshots;\n journalContext = WorkJournal.formatSnapshotsForAI(snapshots);\n\n if (isDebug) {\n console.log('');\n console.log(colors.accent(`─── Debug: Journal Entries (${snapshots.length}) ───`));\n console.log(colors.muted(journalContext.slice(0, 2000)));\n if (journalContext.length > 2000) {\n console.log(colors.muted(`... (${journalContext.length - 2000} more chars)`));\n }\n console.log('');\n }\n }\n }\n\n if (ctx.commits.length === 0 && ctx.pullRequests.length === 0 && !journalSnapshots) {\n spinner.stop();\n console.log('');\n console.log(UI.warning('No commits, PRs, or journal entries found for this week'));\n console.log(\n UI.info(\n 'Try a different date range with --from / --to, or take snapshots with: devdaily snapshot'\n )\n );\n process.exit(0);\n }\n\n spinner.stop();\n\n // ── Debug mode: show full context ──────────────────────────────────\n if (isDebug) {\n console.log('');\n console.log(colors.accent('─── Debug: Assembled Context ───'));\n console.log(StandupContextBuilder.formatDebugSummary(ctx));\n console.log('');\n console.log(colors.accent('─── Debug: Full Prompt Context Block ───'));\n console.log(colors.muted(StandupContextBuilder.formatForPrompt(ctx)));\n console.log('');\n }\n\n // ── JSON mode ──────────────────────────────────────────────────────\n if (options.json) {\n const jsonData = {\n dateRange: { from: startStr, to: endStr },\n commits: ctx.commits.length,\n pullRequests: ctx.pullRequests.length,\n tickets: ctx.tickets.length,\n diffStats: ctx.diffStats,\n categories: ctx.categories,\n topChangedFiles: ctx.topChangedFiles,\n branch: ctx.branch,\n journalEntries: journalSnapshots?.length || 0,\n };\n console.log(JSON.stringify(jsonData, null, 2));\n return;\n }\n\n // ── Raw context mode: just output the context block ────────────────\n if (options.rawContext) {\n console.log('');\n console.log(StandupContextBuilder.formatForPrompt(ctx));\n if (journalContext) {\n console.log('');\n console.log('--- JOURNAL HISTORY ---');\n console.log(journalContext);\n }\n return;\n }\n\n // ── Phase 2: Generate weekly summary with AI ───────────────────────\n const genSpinner = UI.spinner('Generating weekly summary with Copilot CLI...');\n genSpinner.start();\n\n let summary: string;\n\n if (journalContext) {\n // Enhanced prompt with journal context\n const contextBlock = StandupContextBuilder.formatForPrompt(ctx);\n const prompt = buildEnhancedWeeklyPrompt(contextBlock, journalContext, startStr, endStr);\n summary = await copilot.generateFromPrompt(prompt);\n } else {\n summary = await copilot.generateWeeklyFromContext(ctx);\n }\n\n genSpinner.stop();\n\n // ── Phase 3: Output ────────────────────────────────────────────────\n const title = `${ASCII.icons.week} Week in Review (${formatDateRange(start, end)})`;\n\n console.log('');\n console.log(UI.box(summary, title));\n\n // Stats bar\n if (config.output.showStats) {\n const statItems: { label: string; value: string | number; color?: string }[] = [\n { label: 'commits', value: ctx.commits.length },\n ];\n if (ctx.diffStats) {\n statItems.push(\n { label: 'lines added', value: `+${ctx.diffStats.insertions}`, color: 'green' },\n { label: 'lines removed', value: `-${ctx.diffStats.deletions}`, color: 'red' }\n );\n }\n if (ctx.pullRequests.length > 0) {\n statItems.push({ label: 'PRs', value: ctx.pullRequests.length });\n }\n if (ctx.tickets.length > 0) {\n statItems.push({ label: 'tickets', value: ctx.tickets.length });\n }\n if (ctx.categories.length > 0) {\n statItems.push({ label: 'primary area', value: ctx.categories[0].name });\n }\n if (journalSnapshots) {\n statItems.push({ label: 'journal days', value: journalSnapshots.length });\n }\n console.log(UI.stats(statItems));\n }\n console.log('');\n\n // Copy to clipboard\n if (options.copy && config.output.copyToClipboard !== false) {\n await copyToClipboard(summary);\n console.log(UI.success('Copied to clipboard'));\n }\n\n // Save to journal\n if (options.save) {\n try {\n // Detect project ID for saving\n let projectIdForSave = options.project;\n if (!projectIdForSave && journalSnapshots && journalSnapshots.length > 0) {\n projectIdForSave = journalSnapshots[0].projectId;\n }\n if (!projectIdForSave) {\n projectIdForSave = WorkJournal.sanitizeProjectId(\n ctx.repo.name || process.cwd().split('/').pop() || 'unknown'\n );\n }\n\n journal.setAISummary(projectIdForSave, summary, endStr);\n console.log(UI.success('Summary saved to journal'));\n } catch (err) {\n console.log(UI.warning(`Could not save to journal: ${(err as Error).message}`));\n }\n }\n\n // ── Auto-snapshot side-effect ──────────────────────────────────────\n if (options.autoSnapshot !== false) {\n await sideEffectSnapshot({\n source: 'week',\n note: `Weekly summary generated (${startStr} → ${endStr})`,\n debug: isDebug,\n });\n }\n } catch (error) {\n spinner.stop();\n console.log('');\n console.log(UI.error('Failed to generate weekly summary'));\n console.log(colors.muted((error as Error).message));\n\n if (isDebug && error instanceof Error && error.stack) {\n console.log('');\n console.log(colors.muted('Stack trace:'));\n console.log(colors.muted(error.stack));\n }\n\n process.exit(1);\n }\n });\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction dateToString(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n}\n\nfunction buildEnhancedWeeklyPrompt(\n liveContext: string,\n journalContext: string,\n fromDate: string,\n toDate: string\n): string {\n return `You are a developer assistant generating a weekly work summary for the period ${fromDate} to ${toDate}.\n\nYou have TWO sources of data:\n1. LIVE GIT DATA — commits, PRs, tickets from the current repo (most accurate for current state)\n2. JOURNAL HISTORY — saved snapshots from previous days (provides historical context and continuity)\n\nGenerate a clear, well-structured weekly summary with these sections:\n\n## Accomplishments\n- List the key things completed this week\n- Group related commits into logical accomplishments\n- Reference PR numbers and ticket IDs where available\n\n## In Progress\n- Work that's started but not yet complete\n- Open PRs, active branches, pending reviews\n\n## Key Metrics\n- Lines changed, files touched, PRs merged\n- Work area breakdown (frontend, backend, etc.)\n\n## Notable Items\n- Any breaking changes, new features, or significant refactors\n- Cross-cutting concerns or patterns you notice\n\nRules:\n- Be concise but comprehensive\n- Use bullet points\n- Reference specific PR numbers (#N), ticket IDs, and branch names\n- Don't hallucinate — only use information from the provided data\n- If journal data shows work on multiple days, show the progression\n- Highlight continuity: work that spans multiple days or builds on earlier work\n\n---\nLIVE GIT DATA:\n${liveContext}\n\n---\nJOURNAL HISTORY:\n${journalContext}\n\n---\nGenerate the weekly summary now:`;\n}\n\nfunction buildCrossProjectWeeklyPrompt(\n journalContext: string,\n fromDate: string,\n toDate: string,\n crossProjectSummary: {\n projects: {\n projectId: string;\n totalCommits: number;\n activeDays: number;\n branches: string[];\n categories: { name: string; percentage: number }[];\n diffStats: { filesChanged: number; insertions: number; deletions: number };\n }[];\n totalCommits: number;\n totalActiveDays: number;\n }\n): string {\n const projectList = crossProjectSummary.projects\n .map(\n (p) =>\n `- ${p.projectId}: ${p.totalCommits} commits across ${p.activeDays} days, branches: ${p.branches.slice(0, 5).join(', ')}`\n )\n .join('\\n');\n\n return `You are a developer assistant generating a CROSS-PROJECT weekly summary for ${fromDate} to ${toDate}.\n\nThis developer worked on ${crossProjectSummary.projects.length} project(s) this week with ${crossProjectSummary.totalCommits} total commits across ${crossProjectSummary.totalActiveDays} active days.\n\nProjects overview:\n${projectList}\n\nGenerate a summary that:\n\n## Week Overview\n- High-level: what was this week about? What were the main themes across all projects?\n- How was time split between projects?\n\n## Per-Project Highlights\n- For each project, summarize the key accomplishments (2-3 bullets each)\n- Reference specific branches, PRs, and tickets\n\n## Cross-Cutting Themes\n- Any patterns across projects (e.g., \"infrastructure week\", \"bug-fix sprint\")\n- Context switching patterns — how many projects were touched per day?\n\n## This Week in Numbers\n- Commits, PRs, files changed across all projects\n- Most active project and most active day\n\nRules:\n- Be concise — this is a high-level view, not a detailed log\n- Organize by project, then highlight cross-project themes\n- Don't hallucinate — only use information from the data\n- Reference specific branch names and commit messages when they tell a story\n- If a project had no activity, don't mention it\n\n---\nJOURNAL DATA:\n${journalContext}\n\n---\nGenerate the cross-project weekly summary now:`;\n}\n","import { Command } from 'commander';\nimport { SnapshotBuilder } from '../core/snapshot-builder.js';\nimport { WorkJournal } from '../core/work-journal.js';\nimport { GitAnalyzer } from '../core/git-analyzer.js';\nimport { CopilotClient } from '../core/copilot.js';\nimport UI from '../ui/renderer.js';\nimport { copyToClipboard } from '../utils/helpers.js';\nimport { getConfig } from '../config/index.js';\n\nconst { colors } = UI;\n\nexport const contextCommand = new Command('context')\n .description('Recover what you were working on — fight context switching amnesia')\n .option('-d, --days <number>', 'Number of days to look back', '7')\n .option('-p, --project <id>', 'Filter by project identifier')\n .option('--all-projects', 'Show context across all tracked projects')\n .option('--date <date>', 'Show context for a specific date (YYYY-MM-DD)')\n .option('--from <date>', 'Start date for range (YYYY-MM-DD)')\n .option('--to <date>', 'End date for range (YYYY-MM-DD)')\n .option('--ai', 'Generate an AI-powered \"where did I leave off?\" summary')\n .option('--branches', 'Show detailed active branch status')\n .option('--no-copy', 'Do not copy to clipboard')\n .option('--raw', 'Output raw context data (no formatting)')\n .option('--debug', 'Show debug output')\n .action(async (options) => {\n const config = getConfig();\n const git = new GitAnalyzer();\n const isDebug = options.debug || process.env.DEVD_DEBUG === '1';\n const journal = new WorkJournal();\n\n // ── Determine date range ───────────────────────────────────────────────\n let fromDate: string;\n let toDate: string;\n\n if (options.date) {\n fromDate = options.date;\n toDate = options.date;\n } else if (options.from || options.to) {\n const today = journal.todayString();\n fromDate = options.from || today;\n toDate = options.to || today;\n } else {\n const days = parseInt(options.days, 10) || 7;\n const from = new Date();\n from.setDate(from.getDate() - days);\n fromDate = journal.dateToString(from);\n toDate = journal.todayString();\n }\n\n // ── Check if we have journal data ──────────────────────────────────────\n const projectId = options.project || null;\n const snapshots = journal.getSnapshotsForRange(\n options.allProjects ? null : projectId,\n fromDate,\n toDate\n );\n\n // If no journal data, try to take a live snapshot first\n if (snapshots.length === 0 && !options.allProjects) {\n if (await git.isRepository()) {\n console.log('');\n console.log(\n UI.info('No journal entries found. Taking a live snapshot of your current project...')\n );\n console.log('');\n\n const spinner = UI.spinner('Analyzing current project state...');\n spinner.start();\n\n try {\n const builder = new SnapshotBuilder(undefined, isDebug);\n const result = await builder.takeAndSave({ debug: isDebug });\n snapshots.push(result.snapshot);\n spinner.stop();\n console.log(\n UI.success(\n `Snapshot saved for ${result.snapshot.projectId}. Future runs will have history.`\n )\n );\n console.log('');\n } catch (err) {\n spinner.stop();\n console.log(UI.warning(`Could not take snapshot: ${(err as Error).message}`));\n console.log('');\n }\n }\n }\n\n if (snapshots.length === 0) {\n console.log('');\n console.log(UI.warning('No work context found for the specified period.'));\n console.log('');\n console.log(UI.info('To start building your work journal:'));\n console.log(` ${colors.accent('devdaily snapshot')} Take a snapshot now`);\n console.log(` ${colors.accent('devdaily snapshot --list')} View your journal entries`);\n console.log(` ${colors.accent('devdaily context --days=14')} Look further back`);\n console.log('');\n return;\n }\n\n // ── Group snapshots by project ─────────────────────────────────────────\n const byProject = new Map<string, typeof snapshots>();\n for (const s of snapshots) {\n const existing = byProject.get(s.projectId);\n if (existing) {\n existing.push(s);\n } else {\n byProject.set(s.projectId, [s]);\n }\n }\n\n // ── Raw mode ───────────────────────────────────────────────────────────\n if (options.raw) {\n console.log(WorkJournal.formatSnapshotsForAI(snapshots));\n return;\n }\n\n // ── Render context recovery ────────────────────────────────────────────\n console.log('');\n\n const dateRangeLabel = fromDate === toDate ? fromDate : `${fromDate} → ${toDate}`;\n\n console.log(UI.section(`🧠 Context Recovery — ${dateRangeLabel}`));\n console.log('');\n\n for (const [pid, projectSnapshots] of byProject) {\n const sortedSnapshots = projectSnapshots.sort(\n (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()\n );\n\n const latestSnapshot = sortedSnapshots[0];\n const totalCommits = sortedSnapshots.reduce((sum, s) => sum + s.todayCommits.length, 0);\n const activeDays = sortedSnapshots.length;\n\n // ── Project header ───────────────────────────────────────────────\n console.log(` ${colors.accent('━━━')} 📂 ${colors.accent(pid)} ${colors.accent('━━━')}`);\n console.log(` ${colors.muted(latestSnapshot.repoPath)}`);\n console.log(\n ` ${activeDays} active day${activeDays !== 1 ? 's' : ''} · ${totalCommits} commit${totalCommits !== 1 ? 's' : ''}`\n );\n console.log('');\n\n // ── Current state (from most recent snapshot) ────────────────────\n console.log(` ${colors.accent('Current branch:')} ${latestSnapshot.currentBranch}`);\n\n if (latestSnapshot.activeBranches.length > 0) {\n // Find branches with work-in-progress\n const wipBranches = latestSnapshot.activeBranches.filter(\n (b) => b.aheadOfBase > 0 || b.hasUncommittedChanges\n );\n\n if (wipBranches.length > 0 || options.branches) {\n const branchesToShow = options.branches ? latestSnapshot.activeBranches : wipBranches;\n\n console.log('');\n console.log(\n ` ${colors.accent('Active branches')} ${colors.muted(`(${branchesToShow.length}):`)}`\n );\n\n for (const branch of branchesToShow.slice(0, 15)) {\n const isCurrent = branch.name === latestSnapshot.currentBranch;\n const marker = isCurrent ? colors.success(' ← you are here') : '';\n let status = '';\n\n if (branch.aheadOfBase > 0) {\n status += colors.warning(` ↑${branch.aheadOfBase} ahead`);\n }\n if (branch.hasUncommittedChanges) {\n status += colors.error(' ● uncommitted changes');\n }\n\n console.log(\n ` ${isCurrent ? colors.accent('▸') : ' '} ${branch.name}${marker}${status}`\n );\n if (branch.lastCommitMessage) {\n console.log(\n ` ${colors.muted(`Last: ${branch.lastCommitMessage.slice(0, 60)}`)}`\n );\n }\n if (branch.hasUncommittedChanges && branch.uncommittedFiles.length > 0) {\n const fileList = branch.uncommittedFiles.slice(0, 5).join(', ');\n const more =\n branch.uncommittedFiles.length > 5\n ? ` +${branch.uncommittedFiles.length - 5} more`\n : '';\n console.log(` ${colors.muted(`Modified: ${fileList}${more}`)}`);\n }\n }\n\n if (branchesToShow.length > 15) {\n console.log(\n ` ${colors.muted(`... and ${branchesToShow.length - 15} more branches`)}`\n );\n }\n }\n }\n\n // ── Recent activity timeline ─────────────────────────────────────\n console.log('');\n console.log(` ${colors.accent('Activity timeline:')}`);\n\n for (const snapshot of sortedSnapshots.slice(0, 10)) {\n const isToday = snapshot.date === journal.todayString();\n const dateLabel = isToday ? `${snapshot.date} ${colors.success('(today)')}` : snapshot.date;\n\n const commitCount = snapshot.todayCommits.length;\n const prInfo =\n snapshot.pullRequests.length > 0\n ? ` · ${snapshot.pullRequests.length} PR${snapshot.pullRequests.length !== 1 ? 's' : ''}`\n : '';\n\n const diffInfo = snapshot.diffStats\n ? ` · ${colors.success(`+${snapshot.diffStats.insertions}`)}/${colors.error(`-${snapshot.diffStats.deletions}`)}`\n : '';\n\n console.log(\n ` ${colors.accent('│')} ${dateLabel} 🌿 ${snapshot.currentBranch} 📝 ${commitCount}${prInfo}${diffInfo}`\n );\n\n // Show top commits for each day\n for (const commit of snapshot.todayCommits.slice(0, 3)) {\n console.log(\n ` ${colors.accent('│')} ${colors.muted(commit.shortHash)} ${commit.message.slice(0, 55)}`\n );\n }\n if (snapshot.todayCommits.length > 3) {\n console.log(\n ` ${colors.accent('│')} ${colors.muted(`... +${snapshot.todayCommits.length - 3} more commits`)}`\n );\n }\n\n // Show notes if present\n if (snapshot.notes) {\n console.log(\n ` ${colors.accent('│')} ${colors.warning('📌')} ${snapshot.notes.split('\\n')[0].slice(0, 55)}`\n );\n }\n }\n\n if (sortedSnapshots.length > 10) {\n console.log(\n ` ${colors.accent('│')} ${colors.muted(`... ${sortedSnapshots.length - 10} more days`)}`\n );\n }\n console.log(` ${colors.accent('╵')}`);\n\n // ── PRs ──────────────────────────────────────────────────────────\n const allPRs = new Map<number, (typeof latestSnapshot.pullRequests)[0]>();\n for (const s of sortedSnapshots) {\n for (const pr of s.pullRequests) {\n allPRs.set(pr.number, pr);\n }\n }\n\n if (allPRs.size > 0) {\n console.log('');\n console.log(` ${colors.accent('Pull Requests:')}`);\n for (const pr of allPRs.values()) {\n const stateIcon =\n pr.state === 'open'\n ? colors.success('○')\n : pr.state === 'merged'\n ? colors.accent('●')\n : colors.muted('✕');\n console.log(` ${stateIcon} #${pr.number} ${pr.title.slice(0, 55)} (${pr.state})`);\n }\n }\n\n // ── Tickets ──────────────────────────────────────────────────────\n const allTickets = new Map<string, (typeof latestSnapshot.tickets)[0]>();\n for (const s of sortedSnapshots) {\n for (const t of s.tickets) {\n allTickets.set(t.id, t);\n }\n }\n\n if (allTickets.size > 0) {\n console.log('');\n console.log(` ${colors.accent('Tickets:')}`);\n for (const ticket of allTickets.values()) {\n const titlePart = ticket.title ? `: ${ticket.title.slice(0, 50)}` : '';\n console.log(` ${ticket.id}${titlePart} ${colors.muted(`[${ticket.status}]`)}`);\n }\n }\n\n // ── Work areas ───────────────────────────────────────────────────\n const catMap = new Map<string, number[]>();\n for (const s of sortedSnapshots) {\n for (const cat of s.categories) {\n const existing = catMap.get(cat.name);\n if (existing) {\n existing.push(cat.percentage);\n } else {\n catMap.set(cat.name, [cat.percentage]);\n }\n }\n }\n\n if (catMap.size > 0) {\n console.log('');\n console.log(` ${colors.accent('Work areas:')}`);\n const categories = Array.from(catMap.entries())\n .map(([name, percentages]) => ({\n name,\n avgPercentage: Math.round(percentages.reduce((a, b) => a + b, 0) / percentages.length),\n }))\n .sort((a, b) => b.avgPercentage - a.avgPercentage)\n .slice(0, 5);\n\n for (const cat of categories) {\n const barFilled = Math.round(cat.avgPercentage / 5);\n const barEmpty = 20 - barFilled;\n const bar = '█'.repeat(barFilled) + '░'.repeat(barEmpty);\n console.log(` ${cat.name.padEnd(14)} ${bar} ${cat.avgPercentage}%`);\n }\n }\n\n console.log('');\n }\n\n // ── AI-powered summary ─────────────────────────────────────────────────\n if (options.ai) {\n const copilot = new CopilotClient({ debug: isDebug });\n\n if (!(await copilot.isInstalled())) {\n console.log(\n UI.warning(\n 'GitHub Copilot CLI not found — skipping AI summary. Install with: gh extension install github/gh-copilot'\n )\n );\n } else {\n const genSpinner = UI.spinner('Generating \"where did I leave off?\" summary with AI...');\n genSpinner.start();\n\n try {\n const contextBlock = WorkJournal.formatSnapshotsForAI(snapshots);\n\n const prompt = buildContextRecoveryPrompt(contextBlock, fromDate, toDate);\n const summary = await copilot.generateFromPrompt(prompt);\n\n genSpinner.stop();\n\n console.log(UI.box(summary, '🧠 Where You Left Off'));\n console.log('');\n\n // Copy to clipboard\n if (options.copy !== false && config.output.copyToClipboard !== false) {\n await copyToClipboard(summary);\n console.log(UI.success('Copied to clipboard'));\n console.log('');\n }\n } catch (err) {\n genSpinner.stop();\n console.log(UI.warning(`AI summary failed: ${(err as Error).message}`));\n console.log('');\n }\n }\n }\n\n // ── Helpful tips ───────────────────────────────────────────────────────\n if (!options.ai) {\n console.log(\n colors.muted(\n ` Tip: Add ${colors.accent('--ai')} for an AI-powered \"where did I leave off?\" summary`\n )\n );\n console.log(\n colors.muted(` Add ${colors.accent('--branches')} for detailed branch status`)\n );\n console.log('');\n }\n });\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction buildContextRecoveryPrompt(\n contextBlock: string,\n fromDate: string,\n toDate: string\n): string {\n return `You are a developer assistant helping me recover my work context after time away or context switching.\n\nBelow is a journal of my recent development activity from ${fromDate} to ${toDate}, including commits, branches, PRs, tickets, and file changes.\n\nYour job is to give me a concise, actionable \"where I left off\" briefing. Structure it as:\n\n1. **What I was working on** — The main themes/features/tasks (2-3 sentences max)\n2. **Current state** — What's in progress, what's done, what's pending\n3. **Open threads** — Branches with uncommitted work, open PRs needing attention, unfinished tasks\n4. **Suggested next steps** — What I should probably pick up first based on the activity pattern\n\nRules:\n- Be concise and practical — this is for getting back up to speed quickly\n- Reference specific branch names, PR numbers, and ticket IDs when available\n- Don't invent or hallucinate details that aren't in the data\n- If multiple projects are present, organize by project\n- Use bullet points for readability\n\n---\nWORK JOURNAL DATA:\n${contextBlock}\n---\n\nGenerate the context recovery briefing now:`;\n}\n","import { Command } from 'commander';\nimport { SnapshotBuilder } from '../core/snapshot-builder.js';\nimport { WorkJournal } from '../core/work-journal.js';\nimport { GitAnalyzer } from '../core/git-analyzer.js';\nimport UI from '../ui/renderer.js';\n\nconst { colors } = UI;\n\nexport const snapshotCommand = new Command('snapshot')\n .description('Save a snapshot of your current work state to your local journal')\n .option('-d, --date <date>', 'Snapshot date (YYYY-MM-DD, default: today)')\n .option('-p, --project <id>', 'Override project identifier')\n .option('-n, --note <text>', 'Attach a note to this snapshot')\n .option('-t, --tag <tags...>', 'Add custom tags to the snapshot')\n .option('--no-prs', 'Skip fetching PR data')\n .option('--no-tickets', 'Skip fetching ticket data')\n .option('--no-branches', 'Skip listing active branches')\n .option('--light', 'Quick snapshot — commits and branch info only (no PRs/tickets)')\n .option('--debug', 'Show detailed debug output')\n .option('--stats', 'Show journal storage stats instead of taking a snapshot')\n .option('--list [days]', 'List recent snapshots (default: 7 days)')\n .option('--prune <days>', 'Remove journal entries older than N days')\n .action(async (options) => {\n const git = new GitAnalyzer();\n const isDebug = options.debug || process.env.DEVD_DEBUG === '1';\n\n // ── Stats mode ─────────────────────────────────────────────────────────\n if (options.stats) {\n const journal = new WorkJournal();\n const stats = journal.getStats();\n\n console.log('');\n console.log(UI.section('📓 Journal Stats'));\n console.log('');\n console.log(` ${colors.accent('Total snapshots:')} ${stats.totalSnapshots}`);\n console.log(` ${colors.accent('Active dates:')} ${stats.totalDates}`);\n console.log(` ${colors.accent('Projects tracked:')} ${stats.totalProjects}`);\n console.log(\n ` ${colors.accent('Oldest entry:')} ${stats.oldestEntry || colors.muted('none')}`\n );\n console.log(\n ` ${colors.accent('Newest entry:')} ${stats.newestEntry || colors.muted('none')}`\n );\n console.log(` ${colors.accent('Storage used:')} ${formatBytes(stats.storageBytes)}`);\n console.log('');\n\n const projects = journal.getProjects();\n if (projects.length > 0) {\n console.log(UI.section('📂 Tracked Projects'));\n console.log('');\n for (const project of projects) {\n const lastSeen = project.lastSnapshotDate;\n const daysAgo = daysBetween(lastSeen, new Date().toISOString().split('T')[0]);\n const freshness =\n daysAgo === 0\n ? colors.success('today')\n : daysAgo <= 3\n ? colors.warning(`${daysAgo}d ago`)\n : colors.muted(`${daysAgo}d ago`);\n\n console.log(\n ` ${colors.accent(project.projectId.padEnd(30))} ${freshness} (${project.snapshotCount} snapshots)`\n );\n console.log(` ${colors.muted(project.repoPath)}`);\n }\n console.log('');\n }\n\n return;\n }\n\n // ── List mode ──────────────────────────────────────────────────────────\n if (options.list !== undefined) {\n const days = typeof options.list === 'string' ? parseInt(options.list, 10) : 7;\n const journal = new WorkJournal();\n const recent = journal.getRecentActivity(isNaN(days) ? 7 : days);\n\n if (recent.length === 0) {\n console.log('');\n console.log(UI.warning('No journal entries found'));\n console.log(UI.info('Take your first snapshot with: devdaily snapshot'));\n console.log('');\n return;\n }\n\n console.log('');\n console.log(UI.section(`📓 Recent Activity (last ${isNaN(days) ? 7 : days} days)`));\n console.log('');\n\n // Group by date\n const byDate = new Map<string, typeof recent>();\n for (const snapshot of recent) {\n const existing = byDate.get(snapshot.date);\n if (existing) {\n existing.push(snapshot);\n } else {\n byDate.set(snapshot.date, [snapshot]);\n }\n }\n\n for (const [date, snapshots] of byDate) {\n const isToday = date === journal.todayString();\n const dateLabel = isToday ? `${date} ${colors.success('(today)')}` : date;\n console.log(` ${colors.accent('━━━')} ${dateLabel} ${colors.accent('━━━')}`);\n\n for (const snapshot of snapshots) {\n const commitCount = snapshot.todayCommits.length;\n const branch = snapshot.currentBranch;\n const prCount = snapshot.pullRequests.length;\n\n let line = ` ${colors.accent(snapshot.projectId)}`;\n line += ` 🌿 ${branch}`;\n if (commitCount > 0) {\n line += ` 📝 ${commitCount} commit${commitCount !== 1 ? 's' : ''}`;\n }\n if (prCount > 0) {\n line += ` 🔄 ${prCount} PR${prCount !== 1 ? 's' : ''}`;\n }\n if (snapshot.diffStats) {\n line += ` ${colors.success(`+${snapshot.diffStats.insertions}`)}/${colors.error(`-${snapshot.diffStats.deletions}`)}`;\n }\n console.log(line);\n\n // Show top commits\n for (const commit of snapshot.todayCommits.slice(0, 3)) {\n console.log(` ${colors.muted(commit.shortHash)} ${commit.message.slice(0, 60)}`);\n }\n if (snapshot.todayCommits.length > 3) {\n console.log(\n ` ${colors.muted(`... and ${snapshot.todayCommits.length - 3} more`)}`\n );\n }\n\n if (snapshot.notes) {\n console.log(\n ` ${colors.warning('📌')} ${snapshot.notes.split('\\n')[0].slice(0, 60)}`\n );\n }\n\n if (snapshot.tags.length > 0) {\n console.log(\n ` ${colors.muted('tags:')} ${snapshot.tags.slice(0, 8).join(', ')}${snapshot.tags.length > 8 ? '...' : ''}`\n );\n }\n }\n console.log('');\n }\n\n return;\n }\n\n // ── Prune mode ─────────────────────────────────────────────────────────\n if (options.prune) {\n const maxAgeDays = parseInt(options.prune, 10);\n if (isNaN(maxAgeDays) || maxAgeDays < 1) {\n console.log(UI.error('Invalid prune age. Use a positive number of days.'));\n process.exit(1);\n }\n\n const journal = new WorkJournal();\n const { removedDates, removedSnapshots } = journal.prune(maxAgeDays);\n\n if (removedDates.length === 0) {\n console.log(UI.info(`No journal entries older than ${maxAgeDays} days.`));\n } else {\n console.log(\n UI.success(\n `Pruned ${removedSnapshots} snapshot(s) across ${removedDates.length} date(s) older than ${maxAgeDays} days.`\n )\n );\n }\n return;\n }\n\n // ── Take snapshot ──────────────────────────────────────────────────────\n if (!(await git.isRepository())) {\n console.log(UI.error('Not a git repository'));\n console.log(UI.info('Run this command inside a git repository'));\n process.exit(1);\n }\n\n const spinner = UI.spinner('Taking snapshot of your work state...');\n spinner.start();\n\n try {\n const builder = new SnapshotBuilder(undefined, isDebug);\n const isLight = options.light;\n\n const result = isLight\n ? await (async () => {\n const r = await builder.takeLightSnapshot({\n date: options.date,\n projectId: options.project,\n note: options.note,\n tags: options.tag,\n debug: isDebug,\n });\n const journal = new WorkJournal();\n journal.saveSnapshot(r.snapshot);\n return r;\n })()\n : await builder.takeAndSave({\n date: options.date,\n projectId: options.project,\n skipPRs: options.prs === false,\n skipTickets: options.tickets === false,\n includeBranches: options.branches !== false,\n note: options.note,\n tags: options.tag,\n debug: isDebug,\n });\n\n spinner.stop();\n\n const { snapshot, merged, warnings, durationMs } = result;\n\n // ── Output ─────────────────────────────────────────────────────────\n console.log('');\n\n const action = merged ? 'Updated' : 'Saved';\n const title = `📸 ${action} snapshot for ${snapshot.projectId}`;\n\n const summaryLines: string[] = [];\n summaryLines.push(`📅 Date: ${snapshot.date}`);\n summaryLines.push(`🌿 Branch: ${snapshot.currentBranch}`);\n summaryLines.push(`📝 Commits: ${snapshot.todayCommits.length} today`);\n\n if (snapshot.activeBranches.length > 0) {\n summaryLines.push(`🔀 Active branches: ${snapshot.activeBranches.length}`);\n }\n\n if (snapshot.pullRequests.length > 0) {\n summaryLines.push(\n `🔄 PRs: ${snapshot.pullRequests.map((pr) => `#${pr.number} (${pr.state})`).join(', ')}`\n );\n }\n\n if (snapshot.diffStats) {\n summaryLines.push(\n `📊 Changes: ${snapshot.diffStats.filesChanged} files, +${snapshot.diffStats.insertions}/-${snapshot.diffStats.deletions}`\n );\n }\n\n if (snapshot.tags.length > 0) {\n summaryLines.push(`🏷️ Tags: ${snapshot.tags.join(', ')}`);\n }\n\n if (snapshot.notes) {\n summaryLines.push(`📌 Note: ${snapshot.notes}`);\n }\n\n console.log(UI.box(summaryLines.join('\\n'), title));\n\n // Show top commits\n if (snapshot.todayCommits.length > 0) {\n console.log('');\n console.log(` ${colors.accent(\"Today's commits:\")}`);\n for (const commit of snapshot.todayCommits.slice(0, 8)) {\n console.log(` ${colors.muted(commit.shortHash)} ${commit.message.slice(0, 70)}`);\n }\n if (snapshot.todayCommits.length > 8) {\n console.log(` ${colors.muted(`... and ${snapshot.todayCommits.length - 8} more`)}`);\n }\n }\n\n // Show active branches (if any have WIP)\n const wipBranches = snapshot.activeBranches.filter(\n (b) => b.hasUncommittedChanges || b.aheadOfBase > 0\n );\n if (wipBranches.length > 0) {\n console.log('');\n console.log(` ${colors.accent('Active work:')}`);\n for (const branch of wipBranches.slice(0, 10)) {\n let status = '';\n if (branch.aheadOfBase > 0) {\n status += colors.warning(`↑${branch.aheadOfBase}`);\n }\n if (branch.hasUncommittedChanges) {\n status += ` ${colors.error('●')} uncommitted`;\n }\n const current = branch.name === snapshot.currentBranch ? ' ←' : '';\n console.log(\n ` ${branch.name}${colors.accent(current)} ${status} ${colors.muted(branch.lastCommitMessage.slice(0, 40))}`\n );\n }\n }\n\n // Warnings\n if (warnings.length > 0) {\n console.log('');\n for (const w of warnings) {\n console.log(UI.warning(w));\n }\n }\n\n // Stats bar\n const statItems: { label: string; value: string | number }[] = [\n { label: 'time', value: `${durationMs}ms` },\n { label: 'commits', value: snapshot.todayCommits.length },\n ];\n if (snapshot.activeBranches.length > 0) {\n statItems.push({ label: 'branches', value: snapshot.activeBranches.length });\n }\n if (isLight) {\n statItems.push({ label: 'mode', value: 'light' });\n }\n console.log('');\n console.log(UI.stats(statItems));\n\n console.log('');\n console.log(\n UI.info(\n `Snapshot saved to journal. Use ${colors.accent('devdaily snapshot --list')} to see history.`\n )\n );\n console.log('');\n } catch (error) {\n spinner.stop();\n console.log('');\n console.log(UI.error('Failed to take snapshot'));\n console.log(colors.muted((error as Error).message));\n\n if (isDebug && error instanceof Error && error.stack) {\n console.log('');\n console.log(colors.muted('Stack trace:'));\n console.log(colors.muted(error.stack));\n }\n\n process.exit(1);\n }\n });\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const units = ['B', 'KB', 'MB', 'GB'];\n const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);\n const value = bytes / Math.pow(1024, i);\n return `${value.toFixed(i === 0 ? 0 : 1)} ${units[i]}`;\n}\n\nfunction daysBetween(dateStr: string, todayStr: string): number {\n const d1 = new Date(dateStr);\n const d2 = new Date(todayStr);\n return Math.round(Math.abs(d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24));\n}\n","import { Command } from 'commander';\nimport { WorkJournal } from '../core/work-journal.js';\nimport { CopilotClient } from '../core/copilot.js';\nimport UI from '../ui/renderer.js';\nimport { copyToClipboard } from '../utils/helpers.js';\nimport { getConfig } from '../config/index.js';\n\nconst { colors } = UI;\n\nexport const recallCommand = new Command('recall')\n .description('Search your work history — \"when did I last work on X?\"')\n .argument('[query...]', 'Search query (e.g., \"auth\", \"login page\", \"PROJ-123\")')\n .option('-p, --project <id>', 'Filter by project identifier')\n .option('--from <date>', 'Start date for search range (YYYY-MM-DD)')\n .option('--to <date>', 'End date for search range (YYYY-MM-DD)')\n .option('-d, --days <number>', 'Search last N days (default: 90)', '90')\n .option('-t, --tag <tags...>', 'Filter by tags')\n .option('-f, --file <path>', 'Search for a specific file path')\n .option('-l, --limit <number>', 'Max results to show (default: 10)', '10')\n .option('--ai', 'Generate an AI-powered summary of the search results')\n .option('--no-copy', 'Do not copy to clipboard')\n .option('--json', 'Output results as JSON')\n .option('--debug', 'Show debug output')\n .action(async (queryParts, options) => {\n const config = getConfig();\n const journal = new WorkJournal();\n const isDebug = options.debug || process.env.DEVD_DEBUG === '1';\n\n const query = queryParts.join(' ').trim();\n\n // ── Validate input ───────────────────────────────────────────────────\n if (!query && !options.tag && !options.file) {\n console.log('');\n console.log(UI.section('🔍 Recall — Search Your Work History'));\n console.log('');\n console.log(' Search across all your journal snapshots to find when you');\n console.log(' last worked on something, touched a file, or used a branch.');\n console.log('');\n console.log(` ${colors.accent('Usage:')}`);\n console.log(` devdaily recall <query> Search by keyword`);\n console.log(` devdaily recall \"auth feature\" Search for a phrase`);\n console.log(` devdaily recall PROJ-123 Search for a ticket`);\n console.log(` devdaily recall --file src/auth.ts Search for a file`);\n console.log(` devdaily recall --tag bugfix Search by tag`);\n console.log(` devdaily recall login --ai Get AI summary of results`);\n console.log('');\n console.log(` ${colors.accent('Options:')}`);\n console.log(` --from / --to Date range (YYYY-MM-DD)`);\n console.log(` --days <N> Search last N days (default: 90)`);\n console.log(` --project <id> Filter by project`);\n console.log(` --limit <N> Max results (default: 10)`);\n console.log('');\n\n // Show quick stats\n const stats = journal.getStats();\n if (stats.totalSnapshots > 0) {\n console.log(\n ` ${colors.muted('Your journal:')} ${stats.totalSnapshots} snapshots across ${stats.totalProjects} project(s), ${stats.totalDates} day(s)`\n );\n if (stats.oldestEntry && stats.newestEntry) {\n console.log(` ${colors.muted('Range:')} ${stats.oldestEntry} → ${stats.newestEntry}`);\n }\n } else {\n console.log(\n ` ${colors.muted('Your journal is empty. Run')} ${colors.accent('devdaily snapshot')} ${colors.muted('to start tracking.')}`\n );\n }\n console.log('');\n return;\n }\n\n // ── File search mode ───────────────────────────────────────────────────\n if (options.file) {\n const fileResults = journal.findFileHistory(\n options.file,\n options.project,\n parseInt(options.days, 10) || 90\n );\n\n if (fileResults.length === 0) {\n console.log('');\n console.log(UI.warning(`No history found for file: ${options.file}`));\n console.log(UI.info('Try broadening your search with a partial path or more --days'));\n console.log('');\n return;\n }\n\n console.log('');\n console.log(UI.section(`📄 File History: ${options.file}`));\n console.log('');\n\n const limit = parseInt(options.limit, 10) || 10;\n const toShow = fileResults.slice(-limit).reverse(); // Most recent first\n\n for (const entry of toShow) {\n const isToday = entry.date === journal.todayString();\n const dateLabel = isToday ? `${entry.date} ${colors.success('(today)')}` : entry.date;\n\n console.log(` ${colors.accent('│')} ${dateLabel}`);\n for (const commit of entry.commits.slice(0, 5)) {\n const files = commit.filesChanged\n ? commit.filesChanged.filter((f) =>\n f.toLowerCase().includes(options.file.toLowerCase())\n )\n : [];\n const fileNote = files.length > 0 ? colors.muted(` [${files.join(', ')}]`) : '';\n console.log(\n ` ${colors.accent('│')} ${colors.muted(commit.shortHash)} ${commit.message.slice(0, 55)}${fileNote}`\n );\n }\n if (entry.commits.length > 5) {\n console.log(\n ` ${colors.accent('│')} ${colors.muted(`... +${entry.commits.length - 5} more commits`)}`\n );\n }\n }\n console.log(` ${colors.accent('╵')}`);\n\n if (fileResults.length > limit) {\n console.log('');\n console.log(\n colors.muted(` Showing ${limit} of ${fileResults.length} days. Use --limit to see more.`)\n );\n }\n\n console.log('');\n return;\n }\n\n // ── Text / tag search mode ─────────────────────────────────────────────\n const spinner = UI.spinner(`Searching journal for \"${query || options.tag?.join(', ')}\"...`);\n spinner.start();\n\n // Determine date range\n let fromDate: string | undefined;\n let toDate: string | undefined;\n\n if (options.from || options.to) {\n fromDate = options.from;\n toDate = options.to;\n } else {\n const days = parseInt(options.days, 10) || 90;\n const from = new Date();\n from.setDate(from.getDate() - days);\n fromDate = journal.dateToString(from);\n toDate = journal.todayString();\n }\n\n const limit = parseInt(options.limit, 10) || 10;\n\n const results = journal.search({\n projectId: options.project,\n from: fromDate,\n to: toDate,\n query: query || undefined,\n tags: options.tag,\n limit,\n });\n\n spinner.stop();\n\n // ── JSON output ────────────────────────────────────────────────────────\n if (options.json) {\n const jsonOutput = results.map((r) => ({\n date: r.snapshot.date,\n projectId: r.snapshot.projectId,\n branch: r.snapshot.currentBranch,\n score: r.score,\n matchReasons: r.matchReasons,\n commits: r.snapshot.todayCommits.length,\n prs: r.snapshot.pullRequests.length,\n tags: r.snapshot.tags,\n notes: r.snapshot.notes || null,\n }));\n console.log(JSON.stringify(jsonOutput, null, 2));\n return;\n }\n\n // ── No results ─────────────────────────────────────────────────────────\n if (results.length === 0) {\n console.log('');\n const searchTerm = query || (options.tag ? `tags: ${options.tag.join(', ')}` : 'unknown');\n console.log(UI.warning(`No matches found for \"${searchTerm}\"`));\n console.log('');\n console.log(UI.info('Tips:'));\n console.log(` • Try a broader search term`);\n console.log(` • Increase the lookback window with ${colors.accent('--days 180')}`);\n console.log(` • Search across all projects with no ${colors.accent('--project')} filter`);\n console.log(\n ` • Make sure you've been taking snapshots (${colors.accent('devdaily snapshot')})`\n );\n console.log('');\n return;\n }\n\n // ── Render results ─────────────────────────────────────────────────────\n console.log('');\n\n const searchLabel = query\n ? `\"${query}\"`\n : options.tag\n ? `tags: ${options.tag.join(', ')}`\n : 'all';\n console.log(UI.section(`🔍 Recall — ${results.length} result(s) for ${searchLabel}`));\n console.log('');\n\n for (let i = 0; i < results.length; i++) {\n const { snapshot, matchReasons, score } = results[i];\n const isToday = snapshot.date === journal.todayString();\n const dateLabel = isToday ? `${snapshot.date} ${colors.success('(today)')}` : snapshot.date;\n\n // Result header\n const scoreBar = '●'.repeat(Math.min(score, 10)) + '○'.repeat(Math.max(0, 10 - score));\n console.log(\n ` ${colors.accent(`${i + 1}.`)} ${dateLabel} 📂 ${colors.accent(snapshot.projectId)} 🌿 ${snapshot.currentBranch} ${colors.muted(scoreBar)}`\n );\n\n // Match reasons\n if (matchReasons.length > 0) {\n const reasonsStr = matchReasons.slice(0, 5).join(', ');\n const more = matchReasons.length > 5 ? ` +${matchReasons.length - 5} more` : '';\n console.log(` ${colors.muted(`Matched: ${reasonsStr}${more}`)}`);\n }\n\n // Commits\n if (snapshot.todayCommits.length > 0) {\n const relevantCommits = query\n ? snapshot.todayCommits.filter(\n (c) =>\n c.message.toLowerCase().includes(query.toLowerCase()) ||\n c.filesChanged?.some((f) => f.toLowerCase().includes(query.toLowerCase()))\n )\n : [];\n\n const commitsToShow =\n relevantCommits.length > 0\n ? relevantCommits.slice(0, 3)\n : snapshot.todayCommits.slice(0, 2);\n\n for (const commit of commitsToShow) {\n // Highlight matching text in commit message\n const msg = query\n ? highlightMatch(commit.message.slice(0, 60), query)\n : commit.message.slice(0, 60);\n console.log(` ${colors.muted(commit.shortHash)} ${msg}`);\n }\n\n const remaining = snapshot.todayCommits.length - commitsToShow.length;\n if (remaining > 0) {\n console.log(` ${colors.muted(`... +${remaining} more commit(s)`)}`);\n }\n }\n\n // PRs (if relevant)\n if (snapshot.pullRequests.length > 0) {\n const relevantPRs = query\n ? snapshot.pullRequests.filter((pr) =>\n pr.title.toLowerCase().includes(query.toLowerCase())\n )\n : snapshot.pullRequests;\n\n if (relevantPRs.length > 0) {\n for (const pr of relevantPRs.slice(0, 2)) {\n const stateIcon =\n pr.state === 'open'\n ? colors.success('○')\n : pr.state === 'merged'\n ? colors.accent('●')\n : colors.muted('✕');\n const title = query\n ? highlightMatch(pr.title.slice(0, 50), query)\n : pr.title.slice(0, 50);\n console.log(` ${stateIcon} PR #${pr.number} ${title}`);\n }\n }\n }\n\n // Notes\n if (snapshot.notes) {\n const notePreview = snapshot.notes.split('\\n')[0].slice(0, 55);\n const highlighted = query ? highlightMatch(notePreview, query) : notePreview;\n console.log(` ${colors.warning('📌')} ${highlighted}`);\n }\n\n // Diff stats\n if (snapshot.diffStats && snapshot.diffStats.insertions + snapshot.diffStats.deletions > 0) {\n console.log(\n ` ${colors.muted(`${snapshot.diffStats.filesChanged} files`)} ${colors.success(`+${snapshot.diffStats.insertions}`)}/${colors.error(`-${snapshot.diffStats.deletions}`)}`\n );\n }\n\n // Tags\n if (snapshot.tags.length > 0) {\n const relevantTags = query\n ? snapshot.tags.filter((t) => t.toLowerCase().includes(query.toLowerCase()))\n : [];\n\n if (relevantTags.length > 0) {\n console.log(` ${colors.muted('tags:')} ${relevantTags.join(', ')}`);\n }\n }\n\n console.log('');\n }\n\n // ── Search metadata ────────────────────────────────────────────────────\n const stats = journal.getStats();\n console.log(\n colors.muted(\n ` Searched ${stats.totalSnapshots} snapshots across ${stats.totalProjects} project(s) from ${fromDate} to ${toDate}`\n )\n );\n console.log('');\n\n // ── AI summary of search results ───────────────────────────────────────\n if (options.ai) {\n const copilot = new CopilotClient({ debug: isDebug });\n\n if (!(await copilot.isInstalled())) {\n console.log(\n UI.warning(\n 'GitHub Copilot CLI not found — skipping AI summary. Install with: gh extension install github/gh-copilot'\n )\n );\n } else {\n const genSpinner = UI.spinner('Generating AI summary of search results...');\n genSpinner.start();\n\n try {\n const snapshotsForAI = results.map((r) => r.snapshot);\n const contextBlock = WorkJournal.formatSnapshotsForAI(snapshotsForAI);\n\n const prompt = buildRecallSummaryPrompt(query, contextBlock, fromDate!, toDate!);\n const summary = await copilot.generateFromPrompt(prompt);\n\n genSpinner.stop();\n\n console.log(UI.box(summary, `🔍 AI Summary: \"${query}\"`));\n console.log('');\n\n // Copy to clipboard\n if (options.copy !== false && config.output.copyToClipboard !== false) {\n await copyToClipboard(summary);\n console.log(UI.success('Copied to clipboard'));\n console.log('');\n }\n } catch (err) {\n genSpinner.stop();\n console.log(UI.warning(`AI summary failed: ${(err as Error).message}`));\n console.log('');\n }\n }\n } else if (results.length > 0) {\n console.log(\n colors.muted(\n ` Tip: Add ${colors.accent('--ai')} for an AI-powered summary of these results`\n )\n );\n console.log('');\n }\n });\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/**\n * Highlight matching substring in text using accent color.\n */\nfunction highlightMatch(text: string, query: string): string {\n if (!query) return text;\n\n const lowerText = text.toLowerCase();\n const lowerQuery = query.toLowerCase();\n const index = lowerText.indexOf(lowerQuery);\n\n if (index === -1) return text;\n\n const before = text.slice(0, index);\n const match = text.slice(index, index + query.length);\n const after = text.slice(index + query.length);\n\n return `${before}${colors.accent(match)}${after}`;\n}\n\n/**\n * Build an AI prompt for summarizing recall search results.\n */\nfunction buildRecallSummaryPrompt(\n query: string,\n contextBlock: string,\n fromDate: string,\n toDate: string\n): string {\n return `You are a developer assistant helping me recall past work.\n\nI searched my work journal for \"${query}\" and found the matching entries below (from ${fromDate} to ${toDate}).\n\nYour job is to give me a concise summary that answers: \"What did I do related to '${query}'?\"\n\nStructure your response as:\n1. **Summary** — What the work related to \"${query}\" was about (2-3 sentences)\n2. **Timeline** — When the key activities happened (brief chronological list)\n3. **Key details** — Specific branches, PRs, files, or tickets that are most relevant\n4. **Current state** — Is this work done, still in progress, or abandoned?\n\nRules:\n- Be concise and factual — only use information from the data\n- Reference specific commit hashes, branch names, PR numbers when helpful\n- If the query matches across multiple projects, organize by project\n- Don't hallucinate or invent details\n\n---\nMATCHING JOURNAL ENTRIES:\n${contextBlock}\n---\n\nGenerate the recall summary now:`;\n}\n","import { Command } from 'commander';\nimport { existsSync, readFileSync, appendFileSync, writeFileSync } from 'fs';\nimport { homedir } from 'os';\nimport { join } from 'path';\nimport inquirer from 'inquirer';\nimport UI from '../ui/renderer.js';\nimport { ASCII } from '../ui/ascii.js';\nimport { ConfigManager, type Secrets } from '../config/index.js';\nimport { GitAnalyzer } from '../core/git-analyzer.js';\nimport { generateSamplePRPrompt, findPRPromptFile } from '../core/pr-prompt.js';\nimport { installGitHooks, removeGitHooks } from '../core/auto-snapshot.js';\n\nconst { colors } = UI;\n\n// Shell config file paths\nconst SHELL_CONFIGS = {\n zsh: join(homedir(), '.zshrc'),\n bash: join(homedir(), '.bashrc'),\n fish: join(homedir(), '.config', 'fish', 'config.fish'),\n};\n\n// Alias to add\nconst ALIAS_LINE = {\n zsh: `\\n# DevDaily AI alias\\nalias dd='devdaily'\\n`,\n bash: `\\n# DevDaily AI alias\\nalias dd='devdaily'\\n`,\n fish: `\\n# DevDaily AI alias\\nalias dd 'devdaily'\\n`,\n};\n\n// Shell completions\nconst COMPLETIONS = {\n zsh: `\n# DevDaily AI completions\n_devdaily() {\n local commands=\"standup pr week dash config init help\"\n local standup_opts=\"--days --format --no-copy\"\n local pr_opts=\"--base --create --draft --no-copy\"\n local week_opts=\"--last --start --no-copy\"\n\n _arguments \\\\\n '1:command:($commands)' \\\\\n '*::arg:->args'\n\n case $words[1] in\n standup|s|su)\n _arguments $standup_opts\n ;;\n pr|p)\n _arguments $pr_opts\n ;;\n week|w)\n _arguments $week_opts\n ;;\n esac\n}\ncompdef _devdaily devdaily\ncompdef _devdaily dd\n`,\n bash: `\n# DevDaily AI completions\n_devdaily_completions() {\n local cur=\"\\${COMP_WORDS[COMP_CWORD]}\"\n local commands=\"standup pr week dash config init help\"\n\n if [ \\${COMP_CWORD} -eq 1 ]; then\n COMPREPLY=( $(compgen -W \"\\${commands}\" -- \\${cur}) )\n fi\n}\ncomplete -F _devdaily_completions devdaily\ncomplete -F _devdaily_completions dd\n`,\n fish: `\n# DevDaily AI completions\ncomplete -c devdaily -n __fish_use_subcommand -a standup -d 'Generate standup notes'\ncomplete -c devdaily -n __fish_use_subcommand -a pr -d 'Generate PR description'\ncomplete -c devdaily -n __fish_use_subcommand -a week -d 'Generate weekly summary'\ncomplete -c devdaily -n __fish_use_subcommand -a dash -d 'Open dashboard'\ncomplete -c devdaily -n __fish_use_subcommand -a config -d 'Manage configuration'\ncomplete -c devdaily -n __fish_use_subcommand -a init -d 'Initialize DevDaily'\ncomplete -c dd -w devdaily\n`,\n};\n\n/**\n * Detect current shell\n */\nconst detectShell = (): 'zsh' | 'bash' | 'fish' => {\n const shell = process.env.SHELL || '';\n\n if (shell.includes('zsh')) return 'zsh';\n if (shell.includes('fish')) return 'fish';\n return 'bash';\n};\n\n/**\n * Check if alias already exists\n */\nconst hasAlias = (shell: 'zsh' | 'bash' | 'fish'): boolean => {\n const configPath = SHELL_CONFIGS[shell];\n\n if (!existsSync(configPath)) return false;\n\n const content = readFileSync(configPath, 'utf-8');\n return content.includes(\"alias dd='devdaily'\") || content.includes(\"alias dd 'devdaily'\");\n};\n\n/**\n * Add alias to shell config\n */\nconst addAlias = (shell: 'zsh' | 'bash' | 'fish'): void => {\n const configPath = SHELL_CONFIGS[shell];\n const aliasLine = ALIAS_LINE[shell];\n\n appendFileSync(configPath, aliasLine);\n};\n\n/**\n * Add completions to shell config\n */\nconst addCompletions = (shell: 'zsh' | 'bash' | 'fish'): void => {\n const configPath = SHELL_CONFIGS[shell];\n const completions = COMPLETIONS[shell];\n\n appendFileSync(configPath, completions);\n};\n\n/**\n * Check if completions already exist\n */\nconst hasCompletions = (shell: 'zsh' | 'bash' | 'fish'): boolean => {\n const configPath = SHELL_CONFIGS[shell];\n\n if (!existsSync(configPath)) return false;\n\n const content = readFileSync(configPath, 'utf-8');\n return content.includes('DevDaily AI completions');\n};\n\nexport const initCommand = new Command('init')\n .description('Set up DevDaily (aliases, shell completions, config)')\n .option('-g, --global', 'Set up globally for all projects')\n .option('--alias', 'Only set up shell alias (dd)')\n .option('--completions', 'Only set up shell completions')\n .option('--config', 'Only create config file')\n .option('--pm', 'Only set up project management integration')\n .option('--notifications', 'Only set up Slack/Discord notifications')\n .option('--git-hooks', 'Install git hooks for automatic snapshots (post-commit, post-checkout)')\n .option('--remove-hooks', 'Remove previously installed devdaily git hooks')\n .action(async (options) => {\n console.log('');\n console.log(UI.header('DevDaily Setup'));\n console.log('');\n\n const shell = detectShell();\n console.log(UI.info(`Detected shell: ${shell}`));\n console.log('');\n\n const tasks: Array<{ name: string; done: boolean; skipped: boolean }> = [];\n\n // Auto-detect default branch\n let detectedDefaultBranch = 'main';\n const git = new GitAnalyzer();\n const isRepo = await git.isRepository();\n\n if (isRepo) {\n const branchSpinner = UI.spinner('Detecting default branch...');\n branchSpinner.start();\n try {\n detectedDefaultBranch = await git.getDefaultBranch();\n branchSpinner.stop();\n console.log(UI.info(`Detected default branch: ${colors.accent(detectedDefaultBranch)}`));\n } catch {\n branchSpinner.stop();\n console.log(colors.muted(' Could not auto-detect default branch, using \"main\"'));\n }\n }\n\n // Check for existing PR prompt file\n let hasPRPrompt = false;\n if (isRepo) {\n try {\n const repoRoot = await git.getRepoRoot();\n hasPRPrompt = (await findPRPromptFile(repoRoot)) !== null;\n } catch {\n // ignore\n }\n }\n\n console.log('');\n\n // Interactive setup if no specific options\n // Handle --remove-hooks early\n if (options.removeHooks) {\n console.log(colors.bold('📸 Removing DevDaily Git Hooks'));\n console.log('');\n const removeResult = await removeGitHooks();\n if (removeResult.removed.length > 0) {\n for (const name of removeResult.removed) {\n console.log(UI.success(`Removed: ${name}`));\n }\n } else {\n console.log(UI.info('No devdaily git hooks found to remove.'));\n }\n for (const w of removeResult.warnings) {\n console.log(UI.warning(w));\n }\n console.log('');\n return;\n }\n\n const hasSpecificOption =\n options.alias ||\n options.completions ||\n options.config ||\n options.pm ||\n options.notifications ||\n options.gitHooks ||\n options.git_hooks;\n\n if (!hasSpecificOption) {\n const { features } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'features',\n message: 'What would you like to set up?',\n choices: [\n {\n name: `Shell alias (${colors.accent('dd')} → ${colors.primary('devdaily')})`,\n value: 'alias',\n checked: !hasAlias(shell),\n },\n {\n name: 'Shell completions (tab completion)',\n value: 'completions',\n checked: !hasCompletions(shell),\n },\n {\n name: `Create ${options.global ? 'global' : 'project'} config file`,\n value: 'config',\n checked: true,\n },\n {\n name: `${colors.accent('🎫')} Project management integration (Jira/Linear/Notion)`,\n value: 'pm',\n checked: true,\n },\n {\n name: `${colors.accent('🔀')} Default branch & PR settings`,\n value: 'branch',\n checked: true,\n },\n {\n name: `${colors.accent('📝')} PR description prompt file (.devdaily-pr-prompt.md)`,\n value: 'pr_prompt',\n checked: !hasPRPrompt,\n },\n {\n name: `${colors.accent('🔔')} Notifications (Slack/Discord webhooks)`,\n value: 'notifications',\n checked: false,\n },\n {\n name: `${colors.accent('📸')} Git hooks for automatic snapshots (post-commit, post-checkout)`,\n value: 'git_hooks',\n checked: false,\n },\n ],\n },\n ]);\n\n options.alias = features.includes('alias');\n options.completions = features.includes('completions');\n options.config = features.includes('config');\n options.pm = features.includes('pm');\n options.branch = features.includes('branch');\n options.pr_prompt = features.includes('pr_prompt');\n options.notifications = features.includes('notifications');\n options.git_hooks = options.gitHooks || features.includes('git_hooks');\n }\n\n console.log('');\n\n // Set up alias\n if (options.alias) {\n if (hasAlias(shell)) {\n console.log(colors.muted(`${ASCII.status.check} Shell alias already exists`));\n tasks.push({ name: 'Shell alias', done: false, skipped: true });\n } else {\n try {\n addAlias(shell);\n console.log(UI.success(`Added shell alias: ${colors.accent('dd')} → devdaily`));\n tasks.push({ name: 'Shell alias', done: true, skipped: false });\n } catch {\n console.log(UI.error('Failed to add shell alias'));\n tasks.push({ name: 'Shell alias', done: false, skipped: false });\n }\n }\n }\n\n // Set up completions\n if (options.completions) {\n if (hasCompletions(shell)) {\n console.log(colors.muted(`${ASCII.status.check} Shell completions already exist`));\n tasks.push({ name: 'Completions', done: false, skipped: true });\n } else {\n try {\n addCompletions(shell);\n console.log(UI.success('Added shell completions'));\n tasks.push({ name: 'Completions', done: true, skipped: false });\n } catch {\n console.log(UI.error('Failed to add completions'));\n tasks.push({ name: 'Completions', done: false, skipped: false });\n }\n }\n }\n\n // Set up project management\n if (options.pm) {\n console.log('');\n console.log(UI.divider());\n console.log('');\n console.log(colors.bold('🎫 Project Management Setup'));\n console.log(colors.muted(' Link your ticket system for richer AI context'));\n console.log('');\n\n const { pmTool } = await inquirer.prompt([\n {\n type: 'list',\n name: 'pmTool',\n message: 'Which project management tool do you use?',\n choices: [\n { name: '🐙 GitHub Issues (default, uses gh CLI)', value: 'github' },\n { name: '🔷 Jira', value: 'jira' },\n { name: '📐 Linear', value: 'linear' },\n { name: '📝 Notion', value: 'notion' },\n { name: '⏭️ Skip for now', value: 'none' },\n ],\n },\n ]);\n\n const configManager = ConfigManager.getInstance();\n const secrets: Secrets = {};\n let ticketPrefix = '';\n\n if (pmTool !== 'none' && pmTool !== 'github') {\n // Ask for ticket prefix\n const { prefix } = await inquirer.prompt([\n {\n type: 'input',\n name: 'prefix',\n message: 'Ticket prefix (e.g., PROJ, ENG, DEV):',\n default: '',\n validate: (input: string) => {\n if (!input) return true; // Optional\n if (/^[A-Z][A-Z0-9]*$/i.test(input)) return true;\n return 'Prefix should be letters/numbers (e.g., PROJ, ENG-1)';\n },\n },\n ]);\n ticketPrefix = prefix.toUpperCase();\n }\n\n // Tool-specific setup\n if (pmTool === 'jira') {\n console.log('');\n console.log(\n colors.muted(' Jira API credentials will be stored in .devdaily.secrets.json')\n );\n console.log(colors.muted(' This file will be added to .gitignore'));\n console.log('');\n\n const jiraAnswers = await inquirer.prompt([\n {\n type: 'input',\n name: 'baseUrl',\n message: 'Jira base URL:',\n default: 'https://yourcompany.atlassian.net',\n validate: (input: string) => input.startsWith('http') || 'Must be a valid URL',\n },\n {\n type: 'input',\n name: 'email',\n message: 'Your Jira email:',\n },\n {\n type: 'password',\n name: 'apiToken',\n message: 'Jira API token:',\n mask: '*',\n },\n ]);\n\n secrets.jira = {\n baseUrl: jiraAnswers.baseUrl,\n email: jiraAnswers.email,\n apiToken: jiraAnswers.apiToken,\n };\n } else if (pmTool === 'linear') {\n console.log('');\n console.log(colors.muted(' Get your API key from Linear Settings → API'));\n console.log('');\n\n const linearAnswers = await inquirer.prompt([\n {\n type: 'password',\n name: 'apiKey',\n message: 'Linear API key:',\n mask: '*',\n },\n ]);\n\n secrets.linear = {\n apiKey: linearAnswers.apiKey,\n };\n } else if (pmTool === 'notion') {\n console.log('');\n console.log(colors.muted(' Create an integration at notion.so/my-integrations'));\n console.log('');\n\n const notionAnswers = await inquirer.prompt([\n {\n type: 'password',\n name: 'apiKey',\n message: 'Notion API key:',\n mask: '*',\n },\n {\n type: 'input',\n name: 'databaseId',\n message: 'Notion database ID (for tasks):',\n },\n ]);\n\n secrets.notion = {\n apiKey: notionAnswers.apiKey,\n databaseId: notionAnswers.databaseId,\n };\n }\n\n // Save PM config\n if (pmTool !== 'none') {\n // Use type assertion since we're doing a partial update\n const pmConfig = {\n projectManagement: {\n tool: pmTool,\n ticketPrefix: ticketPrefix || undefined,\n jira: {},\n linear: {},\n notion: {},\n },\n } as Parameters<typeof configManager.update>[0];\n\n if (options.global) {\n configManager.update(pmConfig);\n configManager.saveGlobal();\n } else {\n configManager.saveLocal(pmConfig as Parameters<typeof configManager.saveLocal>[0]);\n }\n\n // Save secrets if any\n if (Object.keys(secrets).length > 0) {\n configManager.saveSecrets(secrets, options.global);\n\n // Add to gitignore\n if (!options.global) {\n const added = configManager.addSecretsToGitignore();\n if (added) {\n console.log(UI.success('Added .devdaily.secrets.json to .gitignore'));\n }\n }\n }\n\n console.log(UI.success(`Configured ${pmTool} integration`));\n tasks.push({ name: 'PM integration', done: true, skipped: false });\n } else {\n tasks.push({ name: 'PM integration', done: false, skipped: true });\n }\n }\n\n // Set up notifications\n if (options.notifications) {\n console.log('');\n console.log(UI.divider());\n console.log('');\n console.log(colors.bold('🔔 Notification Setup'));\n console.log(colors.muted(' Send standups to Slack or Discord automatically'));\n console.log('');\n\n const { notificationChannels } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'notificationChannels',\n message: 'Which notification channels do you want to set up?',\n choices: [\n { name: '💬 Slack (webhook)', value: 'slack' },\n { name: '🎮 Discord (webhook)', value: 'discord' },\n ],\n },\n ]);\n\n const configManager = ConfigManager.getInstance();\n const secrets: Secrets = {};\n const notificationConfig: {\n slack?: { enabled: boolean };\n discord?: { enabled: boolean };\n } = {};\n\n if (notificationChannels.includes('slack')) {\n console.log('');\n console.log(colors.muted(' Create a Slack webhook at: api.slack.com/apps'));\n console.log(colors.muted(' → Create App → Incoming Webhooks → Add New Webhook'));\n console.log('');\n\n const slackAnswers = await inquirer.prompt([\n {\n type: 'password',\n name: 'webhookUrl',\n message: 'Slack webhook URL:',\n mask: '*',\n validate: (input: string) =>\n input.startsWith('https://hooks.slack.com/') || 'Must be a valid Slack webhook URL',\n },\n ]);\n\n secrets.slack = {\n webhookUrl: slackAnswers.webhookUrl,\n };\n\n notificationConfig.slack = {\n enabled: true,\n };\n\n console.log(UI.success('Slack configured!'));\n }\n\n if (notificationChannels.includes('discord')) {\n console.log('');\n console.log(colors.muted(' Create a Discord webhook:'));\n console.log(colors.muted(' → Server Settings → Integrations → Webhooks → New Webhook'));\n console.log('');\n\n const discordAnswers = await inquirer.prompt([\n {\n type: 'password',\n name: 'webhookUrl',\n message: 'Discord webhook URL:',\n mask: '*',\n validate: (input: string) =>\n input.startsWith('https://discord.com/api/webhooks/') ||\n 'Must be a valid Discord webhook URL',\n },\n ]);\n\n secrets.discord = {\n webhookUrl: discordAnswers.webhookUrl,\n };\n\n notificationConfig.discord = {\n enabled: true,\n };\n\n console.log(UI.success('Discord configured!'));\n }\n\n if (notificationChannels.length > 0) {\n // Save notification config - use type assertion for partial update\n const config = {\n notifications: {\n slack: { enabled: false, ...notificationConfig.slack },\n discord: { enabled: false, ...notificationConfig.discord },\n standupTimezone: 'America/New_York',\n },\n } as Parameters<typeof configManager.update>[0];\n\n if (options.global) {\n configManager.update(config);\n configManager.saveGlobal();\n } else {\n configManager.saveLocal(config as Parameters<typeof configManager.saveLocal>[0]);\n }\n\n // Save secrets\n if (Object.keys(secrets).length > 0) {\n configManager.saveSecrets(secrets, options.global);\n\n if (!options.global) {\n const added = configManager.addSecretsToGitignore();\n if (added) {\n console.log(UI.success('Added .devdaily.secrets.json to .gitignore'));\n }\n }\n }\n\n console.log('');\n console.log(colors.muted(' Usage:'));\n console.log(\n ` ${colors.primary('devdaily standup --send')} ${colors.muted('# Send to all channels')}`\n );\n console.log(\n ` ${colors.primary('devdaily standup --slack')} ${colors.muted('# Send to Slack only')}`\n );\n console.log(\n ` ${colors.primary('devdaily standup --discord')} ${colors.muted('# Send to Discord only')}`\n );\n\n tasks.push({ name: 'Notifications', done: true, skipped: false });\n } else {\n tasks.push({ name: 'Notifications', done: false, skipped: true });\n }\n }\n\n // Default branch & PR settings\n if (options.branch) {\n console.log('');\n console.log(UI.divider());\n console.log('');\n console.log(colors.bold('🔀 Default Branch & PR Settings'));\n console.log(colors.muted(' Configure the base branch for PRs and git comparisons'));\n console.log('');\n\n const branchAnswers = await inquirer.prompt([\n {\n type: 'input',\n name: 'defaultBranch',\n message: 'Default base branch (for PRs, diffs, standups):',\n default: detectedDefaultBranch,\n },\n {\n type: 'confirm',\n name: 'includeDiff',\n message: 'Include code diff in AI prompt for richer PR descriptions?',\n default: true,\n },\n {\n type: 'number',\n name: 'maxDiffLines',\n message: 'Max diff lines to send to AI (to avoid token limits):',\n default: 200,\n when: (answers: Record<string, unknown>) => Boolean(answers.includeDiff),\n },\n ]);\n\n const configManager = ConfigManager.getInstance();\n const prConfig = {\n pr: {\n defaultBase: branchAnswers.defaultBranch,\n includeDiff: branchAnswers.includeDiff,\n maxDiffLines: branchAnswers.maxDiffLines || 200,\n },\n git: {\n defaultBranch: branchAnswers.defaultBranch,\n },\n } as Parameters<typeof configManager.update>[0];\n\n if (options.global) {\n configManager.update(prConfig);\n configManager.saveGlobal();\n } else {\n configManager.saveLocal(prConfig as Parameters<typeof configManager.saveLocal>[0]);\n }\n\n console.log(\n UI.success(`Default branch set to ${colors.accent(branchAnswers.defaultBranch)}`)\n );\n tasks.push({ name: 'Branch & PR settings', done: true, skipped: false });\n }\n\n // PR description prompt file\n if (options.pr_prompt) {\n console.log('');\n console.log(UI.divider());\n console.log('');\n console.log(colors.bold('📝 PR Description Prompt'));\n console.log(\n colors.muted(\n ' Create a .devdaily-pr-prompt.md file to customize how AI generates PR descriptions'\n )\n );\n console.log(\n colors.muted(' Think of it like CLAUDE.md — but specifically for PR descriptions')\n );\n console.log('');\n\n if (hasPRPrompt) {\n console.log(colors.muted(` ${ASCII.status.check} PR prompt file already exists`));\n tasks.push({ name: 'PR prompt file', done: false, skipped: true });\n } else {\n const { createPrompt } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'createPrompt',\n message: 'Create a .devdaily-pr-prompt.md with sample guidelines you can customize?',\n default: true,\n },\n ]);\n\n if (createPrompt) {\n try {\n const repoRoot = isRepo ? await git.getRepoRoot() : process.cwd();\n const promptPath = join(repoRoot, '.devdaily-pr-prompt.md');\n writeFileSync(promptPath, generateSamplePRPrompt());\n console.log(\n UI.success(\n `Created ${colors.accent('.devdaily-pr-prompt.md')} — customize it for your team!`\n )\n );\n tasks.push({ name: 'PR prompt file', done: true, skipped: false });\n } catch {\n console.log(UI.error('Failed to create PR prompt file'));\n tasks.push({ name: 'PR prompt file', done: false, skipped: false });\n }\n } else {\n tasks.push({ name: 'PR prompt file', done: false, skipped: true });\n }\n }\n }\n\n // Create config (if not already done by PM setup)\n if (options.config && !options.pm) {\n try {\n const configManager = ConfigManager.getInstance();\n\n if (options.global) {\n configManager.saveGlobal();\n console.log(UI.success(`Created global config: ${ConfigManager.getGlobalConfigPath()}`));\n } else {\n configManager.saveLocal();\n console.log(UI.success(`Created local config: ${ConfigManager.getLocalConfigPath()}`));\n }\n tasks.push({ name: 'Config file', done: true, skipped: false });\n } catch {\n console.log(UI.error('Failed to create config'));\n tasks.push({ name: 'Config file', done: false, skipped: false });\n }\n }\n\n console.log('');\n console.log(UI.divider());\n console.log('');\n\n // Summary\n // Git hooks for automatic snapshots\n if (options.git_hooks || options.gitHooks) {\n console.log('');\n console.log(UI.divider());\n console.log('');\n console.log(colors.bold('📸 Git Hooks for Automatic Snapshots'));\n console.log(\n colors.muted(\n ' Install hooks that automatically capture your work state on commit and branch switch'\n )\n );\n console.log(\n colors.muted(' Snapshots are lightweight, local-only, and run in the background')\n );\n console.log('');\n\n if (!isRepo) {\n console.log(UI.warning('Not a git repository — skipping git hooks'));\n tasks.push({ name: 'Git hooks', done: false, skipped: true });\n } else {\n const { hookChoices } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'hookChoices',\n message: 'Which hooks would you like to install?',\n choices: [\n {\n name: `post-commit — snapshot after each commit`,\n value: 'post-commit',\n checked: true,\n },\n {\n name: `post-checkout — snapshot when switching branches`,\n value: 'post-checkout',\n checked: true,\n },\n ],\n },\n ]);\n\n if (hookChoices.length === 0) {\n console.log(colors.muted(' No hooks selected'));\n tasks.push({ name: 'Git hooks', done: false, skipped: true });\n } else {\n const hookResult = await installGitHooks({\n postCommit: hookChoices.includes('post-commit'),\n postCheckout: hookChoices.includes('post-checkout'),\n });\n\n if (hookResult.installed.length > 0) {\n for (const name of hookResult.installed) {\n console.log(UI.success(`Installed: ${name}`));\n }\n\n // Update config to reflect git hooks are enabled\n try {\n const configManager = ConfigManager.getInstance();\n const currentConfig = configManager.get();\n configManager.update({\n ...currentConfig,\n journal: {\n ...currentConfig.journal,\n autoSnapshot: true,\n gitHooks: true,\n hooks: {\n postCommit: hookChoices.includes('post-commit'),\n postCheckout: hookChoices.includes('post-checkout'),\n },\n },\n });\n if (options.global) {\n configManager.saveGlobal();\n } else {\n configManager.saveLocal();\n }\n } catch {\n // Non-fatal — hooks are installed even if config update fails\n }\n\n tasks.push({ name: 'Git hooks', done: true, skipped: false });\n }\n\n for (const name of hookResult.skipped) {\n console.log(colors.muted(` ${ASCII.status.check} ${name}`));\n }\n\n for (const w of hookResult.warnings) {\n console.log(UI.warning(w));\n }\n }\n }\n }\n\n const completed = tasks.filter((t) => t.done).length;\n const skipped = tasks.filter((t) => t.skipped).length;\n\n if (completed > 0) {\n console.log(UI.success(`Setup complete! (${completed} task${completed > 1 ? 's' : ''})`));\n console.log('');\n console.log(colors.muted('To apply changes, restart your terminal or run:'));\n console.log(\n ` ${colors.primary(`source ~/${shell === 'fish' ? '.config/fish/config.fish' : `.${shell}rc`}`)}`\n );\n } else if (skipped === tasks.length) {\n console.log(UI.info('Everything is already set up!'));\n }\n\n console.log('');\n console.log(colors.muted('Quick start:'));\n console.log(` ${colors.primary('dd standup')} ${colors.muted('# Generate standup notes')}`);\n console.log(\n ` ${colors.primary('dd pr')} ${colors.muted('# Generate PR description')}`\n );\n console.log(\n ` ${colors.primary('dd dash')} ${colors.muted('# Open interactive dashboard')}`\n );\n console.log(\n ` ${colors.primary('dd context')} ${colors.muted('# Resume where you left off')}`\n );\n console.log('');\n });\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport { ConfigManager, getConfig } from '../config/index.js';\nimport UI from '../ui/renderer.js';\nimport { ASCII } from '../ui/ascii.js';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nconst execAsync = promisify(exec);\n\nexport const configCommand = new Command('config')\n .description('Manage DevDaily configuration')\n .option('-e, --edit', 'Open config in editor')\n .option('--reset', 'Reset to defaults')\n .option('--path', 'Show config file path')\n .option('--show', 'Show current configuration')\n .action(async (options) => {\n const configManager = ConfigManager.getInstance();\n const config = getConfig();\n\n if (options.path) {\n console.log('');\n console.log(UI.keyValue('Config path', configManager.getConfigPath()));\n console.log(UI.keyValue('Global config', ConfigManager.getGlobalConfigPath()));\n console.log(UI.keyValue('Local config', ConfigManager.getLocalConfigPath()));\n console.log('');\n return;\n }\n\n if (options.reset) {\n const { confirm } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: 'Reset configuration to defaults?',\n default: false,\n },\n ]);\n\n if (confirm) {\n configManager.reset();\n console.log(UI.success('Configuration reset to defaults'));\n }\n return;\n }\n\n if (options.edit) {\n const editor = process.env.EDITOR || 'code';\n const configPath = configManager.getConfigPath();\n\n console.log(UI.info(`Opening ${configPath} in ${editor}...`));\n\n try {\n await execAsync(`${editor} \"${configPath}\"`);\n } catch {\n console.log(UI.error(`Failed to open editor. Config path: ${configPath}`));\n }\n return;\n }\n\n if (options.show) {\n console.log('');\n console.log(UI.section('Current Configuration', ASCII.icons.config));\n console.log('');\n console.log(JSON.stringify(config, null, 2));\n console.log('');\n return;\n }\n\n // Interactive configuration\n console.log('');\n console.log(UI.header('Configuration'));\n console.log('');\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What would you like to configure?',\n choices: [\n { name: `${ASCII.icons.standup} Theme & Appearance`, value: 'theme' },\n { name: `${ASCII.icons.pr} Default Settings`, value: 'defaults' },\n { name: `${ASCII.icons.week} Output Preferences`, value: 'output' },\n new inquirer.Separator(),\n { name: 'Show current config', value: 'show' },\n { name: 'Open in editor', value: 'edit' },\n { name: 'Reset to defaults', value: 'reset' },\n new inquirer.Separator(),\n { name: 'Exit', value: 'exit' },\n ],\n },\n ]);\n\n switch (action) {\n case 'theme':\n await configureTheme(configManager);\n break;\n case 'defaults':\n await configureDefaults(configManager);\n break;\n case 'output':\n await configureOutput(configManager);\n break;\n case 'show':\n console.log('');\n console.log(JSON.stringify(config, null, 2));\n console.log('');\n break;\n case 'edit': {\n const editor = process.env.EDITOR || 'code';\n try {\n await execAsync(`${editor} \"${configManager.getConfigPath()}\"`);\n } catch {\n console.log(UI.error('Failed to open editor'));\n }\n break;\n }\n case 'reset':\n configManager.reset();\n console.log(UI.success('Configuration reset'));\n break;\n }\n });\n\nasync function configureTheme(configManager: ConfigManager): Promise<void> {\n const config = configManager.get();\n\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'primary',\n message: 'Primary color:',\n choices: ['blue', 'cyan', 'green', 'magenta', 'yellow', 'red'],\n default: config.theme.primary,\n },\n {\n type: 'confirm',\n name: 'ascii',\n message: 'Show ASCII art logo?',\n default: config.ascii,\n },\n {\n type: 'confirm',\n name: 'compactMode',\n message: 'Use compact mode?',\n default: config.compactMode,\n },\n ]);\n\n configManager.update({\n theme: { ...config.theme, primary: answers.primary },\n ascii: answers.ascii,\n compactMode: answers.compactMode,\n });\n\n console.log(UI.success('Theme updated'));\n}\n\nasync function configureDefaults(configManager: ConfigManager): Promise<void> {\n const config = configManager.get();\n\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'defaultBranch',\n message: 'Default base branch for PRs:',\n default: config.pr.defaultBase,\n },\n {\n type: 'number',\n name: 'standupDays',\n message: 'Default days for standup:',\n default: config.standup.defaultDays,\n },\n {\n type: 'list',\n name: 'weekStart',\n message: 'Week starts on:',\n choices: ['monday', 'sunday'],\n default: config.week.startDay,\n },\n ]);\n\n configManager.update({\n pr: { ...config.pr, defaultBase: answers.defaultBranch },\n standup: { ...config.standup, defaultDays: answers.standupDays },\n week: { ...config.week, startDay: answers.weekStart },\n });\n\n console.log(UI.success('Defaults updated'));\n}\n\nasync function configureOutput(configManager: ConfigManager): Promise<void> {\n const config = configManager.get();\n\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'format',\n message: 'Default output format:',\n choices: ['markdown', 'slack', 'plain', 'json'],\n default: config.output.format,\n },\n {\n type: 'confirm',\n name: 'copyToClipboard',\n message: 'Auto-copy to clipboard?',\n default: config.output.copyToClipboard,\n },\n {\n type: 'confirm',\n name: 'showStats',\n message: 'Show statistics?',\n default: config.output.showStats,\n },\n ]);\n\n configManager.update({\n output: {\n ...config.output,\n format: answers.format,\n copyToClipboard: answers.copyToClipboard,\n showStats: answers.showStats,\n },\n });\n\n console.log(UI.success('Output preferences updated'));\n}\n","import { Command } from 'commander';\nimport { startDashboard } from '../ui/dashboard.js';\n\nexport const dashCommand = new Command('dash')\n .alias('d')\n .alias('dashboard')\n .description('Open interactive dashboard')\n .action(async () => {\n await startDashboard();\n });\n","import { EventEmitter } from 'events';\nimport { getConfig } from '../config/index.js';\n\nexport interface KeyEvent {\n name: string;\n ctrl: boolean;\n meta: boolean;\n shift: boolean;\n sequence: string;\n}\n\nexport type KeyHandler = (key: KeyEvent) => void | Promise<void>;\n\n/**\n * Keyboard input handler for interactive modes\n */\nexport class KeyboardHandler extends EventEmitter {\n private handlers: Map<string, KeyHandler> = new Map();\n private isListening = false;\n\n constructor() {\n super();\n }\n\n /**\n * Start listening for keyboard input\n */\n start(): void {\n if (this.isListening) return;\n\n // Enable raw mode for character-by-character input\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n process.stdin.resume();\n process.stdin.setEncoding('utf8');\n\n process.stdin.on('data', this.handleInput.bind(this));\n this.isListening = true;\n }\n\n /**\n * Stop listening for keyboard input\n */\n stop(): void {\n if (!this.isListening) return;\n\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n process.stdin.removeAllListeners('data');\n this.isListening = false;\n }\n\n /**\n * Register a key handler\n */\n on(key: string, handler: KeyHandler): this {\n this.handlers.set(key.toLowerCase(), handler);\n return this;\n }\n\n /**\n * Remove a key handler\n */\n off(key: string): this {\n this.handlers.delete(key.toLowerCase());\n return this;\n }\n\n /**\n * Handle raw input\n */\n private handleInput(data: string): void {\n const key = this.parseKey(data);\n this.emit('key', key);\n\n // Check for specific handlers\n const keyName = this.getKeyName(key);\n const handler = this.handlers.get(keyName);\n\n if (handler) {\n handler(key);\n }\n\n // Always emit the raw key name\n this.emit(keyName, key);\n }\n\n /**\n * Parse raw input into a KeyEvent\n */\n private parseKey(data: string): KeyEvent {\n const key: KeyEvent = {\n name: '',\n ctrl: false,\n meta: false,\n shift: false,\n sequence: data,\n };\n\n // Handle special sequences\n if (data === '\\x03') {\n key.name = 'c';\n key.ctrl = true;\n } else if (data === '\\x1B') {\n key.name = 'escape';\n } else if (data === '\\r' || data === '\\n') {\n key.name = 'return';\n } else if (data === '\\t') {\n key.name = 'tab';\n } else if (data === '\\x7F') {\n key.name = 'backspace';\n } else if (data === ' ') {\n key.name = 'space';\n } else if (data === '\\x1B[A') {\n key.name = 'up';\n } else if (data === '\\x1B[B') {\n key.name = 'down';\n } else if (data === '\\x1B[C') {\n key.name = 'right';\n } else if (data === '\\x1B[D') {\n key.name = 'left';\n } else if (data === '\\x1B[Z') {\n key.name = 'tab';\n key.shift = true;\n } else if (data.length === 1) {\n key.name = data.toLowerCase();\n key.shift = data !== data.toLowerCase();\n\n // Check for ctrl+letter\n const code = data.charCodeAt(0);\n if (code >= 1 && code <= 26) {\n key.ctrl = true;\n key.name = String.fromCharCode(code + 96);\n }\n } else {\n key.name = data;\n }\n\n return key;\n }\n\n /**\n * Get a normalized key name for handler lookup\n */\n private getKeyName(key: KeyEvent): string {\n let name = '';\n\n if (key.ctrl) name += 'ctrl+';\n if (key.meta) name += 'meta+';\n if (key.shift) name += 'shift+';\n\n name += key.name;\n\n return name.toLowerCase();\n }\n}\n\n/**\n * Create shortcuts help text from config\n */\nexport const getShortcutsHelp = (): Array<{ key: string; action: string }> => {\n const shortcuts = getConfig().shortcuts;\n\n return [\n { key: shortcuts.quit, action: 'Quit' },\n { key: shortcuts.help, action: 'Help' },\n { key: shortcuts.refresh, action: 'Refresh' },\n { key: shortcuts.copy, action: 'Copy to clipboard' },\n { key: shortcuts.create, action: 'Create/Select' },\n { key: shortcuts.back, action: 'Back' },\n { key: '↑/↓', action: 'Navigate' },\n { key: shortcuts.nextProject, action: 'Next project' },\n ];\n};\n\n// Export singleton\nexport const keyboard = new KeyboardHandler();\n","import { GitAnalyzer } from '../core/git-analyzer.js';\nimport { CopilotClient } from '../core/copilot.js';\nimport UI from './renderer.js';\nimport { ASCII } from './ascii.js';\nimport { KeyboardHandler } from './keyboard.js';\nimport { getConfig } from '../config/index.js';\nimport { copyToClipboard } from '../utils/helpers.js';\nimport inquirer from 'inquirer';\n\nconst { colors } = UI;\n\ninterface DashboardState {\n currentView: 'main' | 'standup' | 'pr' | 'week' | 'settings';\n selectedIndex: number;\n isLoading: boolean;\n lastOutput: string | null;\n commits: Array<{ message: string; date: Date }>;\n branch: string;\n stats: { commits: number; files: number; insertions: number; deletions: number };\n}\n\n/**\n * Interactive Dashboard for DevDaily\n */\nexport class Dashboard {\n private git: GitAnalyzer;\n private copilot: CopilotClient;\n private keyboard: KeyboardHandler;\n private state: DashboardState;\n private isRunning = false;\n\n constructor() {\n this.git = new GitAnalyzer();\n this.copilot = new CopilotClient();\n this.keyboard = new KeyboardHandler();\n this.state = {\n currentView: 'main',\n selectedIndex: 0,\n isLoading: false,\n lastOutput: null,\n commits: [],\n branch: '',\n stats: { commits: 0, files: 0, insertions: 0, deletions: 0 },\n };\n }\n\n /**\n * Start the dashboard\n */\n async start(): Promise<void> {\n // Check prerequisites\n if (!(await this.git.isRepository())) {\n console.log(UI.error('Not in a git repository'));\n process.exit(1);\n }\n\n if (!(await this.copilot.isInstalled())) {\n console.log(UI.error('GitHub Copilot CLI not installed'));\n console.log(UI.info('Install with: gh extension install github/gh-copilot'));\n process.exit(1);\n }\n\n this.isRunning = true;\n\n // Load initial data\n await this.loadData();\n\n // Render initial view\n this.render();\n\n // Run main menu loop\n await this.mainMenu();\n }\n\n /**\n * Load git data\n */\n private async loadData(): Promise<void> {\n try {\n this.state.branch = await this.git.getCurrentBranch();\n\n const commits = await this.git.getCommits({\n since: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),\n });\n this.state.commits = commits;\n\n const diffStats = await this.git.getDiffStats();\n this.state.stats = {\n commits: commits.length,\n files: diffStats.filesChanged,\n insertions: diffStats.insertions,\n deletions: diffStats.deletions,\n };\n } catch {\n // Expected: may fail if not in a git repo or no commits exist yet.\n // Dashboard will render with default/empty state values.\n }\n }\n\n /**\n * Render the current view\n */\n private render(): void {\n UI.clear();\n console.log(this.renderMainView());\n }\n\n /**\n * Render the main dashboard view\n */\n private renderMainView(): string {\n const lines: string[] = [];\n\n // Header\n lines.push(UI.header('Dashboard'));\n lines.push('');\n\n // Git status\n lines.push(UI.section('Git Status', ASCII.icons.standup));\n lines.push('');\n lines.push(` ${colors.accent('Branch:')} ${colors.primary(this.state.branch)}`);\n lines.push(\n ` ${colors.accent('Week:')} ${UI.stats([\n { label: 'commits', value: this.state.stats.commits },\n { label: 'files changed', value: this.state.stats.files },\n { label: 'insertions', value: `+${this.state.stats.insertions}`, color: 'green' },\n { label: 'deletions', value: `-${this.state.stats.deletions}`, color: 'red' },\n ])}`\n );\n lines.push('');\n\n // Recent commits\n if (this.state.commits.length > 0) {\n lines.push(colors.bold(' Recent Commits'));\n lines.push('');\n this.state.commits.slice(0, 5).forEach((commit) => {\n const msg =\n commit.message.length > 50 ? commit.message.slice(0, 47) + '...' : commit.message;\n lines.push(` ${colors.muted(ASCII.status.bullet)} ${msg}`);\n });\n lines.push('');\n }\n\n // Shortcuts\n lines.push(UI.divider());\n lines.push('');\n lines.push(\n UI.shortcuts([\n { key: 's', action: 'Standup' },\n { key: 'p', action: 'PR Description' },\n { key: 'w', action: 'Week Summary' },\n { key: 'c', action: 'Config' },\n { key: 'q', action: 'Quit' },\n ])\n );\n lines.push('');\n\n return lines.join('\\n');\n }\n\n /**\n * Main menu loop\n */\n private async mainMenu(): Promise<void> {\n while (this.isRunning) {\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: colors.primary('What would you like to do?'),\n choices: [\n { name: `${ASCII.icons.standup} Generate Standup Notes`, value: 'standup' },\n { name: `${ASCII.icons.pr} Generate PR Description`, value: 'pr' },\n { name: `${ASCII.icons.week} Generate Weekly Summary`, value: 'week' },\n new inquirer.Separator(),\n { name: `${ASCII.icons.config} Configuration`, value: 'config' },\n { name: `${ASCII.status.info} Refresh Data`, value: 'refresh' },\n new inquirer.Separator(),\n { name: `${ASCII.status.cross} Exit`, value: 'exit' },\n ],\n pageSize: 10,\n },\n ]);\n\n switch (action) {\n case 'standup':\n await this.generateStandup();\n break;\n case 'pr':\n await this.generatePR();\n break;\n case 'week':\n await this.generateWeek();\n break;\n case 'config':\n await this.showConfig();\n break;\n case 'refresh':\n await this.refresh();\n break;\n case 'exit':\n this.stop();\n break;\n }\n }\n }\n\n /**\n * Generate standup notes\n */\n private async generateStandup(): Promise<void> {\n const { days } = await inquirer.prompt([\n {\n type: 'list',\n name: 'days',\n message: 'Time range:',\n choices: [\n { name: 'Yesterday (1 day)', value: 1 },\n { name: 'Last 2 days', value: 2 },\n { name: 'Last 3 days', value: 3 },\n { name: 'Last week', value: 7 },\n ],\n },\n ]);\n\n const spinner = UI.spinner('Generating standup notes...');\n spinner.start();\n\n try {\n const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const commits = await this.git.getCommits({ since });\n\n if (commits.length === 0) {\n spinner.stop();\n console.log(UI.warning(`No commits found in the last ${days} day(s)`));\n return;\n }\n\n const messages = commits.map((c) => c.message);\n const standup = await this.copilot.summarizeCommits(messages);\n\n spinner.stop();\n\n console.log('');\n console.log(UI.box(standup, 'Your Standup'));\n console.log(UI.stats([{ label: 'commits analyzed', value: commits.length }]));\n console.log('');\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What next?',\n choices: [\n { name: 'Copy to clipboard', value: 'copy' },\n { name: 'Back to dashboard', value: 'back' },\n ],\n },\n ]);\n\n if (action === 'copy') {\n await copyToClipboard(standup);\n console.log(UI.success('Copied to clipboard!'));\n }\n } catch (error) {\n spinner.stop();\n console.log(UI.error('Failed to generate standup'));\n console.log(colors.muted((error as Error).message));\n }\n }\n\n /**\n * Generate PR description\n */\n private async generatePR(): Promise<void> {\n const config = getConfig();\n\n const { base } = await inquirer.prompt([\n {\n type: 'input',\n name: 'base',\n message: 'Base branch:',\n default: config.pr.defaultBase,\n },\n ]);\n\n const spinner = UI.spinner('Analyzing branch...');\n spinner.start();\n\n try {\n const currentBranch = await this.git.getCurrentBranch();\n\n if (currentBranch === base) {\n spinner.stop();\n console.log(UI.error(`Cannot create PR from ${base} to ${base}`));\n return;\n }\n\n const commits = await this.git.getCommits();\n const files = await this.git.getChangedFiles(base);\n\n spinner.text = 'Generating PR description...';\n\n const description = await this.copilot.generatePRDescription({\n branch: currentBranch,\n commits: commits.map((c) => c.message),\n files,\n issues: [],\n });\n\n spinner.stop();\n\n console.log('');\n console.log(UI.box(description, `PR: ${currentBranch}`));\n console.log(\n UI.stats([\n { label: 'commits', value: commits.length },\n { label: 'files changed', value: files.length },\n ])\n );\n console.log('');\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What next?',\n choices: [\n { name: 'Copy to clipboard', value: 'copy' },\n { name: 'Back to dashboard', value: 'back' },\n ],\n },\n ]);\n\n if (action === 'copy') {\n await copyToClipboard(description);\n console.log(UI.success('Copied to clipboard!'));\n console.log(UI.info('Tip: Use `devdaily pr --create` to create PRs directly'));\n }\n } catch (error) {\n spinner.stop();\n console.log(UI.error('Failed to generate PR description'));\n console.log(colors.muted((error as Error).message));\n }\n }\n\n /**\n * Generate weekly summary\n */\n private async generateWeek(): Promise<void> {\n const spinner = UI.spinner('Generating weekly summary...');\n spinner.start();\n\n try {\n const since = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);\n const commits = await this.git.getCommits({ since });\n\n if (commits.length === 0) {\n spinner.stop();\n console.log(UI.warning('No commits found this week'));\n return;\n }\n\n const stats = await this.git.getDiffStats();\n const messages = commits.map((c) => c.message);\n\n const summary = await this.copilot.generateWeeklySummary({\n commits: messages,\n stats: {\n commits: commits.length,\n linesAdded: stats.insertions,\n linesRemoved: stats.deletions,\n },\n });\n\n spinner.stop();\n\n console.log('');\n console.log(UI.box(summary, 'Weekly Summary'));\n console.log(\n UI.stats([\n { label: 'commits', value: commits.length },\n { label: 'lines added', value: `+${stats.insertions}`, color: 'green' },\n { label: 'lines removed', value: `-${stats.deletions}`, color: 'red' },\n ])\n );\n console.log('');\n\n const { action } = await inquirer.prompt([\n {\n type: 'list',\n name: 'action',\n message: 'What next?',\n choices: [\n { name: 'Copy to clipboard', value: 'copy' },\n { name: 'Back to dashboard', value: 'back' },\n ],\n },\n ]);\n\n if (action === 'copy') {\n await copyToClipboard(summary);\n console.log(UI.success('Copied to clipboard!'));\n }\n } catch (error) {\n spinner.stop();\n console.log(UI.error('Failed to generate weekly summary'));\n console.log(colors.muted((error as Error).message));\n }\n }\n\n /**\n * Show configuration\n */\n private async showConfig(): Promise<void> {\n const config = getConfig();\n\n console.log('');\n console.log(UI.section('Configuration', ASCII.icons.config));\n console.log('');\n console.log(UI.keyValue('Theme', config.theme.primary));\n console.log(UI.keyValue('Default format', config.output.format));\n console.log(UI.keyValue('Copy to clipboard', config.output.copyToClipboard ? 'Yes' : 'No'));\n console.log(UI.keyValue('Default branch', config.pr.defaultBase));\n console.log(UI.keyValue('Week starts', config.week.startDay));\n console.log('');\n\n await inquirer.prompt([\n {\n type: 'input',\n name: 'continue',\n message: 'Press Enter to continue...',\n },\n ]);\n }\n\n /**\n * Refresh data\n */\n private async refresh(): Promise<void> {\n const spinner = UI.spinner('Refreshing...');\n spinner.start();\n\n await this.loadData();\n\n spinner.stop();\n this.render();\n\n console.log(UI.success('Data refreshed'));\n }\n\n /**\n * Stop the dashboard\n */\n stop(): void {\n this.isRunning = false;\n this.keyboard.stop();\n console.log('');\n console.log(UI.info('Goodbye!'));\n }\n}\n\n/**\n * Start the dashboard\n */\nexport const startDashboard = async (): Promise<void> => {\n const dashboard = new Dashboard();\n await dashboard.start();\n};\n","import { Command } from 'commander';\nimport { execa } from 'execa';\nimport UI from '../ui/renderer.js';\nimport { ASCII } from '../ui/ascii.js';\n\nconst { colors } = UI;\n\ninterface CheckResult {\n name: string;\n status: 'ok' | 'warning' | 'error';\n message: string;\n fix?: string;\n}\n\n/**\n * Check if a command exists\n */\nasync function commandExists(cmd: string): Promise<boolean> {\n try {\n await execa('which', [cmd]);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get version of a command\n */\nasync function getVersion(cmd: string, args: string[] = ['--version']): Promise<string | null> {\n try {\n const { stdout } = await execa(cmd, args);\n return stdout.trim().split('\\n')[0];\n } catch {\n return null;\n }\n}\n\n/**\n * Check if gh is authenticated\n */\nasync function isGhAuthenticated(): Promise<boolean> {\n try {\n await execa('gh', ['auth', 'status']);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check which Copilot CLI is installed\n * Returns: 'new' for copilot CLI, 'legacy' for gh copilot extension, null if neither\n */\nasync function getCopilotStatus(): Promise<{ type: 'new' | 'legacy' | null; version?: string }> {\n // Check for new Copilot CLI first (preferred)\n try {\n const { stdout } = await execa('copilot', ['--version']);\n return { type: 'new', version: stdout.trim().split('\\n')[0] };\n } catch {\n // Fallback to legacy gh copilot extension\n try {\n const { stdout } = await execa('gh', ['extension', 'list']);\n if (stdout.includes('copilot')) {\n return { type: 'legacy', version: 'gh extension' };\n }\n } catch {\n // Ignore\n }\n return { type: null };\n }\n}\n\n/**\n * Run all diagnostic checks\n */\nasync function runChecks(): Promise<CheckResult[]> {\n const checks: CheckResult[] = [];\n\n // Check Node.js\n const nodeVersion = await getVersion('node');\n if (nodeVersion) {\n const major = parseInt(nodeVersion.replace('v', '').split('.')[0]);\n if (major >= 18) {\n checks.push({\n name: 'Node.js',\n status: 'ok',\n message: nodeVersion,\n });\n } else {\n checks.push({\n name: 'Node.js',\n status: 'error',\n message: `${nodeVersion} (requires >= 18)`,\n fix: 'Install Node.js 18+ from https://nodejs.org',\n });\n }\n } else {\n checks.push({\n name: 'Node.js',\n status: 'error',\n message: 'Not found',\n fix: 'Install Node.js from https://nodejs.org',\n });\n }\n\n // Check Git\n const gitVersion = await getVersion('git');\n if (gitVersion) {\n checks.push({\n name: 'Git',\n status: 'ok',\n message: gitVersion,\n });\n } else {\n checks.push({\n name: 'Git',\n status: 'error',\n message: 'Not found',\n fix: 'Install Git from https://git-scm.com',\n });\n }\n\n // Check GitHub CLI\n if (await commandExists('gh')) {\n const ghVersion = await getVersion('gh');\n checks.push({\n name: 'GitHub CLI',\n status: 'ok',\n message: ghVersion || 'Installed',\n });\n\n // Check gh auth\n if (await isGhAuthenticated()) {\n checks.push({\n name: 'GitHub Auth',\n status: 'ok',\n message: 'Authenticated',\n });\n } else {\n checks.push({\n name: 'GitHub Auth',\n status: 'error',\n message: 'Not authenticated',\n fix: 'Run: gh auth login',\n });\n }\n\n // Check Copilot CLI (new or legacy)\n const copilotStatus = await getCopilotStatus();\n if (copilotStatus.type === 'new') {\n checks.push({\n name: 'Copilot CLI',\n status: 'ok',\n message: copilotStatus.version || 'Installed',\n });\n } else if (copilotStatus.type === 'legacy') {\n checks.push({\n name: 'Copilot CLI',\n status: 'warning',\n message: 'Using deprecated gh extension. Upgrade to new CLI.',\n fix: 'Run: brew install copilot-cli',\n });\n } else {\n checks.push({\n name: 'Copilot CLI',\n status: 'error',\n message: 'Not found',\n fix: 'Run: brew install copilot-cli',\n });\n }\n } else {\n checks.push({\n name: 'GitHub CLI',\n status: 'error',\n message: 'Not found',\n fix: 'Install from https://cli.github.com',\n });\n checks.push({\n name: 'GitHub Auth',\n status: 'warning',\n message: 'Requires GitHub CLI',\n });\n checks.push({\n name: 'Copilot CLI',\n status: 'warning',\n message: 'Requires GitHub CLI',\n });\n }\n\n return checks;\n}\n\nexport const doctorCommand = new Command('doctor')\n .description('Check system setup and diagnose issues')\n .option('--fix', 'Attempt to fix issues automatically')\n .action(async (options) => {\n console.log('');\n console.log(UI.header('System Check'));\n console.log('');\n\n const spinner = UI.spinner('Running diagnostics...');\n spinner.start();\n\n const checks = await runChecks();\n\n spinner.stop();\n\n // Display results\n console.log(UI.section('Prerequisites', '🔍'));\n console.log('');\n\n const statusIcon = {\n ok: colors.success(ASCII.status.check),\n warning: colors.warning(ASCII.status.warning),\n error: colors.error(ASCII.status.cross),\n };\n\n for (const check of checks) {\n const icon = statusIcon[check.status];\n const name = check.name.padEnd(15);\n const message =\n check.status === 'ok'\n ? colors.muted(check.message)\n : check.status === 'error'\n ? colors.error(check.message)\n : colors.warning(check.message);\n\n console.log(` ${icon} ${name} ${message}`);\n\n if (check.fix && check.status === 'error') {\n console.log(` ${colors.muted('Fix:')} ${colors.accent(check.fix)}`);\n }\n }\n\n console.log('');\n\n // Summary\n const errors = checks.filter((c) => c.status === 'error');\n\n if (errors.length === 0) {\n console.log(UI.success('All checks passed! DevDaily is ready to use.'));\n } else {\n console.log(UI.error(`${errors.length} issue(s) found`));\n console.log('');\n\n if (options.fix) {\n console.log(UI.info('Attempting automatic fixes...'));\n console.log('');\n\n for (const check of errors) {\n if (check.name === 'GitHub Auth') {\n console.log(` ${colors.accent('→')} Running: gh auth login`);\n try {\n await execa('gh', ['auth', 'login'], { stdio: 'inherit' });\n console.log(UI.success('Authenticated successfully'));\n } catch {\n console.log(UI.error('Authentication failed'));\n }\n } else if (check.name === 'Copilot CLI') {\n console.log(` ${colors.accent('→')} Running: brew install copilot-cli`);\n try {\n await execa('brew', ['install', 'copilot-cli'], { stdio: 'inherit' });\n console.log(UI.success('Copilot CLI installed'));\n } catch {\n console.log(UI.error('Installation failed. Try manually: brew install copilot-cli'));\n }\n }\n }\n } else {\n console.log(UI.info('Run `devdaily doctor --fix` to attempt automatic fixes'));\n }\n }\n\n console.log('');\n\n // Quick setup guide if issues found\n if (errors.length > 0) {\n console.log(UI.section('Quick Setup Guide', '📋'));\n console.log('');\n console.log(\n ' ' + colors.muted('1.') + ' Install GitHub CLI: ' + colors.accent('brew install gh')\n );\n console.log(' ' + colors.muted('2.') + ' Authenticate: ' + colors.accent('gh auth login'));\n console.log(\n ' ' +\n colors.muted('3.') +\n ' Install Copilot CLI: ' +\n colors.accent('brew install copilot-cli')\n );\n console.log(\n ' ' + colors.muted('4.') + ' Set up DevDaily: ' + colors.accent('devdaily init')\n );\n console.log('');\n }\n });\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport UI from '../ui/renderer.js';\nimport { ASCII } from '../ui/ascii.js';\nimport { getConfig, getSecrets, ConfigManager } from '../config/index.js';\nimport {\n getProjectManagementClient,\n extractTicketIds,\n JiraClient,\n LinearClient,\n GitHubIssueClient,\n} from '../core/project-management.js';\nimport { type PMConnectionTestResult, type PMTool } from '../core/pm-errors.js';\n\nconst { colors } = UI;\n\n// ─── Helper: render a connection test result ──────────────────────────────────\n\nfunction renderTestResult(result: PMConnectionTestResult): void {\n const icon = result.success\n ? colors.success(ASCII.status.check)\n : colors.error(ASCII.status.cross);\n\n console.log(` ${icon} ${result.message}`);\n\n if (result.details.responseTimeMs !== undefined) {\n console.log(\n ` ${colors.muted('Response time:')} ${colors.accent(`${result.details.responseTimeMs}ms`)}`\n );\n }\n\n if (!result.success && result.error) {\n console.log(` ${colors.muted('Hint:')} ${colors.warning(result.error.hint)}`);\n }\n}\n\n// ─── Helper: show credential status ───────────────────────────────────────────\n\nfunction showCredentialStatus(tool: PMTool): void {\n const secrets = getSecrets();\n const config = getConfig();\n\n console.log('');\n console.log(UI.section('Credential Status', '🔑'));\n console.log('');\n\n if (tool === 'jira') {\n const baseUrl =\n secrets.jira?.baseUrl ||\n config.projectManagement.jira.baseUrl ||\n process.env.JIRA_BASE_URL ||\n '';\n const email = secrets.jira?.email || process.env.JIRA_EMAIL || '';\n const token = secrets.jira?.apiToken || process.env.JIRA_API_TOKEN || '';\n const projectKey = config.projectManagement.jira.projectKey || '';\n const prefix = config.projectManagement.ticketPrefix || '';\n\n showField('Base URL', baseUrl, 'JIRA_BASE_URL');\n showField('Email', email, 'JIRA_EMAIL');\n showField('API Token', token ? maskSecret(token) : '', 'JIRA_API_TOKEN');\n showField('Project Key', projectKey, '.devdaily.json → projectManagement.jira.projectKey');\n showField('Ticket Prefix', prefix, '.devdaily.json → projectManagement.ticketPrefix');\n } else if (tool === 'linear') {\n const apiKey = secrets.linear?.apiKey || process.env.LINEAR_API_KEY || '';\n const teamKey = config.projectManagement.linear.teamKey || '';\n const prefix = config.projectManagement.ticketPrefix || '';\n\n showField('API Key', apiKey ? maskSecret(apiKey) : '', 'LINEAR_API_KEY');\n showField('Team Key', teamKey, '.devdaily.json → projectManagement.linear.teamKey');\n showField('Ticket Prefix', prefix, '.devdaily.json → projectManagement.ticketPrefix');\n } else if (tool === 'github') {\n showField('Auth', '(managed by gh CLI)', 'gh auth login');\n const prefix = config.projectManagement.ticketPrefix || '';\n showField('Ticket Prefix', prefix, '.devdaily.json → projectManagement.ticketPrefix');\n }\n}\n\nfunction showField(label: string, value: string, source: string): void {\n const icon = value ? colors.success(ASCII.status.check) : colors.error(ASCII.status.cross);\n const displayValue = value || colors.muted('not set');\n console.log(` ${icon} ${label.padEnd(16)} ${displayValue}`);\n if (!value) {\n console.log(` ${colors.muted('Set via:')} ${colors.accent(source)}`);\n }\n}\n\nfunction maskSecret(secret: string): string {\n if (secret.length <= 8) return '••••••••';\n return secret.slice(0, 4) + '••••' + secret.slice(-4);\n}\n\n// ─── Helper: fetch a sample ticket to prove it works ──────────────────────────\n\nasync function trySampleTicket(tool: PMTool): Promise<void> {\n const client = getProjectManagementClient();\n\n console.log('');\n console.log(UI.section('Live Ticket Test', '🎫'));\n console.log('');\n\n // Ask user for a ticket ID\n const config = getConfig();\n const prefix = config.projectManagement.ticketPrefix;\n\n let placeholder = '';\n if (tool === 'jira') placeholder = prefix ? `${prefix}-123` : 'PROJ-123';\n else if (tool === 'linear') placeholder = prefix ? `${prefix}-42` : 'ENG-42';\n else if (tool === 'github') placeholder = '#1';\n\n const { ticketId } = await inquirer.prompt([\n {\n type: 'input',\n name: 'ticketId',\n message: `Enter a ticket ID to fetch (e.g. ${placeholder}):`,\n validate: (input: string) => {\n if (!input.trim()) return 'Please enter a ticket ID';\n return true;\n },\n },\n ]);\n\n const spinner = UI.spinner(`Fetching ${ticketId} from ${tool}...`);\n spinner.start();\n\n try {\n const ticket = await client.getTicket(ticketId.trim());\n spinner.stop();\n\n if (ticket) {\n console.log('');\n console.log(colors.success(` ${ASCII.status.check} Ticket found!`));\n console.log('');\n console.log(` ${colors.accent('ID:')} ${ticket.id}`);\n console.log(` ${colors.accent('Title:')} ${ticket.title}`);\n console.log(` ${colors.accent('Status:')} ${ticket.status}`);\n console.log(` ${colors.accent('Type:')} ${ticket.type}`);\n if (ticket.priority) {\n console.log(` ${colors.accent('Priority:')} ${ticket.priority}`);\n }\n if (ticket.assignee) {\n console.log(` ${colors.accent('Assignee:')} ${ticket.assignee}`);\n }\n if (ticket.labels.length > 0) {\n console.log(` ${colors.accent('Labels:')} ${ticket.labels.join(', ')}`);\n }\n if (ticket.url) {\n console.log(` ${colors.accent('URL:')} ${colors.muted(ticket.url)}`);\n }\n\n // Show how it looks as AI context\n console.log('');\n console.log(colors.muted(' This is how DevDaily will present it to Copilot:'));\n console.log('');\n const context = client.formatTicketForContext(ticket);\n for (const line of context.split('\\n')) {\n console.log(` ${colors.muted('│')} ${line}`);\n }\n } else {\n console.log('');\n console.log(colors.warning(` ${ASCII.status.warning} Ticket \"${ticketId}\" not found`));\n console.log(colors.muted(` Make sure the ID is correct and you have access`));\n }\n } catch (err) {\n spinner.stop();\n console.log('');\n console.log(\n colors.error(` ${ASCII.status.cross} Failed to fetch ticket: ${(err as Error).message}`)\n );\n }\n}\n\n// ─── Helper: test ticket extraction from branch/commit ────────────────────────\n\nfunction testTicketExtraction(): void {\n const config = getConfig();\n const tool = config.projectManagement.tool;\n const prefix = config.projectManagement.ticketPrefix;\n\n console.log('');\n console.log(UI.section('Ticket Pattern Matching', '🔍'));\n console.log('');\n\n // Show current config\n console.log(` ${colors.accent('Tool:')} ${tool}`);\n console.log(` ${colors.accent('Prefix:')} ${prefix || colors.muted('(none)')}`);\n console.log('');\n\n // Test against common patterns\n interface PatternTest {\n input: string;\n label: string;\n }\n\n const testCases: PatternTest[] = [];\n\n if (tool === 'jira' || tool === 'linear') {\n const p = prefix || 'PROJ';\n testCases.push(\n { input: `feature/${p}-123-add-login`, label: 'Branch name' },\n { input: `fix: resolve ${p}-456 validation bug`, label: 'Commit msg' },\n { input: `${p}-789/implement-oauth`, label: 'Branch name' },\n { input: `chore: update deps, refs ${p}-10 ${p}-11`, label: 'Multi-ticket' }\n );\n } else if (tool === 'github') {\n testCases.push(\n { input: 'fix/#42-button-color', label: 'Branch name' },\n { input: 'fix: resolve #123 login issue', label: 'Commit msg' },\n { input: 'feat: implements #10 and closes #11', label: 'Multi-ticket' },\n { input: 'feature/add-login-page', label: 'No ticket' }\n );\n }\n\n for (const tc of testCases) {\n const ids = extractTicketIds(tc.input);\n const icon =\n ids.length > 0 ? colors.success(ASCII.status.check) : colors.muted(ASCII.status.pending);\n const found = ids.length > 0 ? colors.success(ids.join(', ')) : colors.muted('(none)');\n\n console.log(\n ` ${icon} ${tc.label.padEnd(14)} ${colors.muted('\"')}${tc.input}${colors.muted('\"')}`\n );\n console.log(` ${colors.muted('→ Extracted:')} ${found}`);\n }\n}\n\n// ─── Helper: interactive quick setup for a tool ───────────────────────────────\n\nasync function quickSetup(tool: PMTool): Promise<boolean> {\n console.log('');\n console.log(UI.section('Quick Setup', '⚙️'));\n console.log('');\n\n if (tool === 'jira') {\n console.log(colors.muted(' Your Jira API token can be created at:'));\n console.log(colors.accent(' https://id.atlassian.com/manage-profile/security/api-tokens'));\n console.log('');\n\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'baseUrl',\n message: 'Jira base URL:',\n default: 'https://yourcompany.atlassian.net',\n validate: (input: string) => input.startsWith('http') || 'Must be a valid URL',\n },\n {\n type: 'input',\n name: 'email',\n message: 'Your Jira email:',\n validate: (input: string) => input.includes('@') || 'Must be a valid email',\n },\n {\n type: 'password',\n name: 'apiToken',\n message: 'Jira API token:',\n mask: '*',\n validate: (input: string) => input.length > 0 || 'API token is required',\n },\n {\n type: 'input',\n name: 'projectKey',\n message: 'Default project key (optional, e.g. PROJ):',\n },\n {\n type: 'input',\n name: 'ticketPrefix',\n message: 'Ticket prefix for extraction (optional, e.g. PROJ):',\n },\n ]);\n\n // Save secrets\n const configManager = ConfigManager.getInstance();\n configManager.saveSecrets(\n {\n jira: {\n baseUrl: answers.baseUrl,\n email: answers.email,\n apiToken: answers.apiToken,\n },\n },\n false\n );\n\n // Update config\n const currentConfig = getConfig();\n configManager.saveLocal({\n ...currentConfig,\n projectManagement: {\n ...currentConfig.projectManagement,\n tool: 'jira',\n ticketPrefix: answers.ticketPrefix || currentConfig.projectManagement.ticketPrefix,\n jira: {\n ...currentConfig.projectManagement.jira,\n projectKey: answers.projectKey || undefined,\n baseUrl: answers.baseUrl,\n },\n },\n });\n\n // Add secrets to gitignore\n configManager.addSecretsToGitignore();\n\n console.log('');\n console.log(UI.success('Jira credentials saved'));\n console.log(colors.muted(' Secrets stored in .devdaily.secrets.json'));\n console.log(colors.muted(' Added to .gitignore'));\n return true;\n } else if (tool === 'linear') {\n console.log(colors.muted(' Get your API key from Linear:'));\n console.log(colors.accent(' Settings → Account → API → Personal API keys'));\n console.log('');\n\n const answers = await inquirer.prompt([\n {\n type: 'password',\n name: 'apiKey',\n message: 'Linear API key:',\n mask: '*',\n validate: (input: string) => input.length > 0 || 'API key is required',\n },\n {\n type: 'input',\n name: 'teamKey',\n message: 'Team key (optional, e.g. ENG):',\n },\n {\n type: 'input',\n name: 'ticketPrefix',\n message: 'Ticket prefix for extraction (optional, e.g. ENG):',\n },\n ]);\n\n // Save secrets\n const configManager = ConfigManager.getInstance();\n configManager.saveSecrets(\n {\n linear: {\n apiKey: answers.apiKey,\n },\n },\n false\n );\n\n // Update config\n const currentConfig = getConfig();\n configManager.saveLocal({\n ...currentConfig,\n projectManagement: {\n ...currentConfig.projectManagement,\n tool: 'linear',\n ticketPrefix: answers.ticketPrefix || currentConfig.projectManagement.ticketPrefix,\n linear: {\n ...currentConfig.projectManagement.linear,\n teamKey: answers.teamKey || undefined,\n },\n },\n });\n\n // Add secrets to gitignore\n configManager.addSecretsToGitignore();\n\n console.log('');\n console.log(UI.success('Linear credentials saved'));\n console.log(colors.muted(' Secrets stored in .devdaily.secrets.json'));\n console.log(colors.muted(' Added to .gitignore'));\n return true;\n } else if (tool === 'github') {\n console.log(colors.muted(' GitHub uses the gh CLI for authentication.'));\n console.log(colors.muted(' If you are not logged in, run: gh auth login'));\n console.log('');\n\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'ticketPrefix',\n message: 'Ticket prefix for extraction (optional):',\n },\n ]);\n\n if (answers.ticketPrefix) {\n const configManager = ConfigManager.getInstance();\n const currentConfig = getConfig();\n configManager.saveLocal({\n ...currentConfig,\n projectManagement: {\n ...currentConfig.projectManagement,\n tool: 'github',\n ticketPrefix: answers.ticketPrefix,\n },\n });\n }\n\n console.log('');\n console.log(UI.success('GitHub configuration saved'));\n return true;\n }\n\n return false;\n}\n\n// ─── Main Command ─────────────────────────────────────────────────────────────\n\nexport const connectCommand = new Command('connect')\n .description('Test and configure PM tool connections (Jira, Linear, GitHub)')\n .option('--tool <tool>', 'PM tool to test (jira, linear, github)')\n .option('--test', 'Run connection test only (non-interactive)')\n .option('--setup', 'Run interactive setup for the selected tool')\n .option('--ticket <id>', 'Fetch a specific ticket to verify')\n .option('--status', 'Show current credential status only')\n .action(async (options) => {\n console.log('');\n console.log(UI.header('PM Connection Manager'));\n console.log('');\n\n // Determine which tool to use\n let tool: PMTool;\n\n if (options.tool) {\n if (!['jira', 'linear', 'github'].includes(options.tool)) {\n console.log(UI.error(`Unsupported tool: ${options.tool}. Use jira, linear, or github.`));\n process.exit(1);\n }\n tool = options.tool as PMTool;\n } else if (options.test || options.status) {\n // Use configured tool for non-interactive modes\n const config = getConfig();\n tool =\n config.projectManagement.tool === 'none'\n ? 'github'\n : (config.projectManagement.tool as PMTool);\n } else {\n // Interactive: ask user\n const { selectedTool } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedTool',\n message: 'Which PM tool do you want to connect?',\n choices: [\n {\n name: `${colors.accent('🐙')} GitHub Issues (uses gh CLI)`,\n value: 'github',\n },\n {\n name: `${colors.accent('🔷')} Jira (REST API)`,\n value: 'jira',\n },\n {\n name: `${colors.accent('📐')} Linear (GraphQL API)`,\n value: 'linear',\n },\n ],\n },\n ]);\n tool = selectedTool;\n }\n\n console.log(` ${colors.accent('Tool:')} ${tool.charAt(0).toUpperCase() + tool.slice(1)}`);\n\n // ── Status-only mode ────────────────────────────────────────────────\n if (options.status) {\n showCredentialStatus(tool);\n console.log('');\n return;\n }\n\n // ── Setup mode ──────────────────────────────────────────────────────\n if (options.setup) {\n await quickSetup(tool);\n console.log('');\n return;\n }\n\n // ── Non-interactive test mode ───────────────────────────────────────\n if (options.test) {\n showCredentialStatus(tool);\n\n console.log('');\n console.log(UI.section('Connection Test', '🔌'));\n console.log('');\n\n const client = getProjectManagementClient();\n const result = await client.testConnection();\n renderTestResult(result);\n\n if (result.success) {\n testTicketExtraction();\n }\n\n // Fetch specific ticket if requested\n if (options.ticket && result.success) {\n const spinner = UI.spinner(`Fetching ${options.ticket} from ${tool}...`);\n spinner.start();\n try {\n const ticket = await client.getTicket(options.ticket);\n spinner.stop();\n if (ticket) {\n console.log('');\n console.log(\n colors.success(` ${ASCII.status.check} Ticket found: [${ticket.id}] ${ticket.title}`)\n );\n } else {\n console.log('');\n console.log(\n colors.warning(` ${ASCII.status.warning} Ticket \"${options.ticket}\" not found`)\n );\n }\n } catch (err) {\n spinner.stop();\n console.log(colors.error(` ${ASCII.status.cross} Error: ${(err as Error).message}`));\n }\n }\n\n console.log('');\n process.exit(result.success ? 0 : 1);\n }\n\n // ── Full interactive mode ───────────────────────────────────────────\n\n // Step 1: Show credential status\n showCredentialStatus(tool);\n\n // Step 2: Check if setup is needed\n const missingFields =\n tool === 'github'\n ? []\n : tool === 'jira'\n ? new JiraClient().getMissingConfig()\n : new LinearClient().getMissingConfig();\n\n if (missingFields.length > 0) {\n console.log('');\n console.log(UI.warning(`Missing configuration: ${missingFields.join(', ')}`));\n\n const { wantSetup } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'wantSetup',\n message: 'Would you like to set up credentials now?',\n default: true,\n },\n ]);\n\n if (wantSetup) {\n const didSetup = await quickSetup(tool);\n if (!didSetup) {\n console.log('');\n return;\n }\n } else {\n console.log('');\n console.log(UI.info('Skipping setup. Run `devdaily connect --setup` later.'));\n console.log('');\n return;\n }\n }\n\n // Step 3: Test connection\n console.log('');\n console.log(UI.section('Connection Test', '🔌'));\n console.log('');\n\n const spinner = UI.spinner(`Testing ${tool} connection...`);\n spinner.start();\n\n // Re-create client to pick up any newly saved credentials\n // ConfigManager is a singleton so we need to get a fresh client\n const freshClient =\n tool === 'jira'\n ? new JiraClient()\n : tool === 'linear'\n ? new LinearClient()\n : new GitHubIssueClient();\n\n const result = await freshClient.testConnection();\n spinner.stop();\n\n renderTestResult(result);\n\n if (!result.success) {\n console.log('');\n console.log(UI.info('Fix the issue above and run `devdaily connect` again.'));\n console.log('');\n return;\n }\n\n // Step 4: Test ticket extraction patterns\n testTicketExtraction();\n\n // Step 5: Offer to fetch a sample ticket\n console.log('');\n const { wantTicketTest } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'wantTicketTest',\n message: 'Would you like to fetch a real ticket to verify?',\n default: true,\n },\n ]);\n\n if (wantTicketTest) {\n await trySampleTicket(tool);\n }\n\n // Step 6: Summary\n console.log('');\n console.log(UI.section('Summary', '📋'));\n console.log('');\n console.log(\n ` ${colors.success(ASCII.status.check)} ${tool.charAt(0).toUpperCase() + tool.slice(1)} integration is ${colors.success('ready')}`\n );\n console.log('');\n console.log(colors.muted(' DevDaily will now:'));\n console.log(colors.muted(' • Extract ticket IDs from your branches and commits'));\n console.log(colors.muted(' • Fetch ticket details to enrich standup & PR context'));\n console.log(colors.muted(' • Pass ticket info to Copilot for smarter summaries'));\n console.log('');\n console.log(\n colors.muted(' Try it:') +\n ` ${colors.accent('devdaily standup')} or ${colors.accent('devdaily pr')}`\n );\n console.log('');\n });\n","import { UI } from './renderer.js';\nimport { ASCII } from './ascii.js';\nimport { getConfig } from '../config/index.js';\n\nconst { colors } = UI;\n\ninterface CommandDef {\n name: string;\n aliases: string[];\n description: string;\n icon: string;\n options: Array<{\n flag: string;\n short?: string;\n description: string;\n default?: string;\n }>;\n examples: string[];\n}\n\nconst COMMANDS: CommandDef[] = [\n {\n name: 'standup',\n aliases: ['s', 'su', 'daily'],\n description: 'Generate standup notes from your recent commits',\n icon: ASCII.icons.standup,\n options: [\n { flag: '--days', short: '-d', description: 'Number of days to look back', default: '1' },\n {\n flag: '--format',\n short: '-f',\n description: 'Output format (markdown|slack|plain|json)',\n default: 'markdown',\n },\n { flag: '--ticket', short: '-t', description: 'Include specific ticket for context' },\n { flag: '--no-tickets', description: 'Skip fetching ticket context' },\n { flag: '--no-copy', description: 'Do not copy to clipboard' },\n { flag: '--author', short: '-a', description: 'Filter by author email' },\n ],\n examples: [\n 'devdaily standup',\n 'devdaily s -d 3',\n 'devdaily standup --ticket=PROJ-123',\n 'dd s # using alias',\n ],\n },\n {\n name: 'pr',\n aliases: ['p', 'pull'],\n description: 'Generate PR description from current branch',\n icon: ASCII.icons.pr,\n options: [\n {\n flag: '--base',\n short: '-b',\n description: 'Base branch to compare against',\n default: 'main',\n },\n { flag: '--create', short: '-c', description: 'Create PR on GitHub immediately' },\n { flag: '--draft', short: '-d', description: 'Create as draft PR' },\n { flag: '--ticket', short: '-t', description: 'Include specific ticket for context' },\n { flag: '--no-tickets', description: 'Skip fetching ticket context' },\n { flag: '--no-copy', description: 'Do not copy to clipboard' },\n ],\n examples: [\n 'devdaily pr',\n 'devdaily p --base=develop',\n 'devdaily pr --ticket=PROJ-123',\n 'devdaily pr -c -d # create draft PR',\n ],\n },\n {\n name: 'week',\n aliases: ['w', 'weekly'],\n description: 'Generate weekly work summary',\n icon: ASCII.icons.week,\n options: [\n { flag: '--last', short: '-l', description: 'Show last week instead of current week' },\n { flag: '--start', short: '-s', description: 'Custom start date (YYYY-MM-DD)' },\n { flag: '--no-tickets', description: 'Skip fetching closed tickets' },\n { flag: '--no-copy', description: 'Do not copy to clipboard' },\n ],\n examples: ['devdaily week', 'devdaily w --last', 'devdaily week --start=2026-02-01'],\n },\n {\n name: 'dash',\n aliases: ['d', 'dashboard'],\n description: 'Open interactive dashboard',\n icon: ASCII.icons.dash,\n options: [],\n examples: ['devdaily dash', 'devdaily d', 'dd # with alias'],\n },\n {\n name: 'init',\n aliases: [],\n description: 'Set up DevDaily (aliases, shell completions)',\n icon: ASCII.icons.init,\n options: [\n { flag: '--global', short: '-g', description: 'Install globally for all projects' },\n { flag: '--alias', description: 'Only set up shell alias (dd)' },\n { flag: '--completions', description: 'Only set up shell completions' },\n ],\n examples: ['devdaily init', 'devdaily init --global', 'devdaily init --alias'],\n },\n {\n name: 'config',\n aliases: ['cfg'],\n description: 'Manage configuration',\n icon: ASCII.icons.config,\n options: [\n { flag: '--edit', short: '-e', description: 'Open config in editor' },\n { flag: '--reset', description: 'Reset to defaults' },\n { flag: '--path', description: 'Show config file path' },\n ],\n examples: ['devdaily config', 'devdaily config --edit', 'devdaily config --path'],\n },\n {\n name: 'doctor',\n aliases: ['check', 'setup'],\n description: 'Check system requirements and fix issues',\n icon: '🩺',\n options: [{ flag: '--fix', description: 'Attempt to automatically fix issues' }],\n examples: ['devdaily doctor', 'devdaily doctor --fix', 'devdaily check'],\n },\n];\n\n/**\n * Render the main help screen\n */\nexport const renderMainHelp = (): string => {\n const lines: string[] = [];\n const config = getConfig();\n\n // Header\n if (config.ascii) {\n lines.push(colors.gradient(ASCII.logoSmall.trim(), ['cyan', 'blue', 'magenta']));\n } else {\n lines.push(colors.gradient('◆ devdaily', ['cyan', 'blue']));\n }\n lines.push('');\n lines.push(colors.muted(' Your AI-powered developer memory'));\n lines.push(colors.muted(' Auto-generate standup notes, PR descriptions, and weekly summaries'));\n lines.push('');\n\n // Usage\n lines.push(colors.bold('USAGE'));\n lines.push('');\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('devdaily')} ${colors.accent('<command>')} ${colors.muted('[options]')}`\n );\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('dd')} ${colors.accent('<command>')} ${colors.muted('[options]')} ${colors.muted('# with alias')}`\n );\n lines.push('');\n\n // Commands\n lines.push(colors.bold('COMMANDS'));\n lines.push('');\n\n COMMANDS.forEach((cmd) => {\n const aliases = cmd.aliases.length > 0 ? colors.muted(` (${cmd.aliases.join(', ')})`) : '';\n const icon = colors.accent(cmd.icon);\n const name = colors.primary(cmd.name.padEnd(12));\n lines.push(` ${icon} ${name}${cmd.description}${aliases}`);\n });\n\n lines.push('');\n\n // Quick start\n lines.push(colors.bold('QUICK START'));\n lines.push('');\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('devdaily init')} ${colors.muted('# Set up aliases & completions')}`\n );\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('devdaily standup')} ${colors.muted(\"# Generate today's standup\")}`\n );\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('devdaily pr')} ${colors.muted('# Generate PR description')}`\n );\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('devdaily dash')} ${colors.muted('# Open interactive dashboard')}`\n );\n lines.push('');\n\n // Shortcuts hint\n lines.push(colors.bold('SHORTCUTS'));\n lines.push('');\n lines.push(\n ` ${colors.accent('[q]')} quit ${colors.accent('[?]')} help ${colors.accent('[r]')} refresh ${colors.accent('[c]')} copy ${colors.accent('[↵]')} select`\n );\n lines.push('');\n\n // Footer\n lines.push(colors.muted('─'.repeat(60)));\n lines.push('');\n lines.push(\n ` ${colors.muted('Run')} ${colors.primary('devdaily <command> --help')} ${colors.muted('for detailed command help')}`\n );\n lines.push(\n ` ${colors.muted('Docs:')} ${colors.accent.underline('https://github.com/hempun10/devdaily')}`\n );\n lines.push('');\n\n return lines.join('\\n');\n};\n\n/**\n * Render help for a specific command\n */\nexport const renderCommandHelp = (commandName: string): string | null => {\n const cmd = COMMANDS.find((c) => c.name === commandName || c.aliases.includes(commandName));\n\n if (!cmd) {\n return null;\n }\n\n const lines: string[] = [];\n\n // Header\n lines.push('');\n lines.push(`${colors.accent(cmd.icon)} ${colors.bold(colors.primary(cmd.name))}`);\n lines.push(colors.muted(cmd.description));\n lines.push('');\n\n // Aliases\n if (cmd.aliases.length > 0) {\n lines.push(colors.bold('ALIASES'));\n lines.push('');\n lines.push(` ${cmd.aliases.map((a) => colors.accent(a)).join(', ')}`);\n lines.push('');\n }\n\n // Usage\n lines.push(colors.bold('USAGE'));\n lines.push('');\n lines.push(\n ` ${colors.muted('$')} ${colors.primary('devdaily')} ${colors.accent(cmd.name)} ${colors.muted('[options]')}`\n );\n lines.push('');\n\n // Options\n if (cmd.options.length > 0) {\n lines.push(colors.bold('OPTIONS'));\n lines.push('');\n\n cmd.options.forEach((opt) => {\n const shortStr = opt.short ? `${colors.accent(opt.short)}, ` : ' ';\n const flagStr = colors.accent(opt.flag.padEnd(16));\n const defaultStr = opt.default ? colors.muted(` [default: ${opt.default}]`) : '';\n lines.push(` ${shortStr}${flagStr} ${opt.description}${defaultStr}`);\n });\n lines.push('');\n }\n\n // Examples\n if (cmd.examples.length > 0) {\n lines.push(colors.bold('EXAMPLES'));\n lines.push('');\n cmd.examples.forEach((ex) => {\n lines.push(` ${colors.muted('$')} ${colors.primary(ex)}`);\n });\n lines.push('');\n }\n\n return lines.join('\\n');\n};\n\n/**\n * Get all command names and aliases for validation\n */\nexport const getAllCommandNames = (): string[] => {\n return COMMANDS.flatMap((cmd) => [cmd.name, ...cmd.aliases]);\n};\n\n/**\n * Get command definition\n */\nexport const getCommand = (name: string): CommandDef | undefined => {\n return COMMANDS.find((c) => c.name === name || c.aliases.includes(name));\n};\n\nexport { COMMANDS };\n"],"mappings":"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","names":["Command","execa","execa","execa","config","config","execa","TICKET_PATTERNS","execa","join","config","join","execa","config","colors","config","description","existsSync","readFileSync","writeFileSync","mkdirSync","homedir","join","existing","execa","config","existsSync","writeFileSync","readFileSync","mkdirSync","join","unlinkSync","colors","config","sendToSlack","sendToDiscord","inquirer","Command","readFile","access","join","fileExists","execa","execa","execa","colors","Command","config","execa","createSpinner","Command","colors","Command","config","genSpinner","summary","title","Command","colors","Command","config","Command","colors","Command","Command","colors","Command","config","stats","limit","Command","existsSync","readFileSync","appendFileSync","writeFileSync","homedir","join","inquirer","colors","join","homedir","existsSync","readFileSync","appendFileSync","Command","inquirer","config","writeFileSync","Command","inquirer","Command","config","inquirer","Command","inquirer","colors","config","Command","Command","execa","colors","execa","Command","Command","inquirer","colors","config","inquirer","Command","result","spinner","colors","config","colors","require","Command"]}