@markmdev/pebble 0.1.18 → 0.1.21

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/index.ts","../../src/shared/types.ts","../../src/cli/lib/storage.ts","../../src/cli/lib/id.ts","../../src/cli/lib/git.ts","../../src/cli/lib/state.ts","../../src/shared/time.ts","../../src/cli/lib/output.ts","../../src/cli/commands/create.ts","../../src/cli/commands/update.ts","../../src/cli/commands/close.ts","../../src/cli/commands/reopen.ts","../../src/cli/commands/delete.ts","../../src/cli/commands/restore.ts","../../src/cli/commands/claim.ts","../../src/cli/commands/list.ts","../../src/cli/commands/show.ts","../../src/cli/commands/ready.ts","../../src/cli/commands/blocked.ts","../../src/cli/commands/dep.ts","../../src/cli/commands/comments.ts","../../src/cli/commands/graph.ts","../../src/cli/commands/ui.ts","../../src/cli/commands/import.ts","../../src/cli/commands/merge.ts","../../src/cli/commands/summary.ts","../../src/cli/commands/history.ts","../../src/cli/commands/search.ts","../../src/cli/commands/verifications.ts","../../src/cli/commands/init.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { createCommand } from './commands/create.js';\nimport { updateCommand } from './commands/update.js';\nimport { closeCommand } from './commands/close.js';\nimport { reopenCommand } from './commands/reopen.js';\nimport { deleteCommand } from './commands/delete.js';\nimport { restoreCommand } from './commands/restore.js';\nimport { claimCommand } from './commands/claim.js';\nimport { listCommand } from './commands/list.js';\nimport { showCommand } from './commands/show.js';\nimport { readyCommand } from './commands/ready.js';\nimport { blockedCommand } from './commands/blocked.js';\nimport { depCommand } from './commands/dep.js';\nimport { commentsCommand } from './commands/comments.js';\nimport { graphCommand } from './commands/graph.js';\nimport { uiCommand } from './commands/ui.js';\nimport { importCommand } from './commands/import.js';\nimport { mergeCommand } from './commands/merge.js';\nimport { summaryCommand } from './commands/summary.js';\nimport { historyCommand } from './commands/history.js';\nimport { searchCommand } from './commands/search.js';\nimport { verificationsCommand } from './commands/verifications.js';\nimport { initCommand } from './commands/init.js';\n\n// Read version from package.json\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('pebble')\n .description('A lightweight JSONL-based issue tracker')\n .version(packageJson.version);\n\n// Global options\nprogram.option('-P, --pretty', 'Human-readable output (default: JSON)');\nprogram.option('--json', 'JSON output (this is the default, flag not needed)');\nprogram.option('--local', 'Use local .pebble directory even in a git worktree');\n\n// Handle --local flag by setting environment variable before commands run\nprogram.hook('preAction', () => {\n if (program.opts().local) {\n process.env.PEBBLE_LOCAL = '1';\n }\n});\n\n// Register all commands\ncreateCommand(program);\nupdateCommand(program);\ncloseCommand(program);\nreopenCommand(program);\ndeleteCommand(program);\nrestoreCommand(program);\nclaimCommand(program);\nlistCommand(program);\nshowCommand(program);\nreadyCommand(program);\nblockedCommand(program);\ndepCommand(program);\ncommentsCommand(program);\ngraphCommand(program);\nuiCommand(program);\nimportCommand(program);\nmergeCommand(program);\nsummaryCommand(program);\nhistoryCommand(program);\nsearchCommand(program);\nverificationsCommand(program);\ninitCommand(program);\n\nprogram.parse();\n","// Issue types\nexport const ISSUE_TYPES = ['task', 'bug', 'epic', 'verification'] as const;\nexport type IssueType = (typeof ISSUE_TYPES)[number];\n\n// Priority levels (0 = critical, 4 = backlog)\nexport const PRIORITIES = [0, 1, 2, 3, 4] as const;\nexport type Priority = (typeof PRIORITIES)[number];\n\n// Status values\nexport const STATUSES = ['open', 'in_progress', 'blocked', 'pending_verification', 'closed'] as const;\nexport type Status = (typeof STATUSES)[number];\n\n// Comment interface\nexport interface Comment {\n text: string;\n timestamp: string; // ISO timestamp\n author?: string;\n}\n\n// Issue interface - the current state of an issue\nexport interface Issue {\n id: string; // PREFIX-xxxxxx (6 char alphanumeric suffix)\n title: string;\n type: IssueType;\n priority: Priority;\n status: Status;\n description?: string;\n parent?: string; // ID of parent epic\n blockedBy: string[]; // IDs of blocking issues\n relatedTo: string[]; // IDs of related issues (bidirectional, non-blocking)\n verifies?: string; // ID of issue this verifies (only for type: verification)\n comments: Comment[];\n createdAt: string; // ISO timestamp\n updatedAt: string; // ISO timestamp\n lastSource?: string; // Folder name from most recent event (worktree/repo root)\n deleted?: boolean; // Soft-deleted flag\n deletedAt?: string; // ISO timestamp of deletion\n _sources?: string[]; // File paths where this issue exists (multi-worktree)\n}\n\n// Event types for append-only JSONL\nexport const EVENT_TYPES = ['create', 'update', 'close', 'reopen', 'comment', 'delete', 'restore'] as const;\nexport type EventType = (typeof EVENT_TYPES)[number];\n\n// Base event interface\ninterface BaseEvent {\n type: EventType;\n issueId: string;\n timestamp: string; // ISO timestamp\n source?: string; // Folder name where command was executed (worktree/repo root)\n}\n\n// Create event - includes all initial issue data\nexport interface CreateEvent extends BaseEvent {\n type: 'create';\n data: {\n title: string;\n type: IssueType;\n priority: Priority;\n description?: string;\n parent?: string;\n verifies?: string; // ID of issue this verifies (only for type: verification)\n };\n}\n\n// Update event - partial issue update\nexport interface UpdateEvent extends BaseEvent {\n type: 'update';\n data: {\n title?: string;\n type?: IssueType;\n priority?: Priority;\n status?: Status;\n description?: string;\n parent?: string;\n blockedBy?: string[];\n relatedTo?: string[];\n };\n}\n\n// Close event\nexport interface CloseEvent extends BaseEvent {\n type: 'close';\n data: {\n reason?: string;\n };\n}\n\n// Reopen event\nexport interface ReopenEvent extends BaseEvent {\n type: 'reopen';\n data: {\n reason?: string;\n };\n}\n\n// Comment event\nexport interface CommentEvent extends BaseEvent {\n type: 'comment';\n data: Comment;\n}\n\n// Delete event - soft delete\nexport interface DeleteEvent extends BaseEvent {\n type: 'delete';\n data: {\n reason?: string;\n cascade?: boolean; // true if this was cascade-deleted as child of epic\n previousStatus?: Status; // Status before deletion (for restore)\n };\n}\n\n// Restore event - undelete\nexport interface RestoreEvent extends BaseEvent {\n type: 'restore';\n data: {\n reason?: string;\n };\n}\n\n// Union type for all events\nexport type IssueEvent =\n | CreateEvent\n | UpdateEvent\n | CloseEvent\n | ReopenEvent\n | CommentEvent\n | DeleteEvent\n | RestoreEvent;\n\n// Config stored in .pebble/config.json\nexport interface PebbleConfig {\n prefix: string;\n version: string;\n useMainTreePebble?: boolean; // default: true - use main tree's .pebble when in a git worktree\n}\n\n// Helper type for issue filters\nexport interface IssueFilters {\n status?: Status;\n type?: IssueType;\n priority?: Priority;\n parent?: string;\n}\n\n// Priority labels for display\nexport const PRIORITY_LABELS: Record<Priority, string> = {\n 0: 'critical',\n 1: 'high',\n 2: 'medium',\n 3: 'low',\n 4: 'backlog',\n};\n\n// Status labels for display\nexport const STATUS_LABELS: Record<Status, string> = {\n open: 'Open',\n in_progress: 'In Progress',\n blocked: 'Blocked',\n pending_verification: 'Pending Verification',\n closed: 'Closed',\n};\n\n// Type labels for display\nexport const TYPE_LABELS: Record<IssueType, string> = {\n task: 'Task',\n bug: 'Bug',\n epic: 'Epic',\n verification: 'Verification',\n};\n\n// Badge variant types (for shadcn/ui Badge component)\nexport type BadgeVariant = 'default' | 'secondary' | 'destructive' | 'outline';\n\n// Status badge variants for UI\nexport const STATUS_BADGE_VARIANTS: Record<Status, BadgeVariant> = {\n open: 'outline',\n in_progress: 'default',\n blocked: 'destructive',\n pending_verification: 'default', // Uses warning color via className\n closed: 'secondary',\n};\n\n// Type badge variants for UI\nexport const TYPE_BADGE_VARIANTS: Record<IssueType, BadgeVariant> = {\n task: 'default',\n bug: 'destructive',\n epic: 'secondary',\n verification: 'outline',\n};\n\n// Priority labels for UI display (capitalized)\nexport const PRIORITY_DISPLAY_LABELS: Record<Priority, string> = {\n 0: 'Critical',\n 1: 'High',\n 2: 'Medium',\n 3: 'Low',\n 4: 'Backlog',\n};\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport type { IssueEvent, PebbleConfig } from '../../shared/types.js';\nimport { derivePrefix } from './id.js';\nimport { getMainWorktreeRoot, getCurrentWorktreeName } from './git.js';\n\nconst PEBBLE_DIR = '.pebble';\nconst ISSUES_FILE = 'issues.jsonl';\nconst CONFIG_FILE = 'config.json';\n\n/**\n * Safely read config without throwing errors.\n * Returns null if config can't be read.\n */\nfunction getConfigSafe(pebbleDir: string): PebbleConfig | null {\n try {\n const configPath = path.join(pebbleDir, CONFIG_FILE);\n if (!fs.existsSync(configPath)) {\n return null;\n }\n const content = fs.readFileSync(configPath, 'utf-8');\n return JSON.parse(content) as PebbleConfig;\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve a local pebble directory to the main tree's pebble directory\n * if we're in a worktree and the config allows it.\n */\nfunction resolveWorktreePebbleDir(localPebbleDir: string): string {\n // Check if --local flag is set (via environment variable)\n if (process.env.PEBBLE_LOCAL === '1') {\n return localPebbleDir;\n }\n\n // Check config for useMainTreePebble setting\n const config = getConfigSafe(localPebbleDir);\n if (config?.useMainTreePebble === false) {\n return localPebbleDir; // Explicitly disabled\n }\n\n // Default behavior: check if we're in a worktree\n const mainRoot = getMainWorktreeRoot();\n if (!mainRoot) {\n return localPebbleDir; // Not in a worktree\n }\n\n // Check if main tree has .pebble\n const mainPebble = path.join(mainRoot, PEBBLE_DIR);\n if (fs.existsSync(mainPebble) && fs.statSync(mainPebble).isDirectory()) {\n return mainPebble;\n }\n\n return localPebbleDir; // Fallback to local\n}\n\n/**\n * Search upward from cwd to find .pebble/ directory.\n * If in a git worktree, checks main tree first (unless --local flag is set).\n * Returns the path to .pebble/ or null if not found.\n */\nexport function discoverPebbleDir(startDir: string = process.cwd()): string | null {\n // If in a worktree and --local not set, check main tree first\n // This handles the case where worktree is a sibling (not child) of main tree\n if (process.env.PEBBLE_LOCAL !== '1') {\n const mainRoot = getMainWorktreeRoot();\n if (mainRoot) {\n const mainPebble = path.join(mainRoot, PEBBLE_DIR);\n if (fs.existsSync(mainPebble) && fs.statSync(mainPebble).isDirectory()) {\n // Check config to see if worktree redirection is disabled\n const config = getConfigSafe(mainPebble);\n if (config?.useMainTreePebble !== false) {\n return mainPebble;\n }\n }\n }\n }\n\n // Fall back to upward search from cwd\n let currentDir = path.resolve(startDir);\n const root = path.parse(currentDir).root;\n\n while (currentDir !== root) {\n const pebbleDir = path.join(currentDir, PEBBLE_DIR);\n if (fs.existsSync(pebbleDir) && fs.statSync(pebbleDir).isDirectory()) {\n return resolveWorktreePebbleDir(pebbleDir);\n }\n currentDir = path.dirname(currentDir);\n }\n\n // Check root as well\n const rootPebble = path.join(root, PEBBLE_DIR);\n if (fs.existsSync(rootPebble) && fs.statSync(rootPebble).isDirectory()) {\n return resolveWorktreePebbleDir(rootPebble);\n }\n\n return null;\n}\n\n/**\n * Get the .pebble directory, throwing if not found\n */\nexport function getPebbleDir(): string {\n const dir = discoverPebbleDir();\n if (!dir) {\n throw new Error('No .pebble directory found. Run a create command to initialize.');\n }\n return dir;\n}\n\n/**\n * Create .pebble/ directory with config if it doesn't exist.\n * In a git worktree, creates in the main tree root (unless --local is set).\n * Returns the path to .pebble/\n */\nexport function ensurePebbleDir(baseDir: string = process.cwd()): string {\n // Check if --local flag is NOT set and we're in a worktree\n // In that case, create in main tree instead of worktree\n let targetDir = baseDir;\n if (process.env.PEBBLE_LOCAL !== '1') {\n const mainRoot = getMainWorktreeRoot();\n if (mainRoot) {\n // Check if main tree already has .pebble\n const mainPebble = path.join(mainRoot, PEBBLE_DIR);\n if (fs.existsSync(mainPebble) && fs.statSync(mainPebble).isDirectory()) {\n return mainPebble; // Use existing main tree .pebble\n }\n // Create in main tree\n targetDir = mainRoot;\n }\n }\n\n const pebbleDir = path.join(targetDir, PEBBLE_DIR);\n\n if (!fs.existsSync(pebbleDir)) {\n fs.mkdirSync(pebbleDir, { recursive: true });\n\n // Create initial config with worktree support enabled by default\n const folderName = path.basename(targetDir);\n const config: PebbleConfig = {\n prefix: derivePrefix(folderName),\n version: '0.1.0',\n useMainTreePebble: true,\n };\n setConfig(config, pebbleDir);\n\n // Create empty issues file\n const issuesPath = path.join(pebbleDir, ISSUES_FILE);\n fs.writeFileSync(issuesPath, '', 'utf-8');\n }\n\n return pebbleDir;\n}\n\n/**\n * Get the path to the issues JSONL file\n */\nexport function getIssuesPath(pebbleDir?: string): string {\n const dir = pebbleDir ?? getPebbleDir();\n return path.join(dir, ISSUES_FILE);\n}\n\n/**\n * Get the source name for events (worktree/repo folder name).\n * Used to track which worktree a command was executed from.\n */\nexport function getEventSource(): string {\n // Try git worktree name first\n const worktreeName = getCurrentWorktreeName();\n if (worktreeName) {\n return worktreeName;\n }\n\n // Fallback: use folder name where .pebble is located\n const pebbleDir = discoverPebbleDir();\n if (pebbleDir) {\n return path.basename(path.dirname(pebbleDir));\n }\n\n return 'unknown';\n}\n\n/**\n * Append an event to the JSONL file.\n * Automatically adds source field if not present.\n */\nexport function appendEvent(event: IssueEvent, pebbleDir?: string): void {\n const issuesPath = getIssuesPath(pebbleDir);\n // Add source if not already present\n const eventWithSource = event.source ? event : { ...event, source: getEventSource() };\n const line = JSON.stringify(eventWithSource) + '\\n';\n fs.appendFileSync(issuesPath, line, 'utf-8');\n}\n\n/**\n * Read all events from a specific JSONL file path\n * Returns empty array if file doesn't exist\n */\nexport function readEventsFromFile(filePath: string): IssueEvent[] {\n if (!fs.existsSync(filePath)) {\n return [];\n }\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const lines = content.split('\\n').filter((line) => line.trim() !== '');\n\n return lines.map((line, index) => {\n try {\n return JSON.parse(line) as IssueEvent;\n } catch {\n throw new Error(`Invalid JSON at line ${index + 1} in ${filePath}: ${line}`);\n }\n });\n}\n\n/**\n * Read all events from the JSONL file\n * Returns empty array if no .pebble directory exists\n */\nexport function readEvents(pebbleDir?: string): IssueEvent[] {\n // If no pebbleDir provided, try to discover one\n // Return empty array if no .pebble directory exists (graceful handling for read operations)\n const dir = pebbleDir ?? discoverPebbleDir();\n if (!dir) {\n return [];\n }\n\n const issuesPath = path.join(dir, ISSUES_FILE);\n\n if (!fs.existsSync(issuesPath)) {\n return [];\n }\n\n const content = fs.readFileSync(issuesPath, 'utf-8');\n const lines = content.split('\\n').filter((line) => line.trim() !== '');\n\n return lines.map((line, index) => {\n try {\n return JSON.parse(line) as IssueEvent;\n } catch {\n throw new Error(`Invalid JSON at line ${index + 1}: ${line}`);\n }\n });\n}\n\n/**\n * Get the config file path\n */\nexport function getConfigPath(pebbleDir?: string): string {\n const dir = pebbleDir ?? getPebbleDir();\n return path.join(dir, CONFIG_FILE);\n}\n\n/**\n * Read the config file\n */\nexport function getConfig(pebbleDir?: string): PebbleConfig {\n const configPath = getConfigPath(pebbleDir);\n\n if (!fs.existsSync(configPath)) {\n throw new Error(\"No .pebble directory found. Run 'pb init' to initialize.\");\n }\n\n const content = fs.readFileSync(configPath, 'utf-8');\n return JSON.parse(content) as PebbleConfig;\n}\n\n/**\n * Write the config file\n */\nexport function setConfig(config: PebbleConfig, pebbleDir?: string): void {\n const dir = pebbleDir ?? getPebbleDir();\n const configPath = path.join(dir, CONFIG_FILE);\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\n/**\n * Get or create the pebble directory\n * If it doesn't exist, creates it in the current directory\n */\nexport function getOrCreatePebbleDir(): string {\n const existing = discoverPebbleDir();\n if (existing) {\n return existing;\n }\n return ensurePebbleDir();\n}\n","import * as crypto from 'crypto';\n\n/**\n * Characters used for ID generation (alphanumeric, lowercase)\n */\nconst ID_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789';\n\n/**\n * Generate a random alphanumeric string of specified length\n */\nfunction randomAlphanumeric(length: number): string {\n const bytes = crypto.randomBytes(length);\n let result = '';\n for (let i = 0; i < length; i++) {\n result += ID_CHARS[bytes[i] % ID_CHARS.length];\n }\n return result;\n}\n\n/**\n * Generate a unique issue ID\n * Format: PREFIX-xxxxxx (6 char alphanumeric suffix)\n */\nexport function generateId(prefix: string): string {\n const suffix = randomAlphanumeric(6);\n return `${prefix}-${suffix}`;\n}\n\n/**\n * Derive a prefix from a folder name\n * Takes first 4 alphabetic/numeric characters and uppercases them\n * Pads with 'X' if less than 4 characters\n */\nexport function derivePrefix(folderName: string): string {\n const clean = folderName.replace(/[^a-zA-Z0-9]/g, '');\n return clean.slice(0, 4).toUpperCase().padEnd(4, 'X');\n}\n\n/**\n * Check if a string is a valid issue ID format\n */\nexport function isValidId(id: string): boolean {\n return /^[A-Z]{4}-[a-z0-9]{6}$/.test(id);\n}\n\n/**\n * Extract the prefix from an issue ID\n */\nexport function extractPrefix(id: string): string | null {\n const match = id.match(/^([A-Z]{4})-[a-z0-9]{6}$/);\n return match ? match[1] : null;\n}\n","import { execSync } from 'child_process';\nimport path from 'path';\n\n/**\n * Check if current directory is inside a git worktree (not the main tree).\n * Returns false if not in a git repo or if already in the main tree.\n */\nexport function isGitWorktree(): boolean {\n try {\n // Get the path to the common git directory (shared across worktrees)\n const gitCommonDir = execSync('git rev-parse --git-common-dir', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n // Get the path to the current worktree's git directory\n const gitDir = execSync('git rev-parse --git-dir', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n // If they differ, we're in a linked worktree\n // Normalize paths for comparison\n const normalizedCommon = path.resolve(gitCommonDir);\n const normalizedGit = path.resolve(gitDir);\n\n return normalizedCommon !== normalizedGit;\n } catch {\n // Not in a git repository or git not installed\n return false;\n }\n}\n\n/**\n * Get the path to the main worktree's root directory.\n * Returns null if not in a git repo, already in main tree, or can't determine.\n */\nexport function getMainWorktreeRoot(): string | null {\n try {\n // Get the common git directory\n const gitCommonDir = execSync('git rev-parse --git-common-dir', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n // Get the current worktree's git directory\n const gitDir = execSync('git rev-parse --git-dir', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n // Normalize paths for comparison\n const normalizedCommon = path.resolve(gitCommonDir);\n const normalizedGit = path.resolve(gitDir);\n\n // If they're the same, we're already in the main tree\n if (normalizedCommon === normalizedGit) {\n return null;\n }\n\n // The main worktree root is the parent of the common git directory\n // For a typical repo, .git is in the root, so we go up one level\n // For worktrees, gitCommonDir is the main repo's .git directory\n const mainRoot = path.dirname(normalizedCommon);\n\n return mainRoot;\n } catch {\n // Not in a git repository or git not installed\n return null;\n }\n}\n\n/**\n * Get the folder name of the current worktree/repo root.\n * Used to record which worktree a command was executed from.\n * Returns null if not in a git repo.\n */\nexport function getCurrentWorktreeName(): string | null {\n try {\n // Get the current worktree/repo root (works for both main tree and worktrees)\n const toplevel = execSync('git rev-parse --show-toplevel', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n return path.basename(toplevel);\n } catch {\n // Not in a git repository or git not installed\n return null;\n }\n}\n","import type {\n Issue,\n IssueEvent,\n CreateEvent,\n UpdateEvent,\n CommentEvent,\n IssueFilters,\n} from '../../shared/types.js';\nimport { readEvents } from './storage.js';\n\n/**\n * Compute current issue state from a list of events\n * Returns a map of issue ID to current Issue state\n */\nexport function computeState(events: IssueEvent[]): Map<string, Issue> {\n const issues = new Map<string, Issue>();\n\n for (const event of events) {\n switch (event.type) {\n case 'create': {\n const createEvent = event as CreateEvent;\n const issue: Issue = {\n id: event.issueId,\n title: createEvent.data.title,\n type: createEvent.data.type,\n priority: createEvent.data.priority,\n status: 'open',\n description: createEvent.data.description,\n parent: createEvent.data.parent,\n blockedBy: [],\n relatedTo: [],\n verifies: createEvent.data.verifies,\n comments: [],\n createdAt: event.timestamp,\n updatedAt: event.timestamp,\n lastSource: event.source,\n };\n issues.set(event.issueId, issue);\n break;\n }\n\n case 'update': {\n const updateEvent = event as UpdateEvent;\n const issue = issues.get(event.issueId);\n if (issue) {\n if (updateEvent.data.title !== undefined) {\n issue.title = updateEvent.data.title;\n }\n if (updateEvent.data.type !== undefined) {\n issue.type = updateEvent.data.type;\n }\n if (updateEvent.data.priority !== undefined) {\n issue.priority = updateEvent.data.priority;\n }\n if (updateEvent.data.status !== undefined) {\n issue.status = updateEvent.data.status;\n }\n if (updateEvent.data.description !== undefined) {\n issue.description = updateEvent.data.description;\n }\n if (updateEvent.data.parent !== undefined) {\n // Empty string means \"clear parent\" (sentinel value from --parent null)\n issue.parent = updateEvent.data.parent || undefined;\n }\n if (updateEvent.data.blockedBy !== undefined) {\n issue.blockedBy = updateEvent.data.blockedBy;\n }\n if (updateEvent.data.relatedTo !== undefined) {\n issue.relatedTo = updateEvent.data.relatedTo;\n }\n issue.updatedAt = event.timestamp;\n if (event.source) issue.lastSource = event.source;\n }\n break;\n }\n\n case 'close': {\n const issue = issues.get(event.issueId);\n if (issue) {\n issue.status = 'closed';\n issue.updatedAt = event.timestamp;\n if (event.source) issue.lastSource = event.source;\n }\n break;\n }\n\n case 'reopen': {\n const issue = issues.get(event.issueId);\n if (issue) {\n issue.status = 'open';\n issue.updatedAt = event.timestamp;\n if (event.source) issue.lastSource = event.source;\n }\n break;\n }\n\n case 'comment': {\n const commentEvent = event as CommentEvent;\n const issue = issues.get(event.issueId);\n if (issue) {\n issue.comments.push(commentEvent.data);\n issue.updatedAt = event.timestamp;\n if (event.source) issue.lastSource = event.source;\n }\n break;\n }\n\n case 'delete': {\n const issue = issues.get(event.issueId);\n if (issue) {\n issue.deleted = true;\n issue.deletedAt = event.timestamp;\n issue.updatedAt = event.timestamp;\n if (event.source) issue.lastSource = event.source;\n }\n break;\n }\n\n case 'restore': {\n const issue = issues.get(event.issueId);\n if (issue) {\n issue.deleted = false;\n issue.deletedAt = undefined;\n issue.updatedAt = event.timestamp;\n if (event.source) issue.lastSource = event.source;\n }\n break;\n }\n }\n }\n\n return issues;\n}\n\n/**\n * Get all issues as an array, optionally filtered\n * By default excludes deleted issues unless includeDeleted is true\n */\nexport function getIssues(filters?: IssueFilters, includeDeleted = false): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n let issues = Array.from(state.values());\n\n // Filter out deleted issues unless explicitly included\n if (!includeDeleted) {\n issues = issues.filter((i) => !i.deleted);\n }\n\n if (filters) {\n if (filters.status !== undefined) {\n issues = issues.filter((i) => i.status === filters.status);\n }\n if (filters.type !== undefined) {\n issues = issues.filter((i) => i.type === filters.type);\n }\n if (filters.priority !== undefined) {\n issues = issues.filter((i) => i.priority === filters.priority);\n }\n if (filters.parent !== undefined) {\n issues = issues.filter((i) => i.parent === filters.parent);\n }\n }\n\n return issues;\n}\n\n/**\n * Get a single issue by ID\n * @param id Issue ID\n * @param includeDeleted If false (default), returns undefined for deleted issues\n */\nexport function getIssue(id: string, includeDeleted = false): Issue | undefined {\n const events = readEvents();\n const state = computeState(events);\n const issue = state.get(id);\n if (issue && issue.deleted && !includeDeleted) {\n return undefined;\n }\n return issue;\n}\n\n/**\n * Resolve a partial ID to a full ID\n * Supports: exact match, prefix match, suffix-only match\n * All matching is case-insensitive\n * Throws if ambiguous (multiple matches) or not found\n */\nexport function resolveId(partial: string): string {\n const events = readEvents();\n const state = computeState(events);\n const allIds = Array.from(state.keys());\n const partialLower = partial.toLowerCase();\n\n // First try exact match (case-insensitive)\n const exactMatch = allIds.find((id) => id.toLowerCase() === partialLower);\n if (exactMatch) {\n return exactMatch;\n }\n\n // Then try prefix match\n const prefixMatches = allIds.filter((id) =>\n id.toLowerCase().startsWith(partialLower)\n );\n\n if (prefixMatches.length === 1) {\n return prefixMatches[0];\n }\n\n if (prefixMatches.length > 1) {\n throw new Error(\n `Ambiguous issue ID '${partial}'. Matches: ${prefixMatches.join(', ')}`\n );\n }\n\n // Then try suffix match (part after the hyphen)\n const suffixMatches = allIds.filter((id) => {\n const hyphenIndex = id.indexOf('-');\n if (hyphenIndex === -1) return false;\n const suffix = id.substring(hyphenIndex + 1).toLowerCase();\n return suffix === partialLower;\n });\n\n if (suffixMatches.length === 1) {\n return suffixMatches[0];\n }\n\n if (suffixMatches.length > 1) {\n throw new Error(\n `Ambiguous issue ID '${partial}'. Matches: ${suffixMatches.join(', ')}`\n );\n }\n\n throw new Error(`Issue not found: ${partial}`);\n}\n\n/**\n * Get issues that are ready for work (non-closed with no open blockers)\n * For verification issues: target must be closed\n * Excludes deleted issues\n */\nexport function getReady(): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n const issues = Array.from(state.values());\n\n return issues.filter((issue) => {\n // Skip deleted issues\n if (issue.deleted) {\n return false;\n }\n\n // Must not be closed or pending_verification\n if (issue.status === 'closed' || issue.status === 'pending_verification') {\n return false;\n }\n\n // All blockers must be closed\n for (const blockerId of issue.blockedBy) {\n const blocker = state.get(blockerId);\n if (blocker && blocker.status !== 'closed') {\n return false;\n }\n }\n\n // For verification issues: target must be closed\n if (issue.type === 'verification' && issue.verifies) {\n const target = state.get(issue.verifies);\n if (!target || target.status !== 'closed') {\n return false;\n }\n }\n\n return true;\n });\n}\n\n/**\n * Get issues that are blocked (have at least one open blocker)\n * Excludes deleted issues\n */\nexport function getBlocked(): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n const issues = Array.from(state.values());\n\n return issues.filter((issue) => {\n // Skip deleted issues\n if (issue.deleted) {\n return false;\n }\n\n // Must not be closed\n if (issue.status === 'closed') {\n return false;\n }\n\n // Check if any blocker is not closed\n for (const blockerId of issue.blockedBy) {\n const blocker = state.get(blockerId);\n if (blocker && blocker.status !== 'closed') {\n return true;\n }\n }\n\n return false;\n });\n}\n\n/**\n * Build a dependency graph as adjacency list\n * Returns a map of issueId -> list of issues it blocks\n */\nexport function buildDependencyGraph(): Map<string, string[]> {\n const events = readEvents();\n const state = computeState(events);\n const graph = new Map<string, string[]>();\n\n // Initialize all nodes\n for (const id of state.keys()) {\n graph.set(id, []);\n }\n\n // Build edges (blocker -> blocked)\n for (const [id, issue] of state) {\n for (const blockerId of issue.blockedBy) {\n const blockerEdges = graph.get(blockerId);\n if (blockerEdges) {\n blockerEdges.push(id);\n }\n }\n }\n\n return graph;\n}\n\n/**\n * Check if adding a dependency would create a cycle\n * Uses DFS to detect if newBlockerId can reach issueId\n */\nexport function detectCycle(issueId: string, newBlockerId: string): boolean {\n if (issueId === newBlockerId) {\n return true; // Self-reference\n }\n\n const graph = buildDependencyGraph();\n\n // Add the proposed edge temporarily\n const blockerEdges = graph.get(newBlockerId) ?? [];\n const testGraph = new Map(graph);\n testGraph.set(newBlockerId, [...blockerEdges, issueId]);\n\n // DFS to check if issueId can reach newBlockerId (which would mean a cycle)\n const visited = new Set<string>();\n const stack = [issueId];\n\n while (stack.length > 0) {\n const current = stack.pop()!;\n\n if (current === newBlockerId) {\n return true; // Found a cycle\n }\n\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n const edges = testGraph.get(current) ?? [];\n for (const next of edges) {\n if (!visited.has(next)) {\n stack.push(next);\n }\n }\n }\n\n return false;\n}\n\n/**\n * Get issues that block a given issue\n */\nexport function getBlockers(issueId: string): Issue[] {\n const issue = getIssue(issueId);\n if (!issue) {\n return [];\n }\n\n const events = readEvents();\n const state = computeState(events);\n\n return issue.blockedBy\n .map((id) => state.get(id))\n .filter((i): i is Issue => i !== undefined);\n}\n\n/**\n * Get issues that are blocked by a given issue\n */\nexport function getBlocking(issueId: string): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n\n return Array.from(state.values()).filter((issue) =>\n issue.blockedBy.includes(issueId)\n );\n}\n\n/**\n * Get children of an epic\n */\nexport function getChildren(epicId: string): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n\n return Array.from(state.values()).filter((issue) => issue.parent === epicId);\n}\n\n/**\n * Get verification issues that verify a given issue\n */\nexport function getVerifications(issueId: string): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n\n return Array.from(state.values()).filter((issue) => issue.verifies === issueId);\n}\n\n/**\n * Check if an epic has any open children\n */\nexport function hasOpenChildren(epicId: string): boolean {\n const children = getChildren(epicId);\n return children.some((child) => child.status !== 'closed');\n}\n\n/**\n * Get issues that became unblocked/ready after closing an issue.\n * Includes:\n * - Issues that were blocked by this issue and now have all blockers closed\n * - Verification issues that verify this issue (they become ready when target closes)\n */\nexport function getNewlyUnblocked(closedIssueId: string): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n const result: Issue[] = [];\n\n for (const issue of state.values()) {\n // Skip closed issues\n if (issue.status === 'closed') continue;\n\n let isUnblockedByThis = false;\n\n // Check if this issue was blocking it\n if (issue.blockedBy.includes(closedIssueId)) {\n // Check if all blockers are now closed\n const allBlockersClosed = issue.blockedBy.every((blockerId) => {\n const blocker = state.get(blockerId);\n return blocker?.status === 'closed';\n });\n if (allBlockersClosed) {\n isUnblockedByThis = true;\n }\n }\n\n // Check if this is a verification issue that verifies the closed issue\n if (issue.type === 'verification' && issue.verifies === closedIssueId) {\n // Check if all blockers are also closed\n const allBlockersClosed = issue.blockedBy.every((blockerId) => {\n const blocker = state.get(blockerId);\n return blocker?.status === 'closed';\n });\n if (allBlockersClosed) {\n isUnblockedByThis = true;\n }\n }\n\n if (isUnblockedByThis) {\n result.push(issue);\n }\n }\n\n return result;\n}\n\n/**\n * Get issues related to a given issue (bidirectional relationship)\n */\nexport function getRelated(issueId: string): Issue[] {\n const issue = getIssue(issueId);\n if (!issue) {\n return [];\n }\n\n const events = readEvents();\n const state = computeState(events);\n\n return issue.relatedTo\n .map((id) => state.get(id))\n .filter((i): i is Issue => i !== undefined);\n}\n\n/**\n * Check if an issue has any open (non-closed) blockers\n */\nexport function hasOpenBlockersById(issueId: string): boolean {\n const issue = getIssue(issueId);\n if (!issue) {\n return false;\n }\n\n const events = readEvents();\n const state = computeState(events);\n\n return issue.blockedBy.some((blockerId) => {\n const blocker = state.get(blockerId);\n return blocker && blocker.status !== 'closed';\n });\n}\n\n/**\n * Get open blockers for an issue (for error messages)\n */\nexport function getOpenBlockers(issueId: string): Issue[] {\n const issue = getIssue(issueId);\n if (!issue) {\n return [];\n }\n\n const events = readEvents();\n const state = computeState(events);\n\n return issue.blockedBy\n .map((id) => state.get(id))\n .filter((i): i is Issue => i !== undefined && i.status !== 'closed');\n}\n\n/**\n * Get the computed state map for efficient lookups\n * Use this when you need to perform multiple lookups to avoid recomputing state\n */\nexport function getComputedState(): Map<string, Issue> {\n const events = readEvents();\n return computeState(events);\n}\n\n/**\n * Get the ancestry chain for an issue (parent → grandparent → great-grandparent...)\n * Returns array ordered from immediate parent to root\n */\nexport function getAncestryChain(\n issueId: string,\n state: Map<string, Issue>\n): Array<{ id: string; title: string }> {\n const chain: Array<{ id: string; title: string }> = [];\n let current = state.get(issueId);\n\n while (current?.parent) {\n const parent = state.get(current.parent);\n if (!parent) break;\n chain.push({ id: parent.id, title: parent.title });\n current = parent;\n }\n\n return chain;\n}\n\n/**\n * Get all descendants of an issue (children, grandchildren, etc.)\n * Used for cascade delete of epics\n * Returns flat array of all descendant issues\n */\nexport function getDescendants(\n issueId: string,\n state?: Map<string, Issue>\n): Issue[] {\n const issueState = state ?? getComputedState();\n const descendants: Issue[] = [];\n\n function collectDescendants(parentId: string) {\n for (const issue of issueState.values()) {\n if (issue.parent === parentId && !issue.deleted) {\n descendants.push(issue);\n // Recursively collect children of this child\n collectDescendants(issue.id);\n }\n }\n }\n\n collectDescendants(issueId);\n return descendants;\n}\n","import { formatDistanceToNow, parseISO } from 'date-fns';\n\n/**\n * Formats an ISO timestamp as a relative time string.\n * @param isoString - ISO 8601 timestamp\n * @returns Human-readable relative time (e.g., \"2 hours ago\", \"yesterday\")\n */\nexport function formatRelativeTime(isoString: string): string {\n try {\n const date = parseISO(isoString);\n return formatDistanceToNow(date, { addSuffix: true });\n } catch {\n return isoString; // Fallback to original if parsing fails\n }\n}\n\n/**\n * Formats a timestamp with both relative and absolute time.\n * @param isoString - ISO 8601 timestamp\n * @returns Object with relative and absolute formatted strings\n */\nexport function formatTimestamp(isoString: string): {\n relative: string;\n absolute: string;\n} {\n try {\n const date = parseISO(isoString);\n return {\n relative: formatDistanceToNow(date, { addSuffix: true }),\n absolute: date.toLocaleString(),\n };\n } catch {\n return {\n relative: isoString,\n absolute: isoString,\n };\n }\n}\n","import type { Issue, IssueEvent, Priority, Status, IssueType } from '../../shared/types.js';\nimport { PRIORITY_LABELS, STATUS_LABELS, TYPE_LABELS } from '../../shared/types.js';\nimport { formatRelativeTime } from '../../shared/time.js';\n\n/**\n * Limit metadata for paginated output\n */\nexport interface LimitInfo {\n total: number;\n shown: number;\n limited: boolean;\n}\n\n/**\n * Format a limit message for pretty output\n */\nexport function formatLimitMessage(info: LimitInfo): string {\n if (!info.limited) return '';\n return `\\n---\\nShowing ${info.shown} of ${info.total} issues. Use --all or --limit <n> to see more.`;\n}\n\n/**\n * Format data as JSON string\n */\nexport function formatJson(data: unknown): string {\n return JSON.stringify(data, null, 2);\n}\n\n/**\n * Format a priority value for display\n */\nfunction formatPriority(priority: Priority): string {\n return `P${priority} (${PRIORITY_LABELS[priority]})`;\n}\n\n/**\n * Format a status value for display\n */\nfunction formatStatus(status: Status): string {\n return STATUS_LABELS[status];\n}\n\n/**\n * Format a type value for display\n */\nfunction formatType(type: IssueType): string {\n return TYPE_LABELS[type];\n}\n\n/**\n * Truncate a string to max length with ellipsis\n */\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return str.slice(0, maxLength - 3) + '...';\n}\n\n/**\n * Pad a string to a fixed width\n */\nfunction pad(str: string, width: number): string {\n return str.padEnd(width);\n}\n\n/**\n * Format a single issue for pretty display\n */\nexport function formatIssuePretty(issue: Issue): string {\n const lines: string[] = [];\n\n lines.push(`${issue.id} - ${issue.title}`);\n lines.push('─'.repeat(60));\n lines.push(`Type: ${formatType(issue.type)}`);\n lines.push(`Priority: ${formatPriority(issue.priority)}`);\n lines.push(`Status: ${formatStatus(issue.status)}`);\n\n if (issue.parent) {\n lines.push(`Parent: ${issue.parent}`);\n }\n\n if (issue.description) {\n lines.push('');\n lines.push('Description:');\n lines.push(issue.description);\n }\n\n if (issue.blockedBy.length > 0) {\n lines.push('');\n lines.push(`Blocked by: ${issue.blockedBy.join(', ')}`);\n }\n\n if (issue.comments.length > 0) {\n lines.push('');\n lines.push('Comments:');\n for (const comment of issue.comments) {\n const author = comment.author ?? 'unknown';\n const date = new Date(comment.timestamp).toLocaleString();\n lines.push(` [${date}] ${author}: ${comment.text}`);\n }\n }\n\n lines.push('');\n lines.push(`Created: ${new Date(issue.createdAt).toLocaleString()}`);\n lines.push(`Updated: ${new Date(issue.updatedAt).toLocaleString()}`);\n\n return lines.join('\\n');\n}\n\n/**\n * Format a single issue with blocking info for pretty display\n */\nexport function formatIssuePrettyWithBlocking(issue: Issue, blocking: Issue[]): string {\n const lines: string[] = [];\n\n lines.push(`${issue.id} - ${issue.title}`);\n lines.push('─'.repeat(60));\n lines.push(`Type: ${formatType(issue.type)}`);\n lines.push(`Priority: ${formatPriority(issue.priority)}`);\n lines.push(`Status: ${formatStatus(issue.status)}`);\n\n if (issue.parent) {\n lines.push(`Parent: ${issue.parent}`);\n }\n\n if (issue.description) {\n lines.push('');\n lines.push('Description:');\n lines.push(issue.description);\n }\n\n if (issue.blockedBy.length > 0) {\n lines.push('');\n lines.push(`Blocked by: ${issue.blockedBy.join(', ')}`);\n }\n\n if (blocking.length > 0) {\n lines.push('');\n lines.push(`Blocking: ${blocking.map(i => i.id).join(', ')}`);\n }\n\n if (issue.comments.length > 0) {\n lines.push('');\n lines.push('Comments:');\n for (const comment of issue.comments) {\n const author = comment.author ?? 'unknown';\n const date = new Date(comment.timestamp).toLocaleString();\n lines.push(` [${date}] ${author}: ${comment.text}`);\n }\n }\n\n lines.push('');\n lines.push(`Created: ${new Date(issue.createdAt).toLocaleString()}`);\n lines.push(`Updated: ${new Date(issue.updatedAt).toLocaleString()}`);\n\n return lines.join('\\n');\n}\n\n/**\n * Context for detailed issue display\n */\nexport interface IssueDetailContext {\n blocking: Issue[];\n children: Issue[];\n verifications: Issue[];\n related: Issue[];\n ancestry?: Array<{ id: string; title: string }>; // Full parent chain\n}\n\n/**\n * Format an issue with full context (children, verifications, related)\n */\nexport function formatIssueDetailPretty(issue: Issue, ctx: IssueDetailContext): string {\n const lines: string[] = [];\n\n lines.push(`${issue.id} - ${issue.title}`);\n lines.push('─'.repeat(60));\n lines.push(`Type: ${formatType(issue.type)}`);\n lines.push(`Priority: ${formatPriority(issue.priority)}`);\n lines.push(`Status: ${formatStatus(issue.status)}`);\n\n // Show ancestry chain if available\n if (ctx.ancestry && ctx.ancestry.length > 0) {\n const chain = [...ctx.ancestry].reverse().map(a => a.id).join(' > ');\n lines.push(`Ancestry: ${chain}`);\n } else if (issue.parent) {\n lines.push(`Parent: ${issue.parent}`);\n }\n\n if (issue.description) {\n lines.push('');\n lines.push('Description:');\n lines.push(issue.description);\n }\n\n // Children (for epics)\n if (ctx.children.length > 0) {\n const closedChildren = ctx.children.filter(c => c.status === 'closed');\n const pendingChildren = ctx.children.filter(c => c.status === 'pending_verification');\n const pendingStr = pendingChildren.length > 0 ? ` (${pendingChildren.length} pending verification)` : '';\n lines.push('');\n lines.push(`Children (${closedChildren.length}/${ctx.children.length} done${pendingStr}):`);\n for (const child of ctx.children) {\n const statusIcon = child.status === 'closed' ? '✓' : child.status === 'in_progress' ? '▶' : '○';\n lines.push(` ${statusIcon} ${child.id} - ${child.title} [${child.status}]`);\n }\n }\n\n // Blocked by\n if (issue.blockedBy.length > 0) {\n lines.push('');\n lines.push(`Blocked by: ${issue.blockedBy.join(', ')}`);\n }\n\n // Blocking\n if (ctx.blocking.length > 0) {\n lines.push('');\n lines.push(`Blocking: ${ctx.blocking.map(i => i.id).join(', ')}`);\n }\n\n // Verifications (especially important for pending_verification status)\n if (ctx.verifications.length > 0) {\n const closedVerifications = ctx.verifications.filter(v => v.status === 'closed');\n lines.push('');\n lines.push(`Verifications (${closedVerifications.length}/${ctx.verifications.length} done):`);\n for (const v of ctx.verifications) {\n const statusIcon = v.status === 'closed' ? '✓' : '○';\n lines.push(` ${statusIcon} ${v.id} - ${v.title} [${v.status}]`);\n }\n } else if (issue.status === 'pending_verification') {\n lines.push('');\n lines.push('Verifications: None found (status may be stale)');\n }\n\n // Related issues\n if (ctx.related.length > 0) {\n lines.push('');\n lines.push(`Related: ${ctx.related.map(r => r.id).join(', ')}`);\n }\n\n // Comments\n if (issue.comments.length > 0) {\n lines.push('');\n lines.push('Comments:');\n for (const comment of issue.comments) {\n const author = comment.author ?? 'unknown';\n const date = new Date(comment.timestamp).toLocaleString();\n lines.push(` [${date}] ${author}: ${comment.text}`);\n }\n }\n\n lines.push('');\n lines.push(`Created: ${new Date(issue.createdAt).toLocaleString()}`);\n lines.push(`Updated: ${new Date(issue.updatedAt).toLocaleString()}`);\n\n return lines.join('\\n');\n}\n\n/**\n * Output detailed issue information\n */\nexport function outputIssueDetail(issue: Issue, ctx: IssueDetailContext, pretty: boolean): void {\n if (pretty) {\n console.log(formatIssueDetailPretty(issue, ctx));\n } else {\n // Include all context in JSON output\n const output = {\n ...issue,\n blocking: ctx.blocking.map(i => i.id),\n children: ctx.children.map(i => ({ id: i.id, title: i.title, status: i.status })),\n verifications: ctx.verifications.map(i => ({ id: i.id, title: i.title, status: i.status })),\n related: ctx.related.map(i => i.id),\n ...(ctx.ancestry && ctx.ancestry.length > 0 && { ancestry: ctx.ancestry }),\n };\n console.log(formatJson(output));\n }\n}\n\n/**\n * Format a list of issues as a table\n */\nexport function formatIssueListPretty(issues: Issue[]): string {\n if (issues.length === 0) {\n return 'No issues found.';\n }\n\n const lines: string[] = [];\n\n // Header\n const idWidth = 12;\n const typeWidth = 6;\n const prioWidth = 4;\n const statusWidth = 12;\n const titleWidth = 40;\n\n const header = [\n pad('ID', idWidth),\n pad('Type', typeWidth),\n pad('Pri', prioWidth),\n pad('Status', statusWidth),\n pad('Title', titleWidth),\n ].join(' │ ');\n\n lines.push(header);\n lines.push('─'.repeat(header.length));\n\n // Rows\n for (const issue of issues) {\n const row = [\n pad(issue.id, idWidth),\n pad(issue.type, typeWidth),\n pad(`P${issue.priority}`, prioWidth),\n pad(issue.status, statusWidth),\n truncate(issue.title, titleWidth),\n ].join(' │ ');\n lines.push(row);\n }\n\n lines.push('');\n lines.push(`Total: ${issues.length} issue(s)`);\n\n return lines.join('\\n');\n}\n\n/**\n * Format dependency info for pretty display\n */\nexport function formatDepsPretty(\n issueId: string,\n blockedBy: Issue[],\n blocking: Issue[],\n related: Issue[] = []\n): string {\n const lines: string[] = [];\n\n lines.push(`Dependencies for ${issueId}`);\n lines.push('─'.repeat(40));\n\n lines.push('');\n lines.push('Blocked by:');\n if (blockedBy.length === 0) {\n lines.push(' (none)');\n } else {\n for (const issue of blockedBy) {\n const status = issue.status === 'closed' ? '✓' : '○';\n lines.push(` ${status} ${issue.id} - ${truncate(issue.title, 30)}`);\n }\n }\n\n lines.push('');\n lines.push('Blocking:');\n if (blocking.length === 0) {\n lines.push(' (none)');\n } else {\n for (const issue of blocking) {\n lines.push(` ○ ${issue.id} - ${truncate(issue.title, 30)}`);\n }\n }\n\n lines.push('');\n lines.push('Related:');\n if (related.length === 0) {\n lines.push(' (none)');\n } else {\n for (const issue of related) {\n const status = issue.status === 'closed' ? '✓' : '○';\n lines.push(` ${status} ${issue.id} - ${truncate(issue.title, 30)}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format events for pretty display\n */\nexport function formatEventsPretty(events: IssueEvent[]): string {\n if (events.length === 0) {\n return 'No events found.';\n }\n\n const lines: string[] = [];\n\n for (const event of events) {\n const date = new Date(event.timestamp).toLocaleString();\n lines.push(`[${date}] ${event.type.toUpperCase()} ${event.issueId}`);\n }\n\n lines.push('');\n lines.push(`Total: ${events.length} event(s)`);\n\n return lines.join('\\n');\n}\n\n/**\n * Format an error for output\n */\nexport function formatError(error: Error | string): string {\n const message = error instanceof Error ? error.message : error;\n return JSON.stringify({ error: message });\n}\n\n/**\n * Format an error for pretty display\n */\nexport function formatErrorPretty(error: Error | string): string {\n const message = error instanceof Error ? error.message : error;\n return `Error: ${message}`;\n}\n\n/**\n * Output data in the requested format\n */\nexport function output(data: unknown, pretty: boolean): void {\n if (pretty) {\n // For pretty mode, we need to know the type\n // This is a generic fallback\n console.log(formatJson(data));\n } else {\n console.log(formatJson(data));\n }\n}\n\n/**\n * Output an issue in the requested format\n */\nexport function outputIssue(issue: Issue, pretty: boolean): void {\n if (pretty) {\n console.log(formatIssuePretty(issue));\n } else {\n console.log(formatJson(issue));\n }\n}\n\n/**\n * Output an issue with blocking info in the requested format\n */\nexport function outputIssueWithBlocking(issue: Issue, blocking: Issue[], pretty: boolean): void {\n if (pretty) {\n console.log(formatIssuePrettyWithBlocking(issue, blocking));\n } else {\n // Include blocking IDs in JSON output\n const output = {\n ...issue,\n blocking: blocking.map(i => i.id),\n };\n console.log(formatJson(output));\n }\n}\n\n/**\n * Output a mutation success response (minimal: id + success)\n */\nexport function outputMutationSuccess(id: string, pretty: boolean): void {\n if (pretty) {\n console.log(`✓ ${id}`);\n } else {\n console.log(JSON.stringify({ id, success: true }));\n }\n}\n\n/**\n * Output a list of issues in the requested format\n */\nexport function outputIssueList(issues: Issue[], pretty: boolean, limitInfo?: LimitInfo): void {\n if (pretty) {\n console.log(formatIssueListPretty(issues));\n if (limitInfo?.limited) {\n console.log(formatLimitMessage(limitInfo));\n }\n } else {\n // Only include _meta when results are actually limited\n if (limitInfo?.limited) {\n console.log(formatJson({ issues, _meta: limitInfo }));\n } else {\n console.log(formatJson(issues));\n }\n }\n}\n\n/**\n * Issue with nested children for tree output\n */\nexport interface IssueTreeNode {\n id: string;\n title: string;\n type: string;\n priority: number;\n status: string;\n createdAt: string;\n childrenCount: number;\n children?: IssueTreeNode[];\n}\n\n/**\n * Build a tree structure from a flat list of issues\n */\nexport function buildIssueTree(issues: Issue[]): IssueTreeNode[] {\n const issueMap = new Map<string, Issue>();\n for (const issue of issues) {\n issueMap.set(issue.id, issue);\n }\n\n // Track which issues are children (have a parent in the list)\n const childIds = new Set<string>();\n for (const issue of issues) {\n if (issue.parent && issueMap.has(issue.parent)) {\n childIds.add(issue.id);\n }\n }\n\n // Build tree nodes recursively\n const buildNode = (issue: Issue): IssueTreeNode => {\n const children = issues\n .filter((i) => i.parent === issue.id)\n .map(buildNode);\n\n return {\n id: issue.id,\n title: issue.title,\n type: issue.type,\n priority: issue.priority,\n status: issue.status,\n createdAt: issue.createdAt,\n childrenCount: children.length,\n ...(children.length > 0 && { children }),\n };\n };\n\n // Start with root issues (no parent or parent not in list)\n const roots = issues.filter((i) => !childIds.has(i.id));\n return roots.map(buildNode);\n}\n\n/**\n * Format issue tree as ASCII tree for pretty display\n */\nexport function formatIssueTreePretty(nodes: IssueTreeNode[], sectionHeader?: string): string {\n if (nodes.length === 0) {\n return 'No issues found.';\n }\n\n const lines: string[] = [];\n\n if (sectionHeader) {\n lines.push(`## ${sectionHeader}`);\n lines.push('');\n }\n\n const countAll = (node: IssueTreeNode): number => {\n const children = node.children ?? [];\n return 1 + children.reduce((sum, child) => sum + countAll(child), 0);\n };\n const totalCount = nodes.reduce((sum, node) => sum + countAll(node), 0);\n\n const formatNode = (node: IssueTreeNode, prefix: string, isLast: boolean, isRoot: boolean): void => {\n const connector = isRoot ? '' : isLast ? '└─ ' : '├─ ';\n const statusIcon = node.status === 'closed' ? '✓' : node.status === 'in_progress' ? '▶' : node.status === 'pending_verification' ? '⏳' : '○';\n const statusText = STATUS_LABELS[node.status as Status].toLowerCase();\n const relativeTime = formatRelativeTime(node.createdAt);\n\n lines.push(`${prefix}${connector}${statusIcon} ${node.id}: ${node.title} [${node.type}] P${node.priority} ${statusText} ${relativeTime}`);\n\n const children = node.children ?? [];\n const childPrefix = isRoot ? '' : prefix + (isLast ? ' ' : '│ ');\n children.forEach((child, index) => {\n const childIsLast = index === children.length - 1;\n formatNode(child, childPrefix, childIsLast, false);\n });\n };\n\n nodes.forEach((node, index) => {\n formatNode(node, '', index === nodes.length - 1, true);\n });\n\n lines.push('');\n lines.push(`Total: ${totalCount} issue(s)`);\n\n return lines.join('\\n');\n}\n\n/**\n * Output issues as a hierarchical tree\n */\nexport function outputIssueTree(issues: Issue[], pretty: boolean, sectionHeader?: string, limitInfo?: LimitInfo): void {\n const tree = buildIssueTree(issues);\n\n if (pretty) {\n console.log(formatIssueTreePretty(tree, sectionHeader));\n if (limitInfo?.limited) {\n console.log(formatLimitMessage(limitInfo));\n }\n } else {\n // Only include _meta when results are actually limited\n if (limitInfo?.limited) {\n console.log(formatJson({ issues: tree, _meta: limitInfo }));\n } else {\n console.log(formatJson(tree));\n }\n }\n}\n\n/**\n * Output an error in the requested format\n */\nexport function outputError(error: Error | string, pretty: boolean): void {\n if (pretty) {\n console.error(formatErrorPretty(error));\n } else {\n console.error(formatError(error));\n }\n process.exit(1);\n}\n\n/**\n * Extended issue info for verbose output\n */\nexport interface VerboseIssueInfo {\n issue: Issue;\n blocking: string[];\n children: number;\n verifications: number;\n blockers?: string[]; // For blocked command: open blockers\n ancestry: Array<{ id: string; title: string }>; // Full parent chain (parent → grandparent → root)\n}\n\n/**\n * Format a list of issues with verbose details\n */\nexport function formatIssueListVerbose(issues: VerboseIssueInfo[], sectionHeader?: string): string {\n if (issues.length === 0) {\n return 'No issues found.';\n }\n\n const lines: string[] = [];\n\n // Add section header if provided\n if (sectionHeader) {\n lines.push(`## ${sectionHeader} (${issues.length})`);\n lines.push('');\n }\n\n for (const info of issues) {\n const { issue, blocking, children, verifications, blockers, ancestry } = info;\n\n lines.push(`${issue.id}: ${issue.title}`);\n lines.push(` Type: ${formatType(issue.type)} | Priority: P${issue.priority} | Created: ${formatRelativeTime(issue.createdAt)}`);\n\n // Show ancestry chain if available (reversed: root > ... > parent)\n if (ancestry.length > 0) {\n const chain = [...ancestry].reverse().map(a => a.title).join(' → ');\n lines.push(` Ancestry: ${chain}`);\n }\n\n // Show blocking/blockers if relevant\n if (blocking.length > 0) {\n lines.push(` Blocking: ${blocking.join(', ')}`);\n }\n if (blockers && blockers.length > 0) {\n lines.push(` Blocked by: ${blockers.join(', ')}`);\n }\n\n // Show children/verifications for epics\n if (issue.type === 'epic' && children > 0) {\n lines.push(` Children: ${children} | Verifications: ${verifications}`);\n }\n\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Output a list of issues with verbose details\n */\nexport function outputIssueListVerbose(issues: VerboseIssueInfo[], pretty: boolean, sectionHeader?: string, limitInfo?: LimitInfo): void {\n if (pretty) {\n console.log(formatIssueListVerbose(issues, sectionHeader));\n if (limitInfo?.limited) {\n console.log(formatLimitMessage(limitInfo));\n }\n } else {\n // JSON output includes all fields\n const output = issues.map(({ issue, blocking, children, verifications, blockers, ancestry }) => ({\n ...issue,\n blocking,\n childrenCount: issue.type === 'epic' ? children : undefined,\n verificationsCount: verifications,\n ...(blockers && { openBlockers: blockers }),\n ...(ancestry.length > 0 && { ancestry }),\n }));\n // Only include _meta when results are actually limited\n if (limitInfo?.limited) {\n console.log(formatJson({ issues: output, _meta: limitInfo }));\n } else {\n console.log(formatJson(output));\n }\n }\n}\n","import { Command } from 'commander';\nimport type { IssueType, Priority, CreateEvent, UpdateEvent } from '../../shared/types.js';\nimport { ISSUE_TYPES, PRIORITIES } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, getConfig, appendEvent } from '../lib/storage.js';\nimport { generateId } from '../lib/id.js';\nimport { getIssue, resolveId } from '../lib/state.js';\nimport { outputMutationSuccess, outputError } from '../lib/output.js';\n\nexport function createCommand(program: Command): void {\n program\n .command('create <title>')\n .description('Create a new issue')\n .option('-t, --type <type>', 'Issue type (task, bug, epic, verification)', 'task')\n .option('-p, --priority <priority>', 'Priority (0-4)', '2')\n .option('-d, --description <desc>', 'Description')\n .option('--parent <id>', 'Parent issue ID')\n .option('--verifies <id>', 'ID of issue this verifies (sets type to verification)')\n .option('--blocked-by <ids>', 'Comma-separated IDs of issues that block this one')\n .option('--blocks <ids>', 'Comma-separated IDs of issues this one will block')\n .action(async (title: string, options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Auto-set type to verification if --verifies is used\n let type = options.type as IssueType;\n if (options.verifies && type !== 'verification') {\n type = 'verification';\n }\n\n // Validate type\n if (!ISSUE_TYPES.includes(type)) {\n throw new Error(`Invalid type: ${type}. Must be one of: ${ISSUE_TYPES.join(', ')}`);\n }\n\n // Validate --verifies is only used with verification type\n if (type === 'verification' && !options.verifies) {\n throw new Error('Verification issues require --verifies <id> to specify the issue being verified');\n }\n\n // Validate priority\n const priority = parseInt(options.priority, 10) as Priority;\n if (!PRIORITIES.includes(priority)) {\n throw new Error(`Invalid priority: ${options.priority}. Must be 0-4`);\n }\n\n // Get or create pebble directory\n const pebbleDir = getOrCreatePebbleDir();\n const config = getConfig(pebbleDir);\n\n // Resolve parent if provided\n let parentId: string | undefined;\n if (options.parent) {\n parentId = resolveId(options.parent);\n const parent = getIssue(parentId);\n if (!parent) {\n throw new Error(`Parent issue not found: ${options.parent}`);\n }\n if (parent.type === 'verification') {\n throw new Error(`Verification issues cannot be parents`);\n }\n if (parent.status === 'closed') {\n throw new Error(`Cannot add children to closed issue: ${parentId}`);\n }\n }\n\n // Resolve verifies if provided\n let verifiesId: string | undefined;\n if (options.verifies) {\n verifiesId = resolveId(options.verifies);\n const target = getIssue(verifiesId);\n if (!target) {\n throw new Error(`Target issue not found: ${options.verifies}`);\n }\n }\n\n // Resolve --blocked-by (issues that block this new issue)\n const blockedByIds: string[] = [];\n if (options.blockedBy) {\n const ids = options.blockedBy.split(',').map((s: string) => s.trim()).filter(Boolean);\n for (const rawId of ids) {\n const resolvedId = resolveId(rawId);\n const blocker = getIssue(resolvedId);\n if (!blocker) {\n throw new Error(`Blocker issue not found: ${rawId}`);\n }\n if (blocker.status === 'closed') {\n throw new Error(`Cannot be blocked by closed issue: ${resolvedId}`);\n }\n blockedByIds.push(resolvedId);\n }\n }\n\n // Resolve --blocks (issues this new issue will block)\n const blocksIds: string[] = [];\n if (options.blocks) {\n const ids = options.blocks.split(',').map((s: string) => s.trim()).filter(Boolean);\n for (const rawId of ids) {\n const resolvedId = resolveId(rawId);\n const blocked = getIssue(resolvedId);\n if (!blocked) {\n throw new Error(`Issue to block not found: ${rawId}`);\n }\n blocksIds.push(resolvedId);\n }\n }\n\n // Generate ID and create event\n const id = generateId(config.prefix);\n const timestamp = new Date().toISOString();\n\n const event: CreateEvent = {\n type: 'create',\n issueId: id,\n timestamp,\n data: {\n title,\n type,\n priority,\n description: options.description,\n parent: parentId,\n verifies: verifiesId,\n },\n };\n\n appendEvent(event, pebbleDir);\n\n // Add dependencies via UpdateEvents\n // --blocked-by: Set this issue's blockedBy array\n if (blockedByIds.length > 0) {\n const depEvent: UpdateEvent = {\n type: 'update',\n issueId: id,\n timestamp: new Date().toISOString(),\n data: { blockedBy: blockedByIds },\n };\n appendEvent(depEvent, pebbleDir);\n }\n\n // --blocks: Add this issue to each target's blockedBy array\n for (const targetId of blocksIds) {\n const target = getIssue(targetId);\n const existingBlockers = target?.blockedBy || [];\n const depEvent: UpdateEvent = {\n type: 'update',\n issueId: targetId,\n timestamp: new Date().toISOString(),\n data: { blockedBy: [...existingBlockers, id] },\n };\n appendEvent(depEvent, pebbleDir);\n }\n\n // Output success\n outputMutationSuccess(id, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { Priority, Status, UpdateEvent } from '../../shared/types.js';\nimport { PRIORITIES, STATUSES } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { getIssue, resolveId, hasOpenBlockersById, getOpenBlockers } from '../lib/state.js';\nimport { outputMutationSuccess, outputError, formatJson } from '../lib/output.js';\n\nexport function updateCommand(program: Command): void {\n program\n .command('update <ids...>')\n .description('Update issues. Supports multiple IDs.')\n .option('--status <status>', 'Status (open, in_progress, blocked, closed)')\n .option('--priority <priority>', 'Priority (0-4)')\n .option('--title <title>', 'Title')\n .option('--description <desc>', 'Description')\n .option('--parent <id>', 'Parent issue ID (use \"null\" to remove parent)')\n .action(async (ids: string[], options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n\n // Support comma-separated IDs: \"ID1,ID2,ID3\" or \"ID1 ID2 ID3\"\n const allIds = ids.flatMap(id => id.split(',').map(s => s.trim()).filter(Boolean));\n\n if (allIds.length === 0) {\n throw new Error('No issue IDs provided');\n }\n\n // Validate options once (they apply to all)\n const data: UpdateEvent['data'] = {};\n let hasChanges = false;\n\n if (options.status !== undefined) {\n const status = options.status as Status;\n if (!STATUSES.includes(status)) {\n throw new Error(`Invalid status: ${status}. Must be one of: ${STATUSES.join(', ')}`);\n }\n data.status = status;\n hasChanges = true;\n }\n\n if (options.priority !== undefined) {\n const priority = parseInt(options.priority, 10) as Priority;\n if (!PRIORITIES.includes(priority)) {\n throw new Error(`Invalid priority: ${options.priority}. Must be 0-4`);\n }\n data.priority = priority;\n hasChanges = true;\n }\n\n if (options.title !== undefined) {\n data.title = options.title;\n hasChanges = true;\n }\n\n if (options.description !== undefined) {\n data.description = options.description;\n hasChanges = true;\n }\n\n if (options.parent !== undefined) {\n if (options.parent.toLowerCase() === 'null') {\n // Remove parent - use empty string as sentinel (undefined would be ignored by state.ts)\n data.parent = '';\n } else {\n // Resolve and validate parent\n const parentId = resolveId(options.parent);\n const parentIssue = getIssue(parentId);\n if (!parentIssue) {\n throw new Error(`Parent issue not found: ${options.parent}`);\n }\n if (parentIssue.type === 'verification') {\n throw new Error(`Verification issues cannot be parents`);\n }\n if (parentIssue.status === 'closed') {\n throw new Error(`Cannot set parent to closed issue: ${parentId}`);\n }\n data.parent = parentId;\n }\n hasChanges = true;\n }\n\n if (!hasChanges) {\n throw new Error('No changes specified. Use --status, --priority, --title, --description, or --parent');\n }\n\n const results: Array<{ id: string; success: boolean; error?: string }> = [];\n\n for (const id of allIds) {\n try {\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n results.push({ id, success: false, error: `Issue not found: ${id}` });\n continue;\n }\n\n // Cannot set status to in_progress if blocked\n if (data.status === 'in_progress' && hasOpenBlockersById(resolvedId)) {\n const blockers = getOpenBlockers(resolvedId);\n const blockerIds = blockers.map(b => b.id).join(', ');\n results.push({ id: resolvedId, success: false, error: `Cannot set to in_progress - blocked by: ${blockerIds}` });\n continue;\n }\n\n const event: UpdateEvent = {\n type: 'update',\n issueId: resolvedId,\n timestamp: new Date().toISOString(),\n data,\n };\n\n appendEvent(event, pebbleDir);\n results.push({ id: resolvedId, success: true });\n } catch (error) {\n results.push({ id, success: false, error: (error as Error).message });\n }\n }\n\n // Output results\n if (allIds.length === 1) {\n // Single issue - output success or error\n const result = results[0];\n if (result.success) {\n outputMutationSuccess(result.id, pretty);\n } else {\n throw new Error(result.error || 'Unknown error');\n }\n } else {\n // Multiple issues - output array of results\n if (pretty) {\n for (const result of results) {\n if (result.success) {\n console.log(`✓ ${result.id}`);\n } else {\n console.log(`✗ ${result.id}: ${result.error}`);\n }\n }\n } else {\n console.log(formatJson(results.map(r => ({\n id: r.id,\n success: r.success,\n ...(r.error && { error: r.error }),\n }))));\n }\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { CloseEvent, CommentEvent, UpdateEvent } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { getIssue, resolveId, hasOpenChildren, getNewlyUnblocked, getVerifications } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\n\nexport function closeCommand(program: Command): void {\n program\n .command('close <ids...>')\n .description('Close issues. Supports multiple IDs.')\n .option('--reason <reason>', 'Reason for closing')\n .option('--comment <text>', 'Add a comment before closing')\n .action(async (ids: string[], options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n\n // Support comma-separated IDs: \"ID1,ID2,ID3\" or \"ID1 ID2 ID3\"\n const allIds = ids.flatMap(id => id.split(',').map(s => s.trim()).filter(Boolean));\n\n if (allIds.length === 0) {\n throw new Error('No issue IDs provided');\n }\n\n const results: Array<{\n id: string;\n success: boolean;\n error?: string;\n status?: 'closed' | 'pending_verification';\n pendingVerifications?: Array<{ id: string; title: string }>;\n unblocked?: Array<{ id: string; title: string }>;\n autoClosed?: { id: string; title: string };\n }> = [];\n\n for (const id of allIds) {\n try {\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n results.push({ id, success: false, error: `Issue not found: ${id}` });\n continue;\n }\n\n if (issue.status === 'closed') {\n results.push({ id: resolvedId, success: false, error: `Issue is already closed: ${resolvedId}` });\n continue;\n }\n\n // Check if epic has open children\n if (issue.type === 'epic' && hasOpenChildren(resolvedId)) {\n results.push({ id: resolvedId, success: false, error: `Cannot close epic with open children: ${resolvedId}` });\n continue;\n }\n\n const timestamp = new Date().toISOString();\n\n // Add comment first if provided\n if (options.comment) {\n const commentEvent: CommentEvent = {\n type: 'comment',\n issueId: resolvedId,\n timestamp,\n data: {\n text: options.comment,\n timestamp,\n },\n };\n appendEvent(commentEvent, pebbleDir);\n }\n\n // Check for pending verifications\n const pendingVerifications = getVerifications(resolvedId)\n .filter(v => v.status !== 'closed');\n\n if (pendingVerifications.length > 0) {\n // Move to pending_verification instead of closed\n const updateEvent: UpdateEvent = {\n type: 'update',\n issueId: resolvedId,\n timestamp,\n data: {\n status: 'pending_verification',\n },\n };\n appendEvent(updateEvent, pebbleDir);\n\n results.push({\n id: resolvedId,\n success: true,\n status: 'pending_verification',\n pendingVerifications: pendingVerifications.map(v => ({ id: v.id, title: v.title })),\n });\n continue;\n }\n\n // No pending verifications - close normally\n const closeEvent: CloseEvent = {\n type: 'close',\n issueId: resolvedId,\n timestamp,\n data: {\n reason: options.reason,\n },\n };\n\n appendEvent(closeEvent, pebbleDir);\n\n // Get issues that became unblocked\n const unblocked = getNewlyUnblocked(resolvedId);\n\n // Check if this was a verification issue and auto-close target if all verifications done\n let autoClosed: { id: string; title: string } | undefined;\n if (issue.verifies) {\n const targetIssue = getIssue(issue.verifies);\n if (targetIssue && targetIssue.status === 'pending_verification') {\n // Re-fetch verifications to get updated state\n const remainingVerifications = getVerifications(issue.verifies)\n .filter(v => v.status !== 'closed');\n\n if (remainingVerifications.length === 0) {\n // All verifications closed - auto-close the target\n const autoCloseEvent: CloseEvent = {\n type: 'close',\n issueId: issue.verifies,\n timestamp: new Date().toISOString(),\n data: {\n reason: 'All verifications completed',\n },\n };\n appendEvent(autoCloseEvent, pebbleDir);\n autoClosed = { id: targetIssue.id, title: targetIssue.title };\n }\n }\n }\n\n results.push({\n id: resolvedId,\n success: true,\n status: 'closed',\n unblocked: unblocked.length > 0 ? unblocked.map(i => ({ id: i.id, title: i.title })) : undefined,\n autoClosed,\n });\n } catch (error) {\n results.push({ id, success: false, error: (error as Error).message });\n }\n }\n\n // Output results\n if (allIds.length === 1) {\n // Single issue - output success or error\n const result = results[0];\n if (result.success) {\n if (pretty) {\n if (result.status === 'pending_verification') {\n console.log(`⏳ ${result.id} → pending_verification`);\n console.log(`\\nPending verifications:`);\n for (const v of result.pendingVerifications || []) {\n console.log(` • ${v.id} - ${v.title}`);\n }\n console.log(`\\nRun: pb verifications ${result.id}`);\n } else {\n console.log(`✓ ${result.id}`);\n if (result.unblocked && result.unblocked.length > 0) {\n console.log(`\\nUnblocked:`);\n for (const u of result.unblocked) {\n console.log(` → ${u.id} - ${u.title}`);\n }\n }\n if (result.autoClosed) {\n console.log(`\\n✓ ${result.autoClosed.id} auto-closed (all verifications complete)`);\n }\n }\n } else {\n console.log(formatJson({\n id: result.id,\n success: true,\n status: result.status,\n ...(result.pendingVerifications && { pendingVerifications: result.pendingVerifications }),\n ...(result.pendingVerifications && { hint: `pb verifications ${result.id}` }),\n ...(result.unblocked && { unblocked: result.unblocked }),\n ...(result.autoClosed && { autoClosed: result.autoClosed }),\n }));\n }\n } else {\n throw new Error(result.error || 'Unknown error');\n }\n } else {\n // Multiple issues - output array of results\n if (pretty) {\n for (const result of results) {\n if (result.success) {\n if (result.status === 'pending_verification') {\n console.log(`⏳ ${result.id} → pending_verification`);\n for (const v of result.pendingVerifications || []) {\n console.log(` • ${v.id} - ${v.title}`);\n }\n console.log(` Run: pb verifications ${result.id}`);\n } else {\n console.log(`✓ ${result.id}`);\n if (result.unblocked && result.unblocked.length > 0) {\n for (const u of result.unblocked) {\n console.log(` → ${u.id} - ${u.title}`);\n }\n }\n if (result.autoClosed) {\n console.log(` ✓ ${result.autoClosed.id} auto-closed (all verifications complete)`);\n }\n }\n } else {\n console.log(`✗ ${result.id}: ${result.error}`);\n }\n }\n } else {\n console.log(formatJson(results.map(r => ({\n id: r.id,\n success: r.success,\n status: r.status,\n ...(r.error && { error: r.error }),\n ...(r.pendingVerifications && { pendingVerifications: r.pendingVerifications }),\n ...(r.pendingVerifications && { hint: `pb verifications ${r.id}` }),\n ...(r.unblocked && { unblocked: r.unblocked }),\n ...(r.autoClosed && { autoClosed: r.autoClosed }),\n }))));\n }\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { ReopenEvent } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { getIssue, resolveId } from '../lib/state.js';\nimport { outputMutationSuccess, outputError } from '../lib/output.js';\n\nexport function reopenCommand(program: Command): void {\n program\n .command('reopen <id>')\n .description('Reopen a closed issue')\n .option('--reason <reason>', 'Reason for reopening')\n .action(async (id: string, options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n if (issue.status !== 'closed') {\n throw new Error(`Issue is not closed: ${resolvedId} (status: ${issue.status})`);\n }\n\n const event: ReopenEvent = {\n type: 'reopen',\n issueId: resolvedId,\n timestamp: new Date().toISOString(),\n data: {\n reason: options.reason,\n },\n };\n\n appendEvent(event, pebbleDir);\n\n // Output success\n outputMutationSuccess(resolvedId, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { DeleteEvent, UpdateEvent, Issue } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { resolveId, getDescendants, getVerifications, getComputedState } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\n\n// Type for accumulated reference cleanup updates\ntype ReferenceUpdates = Map<string, {\n blockedBy?: string[];\n relatedTo?: string[];\n parent?: string;\n}>;\n\n/**\n * Collect reference cleanup updates for a deleted issue.\n * Updates are accumulated into the provided map and merged if the same issue\n * is affected by multiple deletions. Call emitReferenceCleanup() after collecting\n * all updates to emit the events.\n */\nfunction collectReferenceCleanup(\n deletedId: string,\n deletedIds: Set<string>,\n state: Map<string, Issue>,\n updates: ReferenceUpdates\n): void {\n for (const [id, issue] of state) {\n // Skip issues being deleted\n if (deletedIds.has(id)) continue;\n // Skip already deleted issues\n if (issue.deleted) continue;\n\n // Get or create update entry for this issue\n let entry = updates.get(id);\n\n // Check blockedBy - use existing accumulated value if present\n const currentBlockedBy = entry?.blockedBy ?? issue.blockedBy;\n if (currentBlockedBy.includes(deletedId)) {\n if (!entry) {\n entry = {};\n updates.set(id, entry);\n }\n entry.blockedBy = currentBlockedBy.filter((bid) => bid !== deletedId);\n }\n\n // Check relatedTo - use existing accumulated value if present\n const currentRelatedTo = entry?.relatedTo ?? issue.relatedTo;\n if (currentRelatedTo.includes(deletedId)) {\n if (!entry) {\n entry = {};\n updates.set(id, entry);\n }\n entry.relatedTo = currentRelatedTo.filter((rid) => rid !== deletedId);\n }\n\n // Clear parent if it points to deleted issue\n if (issue.parent === deletedId) {\n if (!entry) {\n entry = {};\n updates.set(id, entry);\n }\n entry.parent = ''; // Empty string signals \"clear parent\"\n }\n }\n}\n\n/**\n * Emit all collected reference cleanup updates as UpdateEvents\n */\nfunction emitReferenceCleanup(\n updates: ReferenceUpdates,\n pebbleDir: string,\n timestamp: string\n): void {\n for (const [id, data] of updates) {\n if (Object.keys(data).length > 0) {\n const updateEvent: UpdateEvent = {\n type: 'update',\n issueId: id,\n timestamp,\n data,\n };\n appendEvent(updateEvent, pebbleDir);\n }\n }\n}\n\nexport function deleteCommand(program: Command): void {\n program\n .command('delete <ids...>')\n .description('Delete issues (soft delete). Epics cascade-delete their children.')\n .option('-r, --reason <reason>', 'Reason for deleting')\n .action(async (ids: string[], options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const state = getComputedState();\n\n // Support comma-separated IDs\n const allIds = ids\n .flatMap((id) => id.split(',').map((s) => s.trim()).filter(Boolean));\n\n if (allIds.length === 0) {\n throw new Error('No issue IDs provided');\n }\n\n const results: Array<{\n id: string;\n success: boolean;\n error?: string;\n cascade?: boolean;\n }> = [];\n\n // Collect all issues to delete (including cascaded)\n const toDelete: Array<{ id: string; cascade: boolean }> = [];\n const alreadyQueued = new Set<string>();\n\n for (const id of allIds) {\n try {\n const resolvedId = resolveId(id);\n const issue = state.get(resolvedId);\n\n if (!issue) {\n results.push({ id, success: false, error: `Issue not found: ${id}` });\n continue;\n }\n\n if (issue.deleted) {\n results.push({ id: resolvedId, success: false, error: `Issue is already deleted: ${resolvedId}` });\n continue;\n }\n\n // Add this issue\n if (!alreadyQueued.has(resolvedId)) {\n toDelete.push({ id: resolvedId, cascade: false });\n alreadyQueued.add(resolvedId);\n }\n\n // Get descendants for cascade delete (children, grandchildren, etc.)\n const descendants = getDescendants(resolvedId, state);\n for (const desc of descendants) {\n if (!alreadyQueued.has(desc.id) && !desc.deleted) {\n toDelete.push({ id: desc.id, cascade: true });\n alreadyQueued.add(desc.id);\n }\n }\n\n // Get verification issues that verify this issue - cascade delete them too\n const verifications = getVerifications(resolvedId);\n for (const v of verifications) {\n if (!alreadyQueued.has(v.id) && !v.deleted) {\n toDelete.push({ id: v.id, cascade: true });\n alreadyQueued.add(v.id);\n }\n }\n } catch (error) {\n results.push({ id, success: false, error: (error as Error).message });\n }\n }\n\n // Collect all reference cleanup updates first (to handle multi-issue deletion correctly)\n const timestamp = new Date().toISOString();\n const deletedIds = new Set(toDelete.map(d => d.id));\n const referenceUpdates: ReferenceUpdates = new Map();\n\n for (const { id } of toDelete) {\n collectReferenceCleanup(id, deletedIds, state, referenceUpdates);\n }\n\n // Emit all reference cleanup events\n emitReferenceCleanup(referenceUpdates, pebbleDir, timestamp);\n\n // Now emit delete events\n for (const { id, cascade } of toDelete) {\n const issue = state.get(id);\n if (!issue) continue;\n\n const deleteEvent: DeleteEvent = {\n type: 'delete',\n issueId: id,\n timestamp,\n data: {\n reason: options.reason,\n cascade: cascade || undefined,\n previousStatus: issue.status,\n },\n };\n appendEvent(deleteEvent, pebbleDir);\n\n results.push({ id, success: true, cascade: cascade || undefined });\n }\n\n // Output results\n if (pretty) {\n // Group by primary vs cascade\n const primary = results.filter((r) => r.success && !r.cascade);\n const cascaded = results.filter((r) => r.success && r.cascade);\n const failed = results.filter((r) => !r.success);\n\n for (const result of primary) {\n console.log(`🗑️ ${result.id} deleted`);\n }\n for (const result of cascaded) {\n console.log(` └─ ${result.id} deleted (cascade)`);\n }\n for (const result of failed) {\n console.log(`✗ ${result.id}: ${result.error}`);\n }\n } else {\n console.log(formatJson({\n deleted: results\n .filter((r) => r.success)\n .map((r) => ({ id: r.id, cascade: r.cascade ?? false })),\n ...(results.some((r) => !r.success) && {\n errors: results\n .filter((r) => !r.success)\n .map((r) => ({ id: r.id, error: r.error })),\n }),\n }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { RestoreEvent } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { getIssue, resolveId } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\n\nexport function restoreCommand(program: Command): void {\n program\n .command('restore <ids...>')\n .description('Restore deleted issues')\n .option('-r, --reason <reason>', 'Reason for restoring')\n .action(async (ids: string[], options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n\n // Support comma-separated IDs\n const allIds = ids\n .flatMap((id) => id.split(',').map((s) => s.trim()).filter(Boolean));\n\n if (allIds.length === 0) {\n throw new Error('No issue IDs provided');\n }\n\n const results: Array<{\n id: string;\n success: boolean;\n error?: string;\n }> = [];\n\n const timestamp = new Date().toISOString();\n\n for (const id of allIds) {\n try {\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId, true); // includeDeleted=true to find deleted issues\n\n if (!issue) {\n results.push({ id, success: false, error: `Issue not found: ${id}` });\n continue;\n }\n\n if (!issue.deleted) {\n results.push({ id: resolvedId, success: false, error: `Issue is not deleted: ${resolvedId}` });\n continue;\n }\n\n const restoreEvent: RestoreEvent = {\n type: 'restore',\n issueId: resolvedId,\n timestamp,\n data: {\n reason: options.reason,\n },\n };\n\n appendEvent(restoreEvent, pebbleDir);\n results.push({ id: resolvedId, success: true });\n } catch (error) {\n results.push({ id, success: false, error: (error as Error).message });\n }\n }\n\n // Output results\n if (allIds.length === 1) {\n const result = results[0];\n if (result.success) {\n if (pretty) {\n console.log(`↩️ ${result.id} restored`);\n } else {\n console.log(formatJson({ id: result.id, success: true }));\n }\n } else {\n throw new Error(result.error || 'Unknown error');\n }\n } else {\n if (pretty) {\n for (const result of results) {\n if (result.success) {\n console.log(`↩️ ${result.id} restored`);\n } else {\n console.log(`✗ ${result.id}: ${result.error}`);\n }\n }\n } else {\n console.log(formatJson({\n restored: results.filter((r) => r.success).map((r) => r.id),\n ...(results.some((r) => !r.success) && {\n errors: results\n .filter((r) => !r.success)\n .map((r) => ({ id: r.id, error: r.error })),\n }),\n }));\n }\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { UpdateEvent } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { getIssue, resolveId, hasOpenBlockersById, getOpenBlockers } from '../lib/state.js';\nimport { outputMutationSuccess, outputError, formatJson } from '../lib/output.js';\n\nexport function claimCommand(program: Command): void {\n program\n .command('claim <ids...>')\n .description('Claim issues (set status to in_progress). Supports multiple IDs.')\n .action(async (ids: string[]) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n\n // Support comma-separated IDs: \"ID1,ID2,ID3\" or \"ID1 ID2 ID3\"\n const allIds = ids.flatMap(id => id.split(',').map(s => s.trim()).filter(Boolean));\n\n if (allIds.length === 0) {\n throw new Error('No issue IDs provided');\n }\n\n const results: Array<{ id: string; success: boolean; error?: string }> = [];\n\n for (const id of allIds) {\n try {\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n results.push({ id, success: false, error: `Issue not found: ${id}` });\n continue;\n }\n\n if (issue.status === 'in_progress') {\n results.push({ id: resolvedId, success: true });\n continue;\n }\n\n if (issue.status === 'closed') {\n results.push({ id: resolvedId, success: false, error: `Cannot claim closed issue: ${resolvedId}` });\n continue;\n }\n\n // Check if blocked\n if (hasOpenBlockersById(resolvedId)) {\n const blockers = getOpenBlockers(resolvedId);\n const blockerIds = blockers.map(b => b.id).join(', ');\n results.push({ id: resolvedId, success: false, error: `Cannot claim blocked issue. Blocked by: ${blockerIds}` });\n continue;\n }\n\n const event: UpdateEvent = {\n type: 'update',\n issueId: resolvedId,\n timestamp: new Date().toISOString(),\n data: {\n status: 'in_progress',\n },\n };\n\n appendEvent(event, pebbleDir);\n results.push({ id: resolvedId, success: true });\n } catch (error) {\n results.push({ id, success: false, error: (error as Error).message });\n }\n }\n\n // Output results\n if (allIds.length === 1) {\n // Single issue - output success or error\n const result = results[0];\n if (result.success) {\n outputMutationSuccess(result.id, pretty);\n } else {\n throw new Error(result.error || 'Unknown error');\n }\n } else {\n // Multiple issues - output array of results\n if (pretty) {\n for (const result of results) {\n if (result.success) {\n console.log(`✓ ${result.id}`);\n } else {\n console.log(`✗ ${result.id}: ${result.error}`);\n }\n }\n } else {\n console.log(formatJson(results.map(r => ({\n id: r.id,\n success: r.success,\n ...(r.error && { error: r.error }),\n }))));\n }\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { IssueType, Priority, Status, IssueFilters } from '../../shared/types.js';\nimport { ISSUE_TYPES, PRIORITIES, STATUSES, STATUS_LABELS } from '../../shared/types.js';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssues, resolveId, getBlocking, getChildren, getVerifications, getComputedState, getAncestryChain } from '../lib/state.js';\nimport { outputIssueList, outputIssueListVerbose, outputIssueTree, outputError, type VerboseIssueInfo, type LimitInfo } from '../lib/output.js';\n\nexport function listCommand(program: Command): void {\n program\n .command('list')\n .description('List issues')\n .option('--status <status>', 'Filter by status')\n .option('-t, --type <type>', 'Filter by type')\n .option('--priority <priority>', 'Filter by priority')\n .option('--parent <id>', 'Filter by parent epic')\n .option('-v, --verbose', 'Show expanded details (parent, children, blocking, verifications)')\n .option('--flat', 'Show flat list instead of hierarchical tree')\n .option('--limit <n>', 'Max issues to return (default: 30)')\n .option('--all', 'Show all issues (no limit)')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Auto-init .pebble/ if it doesn't exist\n getOrCreatePebbleDir();\n\n const filters: IssueFilters = {};\n\n if (options.status !== undefined) {\n const status = options.status as Status;\n if (!STATUSES.includes(status)) {\n throw new Error(`Invalid status: ${status}. Must be one of: ${STATUSES.join(', ')}`);\n }\n filters.status = status;\n }\n\n if (options.type !== undefined) {\n const type = options.type as IssueType;\n if (!ISSUE_TYPES.includes(type)) {\n throw new Error(`Invalid type: ${type}. Must be one of: ${ISSUE_TYPES.join(', ')}`);\n }\n filters.type = type;\n }\n\n if (options.priority !== undefined) {\n const priority = parseInt(options.priority, 10) as Priority;\n if (!PRIORITIES.includes(priority)) {\n throw new Error(`Invalid priority: ${options.priority}. Must be 0-4`);\n }\n filters.priority = priority;\n }\n\n if (options.parent !== undefined) {\n filters.parent = resolveId(options.parent);\n }\n\n let issues = getIssues(filters);\n\n // Sort by createdAt descending (newest first)\n issues.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n\n // Apply limit\n const total = issues.length;\n const limit = options.all ? 0 : (options.limit ? parseInt(options.limit, 10) : 30);\n if (limit > 0 && issues.length > limit) {\n issues = issues.slice(0, limit);\n }\n const limitInfo: LimitInfo = {\n total,\n shown: issues.length,\n limited: limit > 0 && total > limit,\n };\n\n // Verbose output: flat list with expanded details\n if (options.verbose) {\n // Get computed state once for efficient ancestry lookups\n const state = getComputedState();\n\n // Build verbose info for each issue\n const verboseIssues: VerboseIssueInfo[] = issues.map((issue) => {\n return {\n issue,\n blocking: getBlocking(issue.id).map((i) => i.id),\n children: getChildren(issue.id).length,\n verifications: getVerifications(issue.id).length,\n ancestry: getAncestryChain(issue.id, state),\n };\n });\n\n // Determine section header based on filters\n let sectionHeader = 'Issues';\n if (filters.status) {\n sectionHeader = `${STATUS_LABELS[filters.status]} Issues`;\n }\n outputIssueListVerbose(verboseIssues, pretty, sectionHeader, limitInfo);\n } else if (options.flat) {\n // Flat output: simple table/list\n outputIssueList(issues, pretty, limitInfo);\n } else {\n // Default: hierarchical tree structure\n let sectionHeader = 'Issues';\n if (filters.status) {\n sectionHeader = `${STATUS_LABELS[filters.status]} Issues`;\n }\n outputIssueTree(issues, pretty, sectionHeader, limitInfo);\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssue, resolveId, getBlocking, getChildren, getVerifications, getRelated, getComputedState, getAncestryChain } from '../lib/state.js';\nimport { outputIssueDetail, outputError } from '../lib/output.js';\n\nexport function showCommand(program: Command): void {\n program\n .command('show <id>')\n .description('Show issue details')\n .action(async (id: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Auto-init .pebble/ if it doesn't exist\n getOrCreatePebbleDir();\n\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n const blocking = getBlocking(resolvedId);\n const children = issue.type === 'epic' ? getChildren(resolvedId) : [];\n const verifications = getVerifications(resolvedId);\n const related = getRelated(resolvedId);\n const state = getComputedState();\n const ancestry = getAncestryChain(resolvedId, state);\n\n outputIssueDetail(issue, { blocking, children, verifications, related, ancestry }, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport { ISSUE_TYPES, type IssueType } from '../../shared/types.js';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getReady, getBlocking, getChildren, getVerifications, getComputedState, getAncestryChain } from '../lib/state.js';\nimport { outputIssueList, outputIssueListVerbose, outputError, type VerboseIssueInfo, type LimitInfo } from '../lib/output.js';\n\nexport function readyCommand(program: Command): void {\n program\n .command('ready')\n .description('Show issues ready for work (no open blockers)')\n .option('-v, --verbose', 'Show expanded details (parent, children, blocking, verifications)')\n .option('-t, --type <type>', 'Filter by type: task, bug, epic, verification')\n .option('--limit <n>', 'Max issues to return (default: 30)')\n .option('--all', 'Show all issues (no limit)')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Auto-init .pebble/ if it doesn't exist\n getOrCreatePebbleDir();\n\n let issues = getReady();\n\n // Filter by type if specified\n if (options.type) {\n const typeFilter = options.type.toLowerCase() as IssueType;\n if (!ISSUE_TYPES.includes(typeFilter)) {\n throw new Error(`Invalid type: ${options.type}. Must be one of: ${ISSUE_TYPES.join(', ')}`);\n }\n issues = issues.filter((i) => i.type === typeFilter);\n }\n\n // Sort by createdAt descending (newest first)\n issues.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n\n // Apply limit\n const total = issues.length;\n const limit = options.all ? 0 : (options.limit ? parseInt(options.limit, 10) : 30);\n if (limit > 0 && issues.length > limit) {\n issues = issues.slice(0, limit);\n }\n const limitInfo: LimitInfo = {\n total,\n shown: issues.length,\n limited: limit > 0 && total > limit,\n };\n\n if (options.verbose) {\n // Get computed state once for efficient ancestry lookups\n const state = getComputedState();\n\n // Build verbose info for each issue\n const verboseIssues: VerboseIssueInfo[] = issues.map((issue) => {\n return {\n issue,\n blocking: getBlocking(issue.id).map((i) => i.id),\n children: getChildren(issue.id).length,\n verifications: getVerifications(issue.id).length,\n ancestry: getAncestryChain(issue.id, state),\n };\n });\n outputIssueListVerbose(verboseIssues, pretty, 'Ready Issues', limitInfo);\n } else {\n outputIssueList(issues, pretty, limitInfo);\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getBlocked, getBlocking, getChildren, getVerifications, getBlockers, getComputedState, getAncestryChain } from '../lib/state.js';\nimport { outputIssueList, outputIssueListVerbose, outputError, type VerboseIssueInfo, type LimitInfo } from '../lib/output.js';\n\nexport function blockedCommand(program: Command): void {\n program\n .command('blocked')\n .description('Show blocked issues (have open blockers)')\n .option('-v, --verbose', 'Show expanded details including WHY each issue is blocked')\n .option('--limit <n>', 'Max issues to return (default: 30)')\n .option('--all', 'Show all issues (no limit)')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Auto-init .pebble/ if it doesn't exist\n getOrCreatePebbleDir();\n\n let issues = getBlocked();\n\n // Sort by createdAt descending (newest first)\n issues.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n\n // Apply limit\n const total = issues.length;\n const limit = options.all ? 0 : (options.limit ? parseInt(options.limit, 10) : 30);\n if (limit > 0 && issues.length > limit) {\n issues = issues.slice(0, limit);\n }\n const limitInfo: LimitInfo = {\n total,\n shown: issues.length,\n limited: limit > 0 && total > limit,\n };\n\n if (options.verbose) {\n // Get computed state once for efficient ancestry lookups\n const state = getComputedState();\n\n // Build verbose info for each issue, including open blockers\n const verboseIssues: VerboseIssueInfo[] = issues.map((issue) => {\n // Get open blockers (issues blocking this one that aren't closed)\n const allBlockers = getBlockers(issue.id);\n const openBlockers = allBlockers\n .filter((b) => b.status !== 'closed')\n .map((b) => b.id);\n\n return {\n issue,\n blocking: getBlocking(issue.id).map((i) => i.id),\n children: getChildren(issue.id).length,\n verifications: getVerifications(issue.id).length,\n blockers: openBlockers,\n ancestry: getAncestryChain(issue.id, state),\n };\n });\n outputIssueListVerbose(verboseIssues, pretty, 'Blocked Issues', limitInfo);\n } else {\n outputIssueList(issues, pretty, limitInfo);\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { Issue, UpdateEvent } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent, readEvents } from '../lib/storage.js';\nimport {\n getIssue,\n resolveId,\n detectCycle,\n getBlockers,\n getBlocking,\n getRelated,\n computeState,\n} from '../lib/state.js';\nimport { outputMutationSuccess, outputError, formatDepsPretty, formatJson } from '../lib/output.js';\n\nexport function depCommand(program: Command): void {\n const dep = program\n .command('dep')\n .description('Manage dependencies');\n\n // dep add <id> [blocker-id] --needs <id> --blocks <id>\n dep\n .command('add <id> [blockerId]')\n .description('Add a blocking dependency. Use --needs or --blocks for self-documenting syntax.')\n .option('--needs <id>', 'Issue that must be completed first (first arg needs this)')\n .option('--blocks <id>', 'Issue that this blocks (first arg blocks this)')\n .action(async (id: string, blockerId: string | undefined, options: { needs?: string; blocks?: string }) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Validate usage: cannot combine flags with each other or with positional\n if (options.needs && options.blocks) {\n throw new Error('Cannot use both --needs and --blocks');\n }\n if (blockerId && (options.needs || options.blocks)) {\n throw new Error('Cannot combine positional blockerId with --needs or --blocks');\n }\n if (!blockerId && !options.needs && !options.blocks) {\n throw new Error('Must provide blockerId, --needs <id>, or --blocks <id>');\n }\n\n const pebbleDir = getOrCreatePebbleDir();\n\n // Determine blocked and blocker based on usage:\n // pb dep add X Y => X is blocked by Y\n // pb dep add X --needs Y => X is blocked by Y (same as above)\n // pb dep add X --blocks Y => Y is blocked by X (inverted)\n let blockedId: string;\n let blockerIdResolved: string;\n\n if (options.blocks) {\n // X blocks Y => Y is blocked by X\n blockedId = resolveId(options.blocks);\n blockerIdResolved = resolveId(id);\n } else {\n // X needs Y or X Y => X is blocked by Y\n blockedId = resolveId(id);\n blockerIdResolved = resolveId(options.needs || blockerId!);\n }\n\n const issue = getIssue(blockedId);\n if (!issue) {\n throw new Error(`Issue not found: ${blockedId}`);\n }\n\n const blocker = getIssue(blockerIdResolved);\n if (!blocker) {\n throw new Error(`Blocker issue not found: ${blockerIdResolved}`);\n }\n\n // Check for self-reference\n if (blockedId === blockerIdResolved) {\n throw new Error('Cannot add self as blocker');\n }\n\n // Check for existing dependency\n if (issue.blockedBy.includes(blockerIdResolved)) {\n throw new Error(`Dependency already exists: ${blockedId} is blocked by ${blockerIdResolved}`);\n }\n\n // Check for cycles\n if (detectCycle(blockedId, blockerIdResolved)) {\n throw new Error(`Adding this dependency would create a cycle`);\n }\n\n // Add the dependency\n const event: UpdateEvent = {\n type: 'update',\n issueId: blockedId,\n timestamp: new Date().toISOString(),\n data: {\n blockedBy: [...issue.blockedBy, blockerIdResolved],\n },\n };\n\n appendEvent(event, pebbleDir);\n\n outputMutationSuccess(blockedId, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n\n // dep remove <id> <blocker-id>\n dep\n .command('remove <id> <blockerId>')\n .description('Remove a blocking dependency')\n .action(async (id: string, blockerId: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const resolvedId = resolveId(id);\n const resolvedBlockerId = resolveId(blockerId);\n\n const issue = getIssue(resolvedId);\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n // Check if dependency exists before removing\n if (!issue.blockedBy.includes(resolvedBlockerId)) {\n throw new Error(`Dependency does not exist: ${resolvedId} is not blocked by ${resolvedBlockerId}`);\n }\n\n // Remove the dependency\n const newBlockedBy = issue.blockedBy.filter((b) => b !== resolvedBlockerId);\n\n const event: UpdateEvent = {\n type: 'update',\n issueId: resolvedId,\n timestamp: new Date().toISOString(),\n data: {\n blockedBy: newBlockedBy,\n },\n };\n\n appendEvent(event, pebbleDir);\n\n outputMutationSuccess(resolvedId, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n\n // dep relate <id1> <id2> - bidirectional relationship\n dep\n .command('relate <id1> <id2>')\n .description('Add a bidirectional related link between two issues')\n .action(async (id1: string, id2: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const resolvedId1 = resolveId(id1);\n const resolvedId2 = resolveId(id2);\n\n const issue1 = getIssue(resolvedId1);\n if (!issue1) {\n throw new Error(`Issue not found: ${id1}`);\n }\n\n const issue2 = getIssue(resolvedId2);\n if (!issue2) {\n throw new Error(`Issue not found: ${id2}`);\n }\n\n // Check for self-reference\n if (resolvedId1 === resolvedId2) {\n throw new Error('Cannot relate issue to itself');\n }\n\n // Check if already related\n if (issue1.relatedTo.includes(resolvedId2)) {\n throw new Error(`Issues are already related: ${resolvedId1} ↔ ${resolvedId2}`);\n }\n\n const timestamp = new Date().toISOString();\n\n // Add bidirectional relationship\n const event1: UpdateEvent = {\n type: 'update',\n issueId: resolvedId1,\n timestamp,\n data: {\n relatedTo: [...issue1.relatedTo, resolvedId2],\n },\n };\n\n const event2: UpdateEvent = {\n type: 'update',\n issueId: resolvedId2,\n timestamp,\n data: {\n relatedTo: [...issue2.relatedTo, resolvedId1],\n },\n };\n\n appendEvent(event1, pebbleDir);\n appendEvent(event2, pebbleDir);\n\n if (pretty) {\n console.log(`✓ ${resolvedId1} ↔ ${resolvedId2}`);\n } else {\n console.log(formatJson({ id1: resolvedId1, id2: resolvedId2, related: true }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n\n // dep unrelate <id1> <id2> - remove bidirectional relationship\n dep\n .command('unrelate <id1> <id2>')\n .description('Remove a bidirectional related link between two issues')\n .action(async (id1: string, id2: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const resolvedId1 = resolveId(id1);\n const resolvedId2 = resolveId(id2);\n\n const issue1 = getIssue(resolvedId1);\n if (!issue1) {\n throw new Error(`Issue not found: ${id1}`);\n }\n\n const issue2 = getIssue(resolvedId2);\n if (!issue2) {\n throw new Error(`Issue not found: ${id2}`);\n }\n\n // Check if related\n if (!issue1.relatedTo.includes(resolvedId2)) {\n throw new Error(`Issues are not related: ${resolvedId1} ↔ ${resolvedId2}`);\n }\n\n const timestamp = new Date().toISOString();\n\n // Remove bidirectional relationship\n const event1: UpdateEvent = {\n type: 'update',\n issueId: resolvedId1,\n timestamp,\n data: {\n relatedTo: issue1.relatedTo.filter((id) => id !== resolvedId2),\n },\n };\n\n const event2: UpdateEvent = {\n type: 'update',\n issueId: resolvedId2,\n timestamp,\n data: {\n relatedTo: issue2.relatedTo.filter((id) => id !== resolvedId1),\n },\n };\n\n appendEvent(event1, pebbleDir);\n appendEvent(event2, pebbleDir);\n\n if (pretty) {\n console.log(`✓ ${resolvedId1} ↮ ${resolvedId2}`);\n } else {\n console.log(formatJson({ id1: resolvedId1, id2: resolvedId2, related: false }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n\n // dep list <id>\n dep\n .command('list <id>')\n .description('List dependencies for an issue')\n .action(async (id: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n const blockedBy = getBlockers(resolvedId);\n const blocking = getBlocking(resolvedId);\n const related = getRelated(resolvedId);\n\n if (pretty) {\n console.log(formatDepsPretty(resolvedId, blockedBy, blocking, related));\n } else {\n console.log(formatJson({\n issueId: resolvedId,\n blockedBy: blockedBy.map((i) => ({ id: i.id, title: i.title, status: i.status })),\n blocking: blocking.map((i) => ({ id: i.id, title: i.title, status: i.status })),\n related: related.map((i) => ({ id: i.id, title: i.title, status: i.status })),\n }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n\n // dep tree <id>\n dep\n .command('tree <id>')\n .description('Show issue tree (children, verifications, and full hierarchy)')\n .action(async (id: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n // Build tree structure - compute state once\n const events = readEvents();\n const state = computeState(events);\n const tree = buildIssueTree(resolvedId, state);\n\n if (pretty) {\n console.log(formatIssueTreePretty(tree));\n } else {\n console.log(formatJson(tree));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n\ninterface IssueTreeNode {\n id: string;\n title: string;\n type: string;\n priority: number;\n status: string;\n isTarget?: boolean; // The issue that was requested\n childrenCount: number;\n children?: IssueTreeNode[];\n}\n\nfunction buildIssueTree(\n issueId: string,\n state: Map<string, Issue>\n): IssueTreeNode | null {\n const issue = state.get(issueId);\n if (!issue) {\n return null;\n }\n\n // Build children recursively\n const buildChildren = (id: string, visited: Set<string>): IssueTreeNode[] => {\n const children: IssueTreeNode[] = [];\n for (const [, i] of state) {\n if ((i.parent === id || i.verifies === id) && !visited.has(i.id)) {\n visited.add(i.id);\n const nodeChildren = buildChildren(i.id, visited);\n children.push({\n id: i.id,\n title: i.title,\n type: i.type,\n priority: i.priority,\n status: i.status,\n isTarget: i.id === issueId,\n childrenCount: nodeChildren.length,\n ...(nodeChildren.length > 0 && { children: nodeChildren }),\n });\n }\n }\n return children;\n };\n\n // Build the target node with its children\n const visited = new Set<string>([issueId]);\n const targetChildren = buildChildren(issueId, visited);\n const targetNode: IssueTreeNode = {\n id: issue.id,\n title: issue.title,\n type: issue.type,\n priority: issue.priority,\n status: issue.status,\n isTarget: true,\n childrenCount: targetChildren.length,\n ...(targetChildren.length > 0 && { children: targetChildren }),\n };\n\n // Walk up the parent chain to find the root\n let currentNode = targetNode;\n let currentIssue = issue;\n\n while (currentIssue.parent) {\n const parentIssue = state.get(currentIssue.parent);\n if (!parentIssue) break;\n\n // Create parent node with current as child, plus any siblings\n const siblings: IssueTreeNode[] = [];\n for (const [, i] of state) {\n if ((i.parent === parentIssue.id || i.verifies === parentIssue.id) && i.id !== currentIssue.id) {\n // Add sibling (but don't expand its children to keep output focused)\n siblings.push({\n id: i.id,\n title: i.title,\n type: i.type,\n priority: i.priority,\n status: i.status,\n childrenCount: 0,\n });\n }\n }\n\n const parentNodeChildren = [currentNode, ...siblings];\n const parentNode: IssueTreeNode = {\n id: parentIssue.id,\n title: parentIssue.title,\n type: parentIssue.type,\n priority: parentIssue.priority,\n status: parentIssue.status,\n childrenCount: parentNodeChildren.length,\n children: parentNodeChildren,\n };\n\n currentNode = parentNode;\n currentIssue = parentIssue;\n }\n\n return currentNode;\n}\n\nfunction formatIssueTreePretty(node: IssueTreeNode | null): string {\n if (!node) {\n return 'Issue not found.';\n }\n\n const lines: string[] = [];\n\n const formatNode = (n: IssueTreeNode, prefix: string, isLast: boolean, isRoot: boolean): void => {\n const connector = isRoot ? '' : isLast ? '└─ ' : '├─ ';\n const statusIcon = n.status === 'closed' ? '✓' : n.status === 'in_progress' ? '▶' : n.status === 'pending_verification' ? '⏳' : '○';\n const marker = n.isTarget ? ' ◀' : '';\n\n lines.push(`${prefix}${connector}${statusIcon} ${n.id}: ${n.title} [${n.type}] P${n.priority}${marker}`);\n\n const children = n.children ?? [];\n const childPrefix = isRoot ? '' : prefix + (isLast ? ' ' : '│ ');\n children.forEach((child, index) => {\n const childIsLast = index === children.length - 1;\n formatNode(child, childPrefix, childIsLast, false);\n });\n };\n\n formatNode(node, '', true, true);\n\n return lines.join('\\n');\n}\n","import { Command } from 'commander';\nimport type { CommentEvent } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { getIssue, resolveId } from '../lib/state.js';\nimport { outputMutationSuccess, outputError } from '../lib/output.js';\n\nexport function commentsCommand(program: Command): void {\n const comments = program\n .command('comments')\n .description('Manage comments');\n\n // comments add <id> <text>\n comments\n .command('add <id> <text>')\n .description('Add a comment to an issue')\n .action(async (id: string, text: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n const timestamp = new Date().toISOString();\n const event: CommentEvent = {\n type: 'comment',\n issueId: resolvedId,\n timestamp,\n data: {\n text,\n timestamp,\n },\n };\n\n appendEvent(event, pebbleDir);\n\n outputMutationSuccess(resolvedId, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssue, getIssues, resolveId } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\nimport type { Issue } from '../../shared/types.js';\n\nexport function graphCommand(program: Command): void {\n program\n .command('graph')\n .description('Show dependency graph')\n .option('--root <id>', 'Filter to subtree rooted at issue')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Auto-init .pebble/ if it doesn't exist\n getOrCreatePebbleDir();\n\n let issues: Issue[];\n\n if (options.root) {\n const rootId = resolveId(options.root);\n const rootIssue = getIssue(rootId);\n if (!rootIssue) {\n throw new Error(`Issue not found: ${options.root}`);\n }\n // Get all issues in the subtree\n issues = getSubtree(rootId);\n } else {\n issues = getIssues({});\n }\n\n if (pretty) {\n console.log(formatGraphPretty(issues));\n } else {\n console.log(formatJson({\n nodes: issues.map((i) => ({\n id: i.id,\n title: i.title,\n status: i.status,\n blockedBy: i.blockedBy,\n })),\n }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n\nfunction getSubtree(rootId: string): Issue[] {\n // Get all issues to build reverse lookup maps\n const allIssues = getIssues({});\n const issueMap = new Map(allIssues.map((i) => [i.id, i]));\n const neighborhood = new Set<string>();\n\n // Traverse upstream: what blocks this issue (recursively)\n function traverseUpstream(id: string) {\n if (neighborhood.has(id)) return;\n neighborhood.add(id);\n const issue = issueMap.get(id);\n if (issue) {\n // Blockers\n for (const blockerId of issue.blockedBy) {\n traverseUpstream(blockerId);\n }\n // Parent\n if (issue.parent) {\n traverseUpstream(issue.parent);\n }\n }\n }\n\n // Traverse downstream: what this issue blocks (recursively)\n function traverseDownstream(id: string) {\n if (neighborhood.has(id)) return;\n neighborhood.add(id);\n // Find issues blocked by this one\n for (const issue of allIssues) {\n if (issue.blockedBy.includes(id)) {\n traverseDownstream(issue.id);\n }\n // Find children\n if (issue.parent === id) {\n traverseDownstream(issue.id);\n }\n }\n }\n\n traverseUpstream(rootId);\n traverseDownstream(rootId);\n\n // Return issues in the neighborhood\n return allIssues.filter((i) => neighborhood.has(i.id));\n}\n\nfunction formatGraphPretty(issues: Issue[]): string {\n if (issues.length === 0) {\n return 'No issues found.';\n }\n\n const lines: string[] = [];\n lines.push('Dependency Graph');\n lines.push('================');\n lines.push('');\n\n // Build adjacency maps\n const blockedByMap = new Map<string, string[]>();\n const blockingMap = new Map<string, string[]>();\n const issueMap = new Map<string, Issue>();\n\n for (const issue of issues) {\n issueMap.set(issue.id, issue);\n blockedByMap.set(issue.id, issue.blockedBy);\n\n for (const blockerId of issue.blockedBy) {\n if (!blockingMap.has(blockerId)) {\n blockingMap.set(blockerId, []);\n }\n blockingMap.get(blockerId)!.push(issue.id);\n }\n }\n\n // Calculate levels using topological sort\n const levels = new Map<string, number>();\n const visited = new Set<string>();\n\n function calculateLevel(id: string): number {\n if (levels.has(id)) return levels.get(id)!;\n if (visited.has(id)) return 0; // Cycle protection\n visited.add(id);\n\n const blockedBy = blockedByMap.get(id) || [];\n let maxBlockerLevel = -1;\n for (const blockerId of blockedBy) {\n const blockerLevel = calculateLevel(blockerId);\n maxBlockerLevel = Math.max(maxBlockerLevel, blockerLevel);\n }\n\n const level = maxBlockerLevel + 1;\n levels.set(id, level);\n return level;\n }\n\n for (const issue of issues) {\n calculateLevel(issue.id);\n }\n\n // Group by level\n const byLevel = new Map<number, Issue[]>();\n for (const issue of issues) {\n const level = levels.get(issue.id) || 0;\n if (!byLevel.has(level)) {\n byLevel.set(level, []);\n }\n byLevel.get(level)!.push(issue);\n }\n\n // Print by level\n const maxLevel = Math.max(...Array.from(levels.values()));\n for (let level = 0; level <= maxLevel; level++) {\n const levelIssues = byLevel.get(level) || [];\n if (levelIssues.length === 0) continue;\n\n lines.push(`Level ${level}:`);\n for (const issue of levelIssues) {\n const statusIcon = issue.status === 'closed' ? '✓' : '○';\n const blockers = issue.blockedBy.length > 0 ? ` ← [${issue.blockedBy.join(', ')}]` : '';\n lines.push(` ${statusIcon} ${issue.id} - ${issue.title}${blockers}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","import { Command } from 'commander';\nimport express, { Response } from 'express';\nimport cors from 'cors';\nimport { fileURLToPath } from 'url';\nimport path from 'path';\nimport fs from 'fs';\nimport net from 'net';\nimport open from 'open';\nimport chokidar from 'chokidar';\nimport {\n getIssue,\n resolveId,\n hasOpenChildren,\n detectCycle,\n computeState,\n getVerifications,\n getDescendants,\n getComputedState,\n} from '../lib/state.js';\nimport {\n readEventsFromFile,\n getOrCreatePebbleDir,\n appendEvent,\n getConfig,\n getEventSource,\n} from '../lib/storage.js';\nimport { generateId } from '../lib/id.js';\nimport { outputError } from '../lib/output.js';\nimport type {\n CreateEvent,\n UpdateEvent,\n CloseEvent,\n ReopenEvent,\n CommentEvent,\n DeleteEvent,\n RestoreEvent,\n IssueType,\n IssueEvent,\n Priority,\n Issue,\n} from '../../shared/types.js';\nimport { ISSUE_TYPES, STATUSES, PRIORITIES } from '../../shared/types.js';\n\n// Check if a port is available\nfunction isPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = net.createServer();\n server.once('error', () => resolve(false));\n server.once('listening', () => {\n server.close();\n resolve(true);\n });\n server.listen(port);\n });\n}\n\n// Find an available port starting from the given port\nasync function findAvailablePort(startPort: number, maxAttempts = 10): Promise<number> {\n for (let i = 0; i < maxAttempts; i++) {\n const port = startPort + i;\n if (await isPortAvailable(port)) {\n return port;\n }\n }\n throw new Error(`No available port found (tried ${startPort}-${startPort + maxAttempts - 1})`);\n}\n\n// Multi-worktree: Issue with source tracking\ninterface IssueWithSource extends Issue {\n _sources: string[]; // File paths where this issue exists\n}\n\n/**\n * Merge events from multiple files, deduplicating by (issueId, timestamp, type).\n * Same event appearing in multiple files = keep first occurrence.\n */\nfunction mergeEventsFromFiles(filePaths: string[]): IssueEvent[] {\n const merged = new Map<string, IssueEvent>();\n\n for (const filePath of filePaths) {\n const events = readEventsFromFile(filePath);\n for (const event of events) {\n const key = `${event.issueId}-${event.timestamp}-${event.type}`;\n if (!merged.has(key)) {\n merged.set(key, event);\n }\n }\n }\n\n // Sort by timestamp ascending (chronological order)\n return Array.from(merged.values()).sort(\n (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()\n );\n}\n\n/**\n * Merge issues from multiple files.\n * Same ID = same issue: keep the version with the latest updatedAt.\n * Tracks which file(s) contain each issue.\n */\nfunction mergeIssuesFromFiles(filePaths: string[]): IssueWithSource[] {\n const merged = new Map<string, { issue: Issue; sources: Set<string> }>();\n\n for (const filePath of filePaths) {\n const events = readEventsFromFile(filePath);\n const state = computeState(events);\n\n for (const [id, issue] of state) {\n const existing = merged.get(id);\n if (!existing) {\n // First time seeing this issue\n merged.set(id, { issue, sources: new Set([filePath]) });\n } else {\n // Issue exists in multiple files - keep the one with latest updatedAt\n existing.sources.add(filePath);\n if (new Date(issue.updatedAt) > new Date(existing.issue.updatedAt)) {\n merged.set(id, { issue, sources: existing.sources });\n }\n }\n }\n }\n\n return Array.from(merged.values()).map(({ issue, sources }) => ({\n ...issue,\n _sources: Array.from(sources),\n }));\n}\n\n/**\n * Find an issue by ID across all source files.\n * Returns the issue and which file to write mutations to.\n */\nfunction findIssueInSources(\n issueId: string,\n filePaths: string[]\n): { issue: Issue; targetFile: string } | null {\n // First, try to find by exact ID or prefix match\n const allIssues = mergeIssuesFromFiles(filePaths);\n\n // Try exact match first\n let found = allIssues.find((i) => i.id === issueId);\n\n // Try prefix match if no exact match\n if (!found) {\n const matches = allIssues.filter((i) => i.id.startsWith(issueId));\n if (matches.length === 1) {\n found = matches[0];\n } else if (matches.length > 1) {\n return null; // Ambiguous\n }\n }\n\n if (!found) {\n return null;\n }\n\n // Use the first source file (where the issue was most recently updated)\n const targetFile = found._sources[0];\n return { issue: found, targetFile };\n}\n\n/**\n * Append an event to a specific file (for multi-worktree mode).\n * Automatically adds source field if not present.\n */\nfunction appendEventToFile(event: IssueEvent, filePath: string): void {\n // Add source if not already present\n const eventWithSource = event.source ? event : { ...event, source: getEventSource() };\n const line = JSON.stringify(eventWithSource) + '\\n';\n fs.appendFileSync(filePath, line, 'utf-8');\n}\n\nexport function uiCommand(program: Command): void {\n const defaultPort = process.env.PEBBLE_UI_PORT || '3333';\n\n program\n .command('ui')\n .description('Serve the React UI')\n .option('--port <port>', 'Port to serve on', defaultPort)\n .option('--no-open', 'Do not open browser automatically')\n .option('--files <paths>', 'Comma-separated paths to issues.jsonl files for multi-worktree view')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Parse multi-worktree files option\n let issueFiles: string[] = [];\n if (options.files) {\n // Parse comma-separated paths\n issueFiles = options.files.split(',').map((p: string) => p.trim()).filter(Boolean);\n if (issueFiles.length === 0) {\n console.error('Error: --files option requires at least one path');\n process.exit(1);\n }\n // Resolve relative paths\n issueFiles = issueFiles.map((p: string) => path.resolve(process.cwd(), p));\n console.log(`Multi-worktree mode: watching ${issueFiles.length} file(s)`);\n for (const f of issueFiles) {\n console.log(` - ${f}`);\n }\n } else {\n // Default: single file mode\n const pebbleDir = getOrCreatePebbleDir();\n issueFiles = [path.join(pebbleDir, 'issues.jsonl')];\n }\n\n // Auto-create .pebble if it doesn't exist (single file mode only)\n if (!options.files) {\n getOrCreatePebbleDir();\n }\n\n const app = express();\n\n // Middleware\n app.use(cors());\n app.use(express.json());\n\n // API routes\n // API routes - use multi-worktree merge when multiple files\n // This is now a function since issueFiles can change dynamically\n const isMultiWorktree = () => issueFiles.length > 1;\n\n // GET /api/sources - Returns available issue files (for multi-worktree)\n app.get('/api/sources', (_req, res) => {\n try {\n res.json({ files: issueFiles, isMultiWorktree: isMultiWorktree() });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/sources - Add a new issue file to watch\n app.post('/api/sources', (req, res) => {\n try {\n const { path: filePath } = req.body;\n if (!filePath || typeof filePath !== 'string') {\n res.status(400).json({ error: 'path is required' });\n return;\n }\n\n const resolved = path.resolve(process.cwd(), filePath);\n\n // Check if file exists\n if (!fs.existsSync(resolved)) {\n res.status(400).json({ error: `File not found: ${filePath}` });\n return;\n }\n\n // Check if already watching\n if (issueFiles.includes(resolved)) {\n res.status(400).json({ error: 'File already being watched' });\n return;\n }\n\n // Add to watched files\n issueFiles.push(resolved);\n watcher.add(resolved);\n\n console.log(`Added source: ${resolved}`);\n res.json({ files: issueFiles, isMultiWorktree: isMultiWorktree() });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // DELETE /api/sources/:index - Remove a watched file\n app.delete('/api/sources/:index', (req, res) => {\n try {\n const index = parseInt(req.params.index, 10);\n if (isNaN(index) || index < 0 || index >= issueFiles.length) {\n res.status(400).json({ error: `Invalid index: ${req.params.index}` });\n return;\n }\n\n // Don't allow removing the last file\n if (issueFiles.length === 1) {\n res.status(400).json({ error: 'Cannot remove the last source file' });\n return;\n }\n\n const removed = issueFiles.splice(index, 1)[0];\n watcher.unwatch(removed);\n\n console.log(`Removed source: ${removed}`);\n res.json({ files: issueFiles, isMultiWorktree: isMultiWorktree() });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // GET /api/worktrees - Detect git worktrees with .pebble/issues.jsonl\n app.get('/api/worktrees', (_req, res) => {\n try {\n const { execSync } = require('child_process');\n let worktreeOutput: string;\n try {\n worktreeOutput = execSync('git worktree list --porcelain', {\n encoding: 'utf-8',\n cwd: process.cwd(),\n });\n } catch {\n // Not a git repo or git not available\n res.json({ worktrees: [] });\n return;\n }\n\n // Parse porcelain output: each worktree block starts with \"worktree <path>\"\n const worktrees: Array<{\n path: string;\n branch: string | null;\n issuesFile: string | null;\n hasIssues: boolean;\n isActive: boolean;\n issueCount: number;\n }> = [];\n\n const blocks = worktreeOutput.trim().split('\\n\\n');\n for (const block of blocks) {\n const lines = block.split('\\n');\n let worktreePath = '';\n let branch: string | null = null;\n\n for (const line of lines) {\n if (line.startsWith('worktree ')) {\n worktreePath = line.slice('worktree '.length);\n } else if (line.startsWith('branch ')) {\n branch = line.slice('branch '.length).replace('refs/heads/', '');\n }\n }\n\n if (worktreePath) {\n const issuesFile = path.join(worktreePath, '.pebble', 'issues.jsonl');\n const hasIssues = fs.existsSync(issuesFile);\n const isActive = issueFiles.includes(issuesFile);\n\n // Count issues if the file exists\n let issueCount = 0;\n if (hasIssues) {\n const events = readEventsFromFile(issuesFile);\n const state = computeState(events);\n issueCount = state.size;\n }\n\n worktrees.push({\n path: worktreePath,\n branch,\n issuesFile: hasIssues ? issuesFile : null,\n hasIssues,\n isActive,\n issueCount,\n });\n }\n }\n\n res.json({ worktrees });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.get('/api/issues', (_req, res) => {\n try {\n // Always read from issueFiles (works for both single and multi-worktree)\n const issues = mergeIssuesFromFiles(issueFiles);\n res.json(issues);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.get('/api/events', (_req, res) => {\n try {\n // Merge and deduplicate events from all sources\n const events = mergeEventsFromFiles(issueFiles);\n res.json(events);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // SSE endpoint for real-time updates\n const sseClients = new Set<Response>();\n let eventCounter = 0;\n\n app.get('/api/events/stream', (req, res) => {\n // Set up SSE headers\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.flushHeaders();\n\n // Add client to the set\n sseClients.add(res);\n\n // Send initial connection message with event ID\n eventCounter++;\n res.write(`id: ${eventCounter}\\ndata: {\"type\":\"connected\"}\\n\\n`);\n\n // Remove client on close\n req.on('close', () => {\n sseClients.delete(res);\n });\n });\n\n // Heartbeat to keep connections alive (every 30 seconds)\n const heartbeatInterval = setInterval(() => {\n for (const client of sseClients) {\n client.write(': heartbeat\\n\\n'); // SSE comment, keeps connection alive\n }\n }, 30000);\n\n // File watcher for issues.jsonl file(s)\n // In multi-worktree mode, watch all specified files\n const watcher = chokidar.watch(issueFiles, {\n persistent: true,\n ignoreInitial: true,\n });\n\n watcher.on('change', () => {\n // Broadcast change to all SSE clients with event ID\n eventCounter++;\n const message = JSON.stringify({ type: 'change', timestamp: new Date().toISOString() });\n for (const client of sseClients) {\n client.write(`id: ${eventCounter}\\ndata: ${message}\\n\\n`);\n }\n });\n\n // Graceful shutdown - clear heartbeat and close file watcher\n const shutdown = () => {\n clearInterval(heartbeatInterval);\n watcher.close();\n process.exit(0);\n };\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n\n // POST /api/issues - Create a new issue\n // Multi-worktree: Use ?target=<index> to specify which file to write to\n app.post('/api/issues', (req, res) => {\n try {\n // Determine target file for multi-worktree mode\n let targetFile: string | null = null;\n if (isMultiWorktree() && req.query.target !== undefined) {\n const targetIndex = parseInt(req.query.target as string, 10);\n if (isNaN(targetIndex) || targetIndex < 0 || targetIndex >= issueFiles.length) {\n res.status(400).json({ error: `Invalid target index: ${req.query.target}` });\n return;\n }\n targetFile = issueFiles[targetIndex];\n }\n\n // Get pebbleDir - for multi-worktree with target, derive from target file path\n const pebbleDir = targetFile ? path.dirname(targetFile) : getOrCreatePebbleDir();\n const config = getConfig(pebbleDir);\n const { title, type, priority, description, parent } = req.body;\n\n // Validate required fields\n if (!title || typeof title !== 'string') {\n res.status(400).json({ error: 'Title is required' });\n return;\n }\n\n // Validate type\n const issueType: IssueType = type || 'task';\n if (!ISSUE_TYPES.includes(issueType)) {\n res.status(400).json({ error: `Invalid type. Must be one of: ${ISSUE_TYPES.join(', ')}` });\n return;\n }\n\n // Validate priority\n const issuePriority: Priority = priority ?? 2;\n if (!PRIORITIES.includes(issuePriority)) {\n res.status(400).json({ error: 'Priority must be 0-4' });\n return;\n }\n\n // Validate parent if provided\n if (parent) {\n const parentIssue = getIssue(parent);\n if (!parentIssue) {\n res.status(400).json({ error: `Parent issue not found: ${parent}` });\n return;\n }\n if (parentIssue.type === 'verification') {\n res.status(400).json({ error: 'Verification issues cannot be parents' });\n return;\n }\n if (parentIssue.status === 'closed') {\n res.status(400).json({ error: 'Cannot add children to a closed issue' });\n return;\n }\n }\n\n const issueId = generateId(config.prefix);\n const timestamp = new Date().toISOString();\n\n const event: CreateEvent = {\n type: 'create',\n issueId,\n timestamp,\n data: {\n title,\n type: issueType,\n priority: issuePriority,\n description,\n parent,\n },\n };\n\n appendEvent(event, pebbleDir);\n const issue = getIssue(issueId);\n res.status(201).json(issue);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // ===== Bulk Operations =====\n // These MUST be defined before parameterized routes like /api/issues/:id\n\n // POST /api/issues/bulk/close - Close multiple issues\n app.post('/api/issues/bulk/close', (req, res) => {\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const { ids } = req.body as { ids: string[] };\n\n if (!ids || !Array.isArray(ids) || ids.length === 0) {\n res.status(400).json({ error: 'ids array is required' });\n return;\n }\n\n const results: Array<{ id: string; success: boolean; error?: string }> = [];\n\n for (const rawId of ids) {\n try {\n const issueId = resolveId(rawId);\n const issue = getIssue(issueId);\n if (!issue) {\n results.push({ id: rawId, success: false, error: `Issue not found: ${rawId}` });\n continue;\n }\n\n if (issue.status === 'closed') {\n results.push({ id: issueId, success: true }); // Already closed\n continue;\n }\n\n // Check if epic with open children\n if (issue.type === 'epic' && hasOpenChildren(issueId)) {\n results.push({ id: issueId, success: false, error: 'Cannot close epic with open children' });\n continue;\n }\n\n // Check for pending verifications\n const pendingVerifications = getVerifications(issueId).filter(v => v.status !== 'closed');\n const timestamp = new Date().toISOString();\n\n if (pendingVerifications.length > 0) {\n // Move to pending_verification instead of closing\n const updateEvent: UpdateEvent = {\n type: 'update',\n issueId,\n timestamp,\n data: { status: 'pending_verification' },\n };\n appendEvent(updateEvent, pebbleDir);\n results.push({\n id: issueId,\n success: true,\n error: `Moved to pending_verification (${pendingVerifications.length} verification(s) pending)`,\n });\n continue;\n }\n\n const event: CloseEvent = {\n issueId,\n timestamp,\n type: 'close',\n data: { reason: 'Bulk close' },\n };\n\n appendEvent(event, pebbleDir);\n results.push({ id: issueId, success: true });\n } catch (error) {\n results.push({ id: rawId, success: false, error: (error as Error).message });\n }\n }\n\n res.json({ results });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/bulk/update - Update multiple issues\n app.post('/api/issues/bulk/update', (req, res) => {\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const { ids, updates } = req.body as {\n ids: string[];\n updates: { status?: string; priority?: number };\n };\n\n if (!ids || !Array.isArray(ids) || ids.length === 0) {\n res.status(400).json({ error: 'ids array is required' });\n return;\n }\n\n if (!updates || Object.keys(updates).length === 0) {\n res.status(400).json({ error: 'updates object is required' });\n return;\n }\n\n // Validate status if provided\n if (updates.status) {\n const validStatuses = ['open', 'in_progress', 'blocked', 'pending_verification'];\n if (!validStatuses.includes(updates.status)) {\n res.status(400).json({\n error: `Invalid status: ${updates.status}. Use close endpoint to close issues.`,\n });\n return;\n }\n }\n\n // Validate priority if provided\n if (updates.priority !== undefined) {\n if (typeof updates.priority !== 'number' || updates.priority < 0 || updates.priority > 4) {\n res.status(400).json({ error: 'Priority must be 0-4' });\n return;\n }\n }\n\n const results: Array<{ id: string; success: boolean; error?: string }> = [];\n\n for (const rawId of ids) {\n try {\n const issueId = resolveId(rawId);\n const issue = getIssue(issueId);\n if (!issue) {\n results.push({ id: rawId, success: false, error: `Issue not found: ${rawId}` });\n continue;\n }\n\n const event: UpdateEvent = {\n issueId,\n timestamp: new Date().toISOString(),\n type: 'update',\n data: {\n ...(updates.status && { status: updates.status as 'open' | 'in_progress' | 'blocked' }),\n ...(updates.priority !== undefined && { priority: updates.priority as 0 | 1 | 2 | 3 | 4 }),\n },\n };\n\n appendEvent(event, pebbleDir);\n results.push({ id: issueId, success: true });\n } catch (error) {\n results.push({ id: rawId, success: false, error: (error as Error).message });\n }\n }\n\n res.json({ results });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // PUT /api/issues/:id - Update an issue\n app.put('/api/issues/:id', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n const { title, type, priority, status, description, parent, relatedTo } = req.body;\n const updates: UpdateEvent['data'] = {};\n\n // Validate and collect updates\n if (title !== undefined) {\n if (typeof title !== 'string' || title.trim() === '') {\n res.status(400).json({ error: 'Title cannot be empty' });\n return;\n }\n updates.title = title;\n }\n\n if (type !== undefined) {\n if (!ISSUE_TYPES.includes(type)) {\n res.status(400).json({ error: `Invalid type. Must be one of: ${ISSUE_TYPES.join(', ')}` });\n return;\n }\n updates.type = type;\n }\n\n if (priority !== undefined) {\n if (!PRIORITIES.includes(priority)) {\n res.status(400).json({ error: 'Priority must be 0-4' });\n return;\n }\n updates.priority = priority;\n }\n\n if (status !== undefined) {\n if (!STATUSES.includes(status)) {\n res.status(400).json({ error: `Invalid status. Must be one of: ${STATUSES.join(', ')}` });\n return;\n }\n updates.status = status;\n }\n\n if (description !== undefined) {\n updates.description = description;\n }\n\n if (parent !== undefined) {\n if (parent !== null) {\n // In multi-worktree mode, check parent in merged sources\n if (isMultiWorktree()) {\n const parentFound = findIssueInSources(parent, issueFiles);\n if (!parentFound) {\n res.status(400).json({ error: `Parent issue not found: ${parent}` });\n return;\n }\n if (parentFound.issue.type === 'verification') {\n res.status(400).json({ error: 'Verification issues cannot be parents' });\n return;\n }\n } else {\n const parentIssue = getIssue(parent);\n if (!parentIssue) {\n res.status(400).json({ error: `Parent issue not found: ${parent}` });\n return;\n }\n if (parentIssue.type === 'verification') {\n res.status(400).json({ error: 'Verification issues cannot be parents' });\n return;\n }\n }\n }\n updates.parent = parent;\n }\n\n if (relatedTo !== undefined) {\n if (!Array.isArray(relatedTo)) {\n res.status(400).json({ error: 'relatedTo must be an array' });\n return;\n }\n // Validate all related IDs exist\n for (const relatedId of relatedTo) {\n if (isMultiWorktree()) {\n const found = findIssueInSources(relatedId, issueFiles);\n if (!found) {\n res.status(400).json({ error: `Related issue not found: ${relatedId}` });\n return;\n }\n } else {\n const relatedIssue = getIssue(relatedId);\n if (!relatedIssue) {\n res.status(400).json({ error: `Related issue not found: ${relatedId}` });\n return;\n }\n }\n }\n updates.relatedTo = relatedTo;\n }\n\n if (Object.keys(updates).length === 0) {\n res.status(400).json({ error: 'No valid updates provided' });\n return;\n }\n\n const timestamp = new Date().toISOString();\n const event: UpdateEvent = {\n type: 'update',\n issueId,\n timestamp,\n data: updates,\n };\n\n appendEventToFile(event, targetFile);\n\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || { ...issue, ...updates, updatedAt: timestamp });\n } else {\n res.json(getIssue(issueId));\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/:id/close - Close an issue\n app.post('/api/issues/:id/close', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n if (issue.status === 'closed') {\n res.status(400).json({ error: 'Issue is already closed' });\n return;\n }\n\n // Check if epic has open children (single-file mode only)\n if (!isMultiWorktree() && issue.type === 'epic' && hasOpenChildren(issueId)) {\n res.status(400).json({ error: 'Cannot close epic with open children' });\n return;\n }\n\n const { reason } = req.body;\n const timestamp = new Date().toISOString();\n\n // Check for pending verifications\n let pendingVerifications: Issue[] = [];\n if (isMultiWorktree()) {\n // In multi-worktree mode, find verifications across all sources\n const allIssues = mergeIssuesFromFiles(issueFiles);\n pendingVerifications = allIssues.filter(\n i => i.verifies === issueId && i.status !== 'closed'\n );\n } else {\n pendingVerifications = getVerifications(issueId).filter(v => v.status !== 'closed');\n }\n\n if (pendingVerifications.length > 0) {\n // Move to pending_verification instead of closed\n const updateEvent: UpdateEvent = {\n type: 'update',\n issueId,\n timestamp,\n data: { status: 'pending_verification' },\n };\n appendEventToFile(updateEvent, targetFile);\n\n // Return updated issue with info about pending verifications\n const updatedIssue = { ...issue, status: 'pending_verification' as const, updatedAt: timestamp };\n res.json({\n ...updatedIssue,\n _pendingVerifications: pendingVerifications.map(v => ({ id: v.id, title: v.title })),\n });\n return;\n }\n\n const event: CloseEvent = {\n type: 'close',\n issueId,\n timestamp,\n data: { reason },\n };\n\n appendEventToFile(event, targetFile);\n\n // Check if this was a verification issue and auto-close target if all verifications done\n let autoClosed: { id: string; title: string } | undefined;\n if (issue.verifies) {\n let targetIssue: Issue | undefined;\n let targetVerifications: Issue[] = [];\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(issue.verifies, issueFiles);\n if (found) {\n targetIssue = found.issue;\n const allIssues = mergeIssuesFromFiles(issueFiles);\n targetVerifications = allIssues.filter(\n i => i.verifies === issue.verifies && i.status !== 'closed'\n );\n }\n } else {\n targetIssue = getIssue(issue.verifies);\n targetVerifications = getVerifications(issue.verifies).filter(v => v.status !== 'closed');\n }\n\n if (targetIssue && targetIssue.status === 'pending_verification' && targetVerifications.length === 0) {\n // All verifications closed - auto-close the target\n const autoCloseEvent: CloseEvent = {\n type: 'close',\n issueId: issue.verifies,\n timestamp: new Date().toISOString(),\n data: { reason: 'All verifications completed' },\n };\n\n if (isMultiWorktree()) {\n const targetFound = findIssueInSources(issue.verifies, issueFiles);\n if (targetFound) {\n appendEventToFile(autoCloseEvent, targetFound.targetFile);\n }\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n appendEventToFile(autoCloseEvent, path.join(pebbleDir, 'issues.jsonl'));\n }\n\n autoClosed = { id: targetIssue.id, title: targetIssue.title };\n }\n }\n\n // Return updated issue\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n const result = updated?.issue || { ...issue, status: 'closed', updatedAt: timestamp };\n res.json(autoClosed ? { ...result, _autoClosed: autoClosed } : result);\n } else {\n const result = getIssue(issueId);\n res.json(autoClosed ? { ...result, _autoClosed: autoClosed } : result);\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/:id/reopen - Reopen an issue\n app.post('/api/issues/:id/reopen', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n if (issue.status !== 'closed') {\n res.status(400).json({ error: 'Issue is not closed' });\n return;\n }\n\n const { reason } = req.body;\n const timestamp = new Date().toISOString();\n\n const event: ReopenEvent = {\n type: 'reopen',\n issueId,\n timestamp,\n data: { reason },\n };\n\n appendEventToFile(event, targetFile);\n\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || { ...issue, status: 'open', updatedAt: timestamp });\n } else {\n res.json(getIssue(issueId));\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/:id/delete - Soft delete an issue (with cascade for epics)\n app.post('/api/issues/:id/delete', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n if (issue.deleted) {\n res.status(400).json({ error: 'Issue is already deleted' });\n return;\n }\n\n const { reason } = req.body;\n const timestamp = new Date().toISOString();\n const state = getComputedState();\n\n // Collect all issues to delete (including cascaded)\n const toDelete: Array<{ id: string; cascade: boolean }> = [];\n const alreadyQueued = new Set<string>();\n\n // Add the main issue\n toDelete.push({ id: issueId, cascade: false });\n alreadyQueued.add(issueId);\n\n // Get descendants for cascade delete\n const descendants = getDescendants(issueId, state);\n for (const desc of descendants) {\n if (!alreadyQueued.has(desc.id) && !desc.deleted) {\n toDelete.push({ id: desc.id, cascade: true });\n alreadyQueued.add(desc.id);\n }\n }\n\n // Get verification issues that verify this issue - cascade delete them too\n const verifications = getVerifications(issueId);\n for (const v of verifications) {\n if (!alreadyQueued.has(v.id) && !v.deleted) {\n toDelete.push({ id: v.id, cascade: true });\n alreadyQueued.add(v.id);\n }\n }\n\n // Helper to clean up references\n const cleanupReferences = (deletedId: string) => {\n for (const [id, iss] of state) {\n if (id === deletedId || iss.deleted) continue;\n\n const updates: Partial<{\n blockedBy: string[];\n relatedTo: string[];\n parent: string;\n }> = {};\n\n if (iss.blockedBy.includes(deletedId)) {\n updates.blockedBy = iss.blockedBy.filter((bid) => bid !== deletedId);\n }\n if (iss.relatedTo.includes(deletedId)) {\n updates.relatedTo = iss.relatedTo.filter((rid) => rid !== deletedId);\n }\n if (iss.parent === deletedId) {\n updates.parent = '';\n }\n\n if (Object.keys(updates).length > 0) {\n const updateEvent: UpdateEvent = {\n type: 'update',\n issueId: id,\n timestamp,\n data: updates,\n };\n appendEventToFile(updateEvent, targetFile);\n }\n }\n };\n\n // Delete all collected issues\n for (const { id, cascade } of toDelete) {\n const iss = state.get(id);\n if (!iss) continue;\n\n cleanupReferences(id);\n\n const deleteEvent: DeleteEvent = {\n type: 'delete',\n issueId: id,\n timestamp,\n data: {\n reason,\n cascade: cascade || undefined,\n previousStatus: iss.status,\n },\n };\n appendEventToFile(deleteEvent, targetFile);\n }\n\n res.json({\n deleted: toDelete,\n });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/:id/restore - Restore a deleted issue\n app.post('/api/issues/:id/restore', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n if (!issue.deleted) {\n res.status(400).json({ error: 'Issue is not deleted' });\n return;\n }\n\n const { reason } = req.body;\n const timestamp = new Date().toISOString();\n\n const event: RestoreEvent = {\n type: 'restore',\n issueId,\n timestamp,\n data: { reason },\n };\n\n appendEventToFile(event, targetFile);\n\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || { ...issue, deleted: false, deletedAt: undefined, updatedAt: timestamp });\n } else {\n res.json(getIssue(issueId));\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/:id/comments - Add a comment\n app.post('/api/issues/:id/comments', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n const { text, author } = req.body;\n\n if (!text || typeof text !== 'string' || text.trim() === '') {\n res.status(400).json({ error: 'Comment text is required' });\n return;\n }\n\n const timestamp = new Date().toISOString();\n\n const event: CommentEvent = {\n type: 'comment',\n issueId,\n timestamp,\n data: {\n text,\n timestamp,\n author,\n },\n };\n\n appendEventToFile(event, targetFile);\n\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || issue);\n } else {\n res.json(getIssue(issueId));\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/:id/deps - Add a dependency\n app.post('/api/issues/:id/deps', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n const { blockerId } = req.body;\n\n if (!blockerId) {\n res.status(400).json({ error: 'blockerId is required' });\n return;\n }\n\n // Resolve blocker ID (check in multi-worktree sources if needed)\n let resolvedBlockerId: string;\n if (isMultiWorktree()) {\n const blockerFound = findIssueInSources(blockerId, issueFiles);\n if (!blockerFound) {\n res.status(404).json({ error: `Blocker issue not found: ${blockerId}` });\n return;\n }\n resolvedBlockerId = blockerFound.issue.id;\n } else {\n resolvedBlockerId = resolveId(blockerId);\n const blockerIssue = getIssue(resolvedBlockerId);\n if (!blockerIssue) {\n res.status(404).json({ error: `Blocker issue not found: ${blockerId}` });\n return;\n }\n }\n\n // Check if already a dependency\n if (issue.blockedBy.includes(resolvedBlockerId)) {\n res.status(400).json({ error: 'Dependency already exists' });\n return;\n }\n\n // Check for cycles (only in single-file mode, cycle detection uses local state)\n if (!isMultiWorktree() && detectCycle(issueId, resolvedBlockerId)) {\n res.status(400).json({ error: 'Adding this dependency would create a cycle' });\n return;\n }\n\n const timestamp = new Date().toISOString();\n const event: UpdateEvent = {\n type: 'update',\n issueId,\n timestamp,\n data: {\n blockedBy: [...issue.blockedBy, resolvedBlockerId],\n },\n };\n\n appendEventToFile(event, targetFile);\n\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || { ...issue, blockedBy: [...issue.blockedBy, resolvedBlockerId], updatedAt: timestamp });\n } else {\n res.json(getIssue(issueId));\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // DELETE /api/issues/:id/deps/:blockerId - Remove a dependency\n app.delete('/api/issues/:id/deps/:blockerId', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n // Resolve blocker ID (check in multi-worktree sources if needed)\n let resolvedBlockerId: string;\n if (isMultiWorktree()) {\n const blockerFound = findIssueInSources(req.params.blockerId, issueFiles);\n if (blockerFound) {\n resolvedBlockerId = blockerFound.issue.id;\n } else {\n // Blocker might not exist anymore, try direct match\n resolvedBlockerId = req.params.blockerId;\n }\n } else {\n resolvedBlockerId = resolveId(req.params.blockerId);\n }\n\n if (!issue.blockedBy.includes(resolvedBlockerId)) {\n res.status(400).json({ error: 'Dependency does not exist' });\n return;\n }\n\n const timestamp = new Date().toISOString();\n const newBlockedBy = issue.blockedBy.filter((id) => id !== resolvedBlockerId);\n const event: UpdateEvent = {\n type: 'update',\n issueId,\n timestamp,\n data: {\n blockedBy: newBlockedBy,\n },\n };\n\n appendEventToFile(event, targetFile);\n\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || { ...issue, blockedBy: newBlockedBy, updatedAt: timestamp });\n } else {\n res.json(getIssue(issueId));\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // Serve static files from the bundled UI\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const uiPath = path.resolve(__dirname, '../ui');\n\n app.use(express.static(uiPath));\n\n // SPA fallback\n app.get('*', (_req, res) => {\n res.sendFile(path.join(uiPath, 'index.html'));\n });\n\n // Start server with port fallback\n const requestedPort = parseInt(options.port, 10);\n const actualPort = await findAvailablePort(requestedPort);\n\n if (actualPort !== requestedPort) {\n console.log(`Port ${requestedPort} is busy, using ${actualPort} instead`);\n }\n\n app.listen(actualPort, () => {\n const url = `http://localhost:${actualPort}`;\n console.log(`Pebble UI running at ${url}`);\n\n if (options.open !== false) {\n open(url);\n }\n });\n } catch (error) {\n outputError(error as Error, pretty);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as readline from 'readline';\nimport type { IssueType, Priority, Status, CreateEvent, UpdateEvent, CloseEvent, CommentEvent } from '../../shared/types.js';\nimport { ensurePebbleDir, appendEvent } from '../lib/storage.js';\nimport { outputError, formatJson } from '../lib/output.js';\nimport { derivePrefix } from '../lib/id.js';\nimport * as path from 'path';\n\n// Beads issue format\ninterface BeadsDependency {\n issue_id: string;\n depends_on_id: string;\n type: 'blocks' | 'parent-child' | 'related' | 'discovered-from';\n created_at: string;\n created_by?: string;\n}\n\ninterface BeadsIssue {\n id: string;\n title: string;\n description?: string;\n status: string;\n priority: number;\n issue_type: string;\n assignee?: string;\n created_at: string;\n created_by?: string;\n updated_at: string;\n closed_at?: string;\n close_reason?: string;\n dependencies?: BeadsDependency[];\n}\n\nexport function importCommand(program: Command): void {\n program\n .command('import <file>')\n .description('Import issues from a Beads issues.jsonl file')\n .option('--dry-run', 'Show what would be imported without writing')\n .option('--prefix <prefix>', 'Override the ID prefix (default: derive from folder name)')\n .action(async (file: string, options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Validate file exists\n if (!fs.existsSync(file)) {\n throw new Error(`File not found: ${file}`);\n }\n\n // Read and parse Beads issues\n const beadsIssues = await parseBeadsFile(file);\n\n if (beadsIssues.length === 0) {\n console.log(pretty ? 'No issues found in file.' : formatJson({ imported: 0 }));\n return;\n }\n\n // Determine prefix\n const prefix = options.prefix ?? derivePrefix(path.basename(process.cwd()));\n\n // Convert to pebble events\n const { events, idMap, stats } = convertToPebbleEvents(beadsIssues, prefix);\n\n if (options.dryRun) {\n if (pretty) {\n console.log('Dry run - would import:');\n console.log(` ${stats.created} issues`);\n console.log(` ${stats.closed} closed issues`);\n console.log(` ${stats.dependencies} block dependencies`);\n console.log(` ${stats.parentChild} parent-child relationships`);\n console.log(` ${stats.comments} comments`);\n console.log('\\nID mapping (beads -> pebble):');\n for (const [beadsId, pebbleId] of idMap) {\n console.log(` ${beadsId} -> ${pebbleId}`);\n }\n } else {\n console.log(formatJson({\n dryRun: true,\n stats,\n idMap: Object.fromEntries(idMap),\n }));\n }\n return;\n }\n\n // Ensure pebble directory exists\n const pebbleDir = ensurePebbleDir();\n\n // Write events\n for (const event of events) {\n appendEvent(event, pebbleDir);\n }\n\n if (pretty) {\n console.log(`Imported ${stats.created} issues from ${file}`);\n console.log(` ${stats.closed} closed`);\n console.log(` ${stats.dependencies} block dependencies`);\n console.log(` ${stats.parentChild} parent-child relationships`);\n console.log(` ${stats.comments} comments`);\n } else {\n console.log(formatJson({\n imported: stats.created,\n closed: stats.closed,\n dependencies: stats.dependencies,\n parentChild: stats.parentChild,\n comments: stats.comments,\n idMap: Object.fromEntries(idMap),\n }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n\nasync function parseBeadsFile(filePath: string): Promise<BeadsIssue[]> {\n const issues: BeadsIssue[] = [];\n\n const fileStream = fs.createReadStream(filePath);\n const rl = readline.createInterface({\n input: fileStream,\n crlfDelay: Infinity,\n });\n\n for await (const line of rl) {\n if (line.trim()) {\n try {\n const issue = JSON.parse(line) as BeadsIssue;\n issues.push(issue);\n } catch {\n // Skip malformed lines\n }\n }\n }\n\n return issues;\n}\n\nfunction convertToPebbleEvents(\n beadsIssues: BeadsIssue[],\n prefix: string\n): {\n events: (CreateEvent | UpdateEvent | CloseEvent | CommentEvent)[];\n idMap: Map<string, string>;\n stats: { created: number; closed: number; dependencies: number; comments: number; parentChild: number };\n} {\n const events: (CreateEvent | UpdateEvent | CloseEvent | CommentEvent)[] = [];\n const idMap = new Map<string, string>();\n const issueTypeMap = new Map<string, string>(); // beadsId -> issue_type\n const stats = { created: 0, closed: 0, dependencies: 0, comments: 0, parentChild: 0 };\n\n // First pass: create ID mapping and type mapping\n for (const issue of beadsIssues) {\n const suffix = generateSuffix();\n const pebbleId = `${prefix}-${suffix}`;\n idMap.set(issue.id, pebbleId);\n issueTypeMap.set(issue.id, issue.issue_type);\n }\n\n // Second pass: create events\n for (const issue of beadsIssues) {\n const pebbleId = idMap.get(issue.id)!;\n\n // Map type (feature, chore -> task)\n let type: IssueType = 'task';\n if (issue.issue_type === 'bug') {\n type = 'bug';\n } else if (issue.issue_type === 'epic') {\n type = 'epic';\n }\n\n // Map priority (clamp to 0-4)\n const priority = Math.max(0, Math.min(4, issue.priority)) as Priority;\n\n // Extract parent from dependencies\n let parent: string | undefined;\n const blockedBy: string[] = [];\n\n if (issue.dependencies) {\n for (const dep of issue.dependencies) {\n if (dep.type === 'parent-child') {\n // Beads stores parent-child on BOTH sides (child->parent AND parent->child)\n // Only process when depends_on_id points to an epic (this issue is a child of that epic)\n // Skip when depends_on_id points to a non-epic (that's the reverse relationship)\n const targetType = issueTypeMap.get(dep.depends_on_id);\n if (targetType === 'epic') {\n const parentPebbleId = idMap.get(dep.depends_on_id);\n if (parentPebbleId) {\n parent = parentPebbleId;\n stats.parentChild++;\n }\n }\n // If targetType is not 'epic', skip - handled when processing the child issue\n } else if (dep.type === 'blocks' && dep.depends_on_id !== issue.id) {\n // This issue is blocked by depends_on_id\n const blockerPebbleId = idMap.get(dep.depends_on_id);\n if (blockerPebbleId) {\n blockedBy.push(blockerPebbleId);\n stats.dependencies++;\n }\n }\n }\n }\n\n // Create event\n const createEvent: CreateEvent = {\n type: 'create',\n issueId: pebbleId,\n timestamp: issue.created_at,\n data: {\n title: issue.title,\n type,\n priority,\n description: issue.description,\n parent,\n },\n };\n events.push(createEvent);\n stats.created++;\n\n // Add blockedBy if any\n if (blockedBy.length > 0) {\n const updateEvent: UpdateEvent = {\n type: 'update',\n issueId: pebbleId,\n timestamp: issue.created_at,\n data: {\n blockedBy,\n },\n };\n events.push(updateEvent);\n }\n\n // Map status (deferred -> open, blocked stays blocked)\n let status: Status = 'open';\n if (issue.status === 'in_progress') {\n status = 'in_progress';\n } else if (issue.status === 'blocked') {\n status = 'blocked';\n } else if (issue.status === 'closed') {\n status = 'closed';\n }\n // 'deferred' and 'open' both map to 'open'\n\n // Update status if not open\n if (status !== 'open' && status !== 'closed') {\n const statusEvent: UpdateEvent = {\n type: 'update',\n issueId: pebbleId,\n timestamp: issue.updated_at,\n data: {\n status,\n },\n };\n events.push(statusEvent);\n }\n\n // Close event if closed\n if (status === 'closed') {\n const closeEvent: CloseEvent = {\n type: 'close',\n issueId: pebbleId,\n timestamp: issue.closed_at ?? issue.updated_at,\n data: {\n reason: issue.close_reason,\n },\n };\n events.push(closeEvent);\n stats.closed++;\n }\n }\n\n return { events, idMap, stats };\n}\n\nfunction generateSuffix(): string {\n const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < 6; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n","import { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { readEventsFromFile } from '../lib/storage.js';\nimport { computeState } from '../lib/state.js';\nimport type { Issue, IssueEvent } from '../../shared/types.js';\n\ninterface MergedIssue extends Issue {\n _sources: string[];\n}\n\n/**\n * Merge events from multiple files, keeping all events sorted by timestamp.\n * Deduplicates events using key: issueId-timestamp-type\n */\nfunction mergeEvents(filePaths: string[]): IssueEvent[] {\n const seen = new Map<string, IssueEvent>();\n\n for (const filePath of filePaths) {\n const events = readEventsFromFile(filePath);\n for (const event of events) {\n // Create a unique key for deduplication\n const key = `${event.issueId}-${event.timestamp}-${event.type}`;\n if (!seen.has(key)) {\n seen.set(key, event);\n }\n }\n }\n\n // Get all unique events and sort by timestamp\n const allEvents = Array.from(seen.values());\n allEvents.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());\n\n return allEvents;\n}\n\n/**\n * Merge issues from multiple files.\n * Same ID = same issue: keep the version with the latest updatedAt.\n */\nfunction mergeIssues(filePaths: string[]): MergedIssue[] {\n const merged = new Map<string, { issue: Issue; sources: Set<string> }>();\n\n for (const filePath of filePaths) {\n const events = readEventsFromFile(filePath);\n const state = computeState(events);\n\n for (const [id, issue] of state) {\n const existing = merged.get(id);\n if (!existing) {\n merged.set(id, { issue, sources: new Set([filePath]) });\n } else {\n existing.sources.add(filePath);\n if (new Date(issue.updatedAt) > new Date(existing.issue.updatedAt)) {\n merged.set(id, { issue, sources: existing.sources });\n }\n }\n }\n }\n\n return Array.from(merged.values()).map(({ issue, sources }) => ({\n ...issue,\n _sources: Array.from(sources),\n }));\n}\n\nexport function mergeCommand(program: Command): void {\n program\n .command('merge <files...>')\n .description('Merge multiple issues.jsonl files into one')\n .option('-o, --output <file>', 'Output file (default: stdout)')\n .option('--state', 'Output computed state instead of raw events')\n .option('--show-sources', 'Include _sources field (only with --state)')\n .action((files: string[], options) => {\n const pretty = program.opts().pretty ?? false;\n\n // Resolve and validate file paths\n const filePaths: string[] = [];\n for (const file of files) {\n const resolved = path.resolve(process.cwd(), file);\n if (!fs.existsSync(resolved)) {\n console.error(`Error: File not found: ${file}`);\n process.exit(1);\n }\n filePaths.push(resolved);\n }\n\n if (filePaths.length < 2) {\n console.error('Error: At least 2 files required for merge');\n process.exit(1);\n }\n\n try {\n let output: string;\n\n if (options.state) {\n // Output computed state as JSON array\n const issues = mergeIssues(filePaths);\n\n // Remove _sources unless requested\n const outputIssues = options.showSources\n ? issues\n : issues.map(({ _sources, ...issue }) => issue);\n\n output = pretty\n ? JSON.stringify(outputIssues, null, 2)\n : JSON.stringify(outputIssues);\n } else {\n // Default: output merged events as JSONL (preserves history)\n const events = mergeEvents(filePaths);\n output = events.map((e) => JSON.stringify(e)).join('\\n');\n }\n\n if (options.output) {\n fs.writeFileSync(options.output, output + '\\n', 'utf-8');\n console.error(`Merged ${filePaths.length} files to ${options.output}`);\n } else {\n console.log(output);\n }\n } catch (error) {\n console.error(`Error: ${(error as Error).message}`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { Status, CommentEvent } from '../../shared/types.js';\nimport { STATUSES, STATUS_LABELS } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, readEvents } from '../lib/storage.js';\nimport { getIssues, getChildren, getIssue, getVerifications } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\nimport { formatRelativeTime } from '../../shared/time.js';\n\ninterface ChildCounts {\n total: number;\n done: number;\n pending_verification: number;\n in_progress: number;\n open: number;\n blocked: number;\n}\n\ninterface EpicSummary {\n id: string;\n title: string;\n description?: string;\n status: Status;\n createdAt: string;\n updatedAt: string;\n parent?: {\n id: string;\n title: string;\n };\n children: ChildCounts;\n verifications: {\n total: number;\n done: number;\n };\n}\n\nfunction countChildren(epicId: string): ChildCounts {\n const children = getChildren(epicId);\n return {\n total: children.length,\n done: children.filter((c) => c.status === 'closed').length,\n pending_verification: children.filter((c) => c.status === 'pending_verification').length,\n in_progress: children.filter((c) => c.status === 'in_progress').length,\n open: children.filter((c) => c.status === 'open').length,\n blocked: children.filter((c) => c.status === 'blocked').length,\n };\n}\n\nfunction countVerifications(epicId: string): { total: number; done: number } {\n const children = getChildren(epicId);\n let total = 0;\n let done = 0;\n\n for (const child of children) {\n const verifications = getVerifications(child.id);\n total += verifications.length;\n done += verifications.filter((v) => v.status === 'closed').length;\n }\n\n return { total, done };\n}\n\ninterface InProgressIssue {\n id: string;\n title: string;\n type: string;\n createdAt: string;\n updatedAt: string;\n lastSource?: string;\n parent?: { id: string; title: string };\n comments: Array<{ text: string; timestamp: string; source?: string }>;\n}\n\nfunction getIssueComments(issueId: string): Array<{ text: string; timestamp: string; source?: string }> {\n const events = readEvents();\n return events\n .filter((e): e is CommentEvent => e.type === 'comment' && e.issueId === issueId)\n .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())\n .map((e) => ({ text: e.data.text, timestamp: e.timestamp, source: e.source }));\n}\n\nfunction formatInProgressPretty(issues: InProgressIssue[]): string {\n if (issues.length === 0) return '';\n\n const lines: string[] = [];\n lines.push(`## In Progress (${issues.length})`);\n lines.push('');\n\n for (const issue of issues) {\n lines.push(`▶ ${issue.id}: ${issue.title} [${issue.type}]`);\n lines.push(` Updated: ${formatRelativeTime(issue.updatedAt)}${issue.lastSource ? ` | Source: ${issue.lastSource}` : ''}`);\n if (issue.parent) {\n lines.push(` Parent: ${issue.parent.title}`);\n }\n if (issue.comments.length > 0) {\n const recentComments = issue.comments.slice(0, 3);\n for (const comment of recentComments) {\n const truncated = comment.text.length > 100 ? comment.text.substring(0, 100) + '...' : comment.text;\n lines.push(` • ${formatRelativeTime(comment.timestamp)}: ${truncated.replace(/\\n/g, ' ')}`);\n }\n if (issue.comments.length > 3) {\n lines.push(` (${issue.comments.length - 3} more comment${issue.comments.length - 3 === 1 ? '' : 's'})`);\n }\n }\n lines.push('');\n }\n return lines.join('\\n');\n}\n\nfunction formatSummaryPretty(summaries: EpicSummary[], sectionHeader: string): string {\n if (summaries.length === 0) {\n return 'No epics found.';\n }\n\n const lines: string[] = [];\n\n // Section header\n lines.push(`## ${sectionHeader} (${summaries.length})`);\n lines.push('');\n\n for (const summary of summaries) {\n const { children, verifications } = summary;\n\n // Epic line: ID: Title\n lines.push(`${summary.id}: ${summary.title}`);\n\n // Timestamps\n lines.push(` Created: ${formatRelativeTime(summary.createdAt)} | Updated: ${formatRelativeTime(summary.updatedAt)}`);\n\n // Counts\n const pendingStr = children.pending_verification > 0 ? ` (${children.pending_verification} pending verification)` : '';\n const issueCount = `Issues: ${children.done}/${children.total} done${pendingStr}`;\n const verifCount = `Verifications: ${verifications.done}/${verifications.total} done`;\n lines.push(` ${issueCount} | ${verifCount}`);\n\n // Parent if exists\n if (summary.parent) {\n lines.push(` Parent: ${summary.parent.id} (${summary.parent.title})`);\n }\n\n // Full description (no trimming)\n if (summary.description) {\n lines.push('');\n lines.push(` ${summary.description}`);\n }\n\n // Command hint\n lines.push('');\n lines.push(` Run \\`pb list --parent ${summary.id}\\` to see all issues.`);\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nexport function summaryCommand(program: Command): void {\n program\n .command('summary')\n .description('Show epic summary with child completion status')\n .option('--status <status>', 'Filter epics by specific status')\n .option('--limit <n>', 'Max epics to return per section', '10')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n getOrCreatePebbleDir();\n\n // Get all epics\n const allEpics = getIssues({ type: 'epic' });\n\n // Helper to build summary for an epic\n const buildSummary = (epic: typeof allEpics[0]): EpicSummary => {\n const summary: EpicSummary = {\n id: epic.id,\n title: epic.title,\n description: epic.description,\n status: epic.status,\n createdAt: epic.createdAt,\n updatedAt: epic.updatedAt,\n children: countChildren(epic.id),\n verifications: countVerifications(epic.id),\n };\n\n if (epic.parent) {\n const parentIssue = getIssue(epic.parent);\n if (parentIssue) {\n summary.parent = {\n id: parentIssue.id,\n title: parentIssue.title,\n };\n }\n }\n\n return summary;\n };\n\n const limit = parseInt(options.limit, 10);\n\n // If filtering by specific status, show only that status\n if (options.status !== undefined) {\n const status = options.status as Status;\n if (!STATUSES.includes(status)) {\n throw new Error(`Invalid status: ${status}. Must be one of: ${STATUSES.join(', ')}`);\n }\n\n let epics = allEpics.filter((e) => e.status === status);\n\n // Sort by createdAt descending (newest first)\n epics.sort((a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n\n // Apply limit\n if (limit > 0) {\n epics = epics.slice(0, limit);\n }\n\n const summaries = epics.map(buildSummary);\n\n if (pretty) {\n console.log(formatSummaryPretty(summaries, `${STATUS_LABELS[status]} Epics`));\n } else {\n console.log(formatJson(summaries));\n }\n return;\n }\n\n // Get in_progress issues with their comments\n const inProgressIssues = getIssues({ status: 'in_progress' });\n inProgressIssues.sort((a, b) =>\n new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()\n );\n\n const inProgressSummaries: InProgressIssue[] = inProgressIssues.map((issue) => {\n const summary: InProgressIssue = {\n id: issue.id,\n title: issue.title,\n type: issue.type,\n createdAt: issue.createdAt,\n updatedAt: issue.updatedAt,\n lastSource: issue.lastSource,\n comments: getIssueComments(issue.id),\n };\n if (issue.parent) {\n const parentIssue = getIssue(issue.parent, true);\n if (parentIssue) {\n summary.parent = { id: parentIssue.id, title: parentIssue.title };\n }\n }\n return summary;\n });\n\n // Default: show open epics + recently closed (last 72h)\n const openEpics = allEpics.filter((e) => e.status !== 'closed');\n\n // Filter closed epics to last 72 hours (using updatedAt as proxy for close time)\n const seventyTwoHoursAgo = Date.now() - (72 * 60 * 60 * 1000);\n const closedEpics = allEpics.filter((e) =>\n e.status === 'closed' &&\n new Date(e.updatedAt).getTime() > seventyTwoHoursAgo\n );\n\n // Sort both by createdAt descending\n openEpics.sort((a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n closedEpics.sort((a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n\n // Apply limit to each section\n const limitedOpen = limit > 0 ? openEpics.slice(0, limit) : openEpics;\n const limitedClosed = limit > 0 ? closedEpics.slice(0, limit) : closedEpics;\n\n const openSummaries = limitedOpen.map(buildSummary);\n const closedSummaries = limitedClosed.map(buildSummary);\n\n if (pretty) {\n const output: string[] = [];\n // In Progress section first\n const inProgressOutput = formatInProgressPretty(inProgressSummaries);\n if (inProgressOutput) {\n output.push(inProgressOutput);\n }\n if (openSummaries.length > 0) {\n if (output.length > 0) output.push('');\n output.push(formatSummaryPretty(openSummaries, 'Open Epics'));\n }\n if (closedSummaries.length > 0) {\n if (output.length > 0) output.push('');\n output.push(formatSummaryPretty(closedSummaries, 'Recently Closed Epics (last 72h)'));\n }\n if (output.length === 0) {\n output.push('No issues in progress and no epics found.');\n }\n console.log(output.join('\\n'));\n } else {\n console.log(formatJson({ inProgress: inProgressSummaries, open: openSummaries, closed: closedSummaries }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { EventType } from '../../shared/types.js';\nimport { EVENT_TYPES } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, readEvents } from '../lib/storage.js';\nimport { computeState } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\n\ninterface HistoryEntry {\n timestamp: string;\n event: EventType;\n issue: {\n id: string;\n title: string;\n type: string;\n };\n parent?: {\n id: string;\n title: string;\n };\n details?: Record<string, unknown>;\n}\n\nfunction parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)([dhms])$/);\n if (!match) {\n throw new Error(`Invalid duration: ${duration}. Use format like \"7d\", \"24h\", \"30m\", \"60s\"`);\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n const multipliers: Record<string, number> = {\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n };\n\n return value * multipliers[unit];\n}\n\nfunction formatRelativeTime(timestamp: string): string {\n const now = Date.now();\n const then = new Date(timestamp).getTime();\n const diff = now - then;\n\n const seconds = Math.floor(diff / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 0) return `${days}d ago`;\n if (hours > 0) return `${hours}h ago`;\n if (minutes > 0) return `${minutes}m ago`;\n return `${seconds}s ago`;\n}\n\nfunction formatHistoryPretty(entries: HistoryEntry[]): string {\n if (entries.length === 0) {\n return 'No events found.';\n }\n\n const lines: string[] = [];\n\n for (const entry of entries) {\n const time = formatRelativeTime(entry.timestamp);\n const eventLabel = entry.event.charAt(0).toUpperCase() + entry.event.slice(1);\n\n let line = `[${time}] ${eventLabel} ${entry.issue.id} \"${entry.issue.title}\" (${entry.issue.type})`;\n\n if (entry.parent) {\n line += ` under ${entry.parent.id}`;\n }\n\n lines.push(line);\n }\n\n return lines.join('\\n');\n}\n\nexport function historyCommand(program: Command): void {\n program\n .command('history')\n .description('Show recent activity log')\n .option('--limit <n>', 'Max events to return', '20')\n .option('--type <types>', 'Filter by event type(s), comma-separated (create,close,reopen,update,comment)')\n .option('--since <duration>', 'Only show events since (e.g., \"7d\", \"24h\")')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n getOrCreatePebbleDir();\n\n const events = readEvents();\n const state = computeState(events);\n\n // Filter by type(s)\n let filteredEvents = events;\n if (options.type !== undefined) {\n const types = options.type.split(',').map((t: string) => t.trim());\n // Validate each type\n for (const t of types) {\n if (!EVENT_TYPES.includes(t as EventType)) {\n throw new Error(`Invalid event type: ${t}. Must be one of: ${EVENT_TYPES.join(', ')}`);\n }\n }\n filteredEvents = filteredEvents.filter((e) => types.includes(e.type));\n }\n\n // Filter by time\n if (options.since !== undefined) {\n const sinceMs = parseDuration(options.since);\n const cutoff = Date.now() - sinceMs;\n filteredEvents = filteredEvents.filter(\n (e) => new Date(e.timestamp).getTime() >= cutoff\n );\n }\n\n // Sort by timestamp descending (newest first)\n filteredEvents.sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()\n );\n\n // Apply limit\n const limit = parseInt(options.limit, 10);\n if (limit > 0) {\n filteredEvents = filteredEvents.slice(0, limit);\n }\n\n // Build history entries\n const entries: HistoryEntry[] = filteredEvents.map((event) => {\n const issue = state.get(event.issueId);\n const entry: HistoryEntry = {\n timestamp: event.timestamp,\n event: event.type,\n issue: {\n id: event.issueId,\n title: issue?.title ?? '(unknown)',\n type: issue?.type ?? 'task',\n },\n };\n\n // Add parent info if available\n if (issue?.parent) {\n const parent = state.get(issue.parent);\n if (parent) {\n entry.parent = {\n id: parent.id,\n title: parent.title,\n };\n }\n }\n\n // Add event-specific details\n if (event.type === 'close' && event.data.reason) {\n entry.details = { reason: event.data.reason };\n } else if (event.type === 'comment') {\n entry.details = { text: event.data.text };\n }\n\n return entry;\n });\n\n if (pretty) {\n console.log(formatHistoryPretty(entries));\n } else {\n console.log(formatJson(entries));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { Issue, IssueType, Status } from '../../shared/types.js';\nimport { ISSUE_TYPES, STATUSES } from '../../shared/types.js';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssues } from '../lib/state.js';\nimport { outputIssueList, outputError } from '../lib/output.js';\n\nfunction searchIssues(issues: Issue[], query: string): Issue[] {\n const lowerQuery = query.toLowerCase();\n\n return issues.filter((issue) => {\n // Search in ID\n if (issue.id.toLowerCase().includes(lowerQuery)) {\n return true;\n }\n\n // Search in title\n if (issue.title.toLowerCase().includes(lowerQuery)) {\n return true;\n }\n\n // Search in description\n if (issue.description?.toLowerCase().includes(lowerQuery)) {\n return true;\n }\n\n // Search in comments\n if (issue.comments.some((c) => c.text.toLowerCase().includes(lowerQuery))) {\n return true;\n }\n\n return false;\n });\n}\n\nexport function searchCommand(program: Command): void {\n program\n .command('search <query>')\n .description('Search issues by text in title, description, and comments')\n .option('--status <status>', 'Filter by status')\n .option('-t, --type <type>', 'Filter by type')\n .option('--limit <n>', 'Max results', '20')\n .action(async (query, options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n getOrCreatePebbleDir();\n\n let issues = getIssues();\n\n // Apply status filter\n if (options.status !== undefined) {\n const status = options.status as Status;\n if (!STATUSES.includes(status)) {\n throw new Error(`Invalid status: ${status}. Must be one of: ${STATUSES.join(', ')}`);\n }\n issues = issues.filter((i) => i.status === status);\n }\n\n // Apply type filter\n if (options.type !== undefined) {\n const type = options.type as IssueType;\n if (!ISSUE_TYPES.includes(type)) {\n throw new Error(`Invalid type: ${type}. Must be one of: ${ISSUE_TYPES.join(', ')}`);\n }\n issues = issues.filter((i) => i.type === type);\n }\n\n // Perform search\n let results = searchIssues(issues, query);\n\n // Sort by relevance (title matches first, then by updatedAt)\n const lowerQuery = query.toLowerCase();\n results.sort((a, b) => {\n const aInTitle = a.title.toLowerCase().includes(lowerQuery);\n const bInTitle = b.title.toLowerCase().includes(lowerQuery);\n\n if (aInTitle && !bInTitle) return -1;\n if (!aInTitle && bInTitle) return 1;\n\n // Secondary sort: newest first\n return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();\n });\n\n // Apply limit\n const limit = parseInt(options.limit, 10);\n if (limit > 0) {\n results = results.slice(0, limit);\n }\n\n outputIssueList(results, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssue, resolveId, getVerifications } from '../lib/state.js';\nimport { outputError, formatJson, formatLimitMessage, type LimitInfo } from '../lib/output.js';\n\nexport function verificationsCommand(program: Command): void {\n program\n .command('verifications <id>')\n .description('List verification issues for a given issue')\n .option('--limit <n>', 'Max verifications to return (default: 30)')\n .option('--all', 'Show all verifications (no limit)')\n .action(async (id: string, options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Ensure pebble directory exists\n getOrCreatePebbleDir();\n\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n let verifications = getVerifications(resolvedId);\n\n // Sort by createdAt descending (newest first)\n verifications.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n\n // Apply limit\n const total = verifications.length;\n const limit = options.all ? 0 : (options.limit ? parseInt(options.limit, 10) : 30);\n if (limit > 0 && verifications.length > limit) {\n verifications = verifications.slice(0, limit);\n }\n const limitInfo: LimitInfo = {\n total,\n shown: verifications.length,\n limited: limit > 0 && total > limit,\n };\n\n if (pretty) {\n if (verifications.length === 0) {\n console.log(`No verifications for ${resolvedId}`);\n } else {\n console.log(`Verifications for ${resolvedId} \"${issue.title}\"`);\n console.log('─'.repeat(50));\n for (const v of verifications) {\n const status = v.status === 'closed' ? '✓' : '○';\n console.log(` ${status} ${v.id} - ${v.title}`);\n }\n console.log('');\n console.log(`Total: ${verifications.length} verification(s)`);\n if (limitInfo.limited) {\n console.log(formatLimitMessage(limitInfo));\n }\n }\n } else {\n const output = {\n issueId: resolvedId,\n verifications: verifications.map((v) => ({\n id: v.id,\n title: v.title,\n status: v.status,\n })),\n ...(limitInfo.limited && { _meta: limitInfo }),\n };\n console.log(formatJson(output));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'path';\nimport { discoverPebbleDir, ensurePebbleDir } from '../lib/storage.js';\n\nexport function initCommand(program: Command): void {\n program\n .command('init')\n .description('Initialize a new .pebble directory in the current directory')\n .option('--force', 'Re-initialize even if .pebble already exists')\n .action((options) => {\n const existing = discoverPebbleDir();\n\n if (existing && !options.force) {\n console.error(JSON.stringify({\n error: 'Already initialized',\n path: existing,\n hint: 'Use --force to re-initialize',\n }));\n process.exit(1);\n }\n\n // Create .pebble in current directory\n const pebbleDir = ensurePebbleDir(process.cwd());\n\n console.log(JSON.stringify({\n initialized: true,\n path: pebbleDir,\n configPath: path.join(pebbleDir, 'config.json'),\n issuesPath: path.join(pebbleDir, 'issues.jsonl'),\n }));\n });\n}\n"],"mappings":"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","names":["readFileSync","fileURLToPath","dirname","join","path","program","program","program","program","program","program","program","program","program","program","program","program","buildIssueTree","formatIssueTreePretty","visited","program","program","path","fs","resolve","fs","program","path","execSync","__filename","__dirname","fs","path","program","fs","path","program","program","formatRelativeTime","program","program","program","path","program","__filename","fileURLToPath","__dirname","dirname","readFileSync","join"]}
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/shared/types.ts","../../src/cli/lib/storage.ts","../../src/cli/lib/id.ts","../../src/cli/lib/git.ts","../../src/cli/lib/state.ts","../../src/shared/time.ts","../../src/cli/lib/output.ts","../../src/cli/commands/create.ts","../../src/cli/commands/update.ts","../../src/cli/commands/close.ts","../../src/cli/commands/reopen.ts","../../src/cli/commands/delete.ts","../../src/cli/commands/restore.ts","../../src/cli/commands/claim.ts","../../src/cli/commands/list.ts","../../src/cli/commands/show.ts","../../src/cli/commands/ready.ts","../../src/cli/commands/blocked.ts","../../src/cli/commands/dep.ts","../../src/cli/commands/comments.ts","../../src/cli/commands/graph.ts","../../src/cli/commands/ui.ts","../../src/cli/commands/import.ts","../../src/cli/commands/merge.ts","../../src/cli/commands/summary.ts","../../src/cli/commands/history.ts","../../src/cli/commands/search.ts","../../src/cli/commands/verifications.ts","../../src/cli/commands/init.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\nimport { createCommand } from './commands/create.js';\nimport { updateCommand } from './commands/update.js';\nimport { closeCommand } from './commands/close.js';\nimport { reopenCommand } from './commands/reopen.js';\nimport { deleteCommand } from './commands/delete.js';\nimport { restoreCommand } from './commands/restore.js';\nimport { claimCommand } from './commands/claim.js';\nimport { listCommand } from './commands/list.js';\nimport { showCommand } from './commands/show.js';\nimport { readyCommand } from './commands/ready.js';\nimport { blockedCommand } from './commands/blocked.js';\nimport { depCommand } from './commands/dep.js';\nimport { commentsCommand } from './commands/comments.js';\nimport { graphCommand } from './commands/graph.js';\nimport { uiCommand } from './commands/ui.js';\nimport { importCommand } from './commands/import.js';\nimport { mergeCommand } from './commands/merge.js';\nimport { summaryCommand } from './commands/summary.js';\nimport { historyCommand } from './commands/history.js';\nimport { searchCommand } from './commands/search.js';\nimport { verificationsCommand } from './commands/verifications.js';\nimport { initCommand } from './commands/init.js';\n\n// Read version from package.json\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('pebble')\n .description('A lightweight JSONL-based issue tracker')\n .version(packageJson.version);\n\n// Global options\nprogram.option('-P, --pretty', 'Human-readable output (default: JSON)');\nprogram.option('--json', 'JSON output (this is the default, flag not needed)');\nprogram.option('--local', 'Use local .pebble directory even in a git worktree');\n\n// Handle --local flag by setting environment variable before commands run\nprogram.hook('preAction', () => {\n if (program.opts().local) {\n process.env.PEBBLE_LOCAL = '1';\n }\n});\n\n// Register all commands\ncreateCommand(program);\nupdateCommand(program);\ncloseCommand(program);\nreopenCommand(program);\ndeleteCommand(program);\nrestoreCommand(program);\nclaimCommand(program);\nlistCommand(program);\nshowCommand(program);\nreadyCommand(program);\nblockedCommand(program);\ndepCommand(program);\ncommentsCommand(program);\ngraphCommand(program);\nuiCommand(program);\nimportCommand(program);\nmergeCommand(program);\nsummaryCommand(program);\nhistoryCommand(program);\nsearchCommand(program);\nverificationsCommand(program);\ninitCommand(program);\n\nprogram.parse();\n","// Issue types\nexport const ISSUE_TYPES = ['task', 'bug', 'epic', 'verification'] as const;\nexport type IssueType = (typeof ISSUE_TYPES)[number];\n\n// Priority levels (0 = critical, 4 = backlog)\nexport const PRIORITIES = [0, 1, 2, 3, 4] as const;\nexport type Priority = (typeof PRIORITIES)[number];\n\n// Status values\nexport const STATUSES = ['open', 'in_progress', 'blocked', 'pending_verification', 'closed'] as const;\nexport type Status = (typeof STATUSES)[number];\n\n// Comment interface\nexport interface Comment {\n text: string;\n timestamp: string; // ISO timestamp\n author?: string;\n}\n\n// Issue interface - the current state of an issue\nexport interface Issue {\n id: string; // PREFIX-xxxxxx (6 char alphanumeric suffix)\n title: string;\n type: IssueType;\n priority: Priority;\n status: Status;\n description?: string;\n parent?: string; // ID of parent epic\n blockedBy: string[]; // IDs of blocking issues\n relatedTo: string[]; // IDs of related issues (bidirectional, non-blocking)\n verifies?: string; // ID of issue this verifies (only for type: verification)\n comments: Comment[];\n createdAt: string; // ISO timestamp\n updatedAt: string; // ISO timestamp\n statusChangedAt?: string; // ISO timestamp of last status change\n lastSource?: string; // Folder name from most recent event (worktree/repo root)\n deleted?: boolean; // Soft-deleted flag\n deletedAt?: string; // ISO timestamp of deletion\n _sources?: string[]; // File paths where this issue exists (multi-worktree)\n}\n\n// Event types for append-only JSONL\nexport const EVENT_TYPES = ['create', 'update', 'close', 'reopen', 'comment', 'delete', 'restore'] as const;\nexport type EventType = (typeof EVENT_TYPES)[number];\n\n// Base event interface\ninterface BaseEvent {\n type: EventType;\n issueId: string;\n timestamp: string; // ISO timestamp\n source?: string; // Folder name where command was executed (worktree/repo root)\n}\n\n// Create event - includes all initial issue data\nexport interface CreateEvent extends BaseEvent {\n type: 'create';\n data: {\n title: string;\n type: IssueType;\n priority: Priority;\n description?: string;\n parent?: string;\n verifies?: string; // ID of issue this verifies (only for type: verification)\n };\n}\n\n// Update event - partial issue update\nexport interface UpdateEvent extends BaseEvent {\n type: 'update';\n data: {\n title?: string;\n type?: IssueType;\n priority?: Priority;\n status?: Status;\n description?: string;\n parent?: string;\n blockedBy?: string[];\n relatedTo?: string[];\n };\n}\n\n// Close event\nexport interface CloseEvent extends BaseEvent {\n type: 'close';\n data: {\n reason?: string;\n };\n}\n\n// Reopen event\nexport interface ReopenEvent extends BaseEvent {\n type: 'reopen';\n data: {\n reason?: string;\n };\n}\n\n// Comment event\nexport interface CommentEvent extends BaseEvent {\n type: 'comment';\n data: Comment;\n}\n\n// Delete event - soft delete\nexport interface DeleteEvent extends BaseEvent {\n type: 'delete';\n data: {\n reason?: string;\n cascade?: boolean; // true if this was cascade-deleted as child of epic\n previousStatus?: Status; // Status before deletion (for restore)\n };\n}\n\n// Restore event - undelete\nexport interface RestoreEvent extends BaseEvent {\n type: 'restore';\n data: {\n reason?: string;\n };\n}\n\n// Union type for all events\nexport type IssueEvent =\n | CreateEvent\n | UpdateEvent\n | CloseEvent\n | ReopenEvent\n | CommentEvent\n | DeleteEvent\n | RestoreEvent;\n\n// Config stored in .pebble/config.json\nexport interface PebbleConfig {\n prefix: string;\n version: string;\n useMainTreePebble?: boolean; // default: true - use main tree's .pebble when in a git worktree\n}\n\n// Helper type for issue filters\nexport interface IssueFilters {\n status?: Status;\n type?: IssueType;\n priority?: Priority;\n parent?: string;\n}\n\n// Priority labels for display\nexport const PRIORITY_LABELS: Record<Priority, string> = {\n 0: 'critical',\n 1: 'high',\n 2: 'medium',\n 3: 'low',\n 4: 'backlog',\n};\n\n// Status labels for display\nexport const STATUS_LABELS: Record<Status, string> = {\n open: 'Open',\n in_progress: 'In Progress',\n blocked: 'Blocked',\n pending_verification: 'Pending Verification',\n closed: 'Closed',\n};\n\n// Type labels for display\nexport const TYPE_LABELS: Record<IssueType, string> = {\n task: 'Task',\n bug: 'Bug',\n epic: 'Epic',\n verification: 'Verification',\n};\n\n// Badge variant types (for shadcn/ui Badge component)\nexport type BadgeVariant = 'default' | 'secondary' | 'destructive' | 'outline';\n\n// Status badge variants for UI\nexport const STATUS_BADGE_VARIANTS: Record<Status, BadgeVariant> = {\n open: 'outline',\n in_progress: 'default',\n blocked: 'destructive',\n pending_verification: 'default', // Uses warning color via className\n closed: 'secondary',\n};\n\n// Type badge variants for UI\nexport const TYPE_BADGE_VARIANTS: Record<IssueType, BadgeVariant> = {\n task: 'default',\n bug: 'destructive',\n epic: 'secondary',\n verification: 'outline',\n};\n\n// Priority labels for UI display (capitalized)\nexport const PRIORITY_DISPLAY_LABELS: Record<Priority, string> = {\n 0: 'Critical',\n 1: 'High',\n 2: 'Medium',\n 3: 'Low',\n 4: 'Backlog',\n};\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport type { IssueEvent, PebbleConfig } from '../../shared/types.js';\nimport { derivePrefix } from './id.js';\nimport { getMainWorktreeRoot, getCurrentWorktreeName } from './git.js';\n\nconst PEBBLE_DIR = '.pebble';\nconst ISSUES_FILE = 'issues.jsonl';\nconst CONFIG_FILE = 'config.json';\n\n/**\n * Safely read config without throwing errors.\n * Returns null if config can't be read.\n */\nfunction getConfigSafe(pebbleDir: string): PebbleConfig | null {\n try {\n const configPath = path.join(pebbleDir, CONFIG_FILE);\n if (!fs.existsSync(configPath)) {\n return null;\n }\n const content = fs.readFileSync(configPath, 'utf-8');\n return JSON.parse(content) as PebbleConfig;\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve a local pebble directory to the main tree's pebble directory\n * if we're in a worktree and the config allows it.\n */\nfunction resolveWorktreePebbleDir(localPebbleDir: string): string {\n // Check if --local flag is set (via environment variable)\n if (process.env.PEBBLE_LOCAL === '1') {\n return localPebbleDir;\n }\n\n // Check config for useMainTreePebble setting\n const config = getConfigSafe(localPebbleDir);\n if (config?.useMainTreePebble === false) {\n return localPebbleDir; // Explicitly disabled\n }\n\n // Default behavior: check if we're in a worktree\n const mainRoot = getMainWorktreeRoot();\n if (!mainRoot) {\n return localPebbleDir; // Not in a worktree\n }\n\n // Check if main tree has .pebble\n const mainPebble = path.join(mainRoot, PEBBLE_DIR);\n if (fs.existsSync(mainPebble) && fs.statSync(mainPebble).isDirectory()) {\n return mainPebble;\n }\n\n return localPebbleDir; // Fallback to local\n}\n\n/**\n * Search upward from cwd to find .pebble/ directory.\n * If in a git worktree, checks main tree first (unless --local flag is set).\n * Returns the path to .pebble/ or null if not found.\n */\nexport function discoverPebbleDir(startDir: string = process.cwd()): string | null {\n // If in a worktree and --local not set, check main tree first\n // This handles the case where worktree is a sibling (not child) of main tree\n if (process.env.PEBBLE_LOCAL !== '1') {\n const mainRoot = getMainWorktreeRoot();\n if (mainRoot) {\n const mainPebble = path.join(mainRoot, PEBBLE_DIR);\n if (fs.existsSync(mainPebble) && fs.statSync(mainPebble).isDirectory()) {\n // Check config to see if worktree redirection is disabled\n const config = getConfigSafe(mainPebble);\n if (config?.useMainTreePebble !== false) {\n return mainPebble;\n }\n }\n }\n }\n\n // Fall back to upward search from cwd\n let currentDir = path.resolve(startDir);\n const root = path.parse(currentDir).root;\n\n while (currentDir !== root) {\n const pebbleDir = path.join(currentDir, PEBBLE_DIR);\n if (fs.existsSync(pebbleDir) && fs.statSync(pebbleDir).isDirectory()) {\n return resolveWorktreePebbleDir(pebbleDir);\n }\n currentDir = path.dirname(currentDir);\n }\n\n // Check root as well\n const rootPebble = path.join(root, PEBBLE_DIR);\n if (fs.existsSync(rootPebble) && fs.statSync(rootPebble).isDirectory()) {\n return resolveWorktreePebbleDir(rootPebble);\n }\n\n return null;\n}\n\n/**\n * Get the .pebble directory, throwing if not found\n */\nexport function getPebbleDir(): string {\n const dir = discoverPebbleDir();\n if (!dir) {\n throw new Error('No .pebble directory found. Run a create command to initialize.');\n }\n return dir;\n}\n\n/**\n * Create .pebble/ directory with config if it doesn't exist.\n * In a git worktree, creates in the main tree root (unless --local is set).\n * Returns the path to .pebble/\n */\nexport function ensurePebbleDir(baseDir: string = process.cwd()): string {\n // Check if --local flag is NOT set and we're in a worktree\n // In that case, create in main tree instead of worktree\n let targetDir = baseDir;\n if (process.env.PEBBLE_LOCAL !== '1') {\n const mainRoot = getMainWorktreeRoot();\n if (mainRoot) {\n // Check if main tree already has .pebble\n const mainPebble = path.join(mainRoot, PEBBLE_DIR);\n if (fs.existsSync(mainPebble) && fs.statSync(mainPebble).isDirectory()) {\n return mainPebble; // Use existing main tree .pebble\n }\n // Create in main tree\n targetDir = mainRoot;\n }\n }\n\n const pebbleDir = path.join(targetDir, PEBBLE_DIR);\n\n if (!fs.existsSync(pebbleDir)) {\n fs.mkdirSync(pebbleDir, { recursive: true });\n\n // Create initial config with worktree support enabled by default\n const folderName = path.basename(targetDir);\n const config: PebbleConfig = {\n prefix: derivePrefix(folderName),\n version: '0.1.0',\n useMainTreePebble: true,\n };\n setConfig(config, pebbleDir);\n\n // Create empty issues file\n const issuesPath = path.join(pebbleDir, ISSUES_FILE);\n fs.writeFileSync(issuesPath, '', 'utf-8');\n }\n\n return pebbleDir;\n}\n\n/**\n * Get the path to the issues JSONL file\n */\nexport function getIssuesPath(pebbleDir?: string): string {\n const dir = pebbleDir ?? getPebbleDir();\n return path.join(dir, ISSUES_FILE);\n}\n\n/**\n * Get the source name for events (worktree/repo folder name).\n * Used to track which worktree a command was executed from.\n */\nexport function getEventSource(): string {\n // Try git worktree name first\n const worktreeName = getCurrentWorktreeName();\n if (worktreeName) {\n return worktreeName;\n }\n\n // Fallback: use folder name where .pebble is located\n const pebbleDir = discoverPebbleDir();\n if (pebbleDir) {\n return path.basename(path.dirname(pebbleDir));\n }\n\n return 'unknown';\n}\n\n/**\n * Append an event to the JSONL file.\n * Automatically adds source field if not present.\n */\nexport function appendEvent(event: IssueEvent, pebbleDir?: string): void {\n const issuesPath = getIssuesPath(pebbleDir);\n // Add source if not already present\n const eventWithSource = event.source ? event : { ...event, source: getEventSource() };\n const line = JSON.stringify(eventWithSource) + '\\n';\n fs.appendFileSync(issuesPath, line, 'utf-8');\n}\n\n/**\n * Read all events from a specific JSONL file path\n * Returns empty array if file doesn't exist\n */\nexport function readEventsFromFile(filePath: string): IssueEvent[] {\n if (!fs.existsSync(filePath)) {\n return [];\n }\n\n const content = fs.readFileSync(filePath, 'utf-8');\n const lines = content.split('\\n').filter((line) => line.trim() !== '');\n\n return lines.map((line, index) => {\n try {\n return JSON.parse(line) as IssueEvent;\n } catch {\n throw new Error(`Invalid JSON at line ${index + 1} in ${filePath}: ${line}`);\n }\n });\n}\n\n/**\n * Read all events from the JSONL file\n * Returns empty array if no .pebble directory exists\n */\nexport function readEvents(pebbleDir?: string): IssueEvent[] {\n // If no pebbleDir provided, try to discover one\n // Return empty array if no .pebble directory exists (graceful handling for read operations)\n const dir = pebbleDir ?? discoverPebbleDir();\n if (!dir) {\n return [];\n }\n\n const issuesPath = path.join(dir, ISSUES_FILE);\n\n if (!fs.existsSync(issuesPath)) {\n return [];\n }\n\n const content = fs.readFileSync(issuesPath, 'utf-8');\n const lines = content.split('\\n').filter((line) => line.trim() !== '');\n\n return lines.map((line, index) => {\n try {\n return JSON.parse(line) as IssueEvent;\n } catch {\n throw new Error(`Invalid JSON at line ${index + 1}: ${line}`);\n }\n });\n}\n\n/**\n * Get the config file path\n */\nexport function getConfigPath(pebbleDir?: string): string {\n const dir = pebbleDir ?? getPebbleDir();\n return path.join(dir, CONFIG_FILE);\n}\n\n/**\n * Read the config file\n */\nexport function getConfig(pebbleDir?: string): PebbleConfig {\n const configPath = getConfigPath(pebbleDir);\n\n if (!fs.existsSync(configPath)) {\n throw new Error(\"No .pebble directory found. Run 'pb init' to initialize.\");\n }\n\n const content = fs.readFileSync(configPath, 'utf-8');\n return JSON.parse(content) as PebbleConfig;\n}\n\n/**\n * Write the config file\n */\nexport function setConfig(config: PebbleConfig, pebbleDir?: string): void {\n const dir = pebbleDir ?? getPebbleDir();\n const configPath = path.join(dir, CONFIG_FILE);\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\\n', 'utf-8');\n}\n\n/**\n * Get or create the pebble directory\n * If it doesn't exist, creates it in the current directory\n */\nexport function getOrCreatePebbleDir(): string {\n const existing = discoverPebbleDir();\n if (existing) {\n return existing;\n }\n return ensurePebbleDir();\n}\n","import * as crypto from 'crypto';\n\n/**\n * Characters used for ID generation (alphanumeric, lowercase)\n */\nconst ID_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789';\n\n/**\n * Generate a random alphanumeric string of specified length\n */\nfunction randomAlphanumeric(length: number): string {\n const bytes = crypto.randomBytes(length);\n let result = '';\n for (let i = 0; i < length; i++) {\n result += ID_CHARS[bytes[i] % ID_CHARS.length];\n }\n return result;\n}\n\n/**\n * Generate a unique issue ID\n * Format: PREFIX-xxxxxx (6 char alphanumeric suffix)\n */\nexport function generateId(prefix: string): string {\n const suffix = randomAlphanumeric(6);\n return `${prefix}-${suffix}`;\n}\n\n/**\n * Derive a prefix from a folder name\n * Takes first 4 alphabetic/numeric characters and uppercases them\n * Pads with 'X' if less than 4 characters\n */\nexport function derivePrefix(folderName: string): string {\n const clean = folderName.replace(/[^a-zA-Z0-9]/g, '');\n return clean.slice(0, 4).toUpperCase().padEnd(4, 'X');\n}\n\n/**\n * Check if a string is a valid issue ID format\n */\nexport function isValidId(id: string): boolean {\n return /^[A-Z]{4}-[a-z0-9]{6}$/.test(id);\n}\n\n/**\n * Extract the prefix from an issue ID\n */\nexport function extractPrefix(id: string): string | null {\n const match = id.match(/^([A-Z]{4})-[a-z0-9]{6}$/);\n return match ? match[1] : null;\n}\n","import { execSync } from 'child_process';\nimport path from 'path';\n\n/**\n * Check if current directory is inside a git worktree (not the main tree).\n * Returns false if not in a git repo or if already in the main tree.\n */\nexport function isGitWorktree(): boolean {\n try {\n // Get the path to the common git directory (shared across worktrees)\n const gitCommonDir = execSync('git rev-parse --git-common-dir', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n // Get the path to the current worktree's git directory\n const gitDir = execSync('git rev-parse --git-dir', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n // If they differ, we're in a linked worktree\n // Normalize paths for comparison\n const normalizedCommon = path.resolve(gitCommonDir);\n const normalizedGit = path.resolve(gitDir);\n\n return normalizedCommon !== normalizedGit;\n } catch {\n // Not in a git repository or git not installed\n return false;\n }\n}\n\n/**\n * Get the path to the main worktree's root directory.\n * Returns null if not in a git repo, already in main tree, or can't determine.\n */\nexport function getMainWorktreeRoot(): string | null {\n try {\n // Get the common git directory\n const gitCommonDir = execSync('git rev-parse --git-common-dir', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n // Get the current worktree's git directory\n const gitDir = execSync('git rev-parse --git-dir', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n // Normalize paths for comparison\n const normalizedCommon = path.resolve(gitCommonDir);\n const normalizedGit = path.resolve(gitDir);\n\n // If they're the same, we're already in the main tree\n if (normalizedCommon === normalizedGit) {\n return null;\n }\n\n // The main worktree root is the parent of the common git directory\n // For a typical repo, .git is in the root, so we go up one level\n // For worktrees, gitCommonDir is the main repo's .git directory\n const mainRoot = path.dirname(normalizedCommon);\n\n return mainRoot;\n } catch {\n // Not in a git repository or git not installed\n return null;\n }\n}\n\n/**\n * Get the folder name of the current worktree/repo root.\n * Used to record which worktree a command was executed from.\n * Returns null if not in a git repo.\n */\nexport function getCurrentWorktreeName(): string | null {\n try {\n // Get the current worktree/repo root (works for both main tree and worktrees)\n const toplevel = execSync('git rev-parse --show-toplevel', {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n return path.basename(toplevel);\n } catch {\n // Not in a git repository or git not installed\n return null;\n }\n}\n","import type {\n Issue,\n IssueEvent,\n CreateEvent,\n UpdateEvent,\n CommentEvent,\n IssueFilters,\n} from '../../shared/types.js';\nimport { readEvents } from './storage.js';\n\n/**\n * Compute current issue state from a list of events\n * Returns a map of issue ID to current Issue state\n */\nexport function computeState(events: IssueEvent[]): Map<string, Issue> {\n const issues = new Map<string, Issue>();\n\n for (const event of events) {\n switch (event.type) {\n case 'create': {\n const createEvent = event as CreateEvent;\n const issue: Issue = {\n id: event.issueId,\n title: createEvent.data.title,\n type: createEvent.data.type,\n priority: createEvent.data.priority,\n status: 'open',\n description: createEvent.data.description,\n parent: createEvent.data.parent,\n blockedBy: [],\n relatedTo: [],\n verifies: createEvent.data.verifies,\n comments: [],\n createdAt: event.timestamp,\n updatedAt: event.timestamp,\n statusChangedAt: event.timestamp, // Initial status is 'open'\n lastSource: event.source,\n };\n issues.set(event.issueId, issue);\n break;\n }\n\n case 'update': {\n const updateEvent = event as UpdateEvent;\n const issue = issues.get(event.issueId);\n if (issue) {\n if (updateEvent.data.title !== undefined) {\n issue.title = updateEvent.data.title;\n }\n if (updateEvent.data.type !== undefined) {\n issue.type = updateEvent.data.type;\n }\n if (updateEvent.data.priority !== undefined) {\n issue.priority = updateEvent.data.priority;\n }\n if (updateEvent.data.status !== undefined) {\n if (issue.status !== updateEvent.data.status) {\n issue.statusChangedAt = event.timestamp;\n }\n issue.status = updateEvent.data.status;\n }\n if (updateEvent.data.description !== undefined) {\n issue.description = updateEvent.data.description;\n }\n if (updateEvent.data.parent !== undefined) {\n // Empty string means \"clear parent\" (sentinel value from --parent null)\n issue.parent = updateEvent.data.parent || undefined;\n }\n if (updateEvent.data.blockedBy !== undefined) {\n issue.blockedBy = updateEvent.data.blockedBy;\n }\n if (updateEvent.data.relatedTo !== undefined) {\n issue.relatedTo = updateEvent.data.relatedTo;\n }\n issue.updatedAt = event.timestamp;\n if (event.source) issue.lastSource = event.source;\n }\n break;\n }\n\n case 'close': {\n const issue = issues.get(event.issueId);\n if (issue) {\n issue.status = 'closed';\n issue.statusChangedAt = event.timestamp;\n issue.updatedAt = event.timestamp;\n if (event.source) issue.lastSource = event.source;\n }\n break;\n }\n\n case 'reopen': {\n const issue = issues.get(event.issueId);\n if (issue) {\n issue.status = 'open';\n issue.statusChangedAt = event.timestamp;\n issue.updatedAt = event.timestamp;\n if (event.source) issue.lastSource = event.source;\n }\n break;\n }\n\n case 'comment': {\n const commentEvent = event as CommentEvent;\n const issue = issues.get(event.issueId);\n if (issue) {\n issue.comments.push(commentEvent.data);\n issue.updatedAt = event.timestamp;\n if (event.source) issue.lastSource = event.source;\n }\n break;\n }\n\n case 'delete': {\n const issue = issues.get(event.issueId);\n if (issue) {\n issue.deleted = true;\n issue.deletedAt = event.timestamp;\n issue.updatedAt = event.timestamp;\n if (event.source) issue.lastSource = event.source;\n }\n break;\n }\n\n case 'restore': {\n const issue = issues.get(event.issueId);\n if (issue) {\n issue.deleted = false;\n issue.deletedAt = undefined;\n issue.updatedAt = event.timestamp;\n if (event.source) issue.lastSource = event.source;\n }\n break;\n }\n }\n }\n\n return issues;\n}\n\n/**\n * Get all issues as an array, optionally filtered\n * By default excludes deleted issues unless includeDeleted is true\n */\nexport function getIssues(filters?: IssueFilters, includeDeleted = false): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n let issues = Array.from(state.values());\n\n // Filter out deleted issues unless explicitly included\n if (!includeDeleted) {\n issues = issues.filter((i) => !i.deleted);\n }\n\n if (filters) {\n if (filters.status !== undefined) {\n issues = issues.filter((i) => i.status === filters.status);\n }\n if (filters.type !== undefined) {\n issues = issues.filter((i) => i.type === filters.type);\n }\n if (filters.priority !== undefined) {\n issues = issues.filter((i) => i.priority === filters.priority);\n }\n if (filters.parent !== undefined) {\n issues = issues.filter((i) => i.parent === filters.parent);\n }\n }\n\n return issues;\n}\n\n/**\n * Get a single issue by ID\n * @param id Issue ID\n * @param includeDeleted If false (default), returns undefined for deleted issues\n */\nexport function getIssue(id: string, includeDeleted = false): Issue | undefined {\n const events = readEvents();\n const state = computeState(events);\n const issue = state.get(id);\n if (issue && issue.deleted && !includeDeleted) {\n return undefined;\n }\n return issue;\n}\n\n/**\n * Resolve a partial ID to a full ID\n * Supports: exact match, prefix match, suffix-only match\n * All matching is case-insensitive\n * Throws if ambiguous (multiple matches) or not found\n */\nexport function resolveId(partial: string): string {\n const events = readEvents();\n const state = computeState(events);\n const allIds = Array.from(state.keys());\n const partialLower = partial.toLowerCase();\n\n // First try exact match (case-insensitive)\n const exactMatch = allIds.find((id) => id.toLowerCase() === partialLower);\n if (exactMatch) {\n return exactMatch;\n }\n\n // Then try prefix match\n const prefixMatches = allIds.filter((id) =>\n id.toLowerCase().startsWith(partialLower)\n );\n\n if (prefixMatches.length === 1) {\n return prefixMatches[0];\n }\n\n if (prefixMatches.length > 1) {\n throw new Error(\n `Ambiguous issue ID '${partial}'. Matches: ${prefixMatches.join(', ')}`\n );\n }\n\n // Then try suffix match (part after the hyphen)\n const suffixMatches = allIds.filter((id) => {\n const hyphenIndex = id.indexOf('-');\n if (hyphenIndex === -1) return false;\n const suffix = id.substring(hyphenIndex + 1).toLowerCase();\n return suffix === partialLower;\n });\n\n if (suffixMatches.length === 1) {\n return suffixMatches[0];\n }\n\n if (suffixMatches.length > 1) {\n throw new Error(\n `Ambiguous issue ID '${partial}'. Matches: ${suffixMatches.join(', ')}`\n );\n }\n\n throw new Error(`Issue not found: ${partial}`);\n}\n\n/**\n * Get issues that are ready for work (non-closed with no open blockers)\n * For verification issues: target must be closed\n * Excludes deleted issues\n */\nexport function getReady(): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n const issues = Array.from(state.values());\n\n return issues.filter((issue) => {\n // Skip deleted issues\n if (issue.deleted) {\n return false;\n }\n\n // Must not be closed or pending_verification\n if (issue.status === 'closed' || issue.status === 'pending_verification') {\n return false;\n }\n\n // All blockers must be closed\n for (const blockerId of issue.blockedBy) {\n const blocker = state.get(blockerId);\n if (blocker && blocker.status !== 'closed') {\n return false;\n }\n }\n\n // For verification issues: target must be closed\n if (issue.type === 'verification' && issue.verifies) {\n const target = state.get(issue.verifies);\n if (!target || target.status !== 'closed') {\n return false;\n }\n }\n\n return true;\n });\n}\n\n/**\n * Get issues that are blocked (have at least one open blocker)\n * Excludes deleted issues\n */\nexport function getBlocked(): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n const issues = Array.from(state.values());\n\n return issues.filter((issue) => {\n // Skip deleted issues\n if (issue.deleted) {\n return false;\n }\n\n // Must not be closed\n if (issue.status === 'closed') {\n return false;\n }\n\n // Check if any blocker is not closed\n for (const blockerId of issue.blockedBy) {\n const blocker = state.get(blockerId);\n if (blocker && blocker.status !== 'closed') {\n return true;\n }\n }\n\n return false;\n });\n}\n\n/**\n * Build a dependency graph as adjacency list\n * Returns a map of issueId -> list of issues it blocks\n */\nexport function buildDependencyGraph(): Map<string, string[]> {\n const events = readEvents();\n const state = computeState(events);\n const graph = new Map<string, string[]>();\n\n // Initialize all nodes\n for (const id of state.keys()) {\n graph.set(id, []);\n }\n\n // Build edges (blocker -> blocked)\n for (const [id, issue] of state) {\n for (const blockerId of issue.blockedBy) {\n const blockerEdges = graph.get(blockerId);\n if (blockerEdges) {\n blockerEdges.push(id);\n }\n }\n }\n\n return graph;\n}\n\n/**\n * Check if adding a dependency would create a cycle\n * Uses DFS to detect if newBlockerId can reach issueId\n */\nexport function detectCycle(issueId: string, newBlockerId: string): boolean {\n if (issueId === newBlockerId) {\n return true; // Self-reference\n }\n\n const graph = buildDependencyGraph();\n\n // Add the proposed edge temporarily\n const blockerEdges = graph.get(newBlockerId) ?? [];\n const testGraph = new Map(graph);\n testGraph.set(newBlockerId, [...blockerEdges, issueId]);\n\n // DFS to check if issueId can reach newBlockerId (which would mean a cycle)\n const visited = new Set<string>();\n const stack = [issueId];\n\n while (stack.length > 0) {\n const current = stack.pop()!;\n\n if (current === newBlockerId) {\n return true; // Found a cycle\n }\n\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n const edges = testGraph.get(current) ?? [];\n for (const next of edges) {\n if (!visited.has(next)) {\n stack.push(next);\n }\n }\n }\n\n return false;\n}\n\n/**\n * Get issues that block a given issue\n */\nexport function getBlockers(issueId: string): Issue[] {\n const issue = getIssue(issueId);\n if (!issue) {\n return [];\n }\n\n const events = readEvents();\n const state = computeState(events);\n\n return issue.blockedBy\n .map((id) => state.get(id))\n .filter((i): i is Issue => i !== undefined);\n}\n\n/**\n * Get issues that are blocked by a given issue\n */\nexport function getBlocking(issueId: string): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n\n return Array.from(state.values()).filter((issue) =>\n issue.blockedBy.includes(issueId)\n );\n}\n\n/**\n * Get children of an epic\n */\nexport function getChildren(epicId: string, includeDeleted = false): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n\n return Array.from(state.values()).filter((issue) =>\n issue.parent === epicId && (includeDeleted || !issue.deleted)\n );\n}\n\n/**\n * Get verification issues that verify a given issue\n */\nexport function getVerifications(issueId: string): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n\n return Array.from(state.values()).filter((issue) => issue.verifies === issueId);\n}\n\n/**\n * Check if an epic has any open children\n */\nexport function hasOpenChildren(epicId: string): boolean {\n const children = getChildren(epicId);\n return children.some((child) => child.status !== 'closed');\n}\n\n/**\n * Get issues that became unblocked/ready after closing an issue.\n * Includes:\n * - Issues that were blocked by this issue and now have all blockers closed\n * - Verification issues that verify this issue (they become ready when target closes)\n */\nexport function getNewlyUnblocked(closedIssueId: string): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n const result: Issue[] = [];\n\n for (const issue of state.values()) {\n // Skip closed issues\n if (issue.status === 'closed') continue;\n\n let isUnblockedByThis = false;\n\n // Check if this issue was blocking it\n if (issue.blockedBy.includes(closedIssueId)) {\n // Check if all blockers are now closed\n const allBlockersClosed = issue.blockedBy.every((blockerId) => {\n const blocker = state.get(blockerId);\n return blocker?.status === 'closed';\n });\n if (allBlockersClosed) {\n isUnblockedByThis = true;\n }\n }\n\n // Check if this is a verification issue that verifies the closed issue\n if (issue.type === 'verification' && issue.verifies === closedIssueId) {\n // Check if all blockers are also closed\n const allBlockersClosed = issue.blockedBy.every((blockerId) => {\n const blocker = state.get(blockerId);\n return blocker?.status === 'closed';\n });\n if (allBlockersClosed) {\n isUnblockedByThis = true;\n }\n }\n\n if (isUnblockedByThis) {\n result.push(issue);\n }\n }\n\n return result;\n}\n\n/**\n * Get issues related to a given issue (bidirectional relationship)\n */\nexport function getRelated(issueId: string): Issue[] {\n const issue = getIssue(issueId);\n if (!issue) {\n return [];\n }\n\n const events = readEvents();\n const state = computeState(events);\n\n return issue.relatedTo\n .map((id) => state.get(id))\n .filter((i): i is Issue => i !== undefined);\n}\n\n/**\n * Check if an issue has any open (non-closed) blockers\n */\nexport function hasOpenBlockersById(issueId: string): boolean {\n const issue = getIssue(issueId);\n if (!issue) {\n return false;\n }\n\n const events = readEvents();\n const state = computeState(events);\n\n return issue.blockedBy.some((blockerId) => {\n const blocker = state.get(blockerId);\n return blocker && blocker.status !== 'closed';\n });\n}\n\n/**\n * Get open blockers for an issue (for error messages)\n */\nexport function getOpenBlockers(issueId: string): Issue[] {\n const issue = getIssue(issueId);\n if (!issue) {\n return [];\n }\n\n const events = readEvents();\n const state = computeState(events);\n\n return issue.blockedBy\n .map((id) => state.get(id))\n .filter((i): i is Issue => i !== undefined && i.status !== 'closed');\n}\n\n/**\n * Get the computed state map for efficient lookups\n * Use this when you need to perform multiple lookups to avoid recomputing state\n */\nexport function getComputedState(): Map<string, Issue> {\n const events = readEvents();\n return computeState(events);\n}\n\n/**\n * Get the ancestry chain for an issue (parent → grandparent → great-grandparent...)\n * Returns array ordered from immediate parent to root\n */\nexport function getAncestryChain(\n issueId: string,\n state: Map<string, Issue>\n): Array<{ id: string; title: string }> {\n const chain: Array<{ id: string; title: string }> = [];\n let current = state.get(issueId);\n\n while (current?.parent) {\n const parent = state.get(current.parent);\n if (!parent) break;\n chain.push({ id: parent.id, title: parent.title });\n current = parent;\n }\n\n return chain;\n}\n\n/**\n * Get all descendants of an issue (children, grandchildren, etc.)\n * Used for cascade delete of epics\n * Returns flat array of all descendant issues\n */\nexport function getDescendants(\n issueId: string,\n state?: Map<string, Issue>\n): Issue[] {\n const issueState = state ?? getComputedState();\n const descendants: Issue[] = [];\n\n function collectDescendants(parentId: string) {\n for (const issue of issueState.values()) {\n if (issue.parent === parentId && !issue.deleted) {\n descendants.push(issue);\n // Recursively collect children of this child\n collectDescendants(issue.id);\n }\n }\n }\n\n collectDescendants(issueId);\n return descendants;\n}\n","import { formatDistanceToNow, parseISO } from 'date-fns';\n\n/**\n * Formats an ISO timestamp as a relative time string.\n * @param isoString - ISO 8601 timestamp\n * @returns Human-readable relative time (e.g., \"2 hours ago\", \"yesterday\")\n */\nexport function formatRelativeTime(isoString: string): string {\n try {\n const date = parseISO(isoString);\n return formatDistanceToNow(date, { addSuffix: true });\n } catch {\n return isoString; // Fallback to original if parsing fails\n }\n}\n\n/**\n * Formats a timestamp with both relative and absolute time.\n * @param isoString - ISO 8601 timestamp\n * @returns Object with relative and absolute formatted strings\n */\nexport function formatTimestamp(isoString: string): {\n relative: string;\n absolute: string;\n} {\n try {\n const date = parseISO(isoString);\n return {\n relative: formatDistanceToNow(date, { addSuffix: true }),\n absolute: date.toLocaleString(),\n };\n } catch {\n return {\n relative: isoString,\n absolute: isoString,\n };\n }\n}\n","import type { Issue, IssueEvent, Priority, Status, IssueType } from '../../shared/types.js';\nimport { PRIORITY_LABELS, STATUS_LABELS, TYPE_LABELS } from '../../shared/types.js';\nimport { formatRelativeTime } from '../../shared/time.js';\n\n/**\n * Limit metadata for paginated output\n */\nexport interface LimitInfo {\n total: number;\n shown: number;\n limited: boolean;\n}\n\n/**\n * Format a limit message for pretty output\n */\nexport function formatLimitMessage(info: LimitInfo): string {\n if (!info.limited) return '';\n return `\\n---\\nShowing ${info.shown} of ${info.total} issues. Use --all or --limit <n> to see more.`;\n}\n\n/**\n * Format data as JSON string\n */\nexport function formatJson(data: unknown): string {\n return JSON.stringify(data, null, 2);\n}\n\n/**\n * Format a priority value for display\n */\nfunction formatPriority(priority: Priority): string {\n return `P${priority} (${PRIORITY_LABELS[priority]})`;\n}\n\n/**\n * Format a status value for display\n */\nfunction formatStatus(status: Status): string {\n return STATUS_LABELS[status];\n}\n\n/**\n * Format a type value for display\n */\nfunction formatType(type: IssueType): string {\n return TYPE_LABELS[type];\n}\n\n/**\n * Truncate a string to max length with ellipsis\n */\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return str.slice(0, maxLength - 3) + '...';\n}\n\n/**\n * Pad a string to a fixed width\n */\nfunction pad(str: string, width: number): string {\n return str.padEnd(width);\n}\n\n/**\n * Format a single issue for pretty display\n */\nexport function formatIssuePretty(issue: Issue): string {\n const lines: string[] = [];\n\n lines.push(`${issue.id} - ${issue.title}`);\n lines.push('─'.repeat(60));\n lines.push(`Type: ${formatType(issue.type)}`);\n lines.push(`Priority: ${formatPriority(issue.priority)}`);\n lines.push(`Status: ${formatStatus(issue.status)}`);\n\n if (issue.parent) {\n lines.push(`Parent: ${issue.parent}`);\n }\n\n if (issue.description) {\n lines.push('');\n lines.push('Description:');\n lines.push(issue.description);\n }\n\n if (issue.blockedBy.length > 0) {\n lines.push('');\n lines.push(`Blocked by: ${issue.blockedBy.join(', ')}`);\n }\n\n if (issue.comments.length > 0) {\n lines.push('');\n lines.push('Comments:');\n for (const comment of issue.comments) {\n const author = comment.author ?? 'unknown';\n const date = new Date(comment.timestamp).toLocaleString();\n lines.push(` [${date}] ${author}: ${comment.text}`);\n }\n }\n\n lines.push('');\n lines.push(`Created: ${new Date(issue.createdAt).toLocaleString()}`);\n lines.push(`Updated: ${new Date(issue.updatedAt).toLocaleString()}`);\n\n return lines.join('\\n');\n}\n\n/**\n * Format a single issue with blocking info for pretty display\n */\nexport function formatIssuePrettyWithBlocking(issue: Issue, blocking: Issue[]): string {\n const lines: string[] = [];\n\n lines.push(`${issue.id} - ${issue.title}`);\n lines.push('─'.repeat(60));\n lines.push(`Type: ${formatType(issue.type)}`);\n lines.push(`Priority: ${formatPriority(issue.priority)}`);\n lines.push(`Status: ${formatStatus(issue.status)}`);\n\n if (issue.parent) {\n lines.push(`Parent: ${issue.parent}`);\n }\n\n if (issue.description) {\n lines.push('');\n lines.push('Description:');\n lines.push(issue.description);\n }\n\n if (issue.blockedBy.length > 0) {\n lines.push('');\n lines.push(`Blocked by: ${issue.blockedBy.join(', ')}`);\n }\n\n if (blocking.length > 0) {\n lines.push('');\n lines.push(`Blocking: ${blocking.map(i => i.id).join(', ')}`);\n }\n\n if (issue.comments.length > 0) {\n lines.push('');\n lines.push('Comments:');\n for (const comment of issue.comments) {\n const author = comment.author ?? 'unknown';\n const date = new Date(comment.timestamp).toLocaleString();\n lines.push(` [${date}] ${author}: ${comment.text}`);\n }\n }\n\n lines.push('');\n lines.push(`Created: ${new Date(issue.createdAt).toLocaleString()}`);\n lines.push(`Updated: ${new Date(issue.updatedAt).toLocaleString()}`);\n\n return lines.join('\\n');\n}\n\n/**\n * Context for detailed issue display\n */\nexport interface IssueDetailContext {\n blocking: Issue[];\n children: Issue[];\n verifications: Issue[];\n related: Issue[];\n ancestry?: Array<{ id: string; title: string }>; // Full parent chain\n}\n\n/**\n * Format an issue with full context (children, verifications, related)\n */\nexport function formatIssueDetailPretty(issue: Issue, ctx: IssueDetailContext): string {\n const lines: string[] = [];\n\n lines.push(`${issue.id} - ${issue.title}`);\n lines.push('─'.repeat(60));\n lines.push(`Type: ${formatType(issue.type)}`);\n lines.push(`Priority: ${formatPriority(issue.priority)}`);\n const statusTime = issue.statusChangedAt ? ` (${formatRelativeTime(issue.statusChangedAt)})` : '';\n lines.push(`Status: ${formatStatus(issue.status)}${statusTime}`);\n\n // Show ancestry chain if available\n if (ctx.ancestry && ctx.ancestry.length > 0) {\n const chain = [...ctx.ancestry].reverse().map(a => a.id).join(' > ');\n lines.push(`Ancestry: ${chain}`);\n } else if (issue.parent) {\n lines.push(`Parent: ${issue.parent}`);\n }\n\n if (issue.description) {\n lines.push('');\n lines.push('Description:');\n lines.push(issue.description);\n }\n\n // Children (for epics)\n if (ctx.children.length > 0) {\n const closedChildren = ctx.children.filter(c => c.status === 'closed');\n const pendingChildren = ctx.children.filter(c => c.status === 'pending_verification');\n const pendingStr = pendingChildren.length > 0 ? ` (${pendingChildren.length} pending verification)` : '';\n lines.push('');\n lines.push(`Children (${closedChildren.length}/${ctx.children.length} done${pendingStr}):`);\n for (const child of ctx.children) {\n const statusIcon = child.status === 'closed' ? '✓' : child.status === 'in_progress' ? '▶' : '○';\n lines.push(` ${statusIcon} ${child.id} - ${child.title} [${child.status}]`);\n }\n }\n\n // Blocked by\n if (issue.blockedBy.length > 0) {\n lines.push('');\n lines.push(`Blocked by: ${issue.blockedBy.join(', ')}`);\n }\n\n // Blocking\n if (ctx.blocking.length > 0) {\n lines.push('');\n lines.push(`Blocking: ${ctx.blocking.map(i => i.id).join(', ')}`);\n }\n\n // Verifications (especially important for pending_verification status)\n if (ctx.verifications.length > 0) {\n const closedVerifications = ctx.verifications.filter(v => v.status === 'closed');\n lines.push('');\n lines.push(`Verifications (${closedVerifications.length}/${ctx.verifications.length} done):`);\n for (const v of ctx.verifications) {\n const statusIcon = v.status === 'closed' ? '✓' : '○';\n lines.push(` ${statusIcon} ${v.id} - ${v.title} [${v.status}]`);\n }\n } else if (issue.status === 'pending_verification') {\n lines.push('');\n lines.push('Verifications: None found (status may be stale)');\n }\n\n // Related issues\n if (ctx.related.length > 0) {\n lines.push('');\n lines.push(`Related: ${ctx.related.map(r => r.id).join(', ')}`);\n }\n\n // Comments\n if (issue.comments.length > 0) {\n lines.push('');\n lines.push('Comments:');\n for (const comment of issue.comments) {\n const author = comment.author ?? 'unknown';\n const date = new Date(comment.timestamp).toLocaleString();\n lines.push(` [${date}] ${author}: ${comment.text}`);\n }\n }\n\n lines.push('');\n lines.push(`Created: ${formatRelativeTime(issue.createdAt)}`);\n lines.push(`Updated: ${formatRelativeTime(issue.updatedAt)}`);\n\n return lines.join('\\n');\n}\n\n/**\n * Output detailed issue information\n */\nexport function outputIssueDetail(issue: Issue, ctx: IssueDetailContext, pretty: boolean): void {\n if (pretty) {\n console.log(formatIssueDetailPretty(issue, ctx));\n } else {\n // Include all context in JSON output\n const output = {\n ...issue,\n blocking: ctx.blocking.map(i => i.id),\n children: ctx.children.map(i => ({ id: i.id, title: i.title, status: i.status })),\n verifications: ctx.verifications.map(i => ({ id: i.id, title: i.title, status: i.status })),\n related: ctx.related.map(i => i.id),\n ...(ctx.ancestry && ctx.ancestry.length > 0 && { ancestry: ctx.ancestry }),\n };\n console.log(formatJson(output));\n }\n}\n\n/**\n * Format a list of issues as a table\n */\nexport function formatIssueListPretty(issues: Issue[]): string {\n if (issues.length === 0) {\n return 'No issues found.';\n }\n\n const lines: string[] = [];\n\n // Header\n const idWidth = 12;\n const typeWidth = 6;\n const prioWidth = 4;\n const statusWidth = 12;\n const titleWidth = 40;\n\n const header = [\n pad('ID', idWidth),\n pad('Type', typeWidth),\n pad('Pri', prioWidth),\n pad('Status', statusWidth),\n pad('Title', titleWidth),\n ].join(' │ ');\n\n lines.push(header);\n lines.push('─'.repeat(header.length));\n\n // Rows\n for (const issue of issues) {\n const row = [\n pad(issue.id, idWidth),\n pad(issue.type, typeWidth),\n pad(`P${issue.priority}`, prioWidth),\n pad(issue.status, statusWidth),\n truncate(issue.title, titleWidth),\n ].join(' │ ');\n lines.push(row);\n }\n\n lines.push('');\n lines.push(`Total: ${issues.length} issue(s)`);\n\n return lines.join('\\n');\n}\n\n/**\n * Format dependency info for pretty display\n */\nexport function formatDepsPretty(\n issueId: string,\n blockedBy: Issue[],\n blocking: Issue[],\n related: Issue[] = []\n): string {\n const lines: string[] = [];\n\n lines.push(`Dependencies for ${issueId}`);\n lines.push('─'.repeat(40));\n\n lines.push('');\n lines.push('Blocked by:');\n if (blockedBy.length === 0) {\n lines.push(' (none)');\n } else {\n for (const issue of blockedBy) {\n const status = issue.status === 'closed' ? '✓' : '○';\n lines.push(` ${status} ${issue.id} - ${truncate(issue.title, 30)}`);\n }\n }\n\n lines.push('');\n lines.push('Blocking:');\n if (blocking.length === 0) {\n lines.push(' (none)');\n } else {\n for (const issue of blocking) {\n lines.push(` ○ ${issue.id} - ${truncate(issue.title, 30)}`);\n }\n }\n\n lines.push('');\n lines.push('Related:');\n if (related.length === 0) {\n lines.push(' (none)');\n } else {\n for (const issue of related) {\n const status = issue.status === 'closed' ? '✓' : '○';\n lines.push(` ${status} ${issue.id} - ${truncate(issue.title, 30)}`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Format events for pretty display\n */\nexport function formatEventsPretty(events: IssueEvent[]): string {\n if (events.length === 0) {\n return 'No events found.';\n }\n\n const lines: string[] = [];\n\n for (const event of events) {\n const date = new Date(event.timestamp).toLocaleString();\n lines.push(`[${date}] ${event.type.toUpperCase()} ${event.issueId}`);\n }\n\n lines.push('');\n lines.push(`Total: ${events.length} event(s)`);\n\n return lines.join('\\n');\n}\n\n/**\n * Format an error for output\n */\nexport function formatError(error: Error | string): string {\n const message = error instanceof Error ? error.message : error;\n return JSON.stringify({ error: message });\n}\n\n/**\n * Format an error for pretty display\n */\nexport function formatErrorPretty(error: Error | string): string {\n const message = error instanceof Error ? error.message : error;\n return `Error: ${message}`;\n}\n\n/**\n * Output data in the requested format\n */\nexport function output(data: unknown, pretty: boolean): void {\n if (pretty) {\n // For pretty mode, we need to know the type\n // This is a generic fallback\n console.log(formatJson(data));\n } else {\n console.log(formatJson(data));\n }\n}\n\n/**\n * Output an issue in the requested format\n */\nexport function outputIssue(issue: Issue, pretty: boolean): void {\n if (pretty) {\n console.log(formatIssuePretty(issue));\n } else {\n console.log(formatJson(issue));\n }\n}\n\n/**\n * Output an issue with blocking info in the requested format\n */\nexport function outputIssueWithBlocking(issue: Issue, blocking: Issue[], pretty: boolean): void {\n if (pretty) {\n console.log(formatIssuePrettyWithBlocking(issue, blocking));\n } else {\n // Include blocking IDs in JSON output\n const output = {\n ...issue,\n blocking: blocking.map(i => i.id),\n };\n console.log(formatJson(output));\n }\n}\n\n/**\n * Extra info that can be included in mutation responses\n */\nexport interface MutationExtra {\n parentReopened?: { id: string; title: string };\n blockersReopened?: Array<{ id: string; title: string }>;\n}\n\n/**\n * Output a mutation success response (minimal: id + success)\n */\nexport function outputMutationSuccess(id: string, pretty: boolean, extra?: MutationExtra): void {\n if (pretty) {\n const notes: string[] = [];\n if (extra?.parentReopened) {\n notes.push(`parent ${extra.parentReopened.id} reopened`);\n }\n if (extra?.blockersReopened?.length) {\n const ids = extra.blockersReopened.map(b => b.id).join(', ');\n notes.push(`blocker${extra.blockersReopened.length > 1 ? 's' : ''} ${ids} reopened`);\n }\n if (notes.length > 0) {\n console.log(`✓ ${id} (${notes.join(', ')})`);\n } else {\n console.log(`✓ ${id}`);\n }\n } else {\n const result: Record<string, unknown> = { id, success: true };\n if (extra?.parentReopened) {\n result._parentReopened = extra.parentReopened;\n }\n if (extra?.blockersReopened?.length) {\n result._blockersReopened = extra.blockersReopened;\n }\n console.log(JSON.stringify(result));\n }\n}\n\n/**\n * Output a list of issues in the requested format\n */\nexport function outputIssueList(issues: Issue[], pretty: boolean, limitInfo?: LimitInfo): void {\n if (pretty) {\n console.log(formatIssueListPretty(issues));\n if (limitInfo?.limited) {\n console.log(formatLimitMessage(limitInfo));\n }\n } else {\n // Only include _meta when results are actually limited\n if (limitInfo?.limited) {\n console.log(formatJson({ issues, _meta: limitInfo }));\n } else {\n console.log(formatJson(issues));\n }\n }\n}\n\n/**\n * Issue with nested children for tree output\n */\nexport interface IssueTreeNode {\n id: string;\n title: string;\n type: string;\n priority: number;\n status: string;\n createdAt: string;\n statusChangedAt?: string;\n childrenCount: number;\n children?: IssueTreeNode[];\n}\n\n/**\n * Build a tree structure from a flat list of issues\n */\nexport function buildIssueTree(issues: Issue[]): IssueTreeNode[] {\n const issueMap = new Map<string, Issue>();\n for (const issue of issues) {\n issueMap.set(issue.id, issue);\n }\n\n // Track which issues are children (have a parent in the list)\n const childIds = new Set<string>();\n for (const issue of issues) {\n if (issue.parent && issueMap.has(issue.parent)) {\n childIds.add(issue.id);\n }\n }\n\n // Build tree nodes recursively\n const buildNode = (issue: Issue): IssueTreeNode => {\n const children = issues\n .filter((i) => i.parent === issue.id)\n .map(buildNode);\n\n return {\n id: issue.id,\n title: issue.title,\n type: issue.type,\n priority: issue.priority,\n status: issue.status,\n createdAt: issue.createdAt,\n statusChangedAt: issue.statusChangedAt,\n childrenCount: children.length,\n ...(children.length > 0 && { children }),\n };\n };\n\n // Start with root issues (no parent or parent not in list)\n const roots = issues.filter((i) => !childIds.has(i.id));\n return roots.map(buildNode);\n}\n\n/**\n * Format issue tree as ASCII tree for pretty display\n */\nexport function formatIssueTreePretty(nodes: IssueTreeNode[], sectionHeader?: string): string {\n if (nodes.length === 0) {\n return 'No issues found.';\n }\n\n const lines: string[] = [];\n\n if (sectionHeader) {\n lines.push(`## ${sectionHeader}`);\n lines.push('');\n }\n\n const countAll = (node: IssueTreeNode): number => {\n const children = node.children ?? [];\n return 1 + children.reduce((sum, child) => sum + countAll(child), 0);\n };\n const totalCount = nodes.reduce((sum, node) => sum + countAll(node), 0);\n\n const formatNode = (node: IssueTreeNode, prefix: string, isLast: boolean, isRoot: boolean): void => {\n const connector = isRoot ? '' : isLast ? '└─ ' : '├─ ';\n const statusIcon = node.status === 'closed' ? '✓' : node.status === 'in_progress' ? '▶' : node.status === 'pending_verification' ? '⏳' : '○';\n const statusText = STATUS_LABELS[node.status as Status].toLowerCase();\n const relativeTime = node.statusChangedAt ? formatRelativeTime(node.statusChangedAt) : formatRelativeTime(node.createdAt);\n\n lines.push(`${prefix}${connector}${statusIcon} ${node.id}: ${node.title} [${node.type}] P${node.priority} ${statusText} ${relativeTime}`);\n\n const children = node.children ?? [];\n const childPrefix = isRoot ? '' : prefix + (isLast ? ' ' : '│ ');\n children.forEach((child, index) => {\n const childIsLast = index === children.length - 1;\n formatNode(child, childPrefix, childIsLast, false);\n });\n };\n\n nodes.forEach((node, index) => {\n formatNode(node, '', index === nodes.length - 1, true);\n });\n\n lines.push('');\n lines.push(`Total: ${totalCount} issue(s)`);\n\n return lines.join('\\n');\n}\n\n/**\n * Output issues as a hierarchical tree\n */\nexport function outputIssueTree(issues: Issue[], pretty: boolean, sectionHeader?: string, limitInfo?: LimitInfo): void {\n const tree = buildIssueTree(issues);\n\n if (pretty) {\n console.log(formatIssueTreePretty(tree, sectionHeader));\n if (limitInfo?.limited) {\n console.log(formatLimitMessage(limitInfo));\n }\n } else {\n // Only include _meta when results are actually limited\n if (limitInfo?.limited) {\n console.log(formatJson({ issues: tree, _meta: limitInfo }));\n } else {\n console.log(formatJson(tree));\n }\n }\n}\n\n/**\n * Output an error in the requested format\n */\nexport function outputError(error: Error | string, pretty: boolean): void {\n if (pretty) {\n console.error(formatErrorPretty(error));\n } else {\n console.error(formatError(error));\n }\n process.exit(1);\n}\n\n/**\n * Extended issue info for verbose output\n */\nexport interface VerboseIssueInfo {\n issue: Issue;\n blocking: string[];\n children: number;\n verifications: number;\n blockers?: string[]; // For blocked command: open blockers\n ancestry: Array<{ id: string; title: string }>; // Full parent chain (parent → grandparent → root)\n}\n\n/**\n * Format a list of issues with verbose details\n */\nexport function formatIssueListVerbose(issues: VerboseIssueInfo[], sectionHeader?: string): string {\n if (issues.length === 0) {\n return 'No issues found.';\n }\n\n const lines: string[] = [];\n\n // Add section header if provided\n if (sectionHeader) {\n lines.push(`## ${sectionHeader} (${issues.length})`);\n lines.push('');\n }\n\n for (const info of issues) {\n const { issue, blocking, children, verifications, blockers, ancestry } = info;\n\n const statusTime = issue.statusChangedAt ? formatRelativeTime(issue.statusChangedAt) : formatRelativeTime(issue.createdAt);\n lines.push(`${issue.id}: ${issue.title}`);\n lines.push(` Type: ${formatType(issue.type)} | Priority: P${issue.priority} | Status: ${formatStatus(issue.status)} (${statusTime})`);\n\n // Show ancestry chain if available (reversed: root > ... > parent)\n if (ancestry.length > 0) {\n const chain = [...ancestry].reverse().map(a => a.title).join(' → ');\n lines.push(` Ancestry: ${chain}`);\n }\n\n // Show blocking/blockers if relevant\n if (blocking.length > 0) {\n lines.push(` Blocking: ${blocking.join(', ')}`);\n }\n if (blockers && blockers.length > 0) {\n lines.push(` Blocked by: ${blockers.join(', ')}`);\n }\n\n // Show children/verifications for epics\n if (issue.type === 'epic' && children > 0) {\n lines.push(` Children: ${children} | Verifications: ${verifications}`);\n }\n\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Output a list of issues with verbose details\n */\nexport function outputIssueListVerbose(issues: VerboseIssueInfo[], pretty: boolean, sectionHeader?: string, limitInfo?: LimitInfo): void {\n if (pretty) {\n console.log(formatIssueListVerbose(issues, sectionHeader));\n if (limitInfo?.limited) {\n console.log(formatLimitMessage(limitInfo));\n }\n } else {\n // JSON output includes all fields\n const output = issues.map(({ issue, blocking, children, verifications, blockers, ancestry }) => ({\n ...issue,\n blocking,\n childrenCount: issue.type === 'epic' ? children : undefined,\n verificationsCount: verifications,\n ...(blockers && { openBlockers: blockers }),\n ...(ancestry.length > 0 && { ancestry }),\n }));\n // Only include _meta when results are actually limited\n if (limitInfo?.limited) {\n console.log(formatJson({ issues: output, _meta: limitInfo }));\n } else {\n console.log(formatJson(output));\n }\n }\n}\n","import { Command } from 'commander';\nimport type { IssueType, Priority, CreateEvent, UpdateEvent, ReopenEvent } from '../../shared/types.js';\nimport { ISSUE_TYPES, PRIORITIES } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, getConfig, appendEvent } from '../lib/storage.js';\nimport { generateId } from '../lib/id.js';\nimport { getIssue, resolveId } from '../lib/state.js';\nimport { outputMutationSuccess, outputError } from '../lib/output.js';\n\nexport function createCommand(program: Command): void {\n program\n .command('create <title>')\n .description('Create a new issue')\n .option('-t, --type <type>', 'Issue type (task, bug, epic, verification)', 'task')\n .option('-p, --priority <priority>', 'Priority (0-4)', '2')\n .option('-d, --description <desc>', 'Description')\n .option('--parent <id>', 'Parent issue ID')\n .option('--verifies <id>', 'ID of issue this verifies (sets type to verification)')\n .option('--blocked-by <ids>', 'Comma-separated IDs of issues that block this one')\n .option('--blocks <ids>', 'Comma-separated IDs of issues this one will block')\n .action(async (title: string, options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Auto-set type to verification if --verifies is used\n let type = options.type as IssueType;\n if (options.verifies && type !== 'verification') {\n type = 'verification';\n }\n\n // Validate type\n if (!ISSUE_TYPES.includes(type)) {\n throw new Error(`Invalid type: ${type}. Must be one of: ${ISSUE_TYPES.join(', ')}`);\n }\n\n // Validate --verifies is only used with verification type\n if (type === 'verification' && !options.verifies) {\n throw new Error('Verification issues require --verifies <id> to specify the issue being verified');\n }\n\n // Validate priority\n const priority = parseInt(options.priority, 10) as Priority;\n if (!PRIORITIES.includes(priority)) {\n throw new Error(`Invalid priority: ${options.priority}. Must be 0-4`);\n }\n\n // Get or create pebble directory\n const pebbleDir = getOrCreatePebbleDir();\n const config = getConfig(pebbleDir);\n\n // Resolve parent if provided\n let parentId: string | undefined;\n let parentReopened: { id: string; title: string } | undefined;\n if (options.parent) {\n parentId = resolveId(options.parent);\n const parent = getIssue(parentId);\n if (!parent) {\n throw new Error(`Parent issue not found: ${options.parent}`);\n }\n if (parent.type === 'verification') {\n throw new Error(`Verification issues cannot be parents`);\n }\n // Auto-reopen closed parent instead of throwing error\n if (parent.status === 'closed') {\n const reopenEvent: ReopenEvent = {\n type: 'reopen',\n issueId: parentId,\n timestamp: new Date().toISOString(),\n data: { reason: 'Reopened to add child' },\n };\n appendEvent(reopenEvent, pebbleDir);\n parentReopened = { id: parentId, title: parent.title };\n }\n }\n\n // Resolve verifies if provided\n let verifiesId: string | undefined;\n if (options.verifies) {\n verifiesId = resolveId(options.verifies);\n const target = getIssue(verifiesId);\n if (!target) {\n throw new Error(`Target issue not found: ${options.verifies}`);\n }\n }\n\n // Resolve --blocked-by (issues that block this new issue)\n const blockedByIds: string[] = [];\n const blockersReopened: Array<{ id: string; title: string }> = [];\n if (options.blockedBy) {\n const ids = options.blockedBy.split(',').map((s: string) => s.trim()).filter(Boolean);\n for (const rawId of ids) {\n const resolvedId = resolveId(rawId);\n const blocker = getIssue(resolvedId);\n if (!blocker) {\n throw new Error(`Blocker issue not found: ${rawId}`);\n }\n // Auto-reopen closed blocker instead of throwing error\n if (blocker.status === 'closed') {\n const reopenEvent: ReopenEvent = {\n type: 'reopen',\n issueId: resolvedId,\n timestamp: new Date().toISOString(),\n data: { reason: 'Reopened to block new issue' },\n };\n appendEvent(reopenEvent, pebbleDir);\n blockersReopened.push({ id: resolvedId, title: blocker.title });\n }\n blockedByIds.push(resolvedId);\n }\n }\n\n // Resolve --blocks (issues this new issue will block)\n const blocksIds: string[] = [];\n if (options.blocks) {\n const ids = options.blocks.split(',').map((s: string) => s.trim()).filter(Boolean);\n for (const rawId of ids) {\n const resolvedId = resolveId(rawId);\n const blocked = getIssue(resolvedId);\n if (!blocked) {\n throw new Error(`Issue to block not found: ${rawId}`);\n }\n blocksIds.push(resolvedId);\n }\n }\n\n // Generate ID and create event\n const id = generateId(config.prefix);\n const timestamp = new Date().toISOString();\n\n const event: CreateEvent = {\n type: 'create',\n issueId: id,\n timestamp,\n data: {\n title,\n type,\n priority,\n description: options.description,\n parent: parentId,\n verifies: verifiesId,\n },\n };\n\n appendEvent(event, pebbleDir);\n\n // Touch parent's updatedAt when child is added\n if (parentId) {\n const parentUpdateEvent: UpdateEvent = {\n type: 'update',\n issueId: parentId,\n timestamp: new Date().toISOString(),\n data: {},\n };\n appendEvent(parentUpdateEvent, pebbleDir);\n }\n\n // Add dependencies via UpdateEvents\n // --blocked-by: Set this issue's blockedBy array\n if (blockedByIds.length > 0) {\n const depEvent: UpdateEvent = {\n type: 'update',\n issueId: id,\n timestamp: new Date().toISOString(),\n data: { blockedBy: blockedByIds },\n };\n appendEvent(depEvent, pebbleDir);\n }\n\n // --blocks: Add this issue to each target's blockedBy array\n for (const targetId of blocksIds) {\n const target = getIssue(targetId);\n const existingBlockers = target?.blockedBy || [];\n const depEvent: UpdateEvent = {\n type: 'update',\n issueId: targetId,\n timestamp: new Date().toISOString(),\n data: { blockedBy: [...existingBlockers, id] },\n };\n appendEvent(depEvent, pebbleDir);\n }\n\n // Output success\n const extra = (parentReopened || blockersReopened.length > 0)\n ? { parentReopened, blockersReopened: blockersReopened.length > 0 ? blockersReopened : undefined }\n : undefined;\n outputMutationSuccess(id, pretty, extra);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { Priority, Status, UpdateEvent, ReopenEvent } from '../../shared/types.js';\nimport { PRIORITIES, STATUSES } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { getIssue, resolveId, hasOpenBlockersById, getOpenBlockers } from '../lib/state.js';\nimport { outputMutationSuccess, outputError, formatJson } from '../lib/output.js';\n\nexport function updateCommand(program: Command): void {\n program\n .command('update <ids...>')\n .description('Update issues. Supports multiple IDs.')\n .option('--status <status>', 'Status (open, in_progress, blocked, closed)')\n .option('--priority <priority>', 'Priority (0-4)')\n .option('--title <title>', 'Title')\n .option('--description <desc>', 'Description')\n .option('--parent <id>', 'Parent issue ID (use \"null\" to remove parent)')\n .action(async (ids: string[], options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n\n // Support comma-separated IDs: \"ID1,ID2,ID3\" or \"ID1 ID2 ID3\"\n const allIds = ids.flatMap(id => id.split(',').map(s => s.trim()).filter(Boolean));\n\n if (allIds.length === 0) {\n throw new Error('No issue IDs provided');\n }\n\n // Validate options once (they apply to all)\n const data: UpdateEvent['data'] = {};\n let hasChanges = false;\n\n if (options.status !== undefined) {\n const status = options.status as Status;\n if (!STATUSES.includes(status)) {\n throw new Error(`Invalid status: ${status}. Must be one of: ${STATUSES.join(', ')}`);\n }\n data.status = status;\n hasChanges = true;\n }\n\n if (options.priority !== undefined) {\n const priority = parseInt(options.priority, 10) as Priority;\n if (!PRIORITIES.includes(priority)) {\n throw new Error(`Invalid priority: ${options.priority}. Must be 0-4`);\n }\n data.priority = priority;\n hasChanges = true;\n }\n\n if (options.title !== undefined) {\n data.title = options.title;\n hasChanges = true;\n }\n\n if (options.description !== undefined) {\n data.description = options.description;\n hasChanges = true;\n }\n\n // Track if we need to reopen a parent\n let parentReopened: { id: string; title: string } | undefined;\n\n if (options.parent !== undefined) {\n if (options.parent.toLowerCase() === 'null') {\n // Remove parent - use empty string as sentinel (undefined would be ignored by state.ts)\n data.parent = '';\n } else {\n // Resolve and validate parent\n const parentId = resolveId(options.parent);\n const parentIssue = getIssue(parentId);\n if (!parentIssue) {\n throw new Error(`Parent issue not found: ${options.parent}`);\n }\n if (parentIssue.type === 'verification') {\n throw new Error(`Verification issues cannot be parents`);\n }\n // Auto-reopen closed parent instead of throwing error\n if (parentIssue.status === 'closed') {\n const reopenEvent: ReopenEvent = {\n type: 'reopen',\n issueId: parentId,\n timestamp: new Date().toISOString(),\n data: { reason: 'Reopened to add child' },\n };\n appendEvent(reopenEvent, pebbleDir);\n parentReopened = { id: parentId, title: parentIssue.title };\n }\n data.parent = parentId;\n }\n hasChanges = true;\n }\n\n if (!hasChanges) {\n throw new Error('No changes specified. Use --status, --priority, --title, --description, or --parent');\n }\n\n const results: Array<{ id: string; success: boolean; error?: string }> = [];\n\n for (const id of allIds) {\n try {\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n results.push({ id, success: false, error: `Issue not found: ${id}` });\n continue;\n }\n\n // Cannot set status to in_progress if blocked\n if (data.status === 'in_progress' && hasOpenBlockersById(resolvedId)) {\n const blockers = getOpenBlockers(resolvedId);\n const blockerIds = blockers.map(b => b.id).join(', ');\n results.push({ id: resolvedId, success: false, error: `Cannot set to in_progress - blocked by: ${blockerIds}` });\n continue;\n }\n\n const event: UpdateEvent = {\n type: 'update',\n issueId: resolvedId,\n timestamp: new Date().toISOString(),\n data,\n };\n\n appendEvent(event, pebbleDir);\n results.push({ id: resolvedId, success: true });\n } catch (error) {\n results.push({ id, success: false, error: (error as Error).message });\n }\n }\n\n // Output results\n if (allIds.length === 1) {\n // Single issue - output success or error\n const result = results[0];\n if (result.success) {\n outputMutationSuccess(result.id, pretty, parentReopened ? { parentReopened } : undefined);\n } else {\n throw new Error(result.error || 'Unknown error');\n }\n } else {\n // Multiple issues - output array of results\n if (pretty) {\n for (const result of results) {\n if (result.success) {\n console.log(`✓ ${result.id}`);\n } else {\n console.log(`✗ ${result.id}: ${result.error}`);\n }\n }\n } else {\n console.log(formatJson(results.map(r => ({\n id: r.id,\n success: r.success,\n ...(r.error && { error: r.error }),\n }))));\n }\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { CloseEvent, CommentEvent, UpdateEvent } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { getIssue, resolveId, hasOpenChildren, getNewlyUnblocked, getVerifications } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\n\nexport function closeCommand(program: Command): void {\n program\n .command('close <ids...>')\n .description('Close issues. Supports multiple IDs.')\n .option('--reason <reason>', 'Reason for closing')\n .option('--comment <text>', 'Add a comment before closing')\n .action(async (ids: string[], options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n\n // Support comma-separated IDs: \"ID1,ID2,ID3\" or \"ID1 ID2 ID3\"\n const allIds = ids.flatMap(id => id.split(',').map(s => s.trim()).filter(Boolean));\n\n if (allIds.length === 0) {\n throw new Error('No issue IDs provided');\n }\n\n const results: Array<{\n id: string;\n success: boolean;\n error?: string;\n status?: 'closed' | 'pending_verification';\n pendingVerifications?: Array<{ id: string; title: string }>;\n unblocked?: Array<{ id: string; title: string }>;\n autoClosed?: { id: string; title: string };\n }> = [];\n\n for (const id of allIds) {\n try {\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n results.push({ id, success: false, error: `Issue not found: ${id}` });\n continue;\n }\n\n if (issue.status === 'closed') {\n results.push({ id: resolvedId, success: false, error: `Issue is already closed: ${resolvedId}` });\n continue;\n }\n\n // Check if issue has open children\n if (hasOpenChildren(resolvedId)) {\n results.push({ id: resolvedId, success: false, error: `Cannot close issue with open children: ${resolvedId}` });\n continue;\n }\n\n const timestamp = new Date().toISOString();\n\n // Add comment first if provided\n if (options.comment) {\n const commentEvent: CommentEvent = {\n type: 'comment',\n issueId: resolvedId,\n timestamp,\n data: {\n text: options.comment,\n timestamp,\n },\n };\n appendEvent(commentEvent, pebbleDir);\n }\n\n // Check for pending verifications\n const pendingVerifications = getVerifications(resolvedId)\n .filter(v => v.status !== 'closed');\n\n if (pendingVerifications.length > 0) {\n // Move to pending_verification instead of closed\n const updateEvent: UpdateEvent = {\n type: 'update',\n issueId: resolvedId,\n timestamp,\n data: {\n status: 'pending_verification',\n },\n };\n appendEvent(updateEvent, pebbleDir);\n\n results.push({\n id: resolvedId,\n success: true,\n status: 'pending_verification',\n pendingVerifications: pendingVerifications.map(v => ({ id: v.id, title: v.title })),\n });\n continue;\n }\n\n // No pending verifications - close normally\n const closeEvent: CloseEvent = {\n type: 'close',\n issueId: resolvedId,\n timestamp,\n data: {\n reason: options.reason,\n },\n };\n\n appendEvent(closeEvent, pebbleDir);\n\n // Get issues that became unblocked\n const unblocked = getNewlyUnblocked(resolvedId);\n\n // Check if this was a verification issue and auto-close target if all verifications done\n let autoClosed: { id: string; title: string } | undefined;\n if (issue.verifies) {\n const targetIssue = getIssue(issue.verifies);\n if (targetIssue && targetIssue.status === 'pending_verification') {\n // Re-fetch verifications to get updated state\n const remainingVerifications = getVerifications(issue.verifies)\n .filter(v => v.status !== 'closed');\n\n if (remainingVerifications.length === 0) {\n // All verifications closed - auto-close the target\n const autoCloseEvent: CloseEvent = {\n type: 'close',\n issueId: issue.verifies,\n timestamp: new Date().toISOString(),\n data: {\n reason: 'All verifications completed',\n },\n };\n appendEvent(autoCloseEvent, pebbleDir);\n autoClosed = { id: targetIssue.id, title: targetIssue.title };\n }\n }\n }\n\n results.push({\n id: resolvedId,\n success: true,\n status: 'closed',\n unblocked: unblocked.length > 0 ? unblocked.map(i => ({ id: i.id, title: i.title })) : undefined,\n autoClosed,\n });\n } catch (error) {\n results.push({ id, success: false, error: (error as Error).message });\n }\n }\n\n // Output results\n if (allIds.length === 1) {\n // Single issue - output success or error\n const result = results[0];\n if (result.success) {\n if (pretty) {\n if (result.status === 'pending_verification') {\n console.log(`⏳ ${result.id} → pending_verification`);\n console.log(`\\nPending verifications:`);\n for (const v of result.pendingVerifications || []) {\n console.log(` • ${v.id} - ${v.title}`);\n }\n console.log(`\\nRun: pb verifications ${result.id}`);\n } else {\n console.log(`✓ ${result.id}`);\n if (result.unblocked && result.unblocked.length > 0) {\n console.log(`\\nUnblocked:`);\n for (const u of result.unblocked) {\n console.log(` → ${u.id} - ${u.title}`);\n }\n }\n if (result.autoClosed) {\n console.log(`\\n✓ ${result.autoClosed.id} auto-closed (all verifications complete)`);\n }\n }\n } else {\n console.log(formatJson({\n id: result.id,\n success: true,\n status: result.status,\n ...(result.pendingVerifications && { pendingVerifications: result.pendingVerifications }),\n ...(result.pendingVerifications && { hint: `pb verifications ${result.id}` }),\n ...(result.unblocked && { unblocked: result.unblocked }),\n ...(result.autoClosed && { autoClosed: result.autoClosed }),\n }));\n }\n } else {\n throw new Error(result.error || 'Unknown error');\n }\n } else {\n // Multiple issues - output array of results\n if (pretty) {\n for (const result of results) {\n if (result.success) {\n if (result.status === 'pending_verification') {\n console.log(`⏳ ${result.id} → pending_verification`);\n for (const v of result.pendingVerifications || []) {\n console.log(` • ${v.id} - ${v.title}`);\n }\n console.log(` Run: pb verifications ${result.id}`);\n } else {\n console.log(`✓ ${result.id}`);\n if (result.unblocked && result.unblocked.length > 0) {\n for (const u of result.unblocked) {\n console.log(` → ${u.id} - ${u.title}`);\n }\n }\n if (result.autoClosed) {\n console.log(` ✓ ${result.autoClosed.id} auto-closed (all verifications complete)`);\n }\n }\n } else {\n console.log(`✗ ${result.id}: ${result.error}`);\n }\n }\n } else {\n console.log(formatJson(results.map(r => ({\n id: r.id,\n success: r.success,\n status: r.status,\n ...(r.error && { error: r.error }),\n ...(r.pendingVerifications && { pendingVerifications: r.pendingVerifications }),\n ...(r.pendingVerifications && { hint: `pb verifications ${r.id}` }),\n ...(r.unblocked && { unblocked: r.unblocked }),\n ...(r.autoClosed && { autoClosed: r.autoClosed }),\n }))));\n }\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { ReopenEvent } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { getIssue, resolveId } from '../lib/state.js';\nimport { outputMutationSuccess, outputError } from '../lib/output.js';\n\nexport function reopenCommand(program: Command): void {\n program\n .command('reopen <id>')\n .description('Reopen a closed issue')\n .option('--reason <reason>', 'Reason for reopening')\n .action(async (id: string, options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n if (issue.status !== 'closed') {\n throw new Error(`Issue is not closed: ${resolvedId} (status: ${issue.status})`);\n }\n\n const event: ReopenEvent = {\n type: 'reopen',\n issueId: resolvedId,\n timestamp: new Date().toISOString(),\n data: {\n reason: options.reason,\n },\n };\n\n appendEvent(event, pebbleDir);\n\n // Output success\n outputMutationSuccess(resolvedId, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { DeleteEvent, UpdateEvent, Issue } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { resolveId, getDescendants, getVerifications, getComputedState } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\n\n// Type for accumulated reference cleanup updates\ntype ReferenceUpdates = Map<string, {\n blockedBy?: string[];\n relatedTo?: string[];\n parent?: string;\n}>;\n\n/**\n * Collect reference cleanup updates for a deleted issue.\n * Updates are accumulated into the provided map and merged if the same issue\n * is affected by multiple deletions. Call emitReferenceCleanup() after collecting\n * all updates to emit the events.\n */\nfunction collectReferenceCleanup(\n deletedId: string,\n deletedIds: Set<string>,\n state: Map<string, Issue>,\n updates: ReferenceUpdates\n): void {\n for (const [id, issue] of state) {\n // Skip issues being deleted\n if (deletedIds.has(id)) continue;\n // Skip already deleted issues\n if (issue.deleted) continue;\n\n // Get or create update entry for this issue\n let entry = updates.get(id);\n\n // Check blockedBy - use existing accumulated value if present\n const currentBlockedBy = entry?.blockedBy ?? issue.blockedBy;\n if (currentBlockedBy.includes(deletedId)) {\n if (!entry) {\n entry = {};\n updates.set(id, entry);\n }\n entry.blockedBy = currentBlockedBy.filter((bid) => bid !== deletedId);\n }\n\n // Check relatedTo - use existing accumulated value if present\n const currentRelatedTo = entry?.relatedTo ?? issue.relatedTo;\n if (currentRelatedTo.includes(deletedId)) {\n if (!entry) {\n entry = {};\n updates.set(id, entry);\n }\n entry.relatedTo = currentRelatedTo.filter((rid) => rid !== deletedId);\n }\n\n // Clear parent if it points to deleted issue\n if (issue.parent === deletedId) {\n if (!entry) {\n entry = {};\n updates.set(id, entry);\n }\n entry.parent = ''; // Empty string signals \"clear parent\"\n }\n }\n}\n\n/**\n * Emit all collected reference cleanup updates as UpdateEvents\n */\nfunction emitReferenceCleanup(\n updates: ReferenceUpdates,\n pebbleDir: string,\n timestamp: string\n): void {\n for (const [id, data] of updates) {\n if (Object.keys(data).length > 0) {\n const updateEvent: UpdateEvent = {\n type: 'update',\n issueId: id,\n timestamp,\n data,\n };\n appendEvent(updateEvent, pebbleDir);\n }\n }\n}\n\nexport function deleteCommand(program: Command): void {\n program\n .command('delete <ids...>')\n .description('Delete issues (soft delete). Epics cascade-delete their children.')\n .option('-r, --reason <reason>', 'Reason for deleting')\n .action(async (ids: string[], options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const state = getComputedState();\n\n // Support comma-separated IDs\n const allIds = ids\n .flatMap((id) => id.split(',').map((s) => s.trim()).filter(Boolean));\n\n if (allIds.length === 0) {\n throw new Error('No issue IDs provided');\n }\n\n const results: Array<{\n id: string;\n success: boolean;\n error?: string;\n cascade?: boolean;\n }> = [];\n\n // Collect all issues to delete (including cascaded)\n const toDelete: Array<{ id: string; cascade: boolean }> = [];\n const alreadyQueued = new Set<string>();\n\n for (const id of allIds) {\n try {\n const resolvedId = resolveId(id);\n const issue = state.get(resolvedId);\n\n if (!issue) {\n results.push({ id, success: false, error: `Issue not found: ${id}` });\n continue;\n }\n\n if (issue.deleted) {\n results.push({ id: resolvedId, success: false, error: `Issue is already deleted: ${resolvedId}` });\n continue;\n }\n\n // Add this issue\n if (!alreadyQueued.has(resolvedId)) {\n toDelete.push({ id: resolvedId, cascade: false });\n alreadyQueued.add(resolvedId);\n }\n\n // Get descendants for cascade delete (children, grandchildren, etc.)\n const descendants = getDescendants(resolvedId, state);\n for (const desc of descendants) {\n if (!alreadyQueued.has(desc.id) && !desc.deleted) {\n toDelete.push({ id: desc.id, cascade: true });\n alreadyQueued.add(desc.id);\n }\n }\n\n // Get verification issues that verify this issue - cascade delete them too\n const verifications = getVerifications(resolvedId);\n for (const v of verifications) {\n if (!alreadyQueued.has(v.id) && !v.deleted) {\n toDelete.push({ id: v.id, cascade: true });\n alreadyQueued.add(v.id);\n }\n }\n } catch (error) {\n results.push({ id, success: false, error: (error as Error).message });\n }\n }\n\n // Collect all reference cleanup updates first (to handle multi-issue deletion correctly)\n const timestamp = new Date().toISOString();\n const deletedIds = new Set(toDelete.map(d => d.id));\n const referenceUpdates: ReferenceUpdates = new Map();\n\n for (const { id } of toDelete) {\n collectReferenceCleanup(id, deletedIds, state, referenceUpdates);\n }\n\n // Emit all reference cleanup events\n emitReferenceCleanup(referenceUpdates, pebbleDir, timestamp);\n\n // Now emit delete events\n for (const { id, cascade } of toDelete) {\n const issue = state.get(id);\n if (!issue) continue;\n\n const deleteEvent: DeleteEvent = {\n type: 'delete',\n issueId: id,\n timestamp,\n data: {\n reason: options.reason,\n cascade: cascade || undefined,\n previousStatus: issue.status,\n },\n };\n appendEvent(deleteEvent, pebbleDir);\n\n results.push({ id, success: true, cascade: cascade || undefined });\n }\n\n // Output results\n if (pretty) {\n // Group by primary vs cascade\n const primary = results.filter((r) => r.success && !r.cascade);\n const cascaded = results.filter((r) => r.success && r.cascade);\n const failed = results.filter((r) => !r.success);\n\n for (const result of primary) {\n console.log(`🗑️ ${result.id} deleted`);\n }\n for (const result of cascaded) {\n console.log(` └─ ${result.id} deleted (cascade)`);\n }\n for (const result of failed) {\n console.log(`✗ ${result.id}: ${result.error}`);\n }\n } else {\n console.log(formatJson({\n deleted: results\n .filter((r) => r.success)\n .map((r) => ({ id: r.id, cascade: r.cascade ?? false })),\n ...(results.some((r) => !r.success) && {\n errors: results\n .filter((r) => !r.success)\n .map((r) => ({ id: r.id, error: r.error })),\n }),\n }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { RestoreEvent } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { getIssue, resolveId } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\n\nexport function restoreCommand(program: Command): void {\n program\n .command('restore <ids...>')\n .description('Restore deleted issues')\n .option('-r, --reason <reason>', 'Reason for restoring')\n .action(async (ids: string[], options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n\n // Support comma-separated IDs\n const allIds = ids\n .flatMap((id) => id.split(',').map((s) => s.trim()).filter(Boolean));\n\n if (allIds.length === 0) {\n throw new Error('No issue IDs provided');\n }\n\n const results: Array<{\n id: string;\n success: boolean;\n error?: string;\n }> = [];\n\n const timestamp = new Date().toISOString();\n\n for (const id of allIds) {\n try {\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId, true); // includeDeleted=true to find deleted issues\n\n if (!issue) {\n results.push({ id, success: false, error: `Issue not found: ${id}` });\n continue;\n }\n\n if (!issue.deleted) {\n results.push({ id: resolvedId, success: false, error: `Issue is not deleted: ${resolvedId}` });\n continue;\n }\n\n const restoreEvent: RestoreEvent = {\n type: 'restore',\n issueId: resolvedId,\n timestamp,\n data: {\n reason: options.reason,\n },\n };\n\n appendEvent(restoreEvent, pebbleDir);\n results.push({ id: resolvedId, success: true });\n } catch (error) {\n results.push({ id, success: false, error: (error as Error).message });\n }\n }\n\n // Output results\n if (allIds.length === 1) {\n const result = results[0];\n if (result.success) {\n if (pretty) {\n console.log(`↩️ ${result.id} restored`);\n } else {\n console.log(formatJson({ id: result.id, success: true }));\n }\n } else {\n throw new Error(result.error || 'Unknown error');\n }\n } else {\n if (pretty) {\n for (const result of results) {\n if (result.success) {\n console.log(`↩️ ${result.id} restored`);\n } else {\n console.log(`✗ ${result.id}: ${result.error}`);\n }\n }\n } else {\n console.log(formatJson({\n restored: results.filter((r) => r.success).map((r) => r.id),\n ...(results.some((r) => !r.success) && {\n errors: results\n .filter((r) => !r.success)\n .map((r) => ({ id: r.id, error: r.error })),\n }),\n }));\n }\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { UpdateEvent } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { getIssue, resolveId, hasOpenBlockersById, getOpenBlockers } from '../lib/state.js';\nimport { outputMutationSuccess, outputError, formatJson } from '../lib/output.js';\n\nexport function claimCommand(program: Command): void {\n program\n .command('claim <ids...>')\n .description('Claim issues (set status to in_progress). Supports multiple IDs.')\n .action(async (ids: string[]) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n\n // Support comma-separated IDs: \"ID1,ID2,ID3\" or \"ID1 ID2 ID3\"\n const allIds = ids.flatMap(id => id.split(',').map(s => s.trim()).filter(Boolean));\n\n if (allIds.length === 0) {\n throw new Error('No issue IDs provided');\n }\n\n const results: Array<{ id: string; success: boolean; error?: string }> = [];\n\n for (const id of allIds) {\n try {\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n results.push({ id, success: false, error: `Issue not found: ${id}` });\n continue;\n }\n\n if (issue.status === 'in_progress') {\n results.push({ id: resolvedId, success: true });\n continue;\n }\n\n if (issue.status === 'closed') {\n results.push({ id: resolvedId, success: false, error: `Cannot claim closed issue: ${resolvedId}` });\n continue;\n }\n\n // Check if blocked\n if (hasOpenBlockersById(resolvedId)) {\n const blockers = getOpenBlockers(resolvedId);\n const blockerIds = blockers.map(b => b.id).join(', ');\n results.push({ id: resolvedId, success: false, error: `Cannot claim blocked issue. Blocked by: ${blockerIds}` });\n continue;\n }\n\n const event: UpdateEvent = {\n type: 'update',\n issueId: resolvedId,\n timestamp: new Date().toISOString(),\n data: {\n status: 'in_progress',\n },\n };\n\n appendEvent(event, pebbleDir);\n results.push({ id: resolvedId, success: true });\n } catch (error) {\n results.push({ id, success: false, error: (error as Error).message });\n }\n }\n\n // Output results\n if (allIds.length === 1) {\n // Single issue - output success or error\n const result = results[0];\n if (result.success) {\n outputMutationSuccess(result.id, pretty);\n } else {\n throw new Error(result.error || 'Unknown error');\n }\n } else {\n // Multiple issues - output array of results\n if (pretty) {\n for (const result of results) {\n if (result.success) {\n console.log(`✓ ${result.id}`);\n } else {\n console.log(`✗ ${result.id}: ${result.error}`);\n }\n }\n } else {\n console.log(formatJson(results.map(r => ({\n id: r.id,\n success: r.success,\n ...(r.error && { error: r.error }),\n }))));\n }\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { IssueType, Priority, Status, IssueFilters } from '../../shared/types.js';\nimport { ISSUE_TYPES, PRIORITIES, STATUSES, STATUS_LABELS } from '../../shared/types.js';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssues, resolveId, getBlocking, getChildren, getVerifications, getComputedState, getAncestryChain } from '../lib/state.js';\nimport { outputIssueList, outputIssueListVerbose, outputIssueTree, outputError, type VerboseIssueInfo, type LimitInfo } from '../lib/output.js';\n\nexport function listCommand(program: Command): void {\n program\n .command('list')\n .description('List issues')\n .option('--status <status>', 'Filter by status')\n .option('-t, --type <type>', 'Filter by type')\n .option('--priority <priority>', 'Filter by priority')\n .option('--parent <id>', 'Filter by parent epic')\n .option('-v, --verbose', 'Show expanded details (parent, children, blocking, verifications)')\n .option('--flat', 'Show flat list instead of hierarchical tree')\n .option('--limit <n>', 'Max issues to return (default: 30)')\n .option('--all', 'Show all issues (no limit)')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Auto-init .pebble/ if it doesn't exist\n getOrCreatePebbleDir();\n\n const filters: IssueFilters = {};\n\n if (options.status !== undefined) {\n const status = options.status as Status;\n if (!STATUSES.includes(status)) {\n throw new Error(`Invalid status: ${status}. Must be one of: ${STATUSES.join(', ')}`);\n }\n filters.status = status;\n }\n\n if (options.type !== undefined) {\n const type = options.type as IssueType;\n if (!ISSUE_TYPES.includes(type)) {\n throw new Error(`Invalid type: ${type}. Must be one of: ${ISSUE_TYPES.join(', ')}`);\n }\n filters.type = type;\n }\n\n if (options.priority !== undefined) {\n const priority = parseInt(options.priority, 10) as Priority;\n if (!PRIORITIES.includes(priority)) {\n throw new Error(`Invalid priority: ${options.priority}. Must be 0-4`);\n }\n filters.priority = priority;\n }\n\n if (options.parent !== undefined) {\n filters.parent = resolveId(options.parent);\n }\n\n let issues = getIssues(filters);\n\n // Sort by createdAt descending (newest first)\n issues.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n\n // Apply limit\n const total = issues.length;\n const limit = options.all ? 0 : (options.limit ? parseInt(options.limit, 10) : 30);\n if (limit > 0 && issues.length > limit) {\n issues = issues.slice(0, limit);\n }\n const limitInfo: LimitInfo = {\n total,\n shown: issues.length,\n limited: limit > 0 && total > limit,\n };\n\n // Verbose output: flat list with expanded details\n if (options.verbose) {\n // Get computed state once for efficient ancestry lookups\n const state = getComputedState();\n\n // Build verbose info for each issue\n const verboseIssues: VerboseIssueInfo[] = issues.map((issue) => {\n return {\n issue,\n blocking: getBlocking(issue.id).map((i) => i.id),\n children: getChildren(issue.id).length,\n verifications: getVerifications(issue.id).length,\n ancestry: getAncestryChain(issue.id, state),\n };\n });\n\n // Determine section header based on filters\n let sectionHeader = 'Issues';\n if (filters.status) {\n sectionHeader = `${STATUS_LABELS[filters.status]} Issues`;\n }\n outputIssueListVerbose(verboseIssues, pretty, sectionHeader, limitInfo);\n } else if (options.flat) {\n // Flat output: simple table/list\n outputIssueList(issues, pretty, limitInfo);\n } else {\n // Default: hierarchical tree structure\n let sectionHeader = 'Issues';\n if (filters.status) {\n sectionHeader = `${STATUS_LABELS[filters.status]} Issues`;\n }\n outputIssueTree(issues, pretty, sectionHeader, limitInfo);\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssue, resolveId, getBlocking, getChildren, getVerifications, getRelated, getComputedState, getAncestryChain } from '../lib/state.js';\nimport { outputIssueDetail, outputError } from '../lib/output.js';\n\nexport function showCommand(program: Command): void {\n program\n .command('show <id>')\n .description('Show issue details')\n .action(async (id: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Auto-init .pebble/ if it doesn't exist\n getOrCreatePebbleDir();\n\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n const blocking = getBlocking(resolvedId);\n const children = issue.type === 'epic' ? getChildren(resolvedId) : [];\n const verifications = getVerifications(resolvedId);\n const related = getRelated(resolvedId);\n const state = getComputedState();\n const ancestry = getAncestryChain(resolvedId, state);\n\n outputIssueDetail(issue, { blocking, children, verifications, related, ancestry }, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport { ISSUE_TYPES, type IssueType } from '../../shared/types.js';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getReady, getBlocking, getChildren, getVerifications, getComputedState, getAncestryChain } from '../lib/state.js';\nimport { outputIssueList, outputIssueListVerbose, outputError, type VerboseIssueInfo, type LimitInfo } from '../lib/output.js';\n\nexport function readyCommand(program: Command): void {\n program\n .command('ready')\n .description('Show issues ready for work (no open blockers)')\n .option('-v, --verbose', 'Show expanded details (parent, children, blocking, verifications)')\n .option('-t, --type <type>', 'Filter by type: task, bug, epic, verification')\n .option('--limit <n>', 'Max issues to return (default: 30)')\n .option('--all', 'Show all issues (no limit)')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Auto-init .pebble/ if it doesn't exist\n getOrCreatePebbleDir();\n\n let issues = getReady();\n\n // Filter by type if specified\n if (options.type) {\n const typeFilter = options.type.toLowerCase() as IssueType;\n if (!ISSUE_TYPES.includes(typeFilter)) {\n throw new Error(`Invalid type: ${options.type}. Must be one of: ${ISSUE_TYPES.join(', ')}`);\n }\n issues = issues.filter((i) => i.type === typeFilter);\n }\n\n // Sort by createdAt descending (newest first)\n issues.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n\n // Apply limit\n const total = issues.length;\n const limit = options.all ? 0 : (options.limit ? parseInt(options.limit, 10) : 30);\n if (limit > 0 && issues.length > limit) {\n issues = issues.slice(0, limit);\n }\n const limitInfo: LimitInfo = {\n total,\n shown: issues.length,\n limited: limit > 0 && total > limit,\n };\n\n if (options.verbose) {\n // Get computed state once for efficient ancestry lookups\n const state = getComputedState();\n\n // Build verbose info for each issue\n const verboseIssues: VerboseIssueInfo[] = issues.map((issue) => {\n return {\n issue,\n blocking: getBlocking(issue.id).map((i) => i.id),\n children: getChildren(issue.id).length,\n verifications: getVerifications(issue.id).length,\n ancestry: getAncestryChain(issue.id, state),\n };\n });\n outputIssueListVerbose(verboseIssues, pretty, 'Ready Issues', limitInfo);\n } else {\n outputIssueList(issues, pretty, limitInfo);\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getBlocked, getBlocking, getChildren, getVerifications, getBlockers, getComputedState, getAncestryChain } from '../lib/state.js';\nimport { outputIssueList, outputIssueListVerbose, outputError, type VerboseIssueInfo, type LimitInfo } from '../lib/output.js';\n\nexport function blockedCommand(program: Command): void {\n program\n .command('blocked')\n .description('Show blocked issues (have open blockers)')\n .option('-v, --verbose', 'Show expanded details including WHY each issue is blocked')\n .option('--limit <n>', 'Max issues to return (default: 30)')\n .option('--all', 'Show all issues (no limit)')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Auto-init .pebble/ if it doesn't exist\n getOrCreatePebbleDir();\n\n let issues = getBlocked();\n\n // Sort by createdAt descending (newest first)\n issues.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n\n // Apply limit\n const total = issues.length;\n const limit = options.all ? 0 : (options.limit ? parseInt(options.limit, 10) : 30);\n if (limit > 0 && issues.length > limit) {\n issues = issues.slice(0, limit);\n }\n const limitInfo: LimitInfo = {\n total,\n shown: issues.length,\n limited: limit > 0 && total > limit,\n };\n\n if (options.verbose) {\n // Get computed state once for efficient ancestry lookups\n const state = getComputedState();\n\n // Build verbose info for each issue, including open blockers\n const verboseIssues: VerboseIssueInfo[] = issues.map((issue) => {\n // Get open blockers (issues blocking this one that aren't closed)\n const allBlockers = getBlockers(issue.id);\n const openBlockers = allBlockers\n .filter((b) => b.status !== 'closed')\n .map((b) => b.id);\n\n return {\n issue,\n blocking: getBlocking(issue.id).map((i) => i.id),\n children: getChildren(issue.id).length,\n verifications: getVerifications(issue.id).length,\n blockers: openBlockers,\n ancestry: getAncestryChain(issue.id, state),\n };\n });\n outputIssueListVerbose(verboseIssues, pretty, 'Blocked Issues', limitInfo);\n } else {\n outputIssueList(issues, pretty, limitInfo);\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { Issue, UpdateEvent } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent, readEvents } from '../lib/storage.js';\nimport {\n getIssue,\n resolveId,\n detectCycle,\n getBlockers,\n getBlocking,\n getRelated,\n computeState,\n} from '../lib/state.js';\nimport { outputMutationSuccess, outputError, formatDepsPretty, formatJson } from '../lib/output.js';\n\nexport function depCommand(program: Command): void {\n const dep = program\n .command('dep')\n .description('Manage dependencies');\n\n // dep add <id> [blocker-id] --needs <id> --blocks <id>\n dep\n .command('add <id> [blockerId]')\n .description('Add a blocking dependency. Use --needs or --blocks for self-documenting syntax.')\n .option('--needs <id>', 'Issue that must be completed first (first arg needs this)')\n .option('--blocks <id>', 'Issue that this blocks (first arg blocks this)')\n .action(async (id: string, blockerId: string | undefined, options: { needs?: string; blocks?: string }) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Validate usage: cannot combine flags with each other or with positional\n if (options.needs && options.blocks) {\n throw new Error('Cannot use both --needs and --blocks');\n }\n if (blockerId && (options.needs || options.blocks)) {\n throw new Error('Cannot combine positional blockerId with --needs or --blocks');\n }\n if (!blockerId && !options.needs && !options.blocks) {\n throw new Error('Must provide blockerId, --needs <id>, or --blocks <id>');\n }\n\n const pebbleDir = getOrCreatePebbleDir();\n\n // Determine blocked and blocker based on usage:\n // pb dep add X Y => X is blocked by Y\n // pb dep add X --needs Y => X is blocked by Y (same as above)\n // pb dep add X --blocks Y => Y is blocked by X (inverted)\n let blockedId: string;\n let blockerIdResolved: string;\n\n if (options.blocks) {\n // X blocks Y => Y is blocked by X\n blockedId = resolveId(options.blocks);\n blockerIdResolved = resolveId(id);\n } else {\n // X needs Y or X Y => X is blocked by Y\n blockedId = resolveId(id);\n blockerIdResolved = resolveId(options.needs || blockerId!);\n }\n\n const issue = getIssue(blockedId);\n if (!issue) {\n throw new Error(`Issue not found: ${blockedId}`);\n }\n\n const blocker = getIssue(blockerIdResolved);\n if (!blocker) {\n throw new Error(`Blocker issue not found: ${blockerIdResolved}`);\n }\n\n // Check for self-reference\n if (blockedId === blockerIdResolved) {\n throw new Error('Cannot add self as blocker');\n }\n\n // Check for existing dependency\n if (issue.blockedBy.includes(blockerIdResolved)) {\n throw new Error(`Dependency already exists: ${blockedId} is blocked by ${blockerIdResolved}`);\n }\n\n // Check for cycles\n if (detectCycle(blockedId, blockerIdResolved)) {\n throw new Error(`Adding this dependency would create a cycle`);\n }\n\n // Add the dependency\n const event: UpdateEvent = {\n type: 'update',\n issueId: blockedId,\n timestamp: new Date().toISOString(),\n data: {\n blockedBy: [...issue.blockedBy, blockerIdResolved],\n },\n };\n\n appendEvent(event, pebbleDir);\n\n outputMutationSuccess(blockedId, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n\n // dep remove <id> <blocker-id>\n dep\n .command('remove <id> <blockerId>')\n .description('Remove a blocking dependency')\n .action(async (id: string, blockerId: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const resolvedId = resolveId(id);\n const resolvedBlockerId = resolveId(blockerId);\n\n const issue = getIssue(resolvedId);\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n // Check if dependency exists before removing\n if (!issue.blockedBy.includes(resolvedBlockerId)) {\n throw new Error(`Dependency does not exist: ${resolvedId} is not blocked by ${resolvedBlockerId}`);\n }\n\n // Remove the dependency\n const newBlockedBy = issue.blockedBy.filter((b) => b !== resolvedBlockerId);\n\n const event: UpdateEvent = {\n type: 'update',\n issueId: resolvedId,\n timestamp: new Date().toISOString(),\n data: {\n blockedBy: newBlockedBy,\n },\n };\n\n appendEvent(event, pebbleDir);\n\n outputMutationSuccess(resolvedId, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n\n // dep relate <id1> <id2> - bidirectional relationship\n dep\n .command('relate <id1> <id2>')\n .description('Add a bidirectional related link between two issues')\n .action(async (id1: string, id2: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const resolvedId1 = resolveId(id1);\n const resolvedId2 = resolveId(id2);\n\n const issue1 = getIssue(resolvedId1);\n if (!issue1) {\n throw new Error(`Issue not found: ${id1}`);\n }\n\n const issue2 = getIssue(resolvedId2);\n if (!issue2) {\n throw new Error(`Issue not found: ${id2}`);\n }\n\n // Check for self-reference\n if (resolvedId1 === resolvedId2) {\n throw new Error('Cannot relate issue to itself');\n }\n\n // Check if already related\n if (issue1.relatedTo.includes(resolvedId2)) {\n throw new Error(`Issues are already related: ${resolvedId1} ↔ ${resolvedId2}`);\n }\n\n const timestamp = new Date().toISOString();\n\n // Add bidirectional relationship\n const event1: UpdateEvent = {\n type: 'update',\n issueId: resolvedId1,\n timestamp,\n data: {\n relatedTo: [...issue1.relatedTo, resolvedId2],\n },\n };\n\n const event2: UpdateEvent = {\n type: 'update',\n issueId: resolvedId2,\n timestamp,\n data: {\n relatedTo: [...issue2.relatedTo, resolvedId1],\n },\n };\n\n appendEvent(event1, pebbleDir);\n appendEvent(event2, pebbleDir);\n\n if (pretty) {\n console.log(`✓ ${resolvedId1} ↔ ${resolvedId2}`);\n } else {\n console.log(formatJson({ id1: resolvedId1, id2: resolvedId2, related: true }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n\n // dep unrelate <id1> <id2> - remove bidirectional relationship\n dep\n .command('unrelate <id1> <id2>')\n .description('Remove a bidirectional related link between two issues')\n .action(async (id1: string, id2: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const resolvedId1 = resolveId(id1);\n const resolvedId2 = resolveId(id2);\n\n const issue1 = getIssue(resolvedId1);\n if (!issue1) {\n throw new Error(`Issue not found: ${id1}`);\n }\n\n const issue2 = getIssue(resolvedId2);\n if (!issue2) {\n throw new Error(`Issue not found: ${id2}`);\n }\n\n // Check if related\n if (!issue1.relatedTo.includes(resolvedId2)) {\n throw new Error(`Issues are not related: ${resolvedId1} ↔ ${resolvedId2}`);\n }\n\n const timestamp = new Date().toISOString();\n\n // Remove bidirectional relationship\n const event1: UpdateEvent = {\n type: 'update',\n issueId: resolvedId1,\n timestamp,\n data: {\n relatedTo: issue1.relatedTo.filter((id) => id !== resolvedId2),\n },\n };\n\n const event2: UpdateEvent = {\n type: 'update',\n issueId: resolvedId2,\n timestamp,\n data: {\n relatedTo: issue2.relatedTo.filter((id) => id !== resolvedId1),\n },\n };\n\n appendEvent(event1, pebbleDir);\n appendEvent(event2, pebbleDir);\n\n if (pretty) {\n console.log(`✓ ${resolvedId1} ↮ ${resolvedId2}`);\n } else {\n console.log(formatJson({ id1: resolvedId1, id2: resolvedId2, related: false }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n\n // dep list <id>\n dep\n .command('list <id>')\n .description('List dependencies for an issue')\n .action(async (id: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n const blockedBy = getBlockers(resolvedId);\n const blocking = getBlocking(resolvedId);\n const related = getRelated(resolvedId);\n\n if (pretty) {\n console.log(formatDepsPretty(resolvedId, blockedBy, blocking, related));\n } else {\n console.log(formatJson({\n issueId: resolvedId,\n blockedBy: blockedBy.map((i) => ({ id: i.id, title: i.title, status: i.status })),\n blocking: blocking.map((i) => ({ id: i.id, title: i.title, status: i.status })),\n related: related.map((i) => ({ id: i.id, title: i.title, status: i.status })),\n }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n\n // dep tree <id>\n dep\n .command('tree <id>')\n .description('Show issue tree (children, verifications, and full hierarchy)')\n .action(async (id: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n // Build tree structure - compute state once\n const events = readEvents();\n const state = computeState(events);\n const tree = buildIssueTree(resolvedId, state);\n\n if (pretty) {\n console.log(formatIssueTreePretty(tree));\n } else {\n console.log(formatJson(tree));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n\ninterface IssueTreeNode {\n id: string;\n title: string;\n type: string;\n priority: number;\n status: string;\n isTarget?: boolean; // The issue that was requested\n childrenCount: number;\n children?: IssueTreeNode[];\n}\n\nfunction buildIssueTree(\n issueId: string,\n state: Map<string, Issue>\n): IssueTreeNode | null {\n const issue = state.get(issueId);\n if (!issue) {\n return null;\n }\n\n // Build children recursively\n const buildChildren = (id: string, visited: Set<string>): IssueTreeNode[] => {\n const children: IssueTreeNode[] = [];\n for (const [, i] of state) {\n if ((i.parent === id || i.verifies === id) && !visited.has(i.id)) {\n visited.add(i.id);\n const nodeChildren = buildChildren(i.id, visited);\n children.push({\n id: i.id,\n title: i.title,\n type: i.type,\n priority: i.priority,\n status: i.status,\n isTarget: i.id === issueId,\n childrenCount: nodeChildren.length,\n ...(nodeChildren.length > 0 && { children: nodeChildren }),\n });\n }\n }\n return children;\n };\n\n // Build the target node with its children\n const visited = new Set<string>([issueId]);\n const targetChildren = buildChildren(issueId, visited);\n const targetNode: IssueTreeNode = {\n id: issue.id,\n title: issue.title,\n type: issue.type,\n priority: issue.priority,\n status: issue.status,\n isTarget: true,\n childrenCount: targetChildren.length,\n ...(targetChildren.length > 0 && { children: targetChildren }),\n };\n\n // Walk up the parent chain to find the root\n let currentNode = targetNode;\n let currentIssue = issue;\n\n while (currentIssue.parent) {\n const parentIssue = state.get(currentIssue.parent);\n if (!parentIssue) break;\n\n // Create parent node with current as child, plus any siblings\n const siblings: IssueTreeNode[] = [];\n for (const [, i] of state) {\n if ((i.parent === parentIssue.id || i.verifies === parentIssue.id) && i.id !== currentIssue.id) {\n // Add sibling (but don't expand its children to keep output focused)\n siblings.push({\n id: i.id,\n title: i.title,\n type: i.type,\n priority: i.priority,\n status: i.status,\n childrenCount: 0,\n });\n }\n }\n\n const parentNodeChildren = [currentNode, ...siblings];\n const parentNode: IssueTreeNode = {\n id: parentIssue.id,\n title: parentIssue.title,\n type: parentIssue.type,\n priority: parentIssue.priority,\n status: parentIssue.status,\n childrenCount: parentNodeChildren.length,\n children: parentNodeChildren,\n };\n\n currentNode = parentNode;\n currentIssue = parentIssue;\n }\n\n return currentNode;\n}\n\nfunction formatIssueTreePretty(node: IssueTreeNode | null): string {\n if (!node) {\n return 'Issue not found.';\n }\n\n const lines: string[] = [];\n\n const formatNode = (n: IssueTreeNode, prefix: string, isLast: boolean, isRoot: boolean): void => {\n const connector = isRoot ? '' : isLast ? '└─ ' : '├─ ';\n const statusIcon = n.status === 'closed' ? '✓' : n.status === 'in_progress' ? '▶' : n.status === 'pending_verification' ? '⏳' : '○';\n const marker = n.isTarget ? ' ◀' : '';\n\n lines.push(`${prefix}${connector}${statusIcon} ${n.id}: ${n.title} [${n.type}] P${n.priority}${marker}`);\n\n const children = n.children ?? [];\n const childPrefix = isRoot ? '' : prefix + (isLast ? ' ' : '│ ');\n children.forEach((child, index) => {\n const childIsLast = index === children.length - 1;\n formatNode(child, childPrefix, childIsLast, false);\n });\n };\n\n formatNode(node, '', true, true);\n\n return lines.join('\\n');\n}\n","import { Command } from 'commander';\nimport type { CommentEvent } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, appendEvent } from '../lib/storage.js';\nimport { getIssue, resolveId } from '../lib/state.js';\nimport { outputMutationSuccess, outputError } from '../lib/output.js';\n\nexport function commentsCommand(program: Command): void {\n const comments = program\n .command('comments')\n .description('Manage comments');\n\n // comments add <id> <text>\n comments\n .command('add <id> <text>')\n .description('Add a comment to an issue')\n .action(async (id: string, text: string) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n const timestamp = new Date().toISOString();\n const event: CommentEvent = {\n type: 'comment',\n issueId: resolvedId,\n timestamp,\n data: {\n text,\n timestamp,\n },\n };\n\n appendEvent(event, pebbleDir);\n\n outputMutationSuccess(resolvedId, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssue, getIssues, resolveId } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\nimport type { Issue } from '../../shared/types.js';\n\nexport function graphCommand(program: Command): void {\n program\n .command('graph')\n .description('Show dependency graph')\n .option('--root <id>', 'Filter to subtree rooted at issue')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Auto-init .pebble/ if it doesn't exist\n getOrCreatePebbleDir();\n\n let issues: Issue[];\n\n if (options.root) {\n const rootId = resolveId(options.root);\n const rootIssue = getIssue(rootId);\n if (!rootIssue) {\n throw new Error(`Issue not found: ${options.root}`);\n }\n // Get all issues in the subtree\n issues = getSubtree(rootId);\n } else {\n issues = getIssues({});\n }\n\n if (pretty) {\n console.log(formatGraphPretty(issues));\n } else {\n console.log(formatJson({\n nodes: issues.map((i) => ({\n id: i.id,\n title: i.title,\n status: i.status,\n blockedBy: i.blockedBy,\n })),\n }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n\nfunction getSubtree(rootId: string): Issue[] {\n // Get all issues to build reverse lookup maps\n const allIssues = getIssues({});\n const issueMap = new Map(allIssues.map((i) => [i.id, i]));\n const neighborhood = new Set<string>();\n\n // Traverse upstream: what blocks this issue (recursively)\n function traverseUpstream(id: string) {\n if (neighborhood.has(id)) return;\n neighborhood.add(id);\n const issue = issueMap.get(id);\n if (issue) {\n // Blockers\n for (const blockerId of issue.blockedBy) {\n traverseUpstream(blockerId);\n }\n // Parent\n if (issue.parent) {\n traverseUpstream(issue.parent);\n }\n }\n }\n\n // Traverse downstream: what this issue blocks (recursively)\n function traverseDownstream(id: string) {\n if (neighborhood.has(id)) return;\n neighborhood.add(id);\n // Find issues blocked by this one\n for (const issue of allIssues) {\n if (issue.blockedBy.includes(id)) {\n traverseDownstream(issue.id);\n }\n // Find children\n if (issue.parent === id) {\n traverseDownstream(issue.id);\n }\n }\n }\n\n traverseUpstream(rootId);\n traverseDownstream(rootId);\n\n // Return issues in the neighborhood\n return allIssues.filter((i) => neighborhood.has(i.id));\n}\n\nfunction formatGraphPretty(issues: Issue[]): string {\n if (issues.length === 0) {\n return 'No issues found.';\n }\n\n const lines: string[] = [];\n lines.push('Dependency Graph');\n lines.push('================');\n lines.push('');\n\n // Build adjacency maps\n const blockedByMap = new Map<string, string[]>();\n const blockingMap = new Map<string, string[]>();\n const issueMap = new Map<string, Issue>();\n\n for (const issue of issues) {\n issueMap.set(issue.id, issue);\n blockedByMap.set(issue.id, issue.blockedBy);\n\n for (const blockerId of issue.blockedBy) {\n if (!blockingMap.has(blockerId)) {\n blockingMap.set(blockerId, []);\n }\n blockingMap.get(blockerId)!.push(issue.id);\n }\n }\n\n // Calculate levels using topological sort\n const levels = new Map<string, number>();\n const visited = new Set<string>();\n\n function calculateLevel(id: string): number {\n if (levels.has(id)) return levels.get(id)!;\n if (visited.has(id)) return 0; // Cycle protection\n visited.add(id);\n\n const blockedBy = blockedByMap.get(id) || [];\n let maxBlockerLevel = -1;\n for (const blockerId of blockedBy) {\n const blockerLevel = calculateLevel(blockerId);\n maxBlockerLevel = Math.max(maxBlockerLevel, blockerLevel);\n }\n\n const level = maxBlockerLevel + 1;\n levels.set(id, level);\n return level;\n }\n\n for (const issue of issues) {\n calculateLevel(issue.id);\n }\n\n // Group by level\n const byLevel = new Map<number, Issue[]>();\n for (const issue of issues) {\n const level = levels.get(issue.id) || 0;\n if (!byLevel.has(level)) {\n byLevel.set(level, []);\n }\n byLevel.get(level)!.push(issue);\n }\n\n // Print by level\n const maxLevel = Math.max(...Array.from(levels.values()));\n for (let level = 0; level <= maxLevel; level++) {\n const levelIssues = byLevel.get(level) || [];\n if (levelIssues.length === 0) continue;\n\n lines.push(`Level ${level}:`);\n for (const issue of levelIssues) {\n const statusIcon = issue.status === 'closed' ? '✓' : '○';\n const blockers = issue.blockedBy.length > 0 ? ` ← [${issue.blockedBy.join(', ')}]` : '';\n lines.push(` ${statusIcon} ${issue.id} - ${issue.title}${blockers}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","import { Command } from 'commander';\nimport express, { Response } from 'express';\nimport cors from 'cors';\nimport { fileURLToPath } from 'url';\nimport path from 'path';\nimport fs from 'fs';\nimport net from 'net';\nimport open from 'open';\nimport chokidar from 'chokidar';\nimport {\n getIssue,\n resolveId,\n hasOpenChildren,\n detectCycle,\n computeState,\n getVerifications,\n getDescendants,\n getComputedState,\n} from '../lib/state.js';\nimport {\n readEventsFromFile,\n getOrCreatePebbleDir,\n appendEvent,\n getConfig,\n getEventSource,\n} from '../lib/storage.js';\nimport { generateId } from '../lib/id.js';\nimport { outputError } from '../lib/output.js';\nimport type {\n CreateEvent,\n UpdateEvent,\n CloseEvent,\n ReopenEvent,\n CommentEvent,\n DeleteEvent,\n RestoreEvent,\n IssueType,\n IssueEvent,\n Priority,\n Issue,\n} from '../../shared/types.js';\nimport { ISSUE_TYPES, STATUSES, PRIORITIES } from '../../shared/types.js';\n\n// Check if a port is available\nfunction isPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = net.createServer();\n server.once('error', () => resolve(false));\n server.once('listening', () => {\n server.close();\n resolve(true);\n });\n server.listen(port);\n });\n}\n\n// Find an available port starting from the given port\nasync function findAvailablePort(startPort: number, maxAttempts = 10): Promise<number> {\n for (let i = 0; i < maxAttempts; i++) {\n const port = startPort + i;\n if (await isPortAvailable(port)) {\n return port;\n }\n }\n throw new Error(`No available port found (tried ${startPort}-${startPort + maxAttempts - 1})`);\n}\n\n// Multi-worktree: Issue with source tracking\ninterface IssueWithSource extends Issue {\n _sources: string[]; // File paths where this issue exists\n}\n\n/**\n * Merge events from multiple files, deduplicating by (issueId, timestamp, type).\n * Same event appearing in multiple files = keep first occurrence.\n */\nfunction mergeEventsFromFiles(filePaths: string[]): IssueEvent[] {\n const merged = new Map<string, IssueEvent>();\n\n for (const filePath of filePaths) {\n const events = readEventsFromFile(filePath);\n for (const event of events) {\n const key = `${event.issueId}-${event.timestamp}-${event.type}`;\n if (!merged.has(key)) {\n merged.set(key, event);\n }\n }\n }\n\n // Sort by timestamp ascending (chronological order)\n return Array.from(merged.values()).sort(\n (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()\n );\n}\n\n/**\n * Merge issues from multiple files.\n * Same ID = same issue: keep the version with the latest updatedAt.\n * Tracks which file(s) contain each issue.\n */\nfunction mergeIssuesFromFiles(filePaths: string[]): IssueWithSource[] {\n const merged = new Map<string, { issue: Issue; sources: Set<string> }>();\n\n for (const filePath of filePaths) {\n const events = readEventsFromFile(filePath);\n const state = computeState(events);\n\n for (const [id, issue] of state) {\n const existing = merged.get(id);\n if (!existing) {\n // First time seeing this issue\n merged.set(id, { issue, sources: new Set([filePath]) });\n } else {\n // Issue exists in multiple files - keep the one with latest updatedAt\n existing.sources.add(filePath);\n if (new Date(issue.updatedAt) > new Date(existing.issue.updatedAt)) {\n merged.set(id, { issue, sources: existing.sources });\n }\n }\n }\n }\n\n return Array.from(merged.values()).map(({ issue, sources }) => ({\n ...issue,\n _sources: Array.from(sources),\n }));\n}\n\n/**\n * Find an issue by ID across all source files.\n * Returns the issue and which file to write mutations to.\n */\nfunction findIssueInSources(\n issueId: string,\n filePaths: string[]\n): { issue: Issue; targetFile: string } | null {\n // First, try to find by exact ID or prefix match\n const allIssues = mergeIssuesFromFiles(filePaths);\n\n // Try exact match first\n let found = allIssues.find((i) => i.id === issueId);\n\n // Try prefix match if no exact match\n if (!found) {\n const matches = allIssues.filter((i) => i.id.startsWith(issueId));\n if (matches.length === 1) {\n found = matches[0];\n } else if (matches.length > 1) {\n return null; // Ambiguous\n }\n }\n\n if (!found) {\n return null;\n }\n\n // Use the first source file (where the issue was most recently updated)\n const targetFile = found._sources[0];\n return { issue: found, targetFile };\n}\n\n/**\n * Append an event to a specific file (for multi-worktree mode).\n * Automatically adds source field if not present.\n */\nfunction appendEventToFile(event: IssueEvent, filePath: string): void {\n // Add source if not already present\n const eventWithSource = event.source ? event : { ...event, source: getEventSource() };\n const line = JSON.stringify(eventWithSource) + '\\n';\n fs.appendFileSync(filePath, line, 'utf-8');\n}\n\nexport function uiCommand(program: Command): void {\n const defaultPort = process.env.PEBBLE_UI_PORT || '3333';\n\n program\n .command('ui')\n .description('Serve the React UI')\n .option('--port <port>', 'Port to serve on', defaultPort)\n .option('--no-open', 'Do not open browser automatically')\n .option('--files <paths>', 'Comma-separated paths to issues.jsonl files for multi-worktree view')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Parse multi-worktree files option\n let issueFiles: string[] = [];\n if (options.files) {\n // Parse comma-separated paths\n issueFiles = options.files.split(',').map((p: string) => p.trim()).filter(Boolean);\n if (issueFiles.length === 0) {\n console.error('Error: --files option requires at least one path');\n process.exit(1);\n }\n // Resolve relative paths\n issueFiles = issueFiles.map((p: string) => path.resolve(process.cwd(), p));\n console.log(`Multi-worktree mode: watching ${issueFiles.length} file(s)`);\n for (const f of issueFiles) {\n console.log(` - ${f}`);\n }\n } else {\n // Default: single file mode\n const pebbleDir = getOrCreatePebbleDir();\n issueFiles = [path.join(pebbleDir, 'issues.jsonl')];\n }\n\n // Auto-create .pebble if it doesn't exist (single file mode only)\n if (!options.files) {\n getOrCreatePebbleDir();\n }\n\n const app = express();\n\n // Middleware\n app.use(cors());\n app.use(express.json());\n\n // API routes\n // API routes - use multi-worktree merge when multiple files\n // This is now a function since issueFiles can change dynamically\n const isMultiWorktree = () => issueFiles.length > 1;\n\n // GET /api/sources - Returns available issue files (for multi-worktree)\n app.get('/api/sources', (_req, res) => {\n try {\n res.json({ files: issueFiles, isMultiWorktree: isMultiWorktree() });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/sources - Add a new issue file to watch\n app.post('/api/sources', (req, res) => {\n try {\n const { path: filePath } = req.body;\n if (!filePath || typeof filePath !== 'string') {\n res.status(400).json({ error: 'path is required' });\n return;\n }\n\n const resolved = path.resolve(process.cwd(), filePath);\n\n // Check if file exists\n if (!fs.existsSync(resolved)) {\n res.status(400).json({ error: `File not found: ${filePath}` });\n return;\n }\n\n // Check if already watching\n if (issueFiles.includes(resolved)) {\n res.status(400).json({ error: 'File already being watched' });\n return;\n }\n\n // Add to watched files\n issueFiles.push(resolved);\n watcher.add(resolved);\n\n console.log(`Added source: ${resolved}`);\n res.json({ files: issueFiles, isMultiWorktree: isMultiWorktree() });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // DELETE /api/sources/:index - Remove a watched file\n app.delete('/api/sources/:index', (req, res) => {\n try {\n const index = parseInt(req.params.index, 10);\n if (isNaN(index) || index < 0 || index >= issueFiles.length) {\n res.status(400).json({ error: `Invalid index: ${req.params.index}` });\n return;\n }\n\n // Don't allow removing the last file\n if (issueFiles.length === 1) {\n res.status(400).json({ error: 'Cannot remove the last source file' });\n return;\n }\n\n const removed = issueFiles.splice(index, 1)[0];\n watcher.unwatch(removed);\n\n console.log(`Removed source: ${removed}`);\n res.json({ files: issueFiles, isMultiWorktree: isMultiWorktree() });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // GET /api/worktrees - Detect git worktrees with .pebble/issues.jsonl\n app.get('/api/worktrees', (_req, res) => {\n try {\n const { execSync } = require('child_process');\n let worktreeOutput: string;\n try {\n worktreeOutput = execSync('git worktree list --porcelain', {\n encoding: 'utf-8',\n cwd: process.cwd(),\n });\n } catch {\n // Not a git repo or git not available\n res.json({ worktrees: [] });\n return;\n }\n\n // Parse porcelain output: each worktree block starts with \"worktree <path>\"\n const worktrees: Array<{\n path: string;\n branch: string | null;\n issuesFile: string | null;\n hasIssues: boolean;\n isActive: boolean;\n issueCount: number;\n }> = [];\n\n const blocks = worktreeOutput.trim().split('\\n\\n');\n for (const block of blocks) {\n const lines = block.split('\\n');\n let worktreePath = '';\n let branch: string | null = null;\n\n for (const line of lines) {\n if (line.startsWith('worktree ')) {\n worktreePath = line.slice('worktree '.length);\n } else if (line.startsWith('branch ')) {\n branch = line.slice('branch '.length).replace('refs/heads/', '');\n }\n }\n\n if (worktreePath) {\n const issuesFile = path.join(worktreePath, '.pebble', 'issues.jsonl');\n const hasIssues = fs.existsSync(issuesFile);\n const isActive = issueFiles.includes(issuesFile);\n\n // Count issues if the file exists\n let issueCount = 0;\n if (hasIssues) {\n const events = readEventsFromFile(issuesFile);\n const state = computeState(events);\n issueCount = state.size;\n }\n\n worktrees.push({\n path: worktreePath,\n branch,\n issuesFile: hasIssues ? issuesFile : null,\n hasIssues,\n isActive,\n issueCount,\n });\n }\n }\n\n res.json({ worktrees });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.get('/api/issues', (_req, res) => {\n try {\n // Always read from issueFiles (works for both single and multi-worktree)\n const issues = mergeIssuesFromFiles(issueFiles);\n res.json(issues);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n app.get('/api/events', (_req, res) => {\n try {\n // Merge and deduplicate events from all sources\n const events = mergeEventsFromFiles(issueFiles);\n res.json(events);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // SSE endpoint for real-time updates\n const sseClients = new Set<Response>();\n let eventCounter = 0;\n\n app.get('/api/events/stream', (req, res) => {\n // Set up SSE headers\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.flushHeaders();\n\n // Add client to the set\n sseClients.add(res);\n\n // Send initial connection message with event ID\n eventCounter++;\n res.write(`id: ${eventCounter}\\ndata: {\"type\":\"connected\"}\\n\\n`);\n\n // Remove client on close\n req.on('close', () => {\n sseClients.delete(res);\n });\n });\n\n // Heartbeat to keep connections alive (every 30 seconds)\n const heartbeatInterval = setInterval(() => {\n for (const client of sseClients) {\n client.write(': heartbeat\\n\\n'); // SSE comment, keeps connection alive\n }\n }, 30000);\n\n // File watcher for issues.jsonl file(s)\n // In multi-worktree mode, watch all specified files\n const watcher = chokidar.watch(issueFiles, {\n persistent: true,\n ignoreInitial: true,\n });\n\n watcher.on('change', () => {\n // Broadcast change to all SSE clients with event ID\n eventCounter++;\n const message = JSON.stringify({ type: 'change', timestamp: new Date().toISOString() });\n for (const client of sseClients) {\n client.write(`id: ${eventCounter}\\ndata: ${message}\\n\\n`);\n }\n });\n\n // Graceful shutdown - clear heartbeat and close file watcher\n const shutdown = () => {\n clearInterval(heartbeatInterval);\n watcher.close();\n process.exit(0);\n };\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n\n // POST /api/issues - Create a new issue\n // Multi-worktree: Use ?target=<index> to specify which file to write to\n app.post('/api/issues', (req, res) => {\n try {\n // Determine target file for multi-worktree mode\n let targetFile: string | null = null;\n if (isMultiWorktree() && req.query.target !== undefined) {\n const targetIndex = parseInt(req.query.target as string, 10);\n if (isNaN(targetIndex) || targetIndex < 0 || targetIndex >= issueFiles.length) {\n res.status(400).json({ error: `Invalid target index: ${req.query.target}` });\n return;\n }\n targetFile = issueFiles[targetIndex];\n }\n\n // Get pebbleDir - for multi-worktree with target, derive from target file path\n const pebbleDir = targetFile ? path.dirname(targetFile) : getOrCreatePebbleDir();\n const config = getConfig(pebbleDir);\n const { title, type, priority, description, parent } = req.body;\n\n // Validate required fields\n if (!title || typeof title !== 'string') {\n res.status(400).json({ error: 'Title is required' });\n return;\n }\n\n // Validate type\n const issueType: IssueType = type || 'task';\n if (!ISSUE_TYPES.includes(issueType)) {\n res.status(400).json({ error: `Invalid type. Must be one of: ${ISSUE_TYPES.join(', ')}` });\n return;\n }\n\n // Validate priority\n const issuePriority: Priority = priority ?? 2;\n if (!PRIORITIES.includes(issuePriority)) {\n res.status(400).json({ error: 'Priority must be 0-4' });\n return;\n }\n\n // Validate parent if provided\n let parentReopened: { id: string; title: string } | undefined;\n if (parent) {\n const parentIssue = getIssue(parent);\n if (!parentIssue) {\n res.status(400).json({ error: `Parent issue not found: ${parent}` });\n return;\n }\n if (parentIssue.type === 'verification') {\n res.status(400).json({ error: 'Verification issues cannot be parents' });\n return;\n }\n // Auto-reopen closed parent instead of returning error\n if (parentIssue.status === 'closed') {\n const reopenEvent: ReopenEvent = {\n type: 'reopen',\n issueId: parent,\n timestamp: new Date().toISOString(),\n data: { reason: 'Reopened to add child' },\n };\n appendEvent(reopenEvent, pebbleDir);\n parentReopened = { id: parent, title: parentIssue.title };\n }\n }\n\n const issueId = generateId(config.prefix);\n const timestamp = new Date().toISOString();\n\n const event: CreateEvent = {\n type: 'create',\n issueId,\n timestamp,\n data: {\n title,\n type: issueType,\n priority: issuePriority,\n description,\n parent,\n },\n };\n\n appendEvent(event, pebbleDir);\n\n // Touch parent's updatedAt when child is added\n if (parent) {\n const parentUpdateEvent: UpdateEvent = {\n type: 'update',\n issueId: parent,\n timestamp: new Date().toISOString(),\n data: {},\n };\n appendEvent(parentUpdateEvent, pebbleDir);\n }\n\n const issue = getIssue(issueId);\n const result = parentReopened ? { ...issue, _parentReopened: parentReopened } : issue;\n res.status(201).json(result);\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // ===== Bulk Operations =====\n // These MUST be defined before parameterized routes like /api/issues/:id\n\n // POST /api/issues/bulk/close - Close multiple issues\n app.post('/api/issues/bulk/close', (req, res) => {\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const { ids } = req.body as { ids: string[] };\n\n if (!ids || !Array.isArray(ids) || ids.length === 0) {\n res.status(400).json({ error: 'ids array is required' });\n return;\n }\n\n const results: Array<{ id: string; success: boolean; error?: string }> = [];\n\n for (const rawId of ids) {\n try {\n const issueId = resolveId(rawId);\n const issue = getIssue(issueId);\n if (!issue) {\n results.push({ id: rawId, success: false, error: `Issue not found: ${rawId}` });\n continue;\n }\n\n if (issue.status === 'closed') {\n results.push({ id: issueId, success: true }); // Already closed\n continue;\n }\n\n // Check if issue has open children\n if (hasOpenChildren(issueId)) {\n results.push({ id: issueId, success: false, error: 'Cannot close issue with open children' });\n continue;\n }\n\n // Check for pending verifications\n const pendingVerifications = getVerifications(issueId).filter(v => v.status !== 'closed');\n const timestamp = new Date().toISOString();\n\n if (pendingVerifications.length > 0) {\n // Move to pending_verification instead of closing\n const updateEvent: UpdateEvent = {\n type: 'update',\n issueId,\n timestamp,\n data: { status: 'pending_verification' },\n };\n appendEvent(updateEvent, pebbleDir);\n results.push({\n id: issueId,\n success: true,\n error: `Moved to pending_verification (${pendingVerifications.length} verification(s) pending)`,\n });\n continue;\n }\n\n const event: CloseEvent = {\n issueId,\n timestamp,\n type: 'close',\n data: { reason: 'Bulk close' },\n };\n\n appendEvent(event, pebbleDir);\n results.push({ id: issueId, success: true });\n } catch (error) {\n results.push({ id: rawId, success: false, error: (error as Error).message });\n }\n }\n\n res.json({ results });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/bulk/update - Update multiple issues\n app.post('/api/issues/bulk/update', (req, res) => {\n try {\n const pebbleDir = getOrCreatePebbleDir();\n const { ids, updates } = req.body as {\n ids: string[];\n updates: { status?: string; priority?: number };\n };\n\n if (!ids || !Array.isArray(ids) || ids.length === 0) {\n res.status(400).json({ error: 'ids array is required' });\n return;\n }\n\n if (!updates || Object.keys(updates).length === 0) {\n res.status(400).json({ error: 'updates object is required' });\n return;\n }\n\n // Validate status if provided\n if (updates.status) {\n const validStatuses = ['open', 'in_progress', 'blocked', 'pending_verification'];\n if (!validStatuses.includes(updates.status)) {\n res.status(400).json({\n error: `Invalid status: ${updates.status}. Use close endpoint to close issues.`,\n });\n return;\n }\n }\n\n // Validate priority if provided\n if (updates.priority !== undefined) {\n if (typeof updates.priority !== 'number' || updates.priority < 0 || updates.priority > 4) {\n res.status(400).json({ error: 'Priority must be 0-4' });\n return;\n }\n }\n\n const results: Array<{ id: string; success: boolean; error?: string }> = [];\n\n for (const rawId of ids) {\n try {\n const issueId = resolveId(rawId);\n const issue = getIssue(issueId);\n if (!issue) {\n results.push({ id: rawId, success: false, error: `Issue not found: ${rawId}` });\n continue;\n }\n\n const event: UpdateEvent = {\n issueId,\n timestamp: new Date().toISOString(),\n type: 'update',\n data: {\n ...(updates.status && { status: updates.status as 'open' | 'in_progress' | 'blocked' }),\n ...(updates.priority !== undefined && { priority: updates.priority as 0 | 1 | 2 | 3 | 4 }),\n },\n };\n\n appendEvent(event, pebbleDir);\n results.push({ id: issueId, success: true });\n } catch (error) {\n results.push({ id: rawId, success: false, error: (error as Error).message });\n }\n }\n\n res.json({ results });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // PUT /api/issues/:id - Update an issue\n app.put('/api/issues/:id', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n const { title, type, priority, status, description, parent, relatedTo } = req.body;\n const updates: UpdateEvent['data'] = {};\n\n // Validate and collect updates\n if (title !== undefined) {\n if (typeof title !== 'string' || title.trim() === '') {\n res.status(400).json({ error: 'Title cannot be empty' });\n return;\n }\n updates.title = title;\n }\n\n if (type !== undefined) {\n if (!ISSUE_TYPES.includes(type)) {\n res.status(400).json({ error: `Invalid type. Must be one of: ${ISSUE_TYPES.join(', ')}` });\n return;\n }\n updates.type = type;\n }\n\n if (priority !== undefined) {\n if (!PRIORITIES.includes(priority)) {\n res.status(400).json({ error: 'Priority must be 0-4' });\n return;\n }\n updates.priority = priority;\n }\n\n if (status !== undefined) {\n if (!STATUSES.includes(status)) {\n res.status(400).json({ error: `Invalid status. Must be one of: ${STATUSES.join(', ')}` });\n return;\n }\n updates.status = status;\n }\n\n if (description !== undefined) {\n updates.description = description;\n }\n\n if (parent !== undefined) {\n if (parent !== null) {\n // In multi-worktree mode, check parent in merged sources\n if (isMultiWorktree()) {\n const parentFound = findIssueInSources(parent, issueFiles);\n if (!parentFound) {\n res.status(400).json({ error: `Parent issue not found: ${parent}` });\n return;\n }\n if (parentFound.issue.type === 'verification') {\n res.status(400).json({ error: 'Verification issues cannot be parents' });\n return;\n }\n } else {\n const parentIssue = getIssue(parent);\n if (!parentIssue) {\n res.status(400).json({ error: `Parent issue not found: ${parent}` });\n return;\n }\n if (parentIssue.type === 'verification') {\n res.status(400).json({ error: 'Verification issues cannot be parents' });\n return;\n }\n }\n }\n updates.parent = parent;\n }\n\n if (relatedTo !== undefined) {\n if (!Array.isArray(relatedTo)) {\n res.status(400).json({ error: 'relatedTo must be an array' });\n return;\n }\n // Validate all related IDs exist\n for (const relatedId of relatedTo) {\n if (isMultiWorktree()) {\n const found = findIssueInSources(relatedId, issueFiles);\n if (!found) {\n res.status(400).json({ error: `Related issue not found: ${relatedId}` });\n return;\n }\n } else {\n const relatedIssue = getIssue(relatedId);\n if (!relatedIssue) {\n res.status(400).json({ error: `Related issue not found: ${relatedId}` });\n return;\n }\n }\n }\n updates.relatedTo = relatedTo;\n }\n\n if (Object.keys(updates).length === 0) {\n res.status(400).json({ error: 'No valid updates provided' });\n return;\n }\n\n const timestamp = new Date().toISOString();\n const event: UpdateEvent = {\n type: 'update',\n issueId,\n timestamp,\n data: updates,\n };\n\n appendEventToFile(event, targetFile);\n\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || { ...issue, ...updates, updatedAt: timestamp });\n } else {\n res.json(getIssue(issueId));\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/:id/close - Close an issue\n app.post('/api/issues/:id/close', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n if (issue.status === 'closed') {\n res.status(400).json({ error: 'Issue is already closed' });\n return;\n }\n\n // Check if issue has open children (single-file mode only)\n if (!isMultiWorktree() && hasOpenChildren(issueId)) {\n res.status(400).json({ error: 'Cannot close issue with open children' });\n return;\n }\n\n const { reason } = req.body;\n const timestamp = new Date().toISOString();\n\n // Check for pending verifications\n let pendingVerifications: Issue[] = [];\n if (isMultiWorktree()) {\n // In multi-worktree mode, find verifications across all sources\n const allIssues = mergeIssuesFromFiles(issueFiles);\n pendingVerifications = allIssues.filter(\n i => i.verifies === issueId && i.status !== 'closed'\n );\n } else {\n pendingVerifications = getVerifications(issueId).filter(v => v.status !== 'closed');\n }\n\n if (pendingVerifications.length > 0) {\n // Move to pending_verification instead of closed\n const updateEvent: UpdateEvent = {\n type: 'update',\n issueId,\n timestamp,\n data: { status: 'pending_verification' },\n };\n appendEventToFile(updateEvent, targetFile);\n\n // Return updated issue with info about pending verifications\n const updatedIssue = { ...issue, status: 'pending_verification' as const, updatedAt: timestamp };\n res.json({\n ...updatedIssue,\n _pendingVerifications: pendingVerifications.map(v => ({ id: v.id, title: v.title })),\n });\n return;\n }\n\n const event: CloseEvent = {\n type: 'close',\n issueId,\n timestamp,\n data: { reason },\n };\n\n appendEventToFile(event, targetFile);\n\n // Check if this was a verification issue and auto-close target if all verifications done\n let autoClosed: { id: string; title: string } | undefined;\n if (issue.verifies) {\n let targetIssue: Issue | undefined;\n let targetVerifications: Issue[] = [];\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(issue.verifies, issueFiles);\n if (found) {\n targetIssue = found.issue;\n const allIssues = mergeIssuesFromFiles(issueFiles);\n targetVerifications = allIssues.filter(\n i => i.verifies === issue.verifies && i.status !== 'closed'\n );\n }\n } else {\n targetIssue = getIssue(issue.verifies);\n targetVerifications = getVerifications(issue.verifies).filter(v => v.status !== 'closed');\n }\n\n if (targetIssue && targetIssue.status === 'pending_verification' && targetVerifications.length === 0) {\n // All verifications closed - auto-close the target\n const autoCloseEvent: CloseEvent = {\n type: 'close',\n issueId: issue.verifies,\n timestamp: new Date().toISOString(),\n data: { reason: 'All verifications completed' },\n };\n\n if (isMultiWorktree()) {\n const targetFound = findIssueInSources(issue.verifies, issueFiles);\n if (targetFound) {\n appendEventToFile(autoCloseEvent, targetFound.targetFile);\n }\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n appendEventToFile(autoCloseEvent, path.join(pebbleDir, 'issues.jsonl'));\n }\n\n autoClosed = { id: targetIssue.id, title: targetIssue.title };\n }\n }\n\n // Return updated issue\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n const result = updated?.issue || { ...issue, status: 'closed', updatedAt: timestamp };\n res.json(autoClosed ? { ...result, _autoClosed: autoClosed } : result);\n } else {\n const result = getIssue(issueId);\n res.json(autoClosed ? { ...result, _autoClosed: autoClosed } : result);\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/:id/reopen - Reopen an issue\n app.post('/api/issues/:id/reopen', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n if (issue.status !== 'closed') {\n res.status(400).json({ error: 'Issue is not closed' });\n return;\n }\n\n const { reason } = req.body;\n const timestamp = new Date().toISOString();\n\n const event: ReopenEvent = {\n type: 'reopen',\n issueId,\n timestamp,\n data: { reason },\n };\n\n appendEventToFile(event, targetFile);\n\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || { ...issue, status: 'open', updatedAt: timestamp });\n } else {\n res.json(getIssue(issueId));\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/:id/delete - Soft delete an issue (with cascade for epics)\n app.post('/api/issues/:id/delete', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n if (issue.deleted) {\n res.status(400).json({ error: 'Issue is already deleted' });\n return;\n }\n\n const { reason } = req.body;\n const timestamp = new Date().toISOString();\n const state = getComputedState();\n\n // Collect all issues to delete (including cascaded)\n const toDelete: Array<{ id: string; cascade: boolean }> = [];\n const alreadyQueued = new Set<string>();\n\n // Add the main issue\n toDelete.push({ id: issueId, cascade: false });\n alreadyQueued.add(issueId);\n\n // Get descendants for cascade delete\n const descendants = getDescendants(issueId, state);\n for (const desc of descendants) {\n if (!alreadyQueued.has(desc.id) && !desc.deleted) {\n toDelete.push({ id: desc.id, cascade: true });\n alreadyQueued.add(desc.id);\n }\n }\n\n // Get verification issues that verify this issue - cascade delete them too\n const verifications = getVerifications(issueId);\n for (const v of verifications) {\n if (!alreadyQueued.has(v.id) && !v.deleted) {\n toDelete.push({ id: v.id, cascade: true });\n alreadyQueued.add(v.id);\n }\n }\n\n // Helper to clean up references\n const cleanupReferences = (deletedId: string) => {\n for (const [id, iss] of state) {\n if (id === deletedId || iss.deleted) continue;\n\n const updates: Partial<{\n blockedBy: string[];\n relatedTo: string[];\n parent: string;\n }> = {};\n\n if (iss.blockedBy.includes(deletedId)) {\n updates.blockedBy = iss.blockedBy.filter((bid) => bid !== deletedId);\n }\n if (iss.relatedTo.includes(deletedId)) {\n updates.relatedTo = iss.relatedTo.filter((rid) => rid !== deletedId);\n }\n if (iss.parent === deletedId) {\n updates.parent = '';\n }\n\n if (Object.keys(updates).length > 0) {\n const updateEvent: UpdateEvent = {\n type: 'update',\n issueId: id,\n timestamp,\n data: updates,\n };\n appendEventToFile(updateEvent, targetFile);\n }\n }\n };\n\n // Delete all collected issues\n for (const { id, cascade } of toDelete) {\n const iss = state.get(id);\n if (!iss) continue;\n\n cleanupReferences(id);\n\n const deleteEvent: DeleteEvent = {\n type: 'delete',\n issueId: id,\n timestamp,\n data: {\n reason,\n cascade: cascade || undefined,\n previousStatus: iss.status,\n },\n };\n appendEventToFile(deleteEvent, targetFile);\n }\n\n res.json({\n deleted: toDelete,\n });\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/:id/restore - Restore a deleted issue\n app.post('/api/issues/:id/restore', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n if (!issue.deleted) {\n res.status(400).json({ error: 'Issue is not deleted' });\n return;\n }\n\n const { reason } = req.body;\n const timestamp = new Date().toISOString();\n\n const event: RestoreEvent = {\n type: 'restore',\n issueId,\n timestamp,\n data: { reason },\n };\n\n appendEventToFile(event, targetFile);\n\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || { ...issue, deleted: false, deletedAt: undefined, updatedAt: timestamp });\n } else {\n res.json(getIssue(issueId));\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/:id/comments - Add a comment\n app.post('/api/issues/:id/comments', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n const { text, author } = req.body;\n\n if (!text || typeof text !== 'string' || text.trim() === '') {\n res.status(400).json({ error: 'Comment text is required' });\n return;\n }\n\n const timestamp = new Date().toISOString();\n\n const event: CommentEvent = {\n type: 'comment',\n issueId,\n timestamp,\n data: {\n text,\n timestamp,\n author,\n },\n };\n\n appendEventToFile(event, targetFile);\n\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || issue);\n } else {\n res.json(getIssue(issueId));\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // POST /api/issues/:id/deps - Add a dependency\n app.post('/api/issues/:id/deps', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n const { blockerId } = req.body;\n\n if (!blockerId) {\n res.status(400).json({ error: 'blockerId is required' });\n return;\n }\n\n // Resolve blocker ID (check in multi-worktree sources if needed)\n let resolvedBlockerId: string;\n if (isMultiWorktree()) {\n const blockerFound = findIssueInSources(blockerId, issueFiles);\n if (!blockerFound) {\n res.status(404).json({ error: `Blocker issue not found: ${blockerId}` });\n return;\n }\n resolvedBlockerId = blockerFound.issue.id;\n } else {\n resolvedBlockerId = resolveId(blockerId);\n const blockerIssue = getIssue(resolvedBlockerId);\n if (!blockerIssue) {\n res.status(404).json({ error: `Blocker issue not found: ${blockerId}` });\n return;\n }\n }\n\n // Check if already a dependency\n if (issue.blockedBy.includes(resolvedBlockerId)) {\n res.status(400).json({ error: 'Dependency already exists' });\n return;\n }\n\n // Check for cycles (only in single-file mode, cycle detection uses local state)\n if (!isMultiWorktree() && detectCycle(issueId, resolvedBlockerId)) {\n res.status(400).json({ error: 'Adding this dependency would create a cycle' });\n return;\n }\n\n const timestamp = new Date().toISOString();\n const event: UpdateEvent = {\n type: 'update',\n issueId,\n timestamp,\n data: {\n blockedBy: [...issue.blockedBy, resolvedBlockerId],\n },\n };\n\n appendEventToFile(event, targetFile);\n\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || { ...issue, blockedBy: [...issue.blockedBy, resolvedBlockerId], updatedAt: timestamp });\n } else {\n res.json(getIssue(issueId));\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // DELETE /api/issues/:id/deps/:blockerId - Remove a dependency\n app.delete('/api/issues/:id/deps/:blockerId', (req, res) => {\n try {\n let issue: Issue;\n let issueId: string;\n let targetFile: string;\n\n if (isMultiWorktree()) {\n const found = findIssueInSources(req.params.id, issueFiles);\n if (!found) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = found.issue;\n issueId = issue.id;\n targetFile = found.targetFile;\n } else {\n const pebbleDir = getOrCreatePebbleDir();\n issueId = resolveId(req.params.id);\n const localIssue = getIssue(issueId);\n if (!localIssue) {\n res.status(404).json({ error: `Issue not found: ${req.params.id}` });\n return;\n }\n issue = localIssue;\n targetFile = path.join(pebbleDir, 'issues.jsonl');\n }\n\n // Resolve blocker ID (check in multi-worktree sources if needed)\n let resolvedBlockerId: string;\n if (isMultiWorktree()) {\n const blockerFound = findIssueInSources(req.params.blockerId, issueFiles);\n if (blockerFound) {\n resolvedBlockerId = blockerFound.issue.id;\n } else {\n // Blocker might not exist anymore, try direct match\n resolvedBlockerId = req.params.blockerId;\n }\n } else {\n resolvedBlockerId = resolveId(req.params.blockerId);\n }\n\n if (!issue.blockedBy.includes(resolvedBlockerId)) {\n res.status(400).json({ error: 'Dependency does not exist' });\n return;\n }\n\n const timestamp = new Date().toISOString();\n const newBlockedBy = issue.blockedBy.filter((id) => id !== resolvedBlockerId);\n const event: UpdateEvent = {\n type: 'update',\n issueId,\n timestamp,\n data: {\n blockedBy: newBlockedBy,\n },\n };\n\n appendEventToFile(event, targetFile);\n\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || { ...issue, blockedBy: newBlockedBy, updatedAt: timestamp });\n } else {\n res.json(getIssue(issueId));\n }\n } catch (error) {\n res.status(500).json({ error: (error as Error).message });\n }\n });\n\n // Serve static files from the bundled UI\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const uiPath = path.resolve(__dirname, '../ui');\n\n app.use(express.static(uiPath));\n\n // SPA fallback\n app.get('*', (_req, res) => {\n res.sendFile(path.join(uiPath, 'index.html'));\n });\n\n // Start server with port fallback\n const requestedPort = parseInt(options.port, 10);\n const actualPort = await findAvailablePort(requestedPort);\n\n if (actualPort !== requestedPort) {\n console.log(`Port ${requestedPort} is busy, using ${actualPort} instead`);\n }\n\n app.listen(actualPort, () => {\n const url = `http://localhost:${actualPort}`;\n console.log(`Pebble UI running at ${url}`);\n\n if (options.open !== false) {\n open(url);\n }\n });\n } catch (error) {\n outputError(error as Error, pretty);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as readline from 'readline';\nimport type { IssueType, Priority, Status, CreateEvent, UpdateEvent, CloseEvent, CommentEvent } from '../../shared/types.js';\nimport { ensurePebbleDir, appendEvent } from '../lib/storage.js';\nimport { outputError, formatJson } from '../lib/output.js';\nimport { derivePrefix } from '../lib/id.js';\nimport * as path from 'path';\n\n// Beads issue format\ninterface BeadsDependency {\n issue_id: string;\n depends_on_id: string;\n type: 'blocks' | 'parent-child' | 'related' | 'discovered-from';\n created_at: string;\n created_by?: string;\n}\n\ninterface BeadsIssue {\n id: string;\n title: string;\n description?: string;\n status: string;\n priority: number;\n issue_type: string;\n assignee?: string;\n created_at: string;\n created_by?: string;\n updated_at: string;\n closed_at?: string;\n close_reason?: string;\n dependencies?: BeadsDependency[];\n}\n\nexport function importCommand(program: Command): void {\n program\n .command('import <file>')\n .description('Import issues from a Beads issues.jsonl file')\n .option('--dry-run', 'Show what would be imported without writing')\n .option('--prefix <prefix>', 'Override the ID prefix (default: derive from folder name)')\n .action(async (file: string, options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Validate file exists\n if (!fs.existsSync(file)) {\n throw new Error(`File not found: ${file}`);\n }\n\n // Read and parse Beads issues\n const beadsIssues = await parseBeadsFile(file);\n\n if (beadsIssues.length === 0) {\n console.log(pretty ? 'No issues found in file.' : formatJson({ imported: 0 }));\n return;\n }\n\n // Determine prefix\n const prefix = options.prefix ?? derivePrefix(path.basename(process.cwd()));\n\n // Convert to pebble events\n const { events, idMap, stats } = convertToPebbleEvents(beadsIssues, prefix);\n\n if (options.dryRun) {\n if (pretty) {\n console.log('Dry run - would import:');\n console.log(` ${stats.created} issues`);\n console.log(` ${stats.closed} closed issues`);\n console.log(` ${stats.dependencies} block dependencies`);\n console.log(` ${stats.parentChild} parent-child relationships`);\n console.log(` ${stats.comments} comments`);\n console.log('\\nID mapping (beads -> pebble):');\n for (const [beadsId, pebbleId] of idMap) {\n console.log(` ${beadsId} -> ${pebbleId}`);\n }\n } else {\n console.log(formatJson({\n dryRun: true,\n stats,\n idMap: Object.fromEntries(idMap),\n }));\n }\n return;\n }\n\n // Ensure pebble directory exists\n const pebbleDir = ensurePebbleDir();\n\n // Write events\n for (const event of events) {\n appendEvent(event, pebbleDir);\n }\n\n if (pretty) {\n console.log(`Imported ${stats.created} issues from ${file}`);\n console.log(` ${stats.closed} closed`);\n console.log(` ${stats.dependencies} block dependencies`);\n console.log(` ${stats.parentChild} parent-child relationships`);\n console.log(` ${stats.comments} comments`);\n } else {\n console.log(formatJson({\n imported: stats.created,\n closed: stats.closed,\n dependencies: stats.dependencies,\n parentChild: stats.parentChild,\n comments: stats.comments,\n idMap: Object.fromEntries(idMap),\n }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n\nasync function parseBeadsFile(filePath: string): Promise<BeadsIssue[]> {\n const issues: BeadsIssue[] = [];\n\n const fileStream = fs.createReadStream(filePath);\n const rl = readline.createInterface({\n input: fileStream,\n crlfDelay: Infinity,\n });\n\n for await (const line of rl) {\n if (line.trim()) {\n try {\n const issue = JSON.parse(line) as BeadsIssue;\n issues.push(issue);\n } catch {\n // Skip malformed lines\n }\n }\n }\n\n return issues;\n}\n\nfunction convertToPebbleEvents(\n beadsIssues: BeadsIssue[],\n prefix: string\n): {\n events: (CreateEvent | UpdateEvent | CloseEvent | CommentEvent)[];\n idMap: Map<string, string>;\n stats: { created: number; closed: number; dependencies: number; comments: number; parentChild: number };\n} {\n const events: (CreateEvent | UpdateEvent | CloseEvent | CommentEvent)[] = [];\n const idMap = new Map<string, string>();\n const issueTypeMap = new Map<string, string>(); // beadsId -> issue_type\n const stats = { created: 0, closed: 0, dependencies: 0, comments: 0, parentChild: 0 };\n\n // First pass: create ID mapping and type mapping\n for (const issue of beadsIssues) {\n const suffix = generateSuffix();\n const pebbleId = `${prefix}-${suffix}`;\n idMap.set(issue.id, pebbleId);\n issueTypeMap.set(issue.id, issue.issue_type);\n }\n\n // Second pass: create events\n for (const issue of beadsIssues) {\n const pebbleId = idMap.get(issue.id)!;\n\n // Map type (feature, chore -> task)\n let type: IssueType = 'task';\n if (issue.issue_type === 'bug') {\n type = 'bug';\n } else if (issue.issue_type === 'epic') {\n type = 'epic';\n }\n\n // Map priority (clamp to 0-4)\n const priority = Math.max(0, Math.min(4, issue.priority)) as Priority;\n\n // Extract parent from dependencies\n let parent: string | undefined;\n const blockedBy: string[] = [];\n\n if (issue.dependencies) {\n for (const dep of issue.dependencies) {\n if (dep.type === 'parent-child') {\n // Beads stores parent-child on BOTH sides (child->parent AND parent->child)\n // Only process when depends_on_id points to an epic (this issue is a child of that epic)\n // Skip when depends_on_id points to a non-epic (that's the reverse relationship)\n const targetType = issueTypeMap.get(dep.depends_on_id);\n if (targetType === 'epic') {\n const parentPebbleId = idMap.get(dep.depends_on_id);\n if (parentPebbleId) {\n parent = parentPebbleId;\n stats.parentChild++;\n }\n }\n // If targetType is not 'epic', skip - handled when processing the child issue\n } else if (dep.type === 'blocks' && dep.depends_on_id !== issue.id) {\n // This issue is blocked by depends_on_id\n const blockerPebbleId = idMap.get(dep.depends_on_id);\n if (blockerPebbleId) {\n blockedBy.push(blockerPebbleId);\n stats.dependencies++;\n }\n }\n }\n }\n\n // Create event\n const createEvent: CreateEvent = {\n type: 'create',\n issueId: pebbleId,\n timestamp: issue.created_at,\n data: {\n title: issue.title,\n type,\n priority,\n description: issue.description,\n parent,\n },\n };\n events.push(createEvent);\n stats.created++;\n\n // Add blockedBy if any\n if (blockedBy.length > 0) {\n const updateEvent: UpdateEvent = {\n type: 'update',\n issueId: pebbleId,\n timestamp: issue.created_at,\n data: {\n blockedBy,\n },\n };\n events.push(updateEvent);\n }\n\n // Map status (deferred -> open, blocked stays blocked)\n let status: Status = 'open';\n if (issue.status === 'in_progress') {\n status = 'in_progress';\n } else if (issue.status === 'blocked') {\n status = 'blocked';\n } else if (issue.status === 'closed') {\n status = 'closed';\n }\n // 'deferred' and 'open' both map to 'open'\n\n // Update status if not open\n if (status !== 'open' && status !== 'closed') {\n const statusEvent: UpdateEvent = {\n type: 'update',\n issueId: pebbleId,\n timestamp: issue.updated_at,\n data: {\n status,\n },\n };\n events.push(statusEvent);\n }\n\n // Close event if closed\n if (status === 'closed') {\n const closeEvent: CloseEvent = {\n type: 'close',\n issueId: pebbleId,\n timestamp: issue.closed_at ?? issue.updated_at,\n data: {\n reason: issue.close_reason,\n },\n };\n events.push(closeEvent);\n stats.closed++;\n }\n }\n\n return { events, idMap, stats };\n}\n\nfunction generateSuffix(): string {\n const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';\n let result = '';\n for (let i = 0; i < 6; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n","import { Command } from 'commander';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { readEventsFromFile } from '../lib/storage.js';\nimport { computeState } from '../lib/state.js';\nimport type { Issue, IssueEvent } from '../../shared/types.js';\n\ninterface MergedIssue extends Issue {\n _sources: string[];\n}\n\n/**\n * Merge events from multiple files, keeping all events sorted by timestamp.\n * Deduplicates events using key: issueId-timestamp-type\n */\nfunction mergeEvents(filePaths: string[]): IssueEvent[] {\n const seen = new Map<string, IssueEvent>();\n\n for (const filePath of filePaths) {\n const events = readEventsFromFile(filePath);\n for (const event of events) {\n // Create a unique key for deduplication\n const key = `${event.issueId}-${event.timestamp}-${event.type}`;\n if (!seen.has(key)) {\n seen.set(key, event);\n }\n }\n }\n\n // Get all unique events and sort by timestamp\n const allEvents = Array.from(seen.values());\n allEvents.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());\n\n return allEvents;\n}\n\n/**\n * Merge issues from multiple files.\n * Same ID = same issue: keep the version with the latest updatedAt.\n */\nfunction mergeIssues(filePaths: string[]): MergedIssue[] {\n const merged = new Map<string, { issue: Issue; sources: Set<string> }>();\n\n for (const filePath of filePaths) {\n const events = readEventsFromFile(filePath);\n const state = computeState(events);\n\n for (const [id, issue] of state) {\n const existing = merged.get(id);\n if (!existing) {\n merged.set(id, { issue, sources: new Set([filePath]) });\n } else {\n existing.sources.add(filePath);\n if (new Date(issue.updatedAt) > new Date(existing.issue.updatedAt)) {\n merged.set(id, { issue, sources: existing.sources });\n }\n }\n }\n }\n\n return Array.from(merged.values()).map(({ issue, sources }) => ({\n ...issue,\n _sources: Array.from(sources),\n }));\n}\n\nexport function mergeCommand(program: Command): void {\n program\n .command('merge <files...>')\n .description('Merge multiple issues.jsonl files into one')\n .option('-o, --output <file>', 'Output file (default: stdout)')\n .option('--state', 'Output computed state instead of raw events')\n .option('--show-sources', 'Include _sources field (only with --state)')\n .action((files: string[], options) => {\n const pretty = program.opts().pretty ?? false;\n\n // Resolve and validate file paths\n const filePaths: string[] = [];\n for (const file of files) {\n const resolved = path.resolve(process.cwd(), file);\n if (!fs.existsSync(resolved)) {\n console.error(`Error: File not found: ${file}`);\n process.exit(1);\n }\n filePaths.push(resolved);\n }\n\n if (filePaths.length < 2) {\n console.error('Error: At least 2 files required for merge');\n process.exit(1);\n }\n\n try {\n let output: string;\n\n if (options.state) {\n // Output computed state as JSON array\n const issues = mergeIssues(filePaths);\n\n // Remove _sources unless requested\n const outputIssues = options.showSources\n ? issues\n : issues.map(({ _sources, ...issue }) => issue);\n\n output = pretty\n ? JSON.stringify(outputIssues, null, 2)\n : JSON.stringify(outputIssues);\n } else {\n // Default: output merged events as JSONL (preserves history)\n const events = mergeEvents(filePaths);\n output = events.map((e) => JSON.stringify(e)).join('\\n');\n }\n\n if (options.output) {\n fs.writeFileSync(options.output, output + '\\n', 'utf-8');\n console.error(`Merged ${filePaths.length} files to ${options.output}`);\n } else {\n console.log(output);\n }\n } catch (error) {\n console.error(`Error: ${(error as Error).message}`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { Status, CommentEvent } from '../../shared/types.js';\nimport { STATUSES, STATUS_LABELS } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, readEvents } from '../lib/storage.js';\nimport { getIssues, getChildren, getIssue, getVerifications } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\nimport { formatRelativeTime } from '../../shared/time.js';\n\ninterface ChildCounts {\n total: number;\n done: number;\n pending_verification: number;\n in_progress: number;\n open: number;\n blocked: number;\n}\n\ninterface EpicSummary {\n id: string;\n title: string;\n description?: string;\n status: Status;\n createdAt: string;\n updatedAt: string;\n parent?: {\n id: string;\n title: string;\n };\n children: ChildCounts;\n verifications: {\n total: number;\n done: number;\n };\n}\n\nfunction countChildren(epicId: string): ChildCounts {\n const children = getChildren(epicId);\n return {\n total: children.length,\n done: children.filter((c) => c.status === 'closed').length,\n pending_verification: children.filter((c) => c.status === 'pending_verification').length,\n in_progress: children.filter((c) => c.status === 'in_progress').length,\n open: children.filter((c) => c.status === 'open').length,\n blocked: children.filter((c) => c.status === 'blocked').length,\n };\n}\n\nfunction countVerifications(epicId: string): { total: number; done: number } {\n const children = getChildren(epicId);\n let total = 0;\n let done = 0;\n\n for (const child of children) {\n const verifications = getVerifications(child.id);\n total += verifications.length;\n done += verifications.filter((v) => v.status === 'closed').length;\n }\n\n return { total, done };\n}\n\ninterface InProgressIssue {\n id: string;\n title: string;\n type: string;\n createdAt: string;\n updatedAt: string;\n lastSource?: string;\n parent?: { id: string; title: string };\n comments: Array<{ text: string; timestamp: string; source?: string }>;\n}\n\ninterface ClosedIssue {\n id: string;\n title: string;\n type: string;\n closedAt: string;\n lastSource?: string;\n parent?: { id: string; title: string };\n}\n\nfunction getIssueComments(issueId: string): Array<{ text: string; timestamp: string; source?: string }> {\n const events = readEvents();\n return events\n .filter((e): e is CommentEvent => e.type === 'comment' && e.issueId === issueId)\n .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())\n .map((e) => ({ text: e.data.text, timestamp: e.timestamp, source: e.source }));\n}\n\nfunction formatInProgressPretty(issues: InProgressIssue[]): string {\n if (issues.length === 0) return '';\n\n const lines: string[] = [];\n lines.push(`## In Progress (${issues.length})`);\n lines.push('');\n\n for (const issue of issues) {\n lines.push(`▶ ${issue.id}: ${issue.title} [${issue.type}]`);\n lines.push(` Updated: ${formatRelativeTime(issue.updatedAt)}${issue.lastSource ? ` | Source: ${issue.lastSource}` : ''}`);\n if (issue.parent) {\n lines.push(` Parent: ${issue.parent.title}`);\n }\n if (issue.comments.length > 0) {\n const recentComments = issue.comments.slice(0, 3);\n for (const comment of recentComments) {\n const truncated = comment.text.length > 100 ? comment.text.substring(0, 100) + '...' : comment.text;\n lines.push(` • ${formatRelativeTime(comment.timestamp)}: ${truncated.replace(/\\n/g, ' ')}`);\n }\n if (issue.comments.length > 3) {\n lines.push(` (${issue.comments.length - 3} more comment${issue.comments.length - 3 === 1 ? '' : 's'})`);\n }\n }\n lines.push('');\n }\n return lines.join('\\n');\n}\n\nfunction formatClosedIssuesPretty(issues: ClosedIssue[]): string {\n if (issues.length === 0) return '';\n\n const lines: string[] = [];\n lines.push(`## Recently Closed (${issues.length})`);\n lines.push('');\n\n for (const issue of issues) {\n lines.push(`✓ ${issue.id}: ${issue.title} [${issue.type}]`);\n lines.push(` Closed: ${formatRelativeTime(issue.closedAt)}${issue.lastSource ? ` | Source: ${issue.lastSource}` : ''}`);\n if (issue.parent) {\n lines.push(` Parent: ${issue.parent.title}`);\n }\n lines.push('');\n }\n return lines.join('\\n');\n}\n\nfunction formatSummaryPretty(summaries: EpicSummary[], sectionHeader: string): string {\n if (summaries.length === 0) {\n return 'No epics found.';\n }\n\n const lines: string[] = [];\n\n // Section header\n lines.push(`## ${sectionHeader} (${summaries.length})`);\n lines.push('');\n\n for (const summary of summaries) {\n const { children, verifications } = summary;\n\n // Epic line: ID: Title\n lines.push(`${summary.id}: ${summary.title}`);\n\n // Timestamps\n lines.push(` Created: ${formatRelativeTime(summary.createdAt)} | Updated: ${formatRelativeTime(summary.updatedAt)}`);\n\n // Counts\n const pendingStr = children.pending_verification > 0 ? ` (${children.pending_verification} pending verification)` : '';\n const issueCount = `Issues: ${children.done}/${children.total} done${pendingStr}`;\n const verifCount = `Verifications: ${verifications.done}/${verifications.total} done`;\n lines.push(` ${issueCount} | ${verifCount}`);\n\n // Parent if exists\n if (summary.parent) {\n lines.push(` Parent: ${summary.parent.id} (${summary.parent.title})`);\n }\n\n // Full description (no trimming)\n if (summary.description) {\n lines.push('');\n lines.push(` ${summary.description}`);\n }\n\n // Command hint\n lines.push('');\n lines.push(` Run \\`pb list --parent ${summary.id}\\` to see all issues.`);\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nexport function summaryCommand(program: Command): void {\n program\n .command('summary')\n .description('Show epic summary with child completion status')\n .option('--status <status>', 'Filter epics by specific status')\n .option('--limit <n>', 'Max epics to return per section', '10')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n getOrCreatePebbleDir();\n\n // Get all epics\n const allEpics = getIssues({ type: 'epic' });\n\n // Helper to build summary for an epic\n const buildSummary = (epic: typeof allEpics[0]): EpicSummary => {\n const summary: EpicSummary = {\n id: epic.id,\n title: epic.title,\n description: epic.description,\n status: epic.status,\n createdAt: epic.createdAt,\n updatedAt: epic.updatedAt,\n children: countChildren(epic.id),\n verifications: countVerifications(epic.id),\n };\n\n if (epic.parent) {\n const parentIssue = getIssue(epic.parent);\n if (parentIssue) {\n summary.parent = {\n id: parentIssue.id,\n title: parentIssue.title,\n };\n }\n }\n\n return summary;\n };\n\n const limit = parseInt(options.limit, 10);\n\n // If filtering by specific status, show only that status\n if (options.status !== undefined) {\n const status = options.status as Status;\n if (!STATUSES.includes(status)) {\n throw new Error(`Invalid status: ${status}. Must be one of: ${STATUSES.join(', ')}`);\n }\n\n let epics = allEpics.filter((e) => e.status === status);\n\n // Sort by createdAt descending (newest first)\n epics.sort((a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n\n // Apply limit\n if (limit > 0) {\n epics = epics.slice(0, limit);\n }\n\n const summaries = epics.map(buildSummary);\n\n if (pretty) {\n console.log(formatSummaryPretty(summaries, `${STATUS_LABELS[status]} Epics`));\n } else {\n console.log(formatJson(summaries));\n }\n return;\n }\n\n // Get in_progress issues with their comments\n const inProgressIssues = getIssues({ status: 'in_progress' });\n inProgressIssues.sort((a, b) =>\n new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()\n );\n\n const inProgressSummaries: InProgressIssue[] = inProgressIssues.map((issue) => {\n const summary: InProgressIssue = {\n id: issue.id,\n title: issue.title,\n type: issue.type,\n createdAt: issue.createdAt,\n updatedAt: issue.updatedAt,\n lastSource: issue.lastSource,\n comments: getIssueComments(issue.id),\n };\n if (issue.parent) {\n const parentIssue = getIssue(issue.parent, true);\n if (parentIssue) {\n summary.parent = { id: parentIssue.id, title: parentIssue.title };\n }\n }\n return summary;\n });\n\n // Default: show open epics + recently closed (last 72h)\n const openEpics = allEpics.filter((e) => e.status !== 'closed');\n\n // Filter closed epics to last 72 hours (using updatedAt as proxy for close time)\n const seventyTwoHoursAgo = Date.now() - (72 * 60 * 60 * 1000);\n const closedEpics = allEpics.filter((e) =>\n e.status === 'closed' &&\n new Date(e.updatedAt).getTime() > seventyTwoHoursAgo\n );\n\n // Sort both by createdAt descending\n openEpics.sort((a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n closedEpics.sort((a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n );\n\n // Apply limit to each section\n const limitedOpen = limit > 0 ? openEpics.slice(0, limit) : openEpics;\n const limitedClosed = limit > 0 ? closedEpics.slice(0, limit) : closedEpics;\n\n const openSummaries = limitedOpen.map(buildSummary);\n const closedSummaries = limitedClosed.map(buildSummary);\n\n // Get last 20 closed issues (any type)\n let closedIssues = getIssues({ status: 'closed' });\n closedIssues.sort((a, b) =>\n new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()\n );\n closedIssues = closedIssues.slice(0, 20);\n\n const recentlyClosedSummaries: ClosedIssue[] = closedIssues.map((issue) => {\n const summary: ClosedIssue = {\n id: issue.id,\n title: issue.title,\n type: issue.type,\n closedAt: issue.updatedAt,\n lastSource: issue.lastSource,\n };\n if (issue.parent) {\n const parentIssue = getIssue(issue.parent, true);\n if (parentIssue) {\n summary.parent = { id: parentIssue.id, title: parentIssue.title };\n }\n }\n return summary;\n });\n\n if (pretty) {\n const output: string[] = [];\n // In Progress section first\n const inProgressOutput = formatInProgressPretty(inProgressSummaries);\n if (inProgressOutput) {\n output.push(inProgressOutput);\n }\n if (openSummaries.length > 0) {\n if (output.length > 0) output.push('');\n output.push(formatSummaryPretty(openSummaries, 'Open Epics'));\n }\n if (closedSummaries.length > 0) {\n if (output.length > 0) output.push('');\n output.push(formatSummaryPretty(closedSummaries, 'Recently Closed Epics (last 72h)'));\n }\n if (recentlyClosedSummaries.length > 0) {\n if (output.length > 0) output.push('');\n output.push(formatClosedIssuesPretty(recentlyClosedSummaries));\n }\n if (output.length === 0) {\n output.push('No issues in progress and no epics found.');\n }\n console.log(output.join('\\n'));\n } else {\n console.log(formatJson({ inProgress: inProgressSummaries, open: openSummaries, closed: closedSummaries, recentlyClosed: recentlyClosedSummaries }));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { EventType } from '../../shared/types.js';\nimport { EVENT_TYPES } from '../../shared/types.js';\nimport { getOrCreatePebbleDir, readEvents } from '../lib/storage.js';\nimport { computeState } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\n\ninterface HistoryEntry {\n timestamp: string;\n event: EventType;\n issue: {\n id: string;\n title: string;\n type: string;\n };\n parent?: {\n id: string;\n title: string;\n };\n details?: Record<string, unknown>;\n}\n\nfunction parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)([dhms])$/);\n if (!match) {\n throw new Error(`Invalid duration: ${duration}. Use format like \"7d\", \"24h\", \"30m\", \"60s\"`);\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n const multipliers: Record<string, number> = {\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n };\n\n return value * multipliers[unit];\n}\n\nfunction formatRelativeTime(timestamp: string): string {\n const now = Date.now();\n const then = new Date(timestamp).getTime();\n const diff = now - then;\n\n const seconds = Math.floor(diff / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 0) return `${days}d ago`;\n if (hours > 0) return `${hours}h ago`;\n if (minutes > 0) return `${minutes}m ago`;\n return `${seconds}s ago`;\n}\n\nfunction formatHistoryPretty(entries: HistoryEntry[]): string {\n if (entries.length === 0) {\n return 'No events found.';\n }\n\n const lines: string[] = [];\n\n for (const entry of entries) {\n const time = formatRelativeTime(entry.timestamp);\n const eventLabel = entry.event.charAt(0).toUpperCase() + entry.event.slice(1);\n\n let line = `[${time}] ${eventLabel} ${entry.issue.id} \"${entry.issue.title}\" (${entry.issue.type})`;\n\n if (entry.parent) {\n line += ` under ${entry.parent.id}`;\n }\n\n lines.push(line);\n }\n\n return lines.join('\\n');\n}\n\nexport function historyCommand(program: Command): void {\n program\n .command('history')\n .description('Show recent activity log')\n .option('--limit <n>', 'Max events to return', '20')\n .option('--type <types>', 'Filter by event type(s), comma-separated (create,close,reopen,update,comment)')\n .option('--since <duration>', 'Only show events since (e.g., \"7d\", \"24h\")')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n getOrCreatePebbleDir();\n\n const events = readEvents();\n const state = computeState(events);\n\n // Filter by type(s)\n let filteredEvents = events;\n if (options.type !== undefined) {\n const types = options.type.split(',').map((t: string) => t.trim());\n // Validate each type\n for (const t of types) {\n if (!EVENT_TYPES.includes(t as EventType)) {\n throw new Error(`Invalid event type: ${t}. Must be one of: ${EVENT_TYPES.join(', ')}`);\n }\n }\n filteredEvents = filteredEvents.filter((e) => types.includes(e.type));\n }\n\n // Filter by time\n if (options.since !== undefined) {\n const sinceMs = parseDuration(options.since);\n const cutoff = Date.now() - sinceMs;\n filteredEvents = filteredEvents.filter(\n (e) => new Date(e.timestamp).getTime() >= cutoff\n );\n }\n\n // Sort by timestamp descending (newest first)\n filteredEvents.sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()\n );\n\n // Apply limit\n const limit = parseInt(options.limit, 10);\n if (limit > 0) {\n filteredEvents = filteredEvents.slice(0, limit);\n }\n\n // Build history entries\n const entries: HistoryEntry[] = filteredEvents.map((event) => {\n const issue = state.get(event.issueId);\n const entry: HistoryEntry = {\n timestamp: event.timestamp,\n event: event.type,\n issue: {\n id: event.issueId,\n title: issue?.title ?? '(unknown)',\n type: issue?.type ?? 'task',\n },\n };\n\n // Add parent info if available\n if (issue?.parent) {\n const parent = state.get(issue.parent);\n if (parent) {\n entry.parent = {\n id: parent.id,\n title: parent.title,\n };\n }\n }\n\n // Add event-specific details\n if (event.type === 'close' && event.data.reason) {\n entry.details = { reason: event.data.reason };\n } else if (event.type === 'comment') {\n entry.details = { text: event.data.text };\n }\n\n return entry;\n });\n\n if (pretty) {\n console.log(formatHistoryPretty(entries));\n } else {\n console.log(formatJson(entries));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport type { Issue, IssueType, Status } from '../../shared/types.js';\nimport { ISSUE_TYPES, STATUSES } from '../../shared/types.js';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssues } from '../lib/state.js';\nimport { outputIssueList, outputError } from '../lib/output.js';\n\nfunction searchIssues(issues: Issue[], query: string): Issue[] {\n const lowerQuery = query.toLowerCase();\n\n return issues.filter((issue) => {\n // Search in ID\n if (issue.id.toLowerCase().includes(lowerQuery)) {\n return true;\n }\n\n // Search in title\n if (issue.title.toLowerCase().includes(lowerQuery)) {\n return true;\n }\n\n // Search in description\n if (issue.description?.toLowerCase().includes(lowerQuery)) {\n return true;\n }\n\n // Search in comments\n if (issue.comments.some((c) => c.text.toLowerCase().includes(lowerQuery))) {\n return true;\n }\n\n return false;\n });\n}\n\nexport function searchCommand(program: Command): void {\n program\n .command('search <query>')\n .description('Search issues by text in title, description, and comments')\n .option('--status <status>', 'Filter by status')\n .option('-t, --type <type>', 'Filter by type')\n .option('--limit <n>', 'Max results', '20')\n .action(async (query, options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n getOrCreatePebbleDir();\n\n let issues = getIssues();\n\n // Apply status filter\n if (options.status !== undefined) {\n const status = options.status as Status;\n if (!STATUSES.includes(status)) {\n throw new Error(`Invalid status: ${status}. Must be one of: ${STATUSES.join(', ')}`);\n }\n issues = issues.filter((i) => i.status === status);\n }\n\n // Apply type filter\n if (options.type !== undefined) {\n const type = options.type as IssueType;\n if (!ISSUE_TYPES.includes(type)) {\n throw new Error(`Invalid type: ${type}. Must be one of: ${ISSUE_TYPES.join(', ')}`);\n }\n issues = issues.filter((i) => i.type === type);\n }\n\n // Perform search\n let results = searchIssues(issues, query);\n\n // Sort by relevance (title matches first, then by updatedAt)\n const lowerQuery = query.toLowerCase();\n results.sort((a, b) => {\n const aInTitle = a.title.toLowerCase().includes(lowerQuery);\n const bInTitle = b.title.toLowerCase().includes(lowerQuery);\n\n if (aInTitle && !bInTitle) return -1;\n if (!aInTitle && bInTitle) return 1;\n\n // Secondary sort: newest first\n return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();\n });\n\n // Apply limit\n const limit = parseInt(options.limit, 10);\n if (limit > 0) {\n results = results.slice(0, limit);\n }\n\n outputIssueList(results, pretty);\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssue, resolveId, getVerifications } from '../lib/state.js';\nimport { outputError, formatJson, formatLimitMessage, type LimitInfo } from '../lib/output.js';\n\nexport function verificationsCommand(program: Command): void {\n program\n .command('verifications <id>')\n .description('List verification issues for a given issue')\n .option('--limit <n>', 'Max verifications to return (default: 30)')\n .option('--all', 'Show all verifications (no limit)')\n .action(async (id: string, options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n // Ensure pebble directory exists\n getOrCreatePebbleDir();\n\n const resolvedId = resolveId(id);\n const issue = getIssue(resolvedId);\n\n if (!issue) {\n throw new Error(`Issue not found: ${id}`);\n }\n\n let verifications = getVerifications(resolvedId);\n\n // Sort by createdAt descending (newest first)\n verifications.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());\n\n // Apply limit\n const total = verifications.length;\n const limit = options.all ? 0 : (options.limit ? parseInt(options.limit, 10) : 30);\n if (limit > 0 && verifications.length > limit) {\n verifications = verifications.slice(0, limit);\n }\n const limitInfo: LimitInfo = {\n total,\n shown: verifications.length,\n limited: limit > 0 && total > limit,\n };\n\n if (pretty) {\n if (verifications.length === 0) {\n console.log(`No verifications for ${resolvedId}`);\n } else {\n console.log(`Verifications for ${resolvedId} \"${issue.title}\"`);\n console.log('─'.repeat(50));\n for (const v of verifications) {\n const status = v.status === 'closed' ? '✓' : '○';\n console.log(` ${status} ${v.id} - ${v.title}`);\n }\n console.log('');\n console.log(`Total: ${verifications.length} verification(s)`);\n if (limitInfo.limited) {\n console.log(formatLimitMessage(limitInfo));\n }\n }\n } else {\n const output = {\n issueId: resolvedId,\n verifications: verifications.map((v) => ({\n id: v.id,\n title: v.title,\n status: v.status,\n })),\n ...(limitInfo.limited && { _meta: limitInfo }),\n };\n console.log(formatJson(output));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n","import { Command } from 'commander';\nimport * as path from 'path';\nimport { discoverPebbleDir, ensurePebbleDir } from '../lib/storage.js';\n\nexport function initCommand(program: Command): void {\n program\n .command('init')\n .description('Initialize a new .pebble directory in the current directory')\n .option('--force', 'Re-initialize even if .pebble already exists')\n .action((options) => {\n const existing = discoverPebbleDir();\n\n if (existing && !options.force) {\n console.error(JSON.stringify({\n error: 'Already initialized',\n path: existing,\n hint: 'Use --force to re-initialize',\n }));\n process.exit(1);\n }\n\n // Create .pebble in current directory\n const pebbleDir = ensurePebbleDir(process.cwd());\n\n console.log(JSON.stringify({\n initialized: true,\n path: pebbleDir,\n configPath: path.join(pebbleDir, 'config.json'),\n issuesPath: path.join(pebbleDir, 'issues.jsonl'),\n }));\n });\n}\n"],"mappings":"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","names":["readFileSync","fileURLToPath","dirname","join","path","program","program","program","program","program","program","program","program","program","program","program","program","buildIssueTree","formatIssueTreePretty","visited","program","program","path","fs","resolve","fs","program","path","execSync","__filename","__dirname","fs","path","program","fs","path","program","program","formatRelativeTime","program","program","program","path","program","__filename","fileURLToPath","__dirname","dirname","readFileSync","join"]}