@ondrej-svec/hog 1.16.2 → 1.18.0

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/ai.ts","../src/api.ts","../src/log-persistence.ts","../src/types.ts","../src/board/constants.ts","../src/github.ts","../src/sync-state.ts","../src/pick.ts","../src/clipboard.ts","../src/board/hooks/use-action-log.ts","../src/board/hooks/use-actions.ts","../src/board/hooks/use-data.ts","../src/board/hooks/use-keyboard.ts","../src/board/hooks/use-multi-select.ts","../src/board/hooks/use-navigation.ts","../src/board/hooks/use-panel-focus.ts","../src/board/hooks/use-toast.ts","../src/board/hooks/use-ui-state.ts","../src/board/components/action-log.tsx","../src/board/components/panel.tsx","../src/board/components/activity-panel.tsx","../src/board/components/detail-panel.tsx","../src/board/components/hint-bar.tsx","../src/board/components/bulk-action-menu.tsx","../src/board/ink-instance.ts","../src/board/components/comment-input.tsx","../src/board/components/confirm-prompt.tsx","../src/board/components/label-picker.tsx","../src/board/components/create-issue-form.tsx","../src/board/components/edit-issue-overlay.tsx","../src/board/components/focus-mode.tsx","../src/board/components/fuzzy-picker.tsx","../src/board/components/help-overlay.tsx","../src/board/components/nl-create-overlay.tsx","../src/board/components/search-bar.tsx","../src/board/components/status-picker.tsx","../src/board/components/overlay-renderer.tsx","../src/board/components/panel-layout.tsx","../src/board/components/repos-panel.tsx","../src/board/components/issue-row.tsx","../src/board/components/row-renderer.tsx","../src/board/components/statuses-panel.tsx","../src/board/components/toast-container.tsx","../src/board/components/dashboard.tsx","../src/board/live.tsx","../src/board/fetch.ts","../src/board/theme.ts","../src/board/format-static.ts","../src/cli.ts","../src/init.ts","../src/output.ts","../src/sync.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\n\nexport const CONFIG_DIR = join(homedir(), \".config\", \"hog\");\nconst AUTH_FILE = join(CONFIG_DIR, \"auth.json\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\ninterface AuthData {\n accessToken: string;\n clientId: string;\n clientSecret: string;\n openrouterApiKey?: string;\n}\n\n// ── Config Schema (Zod) ──\n\nconst COMPLETION_ACTION_SCHEMA = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"updateProjectStatus\"), optionId: z.string() }),\n z.object({ type: z.literal(\"closeIssue\") }),\n z.object({ type: z.literal(\"addLabel\"), label: z.string() }),\n]);\n\nconst REPO_NAME_PATTERN = /^[\\w.-]+\\/[\\w.-]+$/;\n\nconst REPO_CONFIG_SCHEMA = z.object({\n name: z.string().regex(REPO_NAME_PATTERN, \"Must be owner/repo format\"),\n shortName: z.string().min(1),\n projectNumber: z.number().int().positive(),\n statusFieldId: z.string().min(1),\n dueDateFieldId: z.string().optional(),\n completionAction: COMPLETION_ACTION_SCHEMA,\n statusGroups: z.array(z.string()).optional(),\n});\n\nconst BOARD_CONFIG_SCHEMA = z.object({\n refreshInterval: z.number().int().min(10).default(60),\n backlogLimit: z.number().int().min(1).default(20),\n assignee: z.string().min(1),\n focusDuration: z.number().int().min(60).default(1500),\n});\n\nconst TICKTICK_CONFIG_SCHEMA = z.object({\n enabled: z.boolean().default(true),\n});\n\nconst PROFILE_SCHEMA = z.object({\n repos: z.array(REPO_CONFIG_SCHEMA).default([]),\n board: BOARD_CONFIG_SCHEMA,\n ticktick: TICKTICK_CONFIG_SCHEMA.default({ enabled: true }),\n});\n\nconst HOG_CONFIG_SCHEMA = z.object({\n version: z.number().int().default(3),\n defaultProjectId: z.string().optional(),\n defaultProjectName: z.string().optional(),\n repos: z.array(REPO_CONFIG_SCHEMA).default([]),\n board: BOARD_CONFIG_SCHEMA,\n ticktick: TICKTICK_CONFIG_SCHEMA.default({ enabled: true }),\n profiles: z.record(z.string(), PROFILE_SCHEMA).default({}),\n defaultProfile: z.string().optional(),\n});\n\nexport type CompletionAction = z.infer<typeof COMPLETION_ACTION_SCHEMA>;\nexport type RepoConfig = z.infer<typeof REPO_CONFIG_SCHEMA>;\nexport type BoardConfig = z.infer<typeof BOARD_CONFIG_SCHEMA>;\nexport type ProfileConfig = z.infer<typeof PROFILE_SCHEMA>;\nexport type HogConfig = z.infer<typeof HOG_CONFIG_SCHEMA>;\n\n// ── Config Migration ──\n\nfunction migrateConfig(raw: Record<string, unknown>): HogConfig {\n const version = typeof raw[\"version\"] === \"number\" ? raw[\"version\"] : 1;\n\n if (version < 2) {\n // v1 → v2: Add repos and board config from legacy defaults\n raw = {\n ...raw,\n version: 2,\n repos: [],\n board: {\n refreshInterval: 60,\n backlogLimit: 20,\n assignee: \"unknown\",\n },\n };\n }\n\n const currentVersion = typeof raw[\"version\"] === \"number\" ? raw[\"version\"] : 2;\n if (currentVersion < 3) {\n // v2 → v3: Add ticktick config, infer enabled from auth.json presence\n raw = {\n ...raw,\n version: 3,\n ticktick: { enabled: existsSync(AUTH_FILE) },\n };\n }\n\n return HOG_CONFIG_SCHEMA.parse(raw);\n}\n\n// ── Config Access ──\n\nexport function loadFullConfig(): HogConfig {\n const raw = loadRawConfig();\n\n if (Object.keys(raw).length === 0) {\n // No config exists — create from legacy defaults\n const config = migrateConfig({});\n saveFullConfig(config);\n return config;\n }\n\n const version = typeof raw[\"version\"] === \"number\" ? raw[\"version\"] : 1;\n if (version < 3) {\n const migrated = migrateConfig(raw);\n saveFullConfig(migrated);\n return migrated;\n }\n\n return HOG_CONFIG_SCHEMA.parse(raw);\n}\n\nexport function saveFullConfig(config: HogConfig): void {\n ensureDir();\n writeFileSync(CONFIG_FILE, `${JSON.stringify(config, null, 2)}\\n`, { mode: 0o600 });\n}\n\nfunction loadRawConfig(): Record<string, unknown> {\n if (!existsSync(CONFIG_FILE)) return {};\n try {\n return JSON.parse(readFileSync(CONFIG_FILE, \"utf-8\")) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\n/**\n * Resolve a profile from the config.\n * Priority: explicit profileName > config.defaultProfile > top-level config.\n * Returns a HogConfig with the resolved profile's repos/board/ticktick.\n */\nexport function resolveProfile(\n config: HogConfig,\n profileName?: string | undefined,\n): { resolved: HogConfig; activeProfile: string | null } {\n const name = profileName ?? config.defaultProfile;\n\n if (!name) {\n return { resolved: config, activeProfile: null };\n }\n\n const profile = config.profiles[name];\n if (!profile) {\n console.error(\n `Profile \"${name}\" not found. Available: ${Object.keys(config.profiles).join(\", \") || \"(none)\"}`,\n );\n process.exit(1);\n }\n\n return {\n resolved: { ...config, repos: profile.repos, board: profile.board, ticktick: profile.ticktick },\n activeProfile: name,\n };\n}\n\nexport function findRepo(config: HogConfig, shortNameOrFull: string): RepoConfig | undefined {\n return config.repos.find((r) => r.shortName === shortNameOrFull || r.name === shortNameOrFull);\n}\n\nexport function validateRepoName(name: string): boolean {\n return REPO_NAME_PATTERN.test(name);\n}\n\n// ── Legacy Config Access (backward compat) ──\n\ninterface ConfigData {\n defaultProjectId?: string;\n defaultProjectName?: string;\n}\n\nfunction ensureDir(): void {\n mkdirSync(CONFIG_DIR, { recursive: true });\n}\n\nexport function getAuth(): AuthData | null {\n if (!existsSync(AUTH_FILE)) return null;\n try {\n return JSON.parse(readFileSync(AUTH_FILE, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\nexport function saveAuth(data: AuthData): void {\n ensureDir();\n writeFileSync(AUTH_FILE, `${JSON.stringify(data, null, 2)}\\n`, {\n mode: 0o600,\n });\n}\n\nexport function getLlmAuth(): { provider: \"openrouter\"; apiKey: string } | null {\n const auth = getAuth();\n if (auth?.openrouterApiKey) return { provider: \"openrouter\", apiKey: auth.openrouterApiKey };\n return null;\n}\n\nexport function saveLlmAuth(openrouterApiKey: string): void {\n const existing = getAuth();\n const updated: AuthData = existing\n ? { ...existing, openrouterApiKey }\n : { accessToken: \"\", clientId: \"\", clientSecret: \"\", openrouterApiKey };\n saveAuth(updated);\n}\n\nexport function clearLlmAuth(): void {\n const existing = getAuth();\n if (!existing) return;\n const { openrouterApiKey: _, ...rest } = existing;\n saveAuth(rest as AuthData);\n}\n\nexport function getConfig(): ConfigData {\n if (!existsSync(CONFIG_FILE)) return {};\n try {\n return JSON.parse(readFileSync(CONFIG_FILE, \"utf-8\"));\n } catch {\n return {};\n }\n}\n\nexport function saveConfig(data: ConfigData): void {\n ensureDir();\n const existing = getConfig();\n writeFileSync(CONFIG_FILE, `${JSON.stringify({ ...existing, ...data }, null, 2)}\\n`, {\n mode: 0o600,\n });\n}\n\nexport function requireAuth(): AuthData {\n const auth = getAuth();\n if (!auth) {\n console.error(\"Not authenticated. Run `hog init` first.\");\n process.exit(1);\n }\n return auth;\n}\n","/**\n * Natural language issue field extraction.\n *\n * Two-layer approach:\n * 1. Heuristic parser — always runs, no API key needed.\n * 2. Optional LLM layer — used when OPENROUTER_API_KEY or ANTHROPIC_API_KEY is set.\n * If both keys are set, OpenRouter is preferred.\n *\n * The merge strategy: heuristic wins on explicitly-marked tokens (#, @, due);\n * LLM wins only on ambiguous title cleanup.\n * 3. Stored key fallback — when no env var is set, reads openrouterApiKey from auth.json\n * (stored via `hog init` or `hog config ai:set-key`).\n */\n\nimport { getLlmAuth } from \"./config.js\";\n\nexport interface ParsedIssue {\n title: string;\n labels: string[];\n assignee: string | null;\n dueDate: string | null; // YYYY-MM-DD\n}\n\n// ── Heuristic Parser ──\n\n/**\n * Parse a natural-language issue string with simple token extraction.\n *\n * Token rules:\n * - `#word` → label (lowercased)\n * - `@me`/`@user` → assignee\n * - `due <expr>` → due date (chrono-node, forwardDate, dynamically imported)\n * - everything else → title\n *\n * Returns null if the title after stripping tokens is empty.\n */\nexport async function parseHeuristic(\n input: string,\n today: Date = new Date(),\n): Promise<ParsedIssue | null> {\n let remaining = input;\n\n // Extract #labels\n const labelMatches = [...remaining.matchAll(/#([\\w:/-]+)/g)];\n const rawLabels = labelMatches.map((m) => (m[1] ?? \"\").toLowerCase());\n remaining = remaining.replace(/#[\\w:/-]+/g, \"\").trim();\n\n // Extract @assignee (last one wins)\n const assigneeMatches = [...remaining.matchAll(/@([\\w-]+)/g)];\n const assignee =\n assigneeMatches.length > 0 ? (assigneeMatches[assigneeMatches.length - 1]?.[1] ?? null) : null;\n remaining = remaining.replace(/@[\\w-]+/g, \"\").trim();\n\n // Extract \"due <expression>\"\n let dueDate: string | null = null;\n const dueMatch = remaining.match(/\\bdue\\s+(.+?)(?:\\s+#|\\s+@|$)/i);\n if (dueMatch?.[1]) {\n const { parse } = await import(\"chrono-node\");\n const results = parse(dueMatch[1], { instant: today }, { forwardDate: true });\n const first = results[0];\n if (first) {\n let date = first.date();\n // chrono-node bug #240: forwardDate may not advance year for e.g. \"Jan 15\"\n // when today is Jan 16 — post-check and add a year if the parsed date is in the past\n if (date < today) {\n date = new Date(date);\n date.setFullYear(date.getFullYear() + 1);\n }\n const yyyy = date.getFullYear();\n const mm = String(date.getMonth() + 1).padStart(2, \"0\");\n const dd = String(date.getDate()).padStart(2, \"0\");\n dueDate = `${yyyy}-${mm}-${dd}`;\n }\n remaining = remaining.slice(0, dueMatch.index ?? 0).trim();\n }\n\n // What's left is the title\n const title = remaining.replace(/\\s+/g, \" \").trim();\n if (!title) return null;\n\n return { title, labels: rawLabels, assignee, dueDate };\n}\n\n// ── LLM Parser ──\n\ninterface LLMResult {\n title: string;\n labels: string[];\n due_date: string | null;\n assignee: string | null;\n}\n\nfunction detectProvider(): { provider: \"openrouter\" | \"anthropic\"; apiKey: string } | null {\n const orKey = process.env[\"OPENROUTER_API_KEY\"];\n if (orKey) return { provider: \"openrouter\", apiKey: orKey };\n const antKey = process.env[\"ANTHROPIC_API_KEY\"];\n if (antKey) return { provider: \"anthropic\", apiKey: antKey };\n // Fall back to key stored via `hog init` / `hog config ai:set-key`\n return getLlmAuth();\n}\n\nasync function callLLM(\n userText: string,\n validLabels: string[],\n today: Date,\n providerConfig: { provider: \"openrouter\" | \"anthropic\"; apiKey: string },\n): Promise<LLMResult | null> {\n const { provider, apiKey } = providerConfig;\n const todayStr = today.toISOString().slice(0, 10);\n const systemPrompt = `Extract GitHub issue fields. Today is ${todayStr}. Return JSON with: title (string), labels (string[]), due_date (YYYY-MM-DD or null), assignee (string or null).`;\n const escapedText = userText.replace(/<\\/input>/gi, \"< /input>\");\n const userContent = `<input>${escapedText}</input>\\n<valid_labels>${validLabels.join(\",\")}</valid_labels>`;\n\n const jsonSchema = {\n name: \"issue\",\n schema: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n labels: { type: \"array\", items: { type: \"string\" } },\n due_date: { type: [\"string\", \"null\"] },\n assignee: { type: [\"string\", \"null\"] },\n },\n required: [\"title\", \"labels\", \"due_date\", \"assignee\"],\n additionalProperties: false,\n },\n };\n\n try {\n let response: Response;\n\n if (provider === \"openrouter\") {\n response = await fetch(\"https://openrouter.ai/api/v1/chat/completions\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: \"google/gemini-2.5-flash\",\n messages: [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userContent },\n ],\n response_format: { type: \"json_schema\", json_schema: jsonSchema },\n max_tokens: 256,\n temperature: 0,\n }),\n signal: AbortSignal.timeout(5_000),\n });\n } else {\n // Anthropic direct\n response = await fetch(\"https://api.anthropic.com/v1/messages\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify({\n model: \"claude-haiku-4-5-20251001\",\n system: systemPrompt,\n messages: [{ role: \"user\", content: userContent }],\n max_tokens: 256,\n }),\n signal: AbortSignal.timeout(5_000),\n });\n }\n\n if (!response.ok) return null;\n\n const json = (await response.json()) as Record<string, unknown>;\n\n let raw: unknown;\n if (provider === \"openrouter\") {\n const choicesRaw = json[\"choices\"];\n if (!Array.isArray(choicesRaw)) return null;\n const firstChoice = choicesRaw[0] as { message?: { content?: string } } | undefined;\n const content = firstChoice?.message?.content;\n if (!content) return null;\n raw = JSON.parse(content);\n } else {\n // Anthropic: content[0].text\n const contentRaw = json[\"content\"];\n if (!Array.isArray(contentRaw)) return null;\n const firstItem = contentRaw[0] as { type: string; text?: string } | undefined;\n const text = firstItem?.text;\n if (!text) return null;\n raw = JSON.parse(text);\n }\n\n if (!raw || typeof raw !== \"object\") return null;\n const r = raw as Record<string, unknown>;\n\n const ISO_DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n return {\n title: typeof r[\"title\"] === \"string\" ? r[\"title\"] : \"\",\n labels: Array.isArray(r[\"labels\"])\n ? (r[\"labels\"] as unknown[]).filter((l): l is string => typeof l === \"string\")\n : [],\n due_date:\n typeof r[\"due_date\"] === \"string\" && ISO_DATE_RE.test(r[\"due_date\"]) ? r[\"due_date\"] : null,\n assignee: typeof r[\"assignee\"] === \"string\" ? r[\"assignee\"] : null,\n };\n } catch {\n return null;\n }\n}\n\n// ── Combined extractor ──\n\nexport interface ExtractOptions {\n /** Repo label list for validation hints */\n validLabels?: string[];\n /** Override today's date (for testing) */\n today?: Date;\n /** Called with a warning if LLM was unavailable but was configured */\n onLlmFallback?: ((reason: string) => void) | undefined;\n}\n\n/**\n * Extract issue fields from a natural language string.\n * Runs heuristic first, then optionally merges LLM result on top.\n * Heuristic wins on explicit tokens (#, @, due); LLM wins on title cleanup.\n */\nexport async function extractIssueFields(\n input: string,\n options: ExtractOptions = {},\n): Promise<ParsedIssue | null> {\n const today = options.today ?? new Date();\n const heuristic = await parseHeuristic(input, today);\n if (!heuristic) return null;\n\n const providerConfig = detectProvider();\n if (!providerConfig) return heuristic;\n\n const llmResult = await callLLM(input, options.validLabels ?? [], today, providerConfig);\n if (!llmResult) {\n options.onLlmFallback?.(\"AI parsing unavailable, used keyword matching\");\n return heuristic;\n }\n\n // After parsing LLM response, validate labels against known valid labels\n const safeLabels =\n options.validLabels && options.validLabels.length > 0\n ? llmResult.labels.filter((l) => (options.validLabels ?? []).includes(l))\n : llmResult.labels;\n\n // Merge: heuristic wins on explicit tokens; LLM fills in title cleanup\n const merged: ParsedIssue = {\n ...llmResult,\n // Heuristic explicit tokens always win\n labels: heuristic.labels.length > 0 ? heuristic.labels : safeLabels,\n assignee: heuristic.assignee ?? llmResult.assignee,\n dueDate: heuristic.dueDate ?? llmResult.due_date,\n // LLM title is used only if heuristic left explicit tokens\n title:\n heuristic.labels.length > 0 || heuristic.assignee || heuristic.dueDate\n ? llmResult.title || heuristic.title\n : heuristic.title,\n };\n\n return merged;\n}\n\n/** Returns true if an LLM API key is configured. */\nexport function hasLlmApiKey(): boolean {\n return detectProvider() !== null;\n}\n","import type { CreateTaskInput, Project, ProjectData, Task, UpdateTaskInput } from \"./types.js\";\n\nconst BASE_URL = \"https://api.ticktick.com/open/v1\";\n\nexport class TickTickClient {\n private token: string;\n\n constructor(token: string) {\n this.token = token;\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T | null> {\n const url = `${BASE_URL}${path}`;\n\n const init: RequestInit = {\n method,\n headers: {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n },\n };\n\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n }\n\n const res = await fetch(url, init);\n\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`TickTick API error ${res.status}: ${text}`);\n }\n\n const text = await res.text();\n if (!text) return null;\n return JSON.parse(text) as T;\n }\n\n async listProjects(): Promise<Project[]> {\n return (await this.request<Project[]>(\"GET\", \"/project\")) ?? [];\n }\n\n async getProject(projectId: string): Promise<Project> {\n const result = await this.request<Project>(\"GET\", `/project/${projectId}`);\n if (!result) throw new Error(`TickTick API returned empty response for project ${projectId}`);\n return result;\n }\n\n async getProjectData(projectId: string): Promise<ProjectData> {\n const result = await this.request<ProjectData>(\"GET\", `/project/${projectId}/data`);\n if (!result)\n throw new Error(`TickTick API returned empty response for project data ${projectId}`);\n return result;\n }\n\n async listTasks(projectId: string): Promise<Task[]> {\n const data = await this.getProjectData(projectId);\n return data.tasks ?? [];\n }\n\n async getTask(projectId: string, taskId: string): Promise<Task> {\n const result = await this.request<Task>(\"GET\", `/project/${projectId}/task/${taskId}`);\n if (!result) throw new Error(`TickTick API returned empty response for task ${taskId}`);\n return result;\n }\n\n async createTask(input: CreateTaskInput): Promise<Task> {\n const result = await this.request<Task>(\"POST\", \"/task\", input);\n if (!result) throw new Error(\"TickTick API returned empty response for createTask\");\n return result;\n }\n\n async updateTask(input: UpdateTaskInput): Promise<Task> {\n const result = await this.request<Task>(\"POST\", `/task/${input.id}`, input);\n if (!result) throw new Error(`TickTick API returned empty response for updateTask ${input.id}`);\n return result;\n }\n\n async completeTask(projectId: string, taskId: string): Promise<void> {\n await this.request<void>(\"POST\", `/project/${projectId}/task/${taskId}/complete`);\n }\n\n async deleteTask(projectId: string, taskId: string): Promise<void> {\n await this.request<void>(\"DELETE\", `/project/${projectId}/task/${taskId}`);\n }\n}\n","import {\n existsSync,\n mkdirSync,\n readFileSync,\n statSync,\n truncateSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nconst LOG_FILE = join(homedir(), \".config\", \"hog\", \"action-log.json\");\nconst MAX_ENTRIES = 1000;\nconst MAX_SIZE_BYTES = 10 * 1024 * 1024; // 10MB\n\nexport interface PersistedLogEntry {\n readonly id: string;\n readonly description: string;\n readonly status: \"success\" | \"error\" | \"pending\";\n readonly timestamp: number;\n readonly repo?: string;\n}\n\nfunction readLog(): PersistedLogEntry[] {\n if (!existsSync(LOG_FILE)) return [];\n try {\n const raw = readFileSync(LOG_FILE, \"utf-8\");\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? (parsed as PersistedLogEntry[]) : [];\n } catch {\n return [];\n }\n}\n\nfunction writeLog(entries: PersistedLogEntry[]): void {\n mkdirSync(dirname(LOG_FILE), { recursive: true });\n writeFileSync(LOG_FILE, JSON.stringify(entries, null, 2), \"utf-8\");\n}\n\nexport function appendActionLog(entry: PersistedLogEntry): void {\n // Check size and rotate if needed\n if (existsSync(LOG_FILE)) {\n const stats = statSync(LOG_FILE);\n if (stats.size > MAX_SIZE_BYTES) {\n truncateSync(LOG_FILE, 0);\n }\n }\n const entries = readLog();\n entries.push(entry);\n // Keep only last MAX_ENTRIES\n if (entries.length > MAX_ENTRIES) {\n entries.splice(0, entries.length - MAX_ENTRIES);\n }\n writeLog(entries);\n}\n\nexport function getActionLog(limit = 50): PersistedLogEntry[] {\n const entries = readLog();\n return entries.slice(-limit);\n}\n\nexport function clearActionLog(): void {\n writeLog([]);\n}\n","// ── Result Type (no throwing in data layer) ──\n\nexport type Result<T, E> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: E };\n\nexport interface FetchError {\n readonly type: \"github\" | \"ticktick\" | \"network\";\n readonly message: string;\n}\n\n// ── Board Data Types ──\n\nexport interface BoardIssue {\n readonly number: number;\n readonly title: string;\n readonly url: string;\n readonly state: string;\n readonly assignee: string | null;\n readonly labels: readonly string[];\n readonly updatedAt: string;\n readonly repo: string;\n}\n\nexport interface BoardData {\n readonly github: readonly BoardIssue[];\n readonly ticktick: readonly Task[];\n readonly fetchedAt: Date;\n}\n\n// ── Pick Command ──\n\nexport interface PickResult {\n readonly success: boolean;\n readonly issue: BoardIssue;\n readonly ticktickTask?: Task;\n readonly warning?: string;\n}\n\n// ── TickTick Open API types ──\n\nexport interface Task {\n id: string;\n projectId: string;\n title: string;\n content: string;\n desc: string;\n isAllDay: boolean;\n startDate: string;\n dueDate: string;\n completedTime: string;\n priority: Priority;\n reminders: string[];\n repeatFlag: string;\n sortOrder: number;\n status: TaskStatus;\n timeZone: string;\n tags: string[];\n items: ChecklistItem[];\n}\n\nexport interface ChecklistItem {\n id: string;\n title: string;\n status: number;\n completedTime: number;\n isAllDay: boolean;\n sortOrder: number;\n startDate: string;\n timeZone: string;\n}\n\nexport interface Project {\n id: string;\n name: string;\n color: string;\n sortOrder: number;\n closed: boolean;\n groupId: string;\n viewMode: string;\n kind: string;\n}\n\nexport interface ProjectData {\n project: Project;\n tasks: Task[];\n}\n\nexport enum Priority {\n None = 0,\n Low = 1,\n Medium = 3,\n High = 5,\n}\n\nexport enum TaskStatus {\n Active = 0,\n Completed = 2,\n}\n\nexport interface CreateTaskInput {\n title: string;\n projectId?: string;\n content?: string;\n priority?: Priority;\n startDate?: string;\n dueDate?: string;\n isAllDay?: boolean;\n timeZone?: string;\n tags?: string[];\n}\n\nexport interface UpdateTaskInput {\n id: string;\n projectId: string;\n title?: string;\n content?: string;\n priority?: Priority;\n startDate?: string;\n dueDate?: string;\n isAllDay?: boolean;\n tags?: string[];\n}\n","/**\n * Shared board constants and utilities.\n * Extracted to prevent duplication across components and hooks.\n */\n\n/** Statuses that trigger completion actions (TickTick close, project complete). */\nexport const TERMINAL_STATUS_RE = /^(done|shipped|won't|wont|closed|complete|completed)$/i;\n\nexport function isTerminalStatus(status: string): boolean {\n return TERMINAL_STATUS_RE.test(status);\n}\n\n/** Returns true if a nav ID is a header row (not a navigable issue/task). */\nexport function isHeaderId(id: string | null): boolean {\n return id != null && (id.startsWith(\"header:\") || id.startsWith(\"sub:\"));\n}\n\n/** Formats a date as a relative \"Xm ago\" string. */\nexport function timeAgo(date: Date): string {\n const seconds = Math.floor((Date.now() - date.getTime()) / 1000);\n if (seconds < 10) return \"just now\";\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n return `${minutes}m ago`;\n}\n\n/** Formats an unknown error as a string. */\nexport function formatError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import { execFile, execFileSync } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface GitHubIssue {\n readonly number: number;\n readonly title: string;\n readonly url: string;\n readonly state: string;\n readonly updatedAt: string;\n readonly labels: { name: string }[];\n readonly assignees?: { login: string }[];\n readonly targetDate?: string;\n readonly body?: string;\n readonly projectStatus?: string;\n readonly slackThreadUrl?: string;\n /**\n * All other GitHub Project custom field values keyed by field name.\n * Includes single-select, text, number, and iteration fields — excluding\n * Status (→ projectStatus) and date fields (→ targetDate).\n * Example: { Workstream: \"Platform\", Size: \"M\", Priority: \"High\" }\n */\n readonly customFields?: Record<string, string>;\n}\n\nexport interface ProjectFieldValues {\n targetDate?: string;\n status?: string;\n customFields?: Record<string, string>;\n}\n\nexport interface RepoProjectConfig {\n projectNumber: number;\n statusFieldId: string;\n optionId: string;\n}\n\n/** Matches common date field names used in GitHub Projects v2 (case-insensitive). */\nconst DATE_FIELD_NAME_RE = /^(target\\s*date|due\\s*date|due|deadline)$/i;\n\nfunction runGh(args: string[]): string {\n return execFileSync(\"gh\", args, { encoding: \"utf-8\", timeout: 30_000 }).trim();\n}\n\nfunction runGhJson<T>(args: string[]): T {\n const output = runGh(args);\n return JSON.parse(output) as T;\n}\n\nasync function runGhAsync(args: string[]): Promise<string> {\n const { stdout } = await execFileAsync(\"gh\", args, { encoding: \"utf-8\", timeout: 30_000 });\n return stdout.trim();\n}\n\nasync function runGhJsonAsync<T>(args: string[]): Promise<T> {\n const output = await runGhAsync(args);\n return JSON.parse(output) as T;\n}\n\nexport function fetchAssignedIssues(repo: string, assignee: string): GitHubIssue[] {\n return runGhJson<GitHubIssue[]>([\n \"issue\",\n \"list\",\n \"--repo\",\n repo,\n \"--assignee\",\n assignee,\n \"--state\",\n \"open\",\n \"--json\",\n \"number,title,url,state,updatedAt,labels\",\n \"--limit\",\n \"100\",\n ]);\n}\n\nexport interface FetchIssuesOptions {\n assignee?: string | undefined;\n state?: \"open\" | \"closed\" | \"all\" | undefined;\n limit?: number | undefined;\n}\n\nexport function fetchRepoIssues(repo: string, options: FetchIssuesOptions = {}): GitHubIssue[] {\n const { state = \"open\", limit = 100 } = options;\n const args = [\n \"issue\",\n \"list\",\n \"--repo\",\n repo,\n \"--state\",\n state,\n \"--json\",\n \"number,title,url,state,updatedAt,labels,assignees,body\",\n \"--limit\",\n String(limit),\n ];\n if (options.assignee) {\n args.push(\"--assignee\", options.assignee);\n }\n return runGhJson<GitHubIssue[]>(args);\n}\n\nexport function assignIssue(repo: string, issueNumber: number): void {\n runGh([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--add-assignee\", \"@me\"]);\n}\n\nexport async function assignIssueAsync(repo: string, issueNumber: number): Promise<void> {\n await runGhAsync([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--add-assignee\", \"@me\"]);\n}\n\nexport async function assignIssueToAsync(\n repo: string,\n issueNumber: number,\n user: string,\n): Promise<void> {\n await runGhAsync([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--add-assignee\", user]);\n}\n\nexport async function unassignIssueAsync(\n repo: string,\n issueNumber: number,\n user: string,\n): Promise<void> {\n await runGhAsync([\n \"issue\",\n \"edit\",\n String(issueNumber),\n \"--repo\",\n repo,\n \"--remove-assignee\",\n user,\n ]);\n}\n\nexport async function fetchIssueAsync(repo: string, issueNumber: number): Promise<GitHubIssue> {\n return runGhJsonAsync<GitHubIssue>([\n \"issue\",\n \"view\",\n String(issueNumber),\n \"--repo\",\n repo,\n \"--json\",\n \"number,title,url,state,updatedAt,labels,assignees,body,projectStatus\",\n ]);\n}\n\nexport async function closeIssueAsync(repo: string, issueNumber: number): Promise<void> {\n await runGhAsync([\"issue\", \"close\", String(issueNumber), \"--repo\", repo]);\n}\n\nexport async function createIssueAsync(\n repo: string,\n title: string,\n body: string,\n labels?: string[],\n): Promise<string> {\n const args = [\"issue\", \"create\", \"--repo\", repo, \"--title\", title, \"--body\", body];\n if (labels && labels.length > 0) {\n for (const label of labels) {\n args.push(\"--label\", label);\n }\n }\n return runGhAsync(args);\n}\n\nexport async function editIssueTitleAsync(\n repo: string,\n issueNumber: number,\n title: string,\n): Promise<void> {\n await runGhAsync([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--title\", title]);\n}\n\nexport async function editIssueBodyAsync(\n repo: string,\n issueNumber: number,\n body: string,\n): Promise<void> {\n await runGhAsync([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--body\", body]);\n}\n\nexport async function addCommentAsync(\n repo: string,\n issueNumber: number,\n body: string,\n): Promise<void> {\n await runGhAsync([\"issue\", \"comment\", String(issueNumber), \"--repo\", repo, \"--body\", body]);\n}\n\nexport async function addLabelAsync(\n repo: string,\n issueNumber: number,\n label: string,\n): Promise<void> {\n await runGhAsync([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--add-label\", label]);\n}\n\nexport async function removeLabelAsync(\n repo: string,\n issueNumber: number,\n label: string,\n): Promise<void> {\n await runGhAsync([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--remove-label\", label]);\n}\n\nexport async function updateLabelsAsync(\n repo: string,\n issueNumber: number,\n addLabels: string[],\n removeLabels: string[],\n): Promise<void> {\n const args = [\"issue\", \"edit\", String(issueNumber), \"--repo\", repo];\n for (const label of addLabels) args.push(\"--add-label\", label);\n for (const label of removeLabels) args.push(\"--remove-label\", label);\n await runGhAsync(args);\n}\n\nexport interface IssueComment {\n readonly body: string;\n readonly author: { readonly login: string };\n readonly createdAt: string;\n}\n\nexport async function fetchIssueCommentsAsync(\n repo: string,\n issueNumber: number,\n): Promise<IssueComment[]> {\n const result = await runGhJsonAsync<{ comments: IssueComment[] }>([\n \"issue\",\n \"view\",\n String(issueNumber),\n \"--repo\",\n repo,\n \"--json\",\n \"comments\",\n ]);\n return result.comments ?? [];\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: parses multiple GitHub Project field types\nexport function fetchProjectFields(\n repo: string,\n issueNumber: number,\n projectNumber: number,\n): ProjectFieldValues {\n // GraphQL query to get project item fields for this issue\n const query = `\n query($owner: String!, $repo: String!, $issueNumber: Int!) {\n repository(owner: $owner, name: $repo) {\n issue(number: $issueNumber) {\n projectItems(first: 10) {\n nodes {\n project { number }\n fieldValues(first: 20) {\n nodes {\n ... on ProjectV2ItemFieldDateValue {\n field { ... on ProjectV2Field { name } }\n date\n }\n ... on ProjectV2ItemFieldSingleSelectValue {\n field { ... on ProjectV2SingleSelectField { name } }\n name\n }\n ... on ProjectV2ItemFieldTextValue {\n field { ... on ProjectV2Field { name } }\n text\n }\n ... on ProjectV2ItemFieldNumberValue {\n field { ... on ProjectV2Field { name } }\n number\n }\n ... on ProjectV2ItemFieldIterationValue {\n field { ... on ProjectV2IterationField { name } }\n title\n }\n }\n }\n }\n }\n }\n }\n }\n `;\n\n const [owner, repoName] = repo.split(\"/\");\n if (!(owner && repoName)) return {};\n\n try {\n const result = runGhJson<GraphQLResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${query}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `repo=${repoName}`,\n \"-F\",\n `issueNumber=${String(issueNumber)}`,\n ]);\n\n const items = result?.data?.repository?.issue?.projectItems?.nodes ?? [];\n const projectItem = items.find((item) => item?.project?.number === projectNumber);\n\n if (!projectItem) return {};\n\n const fields: ProjectFieldValues = {};\n const fieldValues = projectItem.fieldValues?.nodes ?? [];\n\n for (const fv of fieldValues) {\n if (!fv) continue;\n const fieldName = fv.field?.name ?? \"\";\n if (\"date\" in fv && DATE_FIELD_NAME_RE.test(fieldName)) {\n fields.targetDate = fv.date;\n } else if (\"name\" in fv && fieldName === \"Status\") {\n fields.status = fv.name;\n } else if (fieldName) {\n const value =\n \"text\" in fv && fv.text != null\n ? fv.text\n : \"number\" in fv && fv.number != null\n ? String(fv.number)\n : \"name\" in fv && fv.name != null\n ? fv.name\n : \"title\" in fv && fv.title != null\n ? fv.title\n : null;\n if (value != null) {\n if (!fields.customFields) fields.customFields = {};\n fields.customFields[fieldName] = value;\n }\n }\n }\n\n return fields;\n } catch {\n return {};\n }\n}\n\nexport interface ProjectEnrichment {\n targetDate?: string;\n projectStatus?: string;\n customFields?: Record<string, string>;\n}\n\n/**\n * Fetch target dates and project statuses for all issues in a project in one GraphQL call.\n * Returns a Map from issue number to enrichment data.\n */\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: parses multiple GitHub Project field types across all items\nexport function fetchProjectEnrichment(\n repo: string,\n projectNumber: number,\n): Map<number, ProjectEnrichment> {\n const [owner] = repo.split(\"/\");\n if (!owner) return new Map();\n\n const query = `\n query($owner: String!, $projectNumber: Int!, $cursor: String) {\n organization(login: $owner) {\n projectV2(number: $projectNumber) {\n items(first: 100, after: $cursor) {\n pageInfo { hasNextPage endCursor }\n nodes {\n content {\n ... on Issue {\n number\n }\n }\n fieldValues(first: 20) {\n nodes {\n ... on ProjectV2ItemFieldDateValue {\n field { ... on ProjectV2Field { name } }\n date\n }\n ... on ProjectV2ItemFieldSingleSelectValue {\n field { ... on ProjectV2SingleSelectField { name } }\n name\n }\n ... on ProjectV2ItemFieldTextValue {\n field { ... on ProjectV2Field { name } }\n text\n }\n ... on ProjectV2ItemFieldNumberValue {\n field { ... on ProjectV2Field { name } }\n number\n }\n ... on ProjectV2ItemFieldIterationValue {\n field { ... on ProjectV2IterationField { name } }\n title\n }\n }\n }\n }\n }\n }\n }\n }\n `;\n\n try {\n const enrichMap = new Map<number, ProjectEnrichment>();\n let cursor: string | null = null;\n\n do {\n const args = [\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${query}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `projectNumber=${String(projectNumber)}`,\n ];\n if (cursor) args.push(\"-f\", `cursor=${cursor}`);\n const result = runGhJson<ProjectItemsResult>(args);\n const page = result?.data?.organization?.projectV2?.items;\n const nodes = page?.nodes ?? [];\n\n for (const item of nodes) {\n if (!item?.content?.number) continue;\n const enrichment: ProjectEnrichment = {};\n const fieldValues = item.fieldValues?.nodes ?? [];\n for (const fv of fieldValues) {\n if (!fv) continue;\n const fieldName = fv.field?.name ?? \"\";\n if (\"date\" in fv && fv.date && DATE_FIELD_NAME_RE.test(fieldName)) {\n enrichment.targetDate = fv.date;\n } else if (\"name\" in fv && fieldName === \"Status\" && fv.name) {\n enrichment.projectStatus = fv.name;\n } else if (fieldName) {\n const value =\n \"text\" in fv && fv.text != null\n ? fv.text\n : \"number\" in fv && fv.number != null\n ? String(fv.number)\n : \"name\" in fv && fv.name != null\n ? fv.name\n : \"title\" in fv && fv.title != null\n ? fv.title\n : null;\n if (value != null) {\n if (!enrichment.customFields) enrichment.customFields = {};\n enrichment.customFields[fieldName] = value;\n }\n }\n }\n enrichMap.set(item.content.number, enrichment);\n }\n\n if (!page?.pageInfo?.hasNextPage) break;\n cursor = page.pageInfo.endCursor ?? null;\n } while (cursor);\n\n return enrichMap;\n } catch {\n return new Map();\n }\n}\n\n/** Backwards-compatible wrapper for fetchProjectEnrichment. */\nexport function fetchProjectTargetDates(repo: string, projectNumber: number): Map<number, string> {\n const enrichMap = fetchProjectEnrichment(repo, projectNumber);\n const dateMap = new Map<number, string>();\n for (const [num, e] of enrichMap) {\n if (e.targetDate) dateMap.set(num, e.targetDate);\n }\n return dateMap;\n}\n\nexport interface StatusOption {\n id: string;\n name: string;\n}\n\n/**\n * Fetch available project status options (the SingleSelectField values).\n * Returns options in the order defined on the project board.\n */\nexport function fetchProjectStatusOptions(\n repo: string,\n projectNumber: number,\n _statusFieldId: string,\n): StatusOption[] {\n const [owner] = repo.split(\"/\");\n if (!owner) return [];\n\n const query = `\n query($owner: String!, $projectNumber: Int!) {\n organization(login: $owner) {\n projectV2(number: $projectNumber) {\n field(name: \"Status\") {\n ... on ProjectV2SingleSelectField {\n options {\n id\n name\n }\n }\n }\n }\n }\n }\n `;\n\n try {\n const result = runGhJson<ProjectStatusResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${query}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `projectNumber=${String(projectNumber)}`,\n ]);\n\n return result?.data?.organization?.projectV2?.field?.options ?? [];\n } catch {\n return [];\n }\n}\n\nexport function addLabel(repo: string, issueNumber: number, label: string): void {\n runGh([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--add-label\", label]);\n}\n\nexport interface LabelOption {\n name: string;\n color: string;\n}\n\n/**\n * Fetch all labels defined in the repo asynchronously.\n * Uses execFileAsync (not execFileSync) to avoid blocking the React render thread.\n */\nexport async function fetchRepoLabelsAsync(repo: string): Promise<LabelOption[]> {\n try {\n const result = await runGhJsonAsync<LabelOption[]>([\n \"label\",\n \"list\",\n \"--repo\",\n repo,\n \"--json\",\n \"name,color\",\n ]);\n return Array.isArray(result) ? result : [];\n } catch {\n return [];\n }\n}\n\n/** Cache for GitHub Projects node IDs — these are immutable per project number. */\nconst projectNodeIdCache = new Map<string, string>();\n\n/** Clears the project node ID cache. Intended for use in tests only. */\nexport function clearProjectNodeIdCache(): void {\n projectNodeIdCache.clear();\n}\n\nasync function getProjectNodeId(owner: string, projectNumber: number): Promise<string | null> {\n const key = `${owner}/${String(projectNumber)}`;\n const cached = projectNodeIdCache.get(key);\n if (cached !== undefined) return cached;\n\n const projectQuery = `\n query($owner: String!) {\n organization(login: $owner) {\n projectV2(number: ${projectNumber}) {\n id\n }\n }\n }\n `;\n\n const projectResult = await runGhJsonAsync<GraphQLProjectResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${projectQuery}`,\n \"-F\",\n `owner=${owner}`,\n ]);\n\n const projectId = projectResult?.data?.organization?.projectV2?.id;\n if (!projectId) return null;\n projectNodeIdCache.set(key, projectId);\n return projectId;\n}\n\nexport function updateProjectItemStatus(\n repo: string,\n issueNumber: number,\n projectConfig: RepoProjectConfig,\n): void {\n const [owner, repoName] = repo.split(\"/\");\n if (!(owner && repoName)) return;\n\n // First get the project item ID\n const findItemQuery = `\n query($owner: String!, $repo: String!, $issueNumber: Int!) {\n repository(owner: $owner, name: $repo) {\n issue(number: $issueNumber) {\n projectItems(first: 10) {\n nodes {\n id\n project { number }\n }\n }\n }\n }\n }\n `;\n\n const findResult = runGhJson<GraphQLResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${findItemQuery}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `repo=${repoName}`,\n \"-F\",\n `issueNumber=${String(issueNumber)}`,\n ]);\n\n const items = findResult?.data?.repository?.issue?.projectItems?.nodes ?? [];\n const projectNumber = projectConfig.projectNumber;\n const projectItem = items.find((item) => item?.project?.number === projectNumber);\n\n if (!projectItem?.id) return;\n\n // Get the project ID\n const projectQuery = `\n query($owner: String!) {\n organization(login: $owner) {\n projectV2(number: ${projectNumber}) {\n id\n }\n }\n }\n `;\n\n const projectResult = runGhJson<GraphQLProjectResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${projectQuery}`,\n \"-F\",\n `owner=${owner}`,\n ]);\n\n const projectId = projectResult?.data?.organization?.projectV2?.id;\n if (!projectId) return;\n\n const statusFieldId = projectConfig.statusFieldId;\n const optionId = projectConfig.optionId;\n\n // Mutation to update the status\n const mutation = `\n mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {\n updateProjectV2ItemFieldValue(\n input: {\n projectId: $projectId\n itemId: $itemId\n fieldId: $fieldId\n value: { singleSelectOptionId: $optionId }\n }\n ) {\n projectV2Item { id }\n }\n }\n `;\n\n runGh([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${mutation}`,\n \"-F\",\n `projectId=${projectId}`,\n \"-F\",\n `itemId=${projectItem.id}`,\n \"-F\",\n `fieldId=${statusFieldId}`,\n \"-F\",\n `optionId=${optionId}`,\n ]);\n}\n\nexport async function updateProjectItemStatusAsync(\n repo: string,\n issueNumber: number,\n projectConfig: RepoProjectConfig,\n): Promise<void> {\n const [owner, repoName] = repo.split(\"/\");\n if (!(owner && repoName)) return;\n\n const findItemQuery = `\n query($owner: String!, $repo: String!, $issueNumber: Int!) {\n repository(owner: $owner, name: $repo) {\n issue(number: $issueNumber) {\n projectItems(first: 10) {\n nodes {\n id\n project { number }\n }\n }\n }\n }\n }\n `;\n\n const findResult = await runGhJsonAsync<GraphQLResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${findItemQuery}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `repo=${repoName}`,\n \"-F\",\n `issueNumber=${String(issueNumber)}`,\n ]);\n\n const items = findResult?.data?.repository?.issue?.projectItems?.nodes ?? [];\n const projectNumber = projectConfig.projectNumber;\n const projectItem = items.find((item) => item?.project?.number === projectNumber);\n\n if (!projectItem?.id) return;\n\n const projectId = await getProjectNodeId(owner, projectNumber);\n if (!projectId) return;\n\n const statusFieldId = projectConfig.statusFieldId;\n const optionId = projectConfig.optionId;\n\n const mutation = `\n mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {\n updateProjectV2ItemFieldValue(\n input: {\n projectId: $projectId\n itemId: $itemId\n fieldId: $fieldId\n value: { singleSelectOptionId: $optionId }\n }\n ) {\n projectV2Item { id }\n }\n }\n `;\n\n await runGhAsync([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${mutation}`,\n \"-F\",\n `projectId=${projectId}`,\n \"-F\",\n `itemId=${projectItem.id}`,\n \"-F\",\n `fieldId=${statusFieldId}`,\n \"-F\",\n `optionId=${optionId}`,\n ]);\n}\n\nexport interface RepoDueDateConfig {\n projectNumber: number;\n dueDateFieldId: string;\n}\n\n/**\n * Set a date field value on a GitHub Projects v2 item for the given issue.\n * Uses the same 3-step pattern as updateProjectItemStatusAsync.\n */\nexport async function updateProjectItemDateAsync(\n repo: string,\n issueNumber: number,\n projectConfig: RepoDueDateConfig,\n dueDate: string,\n): Promise<void> {\n const [owner, repoName] = repo.split(\"/\");\n if (!(owner && repoName)) return;\n\n const findItemQuery = `\n query($owner: String!, $repo: String!, $issueNumber: Int!) {\n repository(owner: $owner, name: $repo) {\n issue(number: $issueNumber) {\n projectItems(first: 10) {\n nodes {\n id\n project { number }\n }\n }\n }\n }\n }\n `;\n\n const findResult = await runGhJsonAsync<GraphQLResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${findItemQuery}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `repo=${repoName}`,\n \"-F\",\n `issueNumber=${String(issueNumber)}`,\n ]);\n\n const items = findResult?.data?.repository?.issue?.projectItems?.nodes ?? [];\n const projectItem = items.find((item) => item?.project?.number === projectConfig.projectNumber);\n\n if (!projectItem?.id) return;\n\n const projectId = await getProjectNodeId(owner, projectConfig.projectNumber);\n if (!projectId) return;\n\n const mutation = `\n mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $date: Date!) {\n updateProjectV2ItemFieldValue(\n input: {\n projectId: $projectId\n itemId: $itemId\n fieldId: $fieldId\n value: { date: $date }\n }\n ) {\n projectV2Item { id }\n }\n }\n `;\n\n await runGhAsync([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${mutation}`,\n \"-F\",\n `projectId=${projectId}`,\n \"-F\",\n `itemId=${projectItem.id}`,\n \"-F\",\n `fieldId=${projectConfig.dueDateFieldId}`,\n \"-F\",\n `date=${dueDate}`,\n ]);\n}\n\n// Internal GraphQL response types\n\ninterface FieldValue {\n field?: { name?: string };\n date?: string;\n name?: string;\n text?: string;\n number?: number;\n title?: string; // iteration field title\n}\n\ninterface ProjectItem {\n id?: string;\n project?: { number?: number };\n fieldValues?: { nodes?: (FieldValue | null)[] };\n}\n\ninterface GraphQLResult {\n data?: {\n repository?: {\n issue?: {\n projectItems?: {\n nodes?: (ProjectItem | null)[];\n };\n };\n };\n };\n}\n\ninterface GraphQLProjectResult {\n data?: {\n organization?: {\n projectV2?: {\n id?: string;\n };\n };\n };\n}\n\ninterface ProjectItemNode {\n content?: { number?: number };\n fieldValues?: { nodes?: (FieldValue | null)[] };\n}\n\ninterface ProjectItemsResult {\n data?: {\n organization?: {\n projectV2?: {\n items?: {\n pageInfo?: { hasNextPage: boolean; endCursor?: string };\n nodes?: (ProjectItemNode | null)[];\n };\n };\n };\n };\n}\n\ninterface ProjectStatusResult {\n data?: {\n organization?: {\n projectV2?: {\n field?: {\n options?: StatusOption[];\n };\n };\n };\n };\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nconst CONFIG_DIR = join(homedir(), \".config\", \"hog\");\nconst STATE_FILE = join(CONFIG_DIR, \"sync-state.json\");\n\nexport interface SyncMapping {\n githubRepo: string;\n githubIssueNumber: number;\n githubUrl: string;\n ticktickTaskId: string;\n ticktickProjectId: string;\n githubUpdatedAt: string;\n lastSyncedAt: string;\n}\n\nexport interface SyncState {\n mappings: SyncMapping[];\n lastSyncAt?: string;\n}\n\nexport function loadSyncState(): SyncState {\n if (!existsSync(STATE_FILE)) return { mappings: [] };\n try {\n return JSON.parse(readFileSync(STATE_FILE, \"utf-8\")) as SyncState;\n } catch {\n return { mappings: [] };\n }\n}\n\nexport function saveSyncState(state: SyncState): void {\n writeFileSync(STATE_FILE, `${JSON.stringify(state, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport function findMapping(\n state: SyncState,\n githubRepo: string,\n issueNumber: number,\n): SyncMapping | undefined {\n return state.mappings.find(\n (m) => m.githubRepo === githubRepo && m.githubIssueNumber === issueNumber,\n );\n}\n\nexport function findMappingByTaskId(\n state: SyncState,\n ticktickTaskId: string,\n): SyncMapping | undefined {\n return state.mappings.find((m) => m.ticktickTaskId === ticktickTaskId);\n}\n\nexport function upsertMapping(state: SyncState, mapping: SyncMapping): void {\n const idx = state.mappings.findIndex(\n (m) => m.githubRepo === mapping.githubRepo && m.githubIssueNumber === mapping.githubIssueNumber,\n );\n if (idx >= 0) {\n state.mappings[idx] = mapping;\n } else {\n state.mappings.push(mapping);\n }\n}\n\nexport function removeMapping(state: SyncState, githubRepo: string, issueNumber: number): void {\n state.mappings = state.mappings.filter(\n (m) => !(m.githubRepo === githubRepo && m.githubIssueNumber === issueNumber),\n );\n}\n","import { TickTickClient } from \"./api.js\";\nimport type { HogConfig, RepoConfig } from \"./config.js\";\nimport { findRepo, requireAuth } from \"./config.js\";\nimport type { GitHubIssue } from \"./github.js\";\nimport { assignIssue, fetchProjectFields, fetchRepoIssues } from \"./github.js\";\nimport { findMapping, loadSyncState, saveSyncState, upsertMapping } from \"./sync-state.js\";\nimport type { BoardIssue, PickResult, Task } from \"./types.js\";\nimport { Priority } from \"./types.js\";\n\nconst ISSUE_REF_PATTERN = /^([a-zA-Z0-9_.-]+)\\/(\\d+)$/;\n\nexport interface ParsedIssueRef {\n repo: RepoConfig;\n issueNumber: number;\n}\n\nexport function parseIssueRef(input: string, config: HogConfig): ParsedIssueRef {\n const match = input.match(ISSUE_REF_PATTERN);\n if (!(match?.[1] && match[2])) {\n throw new Error(\"Invalid format. Use: shortName/number (e.g., myrepo/145)\");\n }\n\n const repoShortName = match[1];\n const repo = findRepo(config, repoShortName);\n if (!repo) {\n throw new Error(`Unknown repo \"${repoShortName}\". Run: hog config repos`);\n }\n\n const num = Number.parseInt(match[2], 10);\n if (num < 1 || num > 999999) {\n throw new Error(\"Invalid issue number\");\n }\n\n return { repo, issueNumber: num };\n}\n\nfunction appendWarning(existing: string | undefined, addition: string): string {\n return existing ? `${existing}. ${addition}` : addition;\n}\n\nfunction mapPriority(labels: readonly string[]): Priority {\n for (const label of labels) {\n if (label === \"priority:critical\" || label === \"priority:high\") return Priority.High;\n if (label === \"priority:medium\") return Priority.Medium;\n if (label === \"priority:low\") return Priority.Low;\n }\n return Priority.None;\n}\n\nfunction toBoardIssue(issue: GitHubIssue, repoName: string): BoardIssue {\n return {\n number: issue.number,\n title: issue.title,\n url: issue.url,\n state: issue.state,\n assignee: issue.assignees?.[0]?.login ?? null,\n labels: issue.labels.map((l) => l.name),\n updatedAt: issue.updatedAt,\n repo: repoName,\n };\n}\n\nasync function syncToTickTick(\n repo: RepoConfig,\n issue: GitHubIssue,\n boardIssue: BoardIssue,\n): Promise<{ task?: Task; warning?: string }> {\n const state = loadSyncState();\n const existing = findMapping(state, repo.name, issue.number);\n\n if (existing) {\n return { warning: \"TickTick task already exists from sync.\" };\n }\n\n const auth = requireAuth();\n const api = new TickTickClient(auth.accessToken);\n const projectFields = fetchProjectFields(repo.name, issue.number, repo.projectNumber);\n\n const input = {\n title: issue.title,\n content: `GitHub: ${issue.url}`,\n priority: mapPriority(boardIssue.labels),\n tags: [\"github\", repo.shortName],\n ...(projectFields.targetDate ? { dueDate: projectFields.targetDate, isAllDay: true } : {}),\n };\n\n const task = await api.createTask(input);\n\n upsertMapping(state, {\n githubRepo: repo.name,\n githubIssueNumber: issue.number,\n githubUrl: issue.url,\n ticktickTaskId: task.id,\n ticktickProjectId: task.projectId,\n githubUpdatedAt: issue.updatedAt,\n lastSyncedAt: new Date().toISOString(),\n });\n saveSyncState(state);\n\n return { task };\n}\n\nexport async function pickIssue(config: HogConfig, ref: ParsedIssueRef): Promise<PickResult> {\n const { repo, issueNumber } = ref;\n\n // 1. Fetch open issues and find the target\n const allIssues = fetchRepoIssues(repo.name, { state: \"open\", limit: 200 });\n const issue = allIssues.find((i) => i.number === issueNumber);\n\n if (!issue) {\n throw new Error(`Issue #${issueNumber} not found in ${repo.name}. Is it open?`);\n }\n\n const boardIssue = toBoardIssue(issue, repo.name);\n let warning: string | undefined;\n\n // 2. Check if already assigned\n if (boardIssue.assignee === config.board.assignee) {\n warning = \"Issue is already assigned to you\";\n } else if (boardIssue.assignee) {\n warning = `Issue is currently assigned to ${boardIssue.assignee}. Reassigning to you.`;\n }\n\n // 3. Assign on GitHub\n assignIssue(repo.name, issueNumber);\n\n // 4. Try to create TickTick task (non-critical — log warning on failure)\n let ticktickTask: Task | undefined;\n try {\n const result = await syncToTickTick(repo, issue, boardIssue);\n ticktickTask = result.task;\n if (result.warning) {\n warning = appendWarning(warning, result.warning);\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n warning = appendWarning(warning, `TickTick sync failed: ${msg}. Run 'hog sync run' to retry.`);\n }\n\n return {\n success: true,\n issue: boardIssue,\n ...(ticktickTask ? { ticktickTask } : {}),\n ...(warning ? { warning } : {}),\n } satisfies PickResult;\n}\n","/**\n * Returns the clipboard command args for the current platform/environment,\n * or null if no clipboard tool is available.\n *\n * Detection order: WSL → Wayland → X11 → macOS/Windows → null\n */\nexport function getClipboardArgs(): readonly string[] | null {\n if (process.platform === \"darwin\") return [\"pbcopy\"] as const;\n if (process.platform === \"win32\") return [\"clip\"] as const;\n // WSL: check both vars — WSL_DISTRO_NAME is unset for root users\n if (process.env[\"WSL_DISTRO_NAME\"] ?? process.env[\"WSL_INTEROP\"]) return [\"clip.exe\"] as const;\n // Wayland before X11 (wl-copy, not xclip which has a pipe-hang bug)\n if (process.env[\"WAYLAND_DISPLAY\"]) return [\"wl-copy\"] as const;\n // X11: use xsel (NOT xclip — known pipe-hang bug when no clipboard manager)\n if (process.env[\"DISPLAY\"]) return [\"xsel\", \"--clipboard\", \"--input\"] as const;\n return null;\n}\n","import { useCallback, useRef, useState } from \"react\";\nimport { appendActionLog } from \"../../log-persistence.js\";\nimport type { ToastAPI } from \"./use-toast.js\";\n\n// ── Types ──\n\nexport interface ActionLogEntry {\n readonly id: string;\n readonly description: string;\n readonly status: \"success\" | \"error\" | \"pending\";\n readonly ago: number;\n /** undefined = not undoable */\n readonly undo?: () => Promise<void>;\n /** retry callback for error entries */\n readonly retry?: () => void;\n}\n\nexport interface UseActionLogResult {\n entries: ActionLogEntry[];\n pushEntry: (entry: ActionLogEntry) => void;\n undoLast: () => Promise<void>;\n hasUndoable: boolean;\n}\n\nlet entryIdCounter = 0;\nexport function nextEntryId(): string {\n entryIdCounter += 1;\n return String(entryIdCounter);\n}\n\n/** Reset the entry ID counter — call in beforeEach to ensure deterministic IDs in tests. */\nexport function resetEntryIdCounter(): void {\n entryIdCounter = 0;\n}\n\nexport function useActionLog(toast: ToastAPI, refresh: () => void): UseActionLogResult {\n const [entries, setEntries] = useState<ActionLogEntry[]>([]);\n // Stable ref so undoLast doesn't depend on entries in its dependency array\n const entriesRef = useRef<ActionLogEntry[]>([]);\n entriesRef.current = entries;\n\n const pushEntry = useCallback((entry: ActionLogEntry) => {\n setEntries((prev) => [...prev.slice(-9), entry]); // keep last 10 in memory\n // Persist to disk (best-effort)\n try {\n appendActionLog({\n id: entry.id,\n description: entry.description,\n status: entry.status,\n timestamp: entry.ago,\n });\n } catch {\n // ignore persistence errors\n }\n }, []);\n\n const undoLast = useCallback(async () => {\n const undoable = [...entriesRef.current].reverse().find((e) => e.undo);\n if (!undoable?.undo) {\n toast.info(\"Nothing to undo\");\n return;\n }\n const thunk = undoable.undo;\n // Clear BEFORE execution to prevent double-undo window (omit undo property entirely)\n setEntries((prev) =>\n prev.map((e) => {\n if (e.id !== undoable.id) return e;\n // Omit the undo property to satisfy exactOptionalPropertyTypes\n const { undo: _removed, ...rest } = e;\n return rest;\n }),\n );\n const t = toast.loading(`Undoing: ${undoable.description}`);\n try {\n await thunk();\n t.resolve(`Undone: ${undoable.description}`);\n } catch (err) {\n t.reject(`Undo failed: ${err instanceof Error ? err.message : String(err)}`);\n refresh(); // revert optimistic state\n }\n }, [toast, refresh]);\n\n const hasUndoable = entries.some((e) => !!e.undo);\n\n return { entries, pushEntry, undoLast, hasUndoable };\n}\n","import { useCallback, useRef } from \"react\";\nimport type { HogConfig, RepoConfig } from \"../../config.js\";\nimport type {\n GitHubIssue,\n RepoDueDateConfig,\n RepoProjectConfig,\n StatusOption,\n} from \"../../github.js\";\nimport {\n addCommentAsync,\n addLabelAsync,\n assignIssueAsync,\n closeIssueAsync,\n createIssueAsync,\n unassignIssueAsync,\n updateLabelsAsync,\n updateProjectItemDateAsync,\n updateProjectItemStatusAsync,\n} from \"../../github.js\";\nimport { pickIssue } from \"../../pick.js\";\nimport { TERMINAL_STATUS_RE } from \"../constants.js\";\nimport type { DashboardData, RepoData } from \"../fetch.js\";\nimport type { ActionLogEntry } from \"./use-action-log.js\";\nimport { nextEntryId } from \"./use-action-log.js\";\nimport type { ToastAPI } from \"./use-toast.js\";\n\n// ── Types ──\n\nexport interface ActionContext {\n /** Currently selected issue (null if header or task) */\n issue: GitHubIssue | null;\n /** Repo name for the selected issue */\n repoName: string | null;\n /** Repo config for the selected issue */\n repoConfig: RepoConfig | null;\n /** Status options for the selected issue's repo */\n statusOptions: StatusOption[];\n}\n\nexport interface UseActionsResult {\n handlePick: () => void;\n handleComment: (body: string) => void;\n handleStatusChange: (optionId: string) => void;\n handleAssign: () => void;\n handleLabelChange: (addLabels: string[], removeLabels: string[]) => void;\n handleCreateIssue: (\n repo: string,\n title: string,\n body: string,\n dueDate?: string | null,\n labels?: string[],\n ) => Promise<{ repo: string; issueNumber: number } | null>;\n /** Bulk actions — return failed IDs (empty = all succeeded) */\n handleBulkAssign: (ids: ReadonlySet<string>) => Promise<string[]>;\n handleBulkUnassign: (ids: ReadonlySet<string>) => Promise<string[]>;\n handleBulkStatusChange: (ids: ReadonlySet<string>, optionId: string) => Promise<string[]>;\n}\n\ninterface UseActionsOptions {\n config: HogConfig;\n repos: RepoData[];\n selectedId: string | null;\n toast: ToastAPI;\n mutateData: (fn: (data: DashboardData) => DashboardData) => void;\n refresh: (silent?: boolean) => void;\n onOverlayDone: () => void;\n pushEntry?: (entry: ActionLogEntry) => void;\n registerPendingMutation?: (\n repoName: string,\n issueNumber: number,\n fields: { projectStatus?: string },\n ) => void;\n clearPendingMutation?: (repoName: string, issueNumber: number) => void;\n}\n\n// ── Helpers ──\n\nfunction findIssueContext(\n repos: RepoData[],\n selectedId: string | null,\n config: HogConfig,\n): ActionContext {\n if (!selectedId?.startsWith(\"gh:\")) {\n return { issue: null, repoName: null, repoConfig: null, statusOptions: [] };\n }\n\n for (const rd of repos) {\n for (const issue of rd.issues) {\n if (`gh:${rd.repo.name}:${issue.number}` === selectedId) {\n const repoConfig = config.repos.find((r) => r.name === rd.repo.name) ?? null;\n return { issue, repoName: rd.repo.name, repoConfig, statusOptions: rd.statusOptions };\n }\n }\n }\n return { issue: null, repoName: null, repoConfig: null, statusOptions: [] };\n}\n\n// ── Hook ──\n\n/** Trigger the configured completion action for a repo when moving to terminal status */\nasync function triggerCompletionActionAsync(\n action: RepoConfig[\"completionAction\"],\n repoName: string,\n issueNumber: number,\n): Promise<void> {\n switch (action.type) {\n case \"closeIssue\":\n await closeIssueAsync(repoName, issueNumber);\n break;\n case \"addLabel\":\n await addLabelAsync(repoName, issueNumber, action.label);\n break;\n case \"updateProjectStatus\":\n // This would require additional project config (optionId for the target status).\n // The user already changed the status, so this is a no-op.\n break;\n }\n}\n\n/** Apply optimistic status updates and register pending mutations for a set of issue IDs. */\nfunction applyBulkOptimisticStatusUpdates(\n ids: ReadonlySet<string>,\n optionId: string,\n repos: RepoData[],\n config: HogConfig,\n mutateData: (fn: (data: DashboardData) => DashboardData) => void,\n registerPendingMutation:\n | ((repoName: string, issueNumber: number, fields: { projectStatus?: string }) => void)\n | undefined,\n): void {\n for (const id of ids) {\n const ctx = findIssueContext(repos, id, config);\n if (!(ctx.issue && ctx.repoName)) continue;\n const { issue: ctxIssue, repoName: ctxRepo, statusOptions: ctxOpts } = ctx;\n mutateData((data) => optimisticSetStatus(data, ctxRepo, ctxIssue.number, ctxOpts, optionId));\n const ctxStatusName = ctxOpts.find((o) => o.id === optionId)?.name;\n if (ctxStatusName) {\n registerPendingMutation?.(ctxRepo, ctxIssue.number, { projectStatus: ctxStatusName });\n }\n }\n}\n\n/** Find the display name of a status option from any issue in the given id set. */\nfunction resolveOptionName(\n repos: RepoData[],\n ids: ReadonlySet<string>,\n config: HogConfig,\n optionId: string,\n): string {\n for (const id of ids) {\n const name = findIssueContext(repos, id, config).statusOptions.find(\n (o) => o.id === optionId,\n )?.name;\n if (name) return name;\n }\n return optionId;\n}\n\n/** Clear pending mutations for a list of failed issue IDs (format: \"gh:repo:number\"). */\nfunction clearFailedMutations(\n failedIds: string[],\n clearFn: ((repoName: string, issueNumber: number) => void) | undefined,\n): void {\n if (!clearFn) return;\n for (const failedId of failedIds) {\n const lastColon = failedId.lastIndexOf(\":\");\n const failedRepo = failedId.slice(3, lastColon); // strip leading \"gh:\"\n const failedIssueNumber = parseInt(failedId.slice(lastColon + 1), 10);\n clearFn(failedRepo, failedIssueNumber);\n }\n}\n\n/** Helper: optimistically set projectStatus on an issue in local data */\nfunction optimisticSetStatus(\n data: DashboardData,\n repoName: string,\n issueNumber: number,\n statusOptions: StatusOption[],\n optionId: string,\n): DashboardData {\n const statusName = statusOptions.find((o) => o.id === optionId)?.name;\n if (!statusName) return data;\n\n return {\n ...data,\n repos: data.repos.map((rd) => {\n if (rd.repo.name !== repoName) return rd;\n return {\n ...rd,\n issues: rd.issues.map((issue) =>\n issue.number === issueNumber ? { ...issue, projectStatus: statusName } : issue,\n ),\n };\n }),\n };\n}\n\nexport function useActions({\n config,\n repos,\n selectedId,\n toast,\n refresh,\n mutateData,\n onOverlayDone,\n pushEntry,\n registerPendingMutation,\n clearPendingMutation,\n}: UseActionsOptions): UseActionsResult {\n // Use refs so callbacks don't need to depend on frequently-changing values\n const configRef = useRef(config);\n const reposRef = useRef(repos);\n const selectedIdRef = useRef(selectedId);\n const pushEntryRef = useRef(pushEntry);\n const registerPendingMutationRef = useRef(registerPendingMutation);\n const clearPendingMutationRef = useRef(clearPendingMutation);\n configRef.current = config;\n reposRef.current = repos;\n selectedIdRef.current = selectedId;\n pushEntryRef.current = pushEntry;\n registerPendingMutationRef.current = registerPendingMutation;\n clearPendingMutationRef.current = clearPendingMutation;\n\n const handlePick = useCallback(() => {\n const ctx = findIssueContext(reposRef.current, selectedIdRef.current, configRef.current);\n if (!(ctx.issue && ctx.repoConfig)) return;\n\n const { issue, repoConfig } = ctx;\n const assignees = issue.assignees ?? [];\n if (assignees.some((a) => a.login === configRef.current.board.assignee)) {\n toast.info(`Already assigned to @${configRef.current.board.assignee}`);\n return;\n }\n const firstAssignee = assignees[0];\n if (firstAssignee) {\n toast.info(`Already assigned to @${firstAssignee.login}`);\n return;\n }\n\n const t = toast.loading(`Picking ${repoConfig.shortName}#${issue.number}...`);\n pickIssue(configRef.current, { repo: repoConfig, issueNumber: issue.number })\n .then((result) => {\n const msg = `Picked ${repoConfig.shortName}#${issue.number} — assigned + synced to TickTick`;\n t.resolve(result.warning ? `${msg} (${result.warning})` : msg);\n refresh();\n })\n .catch((err) => {\n t.reject(`Pick failed: ${err instanceof Error ? err.message : String(err)}`);\n });\n }, [toast, refresh]);\n\n const handleComment = useCallback(\n (body: string) => {\n const ctx = findIssueContext(reposRef.current, selectedIdRef.current, configRef.current);\n if (!(ctx.issue && ctx.repoName)) {\n onOverlayDone();\n return;\n }\n\n const { issue, repoName } = ctx;\n const t = toast.loading(\"Commenting...\");\n addCommentAsync(repoName, issue.number, body)\n .then(() => {\n t.resolve(`Comment posted on #${issue.number}`);\n pushEntryRef.current?.({\n id: nextEntryId(),\n description: `comment on #${issue.number}`,\n status: \"success\",\n ago: Date.now(),\n });\n refresh();\n onOverlayDone();\n })\n .catch((err) => {\n t.reject(`Comment failed: ${err instanceof Error ? err.message : String(err)}`);\n pushEntryRef.current?.({\n id: nextEntryId(),\n description: `comment on #${issue.number} failed`,\n status: \"error\",\n ago: Date.now(),\n });\n });\n },\n [toast, refresh, onOverlayDone],\n );\n\n const handleStatusChange = useCallback(\n (optionId: string) => {\n const ctx = findIssueContext(reposRef.current, selectedIdRef.current, configRef.current);\n if (!(ctx.issue && ctx.repoName && ctx.repoConfig)) {\n onOverlayDone();\n return;\n }\n\n const { issue, repoName, repoConfig, statusOptions } = ctx;\n\n // Capture the inverse synchronously before the async mutation (undo thunk)\n const previousOptionId = statusOptions.find((o) => o.name === issue.projectStatus)?.id;\n const undoThunk = previousOptionId\n ? async () => {\n mutateData((data) =>\n optimisticSetStatus(data, repoName, issue.number, statusOptions, previousOptionId),\n );\n const undoProjectConfig: RepoProjectConfig = {\n projectNumber: repoConfig.projectNumber,\n statusFieldId: repoConfig.statusFieldId,\n optionId: previousOptionId,\n };\n await updateProjectItemStatusAsync(repoName, issue.number, undoProjectConfig);\n }\n : undefined;\n\n // Optimistic update: move issue to new section immediately\n mutateData((data) =>\n optimisticSetStatus(data, repoName, issue.number, statusOptions, optionId),\n );\n // Register a pending mutation so subsequent refreshes (e.g. triggered by\n // assign) don't revert this status change before GitHub propagates it.\n const statusName = statusOptions.find((o) => o.id === optionId)?.name;\n if (statusName) {\n registerPendingMutationRef.current?.(repoName, issue.number, {\n projectStatus: statusName,\n });\n }\n\n const t = toast.loading(\"Moving...\");\n const projectConfig: RepoProjectConfig = {\n projectNumber: repoConfig.projectNumber,\n statusFieldId: repoConfig.statusFieldId,\n optionId,\n };\n\n updateProjectItemStatusAsync(repoName, issue.number, projectConfig)\n .then(async () => {\n const optionName = statusOptions.find((o) => o.id === optionId)?.name ?? optionId;\n\n // If terminal status, trigger completion action\n if (TERMINAL_STATUS_RE.test(optionName) && repoConfig.completionAction) {\n try {\n await triggerCompletionActionAsync(\n repoConfig.completionAction,\n repoName,\n issue.number,\n );\n t.resolve(\n `#${issue.number} \\u2192 ${optionName} (${repoConfig.completionAction.type})`,\n );\n } catch {\n toast.info(`#${issue.number} \\u2192 ${optionName} (completion action failed)`);\n }\n } else {\n t.resolve(`#${issue.number} \\u2192 ${optionName}`);\n }\n pushEntryRef.current?.({\n id: nextEntryId(),\n description: `#${issue.number} \\u2192 ${optionName}`,\n status: \"success\",\n ago: Date.now(),\n ...(undoThunk ? { undo: undoThunk } : {}),\n });\n // Do NOT refresh here — GitHub Projects v2 GraphQL is eventually consistent\n })\n .catch((err) => {\n t.reject(`Status change failed: ${err instanceof Error ? err.message : String(err)}`);\n pushEntryRef.current?.({\n id: nextEntryId(),\n description: `#${issue.number} status change failed`,\n status: \"error\",\n ago: Date.now(),\n });\n // Clear the pending mutation before reverting so the refresh fetches server state\n clearPendingMutationRef.current?.(repoName, issue.number);\n refresh(); // revert optimistic update on failure\n })\n .finally(() => {\n onOverlayDone();\n });\n },\n [toast, refresh, mutateData, onOverlayDone],\n );\n\n const handleAssign = useCallback(() => {\n const ctx = findIssueContext(reposRef.current, selectedIdRef.current, configRef.current);\n if (!(ctx.issue && ctx.repoName)) return;\n\n const { issue, repoName } = ctx;\n const assignees = issue.assignees ?? [];\n if (assignees.some((a) => a.login === configRef.current.board.assignee)) {\n toast.info(`Already assigned to @${configRef.current.board.assignee}`);\n return;\n }\n const firstAssignee = assignees[0];\n if (firstAssignee) {\n toast.info(`Already assigned to @${firstAssignee.login}`);\n return;\n }\n\n const t = toast.loading(\"Assigning...\");\n assignIssueAsync(repoName, issue.number)\n .then(() => {\n t.resolve(`Assigned #${issue.number} to @${configRef.current.board.assignee}`);\n pushEntryRef.current?.({\n id: nextEntryId(),\n description: `#${issue.number} assigned`,\n status: \"success\",\n ago: Date.now(),\n undo: async () => {\n await unassignIssueAsync(repoName, issue.number, \"@me\");\n },\n });\n refresh();\n })\n .catch((err) => {\n t.reject(`Assign failed: ${err instanceof Error ? err.message : String(err)}`);\n pushEntryRef.current?.({\n id: nextEntryId(),\n description: `#${issue.number} assign failed`,\n status: \"error\",\n ago: Date.now(),\n });\n });\n }, [toast, refresh]);\n\n const handleCreateIssue = useCallback(\n async (\n repo: string,\n title: string,\n body: string,\n dueDate?: string | null,\n labels?: string[],\n ): Promise<{ repo: string; issueNumber: number } | null> => {\n const repoConfig = configRef.current.repos.find((r) => r.name === repo);\n\n // If due date but no project date field configured, fall back to body text\n let effectiveBody = body;\n if (dueDate && !repoConfig?.dueDateFieldId) {\n const dueLine = `Due: ${dueDate}`;\n effectiveBody = body ? `${body}\\n\\n${dueLine}` : dueLine;\n }\n\n const t = toast.loading(\"Creating...\");\n try {\n const output = await createIssueAsync(repo, title, effectiveBody, labels);\n\n // gh issue create returns the URL of the new issue\n const match = output.match(/\\/(\\d+)$/);\n const issueNumber = match?.[1] ? parseInt(match[1], 10) : 0;\n const shortName = repoConfig?.shortName ?? repo;\n\n // If due date field configured, set it on the project item (best-effort)\n if (issueNumber > 0 && dueDate && repoConfig?.dueDateFieldId) {\n const dueDateConfig: RepoDueDateConfig = {\n projectNumber: repoConfig.projectNumber,\n dueDateFieldId: repoConfig.dueDateFieldId,\n };\n updateProjectItemDateAsync(repo, issueNumber, dueDateConfig, dueDate).catch(() => {\n // best-effort: don't fail the whole create if date field update fails\n });\n }\n\n t.resolve(`Created ${shortName}#${issueNumber}`);\n refresh();\n onOverlayDone();\n return issueNumber > 0 ? { repo, issueNumber } : null;\n } catch (err) {\n t.reject(`Create failed: ${err instanceof Error ? err.message : String(err)}`);\n onOverlayDone();\n return null;\n }\n },\n [toast, refresh, onOverlayDone],\n );\n\n const handleLabelChange = useCallback(\n (addLabels: string[], removeLabels: string[]) => {\n const ctx = findIssueContext(reposRef.current, selectedIdRef.current, configRef.current);\n if (!(ctx.issue && ctx.repoName)) return;\n const { issue, repoName } = ctx;\n\n const t = toast.loading(\"Updating labels...\");\n updateLabelsAsync(repoName, issue.number, addLabels, removeLabels)\n .then(() => {\n t.resolve(`Labels updated on #${issue.number}`);\n refresh();\n onOverlayDone();\n })\n .catch((err) => {\n t.reject(`Label update failed: ${err instanceof Error ? err.message : String(err)}`);\n onOverlayDone();\n });\n },\n [toast, refresh, onOverlayDone],\n );\n\n // ── Bulk actions ──\n // Each returns an array of IDs that failed (empty = all succeeded)\n\n const handleBulkAssign = useCallback(\n async (ids: ReadonlySet<string>): Promise<string[]> => {\n const failed: string[] = [];\n const t = toast.loading(`Assigning ${ids.size} issue${ids.size > 1 ? \"s\" : \"\"}...`);\n for (const id of ids) {\n const ctx = findIssueContext(reposRef.current, id, configRef.current);\n if (!(ctx.issue && ctx.repoName)) {\n failed.push(id);\n continue;\n }\n\n const assignees = ctx.issue.assignees ?? [];\n if (assignees.some((a) => a.login === configRef.current.board.assignee)) continue; // already assigned, skip\n\n try {\n await assignIssueAsync(ctx.repoName, ctx.issue.number);\n } catch {\n failed.push(id);\n }\n }\n const total = ids.size;\n const ok = total - failed.length;\n if (failed.length === 0) {\n t.resolve(\n `Assigned ${total} issue${total > 1 ? \"s\" : \"\"} to @${configRef.current.board.assignee}`,\n );\n } else {\n t.reject(`${ok} assigned, ${failed.length} failed`);\n }\n refresh();\n return failed;\n },\n [toast, refresh],\n );\n\n const handleBulkUnassign = useCallback(\n async (ids: ReadonlySet<string>): Promise<string[]> => {\n const failed: string[] = [];\n const t = toast.loading(`Unassigning ${ids.size} issue${ids.size > 1 ? \"s\" : \"\"}...`);\n for (const id of ids) {\n const ctx = findIssueContext(reposRef.current, id, configRef.current);\n if (!(ctx.issue && ctx.repoName)) {\n failed.push(id);\n continue;\n }\n\n const assignees = ctx.issue.assignees ?? [];\n if (!assignees.some((a) => a.login === configRef.current.board.assignee)) continue; // not self-assigned, skip\n\n try {\n await unassignIssueAsync(ctx.repoName, ctx.issue.number, \"@me\");\n } catch {\n failed.push(id);\n }\n }\n const total = ids.size;\n const ok = total - failed.length;\n if (failed.length === 0) {\n t.resolve(`Unassigned ${total} issue${total > 1 ? \"s\" : \"\"}`);\n } else {\n t.reject(`${ok} unassigned, ${failed.length} failed`);\n }\n refresh();\n return failed;\n },\n [toast, refresh],\n );\n\n const handleBulkStatusChange = useCallback(\n async (ids: ReadonlySet<string>, optionId: string): Promise<string[]> => {\n // Optimistic update: move all issues to new section immediately, register pending mutations\n applyBulkOptimisticStatusUpdates(\n ids,\n optionId,\n reposRef.current,\n configRef.current,\n mutateData,\n registerPendingMutationRef.current,\n );\n\n const t = toast.loading(`Moving ${ids.size} issue${ids.size > 1 ? \"s\" : \"\"}...`);\n const failed: string[] = [];\n for (const id of ids) {\n const ctx = findIssueContext(reposRef.current, id, configRef.current);\n if (!(ctx.issue && ctx.repoName && ctx.repoConfig)) {\n failed.push(id);\n continue;\n }\n\n try {\n const projectConfig: RepoProjectConfig = {\n projectNumber: ctx.repoConfig.projectNumber,\n statusFieldId: ctx.repoConfig.statusFieldId,\n optionId,\n };\n await updateProjectItemStatusAsync(ctx.repoName, ctx.issue.number, projectConfig);\n } catch {\n failed.push(id);\n }\n }\n const total = ids.size;\n const ok = total - failed.length;\n const optionName = resolveOptionName(reposRef.current, ids, configRef.current, optionId);\n if (failed.length === 0) {\n t.resolve(`Moved ${total} issue${total > 1 ? \"s\" : \"\"} to ${optionName}`);\n // Do not refresh — same eventual-consistency issue as single status change.\n // Pending mutations will preserve the optimistic state across auto-refreshes.\n } else {\n t.reject(`${ok} moved to ${optionName}, ${failed.length} failed`);\n // Clear pending mutations for failed issues so the refresh fetches their server state\n clearFailedMutations(failed, clearPendingMutationRef.current);\n refresh(); // revert optimistic updates for failed items\n }\n return failed;\n },\n [toast, refresh, mutateData],\n );\n\n return {\n handlePick,\n handleComment,\n handleStatusChange,\n handleAssign,\n handleLabelChange,\n handleCreateIssue,\n handleBulkAssign,\n handleBulkUnassign,\n handleBulkStatusChange,\n };\n}\n\nexport { findIssueContext };\n","import { Worker } from \"node:worker_threads\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { HogConfig } from \"../../config.js\";\nimport type { DashboardData, FetchOptions } from \"../fetch.js\";\n\nexport type DataStatus = \"loading\" | \"success\" | \"error\";\n\n/** Fields that can be held as pending optimistic overrides until the server reflects them. */\nexport interface PendingMutation {\n projectStatus?: string;\n expiresAt: number; // Date.now() + TTL\n}\n\n/** Apply any non-expired pending mutations on top of fresh server data. */\nfunction applyPendingMutations(\n data: DashboardData,\n pending: Map<string, PendingMutation>,\n): DashboardData {\n const now = Date.now();\n // Expire stale entries\n for (const [key, m] of pending) {\n if (m.expiresAt <= now) pending.delete(key);\n }\n if (pending.size === 0) return data;\n\n return {\n ...data,\n repos: data.repos.map((rd) => ({\n ...rd,\n issues: rd.issues.map((issue) => {\n const mutation = pending.get(`${rd.repo.name}:${issue.number}`);\n if (!mutation || mutation.expiresAt <= now) return issue;\n return mutation.projectStatus !== undefined\n ? { ...issue, projectStatus: mutation.projectStatus }\n : issue;\n }),\n })),\n };\n}\n\nexport interface DataState {\n status: DataStatus;\n data: DashboardData | null;\n error: string | null;\n lastRefresh: Date | null;\n isRefreshing: boolean;\n consecutiveFailures: number;\n autoRefreshPaused: boolean;\n}\n\nconst INITIAL_STATE: DataState = {\n status: \"loading\",\n data: null,\n error: null,\n lastRefresh: null,\n isRefreshing: false,\n consecutiveFailures: 0,\n autoRefreshPaused: false,\n};\n\n/** Stale thresholds for refresh age color */\nexport const STALE_THRESHOLDS = {\n FRESH: 60_000, // 0-60s → green\n AGING: 300_000, // 60s-5m → yellow\n // 5m+ → red\n} as const;\n\n/** Maximum consecutive failures before pausing auto-refresh */\nexport const MAX_REFRESH_FAILURES = 3;\n\n/** Compute age color based on time since last refresh */\nexport function refreshAgeColor(lastRefresh: Date | null): \"green\" | \"yellow\" | \"red\" | \"gray\" {\n if (!lastRefresh) return \"gray\";\n const age = Date.now() - lastRefresh.getTime();\n if (age < STALE_THRESHOLDS.FRESH) return \"green\";\n if (age < STALE_THRESHOLDS.AGING) return \"yellow\";\n return \"red\";\n}\n\n/** Discriminated union for worker messages */\ntype WorkerMessage = { type: \"success\"; data: DashboardData } | { type: \"error\"; error: string };\n\n/** Return type of the useData hook */\nexport type UseDataResult = DataState & {\n refresh: (silent?: boolean) => void;\n mutateData: (updater: (prev: DashboardData) => DashboardData) => void;\n pauseAutoRefresh: () => void;\n resumeAutoRefresh: () => void;\n registerPendingMutation: (\n repoName: string,\n issueNumber: number,\n fields: Pick<PendingMutation, \"projectStatus\">,\n ttlMs?: number,\n ) => void;\n clearPendingMutation: (repoName: string, issueNumber: number) => void;\n};\n\nexport function useData(\n config: HogConfig,\n options: FetchOptions,\n refreshIntervalMs: number,\n): UseDataResult {\n const [state, setState] = useState<DataState>(INITIAL_STATE);\n const activeRequestRef = useRef<{ canceled: boolean } | null>(null);\n const workerRef = useRef<Worker | null>(null);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const pendingMutationsRef = useRef<Map<string, PendingMutation>>(new Map());\n\n // Store config/options in refs so refresh callback is stable\n const configRef = useRef(config);\n const optionsRef = useRef(options);\n configRef.current = config;\n optionsRef.current = options;\n\n /**\n * Trigger a data refresh.\n * Pass `silent = true` for background auto-refreshes to avoid showing the\n * loading spinner (eliminates one re-render per cycle and prevents blinking).\n */\n const refresh = useCallback((silent = false) => {\n // Cancel any in-flight request\n if (activeRequestRef.current) {\n activeRequestRef.current.canceled = true;\n }\n workerRef.current?.terminate();\n\n const token = { canceled: false };\n activeRequestRef.current = token;\n\n if (!silent) {\n setState((prev) => ({ ...prev, isRefreshing: true }));\n }\n\n const worker = new Worker(\n new URL(\n import.meta.url.endsWith(\".ts\")\n ? \"../fetch-worker.ts\" // dev: tsx running source\n : \"./fetch-worker.js\", // prod: tsup bundle in dist/\n import.meta.url,\n ),\n { workerData: { config: configRef.current, options: optionsRef.current } },\n );\n workerRef.current = worker;\n\n worker.on(\"message\", (rawMsg) => {\n const msg = rawMsg as WorkerMessage;\n if (token.canceled) {\n worker.terminate();\n return;\n }\n\n if (msg.type === \"success\" && msg.data) {\n // Revive Date objects (structured clone preserves them, but defensive)\n const raw = msg.data;\n raw.fetchedAt = new Date(raw.fetchedAt);\n for (const ev of raw.activity) {\n ev.timestamp = new Date(ev.timestamp);\n }\n // Apply any pending optimistic overrides so a refresh triggered by\n // an unrelated action (e.g. assign) doesn't revert a status change\n // that GitHub Projects v2 hasn't propagated yet.\n const data = applyPendingMutations(raw, pendingMutationsRef.current);\n\n setState({\n status: \"success\",\n data,\n error: null,\n lastRefresh: new Date(),\n isRefreshing: false,\n consecutiveFailures: 0,\n autoRefreshPaused: false,\n });\n } else if (msg.type === \"error\") {\n setState((prev) => {\n const failures = prev.consecutiveFailures + 1;\n return {\n ...prev,\n status: prev.data ? \"success\" : \"error\",\n error: msg.error,\n isRefreshing: false,\n consecutiveFailures: failures,\n autoRefreshPaused: failures >= MAX_REFRESH_FAILURES,\n };\n });\n }\n worker.terminate();\n });\n\n worker.on(\"error\", (err) => {\n if (token.canceled) return;\n setState((prev) => {\n const failures = prev.consecutiveFailures + 1;\n return {\n ...prev,\n status: prev.data ? \"success\" : \"error\",\n error: err.message,\n isRefreshing: false,\n consecutiveFailures: failures,\n autoRefreshPaused: failures >= MAX_REFRESH_FAILURES,\n };\n });\n });\n }, []);\n\n // Initial fetch — runs once on mount\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n // Auto-refresh interval — skips when paused\n const stateRef = useRef(state);\n stateRef.current = state;\n\n useEffect(() => {\n if (refreshIntervalMs <= 0) return;\n\n intervalRef.current = setInterval(() => {\n if (!stateRef.current.autoRefreshPaused) {\n refresh(true); // silent: skip isRefreshing spinner to avoid blinking\n }\n }, refreshIntervalMs);\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n }\n };\n }, [refresh, refreshIntervalMs]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (activeRequestRef.current) {\n activeRequestRef.current.canceled = true;\n }\n workerRef.current?.terminate();\n };\n }, []);\n\n /** Locally mutate data without fetching (for optimistic updates). */\n const mutateData = useCallback((fn: (data: DashboardData) => DashboardData) => {\n setState((prev) => {\n if (!prev.data) return prev;\n return { ...prev, data: fn(prev.data) };\n });\n }, []);\n\n const pauseAutoRefresh = useCallback(() => {\n setState((prev) => ({ ...prev, autoRefreshPaused: true }));\n }, []);\n\n const resumeAutoRefresh = useCallback(() => {\n setState((prev) => ({ ...prev, autoRefreshPaused: false }));\n }, []);\n\n /**\n * Register an optimistic override for an issue field.\n * The override survives refreshes for `ttlMs` ms (default 90 s), giving\n * GitHub Projects v2 time to propagate the change.\n */\n const registerPendingMutation = useCallback(\n (\n repoName: string,\n issueNumber: number,\n fields: Pick<PendingMutation, \"projectStatus\">,\n ttlMs = 90_000,\n ) => {\n pendingMutationsRef.current.set(`${repoName}:${issueNumber}`, {\n ...fields,\n expiresAt: Date.now() + ttlMs,\n });\n },\n [],\n );\n\n /** Remove a pending mutation immediately (call on action failure before refresh). */\n const clearPendingMutation = useCallback((repoName: string, issueNumber: number) => {\n pendingMutationsRef.current.delete(`${repoName}:${issueNumber}`);\n }, []);\n\n return {\n ...state,\n refresh,\n mutateData,\n pauseAutoRefresh,\n resumeAutoRefresh,\n registerPendingMutation,\n clearPendingMutation,\n };\n}\n","import { useInput } from \"ink\";\nimport { useCallback } from \"react\";\nimport type { GitHubIssue } from \"../../github.js\";\nimport type { UseMultiSelectResult } from \"./use-multi-select.js\";\nimport type { UseNavigationResult } from \"./use-navigation.js\";\nimport type { PanelId } from \"./use-panel-focus.js\";\nimport type { UseUIStateResult } from \"./use-ui-state.js\";\n\n// ── Types ──\n\ninterface KeyboardActions {\n exit: () => void;\n refresh: () => void;\n handleSlack: () => void;\n handleCopyLink: () => void;\n handleOpen: () => void;\n handleEnterFocus: () => void;\n handlePick: () => void;\n handleAssign: () => void;\n handleEnterLabel: () => void;\n handleEnterCreateNl: () => void;\n handleErrorAction: (action: \"dismiss\" | \"retry\") => boolean;\n toastInfo: (msg: string) => void;\n handleToggleMine: () => void;\n handleEnterFuzzyPicker: () => void;\n handleEnterEditIssue: () => void;\n handleUndo: () => void;\n handleToggleLog: () => void;\n}\n\ninterface PanelNav {\n moveUp: () => void;\n moveDown: () => void;\n}\n\ninterface UseKeyboardOptions {\n ui: UseUIStateResult;\n /** Issues panel (3) navigation */\n nav: Pick<UseNavigationResult, \"moveUp\" | \"moveDown\" | \"selectedId\">;\n multiSelect: Pick<UseMultiSelectResult, \"count\" | \"toggle\" | \"clear\">;\n selectedIssue: GitHubIssue | null;\n selectedRepoStatusOptionsLength: number;\n actions: KeyboardActions;\n onSearchEscape: () => void;\n panelFocus: { activePanelId: PanelId; focusPanel: (id: PanelId) => void };\n reposNav: PanelNav;\n statusesNav: PanelNav;\n activityNav: PanelNav;\n onRepoEnter: () => void;\n onStatusEnter: () => void;\n onActivityEnter: () => void;\n /** Whether the detail panel is visible as a side-by-side column (wide layout). */\n showDetailPanel: boolean;\n}\n\n/** Sets up all useInput keyboard handlers for the board. */\nexport function useKeyboard({\n ui,\n nav,\n multiSelect,\n selectedIssue,\n selectedRepoStatusOptionsLength,\n actions,\n onSearchEscape,\n panelFocus,\n reposNav,\n statusesNav,\n activityNav,\n onRepoEnter,\n onStatusEnter,\n onActivityEnter,\n showDetailPanel,\n}: UseKeyboardOptions): void {\n const {\n exit,\n refresh,\n handleSlack,\n handleCopyLink,\n handleOpen,\n handleEnterFocus,\n handlePick,\n handleAssign,\n handleEnterLabel,\n handleEnterCreateNl,\n handleErrorAction,\n toastInfo,\n handleToggleMine,\n handleEnterFuzzyPicker,\n handleEnterEditIssue,\n handleUndo,\n handleToggleLog,\n } = actions;\n\n const handleInput = useCallback(\n (\n input: string,\n key: {\n downArrow: boolean;\n upArrow: boolean;\n tab: boolean;\n shift: boolean;\n return: boolean;\n escape: boolean;\n },\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: keyboard handler with many shortcuts\n ) => {\n // Help toggle works in any state\n if (input === \"?\") {\n ui.toggleHelp();\n return;\n }\n\n // Escape: in multiSelect, clear selection and return to normal\n // In focus mode, FocusMode component handles Escape\n if (key.escape && ui.state.mode !== \"focus\") {\n if (ui.state.mode === \"multiSelect\") {\n multiSelect.clear();\n }\n ui.exitOverlay();\n return;\n }\n\n // Navigation (works in normal, multiSelect, focus)\n if (ui.canNavigate) {\n if (input === \"j\" || key.downArrow) {\n switch (panelFocus.activePanelId) {\n case 1:\n reposNav.moveDown();\n break;\n case 2:\n statusesNav.moveDown();\n break;\n case 3:\n nav.moveDown();\n break;\n case 4:\n activityNav.moveDown();\n break;\n default:\n break; // panel 0 (detail): no-op\n }\n return;\n }\n if (input === \"k\" || key.upArrow) {\n switch (panelFocus.activePanelId) {\n case 1:\n reposNav.moveUp();\n break;\n case 2:\n statusesNav.moveUp();\n break;\n case 3:\n nav.moveUp();\n break;\n case 4:\n activityNav.moveUp();\n break;\n default:\n break; // panel 0 (detail): no-op\n }\n return;\n }\n }\n\n // Multi-select mode actions\n if (ui.state.mode === \"multiSelect\") {\n // Space toggles selection on current item\n if (input === \" \") {\n const id = nav.selectedId;\n if (id) {\n multiSelect.toggle(id);\n }\n return;\n }\n // Enter opens bulk action menu when items are selected\n if (key.return) {\n if (multiSelect.count > 0) {\n ui.enterBulkAction();\n }\n return;\n }\n // 'm' in multiSelect with selection opens bulk action menu\n if (input === \"m\" && multiSelect.count > 0) {\n ui.enterBulkAction();\n return;\n }\n return; // No other actions in multiSelect mode\n }\n\n // Toast error actions (dismiss/retry) — work in normal mode\n if (input === \"d\") {\n if (handleErrorAction(\"dismiss\")) return;\n }\n if (input === \"r\" && handleErrorAction(\"retry\")) return;\n\n // Issue actions that also work from the detail overlay\n if (ui.canAct || ui.state.mode === \"overlay:detail\") {\n if (input === \"y\") {\n handleCopyLink();\n return;\n }\n if (input === \"o\") {\n handleSlack();\n return;\n }\n if (input === \"c\") {\n if (selectedIssue) {\n multiSelect.clear();\n ui.enterComment();\n }\n return;\n }\n if (input === \"e\") {\n if (selectedIssue) {\n handleEnterEditIssue();\n }\n return;\n }\n }\n\n // Actions (only in normal mode)\n if (ui.canAct) {\n // Digit 0-4: focus panel by number.\n // On narrow layouts digit 0 opens the detail overlay (panel is not visible).\n const digit = parseInt(input, 10);\n if (!Number.isNaN(digit) && digit >= 0 && digit <= 4) {\n if (digit === 0 && !showDetailPanel) {\n ui.enterDetail();\n } else {\n panelFocus.focusPanel(digit as PanelId);\n }\n return;\n }\n\n if (input === \"/\") {\n multiSelect.clear();\n ui.enterSearch();\n return;\n }\n if (input === \"q\") {\n exit();\n return;\n }\n if (input === \"r\" || input === \"R\") {\n multiSelect.clear();\n refresh();\n return;\n }\n if (input === \"p\") {\n handlePick();\n return;\n }\n if (input === \"a\") {\n handleAssign();\n return;\n }\n if (input === \"u\") {\n handleUndo();\n return;\n }\n if (input === \"L\") {\n handleToggleLog();\n return;\n }\n if (input === \"m\") {\n if (selectedIssue && selectedRepoStatusOptionsLength > 0) {\n multiSelect.clear();\n ui.enterStatus();\n } else if (selectedIssue) {\n toastInfo(\"Issue not in a project board\");\n }\n return;\n }\n if (input === \"n\") {\n multiSelect.clear();\n ui.enterCreate();\n return;\n }\n if (input === \"f\") {\n handleEnterFocus();\n return;\n }\n if (input === \"l\") {\n if (selectedIssue) {\n multiSelect.clear();\n handleEnterLabel();\n }\n return;\n }\n if (input === \"I\") {\n handleEnterCreateNl();\n return;\n }\n if (input === \"t\") {\n handleToggleMine();\n return;\n }\n if (input === \"F\") {\n handleEnterFuzzyPicker();\n return;\n }\n\n // Space on an item: toggle selection + enter multiSelect mode\n if (input === \" \") {\n const id = nav.selectedId;\n if (id) {\n multiSelect.toggle(id);\n ui.enterMultiSelect();\n }\n return;\n }\n\n if (key.return) {\n switch (panelFocus.activePanelId) {\n case 1:\n onRepoEnter();\n break;\n case 2:\n onStatusEnter();\n break;\n case 3:\n handleOpen();\n break;\n case 4:\n onActivityEnter();\n break;\n default:\n break; // panel 0 (detail): no-op\n }\n return;\n }\n }\n },\n [\n ui,\n nav,\n panelFocus,\n reposNav,\n statusesNav,\n activityNav,\n onRepoEnter,\n onStatusEnter,\n onActivityEnter,\n exit,\n refresh,\n handleSlack,\n handleCopyLink,\n handleOpen,\n handlePick,\n handleAssign,\n handleEnterLabel,\n handleEnterCreateNl,\n selectedIssue,\n selectedRepoStatusOptionsLength,\n toastInfo,\n nav.selectedId,\n multiSelect,\n handleEnterFocus,\n handleErrorAction,\n handleToggleMine,\n handleEnterFuzzyPicker,\n handleEnterEditIssue,\n handleUndo,\n handleToggleLog,\n showDetailPanel,\n ],\n );\n\n // Active when NOT in a text-input overlay.\n // overlay:detail needs Escape to close, so it must remain active.\n const inputActive =\n ui.state.mode === \"normal\" ||\n ui.state.mode === \"multiSelect\" ||\n ui.state.mode === \"focus\" ||\n ui.state.mode === \"overlay:detail\";\n useInput(handleInput, { isActive: inputActive });\n\n // Search mode input handler\n const handleSearchEscape = useCallback(\n (_input: string, key: { escape: boolean }) => {\n if (key.escape) {\n onSearchEscape();\n }\n },\n [onSearchEscape],\n );\n useInput(handleSearchEscape, { isActive: ui.state.mode === \"search\" });\n}\n","import { useCallback, useRef, useState } from \"react\";\n\nexport interface UseMultiSelectResult {\n /** Currently selected item IDs */\n selected: ReadonlySet<string>;\n /** How many items are selected */\n count: number;\n /** Whether a specific item is selected */\n isSelected: (id: string) => boolean;\n /** Toggle selection for one item. Returns the new set. */\n toggle: (id: string) => void;\n /** Clear all selections */\n clear: () => void;\n /** Remove selected IDs that are no longer in the valid set */\n prune: (validIds: ReadonlySet<string>) => void;\n /** The repo constraint — only items from this repo can be selected */\n constrainedRepo: string | null;\n}\n\n/**\n * Tracks multi-select state for the board.\n *\n * Constraint: all selected items must belong to the same repo section.\n * If the user toggles an item from a different repo, the selection resets\n * to just that item.\n */\nexport function useMultiSelect(getRepoForId: (id: string) => string | null): UseMultiSelectResult {\n const [selected, setSelected] = useState<ReadonlySet<string>>(new Set());\n const repoRef = useRef<string | null>(null);\n const getRepoRef = useRef(getRepoForId);\n getRepoRef.current = getRepoForId;\n\n const toggle = useCallback((id: string) => {\n setSelected((prev) => {\n const repo = getRepoRef.current(id);\n // Headers and non-repo items can't be selected\n if (!repo) return prev;\n\n const next = new Set(prev);\n\n if (next.has(id)) {\n next.delete(id);\n if (next.size === 0) repoRef.current = null;\n } else {\n // Different repo? Reset to just this item\n if (repoRef.current && repoRef.current !== repo) {\n next.clear();\n }\n repoRef.current = repo;\n next.add(id);\n }\n return next;\n });\n }, []);\n\n const clear = useCallback(() => {\n setSelected(new Set());\n repoRef.current = null;\n }, []);\n\n const prune = useCallback((validIds: ReadonlySet<string>) => {\n setSelected((prev) => {\n const next = new Set<string>();\n for (const id of prev) {\n if (validIds.has(id)) next.add(id);\n }\n if (next.size === prev.size) return prev; // no change\n if (next.size === 0) repoRef.current = null;\n return next;\n });\n }, []);\n\n const isSelected = useCallback((id: string) => selected.has(id), [selected]);\n\n return {\n selected,\n count: selected.size,\n isSelected,\n toggle,\n clear,\n prune,\n constrainedRepo: repoRef.current,\n };\n}\n","import { useCallback, useMemo, useReducer, useRef } from \"react\";\n\nexport type SectionId = string;\n\nexport interface NavItem {\n id: string;\n section: SectionId;\n type: \"header\" | \"subHeader\" | \"item\";\n subSection?: SectionId;\n}\n\ninterface NavState {\n selectedId: string | null;\n /** Section of the currently selected item (used for fallback when item disappears) */\n selectedSection: SectionId | null;\n sections: SectionId[];\n collapsedSections: Set<SectionId>;\n /** Full item list, kept in state so reducer can relocate cursor on collapse */\n allItems: NavItem[];\n}\n\ntype NavAction =\n | { type: \"SET_ITEMS\"; items: NavItem[] }\n | { type: \"SELECT\"; id: string; section?: SectionId | undefined }\n | { type: \"TOGGLE_SECTION\"; section: SectionId }\n | { type: \"COLLAPSE_ALL\" };\n\nfunction arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\n/** Find a fallback item when the selected item disappears from the list. */\nexport function findFallback(items: NavItem[], oldSection: SectionId | null): NavItem | undefined {\n if (oldSection) {\n // Prefer next item in same section (skip headers/subHeaders)\n const sectionItem = items.find((i) => i.section === oldSection && i.type === \"item\");\n if (sectionItem) return sectionItem;\n // Section header as last resort within section\n const sectionHeader = items.find((i) => i.section === oldSection && i.type === \"header\");\n if (sectionHeader) return sectionHeader;\n }\n // Fall back to first header globally\n return items.find((i) => i.type === \"header\") ?? items[0];\n}\n\n/** When collapsing a section/sub-section, return new cursor if the selected item becomes hidden. */\nfunction relocateOnToggle(\n state: NavState,\n section: SectionId,\n): Pick<NavState, \"selectedId\" | \"selectedSection\"> {\n if (!state.selectedId) return { selectedId: null, selectedSection: null };\n const selected = state.allItems.find((i) => i.id === state.selectedId);\n if (!selected) return { selectedId: state.selectedId, selectedSection: state.selectedSection };\n const insideCollapsedSubSection = selected.subSection === section;\n const insideCollapsedSection =\n !insideCollapsedSubSection && selected.section === section && selected.type !== \"header\";\n if (insideCollapsedSubSection) {\n const subHeader = state.allItems.find((i) => i.id === section && i.type === \"subHeader\");\n if (subHeader) return { selectedId: subHeader.id, selectedSection: subHeader.section };\n } else if (insideCollapsedSection) {\n const header = state.allItems.find((i) => i.section === section && i.type === \"header\");\n if (header) return { selectedId: header.id, selectedSection: header.section };\n }\n return { selectedId: state.selectedId, selectedSection: state.selectedSection };\n}\n\n/** When collapsing all, return cursor relocated to section header if currently on a non-header item. */\nfunction relocateOnCollapseAll(state: NavState): Pick<NavState, \"selectedId\" | \"selectedSection\"> {\n if (!state.selectedId) return { selectedId: null, selectedSection: null };\n const selected = state.allItems.find((i) => i.id === state.selectedId);\n if (!selected || selected.type === \"header\") {\n return { selectedId: state.selectedId, selectedSection: state.selectedSection };\n }\n const header = state.allItems.find((i) => i.section === selected.section && i.type === \"header\");\n if (header) return { selectedId: header.id, selectedSection: header.section };\n return { selectedId: state.selectedId, selectedSection: state.selectedSection };\n}\n\nfunction navReducer(state: NavState, action: NavAction): NavState {\n switch (action.type) {\n case \"SET_ITEMS\": {\n const sections = [...new Set(action.items.map((i) => i.section))];\n const isFirstLoad = state.sections.length === 0;\n // On first load: expand all sections except Activity (collapse it by default)\n // On refresh: preserve collapsed state, pruning orphan keys that no longer exist\n let collapsedSections: Set<SectionId>;\n if (isFirstLoad) {\n collapsedSections = new Set(sections.filter((s) => s === \"activity\"));\n } else {\n // Prune orphan keys — only keep IDs that still exist in the new tree\n const validIds = new Set<SectionId>([\n ...sections,\n ...action.items.filter((i) => i.type === \"subHeader\").map((i) => i.id),\n ]);\n collapsedSections = new Set([...state.collapsedSections].filter((id) => validIds.has(id)));\n }\n const selectionValid =\n state.selectedId != null && action.items.some((i) => i.id === state.selectedId);\n\n // Bail out if nothing meaningful changed (same sections, valid selection).\n // Still update allItems so relocateOnToggle/relocateOnCollapseAll use\n // current item positions — e.g. when an issue moves sub-sections after a\n // status change or new issues arrive from a background refresh.\n if (!isFirstLoad && selectionValid && arraysEqual(sections, state.sections)) {\n return state.allItems === action.items ? state : { ...state, allItems: action.items };\n }\n\n if (selectionValid) {\n // Update selectedSection in case it wasn't set yet (e.g., first load)\n const selected = action.items.find((i) => i.id === state.selectedId);\n return {\n ...state,\n selectedSection: selected?.section ?? state.selectedSection,\n sections,\n collapsedSections,\n allItems: action.items,\n };\n }\n\n // Selected item disappeared — find best fallback\n const fallback = findFallback(action.items, state.selectedSection);\n return {\n selectedId: fallback?.id ?? null,\n selectedSection: fallback?.section ?? null,\n sections,\n collapsedSections,\n allItems: action.items,\n };\n }\n case \"SELECT\": {\n return {\n ...state,\n selectedId: action.id,\n selectedSection: action.section ?? state.selectedSection,\n };\n }\n case \"TOGGLE_SECTION\": {\n const next = new Set(state.collapsedSections);\n const isCollapsing = !next.has(action.section);\n if (isCollapsing) {\n next.add(action.section);\n const cursor = relocateOnToggle(state, action.section);\n return { ...state, collapsedSections: next, ...cursor };\n }\n next.delete(action.section);\n return { ...state, collapsedSections: next };\n }\n case \"COLLAPSE_ALL\": {\n const next = new Set(state.sections);\n const cursor = relocateOnCollapseAll(state);\n return { ...state, collapsedSections: next, ...cursor };\n }\n default:\n return state;\n }\n}\n\n/** Returns only items that should be navigable (headers + non-collapsed items). */\nfunction getVisibleItems(allItems: NavItem[], collapsedSections: Set<SectionId>): NavItem[] {\n return allItems.filter((item) => {\n if (item.type === \"header\") return true;\n if (collapsedSections.has(item.section)) return false;\n if (item.type === \"subHeader\") return true;\n if (item.subSection && collapsedSections.has(item.subSection)) return false;\n return true;\n });\n}\n\nexport interface UseNavigationResult {\n selectedId: string | null;\n selectedIndex: number;\n collapsedSections: Set<SectionId>;\n moveUp: () => void;\n moveDown: () => void;\n nextSection: () => void;\n prevSection: () => void;\n toggleSection: () => void;\n collapseAll: () => void;\n select: (id: string) => void;\n isCollapsed: (section: SectionId) => boolean;\n}\n\nexport function useNavigation(allItems: NavItem[]): UseNavigationResult {\n const [state, dispatch] = useReducer(navReducer, {\n selectedId: null,\n selectedSection: null,\n sections: [],\n collapsedSections: new Set<SectionId>(),\n allItems: [],\n });\n\n // Sync items into reducer when they change (by reference comparison).\n // Dispatching during render is safe here: the ref prevents re-dispatch\n // on the subsequent re-render since allItems will be the same reference.\n const prevItemsRef = useRef<NavItem[] | null>(null);\n if (allItems !== prevItemsRef.current) {\n prevItemsRef.current = allItems;\n dispatch({ type: \"SET_ITEMS\", items: allItems });\n }\n\n const visibleItems = useMemo(\n () => getVisibleItems(allItems, state.collapsedSections),\n [allItems, state.collapsedSections],\n );\n\n const selectedIndex = useMemo(() => {\n if (!state.selectedId) return 0;\n const idx = visibleItems.findIndex((i) => i.id === state.selectedId);\n return idx >= 0 ? idx : 0;\n }, [state.selectedId, visibleItems]);\n\n const moveUp = useCallback(() => {\n const newIdx = Math.max(0, selectedIndex - 1);\n const item = visibleItems[newIdx];\n if (item) dispatch({ type: \"SELECT\", id: item.id, section: item.section });\n }, [selectedIndex, visibleItems]);\n\n const moveDown = useCallback(() => {\n const newIdx = Math.min(visibleItems.length - 1, selectedIndex + 1);\n const item = visibleItems[newIdx];\n if (item) dispatch({ type: \"SELECT\", id: item.id, section: item.section });\n }, [selectedIndex, visibleItems]);\n\n const nextSection = useCallback(() => {\n const currentItem = visibleItems[selectedIndex];\n if (!currentItem) return;\n const currentSectionIdx = state.sections.indexOf(currentItem.section);\n const nextSectionId = state.sections[currentSectionIdx + 1];\n if (!nextSectionId) return;\n const header = visibleItems.find((i) => i.section === nextSectionId && i.type === \"header\");\n if (header) dispatch({ type: \"SELECT\", id: header.id, section: header.section });\n }, [selectedIndex, visibleItems, state.sections]);\n\n const prevSection = useCallback(() => {\n const currentItem = visibleItems[selectedIndex];\n if (!currentItem) return;\n const currentSectionIdx = state.sections.indexOf(currentItem.section);\n const prevSectionId = state.sections[currentSectionIdx - 1];\n if (!prevSectionId) return;\n const header = visibleItems.find((i) => i.section === prevSectionId && i.type === \"header\");\n if (header) dispatch({ type: \"SELECT\", id: header.id, section: header.section });\n }, [selectedIndex, visibleItems, state.sections]);\n\n const toggleSection = useCallback(() => {\n const currentItem = visibleItems[selectedIndex];\n if (!currentItem) return;\n // Only headers and subHeaders are toggle targets; items have no collapse behaviour\n if (currentItem.type === \"item\") return;\n // Sub-headers toggle their own ID (used as sub-section key); headers toggle the section\n const key = currentItem.type === \"subHeader\" ? currentItem.id : currentItem.section;\n dispatch({ type: \"TOGGLE_SECTION\", section: key });\n }, [selectedIndex, visibleItems]);\n\n const collapseAll = useCallback(() => {\n dispatch({ type: \"COLLAPSE_ALL\" });\n }, []);\n\n const allItemsRef = useRef(allItems);\n allItemsRef.current = allItems;\n\n const select = useCallback((id: string) => {\n const item = allItemsRef.current.find((i) => i.id === id);\n dispatch({ type: \"SELECT\", id, section: item?.section });\n }, []);\n\n const isCollapsed = useCallback(\n (section: SectionId) => state.collapsedSections.has(section),\n [state.collapsedSections],\n );\n\n return {\n selectedId: state.selectedId,\n selectedIndex,\n collapsedSections: state.collapsedSections,\n moveUp,\n moveDown,\n nextSection,\n prevSection,\n toggleSection,\n collapseAll,\n select,\n isCollapsed,\n };\n}\n","import { useCallback, useState } from \"react\";\n\n// ── Types ──\n\n/** 0=Detail, 1=Repos, 2=Statuses, 3=Issues, 4=Activity */\nexport type PanelId = 0 | 1 | 2 | 3 | 4;\n\nexport interface UsePanelFocusResult {\n activePanelId: PanelId;\n focusPanel: (id: PanelId) => void;\n isPanelActive: (id: PanelId) => boolean;\n}\n\n// ── Hook ──\n\nexport function usePanelFocus(initialPanel: PanelId = 3): UsePanelFocusResult {\n const [activePanelId, setActivePanelId] = useState<PanelId>(initialPanel);\n\n const focusPanel = useCallback((id: PanelId) => {\n setActivePanelId(id);\n }, []);\n\n const isPanelActive = useCallback((id: PanelId) => activePanelId === id, [activePanelId]);\n\n return { activePanelId, focusPanel, isPanelActive };\n}\n","import { useCallback, useRef, useState } from \"react\";\n\nexport interface Toast {\n id: string;\n type: \"info\" | \"success\" | \"error\" | \"loading\";\n message: string;\n retry?: () => void;\n createdAt: number;\n}\n\nexport interface ToastAPI {\n info: (message: string) => void;\n success: (message: string) => void;\n error: (message: string, retry?: () => void) => void;\n loading: (message: string) => { resolve: (msg: string) => void; reject: (msg: string) => void };\n}\n\nexport interface UseToastResult {\n toasts: Toast[];\n toast: ToastAPI;\n /** Dismiss oldest error toast, or call its retry. Returns true if handled. */\n handleErrorAction: (action: \"dismiss\" | \"retry\") => boolean;\n}\n\nconst MAX_VISIBLE = 3;\nconst AUTO_DISMISS_MS = 3000;\n\nlet nextId = 0;\n\nexport function useToast(): UseToastResult {\n const [toasts, setToasts] = useState<Toast[]>([]);\n const timersRef = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());\n\n const clearTimer = useCallback((id: string) => {\n const timer = timersRef.current.get(id);\n if (timer) {\n clearTimeout(timer);\n timersRef.current.delete(id);\n }\n }, []);\n\n const removeToast = useCallback(\n (id: string) => {\n clearTimer(id);\n setToasts((prev) => prev.filter((t) => t.id !== id));\n },\n [clearTimer],\n );\n\n const addToast = useCallback(\n (t: Omit<Toast, \"id\" | \"createdAt\">): string => {\n const id = `toast-${++nextId}`;\n const newToast: Toast = { ...t, id, createdAt: Date.now() };\n\n setToasts((prev) => {\n const next = [...prev, newToast];\n // Enforce max visible: evict oldest dismissable toast\n while (next.length > MAX_VISIBLE) {\n const evictIdx = next.findIndex((x) => x.type !== \"error\" && x.type !== \"loading\");\n if (evictIdx >= 0) {\n const evictToast = next[evictIdx];\n if (evictToast) clearTimer(evictToast.id);\n next.splice(evictIdx, 1);\n } else {\n // All are persistent — evict oldest anyway\n const oldest = next[0];\n if (oldest) clearTimer(oldest.id);\n next.shift();\n }\n }\n return next;\n });\n\n // Auto-dismiss for info/success\n if (t.type === \"info\" || t.type === \"success\") {\n const timer = setTimeout(() => removeToast(id), AUTO_DISMISS_MS);\n timersRef.current.set(id, timer);\n }\n\n return id;\n },\n [removeToast, clearTimer],\n );\n\n const toast: ToastAPI = {\n info: useCallback(\n (message: string) => {\n addToast({ type: \"info\", message });\n },\n [addToast],\n ),\n\n success: useCallback(\n (message: string) => {\n addToast({ type: \"success\", message });\n },\n [addToast],\n ),\n\n error: useCallback(\n (message: string, retry?: () => void) => {\n addToast(retry ? { type: \"error\", message, retry } : { type: \"error\", message });\n },\n [addToast],\n ),\n\n loading: useCallback(\n (message: string) => {\n const id = addToast({ type: \"loading\", message });\n return {\n resolve: (msg: string) => {\n removeToast(id);\n addToast({ type: \"success\", message: msg });\n },\n reject: (msg: string) => {\n removeToast(id);\n addToast({ type: \"error\", message: msg });\n },\n };\n },\n [addToast, removeToast],\n ),\n };\n\n const handleErrorAction = useCallback(\n (action: \"dismiss\" | \"retry\"): boolean => {\n const errorToast = toasts.find((t) => t.type === \"error\");\n if (!errorToast) return false;\n\n if (action === \"retry\" && errorToast.retry) {\n removeToast(errorToast.id);\n errorToast.retry();\n return true;\n }\n if (action === \"dismiss\") {\n removeToast(errorToast.id);\n return true;\n }\n return false;\n },\n [toasts, removeToast],\n );\n\n return { toasts, toast, handleErrorAction };\n}\n","import { useCallback, useReducer } from \"react\";\n\n// ── UI States ──\n\nexport type UIMode =\n | \"normal\"\n | \"search\"\n | \"overlay:comment\"\n | \"overlay:status\"\n | \"overlay:create\"\n | \"overlay:createNl\"\n | \"overlay:label\"\n | \"overlay:bulkAction\"\n | \"overlay:confirmPick\"\n | \"overlay:help\"\n | \"overlay:fuzzyPicker\"\n | \"overlay:editIssue\"\n | \"overlay:detail\"\n | \"multiSelect\"\n | \"focus\";\n\nexport interface UIState {\n mode: UIMode;\n /** Help overlay stacks on top of any mode */\n helpVisible: boolean;\n /** Previous mode to return to (for overlays) */\n previousMode: UIMode;\n}\n\n// ── Actions ──\n\nexport type UIAction =\n | { type: \"ENTER_SEARCH\" }\n | { type: \"ENTER_COMMENT\" }\n | { type: \"ENTER_STATUS\" }\n | { type: \"ENTER_CREATE\" }\n | { type: \"ENTER_CREATE_NL\" }\n | { type: \"ENTER_LABEL\" }\n | { type: \"ENTER_MULTI_SELECT\" }\n | { type: \"ENTER_BULK_ACTION\" }\n | { type: \"ENTER_CONFIRM_PICK\" }\n | { type: \"ENTER_FOCUS\" }\n | { type: \"ENTER_FUZZY_PICKER\" }\n | { type: \"ENTER_EDIT_ISSUE\" }\n | { type: \"ENTER_DETAIL\" }\n | { type: \"TOGGLE_HELP\" }\n | { type: \"EXIT_OVERLAY\" }\n | { type: \"EXIT_TO_NORMAL\" }\n | { type: \"CLEAR_MULTI_SELECT\" };\n\n// ── Reducer ──\n\nconst INITIAL_STATE: UIState = {\n mode: \"normal\",\n helpVisible: false,\n previousMode: \"normal\",\n};\n\nfunction enterStatusMode(state: UIState): UIState {\n if (state.mode !== \"normal\" && state.mode !== \"overlay:bulkAction\") return state;\n const previousMode: UIMode = state.mode === \"overlay:bulkAction\" ? \"multiSelect\" : \"normal\";\n return { ...state, mode: \"overlay:status\", previousMode };\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: UI state machine with many action types\nfunction uiReducer(state: UIState, action: UIAction): UIState {\n switch (action.type) {\n case \"ENTER_SEARCH\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"search\", previousMode: \"normal\" };\n\n case \"ENTER_COMMENT\":\n if (state.mode !== \"normal\" && state.mode !== \"overlay:detail\") return state;\n return { ...state, mode: \"overlay:comment\", previousMode: \"normal\" };\n\n case \"ENTER_STATUS\":\n return enterStatusMode(state);\n\n case \"ENTER_CREATE\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"overlay:create\", previousMode: \"normal\" };\n\n case \"ENTER_CREATE_NL\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"overlay:createNl\", previousMode: \"normal\" };\n\n case \"ENTER_LABEL\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"overlay:label\", previousMode: \"normal\" };\n\n case \"ENTER_MULTI_SELECT\":\n if (state.mode !== \"normal\" && state.mode !== \"multiSelect\") return state;\n return { ...state, mode: \"multiSelect\", previousMode: \"normal\" };\n\n case \"ENTER_BULK_ACTION\":\n if (state.mode !== \"multiSelect\") return state;\n return { ...state, mode: \"overlay:bulkAction\", previousMode: \"multiSelect\" };\n\n case \"ENTER_CONFIRM_PICK\":\n // Can transition from create overlay (after success) or normal\n return { ...state, mode: \"overlay:confirmPick\", previousMode: \"normal\" };\n\n case \"ENTER_FOCUS\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"focus\", previousMode: \"normal\" };\n\n case \"ENTER_FUZZY_PICKER\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"overlay:fuzzyPicker\", previousMode: \"normal\" };\n\n case \"ENTER_EDIT_ISSUE\":\n if (state.mode !== \"normal\" && state.mode !== \"overlay:detail\") return state;\n return { ...state, mode: \"overlay:editIssue\", previousMode: \"normal\" };\n\n case \"ENTER_DETAIL\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"overlay:detail\", previousMode: \"normal\" };\n\n case \"TOGGLE_HELP\":\n // Help stacks on any mode\n return { ...state, helpVisible: !state.helpVisible };\n\n case \"EXIT_OVERLAY\":\n // Close help first if visible, then return to previous mode\n if (state.helpVisible) {\n return { ...state, helpVisible: false };\n }\n return { ...state, mode: state.previousMode, previousMode: \"normal\" };\n\n case \"EXIT_TO_NORMAL\":\n return { ...state, mode: \"normal\", helpVisible: false, previousMode: \"normal\" };\n\n case \"CLEAR_MULTI_SELECT\":\n if (state.mode === \"multiSelect\") {\n return { ...state, mode: \"normal\", previousMode: \"normal\" };\n }\n return state;\n\n default:\n return state;\n }\n}\n\n// ── Derived state helpers ──\n\n/** Whether navigation shortcuts (j/k/tab) should work */\nexport function canNavigate(state: UIState): boolean {\n const { mode } = state;\n return mode === \"normal\" || mode === \"multiSelect\" || mode === \"focus\";\n}\n\n/** Whether action shortcuts (p/a/u/c/m/s/n) should work */\nexport function canAct(state: UIState): boolean {\n return state.mode === \"normal\";\n}\n\n/** Whether the UI is in an overlay/input state */\nexport function isOverlay(state: UIState): boolean {\n return state.mode.startsWith(\"overlay:\") || state.mode === \"search\";\n}\n\n// ── Hook ──\n\nexport interface UseUIStateResult {\n state: UIState;\n enterSearch: () => void;\n enterComment: () => void;\n enterStatus: () => void;\n enterCreate: () => void;\n enterCreateNl: () => void;\n enterLabel: () => void;\n enterMultiSelect: () => void;\n enterBulkAction: () => void;\n enterConfirmPick: () => void;\n enterFocus: () => void;\n enterFuzzyPicker: () => void;\n enterEditIssue: () => void;\n enterDetail: () => void;\n toggleHelp: () => void;\n exitOverlay: () => void;\n exitToNormal: () => void;\n clearMultiSelect: () => void;\n canNavigate: boolean;\n canAct: boolean;\n isOverlay: boolean;\n}\n\nexport function useUIState(): UseUIStateResult {\n const [state, dispatch] = useReducer(uiReducer, INITIAL_STATE);\n\n return {\n state,\n enterSearch: useCallback(() => dispatch({ type: \"ENTER_SEARCH\" }), []),\n enterComment: useCallback(() => dispatch({ type: \"ENTER_COMMENT\" }), []),\n enterStatus: useCallback(() => dispatch({ type: \"ENTER_STATUS\" }), []),\n enterCreate: useCallback(() => dispatch({ type: \"ENTER_CREATE\" }), []),\n enterCreateNl: useCallback(() => dispatch({ type: \"ENTER_CREATE_NL\" }), []),\n enterLabel: useCallback(() => dispatch({ type: \"ENTER_LABEL\" }), []),\n enterMultiSelect: useCallback(() => dispatch({ type: \"ENTER_MULTI_SELECT\" }), []),\n enterBulkAction: useCallback(() => dispatch({ type: \"ENTER_BULK_ACTION\" }), []),\n enterConfirmPick: useCallback(() => dispatch({ type: \"ENTER_CONFIRM_PICK\" }), []),\n enterFocus: useCallback(() => dispatch({ type: \"ENTER_FOCUS\" }), []),\n enterFuzzyPicker: useCallback(() => dispatch({ type: \"ENTER_FUZZY_PICKER\" }), []),\n enterEditIssue: useCallback(() => dispatch({ type: \"ENTER_EDIT_ISSUE\" }), []),\n enterDetail: useCallback(() => dispatch({ type: \"ENTER_DETAIL\" }), []),\n toggleHelp: useCallback(() => dispatch({ type: \"TOGGLE_HELP\" }), []),\n exitOverlay: useCallback(() => dispatch({ type: \"EXIT_OVERLAY\" }), []),\n exitToNormal: useCallback(() => dispatch({ type: \"EXIT_TO_NORMAL\" }), []),\n clearMultiSelect: useCallback(() => dispatch({ type: \"CLEAR_MULTI_SELECT\" }), []),\n canNavigate: canNavigate(state),\n canAct: canAct(state),\n isOverlay: isOverlay(state),\n };\n}\n","import { Box, Text } from \"ink\";\nimport { useEffect, useState } from \"react\";\nimport type { ActionLogEntry } from \"../hooks/use-action-log.js\";\n\ninterface ActionLogProps {\n readonly entries: ActionLogEntry[];\n}\n\nfunction relativeTime(ago: number): string {\n const seconds = Math.floor((Date.now() - ago) / 1000);\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h ago`;\n}\n\nfunction statusPrefix(status: ActionLogEntry[\"status\"]): string {\n if (status === \"success\") return \"\\u2713\";\n if (status === \"error\") return \"\\u2717\";\n return \"\\u22EF\";\n}\n\nfunction statusColor(status: ActionLogEntry[\"status\"]): \"green\" | \"red\" | \"yellow\" {\n if (status === \"success\") return \"green\";\n if (status === \"error\") return \"red\";\n return \"yellow\";\n}\n\nfunction ActionLog({ entries }: ActionLogProps) {\n // Tick every 5s to update relative timestamps\n const [, setTick] = useState(0);\n useEffect(() => {\n const id = setInterval(() => setTick((t) => t + 1), 5_000);\n return () => clearInterval(id);\n }, []);\n\n const visible = entries.slice(-5);\n // Find the most recent undoable entry\n const lastUndoable = [...entries].reverse().find((e) => !!e.undo);\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"single\" borderColor=\"gray\">\n <Box paddingX={1}>\n <Text color=\"gray\" bold>\n Action Log\n </Text>\n <Text color=\"gray\" dimColor>\n {\" \"}\n (L: close)\n </Text>\n </Box>\n {visible.length === 0 ? (\n <Box paddingX={1}>\n <Text dimColor>No actions yet.</Text>\n </Box>\n ) : (\n visible.map((entry) => {\n const isUndoable = lastUndoable?.id === entry.id && !!entry.undo;\n return (\n <Box key={entry.id} paddingX={1}>\n <Text color={statusColor(entry.status)}>{statusPrefix(entry.status)} </Text>\n <Text>{entry.description}</Text>\n <Text dimColor> {relativeTime(entry.ago)}</Text>\n {isUndoable ? <Text color=\"cyan\"> [u: undo]</Text> : null}\n {entry.retry && entry.status === \"error\" ? (\n <Text color=\"yellow\"> [retry]</Text>\n ) : null}\n </Box>\n );\n })\n )}\n </Box>\n );\n}\n\nexport { ActionLog };\nexport type { ActionLogProps };\n","import { Box, Text } from \"ink\";\nimport type { ReactNode } from \"react\";\n\ninterface PanelProps {\n /** Text shown inside the top border: ╭─ title ──╮ */\n readonly title: string;\n /** Whether this panel is currently focused (cyan border vs gray) */\n readonly isActive: boolean;\n /** Total outer width including border chars */\n readonly width: number;\n /** Fixed total height (optional; use flexGrow instead for variable-height panels) */\n readonly height?: number | undefined;\n /** CSS flex grow factor — use 1 for panels that should fill available space */\n readonly flexGrow?: number | undefined;\n readonly children: ReactNode;\n}\n\n/**\n * Build the top border line with the title embedded.\n * Output: ╭─ title ─────────╮ (exactly `width` chars)\n */\nexport function buildTopLine(title: string, width: number): string {\n const titlePart = `─ ${title} `; // \"─ title \"\n const dashCount = Math.max(0, width - 2 - titlePart.length); // corners = 2 chars\n return `╭${titlePart}${\"─\".repeat(dashCount)}╮`;\n}\n\n/**\n * A lazygit-style panel: title embedded in the top border, rounded corners,\n * cyan border when active / gray when inactive.\n *\n * Rendering:\n * ╭─ [1] Repos ──────────╮ ← manually drawn Text (1 row)\n * │ content │ ← Ink Box with borderTop=false\n * ╰───────────────────────╯ ← from Ink Box bottom border\n */\nexport function Panel({ title, isActive, width, height, flexGrow, children }: PanelProps) {\n const color = isActive ? \"cyan\" : \"gray\";\n const topLine = buildTopLine(title, width);\n\n return (\n <Box flexDirection=\"column\" width={width} height={height} flexGrow={flexGrow} overflow=\"hidden\">\n <Text color={color}>{topLine}</Text>\n <Box\n borderStyle=\"round\"\n borderTop={false}\n borderColor={color}\n flexDirection=\"column\"\n flexGrow={1}\n overflow=\"hidden\"\n width={width}\n >\n {children}\n </Box>\n </Box>\n );\n}\n\nexport type { PanelProps };\n","import { Box, Text } from \"ink\";\nimport { timeAgo } from \"../constants.js\";\nimport type { ActivityEvent } from \"../fetch.js\";\nimport { Panel } from \"./panel.js\";\n\nexport interface ActivityPanelProps {\n readonly events: ActivityEvent[];\n readonly selectedIdx: number;\n readonly isActive: boolean;\n readonly height: number;\n readonly width: number;\n}\n\nexport function ActivityPanel({\n events,\n selectedIdx,\n isActive,\n height,\n width,\n}: ActivityPanelProps) {\n // Panel takes 1 row for top border text + 1 row for bottom border inside the inner Box\n // = 2 overhead rows → content rows = height - 2\n const maxRows = Math.max(1, height - 2);\n const visible = events.slice(0, maxRows);\n\n return (\n <Panel title=\"[4] Activity\" isActive={isActive} width={width} height={height}>\n {visible.length === 0 ? (\n <Text color=\"gray\"> No recent activity</Text>\n ) : (\n visible.map((event, i) => {\n const isSel = isActive && i === selectedIdx;\n const ago = timeAgo(event.timestamp);\n return (\n <Box key={`${event.repoShortName}:${event.issueNumber}:${i}`}>\n <Text color={isSel ? \"cyan\" : \"gray\"} bold={isSel}>\n {isSel ? \"► \" : \" \"}\n {ago}\n </Text>\n <Text color={isSel ? \"white\" : \"gray\"}>\n {\" \"}\n @{event.actor} {event.summary}{\" \"}\n </Text>\n <Text dimColor>({event.repoShortName})</Text>\n </Box>\n );\n })\n )}\n </Panel>\n );\n}\n","import { Box, Text } from \"ink\";\nimport { useEffect } from \"react\";\nimport type { GitHubIssue, IssueComment } from \"../../github.js\";\nimport { Panel } from \"./panel.js\";\n\ninterface DetailPanelProps {\n readonly issue: GitHubIssue | null;\n readonly width: number;\n readonly height?: number | undefined;\n readonly isActive: boolean;\n readonly commentsState?: IssueComment[] | \"loading\" | \"error\" | null;\n readonly fetchComments?: (repo: string, issueNumber: number) => void;\n readonly issueRepo?: string | null;\n}\n\n/** Strip common markdown syntax for plain text display. */\nfunction stripMarkdown(text: string): string {\n return text\n .replace(/^#{1,6}\\s+/gm, \"\") // headers\n .replace(/\\*\\*(.+?)\\*\\*/g, \"$1\") // bold\n .replace(/\\*(.+?)\\*/g, \"$1\") // italic\n .replace(/__(.+?)__/g, \"$1\") // bold alt\n .replace(/_(.+?)_/g, \"$1\") // italic alt\n .replace(/~~(.+?)~~/g, \"$1\") // strikethrough\n .replace(/`{1,3}[^`]*`{1,3}/g, (m) => m.replace(/`/g, \"\")) // inline code\n .replace(/^\\s*[-*+]\\s+/gm, \" - \") // list items\n .replace(/^\\s*\\d+\\.\\s+/gm, \" \") // numbered lists\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\") // links\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, \"[$1]\") // images\n .replace(/^>\\s+/gm, \" \") // blockquotes\n .replace(/---+/g, \"\") // horizontal rules\n .replace(/\\n{3,}/g, \"\\n\\n\") // collapse blank lines\n .trim();\n}\n\nfunction formatBody(body: string, maxLines: number): { text: string; remaining: number } {\n const plain = stripMarkdown(body);\n const lines = plain.split(\"\\n\");\n const truncated = lines.slice(0, maxLines).join(\"\\n\");\n return { text: truncated, remaining: Math.max(0, lines.length - maxLines) };\n}\n\nconst SLACK_URL_RE = /https:\\/\\/[^/]+\\.slack\\.com\\/archives\\/[A-Z0-9]+\\/p[0-9]+/gi;\n\nfunction countSlackLinks(body: string | undefined): number {\n if (!body) return 0;\n return (body.match(SLACK_URL_RE) ?? []).length;\n}\n\nfunction BodySection({\n body,\n issueNumber,\n}: {\n readonly body: string;\n readonly issueNumber: number;\n}) {\n const { text, remaining } = formatBody(body, 15);\n return (\n <>\n <Text>{\"\"}</Text>\n <Text dimColor>--- Description ---</Text>\n <Text wrap=\"wrap\">{text}</Text>\n {remaining > 0 ? (\n <Text dimColor>\n ... ({remaining} more lines — gh issue view {issueNumber} for full)\n </Text>\n ) : null}\n </>\n );\n}\n\nfunction formatCommentAge(createdAt: string): string {\n const seconds = Math.floor((Date.now() - new Date(createdAt).getTime()) / 1000);\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nfunction DetailPanel({\n issue,\n width,\n height,\n isActive,\n commentsState,\n fetchComments,\n issueRepo,\n}: DetailPanelProps) {\n // Trigger lazy fetch when issue changes and panel is visible\n useEffect(() => {\n if (!(issue && fetchComments && issueRepo)) return;\n if (commentsState !== null && commentsState !== undefined) return; // already fetched or loading\n fetchComments(issueRepo, issue.number);\n }, [issue, issueRepo, fetchComments, commentsState]);\n\n if (!issue) {\n return (\n <Panel title=\"[0] Detail\" isActive={isActive} width={width} height={height}>\n <Text color=\"gray\">No item selected</Text>\n </Panel>\n );\n }\n\n return (\n <Panel title=\"[0] Detail\" isActive={isActive} width={width} height={height}>\n <Text color=\"cyan\" bold>\n #{issue.number} {issue.title}\n </Text>\n <Text>{\"\"}</Text>\n\n <Box>\n <Text color=\"gray\">State: </Text>\n <Text color={issue.state === \"open\" ? \"green\" : \"red\"}>{issue.state}</Text>\n </Box>\n\n {(issue.assignees ?? []).length > 0 ? (\n <Box>\n <Text color=\"gray\">Assignees: </Text>\n <Text>{(issue.assignees ?? []).map((a) => a.login).join(\", \")}</Text>\n </Box>\n ) : null}\n\n {issue.labels.length > 0 ? (\n <Box>\n <Text color=\"gray\">Labels: </Text>\n <Text>{issue.labels.map((l) => l.name).join(\", \")}</Text>\n </Box>\n ) : null}\n\n {issue.projectStatus ? (\n <Box>\n <Text color=\"gray\">Status: </Text>\n <Text color=\"magenta\">{issue.projectStatus}</Text>\n </Box>\n ) : null}\n\n {issue.targetDate ? (\n <Box>\n <Text color=\"gray\">Target: </Text>\n <Text>{issue.targetDate}</Text>\n </Box>\n ) : null}\n\n <Box>\n <Text color=\"gray\">Updated: </Text>\n <Text>{new Date(issue.updatedAt).toLocaleString()}</Text>\n </Box>\n\n {issue.slackThreadUrl ? (\n <Box>\n <Text color=\"gray\">Slack: </Text>\n <Text color=\"blue\">\n {countSlackLinks(issue.body) > 1\n ? `${countSlackLinks(issue.body)} links (s opens first)`\n : \"thread (s to open)\"}\n </Text>\n </Box>\n ) : null}\n\n {issue.body ? (\n <BodySection body={issue.body} issueNumber={issue.number} />\n ) : (\n <>\n <Text>{\"\"}</Text>\n <Text color=\"gray\">(no description)</Text>\n </>\n )}\n\n {/* Comments section */}\n <Text>{\"\"}</Text>\n <Text dimColor>--- Comments ---</Text>\n {commentsState === \"loading\" ? (\n <Text dimColor>fetching comments...</Text>\n ) : commentsState === \"error\" ? (\n <Text color=\"red\">could not load comments</Text>\n ) : commentsState && commentsState.length === 0 ? (\n <Text dimColor>No comments yet.</Text>\n ) : commentsState && commentsState.length > 0 ? (\n commentsState.slice(-5).map((comment, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: stable list\n <Box key={i} flexDirection=\"column\" marginBottom={1}>\n <Text color=\"cyan\">\n @{comment.author.login} · {formatCommentAge(comment.createdAt)}\n </Text>\n <Text wrap=\"wrap\"> {comment.body.split(\"\\n\")[0]}</Text>\n </Box>\n ))\n ) : (\n <Text dimColor>fetching comments...</Text>\n )}\n\n <Text>{\"\"}</Text>\n <Text color=\"gray\" dimColor>\n {issue.url}\n </Text>\n </Panel>\n );\n}\n\nexport { DetailPanel };\nexport type { DetailPanelProps };\n","import { Box, Text } from \"ink\";\nimport type { PanelId } from \"../hooks/use-panel-focus.js\";\nimport type { UIMode } from \"../hooks/use-ui-state.js\";\n\ninterface HintBarProps {\n readonly uiMode: UIMode;\n readonly activePanelId: PanelId;\n readonly multiSelectCount: number;\n readonly searchQuery: string;\n readonly mineOnly: boolean;\n readonly hasUndoable?: boolean;\n}\n\nfunction HintBar({\n uiMode,\n activePanelId,\n multiSelectCount,\n searchQuery,\n mineOnly,\n hasUndoable,\n}: HintBarProps) {\n if (uiMode === \"multiSelect\") {\n return (\n <Box>\n <Text color=\"cyan\" bold>\n [MULTI-SELECT] {multiSelectCount} selected\n </Text>\n <Text color=\"gray\"> Space:toggle Enter:actions Esc:cancel</Text>\n </Box>\n );\n }\n\n if (uiMode === \"focus\") {\n return (\n <Box>\n <Text color=\"magenta\" bold>\n [FOCUS] Focus mode — Esc to exit\n </Text>\n </Box>\n );\n }\n\n if (uiMode === \"search\") {\n return (\n <Box>\n <Text color=\"yellow\" bold>\n [SEARCH]\n </Text>\n <Text color=\"gray\"> type to filter Enter:confirm Esc:clear</Text>\n {searchQuery ? <Text color=\"yellow\"> \"{searchQuery}\"</Text> : null}\n </Box>\n );\n }\n\n if (uiMode === \"overlay:fuzzyPicker\") {\n return (\n <Box>\n <Text color=\"gray\">↑↓/Ctrl-J/K:nav Enter:jump Esc:close</Text>\n </Box>\n );\n }\n\n if (uiMode === \"overlay:detail\") {\n return (\n <Box>\n <Text color=\"cyan\" bold>\n [DETAIL]\n </Text>\n <Text color=\"gray\"> Esc:close e:edit c:comment y:copy-link ? help</Text>\n </Box>\n );\n }\n\n if (uiMode.startsWith(\"overlay:\")) {\n return (\n <Box>\n <Text color=\"gray\">j/k:nav Enter:select Esc:cancel</Text>\n </Box>\n );\n }\n\n // Normal mode — context-sensitive hints per active panel\n const panelHints: Record<PanelId, string> = {\n 0: \"j/k:scroll Esc:close ? help\",\n 1: \"j/k:move Enter:filter 0-4:panel ? help\",\n 2: \"j/k:move Enter:filter Esc:clear 0-4:panel ? help\",\n 3: `j/k:move p:pick m:status c:comment /:search n:new 0-4:panel${hasUndoable ? \" u:undo\" : \"\"} ? help q:quit`,\n 4: \"j/k:scroll Enter:jump r:refresh 0-4:panel ? help\",\n };\n\n return (\n <Box>\n <Text color=\"gray\">{panelHints[activePanelId]}</Text>\n {mineOnly ? <Text color=\"cyan\"> filter:@me</Text> : null}\n {searchQuery ? <Text color=\"yellow\"> filter:\"{searchQuery}\"</Text> : null}\n </Box>\n );\n}\n\nexport { HintBar };\nexport type { HintBarProps };\n","import { Box, Text, useInput } from \"ink\";\nimport { useState } from \"react\";\n\nexport type BulkAction =\n | { type: \"assign\" }\n | { type: \"statusChange\" }\n | { type: \"unassign\" }\n | { type: \"complete\" }\n | { type: \"delete\" };\n\ninterface BulkActionMenuProps {\n readonly count: number;\n /** What kinds of items are selected */\n readonly selectionType: \"github\" | \"ticktick\" | \"mixed\";\n readonly onSelect: (action: BulkAction) => void;\n readonly onCancel: () => void;\n}\n\ninterface MenuItem {\n label: string;\n action: BulkAction;\n}\n\nfunction getMenuItems(selectionType: \"github\" | \"ticktick\" | \"mixed\"): MenuItem[] {\n if (selectionType === \"github\") {\n return [\n { label: \"Assign all to me\", action: { type: \"assign\" } },\n { label: \"Unassign all from me\", action: { type: \"unassign\" } },\n { label: \"Move status (all)\", action: { type: \"statusChange\" } },\n ];\n }\n if (selectionType === \"ticktick\") {\n return [\n { label: \"Complete all\", action: { type: \"complete\" } },\n { label: \"Delete all\", action: { type: \"delete\" } },\n ];\n }\n // Mixed: only show actions valid for all types — none in our case\n return [];\n}\n\nfunction BulkActionMenu({ count, selectionType, onSelect, onCancel }: BulkActionMenuProps) {\n const items = getMenuItems(selectionType);\n const [selectedIdx, setSelectedIdx] = useState(0);\n\n useInput((input, key) => {\n if (key.escape) return onCancel();\n if (key.return) {\n const item = items[selectedIdx];\n if (item) onSelect(item.action);\n return;\n }\n if (input === \"j\" || key.downArrow) {\n setSelectedIdx((i) => Math.min(i + 1, items.length - 1));\n }\n if (input === \"k\" || key.upArrow) {\n setSelectedIdx((i) => Math.max(i - 1, 0));\n }\n });\n\n if (items.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"yellow\">No bulk actions for mixed selection types.</Text>\n <Text dimColor>Esc to cancel</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Bulk action ({count} selected):\n </Text>\n {items.map((item, i) => {\n const isSelected = i === selectedIdx;\n const prefix = isSelected ? \"> \" : \" \";\n return (\n <Text key={item.action.type} {...(isSelected ? { color: \"cyan\" as const } : {})}>\n {prefix}\n {item.label}\n </Text>\n );\n })}\n <Text dimColor>j/k:navigate Enter:select Esc:cancel</Text>\n </Box>\n );\n}\n\nexport { BulkActionMenu, getMenuItems };\n","import type { Instance } from \"ink\";\n\nlet inkInstance: Instance | null = null;\n\n/** Store the Ink render instance for use in editor integration ($EDITOR launch). */\nexport function setInkInstance(instance: Instance): void {\n inkInstance = instance;\n}\n\nexport function getInkInstance(): Instance | null {\n return inkInstance;\n}\n","import { spawnSync } from \"node:child_process\";\nimport { mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { TextInput } from \"@inkjs/ui\";\nimport { Box, Text, useInput, useStdin } from \"ink\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { getInkInstance } from \"../ink-instance.js\";\n\ninterface CommentInputProps {\n readonly issueNumber: number;\n readonly onSubmit: (body: string) => void;\n readonly onCancel: () => void;\n readonly onPauseRefresh?: () => void;\n readonly onResumeRefresh?: () => void;\n}\n\nfunction CommentInput({\n issueNumber,\n onSubmit,\n onCancel,\n onPauseRefresh,\n onResumeRefresh,\n}: CommentInputProps) {\n const [value, setValue] = useState(\"\");\n const [editing, setEditing] = useState(false);\n const { setRawMode } = useStdin();\n // Capture stable refs to avoid stale closures in useEffect\n const onSubmitRef = useRef(onSubmit);\n const onCancelRef = useRef(onCancel);\n const onPauseRef = useRef(onPauseRefresh);\n const onResumeRef = useRef(onResumeRefresh);\n onSubmitRef.current = onSubmit;\n onCancelRef.current = onCancel;\n onPauseRef.current = onPauseRefresh;\n onResumeRef.current = onResumeRefresh;\n\n useInput((_input, key) => {\n if (editing) return;\n if (key.escape) {\n onCancel();\n return;\n }\n // ctrl+e: transition to \"editing\" sub-state before launching editor\n if (_input === \"\\x05\") {\n setEditing(true);\n }\n });\n\n // Launch editor after TextInput has unmounted (editing === true)\n useEffect(() => {\n if (!editing) return;\n\n const editorEnv = process.env[\"VISUAL\"] ?? process.env[\"EDITOR\"] ?? \"vi\";\n // Split to handle \"code --wait\" style editors\n const [cmd, ...extraArgs] = editorEnv.split(\" \").filter(Boolean);\n if (!cmd) {\n setEditing(false);\n return;\n }\n\n let tmpDir: string | null = null;\n let tmpFile: string | null = null;\n\n try {\n // Pause auto-refresh before handing over the terminal\n onPauseRef.current?.();\n\n // Prepare temp file with current value as seed content\n tmpDir = mkdtempSync(join(tmpdir(), \"hog-comment-\"));\n tmpFile = join(tmpDir, \"comment.md\");\n writeFileSync(tmpFile, value);\n\n // Suspend Ink and restore terminal to cooked mode\n const inkInstance = getInkInstance();\n inkInstance?.clear();\n setRawMode(false);\n\n spawnSync(cmd, [...extraArgs, tmpFile], { stdio: \"inherit\" });\n\n // Read back the file content\n const content = readFileSync(tmpFile, \"utf-8\").trim();\n\n // Restore raw mode for Ink\n setRawMode(true);\n\n if (content) {\n onSubmitRef.current(content);\n } else {\n // Empty save — treat as cancel\n onCancelRef.current();\n }\n } finally {\n onResumeRef.current?.();\n if (tmpDir) {\n try {\n rmSync(tmpDir, { recursive: true, force: true });\n } catch {\n // ignore cleanup errors\n }\n }\n setEditing(false);\n }\n }, [editing, value, setRawMode]);\n\n if (editing) {\n return (\n <Box>\n <Text color=\"cyan\">Opening editor for #{issueNumber}…</Text>\n </Box>\n );\n }\n\n return (\n <Box>\n <Text color=\"cyan\">comment #{issueNumber}: </Text>\n <TextInput\n defaultValue={value}\n placeholder=\"type comment (ctrl+e for editor), Enter to post...\"\n onChange={setValue}\n onSubmit={(text) => {\n if (text.trim()) onSubmit(text.trim());\n else onCancel();\n }}\n />\n </Box>\n );\n}\n\nexport { CommentInput };\n","import { Box, Text, useInput } from \"ink\";\n\ninterface ConfirmPromptProps {\n readonly message: string;\n readonly onConfirm: () => void;\n readonly onCancel: () => void;\n}\n\nfunction ConfirmPrompt({ message, onConfirm, onCancel }: ConfirmPromptProps) {\n useInput((input, key) => {\n if (input === \"y\" || input === \"Y\") return onConfirm();\n if (input === \"n\" || input === \"N\" || key.escape) return onCancel();\n });\n\n return (\n <Box>\n <Text color=\"cyan\">{message}</Text>\n <Text color=\"gray\"> (y/n)</Text>\n </Box>\n );\n}\n\nexport { ConfirmPrompt };\n","import { Spinner } from \"@inkjs/ui\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type { LabelOption } from \"../../github.js\";\nimport { fetchRepoLabelsAsync } from \"../../github.js\";\n\ninterface LabelPickerProps {\n readonly repo: string;\n readonly currentLabels: string[];\n /** Session-level cache — passed by ref so it persists across overlay open/close */\n readonly labelCache: Record<string, LabelOption[]>;\n readonly onConfirm: (addLabels: string[], removeLabels: string[]) => void;\n readonly onCancel: () => void;\n readonly onError: (msg: string) => void;\n}\n\nfunction LabelPicker({\n repo,\n currentLabels,\n labelCache,\n onConfirm,\n onCancel,\n onError,\n}: LabelPickerProps) {\n const [labels, setLabels] = useState<LabelOption[] | null>(labelCache[repo] ?? null);\n const [loading, setLoading] = useState(labels === null);\n const [fetchAttempted, setFetchAttempted] = useState(false);\n // Selected label names (start with current labels pre-selected)\n const [selected, setSelected] = useState<ReadonlySet<string>>(new Set(currentLabels));\n const [cursor, setCursor] = useState(0);\n const submittedRef = useRef(false);\n\n // Fetch labels lazily on mount if not cached.\n // `fetchAttempted` guards against re-firing on error (labels stays null on error,\n // so removing `labels` from deps and using this flag breaks the infinite loop).\n // biome-ignore lint/correctness/useExhaustiveDependencies: `labels` intentionally omitted — fetchAttempted flag prevents the infinite re-fetch loop that occurs when labels stays null after an error\n useEffect(() => {\n if (labels !== null || fetchAttempted) return;\n setFetchAttempted(true);\n setLoading(true);\n let canceled = false;\n fetchRepoLabelsAsync(repo)\n .then((fetched) => {\n if (canceled) return;\n labelCache[repo] = fetched;\n setLabels(fetched);\n setLoading(false);\n })\n .catch(() => {\n if (canceled) return;\n setLoading(false);\n onError(`Could not fetch labels for ${repo}`);\n });\n return () => {\n canceled = true;\n };\n }, [repo, fetchAttempted, labelCache, onError]);\n\n useInput((input, key) => {\n if (loading) return;\n\n if (key.escape) {\n onCancel();\n return;\n }\n\n if (key.return) {\n if (submittedRef.current) return;\n submittedRef.current = true;\n\n const allLabels = labels ?? [];\n const add = [...selected].filter((l) => !currentLabels.includes(l));\n const remove = currentLabels.filter((l) => {\n // Only remove non-orphaned labels (labels that exist in the repo list)\n const exists = allLabels.some((rl) => rl.name === l);\n return exists && !selected.has(l);\n });\n\n onConfirm(add, remove);\n return;\n }\n\n if (input === \" \") {\n const allLabels = labels ?? [];\n const item = allLabels[cursor];\n if (!item) return;\n setSelected((prev) => {\n const next = new Set(prev);\n if (next.has(item.name)) {\n next.delete(item.name);\n } else {\n next.add(item.name);\n }\n return next;\n });\n return;\n }\n\n if (input === \"j\" || key.downArrow) {\n setCursor((i) => Math.min(i + 1, (labels?.length ?? 1) - 1));\n }\n if (input === \"k\" || key.upArrow) {\n setCursor((i) => Math.max(i - 1, 0));\n }\n });\n\n if (loading) {\n return (\n <Box>\n <Spinner label=\"Fetching labels...\" />\n </Box>\n );\n }\n\n const allLabels = labels ?? [];\n\n if (allLabels.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Labels:\n </Text>\n <Text dimColor>No labels in this repo</Text>\n <Text dimColor>Esc:cancel</Text>\n </Box>\n );\n }\n\n // Orphaned: labels on the issue that don't exist in the repo label list\n const repoLabelNames = new Set(allLabels.map((l) => l.name));\n const orphanedLabels = currentLabels.filter((l) => !repoLabelNames.has(l));\n\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Labels (Space:toggle Enter:confirm Esc:cancel):\n </Text>\n {orphanedLabels.map((name) => (\n <Text key={`orphan:${name}`} dimColor>\n {selected.has(name) ? \"[x]\" : \"[ ]\"} {name} (orphaned)\n </Text>\n ))}\n {allLabels.map((label, i) => {\n const isSel = i === cursor;\n const isChecked = selected.has(label.name);\n return (\n <Text key={label.name} {...(isSel ? { color: \"cyan\" as const } : {})}>\n {isSel ? \">\" : \" \"} {isChecked ? \"[x]\" : \"[ ]\"} {label.name}\n </Text>\n );\n })}\n </Box>\n );\n}\n\nexport { LabelPicker };\n","import { TextInput } from \"@inkjs/ui\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useState } from \"react\";\nimport type { RepoConfig } from \"../../config.js\";\nimport type { LabelOption } from \"../../github.js\";\nimport { LabelPicker } from \"./label-picker.js\";\n\ninterface CreateIssueFormProps {\n readonly repos: RepoConfig[];\n readonly defaultRepo: string | null;\n readonly onSubmit: (\n repo: string,\n title: string,\n body: string,\n dueDate: string | null,\n labels?: string[],\n ) => void;\n readonly onCancel: () => void;\n /** Session-level label cache — passed from dashboard so it persists across form open/close */\n readonly labelCache?: Record<string, LabelOption[]>;\n}\n\nfunction CreateIssueForm({\n repos,\n defaultRepo,\n onSubmit,\n onCancel,\n labelCache,\n}: CreateIssueFormProps) {\n const defaultRepoIdx = defaultRepo\n ? Math.max(\n 0,\n repos.findIndex((r) => r.name === defaultRepo),\n )\n : 0;\n\n const [repoIdx, setRepoIdx] = useState(defaultRepoIdx);\n const [title, setTitle] = useState(\"\");\n const [field, setField] = useState<\"repo\" | \"title\" | \"labels\">(\"title\");\n\n useInput((input, key) => {\n // LabelPicker handles its own input in the labels step\n if (field === \"labels\") return;\n\n if (key.escape) return onCancel();\n\n if (field === \"repo\") {\n if (input === \"j\" || key.downArrow) {\n setRepoIdx((i) => Math.min(i + 1, repos.length - 1));\n }\n if (input === \"k\" || key.upArrow) {\n setRepoIdx((i) => Math.max(i - 1, 0));\n }\n if (key.tab) setField(\"title\");\n if (key.return) setField(\"title\");\n }\n });\n\n const selectedRepo = repos[repoIdx];\n\n // Labels step — LabelPicker takes over input completely\n if (field === \"labels\" && selectedRepo) {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Create Issue — Add Labels (optional)\n </Text>\n <Text dimColor>\n Repo: {selectedRepo.shortName} Title: {title}\n </Text>\n <LabelPicker\n repo={selectedRepo.name}\n currentLabels={[]}\n labelCache={labelCache ?? {}}\n onConfirm={(addLabels) => {\n onSubmit(\n selectedRepo.name,\n title,\n \"\",\n null,\n addLabels.length > 0 ? addLabels : undefined,\n );\n }}\n onCancel={() => {\n // Esc skips labels and submits without them\n onSubmit(selectedRepo.name, title, \"\", null);\n }}\n onError={() => {\n // On fetch error, skip labels and submit\n onSubmit(selectedRepo.name, title, \"\", null);\n }}\n />\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Create Issue\n </Text>\n\n {/* Repo selector */}\n <Box>\n <Text dimColor={field !== \"repo\"}>Repo: </Text>\n {repos.map((r, i) => (\n <Text\n key={r.name}\n {...(i === repoIdx ? { color: \"cyan\" as const, bold: true } : {})}\n dimColor={field !== \"repo\"}\n >\n {i === repoIdx ? `[${r.shortName}]` : ` ${r.shortName} `}\n </Text>\n ))}\n {field === \"repo\" ? <Text dimColor> j/k:select Tab:next</Text> : null}\n </Box>\n\n {/* Title input */}\n <Box>\n <Text dimColor={field !== \"title\"}>Title: </Text>\n {field === \"title\" ? (\n <TextInput\n defaultValue={title}\n placeholder=\"issue title...\"\n onChange={setTitle}\n onSubmit={(text) => {\n const trimmed = text.trim();\n if (!(trimmed && selectedRepo)) return;\n if (labelCache !== undefined) {\n // Advance to labels step\n setTitle(trimmed);\n setField(\"labels\");\n } else {\n onSubmit(selectedRepo.name, trimmed, \"\", null);\n }\n }}\n />\n ) : (\n <Text>{title || \"(empty)\"}</Text>\n )}\n </Box>\n\n <Text dimColor>Tab:switch fields Enter:next Esc:cancel</Text>\n </Box>\n );\n}\n\nexport { CreateIssueForm };\n","import { spawnSync } from \"node:child_process\";\nimport { mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { Box, Text, useStdin } from \"ink\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type { RepoConfig } from \"../../config.js\";\nimport type { GitHubIssue, LabelOption, StatusOption } from \"../../github.js\";\nimport {\n assignIssueToAsync,\n editIssueBodyAsync,\n editIssueTitleAsync,\n fetchRepoLabelsAsync,\n unassignIssueAsync,\n updateLabelsAsync,\n updateProjectItemStatusAsync,\n} from \"../../github.js\";\nimport type { ActionLogEntry } from \"../hooks/use-action-log.js\";\nimport { nextEntryId } from \"../hooks/use-action-log.js\";\nimport { getInkInstance } from \"../ink-instance.js\";\n\ninterface EditIssueOverlayProps {\n readonly issue: GitHubIssue;\n readonly repoName: string;\n readonly repoConfig: RepoConfig | null;\n readonly statusOptions: StatusOption[];\n readonly labelCache: Record<string, LabelOption[]>;\n readonly onDone: () => void;\n readonly onPauseRefresh?: () => void;\n readonly onResumeRefresh?: () => void;\n readonly onToastInfo: (msg: string) => void;\n readonly onToastError: (msg: string) => void;\n readonly onPushEntry?: (entry: ActionLogEntry) => void;\n}\n\ninterface ParsedFrontMatter {\n title: string;\n status: string;\n labels: string[];\n assignee: string;\n body: string;\n}\n\nfunction buildEditorFile(\n issue: GitHubIssue,\n repoName: string,\n statusOptions: StatusOption[],\n repoLabels: LabelOption[],\n): string {\n const statusNames = statusOptions.map((o) => o.name).join(\", \");\n const labelNames = repoLabels.map((l) => l.name).join(\", \");\n const currentLabels = issue.labels.map((l) => l.name);\n const currentAssignee = (issue.assignees ?? [])[0]?.login ?? \"\";\n\n const labelsYaml =\n currentLabels.length > 0 ? currentLabels.map((l) => ` - ${l}`).join(\"\\n\") : \" # - label-name\";\n\n return `# --- HOG ISSUE EDIT ---\n# Editing: ${repoName}#${issue.number}\n# Available status: ${statusNames || \"none\"}\n# Available labels: ${labelNames || \"none\"}\n# ──────────────────────────────────────────────────────────────\ntitle: ${issue.title}\nstatus: ${issue.projectStatus ?? \"\"}\nlabels:\n${labelsYaml}\nassignee: ${currentAssignee}\n---\n\n${issue.body ?? \"\"}`;\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: YAML front matter parser\nfunction parseFrontMatter(content: string): ParsedFrontMatter {\n // Strip comment lines (# ...) before parsing\n const lines = content.split(\"\\n\");\n // Find the separator --- after the front matter block (skip leading comment lines)\n let frontMatterStart = -1;\n let frontMatterEnd = -1;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (line.trimStart().startsWith(\"#\")) continue; // skip comment lines\n if (frontMatterStart === -1 && (line.trim() === \"---\" || line.startsWith(\"title:\"))) {\n frontMatterStart = i;\n // If this line is \"---\", the FM starts on next line\n if (line.trim() === \"---\") frontMatterStart = i + 1;\n } else if (frontMatterStart !== -1 && line.trim() === \"---\") {\n frontMatterEnd = i;\n break;\n }\n }\n\n // Collect front matter lines (non-comment, non-empty lines before the body separator)\n const fmLines: string[] = [];\n if (frontMatterStart >= 0 && frontMatterEnd > frontMatterStart) {\n for (let i = frontMatterStart; i < frontMatterEnd; i++) {\n const line = lines[i] ?? \"\";\n if (!line.trimStart().startsWith(\"#\")) fmLines.push(line);\n }\n }\n\n // Simple key-value parser\n let title = \"\";\n let status = \"\";\n const labels: string[] = [];\n let assignee = \"\";\n let inLabels = false;\n\n for (const line of fmLines) {\n if (line.startsWith(\"title:\")) {\n title = line.slice(\"title:\".length).trim();\n inLabels = false;\n } else if (line.startsWith(\"status:\")) {\n status = line.slice(\"status:\".length).trim();\n inLabels = false;\n } else if (line.startsWith(\"assignee:\")) {\n assignee = line.slice(\"assignee:\".length).trim();\n inLabels = false;\n } else if (line.startsWith(\"labels:\")) {\n inLabels = true;\n } else if (inLabels && line.trimStart().startsWith(\"- \")) {\n const label = line.trimStart().slice(2).trim();\n if (label && !label.startsWith(\"#\")) labels.push(label);\n } else if (line.match(/^\\w/)) {\n inLabels = false;\n }\n }\n\n // Body is everything after the closing ---\n const body =\n frontMatterEnd >= 0\n ? lines\n .slice(frontMatterEnd + 1)\n .join(\"\\n\")\n .trim()\n : \"\";\n\n return { title, status, labels, assignee, body };\n}\n\nfunction EditIssueOverlay({\n issue,\n repoName,\n repoConfig,\n statusOptions,\n labelCache,\n onDone,\n onPauseRefresh,\n onResumeRefresh,\n onToastInfo,\n onToastError,\n onPushEntry,\n}: EditIssueOverlayProps) {\n const [editing, setEditing] = useState(true);\n const { setRawMode } = useStdin();\n\n // Stable refs to avoid stale closures\n const onDoneRef = useRef(onDone);\n const onPauseRef = useRef(onPauseRefresh);\n const onResumeRef = useRef(onResumeRefresh);\n onDoneRef.current = onDone;\n onPauseRef.current = onPauseRefresh;\n onResumeRef.current = onResumeRefresh;\n\n useEffect(() => {\n if (!editing) return;\n\n // Use falsy check (not ??) to handle VISUAL=\"\" properly\n const editorEnv = process.env[\"VISUAL\"] || process.env[\"EDITOR\"] || \"vi\";\n const [cmd, ...extraArgs] = editorEnv.split(\" \").filter(Boolean);\n if (!cmd) {\n onDoneRef.current();\n return;\n }\n\n let tmpDir: string | null = null;\n let tmpFile: string | null = null;\n\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: editor session loop with per-field apply\n const runEditor = async () => {\n // Fetch labels from cache or remotely\n let repoLabels: LabelOption[] = labelCache[repoName] ?? [];\n if (repoLabels.length === 0) {\n try {\n repoLabels = await fetchRepoLabelsAsync(repoName);\n } catch {\n // best-effort; continue without labels\n }\n }\n\n tmpDir = mkdtempSync(join(tmpdir(), \"hog-edit-\"));\n tmpFile = join(tmpDir, `issue-${issue.number}.md`);\n\n let currentContent = buildEditorFile(issue, repoName, statusOptions, repoLabels);\n writeFileSync(tmpFile, currentContent);\n\n onPauseRef.current?.();\n\n const inkInstance = getInkInstance();\n inkInstance?.clear();\n setRawMode(false);\n\n // Reopen loop — repeat on validation errors\n while (true) {\n writeFileSync(tmpFile, currentContent);\n const result = spawnSync(cmd, [...extraArgs, tmpFile], { stdio: \"inherit\" });\n\n // Non-zero exit or signal = editor crashed/cancelled\n if (result.status !== 0 || result.signal !== null || result.error) {\n break;\n }\n\n currentContent = readFileSync(tmpFile, \"utf-8\");\n const parsed = parseFrontMatter(currentContent);\n\n // Zero-changes detection\n const origLabels = issue.labels.map((l) => l.name).sort();\n const newLabels = [...parsed.labels].sort();\n const origAssignee = (issue.assignees ?? [])[0]?.login ?? \"\";\n const unchanged =\n parsed.title === issue.title &&\n parsed.status === (issue.projectStatus ?? \"\") &&\n JSON.stringify(origLabels) === JSON.stringify(newLabels) &&\n parsed.assignee === origAssignee &&\n parsed.body === (issue.body ?? \"\").trim();\n\n if (unchanged) {\n onToastInfo(\"No changes made\");\n break;\n }\n\n // Validation\n const errors: string[] = [];\n if (!parsed.title.trim()) errors.push(\"title cannot be empty\");\n if (\n parsed.status &&\n statusOptions.length > 0 &&\n !statusOptions.some((o) => o.name === parsed.status)\n ) {\n const valid = statusOptions.map((o) => o.name).join(\", \");\n errors.push(`status \"${parsed.status}\" not found → valid: ${valid}`);\n }\n\n if (errors.length > 0) {\n // Inject error comments at top of preserved user content\n const errorBlock = `${errors.map((e) => `# ERROR: ${e}`).join(\"\\n\")}\\n`;\n currentContent = errorBlock + currentContent;\n continue; // reopen editor\n }\n\n // Apply changes sequentially with individual try/catch\n setRawMode(true);\n const changedFields: string[] = [];\n\n if (parsed.title !== issue.title) {\n try {\n await editIssueTitleAsync(repoName, issue.number, parsed.title);\n changedFields.push(\"title\");\n } catch {\n onToastError(`Failed to update title on #${issue.number}`);\n }\n }\n\n if (parsed.body !== (issue.body ?? \"\").trim()) {\n try {\n await editIssueBodyAsync(repoName, issue.number, parsed.body);\n changedFields.push(\"body\");\n } catch {\n onToastError(`Failed to update body on #${issue.number}`);\n }\n }\n\n if (parsed.status && parsed.status !== (issue.projectStatus ?? \"\") && repoConfig) {\n const targetOption = statusOptions.find((o) => o.name === parsed.status);\n if (targetOption) {\n try {\n await updateProjectItemStatusAsync(repoName, issue.number, {\n projectNumber: repoConfig.projectNumber,\n statusFieldId: repoConfig.statusFieldId,\n optionId: targetOption.id,\n });\n changedFields.push(\"status\");\n } catch {\n onToastError(`Failed to update status on #${issue.number}`);\n }\n }\n }\n\n // Labels: compute adds/removes\n const addLabels = parsed.labels.filter((l) => !origLabels.includes(l));\n const removeLabels = origLabels.filter((l) => !parsed.labels.includes(l));\n if (addLabels.length > 0 || removeLabels.length > 0) {\n try {\n await updateLabelsAsync(repoName, issue.number, addLabels, removeLabels);\n changedFields.push(\"labels\");\n } catch {\n onToastError(`Failed to update labels on #${issue.number}`);\n }\n }\n\n if (parsed.assignee !== origAssignee) {\n try {\n if (parsed.assignee) {\n await assignIssueToAsync(repoName, issue.number, parsed.assignee);\n }\n if (origAssignee) {\n await unassignIssueAsync(repoName, issue.number, origAssignee);\n }\n changedFields.push(\"assignee\");\n } catch {\n onToastError(`Failed to update assignee on #${issue.number}`);\n }\n }\n\n if (changedFields.length > 0) {\n onToastInfo(`#${issue.number}: ${changedFields.join(\", \")} updated`);\n onPushEntry?.({\n id: nextEntryId(),\n description: `#${issue.number} edited (${changedFields.join(\", \")})`,\n status: \"success\",\n ago: Date.now(),\n });\n }\n break;\n }\n };\n\n runEditor()\n .catch(() => {\n // ignore errors — best effort\n })\n .finally(() => {\n // Always restore raw mode\n try {\n setRawMode(true);\n } catch {\n // ignore\n }\n onResumeRef.current?.();\n if (tmpDir) {\n try {\n rmSync(tmpDir, { recursive: true, force: true });\n } catch {\n // ignore cleanup errors\n }\n }\n setEditing(false);\n onDoneRef.current();\n });\n }, [\n editing,\n issue,\n repoName,\n repoConfig,\n statusOptions,\n labelCache,\n setRawMode,\n onToastInfo,\n onToastError,\n onPushEntry,\n ]);\n\n if (!editing) return null;\n\n return (\n <Box>\n <Text color=\"cyan\">Opening editor for #{issue.number}…</Text>\n </Box>\n );\n}\n\nexport { EditIssueOverlay, buildEditorFile, parseFrontMatter };\nexport type { EditIssueOverlayProps };\n","import { Box, Text, useInput } from \"ink\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type FocusEndAction = \"restart\" | \"break\" | \"done\" | \"exit\";\n\ninterface FocusModeProps {\n /** Label to show (e.g. \"aibility#142 — Fix login bug\") */\n label: string;\n /** Duration in seconds (default 1500 = 25 min) */\n durationSec: number;\n /** Called when user exits focus mode */\n onExit: () => void;\n /** Called when timer ends and user picks an action */\n onEndAction: (action: FocusEndAction) => void;\n}\n\nfunction formatTime(secs: number): string {\n const m = Math.floor(secs / 60);\n const s = secs % 60;\n return `${String(m).padStart(2, \"0\")}:${String(s).padStart(2, \"0\")}`;\n}\n\nexport function FocusMode({ label, durationSec, onExit, onEndAction }: FocusModeProps) {\n const [remaining, setRemaining] = useState(durationSec);\n const [timerDone, setTimerDone] = useState(false);\n const bellSentRef = useRef(false);\n\n // Countdown timer\n useEffect(() => {\n if (timerDone) return;\n\n const interval = setInterval(() => {\n setRemaining((prev) => {\n if (prev <= 1) {\n clearInterval(interval);\n setTimerDone(true);\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n\n return () => clearInterval(interval);\n }, [timerDone]);\n\n // Terminal bell on completion\n useEffect(() => {\n if (timerDone && !bellSentRef.current) {\n bellSentRef.current = true;\n process.stdout.write(\"\\x07\");\n }\n }, [timerDone]);\n\n // Input: during timer, only Escape exits\n // After timer, show prompt: c=Continue, b=Break, d=Done, Esc=Exit\n const handleInput = useCallback(\n (input: string, key: { escape: boolean }) => {\n if (key.escape) {\n if (timerDone) {\n onEndAction(\"exit\");\n } else {\n onExit();\n }\n return;\n }\n\n if (!timerDone) return; // No other keys during timer\n\n switch (input.toLowerCase()) {\n case \"c\":\n onEndAction(\"restart\");\n break;\n case \"b\":\n onEndAction(\"break\");\n break;\n case \"d\":\n onEndAction(\"done\");\n break;\n }\n },\n [timerDone, onExit, onEndAction],\n );\n\n useInput(handleInput);\n\n if (timerDone) {\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text color=\"green\" bold>\n Focus complete!\n </Text>\n <Text color=\"gray\"> {label}</Text>\n </Box>\n <Box marginTop={1}>\n <Text color=\"cyan\">[c]</Text>\n <Text> Continue </Text>\n <Text color=\"cyan\">[b]</Text>\n <Text> Break </Text>\n <Text color=\"cyan\">[d]</Text>\n <Text> Done </Text>\n <Text color=\"gray\">[Esc]</Text>\n <Text> Exit</Text>\n </Box>\n </Box>\n );\n }\n\n const progress = 1 - remaining / durationSec;\n const barWidth = 20;\n const filled = Math.round(progress * barWidth);\n const bar = \"\\u2588\".repeat(filled) + \"\\u2591\".repeat(barWidth - filled);\n\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text color=\"magenta\" bold>\n Focus:{\" \"}\n </Text>\n <Text>{label}</Text>\n </Box>\n <Box>\n <Text color=\"magenta\">{bar}</Text>\n <Text> </Text>\n <Text bold>{formatTime(remaining)}</Text>\n <Text color=\"gray\"> remaining</Text>\n </Box>\n <Text color=\"gray\" dimColor>\n Esc to exit focus\n </Text>\n </Box>\n );\n}\n\nexport { formatTime };\n","import { TextInput } from \"@inkjs/ui\";\nimport { Fzf } from \"fzf\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useMemo, useState } from \"react\";\nimport type { RepoData } from \"../fetch.js\";\n\ninterface FuzzyPickerIssue {\n readonly navId: string;\n readonly repoShortName: string;\n readonly number: number;\n readonly title: string;\n readonly labels: string;\n readonly assignee: string;\n readonly repoName: string;\n}\n\ninterface FuzzyPickerProps {\n readonly repos: RepoData[];\n readonly onSelect: (navId: string) => void;\n readonly onClose: () => void;\n}\n\nfunction keepCursorVisible(cursor: number, offset: number, visible: number): number {\n if (cursor < offset) return cursor;\n if (cursor >= offset + visible) return cursor - visible + 1;\n return offset;\n}\n\nfunction FuzzyPicker({ repos, onSelect, onClose }: FuzzyPickerProps) {\n const [query, setQuery] = useState(\"\");\n const [cursor, setCursor] = useState(0);\n const [scrollOffset, setScrollOffset] = useState(0);\n\n // Flatten all issues from repos into a searchable list\n const allIssues = useMemo((): FuzzyPickerIssue[] => {\n const items: FuzzyPickerIssue[] = [];\n for (const rd of repos) {\n for (const issue of rd.issues) {\n items.push({\n navId: `gh:${rd.repo.name}:${issue.number}`,\n repoShortName: rd.repo.shortName,\n number: issue.number,\n title: issue.title,\n labels: issue.labels.map((l) => l.name).join(\" \"),\n assignee: (issue.assignees ?? []).map((a) => a.login).join(\" \"),\n repoName: rd.repo.name,\n });\n }\n }\n return items;\n }, [repos]);\n\n // Build fuzzy indexes (rebuilt only when allIssues changes, not on each keystroke)\n const fuzzyIndex = useMemo(\n () => ({\n byTitle: new Fzf(allIssues, {\n selector: (i: FuzzyPickerIssue) => i.title,\n casing: \"smart-case\",\n }),\n byRepo: new Fzf(allIssues, {\n selector: (i: FuzzyPickerIssue) => i.repoShortName,\n casing: \"smart-case\",\n }),\n byNum: new Fzf(allIssues, {\n selector: (i: FuzzyPickerIssue) => `#${String(i.number)}`,\n casing: \"case-insensitive\",\n }),\n byLabel: new Fzf(allIssues, {\n selector: (i: FuzzyPickerIssue) => i.labels,\n casing: \"smart-case\",\n }),\n }),\n [allIssues],\n );\n\n // Fuzzy search results (rebuilt on each query change)\n const results = useMemo((): FuzzyPickerIssue[] => {\n if (!query.trim()) return allIssues.slice(0, 20);\n\n const WEIGHTS = { title: 1.0, repo: 0.6, num: 2.0, label: 0.5 };\n const scoreMap = new Map<string, { item: FuzzyPickerIssue; score: number }>();\n\n function upsert(hits: { item: FuzzyPickerIssue; score: number }[], w: number) {\n for (const h of hits) {\n const s = h.score * w;\n const e = scoreMap.get(h.item.navId);\n if (!e || s > e.score) scoreMap.set(h.item.navId, { item: h.item, score: s });\n }\n }\n\n upsert(fuzzyIndex.byTitle.find(query), WEIGHTS.title);\n upsert(fuzzyIndex.byRepo.find(query), WEIGHTS.repo);\n upsert(fuzzyIndex.byNum.find(query), WEIGHTS.num);\n upsert(fuzzyIndex.byLabel.find(query), WEIGHTS.label);\n\n return [...scoreMap.values()].sort((a, b) => b.score - a.score).map((e) => e.item);\n }, [query, fuzzyIndex, allIssues]);\n\n const VISIBLE = Math.min((process.stdout.rows ?? 24) - 4, 15);\n\n // Internal keyboard navigation (Arrow keys, Ctrl-J/K, Enter, Escape)\n useInput((input, key) => {\n if (key.downArrow || (key.ctrl && input === \"j\")) {\n const newCursor = Math.min(cursor + 1, results.length - 1);\n setCursor(newCursor);\n setScrollOffset((prev) => keepCursorVisible(newCursor, prev, VISIBLE));\n return;\n }\n if (key.upArrow || (key.ctrl && input === \"k\")) {\n const newCursor = Math.max(cursor - 1, 0);\n setCursor(newCursor);\n setScrollOffset((prev) => keepCursorVisible(newCursor, prev, VISIBLE));\n return;\n }\n if (key.return) {\n const selected = results[cursor];\n if (selected) {\n onSelect(selected.navId);\n }\n return;\n }\n if (key.escape) {\n onClose();\n }\n });\n\n const visibleResults = results.slice(scrollOffset, scrollOffset + VISIBLE);\n const totalCount = results.length;\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"cyan\" paddingX={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Find issue{\" \"}\n </Text>\n <Text color=\"gray\">\n ({totalCount} match{totalCount !== 1 ? \"es\" : \"\"}){\" \"}\n </Text>\n <Text color=\"gray\" dimColor>\n ↑↓/Ctrl-J/K nav Enter:jump Esc:close\n </Text>\n </Box>\n <Box>\n <Text color=\"yellow\">{\">\"} </Text>\n <TextInput\n defaultValue={query}\n placeholder=\"type to search...\"\n onChange={(v) => {\n setQuery(v);\n setCursor(0);\n setScrollOffset(0);\n }}\n onSubmit={() => {\n const selected = results[cursor];\n if (selected) onSelect(selected.navId);\n }}\n />\n </Box>\n {scrollOffset > 0 ? (\n <Text color=\"gray\" dimColor>\n ▲ {scrollOffset} more above\n </Text>\n ) : null}\n {visibleResults.map((issue, idx) => {\n const isSelected = scrollOffset + idx === cursor;\n const labelStr = issue.labels\n ? ` [${issue.labels.split(\" \").slice(0, 2).join(\"] [\")}]`\n : \"\";\n const assigneeStr = issue.assignee ? ` @${issue.assignee.split(\" \")[0]}` : \"\";\n return (\n <Box key={issue.navId}>\n {isSelected ? (\n <Text color=\"cyan\" bold>\n {\">\"} {issue.repoShortName}#{issue.number} {issue.title}\n {labelStr}\n {assigneeStr}\n </Text>\n ) : (\n <Text>\n {\" \"}\n {issue.repoShortName}#{issue.number} {issue.title}\n {labelStr}\n {assigneeStr}\n </Text>\n )}\n </Box>\n );\n })}\n {totalCount === 0 ? <Text dimColor>No issues match &quot;{query}&quot;</Text> : null}\n {results.length > scrollOffset + VISIBLE ? (\n <Text color=\"gray\" dimColor>\n ▼ {results.length - scrollOffset - VISIBLE} more below\n </Text>\n ) : null}\n </Box>\n );\n}\n\nexport { FuzzyPicker };\nexport type { FuzzyPickerProps };\n","import { Box, Text, useInput } from \"ink\";\nimport type { UIMode } from \"../hooks/use-ui-state.js\";\n\ninterface HelpOverlayProps {\n readonly currentMode: UIMode;\n readonly onClose: () => void;\n}\n\nconst SHORTCUTS = [\n {\n category: \"Navigation\",\n items: [\n { key: \"j / Down\", desc: \"Move down\" },\n { key: \"k / Up\", desc: \"Move up\" },\n { key: \"Tab\", desc: \"Next repo tab\" },\n { key: \"Shift+Tab\", desc: \"Previous repo tab\" },\n { key: \"1-9\", desc: \"Jump to repo tab by number\" },\n { key: \"s / S\", desc: \"Next / prev status tab\" },\n ],\n },\n {\n category: \"View\",\n items: [\n { key: \"Enter\", desc: \"Open issue in browser\" },\n { key: \"0\", desc: \"Detail panel (full-screen on narrow terminals)\" },\n { key: \"Space\", desc: \"Multi-select item\" },\n { key: \"/\", desc: \"Search (inline filter)\" },\n { key: \"F\", desc: \"Fuzzy find issue (telescope-style)\" },\n { key: \"t\", desc: \"Toggle @me filter (my issues only)\" },\n { key: \"f\", desc: \"Focus mode\" },\n { key: \"?\", desc: \"Toggle help\" },\n { key: \"Esc\", desc: \"Close overlay / Back to normal\" },\n ],\n },\n {\n category: \"Actions\",\n items: [\n { key: \"p\", desc: \"Pick issue (assign + TickTick)\" },\n { key: \"a\", desc: \"Assign to self (no-op if already assigned)\" },\n { key: \"u\", desc: \"Undo last reversible action\" },\n { key: \"e\", desc: \"Edit issue in $EDITOR (title, assignee, status, labels)\" },\n { key: \"c\", desc: \"Comment on issue\" },\n { key: \"m\", desc: \"Move status\" },\n { key: \"e\", desc: \"Edit issue in $EDITOR\" },\n { key: \"o\", desc: \"Open Slack thread\" },\n { key: \"y\", desc: \"Copy issue link to clipboard\" },\n { key: \"n\", desc: \"Create new issue\" },\n { key: \"I\", desc: \"Natural-language issue create\" },\n { key: \"l\", desc: \"Manage labels\" },\n ],\n },\n {\n category: \"Board\",\n items: [\n { key: \"L\", desc: \"Toggle action log\" },\n { key: \"r\", desc: \"Refresh data\" },\n { key: \"q\", desc: \"Quit\" },\n ],\n },\n];\n\nfunction HelpOverlay({ currentMode, onClose }: HelpOverlayProps) {\n useInput((_input, key) => {\n if (key.escape) onClose();\n });\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"cyan\" paddingX={1}>\n <Box justifyContent=\"space-between\">\n <Text color=\"cyan\" bold>\n Keyboard Shortcuts\n </Text>\n <Text dimColor>mode: {currentMode}</Text>\n </Box>\n <Text> </Text>\n {SHORTCUTS.map((group) => (\n <Box key={group.category} flexDirection=\"column\" marginBottom={1}>\n <Text color=\"yellow\" bold>\n {group.category}\n </Text>\n {group.items.map((item) => (\n <Box key={item.key}>\n <Box width={16}>\n <Text color=\"green\">{item.key}</Text>\n </Box>\n <Text>{item.desc}</Text>\n </Box>\n ))}\n </Box>\n ))}\n <Text dimColor>Press ? or Esc to close</Text>\n </Box>\n );\n}\n\nexport { HelpOverlay };\n","import { spawnSync } from \"node:child_process\";\nimport { mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { Spinner, TextInput } from \"@inkjs/ui\";\nimport { Box, Text, useInput, useStdin } from \"ink\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { ParsedIssue } from \"../../ai.js\";\nimport { extractIssueFields } from \"../../ai.js\";\nimport type { RepoConfig } from \"../../config.js\";\nimport type { LabelOption } from \"../../github.js\";\nimport { getInkInstance } from \"../ink-instance.js\";\n\ntype Step = \"input\" | \"body\";\n\ninterface NlCreateOverlayProps {\n readonly repos: RepoConfig[];\n readonly defaultRepoName: string | null;\n readonly labelCache: Record<string, LabelOption[]>;\n readonly onSubmit: (\n repo: string,\n title: string,\n body: string,\n dueDate: string | null,\n labels?: string[],\n ) => void;\n readonly onCancel: () => void;\n readonly onPauseRefresh?: (() => void) | undefined;\n readonly onResumeRefresh?: (() => void) | undefined;\n readonly onLlmFallback?: ((msg: string) => void) | undefined;\n}\n\nfunction NlCreateOverlay({\n repos,\n defaultRepoName,\n labelCache,\n onSubmit,\n onCancel,\n onPauseRefresh,\n onResumeRefresh,\n onLlmFallback,\n}: NlCreateOverlayProps) {\n const [, setInput] = useState(\"\");\n const [isParsing, setIsParsing] = useState(false);\n const [parsed, setParsed] = useState<ParsedIssue | null>(null);\n const [parseError, setParseError] = useState<string | null>(null);\n const [step, setStep] = useState<Step>(\"input\");\n const [body, setBody] = useState(\"\");\n const [editingBody, setEditingBody] = useState(false);\n\n // Guard against double-submit. Safe because the parent (dashboard) always calls\n // onOverlayDone() → ui.exitOverlay() after onSubmit, unmounting this component\n // on both success and failure paths.\n const submittedRef = useRef(false);\n const parseParamsRef = useRef<{\n input: string;\n validLabels: string[];\n } | null>(null);\n\n // Stable refs to avoid stale closures\n const onSubmitRef = useRef(onSubmit);\n const onCancelRef = useRef(onCancel);\n const onPauseRef = useRef(onPauseRefresh);\n const onResumeRef = useRef(onResumeRefresh);\n onSubmitRef.current = onSubmit;\n onCancelRef.current = onCancel;\n onPauseRef.current = onPauseRefresh;\n onResumeRef.current = onResumeRefresh;\n\n const { setRawMode } = useStdin();\n\n // Repo selection in preview (r key cycles)\n const defaultRepoIdx = defaultRepoName\n ? Math.max(\n 0,\n repos.findIndex((r) => r.name === defaultRepoName),\n )\n : 0;\n const [repoIdx, setRepoIdx] = useState(defaultRepoIdx);\n const selectedRepo = repos[repoIdx];\n\n useInput((inputChar, key) => {\n if (isParsing || editingBody) return;\n\n if (key.escape) {\n if (step === \"body\") {\n // Esc from body step goes back to preview\n setStep(\"input\");\n setParsed((p) => p); // keep parsed\n return;\n }\n onCancel();\n return;\n }\n\n // Preview mode controls\n if (parsed && step === \"input\") {\n if (key.return) {\n // Advance to body step\n setStep(\"body\");\n return;\n }\n if (inputChar === \"r\") {\n setRepoIdx((i) => (i + 1) % repos.length);\n return;\n }\n }\n\n // Body step: ctrl+e opens $EDITOR\n if (step === \"body\" && inputChar === \"\\x05\") {\n setEditingBody(true);\n }\n });\n\n // Launch $EDITOR for body input\n useEffect(() => {\n if (!editingBody) return;\n\n const editorEnv = process.env[\"VISUAL\"] ?? process.env[\"EDITOR\"] ?? \"vi\";\n const [cmd, ...extraArgs] = editorEnv.split(\" \").filter(Boolean);\n if (!cmd) {\n setEditingBody(false);\n return;\n }\n\n let tmpDir: string | null = null;\n let tmpFile: string | null = null;\n\n try {\n onPauseRef.current?.();\n tmpDir = mkdtempSync(join(tmpdir(), \"hog-body-\"));\n tmpFile = join(tmpDir, \"body.md\");\n writeFileSync(tmpFile, body);\n\n const inkInstance = getInkInstance();\n inkInstance?.clear();\n setRawMode(false);\n\n spawnSync(cmd, [...extraArgs, tmpFile], { stdio: \"inherit\" });\n\n const content = readFileSync(tmpFile, \"utf-8\");\n setRawMode(true);\n setBody(content.trimEnd());\n } finally {\n onResumeRef.current?.();\n if (tmpFile && tmpDir) {\n try {\n rmSync(tmpDir, { recursive: true, force: true });\n } catch {\n // ignore cleanup errors\n }\n }\n setEditingBody(false);\n }\n }, [editingBody, body, setRawMode]);\n\n // Parse on Enter from TextInput — capture context at submit time to avoid double-fire\n const handleInputSubmit = useCallback(\n (text: string) => {\n const trimmed = text.trim();\n if (!trimmed) return;\n const validLabels = selectedRepo\n ? (labelCache[selectedRepo.name] ?? []).map((l) => l.name)\n : [];\n parseParamsRef.current = { input: trimmed, validLabels };\n setInput(trimmed);\n setParseError(null);\n setIsParsing(true);\n },\n [selectedRepo, labelCache],\n );\n\n useEffect(() => {\n if (!(isParsing && parseParamsRef.current)) return;\n const { input: capturedInput, validLabels } = parseParamsRef.current;\n\n extractIssueFields(capturedInput, {\n validLabels,\n onLlmFallback: onLlmFallback,\n })\n .then((result) => {\n if (!result) {\n setParseError(\"Title is required\");\n setIsParsing(false);\n return;\n }\n const filteredLabels =\n validLabels.length > 0\n ? result.labels.filter((l) => validLabels.includes(l))\n : result.labels;\n setParsed({ ...result, labels: filteredLabels });\n setIsParsing(false);\n })\n .catch(() => {\n setParseError(\"Parsing failed — please try again\");\n setIsParsing(false);\n });\n }, [isParsing, onLlmFallback]);\n\n // ── Spinner view ──\n if (isParsing) {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n ✨ Creating Issue\n </Text>\n <Spinner label=\"Parsing...\" />\n </Box>\n );\n }\n\n // ── Body step ──\n if (parsed && step === \"body\") {\n if (editingBody) {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n ✨ Creating Issue\n </Text>\n <Text color=\"cyan\">Opening editor for body…</Text>\n </Box>\n );\n }\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n ✨ Creating Issue\n </Text>\n <Box>\n <Text dimColor>Title: </Text>\n <Text>{parsed.title}</Text>\n </Box>\n <Box>\n <Text color=\"cyan\">body: </Text>\n <TextInput\n defaultValue={body}\n placeholder=\"optional description (ctrl+e for editor)\"\n onChange={setBody}\n onSubmit={(text) => {\n if (submittedRef.current) return;\n submittedRef.current = true;\n if (!selectedRepo) return;\n const labels = buildLabelList(parsed);\n onSubmitRef.current(\n selectedRepo.name,\n parsed.title,\n text.trim(),\n parsed.dueDate,\n labels.length > 0 ? labels : undefined,\n );\n }}\n />\n </Box>\n <Text dimColor>Enter:create ctrl+e:editor Esc:back</Text>\n </Box>\n );\n }\n\n // ── Preview view ──\n if (parsed) {\n const labels = [...parsed.labels];\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n ✨ Creating Issue\n </Text>\n <Box>\n <Text dimColor>Repo: </Text>\n <Text color=\"cyan\">{selectedRepo?.shortName ?? \"(none)\"}</Text>\n {repos.length > 1 ? <Text dimColor> r:cycle</Text> : null}\n </Box>\n <Box>\n <Text dimColor>Title: </Text>\n <Text>{parsed.title}</Text>\n </Box>\n {labels.length > 0 ? (\n <Box>\n <Text dimColor>Labels: </Text>\n <Text>{labels.join(\", \")}</Text>\n </Box>\n ) : null}\n {parsed.assignee ? (\n <Box>\n <Text dimColor>Assignee: </Text>\n <Text>@{parsed.assignee}</Text>\n </Box>\n ) : null}\n {parsed.dueDate ? (\n <Box>\n <Text dimColor>Due: </Text>\n <Text>{formatDue(parsed.dueDate)}</Text>\n </Box>\n ) : null}\n <Text dimColor>Enter:add body Esc:cancel</Text>\n </Box>\n );\n }\n\n // ── Input view ──\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n ✨ What do you need to do?\n </Text>\n <Box>\n <Text color=\"cyan\">&gt; </Text>\n <TextInput\n placeholder=\"fix login bug #bug #priority:high @me due friday\"\n onChange={setInput}\n onSubmit={handleInputSubmit}\n />\n </Box>\n {parseError ? <Text color=\"red\">{parseError}</Text> : null}\n <Text dimColor>Tip: #label @user due &lt;date&gt; Enter:parse Esc:cancel</Text>\n </Box>\n );\n}\n\n/** Build the label list from parsed issue (labels only, due date goes in body). */\nfunction buildLabelList(parsed: ParsedIssue): string[] {\n return [...parsed.labels];\n}\n\n/** Format YYYY-MM-DD as \"Wed Feb 18\". */\nfunction formatDue(dueDate: string): string {\n const d = new Date(`${dueDate}T12:00:00`);\n return d.toLocaleDateString(\"en-US\", { weekday: \"short\", month: \"short\", day: \"numeric\" });\n}\n\nexport { NlCreateOverlay };\n","import { TextInput } from \"@inkjs/ui\";\nimport { Box, Text } from \"ink\";\n\ninterface SearchBarProps {\n readonly defaultValue: string;\n readonly onChange: (value: string) => void;\n readonly onSubmit: () => void;\n}\n\nfunction SearchBar({ defaultValue, onChange, onSubmit }: SearchBarProps) {\n return (\n <Box>\n <Text color=\"yellow\">/</Text>\n <TextInput\n defaultValue={defaultValue}\n placeholder=\"title, label, status, @user, #123, unassigned…\"\n onChange={onChange}\n onSubmit={onSubmit}\n />\n </Box>\n );\n}\n\nexport { SearchBar };\nexport type { SearchBarProps };\n","import { Box, Text, useInput } from \"ink\";\nimport { useRef, useState } from \"react\";\nimport type { StatusOption } from \"../../github.js\";\nimport { TERMINAL_STATUS_RE } from \"../constants.js\";\n\ninterface StatusPickerProps {\n readonly options: StatusOption[];\n readonly currentStatus: string | undefined;\n readonly onSelect: (optionId: string) => void;\n readonly onCancel: () => void;\n /** When true, terminal statuses appear with a \"(Done)\" suffix and require inline confirm */\n readonly showTerminalStatuses?: boolean;\n}\n\nfunction isTerminal(name: string): boolean {\n return TERMINAL_STATUS_RE.test(name);\n}\n\n// ── Input handler extracted to reduce component complexity ──\n\ninterface InputState {\n options: StatusOption[];\n selectedIdx: number;\n showTerminalStatuses: boolean;\n submittedRef: { current: boolean };\n onSelect: (id: string) => void;\n onCancel: () => void;\n onConfirmTerminal: () => void;\n onNavigate: (fn: (i: number) => number) => void;\n}\n\nfunction handlePickerInput(\n input: string,\n key: { escape: boolean; return: boolean; downArrow: boolean; upArrow: boolean },\n state: InputState,\n): void {\n if (key.escape) {\n state.onCancel();\n return;\n }\n if (key.return) {\n if (state.submittedRef.current) return;\n const opt = state.options[state.selectedIdx];\n if (!opt) return;\n if (isTerminal(opt.name) && state.showTerminalStatuses) {\n state.onConfirmTerminal();\n return;\n }\n state.submittedRef.current = true;\n state.onSelect(opt.id);\n return;\n }\n if (input === \"j\" || key.downArrow) {\n state.onNavigate((i) => Math.min(i + 1, state.options.length - 1));\n }\n if (input === \"k\" || key.upArrow) {\n state.onNavigate((i) => Math.max(i - 1, 0));\n }\n}\n\ninterface ConfirmState {\n opt: StatusOption | undefined;\n submittedRef: { current: boolean };\n onSelect: (id: string) => void;\n onExitConfirm: () => void;\n}\n\nfunction handleConfirmInput(input: string, key: { escape: boolean }, state: ConfirmState): void {\n if (input === \"y\" || input === \"Y\") {\n if (!state.submittedRef.current) {\n state.submittedRef.current = true;\n if (state.opt) state.onSelect(state.opt.id);\n }\n return;\n }\n if (input === \"n\" || input === \"N\" || key.escape) {\n state.onExitConfirm();\n }\n}\n\n// ── Component ──\n\nfunction StatusPicker({\n options,\n currentStatus,\n onSelect,\n onCancel,\n showTerminalStatuses = true,\n}: StatusPickerProps) {\n const [selectedIdx, setSelectedIdx] = useState(() => {\n const idx = options.findIndex((o) => o.name === currentStatus);\n return idx >= 0 ? idx : 0;\n });\n const [confirmingTerminal, setConfirmingTerminal] = useState(false);\n const submittedRef = useRef(false);\n\n useInput((input, key) => {\n if (confirmingTerminal) {\n handleConfirmInput(input, key, {\n opt: options[selectedIdx],\n submittedRef,\n onSelect,\n onExitConfirm: () => setConfirmingTerminal(false),\n });\n return;\n }\n handlePickerInput(input, key, {\n options,\n selectedIdx,\n showTerminalStatuses,\n submittedRef,\n onSelect,\n onCancel,\n onConfirmTerminal: () => setConfirmingTerminal(true),\n onNavigate: setSelectedIdx,\n });\n });\n\n if (confirmingTerminal) {\n const opt = options[selectedIdx];\n return (\n <Box flexDirection=\"column\">\n <Text color=\"yellow\" bold>\n Mark as {opt?.name}?\n </Text>\n <Text dimColor>This will close the issue on GitHub.</Text>\n <Text>Continue? [y/n]</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Move to status:\n </Text>\n {options.map((opt, i) => {\n const isCurrent = opt.name === currentStatus;\n const isSelected = i === selectedIdx;\n const terminal = isTerminal(opt.name) && showTerminalStatuses;\n const prefix = isSelected ? \"> \" : \" \";\n const suffix = isCurrent ? \" (current)\" : terminal ? \" (Done)\" : \"\";\n return (\n <Text\n key={opt.id}\n {...(isSelected\n ? { color: \"cyan\" as const }\n : terminal\n ? { color: \"yellow\" as const }\n : {})}\n dimColor={isCurrent}\n >\n {prefix}\n {opt.name}\n {suffix}\n </Text>\n );\n })}\n <Text dimColor>j/k:navigate Enter:select Esc:cancel</Text>\n </Box>\n );\n}\n\nexport { StatusPicker };\n","import type { HogConfig, RepoConfig } from \"../../config.js\";\nimport type { GitHubIssue, LabelOption, StatusOption } from \"../../github.js\";\nimport type { RepoData } from \"../fetch.js\";\nimport type { ActionLogEntry } from \"../hooks/use-action-log.js\";\nimport type { UIState } from \"../hooks/use-ui-state.js\";\nimport type { BulkAction } from \"./bulk-action-menu.js\";\nimport { BulkActionMenu } from \"./bulk-action-menu.js\";\nimport { CommentInput } from \"./comment-input.js\";\nimport { ConfirmPrompt } from \"./confirm-prompt.js\";\nimport { CreateIssueForm } from \"./create-issue-form.js\";\nimport { EditIssueOverlay } from \"./edit-issue-overlay.js\";\nimport type { FocusEndAction } from \"./focus-mode.js\";\nimport { FocusMode } from \"./focus-mode.js\";\nimport { FuzzyPicker } from \"./fuzzy-picker.js\";\nimport { HelpOverlay } from \"./help-overlay.js\";\nimport { LabelPicker } from \"./label-picker.js\";\nimport { NlCreateOverlay } from \"./nl-create-overlay.js\";\nimport { SearchBar } from \"./search-bar.js\";\nimport { StatusPicker } from \"./status-picker.js\";\n\nexport interface OverlayRendererProps {\n readonly uiState: UIState;\n readonly config: HogConfig;\n readonly repos: RepoData[];\n // Fuzzy picker\n readonly onFuzzySelect: (navId: string) => void;\n readonly onFuzzyClose: () => void;\n // Status picker\n readonly selectedRepoStatusOptions: StatusOption[];\n readonly currentStatus: string | undefined;\n readonly onStatusSelect: (optionId: string) => void;\n readonly onExitOverlay: () => void;\n // Create issue\n readonly defaultRepo: string | null;\n readonly onCreateIssue: (\n repo: string,\n title: string,\n body: string,\n dueDate: string | null,\n labels?: string[],\n ) => void;\n // Confirm pick\n readonly onConfirmPick: () => void;\n readonly onCancelPick: () => void;\n // Bulk action\n readonly multiSelectCount: number;\n readonly multiSelectType: \"github\" | \"ticktick\" | \"mixed\";\n readonly onBulkAction: (action: BulkAction) => void;\n // Focus mode\n readonly focusLabel: string | null;\n readonly focusKey: number;\n readonly onFocusExit: () => void;\n readonly onFocusEndAction: (action: FocusEndAction) => void;\n // Search\n readonly searchQuery: string;\n readonly onSearchChange: (query: string) => void;\n readonly onSearchSubmit: () => void;\n // Comment\n readonly selectedIssue: GitHubIssue | null;\n readonly onComment: (body: string) => void;\n readonly onPauseRefresh: () => void;\n readonly onResumeRefresh: () => void;\n // Help\n readonly onToggleHelp: () => void;\n // Label picker\n readonly labelCache: Record<string, LabelOption[]>;\n readonly onLabelConfirm: (addLabels: string[], removeLabels: string[]) => void;\n readonly onLabelError: (msg: string) => void;\n readonly onLlmFallback?: ((msg: string) => void) | undefined;\n // Edit issue overlay\n readonly selectedRepoName: string | null;\n readonly selectedRepoConfig: RepoConfig | null;\n readonly onToastInfo: (msg: string) => void;\n readonly onToastError: (msg: string) => void;\n readonly onPushEntry?: ((entry: ActionLogEntry) => void) | undefined;\n}\n\n/** Renders whichever overlay is active based on uiMode. */\nfunction OverlayRenderer({\n uiState,\n config,\n repos,\n onFuzzySelect,\n onFuzzyClose,\n selectedRepoStatusOptions,\n currentStatus,\n onStatusSelect,\n onExitOverlay,\n defaultRepo,\n onCreateIssue,\n onConfirmPick,\n onCancelPick,\n multiSelectCount,\n multiSelectType,\n onBulkAction,\n focusLabel,\n focusKey,\n onFocusExit,\n onFocusEndAction,\n searchQuery,\n onSearchChange,\n onSearchSubmit,\n selectedIssue,\n onComment,\n onPauseRefresh,\n onResumeRefresh,\n onToggleHelp,\n labelCache,\n onLabelConfirm,\n onLabelError,\n onLlmFallback,\n selectedRepoName,\n selectedRepoConfig,\n onToastInfo,\n onToastError,\n onPushEntry,\n}: OverlayRendererProps) {\n const { mode, helpVisible } = uiState;\n\n return (\n <>\n {/* Help overlay (stacks on top of any mode) */}\n {helpVisible ? <HelpOverlay currentMode={mode} onClose={onToggleHelp} /> : null}\n\n {/* Status picker overlay */}\n {mode === \"overlay:status\" && selectedRepoStatusOptions.length > 0 ? (\n <StatusPicker\n options={selectedRepoStatusOptions}\n currentStatus={currentStatus}\n onSelect={onStatusSelect}\n onCancel={onExitOverlay}\n />\n ) : null}\n\n {/* Create issue form overlay */}\n {mode === \"overlay:create\" ? (\n <CreateIssueForm\n repos={config.repos}\n defaultRepo={defaultRepo}\n onSubmit={onCreateIssue}\n onCancel={onExitOverlay}\n labelCache={labelCache}\n />\n ) : null}\n\n {/* Confirm pick prompt (after issue create) */}\n {mode === \"overlay:confirmPick\" ? (\n <ConfirmPrompt\n message=\"Pick this issue?\"\n onConfirm={onConfirmPick}\n onCancel={onCancelPick}\n />\n ) : null}\n\n {/* Bulk action menu overlay */}\n {mode === \"overlay:bulkAction\" ? (\n <BulkActionMenu\n count={multiSelectCount}\n selectionType={multiSelectType}\n onSelect={onBulkAction}\n onCancel={onExitOverlay}\n />\n ) : null}\n\n {/* Focus mode overlay */}\n {mode === \"focus\" && focusLabel ? (\n <FocusMode\n key={focusKey}\n label={focusLabel}\n durationSec={config.board.focusDuration ?? 1500}\n onExit={onFocusExit}\n onEndAction={onFocusEndAction}\n />\n ) : null}\n\n {/* Label picker overlay */}\n {mode === \"overlay:label\" && selectedIssue && defaultRepo ? (\n <LabelPicker\n repo={defaultRepo}\n currentLabels={selectedIssue.labels.map((l) => l.name)}\n labelCache={labelCache}\n onConfirm={onLabelConfirm}\n onCancel={onExitOverlay}\n onError={onLabelError}\n />\n ) : null}\n\n {/* Search bar */}\n {mode === \"search\" ? (\n <SearchBar defaultValue={searchQuery} onChange={onSearchChange} onSubmit={onSearchSubmit} />\n ) : null}\n\n {/* Comment input */}\n {mode === \"overlay:comment\" && selectedIssue ? (\n <CommentInput\n issueNumber={selectedIssue.number}\n onSubmit={onComment}\n onCancel={onExitOverlay}\n onPauseRefresh={onPauseRefresh}\n onResumeRefresh={onResumeRefresh}\n />\n ) : null}\n\n {/* Fuzzy picker overlay */}\n {mode === \"overlay:fuzzyPicker\" ? (\n <FuzzyPicker repos={repos} onSelect={onFuzzySelect} onClose={onFuzzyClose} />\n ) : null}\n\n {/* NL create overlay */}\n {mode === \"overlay:createNl\" ? (\n <NlCreateOverlay\n repos={config.repos}\n defaultRepoName={defaultRepo}\n labelCache={labelCache}\n onSubmit={onCreateIssue}\n onCancel={onExitOverlay}\n onPauseRefresh={onPauseRefresh}\n onResumeRefresh={onResumeRefresh}\n onLlmFallback={onLlmFallback}\n />\n ) : null}\n\n {/* Edit issue overlay (launches $EDITOR) */}\n {mode === \"overlay:editIssue\" && selectedIssue && selectedRepoName ? (\n <EditIssueOverlay\n issue={selectedIssue}\n repoName={selectedRepoName}\n repoConfig={selectedRepoConfig}\n statusOptions={selectedRepoStatusOptions}\n labelCache={labelCache}\n onDone={onExitOverlay}\n onPauseRefresh={onPauseRefresh}\n onResumeRefresh={onResumeRefresh}\n onToastInfo={onToastInfo}\n onToastError={onToastError}\n {...(onPushEntry ? { onPushEntry } : {})}\n />\n ) : null}\n </>\n );\n}\n\nexport { OverlayRenderer };\n","import { Box } from \"ink\";\nimport type { ReactNode } from \"react\";\n\n// ── Breakpoints ──\n\nexport const WIDE_THRESHOLD = 160; // full 5-panel layout\nexport const MEDIUM_THRESHOLD = 100; // 2-column (left + issues), no detail\nexport const LEFT_COL_WIDTH = 24;\nexport const ACTIVITY_HEIGHT = 5;\n\nexport type LayoutMode = \"wide\" | \"medium\" | \"stacked\";\n\nexport function getLayoutMode(cols: number): LayoutMode {\n if (cols >= WIDE_THRESHOLD) return \"wide\";\n if (cols >= MEDIUM_THRESHOLD) return \"medium\";\n return \"stacked\";\n}\n\nexport function getDetailWidth(cols: number): number {\n return Math.floor(cols * 0.4);\n}\n\n// ── Panel slots ──\n\ninterface PanelLayoutProps {\n readonly cols: number;\n readonly issuesPanelHeight: number;\n readonly reposPanel: ReactNode;\n readonly statusesPanel: ReactNode;\n readonly issuesPanel: ReactNode;\n readonly detailPanel: ReactNode;\n readonly activityPanel: ReactNode;\n}\n\nexport function PanelLayout({\n cols,\n issuesPanelHeight,\n reposPanel,\n statusesPanel,\n issuesPanel,\n detailPanel,\n activityPanel,\n}: PanelLayoutProps) {\n const mode = getLayoutMode(cols);\n\n if (mode === \"wide\") {\n const detailWidth = getDetailWidth(cols);\n return (\n <Box flexDirection=\"column\">\n {/* Main row: left col + issues + detail */}\n <Box height={issuesPanelHeight}>\n {/* Left column: repos + statuses stacked */}\n <Box flexDirection=\"column\" width={LEFT_COL_WIDTH}>\n {reposPanel}\n {statusesPanel}\n </Box>\n {/* Issues panel fills remaining space */}\n <Box flexGrow={1} flexDirection=\"column\">\n {issuesPanel}\n </Box>\n {/* Detail panel on the right */}\n <Box width={detailWidth} flexDirection=\"column\">\n {detailPanel}\n </Box>\n </Box>\n {/* Activity strip full width */}\n <Box height={ACTIVITY_HEIGHT}>{activityPanel}</Box>\n </Box>\n );\n }\n\n if (mode === \"medium\") {\n return (\n <Box flexDirection=\"column\">\n {/* Main row: left col + issues (no detail) */}\n <Box height={issuesPanelHeight}>\n <Box flexDirection=\"column\" width={LEFT_COL_WIDTH}>\n {reposPanel}\n {statusesPanel}\n </Box>\n <Box flexGrow={1} flexDirection=\"column\">\n {issuesPanel}\n </Box>\n </Box>\n {/* Activity strip full width */}\n <Box height={ACTIVITY_HEIGHT}>{activityPanel}</Box>\n </Box>\n );\n }\n\n // Stacked (<100 cols): all panels full width, fixed heights\n return (\n <Box flexDirection=\"column\">\n {reposPanel}\n {statusesPanel}\n <Box flexGrow={1} flexDirection=\"column\">\n {issuesPanel}\n </Box>\n <Box height={ACTIVITY_HEIGHT}>{activityPanel}</Box>\n </Box>\n );\n}\n\nexport type { PanelLayoutProps };\n","import { Box, Text } from \"ink\";\nimport { Panel } from \"./panel.js\";\n\nexport interface RepoItem {\n name: string;\n openCount: number;\n}\n\nexport interface ReposPanelProps {\n readonly repos: RepoItem[];\n readonly selectedIdx: number;\n readonly isActive: boolean;\n readonly width: number;\n readonly flexGrow?: number;\n}\n\nfunction shortName(fullName: string): string {\n return fullName.includes(\"/\") ? (fullName.split(\"/\")[1] ?? fullName) : fullName;\n}\n\nexport function ReposPanel({ repos, selectedIdx, isActive, width, flexGrow }: ReposPanelProps) {\n // inner content width = total - 2 border chars - 2 padding chars from Box\n const maxLabel = Math.max(4, width - 8); // leave room for \"► \" + \" 99\" + borders\n\n return (\n <Panel title=\"[1] Repos\" isActive={isActive} width={width} flexGrow={flexGrow}>\n {repos.length === 0 ? (\n <Text color=\"gray\">—</Text>\n ) : (\n repos.map((repo, i) => {\n const isSel = i === selectedIdx;\n const label = shortName(repo.name).slice(0, maxLabel);\n return (\n <Box key={repo.name}>\n <Text color={isSel ? \"cyan\" : isActive ? \"white\" : \"gray\"} bold={isSel}>\n {isSel ? \"► \" : \" \"}\n {label}\n </Text>\n <Text color=\"gray\"> {repo.openCount}</Text>\n </Box>\n );\n })\n )}\n </Panel>\n );\n}\n","import { Box, Text } from \"ink\";\nimport type { GitHubIssue } from \"../../github.js\";\n\ninterface IssueRowProps {\n readonly issue: GitHubIssue;\n readonly selfLogin: string;\n readonly isSelected: boolean;\n /** Outer panel width (including border chars). Used to compute title column width. */\n readonly panelWidth: number;\n}\n\nfunction truncate(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, max - 1)}\\u2026` : s;\n}\n\nfunction formatDate(issue: GitHubIssue): { text: string; color: string } {\n if (issue.targetDate) {\n const d = new Date(issue.targetDate);\n const days = Math.ceil((d.getTime() - Date.now()) / 86_400_000);\n if (days < 0) return { text: `${Math.abs(days)}d overdue`, color: \"red\" };\n if (days === 0) return { text: \"today\", color: \"yellow\" };\n if (days === 1) return { text: \"tomorrow\", color: \"white\" };\n if (days <= 7) return { text: `in ${days}d`, color: \"white\" };\n return {\n text: d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" }),\n color: \"gray\",\n };\n }\n const seconds = Math.floor((Date.now() - new Date(issue.updatedAt).getTime()) / 1000);\n if (seconds < 60) return { text: \"now\", color: \"gray\" };\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return { text: `${minutes}m`, color: \"gray\" };\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return { text: `${hours}h`, color: \"gray\" };\n const days = Math.floor(hours / 24);\n if (days < 30) return { text: `${days}d`, color: \"gray\" };\n const months = Math.floor(days / 30);\n return { text: `${months}mo`, color: \"gray\" };\n}\n\nconst PLAIN_ABBREVS: Record<string, string> = {\n bug: \"bug\",\n feature: \"feat\",\n enhancement: \"enh\",\n documentation: \"docs\",\n \"good first issue\": \"gfi\",\n help: \"help\",\n question: \"?\",\n urgent: \"urg!\",\n wontfix: \"wont\",\n task: \"task\",\n};\n\nfunction compactLabel(name: string): string {\n const lc = name.toLowerCase();\n const colon = lc.indexOf(\":\");\n if (colon < 0) return PLAIN_ABBREVS[lc] ?? name.slice(0, 5);\n const key = lc.slice(0, colon);\n const val = name.slice(colon + 1);\n if (key === \"size\") return val.slice(0, 3).toUpperCase();\n if (key === \"priority\") return `p:${val.slice(0, 1).toUpperCase()}`;\n if (key === \"work\") return \"WIP\";\n return `${key.slice(0, 2)}:${val.slice(0, 2)}`;\n}\n\nfunction labelColor(name: string): string {\n const lc = name.toLowerCase();\n if (lc === \"bug\" || lc === \"urgent\" || lc.startsWith(\"priority:h\") || lc.startsWith(\"priority:c\"))\n return \"red\";\n if (lc.startsWith(\"priority:m\") || lc.startsWith(\"work:\")) return \"yellow\";\n if (lc.startsWith(\"priority:l\") || lc === \"wontfix\") return \"gray\";\n if (lc.startsWith(\"size:\")) return \"white\";\n if (lc === \"feature\" || lc === \"enhancement\") return \"green\";\n if (lc === \"documentation\") return \"blue\";\n if (lc === \"good first issue\") return \"magenta\";\n return \"cyan\";\n}\n\n// ── Fixed column widths ──────────────────────────────────────────────────────\n//\n// ► #1234 <title…> [sM] [p:H] username in 4d\n// 2 7 titleW 13 1 10 1 10\n//\n// Inner width = panelWidth - 2 (subtract │ on each side)\n// Fixed overhead = 2 + 7 + 1 + LABEL_W + 1 + ASSIGN_W + 1 + DATE_W = 35\n// titleW = innerW - fixed overhead\n//\nconst CURSOR_W = 2; // \"► \" or \" \"\nconst NUM_W = 7; // \"#xxxx \" (padEnd(5) + 1 space)\nconst LABEL_W = 13; // up to 2 compact labels: \"[bug] [p:H]\"\nconst ASSIGN_W = 10;\nconst DATE_W = 10; // \"3d overdue\" fits in 10\nconst FIXED_OVERHEAD = CURSOR_W + NUM_W + 1 + LABEL_W + 1 + ASSIGN_W + 1 + DATE_W;\n\nfunction IssueRow({ issue, selfLogin, isSelected, panelWidth }: IssueRowProps) {\n const assignees = issue.assignees ?? [];\n const isSelf = assignees.some((a) => a.login === selfLogin);\n const isUnassigned = assignees.length === 0;\n\n const assigneeColor = isSelf ? \"green\" : isUnassigned ? \"gray\" : \"white\";\n const assigneeText = isUnassigned\n ? \"unassigned\"\n : truncate(assignees.map((a) => a.login).join(\", \"), ASSIGN_W);\n\n const labels = (issue.labels ?? []).slice(0, 2);\n const date = formatDate(issue);\n\n // Dynamic title column: fill whatever space remains after fixed columns\n const innerW = panelWidth - 2;\n const titleW = Math.max(8, innerW - FIXED_OVERHEAD);\n const titleStr = truncate(issue.title, titleW).padEnd(titleW);\n const dateStr = date.text.padStart(DATE_W);\n\n return (\n <Box>\n {/* Cursor */}\n {isSelected ? (\n <Text color=\"cyan\" bold>\n {\"\\u25B6 \"}\n </Text>\n ) : (\n <Text>{\" \"}</Text>\n )}\n\n {/* Issue number */}\n <Text color=\"cyan\">#{String(issue.number).padEnd(5)}</Text>\n <Text> </Text>\n\n {/* Title — truncated to exact titleW so total row width is deterministic */}\n {isSelected ? (\n <Text bold color=\"white\">\n {titleStr}\n </Text>\n ) : (\n <Text>{titleStr}</Text>\n )}\n <Text> </Text>\n\n {/* Labels — compact abbreviations in a fixed-width slot */}\n <Box width={LABEL_W} overflow=\"hidden\">\n {labels.length === 0 ? (\n <Text color=\"gray\">{\" \".repeat(LABEL_W)}</Text>\n ) : (\n labels.map((l, i) => (\n <Text key={l.name}>\n {i > 0 ? \" \" : \"\"}\n <Text color={labelColor(l.name)}>[{compactLabel(l.name)}]</Text>\n </Text>\n ))\n )}\n </Box>\n <Text> </Text>\n\n {/* Assignee */}\n <Text color={assigneeColor}>{assigneeText.padEnd(ASSIGN_W)}</Text>\n <Text> </Text>\n\n {/* Date — target date takes priority over updatedAt */}\n <Text color={date.color}>{dateStr}</Text>\n </Box>\n );\n}\n\nexport { IssueRow };\nexport type { IssueRowProps };\n","import { Box, Text } from \"ink\";\nimport type { GitHubIssue } from \"../../github.js\";\nimport type { ActivityEvent } from \"../fetch.js\";\nimport { IssueRow } from \"./issue-row.js\";\n\n// ── Types ──\n\nexport type FlatRow =\n | {\n type: \"sectionHeader\";\n key: string;\n navId: string;\n label: string;\n count: number;\n countLabel: string;\n isCollapsed: boolean;\n }\n | {\n type: \"subHeader\";\n key: string;\n navId: string | null;\n text: string;\n count?: number;\n isCollapsed?: boolean;\n }\n | { type: \"issue\"; key: string; navId: string; issue: GitHubIssue; repoName: string }\n | { type: \"activity\"; key: string; navId: null; event: ActivityEvent }\n | { type: \"error\"; key: string; navId: null; text: string }\n | { type: \"gap\"; key: string; navId: null };\n\ninterface RowRendererProps {\n readonly row: FlatRow;\n readonly selectedId: string | null;\n readonly selfLogin: string;\n readonly isMultiSelected?: boolean | undefined;\n /** Outer issues panel width — passed to IssueRow for single-line truncation. */\n readonly panelWidth?: number | undefined;\n}\n\nexport function RowRenderer({\n row,\n selectedId,\n selfLogin,\n isMultiSelected,\n panelWidth = 120,\n}: RowRendererProps) {\n switch (row.type) {\n case \"sectionHeader\": {\n const arrow = row.isCollapsed ? \"\\u25B6\" : \"\\u25BC\";\n const isSel = selectedId === row.navId;\n return (\n <Box>\n <Text color={isSel ? \"cyan\" : \"white\"} bold>\n {arrow} {row.label}\n </Text>\n <Text color=\"gray\">\n {\" \"}\n ({row.count} {row.countLabel})\n </Text>\n </Box>\n );\n }\n case \"subHeader\": {\n if (row.navId) {\n const arrow = row.isCollapsed ? \"\\u25B6\" : \"\\u25BC\";\n const isSel = selectedId === row.navId;\n return (\n <Box>\n <Text color={isSel ? \"cyan\" : \"gray\"}>\n {\" \"}\n {arrow} {row.text}\n </Text>\n <Text color=\"gray\"> ({row.count})</Text>\n </Box>\n );\n }\n return (\n <Box>\n <Text bold color=\"white\">\n {\" \"}\n {row.text}\n </Text>\n {row.count != null ? <Text color=\"gray\"> ({row.count})</Text> : null}\n </Box>\n );\n }\n case \"issue\": {\n const checkbox = isMultiSelected != null ? (isMultiSelected ? \"\\u2611 \" : \"\\u2610 \") : \"\";\n return (\n <Box>\n {checkbox ? <Text color={isMultiSelected ? \"cyan\" : \"gray\"}>{checkbox}</Text> : null}\n <IssueRow\n issue={row.issue}\n selfLogin={selfLogin}\n isSelected={selectedId === row.navId}\n panelWidth={panelWidth}\n />\n </Box>\n );\n }\n case \"activity\": {\n const ago = new Date(row.event.timestamp).toLocaleTimeString();\n return (\n <Text dimColor>\n {\" \"}\n {ago}: <Text color=\"gray\">@{row.event.actor}</Text> {row.event.summary}{\" \"}\n <Text dimColor>({row.event.repoShortName})</Text>\n </Text>\n );\n }\n case \"error\":\n return <Text color=\"red\"> Error: {row.text}</Text>;\n case \"gap\":\n return <Text>{\"\"}</Text>;\n }\n}\n","import { Box, Text } from \"ink\";\nimport { Panel } from \"./panel.js\";\n\nexport interface StatusItem {\n id: string;\n label: string;\n count: number;\n}\n\nexport interface StatusesPanelProps {\n readonly groups: StatusItem[];\n readonly selectedIdx: number;\n readonly isActive: boolean;\n readonly width: number;\n readonly flexGrow?: number;\n}\n\nexport function StatusesPanel({\n groups,\n selectedIdx,\n isActive,\n width,\n flexGrow,\n}: StatusesPanelProps) {\n const maxLabel = Math.max(4, width - 8);\n\n return (\n <Panel title=\"[2] Statuses\" isActive={isActive} width={width} flexGrow={flexGrow}>\n {groups.length === 0 ? (\n <Text color=\"gray\">—</Text>\n ) : (\n groups.map((group, i) => {\n const isSel = i === selectedIdx;\n const label = group.label.slice(0, maxLabel);\n return (\n <Box key={group.id}>\n <Text color={isSel ? \"cyan\" : isActive ? \"white\" : \"gray\"} bold={isSel}>\n {isSel ? \"► \" : \" \"}\n {label}\n </Text>\n <Text color=\"gray\"> {group.count}</Text>\n </Box>\n );\n })\n )}\n </Panel>\n );\n}\n","import { Spinner } from \"@inkjs/ui\";\nimport { Box, Text } from \"ink\";\nimport type { Toast } from \"../hooks/use-toast.js\";\n\ninterface ToastContainerProps {\n toasts: Toast[];\n}\n\nconst TYPE_COLORS = {\n info: \"cyan\",\n success: \"green\",\n error: \"red\",\n loading: \"cyan\",\n} as const;\n\nconst TYPE_PREFIXES = {\n info: \"\\u2139\",\n success: \"\\u2713\",\n error: \"\\u2717\",\n} as const;\n\nexport function ToastContainer({ toasts }: ToastContainerProps) {\n if (toasts.length === 0) return null;\n\n return (\n <Box flexDirection=\"column\">\n {toasts.map((t) => (\n <Box key={t.id}>\n {t.type === \"loading\" ? (\n <>\n <Spinner label=\"\" />\n <Text color=\"cyan\"> {t.message}</Text>\n </>\n ) : (\n <Text color={TYPE_COLORS[t.type]}>\n {TYPE_PREFIXES[t.type]} {t.message}\n {t.type === \"error\" ? (\n <Text color=\"gray\">{t.retry ? \" [r]etry [d]ismiss\" : \" [d]ismiss\"}</Text>\n ) : null}\n </Text>\n )}\n </Box>\n ))}\n </Box>\n );\n}\n","import { execFileSync, spawnSync } from \"node:child_process\";\nimport { Spinner } from \"@inkjs/ui\";\nimport { Box, Text, useApp, useStdout } from \"ink\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { getClipboardArgs } from \"../../clipboard.js\";\nimport type { HogConfig, RepoConfig } from \"../../config.js\";\nimport type { GitHubIssue, IssueComment, LabelOption, StatusOption } from \"../../github.js\";\nimport { fetchIssueCommentsAsync } from \"../../github.js\";\nimport { isHeaderId, isTerminalStatus, timeAgo } from \"../constants.js\";\nimport type { ActivityEvent, FetchOptions, RepoData } from \"../fetch.js\";\nimport { useActionLog } from \"../hooks/use-action-log.js\";\nimport { useActions } from \"../hooks/use-actions.js\";\nimport { refreshAgeColor, useData } from \"../hooks/use-data.js\";\nimport { useKeyboard } from \"../hooks/use-keyboard.js\";\nimport { useMultiSelect } from \"../hooks/use-multi-select.js\";\nimport type { NavItem } from \"../hooks/use-navigation.js\";\nimport { useNavigation } from \"../hooks/use-navigation.js\";\nimport { usePanelFocus } from \"../hooks/use-panel-focus.js\";\nimport { useToast } from \"../hooks/use-toast.js\";\nimport { useUIState } from \"../hooks/use-ui-state.js\";\nimport { ActionLog } from \"./action-log.js\";\nimport { ActivityPanel } from \"./activity-panel.js\";\nimport type { BulkAction } from \"./bulk-action-menu.js\";\nimport { DetailPanel } from \"./detail-panel.js\";\nimport type { FocusEndAction } from \"./focus-mode.js\";\nimport { HintBar } from \"./hint-bar.js\";\nimport { OverlayRenderer } from \"./overlay-renderer.js\";\nimport { Panel } from \"./panel.js\";\nimport {\n ACTIVITY_HEIGHT,\n getDetailWidth,\n getLayoutMode,\n LEFT_COL_WIDTH,\n PanelLayout,\n} from \"./panel-layout.js\";\nimport { ReposPanel } from \"./repos-panel.js\";\nimport type { FlatRow } from \"./row-renderer.js\";\nimport { RowRenderer } from \"./row-renderer.js\";\nimport { StatusesPanel } from \"./statuses-panel.js\";\nimport { ToastContainer } from \"./toast-container.js\";\n\n// ── Types ──\n\ninterface DashboardProps {\n readonly config: HogConfig;\n readonly options: FetchOptions;\n readonly activeProfile?: string | null;\n}\n\n// ── Helpers ──\n\ninterface StatusGroup {\n label: string;\n statuses: string[];\n}\n\ninterface BoardGroup {\n label: string;\n subId: string; // `sub:${repo.name}:${label}` — globally unique\n issues: GitHubIssue[];\n}\n\ninterface BoardSection {\n repo: RepoConfig;\n sectionId: string; // repo.name — globally unique\n groups: BoardGroup[];\n error: string | null;\n}\n\ninterface BoardTree {\n activity: ActivityEvent[];\n sections: BoardSection[];\n}\n\n/**\n * Resolve status groups for a repo.\n * If `configuredGroups` is provided, use those (each entry is \"Status1,Status2\" — first is header).\n * Otherwise, auto-detect from statusOptions (non-terminal statuses, Backlog last).\n */\nfunction resolveStatusGroups(\n statusOptions: StatusOption[],\n configuredGroups?: string[],\n): StatusGroup[] {\n if (configuredGroups && configuredGroups.length > 0) {\n return configuredGroups.map((entry) => {\n const statuses = entry\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n return { label: statuses[0] ?? entry, statuses };\n });\n }\n\n // Auto-detect: each non-terminal status is its own group, Backlog last\n const nonTerminal = statusOptions.map((o) => o.name).filter((s) => !isTerminalStatus(s));\n if (nonTerminal.length > 0 && !nonTerminal.includes(\"Backlog\")) {\n nonTerminal.push(\"Backlog\");\n }\n const order = nonTerminal.length > 0 ? nonTerminal : [\"In Progress\", \"Backlog\"];\n return order.map((s) => ({ label: s, statuses: [s] }));\n}\n\n/** Extract priority rank from labels. Lower number = higher priority. */\nconst PRIORITY_RANK: Record<string, number> = {\n \"priority:critical\": 0,\n \"priority:high\": 1,\n \"priority:medium\": 2,\n \"priority:low\": 3,\n};\n\nfunction issuePriorityRank(issue: GitHubIssue): number {\n for (const label of issue.labels ?? []) {\n const rank = PRIORITY_RANK[label.name.toLowerCase()];\n if (rank != null) return rank;\n }\n return 99; // no priority label\n}\n\n/** Group issues by project status. Issues without status go to \"Backlog\". Sorted by priority within groups. */\nfunction groupByStatus(issues: GitHubIssue[]): Map<string, GitHubIssue[]> {\n const groups = new Map<string, GitHubIssue[]>();\n for (const issue of issues) {\n const status = issue.projectStatus ?? \"Backlog\";\n const list = groups.get(status);\n if (list) {\n list.push(issue);\n } else {\n groups.set(status, [issue]);\n }\n }\n // Sort each group by priority (high first)\n for (const [, list] of groups) {\n list.sort((a, b) => issuePriorityRank(a) - issuePriorityRank(b));\n }\n return groups;\n}\n\n/** Build the unified board tree — single source of truth for all nav/row builders. */\nfunction buildBoardTree(repos: RepoData[], activity: ActivityEvent[]): BoardTree {\n const sections = repos.map((rd): BoardSection => {\n const sectionId = rd.repo.name;\n\n if (rd.error) {\n return { repo: rd.repo, sectionId, groups: [], error: rd.error };\n }\n\n const statusGroupDefs = resolveStatusGroups(rd.statusOptions, rd.repo.statusGroups);\n const byStatus = groupByStatus(rd.issues);\n const coveredKeys = new Set<string>(); // normalized (lowercase-trim) covered keys\n const groups: BoardGroup[] = [];\n\n for (const sg of statusGroupDefs) {\n const issues: GitHubIssue[] = [];\n for (const [status, statusIssues] of byStatus) {\n if (sg.statuses.some((s) => s.toLowerCase().trim() === status.toLowerCase().trim())) {\n issues.push(...statusIssues);\n }\n }\n if (issues.length === 0) continue;\n issues.sort((a, b) => issuePriorityRank(a) - issuePriorityRank(b));\n groups.push({ label: sg.label, subId: `sub:${sectionId}:${sg.label}`, issues });\n for (const s of sg.statuses) coveredKeys.add(s.toLowerCase().trim());\n }\n\n // Overflow: uncovered non-terminal statuses\n for (const [status, statusIssues] of byStatus) {\n if (!(coveredKeys.has(status.toLowerCase().trim()) || isTerminalStatus(status))) {\n groups.push({ label: status, subId: `sub:${sectionId}:${status}`, issues: statusIssues });\n }\n }\n\n return { repo: rd.repo, sectionId, groups, error: null };\n });\n\n return { activity, sections };\n}\n\n// ── Panel-based row builders ──\n\nfunction buildNavItemsForRepo(\n sections: BoardSection[],\n repoName: string | null,\n statusGroupId: string | null,\n): NavItem[] {\n if (!repoName) return [];\n const section = sections.find((s) => s.sectionId === repoName);\n if (!section) return [];\n const activeGroup = section.groups.find((g) => g.subId === statusGroupId) ?? section.groups[0];\n if (!activeGroup) return [];\n return activeGroup.issues.map((issue) => ({\n id: `gh:${section.repo.name}:${issue.number}`,\n section: repoName,\n type: \"item\" as const,\n }));\n}\n\nfunction buildFlatRowsForRepo(\n sections: BoardSection[],\n repoName: string | null,\n statusGroupId: string | null,\n): FlatRow[] {\n if (!repoName) {\n return [\n {\n type: \"subHeader\" as const,\n key: \"select-repo\",\n navId: null,\n text: \"Select a repo in panel [1]\",\n },\n ];\n }\n const section = sections.find((s) => s.sectionId === repoName);\n if (!section) return [];\n if (section.error) {\n return [{ type: \"error\" as const, key: `error:${repoName}`, navId: null, text: section.error }];\n }\n if (section.groups.length === 0) {\n return [\n {\n type: \"subHeader\" as const,\n key: `empty:${repoName}`,\n navId: null,\n text: \"No open issues\",\n },\n ];\n }\n const activeGroup = section.groups.find((g) => g.subId === statusGroupId) ?? section.groups[0];\n if (!activeGroup) return [];\n if (activeGroup.issues.length === 0) {\n return [\n {\n type: \"subHeader\" as const,\n key: `empty-group:${statusGroupId}`,\n navId: null,\n text: \"No issues in this status group\",\n },\n ];\n }\n return activeGroup.issues.map((issue) => ({\n type: \"issue\" as const,\n key: `gh:${section.repo.name}:${issue.number}`,\n navId: `gh:${section.repo.name}:${issue.number}`,\n issue,\n repoName: section.repo.name,\n }));\n}\n\nfunction openInBrowser(url: string): void {\n if (!(url.startsWith(\"https://\") || url.startsWith(\"http://\"))) return;\n try {\n execFileSync(\"open\", [url], { stdio: \"ignore\" });\n } catch {\n // Silently ignore\n }\n}\n\nfunction findSelectedIssueWithRepo(\n repos: RepoData[],\n selectedId: string | null,\n): { issue: GitHubIssue; repoName: string } | null {\n if (!selectedId?.startsWith(\"gh:\")) return null;\n for (const rd of repos) {\n for (const issue of rd.issues) {\n if (`gh:${rd.repo.name}:${issue.number}` === selectedId)\n return { issue, repoName: rd.repo.name };\n }\n }\n return null;\n}\n\n// ── RefreshAge ──\n\nfunction RefreshAge({ lastRefresh }: { readonly lastRefresh: Date | null }) {\n const [, setTick] = useState(0);\n useEffect(() => {\n const id = setInterval(() => setTick((t) => t + 1), 10_000);\n return () => clearInterval(id);\n }, []);\n if (!lastRefresh) return null;\n return <Text color={refreshAgeColor(lastRefresh)}>Updated {timeAgo(lastRefresh)}</Text>;\n}\n\n// ── Smart search ──\n//\n// Tokens are split on whitespace and AND-ed together.\n// Each token matches if ANY of the following is true:\n// #123 → exact issue number\n// @alice → assignee login substring (@ prefix optional)\n// unassigned → no assignees\n// assigned → has at least one assignee\n// <text> → substring of title, any label name, projectStatus, or assignee login\n\nfunction matchesSearch(issue: GitHubIssue, query: string): boolean {\n if (!query.trim()) return true;\n const tokens = query.toLowerCase().trim().split(/\\s+/);\n const labels = issue.labels ?? [];\n const assignees = issue.assignees ?? [];\n\n return tokens.every((token) => {\n // Issue number: #123\n if (token.startsWith(\"#\")) {\n const num = parseInt(token.slice(1), 10);\n return !Number.isNaN(num) && issue.number === num;\n }\n\n // Explicit assignee: @alice\n if (token.startsWith(\"@\")) {\n const login = token.slice(1);\n return assignees.some((a) => a.login.toLowerCase().includes(login));\n }\n\n // Special keywords\n if (token === \"unassigned\") return assignees.length === 0;\n if (token === \"assigned\") return assignees.length > 0;\n\n // Title\n if (issue.title.toLowerCase().includes(token)) return true;\n\n // Labels — full name (e.g. \"bug\", \"priority:high\", \"size:m\")\n // Substring match means \"high\" finds \"priority:high\", \"m\" finds \"size:m\", etc.\n if (labels.some((l) => l.name.toLowerCase().includes(token))) return true;\n\n // Project status (e.g. \"in progress\", \"backlog\")\n if (issue.projectStatus?.toLowerCase().includes(token)) return true;\n\n // Custom project fields (Workstream, Size, Priority, Iteration, etc.)\n if (\n issue.customFields &&\n Object.values(issue.customFields).some((v) => v.toLowerCase().includes(token))\n )\n return true;\n\n // Assignee login without @ prefix\n if (assignees.some((a) => a.login.toLowerCase().includes(token))) return true;\n\n return false;\n });\n}\n\n// ── Issues panel box (scrollable list + detail) ──\n\nconst CHROME_ROWS = 3; // header (1) + hintbar (1) + paddingX top/bottom (1)\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: main TUI orchestrator\nfunction Dashboard({ config, options, activeProfile }: DashboardProps) {\n const { exit } = useApp();\n const refreshMs = config.board.refreshInterval * 1000;\n const {\n status,\n data,\n error,\n lastRefresh,\n isRefreshing,\n consecutiveFailures,\n autoRefreshPaused,\n refresh,\n mutateData,\n pauseAutoRefresh,\n resumeAutoRefresh,\n registerPendingMutation,\n clearPendingMutation,\n } = useData(config, options, refreshMs);\n\n // Stable empty arrays to avoid new references when data is null\n const allRepos = useMemo(() => data?.repos ?? [], [data?.repos]);\n const allActivity = useMemo(() => data?.activity ?? [], [data?.activity]);\n\n // UI state machine\n const ui = useUIState();\n\n // Panel focus state — default to Issues panel [3]\n const panelFocus = usePanelFocus(3);\n\n // Search state (managed separately — search query persists across mode changes)\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n // My-issues filter: toggle between all issues and issues assigned to me\n const [mineOnly, setMineOnly] = useState(false);\n const handleToggleMine = useCallback(() => {\n setMineOnly((prev) => !prev);\n }, []);\n\n // Toast notification system (replaces old statusMessage)\n const { toasts, toast, handleErrorAction } = useToast();\n\n // Action log\n const [logVisible, setLogVisible] = useState(false);\n const { entries: logEntries, pushEntry, undoLast, hasUndoable } = useActionLog(toast, refresh);\n\n // Auto-expand log when an error entry is pushed\n useEffect(() => {\n const last = logEntries[logEntries.length - 1];\n if (last?.status === \"error\") setLogVisible(true);\n }, [logEntries]);\n\n // After data loads, surface TickTick errors\n useEffect(() => {\n if (data?.ticktickError) {\n toast.error(`TickTick sync failed: ${data.ticktickError}`);\n }\n }, [data?.ticktickError, toast.error]);\n\n // Filter by search query and/or mineOnly\n const repos = useMemo(() => {\n let filtered = allRepos;\n if (mineOnly) {\n const me = config.board.assignee;\n filtered = filtered\n .map((rd) => ({\n ...rd,\n issues: rd.issues.filter((i) => (i.assignees ?? []).some((a) => a.login === me)),\n }))\n .filter((rd) => rd.issues.length > 0);\n }\n if (!searchQuery) return filtered;\n return filtered\n .map((rd) => ({ ...rd, issues: rd.issues.filter((i) => matchesSearch(i, searchQuery)) }))\n .filter((rd) => rd.issues.length > 0);\n }, [allRepos, searchQuery, mineOnly, config.board.assignee]);\n\n // Single source of truth — computed once (no tasks)\n const boardTree = useMemo(() => buildBoardTree(repos, allActivity), [repos, allActivity]);\n\n // Panel [1] — Repos cursor\n const [selectedRepoIdx, setSelectedRepoIdx] = useState(0);\n const clampedRepoIdx = Math.min(selectedRepoIdx, Math.max(0, boardTree.sections.length - 1));\n\n const reposNav = {\n moveUp: useCallback(() => setSelectedRepoIdx((i) => Math.max(0, i - 1)), []),\n moveDown: useCallback(\n () => setSelectedRepoIdx((i) => Math.min(Math.max(0, boardTree.sections.length - 1), i + 1)),\n [boardTree.sections.length],\n ),\n };\n\n // Panel [2] — Statuses cursor\n const [selectedStatusIdx, setSelectedStatusIdx] = useState(0);\n const selectedSection = boardTree.sections[clampedRepoIdx] ?? null;\n const clampedStatusIdx = Math.min(\n selectedStatusIdx,\n Math.max(0, (selectedSection?.groups.length ?? 1) - 1),\n );\n\n const statusesNav = {\n moveUp: useCallback(() => setSelectedStatusIdx((i) => Math.max(0, i - 1)), []),\n moveDown: useCallback(\n () =>\n setSelectedStatusIdx((i) =>\n Math.min(Math.max(0, (selectedSection?.groups.length ?? 1) - 1), i + 1),\n ),\n [selectedSection?.groups.length],\n ),\n };\n\n // Panel [4] — Activity cursor\n const [activitySelectedIdx, setActivitySelectedIdx] = useState(0);\n const clampedActivityIdx = Math.min(\n activitySelectedIdx,\n Math.max(0, boardTree.activity.length - 1),\n );\n\n const activityNav = {\n moveUp: useCallback(() => setActivitySelectedIdx((i) => Math.max(0, i - 1)), []),\n moveDown: useCallback(\n () =>\n setActivitySelectedIdx((i) => Math.min(Math.max(0, boardTree.activity.length - 1), i + 1)),\n [boardTree.activity.length],\n ),\n };\n\n // Derived selection state\n const selectedRepoName = selectedSection?.sectionId ?? null;\n const selectedStatusGroup = selectedSection?.groups[clampedStatusIdx] ?? null;\n const selectedStatusGroupId = selectedStatusGroup?.subId ?? null;\n\n // Panel Enter handlers\n const onRepoEnter = useCallback(() => {\n setSelectedStatusIdx(0);\n panelFocus.focusPanel(3);\n }, [panelFocus]);\n\n const onStatusEnter = useCallback(() => {\n panelFocus.focusPanel(3);\n }, [panelFocus]);\n\n const onActivityEnter = useCallback(() => {\n const event = boardTree.activity[clampedActivityIdx];\n if (!event) return;\n const repoIdx = boardTree.sections.findIndex(\n (s) =>\n s.repo.shortName === event.repoShortName || s.sectionId.endsWith(`/${event.repoShortName}`),\n );\n if (repoIdx >= 0) {\n setSelectedRepoIdx(repoIdx);\n setSelectedStatusIdx(0);\n panelFocus.focusPanel(3);\n }\n }, [boardTree, clampedActivityIdx, panelFocus]);\n\n // Navigation — flat item list for active repo + status group\n const navItems = useMemo(\n () => buildNavItemsForRepo(boardTree.sections, selectedRepoName, selectedStatusGroupId),\n [boardTree.sections, selectedRepoName, selectedStatusGroupId],\n );\n const nav = useNavigation(navItems);\n\n // Multi-select: resolve nav ID → repo name for same-repo constraint\n const getRepoForId = useCallback((id: string): string | null => {\n if (id.startsWith(\"gh:\")) {\n const parts = id.split(\":\");\n return parts.length >= 3 ? `${parts[1]}` : null;\n }\n return null;\n }, []);\n const multiSelect = useMultiSelect(getRepoForId);\n\n // Prune multi-select when items change (e.g., issue closed during refresh)\n useEffect(() => {\n if (multiSelect.count === 0) return;\n const validIds = new Set(navItems.map((i) => i.id));\n multiSelect.prune(validIds);\n }, [navItems, multiSelect]);\n\n // Actions hook\n const actions = useActions({\n config,\n repos,\n selectedId: nav.selectedId,\n toast,\n refresh,\n mutateData,\n onOverlayDone: ui.exitOverlay,\n pushEntry,\n registerPendingMutation,\n clearPendingMutation,\n });\n\n // \"Pick this issue?\" after create — stores the newly created issue info\n const pendingPickRef = useRef<{ repo: string; issueNumber: number } | null>(null);\n\n // Session-level label cache to avoid re-fetching on every overlay open\n const labelCacheRef = useRef<Record<string, LabelOption[]>>({});\n\n // Comment cache: key = \"repo:issueNumber\" → comments or loading/error state\n const commentCacheRef = useRef<Record<string, IssueComment[] | \"loading\" | \"error\">>({});\n // Tick counter triggers re-render when cache is updated (ref changes don't re-render on their own)\n const [commentTick, setCommentTick] = useState(0);\n\n const handleFetchComments = useCallback((repo: string, issueNumber: number) => {\n const key = `${repo}:${issueNumber}`;\n if (commentCacheRef.current[key] !== undefined) return;\n commentCacheRef.current[key] = \"loading\";\n setCommentTick((t) => t + 1);\n fetchIssueCommentsAsync(repo, issueNumber)\n .then((comments) => {\n commentCacheRef.current[key] = comments;\n setCommentTick((t) => t + 1);\n })\n .catch(() => {\n commentCacheRef.current[key] = \"error\";\n setCommentTick((t) => t + 1);\n });\n }, []);\n\n const handleCreateIssueWithPrompt = useCallback(\n (repo: string, title: string, body: string, dueDate: string | null, labels?: string[]) => {\n actions.handleCreateIssue(repo, title, body, dueDate, labels).then((result) => {\n if (result) {\n pendingPickRef.current = result;\n ui.enterConfirmPick();\n }\n });\n },\n [actions, ui],\n );\n\n const handleConfirmPick = useCallback(() => {\n const pending = pendingPickRef.current;\n pendingPickRef.current = null;\n ui.exitOverlay();\n if (!pending) return;\n\n const rc = config.repos.find((r) => r.name === pending.repo);\n if (!rc) return;\n\n const t = toast.loading(`Picking ${rc.shortName}#${pending.issueNumber}...`);\n import(\"../../pick.js\").then(({ pickIssue }) =>\n pickIssue(config, { repo: rc, issueNumber: pending.issueNumber })\n .then((result) => {\n const msg = `Picked ${rc.shortName}#${pending.issueNumber} — assigned + synced to TickTick`;\n t.resolve(result.warning ? `${msg} (${result.warning})` : msg);\n refresh();\n })\n .catch((err: unknown) => {\n t.reject(`Pick failed: ${err instanceof Error ? err.message : String(err)}`);\n }),\n );\n }, [config, toast, refresh, ui]);\n\n const handleCancelPick = useCallback(() => {\n pendingPickRef.current = null;\n ui.exitOverlay();\n }, [ui]);\n\n // Focus mode state\n const [focusLabel, setFocusLabel] = useState<string | null>(null);\n\n const handleEnterFocus = useCallback(() => {\n const id = nav.selectedId;\n if (!id || isHeaderId(id)) return;\n\n let label = \"\";\n if (id.startsWith(\"gh:\")) {\n const found = findSelectedIssueWithRepo(repos, id);\n if (found) {\n const rc = config.repos.find((r) => r.name === found.repoName);\n label = `${rc?.shortName ?? found.repoName}#${found.issue.number} — ${found.issue.title}`;\n }\n }\n\n if (!label) return;\n setFocusLabel(label);\n ui.enterFocus();\n }, [nav.selectedId, repos, config.repos, ui]);\n\n const handleFocusExit = useCallback(() => {\n setFocusLabel(null);\n ui.exitToNormal();\n }, [ui]);\n\n const handleFocusEndAction = useCallback(\n (action: FocusEndAction) => {\n switch (action) {\n case \"restart\":\n toast.info(\"Focus restarted!\");\n setFocusLabel((prev) => prev); // no-op to preserve label\n setFocusKey((k) => k + 1);\n break;\n case \"break\":\n toast.info(\"Break time! Step away for a few minutes.\");\n setFocusLabel(null);\n ui.exitToNormal();\n break;\n case \"done\":\n toast.success(\"Focus session complete!\");\n setFocusLabel(null);\n ui.exitToNormal();\n break;\n case \"exit\":\n setFocusLabel(null);\n ui.exitToNormal();\n break;\n }\n },\n [toast, ui],\n );\n\n // Key to force-remount FocusMode on restart\n const [focusKey, setFocusKey] = useState(0);\n\n // Terminal dimensions\n const { stdout } = useStdout();\n const [termSize, setTermSize] = useState({\n cols: stdout?.columns ?? 80,\n rows: stdout?.rows ?? 24,\n });\n useEffect(() => {\n if (!stdout) return;\n const onResize = () => setTermSize({ cols: stdout.columns, rows: stdout.rows });\n stdout.on(\"resize\", onResize);\n return () => {\n stdout.off(\"resize\", onResize);\n };\n }, [stdout]);\n\n const layoutMode = getLayoutMode(termSize.cols);\n const detailPanelWidth =\n layoutMode === \"wide\" ? getDetailWidth(termSize.cols) : Math.floor(termSize.cols * 0.35);\n const showDetailPanel = layoutMode === \"wide\";\n\n // Explicit widths for title-in-border rendering (usableWidth = cols - 2 for paddingX={1})\n const usableWidth = termSize.cols - 2;\n const issuesPanelWidth = Math.max(\n 20,\n layoutMode === \"wide\"\n ? usableWidth - LEFT_COL_WIDTH - getDetailWidth(termSize.cols)\n : layoutMode === \"medium\"\n ? usableWidth - LEFT_COL_WIDTH\n : usableWidth,\n );\n const activityPanelWidth = usableWidth;\n\n const overlayBarRows = ui.state.mode === \"search\" || ui.state.mode === \"overlay:comment\" ? 1 : 0;\n const toastRows = toasts.length;\n const logPaneRows = logVisible ? 4 : 0;\n\n // Total height available for the panel layout (issues + activity)\n const totalPanelHeight = Math.max(\n 8,\n termSize.rows - CHROME_ROWS - overlayBarRows - toastRows - logPaneRows,\n );\n const issuesPanelHeight = Math.max(5, totalPanelHeight - ACTIVITY_HEIGHT);\n\n // Build flat rows for issues panel\n const flatRows = useMemo(\n () => buildFlatRowsForRepo(boardTree.sections, selectedRepoName, selectedStatusGroupId),\n [boardTree.sections, selectedRepoName, selectedStatusGroupId],\n );\n\n // Scroll offset - tracks viewport position\n const scrollRef = useRef(0);\n // Reset scroll to top when switching repos or status groups\n const prevRepoRef = useRef<string | null>(null);\n const prevStatusRef = useRef<string | null>(null);\n if (selectedRepoName !== prevRepoRef.current || selectedStatusGroupId !== prevStatusRef.current) {\n prevRepoRef.current = selectedRepoName;\n prevStatusRef.current = selectedStatusGroupId;\n scrollRef.current = 0;\n }\n\n const selectedRowIdx = useMemo(\n () => flatRows.findIndex((r) => r.navId === nav.selectedId),\n [flatRows, nav.selectedId],\n );\n\n // Adjust scroll to keep selected item visible\n if (selectedRowIdx >= 0) {\n if (selectedRowIdx < scrollRef.current) {\n scrollRef.current = selectedRowIdx;\n } else if (selectedRowIdx >= scrollRef.current + issuesPanelHeight) {\n scrollRef.current = selectedRowIdx - issuesPanelHeight + 1;\n }\n }\n const maxOffset = Math.max(0, flatRows.length - issuesPanelHeight);\n scrollRef.current = Math.max(0, Math.min(scrollRef.current, maxOffset));\n\n const visibleRows = flatRows.slice(scrollRef.current, scrollRef.current + issuesPanelHeight);\n const hasMoreAbove = scrollRef.current > 0;\n const hasMoreBelow = scrollRef.current + issuesPanelHeight < flatRows.length;\n const aboveCount = scrollRef.current;\n const belowCount = flatRows.length - scrollRef.current - issuesPanelHeight;\n\n // Find selected item for detail panel and overlays\n const selectedItem = useMemo((): {\n issue: GitHubIssue | null;\n repoName: string | null;\n } => {\n const id = nav.selectedId;\n if (!id || isHeaderId(id)) return { issue: null, repoName: null };\n if (id.startsWith(\"gh:\")) {\n for (const rd of repos) {\n for (const issue of rd.issues) {\n if (`gh:${rd.repo.name}:${issue.number}` === id) return { issue, repoName: rd.repo.name };\n }\n }\n }\n return { issue: null, repoName: null };\n }, [nav.selectedId, repos]);\n\n // Derive current commentsState (re-computes on tick or selected issue change)\n // biome-ignore lint/correctness/useExhaustiveDependencies: commentTick is a cache-invalidation signal; it's intentionally in deps without being used in the body\n const currentCommentsState = useMemo((): IssueComment[] | \"loading\" | \"error\" | null => {\n if (!(selectedItem.issue && selectedItem.repoName)) return null;\n return commentCacheRef.current[`${selectedItem.repoName}:${selectedItem.issue.number}`] ?? null;\n }, [selectedItem.issue, selectedItem.repoName, commentTick]);\n\n // Repo config for the selected issue's repo (for edit issue overlay)\n const selectedRepoConfig = useMemo(() => {\n if (!selectedItem.repoName) return null;\n return config.repos.find((r) => r.name === selectedItem.repoName) ?? null;\n }, [selectedItem.repoName, config.repos]);\n\n // Status options for the selected issue's repo (for status picker, single or bulk)\n const selectedRepoStatusOptions = useMemo(() => {\n const repoName = multiSelect.count > 0 ? multiSelect.constrainedRepo : selectedItem.repoName;\n if (!repoName) return [];\n const rd = repos.find((r) => r.repo.name === repoName);\n return rd?.statusOptions ?? [];\n }, [selectedItem.repoName, repos, multiSelect.count, multiSelect.constrainedRepo]);\n\n // Input handlers\n const handleOpen = useCallback(() => {\n const found = findSelectedIssueWithRepo(repos, nav.selectedId);\n if (found) openInBrowser(found.issue.url);\n }, [repos, nav.selectedId]);\n\n const handleSlack = useCallback(() => {\n const found = findSelectedIssueWithRepo(repos, nav.selectedId);\n if (!found?.issue.slackThreadUrl) return;\n openInBrowser(found.issue.slackThreadUrl);\n }, [repos, nav.selectedId]);\n\n const handleCopyLink = useCallback(() => {\n const found = findSelectedIssueWithRepo(repos, nav.selectedId);\n if (!found) return;\n const rc = config.repos.find((r) => r.name === found.repoName);\n const label = `${rc?.shortName ?? found.repoName}#${found.issue.number}`;\n const clipArgs = getClipboardArgs();\n if (clipArgs) {\n const [cmd, ...args] = clipArgs;\n if (!cmd) {\n toast.info(`${label} — ${found.issue.url}`);\n return;\n }\n const result = spawnSync(cmd, args, {\n input: found.issue.url,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n if (result.status === 0) {\n toast.success(`Copied ${label} to clipboard`);\n } else {\n toast.info(`${label} — ${found.issue.url}`);\n }\n } else {\n toast.info(`${label} — ${found.issue.url}`);\n }\n }, [repos, nav.selectedId, config.repos, toast]);\n\n // Multi-select selection type (for bulk action menu)\n const multiSelectType = useMemo((): \"github\" | \"ticktick\" | \"mixed\" => {\n for (const id of multiSelect.selected) {\n if (id.startsWith(\"tt:\")) return \"ticktick\";\n }\n return \"github\";\n }, [multiSelect.selected]);\n\n // Bulk action handler (called from BulkActionMenu)\n const handleBulkAction = useCallback(\n (action: BulkAction) => {\n const ids = multiSelect.selected;\n\n switch (action.type) {\n case \"assign\": {\n ui.exitOverlay();\n actions.handleBulkAssign(ids).then((failedIds) => {\n if (failedIds.length > 0) {\n multiSelect.clear();\n for (const id of failedIds) multiSelect.toggle(id);\n } else {\n multiSelect.clear();\n ui.clearMultiSelect();\n }\n });\n return;\n }\n case \"unassign\": {\n ui.exitOverlay();\n actions.handleBulkUnassign(ids).then((failedIds) => {\n if (failedIds.length > 0) {\n multiSelect.clear();\n for (const id of failedIds) multiSelect.toggle(id);\n } else {\n multiSelect.clear();\n ui.clearMultiSelect();\n }\n });\n return;\n }\n case \"statusChange\":\n ui.enterStatus();\n return;\n case \"complete\":\n case \"delete\":\n toast.info(`Bulk ${action.type} not yet implemented`);\n ui.exitOverlay();\n multiSelect.clear();\n return;\n }\n },\n [multiSelect, actions, ui, toast],\n );\n\n // Bulk status change handler (from StatusPicker when in multiSelect mode)\n const handleBulkStatusSelect = useCallback(\n (optionId: string) => {\n const ids = multiSelect.selected;\n ui.exitOverlay();\n actions.handleBulkStatusChange(ids, optionId).then((failedIds) => {\n if (failedIds.length > 0) {\n multiSelect.clear();\n for (const id of failedIds) multiSelect.toggle(id);\n } else {\n multiSelect.clear();\n ui.clearMultiSelect();\n }\n });\n },\n [multiSelect, actions, ui],\n );\n\n // Fuzzy picker handlers\n const handleFuzzySelect = useCallback(\n (navId: string) => {\n nav.select(navId);\n if (navId.startsWith(\"gh:\")) {\n const parts = navId.split(\":\");\n const repoName = parts[1];\n if (parts.length >= 3 && repoName) {\n const repoIdx = boardTree.sections.findIndex((s) => s.sectionId === repoName);\n if (repoIdx >= 0) {\n setSelectedRepoIdx(repoIdx);\n const section = boardTree.sections[repoIdx];\n const issueNum = parts[2] ? Number(parts[2]) : null;\n const groupIdx =\n section?.groups.findIndex((g) => g.issues.some((iss) => iss.number === issueNum)) ??\n -1;\n setSelectedStatusIdx(Math.max(0, groupIdx));\n }\n }\n }\n ui.exitToNormal();\n },\n [nav, ui, boardTree],\n );\n\n // Keyboard input — all useInput handlers live in use-keyboard.ts\n const onSearchEscape = useCallback(() => {\n ui.exitOverlay();\n setSearchQuery(\"\");\n }, [ui]);\n\n useKeyboard({\n ui,\n nav,\n multiSelect,\n selectedIssue: selectedItem.issue,\n selectedRepoStatusOptionsLength: selectedRepoStatusOptions.length,\n actions: {\n exit,\n refresh,\n handleSlack,\n handleCopyLink,\n handleOpen,\n handleEnterFocus,\n handlePick: actions.handlePick,\n handleAssign: actions.handleAssign,\n handleEnterLabel: ui.enterLabel,\n handleEnterCreateNl: ui.enterCreateNl,\n handleErrorAction,\n toastInfo: toast.info,\n handleToggleMine,\n handleEnterFuzzyPicker: ui.enterFuzzyPicker,\n handleEnterEditIssue: ui.enterEditIssue,\n handleUndo: undoLast,\n handleToggleLog: () => setLogVisible((v) => !v),\n },\n onSearchEscape,\n panelFocus,\n reposNav,\n statusesNav,\n activityNav,\n onRepoEnter,\n onStatusEnter,\n onActivityEnter,\n showDetailPanel,\n });\n\n // Loading state\n if (status === \"loading\" && !data) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Spinner label=\"Loading dashboard...\" />\n </Box>\n );\n }\n\n const now = data?.fetchedAt ?? new Date();\n const dateStr = now.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n\n // Panel [1] — Repos data\n const reposData = boardTree.sections.map(({ repo, groups }) => ({\n name: repo.name,\n openCount: groups.reduce((s, g) => s + g.issues.length, 0),\n }));\n\n // Panel [2] — Statuses data\n const statusesData = (selectedSection?.groups ?? []).map(({ label, subId, issues }) => ({\n id: subId,\n label,\n count: issues.length,\n }));\n\n // Panels\n const reposPanel = (\n <ReposPanel\n repos={reposData}\n selectedIdx={clampedRepoIdx}\n isActive={panelFocus.activePanelId === 1}\n width={LEFT_COL_WIDTH}\n />\n );\n\n const statusesPanel = (\n <StatusesPanel\n groups={statusesData}\n selectedIdx={clampedStatusIdx}\n isActive={panelFocus.activePanelId === 2}\n width={LEFT_COL_WIDTH}\n flexGrow={1}\n />\n );\n\n const issuesPanelTitle = `[3] Issues${selectedSection ? ` — ${selectedSection.repo.shortName}` : \"\"}${selectedStatusGroup ? ` / ${selectedStatusGroup.label}` : \"\"}`;\n\n const issuesPanel = (\n <Panel\n title={issuesPanelTitle}\n isActive={panelFocus.activePanelId === 3}\n width={issuesPanelWidth}\n flexGrow={1}\n >\n {hasMoreAbove ? (\n <Text color=\"gray\" dimColor>\n {\" \"}\n {\"\\u25B2\"} {aboveCount} more above\n </Text>\n ) : null}\n {visibleRows.map((row) => (\n <RowRenderer\n key={row.key}\n row={row}\n selectedId={nav.selectedId}\n selfLogin={config.board.assignee}\n panelWidth={issuesPanelWidth}\n isMultiSelected={\n ui.state.mode === \"multiSelect\" && row.navId\n ? multiSelect.isSelected(row.navId)\n : undefined\n }\n />\n ))}\n {hasMoreBelow ? (\n <Text color=\"gray\" dimColor>\n {\" \"}\n {\"\\u25BC\"} {belowCount} more below\n </Text>\n ) : null}\n </Panel>\n );\n\n const detailPanel = showDetailPanel ? (\n <DetailPanel\n issue={selectedItem.issue}\n width={detailPanelWidth}\n isActive={panelFocus.activePanelId === 0}\n issueRepo={selectedItem.repoName}\n fetchComments={handleFetchComments}\n commentsState={currentCommentsState}\n />\n ) : null;\n\n const activityPanel = (\n <ActivityPanel\n events={boardTree.activity}\n selectedIdx={clampedActivityIdx}\n isActive={panelFocus.activePanelId === 4}\n height={ACTIVITY_HEIGHT}\n width={activityPanelWidth}\n />\n );\n\n return (\n <Box flexDirection=\"column\" paddingX={1}>\n {/* Header */}\n <Box>\n <Text color=\"cyan\" bold>\n HOG BOARD\n </Text>\n {activeProfile ? <Text color=\"yellow\"> [{activeProfile}]</Text> : null}\n <Text color=\"gray\">\n {\" \"}\n {\"\\u2014\"} {dateStr}\n </Text>\n <Text> </Text>\n {isRefreshing ? (\n <>\n <Spinner label=\"\" />\n <Text color=\"cyan\"> Refreshing...</Text>\n </>\n ) : (\n <>\n <RefreshAge lastRefresh={lastRefresh} />\n {consecutiveFailures > 0 ? <Text color=\"red\"> (!)</Text> : null}\n </>\n )}\n {autoRefreshPaused ? (\n <Text color=\"yellow\"> Auto-refresh paused — press r to retry</Text>\n ) : null}\n </Box>\n\n {error ? <Text color=\"red\">Error: {error}</Text> : null}\n\n {/* Overlays — rendered by OverlayRenderer */}\n <OverlayRenderer\n uiState={ui.state}\n config={config}\n repos={allRepos}\n onFuzzySelect={handleFuzzySelect}\n onFuzzyClose={ui.exitToNormal}\n selectedRepoStatusOptions={selectedRepoStatusOptions}\n currentStatus={multiSelect.count > 0 ? undefined : selectedItem.issue?.projectStatus}\n onStatusSelect={multiSelect.count > 0 ? handleBulkStatusSelect : actions.handleStatusChange}\n onExitOverlay={ui.exitOverlay}\n defaultRepo={selectedItem.repoName}\n onCreateIssue={handleCreateIssueWithPrompt}\n onConfirmPick={handleConfirmPick}\n onCancelPick={handleCancelPick}\n multiSelectCount={multiSelect.count}\n multiSelectType={multiSelectType}\n onBulkAction={handleBulkAction}\n focusLabel={focusLabel}\n focusKey={focusKey}\n onFocusExit={handleFocusExit}\n onFocusEndAction={handleFocusEndAction}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n onSearchSubmit={ui.exitOverlay}\n selectedIssue={selectedItem.issue}\n onComment={actions.handleComment}\n onPauseRefresh={pauseAutoRefresh}\n onResumeRefresh={resumeAutoRefresh}\n onToggleHelp={ui.toggleHelp}\n labelCache={labelCacheRef.current}\n onLabelConfirm={actions.handleLabelChange}\n onLabelError={(msg) => toast.error(msg)}\n onLlmFallback={(msg) => toast.info(msg)}\n selectedRepoName={selectedItem.repoName}\n selectedRepoConfig={selectedRepoConfig}\n onToastInfo={toast.info}\n onToastError={toast.error}\n onPushEntry={pushEntry}\n />\n\n {/* Detail overlay — full-screen on narrow layouts (no side panel) */}\n {ui.state.mode === \"overlay:detail\" ? (\n <DetailPanel\n issue={selectedItem.issue}\n width={usableWidth}\n height={issuesPanelHeight + ACTIVITY_HEIGHT}\n isActive={true}\n issueRepo={selectedItem.repoName}\n fetchComments={handleFetchComments}\n commentsState={currentCommentsState}\n />\n ) : null}\n\n {/* Main content: 5-panel layout (hidden during full-screen overlays) */}\n {!ui.state.helpVisible &&\n ui.state.mode !== \"overlay:status\" &&\n ui.state.mode !== \"overlay:create\" &&\n ui.state.mode !== \"overlay:createNl\" &&\n ui.state.mode !== \"overlay:bulkAction\" &&\n ui.state.mode !== \"overlay:confirmPick\" &&\n ui.state.mode !== \"overlay:detail\" &&\n ui.state.mode !== \"focus\" ? (\n <PanelLayout\n cols={termSize.cols}\n issuesPanelHeight={issuesPanelHeight}\n reposPanel={reposPanel}\n statusesPanel={statusesPanel}\n issuesPanel={issuesPanel}\n detailPanel={detailPanel}\n activityPanel={activityPanel}\n />\n ) : null}\n\n {/* Toast notifications */}\n <ToastContainer toasts={toasts} />\n\n {/* Action log pane */}\n {logVisible ? <ActionLog entries={logEntries} /> : null}\n\n {/* Status bar */}\n <HintBar\n uiMode={ui.state.mode}\n activePanelId={panelFocus.activePanelId}\n multiSelectCount={multiSelect.count}\n searchQuery={searchQuery}\n mineOnly={mineOnly}\n hasUndoable={hasUndoable}\n />\n </Box>\n );\n}\n\nexport { Dashboard, matchesSearch };\nexport type { DashboardProps };\n","import { render } from \"ink\";\nimport type { HogConfig } from \"../config.js\";\nimport { Dashboard } from \"./components/dashboard.js\";\nimport type { FetchOptions } from \"./fetch.js\";\nimport { setInkInstance } from \"./ink-instance.js\";\n\nexport async function runLiveDashboard(\n config: HogConfig,\n options: FetchOptions,\n activeProfile?: string | null,\n): Promise<void> {\n const instance = render(\n <Dashboard config={config} options={options} activeProfile={activeProfile ?? null} />,\n );\n setInkInstance(instance);\n\n await instance.waitUntilExit();\n}\n","import { execFileSync } from \"node:child_process\";\nimport { TickTickClient } from \"../api.js\";\nimport type { HogConfig, RepoConfig } from \"../config.js\";\nimport { getConfig, requireAuth } from \"../config.js\";\nimport type { GitHubIssue, StatusOption } from \"../github.js\";\nimport { fetchProjectEnrichment, fetchProjectStatusOptions, fetchRepoIssues } from \"../github.js\";\nimport type { Task } from \"../types.js\";\nimport { TaskStatus } from \"../types.js\";\nimport { formatError } from \"./constants.js\";\n\nexport interface RepoData {\n repo: RepoConfig;\n issues: GitHubIssue[];\n statusOptions: StatusOption[];\n error: string | null;\n}\n\nexport interface ActivityEvent {\n type: \"comment\" | \"status\" | \"assignment\" | \"opened\" | \"closed\" | \"labeled\";\n repoShortName: string;\n issueNumber: number;\n actor: string;\n summary: string;\n timestamp: Date;\n}\n\nexport interface DashboardData {\n repos: RepoData[];\n ticktick: Task[];\n ticktickError: string | null;\n activity: ActivityEvent[];\n fetchedAt: Date;\n}\n\nexport interface FetchOptions {\n repoFilter?: string | undefined;\n mineOnly?: boolean | undefined;\n backlogOnly?: boolean | undefined;\n}\n\nexport const SLACK_URL_RE = /https:\\/\\/[^/]+\\.slack\\.com\\/archives\\/[A-Z0-9]+\\/p[0-9]+/i;\n\nexport function extractSlackUrl(body: string | undefined): string | undefined {\n if (!body) return undefined;\n const match = body.match(SLACK_URL_RE);\n return match?.[0];\n}\n\n/** Fetch recent activity events for a repo (last 24h, max 30 events) */\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: parses multiple GitHub event types\nexport function fetchRecentActivity(repoName: string, shortName: string): ActivityEvent[] {\n try {\n const output = execFileSync(\n \"gh\",\n [\n \"api\",\n `repos/${repoName}/events`,\n \"--paginate\",\n \"-q\",\n '.[] | select(.type == \"IssuesEvent\" or .type == \"IssueCommentEvent\" or .type == \"PullRequestEvent\") | {type: .type, actor: .actor.login, action: .payload.action, number: (.payload.issue.number // .payload.pull_request.number), title: (.payload.issue.title // .payload.pull_request.title), body: .payload.comment.body, created_at: .created_at}',\n ],\n { encoding: \"utf-8\", timeout: 15_000 },\n );\n\n const cutoff = Date.now() - 24 * 60 * 60 * 1000;\n const events: ActivityEvent[] = [];\n\n for (const line of output.trim().split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const ev = JSON.parse(line) as {\n type: string;\n actor: string;\n action: string;\n number: number | null;\n title: string | null;\n body: string | null;\n created_at: string;\n };\n\n const timestamp = new Date(ev.created_at);\n if (timestamp.getTime() < cutoff) continue;\n if (!ev.number) continue;\n\n let eventType: ActivityEvent[\"type\"];\n let summary: string;\n\n if (ev.type === \"IssueCommentEvent\") {\n eventType = \"comment\";\n const preview = ev.body ? ev.body.slice(0, 60).replace(/\\n/g, \" \") : \"\";\n summary = `commented on #${ev.number}${preview ? ` — \"${preview}${(ev.body?.length ?? 0) > 60 ? \"...\" : \"\"}\"` : \"\"}`;\n } else if (ev.type === \"IssuesEvent\") {\n switch (ev.action) {\n case \"opened\":\n eventType = \"opened\";\n summary = `opened #${ev.number}: ${ev.title ?? \"\"}`;\n break;\n case \"closed\":\n eventType = \"closed\";\n summary = `closed #${ev.number}`;\n break;\n case \"assigned\":\n eventType = \"assignment\";\n summary = `assigned #${ev.number}`;\n break;\n case \"labeled\":\n eventType = \"labeled\";\n summary = `labeled #${ev.number}`;\n break;\n default:\n continue;\n }\n } else {\n continue;\n }\n\n events.push({\n type: eventType,\n repoShortName: shortName,\n issueNumber: ev.number,\n actor: ev.actor,\n summary,\n timestamp,\n });\n } catch {\n // Skip malformed event\n }\n }\n\n return events.slice(0, 15);\n } catch {\n return [];\n }\n}\n\nexport async function fetchDashboard(\n config: HogConfig,\n options: FetchOptions = {},\n): Promise<DashboardData> {\n const repos = options.repoFilter\n ? config.repos.filter(\n (r) => r.shortName === options.repoFilter || r.name === options.repoFilter,\n )\n : config.repos;\n\n // GitHub: synchronous (uses gh CLI via execFileSync)\n const repoData: RepoData[] = repos.map((repo) => {\n try {\n const fetchOpts: { assignee?: string } = {};\n if (options.mineOnly) {\n fetchOpts.assignee = config.board.assignee;\n }\n const issues = fetchRepoIssues(repo.name, fetchOpts);\n\n // Enrich issues with target dates + statuses from GitHub Projects (batched)\n let enrichedIssues = issues;\n let statusOptions: StatusOption[] = [];\n try {\n const enrichMap = fetchProjectEnrichment(repo.name, repo.projectNumber);\n enrichedIssues = issues.map((issue): GitHubIssue => {\n const e = enrichMap.get(issue.number);\n const slackUrl = extractSlackUrl(issue.body ?? \"\");\n return {\n ...issue,\n ...(e?.targetDate !== undefined ? { targetDate: e.targetDate } : {}),\n ...(e?.projectStatus !== undefined ? { projectStatus: e.projectStatus } : {}),\n ...(e?.customFields !== undefined ? { customFields: e.customFields } : {}),\n ...(slackUrl ? { slackThreadUrl: slackUrl } : {}),\n };\n });\n statusOptions = fetchProjectStatusOptions(\n repo.name,\n repo.projectNumber,\n repo.statusFieldId,\n );\n } catch {\n // Non-critical: silently skip if project fields fail\n // Compute Slack thread URLs from original issue bodies\n enrichedIssues = issues.map((issue): GitHubIssue => {\n const slackUrl = extractSlackUrl(issue.body ?? \"\");\n return slackUrl ? { ...issue, slackThreadUrl: slackUrl } : issue;\n });\n }\n\n return { repo, issues: enrichedIssues, statusOptions, error: null };\n } catch (err) {\n return { repo, issues: [], statusOptions: [], error: formatError(err) };\n }\n });\n\n // TickTick: async (uses HTTP API) — skip when disabled in config\n let ticktick: Task[] = [];\n let ticktickError: string | null = null;\n if (config.ticktick.enabled) {\n try {\n const auth = requireAuth();\n const api = new TickTickClient(auth.accessToken);\n const cfg = getConfig();\n if (cfg.defaultProjectId) {\n const tasks = await api.listTasks(cfg.defaultProjectId);\n ticktick = tasks.filter((t) => t.status !== TaskStatus.Completed);\n }\n } catch (err) {\n ticktickError = formatError(err);\n }\n }\n\n // Activity: fetch recent events from all repos (non-blocking, best-effort)\n const activity: ActivityEvent[] = [];\n for (const repo of repos) {\n const events = fetchRecentActivity(repo.name, repo.shortName);\n activity.push(...events);\n }\n // Sort by timestamp descending\n activity.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n\n return {\n repos: repoData,\n ticktick,\n ticktickError,\n activity: activity.slice(0, 15),\n fetchedAt: new Date(),\n };\n}\n","import chalk from \"chalk\";\n\nexport interface Theme {\n text: {\n primary: (s: string) => string;\n secondary: (s: string) => string;\n muted: (s: string) => string;\n success: (s: string) => string;\n warning: (s: string) => string;\n error: (s: string) => string;\n accent: (s: string) => string;\n };\n border: {\n primary: (s: string) => string;\n muted: (s: string) => string;\n focus: (s: string) => string;\n };\n priority: {\n high: (s: string) => string;\n medium: (s: string) => string;\n low: (s: string) => string;\n none: (s: string) => string;\n };\n assignee: {\n self: (s: string) => string;\n others: (s: string) => string;\n unassigned: (s: string) => string;\n };\n}\n\nexport const darkTheme: Theme = {\n text: {\n primary: chalk.white,\n secondary: chalk.gray,\n muted: chalk.dim,\n success: chalk.green,\n warning: chalk.yellow,\n error: chalk.red,\n accent: chalk.cyan,\n },\n border: {\n primary: chalk.gray,\n muted: chalk.dim,\n focus: chalk.cyan,\n },\n priority: {\n high: chalk.red,\n medium: chalk.yellow,\n low: chalk.blue,\n none: chalk.gray,\n },\n assignee: {\n self: chalk.greenBright,\n others: chalk.white,\n unassigned: chalk.dim,\n },\n};\n\nexport function getTheme(): Theme {\n return darkTheme;\n}\n","import type { GitHubIssue } from \"../github.js\";\nimport type { Task } from \"../types.js\";\nimport { Priority } from \"../types.js\";\nimport type { DashboardData, RepoData } from \"./fetch.js\";\nimport { getTheme } from \"./theme.js\";\n\nconst theme = getTheme();\n\nfunction truncate(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, max - 1)}\\u2026` : s;\n}\n\nfunction issueAssignee(issue: GitHubIssue, selfLogin: string): string {\n const assignees = issue.assignees ?? [];\n if (assignees.length === 0) return theme.assignee.unassigned(\"unassigned\");\n const names = assignees.map((a) => a.login);\n const isSelf = names.includes(selfLogin);\n const display = names.join(\", \");\n return isSelf ? theme.assignee.self(display) : theme.assignee.others(display);\n}\n\nfunction formatIssueLine(issue: GitHubIssue, selfLogin: string, maxTitle: number): string {\n const num = theme.text.accent(`#${String(issue.number).padEnd(5)}`);\n const title = truncate(issue.title, maxTitle);\n const assignee = issueAssignee(issue, selfLogin);\n return ` ${num} ${title.padEnd(maxTitle)} ${assignee}`;\n}\n\nfunction formatTaskLine(task: Task, maxTitle: number): string {\n const pri =\n task.priority === Priority.High\n ? theme.priority.high(\"[!]\")\n : task.priority === Priority.Medium\n ? theme.priority.medium(\"[~]\")\n : \" \";\n const title = truncate(task.title, maxTitle);\n const due = task.dueDate ? formatDueDate(task.dueDate) : \"\";\n return ` ${pri} ${title.padEnd(maxTitle)} ${theme.text.secondary(due)}`;\n}\n\nfunction formatDueDate(dateStr: string): string {\n const d = new Date(dateStr);\n const now = new Date();\n const days = Math.ceil((d.getTime() - now.getTime()) / 86_400_000);\n\n if (days < 0) return theme.text.error(`${Math.abs(days)}d overdue`);\n if (days === 0) return theme.text.warning(\"today\");\n if (days === 1) return \"tomorrow\";\n if (days <= 7) return `in ${days}d`;\n return d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" });\n}\n\nfunction printSection(title: string, content: string): void {\n const line = theme.border.primary(\"\\u2500\".repeat(Math.max(0, title.length + 4)));\n console.log(`\\n${theme.text.primary(title)}`);\n console.log(line);\n console.log(content);\n}\n\nfunction renderRepoSection(data: RepoData, selfLogin: string, backlogOnly: boolean): string {\n if (data.error) {\n return ` ${theme.text.error(`Error: ${data.error}`)}`;\n }\n\n if (data.issues.length === 0) {\n return ` ${theme.text.muted(\"No open issues\")}`;\n }\n\n const assigned = backlogOnly ? [] : data.issues.filter((i) => (i.assignees ?? []).length > 0);\n const backlog = data.issues.filter((i) => (i.assignees ?? []).length === 0);\n\n const lines: string[] = [];\n const maxTitle = 45;\n\n if (assigned.length > 0) {\n lines.push(` ${theme.text.secondary(\"In Progress\")}`);\n for (const issue of assigned) {\n lines.push(formatIssueLine(issue, selfLogin, maxTitle));\n }\n }\n\n if (backlog.length > 0) {\n if (assigned.length > 0) lines.push(\"\");\n lines.push(` ${theme.text.secondary(\"Backlog (unassigned)\")}`);\n for (const issue of backlog) {\n lines.push(formatIssueLine(issue, selfLogin, maxTitle));\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction renderTickTickSection(tasks: Task[], error: string | null): string {\n if (error) {\n return ` ${theme.text.error(`Error: ${error}`)}`;\n }\n\n if (tasks.length === 0) {\n return ` ${theme.text.muted(\"No active tasks\")}`;\n }\n\n const maxTitle = 45;\n const sorted = [...tasks].sort((a, b) => {\n // Overdue first, then by due date, then by priority\n if (a.dueDate && !b.dueDate) return -1;\n if (!a.dueDate && b.dueDate) return 1;\n if (a.dueDate && b.dueDate) return a.dueDate.localeCompare(b.dueDate);\n return b.priority - a.priority;\n });\n\n return sorted.map((t) => formatTaskLine(t, maxTitle)).join(\"\\n\");\n}\n\nexport function renderStaticBoard(\n data: DashboardData,\n selfLogin: string,\n backlogOnly: boolean,\n): void {\n const now = data.fetchedAt.toLocaleTimeString(\"en-US\", {\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n const date = data.fetchedAt.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n\n console.log(`\\n${theme.text.accent(\"HOG BOARD\")} ${theme.text.muted(`\\u2014 ${date} ${now}`)}`);\n\n // GitHub repos\n for (const rd of data.repos) {\n const issueCount = rd.issues.length;\n const label = `${rd.repo.shortName} ${theme.text.muted(`(${issueCount} issues)`)}`;\n printSection(label, renderRepoSection(rd, selfLogin, backlogOnly));\n }\n\n // TickTick\n if (!backlogOnly) {\n const taskCount = data.ticktick.length;\n const dueToday = data.ticktick.filter((t) => {\n if (!t.dueDate) return false;\n const days = Math.ceil((new Date(t.dueDate).getTime() - Date.now()) / 86_400_000);\n return days <= 0;\n }).length;\n const label =\n dueToday > 0\n ? `Personal (TickTick) ${theme.text.warning(`${dueToday} due today`)} / ${taskCount} total`\n : `Personal (TickTick) ${theme.text.muted(`${taskCount} tasks`)}`;\n printSection(label, renderTickTickSection(data.ticktick, data.ticktickError));\n }\n\n console.log(\"\");\n}\n\nexport function renderBoardJson(data: DashboardData, selfLogin: string): Record<string, unknown> {\n return {\n ok: true,\n data: {\n repos: data.repos.map((rd) => ({\n name: rd.repo.name,\n shortName: rd.repo.shortName,\n error: rd.error,\n issues: rd.issues.map((i) => ({\n number: i.number,\n title: i.title,\n url: i.url,\n state: i.state,\n assignee: (i.assignees ?? [])[0]?.login ?? null,\n assignees: (i.assignees ?? []).map((a) => a.login),\n labels: i.labels.map((l) => l.name),\n updatedAt: i.updatedAt,\n isMine: (i.assignees ?? []).some((a) => a.login === selfLogin),\n slackThreadUrl: i.slackThreadUrl ?? null,\n projectStatus: i.projectStatus ?? null,\n targetDate: i.targetDate ?? null,\n })),\n })),\n ticktick: {\n error: data.ticktickError,\n tasks: data.ticktick.map((t) => ({\n id: t.id,\n title: t.title,\n priority: t.priority,\n dueDate: t.dueDate,\n tags: t.tags,\n })),\n },\n activity: data.activity,\n fetchedAt: data.fetchedAt.toISOString(),\n },\n };\n}\n","const major = Number(process.versions.node.split(\".\")[0]);\nif (major < 22) {\n console.error(\n `hog requires Node.js >= 22 (current: ${process.version}). Install from https://nodejs.org/`,\n );\n process.exit(1);\n}\n\nimport { execFile, execFileSync } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { Command } from \"commander\";\nimport { extractIssueFields, hasLlmApiKey } from \"./ai.js\";\nimport { TickTickClient } from \"./api.js\";\nimport type { CompletionAction, HogConfig, RepoConfig } from \"./config.js\";\nimport {\n clearLlmAuth,\n findRepo,\n getConfig,\n getLlmAuth,\n loadFullConfig,\n requireAuth,\n resolveProfile,\n saveConfig,\n saveFullConfig,\n saveLlmAuth,\n validateRepoName,\n} from \"./config.js\";\nimport { runInit, runReposAdd } from \"./init.js\";\nimport { getActionLog } from \"./log-persistence.js\";\nimport {\n jsonOut,\n printProjects,\n printSuccess,\n printSyncResult,\n printSyncStatus,\n printTask,\n printTasks,\n setFormat,\n useJson,\n} from \"./output.js\";\nimport { getSyncStatus, runSync } from \"./sync.js\";\nimport type { CreateTaskInput, UpdateTaskInput } from \"./types.js\";\nimport { Priority } from \"./types.js\";\n\nconst execFileAsync = promisify(execFile);\n\n// -- Typed option interfaces for each command --\n\ninterface GlobalOptions {\n json?: true;\n human?: true;\n}\n\ninterface InitOptions {\n force?: true;\n}\n\ninterface AddOptions {\n priority?: string;\n date?: string;\n start?: string;\n content?: string;\n tags?: string;\n allDay?: true;\n project?: string;\n}\n\ninterface ListOptions {\n project?: string;\n all?: true;\n priority?: string;\n tag?: string;\n}\n\ninterface ProjectScopedOptions {\n project?: string;\n}\n\ninterface UpdateOptions extends ProjectScopedOptions {\n title?: string;\n priority?: string;\n date?: string;\n content?: string;\n tags?: string;\n}\n\n// -- Helpers --\n\nasync function resolveRef(\n ref: string,\n config: HogConfig,\n): Promise<Awaited<ReturnType<typeof import(\"./pick.js\").parseIssueRef>>> {\n const { parseIssueRef } = await import(\"./pick.js\");\n try {\n return parseIssueRef(ref, config);\n } catch (err) {\n console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n\nfunction errorOut(message: string, data?: Record<string, unknown>): never {\n if (useJson()) {\n jsonOut({ ok: false, error: message, ...(data ? { data } : {}) });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n}\n\nconst PRIORITY_MAP: Record<string, Priority | undefined> = {\n none: Priority.None,\n low: Priority.Low,\n medium: Priority.Medium,\n med: Priority.Medium,\n high: Priority.High,\n};\n\nfunction parsePriority(value: string): Priority {\n const p = PRIORITY_MAP[value.toLowerCase()];\n if (p === undefined) {\n errorOut(`Invalid priority: \"${value}\". Valid values: none, low, medium, high`);\n }\n return p;\n}\n\nfunction createClient(): TickTickClient {\n const auth = requireAuth();\n return new TickTickClient(auth.accessToken);\n}\n\nfunction resolveProjectId(projectId?: string): string {\n if (projectId) return projectId;\n const config = getConfig();\n if (config.defaultProjectId) return config.defaultProjectId;\n console.error(\"No project selected. Run `hog task use-project <id>` or pass --project.\");\n process.exit(1);\n}\n\n// -- Program --\n\nconst program = new Command();\n\nprogram\n .name(\"hog\")\n .description(\"Personal command deck — unified task dashboard for GitHub Projects + TickTick\")\n .version(\"1.16.2\") // x-release-please-version\n .option(\"--json\", \"Force JSON output\")\n .option(\"--human\", \"Force human-readable output\")\n .hook(\"preAction\", (thisCommand) => {\n const opts = thisCommand.opts<GlobalOptions>();\n if (opts.json) setFormat(\"json\");\n if (opts.human) setFormat(\"human\");\n });\n\n// -- Init --\n\nprogram\n .command(\"init\")\n .description(\"Interactive setup wizard\")\n .option(\"--force\", \"Overwrite existing config without prompt\")\n .action(async (opts: InitOptions) => {\n await runInit({ force: opts.force ?? false });\n });\n\n// -- Task commands --\n\nconst task = program.command(\"task\").description(\"Manage TickTick tasks\");\n\ntask\n .command(\"add <title>\")\n .description(\"Create a new task\")\n .option(\"-p, --priority <level>\", \"Priority: none, low, medium, high\")\n .option(\"-d, --date <date>\", \"Due date (ISO 8601)\")\n .option(\"--start <date>\", \"Start date (ISO 8601)\")\n .option(\"-c, --content <text>\", \"Task description/content\")\n .option(\"-t, --tags <tags>\", \"Comma-separated tags\")\n .option(\"--all-day\", \"Mark as all-day task\")\n .option(\"--project <id>\", \"Project ID (overrides default)\")\n .action(async (title: string, opts: AddOptions) => {\n const api = createClient();\n const input: CreateTaskInput = {\n title,\n projectId: resolveProjectId(opts.project),\n };\n\n if (opts.priority) input.priority = parsePriority(opts.priority);\n if (opts.date) input.dueDate = opts.date;\n if (opts.start) input.startDate = opts.start;\n if (opts.content) input.content = opts.content;\n if (opts.tags) input.tags = opts.tags.split(\",\").map((t) => t.trim());\n if (opts.allDay) input.isAllDay = true;\n\n const created = await api.createTask(input);\n printSuccess(`Created: ${created.title}`, { task: created });\n });\n\ntask\n .command(\"list\")\n .description(\"List tasks in a project\")\n .option(\"--project <id>\", \"Project ID (overrides default)\")\n .option(\"--all\", \"Include completed tasks\")\n .option(\"-p, --priority <level>\", \"Filter by minimum priority\")\n .option(\"-t, --tag <tag>\", \"Filter by tag\")\n .action(async (opts: ListOptions) => {\n const api = createClient();\n const projectId = resolveProjectId(opts.project);\n let tasks = await api.listTasks(projectId);\n\n if (!opts.all) {\n tasks = tasks.filter((t) => t.status !== 2);\n }\n if (opts.priority) {\n const minPri = parsePriority(opts.priority);\n tasks = tasks.filter((t) => t.priority >= minPri);\n }\n if (opts.tag) {\n const tag = opts.tag;\n tasks = tasks.filter((t) => t.tags.includes(tag));\n }\n\n printTasks(tasks);\n });\n\ntask\n .command(\"show <taskId>\")\n .description(\"Show task details\")\n .option(\"--project <id>\", \"Project ID (overrides default)\")\n .action(async (taskId: string, opts: ProjectScopedOptions) => {\n const api = createClient();\n const projectId = resolveProjectId(opts.project);\n const t = await api.getTask(projectId, taskId);\n printTask(t);\n });\n\ntask\n .command(\"complete <taskId>\")\n .description(\"Mark a task as completed\")\n .option(\"--project <id>\", \"Project ID (overrides default)\")\n .action(async (taskId: string, opts: ProjectScopedOptions) => {\n const api = createClient();\n const projectId = resolveProjectId(opts.project);\n await api.completeTask(projectId, taskId);\n printSuccess(`Completed task ${taskId}`, { taskId });\n });\n\ntask\n .command(\"update <taskId>\")\n .description(\"Update a task\")\n .option(\"--title <title>\", \"New title\")\n .option(\"-p, --priority <level>\", \"New priority\")\n .option(\"-d, --date <date>\", \"New due date (ISO 8601)\")\n .option(\"-c, --content <text>\", \"New content\")\n .option(\"-t, --tags <tags>\", \"New comma-separated tags\")\n .option(\"--project <id>\", \"Project ID (overrides default)\")\n .action(async (taskId: string, opts: UpdateOptions) => {\n const api = createClient();\n const projectId = resolveProjectId(opts.project);\n const input: UpdateTaskInput = { id: taskId, projectId };\n\n if (opts.title) input.title = opts.title;\n if (opts.priority) input.priority = parsePriority(opts.priority);\n if (opts.date) input.dueDate = opts.date;\n if (opts.content) input.content = opts.content;\n if (opts.tags) input.tags = opts.tags.split(\",\").map((t) => t.trim());\n\n const updated = await api.updateTask(input);\n printSuccess(`Updated: ${updated.title}`, { task: updated });\n });\n\ntask\n .command(\"delete <taskId>\")\n .description(\"Delete a task\")\n .option(\"--project <id>\", \"Project ID (overrides default)\")\n .action(async (taskId: string, opts: ProjectScopedOptions) => {\n const api = createClient();\n const projectId = resolveProjectId(opts.project);\n await api.deleteTask(projectId, taskId);\n printSuccess(`Deleted task ${taskId}`, { taskId });\n });\n\ntask\n .command(\"projects\")\n .description(\"List all projects\")\n .action(async () => {\n const api = createClient();\n const projects = await api.listProjects();\n printProjects(projects);\n });\n\ntask\n .command(\"use-project <projectId>\")\n .description(\"Set the default project for task commands\")\n .action(async (projectId: string) => {\n const api = createClient();\n try {\n const project = await api.getProject(projectId);\n saveConfig({ defaultProjectId: project.id, defaultProjectName: project.name });\n printSuccess(`Default project: ${project.name} (${project.id})`, {\n projectId: project.id,\n projectName: project.name,\n });\n } catch {\n saveConfig({ defaultProjectId: projectId });\n printSuccess(`Default project: ${projectId}`, { projectId });\n }\n });\n\n// -- Sync commands --\n\ninterface SyncRunOptions {\n dryRun?: true;\n}\n\nconst sync = program.command(\"sync\").description(\"Sync GitHub issues with TickTick\");\n\nsync\n .command(\"run\", { isDefault: true })\n .description(\"Run GitHub-TickTick sync\")\n .option(\"--dry-run\", \"Preview changes without applying them\")\n .action(async (opts: SyncRunOptions) => {\n const dryRun = opts.dryRun ?? false;\n const result = await runSync({ dryRun });\n printSyncResult(result, dryRun);\n });\n\nsync\n .command(\"status\")\n .description(\"Show sync status and mappings\")\n .action(() => {\n const { state, repos } = getSyncStatus();\n printSyncStatus(state, repos);\n });\n\n// -- Board command --\n\ninterface BoardOptions {\n repo?: string;\n mine?: true;\n backlog?: true;\n live?: true;\n profile?: string;\n}\n\nprogram\n .command(\"board\")\n .description(\"Show unified task dashboard\")\n .option(\"--repo <name>\", \"Filter by repo (short name or full)\")\n .option(\"--mine\", \"Show only my assigned issues and tasks\")\n .option(\"--backlog\", \"Show only unassigned issues\")\n .option(\"--live\", \"Persistent TUI with auto-refresh and keyboard navigation\")\n .option(\"--profile <name>\", \"Use a named board profile\")\n .action(async (opts: BoardOptions) => {\n const rawCfg = loadFullConfig();\n const { resolved: cfg, activeProfile } = resolveProfile(rawCfg, opts.profile);\n const jsonMode = useJson();\n const fetchOptions = {\n repoFilter: opts.repo,\n mineOnly: opts.mine ?? false,\n backlogOnly: opts.backlog ?? false,\n };\n\n if (opts.live) {\n const { runLiveDashboard } = await import(\"./board/live.js\");\n await runLiveDashboard(cfg, fetchOptions, activeProfile);\n return;\n }\n\n const { fetchDashboard } = await import(\"./board/fetch.js\");\n const data = await fetchDashboard(cfg, fetchOptions);\n\n if (jsonMode) {\n const { renderBoardJson } = await import(\"./board/format-static.js\");\n jsonOut(renderBoardJson(data, cfg.board.assignee));\n } else {\n const { renderStaticBoard } = await import(\"./board/format-static.js\");\n renderStaticBoard(data, cfg.board.assignee, opts.backlog ?? false);\n }\n });\n\n// -- Pick command --\n\nprogram\n .command(\"pick <issueRef>\")\n .description(\"Pick up an issue: assign to self + sync to TickTick (e.g., hog pick aibility/145)\")\n .action(async (issueRef: string) => {\n const cfg = loadFullConfig();\n const { parseIssueRef, pickIssue } = await import(\"./pick.js\");\n const ref = parseIssueRef(issueRef, cfg);\n const result = await pickIssue(cfg, ref);\n\n if (useJson()) {\n jsonOut({\n ok: result.success,\n data: {\n issue: result.issue,\n ticktickTask: result.ticktickTask ?? null,\n warning: result.warning ?? null,\n },\n });\n } else {\n console.log(`Picked ${ref.repo.shortName}#${ref.issueNumber}: ${result.issue.title}`);\n console.log(` GitHub: assigned to @me`);\n if (result.ticktickTask) {\n console.log(` TickTick: task created`);\n }\n if (result.warning) {\n console.log(` Warning: ${result.warning}`);\n }\n }\n });\n\n// -- Config commands --\n\ninterface ConfigAddRepoOptions {\n projectNumber?: string;\n statusFieldId?: string;\n completionType?: string;\n completionOptionId?: string;\n completionLabel?: string;\n}\n\nconst config = program.command(\"config\").description(\"Manage hog configuration\");\n\nconfig\n .command(\"show\")\n .description(\"Show full configuration\")\n .action(() => {\n const cfg = loadFullConfig();\n if (useJson()) {\n jsonOut({ ok: true, data: cfg });\n } else {\n console.log(\"Version:\", cfg.version);\n console.log(\"Default project:\", cfg.defaultProjectId ?? \"(none)\");\n console.log(\"Assignee:\", cfg.board.assignee);\n console.log(\"Refresh interval:\", `${cfg.board.refreshInterval}s`);\n console.log(\"Backlog limit:\", cfg.board.backlogLimit);\n console.log(\"TickTick:\", cfg.ticktick.enabled ? \"enabled\" : \"disabled\");\n console.log(\"\\nRepos:\");\n for (const repo of cfg.repos) {\n console.log(` ${repo.shortName} → ${repo.name} (project #${repo.projectNumber})`);\n console.log(` completion: ${repo.completionAction.type}`);\n }\n }\n });\n\nconfig\n .command(\"repos\")\n .description(\"List configured repositories\")\n .action(() => {\n const cfg = loadFullConfig();\n if (useJson()) {\n jsonOut({ ok: true, data: cfg.repos });\n } else {\n if (cfg.repos.length === 0) {\n console.log(\"No repos configured. Run: hog config repos add <owner/repo>\");\n return;\n }\n for (const repo of cfg.repos) {\n console.log(` ${repo.shortName.padEnd(15)} ${repo.name}`);\n }\n }\n });\n\nconfig\n .command(\"repos:add [name]\")\n .description(\"Add a repository to track (interactive wizard, or pass flags for scripted use)\")\n .option(\"--project-number <n>\", \"GitHub project number (skips interactive prompt)\")\n .option(\"--status-field-id <id>\", \"Project status field ID (skips interactive prompt)\")\n .option(\n \"--completion-type <type>\",\n \"Completion action: addLabel, updateProjectStatus, closeIssue\",\n )\n .option(\"--completion-option-id <id>\", \"Option ID for updateProjectStatus\")\n .option(\"--completion-label <label>\", \"Label for addLabel\")\n .action(async (name: string | undefined, opts: ConfigAddRepoOptions) => {\n // Interactive mode: no project-number or status-field-id provided\n if (!(opts.projectNumber && opts.statusFieldId)) {\n await runReposAdd(name);\n return;\n }\n\n // Non-interactive (scripted) mode: all required flags provided\n if (!name) {\n console.error(\"Name argument required in non-interactive mode.\");\n process.exit(1);\n }\n if (!validateRepoName(name)) {\n console.error(\"Invalid repo name. Use owner/repo format (e.g., myorg/myrepo)\");\n process.exit(1);\n }\n\n const cfg = loadFullConfig();\n if (findRepo(cfg, name)) {\n console.error(`Repo \"${name}\" is already configured.`);\n process.exit(1);\n }\n\n const shortName = name.split(\"/\")[1] ?? name;\n\n if (!opts.completionType) {\n console.error(\"--completion-type required in non-interactive mode\");\n process.exit(1);\n }\n\n let completionAction: CompletionAction;\n switch (opts.completionType) {\n case \"addLabel\":\n if (!opts.completionLabel) {\n console.error(\"--completion-label required for addLabel type\");\n process.exit(1);\n }\n completionAction = { type: \"addLabel\", label: opts.completionLabel };\n break;\n case \"updateProjectStatus\":\n if (!opts.completionOptionId) {\n console.error(\"--completion-option-id required for updateProjectStatus type\");\n process.exit(1);\n }\n completionAction = { type: \"updateProjectStatus\", optionId: opts.completionOptionId };\n break;\n case \"closeIssue\":\n completionAction = { type: \"closeIssue\" };\n break;\n default:\n console.error(\n `Unknown completion type: ${opts.completionType}. Use: addLabel, updateProjectStatus, closeIssue`,\n );\n process.exit(1);\n }\n\n const newRepo: RepoConfig = {\n name,\n shortName,\n projectNumber: Number.parseInt(opts.projectNumber, 10),\n statusFieldId: opts.statusFieldId,\n completionAction,\n };\n\n cfg.repos.push(newRepo);\n saveFullConfig(cfg);\n\n if (useJson()) {\n jsonOut({ ok: true, message: `Added ${name}`, data: newRepo });\n } else {\n console.log(`Added ${shortName} → ${name}`);\n }\n });\n\nconfig\n .command(\"repos:rm <name>\")\n .description(\"Remove a repository from tracking\")\n .action((name: string) => {\n const cfg = loadFullConfig();\n const idx = cfg.repos.findIndex((r) => r.shortName === name || r.name === name);\n if (idx === -1) {\n console.error(`Repo \"${name}\" not found. Run: hog config repos`);\n process.exit(1);\n }\n const [removed] = cfg.repos.splice(idx, 1);\n if (!removed) {\n process.exit(1);\n }\n saveFullConfig(cfg);\n\n if (useJson()) {\n jsonOut({ ok: true, message: `Removed ${removed.name}`, data: removed });\n } else {\n console.log(`Removed ${removed.shortName} → ${removed.name}`);\n console.log(\"Note: Existing sync mappings for this repo remain in sync-state.json.\");\n }\n });\n\nconfig\n .command(\"ticktick:enable\")\n .description(\"Enable TickTick integration in the board\")\n .action(() => {\n const cfg = loadFullConfig();\n cfg.ticktick = { enabled: true };\n saveFullConfig(cfg);\n if (useJson()) {\n jsonOut({ ok: true, message: \"TickTick enabled\" });\n } else {\n printSuccess(\"TickTick integration enabled.\");\n }\n });\n\nconfig\n .command(\"ticktick:disable\")\n .description(\"Disable TickTick integration in the board\")\n .action(() => {\n const cfg = loadFullConfig();\n cfg.ticktick = { enabled: false };\n saveFullConfig(cfg);\n if (useJson()) {\n jsonOut({ ok: true, message: \"TickTick disabled\" });\n } else {\n printSuccess(\"TickTick integration disabled. Board will no longer show TickTick tasks.\");\n }\n });\n\nconfig\n .command(\"ai:set-key <key>\")\n .description(\"Store an OpenRouter API key for AI-enhanced issue creation (I key on board)\")\n .action((key: string) => {\n if (!key.startsWith(\"sk-or-\")) {\n console.error('Error: key must start with \"sk-or-\". Get one at https://openrouter.ai/keys');\n process.exit(1);\n }\n saveLlmAuth(key);\n if (useJson()) {\n jsonOut({ ok: true, message: \"OpenRouter key saved\" });\n } else {\n printSuccess(\"OpenRouter key saved to ~/.config/hog/auth.json\");\n console.log(\" Press I on the board to create issues with natural language.\");\n }\n });\n\nconfig\n .command(\"ai:clear-key\")\n .description(\"Remove the stored OpenRouter API key\")\n .action(() => {\n const existing = getLlmAuth();\n if (!existing) {\n if (useJson()) {\n jsonOut({ ok: true, message: \"No key was stored\" });\n } else {\n console.log(\"No OpenRouter key stored.\");\n }\n return;\n }\n clearLlmAuth();\n if (useJson()) {\n jsonOut({ ok: true, message: \"OpenRouter key removed\" });\n } else {\n printSuccess(\"OpenRouter key removed from ~/.config/hog/auth.json\");\n }\n });\n\nconfig\n .command(\"ai:status\")\n .description(\"Show whether AI-enhanced issue creation is available and which source provides it\")\n .action(() => {\n const envOr = process.env[\"OPENROUTER_API_KEY\"];\n const envAnt = process.env[\"ANTHROPIC_API_KEY\"];\n const stored = getLlmAuth();\n\n if (useJson()) {\n jsonOut({\n ok: true,\n data: {\n active: !!(envOr ?? envAnt ?? stored),\n source: envOr\n ? \"env:OPENROUTER_API_KEY\"\n : envAnt\n ? \"env:ANTHROPIC_API_KEY\"\n : stored\n ? \"config:auth.json\"\n : null,\n provider: envOr ? \"openrouter\" : envAnt ? \"anthropic\" : stored ? \"openrouter\" : null,\n },\n });\n } else if (envOr) {\n console.log(\"AI: active (source: OPENROUTER_API_KEY env var, provider: openrouter)\");\n } else if (envAnt) {\n console.log(\"AI: active (source: ANTHROPIC_API_KEY env var, provider: anthropic)\");\n } else if (stored) {\n console.log(\"AI: active (source: ~/.config/hog/auth.json, provider: openrouter)\");\n } else {\n console.log(\"AI: off — heuristic-only mode\");\n console.log(\" Enable with: hog config ai:set-key <sk-or-...>\");\n console.log(\" Or set env: export OPENROUTER_API_KEY=sk-or-...\");\n }\n });\n\nconfig\n .command(\"profile:create <name>\")\n .description(\"Create a board profile (copies current top-level config)\")\n .action((name: string) => {\n const cfg = loadFullConfig();\n if (cfg.profiles[name]) {\n console.error(`Profile \"${name}\" already exists.`);\n process.exit(1);\n }\n\n cfg.profiles[name] = {\n repos: [...cfg.repos],\n board: { ...cfg.board },\n ticktick: { ...cfg.ticktick },\n };\n saveFullConfig(cfg);\n\n if (useJson()) {\n jsonOut({ ok: true, message: `Created profile \"${name}\"`, data: cfg.profiles[name] });\n } else {\n printSuccess(`Created profile \"${name}\" (copied from current config).`);\n }\n });\n\nconfig\n .command(\"profile:delete <name>\")\n .description(\"Delete a board profile\")\n .action((name: string) => {\n const cfg = loadFullConfig();\n if (!cfg.profiles[name]) {\n console.error(\n `Profile \"${name}\" not found. Available: ${Object.keys(cfg.profiles).join(\", \") || \"(none)\"}`,\n );\n process.exit(1);\n }\n\n delete cfg.profiles[name];\n\n // Clear defaultProfile if it was the deleted one\n if (cfg.defaultProfile === name) {\n cfg.defaultProfile = undefined;\n }\n\n saveFullConfig(cfg);\n\n if (useJson()) {\n jsonOut({ ok: true, message: `Deleted profile \"${name}\"` });\n } else {\n printSuccess(`Deleted profile \"${name}\".`);\n }\n });\n\nconfig\n .command(\"profile:default [name]\")\n .description(\"Set or show the default board profile\")\n .action((name?: string) => {\n const cfg = loadFullConfig();\n\n if (!name) {\n // Show current default\n if (useJson()) {\n jsonOut({\n ok: true,\n data: { defaultProfile: cfg.defaultProfile ?? null, profiles: Object.keys(cfg.profiles) },\n });\n } else {\n console.log(\"Default profile:\", cfg.defaultProfile ?? \"(none)\");\n const names = Object.keys(cfg.profiles);\n if (names.length > 0) {\n console.log(\"Available profiles:\", names.join(\", \"));\n } else {\n console.log(\"No profiles configured. Run: hog config profile:create <name>\");\n }\n }\n return;\n }\n\n if (!cfg.profiles[name]) {\n console.error(\n `Profile \"${name}\" not found. Available: ${Object.keys(cfg.profiles).join(\", \") || \"(none)\"}`,\n );\n process.exit(1);\n }\n\n cfg.defaultProfile = name;\n saveFullConfig(cfg);\n\n if (useJson()) {\n jsonOut({ ok: true, message: `Default profile set to \"${name}\"` });\n } else {\n printSuccess(`Default profile set to \"${name}\".`);\n }\n });\n\n// -- Issue commands --\n\ninterface IssueCreateOptions {\n repo?: string;\n dryRun?: true;\n}\n\ninterface IssueMoveOptions {\n dryRun?: true;\n}\n\ninterface IssueAssignOptions {\n user?: string;\n dryRun?: true;\n}\n\ninterface IssueUnassignOptions {\n user?: string;\n dryRun?: true;\n}\n\ninterface IssueCommentOptions {\n dryRun?: true;\n}\n\ninterface IssueEditOptions {\n title?: string;\n body?: string;\n label?: string[];\n removeLabel?: string[];\n assignee?: string;\n removeAssignee?: string;\n dryRun?: true;\n}\n\ninterface IssueLabelOptions {\n remove?: boolean;\n dryRun?: true;\n}\n\nconst issueCommand = new Command(\"issue\").description(\"GitHub issue utilities\");\n\nissueCommand\n .command(\"create <text>\")\n .description(\"Create a GitHub issue from natural language text\")\n .option(\"--repo <repo>\", \"Target repository (owner/name)\")\n .option(\"--dry-run\", \"Print parsed fields without creating the issue\")\n .action(async (text: string, opts: IssueCreateOptions) => {\n const config = loadFullConfig();\n const repo = opts.repo ?? config.repos[0]?.name;\n if (!repo) {\n console.error(\n \"Error: no repo specified. Use --repo owner/name or configure repos in hog init.\",\n );\n process.exit(1);\n }\n\n if (hasLlmApiKey()) {\n console.error(\"[info] LLM parsing enabled\");\n }\n\n const parsed = await extractIssueFields(text, {\n onLlmFallback: (msg) => console.error(`[warn] ${msg}`),\n });\n\n if (!parsed) {\n console.error(\n \"Error: could not parse a title from input. Ensure your text has a non-empty title.\",\n );\n process.exit(1);\n }\n\n const labels = [...parsed.labels];\n if (parsed.dueDate) labels.push(`due:${parsed.dueDate}`);\n\n // Show parsed fields\n console.error(`Title: ${parsed.title}`);\n if (labels.length > 0) console.error(`Labels: ${labels.join(\", \")}`);\n if (parsed.assignee) console.error(`Assignee: @${parsed.assignee}`);\n if (parsed.dueDate) console.error(`Due: ${parsed.dueDate}`);\n console.error(`Repo: ${repo}`);\n\n if (opts.dryRun) {\n console.error(\"[dry-run] Skipping issue creation.\");\n return;\n }\n\n const args = [\"issue\", \"create\", \"--repo\", repo, \"--title\", parsed.title, \"--body\", \"\"];\n for (const label of labels) {\n args.push(\"--label\", label);\n }\n\n const repoArg = repo;\n try {\n if (useJson()) {\n const output = await execFileAsync(\"gh\", args, { encoding: \"utf-8\", timeout: 60_000 });\n const url = output.stdout.trim();\n const issueNumber = Number.parseInt(url.split(\"/\").pop() ?? \"0\", 10);\n jsonOut({ ok: true, data: { url, issueNumber, repo: repoArg } });\n } else {\n execFileSync(\"gh\", args, { stdio: \"inherit\" });\n }\n } catch (err) {\n console.error(\n `Error: gh issue create failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n process.exit(1);\n }\n });\n\nissueCommand\n .command(\"show <issueRef>\")\n .description(\"Show issue details (format: shortname/number, e.g. myrepo/42)\")\n .action(async (issueRef: string) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n const { fetchIssueAsync } = await import(\"./github.js\");\n const issue = await fetchIssueAsync(ref.repo.name, ref.issueNumber);\n if (useJson()) {\n jsonOut({ ok: true, data: issue });\n } else {\n console.log(`#${issue.number} ${issue.title}`);\n if (issue.projectStatus) console.log(` Status: ${issue.projectStatus}`);\n const labels = issue.labels.map((l) => l.name).join(\", \");\n if (labels) console.log(` Labels: ${labels}`);\n const assignees = (issue.assignees ?? []).map((a) => `@${a.login}`).join(\", \");\n if (assignees) console.log(` Assignee: ${assignees}`);\n console.log(` URL: ${issue.url}`);\n if (issue.body) {\n console.log();\n console.log(issue.body);\n }\n }\n });\n\nissueCommand\n .command(\"move <issueRef> <status>\")\n .description(\"Change project status (e.g. hog issue move myrepo/42 'In Review')\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (issueRef: string, status: string, opts: IssueMoveOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n const rc = ref.repo;\n if (!(rc.statusFieldId && rc.projectNumber)) {\n errorOut(`${rc.name} is not configured with a project board. Run: hog init`, {\n repo: rc.name,\n });\n }\n const { fetchProjectStatusOptions, updateProjectItemStatusAsync } = await import(\"./github.js\");\n const options = fetchProjectStatusOptions(rc.name, rc.projectNumber, rc.statusFieldId);\n const target = options.find((o) => o.name.toLowerCase() === status.toLowerCase());\n if (!target) {\n const valid = options.map((o) => o.name).join(\", \");\n errorOut(`Invalid status \"${status}\". Valid: ${valid}`, { status, validStatuses: valid });\n }\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: {\n action: \"move\",\n issue: ref.issueNumber,\n repo: rc.shortName,\n status: target.name,\n },\n });\n } else {\n console.log(`[dry-run] Would move ${rc.shortName}#${ref.issueNumber} → \"${target.name}\"`);\n }\n return;\n }\n await updateProjectItemStatusAsync(rc.name, ref.issueNumber, {\n projectNumber: rc.projectNumber,\n statusFieldId: rc.statusFieldId,\n optionId: target.id,\n });\n if (useJson()) {\n jsonOut({ ok: true, data: { issue: ref.issueNumber, status: target.name } });\n } else {\n console.log(`Moved ${rc.shortName}#${ref.issueNumber} → ${target.name}`);\n }\n });\n\nissueCommand\n .command(\"assign <issueRef>\")\n .description(\"Assign issue to self or a specific user\")\n .option(\"--user <username>\", \"GitHub username to assign (default: configured assignee)\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (issueRef: string, opts: IssueAssignOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n const user = opts.user ?? cfg.board.assignee;\n if (!user) {\n console.error(\"Error: no user specified. Use --user or configure board.assignee in hog init\");\n process.exit(1);\n }\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: { action: \"assign\", issue: ref.issueNumber, repo: ref.repo.shortName, user },\n });\n } else {\n console.log(`[dry-run] Would assign ${ref.repo.shortName}#${ref.issueNumber} to @${user}`);\n }\n return;\n }\n const { assignIssueToAsync } = await import(\"./github.js\");\n await assignIssueToAsync(ref.repo.name, ref.issueNumber, user);\n if (useJson()) {\n jsonOut({ ok: true, data: { issue: ref.issueNumber, assignee: user } });\n } else {\n console.log(`Assigned ${ref.repo.shortName}#${ref.issueNumber} to @${user}`);\n }\n });\n\nissueCommand\n .command(\"unassign <issueRef>\")\n .description(\"Remove assignee from issue\")\n .option(\"--user <username>\", \"GitHub username to remove (default: configured assignee)\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (issueRef: string, opts: IssueUnassignOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n const user = opts.user ?? cfg.board.assignee;\n if (!user) {\n console.error(\"Error: no user specified. Use --user or configure board.assignee in hog init\");\n process.exit(1);\n }\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: { action: \"unassign\", issue: ref.issueNumber, repo: ref.repo.shortName, user },\n });\n } else {\n console.log(\n `[dry-run] Would remove @${user} from ${ref.repo.shortName}#${ref.issueNumber}`,\n );\n }\n return;\n }\n const { unassignIssueAsync } = await import(\"./github.js\");\n await unassignIssueAsync(ref.repo.name, ref.issueNumber, user);\n if (useJson()) {\n jsonOut({ ok: true, data: { issue: ref.issueNumber, removedAssignee: user } });\n } else {\n console.log(`Removed @${user} from ${ref.repo.shortName}#${ref.issueNumber}`);\n }\n });\n\nissueCommand\n .command(\"comment <issueRef> <text>\")\n .description(\"Post a comment on an issue\")\n .option(\"--dry-run\", \"Print what would be posted without mutating\")\n .action(async (issueRef: string, text: string, opts: IssueCommentOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: { action: \"comment\", issue: ref.issueNumber, repo: ref.repo.shortName, text },\n });\n } else {\n console.log(\n `[dry-run] Would comment on ${ref.repo.shortName}#${ref.issueNumber}: \"${text}\"`,\n );\n }\n return;\n }\n const { addCommentAsync } = await import(\"./github.js\");\n await addCommentAsync(ref.repo.name, ref.issueNumber, text);\n if (useJson()) {\n jsonOut({ ok: true, data: { issue: ref.issueNumber, comment: text } });\n } else {\n console.log(`Commented on ${ref.repo.shortName}#${ref.issueNumber}`);\n }\n });\n\nissueCommand\n .command(\"edit <issueRef>\")\n .description(\"Edit issue fields (title, body, labels, assignees)\")\n .option(\"--title <title>\", \"New title\")\n .option(\"--body <body>\", \"New body\")\n .option(\n \"--label <label>\",\n \"Add label (repeatable)\",\n (v, acc: string[]) => [...acc, v],\n [] as string[],\n )\n .option(\n \"--remove-label <label>\",\n \"Remove label (repeatable)\",\n (v, acc: string[]) => [...acc, v],\n [] as string[],\n )\n .option(\"--assignee <user>\", \"Add assignee\")\n .option(\"--remove-assignee <user>\", \"Remove assignee\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (issueRef: string, opts: IssueEditOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n\n const changes: string[] = [];\n if (opts.title) changes.push(`title → \"${opts.title}\"`);\n if (opts.body !== undefined) changes.push(\"body updated\");\n if (opts.label?.length) changes.push(`add labels: ${opts.label.join(\", \")}`);\n if (opts.removeLabel?.length) changes.push(`remove labels: ${opts.removeLabel.join(\", \")}`);\n if (opts.assignee) changes.push(`add assignee: @${opts.assignee}`);\n if (opts.removeAssignee) changes.push(`remove assignee: @${opts.removeAssignee}`);\n\n if (changes.length === 0) {\n console.error(\"Error: no changes specified. Use --title, --body, --label, etc.\");\n process.exit(1);\n }\n\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: { action: \"edit\", issue: ref.issueNumber, repo: ref.repo.shortName, changes },\n });\n } else {\n console.log(\n `[dry-run] Would edit ${ref.repo.shortName}#${ref.issueNumber}: ${changes.join(\"; \")}`,\n );\n }\n return;\n }\n\n const ghArgs = [\"issue\", \"edit\", String(ref.issueNumber), \"--repo\", ref.repo.name];\n if (opts.title) ghArgs.push(\"--title\", opts.title);\n if (opts.body !== undefined) ghArgs.push(\"--body\", opts.body);\n for (const l of opts.label ?? []) ghArgs.push(\"--add-label\", l);\n for (const l of opts.removeLabel ?? []) ghArgs.push(\"--remove-label\", l);\n if (opts.assignee) ghArgs.push(\"--add-assignee\", opts.assignee);\n if (opts.removeAssignee) ghArgs.push(\"--remove-assignee\", opts.removeAssignee);\n\n if (useJson()) {\n await execFileAsync(\"gh\", ghArgs, { encoding: \"utf-8\", timeout: 30_000 });\n jsonOut({ ok: true, data: { issue: ref.issueNumber, changes } });\n } else {\n execFileSync(\"gh\", ghArgs, { stdio: \"inherit\" });\n console.log(`Updated ${ref.repo.shortName}#${ref.issueNumber}: ${changes.join(\"; \")}`);\n }\n });\n\nissueCommand\n .command(\"label <issueRef> <label>\")\n .description(\"Add or remove a label on an issue\")\n .option(\"--remove\", \"Remove the label instead of adding it\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (issueRef: string, label: string, opts: IssueLabelOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n const verb = opts.remove ? \"remove\" : \"add\";\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: {\n action: `${verb}Label`,\n issue: ref.issueNumber,\n repo: ref.repo.shortName,\n label,\n },\n });\n } else {\n console.log(\n `[dry-run] Would ${verb} label \"${label}\" on ${ref.repo.shortName}#${ref.issueNumber}`,\n );\n }\n return;\n }\n if (opts.remove) {\n const { removeLabelAsync } = await import(\"./github.js\");\n await removeLabelAsync(ref.repo.name, ref.issueNumber, label);\n } else {\n const { addLabelAsync } = await import(\"./github.js\");\n await addLabelAsync(ref.repo.name, ref.issueNumber, label);\n }\n if (useJson()) {\n jsonOut({ ok: true, data: { issue: ref.issueNumber, label, action: verb } });\n } else {\n console.log(\n `${opts.remove ? \"Removed\" : \"Added\"} label \"${label}\" on ${ref.repo.shortName}#${ref.issueNumber}`,\n );\n }\n });\n\nissueCommand\n .command(\"statuses\")\n .description(\"List available project statuses for a repo\")\n .argument(\"<repo>\", \"repo short name (e.g. myrepo)\")\n .action(async (repo: string) => {\n const config = loadFullConfig();\n const repoConfig = config.repos.find((r) => r.shortName === repo || r.name === repo);\n if (!repoConfig) {\n errorOut(`Repo \"${repo}\" is not configured`, { repo });\n }\n const { fetchProjectStatusOptions } = await import(\"./github.js\");\n const statuses = fetchProjectStatusOptions(\n repoConfig.name,\n repoConfig.projectNumber,\n repoConfig.statusFieldId,\n );\n if (useJson()) {\n jsonOut({ ok: true, data: { repo, statuses: statuses.map((s) => s.name) } });\n } else {\n console.log(`Available statuses for ${repo}: ${statuses.map((s) => s.name).join(\", \")}`);\n }\n });\n\n// -- Bulk issue commands --\n\ntype BulkResult = { ref: string; success: true } | { ref: string; success: false; error: string };\n\nasync function moveSingleIssue(r: string, status: string, cfg: HogConfig): Promise<BulkResult> {\n try {\n const ref = await resolveRef(r, cfg);\n const rc = ref.repo;\n if (!(rc.statusFieldId && rc.projectNumber)) {\n throw new Error(`${rc.name} is not configured with a project board. Run: hog init`);\n }\n const { fetchProjectStatusOptions, updateProjectItemStatusAsync } = await import(\"./github.js\");\n const options = fetchProjectStatusOptions(rc.name, rc.projectNumber, rc.statusFieldId);\n const target = options.find((o) => o.name.toLowerCase() === status.toLowerCase());\n if (!target) {\n const valid = options.map((o) => o.name).join(\", \");\n throw new Error(`Invalid status \"${status}\". Valid: ${valid}`);\n }\n await updateProjectItemStatusAsync(rc.name, ref.issueNumber, {\n projectNumber: rc.projectNumber,\n statusFieldId: rc.statusFieldId,\n optionId: target.id,\n });\n return { ref: r, success: true };\n } catch (err) {\n return { ref: r, success: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n\nfunction outputBulkResults(results: BulkResult[]): void {\n const allOk = results.every((r) => r.success);\n if (useJson()) {\n jsonOut({ ok: allOk, results });\n } else {\n for (const r of results) {\n if (!r.success) {\n console.error(\n `Failed ${r.ref}: ${(r as { ref: string; success: false; error: string }).error}`,\n );\n }\n }\n }\n}\n\ninterface IssueBulkAssignOptions {\n user?: string;\n dryRun?: true;\n}\n\ninterface IssueBulkUnassignOptions {\n user?: string;\n dryRun?: true;\n}\n\ninterface IssueBulkMoveOptions {\n dryRun?: true;\n}\n\nissueCommand\n .command(\"bulk-assign <refs...>\")\n .description(\n \"Assign multiple issues to self or a specific user (e.g., hog issue bulk-assign myrepo/42 myrepo/43)\",\n )\n .option(\"--user <username>\", \"GitHub username to assign (default: configured assignee)\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (refs: string[], opts: IssueBulkAssignOptions) => {\n const cfg = loadFullConfig();\n const user = opts.user ?? cfg.board.assignee;\n if (!user) {\n errorOut(\"no user specified. Use --user or configure board.assignee in hog init\");\n }\n\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({ ok: true, dryRun: true, would: { action: \"bulk-assign\", refs, user } });\n } else {\n for (const r of refs) {\n console.log(`[dry-run] Would assign ${r} to @${user}`);\n }\n }\n return;\n }\n\n const { assignIssueToAsync } = await import(\"./github.js\");\n const results: BulkResult[] = [];\n for (const r of refs) {\n try {\n const ref = await resolveRef(r, cfg);\n await assignIssueToAsync(ref.repo.name, ref.issueNumber, user);\n results.push({ ref: r, success: true });\n if (!useJson()) console.log(`Assigned ${r} to @${user}`);\n } catch (err) {\n results.push({\n ref: r,\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n outputBulkResults(results);\n });\n\nissueCommand\n .command(\"bulk-unassign <refs...>\")\n .description(\n \"Remove assignee from multiple issues (e.g., hog issue bulk-unassign myrepo/42 myrepo/43)\",\n )\n .option(\"--user <username>\", \"GitHub username to remove (default: configured assignee)\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (refs: string[], opts: IssueBulkUnassignOptions) => {\n const cfg = loadFullConfig();\n const user = opts.user ?? cfg.board.assignee;\n if (!user) {\n errorOut(\"no user specified. Use --user or configure board.assignee in hog init\");\n }\n\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({ ok: true, dryRun: true, would: { action: \"bulk-unassign\", refs, user } });\n } else {\n for (const r of refs) {\n console.log(`[dry-run] Would remove @${user} from ${r}`);\n }\n }\n return;\n }\n\n const { unassignIssueAsync } = await import(\"./github.js\");\n const results: BulkResult[] = [];\n for (const r of refs) {\n try {\n const ref = await resolveRef(r, cfg);\n await unassignIssueAsync(ref.repo.name, ref.issueNumber, user);\n results.push({ ref: r, success: true });\n if (!useJson()) console.log(`Removed @${user} from ${r}`);\n } catch (err) {\n results.push({\n ref: r,\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n outputBulkResults(results);\n });\n\nissueCommand\n .command(\"bulk-move <status> <refs...>\")\n .description(\n \"Move multiple issues to a project status (e.g., hog issue bulk-move 'In Review' myrepo/42 myrepo/43)\",\n )\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (status: string, refs: string[], opts: IssueBulkMoveOptions) => {\n const cfg = loadFullConfig();\n\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({ ok: true, dryRun: true, would: { action: \"bulk-move\", refs, status } });\n } else {\n for (const r of refs) {\n console.log(`[dry-run] Would move ${r} → \"${status}\"`);\n }\n }\n return;\n }\n\n const results: BulkResult[] = await Promise.all(\n refs.map((r) => moveSingleIssue(r, status, cfg)),\n );\n if (!useJson()) {\n for (const r of results) {\n if (r.success) console.log(`Moved ${r.ref} → ${status}`);\n }\n }\n outputBulkResults(results);\n });\n\nprogram.addCommand(issueCommand);\n\n// -- Log commands --\n\ninterface LogShowOptions {\n limit: string;\n}\n\nconst logCommand = program.command(\"log\").description(\"Action log commands\");\n\nlogCommand\n .command(\"show\")\n .description(\"Show recent action log entries\")\n .option(\"--limit <n>\", \"number of entries to show\", \"50\")\n .action((opts: LogShowOptions) => {\n const limit = Number.parseInt(opts.limit, 10) || 50;\n const entries = getActionLog(limit);\n if (useJson()) {\n jsonOut({ ok: true, data: { entries, count: entries.length } });\n } else {\n if (entries.length === 0) {\n console.log(\"No action log entries.\");\n return;\n }\n for (const e of entries) {\n const prefix = e.status === \"success\" ? \"✓\" : e.status === \"error\" ? \"✗\" : \"…\";\n const ts = new Date(e.timestamp).toLocaleString();\n console.log(`${prefix} [${ts}] ${e.description}`);\n }\n }\n });\n\n// -- Run --\n\nprogram.parseAsync().catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`Error: ${message}`);\n process.exit(1);\n});\n","import { execFileSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { checkbox, confirm, input, select } from \"@inquirer/prompts\";\nimport type { CompletionAction, HogConfig, RepoConfig } from \"./config.js\";\nimport {\n CONFIG_DIR,\n findRepo,\n loadFullConfig,\n saveFullConfig,\n saveLlmAuth,\n validateRepoName,\n} from \"./config.js\";\n\n// ── gh CLI helpers ──\n\nfunction ghJson<T>(args: string[]): T {\n const output = execFileSync(\"gh\", args, { encoding: \"utf-8\", timeout: 30_000 }).trim();\n return JSON.parse(output) as T;\n}\n\nfunction isGhAuthenticated(): boolean {\n try {\n execFileSync(\"gh\", [\"auth\", \"status\"], { encoding: \"utf-8\", timeout: 10_000 });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction getGitHubLogin(): string {\n const user = ghJson<{ login: string }>([\"api\", \"user\"]);\n return user.login;\n}\n\ninterface GhRepo {\n nameWithOwner: string;\n name: string;\n owner: { login: string };\n}\n\nfunction listUserOrgs(): string[] {\n try {\n const orgs = ghJson<{ login: string }[]>([\"api\", \"user/orgs\"]);\n return orgs.map((o) => o.login);\n } catch {\n return [];\n }\n}\n\nfunction listReposForOwner(owner?: string): GhRepo[] {\n const args = [\n \"repo\",\n \"list\",\n ...(owner ? [owner] : []),\n \"--json\",\n \"nameWithOwner,name,owner\",\n \"--limit\",\n \"100\",\n ];\n try {\n return ghJson<GhRepo[]>(args);\n } catch {\n return [];\n }\n}\n\nfunction listAllRepos(): GhRepo[] {\n const orgs = listUserOrgs();\n const personal = listReposForOwner();\n const orgRepos = orgs.flatMap((org) => listReposForOwner(org));\n const all = [...personal, ...orgRepos];\n // Deduplicate by nameWithOwner\n const seen = new Set<string>();\n return all.filter((r) => {\n if (seen.has(r.nameWithOwner)) return false;\n seen.add(r.nameWithOwner);\n return true;\n });\n}\n\ninterface GhProject {\n number: number;\n title: string;\n}\n\nfunction listOrgProjects(owner: string): GhProject[] {\n try {\n const result = ghJson<{ projects: GhProject[] }>([\n \"project\",\n \"list\",\n \"--owner\",\n owner,\n \"--format\",\n \"json\",\n ]);\n return result.projects ?? [];\n } catch {\n return [];\n }\n}\n\ninterface GhProjectFieldOption {\n id: string;\n name: string;\n}\n\ninterface GhProjectField {\n id: string;\n name: string;\n type: string;\n options?: GhProjectFieldOption[];\n}\n\nfunction listProjectFields(owner: string, projectNumber: number): GhProjectField[] {\n try {\n const result = ghJson<{ fields: GhProjectField[] }>([\n \"project\",\n \"field-list\",\n String(projectNumber),\n \"--owner\",\n owner,\n \"--format\",\n \"json\",\n ]);\n return result.fields ?? [];\n } catch {\n return [];\n }\n}\n\ninterface StatusFieldInfo {\n fieldId: string;\n options: GhProjectFieldOption[];\n}\n\nfunction detectStatusField(owner: string, projectNumber: number): StatusFieldInfo | null {\n const fields = listProjectFields(owner, projectNumber);\n const statusField = fields.find(\n (f) => f.name === \"Status\" && f.type === \"ProjectV2SingleSelectField\",\n );\n if (!statusField) return null;\n return { fieldId: statusField.id, options: statusField.options ?? [] };\n}\n\nconst DATE_FIELD_NAME_RE = /^(target\\s*date|due\\s*date|due|deadline)$/i;\n\nfunction detectDateField(owner: string, projectNumber: number): GhProjectField | null {\n const fields = listProjectFields(owner, projectNumber);\n return fields.find((f) => DATE_FIELD_NAME_RE.test(f.name)) ?? null;\n}\n\nfunction createDateField(owner: string, projectNumber: number, fieldName: string): string | null {\n try {\n // Create the field and then list fields to get the ID\n execFileSync(\n \"gh\",\n [\n \"project\",\n \"field-create\",\n String(projectNumber),\n \"--owner\",\n owner,\n \"--name\",\n fieldName,\n \"--data-type\",\n \"DATE\",\n ],\n { encoding: \"utf-8\", timeout: 30_000 },\n );\n // Re-list to find the newly created field\n const fields = listProjectFields(owner, projectNumber);\n return fields.find((f) => f.name === fieldName)?.id ?? null;\n } catch {\n return null;\n }\n}\n\n// ── Wizard ──\n\nexport interface InitOptions {\n force?: boolean;\n}\n\nexport async function runInit(opts: InitOptions = {}): Promise<void> {\n // Ctrl+C handling: inquirer throws on cancel, we catch at the top level\n try {\n await runWizard(opts);\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"User force closed\")) {\n console.log(\"\\nSetup cancelled. No changes were made.\");\n return;\n }\n throw error;\n }\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: interactive setup wizard with many steps\nasync function runWizard(opts: InitOptions): Promise<void> {\n console.log(\"\\n🐗 hog init — Setup Wizard\\n\");\n\n // Step 1: Check existing config\n const configExists = existsSync(`${CONFIG_DIR}/config.json`);\n if (configExists && !opts.force) {\n const overwrite = await confirm({\n message: \"Config already exists. Overwrite?\",\n default: false,\n });\n if (!overwrite) {\n console.log(\"Setup cancelled.\");\n return;\n }\n }\n\n // Step 2: Check gh CLI auth\n console.log(\"Checking GitHub CLI authentication...\");\n if (!isGhAuthenticated()) {\n console.error(\n \"\\nGitHub CLI is not authenticated. Run:\\n\\n gh auth login\\n\\nThen re-run `hog init`.\",\n );\n process.exit(1);\n }\n console.log(\" GitHub CLI authenticated.\\n\");\n\n // Step 3: Detect GitHub user\n const login = getGitHubLogin();\n console.log(` Detected GitHub user: ${login}\\n`);\n\n // Step 4: Select repos (personal + org repos)\n console.log(\"Fetching repositories...\");\n const allRepos = listAllRepos();\n if (allRepos.length === 0) {\n console.error(\"No repositories found. Check your GitHub CLI access.\");\n process.exit(1);\n }\n\n const selectedRepoNames = await checkbox<string>({\n message: \"Select repositories to track:\",\n choices: allRepos.map((r) => ({\n name: r.nameWithOwner,\n value: r.nameWithOwner,\n })),\n });\n\n if (selectedRepoNames.length === 0) {\n console.log(\"No repos selected. You can add repos later with `hog config repos:add`.\");\n }\n\n // Step 5: Configure each repo (project, status field, completion action)\n const repos: RepoConfig[] = [];\n for (const repoName of selectedRepoNames) {\n console.log(`\\nConfiguring ${repoName}...`);\n const [owner, name] = repoName.split(\"/\") as [string, string];\n\n // Detect projects\n const projects = listOrgProjects(owner);\n let projectNumber: number;\n if (projects.length === 0) {\n console.log(\" No GitHub Projects found. Enter project number manually.\");\n const num = await input({ message: ` Project number for ${repoName}:` });\n projectNumber = Number.parseInt(num, 10);\n } else {\n projectNumber = await select<number>({\n message: ` Select project for ${repoName}:`,\n choices: projects.map((p) => ({\n name: `#${p.number} — ${p.title}`,\n value: p.number,\n })),\n });\n }\n\n // Auto-detect status field\n console.log(\" Detecting status field...\");\n const statusInfo = detectStatusField(owner, projectNumber);\n let statusFieldId: string;\n if (statusInfo) {\n statusFieldId = statusInfo.fieldId;\n console.log(` Found status field: ${statusFieldId}`);\n } else {\n console.log(\" Could not auto-detect status field.\");\n statusFieldId = await input({\n message: \" Enter status field ID manually:\",\n });\n }\n\n // Detect due date field\n console.log(\" Detecting due date field...\");\n let dueDateFieldId: string | undefined;\n const existingDateField = detectDateField(owner, projectNumber);\n if (existingDateField) {\n console.log(` Found date field: \"${existingDateField.name}\" (${existingDateField.id})`);\n const useDateField = await confirm({\n message: ` Use \"${existingDateField.name}\" for due dates?`,\n default: true,\n });\n if (useDateField) {\n dueDateFieldId = existingDateField.id;\n }\n } else {\n console.log(\" No due date field found in this project.\");\n const createField = await confirm({\n message: ' Create a \"Due Date\" field for due dates?',\n default: false,\n });\n if (createField) {\n console.log(' Creating \"Due Date\" field...');\n const newFieldId = createDateField(owner, projectNumber, \"Due Date\");\n if (newFieldId) {\n dueDateFieldId = newFieldId;\n console.log(` Created \"Due Date\" field (${newFieldId})`);\n } else {\n console.log(\" Could not create field — due dates will be stored in issue body.\");\n }\n } else {\n console.log(\" Skipped — due dates will be stored in issue body.\");\n }\n }\n\n // Completion action\n const completionType = await select<CompletionAction[\"type\"]>({\n message: ` When a task is completed, what should happen on GitHub?`,\n choices: [\n { name: \"Close the issue\", value: \"closeIssue\" as const },\n { name: \"Add a label (e.g. review:pending)\", value: \"addLabel\" as const },\n { name: \"Update project status column\", value: \"updateProjectStatus\" as const },\n ],\n });\n\n let completionAction: CompletionAction;\n if (completionType === \"addLabel\") {\n const label = await input({\n message: \" Label to add:\",\n default: \"review:pending\",\n });\n completionAction = { type: \"addLabel\", label };\n } else if (completionType === \"updateProjectStatus\") {\n const statusOptions = statusInfo?.options ?? [];\n let optionId: string;\n if (statusOptions.length > 0) {\n optionId = await select<string>({\n message: \" Status to set when completed:\",\n choices: statusOptions.map((o) => ({\n name: o.name,\n value: o.id,\n })),\n });\n } else {\n optionId = await input({\n message: \" Status option ID to set:\",\n });\n }\n completionAction = { type: \"updateProjectStatus\", optionId };\n } else {\n completionAction = { type: \"closeIssue\" };\n }\n\n // Short name\n const shortName = await input({\n message: ` Short name for ${repoName}:`,\n default: name,\n });\n\n repos.push({\n name: repoName,\n shortName,\n projectNumber,\n statusFieldId,\n ...(dueDateFieldId ? { dueDateFieldId } : {}),\n completionAction,\n });\n }\n\n // Step 6: TickTick integration (disabled by default, enable with `hog config ticktick:enable`)\n const ticktickAlreadyEnabled = existsSync(`${CONFIG_DIR}/auth.json`);\n let ticktickAuth = false;\n if (ticktickAlreadyEnabled) {\n ticktickAuth = true;\n console.log(\"TickTick auth found — integration enabled.\");\n }\n\n // Step 7: Board defaults\n console.log(\"\\nBoard settings:\");\n const refreshInterval = await input({\n message: \" Refresh interval (seconds):\",\n default: \"60\",\n });\n const backlogLimit = await input({\n message: \" Backlog limit (max issues per repo):\",\n default: \"20\",\n });\n const focusDuration = await input({\n message: \" Focus timer duration (seconds):\",\n default: \"1500\",\n });\n\n // Step 8: AI / LLM key (optional)\n console.log(\"\\nAI-enhanced issue creation (optional):\");\n console.log(\n ' Press I on the board to create issues with natural language (e.g. \"fix login bug #backend @alice due friday\").',\n );\n console.log(\" Without a key the heuristic parser still works — labels, assignee, and due dates\");\n console.log(\" are extracted from #, @, and due tokens. An OpenRouter key enables richer title\");\n console.log(\" cleanup and inference for ambiguous input.\");\n const setupLlm = await confirm({\n message: \" Set up an OpenRouter API key now?\",\n default: false,\n });\n if (setupLlm) {\n console.log(\" Get a free key at https://openrouter.ai/keys\");\n const llmKey = await input({\n message: \" OpenRouter API key:\",\n validate: (v) => (v.trim().startsWith(\"sk-or-\") ? true : 'Key must start with \"sk-or-\"'),\n });\n saveLlmAuth(llmKey.trim());\n console.log(\" OpenRouter key saved to ~/.config/hog/auth.json\");\n } else {\n console.log(\" Skipped. You can add it later: hog config ai:set-key\");\n }\n\n // Step 9: Build and write config\n const existingConfig = configExists ? loadFullConfig() : undefined;\n const config: HogConfig = {\n version: 3,\n defaultProjectId: existingConfig?.defaultProjectId,\n defaultProjectName: existingConfig?.defaultProjectName,\n repos,\n board: {\n refreshInterval: Number.parseInt(refreshInterval, 10) || 60,\n backlogLimit: Number.parseInt(backlogLimit, 10) || 20,\n assignee: login,\n focusDuration: Number.parseInt(focusDuration, 10) || 1500,\n },\n ticktick: { enabled: ticktickAuth },\n profiles: existingConfig?.profiles ?? {},\n };\n\n saveFullConfig(config);\n console.log(`\\nConfig written to ${CONFIG_DIR}/config.json`);\n console.log(\"\\nSetup complete! Try:\\n\");\n console.log(\" hog board --live # Interactive dashboard\");\n console.log(\" hog task list # List TickTick tasks\");\n console.log(\" hog config show # View configuration\\n\");\n}\n\n// ── repos:add wizard ──\n\nexport async function runReposAdd(initialRepoName?: string): Promise<void> {\n try {\n await runReposAddWizard(initialRepoName);\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"User force closed\")) {\n console.log(\"\\nCancelled. No changes were made.\");\n return;\n }\n throw error;\n }\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: interactive add-repo wizard with many steps\nasync function runReposAddWizard(initialRepoName?: string): Promise<void> {\n console.log(\"\\n🐗 hog config repos:add\\n\");\n\n const cfg = loadFullConfig();\n let repoName = initialRepoName;\n\n if (!repoName) {\n console.log(\"Fetching repositories...\");\n const allRepos = listAllRepos();\n const configuredNames = new Set(cfg.repos.map((r) => r.name));\n const available = allRepos.filter((r) => !configuredNames.has(r.nameWithOwner));\n\n if (available.length === 0) {\n console.log(\n \"No more repositories available to add. All accessible repos are already tracked.\",\n );\n return;\n }\n\n repoName = await select<string>({\n message: \"Select repository to add:\",\n choices: available.map((r) => ({ name: r.nameWithOwner, value: r.nameWithOwner })),\n });\n }\n\n if (!validateRepoName(repoName)) {\n console.error(\"Invalid repo name. Use owner/repo format (e.g. myorg/myrepo).\");\n process.exit(1);\n }\n\n if (findRepo(cfg, repoName)) {\n console.error(`Repo \"${repoName}\" is already configured.`);\n process.exit(1);\n }\n\n const [owner, name] = repoName.split(\"/\") as [string, string];\n console.log(`\\nConfiguring ${repoName}...`);\n\n // Detect projects\n console.log(\" Fetching GitHub Projects...\");\n const projects = listOrgProjects(owner);\n let projectNumber: number;\n if (projects.length === 0) {\n console.log(\" No GitHub Projects found. Enter project number manually.\");\n const num = await input({ message: ` Project number for ${repoName}:` });\n projectNumber = Number.parseInt(num, 10);\n } else {\n projectNumber = await select<number>({\n message: ` Select project for ${repoName}:`,\n choices: projects.map((p) => ({ name: `#${p.number} — ${p.title}`, value: p.number })),\n });\n }\n\n // Auto-detect status field\n console.log(\" Detecting status field...\");\n const statusInfo = detectStatusField(owner, projectNumber);\n let statusFieldId: string;\n if (statusInfo) {\n statusFieldId = statusInfo.fieldId;\n console.log(` Found status field: ${statusFieldId}`);\n } else {\n console.log(\" Could not auto-detect status field.\");\n statusFieldId = await input({ message: \" Enter status field ID manually:\" });\n }\n\n // Detect due date field\n console.log(\" Detecting due date field...\");\n let dueDateFieldId: string | undefined;\n const existingDateField = detectDateField(owner, projectNumber);\n if (existingDateField) {\n console.log(` Found date field: \"${existingDateField.name}\" (${existingDateField.id})`);\n const useDateField = await confirm({\n message: ` Use \"${existingDateField.name}\" for due dates?`,\n default: true,\n });\n if (useDateField) {\n dueDateFieldId = existingDateField.id;\n }\n } else {\n console.log(\" No due date field found.\");\n const createField = await confirm({\n message: ' Create a \"Due Date\" field for this project?',\n default: false,\n });\n if (createField) {\n console.log(' Creating \"Due Date\" field...');\n const newFieldId = createDateField(owner, projectNumber, \"Due Date\");\n if (newFieldId) {\n dueDateFieldId = newFieldId;\n console.log(` Created \"Due Date\" field (${newFieldId})`);\n } else {\n console.log(\" Could not create field — due dates will be stored in issue body.\");\n }\n }\n }\n\n // Completion action\n const completionType = await select<CompletionAction[\"type\"]>({\n message: \" When a task is completed, what should happen on GitHub?\",\n choices: [\n { name: \"Close the issue\", value: \"closeIssue\" as const },\n { name: \"Add a label (e.g. review:pending)\", value: \"addLabel\" as const },\n { name: \"Update project status column\", value: \"updateProjectStatus\" as const },\n ],\n });\n\n let completionAction: CompletionAction;\n if (completionType === \"addLabel\") {\n const label = await input({ message: \" Label to add:\", default: \"review:pending\" });\n completionAction = { type: \"addLabel\", label };\n } else if (completionType === \"updateProjectStatus\") {\n const statusOptions = statusInfo?.options ?? [];\n let optionId: string;\n if (statusOptions.length > 0) {\n optionId = await select<string>({\n message: \" Status to set when completed:\",\n choices: statusOptions.map((o) => ({ name: o.name, value: o.id })),\n });\n } else {\n optionId = await input({ message: \" Status option ID to set:\" });\n }\n completionAction = { type: \"updateProjectStatus\", optionId };\n } else {\n completionAction = { type: \"closeIssue\" };\n }\n\n // Short name\n const shortName = await input({\n message: ` Short name for ${repoName}:`,\n default: name,\n });\n\n const newRepo: RepoConfig = {\n name: repoName,\n shortName,\n projectNumber,\n statusFieldId,\n ...(dueDateFieldId ? { dueDateFieldId } : {}),\n completionAction,\n };\n\n cfg.repos.push(newRepo);\n saveFullConfig(cfg);\n\n console.log(`\\n Added ${shortName} → ${repoName}`);\n console.log(\" Run: hog board --live\\n\");\n}\n","import type { SyncResult } from \"./sync.js\";\nimport type { SyncState } from \"./sync-state.js\";\nimport type { Project, Task } from \"./types.js\";\nimport { Priority } from \"./types.js\";\n\nconst isTTY = process.stdout.isTTY ?? false;\n\nlet forceFormat: \"json\" | \"human\" | null = null;\n\nexport function setFormat(format: \"json\" | \"human\"): void {\n forceFormat = format;\n}\n\nexport function useJson(): boolean {\n if (forceFormat === \"json\") return true;\n if (forceFormat === \"human\") return false;\n return !isTTY;\n}\n\nexport function jsonOut(data: unknown): void {\n console.log(JSON.stringify(data));\n}\n\nconst PRIORITY_LABELS: Record<number, string> = {\n [Priority.None]: \"\",\n [Priority.Low]: \"[low]\",\n [Priority.Medium]: \"[med]\",\n [Priority.High]: \"[HIGH]\",\n};\n\nfunction formatDate(dateStr: string): string {\n if (!dateStr) return \"\";\n const d = new Date(dateStr);\n const now = new Date();\n const days = Math.ceil((d.getTime() - now.getTime()) / 86_400_000);\n\n if (days < 0) return `${Math.abs(days)}d ago`;\n if (days === 0) return \"today\";\n if (days === 1) return \"tomorrow\";\n if (days <= 7) return `in ${days}d`;\n return d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" });\n}\n\nfunction taskLine(t: Task): string {\n const parts: string[] = [];\n const pri = PRIORITY_LABELS[t.priority] ?? \"\";\n if (pri) parts.push(pri);\n parts.push(t.title);\n if (t.dueDate) parts.push(` ${formatDate(t.dueDate)}`);\n if (t.tags.length > 0) parts.push(` #${t.tags.join(\" #\")}`);\n return ` ${t.id} ${parts.join(\" \")}`;\n}\n\nexport function printTasks(tasks: Task[]): void {\n if (useJson()) {\n jsonOut(tasks);\n return;\n }\n if (tasks.length === 0) {\n console.log(\" No tasks.\");\n return;\n }\n for (const t of tasks) {\n console.log(taskLine(t));\n }\n}\n\nexport function printTask(task: Task): void {\n if (useJson()) {\n jsonOut(task);\n return;\n }\n console.log(` ID: ${task.id}`);\n console.log(` Title: ${task.title}`);\n if (task.content) console.log(` Content: ${task.content}`);\n console.log(` Priority: ${PRIORITY_LABELS[task.priority] ?? \"none\"}`);\n if (task.dueDate) console.log(` Due: ${formatDate(task.dueDate)}`);\n if (task.startDate) console.log(` Start: ${formatDate(task.startDate)}`);\n if (task.tags.length > 0) console.log(` Tags: ${task.tags.join(\", \")}`);\n console.log(` Project: ${task.projectId}`);\n console.log(` Status: ${task.status === 2 ? \"completed\" : \"active\"}`);\n}\n\nexport function printProjects(projects: Project[]): void {\n if (useJson()) {\n jsonOut(projects);\n return;\n }\n if (projects.length === 0) {\n console.log(\" No projects.\");\n return;\n }\n for (const p of projects) {\n const closed = p.closed ? \" (closed)\" : \"\";\n console.log(` ${p.id} ${p.name}${closed}`);\n }\n}\n\nexport function printSuccess(message: string, data?: Record<string, unknown> | object): void {\n if (useJson()) {\n jsonOut({ ok: true, message, ...data });\n return;\n }\n console.log(message);\n}\n\nfunction printSection(prefix: string, label: string, icon: string, items: string[]): void {\n if (items.length === 0) return;\n console.log(`${prefix}${label} ${items.length} task(s):`);\n for (const key of items) console.log(` ${icon} ${key}`);\n}\n\nexport function printSyncResult(result: SyncResult, dryRun: boolean): void {\n if (useJson()) {\n jsonOut({ ok: true, dryRun, ...result });\n return;\n }\n const prefix = dryRun ? \"[dry-run] \" : \"\";\n printSection(prefix, \"Created\", \"+\", result.created);\n printSection(prefix, \"Updated\", \"~\", result.updated);\n printSection(prefix, \"Completed\", \"✓\", result.completed);\n printSection(prefix, \"GitHub updated\", \"→\", result.ghUpdated);\n printSection(\"\", \"Errors\", \"✗\", result.errors);\n const total =\n result.created.length +\n result.updated.length +\n result.completed.length +\n result.ghUpdated.length;\n if (total === 0 && result.errors.length === 0) {\n console.log(`${prefix}Everything in sync.`);\n }\n}\n\nexport function printSyncStatus(state: SyncState, repos: string[]): void {\n if (useJson()) {\n jsonOut({ repos, lastSyncAt: state.lastSyncAt ?? null, mappings: state.mappings });\n return;\n }\n console.log(` Repos: ${repos.join(\", \")}`);\n console.log(` Last sync: ${state.lastSyncAt ?? \"never\"}`);\n console.log(` Active mappings: ${state.mappings.length}`);\n if (state.mappings.length > 0) {\n for (const m of state.mappings) {\n console.log(` ${m.githubRepo}#${m.githubIssueNumber} → ${m.ticktickTaskId}`);\n }\n }\n}\n","import { TickTickClient } from \"./api.js\";\nimport { formatError } from \"./board/constants.js\";\nimport type { HogConfig, RepoConfig } from \"./config.js\";\nimport { loadFullConfig, requireAuth } from \"./config.js\";\nimport type { GitHubIssue, ProjectEnrichment } from \"./github.js\";\nimport {\n addLabel,\n fetchAssignedIssues,\n fetchProjectEnrichment,\n updateProjectItemStatus,\n} from \"./github.js\";\nimport type { SyncMapping, SyncState } from \"./sync-state.js\";\nimport {\n findMapping,\n loadSyncState,\n removeMapping,\n saveSyncState,\n upsertMapping,\n} from \"./sync-state.js\";\nimport type { CreateTaskInput, UpdateTaskInput } from \"./types.js\";\nimport { Priority, TaskStatus } from \"./types.js\";\n\nexport interface SyncResult {\n created: string[];\n updated: string[];\n completed: string[];\n ghUpdated: string[];\n errors: string[];\n}\n\ninterface SyncOptions {\n dryRun?: boolean;\n}\n\nfunction emptySyncResult(): SyncResult {\n return { created: [], updated: [], completed: [], ghUpdated: [], errors: [] };\n}\n\nfunction repoShortName(repo: string): string {\n return repo.split(\"/\")[1] ?? repo;\n}\n\nfunction issueTaskTitle(issue: GitHubIssue): string {\n return issue.title;\n}\n\nfunction issueTaskContent(\n issue: GitHubIssue,\n projectFields: { targetDate?: string; status?: string },\n): string {\n const lines = [`GitHub: ${issue.url}`];\n if (projectFields.status) lines.push(`Status: ${projectFields.status}`);\n return lines.join(\"\\n\");\n}\n\nfunction mapPriority(labels: { name: string }[]): Priority {\n for (const label of labels) {\n if (label.name === \"priority:critical\" || label.name === \"priority:high\") return Priority.High;\n if (label.name === \"priority:medium\") return Priority.Medium;\n if (label.name === \"priority:low\") return Priority.Low;\n }\n return Priority.None;\n}\n\nfunction buildCreateInput(\n repo: string,\n issue: GitHubIssue,\n projectFields: { targetDate?: string; status?: string },\n): CreateTaskInput {\n const input: CreateTaskInput = {\n title: issueTaskTitle(issue),\n content: issueTaskContent(issue, projectFields),\n priority: mapPriority(issue.labels),\n tags: [\"github\", repoShortName(repo)],\n };\n if (projectFields.targetDate) {\n input.dueDate = projectFields.targetDate;\n input.isAllDay = true;\n }\n return input;\n}\n\nfunction buildUpdateInput(\n repo: string,\n issue: GitHubIssue,\n projectFields: { targetDate?: string; status?: string },\n mapping: SyncMapping,\n): UpdateTaskInput {\n const input: UpdateTaskInput = {\n id: mapping.ticktickTaskId,\n projectId: mapping.ticktickProjectId,\n title: issueTaskTitle(issue),\n content: issueTaskContent(issue, projectFields),\n priority: mapPriority(issue.labels),\n tags: [\"github\", repoShortName(repo)],\n };\n if (projectFields.targetDate) {\n input.dueDate = projectFields.targetDate;\n }\n return input;\n}\n\n/** Phase 1: Sync GitHub issues to TickTick (create/update). Returns open issue keys and repos that failed to fetch. */\nasync function syncGitHubToTickTick(\n config: HogConfig,\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n): Promise<{ openIssueKeys: Set<string>; failedRepos: Set<string> }> {\n const openIssueKeys = new Set<string>();\n const failedRepos = new Set<string>();\n\n for (const repoConfig of config.repos) {\n let issues: GitHubIssue[];\n try {\n issues = fetchAssignedIssues(repoConfig.name, config.board.assignee);\n } catch (err) {\n result.errors.push(`Failed to fetch issues from ${repoConfig.name}: ${formatError(err)}`);\n failedRepos.add(repoConfig.name);\n continue;\n }\n\n let enrichMap: Map<number, ProjectEnrichment>;\n try {\n enrichMap = fetchProjectEnrichment(repoConfig.name, repoConfig.projectNumber);\n } catch {\n enrichMap = new Map();\n }\n\n for (const issue of issues) {\n const key = `${repoConfig.name}#${issue.number}`;\n openIssueKeys.add(key);\n await syncSingleIssue(state, api, result, dryRun, repoConfig, issue, key, enrichMap);\n }\n }\n\n return { openIssueKeys, failedRepos };\n}\n\nasync function syncSingleIssue(\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n repoConfig: RepoConfig,\n issue: GitHubIssue,\n key: string,\n enrichMap: Map<number, ProjectEnrichment>,\n): Promise<void> {\n try {\n const existing = findMapping(state, repoConfig.name, issue.number);\n\n if (existing && existing.githubUpdatedAt === issue.updatedAt) return;\n\n const enrichment = enrichMap.get(issue.number);\n const projectFields: { targetDate?: string; status?: string } = {\n ...(enrichment?.targetDate !== undefined && { targetDate: enrichment.targetDate }),\n ...(enrichment?.projectStatus !== undefined && { status: enrichment.projectStatus }),\n };\n\n if (!existing) {\n await createTickTickTask(\n state,\n api,\n result,\n dryRun,\n repoConfig.name,\n issue,\n projectFields,\n key,\n );\n } else {\n await updateTickTickTask(\n state,\n api,\n result,\n dryRun,\n repoConfig.name,\n issue,\n projectFields,\n existing,\n key,\n );\n }\n } catch (err) {\n result.errors.push(`${key}: ${formatError(err)}`);\n }\n}\n\nasync function createTickTickTask(\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n repo: string,\n issue: GitHubIssue,\n projectFields: { targetDate?: string; status?: string },\n key: string,\n): Promise<void> {\n if (dryRun) {\n result.created.push(key);\n return;\n }\n const input = buildCreateInput(repo, issue, projectFields);\n const task = await api.createTask(input);\n\n upsertMapping(state, {\n githubRepo: repo,\n githubIssueNumber: issue.number,\n githubUrl: issue.url,\n ticktickTaskId: task.id,\n ticktickProjectId: task.projectId,\n githubUpdatedAt: issue.updatedAt,\n lastSyncedAt: new Date().toISOString(),\n });\n result.created.push(key);\n}\n\nasync function updateTickTickTask(\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n repo: string,\n issue: GitHubIssue,\n projectFields: { targetDate?: string; status?: string },\n existing: SyncMapping,\n key: string,\n): Promise<void> {\n if (dryRun) {\n result.updated.push(key);\n return;\n }\n const input = buildUpdateInput(repo, issue, projectFields, existing);\n await api.updateTask(input);\n\n upsertMapping(state, {\n ...existing,\n githubUpdatedAt: issue.updatedAt,\n lastSyncedAt: new Date().toISOString(),\n });\n result.updated.push(key);\n}\n\n/** Phase 2: Complete TickTick tasks for issues no longer open on GitHub. */\nasync function syncClosedIssues(\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n openIssueKeys: Set<string>,\n failedRepos: Set<string>,\n): Promise<void> {\n for (const mapping of [...state.mappings]) {\n // SAFETY: Never complete tasks from repos we couldn't fetch — we don't know their real state\n if (failedRepos.has(mapping.githubRepo)) continue;\n\n const key = `${mapping.githubRepo}#${mapping.githubIssueNumber}`;\n if (openIssueKeys.has(key)) continue;\n\n try {\n if (dryRun) {\n result.completed.push(key);\n continue;\n }\n await api.completeTask(mapping.ticktickProjectId, mapping.ticktickTaskId);\n removeMapping(state, mapping.githubRepo, mapping.githubIssueNumber);\n result.completed.push(key);\n } catch (err) {\n result.errors.push(`Complete ${key}: ${formatError(err)}`);\n }\n }\n}\n\n/** Phase 3: Update GitHub when TickTick tasks are completed. */\nasync function syncCompletedTasksToGitHub(\n config: HogConfig,\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n): Promise<void> {\n for (const mapping of [...state.mappings]) {\n const key = `${mapping.githubRepo}#${mapping.githubIssueNumber}`;\n try {\n await processCompletedMapping(config, state, api, result, dryRun, mapping, key);\n } catch (err) {\n result.errors.push(`GH update ${key}: ${formatError(err)}`);\n }\n }\n}\n\nasync function processCompletedMapping(\n config: HogConfig,\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n mapping: SyncMapping,\n key: string,\n): Promise<void> {\n let task: Awaited<ReturnType<TickTickClient[\"getTask\"]>>;\n try {\n task = await api.getTask(mapping.ticktickProjectId, mapping.ticktickTaskId);\n } catch {\n return; // Task might have been deleted\n }\n\n if (task.status !== TaskStatus.Completed) return;\n\n if (dryRun) {\n result.ghUpdated.push(key);\n return;\n }\n\n const repo = mapping.githubRepo;\n const repoConfig = config.repos.find((r) => r.name === repo);\n\n if (repoConfig) {\n const action = repoConfig.completionAction;\n switch (action.type) {\n case \"addLabel\":\n addLabel(repo, mapping.githubIssueNumber, action.label);\n break;\n case \"updateProjectStatus\":\n updateProjectItemStatus(repo, mapping.githubIssueNumber, {\n projectNumber: repoConfig.projectNumber,\n statusFieldId: repoConfig.statusFieldId,\n optionId: action.optionId,\n });\n break;\n case \"closeIssue\":\n // Future: close the issue\n break;\n }\n }\n\n removeMapping(state, repo, mapping.githubIssueNumber);\n result.ghUpdated.push(key);\n}\n\nexport async function runSync(options: SyncOptions = {}): Promise<SyncResult> {\n const { dryRun = false } = options;\n const result = emptySyncResult();\n\n const config = loadFullConfig();\n const auth = requireAuth();\n const api = new TickTickClient(auth.accessToken);\n const state = loadSyncState();\n\n const { openIssueKeys, failedRepos } = await syncGitHubToTickTick(\n config,\n state,\n api,\n result,\n dryRun,\n );\n await syncClosedIssues(state, api, result, dryRun, openIssueKeys, failedRepos);\n await syncCompletedTasksToGitHub(config, state, api, result, dryRun);\n\n if (!dryRun) {\n state.lastSyncAt = new Date().toISOString();\n saveSyncState(state);\n }\n\n return result;\n}\n\nexport function getSyncStatus(): { state: SyncState; repos: string[] } {\n const config = loadFullConfig();\n return { state: loadSyncState(), repos: config.repos.map((r) => r.name) };\n}\n"],"mappings":"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","names":["config","input","text","input","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","join","execFileSync","DATE_FIELD_NAME_RE","existsSync","readFileSync","writeFileSync","homedir","join","CONFIG_DIR","input","config","repoShortName","mapPriority","task","useCallback","useRef","config","shortName","useCallback","useRef","useState","config","useCallback","input","useCallback","useRef","useState","useCallback","useRef","select","useCallback","useState","useCallback","useRef","useState","useCallback","useReducer","INITIAL_STATE","useEffect","useState","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","useEffect","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","useInput","useState","jsx","jsxs","input","readFileSync","writeFileSync","join","Box","Text","useInput","useEffect","useRef","useState","jsx","jsxs","inkInstance","Box","Text","useInput","jsx","jsxs","input","Box","Text","useInput","useEffect","useRef","useState","jsx","jsxs","input","allLabels","TextInput","Box","Text","useInput","useState","jsx","jsxs","input","spawnSync","mkdtempSync","readFileSync","rmSync","writeFileSync","tmpdir","join","Box","Text","useStdin","useEffect","useRef","useState","jsx","jsxs","inkInstance","Box","Text","useInput","useCallback","useEffect","useRef","useState","jsx","jsxs","input","TextInput","Box","Text","useInput","useMemo","useState","jsx","jsxs","input","Box","Text","useInput","jsx","jsxs","spawnSync","mkdtempSync","readFileSync","rmSync","writeFileSync","tmpdir","join","Spinner","TextInput","Box","Text","useInput","useStdin","useCallback","useEffect","useRef","useState","jsx","jsxs","inkInstance","TextInput","Box","Text","jsx","jsxs","Box","Text","useInput","useRef","useState","jsx","jsxs","input","Fragment","jsx","jsxs","config","Box","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","formatDate","days","Box","Text","jsx","jsxs","checkbox","Box","Text","jsx","jsxs","Spinner","Box","Text","Fragment","jsx","jsxs","execFileSync","spawnSync","Spinner","Box","Text","useCallback","useEffect","useMemo","useRef","useState","Fragment","jsx","jsxs","config","pickIssue","jsx","config","SLACK_URL_RE","execFileSync","shortName","config","truncate","task","printSection","execFile","execFileSync","promisify","existsSync","shortName","config","task","input","config","task","execFileAsync","promisify","execFile","config","parseIssueRef","input","runLiveDashboard","fetchDashboard","renderBoardJson","renderStaticBoard","pickIssue","shortName","execFileSync","fetchIssueAsync","fetchProjectStatusOptions","updateProjectItemStatusAsync","assignIssueToAsync","unassignIssueAsync","addCommentAsync","removeLabelAsync","addLabelAsync"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/ai.ts","../src/api.ts","../src/log-persistence.ts","../src/types.ts","../src/board/constants.ts","../src/github.ts","../src/sync-state.ts","../src/pick.ts","../src/clipboard.ts","../src/board/hooks/use-action-log.ts","../src/board/hooks/use-actions.ts","../src/board/hooks/use-data.ts","../src/board/hooks/use-keyboard.ts","../src/board/hooks/use-multi-select.ts","../src/board/hooks/use-navigation.ts","../src/board/hooks/use-panel-focus.ts","../src/board/hooks/use-toast.ts","../src/board/hooks/use-ui-state.ts","../src/board/launch-claude.ts","../src/board/components/action-log.tsx","../src/board/components/panel.tsx","../src/board/components/activity-panel.tsx","../src/board/components/detail-panel.tsx","../src/board/components/hint-bar.tsx","../src/board/components/bulk-action-menu.tsx","../src/board/ink-instance.ts","../src/board/components/comment-input.tsx","../src/board/components/confirm-prompt.tsx","../src/board/components/label-picker.tsx","../src/board/components/create-issue-form.tsx","../src/board/components/edit-issue-overlay.tsx","../src/board/components/focus-mode.tsx","../src/board/components/fuzzy-picker.tsx","../src/board/components/help-overlay.tsx","../src/board/components/nl-create-overlay.tsx","../src/board/components/search-bar.tsx","../src/board/components/status-picker.tsx","../src/board/components/overlay-renderer.tsx","../src/board/components/panel-layout.tsx","../src/board/components/repos-panel.tsx","../src/board/components/issue-row.tsx","../src/board/components/row-renderer.tsx","../src/board/components/statuses-panel.tsx","../src/board/components/toast-container.tsx","../src/board/components/dashboard.tsx","../src/board/live.tsx","../src/board/fetch.ts","../src/board/theme.ts","../src/board/format-static.ts","../src/cli.ts","../src/init.ts","../src/output.ts","../src/sync.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join, normalize } from \"node:path\";\nimport { z } from \"zod\";\n\nexport const CONFIG_DIR = join(homedir(), \".config\", \"hog\");\nconst AUTH_FILE = join(CONFIG_DIR, \"auth.json\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\n\ninterface AuthData {\n accessToken: string;\n clientId: string;\n clientSecret: string;\n openrouterApiKey?: string;\n}\n\n// ── Config Schema (Zod) ──\n\nconst COMPLETION_ACTION_SCHEMA = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"updateProjectStatus\"), optionId: z.string() }),\n z.object({ type: z.literal(\"closeIssue\") }),\n z.object({ type: z.literal(\"addLabel\"), label: z.string() }),\n]);\n\nconst REPO_NAME_PATTERN = /^[\\w.-]+\\/[\\w.-]+$/;\n\nconst CLAUDE_START_COMMAND_SCHEMA = z.object({\n command: z.string().min(1),\n extraArgs: z.array(z.string()),\n});\n\nconst REPO_CONFIG_SCHEMA = z.object({\n name: z.string().regex(REPO_NAME_PATTERN, \"Must be owner/repo format\"),\n shortName: z.string().min(1),\n projectNumber: z.number().int().positive(),\n statusFieldId: z.string().min(1),\n dueDateFieldId: z.string().optional(),\n completionAction: COMPLETION_ACTION_SCHEMA,\n statusGroups: z.array(z.string()).optional(),\n localPath: z\n .string()\n .refine((p) => isAbsolute(p), { message: \"localPath must be an absolute path\" })\n .refine((p) => normalize(p) === p, {\n message: \"localPath must be normalized (no .. segments)\",\n })\n .refine((p) => !p.includes(\"\\0\"), { message: \"localPath must not contain null bytes\" })\n .optional(),\n claudeStartCommand: CLAUDE_START_COMMAND_SCHEMA.optional(),\n});\n\nconst BOARD_CONFIG_SCHEMA = z.object({\n refreshInterval: z.number().int().min(10).default(60),\n backlogLimit: z.number().int().min(1).default(20),\n assignee: z.string().min(1),\n focusDuration: z.number().int().min(60).default(1500),\n claudeStartCommand: CLAUDE_START_COMMAND_SCHEMA.optional(),\n claudeLaunchMode: z.enum([\"auto\", \"tmux\", \"terminal\"]).optional(),\n claudeTerminalApp: z\n .enum([\"Terminal\", \"iTerm\", \"Ghostty\", \"WezTerm\", \"Kitty\", \"Alacritty\"])\n .optional(),\n});\n\nconst TICKTICK_CONFIG_SCHEMA = z.object({\n enabled: z.boolean().default(true),\n});\n\nconst PROFILE_SCHEMA = z.object({\n repos: z.array(REPO_CONFIG_SCHEMA).default([]),\n board: BOARD_CONFIG_SCHEMA,\n ticktick: TICKTICK_CONFIG_SCHEMA.default({ enabled: true }),\n});\n\nconst HOG_CONFIG_SCHEMA = z.object({\n version: z.number().int().default(3),\n defaultProjectId: z.string().optional(),\n defaultProjectName: z.string().optional(),\n repos: z.array(REPO_CONFIG_SCHEMA).default([]),\n board: BOARD_CONFIG_SCHEMA,\n ticktick: TICKTICK_CONFIG_SCHEMA.default({ enabled: true }),\n profiles: z.record(z.string(), PROFILE_SCHEMA).default({}),\n defaultProfile: z.string().optional(),\n});\n\nexport type CompletionAction = z.infer<typeof COMPLETION_ACTION_SCHEMA>;\nexport type RepoConfig = z.infer<typeof REPO_CONFIG_SCHEMA>;\nexport type BoardConfig = z.infer<typeof BOARD_CONFIG_SCHEMA>;\nexport type ProfileConfig = z.infer<typeof PROFILE_SCHEMA>;\nexport type HogConfig = z.infer<typeof HOG_CONFIG_SCHEMA>;\n\n// ── Config Migration ──\n\nfunction migrateConfig(raw: Record<string, unknown>): HogConfig {\n const version = typeof raw[\"version\"] === \"number\" ? raw[\"version\"] : 1;\n\n if (version < 2) {\n // v1 → v2: Add repos and board config from legacy defaults\n raw = {\n ...raw,\n version: 2,\n repos: [],\n board: {\n refreshInterval: 60,\n backlogLimit: 20,\n assignee: \"unknown\",\n },\n };\n }\n\n const currentVersion = typeof raw[\"version\"] === \"number\" ? raw[\"version\"] : 2;\n if (currentVersion < 3) {\n // v2 → v3: Add ticktick config, infer enabled from auth.json presence\n raw = {\n ...raw,\n version: 3,\n ticktick: { enabled: existsSync(AUTH_FILE) },\n };\n }\n\n return HOG_CONFIG_SCHEMA.parse(raw);\n}\n\n// ── Config Access ──\n\nexport function loadFullConfig(): HogConfig {\n const raw = loadRawConfig();\n\n if (Object.keys(raw).length === 0) {\n // No config exists — create from legacy defaults\n const config = migrateConfig({});\n saveFullConfig(config);\n return config;\n }\n\n const version = typeof raw[\"version\"] === \"number\" ? raw[\"version\"] : 1;\n if (version < 3) {\n const migrated = migrateConfig(raw);\n saveFullConfig(migrated);\n return migrated;\n }\n\n return HOG_CONFIG_SCHEMA.parse(raw);\n}\n\nexport function saveFullConfig(config: HogConfig): void {\n ensureDir();\n writeFileSync(CONFIG_FILE, `${JSON.stringify(config, null, 2)}\\n`, { mode: 0o600 });\n}\n\nfunction loadRawConfig(): Record<string, unknown> {\n if (!existsSync(CONFIG_FILE)) return {};\n try {\n return JSON.parse(readFileSync(CONFIG_FILE, \"utf-8\")) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\n/**\n * Resolve a profile from the config.\n * Priority: explicit profileName > config.defaultProfile > top-level config.\n * Returns a HogConfig with the resolved profile's repos/board/ticktick.\n */\nexport function resolveProfile(\n config: HogConfig,\n profileName?: string | undefined,\n): { resolved: HogConfig; activeProfile: string | null } {\n const name = profileName ?? config.defaultProfile;\n\n if (!name) {\n return { resolved: config, activeProfile: null };\n }\n\n const profile = config.profiles[name];\n if (!profile) {\n console.error(\n `Profile \"${name}\" not found. Available: ${Object.keys(config.profiles).join(\", \") || \"(none)\"}`,\n );\n process.exit(1);\n }\n\n return {\n resolved: { ...config, repos: profile.repos, board: profile.board, ticktick: profile.ticktick },\n activeProfile: name,\n };\n}\n\nexport function findRepo(config: HogConfig, shortNameOrFull: string): RepoConfig | undefined {\n return config.repos.find((r) => r.shortName === shortNameOrFull || r.name === shortNameOrFull);\n}\n\nexport function validateRepoName(name: string): boolean {\n return REPO_NAME_PATTERN.test(name);\n}\n\n// ── Legacy Config Access (backward compat) ──\n\ninterface ConfigData {\n defaultProjectId?: string;\n defaultProjectName?: string;\n}\n\nfunction ensureDir(): void {\n mkdirSync(CONFIG_DIR, { recursive: true });\n}\n\nexport function getAuth(): AuthData | null {\n if (!existsSync(AUTH_FILE)) return null;\n try {\n return JSON.parse(readFileSync(AUTH_FILE, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\nexport function saveAuth(data: AuthData): void {\n ensureDir();\n writeFileSync(AUTH_FILE, `${JSON.stringify(data, null, 2)}\\n`, {\n mode: 0o600,\n });\n}\n\nexport function getLlmAuth(): { provider: \"openrouter\"; apiKey: string } | null {\n const auth = getAuth();\n if (auth?.openrouterApiKey) return { provider: \"openrouter\", apiKey: auth.openrouterApiKey };\n return null;\n}\n\nexport function saveLlmAuth(openrouterApiKey: string): void {\n const existing = getAuth();\n const updated: AuthData = existing\n ? { ...existing, openrouterApiKey }\n : { accessToken: \"\", clientId: \"\", clientSecret: \"\", openrouterApiKey };\n saveAuth(updated);\n}\n\nexport function clearLlmAuth(): void {\n const existing = getAuth();\n if (!existing) return;\n const { openrouterApiKey: _, ...rest } = existing;\n saveAuth(rest as AuthData);\n}\n\nexport function getConfig(): ConfigData {\n if (!existsSync(CONFIG_FILE)) return {};\n try {\n return JSON.parse(readFileSync(CONFIG_FILE, \"utf-8\"));\n } catch {\n return {};\n }\n}\n\nexport function saveConfig(data: ConfigData): void {\n ensureDir();\n const existing = getConfig();\n writeFileSync(CONFIG_FILE, `${JSON.stringify({ ...existing, ...data }, null, 2)}\\n`, {\n mode: 0o600,\n });\n}\n\nexport function requireAuth(): AuthData {\n const auth = getAuth();\n if (!auth) {\n console.error(\"Not authenticated. Run `hog init` first.\");\n process.exit(1);\n }\n return auth;\n}\n","/**\n * Natural language issue field extraction.\n *\n * Two-layer approach:\n * 1. Heuristic parser — always runs, no API key needed.\n * 2. Optional LLM layer — used when OPENROUTER_API_KEY or ANTHROPIC_API_KEY is set.\n * If both keys are set, OpenRouter is preferred.\n *\n * The merge strategy: heuristic wins on explicitly-marked tokens (#, @, due);\n * LLM wins only on ambiguous title cleanup.\n * 3. Stored key fallback — when no env var is set, reads openrouterApiKey from auth.json\n * (stored via `hog init` or `hog config ai:set-key`).\n */\n\nimport { getLlmAuth } from \"./config.js\";\n\nexport interface ParsedIssue {\n title: string;\n labels: string[];\n assignee: string | null;\n dueDate: string | null; // YYYY-MM-DD\n}\n\n// ── Heuristic Parser ──\n\n/**\n * Parse a natural-language issue string with simple token extraction.\n *\n * Token rules:\n * - `#word` → label (lowercased)\n * - `@me`/`@user` → assignee\n * - `due <expr>` → due date (chrono-node, forwardDate, dynamically imported)\n * - everything else → title\n *\n * Returns null if the title after stripping tokens is empty.\n */\nexport async function parseHeuristic(\n input: string,\n today: Date = new Date(),\n): Promise<ParsedIssue | null> {\n let remaining = input;\n\n // Extract #labels\n const labelMatches = [...remaining.matchAll(/#([\\w:/-]+)/g)];\n const rawLabels = labelMatches.map((m) => (m[1] ?? \"\").toLowerCase());\n remaining = remaining.replace(/#[\\w:/-]+/g, \"\").trim();\n\n // Extract @assignee (last one wins)\n const assigneeMatches = [...remaining.matchAll(/@([\\w-]+)/g)];\n const assignee =\n assigneeMatches.length > 0 ? (assigneeMatches[assigneeMatches.length - 1]?.[1] ?? null) : null;\n remaining = remaining.replace(/@[\\w-]+/g, \"\").trim();\n\n // Extract \"due <expression>\"\n let dueDate: string | null = null;\n const dueMatch = remaining.match(/\\bdue\\s+(.+?)(?:\\s+#|\\s+@|$)/i);\n if (dueMatch?.[1]) {\n const { parse } = await import(\"chrono-node\");\n const results = parse(dueMatch[1], { instant: today }, { forwardDate: true });\n const first = results[0];\n if (first) {\n let date = first.date();\n // chrono-node bug #240: forwardDate may not advance year for e.g. \"Jan 15\"\n // when today is Jan 16 — post-check and add a year if the parsed date is in the past\n if (date < today) {\n date = new Date(date);\n date.setFullYear(date.getFullYear() + 1);\n }\n const yyyy = date.getFullYear();\n const mm = String(date.getMonth() + 1).padStart(2, \"0\");\n const dd = String(date.getDate()).padStart(2, \"0\");\n dueDate = `${yyyy}-${mm}-${dd}`;\n }\n remaining = remaining.slice(0, dueMatch.index ?? 0).trim();\n }\n\n // What's left is the title\n const title = remaining.replace(/\\s+/g, \" \").trim();\n if (!title) return null;\n\n return { title, labels: rawLabels, assignee, dueDate };\n}\n\n// ── LLM Parser ──\n\ninterface LLMResult {\n title: string;\n labels: string[];\n due_date: string | null;\n assignee: string | null;\n}\n\nfunction detectProvider(): { provider: \"openrouter\" | \"anthropic\"; apiKey: string } | null {\n const orKey = process.env[\"OPENROUTER_API_KEY\"];\n if (orKey) return { provider: \"openrouter\", apiKey: orKey };\n const antKey = process.env[\"ANTHROPIC_API_KEY\"];\n if (antKey) return { provider: \"anthropic\", apiKey: antKey };\n // Fall back to key stored via `hog init` / `hog config ai:set-key`\n return getLlmAuth();\n}\n\nasync function callLLM(\n userText: string,\n validLabels: string[],\n today: Date,\n providerConfig: { provider: \"openrouter\" | \"anthropic\"; apiKey: string },\n): Promise<LLMResult | null> {\n const { provider, apiKey } = providerConfig;\n const todayStr = today.toISOString().slice(0, 10);\n const systemPrompt = `Extract GitHub issue fields. Today is ${todayStr}. Return JSON with: title (string), labels (string[]), due_date (YYYY-MM-DD or null), assignee (string or null).`;\n const escapedText = userText.replace(/<\\/input>/gi, \"< /input>\");\n const userContent = `<input>${escapedText}</input>\\n<valid_labels>${validLabels.join(\",\")}</valid_labels>`;\n\n const jsonSchema = {\n name: \"issue\",\n schema: {\n type: \"object\",\n properties: {\n title: { type: \"string\" },\n labels: { type: \"array\", items: { type: \"string\" } },\n due_date: { type: [\"string\", \"null\"] },\n assignee: { type: [\"string\", \"null\"] },\n },\n required: [\"title\", \"labels\", \"due_date\", \"assignee\"],\n additionalProperties: false,\n },\n };\n\n try {\n let response: Response;\n\n if (provider === \"openrouter\") {\n response = await fetch(\"https://openrouter.ai/api/v1/chat/completions\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n model: \"google/gemini-2.5-flash\",\n messages: [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: userContent },\n ],\n response_format: { type: \"json_schema\", json_schema: jsonSchema },\n max_tokens: 256,\n temperature: 0,\n }),\n signal: AbortSignal.timeout(5_000),\n });\n } else {\n // Anthropic direct\n response = await fetch(\"https://api.anthropic.com/v1/messages\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify({\n model: \"claude-haiku-4-5-20251001\",\n system: systemPrompt,\n messages: [{ role: \"user\", content: userContent }],\n max_tokens: 256,\n }),\n signal: AbortSignal.timeout(5_000),\n });\n }\n\n if (!response.ok) return null;\n\n const json = (await response.json()) as Record<string, unknown>;\n\n let raw: unknown;\n if (provider === \"openrouter\") {\n const choicesRaw = json[\"choices\"];\n if (!Array.isArray(choicesRaw)) return null;\n const firstChoice = choicesRaw[0] as { message?: { content?: string } } | undefined;\n const content = firstChoice?.message?.content;\n if (!content) return null;\n raw = JSON.parse(content);\n } else {\n // Anthropic: content[0].text\n const contentRaw = json[\"content\"];\n if (!Array.isArray(contentRaw)) return null;\n const firstItem = contentRaw[0] as { type: string; text?: string } | undefined;\n const text = firstItem?.text;\n if (!text) return null;\n raw = JSON.parse(text);\n }\n\n if (!raw || typeof raw !== \"object\") return null;\n const r = raw as Record<string, unknown>;\n\n const ISO_DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n return {\n title: typeof r[\"title\"] === \"string\" ? r[\"title\"] : \"\",\n labels: Array.isArray(r[\"labels\"])\n ? (r[\"labels\"] as unknown[]).filter((l): l is string => typeof l === \"string\")\n : [],\n due_date:\n typeof r[\"due_date\"] === \"string\" && ISO_DATE_RE.test(r[\"due_date\"]) ? r[\"due_date\"] : null,\n assignee: typeof r[\"assignee\"] === \"string\" ? r[\"assignee\"] : null,\n };\n } catch {\n return null;\n }\n}\n\n// ── Combined extractor ──\n\nexport interface ExtractOptions {\n /** Repo label list for validation hints */\n validLabels?: string[];\n /** Override today's date (for testing) */\n today?: Date;\n /** Called with a warning if LLM was unavailable but was configured */\n onLlmFallback?: ((reason: string) => void) | undefined;\n}\n\n/**\n * Extract issue fields from a natural language string.\n * Runs heuristic first, then optionally merges LLM result on top.\n * Heuristic wins on explicit tokens (#, @, due); LLM wins on title cleanup.\n */\nexport async function extractIssueFields(\n input: string,\n options: ExtractOptions = {},\n): Promise<ParsedIssue | null> {\n const today = options.today ?? new Date();\n const heuristic = await parseHeuristic(input, today);\n if (!heuristic) return null;\n\n const providerConfig = detectProvider();\n if (!providerConfig) return heuristic;\n\n const llmResult = await callLLM(input, options.validLabels ?? [], today, providerConfig);\n if (!llmResult) {\n options.onLlmFallback?.(\"AI parsing unavailable, used keyword matching\");\n return heuristic;\n }\n\n // After parsing LLM response, validate labels against known valid labels\n const safeLabels =\n options.validLabels && options.validLabels.length > 0\n ? llmResult.labels.filter((l) => (options.validLabels ?? []).includes(l))\n : llmResult.labels;\n\n // Merge: heuristic wins on explicit tokens; LLM fills in title cleanup\n const merged: ParsedIssue = {\n ...llmResult,\n // Heuristic explicit tokens always win\n labels: heuristic.labels.length > 0 ? heuristic.labels : safeLabels,\n assignee: heuristic.assignee ?? llmResult.assignee,\n dueDate: heuristic.dueDate ?? llmResult.due_date,\n // LLM title is used only if heuristic left explicit tokens\n title:\n heuristic.labels.length > 0 || heuristic.assignee || heuristic.dueDate\n ? llmResult.title || heuristic.title\n : heuristic.title,\n };\n\n return merged;\n}\n\n/** Returns true if an LLM API key is configured. */\nexport function hasLlmApiKey(): boolean {\n return detectProvider() !== null;\n}\n","import type { CreateTaskInput, Project, ProjectData, Task, UpdateTaskInput } from \"./types.js\";\n\nconst BASE_URL = \"https://api.ticktick.com/open/v1\";\n\nexport class TickTickClient {\n private token: string;\n\n constructor(token: string) {\n this.token = token;\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T | null> {\n const url = `${BASE_URL}${path}`;\n\n const init: RequestInit = {\n method,\n headers: {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n },\n };\n\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n }\n\n const res = await fetch(url, init);\n\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`TickTick API error ${res.status}: ${text}`);\n }\n\n const text = await res.text();\n if (!text) return null;\n return JSON.parse(text) as T;\n }\n\n async listProjects(): Promise<Project[]> {\n return (await this.request<Project[]>(\"GET\", \"/project\")) ?? [];\n }\n\n async getProject(projectId: string): Promise<Project> {\n const result = await this.request<Project>(\"GET\", `/project/${projectId}`);\n if (!result) throw new Error(`TickTick API returned empty response for project ${projectId}`);\n return result;\n }\n\n async getProjectData(projectId: string): Promise<ProjectData> {\n const result = await this.request<ProjectData>(\"GET\", `/project/${projectId}/data`);\n if (!result)\n throw new Error(`TickTick API returned empty response for project data ${projectId}`);\n return result;\n }\n\n async listTasks(projectId: string): Promise<Task[]> {\n const data = await this.getProjectData(projectId);\n return data.tasks ?? [];\n }\n\n async getTask(projectId: string, taskId: string): Promise<Task> {\n const result = await this.request<Task>(\"GET\", `/project/${projectId}/task/${taskId}`);\n if (!result) throw new Error(`TickTick API returned empty response for task ${taskId}`);\n return result;\n }\n\n async createTask(input: CreateTaskInput): Promise<Task> {\n const result = await this.request<Task>(\"POST\", \"/task\", input);\n if (!result) throw new Error(\"TickTick API returned empty response for createTask\");\n return result;\n }\n\n async updateTask(input: UpdateTaskInput): Promise<Task> {\n const result = await this.request<Task>(\"POST\", `/task/${input.id}`, input);\n if (!result) throw new Error(`TickTick API returned empty response for updateTask ${input.id}`);\n return result;\n }\n\n async completeTask(projectId: string, taskId: string): Promise<void> {\n await this.request<void>(\"POST\", `/project/${projectId}/task/${taskId}/complete`);\n }\n\n async deleteTask(projectId: string, taskId: string): Promise<void> {\n await this.request<void>(\"DELETE\", `/project/${projectId}/task/${taskId}`);\n }\n}\n","import {\n existsSync,\n mkdirSync,\n readFileSync,\n statSync,\n truncateSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nconst LOG_FILE = join(homedir(), \".config\", \"hog\", \"action-log.json\");\nconst MAX_ENTRIES = 1000;\nconst MAX_SIZE_BYTES = 10 * 1024 * 1024; // 10MB\n\nexport interface PersistedLogEntry {\n readonly id: string;\n readonly description: string;\n readonly status: \"success\" | \"error\" | \"pending\";\n readonly timestamp: number;\n readonly repo?: string;\n}\n\nfunction readLog(): PersistedLogEntry[] {\n if (!existsSync(LOG_FILE)) return [];\n try {\n const raw = readFileSync(LOG_FILE, \"utf-8\");\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? (parsed as PersistedLogEntry[]) : [];\n } catch {\n return [];\n }\n}\n\nfunction writeLog(entries: PersistedLogEntry[]): void {\n mkdirSync(dirname(LOG_FILE), { recursive: true });\n writeFileSync(LOG_FILE, JSON.stringify(entries, null, 2), \"utf-8\");\n}\n\nexport function appendActionLog(entry: PersistedLogEntry): void {\n // Check size and rotate if needed\n if (existsSync(LOG_FILE)) {\n const stats = statSync(LOG_FILE);\n if (stats.size > MAX_SIZE_BYTES) {\n truncateSync(LOG_FILE, 0);\n }\n }\n const entries = readLog();\n entries.push(entry);\n // Keep only last MAX_ENTRIES\n if (entries.length > MAX_ENTRIES) {\n entries.splice(0, entries.length - MAX_ENTRIES);\n }\n writeLog(entries);\n}\n\nexport function getActionLog(limit = 50): PersistedLogEntry[] {\n const entries = readLog();\n return entries.slice(-limit);\n}\n\nexport function clearActionLog(): void {\n writeLog([]);\n}\n","// ── Result Type (no throwing in data layer) ──\n\nexport type Result<T, E> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly error: E };\n\nexport interface FetchError {\n readonly type: \"github\" | \"ticktick\" | \"network\";\n readonly message: string;\n}\n\n// ── Board Data Types ──\n\nexport interface BoardIssue {\n readonly number: number;\n readonly title: string;\n readonly url: string;\n readonly state: string;\n readonly assignee: string | null;\n readonly labels: readonly string[];\n readonly updatedAt: string;\n readonly repo: string;\n}\n\nexport interface BoardData {\n readonly github: readonly BoardIssue[];\n readonly ticktick: readonly Task[];\n readonly fetchedAt: Date;\n}\n\n// ── Pick Command ──\n\nexport interface PickResult {\n readonly success: boolean;\n readonly issue: BoardIssue;\n readonly ticktickTask?: Task;\n readonly warning?: string;\n}\n\n// ── TickTick Open API types ──\n\nexport interface Task {\n id: string;\n projectId: string;\n title: string;\n content: string;\n desc: string;\n isAllDay: boolean;\n startDate: string;\n dueDate: string;\n completedTime: string;\n priority: Priority;\n reminders: string[];\n repeatFlag: string;\n sortOrder: number;\n status: TaskStatus;\n timeZone: string;\n tags: string[];\n items: ChecklistItem[];\n}\n\nexport interface ChecklistItem {\n id: string;\n title: string;\n status: number;\n completedTime: number;\n isAllDay: boolean;\n sortOrder: number;\n startDate: string;\n timeZone: string;\n}\n\nexport interface Project {\n id: string;\n name: string;\n color: string;\n sortOrder: number;\n closed: boolean;\n groupId: string;\n viewMode: string;\n kind: string;\n}\n\nexport interface ProjectData {\n project: Project;\n tasks: Task[];\n}\n\nexport enum Priority {\n None = 0,\n Low = 1,\n Medium = 3,\n High = 5,\n}\n\nexport enum TaskStatus {\n Active = 0,\n Completed = 2,\n}\n\nexport interface CreateTaskInput {\n title: string;\n projectId?: string;\n content?: string;\n priority?: Priority;\n startDate?: string;\n dueDate?: string;\n isAllDay?: boolean;\n timeZone?: string;\n tags?: string[];\n}\n\nexport interface UpdateTaskInput {\n id: string;\n projectId: string;\n title?: string;\n content?: string;\n priority?: Priority;\n startDate?: string;\n dueDate?: string;\n isAllDay?: boolean;\n tags?: string[];\n}\n","/**\n * Shared board constants and utilities.\n * Extracted to prevent duplication across components and hooks.\n */\n\n/** Statuses that trigger completion actions (TickTick close, project complete). */\nexport const TERMINAL_STATUS_RE = /^(done|shipped|won't|wont|closed|complete|completed)$/i;\n\nexport function isTerminalStatus(status: string): boolean {\n return TERMINAL_STATUS_RE.test(status);\n}\n\n/** Returns true if a nav ID is a header row (not a navigable issue/task). */\nexport function isHeaderId(id: string | null): boolean {\n return id != null && (id.startsWith(\"header:\") || id.startsWith(\"sub:\"));\n}\n\n/** Formats a date as a relative \"Xm ago\" string. */\nexport function timeAgo(date: Date): string {\n const seconds = Math.floor((Date.now() - date.getTime()) / 1000);\n if (seconds < 10) return \"just now\";\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n return `${minutes}m ago`;\n}\n\n/** Formats an unknown error as a string. */\nexport function formatError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import { execFile, execFileSync } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface GitHubIssue {\n readonly number: number;\n readonly title: string;\n readonly url: string;\n readonly state: string;\n readonly updatedAt: string;\n readonly labels: { name: string }[];\n readonly assignees?: { login: string }[];\n readonly targetDate?: string;\n readonly body?: string;\n readonly projectStatus?: string;\n readonly slackThreadUrl?: string;\n /**\n * All other GitHub Project custom field values keyed by field name.\n * Includes single-select, text, number, and iteration fields — excluding\n * Status (→ projectStatus) and date fields (→ targetDate).\n * Example: { Workstream: \"Platform\", Size: \"M\", Priority: \"High\" }\n */\n readonly customFields?: Record<string, string>;\n}\n\nexport interface ProjectFieldValues {\n targetDate?: string;\n status?: string;\n customFields?: Record<string, string>;\n}\n\nexport interface RepoProjectConfig {\n projectNumber: number;\n statusFieldId: string;\n optionId: string;\n}\n\n/** Matches common date field names used in GitHub Projects v2 (case-insensitive). */\nconst DATE_FIELD_NAME_RE = /^(target\\s*date|due\\s*date|due|deadline)$/i;\n\nfunction runGh(args: string[]): string {\n return execFileSync(\"gh\", args, { encoding: \"utf-8\", timeout: 30_000 }).trim();\n}\n\nfunction runGhJson<T>(args: string[]): T {\n const output = runGh(args);\n return JSON.parse(output) as T;\n}\n\nasync function runGhAsync(args: string[]): Promise<string> {\n const { stdout } = await execFileAsync(\"gh\", args, { encoding: \"utf-8\", timeout: 30_000 });\n return stdout.trim();\n}\n\nasync function runGhJsonAsync<T>(args: string[]): Promise<T> {\n const output = await runGhAsync(args);\n return JSON.parse(output) as T;\n}\n\nexport function fetchAssignedIssues(repo: string, assignee: string): GitHubIssue[] {\n return runGhJson<GitHubIssue[]>([\n \"issue\",\n \"list\",\n \"--repo\",\n repo,\n \"--assignee\",\n assignee,\n \"--state\",\n \"open\",\n \"--json\",\n \"number,title,url,state,updatedAt,labels\",\n \"--limit\",\n \"100\",\n ]);\n}\n\nexport interface FetchIssuesOptions {\n assignee?: string | undefined;\n state?: \"open\" | \"closed\" | \"all\" | undefined;\n limit?: number | undefined;\n}\n\nexport function fetchRepoIssues(repo: string, options: FetchIssuesOptions = {}): GitHubIssue[] {\n const { state = \"open\", limit = 100 } = options;\n const args = [\n \"issue\",\n \"list\",\n \"--repo\",\n repo,\n \"--state\",\n state,\n \"--json\",\n \"number,title,url,state,updatedAt,labels,assignees,body\",\n \"--limit\",\n String(limit),\n ];\n if (options.assignee) {\n args.push(\"--assignee\", options.assignee);\n }\n return runGhJson<GitHubIssue[]>(args);\n}\n\nexport function assignIssue(repo: string, issueNumber: number): void {\n runGh([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--add-assignee\", \"@me\"]);\n}\n\nexport async function assignIssueAsync(repo: string, issueNumber: number): Promise<void> {\n await runGhAsync([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--add-assignee\", \"@me\"]);\n}\n\nexport async function assignIssueToAsync(\n repo: string,\n issueNumber: number,\n user: string,\n): Promise<void> {\n await runGhAsync([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--add-assignee\", user]);\n}\n\nexport async function unassignIssueAsync(\n repo: string,\n issueNumber: number,\n user: string,\n): Promise<void> {\n await runGhAsync([\n \"issue\",\n \"edit\",\n String(issueNumber),\n \"--repo\",\n repo,\n \"--remove-assignee\",\n user,\n ]);\n}\n\nexport async function fetchIssueAsync(repo: string, issueNumber: number): Promise<GitHubIssue> {\n return runGhJsonAsync<GitHubIssue>([\n \"issue\",\n \"view\",\n String(issueNumber),\n \"--repo\",\n repo,\n \"--json\",\n \"number,title,url,state,updatedAt,labels,assignees,body,projectStatus\",\n ]);\n}\n\nexport async function closeIssueAsync(repo: string, issueNumber: number): Promise<void> {\n await runGhAsync([\"issue\", \"close\", String(issueNumber), \"--repo\", repo]);\n}\n\nexport async function createIssueAsync(\n repo: string,\n title: string,\n body: string,\n labels?: string[],\n): Promise<string> {\n const args = [\"issue\", \"create\", \"--repo\", repo, \"--title\", title, \"--body\", body];\n if (labels && labels.length > 0) {\n for (const label of labels) {\n args.push(\"--label\", label);\n }\n }\n return runGhAsync(args);\n}\n\nexport async function editIssueTitleAsync(\n repo: string,\n issueNumber: number,\n title: string,\n): Promise<void> {\n await runGhAsync([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--title\", title]);\n}\n\nexport async function editIssueBodyAsync(\n repo: string,\n issueNumber: number,\n body: string,\n): Promise<void> {\n await runGhAsync([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--body\", body]);\n}\n\nexport async function addCommentAsync(\n repo: string,\n issueNumber: number,\n body: string,\n): Promise<void> {\n await runGhAsync([\"issue\", \"comment\", String(issueNumber), \"--repo\", repo, \"--body\", body]);\n}\n\nexport async function addLabelAsync(\n repo: string,\n issueNumber: number,\n label: string,\n): Promise<void> {\n await runGhAsync([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--add-label\", label]);\n}\n\nexport async function removeLabelAsync(\n repo: string,\n issueNumber: number,\n label: string,\n): Promise<void> {\n await runGhAsync([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--remove-label\", label]);\n}\n\nexport async function updateLabelsAsync(\n repo: string,\n issueNumber: number,\n addLabels: string[],\n removeLabels: string[],\n): Promise<void> {\n const args = [\"issue\", \"edit\", String(issueNumber), \"--repo\", repo];\n for (const label of addLabels) args.push(\"--add-label\", label);\n for (const label of removeLabels) args.push(\"--remove-label\", label);\n await runGhAsync(args);\n}\n\nexport interface IssueComment {\n readonly body: string;\n readonly author: { readonly login: string };\n readonly createdAt: string;\n}\n\nexport async function fetchIssueCommentsAsync(\n repo: string,\n issueNumber: number,\n): Promise<IssueComment[]> {\n const result = await runGhJsonAsync<{ comments: IssueComment[] }>([\n \"issue\",\n \"view\",\n String(issueNumber),\n \"--repo\",\n repo,\n \"--json\",\n \"comments\",\n ]);\n return result.comments ?? [];\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: parses multiple GitHub Project field types\nexport function fetchProjectFields(\n repo: string,\n issueNumber: number,\n projectNumber: number,\n): ProjectFieldValues {\n // GraphQL query to get project item fields for this issue\n const query = `\n query($owner: String!, $repo: String!, $issueNumber: Int!) {\n repository(owner: $owner, name: $repo) {\n issue(number: $issueNumber) {\n projectItems(first: 10) {\n nodes {\n project { number }\n fieldValues(first: 20) {\n nodes {\n ... on ProjectV2ItemFieldDateValue {\n field { ... on ProjectV2Field { name } }\n date\n }\n ... on ProjectV2ItemFieldSingleSelectValue {\n field { ... on ProjectV2SingleSelectField { name } }\n name\n }\n ... on ProjectV2ItemFieldTextValue {\n field { ... on ProjectV2Field { name } }\n text\n }\n ... on ProjectV2ItemFieldNumberValue {\n field { ... on ProjectV2Field { name } }\n number\n }\n ... on ProjectV2ItemFieldIterationValue {\n field { ... on ProjectV2IterationField { name } }\n title\n }\n }\n }\n }\n }\n }\n }\n }\n `;\n\n const [owner, repoName] = repo.split(\"/\");\n if (!(owner && repoName)) return {};\n\n try {\n const result = runGhJson<GraphQLResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${query}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `repo=${repoName}`,\n \"-F\",\n `issueNumber=${String(issueNumber)}`,\n ]);\n\n const items = result?.data?.repository?.issue?.projectItems?.nodes ?? [];\n const projectItem = items.find((item) => item?.project?.number === projectNumber);\n\n if (!projectItem) return {};\n\n const fields: ProjectFieldValues = {};\n const fieldValues = projectItem.fieldValues?.nodes ?? [];\n\n for (const fv of fieldValues) {\n if (!fv) continue;\n const fieldName = fv.field?.name ?? \"\";\n if (\"date\" in fv && DATE_FIELD_NAME_RE.test(fieldName)) {\n fields.targetDate = fv.date;\n } else if (\"name\" in fv && fieldName === \"Status\") {\n fields.status = fv.name;\n } else if (fieldName) {\n const value =\n \"text\" in fv && fv.text != null\n ? fv.text\n : \"number\" in fv && fv.number != null\n ? String(fv.number)\n : \"name\" in fv && fv.name != null\n ? fv.name\n : \"title\" in fv && fv.title != null\n ? fv.title\n : null;\n if (value != null) {\n if (!fields.customFields) fields.customFields = {};\n fields.customFields[fieldName] = value;\n }\n }\n }\n\n return fields;\n } catch {\n return {};\n }\n}\n\nexport interface ProjectEnrichment {\n targetDate?: string;\n projectStatus?: string;\n customFields?: Record<string, string>;\n}\n\n/**\n * Fetch target dates and project statuses for all issues in a project in one GraphQL call.\n * Returns a Map from issue number to enrichment data.\n */\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: parses multiple GitHub Project field types across all items\nexport function fetchProjectEnrichment(\n repo: string,\n projectNumber: number,\n): Map<number, ProjectEnrichment> {\n const [owner] = repo.split(\"/\");\n if (!owner) return new Map();\n\n const query = `\n query($owner: String!, $projectNumber: Int!, $cursor: String) {\n organization(login: $owner) {\n projectV2(number: $projectNumber) {\n items(first: 100, after: $cursor) {\n pageInfo { hasNextPage endCursor }\n nodes {\n content {\n ... on Issue {\n number\n }\n }\n fieldValues(first: 20) {\n nodes {\n ... on ProjectV2ItemFieldDateValue {\n field { ... on ProjectV2Field { name } }\n date\n }\n ... on ProjectV2ItemFieldSingleSelectValue {\n field { ... on ProjectV2SingleSelectField { name } }\n name\n }\n ... on ProjectV2ItemFieldTextValue {\n field { ... on ProjectV2Field { name } }\n text\n }\n ... on ProjectV2ItemFieldNumberValue {\n field { ... on ProjectV2Field { name } }\n number\n }\n ... on ProjectV2ItemFieldIterationValue {\n field { ... on ProjectV2IterationField { name } }\n title\n }\n }\n }\n }\n }\n }\n }\n }\n `;\n\n try {\n const enrichMap = new Map<number, ProjectEnrichment>();\n let cursor: string | null = null;\n\n do {\n const args = [\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${query}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `projectNumber=${String(projectNumber)}`,\n ];\n if (cursor) args.push(\"-f\", `cursor=${cursor}`);\n const result = runGhJson<ProjectItemsResult>(args);\n const page = result?.data?.organization?.projectV2?.items;\n const nodes = page?.nodes ?? [];\n\n for (const item of nodes) {\n if (!item?.content?.number) continue;\n const enrichment: ProjectEnrichment = {};\n const fieldValues = item.fieldValues?.nodes ?? [];\n for (const fv of fieldValues) {\n if (!fv) continue;\n const fieldName = fv.field?.name ?? \"\";\n if (\"date\" in fv && fv.date && DATE_FIELD_NAME_RE.test(fieldName)) {\n enrichment.targetDate = fv.date;\n } else if (\"name\" in fv && fieldName === \"Status\" && fv.name) {\n enrichment.projectStatus = fv.name;\n } else if (fieldName) {\n const value =\n \"text\" in fv && fv.text != null\n ? fv.text\n : \"number\" in fv && fv.number != null\n ? String(fv.number)\n : \"name\" in fv && fv.name != null\n ? fv.name\n : \"title\" in fv && fv.title != null\n ? fv.title\n : null;\n if (value != null) {\n if (!enrichment.customFields) enrichment.customFields = {};\n enrichment.customFields[fieldName] = value;\n }\n }\n }\n enrichMap.set(item.content.number, enrichment);\n }\n\n if (!page?.pageInfo?.hasNextPage) break;\n cursor = page.pageInfo.endCursor ?? null;\n } while (cursor);\n\n return enrichMap;\n } catch {\n return new Map();\n }\n}\n\n/** Backwards-compatible wrapper for fetchProjectEnrichment. */\nexport function fetchProjectTargetDates(repo: string, projectNumber: number): Map<number, string> {\n const enrichMap = fetchProjectEnrichment(repo, projectNumber);\n const dateMap = new Map<number, string>();\n for (const [num, e] of enrichMap) {\n if (e.targetDate) dateMap.set(num, e.targetDate);\n }\n return dateMap;\n}\n\nexport interface StatusOption {\n id: string;\n name: string;\n}\n\n/**\n * Fetch available project status options (the SingleSelectField values).\n * Returns options in the order defined on the project board.\n */\nexport function fetchProjectStatusOptions(\n repo: string,\n projectNumber: number,\n _statusFieldId: string,\n): StatusOption[] {\n const [owner] = repo.split(\"/\");\n if (!owner) return [];\n\n const query = `\n query($owner: String!, $projectNumber: Int!) {\n organization(login: $owner) {\n projectV2(number: $projectNumber) {\n field(name: \"Status\") {\n ... on ProjectV2SingleSelectField {\n options {\n id\n name\n }\n }\n }\n }\n }\n }\n `;\n\n try {\n const result = runGhJson<ProjectStatusResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${query}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `projectNumber=${String(projectNumber)}`,\n ]);\n\n return result?.data?.organization?.projectV2?.field?.options ?? [];\n } catch {\n return [];\n }\n}\n\nexport function addLabel(repo: string, issueNumber: number, label: string): void {\n runGh([\"issue\", \"edit\", String(issueNumber), \"--repo\", repo, \"--add-label\", label]);\n}\n\nexport interface LabelOption {\n name: string;\n color: string;\n}\n\n/**\n * Fetch all labels defined in the repo asynchronously.\n * Uses execFileAsync (not execFileSync) to avoid blocking the React render thread.\n */\nexport async function fetchRepoLabelsAsync(repo: string): Promise<LabelOption[]> {\n try {\n const result = await runGhJsonAsync<LabelOption[]>([\n \"label\",\n \"list\",\n \"--repo\",\n repo,\n \"--json\",\n \"name,color\",\n ]);\n return Array.isArray(result) ? result : [];\n } catch {\n return [];\n }\n}\n\n/** Cache for GitHub Projects node IDs — these are immutable per project number. */\nconst projectNodeIdCache = new Map<string, string>();\n\n/** Clears the project node ID cache. Intended for use in tests only. */\nexport function clearProjectNodeIdCache(): void {\n projectNodeIdCache.clear();\n}\n\nasync function getProjectNodeId(owner: string, projectNumber: number): Promise<string | null> {\n const key = `${owner}/${String(projectNumber)}`;\n const cached = projectNodeIdCache.get(key);\n if (cached !== undefined) return cached;\n\n const projectQuery = `\n query($owner: String!) {\n organization(login: $owner) {\n projectV2(number: ${projectNumber}) {\n id\n }\n }\n }\n `;\n\n const projectResult = await runGhJsonAsync<GraphQLProjectResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${projectQuery}`,\n \"-F\",\n `owner=${owner}`,\n ]);\n\n const projectId = projectResult?.data?.organization?.projectV2?.id;\n if (!projectId) return null;\n projectNodeIdCache.set(key, projectId);\n return projectId;\n}\n\nexport function updateProjectItemStatus(\n repo: string,\n issueNumber: number,\n projectConfig: RepoProjectConfig,\n): void {\n const [owner, repoName] = repo.split(\"/\");\n if (!(owner && repoName)) return;\n\n // First get the project item ID\n const findItemQuery = `\n query($owner: String!, $repo: String!, $issueNumber: Int!) {\n repository(owner: $owner, name: $repo) {\n issue(number: $issueNumber) {\n projectItems(first: 10) {\n nodes {\n id\n project { number }\n }\n }\n }\n }\n }\n `;\n\n const findResult = runGhJson<GraphQLResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${findItemQuery}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `repo=${repoName}`,\n \"-F\",\n `issueNumber=${String(issueNumber)}`,\n ]);\n\n const items = findResult?.data?.repository?.issue?.projectItems?.nodes ?? [];\n const projectNumber = projectConfig.projectNumber;\n const projectItem = items.find((item) => item?.project?.number === projectNumber);\n\n if (!projectItem?.id) return;\n\n // Get the project ID\n const projectQuery = `\n query($owner: String!) {\n organization(login: $owner) {\n projectV2(number: ${projectNumber}) {\n id\n }\n }\n }\n `;\n\n const projectResult = runGhJson<GraphQLProjectResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${projectQuery}`,\n \"-F\",\n `owner=${owner}`,\n ]);\n\n const projectId = projectResult?.data?.organization?.projectV2?.id;\n if (!projectId) return;\n\n const statusFieldId = projectConfig.statusFieldId;\n const optionId = projectConfig.optionId;\n\n // Mutation to update the status\n const mutation = `\n mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {\n updateProjectV2ItemFieldValue(\n input: {\n projectId: $projectId\n itemId: $itemId\n fieldId: $fieldId\n value: { singleSelectOptionId: $optionId }\n }\n ) {\n projectV2Item { id }\n }\n }\n `;\n\n runGh([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${mutation}`,\n \"-F\",\n `projectId=${projectId}`,\n \"-F\",\n `itemId=${projectItem.id}`,\n \"-F\",\n `fieldId=${statusFieldId}`,\n \"-F\",\n `optionId=${optionId}`,\n ]);\n}\n\nexport async function updateProjectItemStatusAsync(\n repo: string,\n issueNumber: number,\n projectConfig: RepoProjectConfig,\n): Promise<void> {\n const [owner, repoName] = repo.split(\"/\");\n if (!(owner && repoName)) return;\n\n const findItemQuery = `\n query($owner: String!, $repo: String!, $issueNumber: Int!) {\n repository(owner: $owner, name: $repo) {\n issue(number: $issueNumber) {\n projectItems(first: 10) {\n nodes {\n id\n project { number }\n }\n }\n }\n }\n }\n `;\n\n const findResult = await runGhJsonAsync<GraphQLResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${findItemQuery}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `repo=${repoName}`,\n \"-F\",\n `issueNumber=${String(issueNumber)}`,\n ]);\n\n const items = findResult?.data?.repository?.issue?.projectItems?.nodes ?? [];\n const projectNumber = projectConfig.projectNumber;\n const projectItem = items.find((item) => item?.project?.number === projectNumber);\n\n if (!projectItem?.id) return;\n\n const projectId = await getProjectNodeId(owner, projectNumber);\n if (!projectId) return;\n\n const statusFieldId = projectConfig.statusFieldId;\n const optionId = projectConfig.optionId;\n\n const mutation = `\n mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {\n updateProjectV2ItemFieldValue(\n input: {\n projectId: $projectId\n itemId: $itemId\n fieldId: $fieldId\n value: { singleSelectOptionId: $optionId }\n }\n ) {\n projectV2Item { id }\n }\n }\n `;\n\n await runGhAsync([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${mutation}`,\n \"-F\",\n `projectId=${projectId}`,\n \"-F\",\n `itemId=${projectItem.id}`,\n \"-F\",\n `fieldId=${statusFieldId}`,\n \"-F\",\n `optionId=${optionId}`,\n ]);\n}\n\nexport interface RepoDueDateConfig {\n projectNumber: number;\n dueDateFieldId: string;\n}\n\n/**\n * Set a date field value on a GitHub Projects v2 item for the given issue.\n * Uses the same 3-step pattern as updateProjectItemStatusAsync.\n */\nexport async function updateProjectItemDateAsync(\n repo: string,\n issueNumber: number,\n projectConfig: RepoDueDateConfig,\n dueDate: string,\n): Promise<void> {\n const [owner, repoName] = repo.split(\"/\");\n if (!(owner && repoName)) return;\n\n const findItemQuery = `\n query($owner: String!, $repo: String!, $issueNumber: Int!) {\n repository(owner: $owner, name: $repo) {\n issue(number: $issueNumber) {\n projectItems(first: 10) {\n nodes {\n id\n project { number }\n }\n }\n }\n }\n }\n `;\n\n const findResult = await runGhJsonAsync<GraphQLResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${findItemQuery}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `repo=${repoName}`,\n \"-F\",\n `issueNumber=${String(issueNumber)}`,\n ]);\n\n const items = findResult?.data?.repository?.issue?.projectItems?.nodes ?? [];\n const projectItem = items.find((item) => item?.project?.number === projectConfig.projectNumber);\n\n if (!projectItem?.id) return;\n\n const projectId = await getProjectNodeId(owner, projectConfig.projectNumber);\n if (!projectId) return;\n\n const mutation = `\n mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $date: Date!) {\n updateProjectV2ItemFieldValue(\n input: {\n projectId: $projectId\n itemId: $itemId\n fieldId: $fieldId\n value: { date: $date }\n }\n ) {\n projectV2Item { id }\n }\n }\n `;\n\n await runGhAsync([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${mutation}`,\n \"-F\",\n `projectId=${projectId}`,\n \"-F\",\n `itemId=${projectItem.id}`,\n \"-F\",\n `fieldId=${projectConfig.dueDateFieldId}`,\n \"-F\",\n `date=${dueDate}`,\n ]);\n}\n\n// Internal GraphQL response types\n\ninterface FieldValue {\n field?: { name?: string };\n date?: string;\n name?: string;\n text?: string;\n number?: number;\n title?: string; // iteration field title\n}\n\ninterface ProjectItem {\n id?: string;\n project?: { number?: number };\n fieldValues?: { nodes?: (FieldValue | null)[] };\n}\n\ninterface GraphQLResult {\n data?: {\n repository?: {\n issue?: {\n projectItems?: {\n nodes?: (ProjectItem | null)[];\n };\n };\n };\n };\n}\n\ninterface GraphQLProjectResult {\n data?: {\n organization?: {\n projectV2?: {\n id?: string;\n };\n };\n };\n}\n\ninterface ProjectItemNode {\n content?: { number?: number };\n fieldValues?: { nodes?: (FieldValue | null)[] };\n}\n\ninterface ProjectItemsResult {\n data?: {\n organization?: {\n projectV2?: {\n items?: {\n pageInfo?: { hasNextPage: boolean; endCursor?: string };\n nodes?: (ProjectItemNode | null)[];\n };\n };\n };\n };\n}\n\ninterface ProjectStatusResult {\n data?: {\n organization?: {\n projectV2?: {\n field?: {\n options?: StatusOption[];\n };\n };\n };\n };\n}\n","import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nconst CONFIG_DIR = join(homedir(), \".config\", \"hog\");\nconst STATE_FILE = join(CONFIG_DIR, \"sync-state.json\");\n\nexport interface SyncMapping {\n githubRepo: string;\n githubIssueNumber: number;\n githubUrl: string;\n ticktickTaskId: string;\n ticktickProjectId: string;\n githubUpdatedAt: string;\n lastSyncedAt: string;\n}\n\nexport interface SyncState {\n mappings: SyncMapping[];\n lastSyncAt?: string;\n}\n\nexport function loadSyncState(): SyncState {\n if (!existsSync(STATE_FILE)) return { mappings: [] };\n try {\n return JSON.parse(readFileSync(STATE_FILE, \"utf-8\")) as SyncState;\n } catch {\n return { mappings: [] };\n }\n}\n\nexport function saveSyncState(state: SyncState): void {\n writeFileSync(STATE_FILE, `${JSON.stringify(state, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport function findMapping(\n state: SyncState,\n githubRepo: string,\n issueNumber: number,\n): SyncMapping | undefined {\n return state.mappings.find(\n (m) => m.githubRepo === githubRepo && m.githubIssueNumber === issueNumber,\n );\n}\n\nexport function findMappingByTaskId(\n state: SyncState,\n ticktickTaskId: string,\n): SyncMapping | undefined {\n return state.mappings.find((m) => m.ticktickTaskId === ticktickTaskId);\n}\n\nexport function upsertMapping(state: SyncState, mapping: SyncMapping): void {\n const idx = state.mappings.findIndex(\n (m) => m.githubRepo === mapping.githubRepo && m.githubIssueNumber === mapping.githubIssueNumber,\n );\n if (idx >= 0) {\n state.mappings[idx] = mapping;\n } else {\n state.mappings.push(mapping);\n }\n}\n\nexport function removeMapping(state: SyncState, githubRepo: string, issueNumber: number): void {\n state.mappings = state.mappings.filter(\n (m) => !(m.githubRepo === githubRepo && m.githubIssueNumber === issueNumber),\n );\n}\n","import { TickTickClient } from \"./api.js\";\nimport type { HogConfig, RepoConfig } from \"./config.js\";\nimport { findRepo, requireAuth } from \"./config.js\";\nimport type { GitHubIssue } from \"./github.js\";\nimport { assignIssue, fetchProjectFields, fetchRepoIssues } from \"./github.js\";\nimport { findMapping, loadSyncState, saveSyncState, upsertMapping } from \"./sync-state.js\";\nimport type { BoardIssue, PickResult, Task } from \"./types.js\";\nimport { Priority } from \"./types.js\";\n\nconst ISSUE_REF_PATTERN = /^([a-zA-Z0-9_.-]+)\\/(\\d+)$/;\n\nexport interface ParsedIssueRef {\n repo: RepoConfig;\n issueNumber: number;\n}\n\nexport function parseIssueRef(input: string, config: HogConfig): ParsedIssueRef {\n const match = input.match(ISSUE_REF_PATTERN);\n if (!(match?.[1] && match[2])) {\n throw new Error(\"Invalid format. Use: shortName/number (e.g., myrepo/145)\");\n }\n\n const repoShortName = match[1];\n const repo = findRepo(config, repoShortName);\n if (!repo) {\n throw new Error(`Unknown repo \"${repoShortName}\". Run: hog config repos`);\n }\n\n const num = Number.parseInt(match[2], 10);\n if (num < 1 || num > 999999) {\n throw new Error(\"Invalid issue number\");\n }\n\n return { repo, issueNumber: num };\n}\n\nfunction appendWarning(existing: string | undefined, addition: string): string {\n return existing ? `${existing}. ${addition}` : addition;\n}\n\nfunction mapPriority(labels: readonly string[]): Priority {\n for (const label of labels) {\n if (label === \"priority:critical\" || label === \"priority:high\") return Priority.High;\n if (label === \"priority:medium\") return Priority.Medium;\n if (label === \"priority:low\") return Priority.Low;\n }\n return Priority.None;\n}\n\nfunction toBoardIssue(issue: GitHubIssue, repoName: string): BoardIssue {\n return {\n number: issue.number,\n title: issue.title,\n url: issue.url,\n state: issue.state,\n assignee: issue.assignees?.[0]?.login ?? null,\n labels: issue.labels.map((l) => l.name),\n updatedAt: issue.updatedAt,\n repo: repoName,\n };\n}\n\nasync function syncToTickTick(\n repo: RepoConfig,\n issue: GitHubIssue,\n boardIssue: BoardIssue,\n): Promise<{ task?: Task; warning?: string }> {\n const state = loadSyncState();\n const existing = findMapping(state, repo.name, issue.number);\n\n if (existing) {\n return { warning: \"TickTick task already exists from sync.\" };\n }\n\n const auth = requireAuth();\n const api = new TickTickClient(auth.accessToken);\n const projectFields = fetchProjectFields(repo.name, issue.number, repo.projectNumber);\n\n const input = {\n title: issue.title,\n content: `GitHub: ${issue.url}`,\n priority: mapPriority(boardIssue.labels),\n tags: [\"github\", repo.shortName],\n ...(projectFields.targetDate ? { dueDate: projectFields.targetDate, isAllDay: true } : {}),\n };\n\n const task = await api.createTask(input);\n\n upsertMapping(state, {\n githubRepo: repo.name,\n githubIssueNumber: issue.number,\n githubUrl: issue.url,\n ticktickTaskId: task.id,\n ticktickProjectId: task.projectId,\n githubUpdatedAt: issue.updatedAt,\n lastSyncedAt: new Date().toISOString(),\n });\n saveSyncState(state);\n\n return { task };\n}\n\nexport async function pickIssue(config: HogConfig, ref: ParsedIssueRef): Promise<PickResult> {\n const { repo, issueNumber } = ref;\n\n // 1. Fetch open issues and find the target\n const allIssues = fetchRepoIssues(repo.name, { state: \"open\", limit: 200 });\n const issue = allIssues.find((i) => i.number === issueNumber);\n\n if (!issue) {\n throw new Error(`Issue #${issueNumber} not found in ${repo.name}. Is it open?`);\n }\n\n const boardIssue = toBoardIssue(issue, repo.name);\n let warning: string | undefined;\n\n // 2. Check if already assigned\n if (boardIssue.assignee === config.board.assignee) {\n warning = \"Issue is already assigned to you\";\n } else if (boardIssue.assignee) {\n warning = `Issue is currently assigned to ${boardIssue.assignee}. Reassigning to you.`;\n }\n\n // 3. Assign on GitHub\n assignIssue(repo.name, issueNumber);\n\n // 4. Try to create TickTick task (non-critical — log warning on failure)\n let ticktickTask: Task | undefined;\n try {\n const result = await syncToTickTick(repo, issue, boardIssue);\n ticktickTask = result.task;\n if (result.warning) {\n warning = appendWarning(warning, result.warning);\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n warning = appendWarning(warning, `TickTick sync failed: ${msg}. Run 'hog sync run' to retry.`);\n }\n\n return {\n success: true,\n issue: boardIssue,\n ...(ticktickTask ? { ticktickTask } : {}),\n ...(warning ? { warning } : {}),\n } satisfies PickResult;\n}\n","/**\n * Returns the clipboard command args for the current platform/environment,\n * or null if no clipboard tool is available.\n *\n * Detection order: WSL → Wayland → X11 → macOS/Windows → null\n */\nexport function getClipboardArgs(): readonly string[] | null {\n if (process.platform === \"darwin\") return [\"pbcopy\"] as const;\n if (process.platform === \"win32\") return [\"clip\"] as const;\n // WSL: check both vars — WSL_DISTRO_NAME is unset for root users\n if (process.env[\"WSL_DISTRO_NAME\"] ?? process.env[\"WSL_INTEROP\"]) return [\"clip.exe\"] as const;\n // Wayland before X11 (wl-copy, not xclip which has a pipe-hang bug)\n if (process.env[\"WAYLAND_DISPLAY\"]) return [\"wl-copy\"] as const;\n // X11: use xsel (NOT xclip — known pipe-hang bug when no clipboard manager)\n if (process.env[\"DISPLAY\"]) return [\"xsel\", \"--clipboard\", \"--input\"] as const;\n return null;\n}\n","import { useCallback, useRef, useState } from \"react\";\nimport { appendActionLog } from \"../../log-persistence.js\";\nimport type { ToastAPI } from \"./use-toast.js\";\n\n// ── Types ──\n\nexport interface ActionLogEntry {\n readonly id: string;\n readonly description: string;\n readonly status: \"success\" | \"error\" | \"pending\";\n readonly ago: number;\n /** undefined = not undoable */\n readonly undo?: () => Promise<void>;\n /** retry callback for error entries */\n readonly retry?: () => void;\n}\n\nexport interface UseActionLogResult {\n entries: ActionLogEntry[];\n pushEntry: (entry: ActionLogEntry) => void;\n undoLast: () => Promise<void>;\n hasUndoable: boolean;\n}\n\nlet entryIdCounter = 0;\nexport function nextEntryId(): string {\n entryIdCounter += 1;\n return String(entryIdCounter);\n}\n\n/** Reset the entry ID counter — call in beforeEach to ensure deterministic IDs in tests. */\nexport function resetEntryIdCounter(): void {\n entryIdCounter = 0;\n}\n\nexport function useActionLog(toast: ToastAPI, refresh: () => void): UseActionLogResult {\n const [entries, setEntries] = useState<ActionLogEntry[]>([]);\n // Stable ref so undoLast doesn't depend on entries in its dependency array\n const entriesRef = useRef<ActionLogEntry[]>([]);\n entriesRef.current = entries;\n\n const pushEntry = useCallback((entry: ActionLogEntry) => {\n setEntries((prev) => [...prev.slice(-9), entry]); // keep last 10 in memory\n // Persist to disk (best-effort)\n try {\n appendActionLog({\n id: entry.id,\n description: entry.description,\n status: entry.status,\n timestamp: entry.ago,\n });\n } catch {\n // ignore persistence errors\n }\n }, []);\n\n const undoLast = useCallback(async () => {\n const undoable = [...entriesRef.current].reverse().find((e) => e.undo);\n if (!undoable?.undo) {\n toast.info(\"Nothing to undo\");\n return;\n }\n const thunk = undoable.undo;\n // Clear BEFORE execution to prevent double-undo window (omit undo property entirely)\n setEntries((prev) =>\n prev.map((e) => {\n if (e.id !== undoable.id) return e;\n // Omit the undo property to satisfy exactOptionalPropertyTypes\n const { undo: _removed, ...rest } = e;\n return rest;\n }),\n );\n const t = toast.loading(`Undoing: ${undoable.description}`);\n try {\n await thunk();\n t.resolve(`Undone: ${undoable.description}`);\n } catch (err) {\n t.reject(`Undo failed: ${err instanceof Error ? err.message : String(err)}`);\n refresh(); // revert optimistic state\n }\n }, [toast, refresh]);\n\n const hasUndoable = entries.some((e) => !!e.undo);\n\n return { entries, pushEntry, undoLast, hasUndoable };\n}\n","import { useCallback, useRef } from \"react\";\nimport type { HogConfig, RepoConfig } from \"../../config.js\";\nimport type {\n GitHubIssue,\n RepoDueDateConfig,\n RepoProjectConfig,\n StatusOption,\n} from \"../../github.js\";\nimport {\n addCommentAsync,\n addLabelAsync,\n assignIssueAsync,\n closeIssueAsync,\n createIssueAsync,\n unassignIssueAsync,\n updateLabelsAsync,\n updateProjectItemDateAsync,\n updateProjectItemStatusAsync,\n} from \"../../github.js\";\nimport { pickIssue } from \"../../pick.js\";\nimport { TERMINAL_STATUS_RE } from \"../constants.js\";\nimport type { DashboardData, RepoData } from \"../fetch.js\";\nimport type { ActionLogEntry } from \"./use-action-log.js\";\nimport { nextEntryId } from \"./use-action-log.js\";\nimport type { ToastAPI } from \"./use-toast.js\";\n\n// ── Types ──\n\nexport interface ActionContext {\n /** Currently selected issue (null if header or task) */\n issue: GitHubIssue | null;\n /** Repo name for the selected issue */\n repoName: string | null;\n /** Repo config for the selected issue */\n repoConfig: RepoConfig | null;\n /** Status options for the selected issue's repo */\n statusOptions: StatusOption[];\n}\n\nexport interface UseActionsResult {\n handlePick: () => void;\n handleComment: (body: string) => void;\n handleStatusChange: (optionId: string) => void;\n handleAssign: () => void;\n handleLabelChange: (addLabels: string[], removeLabels: string[]) => void;\n handleCreateIssue: (\n repo: string,\n title: string,\n body: string,\n dueDate?: string | null,\n labels?: string[],\n ) => Promise<{ repo: string; issueNumber: number } | null>;\n /** Bulk actions — return failed IDs (empty = all succeeded) */\n handleBulkAssign: (ids: ReadonlySet<string>) => Promise<string[]>;\n handleBulkUnassign: (ids: ReadonlySet<string>) => Promise<string[]>;\n handleBulkStatusChange: (ids: ReadonlySet<string>, optionId: string) => Promise<string[]>;\n}\n\ninterface UseActionsOptions {\n config: HogConfig;\n repos: RepoData[];\n selectedId: string | null;\n toast: ToastAPI;\n mutateData: (fn: (data: DashboardData) => DashboardData) => void;\n refresh: (silent?: boolean) => void;\n onOverlayDone: () => void;\n pushEntry?: (entry: ActionLogEntry) => void;\n registerPendingMutation?: (\n repoName: string,\n issueNumber: number,\n fields: { projectStatus?: string },\n ) => void;\n clearPendingMutation?: (repoName: string, issueNumber: number) => void;\n}\n\n// ── Helpers ──\n\nfunction findIssueContext(\n repos: RepoData[],\n selectedId: string | null,\n config: HogConfig,\n): ActionContext {\n if (!selectedId?.startsWith(\"gh:\")) {\n return { issue: null, repoName: null, repoConfig: null, statusOptions: [] };\n }\n\n for (const rd of repos) {\n for (const issue of rd.issues) {\n if (`gh:${rd.repo.name}:${issue.number}` === selectedId) {\n const repoConfig = config.repos.find((r) => r.name === rd.repo.name) ?? null;\n return { issue, repoName: rd.repo.name, repoConfig, statusOptions: rd.statusOptions };\n }\n }\n }\n return { issue: null, repoName: null, repoConfig: null, statusOptions: [] };\n}\n\n// ── Hook ──\n\n/** Trigger the configured completion action for a repo when moving to terminal status */\nasync function triggerCompletionActionAsync(\n action: RepoConfig[\"completionAction\"],\n repoName: string,\n issueNumber: number,\n): Promise<void> {\n switch (action.type) {\n case \"closeIssue\":\n await closeIssueAsync(repoName, issueNumber);\n break;\n case \"addLabel\":\n await addLabelAsync(repoName, issueNumber, action.label);\n break;\n case \"updateProjectStatus\":\n // This would require additional project config (optionId for the target status).\n // The user already changed the status, so this is a no-op.\n break;\n }\n}\n\n/** Apply optimistic status updates and register pending mutations for a set of issue IDs. */\nfunction applyBulkOptimisticStatusUpdates(\n ids: ReadonlySet<string>,\n optionId: string,\n repos: RepoData[],\n config: HogConfig,\n mutateData: (fn: (data: DashboardData) => DashboardData) => void,\n registerPendingMutation:\n | ((repoName: string, issueNumber: number, fields: { projectStatus?: string }) => void)\n | undefined,\n): void {\n for (const id of ids) {\n const ctx = findIssueContext(repos, id, config);\n if (!(ctx.issue && ctx.repoName)) continue;\n const { issue: ctxIssue, repoName: ctxRepo, statusOptions: ctxOpts } = ctx;\n mutateData((data) => optimisticSetStatus(data, ctxRepo, ctxIssue.number, ctxOpts, optionId));\n const ctxStatusName = ctxOpts.find((o) => o.id === optionId)?.name;\n if (ctxStatusName) {\n registerPendingMutation?.(ctxRepo, ctxIssue.number, { projectStatus: ctxStatusName });\n }\n }\n}\n\n/** Find the display name of a status option from any issue in the given id set. */\nfunction resolveOptionName(\n repos: RepoData[],\n ids: ReadonlySet<string>,\n config: HogConfig,\n optionId: string,\n): string {\n for (const id of ids) {\n const name = findIssueContext(repos, id, config).statusOptions.find(\n (o) => o.id === optionId,\n )?.name;\n if (name) return name;\n }\n return optionId;\n}\n\n/** Clear pending mutations for a list of failed issue IDs (format: \"gh:repo:number\"). */\nfunction clearFailedMutations(\n failedIds: string[],\n clearFn: ((repoName: string, issueNumber: number) => void) | undefined,\n): void {\n if (!clearFn) return;\n for (const failedId of failedIds) {\n const lastColon = failedId.lastIndexOf(\":\");\n const failedRepo = failedId.slice(3, lastColon); // strip leading \"gh:\"\n const failedIssueNumber = parseInt(failedId.slice(lastColon + 1), 10);\n clearFn(failedRepo, failedIssueNumber);\n }\n}\n\n/** Helper: optimistically set projectStatus on an issue in local data */\nfunction optimisticSetStatus(\n data: DashboardData,\n repoName: string,\n issueNumber: number,\n statusOptions: StatusOption[],\n optionId: string,\n): DashboardData {\n const statusName = statusOptions.find((o) => o.id === optionId)?.name;\n if (!statusName) return data;\n\n return {\n ...data,\n repos: data.repos.map((rd) => {\n if (rd.repo.name !== repoName) return rd;\n return {\n ...rd,\n issues: rd.issues.map((issue) =>\n issue.number === issueNumber ? { ...issue, projectStatus: statusName } : issue,\n ),\n };\n }),\n };\n}\n\nexport function useActions({\n config,\n repos,\n selectedId,\n toast,\n refresh,\n mutateData,\n onOverlayDone,\n pushEntry,\n registerPendingMutation,\n clearPendingMutation,\n}: UseActionsOptions): UseActionsResult {\n // Use refs so callbacks don't need to depend on frequently-changing values\n const configRef = useRef(config);\n const reposRef = useRef(repos);\n const selectedIdRef = useRef(selectedId);\n const pushEntryRef = useRef(pushEntry);\n const registerPendingMutationRef = useRef(registerPendingMutation);\n const clearPendingMutationRef = useRef(clearPendingMutation);\n configRef.current = config;\n reposRef.current = repos;\n selectedIdRef.current = selectedId;\n pushEntryRef.current = pushEntry;\n registerPendingMutationRef.current = registerPendingMutation;\n clearPendingMutationRef.current = clearPendingMutation;\n\n const handlePick = useCallback(() => {\n const ctx = findIssueContext(reposRef.current, selectedIdRef.current, configRef.current);\n if (!(ctx.issue && ctx.repoConfig)) return;\n\n const { issue, repoConfig } = ctx;\n const assignees = issue.assignees ?? [];\n if (assignees.some((a) => a.login === configRef.current.board.assignee)) {\n toast.info(`Already assigned to @${configRef.current.board.assignee}`);\n return;\n }\n const firstAssignee = assignees[0];\n if (firstAssignee) {\n toast.info(`Already assigned to @${firstAssignee.login}`);\n return;\n }\n\n const t = toast.loading(`Picking ${repoConfig.shortName}#${issue.number}...`);\n pickIssue(configRef.current, { repo: repoConfig, issueNumber: issue.number })\n .then((result) => {\n const msg = `Picked ${repoConfig.shortName}#${issue.number} — assigned + synced to TickTick`;\n t.resolve(result.warning ? `${msg} (${result.warning})` : msg);\n refresh();\n })\n .catch((err) => {\n t.reject(`Pick failed: ${err instanceof Error ? err.message : String(err)}`);\n });\n }, [toast, refresh]);\n\n const handleComment = useCallback(\n (body: string) => {\n const ctx = findIssueContext(reposRef.current, selectedIdRef.current, configRef.current);\n if (!(ctx.issue && ctx.repoName)) {\n onOverlayDone();\n return;\n }\n\n const { issue, repoName } = ctx;\n const t = toast.loading(\"Commenting...\");\n addCommentAsync(repoName, issue.number, body)\n .then(() => {\n t.resolve(`Comment posted on #${issue.number}`);\n pushEntryRef.current?.({\n id: nextEntryId(),\n description: `comment on #${issue.number}`,\n status: \"success\",\n ago: Date.now(),\n });\n refresh();\n onOverlayDone();\n })\n .catch((err) => {\n t.reject(`Comment failed: ${err instanceof Error ? err.message : String(err)}`);\n pushEntryRef.current?.({\n id: nextEntryId(),\n description: `comment on #${issue.number} failed`,\n status: \"error\",\n ago: Date.now(),\n });\n });\n },\n [toast, refresh, onOverlayDone],\n );\n\n const handleStatusChange = useCallback(\n (optionId: string) => {\n const ctx = findIssueContext(reposRef.current, selectedIdRef.current, configRef.current);\n if (!(ctx.issue && ctx.repoName && ctx.repoConfig)) {\n onOverlayDone();\n return;\n }\n\n const { issue, repoName, repoConfig, statusOptions } = ctx;\n\n // Capture the inverse synchronously before the async mutation (undo thunk)\n const previousOptionId = statusOptions.find((o) => o.name === issue.projectStatus)?.id;\n const undoThunk = previousOptionId\n ? async () => {\n mutateData((data) =>\n optimisticSetStatus(data, repoName, issue.number, statusOptions, previousOptionId),\n );\n const undoProjectConfig: RepoProjectConfig = {\n projectNumber: repoConfig.projectNumber,\n statusFieldId: repoConfig.statusFieldId,\n optionId: previousOptionId,\n };\n await updateProjectItemStatusAsync(repoName, issue.number, undoProjectConfig);\n }\n : undefined;\n\n // Optimistic update: move issue to new section immediately\n mutateData((data) =>\n optimisticSetStatus(data, repoName, issue.number, statusOptions, optionId),\n );\n // Register a pending mutation so subsequent refreshes (e.g. triggered by\n // assign) don't revert this status change before GitHub propagates it.\n const statusName = statusOptions.find((o) => o.id === optionId)?.name;\n if (statusName) {\n registerPendingMutationRef.current?.(repoName, issue.number, {\n projectStatus: statusName,\n });\n }\n\n const t = toast.loading(\"Moving...\");\n const projectConfig: RepoProjectConfig = {\n projectNumber: repoConfig.projectNumber,\n statusFieldId: repoConfig.statusFieldId,\n optionId,\n };\n\n updateProjectItemStatusAsync(repoName, issue.number, projectConfig)\n .then(async () => {\n const optionName = statusOptions.find((o) => o.id === optionId)?.name ?? optionId;\n\n // If terminal status, trigger completion action\n if (TERMINAL_STATUS_RE.test(optionName) && repoConfig.completionAction) {\n try {\n await triggerCompletionActionAsync(\n repoConfig.completionAction,\n repoName,\n issue.number,\n );\n t.resolve(\n `#${issue.number} \\u2192 ${optionName} (${repoConfig.completionAction.type})`,\n );\n } catch {\n toast.info(`#${issue.number} \\u2192 ${optionName} (completion action failed)`);\n }\n } else {\n t.resolve(`#${issue.number} \\u2192 ${optionName}`);\n }\n pushEntryRef.current?.({\n id: nextEntryId(),\n description: `#${issue.number} \\u2192 ${optionName}`,\n status: \"success\",\n ago: Date.now(),\n ...(undoThunk ? { undo: undoThunk } : {}),\n });\n // Do NOT refresh here — GitHub Projects v2 GraphQL is eventually consistent\n })\n .catch((err) => {\n t.reject(`Status change failed: ${err instanceof Error ? err.message : String(err)}`);\n pushEntryRef.current?.({\n id: nextEntryId(),\n description: `#${issue.number} status change failed`,\n status: \"error\",\n ago: Date.now(),\n });\n // Clear the pending mutation before reverting so the refresh fetches server state\n clearPendingMutationRef.current?.(repoName, issue.number);\n refresh(); // revert optimistic update on failure\n })\n .finally(() => {\n onOverlayDone();\n });\n },\n [toast, refresh, mutateData, onOverlayDone],\n );\n\n const handleAssign = useCallback(() => {\n const ctx = findIssueContext(reposRef.current, selectedIdRef.current, configRef.current);\n if (!(ctx.issue && ctx.repoName)) return;\n\n const { issue, repoName } = ctx;\n const assignees = issue.assignees ?? [];\n if (assignees.some((a) => a.login === configRef.current.board.assignee)) {\n toast.info(`Already assigned to @${configRef.current.board.assignee}`);\n return;\n }\n const firstAssignee = assignees[0];\n if (firstAssignee) {\n toast.info(`Already assigned to @${firstAssignee.login}`);\n return;\n }\n\n const t = toast.loading(\"Assigning...\");\n assignIssueAsync(repoName, issue.number)\n .then(() => {\n t.resolve(`Assigned #${issue.number} to @${configRef.current.board.assignee}`);\n pushEntryRef.current?.({\n id: nextEntryId(),\n description: `#${issue.number} assigned`,\n status: \"success\",\n ago: Date.now(),\n undo: async () => {\n await unassignIssueAsync(repoName, issue.number, \"@me\");\n },\n });\n refresh();\n })\n .catch((err) => {\n t.reject(`Assign failed: ${err instanceof Error ? err.message : String(err)}`);\n pushEntryRef.current?.({\n id: nextEntryId(),\n description: `#${issue.number} assign failed`,\n status: \"error\",\n ago: Date.now(),\n });\n });\n }, [toast, refresh]);\n\n const handleCreateIssue = useCallback(\n async (\n repo: string,\n title: string,\n body: string,\n dueDate?: string | null,\n labels?: string[],\n ): Promise<{ repo: string; issueNumber: number } | null> => {\n const repoConfig = configRef.current.repos.find((r) => r.name === repo);\n\n // If due date but no project date field configured, fall back to body text\n let effectiveBody = body;\n if (dueDate && !repoConfig?.dueDateFieldId) {\n const dueLine = `Due: ${dueDate}`;\n effectiveBody = body ? `${body}\\n\\n${dueLine}` : dueLine;\n }\n\n const t = toast.loading(\"Creating...\");\n try {\n const output = await createIssueAsync(repo, title, effectiveBody, labels);\n\n // gh issue create returns the URL of the new issue\n const match = output.match(/\\/(\\d+)$/);\n const issueNumber = match?.[1] ? parseInt(match[1], 10) : 0;\n const shortName = repoConfig?.shortName ?? repo;\n\n // If due date field configured, set it on the project item (best-effort)\n if (issueNumber > 0 && dueDate && repoConfig?.dueDateFieldId) {\n const dueDateConfig: RepoDueDateConfig = {\n projectNumber: repoConfig.projectNumber,\n dueDateFieldId: repoConfig.dueDateFieldId,\n };\n updateProjectItemDateAsync(repo, issueNumber, dueDateConfig, dueDate).catch(() => {\n // best-effort: don't fail the whole create if date field update fails\n });\n }\n\n t.resolve(`Created ${shortName}#${issueNumber}`);\n refresh();\n onOverlayDone();\n return issueNumber > 0 ? { repo, issueNumber } : null;\n } catch (err) {\n t.reject(`Create failed: ${err instanceof Error ? err.message : String(err)}`);\n onOverlayDone();\n return null;\n }\n },\n [toast, refresh, onOverlayDone],\n );\n\n const handleLabelChange = useCallback(\n (addLabels: string[], removeLabels: string[]) => {\n const ctx = findIssueContext(reposRef.current, selectedIdRef.current, configRef.current);\n if (!(ctx.issue && ctx.repoName)) return;\n const { issue, repoName } = ctx;\n\n const t = toast.loading(\"Updating labels...\");\n updateLabelsAsync(repoName, issue.number, addLabels, removeLabels)\n .then(() => {\n t.resolve(`Labels updated on #${issue.number}`);\n refresh();\n onOverlayDone();\n })\n .catch((err) => {\n t.reject(`Label update failed: ${err instanceof Error ? err.message : String(err)}`);\n onOverlayDone();\n });\n },\n [toast, refresh, onOverlayDone],\n );\n\n // ── Bulk actions ──\n // Each returns an array of IDs that failed (empty = all succeeded)\n\n const handleBulkAssign = useCallback(\n async (ids: ReadonlySet<string>): Promise<string[]> => {\n const failed: string[] = [];\n const t = toast.loading(`Assigning ${ids.size} issue${ids.size > 1 ? \"s\" : \"\"}...`);\n for (const id of ids) {\n const ctx = findIssueContext(reposRef.current, id, configRef.current);\n if (!(ctx.issue && ctx.repoName)) {\n failed.push(id);\n continue;\n }\n\n const assignees = ctx.issue.assignees ?? [];\n if (assignees.some((a) => a.login === configRef.current.board.assignee)) continue; // already assigned, skip\n\n try {\n await assignIssueAsync(ctx.repoName, ctx.issue.number);\n } catch {\n failed.push(id);\n }\n }\n const total = ids.size;\n const ok = total - failed.length;\n if (failed.length === 0) {\n t.resolve(\n `Assigned ${total} issue${total > 1 ? \"s\" : \"\"} to @${configRef.current.board.assignee}`,\n );\n } else {\n t.reject(`${ok} assigned, ${failed.length} failed`);\n }\n refresh();\n return failed;\n },\n [toast, refresh],\n );\n\n const handleBulkUnassign = useCallback(\n async (ids: ReadonlySet<string>): Promise<string[]> => {\n const failed: string[] = [];\n const t = toast.loading(`Unassigning ${ids.size} issue${ids.size > 1 ? \"s\" : \"\"}...`);\n for (const id of ids) {\n const ctx = findIssueContext(reposRef.current, id, configRef.current);\n if (!(ctx.issue && ctx.repoName)) {\n failed.push(id);\n continue;\n }\n\n const assignees = ctx.issue.assignees ?? [];\n if (!assignees.some((a) => a.login === configRef.current.board.assignee)) continue; // not self-assigned, skip\n\n try {\n await unassignIssueAsync(ctx.repoName, ctx.issue.number, \"@me\");\n } catch {\n failed.push(id);\n }\n }\n const total = ids.size;\n const ok = total - failed.length;\n if (failed.length === 0) {\n t.resolve(`Unassigned ${total} issue${total > 1 ? \"s\" : \"\"}`);\n } else {\n t.reject(`${ok} unassigned, ${failed.length} failed`);\n }\n refresh();\n return failed;\n },\n [toast, refresh],\n );\n\n const handleBulkStatusChange = useCallback(\n async (ids: ReadonlySet<string>, optionId: string): Promise<string[]> => {\n // Optimistic update: move all issues to new section immediately, register pending mutations\n applyBulkOptimisticStatusUpdates(\n ids,\n optionId,\n reposRef.current,\n configRef.current,\n mutateData,\n registerPendingMutationRef.current,\n );\n\n const t = toast.loading(`Moving ${ids.size} issue${ids.size > 1 ? \"s\" : \"\"}...`);\n const failed: string[] = [];\n for (const id of ids) {\n const ctx = findIssueContext(reposRef.current, id, configRef.current);\n if (!(ctx.issue && ctx.repoName && ctx.repoConfig)) {\n failed.push(id);\n continue;\n }\n\n try {\n const projectConfig: RepoProjectConfig = {\n projectNumber: ctx.repoConfig.projectNumber,\n statusFieldId: ctx.repoConfig.statusFieldId,\n optionId,\n };\n await updateProjectItemStatusAsync(ctx.repoName, ctx.issue.number, projectConfig);\n } catch {\n failed.push(id);\n }\n }\n const total = ids.size;\n const ok = total - failed.length;\n const optionName = resolveOptionName(reposRef.current, ids, configRef.current, optionId);\n if (failed.length === 0) {\n t.resolve(`Moved ${total} issue${total > 1 ? \"s\" : \"\"} to ${optionName}`);\n // Do not refresh — same eventual-consistency issue as single status change.\n // Pending mutations will preserve the optimistic state across auto-refreshes.\n } else {\n t.reject(`${ok} moved to ${optionName}, ${failed.length} failed`);\n // Clear pending mutations for failed issues so the refresh fetches their server state\n clearFailedMutations(failed, clearPendingMutationRef.current);\n refresh(); // revert optimistic updates for failed items\n }\n return failed;\n },\n [toast, refresh, mutateData],\n );\n\n return {\n handlePick,\n handleComment,\n handleStatusChange,\n handleAssign,\n handleLabelChange,\n handleCreateIssue,\n handleBulkAssign,\n handleBulkUnassign,\n handleBulkStatusChange,\n };\n}\n\nexport { findIssueContext };\n","import { Worker } from \"node:worker_threads\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { HogConfig } from \"../../config.js\";\nimport type { DashboardData, FetchOptions } from \"../fetch.js\";\n\nexport type DataStatus = \"loading\" | \"success\" | \"error\";\n\n/** Fields that can be held as pending optimistic overrides until the server reflects them. */\nexport interface PendingMutation {\n projectStatus?: string;\n expiresAt: number; // Date.now() + TTL\n}\n\n/** Apply any non-expired pending mutations on top of fresh server data. */\nfunction applyPendingMutations(\n data: DashboardData,\n pending: Map<string, PendingMutation>,\n): DashboardData {\n const now = Date.now();\n // Expire stale entries\n for (const [key, m] of pending) {\n if (m.expiresAt <= now) pending.delete(key);\n }\n if (pending.size === 0) return data;\n\n return {\n ...data,\n repos: data.repos.map((rd) => ({\n ...rd,\n issues: rd.issues.map((issue) => {\n const mutation = pending.get(`${rd.repo.name}:${issue.number}`);\n if (!mutation || mutation.expiresAt <= now) return issue;\n return mutation.projectStatus !== undefined\n ? { ...issue, projectStatus: mutation.projectStatus }\n : issue;\n }),\n })),\n };\n}\n\nexport interface DataState {\n status: DataStatus;\n data: DashboardData | null;\n error: string | null;\n lastRefresh: Date | null;\n isRefreshing: boolean;\n consecutiveFailures: number;\n autoRefreshPaused: boolean;\n}\n\nconst INITIAL_STATE: DataState = {\n status: \"loading\",\n data: null,\n error: null,\n lastRefresh: null,\n isRefreshing: false,\n consecutiveFailures: 0,\n autoRefreshPaused: false,\n};\n\n/** Stale thresholds for refresh age color */\nexport const STALE_THRESHOLDS = {\n FRESH: 60_000, // 0-60s → green\n AGING: 300_000, // 60s-5m → yellow\n // 5m+ → red\n} as const;\n\n/** Maximum consecutive failures before pausing auto-refresh */\nexport const MAX_REFRESH_FAILURES = 3;\n\n/** Compute age color based on time since last refresh */\nexport function refreshAgeColor(lastRefresh: Date | null): \"green\" | \"yellow\" | \"red\" | \"gray\" {\n if (!lastRefresh) return \"gray\";\n const age = Date.now() - lastRefresh.getTime();\n if (age < STALE_THRESHOLDS.FRESH) return \"green\";\n if (age < STALE_THRESHOLDS.AGING) return \"yellow\";\n return \"red\";\n}\n\n/** Discriminated union for worker messages */\ntype WorkerMessage = { type: \"success\"; data: DashboardData } | { type: \"error\"; error: string };\n\n/** Return type of the useData hook */\nexport type UseDataResult = DataState & {\n refresh: (silent?: boolean) => void;\n mutateData: (updater: (prev: DashboardData) => DashboardData) => void;\n pauseAutoRefresh: () => void;\n resumeAutoRefresh: () => void;\n registerPendingMutation: (\n repoName: string,\n issueNumber: number,\n fields: Pick<PendingMutation, \"projectStatus\">,\n ttlMs?: number,\n ) => void;\n clearPendingMutation: (repoName: string, issueNumber: number) => void;\n};\n\nexport function useData(\n config: HogConfig,\n options: FetchOptions,\n refreshIntervalMs: number,\n): UseDataResult {\n const [state, setState] = useState<DataState>(INITIAL_STATE);\n const activeRequestRef = useRef<{ canceled: boolean } | null>(null);\n const workerRef = useRef<Worker | null>(null);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const pendingMutationsRef = useRef<Map<string, PendingMutation>>(new Map());\n\n // Store config/options in refs so refresh callback is stable\n const configRef = useRef(config);\n const optionsRef = useRef(options);\n configRef.current = config;\n optionsRef.current = options;\n\n /**\n * Trigger a data refresh.\n * Pass `silent = true` for background auto-refreshes to avoid showing the\n * loading spinner (eliminates one re-render per cycle and prevents blinking).\n */\n const refresh = useCallback((silent = false) => {\n // Cancel any in-flight request\n if (activeRequestRef.current) {\n activeRequestRef.current.canceled = true;\n }\n workerRef.current?.terminate();\n\n const token = { canceled: false };\n activeRequestRef.current = token;\n\n if (!silent) {\n setState((prev) => ({ ...prev, isRefreshing: true }));\n }\n\n const worker = new Worker(\n new URL(\n import.meta.url.endsWith(\".ts\")\n ? \"../fetch-worker.ts\" // dev: tsx running source\n : \"./fetch-worker.js\", // prod: tsup bundle in dist/\n import.meta.url,\n ),\n { workerData: { config: configRef.current, options: optionsRef.current } },\n );\n workerRef.current = worker;\n\n worker.on(\"message\", (rawMsg) => {\n const msg = rawMsg as WorkerMessage;\n if (token.canceled) {\n worker.terminate();\n return;\n }\n\n if (msg.type === \"success\" && msg.data) {\n // Revive Date objects (structured clone preserves them, but defensive)\n const raw = msg.data;\n raw.fetchedAt = new Date(raw.fetchedAt);\n for (const ev of raw.activity) {\n ev.timestamp = new Date(ev.timestamp);\n }\n // Apply any pending optimistic overrides so a refresh triggered by\n // an unrelated action (e.g. assign) doesn't revert a status change\n // that GitHub Projects v2 hasn't propagated yet.\n const data = applyPendingMutations(raw, pendingMutationsRef.current);\n\n setState({\n status: \"success\",\n data,\n error: null,\n lastRefresh: new Date(),\n isRefreshing: false,\n consecutiveFailures: 0,\n autoRefreshPaused: false,\n });\n } else if (msg.type === \"error\") {\n setState((prev) => {\n const failures = prev.consecutiveFailures + 1;\n return {\n ...prev,\n status: prev.data ? \"success\" : \"error\",\n error: msg.error,\n isRefreshing: false,\n consecutiveFailures: failures,\n autoRefreshPaused: failures >= MAX_REFRESH_FAILURES,\n };\n });\n }\n worker.terminate();\n });\n\n worker.on(\"error\", (err) => {\n if (token.canceled) return;\n setState((prev) => {\n const failures = prev.consecutiveFailures + 1;\n return {\n ...prev,\n status: prev.data ? \"success\" : \"error\",\n error: err.message,\n isRefreshing: false,\n consecutiveFailures: failures,\n autoRefreshPaused: failures >= MAX_REFRESH_FAILURES,\n };\n });\n });\n }, []);\n\n // Initial fetch — runs once on mount\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n // Auto-refresh interval — skips when paused\n const stateRef = useRef(state);\n stateRef.current = state;\n\n useEffect(() => {\n if (refreshIntervalMs <= 0) return;\n\n intervalRef.current = setInterval(() => {\n if (!stateRef.current.autoRefreshPaused) {\n refresh(true); // silent: skip isRefreshing spinner to avoid blinking\n }\n }, refreshIntervalMs);\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n }\n };\n }, [refresh, refreshIntervalMs]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (activeRequestRef.current) {\n activeRequestRef.current.canceled = true;\n }\n workerRef.current?.terminate();\n };\n }, []);\n\n /** Locally mutate data without fetching (for optimistic updates). */\n const mutateData = useCallback((fn: (data: DashboardData) => DashboardData) => {\n setState((prev) => {\n if (!prev.data) return prev;\n return { ...prev, data: fn(prev.data) };\n });\n }, []);\n\n const pauseAutoRefresh = useCallback(() => {\n setState((prev) => ({ ...prev, autoRefreshPaused: true }));\n }, []);\n\n const resumeAutoRefresh = useCallback(() => {\n setState((prev) => ({ ...prev, autoRefreshPaused: false }));\n }, []);\n\n /**\n * Register an optimistic override for an issue field.\n * The override survives refreshes for `ttlMs` ms (default 90 s), giving\n * GitHub Projects v2 time to propagate the change.\n */\n const registerPendingMutation = useCallback(\n (\n repoName: string,\n issueNumber: number,\n fields: Pick<PendingMutation, \"projectStatus\">,\n ttlMs = 90_000,\n ) => {\n pendingMutationsRef.current.set(`${repoName}:${issueNumber}`, {\n ...fields,\n expiresAt: Date.now() + ttlMs,\n });\n },\n [],\n );\n\n /** Remove a pending mutation immediately (call on action failure before refresh). */\n const clearPendingMutation = useCallback((repoName: string, issueNumber: number) => {\n pendingMutationsRef.current.delete(`${repoName}:${issueNumber}`);\n }, []);\n\n return {\n ...state,\n refresh,\n mutateData,\n pauseAutoRefresh,\n resumeAutoRefresh,\n registerPendingMutation,\n clearPendingMutation,\n };\n}\n","import { useInput } from \"ink\";\nimport { useCallback } from \"react\";\nimport type { GitHubIssue } from \"../../github.js\";\nimport type { UseMultiSelectResult } from \"./use-multi-select.js\";\nimport type { UseNavigationResult } from \"./use-navigation.js\";\nimport type { PanelId } from \"./use-panel-focus.js\";\nimport type { UseUIStateResult } from \"./use-ui-state.js\";\n\n// ── Types ──\n\ninterface KeyboardActions {\n exit: () => void;\n refresh: () => void;\n handleSlack: () => void;\n handleCopyLink: () => void;\n handleOpen: () => void;\n handleEnterFocus: () => void;\n handlePick: () => void;\n handleAssign: () => void;\n handleEnterLabel: () => void;\n handleEnterCreateNl: () => void;\n handleErrorAction: (action: \"dismiss\" | \"retry\") => boolean;\n toastInfo: (msg: string) => void;\n handleToggleMine: () => void;\n handleEnterFuzzyPicker: () => void;\n handleEnterEditIssue: () => void;\n handleUndo: () => void;\n handleToggleLog: () => void;\n handleLaunchClaude: () => void;\n}\n\ninterface PanelNav {\n moveUp: () => void;\n moveDown: () => void;\n}\n\ninterface UseKeyboardOptions {\n ui: UseUIStateResult;\n /** Issues panel (3) navigation */\n nav: Pick<UseNavigationResult, \"moveUp\" | \"moveDown\" | \"selectedId\">;\n multiSelect: Pick<UseMultiSelectResult, \"count\" | \"toggle\" | \"clear\">;\n selectedIssue: GitHubIssue | null;\n selectedRepoStatusOptionsLength: number;\n actions: KeyboardActions;\n onSearchEscape: () => void;\n panelFocus: { activePanelId: PanelId; focusPanel: (id: PanelId) => void };\n reposNav: PanelNav;\n statusesNav: PanelNav;\n activityNav: PanelNav;\n onRepoEnter: () => void;\n onStatusEnter: () => void;\n onActivityEnter: () => void;\n /** Whether the detail panel is visible as a side-by-side column (wide layout). */\n showDetailPanel: boolean;\n}\n\n/** Sets up all useInput keyboard handlers for the board. */\nexport function useKeyboard({\n ui,\n nav,\n multiSelect,\n selectedIssue,\n selectedRepoStatusOptionsLength,\n actions,\n onSearchEscape,\n panelFocus,\n reposNav,\n statusesNav,\n activityNav,\n onRepoEnter,\n onStatusEnter,\n onActivityEnter,\n showDetailPanel,\n}: UseKeyboardOptions): void {\n const {\n exit,\n refresh,\n handleSlack,\n handleCopyLink,\n handleOpen,\n handleEnterFocus,\n handlePick,\n handleAssign,\n handleEnterLabel,\n handleEnterCreateNl,\n handleErrorAction,\n toastInfo,\n handleToggleMine,\n handleEnterFuzzyPicker,\n handleEnterEditIssue,\n handleUndo,\n handleToggleLog,\n handleLaunchClaude,\n } = actions;\n\n const handleInput = useCallback(\n (\n input: string,\n key: {\n downArrow: boolean;\n upArrow: boolean;\n tab: boolean;\n shift: boolean;\n return: boolean;\n escape: boolean;\n },\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: keyboard handler with many shortcuts\n ) => {\n // Help toggle works in any state\n if (input === \"?\") {\n ui.toggleHelp();\n return;\n }\n\n // Escape: in multiSelect, clear selection and return to normal\n // In focus mode, FocusMode component handles Escape\n if (key.escape && ui.state.mode !== \"focus\") {\n if (ui.state.mode === \"multiSelect\") {\n multiSelect.clear();\n }\n ui.exitOverlay();\n return;\n }\n\n // Navigation (works in normal, multiSelect, focus)\n if (ui.canNavigate) {\n if (input === \"j\" || key.downArrow) {\n switch (panelFocus.activePanelId) {\n case 1:\n reposNav.moveDown();\n break;\n case 2:\n statusesNav.moveDown();\n break;\n case 3:\n nav.moveDown();\n break;\n case 4:\n activityNav.moveDown();\n break;\n default:\n break; // panel 0 (detail): no-op\n }\n return;\n }\n if (input === \"k\" || key.upArrow) {\n switch (panelFocus.activePanelId) {\n case 1:\n reposNav.moveUp();\n break;\n case 2:\n statusesNav.moveUp();\n break;\n case 3:\n nav.moveUp();\n break;\n case 4:\n activityNav.moveUp();\n break;\n default:\n break; // panel 0 (detail): no-op\n }\n return;\n }\n }\n\n // Multi-select mode actions\n if (ui.state.mode === \"multiSelect\") {\n // Space toggles selection on current item\n if (input === \" \") {\n const id = nav.selectedId;\n if (id) {\n multiSelect.toggle(id);\n }\n return;\n }\n // Enter opens bulk action menu when items are selected\n if (key.return) {\n if (multiSelect.count > 0) {\n ui.enterBulkAction();\n }\n return;\n }\n // 'm' in multiSelect with selection opens bulk action menu\n if (input === \"m\" && multiSelect.count > 0) {\n ui.enterBulkAction();\n return;\n }\n return; // No other actions in multiSelect mode\n }\n\n // Toast error actions (dismiss/retry) — work in normal mode\n if (input === \"d\") {\n if (handleErrorAction(\"dismiss\")) return;\n }\n if (input === \"r\" && handleErrorAction(\"retry\")) return;\n\n // Issue actions that also work from the detail overlay\n if (ui.canAct || ui.state.mode === \"overlay:detail\") {\n if (input === \"y\") {\n handleCopyLink();\n return;\n }\n if (input === \"o\") {\n handleSlack();\n return;\n }\n if (input === \"c\") {\n if (selectedIssue) {\n multiSelect.clear();\n ui.enterComment();\n }\n return;\n }\n if (input === \"e\") {\n if (selectedIssue) {\n handleEnterEditIssue();\n }\n return;\n }\n if (input === \"C\") {\n handleLaunchClaude();\n return;\n }\n if (input === \"g\") {\n handleOpen();\n return;\n }\n }\n\n // Actions (only in normal mode)\n if (ui.canAct) {\n // Digit 0-4: focus panel by number.\n // On narrow layouts digit 0 opens the detail overlay (panel is not visible).\n const digit = parseInt(input, 10);\n if (!Number.isNaN(digit) && digit >= 0 && digit <= 4) {\n if (digit === 0 && !showDetailPanel) {\n ui.enterDetail();\n } else {\n panelFocus.focusPanel(digit as PanelId);\n }\n return;\n }\n\n if (input === \"/\") {\n multiSelect.clear();\n ui.enterSearch();\n return;\n }\n if (input === \"q\") {\n exit();\n return;\n }\n if (input === \"r\" || input === \"R\") {\n multiSelect.clear();\n refresh();\n return;\n }\n if (input === \"p\") {\n handlePick();\n return;\n }\n if (input === \"a\") {\n handleAssign();\n return;\n }\n if (input === \"u\") {\n handleUndo();\n return;\n }\n if (input === \"L\") {\n handleToggleLog();\n return;\n }\n if (input === \"m\") {\n if (selectedIssue && selectedRepoStatusOptionsLength > 0) {\n multiSelect.clear();\n ui.enterStatus();\n } else if (selectedIssue) {\n toastInfo(\"Issue not in a project board\");\n }\n return;\n }\n if (input === \"n\") {\n multiSelect.clear();\n ui.enterCreate();\n return;\n }\n if (input === \"f\") {\n handleEnterFocus();\n return;\n }\n if (input === \"l\") {\n if (selectedIssue) {\n multiSelect.clear();\n handleEnterLabel();\n }\n return;\n }\n if (input === \"I\") {\n handleEnterCreateNl();\n return;\n }\n if (input === \"t\") {\n handleToggleMine();\n return;\n }\n if (input === \"F\") {\n handleEnterFuzzyPicker();\n return;\n }\n\n // Space on an item: toggle selection + enter multiSelect mode\n if (input === \" \") {\n const id = nav.selectedId;\n if (id) {\n multiSelect.toggle(id);\n ui.enterMultiSelect();\n }\n return;\n }\n\n if (key.return) {\n switch (panelFocus.activePanelId) {\n case 1:\n onRepoEnter();\n break;\n case 2:\n onStatusEnter();\n break;\n case 3:\n if (showDetailPanel) {\n panelFocus.focusPanel(0);\n } else {\n ui.enterDetail();\n }\n break;\n case 4:\n onActivityEnter();\n break;\n default:\n break; // panel 0 (detail): no-op\n }\n return;\n }\n }\n },\n [\n ui,\n nav,\n panelFocus,\n reposNav,\n statusesNav,\n activityNav,\n onRepoEnter,\n onStatusEnter,\n onActivityEnter,\n exit,\n refresh,\n handleSlack,\n handleCopyLink,\n handleOpen,\n handlePick,\n handleAssign,\n handleEnterLabel,\n handleEnterCreateNl,\n selectedIssue,\n selectedRepoStatusOptionsLength,\n toastInfo,\n nav.selectedId,\n multiSelect,\n handleEnterFocus,\n handleErrorAction,\n handleToggleMine,\n handleEnterFuzzyPicker,\n handleEnterEditIssue,\n handleUndo,\n handleToggleLog,\n handleLaunchClaude,\n showDetailPanel,\n ],\n );\n\n // Active when NOT in a text-input overlay.\n // overlay:detail needs Escape to close, so it must remain active.\n const inputActive =\n ui.state.mode === \"normal\" ||\n ui.state.mode === \"multiSelect\" ||\n ui.state.mode === \"focus\" ||\n ui.state.mode === \"overlay:detail\";\n useInput(handleInput, { isActive: inputActive });\n\n // Search mode input handler\n const handleSearchEscape = useCallback(\n (_input: string, key: { escape: boolean }) => {\n if (key.escape) {\n onSearchEscape();\n }\n },\n [onSearchEscape],\n );\n useInput(handleSearchEscape, { isActive: ui.state.mode === \"search\" });\n}\n","import { useCallback, useRef, useState } from \"react\";\n\nexport interface UseMultiSelectResult {\n /** Currently selected item IDs */\n selected: ReadonlySet<string>;\n /** How many items are selected */\n count: number;\n /** Whether a specific item is selected */\n isSelected: (id: string) => boolean;\n /** Toggle selection for one item. Returns the new set. */\n toggle: (id: string) => void;\n /** Clear all selections */\n clear: () => void;\n /** Remove selected IDs that are no longer in the valid set */\n prune: (validIds: ReadonlySet<string>) => void;\n /** The repo constraint — only items from this repo can be selected */\n constrainedRepo: string | null;\n}\n\n/**\n * Tracks multi-select state for the board.\n *\n * Constraint: all selected items must belong to the same repo section.\n * If the user toggles an item from a different repo, the selection resets\n * to just that item.\n */\nexport function useMultiSelect(getRepoForId: (id: string) => string | null): UseMultiSelectResult {\n const [selected, setSelected] = useState<ReadonlySet<string>>(new Set());\n const repoRef = useRef<string | null>(null);\n const getRepoRef = useRef(getRepoForId);\n getRepoRef.current = getRepoForId;\n\n const toggle = useCallback((id: string) => {\n setSelected((prev) => {\n const repo = getRepoRef.current(id);\n // Headers and non-repo items can't be selected\n if (!repo) return prev;\n\n const next = new Set(prev);\n\n if (next.has(id)) {\n next.delete(id);\n if (next.size === 0) repoRef.current = null;\n } else {\n // Different repo? Reset to just this item\n if (repoRef.current && repoRef.current !== repo) {\n next.clear();\n }\n repoRef.current = repo;\n next.add(id);\n }\n return next;\n });\n }, []);\n\n const clear = useCallback(() => {\n setSelected(new Set());\n repoRef.current = null;\n }, []);\n\n const prune = useCallback((validIds: ReadonlySet<string>) => {\n setSelected((prev) => {\n const next = new Set<string>();\n for (const id of prev) {\n if (validIds.has(id)) next.add(id);\n }\n if (next.size === prev.size) return prev; // no change\n if (next.size === 0) repoRef.current = null;\n return next;\n });\n }, []);\n\n const isSelected = useCallback((id: string) => selected.has(id), [selected]);\n\n return {\n selected,\n count: selected.size,\n isSelected,\n toggle,\n clear,\n prune,\n constrainedRepo: repoRef.current,\n };\n}\n","import { useCallback, useMemo, useReducer, useRef } from \"react\";\n\nexport type SectionId = string;\n\nexport interface NavItem {\n id: string;\n section: SectionId;\n type: \"header\" | \"subHeader\" | \"item\";\n subSection?: SectionId;\n}\n\ninterface NavState {\n selectedId: string | null;\n /** Section of the currently selected item (used for fallback when item disappears) */\n selectedSection: SectionId | null;\n sections: SectionId[];\n collapsedSections: Set<SectionId>;\n /** Full item list, kept in state so reducer can relocate cursor on collapse */\n allItems: NavItem[];\n}\n\ntype NavAction =\n | { type: \"SET_ITEMS\"; items: NavItem[] }\n | { type: \"SELECT\"; id: string; section?: SectionId | undefined }\n | { type: \"TOGGLE_SECTION\"; section: SectionId }\n | { type: \"COLLAPSE_ALL\" };\n\nfunction arraysEqual(a: string[], b: string[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\n/** Find a fallback item when the selected item disappears from the list. */\nexport function findFallback(items: NavItem[], oldSection: SectionId | null): NavItem | undefined {\n if (oldSection) {\n // Prefer next item in same section (skip headers/subHeaders)\n const sectionItem = items.find((i) => i.section === oldSection && i.type === \"item\");\n if (sectionItem) return sectionItem;\n // Section header as last resort within section\n const sectionHeader = items.find((i) => i.section === oldSection && i.type === \"header\");\n if (sectionHeader) return sectionHeader;\n }\n // Fall back to first header globally\n return items.find((i) => i.type === \"header\") ?? items[0];\n}\n\n/** When collapsing a section/sub-section, return new cursor if the selected item becomes hidden. */\nfunction relocateOnToggle(\n state: NavState,\n section: SectionId,\n): Pick<NavState, \"selectedId\" | \"selectedSection\"> {\n if (!state.selectedId) return { selectedId: null, selectedSection: null };\n const selected = state.allItems.find((i) => i.id === state.selectedId);\n if (!selected) return { selectedId: state.selectedId, selectedSection: state.selectedSection };\n const insideCollapsedSubSection = selected.subSection === section;\n const insideCollapsedSection =\n !insideCollapsedSubSection && selected.section === section && selected.type !== \"header\";\n if (insideCollapsedSubSection) {\n const subHeader = state.allItems.find((i) => i.id === section && i.type === \"subHeader\");\n if (subHeader) return { selectedId: subHeader.id, selectedSection: subHeader.section };\n } else if (insideCollapsedSection) {\n const header = state.allItems.find((i) => i.section === section && i.type === \"header\");\n if (header) return { selectedId: header.id, selectedSection: header.section };\n }\n return { selectedId: state.selectedId, selectedSection: state.selectedSection };\n}\n\n/** When collapsing all, return cursor relocated to section header if currently on a non-header item. */\nfunction relocateOnCollapseAll(state: NavState): Pick<NavState, \"selectedId\" | \"selectedSection\"> {\n if (!state.selectedId) return { selectedId: null, selectedSection: null };\n const selected = state.allItems.find((i) => i.id === state.selectedId);\n if (!selected || selected.type === \"header\") {\n return { selectedId: state.selectedId, selectedSection: state.selectedSection };\n }\n const header = state.allItems.find((i) => i.section === selected.section && i.type === \"header\");\n if (header) return { selectedId: header.id, selectedSection: header.section };\n return { selectedId: state.selectedId, selectedSection: state.selectedSection };\n}\n\nfunction navReducer(state: NavState, action: NavAction): NavState {\n switch (action.type) {\n case \"SET_ITEMS\": {\n const sections = [...new Set(action.items.map((i) => i.section))];\n const isFirstLoad = state.sections.length === 0;\n // On first load: expand all sections except Activity (collapse it by default)\n // On refresh: preserve collapsed state, pruning orphan keys that no longer exist\n let collapsedSections: Set<SectionId>;\n if (isFirstLoad) {\n collapsedSections = new Set(sections.filter((s) => s === \"activity\"));\n } else {\n // Prune orphan keys — only keep IDs that still exist in the new tree\n const validIds = new Set<SectionId>([\n ...sections,\n ...action.items.filter((i) => i.type === \"subHeader\").map((i) => i.id),\n ]);\n collapsedSections = new Set([...state.collapsedSections].filter((id) => validIds.has(id)));\n }\n const selectionValid =\n state.selectedId != null && action.items.some((i) => i.id === state.selectedId);\n\n // Bail out if nothing meaningful changed (same sections, valid selection).\n // Still update allItems so relocateOnToggle/relocateOnCollapseAll use\n // current item positions — e.g. when an issue moves sub-sections after a\n // status change or new issues arrive from a background refresh.\n if (!isFirstLoad && selectionValid && arraysEqual(sections, state.sections)) {\n return state.allItems === action.items ? state : { ...state, allItems: action.items };\n }\n\n if (selectionValid) {\n // Update selectedSection in case it wasn't set yet (e.g., first load)\n const selected = action.items.find((i) => i.id === state.selectedId);\n return {\n ...state,\n selectedSection: selected?.section ?? state.selectedSection,\n sections,\n collapsedSections,\n allItems: action.items,\n };\n }\n\n // Selected item disappeared — find best fallback\n const fallback = findFallback(action.items, state.selectedSection);\n return {\n selectedId: fallback?.id ?? null,\n selectedSection: fallback?.section ?? null,\n sections,\n collapsedSections,\n allItems: action.items,\n };\n }\n case \"SELECT\": {\n return {\n ...state,\n selectedId: action.id,\n selectedSection: action.section ?? state.selectedSection,\n };\n }\n case \"TOGGLE_SECTION\": {\n const next = new Set(state.collapsedSections);\n const isCollapsing = !next.has(action.section);\n if (isCollapsing) {\n next.add(action.section);\n const cursor = relocateOnToggle(state, action.section);\n return { ...state, collapsedSections: next, ...cursor };\n }\n next.delete(action.section);\n return { ...state, collapsedSections: next };\n }\n case \"COLLAPSE_ALL\": {\n const next = new Set(state.sections);\n const cursor = relocateOnCollapseAll(state);\n return { ...state, collapsedSections: next, ...cursor };\n }\n default:\n return state;\n }\n}\n\n/** Returns only items that should be navigable (headers + non-collapsed items). */\nfunction getVisibleItems(allItems: NavItem[], collapsedSections: Set<SectionId>): NavItem[] {\n return allItems.filter((item) => {\n if (item.type === \"header\") return true;\n if (collapsedSections.has(item.section)) return false;\n if (item.type === \"subHeader\") return true;\n if (item.subSection && collapsedSections.has(item.subSection)) return false;\n return true;\n });\n}\n\nexport interface UseNavigationResult {\n selectedId: string | null;\n selectedIndex: number;\n collapsedSections: Set<SectionId>;\n moveUp: () => void;\n moveDown: () => void;\n nextSection: () => void;\n prevSection: () => void;\n toggleSection: () => void;\n collapseAll: () => void;\n select: (id: string) => void;\n isCollapsed: (section: SectionId) => boolean;\n}\n\nexport function useNavigation(allItems: NavItem[]): UseNavigationResult {\n const [state, dispatch] = useReducer(navReducer, {\n selectedId: null,\n selectedSection: null,\n sections: [],\n collapsedSections: new Set<SectionId>(),\n allItems: [],\n });\n\n // Sync items into reducer when they change (by reference comparison).\n // Dispatching during render is safe here: the ref prevents re-dispatch\n // on the subsequent re-render since allItems will be the same reference.\n const prevItemsRef = useRef<NavItem[] | null>(null);\n if (allItems !== prevItemsRef.current) {\n prevItemsRef.current = allItems;\n dispatch({ type: \"SET_ITEMS\", items: allItems });\n }\n\n const visibleItems = useMemo(\n () => getVisibleItems(allItems, state.collapsedSections),\n [allItems, state.collapsedSections],\n );\n\n const selectedIndex = useMemo(() => {\n if (!state.selectedId) return 0;\n const idx = visibleItems.findIndex((i) => i.id === state.selectedId);\n return idx >= 0 ? idx : 0;\n }, [state.selectedId, visibleItems]);\n\n const moveUp = useCallback(() => {\n const newIdx = Math.max(0, selectedIndex - 1);\n const item = visibleItems[newIdx];\n if (item) dispatch({ type: \"SELECT\", id: item.id, section: item.section });\n }, [selectedIndex, visibleItems]);\n\n const moveDown = useCallback(() => {\n const newIdx = Math.min(visibleItems.length - 1, selectedIndex + 1);\n const item = visibleItems[newIdx];\n if (item) dispatch({ type: \"SELECT\", id: item.id, section: item.section });\n }, [selectedIndex, visibleItems]);\n\n const nextSection = useCallback(() => {\n const currentItem = visibleItems[selectedIndex];\n if (!currentItem) return;\n const currentSectionIdx = state.sections.indexOf(currentItem.section);\n const nextSectionId = state.sections[currentSectionIdx + 1];\n if (!nextSectionId) return;\n const header = visibleItems.find((i) => i.section === nextSectionId && i.type === \"header\");\n if (header) dispatch({ type: \"SELECT\", id: header.id, section: header.section });\n }, [selectedIndex, visibleItems, state.sections]);\n\n const prevSection = useCallback(() => {\n const currentItem = visibleItems[selectedIndex];\n if (!currentItem) return;\n const currentSectionIdx = state.sections.indexOf(currentItem.section);\n const prevSectionId = state.sections[currentSectionIdx - 1];\n if (!prevSectionId) return;\n const header = visibleItems.find((i) => i.section === prevSectionId && i.type === \"header\");\n if (header) dispatch({ type: \"SELECT\", id: header.id, section: header.section });\n }, [selectedIndex, visibleItems, state.sections]);\n\n const toggleSection = useCallback(() => {\n const currentItem = visibleItems[selectedIndex];\n if (!currentItem) return;\n // Only headers and subHeaders are toggle targets; items have no collapse behaviour\n if (currentItem.type === \"item\") return;\n // Sub-headers toggle their own ID (used as sub-section key); headers toggle the section\n const key = currentItem.type === \"subHeader\" ? currentItem.id : currentItem.section;\n dispatch({ type: \"TOGGLE_SECTION\", section: key });\n }, [selectedIndex, visibleItems]);\n\n const collapseAll = useCallback(() => {\n dispatch({ type: \"COLLAPSE_ALL\" });\n }, []);\n\n const allItemsRef = useRef(allItems);\n allItemsRef.current = allItems;\n\n const select = useCallback((id: string) => {\n const item = allItemsRef.current.find((i) => i.id === id);\n dispatch({ type: \"SELECT\", id, section: item?.section });\n }, []);\n\n const isCollapsed = useCallback(\n (section: SectionId) => state.collapsedSections.has(section),\n [state.collapsedSections],\n );\n\n return {\n selectedId: state.selectedId,\n selectedIndex,\n collapsedSections: state.collapsedSections,\n moveUp,\n moveDown,\n nextSection,\n prevSection,\n toggleSection,\n collapseAll,\n select,\n isCollapsed,\n };\n}\n","import { useCallback, useState } from \"react\";\n\n// ── Types ──\n\n/** 0=Detail, 1=Repos, 2=Statuses, 3=Issues, 4=Activity */\nexport type PanelId = 0 | 1 | 2 | 3 | 4;\n\nexport interface UsePanelFocusResult {\n activePanelId: PanelId;\n focusPanel: (id: PanelId) => void;\n isPanelActive: (id: PanelId) => boolean;\n}\n\n// ── Hook ──\n\nexport function usePanelFocus(initialPanel: PanelId = 3): UsePanelFocusResult {\n const [activePanelId, setActivePanelId] = useState<PanelId>(initialPanel);\n\n const focusPanel = useCallback((id: PanelId) => {\n setActivePanelId(id);\n }, []);\n\n const isPanelActive = useCallback((id: PanelId) => activePanelId === id, [activePanelId]);\n\n return { activePanelId, focusPanel, isPanelActive };\n}\n","import { useCallback, useRef, useState } from \"react\";\n\nexport interface Toast {\n id: string;\n type: \"info\" | \"success\" | \"error\" | \"loading\";\n message: string;\n retry?: () => void;\n createdAt: number;\n}\n\nexport interface ToastAPI {\n info: (message: string) => void;\n success: (message: string) => void;\n error: (message: string, retry?: () => void) => void;\n loading: (message: string) => { resolve: (msg: string) => void; reject: (msg: string) => void };\n}\n\nexport interface UseToastResult {\n toasts: Toast[];\n toast: ToastAPI;\n /** Dismiss oldest error toast, or call its retry. Returns true if handled. */\n handleErrorAction: (action: \"dismiss\" | \"retry\") => boolean;\n}\n\nconst MAX_VISIBLE = 3;\nconst AUTO_DISMISS_MS = 3000;\n\nlet nextId = 0;\n\nexport function useToast(): UseToastResult {\n const [toasts, setToasts] = useState<Toast[]>([]);\n const timersRef = useRef<Map<string, ReturnType<typeof setTimeout>>>(new Map());\n\n const clearTimer = useCallback((id: string) => {\n const timer = timersRef.current.get(id);\n if (timer) {\n clearTimeout(timer);\n timersRef.current.delete(id);\n }\n }, []);\n\n const removeToast = useCallback(\n (id: string) => {\n clearTimer(id);\n setToasts((prev) => prev.filter((t) => t.id !== id));\n },\n [clearTimer],\n );\n\n const addToast = useCallback(\n (t: Omit<Toast, \"id\" | \"createdAt\">): string => {\n const id = `toast-${++nextId}`;\n const newToast: Toast = { ...t, id, createdAt: Date.now() };\n\n setToasts((prev) => {\n const next = [...prev, newToast];\n // Enforce max visible: evict oldest dismissable toast\n while (next.length > MAX_VISIBLE) {\n const evictIdx = next.findIndex((x) => x.type !== \"error\" && x.type !== \"loading\");\n if (evictIdx >= 0) {\n const evictToast = next[evictIdx];\n if (evictToast) clearTimer(evictToast.id);\n next.splice(evictIdx, 1);\n } else {\n // All are persistent — evict oldest anyway\n const oldest = next[0];\n if (oldest) clearTimer(oldest.id);\n next.shift();\n }\n }\n return next;\n });\n\n // Auto-dismiss for info/success\n if (t.type === \"info\" || t.type === \"success\") {\n const timer = setTimeout(() => removeToast(id), AUTO_DISMISS_MS);\n timersRef.current.set(id, timer);\n }\n\n return id;\n },\n [removeToast, clearTimer],\n );\n\n const toast: ToastAPI = {\n info: useCallback(\n (message: string) => {\n addToast({ type: \"info\", message });\n },\n [addToast],\n ),\n\n success: useCallback(\n (message: string) => {\n addToast({ type: \"success\", message });\n },\n [addToast],\n ),\n\n error: useCallback(\n (message: string, retry?: () => void) => {\n addToast(retry ? { type: \"error\", message, retry } : { type: \"error\", message });\n },\n [addToast],\n ),\n\n loading: useCallback(\n (message: string) => {\n const id = addToast({ type: \"loading\", message });\n return {\n resolve: (msg: string) => {\n removeToast(id);\n addToast({ type: \"success\", message: msg });\n },\n reject: (msg: string) => {\n removeToast(id);\n addToast({ type: \"error\", message: msg });\n },\n };\n },\n [addToast, removeToast],\n ),\n };\n\n const handleErrorAction = useCallback(\n (action: \"dismiss\" | \"retry\"): boolean => {\n const errorToast = toasts.find((t) => t.type === \"error\");\n if (!errorToast) return false;\n\n if (action === \"retry\" && errorToast.retry) {\n removeToast(errorToast.id);\n errorToast.retry();\n return true;\n }\n if (action === \"dismiss\") {\n removeToast(errorToast.id);\n return true;\n }\n return false;\n },\n [toasts, removeToast],\n );\n\n return { toasts, toast, handleErrorAction };\n}\n","import { useCallback, useReducer } from \"react\";\n\n// ── UI States ──\n\nexport type UIMode =\n | \"normal\"\n | \"search\"\n | \"overlay:comment\"\n | \"overlay:status\"\n | \"overlay:create\"\n | \"overlay:createNl\"\n | \"overlay:label\"\n | \"overlay:bulkAction\"\n | \"overlay:confirmPick\"\n | \"overlay:help\"\n | \"overlay:fuzzyPicker\"\n | \"overlay:editIssue\"\n | \"overlay:detail\"\n | \"multiSelect\"\n | \"focus\";\n\nexport interface UIState {\n mode: UIMode;\n /** Help overlay stacks on top of any mode */\n helpVisible: boolean;\n /** Previous mode to return to (for overlays) */\n previousMode: UIMode;\n}\n\n// ── Actions ──\n\nexport type UIAction =\n | { type: \"ENTER_SEARCH\" }\n | { type: \"ENTER_COMMENT\" }\n | { type: \"ENTER_STATUS\" }\n | { type: \"ENTER_CREATE\" }\n | { type: \"ENTER_CREATE_NL\" }\n | { type: \"ENTER_LABEL\" }\n | { type: \"ENTER_MULTI_SELECT\" }\n | { type: \"ENTER_BULK_ACTION\" }\n | { type: \"ENTER_CONFIRM_PICK\" }\n | { type: \"ENTER_FOCUS\" }\n | { type: \"ENTER_FUZZY_PICKER\" }\n | { type: \"ENTER_EDIT_ISSUE\" }\n | { type: \"ENTER_DETAIL\" }\n | { type: \"TOGGLE_HELP\" }\n | { type: \"EXIT_OVERLAY\" }\n | { type: \"EXIT_TO_NORMAL\" }\n | { type: \"CLEAR_MULTI_SELECT\" };\n\n// ── Reducer ──\n\nconst INITIAL_STATE: UIState = {\n mode: \"normal\",\n helpVisible: false,\n previousMode: \"normal\",\n};\n\nfunction enterStatusMode(state: UIState): UIState {\n if (state.mode !== \"normal\" && state.mode !== \"overlay:bulkAction\") return state;\n const previousMode: UIMode = state.mode === \"overlay:bulkAction\" ? \"multiSelect\" : \"normal\";\n return { ...state, mode: \"overlay:status\", previousMode };\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: UI state machine with many action types\nfunction uiReducer(state: UIState, action: UIAction): UIState {\n switch (action.type) {\n case \"ENTER_SEARCH\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"search\", previousMode: \"normal\" };\n\n case \"ENTER_COMMENT\":\n if (state.mode !== \"normal\" && state.mode !== \"overlay:detail\") return state;\n return { ...state, mode: \"overlay:comment\", previousMode: \"normal\" };\n\n case \"ENTER_STATUS\":\n return enterStatusMode(state);\n\n case \"ENTER_CREATE\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"overlay:create\", previousMode: \"normal\" };\n\n case \"ENTER_CREATE_NL\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"overlay:createNl\", previousMode: \"normal\" };\n\n case \"ENTER_LABEL\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"overlay:label\", previousMode: \"normal\" };\n\n case \"ENTER_MULTI_SELECT\":\n if (state.mode !== \"normal\" && state.mode !== \"multiSelect\") return state;\n return { ...state, mode: \"multiSelect\", previousMode: \"normal\" };\n\n case \"ENTER_BULK_ACTION\":\n if (state.mode !== \"multiSelect\") return state;\n return { ...state, mode: \"overlay:bulkAction\", previousMode: \"multiSelect\" };\n\n case \"ENTER_CONFIRM_PICK\":\n // Can transition from create overlay (after success) or normal\n return { ...state, mode: \"overlay:confirmPick\", previousMode: \"normal\" };\n\n case \"ENTER_FOCUS\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"focus\", previousMode: \"normal\" };\n\n case \"ENTER_FUZZY_PICKER\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"overlay:fuzzyPicker\", previousMode: \"normal\" };\n\n case \"ENTER_EDIT_ISSUE\":\n if (state.mode !== \"normal\" && state.mode !== \"overlay:detail\") return state;\n return { ...state, mode: \"overlay:editIssue\", previousMode: \"normal\" };\n\n case \"ENTER_DETAIL\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"overlay:detail\", previousMode: \"normal\" };\n\n case \"TOGGLE_HELP\":\n // Help stacks on any mode\n return { ...state, helpVisible: !state.helpVisible };\n\n case \"EXIT_OVERLAY\":\n // Close help first if visible, then return to previous mode\n if (state.helpVisible) {\n return { ...state, helpVisible: false };\n }\n return { ...state, mode: state.previousMode, previousMode: \"normal\" };\n\n case \"EXIT_TO_NORMAL\":\n return { ...state, mode: \"normal\", helpVisible: false, previousMode: \"normal\" };\n\n case \"CLEAR_MULTI_SELECT\":\n if (state.mode === \"multiSelect\") {\n return { ...state, mode: \"normal\", previousMode: \"normal\" };\n }\n return state;\n\n default:\n return state;\n }\n}\n\n// ── Derived state helpers ──\n\n/** Whether navigation shortcuts (j/k/tab) should work */\nexport function canNavigate(state: UIState): boolean {\n const { mode } = state;\n return mode === \"normal\" || mode === \"multiSelect\" || mode === \"focus\";\n}\n\n/** Whether action shortcuts (p/a/u/c/m/s/n) should work */\nexport function canAct(state: UIState): boolean {\n return state.mode === \"normal\";\n}\n\n/** Whether the UI is in an overlay/input state */\nexport function isOverlay(state: UIState): boolean {\n return state.mode.startsWith(\"overlay:\") || state.mode === \"search\";\n}\n\n// ── Hook ──\n\nexport interface UseUIStateResult {\n state: UIState;\n enterSearch: () => void;\n enterComment: () => void;\n enterStatus: () => void;\n enterCreate: () => void;\n enterCreateNl: () => void;\n enterLabel: () => void;\n enterMultiSelect: () => void;\n enterBulkAction: () => void;\n enterConfirmPick: () => void;\n enterFocus: () => void;\n enterFuzzyPicker: () => void;\n enterEditIssue: () => void;\n enterDetail: () => void;\n toggleHelp: () => void;\n exitOverlay: () => void;\n exitToNormal: () => void;\n clearMultiSelect: () => void;\n canNavigate: boolean;\n canAct: boolean;\n isOverlay: boolean;\n}\n\nexport function useUIState(): UseUIStateResult {\n const [state, dispatch] = useReducer(uiReducer, INITIAL_STATE);\n\n return {\n state,\n enterSearch: useCallback(() => dispatch({ type: \"ENTER_SEARCH\" }), []),\n enterComment: useCallback(() => dispatch({ type: \"ENTER_COMMENT\" }), []),\n enterStatus: useCallback(() => dispatch({ type: \"ENTER_STATUS\" }), []),\n enterCreate: useCallback(() => dispatch({ type: \"ENTER_CREATE\" }), []),\n enterCreateNl: useCallback(() => dispatch({ type: \"ENTER_CREATE_NL\" }), []),\n enterLabel: useCallback(() => dispatch({ type: \"ENTER_LABEL\" }), []),\n enterMultiSelect: useCallback(() => dispatch({ type: \"ENTER_MULTI_SELECT\" }), []),\n enterBulkAction: useCallback(() => dispatch({ type: \"ENTER_BULK_ACTION\" }), []),\n enterConfirmPick: useCallback(() => dispatch({ type: \"ENTER_CONFIRM_PICK\" }), []),\n enterFocus: useCallback(() => dispatch({ type: \"ENTER_FOCUS\" }), []),\n enterFuzzyPicker: useCallback(() => dispatch({ type: \"ENTER_FUZZY_PICKER\" }), []),\n enterEditIssue: useCallback(() => dispatch({ type: \"ENTER_EDIT_ISSUE\" }), []),\n enterDetail: useCallback(() => dispatch({ type: \"ENTER_DETAIL\" }), []),\n toggleHelp: useCallback(() => dispatch({ type: \"TOGGLE_HELP\" }), []),\n exitOverlay: useCallback(() => dispatch({ type: \"EXIT_OVERLAY\" }), []),\n exitToNormal: useCallback(() => dispatch({ type: \"EXIT_TO_NORMAL\" }), []),\n clearMultiSelect: useCallback(() => dispatch({ type: \"CLEAR_MULTI_SELECT\" }), []),\n canNavigate: canNavigate(state),\n canAct: canAct(state),\n isOverlay: isOverlay(state),\n };\n}\n","import { spawn, spawnSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport type { BoardIssue, Result } from \"../types.js\";\n\n// ── Types ──\n\nexport type LaunchFailureReason =\n | \"no-local-path\"\n | \"directory-not-found\"\n | \"claude-not-found\"\n | \"tmux-failed\"\n | \"terminal-failed\"\n | \"terminal-app-not-found\"\n | \"ssh-no-tmux\";\n\nexport interface LaunchError {\n readonly kind: LaunchFailureReason;\n readonly message: string;\n readonly cause?: Error;\n}\n\nexport type LaunchResult = Result<void, LaunchError>;\n\nexport interface LaunchClaudeOptions {\n readonly localPath: string;\n readonly issue: Pick<BoardIssue, \"number\" | \"title\" | \"url\">;\n readonly startCommand?: { command: string; extraArgs: readonly string[] } | undefined;\n readonly launchMode?: \"auto\" | \"tmux\" | \"terminal\" | undefined;\n readonly terminalApp?: string | undefined;\n readonly repoFullName?: string | undefined;\n}\n\n// ── Helpers ──\n\nexport function buildPrompt(issue: Pick<BoardIssue, \"number\" | \"title\" | \"url\">): string {\n return `Issue #${issue.number}: ${issue.title}\\nURL: ${issue.url}`;\n}\n\nfunction isClaudeInPath(): boolean {\n const result = spawnSync(\"which\", [\"claude\"], { stdio: \"pipe\" });\n return result.status === 0;\n}\n\nfunction isInTmux(): boolean {\n return !!process.env[\"TMUX\"];\n}\n\nfunction isInSsh(): boolean {\n return !!(process.env[\"SSH_CLIENT\"] ?? process.env[\"SSH_TTY\"]);\n}\n\nfunction detectTerminalApp(): string | undefined {\n return process.env[\"TERM_PROGRAM\"];\n}\n\nfunction resolveCommand(opts: LaunchClaudeOptions): {\n command: string;\n extraArgs: readonly string[];\n} {\n if (opts.startCommand) return opts.startCommand;\n return { command: \"claude\", extraArgs: [] };\n}\n\nfunction launchViaTmux(opts: LaunchClaudeOptions): LaunchResult {\n const { localPath, issue, repoFullName } = opts;\n const { command, extraArgs } = resolveCommand(opts);\n const prompt = buildPrompt(issue);\n\n const windowName = `claude-${issue.number}`;\n const tmuxArgs = [\n \"new-window\",\n \"-d\", // don't steal focus from hog board\n \"-c\",\n localPath,\n \"-n\",\n windowName,\n ];\n\n if (repoFullName) {\n tmuxArgs.push(\"-e\", `HOG_REPO=${repoFullName}`);\n }\n tmuxArgs.push(\"-e\", `HOG_ISSUE=${issue.number}`);\n\n // Build the shell command: command [extraArgs...] -- prompt\n tmuxArgs.push(command, ...extraArgs, \"--\", prompt);\n\n const child = spawn(\"tmux\", tmuxArgs, { stdio: \"ignore\", detached: true });\n child.unref();\n\n return { ok: true, value: undefined };\n}\n\nfunction launchViaTerminalApp(terminalApp: string, opts: LaunchClaudeOptions): LaunchResult {\n const { localPath, issue } = opts;\n const { command, extraArgs } = resolveCommand(opts);\n const prompt = buildPrompt(issue);\n\n const fullCmd = [command, ...extraArgs, \"--\", prompt].join(\" \");\n\n switch (terminalApp) {\n case \"iTerm\": {\n // iTerm2: use AppleScript to open a new window with the correct cwd\n const script = `tell application \"iTerm\"\n create window with default profile command \"bash -c 'cd ${localPath} && ${fullCmd}'\"\nend tell`;\n const result = spawnSync(\"osascript\", [\"-e\", script], { stdio: \"ignore\" });\n if (result.status !== 0) {\n return {\n ok: false,\n error: {\n kind: \"terminal-failed\",\n message: `iTerm2 launch failed. Is iTerm2 installed and running?`,\n },\n };\n }\n return { ok: true, value: undefined };\n }\n\n case \"Terminal\": {\n const child = spawn(\"open\", [\"-a\", \"Terminal\", localPath], {\n stdio: \"ignore\",\n detached: true,\n });\n child.unref();\n return { ok: true, value: undefined };\n }\n\n case \"Ghostty\": {\n const child = spawn(\n \"open\",\n [\"-na\", \"Ghostty\", \"--args\", `--working-directory=${localPath}`],\n { stdio: \"ignore\", detached: true },\n );\n child.unref();\n return { ok: true, value: undefined };\n }\n\n case \"WezTerm\": {\n const child = spawn(\"wezterm\", [\"start\", \"--cwd\", localPath], {\n stdio: \"ignore\",\n detached: true,\n });\n child.unref();\n return { ok: true, value: undefined };\n }\n\n case \"Kitty\": {\n const child = spawn(\n \"kitty\",\n [\"--directory\", localPath, command, ...extraArgs, \"--\", prompt],\n {\n stdio: \"ignore\",\n detached: true,\n },\n );\n child.unref();\n return { ok: true, value: undefined };\n }\n\n case \"Alacritty\": {\n const child = spawn(\n \"alacritty\",\n [\"--command\", \"bash\", \"-c\", `cd ${localPath} && ${fullCmd}`],\n { stdio: \"ignore\", detached: true },\n );\n child.unref();\n return { ok: true, value: undefined };\n }\n\n default:\n return {\n ok: false,\n error: {\n kind: \"terminal-app-not-found\",\n message: `Unknown terminal app: ${terminalApp}`,\n },\n };\n }\n}\n\nfunction launchViaDetectedTerminal(opts: LaunchClaudeOptions): LaunchResult {\n const { terminalApp } = opts;\n\n // Use configured terminal app if specified\n if (terminalApp) {\n return launchViaTerminalApp(terminalApp, opts);\n }\n\n // Detect terminal from environment\n const termProgram = detectTerminalApp();\n\n if (termProgram === \"iTerm.app\") {\n return launchViaTerminalApp(\"iTerm\", opts);\n }\n\n if (termProgram === \"Apple_Terminal\") {\n return launchViaTerminalApp(\"Terminal\", opts);\n }\n\n if (termProgram === \"WezTerm\") {\n return launchViaTerminalApp(\"WezTerm\", opts);\n }\n\n if (termProgram === \"ghostty\") {\n return launchViaTerminalApp(\"Ghostty\", opts);\n }\n\n // Check for kitty via env var (TERM_PROGRAM not set for kitty)\n if (process.env[\"KITTY_WINDOW_ID\"]) {\n return launchViaTerminalApp(\"Kitty\", opts);\n }\n\n // macOS fallback: Terminal.app is always present\n if (process.platform === \"darwin\") {\n return launchViaTerminalApp(\"Terminal\", opts);\n }\n\n // Linux: try xdg-terminal-exec or gnome-terminal\n const { localPath, issue } = opts;\n const { command, extraArgs } = resolveCommand(opts);\n const prompt = buildPrompt(issue);\n\n const child = spawn(\n \"xdg-terminal-exec\",\n [\"bash\", \"-c\", `cd ${localPath} && ${[command, ...extraArgs, \"--\", prompt].join(\" \")}`],\n { stdio: \"ignore\", detached: true },\n );\n child.unref();\n return { ok: true, value: undefined };\n}\n\n// ── Main export ──\n\nexport function launchClaude(opts: LaunchClaudeOptions): LaunchResult {\n const { localPath, launchMode = \"auto\" } = opts;\n\n // Guard: directory must exist\n if (!existsSync(localPath)) {\n return {\n ok: false,\n error: {\n kind: \"directory-not-found\",\n message: `Directory not found: ${localPath}. Check localPath config.`,\n },\n };\n }\n\n // Guard: claude binary must be in PATH\n if (!isClaudeInPath()) {\n return {\n ok: false,\n error: {\n kind: \"claude-not-found\",\n message: \"claude binary not found in PATH. Install Claude Code first.\",\n },\n };\n }\n\n // SSH without tmux: cannot open a local terminal window\n if (isInSsh() && !isInTmux() && launchMode !== \"tmux\") {\n return {\n ok: false,\n error: {\n kind: \"ssh-no-tmux\",\n message: \"Running over SSH without tmux — start tmux to enable Claude Code launch.\",\n },\n };\n }\n\n const useTmux = launchMode === \"tmux\" || (launchMode === \"auto\" && isInTmux());\n\n if (useTmux) {\n const result = launchViaTmux(opts);\n if (!result.ok) {\n // If forced tmux, no fallback\n if (launchMode === \"tmux\") {\n return {\n ok: false,\n error: {\n kind: \"tmux-failed\",\n message: \"tmux launch failed. Is tmux running?\",\n },\n };\n }\n // Auto mode: fall back to terminal\n return launchViaDetectedTerminal(opts);\n }\n return result;\n }\n\n // Force terminal or auto (not in tmux)\n return launchViaDetectedTerminal(opts);\n}\n","import { Box, Text } from \"ink\";\nimport { useEffect, useState } from \"react\";\nimport type { ActionLogEntry } from \"../hooks/use-action-log.js\";\n\ninterface ActionLogProps {\n readonly entries: ActionLogEntry[];\n}\n\nfunction relativeTime(ago: number): string {\n const seconds = Math.floor((Date.now() - ago) / 1000);\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h ago`;\n}\n\nfunction statusPrefix(status: ActionLogEntry[\"status\"]): string {\n if (status === \"success\") return \"\\u2713\";\n if (status === \"error\") return \"\\u2717\";\n return \"\\u22EF\";\n}\n\nfunction statusColor(status: ActionLogEntry[\"status\"]): \"green\" | \"red\" | \"yellow\" {\n if (status === \"success\") return \"green\";\n if (status === \"error\") return \"red\";\n return \"yellow\";\n}\n\nfunction ActionLog({ entries }: ActionLogProps) {\n // Tick every 5s to update relative timestamps\n const [, setTick] = useState(0);\n useEffect(() => {\n const id = setInterval(() => setTick((t) => t + 1), 5_000);\n return () => clearInterval(id);\n }, []);\n\n const visible = entries.slice(-5);\n // Find the most recent undoable entry\n const lastUndoable = [...entries].reverse().find((e) => !!e.undo);\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"single\" borderColor=\"gray\">\n <Box paddingX={1}>\n <Text color=\"gray\" bold>\n Action Log\n </Text>\n <Text color=\"gray\" dimColor>\n {\" \"}\n (L: close)\n </Text>\n </Box>\n {visible.length === 0 ? (\n <Box paddingX={1}>\n <Text dimColor>No actions yet.</Text>\n </Box>\n ) : (\n visible.map((entry) => {\n const isUndoable = lastUndoable?.id === entry.id && !!entry.undo;\n return (\n <Box key={entry.id} paddingX={1}>\n <Text color={statusColor(entry.status)}>{statusPrefix(entry.status)} </Text>\n <Text>{entry.description}</Text>\n <Text dimColor> {relativeTime(entry.ago)}</Text>\n {isUndoable ? <Text color=\"cyan\"> [u: undo]</Text> : null}\n {entry.retry && entry.status === \"error\" ? (\n <Text color=\"yellow\"> [retry]</Text>\n ) : null}\n </Box>\n );\n })\n )}\n </Box>\n );\n}\n\nexport { ActionLog };\nexport type { ActionLogProps };\n","import { Box, Text } from \"ink\";\nimport type { ReactNode } from \"react\";\n\ninterface PanelProps {\n /** Text shown inside the top border: ╭─ title ──╮ */\n readonly title: string;\n /** Whether this panel is currently focused (cyan border vs gray) */\n readonly isActive: boolean;\n /** Total outer width including border chars */\n readonly width: number;\n /** Fixed total height (optional; use flexGrow instead for variable-height panels) */\n readonly height?: number | undefined;\n /** CSS flex grow factor — use 1 for panels that should fill available space */\n readonly flexGrow?: number | undefined;\n readonly children: ReactNode;\n}\n\n/**\n * Build the top border line with the title embedded.\n * Output: ╭─ title ─────────╮ (exactly `width` chars)\n */\nexport function buildTopLine(title: string, width: number): string {\n const titlePart = `─ ${title} `; // \"─ title \"\n const dashCount = Math.max(0, width - 2 - titlePart.length); // corners = 2 chars\n return `╭${titlePart}${\"─\".repeat(dashCount)}╮`;\n}\n\n/**\n * A lazygit-style panel: title embedded in the top border, rounded corners,\n * cyan border when active / gray when inactive.\n *\n * Rendering:\n * ╭─ [1] Repos ──────────╮ ← manually drawn Text (1 row)\n * │ content │ ← Ink Box with borderTop=false\n * ╰───────────────────────╯ ← from Ink Box bottom border\n */\nexport function Panel({ title, isActive, width, height, flexGrow, children }: PanelProps) {\n const color = isActive ? \"cyan\" : \"gray\";\n const topLine = buildTopLine(title, width);\n\n return (\n <Box flexDirection=\"column\" width={width} height={height} flexGrow={flexGrow} overflow=\"hidden\">\n <Text color={color}>{topLine}</Text>\n <Box\n borderStyle=\"round\"\n borderTop={false}\n borderColor={color}\n flexDirection=\"column\"\n flexGrow={1}\n overflow=\"hidden\"\n width={width}\n >\n {children}\n </Box>\n </Box>\n );\n}\n\nexport type { PanelProps };\n","import { Box, Text } from \"ink\";\nimport { timeAgo } from \"../constants.js\";\nimport type { ActivityEvent } from \"../fetch.js\";\nimport { Panel } from \"./panel.js\";\n\nexport interface ActivityPanelProps {\n readonly events: ActivityEvent[];\n readonly selectedIdx: number;\n readonly isActive: boolean;\n readonly height: number;\n readonly width: number;\n}\n\nexport function ActivityPanel({\n events,\n selectedIdx,\n isActive,\n height,\n width,\n}: ActivityPanelProps) {\n // Panel takes 1 row for top border text + 1 row for bottom border inside the inner Box\n // = 2 overhead rows → content rows = height - 2\n const maxRows = Math.max(1, height - 2);\n const visible = events.slice(0, maxRows);\n\n return (\n <Panel title=\"[4] Activity\" isActive={isActive} width={width} height={height}>\n {visible.length === 0 ? (\n <Text color=\"gray\"> No recent activity</Text>\n ) : (\n visible.map((event, i) => {\n const isSel = isActive && i === selectedIdx;\n const ago = timeAgo(event.timestamp);\n return (\n <Box key={`${event.repoShortName}:${event.issueNumber}:${i}`}>\n <Text color={isSel ? \"cyan\" : \"gray\"} bold={isSel}>\n {isSel ? \"► \" : \" \"}\n {ago}\n </Text>\n <Text color={isSel ? \"white\" : \"gray\"}>\n {\" \"}\n @{event.actor} {event.summary}{\" \"}\n </Text>\n <Text dimColor>({event.repoShortName})</Text>\n </Box>\n );\n })\n )}\n </Panel>\n );\n}\n","import { Box, Text } from \"ink\";\nimport { useEffect } from \"react\";\nimport type { GitHubIssue, IssueComment } from \"../../github.js\";\nimport { Panel } from \"./panel.js\";\n\ninterface DetailPanelProps {\n readonly issue: GitHubIssue | null;\n readonly width: number;\n readonly height?: number | undefined;\n readonly isActive: boolean;\n readonly commentsState?: IssueComment[] | \"loading\" | \"error\" | null;\n readonly fetchComments?: (repo: string, issueNumber: number) => void;\n readonly issueRepo?: string | null;\n}\n\n/** Strip common markdown syntax for plain text display. */\nfunction stripMarkdown(text: string): string {\n return text\n .replace(/^#{1,6}\\s+/gm, \"\") // headers\n .replace(/\\*\\*(.+?)\\*\\*/g, \"$1\") // bold\n .replace(/\\*(.+?)\\*/g, \"$1\") // italic\n .replace(/__(.+?)__/g, \"$1\") // bold alt\n .replace(/_(.+?)_/g, \"$1\") // italic alt\n .replace(/~~(.+?)~~/g, \"$1\") // strikethrough\n .replace(/`{1,3}[^`]*`{1,3}/g, (m) => m.replace(/`/g, \"\")) // inline code\n .replace(/^\\s*[-*+]\\s+/gm, \" - \") // list items\n .replace(/^\\s*\\d+\\.\\s+/gm, \" \") // numbered lists\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\") // links\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, \"[$1]\") // images\n .replace(/^>\\s+/gm, \" \") // blockquotes\n .replace(/---+/g, \"\") // horizontal rules\n .replace(/\\n{3,}/g, \"\\n\\n\") // collapse blank lines\n .trim();\n}\n\nfunction formatBody(body: string, maxLines: number): { text: string; remaining: number } {\n const plain = stripMarkdown(body);\n const lines = plain.split(\"\\n\");\n const truncated = lines.slice(0, maxLines).join(\"\\n\");\n return { text: truncated, remaining: Math.max(0, lines.length - maxLines) };\n}\n\nconst SLACK_URL_RE = /https:\\/\\/[^/]+\\.slack\\.com\\/archives\\/[A-Z0-9]+\\/p[0-9]+/gi;\n\nfunction countSlackLinks(body: string | undefined): number {\n if (!body) return 0;\n return (body.match(SLACK_URL_RE) ?? []).length;\n}\n\nfunction BodySection({\n body,\n issueNumber,\n}: {\n readonly body: string;\n readonly issueNumber: number;\n}) {\n const { text, remaining } = formatBody(body, 15);\n return (\n <>\n <Text>{\"\"}</Text>\n <Text dimColor>--- Description ---</Text>\n <Text wrap=\"wrap\">{text}</Text>\n {remaining > 0 ? (\n <Text dimColor>\n ... ({remaining} more lines — gh issue view {issueNumber} for full)\n </Text>\n ) : null}\n </>\n );\n}\n\nfunction formatCommentAge(createdAt: string): string {\n const seconds = Math.floor((Date.now() - new Date(createdAt).getTime()) / 1000);\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nfunction DetailPanel({\n issue,\n width,\n height,\n isActive,\n commentsState,\n fetchComments,\n issueRepo,\n}: DetailPanelProps) {\n // Trigger lazy fetch when issue changes and panel is visible\n useEffect(() => {\n if (!(issue && fetchComments && issueRepo)) return;\n if (commentsState !== null && commentsState !== undefined) return; // already fetched or loading\n fetchComments(issueRepo, issue.number);\n }, [issue, issueRepo, fetchComments, commentsState]);\n\n if (!issue) {\n return (\n <Panel title=\"[0] Detail\" isActive={isActive} width={width} height={height}>\n <Text color=\"gray\">No item selected</Text>\n </Panel>\n );\n }\n\n return (\n <Panel title=\"[0] Detail\" isActive={isActive} width={width} height={height}>\n <Text color=\"cyan\" bold>\n #{issue.number} {issue.title}\n </Text>\n <Text>{\"\"}</Text>\n\n <Box>\n <Text color=\"gray\">State: </Text>\n <Text color={issue.state === \"open\" ? \"green\" : \"red\"}>{issue.state}</Text>\n </Box>\n\n {(issue.assignees ?? []).length > 0 ? (\n <Box>\n <Text color=\"gray\">Assignees: </Text>\n <Text>{(issue.assignees ?? []).map((a) => a.login).join(\", \")}</Text>\n </Box>\n ) : null}\n\n {issue.labels.length > 0 ? (\n <Box>\n <Text color=\"gray\">Labels: </Text>\n <Text>{issue.labels.map((l) => l.name).join(\", \")}</Text>\n </Box>\n ) : null}\n\n {issue.projectStatus ? (\n <Box>\n <Text color=\"gray\">Status: </Text>\n <Text color=\"magenta\">{issue.projectStatus}</Text>\n </Box>\n ) : null}\n\n {issue.targetDate ? (\n <Box>\n <Text color=\"gray\">Target: </Text>\n <Text>{issue.targetDate}</Text>\n </Box>\n ) : null}\n\n <Box>\n <Text color=\"gray\">Updated: </Text>\n <Text>{new Date(issue.updatedAt).toLocaleString()}</Text>\n </Box>\n\n {issue.slackThreadUrl ? (\n <Box>\n <Text color=\"gray\">Slack: </Text>\n <Text color=\"blue\">\n {countSlackLinks(issue.body) > 1\n ? `${countSlackLinks(issue.body)} links (s opens first)`\n : \"thread (s to open)\"}\n </Text>\n </Box>\n ) : null}\n\n {issue.body ? (\n <BodySection body={issue.body} issueNumber={issue.number} />\n ) : (\n <>\n <Text>{\"\"}</Text>\n <Text color=\"gray\">(no description)</Text>\n </>\n )}\n\n {/* Comments section */}\n <Text>{\"\"}</Text>\n <Text dimColor>--- Comments ---</Text>\n {commentsState === \"loading\" ? (\n <Text dimColor>fetching comments...</Text>\n ) : commentsState === \"error\" ? (\n <Text color=\"red\">could not load comments</Text>\n ) : commentsState && commentsState.length === 0 ? (\n <Text dimColor>No comments yet.</Text>\n ) : commentsState && commentsState.length > 0 ? (\n commentsState.slice(-5).map((comment, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: stable list\n <Box key={i} flexDirection=\"column\" marginBottom={1}>\n <Text color=\"cyan\">\n @{comment.author.login} · {formatCommentAge(comment.createdAt)}\n </Text>\n <Text wrap=\"wrap\"> {comment.body.split(\"\\n\")[0]}</Text>\n </Box>\n ))\n ) : (\n <Text dimColor>fetching comments...</Text>\n )}\n\n <Text>{\"\"}</Text>\n <Text color=\"gray\" dimColor>\n {issue.url}\n </Text>\n </Panel>\n );\n}\n\nexport { DetailPanel };\nexport type { DetailPanelProps };\n","import { Box, Text } from \"ink\";\nimport type { PanelId } from \"../hooks/use-panel-focus.js\";\nimport type { UIMode } from \"../hooks/use-ui-state.js\";\n\ninterface HintBarProps {\n readonly uiMode: UIMode;\n readonly activePanelId: PanelId;\n readonly multiSelectCount: number;\n readonly searchQuery: string;\n readonly mineOnly: boolean;\n readonly hasUndoable?: boolean;\n}\n\nfunction HintBar({\n uiMode,\n activePanelId,\n multiSelectCount,\n searchQuery,\n mineOnly,\n hasUndoable,\n}: HintBarProps) {\n if (uiMode === \"multiSelect\") {\n return (\n <Box>\n <Text color=\"cyan\" bold>\n [MULTI-SELECT] {multiSelectCount} selected\n </Text>\n <Text color=\"gray\"> Space:toggle Enter:actions Esc:cancel</Text>\n </Box>\n );\n }\n\n if (uiMode === \"focus\") {\n return (\n <Box>\n <Text color=\"magenta\" bold>\n [FOCUS] Focus mode — Esc to exit\n </Text>\n </Box>\n );\n }\n\n if (uiMode === \"search\") {\n return (\n <Box>\n <Text color=\"yellow\" bold>\n [SEARCH]\n </Text>\n <Text color=\"gray\"> type to filter Enter:confirm Esc:clear</Text>\n {searchQuery ? <Text color=\"yellow\"> \"{searchQuery}\"</Text> : null}\n </Box>\n );\n }\n\n if (uiMode === \"overlay:fuzzyPicker\") {\n return (\n <Box>\n <Text color=\"gray\">↑↓/Ctrl-J/K:nav Enter:jump Esc:close</Text>\n </Box>\n );\n }\n\n if (uiMode === \"overlay:detail\") {\n return (\n <Box>\n <Text color=\"cyan\" bold>\n [DETAIL]\n </Text>\n <Text color=\"gray\"> Esc:close e:edit c:comment g:open y:copy-link C:claude ? help</Text>\n </Box>\n );\n }\n\n if (uiMode.startsWith(\"overlay:\")) {\n return (\n <Box>\n <Text color=\"gray\">j/k:nav Enter:select Esc:cancel</Text>\n </Box>\n );\n }\n\n // Normal mode — context-sensitive hints per active panel\n const panelHints: Record<PanelId, string> = {\n 0: \"j/k:scroll Esc:close ? help\",\n 1: \"j/k:move Enter:filter 0-4:panel ? help\",\n 2: \"j/k:move Enter:filter Esc:clear 0-4:panel ? help\",\n 3: `j/k:move Enter:detail g:open p:pick m:status c:comment C:claude /:search n:new 0-4:panel${hasUndoable ? \" u:undo\" : \"\"} ? help q:quit`,\n 4: \"j/k:scroll Enter:jump r:refresh 0-4:panel ? help\",\n };\n\n return (\n <Box>\n <Text color=\"gray\">{panelHints[activePanelId]}</Text>\n {mineOnly ? <Text color=\"cyan\"> filter:@me</Text> : null}\n {searchQuery ? <Text color=\"yellow\"> filter:\"{searchQuery}\"</Text> : null}\n </Box>\n );\n}\n\nexport { HintBar };\nexport type { HintBarProps };\n","import { Box, Text, useInput } from \"ink\";\nimport { useState } from \"react\";\n\nexport type BulkAction =\n | { type: \"assign\" }\n | { type: \"statusChange\" }\n | { type: \"unassign\" }\n | { type: \"complete\" }\n | { type: \"delete\" };\n\ninterface BulkActionMenuProps {\n readonly count: number;\n /** What kinds of items are selected */\n readonly selectionType: \"github\" | \"ticktick\" | \"mixed\";\n readonly onSelect: (action: BulkAction) => void;\n readonly onCancel: () => void;\n}\n\ninterface MenuItem {\n label: string;\n action: BulkAction;\n}\n\nfunction getMenuItems(selectionType: \"github\" | \"ticktick\" | \"mixed\"): MenuItem[] {\n if (selectionType === \"github\") {\n return [\n { label: \"Assign all to me\", action: { type: \"assign\" } },\n { label: \"Unassign all from me\", action: { type: \"unassign\" } },\n { label: \"Move status (all)\", action: { type: \"statusChange\" } },\n ];\n }\n if (selectionType === \"ticktick\") {\n return [\n { label: \"Complete all\", action: { type: \"complete\" } },\n { label: \"Delete all\", action: { type: \"delete\" } },\n ];\n }\n // Mixed: only show actions valid for all types — none in our case\n return [];\n}\n\nfunction BulkActionMenu({ count, selectionType, onSelect, onCancel }: BulkActionMenuProps) {\n const items = getMenuItems(selectionType);\n const [selectedIdx, setSelectedIdx] = useState(0);\n\n useInput((input, key) => {\n if (key.escape) return onCancel();\n if (key.return) {\n const item = items[selectedIdx];\n if (item) onSelect(item.action);\n return;\n }\n if (input === \"j\" || key.downArrow) {\n setSelectedIdx((i) => Math.min(i + 1, items.length - 1));\n }\n if (input === \"k\" || key.upArrow) {\n setSelectedIdx((i) => Math.max(i - 1, 0));\n }\n });\n\n if (items.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"yellow\">No bulk actions for mixed selection types.</Text>\n <Text dimColor>Esc to cancel</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Bulk action ({count} selected):\n </Text>\n {items.map((item, i) => {\n const isSelected = i === selectedIdx;\n const prefix = isSelected ? \"> \" : \" \";\n return (\n <Text key={item.action.type} {...(isSelected ? { color: \"cyan\" as const } : {})}>\n {prefix}\n {item.label}\n </Text>\n );\n })}\n <Text dimColor>j/k:navigate Enter:select Esc:cancel</Text>\n </Box>\n );\n}\n\nexport { BulkActionMenu, getMenuItems };\n","import type { Instance } from \"ink\";\n\nlet inkInstance: Instance | null = null;\n\n/** Store the Ink render instance for use in editor integration ($EDITOR launch). */\nexport function setInkInstance(instance: Instance): void {\n inkInstance = instance;\n}\n\nexport function getInkInstance(): Instance | null {\n return inkInstance;\n}\n","import { spawnSync } from \"node:child_process\";\nimport { mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { TextInput } from \"@inkjs/ui\";\nimport { Box, Text, useInput, useStdin } from \"ink\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { getInkInstance } from \"../ink-instance.js\";\n\ninterface CommentInputProps {\n readonly issueNumber: number;\n readonly onSubmit: (body: string) => void;\n readonly onCancel: () => void;\n readonly onPauseRefresh?: () => void;\n readonly onResumeRefresh?: () => void;\n}\n\nfunction CommentInput({\n issueNumber,\n onSubmit,\n onCancel,\n onPauseRefresh,\n onResumeRefresh,\n}: CommentInputProps) {\n const [value, setValue] = useState(\"\");\n const [editing, setEditing] = useState(false);\n const { setRawMode } = useStdin();\n // Capture stable refs to avoid stale closures in useEffect\n const onSubmitRef = useRef(onSubmit);\n const onCancelRef = useRef(onCancel);\n const onPauseRef = useRef(onPauseRefresh);\n const onResumeRef = useRef(onResumeRefresh);\n onSubmitRef.current = onSubmit;\n onCancelRef.current = onCancel;\n onPauseRef.current = onPauseRefresh;\n onResumeRef.current = onResumeRefresh;\n\n useInput((_input, key) => {\n if (editing) return;\n if (key.escape) {\n onCancel();\n return;\n }\n // ctrl+e: transition to \"editing\" sub-state before launching editor\n if (_input === \"\\x05\") {\n setEditing(true);\n }\n });\n\n // Launch editor after TextInput has unmounted (editing === true)\n useEffect(() => {\n if (!editing) return;\n\n const editorEnv = process.env[\"VISUAL\"] ?? process.env[\"EDITOR\"] ?? \"vi\";\n // Split to handle \"code --wait\" style editors\n const [cmd, ...extraArgs] = editorEnv.split(\" \").filter(Boolean);\n if (!cmd) {\n setEditing(false);\n return;\n }\n\n let tmpDir: string | null = null;\n let tmpFile: string | null = null;\n\n try {\n // Pause auto-refresh before handing over the terminal\n onPauseRef.current?.();\n\n // Prepare temp file with current value as seed content\n tmpDir = mkdtempSync(join(tmpdir(), \"hog-comment-\"));\n tmpFile = join(tmpDir, \"comment.md\");\n writeFileSync(tmpFile, value);\n\n // Suspend Ink and restore terminal to cooked mode\n const inkInstance = getInkInstance();\n inkInstance?.clear();\n setRawMode(false);\n\n spawnSync(cmd, [...extraArgs, tmpFile], { stdio: \"inherit\" });\n\n // Read back the file content\n const content = readFileSync(tmpFile, \"utf-8\").trim();\n\n // Restore raw mode for Ink\n setRawMode(true);\n\n if (content) {\n onSubmitRef.current(content);\n } else {\n // Empty save — treat as cancel\n onCancelRef.current();\n }\n } finally {\n onResumeRef.current?.();\n if (tmpDir) {\n try {\n rmSync(tmpDir, { recursive: true, force: true });\n } catch {\n // ignore cleanup errors\n }\n }\n setEditing(false);\n }\n }, [editing, value, setRawMode]);\n\n if (editing) {\n return (\n <Box>\n <Text color=\"cyan\">Opening editor for #{issueNumber}…</Text>\n </Box>\n );\n }\n\n return (\n <Box>\n <Text color=\"cyan\">comment #{issueNumber}: </Text>\n <TextInput\n defaultValue={value}\n placeholder=\"type comment (ctrl+e for editor), Enter to post...\"\n onChange={setValue}\n onSubmit={(text) => {\n if (text.trim()) onSubmit(text.trim());\n else onCancel();\n }}\n />\n </Box>\n );\n}\n\nexport { CommentInput };\n","import { Box, Text, useInput } from \"ink\";\n\ninterface ConfirmPromptProps {\n readonly message: string;\n readonly onConfirm: () => void;\n readonly onCancel: () => void;\n}\n\nfunction ConfirmPrompt({ message, onConfirm, onCancel }: ConfirmPromptProps) {\n useInput((input, key) => {\n if (input === \"y\" || input === \"Y\") return onConfirm();\n if (input === \"n\" || input === \"N\" || key.escape) return onCancel();\n });\n\n return (\n <Box>\n <Text color=\"cyan\">{message}</Text>\n <Text color=\"gray\"> (y/n)</Text>\n </Box>\n );\n}\n\nexport { ConfirmPrompt };\n","import { Spinner } from \"@inkjs/ui\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type { LabelOption } from \"../../github.js\";\nimport { fetchRepoLabelsAsync } from \"../../github.js\";\n\ninterface LabelPickerProps {\n readonly repo: string;\n readonly currentLabels: string[];\n /** Session-level cache — passed by ref so it persists across overlay open/close */\n readonly labelCache: Record<string, LabelOption[]>;\n readonly onConfirm: (addLabels: string[], removeLabels: string[]) => void;\n readonly onCancel: () => void;\n readonly onError: (msg: string) => void;\n}\n\nfunction LabelPicker({\n repo,\n currentLabels,\n labelCache,\n onConfirm,\n onCancel,\n onError,\n}: LabelPickerProps) {\n const [labels, setLabels] = useState<LabelOption[] | null>(labelCache[repo] ?? null);\n const [loading, setLoading] = useState(labels === null);\n const [fetchAttempted, setFetchAttempted] = useState(false);\n // Selected label names (start with current labels pre-selected)\n const [selected, setSelected] = useState<ReadonlySet<string>>(new Set(currentLabels));\n const [cursor, setCursor] = useState(0);\n const submittedRef = useRef(false);\n\n // Fetch labels lazily on mount if not cached.\n // `fetchAttempted` guards against re-firing on error (labels stays null on error,\n // so removing `labels` from deps and using this flag breaks the infinite loop).\n // biome-ignore lint/correctness/useExhaustiveDependencies: `labels` intentionally omitted — fetchAttempted flag prevents the infinite re-fetch loop that occurs when labels stays null after an error\n useEffect(() => {\n if (labels !== null || fetchAttempted) return;\n setFetchAttempted(true);\n setLoading(true);\n let canceled = false;\n fetchRepoLabelsAsync(repo)\n .then((fetched) => {\n if (canceled) return;\n labelCache[repo] = fetched;\n setLabels(fetched);\n setLoading(false);\n })\n .catch(() => {\n if (canceled) return;\n setLoading(false);\n onError(`Could not fetch labels for ${repo}`);\n });\n return () => {\n canceled = true;\n };\n }, [repo, fetchAttempted, labelCache, onError]);\n\n useInput((input, key) => {\n if (loading) return;\n\n if (key.escape) {\n onCancel();\n return;\n }\n\n if (key.return) {\n if (submittedRef.current) return;\n submittedRef.current = true;\n\n const allLabels = labels ?? [];\n const add = [...selected].filter((l) => !currentLabels.includes(l));\n const remove = currentLabels.filter((l) => {\n // Only remove non-orphaned labels (labels that exist in the repo list)\n const exists = allLabels.some((rl) => rl.name === l);\n return exists && !selected.has(l);\n });\n\n onConfirm(add, remove);\n return;\n }\n\n if (input === \" \") {\n const allLabels = labels ?? [];\n const item = allLabels[cursor];\n if (!item) return;\n setSelected((prev) => {\n const next = new Set(prev);\n if (next.has(item.name)) {\n next.delete(item.name);\n } else {\n next.add(item.name);\n }\n return next;\n });\n return;\n }\n\n if (input === \"j\" || key.downArrow) {\n setCursor((i) => Math.min(i + 1, (labels?.length ?? 1) - 1));\n }\n if (input === \"k\" || key.upArrow) {\n setCursor((i) => Math.max(i - 1, 0));\n }\n });\n\n if (loading) {\n return (\n <Box>\n <Spinner label=\"Fetching labels...\" />\n </Box>\n );\n }\n\n const allLabels = labels ?? [];\n\n if (allLabels.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Labels:\n </Text>\n <Text dimColor>No labels in this repo</Text>\n <Text dimColor>Esc:cancel</Text>\n </Box>\n );\n }\n\n // Orphaned: labels on the issue that don't exist in the repo label list\n const repoLabelNames = new Set(allLabels.map((l) => l.name));\n const orphanedLabels = currentLabels.filter((l) => !repoLabelNames.has(l));\n\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Labels (Space:toggle Enter:confirm Esc:cancel):\n </Text>\n {orphanedLabels.map((name) => (\n <Text key={`orphan:${name}`} dimColor>\n {selected.has(name) ? \"[x]\" : \"[ ]\"} {name} (orphaned)\n </Text>\n ))}\n {allLabels.map((label, i) => {\n const isSel = i === cursor;\n const isChecked = selected.has(label.name);\n return (\n <Text key={label.name} {...(isSel ? { color: \"cyan\" as const } : {})}>\n {isSel ? \">\" : \" \"} {isChecked ? \"[x]\" : \"[ ]\"} {label.name}\n </Text>\n );\n })}\n </Box>\n );\n}\n\nexport { LabelPicker };\n","import { TextInput } from \"@inkjs/ui\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useState } from \"react\";\nimport type { RepoConfig } from \"../../config.js\";\nimport type { LabelOption } from \"../../github.js\";\nimport { LabelPicker } from \"./label-picker.js\";\n\ninterface CreateIssueFormProps {\n readonly repos: RepoConfig[];\n readonly defaultRepo: string | null;\n readonly onSubmit: (\n repo: string,\n title: string,\n body: string,\n dueDate: string | null,\n labels?: string[],\n ) => void;\n readonly onCancel: () => void;\n /** Session-level label cache — passed from dashboard so it persists across form open/close */\n readonly labelCache?: Record<string, LabelOption[]>;\n}\n\nfunction CreateIssueForm({\n repos,\n defaultRepo,\n onSubmit,\n onCancel,\n labelCache,\n}: CreateIssueFormProps) {\n const defaultRepoIdx = defaultRepo\n ? Math.max(\n 0,\n repos.findIndex((r) => r.name === defaultRepo),\n )\n : 0;\n\n const [repoIdx, setRepoIdx] = useState(defaultRepoIdx);\n const [title, setTitle] = useState(\"\");\n const [field, setField] = useState<\"repo\" | \"title\" | \"labels\">(\"title\");\n\n useInput((input, key) => {\n // LabelPicker handles its own input in the labels step\n if (field === \"labels\") return;\n\n if (key.escape) return onCancel();\n\n if (field === \"repo\") {\n if (input === \"j\" || key.downArrow) {\n setRepoIdx((i) => Math.min(i + 1, repos.length - 1));\n }\n if (input === \"k\" || key.upArrow) {\n setRepoIdx((i) => Math.max(i - 1, 0));\n }\n if (key.tab) setField(\"title\");\n if (key.return) setField(\"title\");\n }\n });\n\n const selectedRepo = repos[repoIdx];\n\n // Labels step — LabelPicker takes over input completely\n if (field === \"labels\" && selectedRepo) {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Create Issue — Add Labels (optional)\n </Text>\n <Text dimColor>\n Repo: {selectedRepo.shortName} Title: {title}\n </Text>\n <LabelPicker\n repo={selectedRepo.name}\n currentLabels={[]}\n labelCache={labelCache ?? {}}\n onConfirm={(addLabels) => {\n onSubmit(\n selectedRepo.name,\n title,\n \"\",\n null,\n addLabels.length > 0 ? addLabels : undefined,\n );\n }}\n onCancel={() => {\n // Esc skips labels and submits without them\n onSubmit(selectedRepo.name, title, \"\", null);\n }}\n onError={() => {\n // On fetch error, skip labels and submit\n onSubmit(selectedRepo.name, title, \"\", null);\n }}\n />\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Create Issue\n </Text>\n\n {/* Repo selector */}\n <Box>\n <Text dimColor={field !== \"repo\"}>Repo: </Text>\n {repos.map((r, i) => (\n <Text\n key={r.name}\n {...(i === repoIdx ? { color: \"cyan\" as const, bold: true } : {})}\n dimColor={field !== \"repo\"}\n >\n {i === repoIdx ? `[${r.shortName}]` : ` ${r.shortName} `}\n </Text>\n ))}\n {field === \"repo\" ? <Text dimColor> j/k:select Tab:next</Text> : null}\n </Box>\n\n {/* Title input */}\n <Box>\n <Text dimColor={field !== \"title\"}>Title: </Text>\n {field === \"title\" ? (\n <TextInput\n defaultValue={title}\n placeholder=\"issue title...\"\n onChange={setTitle}\n onSubmit={(text) => {\n const trimmed = text.trim();\n if (!(trimmed && selectedRepo)) return;\n if (labelCache !== undefined) {\n // Advance to labels step\n setTitle(trimmed);\n setField(\"labels\");\n } else {\n onSubmit(selectedRepo.name, trimmed, \"\", null);\n }\n }}\n />\n ) : (\n <Text>{title || \"(empty)\"}</Text>\n )}\n </Box>\n\n <Text dimColor>Tab:switch fields Enter:next Esc:cancel</Text>\n </Box>\n );\n}\n\nexport { CreateIssueForm };\n","import { spawnSync } from \"node:child_process\";\nimport { mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { Box, Text, useStdin } from \"ink\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type { RepoConfig } from \"../../config.js\";\nimport type { GitHubIssue, LabelOption, StatusOption } from \"../../github.js\";\nimport {\n assignIssueToAsync,\n editIssueBodyAsync,\n editIssueTitleAsync,\n fetchRepoLabelsAsync,\n unassignIssueAsync,\n updateLabelsAsync,\n updateProjectItemStatusAsync,\n} from \"../../github.js\";\nimport type { ActionLogEntry } from \"../hooks/use-action-log.js\";\nimport { nextEntryId } from \"../hooks/use-action-log.js\";\nimport { getInkInstance } from \"../ink-instance.js\";\n\ninterface EditIssueOverlayProps {\n readonly issue: GitHubIssue;\n readonly repoName: string;\n readonly repoConfig: RepoConfig | null;\n readonly statusOptions: StatusOption[];\n readonly labelCache: Record<string, LabelOption[]>;\n readonly onDone: () => void;\n readonly onPauseRefresh?: () => void;\n readonly onResumeRefresh?: () => void;\n readonly onToastInfo: (msg: string) => void;\n readonly onToastError: (msg: string) => void;\n readonly onPushEntry?: (entry: ActionLogEntry) => void;\n}\n\ninterface ParsedFrontMatter {\n title: string;\n status: string;\n labels: string[];\n assignee: string;\n body: string;\n}\n\nfunction buildEditorFile(\n issue: GitHubIssue,\n repoName: string,\n statusOptions: StatusOption[],\n repoLabels: LabelOption[],\n): string {\n const statusNames = statusOptions.map((o) => o.name).join(\", \");\n const labelNames = repoLabels.map((l) => l.name).join(\", \");\n const currentLabels = issue.labels.map((l) => l.name);\n const currentAssignee = (issue.assignees ?? [])[0]?.login ?? \"\";\n\n const labelsYaml =\n currentLabels.length > 0 ? currentLabels.map((l) => ` - ${l}`).join(\"\\n\") : \" # - label-name\";\n\n return `# --- HOG ISSUE EDIT ---\n# Editing: ${repoName}#${issue.number}\n# Available status: ${statusNames || \"none\"}\n# Available labels: ${labelNames || \"none\"}\n# ──────────────────────────────────────────────────────────────\ntitle: ${issue.title}\nstatus: ${issue.projectStatus ?? \"\"}\nlabels:\n${labelsYaml}\nassignee: ${currentAssignee}\n---\n\n${issue.body ?? \"\"}`;\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: YAML front matter parser\nfunction parseFrontMatter(content: string): ParsedFrontMatter {\n // Strip comment lines (# ...) before parsing\n const lines = content.split(\"\\n\");\n // Find the separator --- after the front matter block (skip leading comment lines)\n let frontMatterStart = -1;\n let frontMatterEnd = -1;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (line.trimStart().startsWith(\"#\")) continue; // skip comment lines\n if (frontMatterStart === -1 && (line.trim() === \"---\" || line.startsWith(\"title:\"))) {\n frontMatterStart = i;\n // If this line is \"---\", the FM starts on next line\n if (line.trim() === \"---\") frontMatterStart = i + 1;\n } else if (frontMatterStart !== -1 && line.trim() === \"---\") {\n frontMatterEnd = i;\n break;\n }\n }\n\n // Collect front matter lines (non-comment, non-empty lines before the body separator)\n const fmLines: string[] = [];\n if (frontMatterStart >= 0 && frontMatterEnd > frontMatterStart) {\n for (let i = frontMatterStart; i < frontMatterEnd; i++) {\n const line = lines[i] ?? \"\";\n if (!line.trimStart().startsWith(\"#\")) fmLines.push(line);\n }\n }\n\n // Simple key-value parser\n let title = \"\";\n let status = \"\";\n const labels: string[] = [];\n let assignee = \"\";\n let inLabels = false;\n\n for (const line of fmLines) {\n if (line.startsWith(\"title:\")) {\n title = line.slice(\"title:\".length).trim();\n inLabels = false;\n } else if (line.startsWith(\"status:\")) {\n status = line.slice(\"status:\".length).trim();\n inLabels = false;\n } else if (line.startsWith(\"assignee:\")) {\n assignee = line.slice(\"assignee:\".length).trim();\n inLabels = false;\n } else if (line.startsWith(\"labels:\")) {\n inLabels = true;\n } else if (inLabels && line.trimStart().startsWith(\"- \")) {\n const label = line.trimStart().slice(2).trim();\n if (label && !label.startsWith(\"#\")) labels.push(label);\n } else if (line.match(/^\\w/)) {\n inLabels = false;\n }\n }\n\n // Body is everything after the closing ---\n const body =\n frontMatterEnd >= 0\n ? lines\n .slice(frontMatterEnd + 1)\n .join(\"\\n\")\n .trim()\n : \"\";\n\n return { title, status, labels, assignee, body };\n}\n\nfunction EditIssueOverlay({\n issue,\n repoName,\n repoConfig,\n statusOptions,\n labelCache,\n onDone,\n onPauseRefresh,\n onResumeRefresh,\n onToastInfo,\n onToastError,\n onPushEntry,\n}: EditIssueOverlayProps) {\n const [editing, setEditing] = useState(true);\n const { setRawMode } = useStdin();\n\n // Stable refs to avoid stale closures\n const onDoneRef = useRef(onDone);\n const onPauseRef = useRef(onPauseRefresh);\n const onResumeRef = useRef(onResumeRefresh);\n onDoneRef.current = onDone;\n onPauseRef.current = onPauseRefresh;\n onResumeRef.current = onResumeRefresh;\n\n useEffect(() => {\n if (!editing) return;\n\n // Use falsy check (not ??) to handle VISUAL=\"\" properly\n const editorEnv = process.env[\"VISUAL\"] || process.env[\"EDITOR\"] || \"vi\";\n const [cmd, ...extraArgs] = editorEnv.split(\" \").filter(Boolean);\n if (!cmd) {\n onDoneRef.current();\n return;\n }\n\n let tmpDir: string | null = null;\n let tmpFile: string | null = null;\n\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: editor session loop with per-field apply\n const runEditor = async () => {\n // Fetch labels from cache or remotely\n let repoLabels: LabelOption[] = labelCache[repoName] ?? [];\n if (repoLabels.length === 0) {\n try {\n repoLabels = await fetchRepoLabelsAsync(repoName);\n } catch {\n // best-effort; continue without labels\n }\n }\n\n tmpDir = mkdtempSync(join(tmpdir(), \"hog-edit-\"));\n tmpFile = join(tmpDir, `issue-${issue.number}.md`);\n\n let currentContent = buildEditorFile(issue, repoName, statusOptions, repoLabels);\n writeFileSync(tmpFile, currentContent);\n\n onPauseRef.current?.();\n\n const inkInstance = getInkInstance();\n inkInstance?.clear();\n setRawMode(false);\n\n // Reopen loop — repeat on validation errors\n while (true) {\n writeFileSync(tmpFile, currentContent);\n const result = spawnSync(cmd, [...extraArgs, tmpFile], { stdio: \"inherit\" });\n\n // Non-zero exit or signal = editor crashed/cancelled\n if (result.status !== 0 || result.signal !== null || result.error) {\n break;\n }\n\n currentContent = readFileSync(tmpFile, \"utf-8\");\n const parsed = parseFrontMatter(currentContent);\n\n // Zero-changes detection\n const origLabels = issue.labels.map((l) => l.name).sort();\n const newLabels = [...parsed.labels].sort();\n const origAssignee = (issue.assignees ?? [])[0]?.login ?? \"\";\n const unchanged =\n parsed.title === issue.title &&\n parsed.status === (issue.projectStatus ?? \"\") &&\n JSON.stringify(origLabels) === JSON.stringify(newLabels) &&\n parsed.assignee === origAssignee &&\n parsed.body === (issue.body ?? \"\").trim();\n\n if (unchanged) {\n onToastInfo(\"No changes made\");\n break;\n }\n\n // Validation\n const errors: string[] = [];\n if (!parsed.title.trim()) errors.push(\"title cannot be empty\");\n if (\n parsed.status &&\n statusOptions.length > 0 &&\n !statusOptions.some((o) => o.name === parsed.status)\n ) {\n const valid = statusOptions.map((o) => o.name).join(\", \");\n errors.push(`status \"${parsed.status}\" not found → valid: ${valid}`);\n }\n\n if (errors.length > 0) {\n // Inject error comments at top of preserved user content\n const errorBlock = `${errors.map((e) => `# ERROR: ${e}`).join(\"\\n\")}\\n`;\n currentContent = errorBlock + currentContent;\n continue; // reopen editor\n }\n\n // Apply changes sequentially with individual try/catch\n setRawMode(true);\n const changedFields: string[] = [];\n\n if (parsed.title !== issue.title) {\n try {\n await editIssueTitleAsync(repoName, issue.number, parsed.title);\n changedFields.push(\"title\");\n } catch {\n onToastError(`Failed to update title on #${issue.number}`);\n }\n }\n\n if (parsed.body !== (issue.body ?? \"\").trim()) {\n try {\n await editIssueBodyAsync(repoName, issue.number, parsed.body);\n changedFields.push(\"body\");\n } catch {\n onToastError(`Failed to update body on #${issue.number}`);\n }\n }\n\n if (parsed.status && parsed.status !== (issue.projectStatus ?? \"\") && repoConfig) {\n const targetOption = statusOptions.find((o) => o.name === parsed.status);\n if (targetOption) {\n try {\n await updateProjectItemStatusAsync(repoName, issue.number, {\n projectNumber: repoConfig.projectNumber,\n statusFieldId: repoConfig.statusFieldId,\n optionId: targetOption.id,\n });\n changedFields.push(\"status\");\n } catch {\n onToastError(`Failed to update status on #${issue.number}`);\n }\n }\n }\n\n // Labels: compute adds/removes\n const addLabels = parsed.labels.filter((l) => !origLabels.includes(l));\n const removeLabels = origLabels.filter((l) => !parsed.labels.includes(l));\n if (addLabels.length > 0 || removeLabels.length > 0) {\n try {\n await updateLabelsAsync(repoName, issue.number, addLabels, removeLabels);\n changedFields.push(\"labels\");\n } catch {\n onToastError(`Failed to update labels on #${issue.number}`);\n }\n }\n\n if (parsed.assignee !== origAssignee) {\n try {\n if (parsed.assignee) {\n await assignIssueToAsync(repoName, issue.number, parsed.assignee);\n }\n if (origAssignee) {\n await unassignIssueAsync(repoName, issue.number, origAssignee);\n }\n changedFields.push(\"assignee\");\n } catch {\n onToastError(`Failed to update assignee on #${issue.number}`);\n }\n }\n\n if (changedFields.length > 0) {\n onToastInfo(`#${issue.number}: ${changedFields.join(\", \")} updated`);\n onPushEntry?.({\n id: nextEntryId(),\n description: `#${issue.number} edited (${changedFields.join(\", \")})`,\n status: \"success\",\n ago: Date.now(),\n });\n }\n break;\n }\n };\n\n runEditor()\n .catch(() => {\n // ignore errors — best effort\n })\n .finally(() => {\n // Always restore raw mode\n try {\n setRawMode(true);\n } catch {\n // ignore\n }\n onResumeRef.current?.();\n if (tmpDir) {\n try {\n rmSync(tmpDir, { recursive: true, force: true });\n } catch {\n // ignore cleanup errors\n }\n }\n setEditing(false);\n onDoneRef.current();\n });\n }, [\n editing,\n issue,\n repoName,\n repoConfig,\n statusOptions,\n labelCache,\n setRawMode,\n onToastInfo,\n onToastError,\n onPushEntry,\n ]);\n\n if (!editing) return null;\n\n return (\n <Box>\n <Text color=\"cyan\">Opening editor for #{issue.number}…</Text>\n </Box>\n );\n}\n\nexport { EditIssueOverlay, buildEditorFile, parseFrontMatter };\nexport type { EditIssueOverlayProps };\n","import { Box, Text, useInput } from \"ink\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type FocusEndAction = \"restart\" | \"break\" | \"done\" | \"exit\";\n\ninterface FocusModeProps {\n /** Label to show (e.g. \"aibility#142 — Fix login bug\") */\n label: string;\n /** Duration in seconds (default 1500 = 25 min) */\n durationSec: number;\n /** Called when user exits focus mode */\n onExit: () => void;\n /** Called when timer ends and user picks an action */\n onEndAction: (action: FocusEndAction) => void;\n}\n\nfunction formatTime(secs: number): string {\n const m = Math.floor(secs / 60);\n const s = secs % 60;\n return `${String(m).padStart(2, \"0\")}:${String(s).padStart(2, \"0\")}`;\n}\n\nexport function FocusMode({ label, durationSec, onExit, onEndAction }: FocusModeProps) {\n const [remaining, setRemaining] = useState(durationSec);\n const [timerDone, setTimerDone] = useState(false);\n const bellSentRef = useRef(false);\n\n // Countdown timer\n useEffect(() => {\n if (timerDone) return;\n\n const interval = setInterval(() => {\n setRemaining((prev) => {\n if (prev <= 1) {\n clearInterval(interval);\n setTimerDone(true);\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n\n return () => clearInterval(interval);\n }, [timerDone]);\n\n // Terminal bell on completion\n useEffect(() => {\n if (timerDone && !bellSentRef.current) {\n bellSentRef.current = true;\n process.stdout.write(\"\\x07\");\n }\n }, [timerDone]);\n\n // Input: during timer, only Escape exits\n // After timer, show prompt: c=Continue, b=Break, d=Done, Esc=Exit\n const handleInput = useCallback(\n (input: string, key: { escape: boolean }) => {\n if (key.escape) {\n if (timerDone) {\n onEndAction(\"exit\");\n } else {\n onExit();\n }\n return;\n }\n\n if (!timerDone) return; // No other keys during timer\n\n switch (input.toLowerCase()) {\n case \"c\":\n onEndAction(\"restart\");\n break;\n case \"b\":\n onEndAction(\"break\");\n break;\n case \"d\":\n onEndAction(\"done\");\n break;\n }\n },\n [timerDone, onExit, onEndAction],\n );\n\n useInput(handleInput);\n\n if (timerDone) {\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text color=\"green\" bold>\n Focus complete!\n </Text>\n <Text color=\"gray\"> {label}</Text>\n </Box>\n <Box marginTop={1}>\n <Text color=\"cyan\">[c]</Text>\n <Text> Continue </Text>\n <Text color=\"cyan\">[b]</Text>\n <Text> Break </Text>\n <Text color=\"cyan\">[d]</Text>\n <Text> Done </Text>\n <Text color=\"gray\">[Esc]</Text>\n <Text> Exit</Text>\n </Box>\n </Box>\n );\n }\n\n const progress = 1 - remaining / durationSec;\n const barWidth = 20;\n const filled = Math.round(progress * barWidth);\n const bar = \"\\u2588\".repeat(filled) + \"\\u2591\".repeat(barWidth - filled);\n\n return (\n <Box flexDirection=\"column\">\n <Box>\n <Text color=\"magenta\" bold>\n Focus:{\" \"}\n </Text>\n <Text>{label}</Text>\n </Box>\n <Box>\n <Text color=\"magenta\">{bar}</Text>\n <Text> </Text>\n <Text bold>{formatTime(remaining)}</Text>\n <Text color=\"gray\"> remaining</Text>\n </Box>\n <Text color=\"gray\" dimColor>\n Esc to exit focus\n </Text>\n </Box>\n );\n}\n\nexport { formatTime };\n","import { TextInput } from \"@inkjs/ui\";\nimport { Fzf } from \"fzf\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useMemo, useState } from \"react\";\nimport type { RepoData } from \"../fetch.js\";\n\ninterface FuzzyPickerIssue {\n readonly navId: string;\n readonly repoShortName: string;\n readonly number: number;\n readonly title: string;\n readonly labels: string;\n readonly assignee: string;\n readonly repoName: string;\n}\n\ninterface FuzzyPickerProps {\n readonly repos: RepoData[];\n readonly onSelect: (navId: string) => void;\n readonly onClose: () => void;\n}\n\nfunction keepCursorVisible(cursor: number, offset: number, visible: number): number {\n if (cursor < offset) return cursor;\n if (cursor >= offset + visible) return cursor - visible + 1;\n return offset;\n}\n\nfunction FuzzyPicker({ repos, onSelect, onClose }: FuzzyPickerProps) {\n const [query, setQuery] = useState(\"\");\n const [cursor, setCursor] = useState(0);\n const [scrollOffset, setScrollOffset] = useState(0);\n\n // Flatten all issues from repos into a searchable list\n const allIssues = useMemo((): FuzzyPickerIssue[] => {\n const items: FuzzyPickerIssue[] = [];\n for (const rd of repos) {\n for (const issue of rd.issues) {\n items.push({\n navId: `gh:${rd.repo.name}:${issue.number}`,\n repoShortName: rd.repo.shortName,\n number: issue.number,\n title: issue.title,\n labels: issue.labels.map((l) => l.name).join(\" \"),\n assignee: (issue.assignees ?? []).map((a) => a.login).join(\" \"),\n repoName: rd.repo.name,\n });\n }\n }\n return items;\n }, [repos]);\n\n // Build fuzzy indexes (rebuilt only when allIssues changes, not on each keystroke)\n const fuzzyIndex = useMemo(\n () => ({\n byTitle: new Fzf(allIssues, {\n selector: (i: FuzzyPickerIssue) => i.title,\n casing: \"smart-case\",\n }),\n byRepo: new Fzf(allIssues, {\n selector: (i: FuzzyPickerIssue) => i.repoShortName,\n casing: \"smart-case\",\n }),\n byNum: new Fzf(allIssues, {\n selector: (i: FuzzyPickerIssue) => `#${String(i.number)}`,\n casing: \"case-insensitive\",\n }),\n byLabel: new Fzf(allIssues, {\n selector: (i: FuzzyPickerIssue) => i.labels,\n casing: \"smart-case\",\n }),\n }),\n [allIssues],\n );\n\n // Fuzzy search results (rebuilt on each query change)\n const results = useMemo((): FuzzyPickerIssue[] => {\n if (!query.trim()) return allIssues.slice(0, 20);\n\n const WEIGHTS = { title: 1.0, repo: 0.6, num: 2.0, label: 0.5 };\n const scoreMap = new Map<string, { item: FuzzyPickerIssue; score: number }>();\n\n function upsert(hits: { item: FuzzyPickerIssue; score: number }[], w: number) {\n for (const h of hits) {\n const s = h.score * w;\n const e = scoreMap.get(h.item.navId);\n if (!e || s > e.score) scoreMap.set(h.item.navId, { item: h.item, score: s });\n }\n }\n\n upsert(fuzzyIndex.byTitle.find(query), WEIGHTS.title);\n upsert(fuzzyIndex.byRepo.find(query), WEIGHTS.repo);\n upsert(fuzzyIndex.byNum.find(query), WEIGHTS.num);\n upsert(fuzzyIndex.byLabel.find(query), WEIGHTS.label);\n\n return [...scoreMap.values()].sort((a, b) => b.score - a.score).map((e) => e.item);\n }, [query, fuzzyIndex, allIssues]);\n\n const VISIBLE = Math.min((process.stdout.rows ?? 24) - 4, 15);\n\n // Internal keyboard navigation (Arrow keys, Ctrl-J/K, Enter, Escape)\n useInput((input, key) => {\n if (key.downArrow || (key.ctrl && input === \"j\")) {\n const newCursor = Math.min(cursor + 1, results.length - 1);\n setCursor(newCursor);\n setScrollOffset((prev) => keepCursorVisible(newCursor, prev, VISIBLE));\n return;\n }\n if (key.upArrow || (key.ctrl && input === \"k\")) {\n const newCursor = Math.max(cursor - 1, 0);\n setCursor(newCursor);\n setScrollOffset((prev) => keepCursorVisible(newCursor, prev, VISIBLE));\n return;\n }\n if (key.return) {\n const selected = results[cursor];\n if (selected) {\n onSelect(selected.navId);\n }\n return;\n }\n if (key.escape) {\n onClose();\n }\n });\n\n const visibleResults = results.slice(scrollOffset, scrollOffset + VISIBLE);\n const totalCount = results.length;\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"cyan\" paddingX={1}>\n <Box>\n <Text color=\"cyan\" bold>\n Find issue{\" \"}\n </Text>\n <Text color=\"gray\">\n ({totalCount} match{totalCount !== 1 ? \"es\" : \"\"}){\" \"}\n </Text>\n <Text color=\"gray\" dimColor>\n ↑↓/Ctrl-J/K nav Enter:jump Esc:close\n </Text>\n </Box>\n <Box>\n <Text color=\"yellow\">{\">\"} </Text>\n <TextInput\n defaultValue={query}\n placeholder=\"type to search...\"\n onChange={(v) => {\n setQuery(v);\n setCursor(0);\n setScrollOffset(0);\n }}\n onSubmit={() => {\n const selected = results[cursor];\n if (selected) onSelect(selected.navId);\n }}\n />\n </Box>\n {scrollOffset > 0 ? (\n <Text color=\"gray\" dimColor>\n ▲ {scrollOffset} more above\n </Text>\n ) : null}\n {visibleResults.map((issue, idx) => {\n const isSelected = scrollOffset + idx === cursor;\n const labelStr = issue.labels\n ? ` [${issue.labels.split(\" \").slice(0, 2).join(\"] [\")}]`\n : \"\";\n const assigneeStr = issue.assignee ? ` @${issue.assignee.split(\" \")[0]}` : \"\";\n return (\n <Box key={issue.navId}>\n {isSelected ? (\n <Text color=\"cyan\" bold>\n {\">\"} {issue.repoShortName}#{issue.number} {issue.title}\n {labelStr}\n {assigneeStr}\n </Text>\n ) : (\n <Text>\n {\" \"}\n {issue.repoShortName}#{issue.number} {issue.title}\n {labelStr}\n {assigneeStr}\n </Text>\n )}\n </Box>\n );\n })}\n {totalCount === 0 ? <Text dimColor>No issues match &quot;{query}&quot;</Text> : null}\n {results.length > scrollOffset + VISIBLE ? (\n <Text color=\"gray\" dimColor>\n ▼ {results.length - scrollOffset - VISIBLE} more below\n </Text>\n ) : null}\n </Box>\n );\n}\n\nexport { FuzzyPicker };\nexport type { FuzzyPickerProps };\n","import { Box, Text, useInput } from \"ink\";\nimport type { UIMode } from \"../hooks/use-ui-state.js\";\n\ninterface HelpOverlayProps {\n readonly currentMode: UIMode;\n readonly onClose: () => void;\n}\n\nconst SHORTCUTS = [\n {\n category: \"Navigation\",\n items: [\n { key: \"j / Down\", desc: \"Move down\" },\n { key: \"k / Up\", desc: \"Move up\" },\n { key: \"Tab\", desc: \"Next repo tab\" },\n { key: \"Shift+Tab\", desc: \"Previous repo tab\" },\n { key: \"1-9\", desc: \"Jump to repo tab by number\" },\n { key: \"s / S\", desc: \"Next / prev status tab\" },\n ],\n },\n {\n category: \"View\",\n items: [\n { key: \"Enter\", desc: \"Open detail panel\" },\n { key: \"0\", desc: \"Detail panel (full-screen on narrow terminals)\" },\n { key: \"Space\", desc: \"Multi-select item\" },\n { key: \"/\", desc: \"Search (inline filter)\" },\n { key: \"F\", desc: \"Fuzzy find issue (telescope-style)\" },\n { key: \"t\", desc: \"Toggle @me filter (my issues only)\" },\n { key: \"f\", desc: \"Focus mode\" },\n { key: \"?\", desc: \"Toggle help\" },\n { key: \"Esc\", desc: \"Close overlay / Back to normal\" },\n ],\n },\n {\n category: \"Actions\",\n items: [\n { key: \"p\", desc: \"Pick issue (assign + TickTick)\" },\n { key: \"a\", desc: \"Assign to self (no-op if already assigned)\" },\n { key: \"u\", desc: \"Undo last reversible action\" },\n { key: \"e\", desc: \"Edit issue in $EDITOR (title, assignee, status, labels)\" },\n { key: \"c\", desc: \"Comment on issue\" },\n { key: \"m\", desc: \"Move status\" },\n { key: \"g\", desc: \"Open issue in browser\" },\n { key: \"o\", desc: \"Open Slack thread\" },\n { key: \"y\", desc: \"Copy issue link to clipboard\" },\n { key: \"n\", desc: \"Create new issue\" },\n { key: \"I\", desc: \"Natural-language issue create\" },\n { key: \"l\", desc: \"Manage labels\" },\n { key: \"C\", desc: \"Launch Claude Code session for this issue\" },\n ],\n },\n {\n category: \"Board\",\n items: [\n { key: \"L\", desc: \"Toggle action log\" },\n { key: \"r\", desc: \"Refresh data\" },\n { key: \"q\", desc: \"Quit\" },\n ],\n },\n];\n\nfunction HelpOverlay({ currentMode, onClose }: HelpOverlayProps) {\n useInput((_input, key) => {\n if (key.escape) onClose();\n });\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"cyan\" paddingX={1}>\n <Box justifyContent=\"space-between\">\n <Text color=\"cyan\" bold>\n Keyboard Shortcuts\n </Text>\n <Text dimColor>mode: {currentMode}</Text>\n </Box>\n <Text> </Text>\n {SHORTCUTS.map((group) => (\n <Box key={group.category} flexDirection=\"column\" marginBottom={1}>\n <Text color=\"yellow\" bold>\n {group.category}\n </Text>\n {group.items.map((item) => (\n <Box key={item.key}>\n <Box width={16}>\n <Text color=\"green\">{item.key}</Text>\n </Box>\n <Text>{item.desc}</Text>\n </Box>\n ))}\n </Box>\n ))}\n <Text dimColor>Press ? or Esc to close</Text>\n </Box>\n );\n}\n\nexport { HelpOverlay };\n","import { spawnSync } from \"node:child_process\";\nimport { mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { Spinner, TextInput } from \"@inkjs/ui\";\nimport { Box, Text, useInput, useStdin } from \"ink\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { ParsedIssue } from \"../../ai.js\";\nimport { extractIssueFields } from \"../../ai.js\";\nimport type { RepoConfig } from \"../../config.js\";\nimport type { LabelOption } from \"../../github.js\";\nimport { getInkInstance } from \"../ink-instance.js\";\n\ntype Step = \"input\" | \"body\";\n\ninterface NlCreateOverlayProps {\n readonly repos: RepoConfig[];\n readonly defaultRepoName: string | null;\n readonly labelCache: Record<string, LabelOption[]>;\n readonly onSubmit: (\n repo: string,\n title: string,\n body: string,\n dueDate: string | null,\n labels?: string[],\n ) => void;\n readonly onCancel: () => void;\n readonly onPauseRefresh?: (() => void) | undefined;\n readonly onResumeRefresh?: (() => void) | undefined;\n readonly onLlmFallback?: ((msg: string) => void) | undefined;\n}\n\nfunction NlCreateOverlay({\n repos,\n defaultRepoName,\n labelCache,\n onSubmit,\n onCancel,\n onPauseRefresh,\n onResumeRefresh,\n onLlmFallback,\n}: NlCreateOverlayProps) {\n const [, setInput] = useState(\"\");\n const [isParsing, setIsParsing] = useState(false);\n const [parsed, setParsed] = useState<ParsedIssue | null>(null);\n const [parseError, setParseError] = useState<string | null>(null);\n const [step, setStep] = useState<Step>(\"input\");\n const [body, setBody] = useState(\"\");\n const [editingBody, setEditingBody] = useState(false);\n\n // Guard against double-submit. Safe because the parent (dashboard) always calls\n // onOverlayDone() → ui.exitOverlay() after onSubmit, unmounting this component\n // on both success and failure paths.\n const submittedRef = useRef(false);\n const parseParamsRef = useRef<{\n input: string;\n validLabels: string[];\n } | null>(null);\n\n // Stable refs to avoid stale closures\n const onSubmitRef = useRef(onSubmit);\n const onCancelRef = useRef(onCancel);\n const onPauseRef = useRef(onPauseRefresh);\n const onResumeRef = useRef(onResumeRefresh);\n onSubmitRef.current = onSubmit;\n onCancelRef.current = onCancel;\n onPauseRef.current = onPauseRefresh;\n onResumeRef.current = onResumeRefresh;\n\n const { setRawMode } = useStdin();\n\n // Repo selection in preview (r key cycles)\n const defaultRepoIdx = defaultRepoName\n ? Math.max(\n 0,\n repos.findIndex((r) => r.name === defaultRepoName),\n )\n : 0;\n const [repoIdx, setRepoIdx] = useState(defaultRepoIdx);\n const selectedRepo = repos[repoIdx];\n\n useInput((inputChar, key) => {\n if (isParsing || editingBody) return;\n\n if (key.escape) {\n if (step === \"body\") {\n // Esc from body step goes back to preview\n setStep(\"input\");\n setParsed((p) => p); // keep parsed\n return;\n }\n onCancel();\n return;\n }\n\n // Preview mode controls\n if (parsed && step === \"input\") {\n if (key.return) {\n // Advance to body step\n setStep(\"body\");\n return;\n }\n if (inputChar === \"r\") {\n setRepoIdx((i) => (i + 1) % repos.length);\n return;\n }\n }\n\n // Body step: ctrl+e opens $EDITOR\n if (step === \"body\" && inputChar === \"\\x05\") {\n setEditingBody(true);\n }\n });\n\n // Launch $EDITOR for body input\n useEffect(() => {\n if (!editingBody) return;\n\n const editorEnv = process.env[\"VISUAL\"] ?? process.env[\"EDITOR\"] ?? \"vi\";\n const [cmd, ...extraArgs] = editorEnv.split(\" \").filter(Boolean);\n if (!cmd) {\n setEditingBody(false);\n return;\n }\n\n let tmpDir: string | null = null;\n let tmpFile: string | null = null;\n\n try {\n onPauseRef.current?.();\n tmpDir = mkdtempSync(join(tmpdir(), \"hog-body-\"));\n tmpFile = join(tmpDir, \"body.md\");\n writeFileSync(tmpFile, body);\n\n const inkInstance = getInkInstance();\n inkInstance?.clear();\n setRawMode(false);\n\n spawnSync(cmd, [...extraArgs, tmpFile], { stdio: \"inherit\" });\n\n const content = readFileSync(tmpFile, \"utf-8\");\n setRawMode(true);\n setBody(content.trimEnd());\n } finally {\n onResumeRef.current?.();\n if (tmpFile && tmpDir) {\n try {\n rmSync(tmpDir, { recursive: true, force: true });\n } catch {\n // ignore cleanup errors\n }\n }\n setEditingBody(false);\n }\n }, [editingBody, body, setRawMode]);\n\n // Parse on Enter from TextInput — capture context at submit time to avoid double-fire\n const handleInputSubmit = useCallback(\n (text: string) => {\n const trimmed = text.trim();\n if (!trimmed) return;\n const validLabels = selectedRepo\n ? (labelCache[selectedRepo.name] ?? []).map((l) => l.name)\n : [];\n parseParamsRef.current = { input: trimmed, validLabels };\n setInput(trimmed);\n setParseError(null);\n setIsParsing(true);\n },\n [selectedRepo, labelCache],\n );\n\n useEffect(() => {\n if (!(isParsing && parseParamsRef.current)) return;\n const { input: capturedInput, validLabels } = parseParamsRef.current;\n\n extractIssueFields(capturedInput, {\n validLabels,\n onLlmFallback: onLlmFallback,\n })\n .then((result) => {\n if (!result) {\n setParseError(\"Title is required\");\n setIsParsing(false);\n return;\n }\n const filteredLabels =\n validLabels.length > 0\n ? result.labels.filter((l) => validLabels.includes(l))\n : result.labels;\n setParsed({ ...result, labels: filteredLabels });\n setIsParsing(false);\n })\n .catch(() => {\n setParseError(\"Parsing failed — please try again\");\n setIsParsing(false);\n });\n }, [isParsing, onLlmFallback]);\n\n // ── Spinner view ──\n if (isParsing) {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n ✨ Creating Issue\n </Text>\n <Spinner label=\"Parsing...\" />\n </Box>\n );\n }\n\n // ── Body step ──\n if (parsed && step === \"body\") {\n if (editingBody) {\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n ✨ Creating Issue\n </Text>\n <Text color=\"cyan\">Opening editor for body…</Text>\n </Box>\n );\n }\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n ✨ Creating Issue\n </Text>\n <Box>\n <Text dimColor>Title: </Text>\n <Text>{parsed.title}</Text>\n </Box>\n <Box>\n <Text color=\"cyan\">body: </Text>\n <TextInput\n defaultValue={body}\n placeholder=\"optional description (ctrl+e for editor)\"\n onChange={setBody}\n onSubmit={(text) => {\n if (submittedRef.current) return;\n submittedRef.current = true;\n if (!selectedRepo) return;\n const labels = buildLabelList(parsed);\n onSubmitRef.current(\n selectedRepo.name,\n parsed.title,\n text.trim(),\n parsed.dueDate,\n labels.length > 0 ? labels : undefined,\n );\n }}\n />\n </Box>\n <Text dimColor>Enter:create ctrl+e:editor Esc:back</Text>\n </Box>\n );\n }\n\n // ── Preview view ──\n if (parsed) {\n const labels = [...parsed.labels];\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n ✨ Creating Issue\n </Text>\n <Box>\n <Text dimColor>Repo: </Text>\n <Text color=\"cyan\">{selectedRepo?.shortName ?? \"(none)\"}</Text>\n {repos.length > 1 ? <Text dimColor> r:cycle</Text> : null}\n </Box>\n <Box>\n <Text dimColor>Title: </Text>\n <Text>{parsed.title}</Text>\n </Box>\n {labels.length > 0 ? (\n <Box>\n <Text dimColor>Labels: </Text>\n <Text>{labels.join(\", \")}</Text>\n </Box>\n ) : null}\n {parsed.assignee ? (\n <Box>\n <Text dimColor>Assignee: </Text>\n <Text>@{parsed.assignee}</Text>\n </Box>\n ) : null}\n {parsed.dueDate ? (\n <Box>\n <Text dimColor>Due: </Text>\n <Text>{formatDue(parsed.dueDate)}</Text>\n </Box>\n ) : null}\n <Text dimColor>Enter:add body Esc:cancel</Text>\n </Box>\n );\n }\n\n // ── Input view ──\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n ✨ What do you need to do?\n </Text>\n <Box>\n <Text color=\"cyan\">&gt; </Text>\n <TextInput\n placeholder=\"fix login bug #bug #priority:high @me due friday\"\n onChange={setInput}\n onSubmit={handleInputSubmit}\n />\n </Box>\n {parseError ? <Text color=\"red\">{parseError}</Text> : null}\n <Text dimColor>Tip: #label @user due &lt;date&gt; Enter:parse Esc:cancel</Text>\n </Box>\n );\n}\n\n/** Build the label list from parsed issue (labels only, due date goes in body). */\nfunction buildLabelList(parsed: ParsedIssue): string[] {\n return [...parsed.labels];\n}\n\n/** Format YYYY-MM-DD as \"Wed Feb 18\". */\nfunction formatDue(dueDate: string): string {\n const d = new Date(`${dueDate}T12:00:00`);\n return d.toLocaleDateString(\"en-US\", { weekday: \"short\", month: \"short\", day: \"numeric\" });\n}\n\nexport { NlCreateOverlay };\n","import { TextInput } from \"@inkjs/ui\";\nimport { Box, Text } from \"ink\";\n\ninterface SearchBarProps {\n readonly defaultValue: string;\n readonly onChange: (value: string) => void;\n readonly onSubmit: () => void;\n}\n\nfunction SearchBar({ defaultValue, onChange, onSubmit }: SearchBarProps) {\n return (\n <Box>\n <Text color=\"yellow\">/</Text>\n <TextInput\n defaultValue={defaultValue}\n placeholder=\"title, label, status, @user, #123, unassigned…\"\n onChange={onChange}\n onSubmit={onSubmit}\n />\n </Box>\n );\n}\n\nexport { SearchBar };\nexport type { SearchBarProps };\n","import { Box, Text, useInput } from \"ink\";\nimport { useRef, useState } from \"react\";\nimport type { StatusOption } from \"../../github.js\";\nimport { TERMINAL_STATUS_RE } from \"../constants.js\";\n\ninterface StatusPickerProps {\n readonly options: StatusOption[];\n readonly currentStatus: string | undefined;\n readonly onSelect: (optionId: string) => void;\n readonly onCancel: () => void;\n /** When true, terminal statuses appear with a \"(Done)\" suffix and require inline confirm */\n readonly showTerminalStatuses?: boolean;\n}\n\nfunction isTerminal(name: string): boolean {\n return TERMINAL_STATUS_RE.test(name);\n}\n\n// ── Input handler extracted to reduce component complexity ──\n\ninterface InputState {\n options: StatusOption[];\n selectedIdx: number;\n showTerminalStatuses: boolean;\n submittedRef: { current: boolean };\n onSelect: (id: string) => void;\n onCancel: () => void;\n onConfirmTerminal: () => void;\n onNavigate: (fn: (i: number) => number) => void;\n}\n\nfunction handlePickerInput(\n input: string,\n key: { escape: boolean; return: boolean; downArrow: boolean; upArrow: boolean },\n state: InputState,\n): void {\n if (key.escape) {\n state.onCancel();\n return;\n }\n if (key.return) {\n if (state.submittedRef.current) return;\n const opt = state.options[state.selectedIdx];\n if (!opt) return;\n if (isTerminal(opt.name) && state.showTerminalStatuses) {\n state.onConfirmTerminal();\n return;\n }\n state.submittedRef.current = true;\n state.onSelect(opt.id);\n return;\n }\n if (input === \"j\" || key.downArrow) {\n state.onNavigate((i) => Math.min(i + 1, state.options.length - 1));\n }\n if (input === \"k\" || key.upArrow) {\n state.onNavigate((i) => Math.max(i - 1, 0));\n }\n}\n\ninterface ConfirmState {\n opt: StatusOption | undefined;\n submittedRef: { current: boolean };\n onSelect: (id: string) => void;\n onExitConfirm: () => void;\n}\n\nfunction handleConfirmInput(input: string, key: { escape: boolean }, state: ConfirmState): void {\n if (input === \"y\" || input === \"Y\") {\n if (!state.submittedRef.current) {\n state.submittedRef.current = true;\n if (state.opt) state.onSelect(state.opt.id);\n }\n return;\n }\n if (input === \"n\" || input === \"N\" || key.escape) {\n state.onExitConfirm();\n }\n}\n\n// ── Component ──\n\nfunction StatusPicker({\n options,\n currentStatus,\n onSelect,\n onCancel,\n showTerminalStatuses = true,\n}: StatusPickerProps) {\n const [selectedIdx, setSelectedIdx] = useState(() => {\n const idx = options.findIndex((o) => o.name === currentStatus);\n return idx >= 0 ? idx : 0;\n });\n const [confirmingTerminal, setConfirmingTerminal] = useState(false);\n const submittedRef = useRef(false);\n\n useInput((input, key) => {\n if (confirmingTerminal) {\n handleConfirmInput(input, key, {\n opt: options[selectedIdx],\n submittedRef,\n onSelect,\n onExitConfirm: () => setConfirmingTerminal(false),\n });\n return;\n }\n handlePickerInput(input, key, {\n options,\n selectedIdx,\n showTerminalStatuses,\n submittedRef,\n onSelect,\n onCancel,\n onConfirmTerminal: () => setConfirmingTerminal(true),\n onNavigate: setSelectedIdx,\n });\n });\n\n if (confirmingTerminal) {\n const opt = options[selectedIdx];\n return (\n <Box flexDirection=\"column\">\n <Text color=\"yellow\" bold>\n Mark as {opt?.name}?\n </Text>\n <Text dimColor>This will close the issue on GitHub.</Text>\n <Text>Continue? [y/n]</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text color=\"cyan\" bold>\n Move to status:\n </Text>\n {options.map((opt, i) => {\n const isCurrent = opt.name === currentStatus;\n const isSelected = i === selectedIdx;\n const terminal = isTerminal(opt.name) && showTerminalStatuses;\n const prefix = isSelected ? \"> \" : \" \";\n const suffix = isCurrent ? \" (current)\" : terminal ? \" (Done)\" : \"\";\n return (\n <Text\n key={opt.id}\n {...(isSelected\n ? { color: \"cyan\" as const }\n : terminal\n ? { color: \"yellow\" as const }\n : {})}\n dimColor={isCurrent}\n >\n {prefix}\n {opt.name}\n {suffix}\n </Text>\n );\n })}\n <Text dimColor>j/k:navigate Enter:select Esc:cancel</Text>\n </Box>\n );\n}\n\nexport { StatusPicker };\n","import type { HogConfig, RepoConfig } from \"../../config.js\";\nimport type { GitHubIssue, LabelOption, StatusOption } from \"../../github.js\";\nimport type { RepoData } from \"../fetch.js\";\nimport type { ActionLogEntry } from \"../hooks/use-action-log.js\";\nimport type { UIState } from \"../hooks/use-ui-state.js\";\nimport type { BulkAction } from \"./bulk-action-menu.js\";\nimport { BulkActionMenu } from \"./bulk-action-menu.js\";\nimport { CommentInput } from \"./comment-input.js\";\nimport { ConfirmPrompt } from \"./confirm-prompt.js\";\nimport { CreateIssueForm } from \"./create-issue-form.js\";\nimport { EditIssueOverlay } from \"./edit-issue-overlay.js\";\nimport type { FocusEndAction } from \"./focus-mode.js\";\nimport { FocusMode } from \"./focus-mode.js\";\nimport { FuzzyPicker } from \"./fuzzy-picker.js\";\nimport { HelpOverlay } from \"./help-overlay.js\";\nimport { LabelPicker } from \"./label-picker.js\";\nimport { NlCreateOverlay } from \"./nl-create-overlay.js\";\nimport { SearchBar } from \"./search-bar.js\";\nimport { StatusPicker } from \"./status-picker.js\";\n\nexport interface OverlayRendererProps {\n readonly uiState: UIState;\n readonly config: HogConfig;\n readonly repos: RepoData[];\n // Fuzzy picker\n readonly onFuzzySelect: (navId: string) => void;\n readonly onFuzzyClose: () => void;\n // Status picker\n readonly selectedRepoStatusOptions: StatusOption[];\n readonly currentStatus: string | undefined;\n readonly onStatusSelect: (optionId: string) => void;\n readonly onExitOverlay: () => void;\n // Create issue\n readonly defaultRepo: string | null;\n readonly onCreateIssue: (\n repo: string,\n title: string,\n body: string,\n dueDate: string | null,\n labels?: string[],\n ) => void;\n // Confirm pick\n readonly onConfirmPick: () => void;\n readonly onCancelPick: () => void;\n // Bulk action\n readonly multiSelectCount: number;\n readonly multiSelectType: \"github\" | \"ticktick\" | \"mixed\";\n readonly onBulkAction: (action: BulkAction) => void;\n // Focus mode\n readonly focusLabel: string | null;\n readonly focusKey: number;\n readonly onFocusExit: () => void;\n readonly onFocusEndAction: (action: FocusEndAction) => void;\n // Search\n readonly searchQuery: string;\n readonly onSearchChange: (query: string) => void;\n readonly onSearchSubmit: () => void;\n // Comment\n readonly selectedIssue: GitHubIssue | null;\n readonly onComment: (body: string) => void;\n readonly onPauseRefresh: () => void;\n readonly onResumeRefresh: () => void;\n // Help\n readonly onToggleHelp: () => void;\n // Label picker\n readonly labelCache: Record<string, LabelOption[]>;\n readonly onLabelConfirm: (addLabels: string[], removeLabels: string[]) => void;\n readonly onLabelError: (msg: string) => void;\n readonly onLlmFallback?: ((msg: string) => void) | undefined;\n // Edit issue overlay\n readonly selectedRepoName: string | null;\n readonly selectedRepoConfig: RepoConfig | null;\n readonly onToastInfo: (msg: string) => void;\n readonly onToastError: (msg: string) => void;\n readonly onPushEntry?: ((entry: ActionLogEntry) => void) | undefined;\n}\n\n/** Renders whichever overlay is active based on uiMode. */\nfunction OverlayRenderer({\n uiState,\n config,\n repos,\n onFuzzySelect,\n onFuzzyClose,\n selectedRepoStatusOptions,\n currentStatus,\n onStatusSelect,\n onExitOverlay,\n defaultRepo,\n onCreateIssue,\n onConfirmPick,\n onCancelPick,\n multiSelectCount,\n multiSelectType,\n onBulkAction,\n focusLabel,\n focusKey,\n onFocusExit,\n onFocusEndAction,\n searchQuery,\n onSearchChange,\n onSearchSubmit,\n selectedIssue,\n onComment,\n onPauseRefresh,\n onResumeRefresh,\n onToggleHelp,\n labelCache,\n onLabelConfirm,\n onLabelError,\n onLlmFallback,\n selectedRepoName,\n selectedRepoConfig,\n onToastInfo,\n onToastError,\n onPushEntry,\n}: OverlayRendererProps) {\n const { mode, helpVisible } = uiState;\n\n return (\n <>\n {/* Help overlay (stacks on top of any mode) */}\n {helpVisible ? <HelpOverlay currentMode={mode} onClose={onToggleHelp} /> : null}\n\n {/* Status picker overlay */}\n {mode === \"overlay:status\" && selectedRepoStatusOptions.length > 0 ? (\n <StatusPicker\n options={selectedRepoStatusOptions}\n currentStatus={currentStatus}\n onSelect={onStatusSelect}\n onCancel={onExitOverlay}\n />\n ) : null}\n\n {/* Create issue form overlay */}\n {mode === \"overlay:create\" ? (\n <CreateIssueForm\n repos={config.repos}\n defaultRepo={defaultRepo}\n onSubmit={onCreateIssue}\n onCancel={onExitOverlay}\n labelCache={labelCache}\n />\n ) : null}\n\n {/* Confirm pick prompt (after issue create) */}\n {mode === \"overlay:confirmPick\" ? (\n <ConfirmPrompt\n message=\"Pick this issue?\"\n onConfirm={onConfirmPick}\n onCancel={onCancelPick}\n />\n ) : null}\n\n {/* Bulk action menu overlay */}\n {mode === \"overlay:bulkAction\" ? (\n <BulkActionMenu\n count={multiSelectCount}\n selectionType={multiSelectType}\n onSelect={onBulkAction}\n onCancel={onExitOverlay}\n />\n ) : null}\n\n {/* Focus mode overlay */}\n {mode === \"focus\" && focusLabel ? (\n <FocusMode\n key={focusKey}\n label={focusLabel}\n durationSec={config.board.focusDuration ?? 1500}\n onExit={onFocusExit}\n onEndAction={onFocusEndAction}\n />\n ) : null}\n\n {/* Label picker overlay */}\n {mode === \"overlay:label\" && selectedIssue && defaultRepo ? (\n <LabelPicker\n repo={defaultRepo}\n currentLabels={selectedIssue.labels.map((l) => l.name)}\n labelCache={labelCache}\n onConfirm={onLabelConfirm}\n onCancel={onExitOverlay}\n onError={onLabelError}\n />\n ) : null}\n\n {/* Search bar */}\n {mode === \"search\" ? (\n <SearchBar defaultValue={searchQuery} onChange={onSearchChange} onSubmit={onSearchSubmit} />\n ) : null}\n\n {/* Comment input */}\n {mode === \"overlay:comment\" && selectedIssue ? (\n <CommentInput\n issueNumber={selectedIssue.number}\n onSubmit={onComment}\n onCancel={onExitOverlay}\n onPauseRefresh={onPauseRefresh}\n onResumeRefresh={onResumeRefresh}\n />\n ) : null}\n\n {/* Fuzzy picker overlay */}\n {mode === \"overlay:fuzzyPicker\" ? (\n <FuzzyPicker repos={repos} onSelect={onFuzzySelect} onClose={onFuzzyClose} />\n ) : null}\n\n {/* NL create overlay */}\n {mode === \"overlay:createNl\" ? (\n <NlCreateOverlay\n repos={config.repos}\n defaultRepoName={defaultRepo}\n labelCache={labelCache}\n onSubmit={onCreateIssue}\n onCancel={onExitOverlay}\n onPauseRefresh={onPauseRefresh}\n onResumeRefresh={onResumeRefresh}\n onLlmFallback={onLlmFallback}\n />\n ) : null}\n\n {/* Edit issue overlay (launches $EDITOR) */}\n {mode === \"overlay:editIssue\" && selectedIssue && selectedRepoName ? (\n <EditIssueOverlay\n issue={selectedIssue}\n repoName={selectedRepoName}\n repoConfig={selectedRepoConfig}\n statusOptions={selectedRepoStatusOptions}\n labelCache={labelCache}\n onDone={onExitOverlay}\n onPauseRefresh={onPauseRefresh}\n onResumeRefresh={onResumeRefresh}\n onToastInfo={onToastInfo}\n onToastError={onToastError}\n {...(onPushEntry ? { onPushEntry } : {})}\n />\n ) : null}\n </>\n );\n}\n\nexport { OverlayRenderer };\n","import { Box } from \"ink\";\nimport type { ReactNode } from \"react\";\n\n// ── Breakpoints ──\n\nexport const WIDE_THRESHOLD = 160; // full 5-panel layout\nexport const MEDIUM_THRESHOLD = 100; // 2-column (left + issues), no detail\nexport const LEFT_COL_WIDTH = 24;\nexport const ACTIVITY_HEIGHT = 5;\n\nexport type LayoutMode = \"wide\" | \"medium\" | \"stacked\";\n\nexport function getLayoutMode(cols: number): LayoutMode {\n if (cols >= WIDE_THRESHOLD) return \"wide\";\n if (cols >= MEDIUM_THRESHOLD) return \"medium\";\n return \"stacked\";\n}\n\nexport function getDetailWidth(cols: number): number {\n return Math.floor(cols * 0.4);\n}\n\n// ── Panel slots ──\n\ninterface PanelLayoutProps {\n readonly cols: number;\n readonly issuesPanelHeight: number;\n readonly reposPanel: ReactNode;\n readonly statusesPanel: ReactNode;\n readonly issuesPanel: ReactNode;\n readonly detailPanel: ReactNode;\n readonly activityPanel: ReactNode;\n}\n\nexport function PanelLayout({\n cols,\n issuesPanelHeight,\n reposPanel,\n statusesPanel,\n issuesPanel,\n detailPanel,\n activityPanel,\n}: PanelLayoutProps) {\n const mode = getLayoutMode(cols);\n\n if (mode === \"wide\") {\n const detailWidth = getDetailWidth(cols);\n return (\n <Box flexDirection=\"column\">\n {/* Main row: left col + issues + detail */}\n <Box height={issuesPanelHeight}>\n {/* Left column: repos + statuses stacked */}\n <Box flexDirection=\"column\" width={LEFT_COL_WIDTH}>\n {reposPanel}\n {statusesPanel}\n </Box>\n {/* Issues panel fills remaining space */}\n <Box flexGrow={1} flexDirection=\"column\">\n {issuesPanel}\n </Box>\n {/* Detail panel on the right */}\n <Box width={detailWidth} flexDirection=\"column\">\n {detailPanel}\n </Box>\n </Box>\n {/* Activity strip full width */}\n <Box height={ACTIVITY_HEIGHT}>{activityPanel}</Box>\n </Box>\n );\n }\n\n if (mode === \"medium\") {\n return (\n <Box flexDirection=\"column\">\n {/* Main row: left col + issues (no detail) */}\n <Box height={issuesPanelHeight}>\n <Box flexDirection=\"column\" width={LEFT_COL_WIDTH}>\n {reposPanel}\n {statusesPanel}\n </Box>\n <Box flexGrow={1} flexDirection=\"column\">\n {issuesPanel}\n </Box>\n </Box>\n {/* Activity strip full width */}\n <Box height={ACTIVITY_HEIGHT}>{activityPanel}</Box>\n </Box>\n );\n }\n\n // Stacked (<100 cols): all panels full width, fixed heights\n return (\n <Box flexDirection=\"column\">\n {reposPanel}\n {statusesPanel}\n <Box flexGrow={1} flexDirection=\"column\">\n {issuesPanel}\n </Box>\n <Box height={ACTIVITY_HEIGHT}>{activityPanel}</Box>\n </Box>\n );\n}\n\nexport type { PanelLayoutProps };\n","import { Box, Text } from \"ink\";\nimport { Panel } from \"./panel.js\";\n\nexport interface RepoItem {\n name: string;\n openCount: number;\n}\n\nexport interface ReposPanelProps {\n readonly repos: RepoItem[];\n readonly selectedIdx: number;\n readonly isActive: boolean;\n readonly width: number;\n readonly flexGrow?: number;\n}\n\nfunction shortName(fullName: string): string {\n return fullName.includes(\"/\") ? (fullName.split(\"/\")[1] ?? fullName) : fullName;\n}\n\nexport function ReposPanel({ repos, selectedIdx, isActive, width, flexGrow }: ReposPanelProps) {\n // inner content width = total - 2 border chars - 2 padding chars from Box\n const maxLabel = Math.max(4, width - 8); // leave room for \"► \" + \" 99\" + borders\n\n return (\n <Panel title=\"[1] Repos\" isActive={isActive} width={width} flexGrow={flexGrow}>\n {repos.length === 0 ? (\n <Text color=\"gray\">—</Text>\n ) : (\n repos.map((repo, i) => {\n const isSel = i === selectedIdx;\n const label = shortName(repo.name).slice(0, maxLabel);\n return (\n <Box key={repo.name}>\n <Text color={isSel ? \"cyan\" : isActive ? \"white\" : \"gray\"} bold={isSel}>\n {isSel ? \"► \" : \" \"}\n {label}\n </Text>\n <Text color=\"gray\"> {repo.openCount}</Text>\n </Box>\n );\n })\n )}\n </Panel>\n );\n}\n","import { Box, Text } from \"ink\";\nimport type { GitHubIssue } from \"../../github.js\";\n\ninterface IssueRowProps {\n readonly issue: GitHubIssue;\n readonly selfLogin: string;\n readonly isSelected: boolean;\n /** Outer panel width (including border chars). Used to compute title column width. */\n readonly panelWidth: number;\n}\n\nfunction truncate(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, max - 1)}\\u2026` : s;\n}\n\nfunction formatDate(issue: GitHubIssue): { text: string; color: string } {\n if (issue.targetDate) {\n const d = new Date(issue.targetDate);\n const days = Math.ceil((d.getTime() - Date.now()) / 86_400_000);\n if (days < 0) return { text: `${Math.abs(days)}d overdue`, color: \"red\" };\n if (days === 0) return { text: \"today\", color: \"yellow\" };\n if (days === 1) return { text: \"tomorrow\", color: \"white\" };\n if (days <= 7) return { text: `in ${days}d`, color: \"white\" };\n return {\n text: d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" }),\n color: \"gray\",\n };\n }\n const seconds = Math.floor((Date.now() - new Date(issue.updatedAt).getTime()) / 1000);\n if (seconds < 60) return { text: \"now\", color: \"gray\" };\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return { text: `${minutes}m`, color: \"gray\" };\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return { text: `${hours}h`, color: \"gray\" };\n const days = Math.floor(hours / 24);\n if (days < 30) return { text: `${days}d`, color: \"gray\" };\n const months = Math.floor(days / 30);\n return { text: `${months}mo`, color: \"gray\" };\n}\n\nconst PLAIN_ABBREVS: Record<string, string> = {\n bug: \"bug\",\n feature: \"feat\",\n enhancement: \"enh\",\n documentation: \"docs\",\n \"good first issue\": \"gfi\",\n help: \"help\",\n question: \"?\",\n urgent: \"urg!\",\n wontfix: \"wont\",\n task: \"task\",\n};\n\nfunction compactLabel(name: string): string {\n const lc = name.toLowerCase();\n const colon = lc.indexOf(\":\");\n if (colon < 0) return PLAIN_ABBREVS[lc] ?? name.slice(0, 5);\n const key = lc.slice(0, colon);\n const val = name.slice(colon + 1);\n if (key === \"size\") return val.slice(0, 3).toUpperCase();\n if (key === \"priority\") return `p:${val.slice(0, 1).toUpperCase()}`;\n if (key === \"work\") return \"WIP\";\n return `${key.slice(0, 2)}:${val.slice(0, 2)}`;\n}\n\nfunction labelColor(name: string): string {\n const lc = name.toLowerCase();\n if (lc === \"bug\" || lc === \"urgent\" || lc.startsWith(\"priority:h\") || lc.startsWith(\"priority:c\"))\n return \"red\";\n if (lc.startsWith(\"priority:m\") || lc.startsWith(\"work:\")) return \"yellow\";\n if (lc.startsWith(\"priority:l\") || lc === \"wontfix\") return \"gray\";\n if (lc.startsWith(\"size:\")) return \"white\";\n if (lc === \"feature\" || lc === \"enhancement\") return \"green\";\n if (lc === \"documentation\") return \"blue\";\n if (lc === \"good first issue\") return \"magenta\";\n return \"cyan\";\n}\n\n// ── Fixed column widths ──────────────────────────────────────────────────────\n//\n// ► #1234 <title…> [sM] [p:H] username in 4d\n// 2 7 titleW 13 1 10 1 10\n//\n// Inner width = panelWidth - 2 (subtract │ on each side)\n// Fixed overhead = 2 + 7 + 1 + LABEL_W + 1 + ASSIGN_W + 1 + DATE_W = 35\n// titleW = innerW - fixed overhead\n//\nconst CURSOR_W = 2; // \"► \" or \" \"\nconst NUM_W = 7; // \"#xxxx \" (padEnd(5) + 1 space)\nconst LABEL_W = 13; // up to 2 compact labels: \"[bug] [p:H]\"\nconst ASSIGN_W = 10;\nconst DATE_W = 10; // \"3d overdue\" fits in 10\nconst FIXED_OVERHEAD = CURSOR_W + NUM_W + 1 + LABEL_W + 1 + ASSIGN_W + 1 + DATE_W;\n\nfunction IssueRow({ issue, selfLogin, isSelected, panelWidth }: IssueRowProps) {\n const assignees = issue.assignees ?? [];\n const isSelf = assignees.some((a) => a.login === selfLogin);\n const isUnassigned = assignees.length === 0;\n\n const assigneeColor = isSelf ? \"green\" : isUnassigned ? \"gray\" : \"white\";\n const assigneeText = isUnassigned\n ? \"unassigned\"\n : truncate(assignees.map((a) => a.login).join(\", \"), ASSIGN_W);\n\n const labels = (issue.labels ?? []).slice(0, 2);\n const date = formatDate(issue);\n\n // Dynamic title column: fill whatever space remains after fixed columns\n const innerW = panelWidth - 2;\n const titleW = Math.max(8, innerW - FIXED_OVERHEAD);\n const titleStr = truncate(issue.title, titleW).padEnd(titleW);\n const dateStr = date.text.padStart(DATE_W);\n\n return (\n <Box>\n {/* Cursor */}\n {isSelected ? (\n <Text color=\"cyan\" bold>\n {\"\\u25B6 \"}\n </Text>\n ) : (\n <Text>{\" \"}</Text>\n )}\n\n {/* Issue number */}\n <Text color=\"cyan\">#{String(issue.number).padEnd(5)}</Text>\n <Text> </Text>\n\n {/* Title — truncated to exact titleW so total row width is deterministic */}\n {isSelected ? (\n <Text bold color=\"white\">\n {titleStr}\n </Text>\n ) : (\n <Text>{titleStr}</Text>\n )}\n <Text> </Text>\n\n {/* Labels — compact abbreviations in a fixed-width slot */}\n <Box width={LABEL_W} overflow=\"hidden\">\n {labels.length === 0 ? (\n <Text color=\"gray\">{\" \".repeat(LABEL_W)}</Text>\n ) : (\n labels.map((l, i) => (\n <Text key={l.name}>\n {i > 0 ? \" \" : \"\"}\n <Text color={labelColor(l.name)}>[{compactLabel(l.name)}]</Text>\n </Text>\n ))\n )}\n </Box>\n <Text> </Text>\n\n {/* Assignee */}\n <Text color={assigneeColor}>{assigneeText.padEnd(ASSIGN_W)}</Text>\n <Text> </Text>\n\n {/* Date — target date takes priority over updatedAt */}\n <Text color={date.color}>{dateStr}</Text>\n </Box>\n );\n}\n\nexport { IssueRow };\nexport type { IssueRowProps };\n","import { Box, Text } from \"ink\";\nimport type { GitHubIssue } from \"../../github.js\";\nimport type { ActivityEvent } from \"../fetch.js\";\nimport { IssueRow } from \"./issue-row.js\";\n\n// ── Types ──\n\nexport type FlatRow =\n | {\n type: \"sectionHeader\";\n key: string;\n navId: string;\n label: string;\n count: number;\n countLabel: string;\n isCollapsed: boolean;\n }\n | {\n type: \"subHeader\";\n key: string;\n navId: string | null;\n text: string;\n count?: number;\n isCollapsed?: boolean;\n }\n | { type: \"issue\"; key: string; navId: string; issue: GitHubIssue; repoName: string }\n | { type: \"activity\"; key: string; navId: null; event: ActivityEvent }\n | { type: \"error\"; key: string; navId: null; text: string }\n | { type: \"gap\"; key: string; navId: null };\n\ninterface RowRendererProps {\n readonly row: FlatRow;\n readonly selectedId: string | null;\n readonly selfLogin: string;\n readonly isMultiSelected?: boolean | undefined;\n /** Outer issues panel width — passed to IssueRow for single-line truncation. */\n readonly panelWidth?: number | undefined;\n}\n\nexport function RowRenderer({\n row,\n selectedId,\n selfLogin,\n isMultiSelected,\n panelWidth = 120,\n}: RowRendererProps) {\n switch (row.type) {\n case \"sectionHeader\": {\n const arrow = row.isCollapsed ? \"\\u25B6\" : \"\\u25BC\";\n const isSel = selectedId === row.navId;\n return (\n <Box>\n <Text color={isSel ? \"cyan\" : \"white\"} bold>\n {arrow} {row.label}\n </Text>\n <Text color=\"gray\">\n {\" \"}\n ({row.count} {row.countLabel})\n </Text>\n </Box>\n );\n }\n case \"subHeader\": {\n if (row.navId) {\n const arrow = row.isCollapsed ? \"\\u25B6\" : \"\\u25BC\";\n const isSel = selectedId === row.navId;\n return (\n <Box>\n <Text color={isSel ? \"cyan\" : \"gray\"}>\n {\" \"}\n {arrow} {row.text}\n </Text>\n <Text color=\"gray\"> ({row.count})</Text>\n </Box>\n );\n }\n return (\n <Box>\n <Text bold color=\"white\">\n {\" \"}\n {row.text}\n </Text>\n {row.count != null ? <Text color=\"gray\"> ({row.count})</Text> : null}\n </Box>\n );\n }\n case \"issue\": {\n const checkbox = isMultiSelected != null ? (isMultiSelected ? \"\\u2611 \" : \"\\u2610 \") : \"\";\n return (\n <Box>\n {checkbox ? <Text color={isMultiSelected ? \"cyan\" : \"gray\"}>{checkbox}</Text> : null}\n <IssueRow\n issue={row.issue}\n selfLogin={selfLogin}\n isSelected={selectedId === row.navId}\n panelWidth={panelWidth}\n />\n </Box>\n );\n }\n case \"activity\": {\n const ago = new Date(row.event.timestamp).toLocaleTimeString();\n return (\n <Text dimColor>\n {\" \"}\n {ago}: <Text color=\"gray\">@{row.event.actor}</Text> {row.event.summary}{\" \"}\n <Text dimColor>({row.event.repoShortName})</Text>\n </Text>\n );\n }\n case \"error\":\n return <Text color=\"red\"> Error: {row.text}</Text>;\n case \"gap\":\n return <Text>{\"\"}</Text>;\n }\n}\n","import { Box, Text } from \"ink\";\nimport { Panel } from \"./panel.js\";\n\nexport interface StatusItem {\n id: string;\n label: string;\n count: number;\n}\n\nexport interface StatusesPanelProps {\n readonly groups: StatusItem[];\n readonly selectedIdx: number;\n readonly isActive: boolean;\n readonly width: number;\n readonly flexGrow?: number;\n}\n\nexport function StatusesPanel({\n groups,\n selectedIdx,\n isActive,\n width,\n flexGrow,\n}: StatusesPanelProps) {\n const maxLabel = Math.max(4, width - 8);\n\n return (\n <Panel title=\"[2] Statuses\" isActive={isActive} width={width} flexGrow={flexGrow}>\n {groups.length === 0 ? (\n <Text color=\"gray\">—</Text>\n ) : (\n groups.map((group, i) => {\n const isSel = i === selectedIdx;\n const label = group.label.slice(0, maxLabel);\n return (\n <Box key={group.id}>\n <Text color={isSel ? \"cyan\" : isActive ? \"white\" : \"gray\"} bold={isSel}>\n {isSel ? \"► \" : \" \"}\n {label}\n </Text>\n <Text color=\"gray\"> {group.count}</Text>\n </Box>\n );\n })\n )}\n </Panel>\n );\n}\n","import { Spinner } from \"@inkjs/ui\";\nimport { Box, Text } from \"ink\";\nimport type { Toast } from \"../hooks/use-toast.js\";\n\ninterface ToastContainerProps {\n toasts: Toast[];\n}\n\nconst TYPE_COLORS = {\n info: \"cyan\",\n success: \"green\",\n error: \"red\",\n loading: \"cyan\",\n} as const;\n\nconst TYPE_PREFIXES = {\n info: \"\\u2139\",\n success: \"\\u2713\",\n error: \"\\u2717\",\n} as const;\n\nexport function ToastContainer({ toasts }: ToastContainerProps) {\n if (toasts.length === 0) return null;\n\n return (\n <Box flexDirection=\"column\">\n {toasts.map((t) => (\n <Box key={t.id}>\n {t.type === \"loading\" ? (\n <>\n <Spinner label=\"\" />\n <Text color=\"cyan\"> {t.message}</Text>\n </>\n ) : (\n <Text color={TYPE_COLORS[t.type]}>\n {TYPE_PREFIXES[t.type]} {t.message}\n {t.type === \"error\" ? (\n <Text color=\"gray\">{t.retry ? \" [r]etry [d]ismiss\" : \" [d]ismiss\"}</Text>\n ) : null}\n </Text>\n )}\n </Box>\n ))}\n </Box>\n );\n}\n","import { execFileSync, spawnSync } from \"node:child_process\";\nimport { Spinner } from \"@inkjs/ui\";\nimport { Box, Text, useApp, useStdout } from \"ink\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { getClipboardArgs } from \"../../clipboard.js\";\nimport type { HogConfig, RepoConfig } from \"../../config.js\";\nimport type { GitHubIssue, IssueComment, LabelOption, StatusOption } from \"../../github.js\";\nimport { fetchIssueCommentsAsync } from \"../../github.js\";\nimport { isHeaderId, isTerminalStatus, timeAgo } from \"../constants.js\";\nimport type { ActivityEvent, FetchOptions, RepoData } from \"../fetch.js\";\nimport { useActionLog } from \"../hooks/use-action-log.js\";\nimport { useActions } from \"../hooks/use-actions.js\";\nimport { refreshAgeColor, useData } from \"../hooks/use-data.js\";\nimport { useKeyboard } from \"../hooks/use-keyboard.js\";\nimport { useMultiSelect } from \"../hooks/use-multi-select.js\";\nimport type { NavItem } from \"../hooks/use-navigation.js\";\nimport { useNavigation } from \"../hooks/use-navigation.js\";\nimport { usePanelFocus } from \"../hooks/use-panel-focus.js\";\nimport { useToast } from \"../hooks/use-toast.js\";\nimport { useUIState } from \"../hooks/use-ui-state.js\";\nimport { launchClaude } from \"../launch-claude.js\";\nimport { ActionLog } from \"./action-log.js\";\nimport { ActivityPanel } from \"./activity-panel.js\";\nimport type { BulkAction } from \"./bulk-action-menu.js\";\nimport { DetailPanel } from \"./detail-panel.js\";\nimport type { FocusEndAction } from \"./focus-mode.js\";\nimport { HintBar } from \"./hint-bar.js\";\nimport { OverlayRenderer } from \"./overlay-renderer.js\";\nimport { Panel } from \"./panel.js\";\nimport {\n ACTIVITY_HEIGHT,\n getDetailWidth,\n getLayoutMode,\n LEFT_COL_WIDTH,\n PanelLayout,\n} from \"./panel-layout.js\";\nimport { ReposPanel } from \"./repos-panel.js\";\nimport type { FlatRow } from \"./row-renderer.js\";\nimport { RowRenderer } from \"./row-renderer.js\";\nimport { StatusesPanel } from \"./statuses-panel.js\";\nimport { ToastContainer } from \"./toast-container.js\";\n\n// ── Types ──\n\ninterface DashboardProps {\n readonly config: HogConfig;\n readonly options: FetchOptions;\n readonly activeProfile?: string | null;\n}\n\n// ── Helpers ──\n\ninterface StatusGroup {\n label: string;\n statuses: string[];\n}\n\ninterface BoardGroup {\n label: string;\n subId: string; // `sub:${repo.name}:${label}` — globally unique\n issues: GitHubIssue[];\n}\n\ninterface BoardSection {\n repo: RepoConfig;\n sectionId: string; // repo.name — globally unique\n groups: BoardGroup[];\n error: string | null;\n}\n\ninterface BoardTree {\n activity: ActivityEvent[];\n sections: BoardSection[];\n}\n\n/**\n * Resolve status groups for a repo.\n * If `configuredGroups` is provided, use those (each entry is \"Status1,Status2\" — first is header).\n * Otherwise, auto-detect from statusOptions (non-terminal statuses, Backlog last).\n */\nfunction resolveStatusGroups(\n statusOptions: StatusOption[],\n configuredGroups?: string[],\n): StatusGroup[] {\n if (configuredGroups && configuredGroups.length > 0) {\n return configuredGroups.map((entry) => {\n const statuses = entry\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n return { label: statuses[0] ?? entry, statuses };\n });\n }\n\n // Auto-detect: each non-terminal status is its own group, Backlog last\n const nonTerminal = statusOptions.map((o) => o.name).filter((s) => !isTerminalStatus(s));\n if (nonTerminal.length > 0 && !nonTerminal.includes(\"Backlog\")) {\n nonTerminal.push(\"Backlog\");\n }\n const order = nonTerminal.length > 0 ? nonTerminal : [\"In Progress\", \"Backlog\"];\n return order.map((s) => ({ label: s, statuses: [s] }));\n}\n\n/** Extract priority rank from labels. Lower number = higher priority. */\nconst PRIORITY_RANK: Record<string, number> = {\n \"priority:critical\": 0,\n \"priority:high\": 1,\n \"priority:medium\": 2,\n \"priority:low\": 3,\n};\n\nfunction issuePriorityRank(issue: GitHubIssue): number {\n for (const label of issue.labels ?? []) {\n const rank = PRIORITY_RANK[label.name.toLowerCase()];\n if (rank != null) return rank;\n }\n return 99; // no priority label\n}\n\n/** Group issues by project status. Issues without status go to \"Backlog\". Sorted by priority within groups. */\nfunction groupByStatus(issues: GitHubIssue[]): Map<string, GitHubIssue[]> {\n const groups = new Map<string, GitHubIssue[]>();\n for (const issue of issues) {\n const status = issue.projectStatus ?? \"Backlog\";\n const list = groups.get(status);\n if (list) {\n list.push(issue);\n } else {\n groups.set(status, [issue]);\n }\n }\n // Sort each group by priority (high first)\n for (const [, list] of groups) {\n list.sort((a, b) => issuePriorityRank(a) - issuePriorityRank(b));\n }\n return groups;\n}\n\n/** Build the unified board tree — single source of truth for all nav/row builders. */\nfunction buildBoardTree(repos: RepoData[], activity: ActivityEvent[]): BoardTree {\n const sections = repos.map((rd): BoardSection => {\n const sectionId = rd.repo.name;\n\n if (rd.error) {\n return { repo: rd.repo, sectionId, groups: [], error: rd.error };\n }\n\n const statusGroupDefs = resolveStatusGroups(rd.statusOptions, rd.repo.statusGroups);\n const byStatus = groupByStatus(rd.issues);\n const coveredKeys = new Set<string>(); // normalized (lowercase-trim) covered keys\n const groups: BoardGroup[] = [];\n\n for (const sg of statusGroupDefs) {\n const issues: GitHubIssue[] = [];\n for (const [status, statusIssues] of byStatus) {\n if (sg.statuses.some((s) => s.toLowerCase().trim() === status.toLowerCase().trim())) {\n issues.push(...statusIssues);\n }\n }\n if (issues.length === 0) continue;\n issues.sort((a, b) => issuePriorityRank(a) - issuePriorityRank(b));\n groups.push({ label: sg.label, subId: `sub:${sectionId}:${sg.label}`, issues });\n for (const s of sg.statuses) coveredKeys.add(s.toLowerCase().trim());\n }\n\n // Overflow: uncovered non-terminal statuses\n for (const [status, statusIssues] of byStatus) {\n if (!(coveredKeys.has(status.toLowerCase().trim()) || isTerminalStatus(status))) {\n groups.push({ label: status, subId: `sub:${sectionId}:${status}`, issues: statusIssues });\n }\n }\n\n return { repo: rd.repo, sectionId, groups, error: null };\n });\n\n return { activity, sections };\n}\n\n// ── Panel-based row builders ──\n\nfunction buildNavItemsForRepo(\n sections: BoardSection[],\n repoName: string | null,\n statusGroupId: string | null,\n): NavItem[] {\n if (!repoName) return [];\n const section = sections.find((s) => s.sectionId === repoName);\n if (!section) return [];\n const activeGroup = section.groups.find((g) => g.subId === statusGroupId) ?? section.groups[0];\n if (!activeGroup) return [];\n return activeGroup.issues.map((issue) => ({\n id: `gh:${section.repo.name}:${issue.number}`,\n section: repoName,\n type: \"item\" as const,\n }));\n}\n\nfunction buildFlatRowsForRepo(\n sections: BoardSection[],\n repoName: string | null,\n statusGroupId: string | null,\n): FlatRow[] {\n if (!repoName) {\n return [\n {\n type: \"subHeader\" as const,\n key: \"select-repo\",\n navId: null,\n text: \"Select a repo in panel [1]\",\n },\n ];\n }\n const section = sections.find((s) => s.sectionId === repoName);\n if (!section) return [];\n if (section.error) {\n return [{ type: \"error\" as const, key: `error:${repoName}`, navId: null, text: section.error }];\n }\n if (section.groups.length === 0) {\n return [\n {\n type: \"subHeader\" as const,\n key: `empty:${repoName}`,\n navId: null,\n text: \"No open issues\",\n },\n ];\n }\n const activeGroup = section.groups.find((g) => g.subId === statusGroupId) ?? section.groups[0];\n if (!activeGroup) return [];\n if (activeGroup.issues.length === 0) {\n return [\n {\n type: \"subHeader\" as const,\n key: `empty-group:${statusGroupId}`,\n navId: null,\n text: \"No issues in this status group\",\n },\n ];\n }\n return activeGroup.issues.map((issue) => ({\n type: \"issue\" as const,\n key: `gh:${section.repo.name}:${issue.number}`,\n navId: `gh:${section.repo.name}:${issue.number}`,\n issue,\n repoName: section.repo.name,\n }));\n}\n\nfunction openInBrowser(url: string): void {\n if (!(url.startsWith(\"https://\") || url.startsWith(\"http://\"))) return;\n try {\n execFileSync(\"open\", [url], { stdio: \"ignore\" });\n } catch {\n // Silently ignore\n }\n}\n\nfunction findSelectedIssueWithRepo(\n repos: RepoData[],\n selectedId: string | null,\n): { issue: GitHubIssue; repoName: string } | null {\n if (!selectedId?.startsWith(\"gh:\")) return null;\n for (const rd of repos) {\n for (const issue of rd.issues) {\n if (`gh:${rd.repo.name}:${issue.number}` === selectedId)\n return { issue, repoName: rd.repo.name };\n }\n }\n return null;\n}\n\n// ── RefreshAge ──\n\nfunction RefreshAge({ lastRefresh }: { readonly lastRefresh: Date | null }) {\n const [, setTick] = useState(0);\n useEffect(() => {\n const id = setInterval(() => setTick((t) => t + 1), 10_000);\n return () => clearInterval(id);\n }, []);\n if (!lastRefresh) return null;\n return <Text color={refreshAgeColor(lastRefresh)}>Updated {timeAgo(lastRefresh)}</Text>;\n}\n\n// ── Smart search ──\n//\n// Tokens are split on whitespace and AND-ed together.\n// Each token matches if ANY of the following is true:\n// #123 → exact issue number\n// @alice → assignee login substring (@ prefix optional)\n// unassigned → no assignees\n// assigned → has at least one assignee\n// <text> → substring of title, any label name, projectStatus, or assignee login\n\nfunction matchesSearch(issue: GitHubIssue, query: string): boolean {\n if (!query.trim()) return true;\n const tokens = query.toLowerCase().trim().split(/\\s+/);\n const labels = issue.labels ?? [];\n const assignees = issue.assignees ?? [];\n\n return tokens.every((token) => {\n // Issue number: #123\n if (token.startsWith(\"#\")) {\n const num = parseInt(token.slice(1), 10);\n return !Number.isNaN(num) && issue.number === num;\n }\n\n // Explicit assignee: @alice\n if (token.startsWith(\"@\")) {\n const login = token.slice(1);\n return assignees.some((a) => a.login.toLowerCase().includes(login));\n }\n\n // Special keywords\n if (token === \"unassigned\") return assignees.length === 0;\n if (token === \"assigned\") return assignees.length > 0;\n\n // Title\n if (issue.title.toLowerCase().includes(token)) return true;\n\n // Labels — full name (e.g. \"bug\", \"priority:high\", \"size:m\")\n // Substring match means \"high\" finds \"priority:high\", \"m\" finds \"size:m\", etc.\n if (labels.some((l) => l.name.toLowerCase().includes(token))) return true;\n\n // Project status (e.g. \"in progress\", \"backlog\")\n if (issue.projectStatus?.toLowerCase().includes(token)) return true;\n\n // Custom project fields (Workstream, Size, Priority, Iteration, etc.)\n if (\n issue.customFields &&\n Object.values(issue.customFields).some((v) => v.toLowerCase().includes(token))\n )\n return true;\n\n // Assignee login without @ prefix\n if (assignees.some((a) => a.login.toLowerCase().includes(token))) return true;\n\n return false;\n });\n}\n\n// ── Issues panel box (scrollable list + detail) ──\n\nconst CHROME_ROWS = 3; // header (1) + hintbar (1) + paddingX top/bottom (1)\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: main TUI orchestrator\nfunction Dashboard({ config, options, activeProfile }: DashboardProps) {\n const { exit } = useApp();\n const refreshMs = config.board.refreshInterval * 1000;\n const {\n status,\n data,\n error,\n lastRefresh,\n isRefreshing,\n consecutiveFailures,\n autoRefreshPaused,\n refresh,\n mutateData,\n pauseAutoRefresh,\n resumeAutoRefresh,\n registerPendingMutation,\n clearPendingMutation,\n } = useData(config, options, refreshMs);\n\n // Stable empty arrays to avoid new references when data is null\n const allRepos = useMemo(() => data?.repos ?? [], [data?.repos]);\n const allActivity = useMemo(() => data?.activity ?? [], [data?.activity]);\n\n // UI state machine\n const ui = useUIState();\n\n // Panel focus state — default to Issues panel [3]\n const panelFocus = usePanelFocus(3);\n\n // Search state (managed separately — search query persists across mode changes)\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n // My-issues filter: toggle between all issues and issues assigned to me\n const [mineOnly, setMineOnly] = useState(false);\n const handleToggleMine = useCallback(() => {\n setMineOnly((prev) => !prev);\n }, []);\n\n // Toast notification system (replaces old statusMessage)\n const { toasts, toast, handleErrorAction } = useToast();\n\n // Action log\n const [logVisible, setLogVisible] = useState(false);\n const { entries: logEntries, pushEntry, undoLast, hasUndoable } = useActionLog(toast, refresh);\n\n // Auto-expand log when an error entry is pushed\n useEffect(() => {\n const last = logEntries[logEntries.length - 1];\n if (last?.status === \"error\") setLogVisible(true);\n }, [logEntries]);\n\n // After data loads, surface TickTick errors\n useEffect(() => {\n if (data?.ticktickError) {\n toast.error(`TickTick sync failed: ${data.ticktickError}`);\n }\n }, [data?.ticktickError, toast.error]);\n\n // Filter by search query and/or mineOnly\n const repos = useMemo(() => {\n let filtered = allRepos;\n if (mineOnly) {\n const me = config.board.assignee;\n filtered = filtered\n .map((rd) => ({\n ...rd,\n issues: rd.issues.filter((i) => (i.assignees ?? []).some((a) => a.login === me)),\n }))\n .filter((rd) => rd.issues.length > 0);\n }\n if (!searchQuery) return filtered;\n return filtered\n .map((rd) => ({ ...rd, issues: rd.issues.filter((i) => matchesSearch(i, searchQuery)) }))\n .filter((rd) => rd.issues.length > 0);\n }, [allRepos, searchQuery, mineOnly, config.board.assignee]);\n\n // Single source of truth — computed once (no tasks)\n const boardTree = useMemo(() => buildBoardTree(repos, allActivity), [repos, allActivity]);\n\n // Panel [1] — Repos cursor\n const [selectedRepoIdx, setSelectedRepoIdx] = useState(0);\n const clampedRepoIdx = Math.min(selectedRepoIdx, Math.max(0, boardTree.sections.length - 1));\n\n const reposNav = {\n moveUp: useCallback(() => setSelectedRepoIdx((i) => Math.max(0, i - 1)), []),\n moveDown: useCallback(\n () => setSelectedRepoIdx((i) => Math.min(Math.max(0, boardTree.sections.length - 1), i + 1)),\n [boardTree.sections.length],\n ),\n };\n\n // Panel [2] — Statuses cursor\n const [selectedStatusIdx, setSelectedStatusIdx] = useState(0);\n const selectedSection = boardTree.sections[clampedRepoIdx] ?? null;\n const clampedStatusIdx = Math.min(\n selectedStatusIdx,\n Math.max(0, (selectedSection?.groups.length ?? 1) - 1),\n );\n\n const statusesNav = {\n moveUp: useCallback(() => setSelectedStatusIdx((i) => Math.max(0, i - 1)), []),\n moveDown: useCallback(\n () =>\n setSelectedStatusIdx((i) =>\n Math.min(Math.max(0, (selectedSection?.groups.length ?? 1) - 1), i + 1),\n ),\n [selectedSection?.groups.length],\n ),\n };\n\n // Panel [4] — Activity cursor\n const [activitySelectedIdx, setActivitySelectedIdx] = useState(0);\n const clampedActivityIdx = Math.min(\n activitySelectedIdx,\n Math.max(0, boardTree.activity.length - 1),\n );\n\n const activityNav = {\n moveUp: useCallback(() => setActivitySelectedIdx((i) => Math.max(0, i - 1)), []),\n moveDown: useCallback(\n () =>\n setActivitySelectedIdx((i) => Math.min(Math.max(0, boardTree.activity.length - 1), i + 1)),\n [boardTree.activity.length],\n ),\n };\n\n // Derived selection state\n const selectedRepoName = selectedSection?.sectionId ?? null;\n const selectedStatusGroup = selectedSection?.groups[clampedStatusIdx] ?? null;\n const selectedStatusGroupId = selectedStatusGroup?.subId ?? null;\n\n // Panel Enter handlers\n const onRepoEnter = useCallback(() => {\n setSelectedStatusIdx(0);\n panelFocus.focusPanel(3);\n }, [panelFocus]);\n\n const onStatusEnter = useCallback(() => {\n panelFocus.focusPanel(3);\n }, [panelFocus]);\n\n const onActivityEnter = useCallback(() => {\n const event = boardTree.activity[clampedActivityIdx];\n if (!event) return;\n const repoIdx = boardTree.sections.findIndex(\n (s) =>\n s.repo.shortName === event.repoShortName || s.sectionId.endsWith(`/${event.repoShortName}`),\n );\n if (repoIdx >= 0) {\n setSelectedRepoIdx(repoIdx);\n setSelectedStatusIdx(0);\n panelFocus.focusPanel(3);\n }\n }, [boardTree, clampedActivityIdx, panelFocus]);\n\n // Navigation — flat item list for active repo + status group\n const navItems = useMemo(\n () => buildNavItemsForRepo(boardTree.sections, selectedRepoName, selectedStatusGroupId),\n [boardTree.sections, selectedRepoName, selectedStatusGroupId],\n );\n const nav = useNavigation(navItems);\n\n // Multi-select: resolve nav ID → repo name for same-repo constraint\n const getRepoForId = useCallback((id: string): string | null => {\n if (id.startsWith(\"gh:\")) {\n const parts = id.split(\":\");\n return parts.length >= 3 ? `${parts[1]}` : null;\n }\n return null;\n }, []);\n const multiSelect = useMultiSelect(getRepoForId);\n\n // Prune multi-select when items change (e.g., issue closed during refresh)\n useEffect(() => {\n if (multiSelect.count === 0) return;\n const validIds = new Set(navItems.map((i) => i.id));\n multiSelect.prune(validIds);\n }, [navItems, multiSelect]);\n\n // Actions hook\n const actions = useActions({\n config,\n repos,\n selectedId: nav.selectedId,\n toast,\n refresh,\n mutateData,\n onOverlayDone: ui.exitOverlay,\n pushEntry,\n registerPendingMutation,\n clearPendingMutation,\n });\n\n // \"Pick this issue?\" after create — stores the newly created issue info\n const pendingPickRef = useRef<{ repo: string; issueNumber: number } | null>(null);\n\n // Session-level label cache to avoid re-fetching on every overlay open\n const labelCacheRef = useRef<Record<string, LabelOption[]>>({});\n\n // Comment cache: key = \"repo:issueNumber\" → comments or loading/error state\n const commentCacheRef = useRef<Record<string, IssueComment[] | \"loading\" | \"error\">>({});\n // Tick counter triggers re-render when cache is updated (ref changes don't re-render on their own)\n const [commentTick, setCommentTick] = useState(0);\n\n const handleFetchComments = useCallback((repo: string, issueNumber: number) => {\n const key = `${repo}:${issueNumber}`;\n if (commentCacheRef.current[key] !== undefined) return;\n commentCacheRef.current[key] = \"loading\";\n setCommentTick((t) => t + 1);\n fetchIssueCommentsAsync(repo, issueNumber)\n .then((comments) => {\n commentCacheRef.current[key] = comments;\n setCommentTick((t) => t + 1);\n })\n .catch(() => {\n commentCacheRef.current[key] = \"error\";\n setCommentTick((t) => t + 1);\n });\n }, []);\n\n const handleCreateIssueWithPrompt = useCallback(\n (repo: string, title: string, body: string, dueDate: string | null, labels?: string[]) => {\n actions.handleCreateIssue(repo, title, body, dueDate, labels).then((result) => {\n if (result) {\n pendingPickRef.current = result;\n ui.enterConfirmPick();\n }\n });\n },\n [actions, ui],\n );\n\n const handleConfirmPick = useCallback(() => {\n const pending = pendingPickRef.current;\n pendingPickRef.current = null;\n ui.exitOverlay();\n if (!pending) return;\n\n const rc = config.repos.find((r) => r.name === pending.repo);\n if (!rc) return;\n\n const t = toast.loading(`Picking ${rc.shortName}#${pending.issueNumber}...`);\n import(\"../../pick.js\").then(({ pickIssue }) =>\n pickIssue(config, { repo: rc, issueNumber: pending.issueNumber })\n .then((result) => {\n const msg = `Picked ${rc.shortName}#${pending.issueNumber} — assigned + synced to TickTick`;\n t.resolve(result.warning ? `${msg} (${result.warning})` : msg);\n refresh();\n })\n .catch((err: unknown) => {\n t.reject(`Pick failed: ${err instanceof Error ? err.message : String(err)}`);\n }),\n );\n }, [config, toast, refresh, ui]);\n\n const handleCancelPick = useCallback(() => {\n pendingPickRef.current = null;\n ui.exitOverlay();\n }, [ui]);\n\n // Focus mode state\n const [focusLabel, setFocusLabel] = useState<string | null>(null);\n\n const handleEnterFocus = useCallback(() => {\n const id = nav.selectedId;\n if (!id || isHeaderId(id)) return;\n\n let label = \"\";\n if (id.startsWith(\"gh:\")) {\n const found = findSelectedIssueWithRepo(repos, id);\n if (found) {\n const rc = config.repos.find((r) => r.name === found.repoName);\n label = `${rc?.shortName ?? found.repoName}#${found.issue.number} — ${found.issue.title}`;\n }\n }\n\n if (!label) return;\n setFocusLabel(label);\n ui.enterFocus();\n }, [nav.selectedId, repos, config.repos, ui]);\n\n const handleFocusExit = useCallback(() => {\n setFocusLabel(null);\n ui.exitToNormal();\n }, [ui]);\n\n const handleFocusEndAction = useCallback(\n (action: FocusEndAction) => {\n switch (action) {\n case \"restart\":\n toast.info(\"Focus restarted!\");\n setFocusLabel((prev) => prev); // no-op to preserve label\n setFocusKey((k) => k + 1);\n break;\n case \"break\":\n toast.info(\"Break time! Step away for a few minutes.\");\n setFocusLabel(null);\n ui.exitToNormal();\n break;\n case \"done\":\n toast.success(\"Focus session complete!\");\n setFocusLabel(null);\n ui.exitToNormal();\n break;\n case \"exit\":\n setFocusLabel(null);\n ui.exitToNormal();\n break;\n }\n },\n [toast, ui],\n );\n\n // Key to force-remount FocusMode on restart\n const [focusKey, setFocusKey] = useState(0);\n\n // Terminal dimensions\n const { stdout } = useStdout();\n const [termSize, setTermSize] = useState({\n cols: stdout?.columns ?? 80,\n rows: stdout?.rows ?? 24,\n });\n useEffect(() => {\n if (!stdout) return;\n const onResize = () => setTermSize({ cols: stdout.columns, rows: stdout.rows });\n stdout.on(\"resize\", onResize);\n return () => {\n stdout.off(\"resize\", onResize);\n };\n }, [stdout]);\n\n const layoutMode = getLayoutMode(termSize.cols);\n const detailPanelWidth =\n layoutMode === \"wide\" ? getDetailWidth(termSize.cols) : Math.floor(termSize.cols * 0.35);\n const showDetailPanel = layoutMode === \"wide\";\n\n // Explicit widths for title-in-border rendering (usableWidth = cols - 2 for paddingX={1})\n const usableWidth = termSize.cols - 2;\n const issuesPanelWidth = Math.max(\n 20,\n layoutMode === \"wide\"\n ? usableWidth - LEFT_COL_WIDTH - getDetailWidth(termSize.cols)\n : layoutMode === \"medium\"\n ? usableWidth - LEFT_COL_WIDTH\n : usableWidth,\n );\n const activityPanelWidth = usableWidth;\n\n const overlayBarRows = ui.state.mode === \"search\" || ui.state.mode === \"overlay:comment\" ? 1 : 0;\n const toastRows = toasts.length;\n const logPaneRows = logVisible ? 4 : 0;\n\n // Total height available for the panel layout (issues + activity)\n const totalPanelHeight = Math.max(\n 8,\n termSize.rows - CHROME_ROWS - overlayBarRows - toastRows - logPaneRows,\n );\n const issuesPanelHeight = Math.max(5, totalPanelHeight - ACTIVITY_HEIGHT);\n\n // Build flat rows for issues panel\n const flatRows = useMemo(\n () => buildFlatRowsForRepo(boardTree.sections, selectedRepoName, selectedStatusGroupId),\n [boardTree.sections, selectedRepoName, selectedStatusGroupId],\n );\n\n // Scroll offset - tracks viewport position\n const scrollRef = useRef(0);\n // Reset scroll to top when switching repos or status groups\n const prevRepoRef = useRef<string | null>(null);\n const prevStatusRef = useRef<string | null>(null);\n if (selectedRepoName !== prevRepoRef.current || selectedStatusGroupId !== prevStatusRef.current) {\n prevRepoRef.current = selectedRepoName;\n prevStatusRef.current = selectedStatusGroupId;\n scrollRef.current = 0;\n }\n\n const selectedRowIdx = useMemo(\n () => flatRows.findIndex((r) => r.navId === nav.selectedId),\n [flatRows, nav.selectedId],\n );\n\n // Adjust scroll to keep selected item visible\n if (selectedRowIdx >= 0) {\n if (selectedRowIdx < scrollRef.current) {\n scrollRef.current = selectedRowIdx;\n } else if (selectedRowIdx >= scrollRef.current + issuesPanelHeight) {\n scrollRef.current = selectedRowIdx - issuesPanelHeight + 1;\n }\n }\n const maxOffset = Math.max(0, flatRows.length - issuesPanelHeight);\n scrollRef.current = Math.max(0, Math.min(scrollRef.current, maxOffset));\n\n const visibleRows = flatRows.slice(scrollRef.current, scrollRef.current + issuesPanelHeight);\n const hasMoreAbove = scrollRef.current > 0;\n const hasMoreBelow = scrollRef.current + issuesPanelHeight < flatRows.length;\n const aboveCount = scrollRef.current;\n const belowCount = flatRows.length - scrollRef.current - issuesPanelHeight;\n\n // Find selected item for detail panel and overlays\n const selectedItem = useMemo((): {\n issue: GitHubIssue | null;\n repoName: string | null;\n } => {\n const id = nav.selectedId;\n if (!id || isHeaderId(id)) return { issue: null, repoName: null };\n if (id.startsWith(\"gh:\")) {\n for (const rd of repos) {\n for (const issue of rd.issues) {\n if (`gh:${rd.repo.name}:${issue.number}` === id) return { issue, repoName: rd.repo.name };\n }\n }\n }\n return { issue: null, repoName: null };\n }, [nav.selectedId, repos]);\n\n // Derive current commentsState (re-computes on tick or selected issue change)\n // biome-ignore lint/correctness/useExhaustiveDependencies: commentTick is a cache-invalidation signal; it's intentionally in deps without being used in the body\n const currentCommentsState = useMemo((): IssueComment[] | \"loading\" | \"error\" | null => {\n if (!(selectedItem.issue && selectedItem.repoName)) return null;\n return commentCacheRef.current[`${selectedItem.repoName}:${selectedItem.issue.number}`] ?? null;\n }, [selectedItem.issue, selectedItem.repoName, commentTick]);\n\n // Repo config for the selected issue's repo (for edit issue overlay)\n const selectedRepoConfig = useMemo(() => {\n if (!selectedItem.repoName) return null;\n return config.repos.find((r) => r.name === selectedItem.repoName) ?? null;\n }, [selectedItem.repoName, config.repos]);\n\n // Status options for the selected issue's repo (for status picker, single or bulk)\n const selectedRepoStatusOptions = useMemo(() => {\n const repoName = multiSelect.count > 0 ? multiSelect.constrainedRepo : selectedItem.repoName;\n if (!repoName) return [];\n const rd = repos.find((r) => r.repo.name === repoName);\n return rd?.statusOptions ?? [];\n }, [selectedItem.repoName, repos, multiSelect.count, multiSelect.constrainedRepo]);\n\n // Input handlers\n const handleOpen = useCallback(() => {\n const found = findSelectedIssueWithRepo(repos, nav.selectedId);\n if (found) openInBrowser(found.issue.url);\n }, [repos, nav.selectedId]);\n\n const handleSlack = useCallback(() => {\n const found = findSelectedIssueWithRepo(repos, nav.selectedId);\n if (!found?.issue.slackThreadUrl) return;\n openInBrowser(found.issue.slackThreadUrl);\n }, [repos, nav.selectedId]);\n\n const handleCopyLink = useCallback(() => {\n const found = findSelectedIssueWithRepo(repos, nav.selectedId);\n if (!found) return;\n const rc = config.repos.find((r) => r.name === found.repoName);\n const label = `${rc?.shortName ?? found.repoName}#${found.issue.number}`;\n const clipArgs = getClipboardArgs();\n if (clipArgs) {\n const [cmd, ...args] = clipArgs;\n if (!cmd) {\n toast.info(`${label} — ${found.issue.url}`);\n return;\n }\n const result = spawnSync(cmd, args, {\n input: found.issue.url,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n if (result.status === 0) {\n toast.success(`Copied ${label} to clipboard`);\n } else {\n toast.info(`${label} — ${found.issue.url}`);\n }\n } else {\n toast.info(`${label} — ${found.issue.url}`);\n }\n }, [repos, nav.selectedId, config.repos, toast]);\n\n const handleLaunchClaude = useCallback(() => {\n const found = findSelectedIssueWithRepo(repos, nav.selectedId);\n if (!found) return; // cursor on header / empty row → silent no-op\n\n const rc = config.repos.find((r) => r.name === found.repoName);\n if (!rc?.localPath) {\n toast.info(\n `Set localPath for ${rc?.shortName ?? found.repoName} in ~/.config/hog/config.json to enable Claude Code launch`,\n );\n return;\n }\n\n const resolvedStartCommand = rc.claudeStartCommand ?? config.board.claudeStartCommand;\n const result = launchClaude({\n localPath: rc.localPath,\n issue: { number: found.issue.number, title: found.issue.title, url: found.issue.url },\n ...(resolvedStartCommand ? { startCommand: resolvedStartCommand } : {}),\n launchMode: config.board.claudeLaunchMode ?? \"auto\",\n ...(config.board.claudeTerminalApp ? { terminalApp: config.board.claudeTerminalApp } : {}),\n repoFullName: found.repoName,\n });\n\n if (!result.ok) {\n toast.error(result.error.message);\n return;\n }\n\n toast.info(`Claude Code session opened in ${rc.shortName ?? found.repoName}`);\n }, [repos, nav.selectedId, config.repos, config.board, toast]);\n\n // Multi-select selection type (for bulk action menu)\n const multiSelectType = useMemo((): \"github\" | \"ticktick\" | \"mixed\" => {\n for (const id of multiSelect.selected) {\n if (id.startsWith(\"tt:\")) return \"ticktick\";\n }\n return \"github\";\n }, [multiSelect.selected]);\n\n // Bulk action handler (called from BulkActionMenu)\n const handleBulkAction = useCallback(\n (action: BulkAction) => {\n const ids = multiSelect.selected;\n\n switch (action.type) {\n case \"assign\": {\n ui.exitOverlay();\n actions.handleBulkAssign(ids).then((failedIds) => {\n if (failedIds.length > 0) {\n multiSelect.clear();\n for (const id of failedIds) multiSelect.toggle(id);\n } else {\n multiSelect.clear();\n ui.clearMultiSelect();\n }\n });\n return;\n }\n case \"unassign\": {\n ui.exitOverlay();\n actions.handleBulkUnassign(ids).then((failedIds) => {\n if (failedIds.length > 0) {\n multiSelect.clear();\n for (const id of failedIds) multiSelect.toggle(id);\n } else {\n multiSelect.clear();\n ui.clearMultiSelect();\n }\n });\n return;\n }\n case \"statusChange\":\n ui.enterStatus();\n return;\n case \"complete\":\n case \"delete\":\n toast.info(`Bulk ${action.type} not yet implemented`);\n ui.exitOverlay();\n multiSelect.clear();\n return;\n }\n },\n [multiSelect, actions, ui, toast],\n );\n\n // Bulk status change handler (from StatusPicker when in multiSelect mode)\n const handleBulkStatusSelect = useCallback(\n (optionId: string) => {\n const ids = multiSelect.selected;\n ui.exitOverlay();\n actions.handleBulkStatusChange(ids, optionId).then((failedIds) => {\n if (failedIds.length > 0) {\n multiSelect.clear();\n for (const id of failedIds) multiSelect.toggle(id);\n } else {\n multiSelect.clear();\n ui.clearMultiSelect();\n }\n });\n },\n [multiSelect, actions, ui],\n );\n\n // Fuzzy picker handlers\n const handleFuzzySelect = useCallback(\n (navId: string) => {\n nav.select(navId);\n if (navId.startsWith(\"gh:\")) {\n const parts = navId.split(\":\");\n const repoName = parts[1];\n if (parts.length >= 3 && repoName) {\n const repoIdx = boardTree.sections.findIndex((s) => s.sectionId === repoName);\n if (repoIdx >= 0) {\n setSelectedRepoIdx(repoIdx);\n const section = boardTree.sections[repoIdx];\n const issueNum = parts[2] ? Number(parts[2]) : null;\n const groupIdx =\n section?.groups.findIndex((g) => g.issues.some((iss) => iss.number === issueNum)) ??\n -1;\n setSelectedStatusIdx(Math.max(0, groupIdx));\n }\n }\n }\n ui.exitToNormal();\n },\n [nav, ui, boardTree],\n );\n\n // Keyboard input — all useInput handlers live in use-keyboard.ts\n const onSearchEscape = useCallback(() => {\n ui.exitOverlay();\n setSearchQuery(\"\");\n }, [ui]);\n\n useKeyboard({\n ui,\n nav,\n multiSelect,\n selectedIssue: selectedItem.issue,\n selectedRepoStatusOptionsLength: selectedRepoStatusOptions.length,\n actions: {\n exit,\n refresh,\n handleSlack,\n handleCopyLink,\n handleOpen,\n handleEnterFocus,\n handlePick: actions.handlePick,\n handleAssign: actions.handleAssign,\n handleEnterLabel: ui.enterLabel,\n handleEnterCreateNl: ui.enterCreateNl,\n handleErrorAction,\n toastInfo: toast.info,\n handleToggleMine,\n handleEnterFuzzyPicker: ui.enterFuzzyPicker,\n handleEnterEditIssue: ui.enterEditIssue,\n handleUndo: undoLast,\n handleToggleLog: () => setLogVisible((v) => !v),\n handleLaunchClaude,\n },\n onSearchEscape,\n panelFocus,\n reposNav,\n statusesNav,\n activityNav,\n onRepoEnter,\n onStatusEnter,\n onActivityEnter,\n showDetailPanel,\n });\n\n // Loading state\n if (status === \"loading\" && !data) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <Spinner label=\"Loading dashboard...\" />\n </Box>\n );\n }\n\n const now = data?.fetchedAt ?? new Date();\n const dateStr = now.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n\n // Panel [1] — Repos data\n const reposData = boardTree.sections.map(({ repo, groups }) => ({\n name: repo.name,\n openCount: groups.reduce((s, g) => s + g.issues.length, 0),\n }));\n\n // Panel [2] — Statuses data\n const statusesData = (selectedSection?.groups ?? []).map(({ label, subId, issues }) => ({\n id: subId,\n label,\n count: issues.length,\n }));\n\n // Panels\n const reposPanel = (\n <ReposPanel\n repos={reposData}\n selectedIdx={clampedRepoIdx}\n isActive={panelFocus.activePanelId === 1}\n width={LEFT_COL_WIDTH}\n />\n );\n\n const statusesPanel = (\n <StatusesPanel\n groups={statusesData}\n selectedIdx={clampedStatusIdx}\n isActive={panelFocus.activePanelId === 2}\n width={LEFT_COL_WIDTH}\n flexGrow={1}\n />\n );\n\n const issuesPanelTitle = `[3] Issues${selectedSection ? ` — ${selectedSection.repo.shortName}` : \"\"}${selectedStatusGroup ? ` / ${selectedStatusGroup.label}` : \"\"}`;\n\n const issuesPanel = (\n <Panel\n title={issuesPanelTitle}\n isActive={panelFocus.activePanelId === 3}\n width={issuesPanelWidth}\n flexGrow={1}\n >\n {hasMoreAbove ? (\n <Text color=\"gray\" dimColor>\n {\" \"}\n {\"\\u25B2\"} {aboveCount} more above\n </Text>\n ) : null}\n {visibleRows.map((row) => (\n <RowRenderer\n key={row.key}\n row={row}\n selectedId={nav.selectedId}\n selfLogin={config.board.assignee}\n panelWidth={issuesPanelWidth}\n isMultiSelected={\n ui.state.mode === \"multiSelect\" && row.navId\n ? multiSelect.isSelected(row.navId)\n : undefined\n }\n />\n ))}\n {hasMoreBelow ? (\n <Text color=\"gray\" dimColor>\n {\" \"}\n {\"\\u25BC\"} {belowCount} more below\n </Text>\n ) : null}\n </Panel>\n );\n\n const detailPanel = showDetailPanel ? (\n <DetailPanel\n issue={selectedItem.issue}\n width={detailPanelWidth}\n isActive={panelFocus.activePanelId === 0}\n issueRepo={selectedItem.repoName}\n fetchComments={handleFetchComments}\n commentsState={currentCommentsState}\n />\n ) : null;\n\n const activityPanel = (\n <ActivityPanel\n events={boardTree.activity}\n selectedIdx={clampedActivityIdx}\n isActive={panelFocus.activePanelId === 4}\n height={ACTIVITY_HEIGHT}\n width={activityPanelWidth}\n />\n );\n\n return (\n <Box flexDirection=\"column\" paddingX={1}>\n {/* Header */}\n <Box>\n <Text color=\"cyan\" bold>\n HOG BOARD\n </Text>\n {activeProfile ? <Text color=\"yellow\"> [{activeProfile}]</Text> : null}\n <Text color=\"gray\">\n {\" \"}\n {\"\\u2014\"} {dateStr}\n </Text>\n <Text> </Text>\n {isRefreshing ? (\n <>\n <Spinner label=\"\" />\n <Text color=\"cyan\"> Refreshing...</Text>\n </>\n ) : (\n <>\n <RefreshAge lastRefresh={lastRefresh} />\n {consecutiveFailures > 0 ? <Text color=\"red\"> (!)</Text> : null}\n </>\n )}\n {autoRefreshPaused ? (\n <Text color=\"yellow\"> Auto-refresh paused — press r to retry</Text>\n ) : null}\n </Box>\n\n {error ? <Text color=\"red\">Error: {error}</Text> : null}\n\n {/* Overlays — rendered by OverlayRenderer */}\n <OverlayRenderer\n uiState={ui.state}\n config={config}\n repos={allRepos}\n onFuzzySelect={handleFuzzySelect}\n onFuzzyClose={ui.exitToNormal}\n selectedRepoStatusOptions={selectedRepoStatusOptions}\n currentStatus={multiSelect.count > 0 ? undefined : selectedItem.issue?.projectStatus}\n onStatusSelect={multiSelect.count > 0 ? handleBulkStatusSelect : actions.handleStatusChange}\n onExitOverlay={ui.exitOverlay}\n defaultRepo={selectedItem.repoName}\n onCreateIssue={handleCreateIssueWithPrompt}\n onConfirmPick={handleConfirmPick}\n onCancelPick={handleCancelPick}\n multiSelectCount={multiSelect.count}\n multiSelectType={multiSelectType}\n onBulkAction={handleBulkAction}\n focusLabel={focusLabel}\n focusKey={focusKey}\n onFocusExit={handleFocusExit}\n onFocusEndAction={handleFocusEndAction}\n searchQuery={searchQuery}\n onSearchChange={setSearchQuery}\n onSearchSubmit={ui.exitOverlay}\n selectedIssue={selectedItem.issue}\n onComment={actions.handleComment}\n onPauseRefresh={pauseAutoRefresh}\n onResumeRefresh={resumeAutoRefresh}\n onToggleHelp={ui.toggleHelp}\n labelCache={labelCacheRef.current}\n onLabelConfirm={actions.handleLabelChange}\n onLabelError={(msg) => toast.error(msg)}\n onLlmFallback={(msg) => toast.info(msg)}\n selectedRepoName={selectedItem.repoName}\n selectedRepoConfig={selectedRepoConfig}\n onToastInfo={toast.info}\n onToastError={toast.error}\n onPushEntry={pushEntry}\n />\n\n {/* Detail overlay — full-screen on narrow layouts (no side panel) */}\n {ui.state.mode === \"overlay:detail\" ? (\n <DetailPanel\n issue={selectedItem.issue}\n width={usableWidth}\n height={issuesPanelHeight + ACTIVITY_HEIGHT}\n isActive={true}\n issueRepo={selectedItem.repoName}\n fetchComments={handleFetchComments}\n commentsState={currentCommentsState}\n />\n ) : null}\n\n {/* Main content: 5-panel layout (hidden during full-screen overlays) */}\n {!ui.state.helpVisible &&\n ui.state.mode !== \"overlay:status\" &&\n ui.state.mode !== \"overlay:create\" &&\n ui.state.mode !== \"overlay:createNl\" &&\n ui.state.mode !== \"overlay:bulkAction\" &&\n ui.state.mode !== \"overlay:confirmPick\" &&\n ui.state.mode !== \"overlay:detail\" &&\n ui.state.mode !== \"focus\" ? (\n <PanelLayout\n cols={termSize.cols}\n issuesPanelHeight={issuesPanelHeight}\n reposPanel={reposPanel}\n statusesPanel={statusesPanel}\n issuesPanel={issuesPanel}\n detailPanel={detailPanel}\n activityPanel={activityPanel}\n />\n ) : null}\n\n {/* Toast notifications */}\n <ToastContainer toasts={toasts} />\n\n {/* Action log pane */}\n {logVisible ? <ActionLog entries={logEntries} /> : null}\n\n {/* Status bar */}\n <HintBar\n uiMode={ui.state.mode}\n activePanelId={panelFocus.activePanelId}\n multiSelectCount={multiSelect.count}\n searchQuery={searchQuery}\n mineOnly={mineOnly}\n hasUndoable={hasUndoable}\n />\n </Box>\n );\n}\n\nexport { Dashboard, matchesSearch };\nexport type { DashboardProps };\n","import { render } from \"ink\";\nimport type { HogConfig } from \"../config.js\";\nimport { Dashboard } from \"./components/dashboard.js\";\nimport type { FetchOptions } from \"./fetch.js\";\nimport { setInkInstance } from \"./ink-instance.js\";\n\nexport async function runLiveDashboard(\n config: HogConfig,\n options: FetchOptions,\n activeProfile?: string | null,\n): Promise<void> {\n const instance = render(\n <Dashboard config={config} options={options} activeProfile={activeProfile ?? null} />,\n );\n setInkInstance(instance);\n\n await instance.waitUntilExit();\n}\n","import { execFileSync } from \"node:child_process\";\nimport { TickTickClient } from \"../api.js\";\nimport type { HogConfig, RepoConfig } from \"../config.js\";\nimport { getConfig, requireAuth } from \"../config.js\";\nimport type { GitHubIssue, StatusOption } from \"../github.js\";\nimport { fetchProjectEnrichment, fetchProjectStatusOptions, fetchRepoIssues } from \"../github.js\";\nimport type { Task } from \"../types.js\";\nimport { TaskStatus } from \"../types.js\";\nimport { formatError } from \"./constants.js\";\n\nexport interface RepoData {\n repo: RepoConfig;\n issues: GitHubIssue[];\n statusOptions: StatusOption[];\n error: string | null;\n}\n\nexport interface ActivityEvent {\n type: \"comment\" | \"status\" | \"assignment\" | \"opened\" | \"closed\" | \"labeled\";\n repoShortName: string;\n issueNumber: number;\n actor: string;\n summary: string;\n timestamp: Date;\n}\n\nexport interface DashboardData {\n repos: RepoData[];\n ticktick: Task[];\n ticktickError: string | null;\n activity: ActivityEvent[];\n fetchedAt: Date;\n}\n\nexport interface FetchOptions {\n repoFilter?: string | undefined;\n mineOnly?: boolean | undefined;\n backlogOnly?: boolean | undefined;\n}\n\nexport const SLACK_URL_RE = /https:\\/\\/[^/]+\\.slack\\.com\\/archives\\/[A-Z0-9]+\\/p[0-9]+/i;\n\nexport function extractSlackUrl(body: string | undefined): string | undefined {\n if (!body) return undefined;\n const match = body.match(SLACK_URL_RE);\n return match?.[0];\n}\n\n/** Fetch recent activity events for a repo (last 24h, max 30 events) */\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: parses multiple GitHub event types\nexport function fetchRecentActivity(repoName: string, shortName: string): ActivityEvent[] {\n try {\n const output = execFileSync(\n \"gh\",\n [\n \"api\",\n `repos/${repoName}/events`,\n \"--paginate\",\n \"-q\",\n '.[] | select(.type == \"IssuesEvent\" or .type == \"IssueCommentEvent\" or .type == \"PullRequestEvent\") | {type: .type, actor: .actor.login, action: .payload.action, number: (.payload.issue.number // .payload.pull_request.number), title: (.payload.issue.title // .payload.pull_request.title), body: .payload.comment.body, created_at: .created_at}',\n ],\n { encoding: \"utf-8\", timeout: 15_000 },\n );\n\n const cutoff = Date.now() - 24 * 60 * 60 * 1000;\n const events: ActivityEvent[] = [];\n\n for (const line of output.trim().split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const ev = JSON.parse(line) as {\n type: string;\n actor: string;\n action: string;\n number: number | null;\n title: string | null;\n body: string | null;\n created_at: string;\n };\n\n const timestamp = new Date(ev.created_at);\n if (timestamp.getTime() < cutoff) continue;\n if (!ev.number) continue;\n\n let eventType: ActivityEvent[\"type\"];\n let summary: string;\n\n if (ev.type === \"IssueCommentEvent\") {\n eventType = \"comment\";\n const preview = ev.body ? ev.body.slice(0, 60).replace(/\\n/g, \" \") : \"\";\n summary = `commented on #${ev.number}${preview ? ` — \"${preview}${(ev.body?.length ?? 0) > 60 ? \"...\" : \"\"}\"` : \"\"}`;\n } else if (ev.type === \"IssuesEvent\") {\n switch (ev.action) {\n case \"opened\":\n eventType = \"opened\";\n summary = `opened #${ev.number}: ${ev.title ?? \"\"}`;\n break;\n case \"closed\":\n eventType = \"closed\";\n summary = `closed #${ev.number}`;\n break;\n case \"assigned\":\n eventType = \"assignment\";\n summary = `assigned #${ev.number}`;\n break;\n case \"labeled\":\n eventType = \"labeled\";\n summary = `labeled #${ev.number}`;\n break;\n default:\n continue;\n }\n } else {\n continue;\n }\n\n events.push({\n type: eventType,\n repoShortName: shortName,\n issueNumber: ev.number,\n actor: ev.actor,\n summary,\n timestamp,\n });\n } catch {\n // Skip malformed event\n }\n }\n\n return events.slice(0, 15);\n } catch {\n return [];\n }\n}\n\nexport async function fetchDashboard(\n config: HogConfig,\n options: FetchOptions = {},\n): Promise<DashboardData> {\n const repos = options.repoFilter\n ? config.repos.filter(\n (r) => r.shortName === options.repoFilter || r.name === options.repoFilter,\n )\n : config.repos;\n\n // GitHub: synchronous (uses gh CLI via execFileSync)\n const repoData: RepoData[] = repos.map((repo) => {\n try {\n const fetchOpts: { assignee?: string } = {};\n if (options.mineOnly) {\n fetchOpts.assignee = config.board.assignee;\n }\n const issues = fetchRepoIssues(repo.name, fetchOpts);\n\n // Enrich issues with target dates + statuses from GitHub Projects (batched)\n let enrichedIssues = issues;\n let statusOptions: StatusOption[] = [];\n try {\n const enrichMap = fetchProjectEnrichment(repo.name, repo.projectNumber);\n enrichedIssues = issues.map((issue): GitHubIssue => {\n const e = enrichMap.get(issue.number);\n const slackUrl = extractSlackUrl(issue.body ?? \"\");\n return {\n ...issue,\n ...(e?.targetDate !== undefined ? { targetDate: e.targetDate } : {}),\n ...(e?.projectStatus !== undefined ? { projectStatus: e.projectStatus } : {}),\n ...(e?.customFields !== undefined ? { customFields: e.customFields } : {}),\n ...(slackUrl ? { slackThreadUrl: slackUrl } : {}),\n };\n });\n statusOptions = fetchProjectStatusOptions(\n repo.name,\n repo.projectNumber,\n repo.statusFieldId,\n );\n } catch {\n // Non-critical: silently skip if project fields fail\n // Compute Slack thread URLs from original issue bodies\n enrichedIssues = issues.map((issue): GitHubIssue => {\n const slackUrl = extractSlackUrl(issue.body ?? \"\");\n return slackUrl ? { ...issue, slackThreadUrl: slackUrl } : issue;\n });\n }\n\n return { repo, issues: enrichedIssues, statusOptions, error: null };\n } catch (err) {\n return { repo, issues: [], statusOptions: [], error: formatError(err) };\n }\n });\n\n // TickTick: async (uses HTTP API) — skip when disabled in config\n let ticktick: Task[] = [];\n let ticktickError: string | null = null;\n if (config.ticktick.enabled) {\n try {\n const auth = requireAuth();\n const api = new TickTickClient(auth.accessToken);\n const cfg = getConfig();\n if (cfg.defaultProjectId) {\n const tasks = await api.listTasks(cfg.defaultProjectId);\n ticktick = tasks.filter((t) => t.status !== TaskStatus.Completed);\n }\n } catch (err) {\n ticktickError = formatError(err);\n }\n }\n\n // Activity: fetch recent events from all repos (non-blocking, best-effort)\n const activity: ActivityEvent[] = [];\n for (const repo of repos) {\n const events = fetchRecentActivity(repo.name, repo.shortName);\n activity.push(...events);\n }\n // Sort by timestamp descending\n activity.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n\n return {\n repos: repoData,\n ticktick,\n ticktickError,\n activity: activity.slice(0, 15),\n fetchedAt: new Date(),\n };\n}\n","import chalk from \"chalk\";\n\nexport interface Theme {\n text: {\n primary: (s: string) => string;\n secondary: (s: string) => string;\n muted: (s: string) => string;\n success: (s: string) => string;\n warning: (s: string) => string;\n error: (s: string) => string;\n accent: (s: string) => string;\n };\n border: {\n primary: (s: string) => string;\n muted: (s: string) => string;\n focus: (s: string) => string;\n };\n priority: {\n high: (s: string) => string;\n medium: (s: string) => string;\n low: (s: string) => string;\n none: (s: string) => string;\n };\n assignee: {\n self: (s: string) => string;\n others: (s: string) => string;\n unassigned: (s: string) => string;\n };\n}\n\nexport const darkTheme: Theme = {\n text: {\n primary: chalk.white,\n secondary: chalk.gray,\n muted: chalk.dim,\n success: chalk.green,\n warning: chalk.yellow,\n error: chalk.red,\n accent: chalk.cyan,\n },\n border: {\n primary: chalk.gray,\n muted: chalk.dim,\n focus: chalk.cyan,\n },\n priority: {\n high: chalk.red,\n medium: chalk.yellow,\n low: chalk.blue,\n none: chalk.gray,\n },\n assignee: {\n self: chalk.greenBright,\n others: chalk.white,\n unassigned: chalk.dim,\n },\n};\n\nexport function getTheme(): Theme {\n return darkTheme;\n}\n","import type { GitHubIssue } from \"../github.js\";\nimport type { Task } from \"../types.js\";\nimport { Priority } from \"../types.js\";\nimport type { DashboardData, RepoData } from \"./fetch.js\";\nimport { getTheme } from \"./theme.js\";\n\nconst theme = getTheme();\n\nfunction truncate(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, max - 1)}\\u2026` : s;\n}\n\nfunction issueAssignee(issue: GitHubIssue, selfLogin: string): string {\n const assignees = issue.assignees ?? [];\n if (assignees.length === 0) return theme.assignee.unassigned(\"unassigned\");\n const names = assignees.map((a) => a.login);\n const isSelf = names.includes(selfLogin);\n const display = names.join(\", \");\n return isSelf ? theme.assignee.self(display) : theme.assignee.others(display);\n}\n\nfunction formatIssueLine(issue: GitHubIssue, selfLogin: string, maxTitle: number): string {\n const num = theme.text.accent(`#${String(issue.number).padEnd(5)}`);\n const title = truncate(issue.title, maxTitle);\n const assignee = issueAssignee(issue, selfLogin);\n return ` ${num} ${title.padEnd(maxTitle)} ${assignee}`;\n}\n\nfunction formatTaskLine(task: Task, maxTitle: number): string {\n const pri =\n task.priority === Priority.High\n ? theme.priority.high(\"[!]\")\n : task.priority === Priority.Medium\n ? theme.priority.medium(\"[~]\")\n : \" \";\n const title = truncate(task.title, maxTitle);\n const due = task.dueDate ? formatDueDate(task.dueDate) : \"\";\n return ` ${pri} ${title.padEnd(maxTitle)} ${theme.text.secondary(due)}`;\n}\n\nfunction formatDueDate(dateStr: string): string {\n const d = new Date(dateStr);\n const now = new Date();\n const days = Math.ceil((d.getTime() - now.getTime()) / 86_400_000);\n\n if (days < 0) return theme.text.error(`${Math.abs(days)}d overdue`);\n if (days === 0) return theme.text.warning(\"today\");\n if (days === 1) return \"tomorrow\";\n if (days <= 7) return `in ${days}d`;\n return d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" });\n}\n\nfunction printSection(title: string, content: string): void {\n const line = theme.border.primary(\"\\u2500\".repeat(Math.max(0, title.length + 4)));\n console.log(`\\n${theme.text.primary(title)}`);\n console.log(line);\n console.log(content);\n}\n\nfunction renderRepoSection(data: RepoData, selfLogin: string, backlogOnly: boolean): string {\n if (data.error) {\n return ` ${theme.text.error(`Error: ${data.error}`)}`;\n }\n\n if (data.issues.length === 0) {\n return ` ${theme.text.muted(\"No open issues\")}`;\n }\n\n const assigned = backlogOnly ? [] : data.issues.filter((i) => (i.assignees ?? []).length > 0);\n const backlog = data.issues.filter((i) => (i.assignees ?? []).length === 0);\n\n const lines: string[] = [];\n const maxTitle = 45;\n\n if (assigned.length > 0) {\n lines.push(` ${theme.text.secondary(\"In Progress\")}`);\n for (const issue of assigned) {\n lines.push(formatIssueLine(issue, selfLogin, maxTitle));\n }\n }\n\n if (backlog.length > 0) {\n if (assigned.length > 0) lines.push(\"\");\n lines.push(` ${theme.text.secondary(\"Backlog (unassigned)\")}`);\n for (const issue of backlog) {\n lines.push(formatIssueLine(issue, selfLogin, maxTitle));\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction renderTickTickSection(tasks: Task[], error: string | null): string {\n if (error) {\n return ` ${theme.text.error(`Error: ${error}`)}`;\n }\n\n if (tasks.length === 0) {\n return ` ${theme.text.muted(\"No active tasks\")}`;\n }\n\n const maxTitle = 45;\n const sorted = [...tasks].sort((a, b) => {\n // Overdue first, then by due date, then by priority\n if (a.dueDate && !b.dueDate) return -1;\n if (!a.dueDate && b.dueDate) return 1;\n if (a.dueDate && b.dueDate) return a.dueDate.localeCompare(b.dueDate);\n return b.priority - a.priority;\n });\n\n return sorted.map((t) => formatTaskLine(t, maxTitle)).join(\"\\n\");\n}\n\nexport function renderStaticBoard(\n data: DashboardData,\n selfLogin: string,\n backlogOnly: boolean,\n): void {\n const now = data.fetchedAt.toLocaleTimeString(\"en-US\", {\n hour: \"2-digit\",\n minute: \"2-digit\",\n });\n const date = data.fetchedAt.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n\n console.log(`\\n${theme.text.accent(\"HOG BOARD\")} ${theme.text.muted(`\\u2014 ${date} ${now}`)}`);\n\n // GitHub repos\n for (const rd of data.repos) {\n const issueCount = rd.issues.length;\n const label = `${rd.repo.shortName} ${theme.text.muted(`(${issueCount} issues)`)}`;\n printSection(label, renderRepoSection(rd, selfLogin, backlogOnly));\n }\n\n // TickTick\n if (!backlogOnly) {\n const taskCount = data.ticktick.length;\n const dueToday = data.ticktick.filter((t) => {\n if (!t.dueDate) return false;\n const days = Math.ceil((new Date(t.dueDate).getTime() - Date.now()) / 86_400_000);\n return days <= 0;\n }).length;\n const label =\n dueToday > 0\n ? `Personal (TickTick) ${theme.text.warning(`${dueToday} due today`)} / ${taskCount} total`\n : `Personal (TickTick) ${theme.text.muted(`${taskCount} tasks`)}`;\n printSection(label, renderTickTickSection(data.ticktick, data.ticktickError));\n }\n\n console.log(\"\");\n}\n\nexport function renderBoardJson(data: DashboardData, selfLogin: string): Record<string, unknown> {\n return {\n ok: true,\n data: {\n repos: data.repos.map((rd) => ({\n name: rd.repo.name,\n shortName: rd.repo.shortName,\n error: rd.error,\n issues: rd.issues.map((i) => ({\n number: i.number,\n title: i.title,\n url: i.url,\n state: i.state,\n assignee: (i.assignees ?? [])[0]?.login ?? null,\n assignees: (i.assignees ?? []).map((a) => a.login),\n labels: i.labels.map((l) => l.name),\n updatedAt: i.updatedAt,\n isMine: (i.assignees ?? []).some((a) => a.login === selfLogin),\n slackThreadUrl: i.slackThreadUrl ?? null,\n projectStatus: i.projectStatus ?? null,\n targetDate: i.targetDate ?? null,\n })),\n })),\n ticktick: {\n error: data.ticktickError,\n tasks: data.ticktick.map((t) => ({\n id: t.id,\n title: t.title,\n priority: t.priority,\n dueDate: t.dueDate,\n tags: t.tags,\n })),\n },\n activity: data.activity,\n fetchedAt: data.fetchedAt.toISOString(),\n },\n };\n}\n","const major = Number(process.versions.node.split(\".\")[0]);\nif (major < 22) {\n console.error(\n `hog requires Node.js >= 22 (current: ${process.version}). Install from https://nodejs.org/`,\n );\n process.exit(1);\n}\n\nimport { execFile, execFileSync } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { Command } from \"commander\";\nimport { extractIssueFields, hasLlmApiKey } from \"./ai.js\";\nimport { TickTickClient } from \"./api.js\";\nimport type { CompletionAction, HogConfig, RepoConfig } from \"./config.js\";\nimport {\n clearLlmAuth,\n findRepo,\n getConfig,\n getLlmAuth,\n loadFullConfig,\n requireAuth,\n resolveProfile,\n saveConfig,\n saveFullConfig,\n saveLlmAuth,\n validateRepoName,\n} from \"./config.js\";\nimport { runInit, runReposAdd } from \"./init.js\";\nimport { getActionLog } from \"./log-persistence.js\";\nimport {\n jsonOut,\n printProjects,\n printSuccess,\n printSyncResult,\n printSyncStatus,\n printTask,\n printTasks,\n setFormat,\n useJson,\n} from \"./output.js\";\nimport { getSyncStatus, runSync } from \"./sync.js\";\nimport type { CreateTaskInput, UpdateTaskInput } from \"./types.js\";\nimport { Priority } from \"./types.js\";\n\nconst execFileAsync = promisify(execFile);\n\n// -- Typed option interfaces for each command --\n\ninterface GlobalOptions {\n json?: true;\n human?: true;\n}\n\ninterface InitOptions {\n force?: true;\n}\n\ninterface AddOptions {\n priority?: string;\n date?: string;\n start?: string;\n content?: string;\n tags?: string;\n allDay?: true;\n project?: string;\n}\n\ninterface ListOptions {\n project?: string;\n all?: true;\n priority?: string;\n tag?: string;\n}\n\ninterface ProjectScopedOptions {\n project?: string;\n}\n\ninterface UpdateOptions extends ProjectScopedOptions {\n title?: string;\n priority?: string;\n date?: string;\n content?: string;\n tags?: string;\n}\n\n// -- Helpers --\n\nasync function resolveRef(\n ref: string,\n config: HogConfig,\n): Promise<Awaited<ReturnType<typeof import(\"./pick.js\").parseIssueRef>>> {\n const { parseIssueRef } = await import(\"./pick.js\");\n try {\n return parseIssueRef(ref, config);\n } catch (err) {\n console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n\nfunction errorOut(message: string, data?: Record<string, unknown>): never {\n if (useJson()) {\n jsonOut({ ok: false, error: message, ...(data ? { data } : {}) });\n } else {\n console.error(`Error: ${message}`);\n }\n process.exit(1);\n}\n\nconst PRIORITY_MAP: Record<string, Priority | undefined> = {\n none: Priority.None,\n low: Priority.Low,\n medium: Priority.Medium,\n med: Priority.Medium,\n high: Priority.High,\n};\n\nfunction parsePriority(value: string): Priority {\n const p = PRIORITY_MAP[value.toLowerCase()];\n if (p === undefined) {\n errorOut(`Invalid priority: \"${value}\". Valid values: none, low, medium, high`);\n }\n return p;\n}\n\nfunction createClient(): TickTickClient {\n const auth = requireAuth();\n return new TickTickClient(auth.accessToken);\n}\n\nfunction resolveProjectId(projectId?: string): string {\n if (projectId) return projectId;\n const config = getConfig();\n if (config.defaultProjectId) return config.defaultProjectId;\n console.error(\"No project selected. Run `hog task use-project <id>` or pass --project.\");\n process.exit(1);\n}\n\n// -- Program --\n\nconst program = new Command();\n\nprogram\n .name(\"hog\")\n .description(\"Personal command deck — unified task dashboard for GitHub Projects + TickTick\")\n .version(\"1.18.0\") // x-release-please-version\n .option(\"--json\", \"Force JSON output\")\n .option(\"--human\", \"Force human-readable output\")\n .hook(\"preAction\", (thisCommand) => {\n const opts = thisCommand.opts<GlobalOptions>();\n if (opts.json) setFormat(\"json\");\n if (opts.human) setFormat(\"human\");\n });\n\n// -- Init --\n\nprogram\n .command(\"init\")\n .description(\"Interactive setup wizard\")\n .option(\"--force\", \"Overwrite existing config without prompt\")\n .action(async (opts: InitOptions) => {\n await runInit({ force: opts.force ?? false });\n });\n\n// -- Task commands --\n\nconst task = program.command(\"task\").description(\"Manage TickTick tasks\");\n\ntask\n .command(\"add <title>\")\n .description(\"Create a new task\")\n .option(\"-p, --priority <level>\", \"Priority: none, low, medium, high\")\n .option(\"-d, --date <date>\", \"Due date (ISO 8601)\")\n .option(\"--start <date>\", \"Start date (ISO 8601)\")\n .option(\"-c, --content <text>\", \"Task description/content\")\n .option(\"-t, --tags <tags>\", \"Comma-separated tags\")\n .option(\"--all-day\", \"Mark as all-day task\")\n .option(\"--project <id>\", \"Project ID (overrides default)\")\n .action(async (title: string, opts: AddOptions) => {\n const api = createClient();\n const input: CreateTaskInput = {\n title,\n projectId: resolveProjectId(opts.project),\n };\n\n if (opts.priority) input.priority = parsePriority(opts.priority);\n if (opts.date) input.dueDate = opts.date;\n if (opts.start) input.startDate = opts.start;\n if (opts.content) input.content = opts.content;\n if (opts.tags) input.tags = opts.tags.split(\",\").map((t) => t.trim());\n if (opts.allDay) input.isAllDay = true;\n\n const created = await api.createTask(input);\n printSuccess(`Created: ${created.title}`, { task: created });\n });\n\ntask\n .command(\"list\")\n .description(\"List tasks in a project\")\n .option(\"--project <id>\", \"Project ID (overrides default)\")\n .option(\"--all\", \"Include completed tasks\")\n .option(\"-p, --priority <level>\", \"Filter by minimum priority\")\n .option(\"-t, --tag <tag>\", \"Filter by tag\")\n .action(async (opts: ListOptions) => {\n const api = createClient();\n const projectId = resolveProjectId(opts.project);\n let tasks = await api.listTasks(projectId);\n\n if (!opts.all) {\n tasks = tasks.filter((t) => t.status !== 2);\n }\n if (opts.priority) {\n const minPri = parsePriority(opts.priority);\n tasks = tasks.filter((t) => t.priority >= minPri);\n }\n if (opts.tag) {\n const tag = opts.tag;\n tasks = tasks.filter((t) => t.tags.includes(tag));\n }\n\n printTasks(tasks);\n });\n\ntask\n .command(\"show <taskId>\")\n .description(\"Show task details\")\n .option(\"--project <id>\", \"Project ID (overrides default)\")\n .action(async (taskId: string, opts: ProjectScopedOptions) => {\n const api = createClient();\n const projectId = resolveProjectId(opts.project);\n const t = await api.getTask(projectId, taskId);\n printTask(t);\n });\n\ntask\n .command(\"complete <taskId>\")\n .description(\"Mark a task as completed\")\n .option(\"--project <id>\", \"Project ID (overrides default)\")\n .action(async (taskId: string, opts: ProjectScopedOptions) => {\n const api = createClient();\n const projectId = resolveProjectId(opts.project);\n await api.completeTask(projectId, taskId);\n printSuccess(`Completed task ${taskId}`, { taskId });\n });\n\ntask\n .command(\"update <taskId>\")\n .description(\"Update a task\")\n .option(\"--title <title>\", \"New title\")\n .option(\"-p, --priority <level>\", \"New priority\")\n .option(\"-d, --date <date>\", \"New due date (ISO 8601)\")\n .option(\"-c, --content <text>\", \"New content\")\n .option(\"-t, --tags <tags>\", \"New comma-separated tags\")\n .option(\"--project <id>\", \"Project ID (overrides default)\")\n .action(async (taskId: string, opts: UpdateOptions) => {\n const api = createClient();\n const projectId = resolveProjectId(opts.project);\n const input: UpdateTaskInput = { id: taskId, projectId };\n\n if (opts.title) input.title = opts.title;\n if (opts.priority) input.priority = parsePriority(opts.priority);\n if (opts.date) input.dueDate = opts.date;\n if (opts.content) input.content = opts.content;\n if (opts.tags) input.tags = opts.tags.split(\",\").map((t) => t.trim());\n\n const updated = await api.updateTask(input);\n printSuccess(`Updated: ${updated.title}`, { task: updated });\n });\n\ntask\n .command(\"delete <taskId>\")\n .description(\"Delete a task\")\n .option(\"--project <id>\", \"Project ID (overrides default)\")\n .action(async (taskId: string, opts: ProjectScopedOptions) => {\n const api = createClient();\n const projectId = resolveProjectId(opts.project);\n await api.deleteTask(projectId, taskId);\n printSuccess(`Deleted task ${taskId}`, { taskId });\n });\n\ntask\n .command(\"projects\")\n .description(\"List all projects\")\n .action(async () => {\n const api = createClient();\n const projects = await api.listProjects();\n printProjects(projects);\n });\n\ntask\n .command(\"use-project <projectId>\")\n .description(\"Set the default project for task commands\")\n .action(async (projectId: string) => {\n const api = createClient();\n try {\n const project = await api.getProject(projectId);\n saveConfig({ defaultProjectId: project.id, defaultProjectName: project.name });\n printSuccess(`Default project: ${project.name} (${project.id})`, {\n projectId: project.id,\n projectName: project.name,\n });\n } catch {\n saveConfig({ defaultProjectId: projectId });\n printSuccess(`Default project: ${projectId}`, { projectId });\n }\n });\n\n// -- Sync commands --\n\ninterface SyncRunOptions {\n dryRun?: true;\n}\n\nconst sync = program.command(\"sync\").description(\"Sync GitHub issues with TickTick\");\n\nsync\n .command(\"run\", { isDefault: true })\n .description(\"Run GitHub-TickTick sync\")\n .option(\"--dry-run\", \"Preview changes without applying them\")\n .action(async (opts: SyncRunOptions) => {\n const dryRun = opts.dryRun ?? false;\n const result = await runSync({ dryRun });\n printSyncResult(result, dryRun);\n });\n\nsync\n .command(\"status\")\n .description(\"Show sync status and mappings\")\n .action(() => {\n const { state, repos } = getSyncStatus();\n printSyncStatus(state, repos);\n });\n\n// -- Board command --\n\ninterface BoardOptions {\n repo?: string;\n mine?: true;\n backlog?: true;\n live?: true;\n profile?: string;\n}\n\nprogram\n .command(\"board\")\n .description(\"Show unified task dashboard\")\n .option(\"--repo <name>\", \"Filter by repo (short name or full)\")\n .option(\"--mine\", \"Show only my assigned issues and tasks\")\n .option(\"--backlog\", \"Show only unassigned issues\")\n .option(\"--live\", \"Persistent TUI with auto-refresh and keyboard navigation\")\n .option(\"--profile <name>\", \"Use a named board profile\")\n .action(async (opts: BoardOptions) => {\n const rawCfg = loadFullConfig();\n const { resolved: cfg, activeProfile } = resolveProfile(rawCfg, opts.profile);\n const jsonMode = useJson();\n const fetchOptions = {\n repoFilter: opts.repo,\n mineOnly: opts.mine ?? false,\n backlogOnly: opts.backlog ?? false,\n };\n\n if (opts.live) {\n const { runLiveDashboard } = await import(\"./board/live.js\");\n await runLiveDashboard(cfg, fetchOptions, activeProfile);\n return;\n }\n\n const { fetchDashboard } = await import(\"./board/fetch.js\");\n const data = await fetchDashboard(cfg, fetchOptions);\n\n if (jsonMode) {\n const { renderBoardJson } = await import(\"./board/format-static.js\");\n jsonOut(renderBoardJson(data, cfg.board.assignee));\n } else {\n const { renderStaticBoard } = await import(\"./board/format-static.js\");\n renderStaticBoard(data, cfg.board.assignee, opts.backlog ?? false);\n }\n });\n\n// -- Pick command --\n\nprogram\n .command(\"pick <issueRef>\")\n .description(\"Pick up an issue: assign to self + sync to TickTick (e.g., hog pick aibility/145)\")\n .action(async (issueRef: string) => {\n const cfg = loadFullConfig();\n const { parseIssueRef, pickIssue } = await import(\"./pick.js\");\n const ref = parseIssueRef(issueRef, cfg);\n const result = await pickIssue(cfg, ref);\n\n if (useJson()) {\n jsonOut({\n ok: result.success,\n data: {\n issue: result.issue,\n ticktickTask: result.ticktickTask ?? null,\n warning: result.warning ?? null,\n },\n });\n } else {\n console.log(`Picked ${ref.repo.shortName}#${ref.issueNumber}: ${result.issue.title}`);\n console.log(` GitHub: assigned to @me`);\n if (result.ticktickTask) {\n console.log(` TickTick: task created`);\n }\n if (result.warning) {\n console.log(` Warning: ${result.warning}`);\n }\n }\n });\n\n// -- Launch command --\n\ninterface LaunchOptions {\n dryRun?: true;\n}\n\nprogram\n .command(\"launch <issueRef>\")\n .description(\"Launch Claude Code for an issue in its local repo directory\")\n .option(\"--dry-run\", \"Print resolved config without spawning\")\n .action(async (issueRef: string, opts: LaunchOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n const rc = ref.repo;\n\n if (!rc.localPath) {\n errorOut(\n `Set localPath for ${rc.shortName} in ~/.config/hog/config.json to enable Claude Code launch`,\n { repo: rc.shortName },\n );\n }\n\n const startCommand = rc.claudeStartCommand ?? cfg.board.claudeStartCommand;\n const launchMode = cfg.board.claudeLaunchMode ?? \"auto\";\n const terminalApp = cfg.board.claudeTerminalApp;\n\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: {\n localPath: rc.localPath,\n command: startCommand?.command ?? \"claude\",\n extraArgs: startCommand?.extraArgs ?? [],\n launchMode,\n terminalApp: terminalApp ?? null,\n issueNumber: ref.issueNumber,\n repo: rc.shortName,\n },\n });\n } else {\n console.log(`[dry-run] Would launch Claude Code for ${rc.shortName}#${ref.issueNumber}`);\n console.log(` localPath: ${rc.localPath}`);\n console.log(` command: ${startCommand?.command ?? \"claude\"}`);\n console.log(` launchMode: ${launchMode}`);\n if (terminalApp) console.log(` terminalApp: ${terminalApp}`);\n }\n return;\n }\n\n const { launchClaude } = await import(\"./board/launch-claude.js\");\n const { fetchIssueAsync } = await import(\"./github.js\");\n\n const issue = await fetchIssueAsync(rc.name, ref.issueNumber);\n\n const result = launchClaude({\n localPath: rc.localPath,\n issue: { number: issue.number, title: issue.title, url: issue.url },\n ...(startCommand ? { startCommand } : {}),\n launchMode,\n ...(terminalApp ? { terminalApp } : {}),\n repoFullName: rc.name,\n });\n\n if (!result.ok) {\n errorOut(result.error.message, { kind: result.error.kind });\n }\n\n if (useJson()) {\n jsonOut({ ok: true, data: { repo: rc.shortName, issue: ref.issueNumber } });\n } else {\n console.log(`Claude Code session opened in ${rc.shortName}#${ref.issueNumber}`);\n }\n });\n\n// -- Config commands --\n\ninterface ConfigAddRepoOptions {\n projectNumber?: string;\n statusFieldId?: string;\n completionType?: string;\n completionOptionId?: string;\n completionLabel?: string;\n}\n\nconst config = program.command(\"config\").description(\"Manage hog configuration\");\n\nconfig\n .command(\"show\")\n .description(\"Show full configuration\")\n .action(() => {\n const cfg = loadFullConfig();\n if (useJson()) {\n jsonOut({ ok: true, data: cfg });\n } else {\n console.log(\"Version:\", cfg.version);\n console.log(\"Default project:\", cfg.defaultProjectId ?? \"(none)\");\n console.log(\"Assignee:\", cfg.board.assignee);\n console.log(\"Refresh interval:\", `${cfg.board.refreshInterval}s`);\n console.log(\"Backlog limit:\", cfg.board.backlogLimit);\n console.log(\"TickTick:\", cfg.ticktick.enabled ? \"enabled\" : \"disabled\");\n console.log(\"\\nRepos:\");\n for (const repo of cfg.repos) {\n console.log(` ${repo.shortName} → ${repo.name} (project #${repo.projectNumber})`);\n console.log(` completion: ${repo.completionAction.type}`);\n }\n }\n });\n\nconfig\n .command(\"repos\")\n .description(\"List configured repositories\")\n .action(() => {\n const cfg = loadFullConfig();\n if (useJson()) {\n jsonOut({ ok: true, data: cfg.repos });\n } else {\n if (cfg.repos.length === 0) {\n console.log(\"No repos configured. Run: hog config repos add <owner/repo>\");\n return;\n }\n for (const repo of cfg.repos) {\n console.log(` ${repo.shortName.padEnd(15)} ${repo.name}`);\n }\n }\n });\n\nconfig\n .command(\"repos:add [name]\")\n .description(\"Add a repository to track (interactive wizard, or pass flags for scripted use)\")\n .option(\"--project-number <n>\", \"GitHub project number (skips interactive prompt)\")\n .option(\"--status-field-id <id>\", \"Project status field ID (skips interactive prompt)\")\n .option(\n \"--completion-type <type>\",\n \"Completion action: addLabel, updateProjectStatus, closeIssue\",\n )\n .option(\"--completion-option-id <id>\", \"Option ID for updateProjectStatus\")\n .option(\"--completion-label <label>\", \"Label for addLabel\")\n .action(async (name: string | undefined, opts: ConfigAddRepoOptions) => {\n // Interactive mode: no project-number or status-field-id provided\n if (!(opts.projectNumber && opts.statusFieldId)) {\n await runReposAdd(name);\n return;\n }\n\n // Non-interactive (scripted) mode: all required flags provided\n if (!name) {\n console.error(\"Name argument required in non-interactive mode.\");\n process.exit(1);\n }\n if (!validateRepoName(name)) {\n console.error(\"Invalid repo name. Use owner/repo format (e.g., myorg/myrepo)\");\n process.exit(1);\n }\n\n const cfg = loadFullConfig();\n if (findRepo(cfg, name)) {\n console.error(`Repo \"${name}\" is already configured.`);\n process.exit(1);\n }\n\n const shortName = name.split(\"/\")[1] ?? name;\n\n if (!opts.completionType) {\n console.error(\"--completion-type required in non-interactive mode\");\n process.exit(1);\n }\n\n let completionAction: CompletionAction;\n switch (opts.completionType) {\n case \"addLabel\":\n if (!opts.completionLabel) {\n console.error(\"--completion-label required for addLabel type\");\n process.exit(1);\n }\n completionAction = { type: \"addLabel\", label: opts.completionLabel };\n break;\n case \"updateProjectStatus\":\n if (!opts.completionOptionId) {\n console.error(\"--completion-option-id required for updateProjectStatus type\");\n process.exit(1);\n }\n completionAction = { type: \"updateProjectStatus\", optionId: opts.completionOptionId };\n break;\n case \"closeIssue\":\n completionAction = { type: \"closeIssue\" };\n break;\n default:\n console.error(\n `Unknown completion type: ${opts.completionType}. Use: addLabel, updateProjectStatus, closeIssue`,\n );\n process.exit(1);\n }\n\n const newRepo: RepoConfig = {\n name,\n shortName,\n projectNumber: Number.parseInt(opts.projectNumber, 10),\n statusFieldId: opts.statusFieldId,\n completionAction,\n };\n\n cfg.repos.push(newRepo);\n saveFullConfig(cfg);\n\n if (useJson()) {\n jsonOut({ ok: true, message: `Added ${name}`, data: newRepo });\n } else {\n console.log(`Added ${shortName} → ${name}`);\n }\n });\n\nconfig\n .command(\"repos:rm <name>\")\n .description(\"Remove a repository from tracking\")\n .action((name: string) => {\n const cfg = loadFullConfig();\n const idx = cfg.repos.findIndex((r) => r.shortName === name || r.name === name);\n if (idx === -1) {\n console.error(`Repo \"${name}\" not found. Run: hog config repos`);\n process.exit(1);\n }\n const [removed] = cfg.repos.splice(idx, 1);\n if (!removed) {\n process.exit(1);\n }\n saveFullConfig(cfg);\n\n if (useJson()) {\n jsonOut({ ok: true, message: `Removed ${removed.name}`, data: removed });\n } else {\n console.log(`Removed ${removed.shortName} → ${removed.name}`);\n console.log(\"Note: Existing sync mappings for this repo remain in sync-state.json.\");\n }\n });\n\nconfig\n .command(\"ticktick:enable\")\n .description(\"Enable TickTick integration in the board\")\n .action(() => {\n const cfg = loadFullConfig();\n cfg.ticktick = { enabled: true };\n saveFullConfig(cfg);\n if (useJson()) {\n jsonOut({ ok: true, message: \"TickTick enabled\" });\n } else {\n printSuccess(\"TickTick integration enabled.\");\n }\n });\n\nconfig\n .command(\"ticktick:disable\")\n .description(\"Disable TickTick integration in the board\")\n .action(() => {\n const cfg = loadFullConfig();\n cfg.ticktick = { enabled: false };\n saveFullConfig(cfg);\n if (useJson()) {\n jsonOut({ ok: true, message: \"TickTick disabled\" });\n } else {\n printSuccess(\"TickTick integration disabled. Board will no longer show TickTick tasks.\");\n }\n });\n\nconfig\n .command(\"ai:set-key <key>\")\n .description(\"Store an OpenRouter API key for AI-enhanced issue creation (I key on board)\")\n .action((key: string) => {\n if (!key.startsWith(\"sk-or-\")) {\n console.error('Error: key must start with \"sk-or-\". Get one at https://openrouter.ai/keys');\n process.exit(1);\n }\n saveLlmAuth(key);\n if (useJson()) {\n jsonOut({ ok: true, message: \"OpenRouter key saved\" });\n } else {\n printSuccess(\"OpenRouter key saved to ~/.config/hog/auth.json\");\n console.log(\" Press I on the board to create issues with natural language.\");\n }\n });\n\nconfig\n .command(\"ai:clear-key\")\n .description(\"Remove the stored OpenRouter API key\")\n .action(() => {\n const existing = getLlmAuth();\n if (!existing) {\n if (useJson()) {\n jsonOut({ ok: true, message: \"No key was stored\" });\n } else {\n console.log(\"No OpenRouter key stored.\");\n }\n return;\n }\n clearLlmAuth();\n if (useJson()) {\n jsonOut({ ok: true, message: \"OpenRouter key removed\" });\n } else {\n printSuccess(\"OpenRouter key removed from ~/.config/hog/auth.json\");\n }\n });\n\nconfig\n .command(\"ai:status\")\n .description(\"Show whether AI-enhanced issue creation is available and which source provides it\")\n .action(() => {\n const envOr = process.env[\"OPENROUTER_API_KEY\"];\n const envAnt = process.env[\"ANTHROPIC_API_KEY\"];\n const stored = getLlmAuth();\n\n if (useJson()) {\n jsonOut({\n ok: true,\n data: {\n active: !!(envOr ?? envAnt ?? stored),\n source: envOr\n ? \"env:OPENROUTER_API_KEY\"\n : envAnt\n ? \"env:ANTHROPIC_API_KEY\"\n : stored\n ? \"config:auth.json\"\n : null,\n provider: envOr ? \"openrouter\" : envAnt ? \"anthropic\" : stored ? \"openrouter\" : null,\n },\n });\n } else if (envOr) {\n console.log(\"AI: active (source: OPENROUTER_API_KEY env var, provider: openrouter)\");\n } else if (envAnt) {\n console.log(\"AI: active (source: ANTHROPIC_API_KEY env var, provider: anthropic)\");\n } else if (stored) {\n console.log(\"AI: active (source: ~/.config/hog/auth.json, provider: openrouter)\");\n } else {\n console.log(\"AI: off — heuristic-only mode\");\n console.log(\" Enable with: hog config ai:set-key <sk-or-...>\");\n console.log(\" Or set env: export OPENROUTER_API_KEY=sk-or-...\");\n }\n });\n\nconfig\n .command(\"profile:create <name>\")\n .description(\"Create a board profile (copies current top-level config)\")\n .action((name: string) => {\n const cfg = loadFullConfig();\n if (cfg.profiles[name]) {\n console.error(`Profile \"${name}\" already exists.`);\n process.exit(1);\n }\n\n cfg.profiles[name] = {\n repos: [...cfg.repos],\n board: { ...cfg.board },\n ticktick: { ...cfg.ticktick },\n };\n saveFullConfig(cfg);\n\n if (useJson()) {\n jsonOut({ ok: true, message: `Created profile \"${name}\"`, data: cfg.profiles[name] });\n } else {\n printSuccess(`Created profile \"${name}\" (copied from current config).`);\n }\n });\n\nconfig\n .command(\"profile:delete <name>\")\n .description(\"Delete a board profile\")\n .action((name: string) => {\n const cfg = loadFullConfig();\n if (!cfg.profiles[name]) {\n console.error(\n `Profile \"${name}\" not found. Available: ${Object.keys(cfg.profiles).join(\", \") || \"(none)\"}`,\n );\n process.exit(1);\n }\n\n delete cfg.profiles[name];\n\n // Clear defaultProfile if it was the deleted one\n if (cfg.defaultProfile === name) {\n cfg.defaultProfile = undefined;\n }\n\n saveFullConfig(cfg);\n\n if (useJson()) {\n jsonOut({ ok: true, message: `Deleted profile \"${name}\"` });\n } else {\n printSuccess(`Deleted profile \"${name}\".`);\n }\n });\n\nconfig\n .command(\"profile:default [name]\")\n .description(\"Set or show the default board profile\")\n .action((name?: string) => {\n const cfg = loadFullConfig();\n\n if (!name) {\n // Show current default\n if (useJson()) {\n jsonOut({\n ok: true,\n data: { defaultProfile: cfg.defaultProfile ?? null, profiles: Object.keys(cfg.profiles) },\n });\n } else {\n console.log(\"Default profile:\", cfg.defaultProfile ?? \"(none)\");\n const names = Object.keys(cfg.profiles);\n if (names.length > 0) {\n console.log(\"Available profiles:\", names.join(\", \"));\n } else {\n console.log(\"No profiles configured. Run: hog config profile:create <name>\");\n }\n }\n return;\n }\n\n if (!cfg.profiles[name]) {\n console.error(\n `Profile \"${name}\" not found. Available: ${Object.keys(cfg.profiles).join(\", \") || \"(none)\"}`,\n );\n process.exit(1);\n }\n\n cfg.defaultProfile = name;\n saveFullConfig(cfg);\n\n if (useJson()) {\n jsonOut({ ok: true, message: `Default profile set to \"${name}\"` });\n } else {\n printSuccess(`Default profile set to \"${name}\".`);\n }\n });\n\n// -- Issue commands --\n\ninterface IssueCreateOptions {\n repo?: string;\n dryRun?: true;\n}\n\ninterface IssueMoveOptions {\n dryRun?: true;\n}\n\ninterface IssueAssignOptions {\n user?: string;\n dryRun?: true;\n}\n\ninterface IssueUnassignOptions {\n user?: string;\n dryRun?: true;\n}\n\ninterface IssueCommentOptions {\n dryRun?: true;\n}\n\ninterface IssueEditOptions {\n title?: string;\n body?: string;\n label?: string[];\n removeLabel?: string[];\n assignee?: string;\n removeAssignee?: string;\n dryRun?: true;\n}\n\ninterface IssueLabelOptions {\n remove?: boolean;\n dryRun?: true;\n}\n\nconst issueCommand = new Command(\"issue\").description(\"GitHub issue utilities\");\n\nissueCommand\n .command(\"create <text>\")\n .description(\"Create a GitHub issue from natural language text\")\n .option(\"--repo <repo>\", \"Target repository (owner/name)\")\n .option(\"--dry-run\", \"Print parsed fields without creating the issue\")\n .action(async (text: string, opts: IssueCreateOptions) => {\n const config = loadFullConfig();\n const repo = opts.repo ?? config.repos[0]?.name;\n if (!repo) {\n console.error(\n \"Error: no repo specified. Use --repo owner/name or configure repos in hog init.\",\n );\n process.exit(1);\n }\n\n if (hasLlmApiKey()) {\n console.error(\"[info] LLM parsing enabled\");\n }\n\n const parsed = await extractIssueFields(text, {\n onLlmFallback: (msg) => console.error(`[warn] ${msg}`),\n });\n\n if (!parsed) {\n console.error(\n \"Error: could not parse a title from input. Ensure your text has a non-empty title.\",\n );\n process.exit(1);\n }\n\n const labels = [...parsed.labels];\n if (parsed.dueDate) labels.push(`due:${parsed.dueDate}`);\n\n // Show parsed fields\n console.error(`Title: ${parsed.title}`);\n if (labels.length > 0) console.error(`Labels: ${labels.join(\", \")}`);\n if (parsed.assignee) console.error(`Assignee: @${parsed.assignee}`);\n if (parsed.dueDate) console.error(`Due: ${parsed.dueDate}`);\n console.error(`Repo: ${repo}`);\n\n if (opts.dryRun) {\n console.error(\"[dry-run] Skipping issue creation.\");\n return;\n }\n\n const args = [\"issue\", \"create\", \"--repo\", repo, \"--title\", parsed.title, \"--body\", \"\"];\n for (const label of labels) {\n args.push(\"--label\", label);\n }\n\n const repoArg = repo;\n try {\n if (useJson()) {\n const output = await execFileAsync(\"gh\", args, { encoding: \"utf-8\", timeout: 60_000 });\n const url = output.stdout.trim();\n const issueNumber = Number.parseInt(url.split(\"/\").pop() ?? \"0\", 10);\n jsonOut({ ok: true, data: { url, issueNumber, repo: repoArg } });\n } else {\n execFileSync(\"gh\", args, { stdio: \"inherit\" });\n }\n } catch (err) {\n console.error(\n `Error: gh issue create failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n process.exit(1);\n }\n });\n\nissueCommand\n .command(\"show <issueRef>\")\n .description(\"Show issue details (format: shortname/number, e.g. myrepo/42)\")\n .action(async (issueRef: string) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n const { fetchIssueAsync } = await import(\"./github.js\");\n const issue = await fetchIssueAsync(ref.repo.name, ref.issueNumber);\n if (useJson()) {\n jsonOut({ ok: true, data: issue });\n } else {\n console.log(`#${issue.number} ${issue.title}`);\n if (issue.projectStatus) console.log(` Status: ${issue.projectStatus}`);\n const labels = issue.labels.map((l) => l.name).join(\", \");\n if (labels) console.log(` Labels: ${labels}`);\n const assignees = (issue.assignees ?? []).map((a) => `@${a.login}`).join(\", \");\n if (assignees) console.log(` Assignee: ${assignees}`);\n console.log(` URL: ${issue.url}`);\n if (issue.body) {\n console.log();\n console.log(issue.body);\n }\n }\n });\n\nissueCommand\n .command(\"move <issueRef> <status>\")\n .description(\"Change project status (e.g. hog issue move myrepo/42 'In Review')\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (issueRef: string, status: string, opts: IssueMoveOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n const rc = ref.repo;\n if (!(rc.statusFieldId && rc.projectNumber)) {\n errorOut(`${rc.name} is not configured with a project board. Run: hog init`, {\n repo: rc.name,\n });\n }\n const { fetchProjectStatusOptions, updateProjectItemStatusAsync } = await import(\"./github.js\");\n const options = fetchProjectStatusOptions(rc.name, rc.projectNumber, rc.statusFieldId);\n const target = options.find((o) => o.name.toLowerCase() === status.toLowerCase());\n if (!target) {\n const valid = options.map((o) => o.name).join(\", \");\n errorOut(`Invalid status \"${status}\". Valid: ${valid}`, { status, validStatuses: valid });\n }\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: {\n action: \"move\",\n issue: ref.issueNumber,\n repo: rc.shortName,\n status: target.name,\n },\n });\n } else {\n console.log(`[dry-run] Would move ${rc.shortName}#${ref.issueNumber} → \"${target.name}\"`);\n }\n return;\n }\n await updateProjectItemStatusAsync(rc.name, ref.issueNumber, {\n projectNumber: rc.projectNumber,\n statusFieldId: rc.statusFieldId,\n optionId: target.id,\n });\n if (useJson()) {\n jsonOut({ ok: true, data: { issue: ref.issueNumber, status: target.name } });\n } else {\n console.log(`Moved ${rc.shortName}#${ref.issueNumber} → ${target.name}`);\n }\n });\n\nissueCommand\n .command(\"assign <issueRef>\")\n .description(\"Assign issue to self or a specific user\")\n .option(\"--user <username>\", \"GitHub username to assign (default: configured assignee)\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (issueRef: string, opts: IssueAssignOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n const user = opts.user ?? cfg.board.assignee;\n if (!user) {\n console.error(\"Error: no user specified. Use --user or configure board.assignee in hog init\");\n process.exit(1);\n }\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: { action: \"assign\", issue: ref.issueNumber, repo: ref.repo.shortName, user },\n });\n } else {\n console.log(`[dry-run] Would assign ${ref.repo.shortName}#${ref.issueNumber} to @${user}`);\n }\n return;\n }\n const { assignIssueToAsync } = await import(\"./github.js\");\n await assignIssueToAsync(ref.repo.name, ref.issueNumber, user);\n if (useJson()) {\n jsonOut({ ok: true, data: { issue: ref.issueNumber, assignee: user } });\n } else {\n console.log(`Assigned ${ref.repo.shortName}#${ref.issueNumber} to @${user}`);\n }\n });\n\nissueCommand\n .command(\"unassign <issueRef>\")\n .description(\"Remove assignee from issue\")\n .option(\"--user <username>\", \"GitHub username to remove (default: configured assignee)\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (issueRef: string, opts: IssueUnassignOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n const user = opts.user ?? cfg.board.assignee;\n if (!user) {\n console.error(\"Error: no user specified. Use --user or configure board.assignee in hog init\");\n process.exit(1);\n }\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: { action: \"unassign\", issue: ref.issueNumber, repo: ref.repo.shortName, user },\n });\n } else {\n console.log(\n `[dry-run] Would remove @${user} from ${ref.repo.shortName}#${ref.issueNumber}`,\n );\n }\n return;\n }\n const { unassignIssueAsync } = await import(\"./github.js\");\n await unassignIssueAsync(ref.repo.name, ref.issueNumber, user);\n if (useJson()) {\n jsonOut({ ok: true, data: { issue: ref.issueNumber, removedAssignee: user } });\n } else {\n console.log(`Removed @${user} from ${ref.repo.shortName}#${ref.issueNumber}`);\n }\n });\n\nissueCommand\n .command(\"comment <issueRef> <text>\")\n .description(\"Post a comment on an issue\")\n .option(\"--dry-run\", \"Print what would be posted without mutating\")\n .action(async (issueRef: string, text: string, opts: IssueCommentOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: { action: \"comment\", issue: ref.issueNumber, repo: ref.repo.shortName, text },\n });\n } else {\n console.log(\n `[dry-run] Would comment on ${ref.repo.shortName}#${ref.issueNumber}: \"${text}\"`,\n );\n }\n return;\n }\n const { addCommentAsync } = await import(\"./github.js\");\n await addCommentAsync(ref.repo.name, ref.issueNumber, text);\n if (useJson()) {\n jsonOut({ ok: true, data: { issue: ref.issueNumber, comment: text } });\n } else {\n console.log(`Commented on ${ref.repo.shortName}#${ref.issueNumber}`);\n }\n });\n\nissueCommand\n .command(\"edit <issueRef>\")\n .description(\"Edit issue fields (title, body, labels, assignees)\")\n .option(\"--title <title>\", \"New title\")\n .option(\"--body <body>\", \"New body\")\n .option(\n \"--label <label>\",\n \"Add label (repeatable)\",\n (v, acc: string[]) => [...acc, v],\n [] as string[],\n )\n .option(\n \"--remove-label <label>\",\n \"Remove label (repeatable)\",\n (v, acc: string[]) => [...acc, v],\n [] as string[],\n )\n .option(\"--assignee <user>\", \"Add assignee\")\n .option(\"--remove-assignee <user>\", \"Remove assignee\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (issueRef: string, opts: IssueEditOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n\n const changes: string[] = [];\n if (opts.title) changes.push(`title → \"${opts.title}\"`);\n if (opts.body !== undefined) changes.push(\"body updated\");\n if (opts.label?.length) changes.push(`add labels: ${opts.label.join(\", \")}`);\n if (opts.removeLabel?.length) changes.push(`remove labels: ${opts.removeLabel.join(\", \")}`);\n if (opts.assignee) changes.push(`add assignee: @${opts.assignee}`);\n if (opts.removeAssignee) changes.push(`remove assignee: @${opts.removeAssignee}`);\n\n if (changes.length === 0) {\n console.error(\"Error: no changes specified. Use --title, --body, --label, etc.\");\n process.exit(1);\n }\n\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: { action: \"edit\", issue: ref.issueNumber, repo: ref.repo.shortName, changes },\n });\n } else {\n console.log(\n `[dry-run] Would edit ${ref.repo.shortName}#${ref.issueNumber}: ${changes.join(\"; \")}`,\n );\n }\n return;\n }\n\n const ghArgs = [\"issue\", \"edit\", String(ref.issueNumber), \"--repo\", ref.repo.name];\n if (opts.title) ghArgs.push(\"--title\", opts.title);\n if (opts.body !== undefined) ghArgs.push(\"--body\", opts.body);\n for (const l of opts.label ?? []) ghArgs.push(\"--add-label\", l);\n for (const l of opts.removeLabel ?? []) ghArgs.push(\"--remove-label\", l);\n if (opts.assignee) ghArgs.push(\"--add-assignee\", opts.assignee);\n if (opts.removeAssignee) ghArgs.push(\"--remove-assignee\", opts.removeAssignee);\n\n if (useJson()) {\n await execFileAsync(\"gh\", ghArgs, { encoding: \"utf-8\", timeout: 30_000 });\n jsonOut({ ok: true, data: { issue: ref.issueNumber, changes } });\n } else {\n execFileSync(\"gh\", ghArgs, { stdio: \"inherit\" });\n console.log(`Updated ${ref.repo.shortName}#${ref.issueNumber}: ${changes.join(\"; \")}`);\n }\n });\n\nissueCommand\n .command(\"label <issueRef> <label>\")\n .description(\"Add or remove a label on an issue\")\n .option(\"--remove\", \"Remove the label instead of adding it\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (issueRef: string, label: string, opts: IssueLabelOptions) => {\n const cfg = loadFullConfig();\n const ref = await resolveRef(issueRef, cfg);\n const verb = opts.remove ? \"remove\" : \"add\";\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({\n ok: true,\n dryRun: true,\n would: {\n action: `${verb}Label`,\n issue: ref.issueNumber,\n repo: ref.repo.shortName,\n label,\n },\n });\n } else {\n console.log(\n `[dry-run] Would ${verb} label \"${label}\" on ${ref.repo.shortName}#${ref.issueNumber}`,\n );\n }\n return;\n }\n if (opts.remove) {\n const { removeLabelAsync } = await import(\"./github.js\");\n await removeLabelAsync(ref.repo.name, ref.issueNumber, label);\n } else {\n const { addLabelAsync } = await import(\"./github.js\");\n await addLabelAsync(ref.repo.name, ref.issueNumber, label);\n }\n if (useJson()) {\n jsonOut({ ok: true, data: { issue: ref.issueNumber, label, action: verb } });\n } else {\n console.log(\n `${opts.remove ? \"Removed\" : \"Added\"} label \"${label}\" on ${ref.repo.shortName}#${ref.issueNumber}`,\n );\n }\n });\n\nissueCommand\n .command(\"statuses\")\n .description(\"List available project statuses for a repo\")\n .argument(\"<repo>\", \"repo short name (e.g. myrepo)\")\n .action(async (repo: string) => {\n const config = loadFullConfig();\n const repoConfig = config.repos.find((r) => r.shortName === repo || r.name === repo);\n if (!repoConfig) {\n errorOut(`Repo \"${repo}\" is not configured`, { repo });\n }\n const { fetchProjectStatusOptions } = await import(\"./github.js\");\n const statuses = fetchProjectStatusOptions(\n repoConfig.name,\n repoConfig.projectNumber,\n repoConfig.statusFieldId,\n );\n if (useJson()) {\n jsonOut({ ok: true, data: { repo, statuses: statuses.map((s) => s.name) } });\n } else {\n console.log(`Available statuses for ${repo}: ${statuses.map((s) => s.name).join(\", \")}`);\n }\n });\n\n// -- Bulk issue commands --\n\ntype BulkResult = { ref: string; success: true } | { ref: string; success: false; error: string };\n\nasync function moveSingleIssue(r: string, status: string, cfg: HogConfig): Promise<BulkResult> {\n try {\n const ref = await resolveRef(r, cfg);\n const rc = ref.repo;\n if (!(rc.statusFieldId && rc.projectNumber)) {\n throw new Error(`${rc.name} is not configured with a project board. Run: hog init`);\n }\n const { fetchProjectStatusOptions, updateProjectItemStatusAsync } = await import(\"./github.js\");\n const options = fetchProjectStatusOptions(rc.name, rc.projectNumber, rc.statusFieldId);\n const target = options.find((o) => o.name.toLowerCase() === status.toLowerCase());\n if (!target) {\n const valid = options.map((o) => o.name).join(\", \");\n throw new Error(`Invalid status \"${status}\". Valid: ${valid}`);\n }\n await updateProjectItemStatusAsync(rc.name, ref.issueNumber, {\n projectNumber: rc.projectNumber,\n statusFieldId: rc.statusFieldId,\n optionId: target.id,\n });\n return { ref: r, success: true };\n } catch (err) {\n return { ref: r, success: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n\nfunction outputBulkResults(results: BulkResult[]): void {\n const allOk = results.every((r) => r.success);\n if (useJson()) {\n jsonOut({ ok: allOk, results });\n } else {\n for (const r of results) {\n if (!r.success) {\n console.error(\n `Failed ${r.ref}: ${(r as { ref: string; success: false; error: string }).error}`,\n );\n }\n }\n }\n}\n\ninterface IssueBulkAssignOptions {\n user?: string;\n dryRun?: true;\n}\n\ninterface IssueBulkUnassignOptions {\n user?: string;\n dryRun?: true;\n}\n\ninterface IssueBulkMoveOptions {\n dryRun?: true;\n}\n\nissueCommand\n .command(\"bulk-assign <refs...>\")\n .description(\n \"Assign multiple issues to self or a specific user (e.g., hog issue bulk-assign myrepo/42 myrepo/43)\",\n )\n .option(\"--user <username>\", \"GitHub username to assign (default: configured assignee)\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (refs: string[], opts: IssueBulkAssignOptions) => {\n const cfg = loadFullConfig();\n const user = opts.user ?? cfg.board.assignee;\n if (!user) {\n errorOut(\"no user specified. Use --user or configure board.assignee in hog init\");\n }\n\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({ ok: true, dryRun: true, would: { action: \"bulk-assign\", refs, user } });\n } else {\n for (const r of refs) {\n console.log(`[dry-run] Would assign ${r} to @${user}`);\n }\n }\n return;\n }\n\n const { assignIssueToAsync } = await import(\"./github.js\");\n const results: BulkResult[] = [];\n for (const r of refs) {\n try {\n const ref = await resolveRef(r, cfg);\n await assignIssueToAsync(ref.repo.name, ref.issueNumber, user);\n results.push({ ref: r, success: true });\n if (!useJson()) console.log(`Assigned ${r} to @${user}`);\n } catch (err) {\n results.push({\n ref: r,\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n outputBulkResults(results);\n });\n\nissueCommand\n .command(\"bulk-unassign <refs...>\")\n .description(\n \"Remove assignee from multiple issues (e.g., hog issue bulk-unassign myrepo/42 myrepo/43)\",\n )\n .option(\"--user <username>\", \"GitHub username to remove (default: configured assignee)\")\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (refs: string[], opts: IssueBulkUnassignOptions) => {\n const cfg = loadFullConfig();\n const user = opts.user ?? cfg.board.assignee;\n if (!user) {\n errorOut(\"no user specified. Use --user or configure board.assignee in hog init\");\n }\n\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({ ok: true, dryRun: true, would: { action: \"bulk-unassign\", refs, user } });\n } else {\n for (const r of refs) {\n console.log(`[dry-run] Would remove @${user} from ${r}`);\n }\n }\n return;\n }\n\n const { unassignIssueAsync } = await import(\"./github.js\");\n const results: BulkResult[] = [];\n for (const r of refs) {\n try {\n const ref = await resolveRef(r, cfg);\n await unassignIssueAsync(ref.repo.name, ref.issueNumber, user);\n results.push({ ref: r, success: true });\n if (!useJson()) console.log(`Removed @${user} from ${r}`);\n } catch (err) {\n results.push({\n ref: r,\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n outputBulkResults(results);\n });\n\nissueCommand\n .command(\"bulk-move <status> <refs...>\")\n .description(\n \"Move multiple issues to a project status (e.g., hog issue bulk-move 'In Review' myrepo/42 myrepo/43)\",\n )\n .option(\"--dry-run\", \"Print what would change without mutating\")\n .action(async (status: string, refs: string[], opts: IssueBulkMoveOptions) => {\n const cfg = loadFullConfig();\n\n if (opts.dryRun) {\n if (useJson()) {\n jsonOut({ ok: true, dryRun: true, would: { action: \"bulk-move\", refs, status } });\n } else {\n for (const r of refs) {\n console.log(`[dry-run] Would move ${r} → \"${status}\"`);\n }\n }\n return;\n }\n\n const results: BulkResult[] = await Promise.all(\n refs.map((r) => moveSingleIssue(r, status, cfg)),\n );\n if (!useJson()) {\n for (const r of results) {\n if (r.success) console.log(`Moved ${r.ref} → ${status}`);\n }\n }\n outputBulkResults(results);\n });\n\nprogram.addCommand(issueCommand);\n\n// -- Log commands --\n\ninterface LogShowOptions {\n limit: string;\n}\n\nconst logCommand = program.command(\"log\").description(\"Action log commands\");\n\nlogCommand\n .command(\"show\")\n .description(\"Show recent action log entries\")\n .option(\"--limit <n>\", \"number of entries to show\", \"50\")\n .action((opts: LogShowOptions) => {\n const limit = Number.parseInt(opts.limit, 10) || 50;\n const entries = getActionLog(limit);\n if (useJson()) {\n jsonOut({ ok: true, data: { entries, count: entries.length } });\n } else {\n if (entries.length === 0) {\n console.log(\"No action log entries.\");\n return;\n }\n for (const e of entries) {\n const prefix = e.status === \"success\" ? \"✓\" : e.status === \"error\" ? \"✗\" : \"…\";\n const ts = new Date(e.timestamp).toLocaleString();\n console.log(`${prefix} [${ts}] ${e.description}`);\n }\n }\n });\n\n// -- Run --\n\nprogram.parseAsync().catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`Error: ${message}`);\n process.exit(1);\n});\n","import { execFileSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { checkbox, confirm, input, select } from \"@inquirer/prompts\";\nimport type { CompletionAction, HogConfig, RepoConfig } from \"./config.js\";\nimport {\n CONFIG_DIR,\n findRepo,\n loadFullConfig,\n saveFullConfig,\n saveLlmAuth,\n validateRepoName,\n} from \"./config.js\";\n\n// ── gh CLI helpers ──\n\nfunction ghJson<T>(args: string[]): T {\n const output = execFileSync(\"gh\", args, { encoding: \"utf-8\", timeout: 30_000 }).trim();\n return JSON.parse(output) as T;\n}\n\nfunction isGhAuthenticated(): boolean {\n try {\n execFileSync(\"gh\", [\"auth\", \"status\"], { encoding: \"utf-8\", timeout: 10_000 });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction getGitHubLogin(): string {\n const user = ghJson<{ login: string }>([\"api\", \"user\"]);\n return user.login;\n}\n\ninterface GhRepo {\n nameWithOwner: string;\n name: string;\n owner: { login: string };\n}\n\nfunction listUserOrgs(): string[] {\n try {\n const orgs = ghJson<{ login: string }[]>([\"api\", \"user/orgs\"]);\n return orgs.map((o) => o.login);\n } catch {\n return [];\n }\n}\n\nfunction listReposForOwner(owner?: string): GhRepo[] {\n const args = [\n \"repo\",\n \"list\",\n ...(owner ? [owner] : []),\n \"--json\",\n \"nameWithOwner,name,owner\",\n \"--limit\",\n \"100\",\n ];\n try {\n return ghJson<GhRepo[]>(args);\n } catch {\n return [];\n }\n}\n\nfunction listAllRepos(): GhRepo[] {\n const orgs = listUserOrgs();\n const personal = listReposForOwner();\n const orgRepos = orgs.flatMap((org) => listReposForOwner(org));\n const all = [...personal, ...orgRepos];\n // Deduplicate by nameWithOwner\n const seen = new Set<string>();\n return all.filter((r) => {\n if (seen.has(r.nameWithOwner)) return false;\n seen.add(r.nameWithOwner);\n return true;\n });\n}\n\ninterface GhProject {\n number: number;\n title: string;\n}\n\nfunction listOrgProjects(owner: string): GhProject[] {\n try {\n const result = ghJson<{ projects: GhProject[] }>([\n \"project\",\n \"list\",\n \"--owner\",\n owner,\n \"--format\",\n \"json\",\n ]);\n return result.projects ?? [];\n } catch {\n return [];\n }\n}\n\ninterface GhProjectFieldOption {\n id: string;\n name: string;\n}\n\ninterface GhProjectField {\n id: string;\n name: string;\n type: string;\n options?: GhProjectFieldOption[];\n}\n\nfunction listProjectFields(owner: string, projectNumber: number): GhProjectField[] {\n try {\n const result = ghJson<{ fields: GhProjectField[] }>([\n \"project\",\n \"field-list\",\n String(projectNumber),\n \"--owner\",\n owner,\n \"--format\",\n \"json\",\n ]);\n return result.fields ?? [];\n } catch {\n return [];\n }\n}\n\ninterface StatusFieldInfo {\n fieldId: string;\n options: GhProjectFieldOption[];\n}\n\nfunction detectStatusField(owner: string, projectNumber: number): StatusFieldInfo | null {\n const fields = listProjectFields(owner, projectNumber);\n const statusField = fields.find(\n (f) => f.name === \"Status\" && f.type === \"ProjectV2SingleSelectField\",\n );\n if (!statusField) return null;\n return { fieldId: statusField.id, options: statusField.options ?? [] };\n}\n\nconst DATE_FIELD_NAME_RE = /^(target\\s*date|due\\s*date|due|deadline)$/i;\n\nfunction detectDateField(owner: string, projectNumber: number): GhProjectField | null {\n const fields = listProjectFields(owner, projectNumber);\n return fields.find((f) => DATE_FIELD_NAME_RE.test(f.name)) ?? null;\n}\n\nfunction createDateField(owner: string, projectNumber: number, fieldName: string): string | null {\n try {\n // Create the field and then list fields to get the ID\n execFileSync(\n \"gh\",\n [\n \"project\",\n \"field-create\",\n String(projectNumber),\n \"--owner\",\n owner,\n \"--name\",\n fieldName,\n \"--data-type\",\n \"DATE\",\n ],\n { encoding: \"utf-8\", timeout: 30_000 },\n );\n // Re-list to find the newly created field\n const fields = listProjectFields(owner, projectNumber);\n return fields.find((f) => f.name === fieldName)?.id ?? null;\n } catch {\n return null;\n }\n}\n\n// ── Wizard ──\n\nexport interface InitOptions {\n force?: boolean;\n}\n\nexport async function runInit(opts: InitOptions = {}): Promise<void> {\n // Ctrl+C handling: inquirer throws on cancel, we catch at the top level\n try {\n await runWizard(opts);\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"User force closed\")) {\n console.log(\"\\nSetup cancelled. No changes were made.\");\n return;\n }\n throw error;\n }\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: interactive setup wizard with many steps\nasync function runWizard(opts: InitOptions): Promise<void> {\n console.log(\"\\n🐗 hog init — Setup Wizard\\n\");\n\n // Step 1: Check existing config\n const configExists = existsSync(`${CONFIG_DIR}/config.json`);\n if (configExists && !opts.force) {\n const overwrite = await confirm({\n message: \"Config already exists. Overwrite?\",\n default: false,\n });\n if (!overwrite) {\n console.log(\"Setup cancelled.\");\n return;\n }\n }\n\n // Step 2: Check gh CLI auth\n console.log(\"Checking GitHub CLI authentication...\");\n if (!isGhAuthenticated()) {\n console.error(\n \"\\nGitHub CLI is not authenticated. Run:\\n\\n gh auth login\\n\\nThen re-run `hog init`.\",\n );\n process.exit(1);\n }\n console.log(\" GitHub CLI authenticated.\\n\");\n\n // Step 3: Detect GitHub user\n const login = getGitHubLogin();\n console.log(` Detected GitHub user: ${login}\\n`);\n\n // Step 4: Select repos (personal + org repos)\n console.log(\"Fetching repositories...\");\n const allRepos = listAllRepos();\n if (allRepos.length === 0) {\n console.error(\"No repositories found. Check your GitHub CLI access.\");\n process.exit(1);\n }\n\n const selectedRepoNames = await checkbox<string>({\n message: \"Select repositories to track:\",\n choices: allRepos.map((r) => ({\n name: r.nameWithOwner,\n value: r.nameWithOwner,\n })),\n });\n\n if (selectedRepoNames.length === 0) {\n console.log(\"No repos selected. You can add repos later with `hog config repos:add`.\");\n }\n\n // Step 5: Configure each repo (project, status field, completion action)\n const repos: RepoConfig[] = [];\n for (const repoName of selectedRepoNames) {\n console.log(`\\nConfiguring ${repoName}...`);\n const [owner, name] = repoName.split(\"/\") as [string, string];\n\n // Detect projects\n const projects = listOrgProjects(owner);\n let projectNumber: number;\n if (projects.length === 0) {\n console.log(\" No GitHub Projects found. Enter project number manually.\");\n const num = await input({ message: ` Project number for ${repoName}:` });\n projectNumber = Number.parseInt(num, 10);\n } else {\n projectNumber = await select<number>({\n message: ` Select project for ${repoName}:`,\n choices: projects.map((p) => ({\n name: `#${p.number} — ${p.title}`,\n value: p.number,\n })),\n });\n }\n\n // Auto-detect status field\n console.log(\" Detecting status field...\");\n const statusInfo = detectStatusField(owner, projectNumber);\n let statusFieldId: string;\n if (statusInfo) {\n statusFieldId = statusInfo.fieldId;\n console.log(` Found status field: ${statusFieldId}`);\n } else {\n console.log(\" Could not auto-detect status field.\");\n statusFieldId = await input({\n message: \" Enter status field ID manually:\",\n });\n }\n\n // Detect due date field\n console.log(\" Detecting due date field...\");\n let dueDateFieldId: string | undefined;\n const existingDateField = detectDateField(owner, projectNumber);\n if (existingDateField) {\n console.log(` Found date field: \"${existingDateField.name}\" (${existingDateField.id})`);\n const useDateField = await confirm({\n message: ` Use \"${existingDateField.name}\" for due dates?`,\n default: true,\n });\n if (useDateField) {\n dueDateFieldId = existingDateField.id;\n }\n } else {\n console.log(\" No due date field found in this project.\");\n const createField = await confirm({\n message: ' Create a \"Due Date\" field for due dates?',\n default: false,\n });\n if (createField) {\n console.log(' Creating \"Due Date\" field...');\n const newFieldId = createDateField(owner, projectNumber, \"Due Date\");\n if (newFieldId) {\n dueDateFieldId = newFieldId;\n console.log(` Created \"Due Date\" field (${newFieldId})`);\n } else {\n console.log(\" Could not create field — due dates will be stored in issue body.\");\n }\n } else {\n console.log(\" Skipped — due dates will be stored in issue body.\");\n }\n }\n\n // Completion action\n const completionType = await select<CompletionAction[\"type\"]>({\n message: ` When a task is completed, what should happen on GitHub?`,\n choices: [\n { name: \"Close the issue\", value: \"closeIssue\" as const },\n { name: \"Add a label (e.g. review:pending)\", value: \"addLabel\" as const },\n { name: \"Update project status column\", value: \"updateProjectStatus\" as const },\n ],\n });\n\n let completionAction: CompletionAction;\n if (completionType === \"addLabel\") {\n const label = await input({\n message: \" Label to add:\",\n default: \"review:pending\",\n });\n completionAction = { type: \"addLabel\", label };\n } else if (completionType === \"updateProjectStatus\") {\n const statusOptions = statusInfo?.options ?? [];\n let optionId: string;\n if (statusOptions.length > 0) {\n optionId = await select<string>({\n message: \" Status to set when completed:\",\n choices: statusOptions.map((o) => ({\n name: o.name,\n value: o.id,\n })),\n });\n } else {\n optionId = await input({\n message: \" Status option ID to set:\",\n });\n }\n completionAction = { type: \"updateProjectStatus\", optionId };\n } else {\n completionAction = { type: \"closeIssue\" };\n }\n\n // Short name\n const shortName = await input({\n message: ` Short name for ${repoName}:`,\n default: name,\n });\n\n repos.push({\n name: repoName,\n shortName,\n projectNumber,\n statusFieldId,\n ...(dueDateFieldId ? { dueDateFieldId } : {}),\n completionAction,\n });\n }\n\n // Step 6: TickTick integration (disabled by default, enable with `hog config ticktick:enable`)\n const ticktickAlreadyEnabled = existsSync(`${CONFIG_DIR}/auth.json`);\n let ticktickAuth = false;\n if (ticktickAlreadyEnabled) {\n ticktickAuth = true;\n console.log(\"TickTick auth found — integration enabled.\");\n }\n\n // Step 7: Board defaults\n console.log(\"\\nBoard settings:\");\n const refreshInterval = await input({\n message: \" Refresh interval (seconds):\",\n default: \"60\",\n });\n const backlogLimit = await input({\n message: \" Backlog limit (max issues per repo):\",\n default: \"20\",\n });\n const focusDuration = await input({\n message: \" Focus timer duration (seconds):\",\n default: \"1500\",\n });\n\n // Step 8: AI / LLM key (optional)\n console.log(\"\\nAI-enhanced issue creation (optional):\");\n console.log(\n ' Press I on the board to create issues with natural language (e.g. \"fix login bug #backend @alice due friday\").',\n );\n console.log(\" Without a key the heuristic parser still works — labels, assignee, and due dates\");\n console.log(\" are extracted from #, @, and due tokens. An OpenRouter key enables richer title\");\n console.log(\" cleanup and inference for ambiguous input.\");\n const setupLlm = await confirm({\n message: \" Set up an OpenRouter API key now?\",\n default: false,\n });\n if (setupLlm) {\n console.log(\" Get a free key at https://openrouter.ai/keys\");\n const llmKey = await input({\n message: \" OpenRouter API key:\",\n validate: (v) => (v.trim().startsWith(\"sk-or-\") ? true : 'Key must start with \"sk-or-\"'),\n });\n saveLlmAuth(llmKey.trim());\n console.log(\" OpenRouter key saved to ~/.config/hog/auth.json\");\n } else {\n console.log(\" Skipped. You can add it later: hog config ai:set-key\");\n }\n\n // Step 9: Build and write config\n const existingConfig = configExists ? loadFullConfig() : undefined;\n const config: HogConfig = {\n version: 3,\n defaultProjectId: existingConfig?.defaultProjectId,\n defaultProjectName: existingConfig?.defaultProjectName,\n repos,\n board: {\n refreshInterval: Number.parseInt(refreshInterval, 10) || 60,\n backlogLimit: Number.parseInt(backlogLimit, 10) || 20,\n assignee: login,\n focusDuration: Number.parseInt(focusDuration, 10) || 1500,\n },\n ticktick: { enabled: ticktickAuth },\n profiles: existingConfig?.profiles ?? {},\n };\n\n saveFullConfig(config);\n console.log(`\\nConfig written to ${CONFIG_DIR}/config.json`);\n console.log(\"\\nSetup complete! Try:\\n\");\n console.log(\" hog board --live # Interactive dashboard\");\n console.log(\" hog task list # List TickTick tasks\");\n console.log(\" hog config show # View configuration\\n\");\n}\n\n// ── repos:add wizard ──\n\nexport async function runReposAdd(initialRepoName?: string): Promise<void> {\n try {\n await runReposAddWizard(initialRepoName);\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"User force closed\")) {\n console.log(\"\\nCancelled. No changes were made.\");\n return;\n }\n throw error;\n }\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: interactive add-repo wizard with many steps\nasync function runReposAddWizard(initialRepoName?: string): Promise<void> {\n console.log(\"\\n🐗 hog config repos:add\\n\");\n\n const cfg = loadFullConfig();\n let repoName = initialRepoName;\n\n if (!repoName) {\n console.log(\"Fetching repositories...\");\n const allRepos = listAllRepos();\n const configuredNames = new Set(cfg.repos.map((r) => r.name));\n const available = allRepos.filter((r) => !configuredNames.has(r.nameWithOwner));\n\n if (available.length === 0) {\n console.log(\n \"No more repositories available to add. All accessible repos are already tracked.\",\n );\n return;\n }\n\n repoName = await select<string>({\n message: \"Select repository to add:\",\n choices: available.map((r) => ({ name: r.nameWithOwner, value: r.nameWithOwner })),\n });\n }\n\n if (!validateRepoName(repoName)) {\n console.error(\"Invalid repo name. Use owner/repo format (e.g. myorg/myrepo).\");\n process.exit(1);\n }\n\n if (findRepo(cfg, repoName)) {\n console.error(`Repo \"${repoName}\" is already configured.`);\n process.exit(1);\n }\n\n const [owner, name] = repoName.split(\"/\") as [string, string];\n console.log(`\\nConfiguring ${repoName}...`);\n\n // Detect projects\n console.log(\" Fetching GitHub Projects...\");\n const projects = listOrgProjects(owner);\n let projectNumber: number;\n if (projects.length === 0) {\n console.log(\" No GitHub Projects found. Enter project number manually.\");\n const num = await input({ message: ` Project number for ${repoName}:` });\n projectNumber = Number.parseInt(num, 10);\n } else {\n projectNumber = await select<number>({\n message: ` Select project for ${repoName}:`,\n choices: projects.map((p) => ({ name: `#${p.number} — ${p.title}`, value: p.number })),\n });\n }\n\n // Auto-detect status field\n console.log(\" Detecting status field...\");\n const statusInfo = detectStatusField(owner, projectNumber);\n let statusFieldId: string;\n if (statusInfo) {\n statusFieldId = statusInfo.fieldId;\n console.log(` Found status field: ${statusFieldId}`);\n } else {\n console.log(\" Could not auto-detect status field.\");\n statusFieldId = await input({ message: \" Enter status field ID manually:\" });\n }\n\n // Detect due date field\n console.log(\" Detecting due date field...\");\n let dueDateFieldId: string | undefined;\n const existingDateField = detectDateField(owner, projectNumber);\n if (existingDateField) {\n console.log(` Found date field: \"${existingDateField.name}\" (${existingDateField.id})`);\n const useDateField = await confirm({\n message: ` Use \"${existingDateField.name}\" for due dates?`,\n default: true,\n });\n if (useDateField) {\n dueDateFieldId = existingDateField.id;\n }\n } else {\n console.log(\" No due date field found.\");\n const createField = await confirm({\n message: ' Create a \"Due Date\" field for this project?',\n default: false,\n });\n if (createField) {\n console.log(' Creating \"Due Date\" field...');\n const newFieldId = createDateField(owner, projectNumber, \"Due Date\");\n if (newFieldId) {\n dueDateFieldId = newFieldId;\n console.log(` Created \"Due Date\" field (${newFieldId})`);\n } else {\n console.log(\" Could not create field — due dates will be stored in issue body.\");\n }\n }\n }\n\n // Completion action\n const completionType = await select<CompletionAction[\"type\"]>({\n message: \" When a task is completed, what should happen on GitHub?\",\n choices: [\n { name: \"Close the issue\", value: \"closeIssue\" as const },\n { name: \"Add a label (e.g. review:pending)\", value: \"addLabel\" as const },\n { name: \"Update project status column\", value: \"updateProjectStatus\" as const },\n ],\n });\n\n let completionAction: CompletionAction;\n if (completionType === \"addLabel\") {\n const label = await input({ message: \" Label to add:\", default: \"review:pending\" });\n completionAction = { type: \"addLabel\", label };\n } else if (completionType === \"updateProjectStatus\") {\n const statusOptions = statusInfo?.options ?? [];\n let optionId: string;\n if (statusOptions.length > 0) {\n optionId = await select<string>({\n message: \" Status to set when completed:\",\n choices: statusOptions.map((o) => ({ name: o.name, value: o.id })),\n });\n } else {\n optionId = await input({ message: \" Status option ID to set:\" });\n }\n completionAction = { type: \"updateProjectStatus\", optionId };\n } else {\n completionAction = { type: \"closeIssue\" };\n }\n\n // Short name\n const shortName = await input({\n message: ` Short name for ${repoName}:`,\n default: name,\n });\n\n const newRepo: RepoConfig = {\n name: repoName,\n shortName,\n projectNumber,\n statusFieldId,\n ...(dueDateFieldId ? { dueDateFieldId } : {}),\n completionAction,\n };\n\n cfg.repos.push(newRepo);\n saveFullConfig(cfg);\n\n console.log(`\\n Added ${shortName} → ${repoName}`);\n console.log(\" Run: hog board --live\\n\");\n}\n","import type { SyncResult } from \"./sync.js\";\nimport type { SyncState } from \"./sync-state.js\";\nimport type { Project, Task } from \"./types.js\";\nimport { Priority } from \"./types.js\";\n\nconst isTTY = process.stdout.isTTY ?? false;\n\nlet forceFormat: \"json\" | \"human\" | null = null;\n\nexport function setFormat(format: \"json\" | \"human\"): void {\n forceFormat = format;\n}\n\nexport function useJson(): boolean {\n if (forceFormat === \"json\") return true;\n if (forceFormat === \"human\") return false;\n return !isTTY;\n}\n\nexport function jsonOut(data: unknown): void {\n console.log(JSON.stringify(data));\n}\n\nconst PRIORITY_LABELS: Record<number, string> = {\n [Priority.None]: \"\",\n [Priority.Low]: \"[low]\",\n [Priority.Medium]: \"[med]\",\n [Priority.High]: \"[HIGH]\",\n};\n\nfunction formatDate(dateStr: string): string {\n if (!dateStr) return \"\";\n const d = new Date(dateStr);\n const now = new Date();\n const days = Math.ceil((d.getTime() - now.getTime()) / 86_400_000);\n\n if (days < 0) return `${Math.abs(days)}d ago`;\n if (days === 0) return \"today\";\n if (days === 1) return \"tomorrow\";\n if (days <= 7) return `in ${days}d`;\n return d.toLocaleDateString(\"en-US\", { month: \"short\", day: \"numeric\" });\n}\n\nfunction taskLine(t: Task): string {\n const parts: string[] = [];\n const pri = PRIORITY_LABELS[t.priority] ?? \"\";\n if (pri) parts.push(pri);\n parts.push(t.title);\n if (t.dueDate) parts.push(` ${formatDate(t.dueDate)}`);\n if (t.tags.length > 0) parts.push(` #${t.tags.join(\" #\")}`);\n return ` ${t.id} ${parts.join(\" \")}`;\n}\n\nexport function printTasks(tasks: Task[]): void {\n if (useJson()) {\n jsonOut(tasks);\n return;\n }\n if (tasks.length === 0) {\n console.log(\" No tasks.\");\n return;\n }\n for (const t of tasks) {\n console.log(taskLine(t));\n }\n}\n\nexport function printTask(task: Task): void {\n if (useJson()) {\n jsonOut(task);\n return;\n }\n console.log(` ID: ${task.id}`);\n console.log(` Title: ${task.title}`);\n if (task.content) console.log(` Content: ${task.content}`);\n console.log(` Priority: ${PRIORITY_LABELS[task.priority] ?? \"none\"}`);\n if (task.dueDate) console.log(` Due: ${formatDate(task.dueDate)}`);\n if (task.startDate) console.log(` Start: ${formatDate(task.startDate)}`);\n if (task.tags.length > 0) console.log(` Tags: ${task.tags.join(\", \")}`);\n console.log(` Project: ${task.projectId}`);\n console.log(` Status: ${task.status === 2 ? \"completed\" : \"active\"}`);\n}\n\nexport function printProjects(projects: Project[]): void {\n if (useJson()) {\n jsonOut(projects);\n return;\n }\n if (projects.length === 0) {\n console.log(\" No projects.\");\n return;\n }\n for (const p of projects) {\n const closed = p.closed ? \" (closed)\" : \"\";\n console.log(` ${p.id} ${p.name}${closed}`);\n }\n}\n\nexport function printSuccess(message: string, data?: Record<string, unknown> | object): void {\n if (useJson()) {\n jsonOut({ ok: true, message, ...data });\n return;\n }\n console.log(message);\n}\n\nfunction printSection(prefix: string, label: string, icon: string, items: string[]): void {\n if (items.length === 0) return;\n console.log(`${prefix}${label} ${items.length} task(s):`);\n for (const key of items) console.log(` ${icon} ${key}`);\n}\n\nexport function printSyncResult(result: SyncResult, dryRun: boolean): void {\n if (useJson()) {\n jsonOut({ ok: true, dryRun, ...result });\n return;\n }\n const prefix = dryRun ? \"[dry-run] \" : \"\";\n printSection(prefix, \"Created\", \"+\", result.created);\n printSection(prefix, \"Updated\", \"~\", result.updated);\n printSection(prefix, \"Completed\", \"✓\", result.completed);\n printSection(prefix, \"GitHub updated\", \"→\", result.ghUpdated);\n printSection(\"\", \"Errors\", \"✗\", result.errors);\n const total =\n result.created.length +\n result.updated.length +\n result.completed.length +\n result.ghUpdated.length;\n if (total === 0 && result.errors.length === 0) {\n console.log(`${prefix}Everything in sync.`);\n }\n}\n\nexport function printSyncStatus(state: SyncState, repos: string[]): void {\n if (useJson()) {\n jsonOut({ repos, lastSyncAt: state.lastSyncAt ?? null, mappings: state.mappings });\n return;\n }\n console.log(` Repos: ${repos.join(\", \")}`);\n console.log(` Last sync: ${state.lastSyncAt ?? \"never\"}`);\n console.log(` Active mappings: ${state.mappings.length}`);\n if (state.mappings.length > 0) {\n for (const m of state.mappings) {\n console.log(` ${m.githubRepo}#${m.githubIssueNumber} → ${m.ticktickTaskId}`);\n }\n }\n}\n","import { TickTickClient } from \"./api.js\";\nimport { formatError } from \"./board/constants.js\";\nimport type { HogConfig, RepoConfig } from \"./config.js\";\nimport { loadFullConfig, requireAuth } from \"./config.js\";\nimport type { GitHubIssue, ProjectEnrichment } from \"./github.js\";\nimport {\n addLabel,\n fetchAssignedIssues,\n fetchProjectEnrichment,\n updateProjectItemStatus,\n} from \"./github.js\";\nimport type { SyncMapping, SyncState } from \"./sync-state.js\";\nimport {\n findMapping,\n loadSyncState,\n removeMapping,\n saveSyncState,\n upsertMapping,\n} from \"./sync-state.js\";\nimport type { CreateTaskInput, UpdateTaskInput } from \"./types.js\";\nimport { Priority, TaskStatus } from \"./types.js\";\n\nexport interface SyncResult {\n created: string[];\n updated: string[];\n completed: string[];\n ghUpdated: string[];\n errors: string[];\n}\n\ninterface SyncOptions {\n dryRun?: boolean;\n}\n\nfunction emptySyncResult(): SyncResult {\n return { created: [], updated: [], completed: [], ghUpdated: [], errors: [] };\n}\n\nfunction repoShortName(repo: string): string {\n return repo.split(\"/\")[1] ?? repo;\n}\n\nfunction issueTaskTitle(issue: GitHubIssue): string {\n return issue.title;\n}\n\nfunction issueTaskContent(\n issue: GitHubIssue,\n projectFields: { targetDate?: string; status?: string },\n): string {\n const lines = [`GitHub: ${issue.url}`];\n if (projectFields.status) lines.push(`Status: ${projectFields.status}`);\n return lines.join(\"\\n\");\n}\n\nfunction mapPriority(labels: { name: string }[]): Priority {\n for (const label of labels) {\n if (label.name === \"priority:critical\" || label.name === \"priority:high\") return Priority.High;\n if (label.name === \"priority:medium\") return Priority.Medium;\n if (label.name === \"priority:low\") return Priority.Low;\n }\n return Priority.None;\n}\n\nfunction buildCreateInput(\n repo: string,\n issue: GitHubIssue,\n projectFields: { targetDate?: string; status?: string },\n): CreateTaskInput {\n const input: CreateTaskInput = {\n title: issueTaskTitle(issue),\n content: issueTaskContent(issue, projectFields),\n priority: mapPriority(issue.labels),\n tags: [\"github\", repoShortName(repo)],\n };\n if (projectFields.targetDate) {\n input.dueDate = projectFields.targetDate;\n input.isAllDay = true;\n }\n return input;\n}\n\nfunction buildUpdateInput(\n repo: string,\n issue: GitHubIssue,\n projectFields: { targetDate?: string; status?: string },\n mapping: SyncMapping,\n): UpdateTaskInput {\n const input: UpdateTaskInput = {\n id: mapping.ticktickTaskId,\n projectId: mapping.ticktickProjectId,\n title: issueTaskTitle(issue),\n content: issueTaskContent(issue, projectFields),\n priority: mapPriority(issue.labels),\n tags: [\"github\", repoShortName(repo)],\n };\n if (projectFields.targetDate) {\n input.dueDate = projectFields.targetDate;\n }\n return input;\n}\n\n/** Phase 1: Sync GitHub issues to TickTick (create/update). Returns open issue keys and repos that failed to fetch. */\nasync function syncGitHubToTickTick(\n config: HogConfig,\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n): Promise<{ openIssueKeys: Set<string>; failedRepos: Set<string> }> {\n const openIssueKeys = new Set<string>();\n const failedRepos = new Set<string>();\n\n for (const repoConfig of config.repos) {\n let issues: GitHubIssue[];\n try {\n issues = fetchAssignedIssues(repoConfig.name, config.board.assignee);\n } catch (err) {\n result.errors.push(`Failed to fetch issues from ${repoConfig.name}: ${formatError(err)}`);\n failedRepos.add(repoConfig.name);\n continue;\n }\n\n let enrichMap: Map<number, ProjectEnrichment>;\n try {\n enrichMap = fetchProjectEnrichment(repoConfig.name, repoConfig.projectNumber);\n } catch {\n enrichMap = new Map();\n }\n\n for (const issue of issues) {\n const key = `${repoConfig.name}#${issue.number}`;\n openIssueKeys.add(key);\n await syncSingleIssue(state, api, result, dryRun, repoConfig, issue, key, enrichMap);\n }\n }\n\n return { openIssueKeys, failedRepos };\n}\n\nasync function syncSingleIssue(\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n repoConfig: RepoConfig,\n issue: GitHubIssue,\n key: string,\n enrichMap: Map<number, ProjectEnrichment>,\n): Promise<void> {\n try {\n const existing = findMapping(state, repoConfig.name, issue.number);\n\n if (existing && existing.githubUpdatedAt === issue.updatedAt) return;\n\n const enrichment = enrichMap.get(issue.number);\n const projectFields: { targetDate?: string; status?: string } = {\n ...(enrichment?.targetDate !== undefined && { targetDate: enrichment.targetDate }),\n ...(enrichment?.projectStatus !== undefined && { status: enrichment.projectStatus }),\n };\n\n if (!existing) {\n await createTickTickTask(\n state,\n api,\n result,\n dryRun,\n repoConfig.name,\n issue,\n projectFields,\n key,\n );\n } else {\n await updateTickTickTask(\n state,\n api,\n result,\n dryRun,\n repoConfig.name,\n issue,\n projectFields,\n existing,\n key,\n );\n }\n } catch (err) {\n result.errors.push(`${key}: ${formatError(err)}`);\n }\n}\n\nasync function createTickTickTask(\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n repo: string,\n issue: GitHubIssue,\n projectFields: { targetDate?: string; status?: string },\n key: string,\n): Promise<void> {\n if (dryRun) {\n result.created.push(key);\n return;\n }\n const input = buildCreateInput(repo, issue, projectFields);\n const task = await api.createTask(input);\n\n upsertMapping(state, {\n githubRepo: repo,\n githubIssueNumber: issue.number,\n githubUrl: issue.url,\n ticktickTaskId: task.id,\n ticktickProjectId: task.projectId,\n githubUpdatedAt: issue.updatedAt,\n lastSyncedAt: new Date().toISOString(),\n });\n result.created.push(key);\n}\n\nasync function updateTickTickTask(\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n repo: string,\n issue: GitHubIssue,\n projectFields: { targetDate?: string; status?: string },\n existing: SyncMapping,\n key: string,\n): Promise<void> {\n if (dryRun) {\n result.updated.push(key);\n return;\n }\n const input = buildUpdateInput(repo, issue, projectFields, existing);\n await api.updateTask(input);\n\n upsertMapping(state, {\n ...existing,\n githubUpdatedAt: issue.updatedAt,\n lastSyncedAt: new Date().toISOString(),\n });\n result.updated.push(key);\n}\n\n/** Phase 2: Complete TickTick tasks for issues no longer open on GitHub. */\nasync function syncClosedIssues(\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n openIssueKeys: Set<string>,\n failedRepos: Set<string>,\n): Promise<void> {\n for (const mapping of [...state.mappings]) {\n // SAFETY: Never complete tasks from repos we couldn't fetch — we don't know their real state\n if (failedRepos.has(mapping.githubRepo)) continue;\n\n const key = `${mapping.githubRepo}#${mapping.githubIssueNumber}`;\n if (openIssueKeys.has(key)) continue;\n\n try {\n if (dryRun) {\n result.completed.push(key);\n continue;\n }\n await api.completeTask(mapping.ticktickProjectId, mapping.ticktickTaskId);\n removeMapping(state, mapping.githubRepo, mapping.githubIssueNumber);\n result.completed.push(key);\n } catch (err) {\n result.errors.push(`Complete ${key}: ${formatError(err)}`);\n }\n }\n}\n\n/** Phase 3: Update GitHub when TickTick tasks are completed. */\nasync function syncCompletedTasksToGitHub(\n config: HogConfig,\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n): Promise<void> {\n for (const mapping of [...state.mappings]) {\n const key = `${mapping.githubRepo}#${mapping.githubIssueNumber}`;\n try {\n await processCompletedMapping(config, state, api, result, dryRun, mapping, key);\n } catch (err) {\n result.errors.push(`GH update ${key}: ${formatError(err)}`);\n }\n }\n}\n\nasync function processCompletedMapping(\n config: HogConfig,\n state: SyncState,\n api: TickTickClient,\n result: SyncResult,\n dryRun: boolean,\n mapping: SyncMapping,\n key: string,\n): Promise<void> {\n let task: Awaited<ReturnType<TickTickClient[\"getTask\"]>>;\n try {\n task = await api.getTask(mapping.ticktickProjectId, mapping.ticktickTaskId);\n } catch {\n return; // Task might have been deleted\n }\n\n if (task.status !== TaskStatus.Completed) return;\n\n if (dryRun) {\n result.ghUpdated.push(key);\n return;\n }\n\n const repo = mapping.githubRepo;\n const repoConfig = config.repos.find((r) => r.name === repo);\n\n if (repoConfig) {\n const action = repoConfig.completionAction;\n switch (action.type) {\n case \"addLabel\":\n addLabel(repo, mapping.githubIssueNumber, action.label);\n break;\n case \"updateProjectStatus\":\n updateProjectItemStatus(repo, mapping.githubIssueNumber, {\n projectNumber: repoConfig.projectNumber,\n statusFieldId: repoConfig.statusFieldId,\n optionId: action.optionId,\n });\n break;\n case \"closeIssue\":\n // Future: close the issue\n break;\n }\n }\n\n removeMapping(state, repo, mapping.githubIssueNumber);\n result.ghUpdated.push(key);\n}\n\nexport async function runSync(options: SyncOptions = {}): Promise<SyncResult> {\n const { dryRun = false } = options;\n const result = emptySyncResult();\n\n const config = loadFullConfig();\n const auth = requireAuth();\n const api = new TickTickClient(auth.accessToken);\n const state = loadSyncState();\n\n const { openIssueKeys, failedRepos } = await syncGitHubToTickTick(\n config,\n state,\n api,\n result,\n dryRun,\n );\n await syncClosedIssues(state, api, result, dryRun, openIssueKeys, failedRepos);\n await syncCompletedTasksToGitHub(config, state, api, result, dryRun);\n\n if (!dryRun) {\n state.lastSyncAt = new Date().toISOString();\n saveSyncState(state);\n }\n\n return result;\n}\n\nexport function getSyncStatus(): { state: SyncState; repos: string[] } {\n const config = loadFullConfig();\n return { state: loadSyncState(), repos: config.repos.map((r) => r.name) };\n}\n"],"mappings":"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","names":["config","input","text","input","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","join","execFileSync","DATE_FIELD_NAME_RE","existsSync","readFileSync","writeFileSync","homedir","join","CONFIG_DIR","input","config","repoShortName","mapPriority","task","useCallback","useRef","config","shortName","useCallback","useRef","useState","config","useCallback","input","useCallback","useRef","useState","useCallback","useRef","select","useCallback","useState","useCallback","useRef","useState","useCallback","useReducer","INITIAL_STATE","existsSync","useEffect","useState","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","useEffect","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","useInput","useState","jsx","jsxs","input","spawnSync","readFileSync","writeFileSync","join","Box","Text","useInput","useEffect","useRef","useState","jsx","jsxs","inkInstance","Box","Text","useInput","jsx","jsxs","input","Box","Text","useInput","useEffect","useRef","useState","jsx","jsxs","input","allLabels","TextInput","Box","Text","useInput","useState","jsx","jsxs","input","spawnSync","mkdtempSync","readFileSync","rmSync","writeFileSync","tmpdir","join","Box","Text","useStdin","useEffect","useRef","useState","jsx","jsxs","inkInstance","Box","Text","useInput","useCallback","useEffect","useRef","useState","jsx","jsxs","input","TextInput","Box","Text","useInput","useMemo","useState","jsx","jsxs","input","Box","Text","useInput","jsx","jsxs","spawnSync","mkdtempSync","readFileSync","rmSync","writeFileSync","tmpdir","join","Spinner","TextInput","Box","Text","useInput","useStdin","useCallback","useEffect","useRef","useState","jsx","jsxs","inkInstance","TextInput","Box","Text","jsx","jsxs","Box","Text","useInput","useRef","useState","jsx","jsxs","input","Fragment","jsx","jsxs","config","Box","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","formatDate","days","Box","Text","jsx","jsxs","checkbox","Box","Text","jsx","jsxs","Spinner","Box","Text","Fragment","jsx","jsxs","execFileSync","spawnSync","Spinner","Box","Text","useCallback","useEffect","useMemo","useRef","useState","Fragment","jsx","jsxs","config","pickIssue","jsx","config","SLACK_URL_RE","execFileSync","shortName","config","truncate","task","printSection","execFile","execFileSync","promisify","existsSync","shortName","config","task","input","config","task","execFileAsync","promisify","execFile","config","parseIssueRef","input","runLiveDashboard","fetchDashboard","renderBoardJson","renderStaticBoard","pickIssue","launchClaude","fetchIssueAsync","shortName","execFileSync","fetchProjectStatusOptions","updateProjectItemStatusAsync","assignIssueToAsync","unassignIssueAsync","addCommentAsync","removeLabelAsync","addLabelAsync"]}