@markmdev/pebble 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +65 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/ui/assets/index-DzH8YyE_.js +322 -0
- package/dist/ui/index.html +1 -1
- package/package.json +1 -1
- package/dist/ui/assets/index-D7K46Jfk.js +0 -317
package/dist/cli/index.js.map
CHANGED
|
@@ -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/state.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/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 { createCommand } from './commands/create.js';\nimport { updateCommand } from './commands/update.js';\nimport { closeCommand } from './commands/close.js';\nimport { reopenCommand } from './commands/reopen.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\nconst program = new Command();\n\nprogram\n .name('pebble')\n .description('A lightweight JSONL-based issue tracker')\n .version('0.1.0');\n\n// Global options\nprogram.option('-P, --pretty', 'Human-readable output (default: JSON)');\n\n// Register all commands\ncreateCommand(program);\nupdateCommand(program);\ncloseCommand(program);\nreopenCommand(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 _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'] 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}\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// Union type for all events\nexport type IssueEvent =\n | CreateEvent\n | UpdateEvent\n | CloseEvent\n | ReopenEvent\n | CommentEvent;\n\n// Config stored in .pebble/config.json\nexport interface PebbleConfig {\n prefix: string;\n version: string;\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';\n\nconst PEBBLE_DIR = '.pebble';\nconst ISSUES_FILE = 'issues.jsonl';\nconst CONFIG_FILE = 'config.json';\n\n/**\n * Search upward from cwd to find .pebble/ directory\n * Returns the path to .pebble/ or null if not found\n */\nexport function discoverPebbleDir(startDir: string = process.cwd()): string | null {\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 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 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 * Returns the path to .pebble/\n */\nexport function ensurePebbleDir(baseDir: string = process.cwd()): string {\n const pebbleDir = path.join(baseDir, PEBBLE_DIR);\n\n if (!fs.existsSync(pebbleDir)) {\n fs.mkdirSync(pebbleDir, { recursive: true });\n\n // Create initial config\n const folderName = path.basename(baseDir);\n const config: PebbleConfig = {\n prefix: derivePrefix(folderName),\n version: '0.1.0',\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 * Append an event to the JSONL file\n */\nexport function appendEvent(event: IssueEvent, pebbleDir?: string): void {\n const issuesPath = getIssuesPath(pebbleDir);\n const line = JSON.stringify(event) + '\\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 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 };\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 }\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 }\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 }\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 }\n break;\n }\n }\n }\n\n return issues;\n}\n\n/**\n * Get all issues as an array, optionally filtered\n */\nexport function getIssues(filters?: IssueFilters): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n let issues = Array.from(state.values());\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 */\nexport function getIssue(id: string): Issue | undefined {\n const events = readEvents();\n const state = computeState(events);\n return state.get(id);\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 */\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 // 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 */\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 // 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","import type { Issue, IssueEvent, Priority, Status, IssueType } from '../../shared/types.js';\nimport { PRIORITY_LABELS, STATUS_LABELS, TYPE_LABELS } from '../../shared/types.js';\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 * 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): void {\n if (pretty) {\n console.log(formatIssueListPretty(issues));\n } else {\n console.log(formatJson(issues));\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}\n\n/**\n * Format a list of issues with verbose details\n */\nexport function formatIssueListVerbose(issues: VerboseIssueInfo[]): string {\n if (issues.length === 0) {\n return 'No issues found.';\n }\n\n const lines: string[] = [];\n\n for (const info of issues) {\n const { issue, blocking, children, verifications, blockers } = info;\n\n lines.push(`${issue.id} - ${issue.title}`);\n lines.push('─'.repeat(60));\n lines.push(` Type: ${formatType(issue.type)}`);\n lines.push(` Priority: P${issue.priority}`);\n lines.push(` Status: ${issue.status}`);\n lines.push(` Parent: ${issue.parent || '-'}`);\n lines.push(` Children: ${issue.type === 'epic' ? children : '-'}`);\n lines.push(` Blocking: ${blocking.length > 0 ? blocking.join(', ') : '[]'}`);\n lines.push(` Verifications: ${verifications}`);\n\n if (blockers && blockers.length > 0) {\n lines.push(` Blocked by: ${blockers.join(', ')}`);\n }\n\n lines.push('');\n }\n\n lines.push(`Total: ${issues.length} issue(s)`);\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): void {\n if (pretty) {\n console.log(formatIssueListVerbose(issues));\n } else {\n // JSON output includes all fields\n const output = issues.map(({ issue, blocking, children, verifications, blockers }) => ({\n ...issue,\n blocking,\n childrenCount: issue.type === 'epic' ? children : undefined,\n verificationsCount: verifications,\n ...(blockers && { openBlockers: blockers }),\n }));\n console.log(formatJson(output));\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 epic 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 !== 'epic') {\n throw new Error(`Parent must be an epic, got: ${parent.type}`);\n }\n if (parent.status === 'closed') {\n throw new Error(`Cannot add children to closed epic: ${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 epic 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 !== 'epic') {\n throw new Error(`Parent must be an epic. ${parentId} is a ${parentIssue.type}`);\n }\n if (parentIssue.status === 'closed') {\n throw new Error(`Cannot set parent to closed epic: ${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 }> = [];\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 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 });\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 } 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 }\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.unblocked && { unblocked: result.unblocked }),\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 } 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 }\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.unblocked && { unblocked: r.unblocked }),\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 { 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 } from '../../shared/types.js';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssues, resolveId } from '../lib/state.js';\nimport { outputIssueList, outputError } 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 .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 const issues = getIssues(filters);\n outputIssueList(issues, 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, getBlocking } from '../lib/state.js';\nimport { outputIssueWithBlocking, 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 outputIssueWithBlocking(issue, blocking, 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 { getReady, getBlocking, getChildren, getVerifications } from '../lib/state.js';\nimport { outputIssueList, outputIssueListVerbose, outputError, type VerboseIssueInfo } 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 .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 issues = getReady();\n\n if (options.verbose) {\n // Build verbose info for each issue\n const verboseIssues: VerboseIssueInfo[] = issues.map((issue) => ({\n issue,\n blocking: getBlocking(issue.id).map((i) => i.id),\n children: getChildren(issue.id).length,\n verifications: getVerifications(issue.id).length,\n }));\n outputIssueListVerbose(verboseIssues, pretty);\n } else {\n outputIssueList(issues, pretty);\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 } from '../lib/state.js';\nimport { outputIssueList, outputIssueListVerbose, outputError, type VerboseIssueInfo } 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 .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 issues = getBlocked();\n\n if (options.verbose) {\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 };\n });\n outputIssueListVerbose(verboseIssues, pretty);\n } else {\n outputIssueList(issues, pretty);\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>\n dep\n .command('add <id> <blockerId>')\n .description('Add 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 const blocker = getIssue(resolvedBlockerId);\n if (!blocker) {\n throw new Error(`Blocker issue not found: ${blockerId}`);\n }\n\n // Check for self-reference\n if (resolvedId === resolvedBlockerId) {\n throw new Error('Cannot add self as blocker');\n }\n\n // Check for existing dependency\n if (issue.blockedBy.includes(resolvedBlockerId)) {\n throw new Error(`Dependency already exists: ${resolvedId} is blocked by ${resolvedBlockerId}`);\n }\n\n // Check for cycles\n if (detectCycle(resolvedId, resolvedBlockerId)) {\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: resolvedId,\n timestamp: new Date().toISOString(),\n data: {\n blockedBy: [...issue.blockedBy, resolvedBlockerId],\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 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 dependency tree')\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 visited = new Set<string>();\n const tree = buildDepTree(resolvedId, visited, 0, state);\n\n if (pretty) {\n console.log(formatDepTree(tree));\n } else {\n console.log(formatJson(tree));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n\ninterface TreeNode {\n id: string;\n title: string;\n status: string;\n depth: number;\n blockedBy: TreeNode[];\n}\n\nfunction buildDepTree(\n issueId: string,\n visited: Set<string>,\n depth: number,\n state: Map<string, Issue>\n): TreeNode | null {\n if (visited.has(issueId)) {\n return null; // Prevent infinite loops\n }\n visited.add(issueId);\n\n const issue = state.get(issueId);\n if (!issue) {\n return null;\n }\n\n const blockedBy: TreeNode[] = [];\n for (const blockerId of issue.blockedBy) {\n const child = buildDepTree(blockerId, visited, depth + 1, state);\n if (child) {\n blockedBy.push(child);\n }\n }\n\n return {\n id: issue.id,\n title: issue.title,\n status: issue.status,\n depth,\n blockedBy,\n };\n}\n\nfunction formatDepTree(node: TreeNode | null, prefix: string = '', isRoot: boolean = true): string {\n if (!node) {\n return '';\n }\n\n const lines: string[] = [];\n const statusIcon = node.status === 'closed' ? '✓' : '○';\n\n if (isRoot) {\n lines.push(`${statusIcon} ${node.id} - ${node.title}`);\n }\n\n for (let i = 0; i < node.blockedBy.length; i++) {\n const child = node.blockedBy[i];\n const isLast = i === node.blockedBy.length - 1;\n const connector = isLast ? '└─ ' : '├─ ';\n const childPrefix = prefix + (isLast ? ' ' : '│ ');\n\n const childStatusIcon = child.status === 'closed' ? '✓' : '○';\n lines.push(`${prefix}${connector}${childStatusIcon} ${child.id} - ${child.title}`);\n\n if (child.blockedBy.length > 0) {\n lines.push(formatDepTree(child, childPrefix, false));\n }\n }\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} from '../lib/state.js';\nimport {\n readEventsFromFile,\n getOrCreatePebbleDir,\n appendEvent,\n getConfig,\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 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 */\nfunction appendEventToFile(event: IssueEvent, filePath: string): void {\n const line = JSON.stringify(event) + '\\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 !== 'epic') {\n res.status(400).json({ error: 'Parent must be an epic' });\n return;\n }\n if (parentIssue.status === 'closed') {\n res.status(400).json({ error: 'Cannot add children to a closed epic' });\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 const event: CloseEvent = {\n issueId,\n timestamp: new Date().toISOString(),\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 } = 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 !== 'epic') {\n res.status(400).json({ error: 'Parent must be an epic' });\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 !== 'epic') {\n res.status(400).json({ error: 'Parent must be an epic' });\n return;\n }\n }\n }\n updates.parent = parent;\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 const event: CloseEvent = {\n type: 'close',\n issueId,\n timestamp,\n data: { reason },\n };\n\n appendEventToFile(event, targetFile);\n\n // Return updated issue\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || { ...issue, status: 'closed', 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/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/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 } from '../../shared/types.js';\nimport { STATUSES } from '../../shared/types.js';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssues, getChildren, getIssue } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\n\ninterface ChildCounts {\n total: number;\n done: 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 parent?: {\n id: string;\n title: string;\n };\n children: ChildCounts;\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 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 formatSummaryPretty(summaries: EpicSummary[]): string {\n if (summaries.length === 0) {\n return 'No epics found.';\n }\n\n const lines: string[] = [];\n\n for (const summary of summaries) {\n const { children } = summary;\n const progress = children.total > 0\n ? `(${children.done}/${children.total} done)`\n : '(no children)';\n\n lines.push(`${summary.id} ${summary.title} ${progress}`);\n\n if (summary.parent) {\n lines.push(` Parent: ${summary.parent.id} \"${summary.parent.title}\"`);\n }\n\n if (summary.description) {\n // Truncate description to first line, max 60 chars\n const desc = summary.description.split('\\n')[0];\n const truncated = desc.length > 60 ? desc.slice(0, 57) + '...' : desc;\n lines.push(` ${truncated}`);\n }\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 status (default: open)')\n .option('--limit <n>', 'Max epics to return', '10')\n .option('--include-closed', 'Include closed epics')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n getOrCreatePebbleDir();\n\n // Get all epics\n let epics = getIssues({ type: 'epic' });\n\n // Filter by status\n if (options.includeClosed) {\n // Show all epics\n } else 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 epics = epics.filter((e) => e.status === status);\n } else {\n // Default: show non-closed epics\n epics = epics.filter((e) => e.status !== 'closed');\n }\n\n // Sort by updatedAt descending (most recently updated first)\n epics.sort((a, b) =>\n new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()\n );\n\n // Apply limit\n const limit = parseInt(options.limit, 10);\n if (limit > 0) {\n epics = epics.slice(0, limit);\n }\n\n // Build summaries\n const summaries: EpicSummary[] = epics.map((epic) => {\n const summary: EpicSummary = {\n id: epic.id,\n title: epic.title,\n description: epic.description,\n status: epic.status,\n children: countChildren(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 if (pretty) {\n console.log(formatSummaryPretty(summaries));\n } else {\n console.log(formatJson(summaries));\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: most recently updated first\n return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).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 } 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 .action(async (id: string) => {\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 const verifications = getVerifications(resolvedId);\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 }\n } else {\n console.log(formatJson({\n issueId: resolvedId,\n verifications: verifications.map((v) => ({\n id: v.id,\n title: v.title,\n status: v.status,\n })),\n }));\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":["program","program","program","program","program","program","program","program","program","program","program","program","path","fs","resolve","fs","program","path","__filename","__dirname","fs","path","program","fs","path","program","program","program","program","program","path","program"]}
|
|
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/state.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/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 { createCommand } from './commands/create.js';\nimport { updateCommand } from './commands/update.js';\nimport { closeCommand } from './commands/close.js';\nimport { reopenCommand } from './commands/reopen.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\nconst program = new Command();\n\nprogram\n .name('pebble')\n .description('A lightweight JSONL-based issue tracker')\n .version('0.1.0');\n\n// Global options\nprogram.option('-P, --pretty', 'Human-readable output (default: JSON)');\n\n// Register all commands\ncreateCommand(program);\nupdateCommand(program);\ncloseCommand(program);\nreopenCommand(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 _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'] 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}\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// Union type for all events\nexport type IssueEvent =\n | CreateEvent\n | UpdateEvent\n | CloseEvent\n | ReopenEvent\n | CommentEvent;\n\n// Config stored in .pebble/config.json\nexport interface PebbleConfig {\n prefix: string;\n version: string;\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';\n\nconst PEBBLE_DIR = '.pebble';\nconst ISSUES_FILE = 'issues.jsonl';\nconst CONFIG_FILE = 'config.json';\n\n/**\n * Search upward from cwd to find .pebble/ directory\n * Returns the path to .pebble/ or null if not found\n */\nexport function discoverPebbleDir(startDir: string = process.cwd()): string | null {\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 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 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 * Returns the path to .pebble/\n */\nexport function ensurePebbleDir(baseDir: string = process.cwd()): string {\n const pebbleDir = path.join(baseDir, PEBBLE_DIR);\n\n if (!fs.existsSync(pebbleDir)) {\n fs.mkdirSync(pebbleDir, { recursive: true });\n\n // Create initial config\n const folderName = path.basename(baseDir);\n const config: PebbleConfig = {\n prefix: derivePrefix(folderName),\n version: '0.1.0',\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 * Append an event to the JSONL file\n */\nexport function appendEvent(event: IssueEvent, pebbleDir?: string): void {\n const issuesPath = getIssuesPath(pebbleDir);\n const line = JSON.stringify(event) + '\\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 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 };\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 }\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 }\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 }\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 }\n break;\n }\n }\n }\n\n return issues;\n}\n\n/**\n * Get all issues as an array, optionally filtered\n */\nexport function getIssues(filters?: IssueFilters): Issue[] {\n const events = readEvents();\n const state = computeState(events);\n let issues = Array.from(state.values());\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 */\nexport function getIssue(id: string): Issue | undefined {\n const events = readEvents();\n const state = computeState(events);\n return state.get(id);\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 */\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 // 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 */\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 // 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","import type { Issue, IssueEvent, Priority, Status, IssueType } from '../../shared/types.js';\nimport { PRIORITY_LABELS, STATUS_LABELS, TYPE_LABELS } from '../../shared/types.js';\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 * 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): void {\n if (pretty) {\n console.log(formatIssueListPretty(issues));\n } else {\n console.log(formatJson(issues));\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}\n\n/**\n * Format a list of issues with verbose details\n */\nexport function formatIssueListVerbose(issues: VerboseIssueInfo[]): string {\n if (issues.length === 0) {\n return 'No issues found.';\n }\n\n const lines: string[] = [];\n\n for (const info of issues) {\n const { issue, blocking, children, verifications, blockers } = info;\n\n lines.push(`${issue.id} - ${issue.title}`);\n lines.push('─'.repeat(60));\n lines.push(` Type: ${formatType(issue.type)}`);\n lines.push(` Priority: P${issue.priority}`);\n lines.push(` Status: ${issue.status}`);\n lines.push(` Parent: ${issue.parent || '-'}`);\n lines.push(` Children: ${issue.type === 'epic' ? children : '-'}`);\n lines.push(` Blocking: ${blocking.length > 0 ? blocking.join(', ') : '[]'}`);\n lines.push(` Verifications: ${verifications}`);\n\n if (blockers && blockers.length > 0) {\n lines.push(` Blocked by: ${blockers.join(', ')}`);\n }\n\n lines.push('');\n }\n\n lines.push(`Total: ${issues.length} issue(s)`);\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): void {\n if (pretty) {\n console.log(formatIssueListVerbose(issues));\n } else {\n // JSON output includes all fields\n const output = issues.map(({ issue, blocking, children, verifications, blockers }) => ({\n ...issue,\n blocking,\n childrenCount: issue.type === 'epic' ? children : undefined,\n verificationsCount: verifications,\n ...(blockers && { openBlockers: blockers }),\n }));\n console.log(formatJson(output));\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 epic 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 !== 'epic') {\n throw new Error(`Parent must be an epic, got: ${parent.type}`);\n }\n if (parent.status === 'closed') {\n throw new Error(`Cannot add children to closed epic: ${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 epic 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 !== 'epic') {\n throw new Error(`Parent must be an epic. ${parentId} is a ${parentIssue.type}`);\n }\n if (parentIssue.status === 'closed') {\n throw new Error(`Cannot set parent to closed epic: ${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 }> = [];\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 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 });\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 } 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 }\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.unblocked && { unblocked: result.unblocked }),\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 } 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 }\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.unblocked && { unblocked: r.unblocked }),\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 { 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 } from '../../shared/types.js';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssues, resolveId } from '../lib/state.js';\nimport { outputIssueList, outputError } 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 .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 const issues = getIssues(filters);\n outputIssueList(issues, 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, getBlocking } from '../lib/state.js';\nimport { outputIssueWithBlocking, 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 outputIssueWithBlocking(issue, blocking, 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 { getReady, getBlocking, getChildren, getVerifications } from '../lib/state.js';\nimport { outputIssueList, outputIssueListVerbose, outputError, type VerboseIssueInfo } 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 .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 issues = getReady();\n\n if (options.verbose) {\n // Build verbose info for each issue\n const verboseIssues: VerboseIssueInfo[] = issues.map((issue) => ({\n issue,\n blocking: getBlocking(issue.id).map((i) => i.id),\n children: getChildren(issue.id).length,\n verifications: getVerifications(issue.id).length,\n }));\n outputIssueListVerbose(verboseIssues, pretty);\n } else {\n outputIssueList(issues, pretty);\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 } from '../lib/state.js';\nimport { outputIssueList, outputIssueListVerbose, outputError, type VerboseIssueInfo } 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 .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 issues = getBlocked();\n\n if (options.verbose) {\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 };\n });\n outputIssueListVerbose(verboseIssues, pretty);\n } else {\n outputIssueList(issues, pretty);\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>\n dep\n .command('add <id> <blockerId>')\n .description('Add 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 const blocker = getIssue(resolvedBlockerId);\n if (!blocker) {\n throw new Error(`Blocker issue not found: ${blockerId}`);\n }\n\n // Check for self-reference\n if (resolvedId === resolvedBlockerId) {\n throw new Error('Cannot add self as blocker');\n }\n\n // Check for existing dependency\n if (issue.blockedBy.includes(resolvedBlockerId)) {\n throw new Error(`Dependency already exists: ${resolvedId} is blocked by ${resolvedBlockerId}`);\n }\n\n // Check for cycles\n if (detectCycle(resolvedId, resolvedBlockerId)) {\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: resolvedId,\n timestamp: new Date().toISOString(),\n data: {\n blockedBy: [...issue.blockedBy, resolvedBlockerId],\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 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 dependency tree')\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 visited = new Set<string>();\n const tree = buildDepTree(resolvedId, visited, 0, state);\n\n if (pretty) {\n console.log(formatDepTree(tree));\n } else {\n console.log(formatJson(tree));\n }\n } catch (error) {\n outputError(error as Error, pretty);\n }\n });\n}\n\ninterface TreeNode {\n id: string;\n title: string;\n status: string;\n depth: number;\n blockedBy: TreeNode[];\n}\n\nfunction buildDepTree(\n issueId: string,\n visited: Set<string>,\n depth: number,\n state: Map<string, Issue>\n): TreeNode | null {\n if (visited.has(issueId)) {\n return null; // Prevent infinite loops\n }\n visited.add(issueId);\n\n const issue = state.get(issueId);\n if (!issue) {\n return null;\n }\n\n const blockedBy: TreeNode[] = [];\n for (const blockerId of issue.blockedBy) {\n const child = buildDepTree(blockerId, visited, depth + 1, state);\n if (child) {\n blockedBy.push(child);\n }\n }\n\n return {\n id: issue.id,\n title: issue.title,\n status: issue.status,\n depth,\n blockedBy,\n };\n}\n\nfunction formatDepTree(node: TreeNode | null, prefix: string = '', isRoot: boolean = true): string {\n if (!node) {\n return '';\n }\n\n const lines: string[] = [];\n const statusIcon = node.status === 'closed' ? '✓' : '○';\n\n if (isRoot) {\n lines.push(`${statusIcon} ${node.id} - ${node.title}`);\n }\n\n for (let i = 0; i < node.blockedBy.length; i++) {\n const child = node.blockedBy[i];\n const isLast = i === node.blockedBy.length - 1;\n const connector = isLast ? '└─ ' : '├─ ';\n const childPrefix = prefix + (isLast ? ' ' : '│ ');\n\n const childStatusIcon = child.status === 'closed' ? '✓' : '○';\n lines.push(`${prefix}${connector}${childStatusIcon} ${child.id} - ${child.title}`);\n\n if (child.blockedBy.length > 0) {\n lines.push(formatDepTree(child, childPrefix, false));\n }\n }\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} from '../lib/state.js';\nimport {\n readEventsFromFile,\n getOrCreatePebbleDir,\n appendEvent,\n getConfig,\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 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 */\nfunction appendEventToFile(event: IssueEvent, filePath: string): void {\n const line = JSON.stringify(event) + '\\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 !== 'epic') {\n res.status(400).json({ error: 'Parent must be an epic' });\n return;\n }\n if (parentIssue.status === 'closed') {\n res.status(400).json({ error: 'Cannot add children to a closed epic' });\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 !== 'epic') {\n res.status(400).json({ error: 'Parent must be an epic' });\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 !== 'epic') {\n res.status(400).json({ error: 'Parent must be an epic' });\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 // Return updated issue\n if (isMultiWorktree()) {\n const updated = findIssueInSources(issueId, issueFiles);\n res.json(updated?.issue || { ...issue, status: 'closed', 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/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/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 } from '../../shared/types.js';\nimport { STATUSES } from '../../shared/types.js';\nimport { getOrCreatePebbleDir } from '../lib/storage.js';\nimport { getIssues, getChildren, getIssue } from '../lib/state.js';\nimport { outputError, formatJson } from '../lib/output.js';\n\ninterface ChildCounts {\n total: number;\n done: 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 parent?: {\n id: string;\n title: string;\n };\n children: ChildCounts;\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 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 formatSummaryPretty(summaries: EpicSummary[]): string {\n if (summaries.length === 0) {\n return 'No epics found.';\n }\n\n const lines: string[] = [];\n\n for (const summary of summaries) {\n const { children } = summary;\n const progress = children.total > 0\n ? `(${children.done}/${children.total} done)`\n : '(no children)';\n\n lines.push(`${summary.id} ${summary.title} ${progress}`);\n\n if (summary.parent) {\n lines.push(` Parent: ${summary.parent.id} \"${summary.parent.title}\"`);\n }\n\n if (summary.description) {\n // Truncate description to first line, max 60 chars\n const desc = summary.description.split('\\n')[0];\n const truncated = desc.length > 60 ? desc.slice(0, 57) + '...' : desc;\n lines.push(` ${truncated}`);\n }\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 status (default: open)')\n .option('--limit <n>', 'Max epics to return', '10')\n .option('--include-closed', 'Include closed epics')\n .action(async (options) => {\n const pretty = program.opts().pretty ?? false;\n\n try {\n getOrCreatePebbleDir();\n\n // Get all epics\n let epics = getIssues({ type: 'epic' });\n\n // Filter by status\n if (options.includeClosed) {\n // Show all epics\n } else 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 epics = epics.filter((e) => e.status === status);\n } else {\n // Default: show non-closed epics\n epics = epics.filter((e) => e.status !== 'closed');\n }\n\n // Sort by updatedAt descending (most recently updated first)\n epics.sort((a, b) =>\n new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()\n );\n\n // Apply limit\n const limit = parseInt(options.limit, 10);\n if (limit > 0) {\n epics = epics.slice(0, limit);\n }\n\n // Build summaries\n const summaries: EpicSummary[] = epics.map((epic) => {\n const summary: EpicSummary = {\n id: epic.id,\n title: epic.title,\n description: epic.description,\n status: epic.status,\n children: countChildren(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 if (pretty) {\n console.log(formatSummaryPretty(summaries));\n } else {\n console.log(formatJson(summaries));\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: most recently updated first\n return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).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 } 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 .action(async (id: string) => {\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 const verifications = getVerifications(resolvedId);\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 }\n } else {\n console.log(formatJson({\n issueId: resolvedId,\n verifications: verifications.map((v) => ({\n id: v.id,\n title: v.title,\n status: v.status,\n })),\n }));\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":["program","program","program","program","program","program","program","program","program","program","program","program","path","fs","resolve","fs","program","path","__filename","__dirname","fs","path","program","fs","path","program","program","program","program","program","path","program"]}
|