@ondrej-svec/hog 1.2.0 → 1.3.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 +1821 -846
- package/dist/cli.js.map +1 -1
- package/dist/fetch-worker.js.map +1 -1
- package/package.json +2 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/api.ts","../src/config.ts","../src/types.ts","../src/github.ts","../src/sync-state.ts","../src/pick.ts","../src/board/hooks/use-actions.ts","../src/board/hooks/use-data.ts","../src/board/hooks/use-multi-select.ts","../src/board/hooks/use-navigation.ts","../src/board/hooks/use-toast.ts","../src/board/hooks/use-ui-state.ts","../src/board/components/bulk-action-menu.tsx","../src/board/components/comment-input.tsx","../src/board/components/confirm-prompt.tsx","../src/board/components/create-issue-form.tsx","../src/board/components/detail-panel.tsx","../src/board/components/focus-mode.tsx","../src/board/components/help-overlay.tsx","../src/board/components/issue-row.tsx","../src/board/components/search-bar.tsx","../src/board/components/status-picker.tsx","../src/board/components/task-row.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 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> {\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 undefined as T;\n return JSON.parse(text) as T;\n }\n\n async listProjects(): Promise<Project[]> {\n return this.request<Project[]>(\"GET\", \"/project\");\n }\n\n async getProject(projectId: string): Promise<Project> {\n return this.request<Project>(\"GET\", `/project/${projectId}`);\n }\n\n async getProjectData(projectId: string): Promise<ProjectData> {\n return this.request<ProjectData>(\"GET\", `/project/${projectId}/data`);\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 return this.request<Task>(\"GET\", `/project/${projectId}/task/${taskId}`);\n }\n\n async createTask(input: CreateTaskInput): Promise<Task> {\n return this.request<Task>(\"POST\", \"/task\", input);\n }\n\n async updateTask(input: UpdateTaskInput): Promise<Task> {\n return this.request<Task>(\"POST\", `/task/${input.id}`, input);\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 { 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}\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 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// ── Legacy Repo Defaults (for migration) ──\n\nconst LEGACY_REPOS: RepoConfig[] = [];\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: LEGACY_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 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}\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","// ── 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","import { execFile, execFileSync } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface GitHubIssue {\n number: number;\n title: string;\n url: string;\n state: string;\n updatedAt: string;\n labels: { name: string }[];\n assignees?: { login: string }[];\n targetDate?: string;\n body?: string;\n projectStatus?: string;\n slackThreadUrl?: string;\n}\n\nexport interface ProjectFieldValues {\n targetDate?: string;\n status?: string;\n}\n\nexport interface RepoProjectConfig {\n projectNumber: number;\n statusFieldId: string;\n optionId: string;\n}\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 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 }\n }\n }\n }\n }\n }\n }\n `;\n\n const [owner, repoName] = repo.split(\"/\");\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 if (\"date\" in fv && fv.field?.name === \"Target date\") {\n fields.targetDate = fv.date;\n }\n if (\"name\" in fv && fv.field?.name === \"Status\") {\n fields.status = fv.name;\n }\n }\n\n return fields;\n } catch {\n return {};\n }\n}\n\nexport interface ProjectEnrichment {\n targetDate?: string;\n projectStatus?: 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 */\nexport function fetchProjectEnrichment(\n repo: string,\n projectNumber: number,\n): Map<number, ProjectEnrichment> {\n const [owner] = repo.split(\"/\");\n\n const query = `\n query($owner: String!, $projectNumber: Int!) {\n organization(login: $owner) {\n projectV2(number: $projectNumber) {\n items(first: 100) {\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 }\n }\n }\n }\n }\n }\n }\n `;\n\n try {\n const result = runGhJson<ProjectItemsResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${query}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `projectNumber=${String(projectNumber)}`,\n ]);\n\n const items = result?.data?.organization?.projectV2?.items?.nodes ?? [];\n const enrichMap = new Map<number, ProjectEnrichment>();\n\n for (const item of items) {\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 if (\"date\" in fv && fv.field?.name === \"Target date\" && fv.date) {\n enrichment.targetDate = fv.date;\n }\n if (\"name\" in fv && fv.field?.name === \"Status\" && fv.name) {\n enrichment.projectStatus = fv.name;\n }\n }\n enrichMap.set(item.content.number, enrichment);\n }\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\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 function updateProjectItemStatus(\n repo: string,\n issueNumber: number,\n projectConfig: RepoProjectConfig,\n): void {\n const [owner, repoName] = repo.split(\"/\");\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\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 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;\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\n// Internal GraphQL response types\n\ninterface FieldValue {\n field?: { name?: string };\n date?: string;\n name?: string;\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 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`);\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","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { useCallback, useRef } from \"react\";\nimport type { HogConfig, RepoConfig } from \"../../config.js\";\nimport type { GitHubIssue, RepoProjectConfig, StatusOption } from \"../../github.js\";\nimport { assignIssueAsync, updateProjectItemStatusAsync } from \"../../github.js\";\nimport { pickIssue } from \"../../pick.js\";\nimport type { DashboardData, RepoData } from \"../fetch.js\";\nimport type { ToastAPI } from \"./use-toast.js\";\n\nconst execFileAsync = promisify(execFile);\n\nconst TERMINAL_STATUS_RE = /^(done|shipped|won't|wont|closed|complete|completed)$/i;\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 handleUnassign: () => void;\n handleCreateIssue: (\n repo: string,\n title: string,\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: () => void;\n onOverlayDone: () => 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 execFileAsync(\"gh\", [\"issue\", \"close\", String(issueNumber), \"--repo\", repoName], {\n encoding: \"utf-8\",\n timeout: 30_000,\n });\n break;\n case \"addLabel\":\n await execFileAsync(\n \"gh\",\n [\"issue\", \"edit\", String(issueNumber), \"--repo\", repoName, \"--add-label\", action.label],\n { encoding: \"utf-8\", timeout: 30_000 },\n );\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/** 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}: 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 configRef.current = config;\n reposRef.current = repos;\n selectedIdRef.current = selectedId;\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 execFileAsync(\n \"gh\",\n [\"issue\", \"comment\", String(issue.number), \"--repo\", repoName, \"--body\", body],\n { encoding: \"utf-8\", timeout: 30_000 },\n )\n .then(() => {\n t.resolve(`Comment posted on #${issue.number}`);\n refresh();\n })\n .catch((err) => {\n t.reject(`Comment failed: ${err instanceof Error ? err.message : String(err)}`);\n })\n .finally(() => {\n onOverlayDone();\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 // Optimistic update: move issue to new section immediately\n mutateData((data) =>\n optimisticSetStatus(data, repoName, issue.number, statusOptions, optionId),\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 refresh();\n })\n .catch((err) => {\n t.reject(`Status change failed: ${err instanceof Error ? err.message : String(err)}`);\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 refresh();\n })\n .catch((err) => {\n t.reject(`Assign failed: ${err instanceof Error ? err.message : String(err)}`);\n });\n }, [toast, refresh]);\n\n const handleUnassign = 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 const selfAssigned = assignees.some((a) => a.login === configRef.current.board.assignee);\n\n if (!selfAssigned) {\n const firstAssignee = assignees[0];\n if (firstAssignee) {\n toast.info(`Assigned to @${firstAssignee.login} \\u2014 can only unassign self`);\n } else {\n toast.info(\"Not assigned\");\n }\n return;\n }\n\n const t = toast.loading(\"Unassigning...\");\n execFileAsync(\n \"gh\",\n [\"issue\", \"edit\", String(issue.number), \"--repo\", repoName, \"--remove-assignee\", \"@me\"],\n { encoding: \"utf-8\", timeout: 30_000 },\n )\n .then(() => {\n t.resolve(`Unassigned #${issue.number} from @${configRef.current.board.assignee}`);\n refresh();\n })\n .catch((err) => {\n t.reject(`Unassign failed: ${err instanceof Error ? err.message : String(err)}`);\n });\n }, [toast, refresh]);\n\n const handleCreateIssue = useCallback(\n async (\n repo: string,\n title: string,\n labels?: string[],\n ): Promise<{ repo: string; issueNumber: number } | null> => {\n const args = [\"issue\", \"create\", \"--repo\", repo, \"--title\", title];\n if (labels && labels.length > 0) {\n for (const label of labels) {\n args.push(\"--label\", label);\n }\n }\n const t = toast.loading(\"Creating...\");\n try {\n const { stdout } = await execFileAsync(\"gh\", args, { encoding: \"utf-8\", timeout: 30_000 });\n const output = stdout.trim();\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 = configRef.current.repos.find((r) => r.name === repo)?.shortName ?? repo;\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 // ── 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 execFileAsync(\n \"gh\",\n [\n \"issue\",\n \"edit\",\n String(ctx.issue.number),\n \"--repo\",\n ctx.repoName,\n \"--remove-assignee\",\n \"@me\",\n ],\n { encoding: \"utf-8\", timeout: 30_000 },\n );\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\n for (const id of ids) {\n const ctx = findIssueContext(reposRef.current, id, configRef.current);\n if (ctx.issue && ctx.repoName) {\n const { issue: ctxIssue, repoName: ctxRepo, statusOptions: ctxOpts } = ctx;\n mutateData((data) =>\n optimisticSetStatus(data, ctxRepo, ctxIssue.number, ctxOpts, optionId),\n );\n }\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 = (() => {\n for (const id of ids) {\n const ctx = findIssueContext(reposRef.current, id, configRef.current);\n const name = ctx.statusOptions.find((o) => o.id === optionId)?.name;\n if (name) return name;\n }\n return optionId;\n })();\n if (failed.length === 0) {\n t.resolve(`Moved ${total} issue${total > 1 ? \"s\" : \"\"} to ${optionName}`);\n } else {\n t.reject(`${ok} moved to ${optionName}, ${failed.length} failed`);\n }\n refresh();\n return failed;\n },\n [toast, refresh, mutateData],\n );\n\n return {\n handlePick,\n handleComment,\n handleStatusChange,\n handleAssign,\n handleUnassign,\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\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\nexport function useData(\n config: HogConfig,\n options: FetchOptions,\n refreshIntervalMs: number,\n): DataState & {\n refresh: () => void;\n mutateData: (fn: (data: DashboardData) => DashboardData) => void;\n} {\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\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 const refresh = useCallback(() => {\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 setState((prev) => ({ ...prev, isRefreshing: true }));\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\", (msg: { type: string; data?: DashboardData; error?: string }) => {\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 data = msg.data;\n data.fetchedAt = new Date(data.fetchedAt);\n for (const ev of data.activity) {\n ev.timestamp = new Date(ev.timestamp);\n }\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 {\n setState((prev) => {\n const failures = prev.consecutiveFailures + 1;\n return {\n ...prev,\n status: prev.data ? \"success\" : \"error\",\n error: msg.error ?? \"Unknown 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();\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 return { ...state, refresh, mutateData };\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}\n\ntype NavAction =\n | { type: \"SET_ITEMS\"; items: NavItem[] }\n | { type: \"SELECT\"; id: string; section?: SectionId | undefined }\n | { type: \"TOGGLE_SECTION\"; section: SectionId };\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\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, collapse all sections; on refresh, preserve collapsed state\n const collapsedSections = isFirstLoad ? new Set(sections) : state.collapsedSections;\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 if (!isFirstLoad && selectionValid && arraysEqual(sections, state.sections)) {\n return state;\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 };\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 };\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 if (next.has(action.section)) {\n next.delete(action.section);\n } else {\n next.add(action.section);\n }\n return { ...state, collapsedSections: next };\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 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 });\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 // 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 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 select,\n isCollapsed,\n };\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: (id: string) => void;\n dismissAll: () => void;\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 dismiss = useCallback(\n (id: string) => {\n removeToast(id);\n },\n [removeToast],\n );\n\n const dismissAll = useCallback(() => {\n for (const timer of timersRef.current.values()) {\n clearTimeout(timer);\n }\n timersRef.current.clear();\n setToasts([]);\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, dismiss, dismissAll, 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:bulkAction\"\n | \"overlay:confirmPick\"\n | \"overlay:help\"\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_MULTI_SELECT\" }\n | { type: \"ENTER_BULK_ACTION\" }\n | { type: \"ENTER_CONFIRM_PICK\" }\n | { type: \"ENTER_FOCUS\" }\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 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\") return state;\n return { ...state, mode: \"overlay:comment\", previousMode: \"normal\" };\n\n case \"ENTER_STATUS\":\n if (state.mode !== \"normal\" && state.mode !== \"overlay:bulkAction\") return state;\n return {\n ...state,\n mode: \"overlay:status\",\n previousMode: state.mode === \"overlay:bulkAction\" ? \"multiSelect\" : \"normal\",\n };\n\n case \"ENTER_CREATE\":\n if (state.mode !== \"normal\") return state;\n return { ...state, mode: \"overlay:create\", 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 \"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 enterMultiSelect: () => void;\n enterBulkAction: () => void;\n enterConfirmPick: () => void;\n enterFocus: () => 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 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 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, 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 { TextInput } from \"@inkjs/ui\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useState } from \"react\";\n\ninterface CommentInputProps {\n readonly issueNumber: number;\n readonly onSubmit: (body: string) => void;\n readonly onCancel: () => void;\n}\n\nfunction CommentInput({ issueNumber, onSubmit, onCancel }: CommentInputProps) {\n const [value, setValue] = useState(\"\");\n\n useInput((_input, key) => {\n if (key.escape) onCancel();\n });\n\n return (\n <Box>\n <Text color=\"cyan\">comment #{issueNumber}: </Text>\n <TextInput\n defaultValue={value}\n placeholder=\"type comment, 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 { TextInput } from \"@inkjs/ui\";\nimport { Box, Text, useInput } from \"ink\";\nimport { useState } from \"react\";\nimport type { RepoConfig } from \"../../config.js\";\n\ninterface CreateIssueFormProps {\n readonly repos: RepoConfig[];\n readonly defaultRepo: string | null;\n readonly onSubmit: (repo: string, title: string, labels?: string[]) => void;\n readonly onCancel: () => void;\n}\n\nfunction CreateIssueForm({ repos, defaultRepo, onSubmit, onCancel }: 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\">(\"title\");\n\n useInput((input, key) => {\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 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 if (text.trim() && selectedRepo) {\n onSubmit(selectedRepo.name, text.trim());\n }\n }}\n />\n ) : (\n <Text>{title || \"(empty)\"}</Text>\n )}\n </Box>\n\n <Text dimColor>Tab:switch fields Enter:submit Esc:cancel</Text>\n </Box>\n );\n}\n\nexport { CreateIssueForm };\n","import { Box, Text } from \"ink\";\nimport type { GitHubIssue } from \"../../github.js\";\nimport type { Task } from \"../../types.js\";\nimport { Priority } from \"../../types.js\";\n\ninterface DetailPanelProps {\n readonly issue: GitHubIssue | null;\n readonly task: Task | null;\n readonly width: number;\n}\n\nfunction truncateLines(text: string, maxLines: number): string {\n const lines = text.split(\"\\n\").slice(0, maxLines);\n return lines.join(\"\\n\");\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\nconst PRIORITY_LABELS: Record<number, string> = {\n [Priority.High]: \"High\",\n [Priority.Medium]: \"Medium\",\n [Priority.Low]: \"Low\",\n [Priority.None]: \"None\",\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\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: conditional rendering for issue vs task\nfunction DetailPanel({ issue, task, width }: DetailPanelProps) {\n if (!(issue || task)) {\n return (\n <Box\n width={width}\n borderStyle=\"single\"\n borderColor=\"gray\"\n flexDirection=\"column\"\n paddingX={1}\n >\n <Text color=\"gray\">No item selected</Text>\n </Box>\n );\n }\n\n if (issue) {\n return (\n <Box\n width={width}\n borderStyle=\"single\"\n borderColor=\"cyan\"\n flexDirection=\"column\"\n paddingX={1}\n >\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 <Text>{\"\"}</Text>\n <Text color=\"gray\" dimColor>\n {issue.url}\n </Text>\n </Box>\n );\n }\n\n // TickTick task — task is guaranteed non-null here (early return above covers null case)\n const t = task as Task;\n return (\n <Box\n width={width}\n borderStyle=\"single\"\n borderColor=\"yellow\"\n flexDirection=\"column\"\n paddingX={1}\n >\n <Text color=\"yellow\" bold>\n {t.title}\n </Text>\n <Text>{\"\"}</Text>\n\n <Box>\n <Text color=\"gray\">Priority: </Text>\n <Text>{PRIORITY_LABELS[t.priority] ?? \"None\"}</Text>\n </Box>\n\n {t.dueDate ? (\n <Box>\n <Text color=\"gray\">Due: </Text>\n <Text>{new Date(t.dueDate).toLocaleDateString()}</Text>\n </Box>\n ) : null}\n\n {(t.tags ?? []).length > 0 ? (\n <Box>\n <Text color=\"gray\">Tags: </Text>\n <Text>{t.tags.join(\", \")}</Text>\n </Box>\n ) : null}\n\n {t.content ? (\n <>\n <Text>{\"\"}</Text>\n <Text>{truncateLines(t.content, 8)}</Text>\n </>\n ) : null}\n\n {(t.items ?? []).length > 0 ? (\n <>\n <Text>{\"\"}</Text>\n <Text color=\"gray\">Checklist:</Text>\n {t.items.slice(0, 5).map((item) => (\n <Text key={item.id}>\n {item.status === 2 ? \"\\u2611\" : \"\\u2610\"} {item.title}\n </Text>\n ))}\n {t.items.length > 5 ? <Text color=\"gray\">...and {t.items.length - 5} more</Text> : null}\n </>\n ) : null}\n </Box>\n );\n}\n\nexport { DetailPanel };\nexport type { DetailPanelProps };\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 { 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 section\" },\n { key: \"Shift+Tab\", desc: \"Previous section\" },\n ],\n },\n {\n category: \"View\",\n items: [\n { key: \"Enter\", desc: \"Toggle section / Open in browser\" },\n { key: \"Space\", desc: \"Toggle section / Multi-select\" },\n { key: \"/\", desc: \"Search\" },\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\" },\n { key: \"u\", desc: \"Unassign self\" },\n { key: \"c\", desc: \"Comment on issue\" },\n { key: \"m\", desc: \"Move status\" },\n { key: \"s\", desc: \"Open Slack thread\" },\n { key: \"n\", desc: \"Create new issue\" },\n ],\n },\n {\n category: \"Board\",\n items: [\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 { 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}\n\nfunction truncate(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, max - 1)}\\u2026` : s;\n}\n\nfunction formatTargetDate(dateStr: string | undefined): { text: string; color: string } {\n if (!dateStr) return { text: \"\", color: \"gray\" };\n const d = new Date(dateStr);\n const days = Math.ceil((d.getTime() - Date.now()) / 86_400_000);\n\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\nfunction timeAgo(dateStr: string): string {\n const seconds = Math.floor((Date.now() - new Date(dateStr).getTime()) / 1000);\n if (seconds < 60) return \"now\";\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h`;\n const days = Math.floor(hours / 24);\n if (days < 30) return `${days}d`;\n const months = Math.floor(days / 30);\n return `${months}mo`;\n}\n\nconst LABEL_COLORS: Record<string, string> = {\n bug: \"red\",\n enhancement: \"green\",\n feature: \"green\",\n documentation: \"blue\",\n \"good first issue\": \"magenta\",\n help: \"yellow\",\n question: \"yellow\",\n urgent: \"red\",\n wontfix: \"gray\",\n};\n\nfunction labelColor(name: string): string {\n return LABEL_COLORS[name.toLowerCase()] ?? \"cyan\";\n}\n\nconst LABEL_COL_WIDTH = 30;\n\nfunction IssueRow({ issue, selfLogin, isSelected }: 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(\", \"), 14);\n const labels = (issue.labels ?? []).slice(0, 2);\n const target = formatTargetDate(issue.targetDate);\n const titleStr = truncate(issue.title, 42).padEnd(42);\n\n return (\n <Box>\n {isSelected ? (\n <Text color=\"cyan\" bold>\n {\"\\u25B6 \"}\n </Text>\n ) : (\n <Text>{\" \"}</Text>\n )}\n <Text color=\"cyan\">#{String(issue.number).padEnd(5)}</Text>\n <Text> </Text>\n {isSelected ? (\n <Text color=\"white\" bold>\n {titleStr}\n </Text>\n ) : (\n <Text>{titleStr}</Text>\n )}\n <Text> </Text>\n <Box width={LABEL_COL_WIDTH}>\n {labels.map((l, i) => (\n <Text key={l.name}>\n {i > 0 ? \" \" : \"\"}\n <Text color={labelColor(l.name)}>[{truncate(l.name, 12)}]</Text>\n </Text>\n ))}\n </Box>\n <Text> </Text>\n <Text color={assigneeColor}>{assigneeText.padEnd(14)}</Text>\n <Text> </Text>\n <Text color=\"gray\">{timeAgo(issue.updatedAt).padStart(4)}</Text>\n {target.text ? (\n <>\n <Text> </Text>\n <Text color={target.color}>{target.text}</Text>\n </>\n ) : null}\n </Box>\n );\n}\n\nexport { IssueRow };\nexport type { IssueRowProps };\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=\"search...\"\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 { useState } from \"react\";\nimport type { StatusOption } from \"../../github.js\";\n\ninterface StatusPickerProps {\n readonly options: StatusOption[];\n readonly currentStatus: string | undefined;\n readonly onSelect: (optionId: string) => void;\n readonly onCancel: () => void;\n}\n\nfunction StatusPicker({ options, currentStatus, onSelect, onCancel }: StatusPickerProps) {\n const [selectedIdx, setSelectedIdx] = useState(() => {\n const idx = options.findIndex((o) => o.name === currentStatus);\n return idx >= 0 ? idx : 0;\n });\n\n useInput((input, key) => {\n if (key.escape) return onCancel();\n if (key.return) {\n const opt = options[selectedIdx];\n if (opt) onSelect(opt.id);\n return;\n }\n if (input === \"j\" || key.downArrow) {\n setSelectedIdx((i) => Math.min(i + 1, options.length - 1));\n }\n if (input === \"k\" || key.upArrow) {\n setSelectedIdx((i) => Math.max(i - 1, 0));\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 prefix = isSelected ? \"> \" : \" \";\n const suffix = isCurrent ? \" (current)\" : \"\";\n return (\n <Text\n key={opt.id}\n {...(isSelected ? { color: \"cyan\" as const } : {})}\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 { Box, Text } from \"ink\";\nimport type { Task } from \"../../types.js\";\nimport { Priority } from \"../../types.js\";\n\ninterface TaskRowProps {\n readonly task: Task;\n readonly isSelected: boolean;\n}\n\nfunction truncate(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, max - 1)}\\u2026` : s;\n}\n\nfunction formatDue(dateStr: string | undefined): { text: string; color: string } {\n if (!dateStr) return { text: \"\", color: \"gray\" };\n const d = new Date(dateStr);\n const days = Math.ceil((d.getTime() - Date.now()) / 86_400_000);\n\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\nconst PRIORITY_INDICATORS: Record<number, { text: string; color: string }> = {\n [Priority.High]: { text: \"[!]\", color: \"red\" },\n [Priority.Medium]: { text: \"[~]\", color: \"yellow\" },\n [Priority.Low]: { text: \"[\\u2193]\", color: \"blue\" },\n [Priority.None]: { text: \" \", color: \"gray\" },\n};\n\nconst DEFAULT_PRIORITY = { text: \" \", color: \"gray\" };\n\nfunction TaskRow({ task, isSelected }: TaskRowProps) {\n const pri = PRIORITY_INDICATORS[task.priority] ?? DEFAULT_PRIORITY;\n const due = formatDue(task.dueDate);\n const titleStr = truncate(task.title, 45).padEnd(45);\n\n return (\n <Box>\n {isSelected ? (\n <Text color=\"cyan\" bold>\n {\"\\u25B6 \"}\n </Text>\n ) : (\n <Text>{\" \"}</Text>\n )}\n <Text color={pri.color}>{pri.text}</Text>\n <Text> </Text>\n {isSelected ? (\n <Text color=\"white\" bold>\n {titleStr}\n </Text>\n ) : (\n <Text>{titleStr}</Text>\n )}\n <Text> </Text>\n <Text color={due.color}>{due.text}</Text>\n </Box>\n );\n}\n\nexport { TaskRow };\nexport type { TaskRowProps };\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 } from \"node:child_process\";\nimport { Spinner } from \"@inkjs/ui\";\nimport { Box, Text, useApp, useInput, useStdout } from \"ink\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { HogConfig } from \"../../config.js\";\nimport type { GitHubIssue, StatusOption } from \"../../github.js\";\nimport type { Task } from \"../../types.js\";\nimport type { ActivityEvent, FetchOptions, RepoData } from \"../fetch.js\";\nimport { useActions } from \"../hooks/use-actions.js\";\nimport { refreshAgeColor, useData } from \"../hooks/use-data.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 { useToast } from \"../hooks/use-toast.js\";\nimport { useUIState } 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 { DetailPanel } from \"./detail-panel.js\";\nimport type { FocusEndAction } from \"./focus-mode.js\";\nimport { FocusMode } from \"./focus-mode.js\";\nimport { HelpOverlay } from \"./help-overlay.js\";\nimport { IssueRow } from \"./issue-row.js\";\nimport { SearchBar } from \"./search-bar.js\";\nimport { StatusPicker } from \"./status-picker.js\";\nimport { TaskRow } from \"./task-row.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\ntype 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: \"task\"; key: string; navId: string; task: Task }\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\n// ── Helpers ──\n\nconst TERMINAL_STATUS_RE = /^(done|shipped|won't|wont|closed|complete|completed)$/i;\n\nfunction isTerminalStatus(status: string): boolean {\n return TERMINAL_STATUS_RE.test(status);\n}\n\ninterface StatusGroup {\n label: string;\n statuses: string[];\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/** Collect issues for a status group (may span multiple statuses). */\nfunction collectGroupIssues(\n statusGroup: StatusGroup,\n byStatus: Map<string, GitHubIssue[]>,\n): GitHubIssue[] {\n const issues: GitHubIssue[] = [];\n for (const status of statusGroup.statuses) {\n const list = byStatus.get(status);\n if (list) issues.push(...list);\n }\n issues.sort((a, b) => issuePriorityRank(a) - issuePriorityRank(b));\n return issues;\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: TUI navigation tree builder\nfunction buildNavItems(repos: RepoData[], tasks: Task[], activityCount: number): NavItem[] {\n const items: NavItem[] = [];\n if (activityCount > 0) {\n items.push({ id: \"header:activity\", section: \"activity\", type: \"header\" });\n }\n for (const rd of repos) {\n items.push({ id: `header:${rd.repo.shortName}`, section: rd.repo.shortName, type: \"header\" });\n const statusGroupDefs = resolveStatusGroups(rd.statusOptions, rd.repo.statusGroups);\n const byStatus = groupByStatus(rd.issues);\n const coveredStatuses = new Set<string>();\n\n for (const sg of statusGroupDefs) {\n const groupIssues = collectGroupIssues(sg, byStatus);\n if (groupIssues.length === 0) continue;\n const subId = `sub:${rd.repo.shortName}:${sg.label}`;\n items.push({ id: subId, section: rd.repo.shortName, type: \"subHeader\" });\n for (const issue of groupIssues) {\n items.push({\n id: `gh:${rd.repo.name}:${issue.number}`,\n section: rd.repo.shortName,\n type: \"item\",\n subSection: subId,\n });\n }\n for (const s of sg.statuses) coveredStatuses.add(s);\n }\n // Any issues in statuses not covered by groups (non-terminal) go at the end\n for (const [status, issues] of byStatus) {\n if (!(coveredStatuses.has(status) || isTerminalStatus(status)) && issues.length > 0) {\n const subId = `sub:${rd.repo.shortName}:${status}`;\n items.push({ id: subId, section: rd.repo.shortName, type: \"subHeader\" });\n for (const issue of issues) {\n items.push({\n id: `gh:${rd.repo.name}:${issue.number}`,\n section: rd.repo.shortName,\n type: \"item\",\n subSection: subId,\n });\n }\n }\n }\n }\n if (tasks.length > 0) {\n items.push({ id: \"header:ticktick\", section: \"ticktick\", type: \"header\" });\n for (const task of tasks) {\n items.push({ id: `tt:${task.id}`, section: \"ticktick\", type: \"item\" });\n }\n }\n return items;\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: flattens nested data into rows\nfunction buildFlatRows(\n repos: RepoData[],\n tasks: Task[],\n activity: ActivityEvent[],\n isCollapsed: (section: string) => boolean,\n): FlatRow[] {\n const rows: FlatRow[] = [];\n\n // Activity section (collapsed by default)\n if (activity.length > 0) {\n const collapsed = isCollapsed(\"activity\");\n rows.push({\n type: \"sectionHeader\",\n key: \"header:activity\",\n navId: \"header:activity\",\n label: \"Recent Activity (24h)\",\n count: activity.length,\n countLabel: \"events\",\n isCollapsed: collapsed,\n });\n if (!collapsed) {\n for (const [i, event] of activity.entries()) {\n rows.push({ type: \"activity\", key: `act:${i}`, navId: null, event });\n }\n }\n }\n\n for (const rd of repos) {\n const { repo, issues, error: repoError } = rd;\n const collapsed = isCollapsed(repo.shortName);\n\n rows.push({\n type: \"sectionHeader\",\n key: `header:${repo.shortName}`,\n navId: `header:${repo.shortName}`,\n label: repo.shortName,\n count: issues.length,\n countLabel: \"issues\",\n isCollapsed: collapsed,\n });\n\n if (!collapsed) {\n if (repoError) {\n rows.push({ type: \"error\", key: `error:${repo.shortName}`, navId: null, text: repoError });\n } else if (issues.length === 0) {\n rows.push({\n type: \"subHeader\",\n key: `empty:${repo.shortName}`,\n navId: null,\n text: \"No open issues\",\n });\n } else {\n const statusGroupDefs = resolveStatusGroups(rd.statusOptions, rd.repo.statusGroups);\n const byStatus = groupByStatus(issues);\n const coveredStatuses = new Set<string>();\n let isFirstGroup = true;\n\n for (const sg of statusGroupDefs) {\n const groupIssues = collectGroupIssues(sg, byStatus);\n if (groupIssues.length === 0) continue;\n\n if (!isFirstGroup) {\n rows.push({ type: \"gap\", key: `gap:${repo.shortName}:${sg.label}`, navId: null });\n }\n isFirstGroup = false;\n\n const subId = `sub:${repo.shortName}:${sg.label}`;\n const subCollapsed = isCollapsed(subId);\n rows.push({\n type: \"subHeader\",\n key: subId,\n navId: subId,\n text: sg.label,\n count: groupIssues.length,\n isCollapsed: subCollapsed,\n });\n if (!subCollapsed) {\n for (const issue of groupIssues) {\n rows.push({\n type: \"issue\",\n key: `gh:${repo.name}:${issue.number}`,\n navId: `gh:${repo.name}:${issue.number}`,\n issue,\n repoName: repo.name,\n });\n }\n }\n for (const s of sg.statuses) coveredStatuses.add(s);\n }\n\n // Any statuses not covered by groups (non-terminal) go at the end\n for (const [status, groupIssues] of byStatus) {\n if (\n !(coveredStatuses.has(status) || isTerminalStatus(status)) &&\n groupIssues.length > 0\n ) {\n if (!isFirstGroup) {\n rows.push({ type: \"gap\", key: `gap:${repo.shortName}:${status}`, navId: null });\n }\n isFirstGroup = false;\n const subId = `sub:${repo.shortName}:${status}`;\n const subCollapsed = isCollapsed(subId);\n rows.push({\n type: \"subHeader\",\n key: subId,\n navId: subId,\n text: status,\n count: groupIssues.length,\n isCollapsed: subCollapsed,\n });\n if (!subCollapsed) {\n for (const issue of groupIssues) {\n rows.push({\n type: \"issue\",\n key: `gh:${repo.name}:${issue.number}`,\n navId: `gh:${repo.name}:${issue.number}`,\n issue,\n repoName: repo.name,\n });\n }\n }\n }\n }\n }\n }\n }\n\n if (tasks.length > 0) {\n const collapsed = isCollapsed(\"ticktick\");\n rows.push({\n type: \"sectionHeader\",\n key: \"header:ticktick\",\n navId: \"header:ticktick\",\n label: \"Personal (TickTick)\",\n count: tasks.length,\n countLabel: \"tasks\",\n isCollapsed: collapsed,\n });\n if (!collapsed) {\n for (const task of tasks) {\n rows.push({ type: \"task\", key: `tt:${task.id}`, navId: `tt:${task.id}`, task });\n }\n }\n }\n\n return rows;\n}\n\nfunction 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\nfunction openInBrowser(url: string): void {\n try {\n execFileSync(\"open\", [url], { stdio: \"ignore\" });\n } catch {\n // Silently ignore\n }\n}\n\nfunction findSelectedUrl(repos: RepoData[], selectedId: string | null): 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) return issue.url;\n }\n }\n return null;\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\nfunction isHeaderId(id: string | null): boolean {\n return id != null && (id.startsWith(\"header:\") || id.startsWith(\"sub:\"));\n}\n\n// ── Row Renderer ──\n\ninterface RowRendererProps {\n readonly row: FlatRow;\n readonly selectedId: string | null;\n readonly selfLogin: string;\n readonly isMultiSelected?: boolean | undefined;\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: many row type variants\nfunction RowRenderer({ row, selectedId, selfLogin, isMultiSelected }: 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 <Text color=\"gray\"> {row.text}</Text>;\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 issue={row.issue} selfLogin={selfLogin} isSelected={selectedId === row.navId} />\n </Box>\n );\n }\n case \"task\": {\n const checkbox = isMultiSelected != null ? (isMultiSelected ? \"\\u2611 \" : \"\\u2610 \") : \"\";\n return (\n <Box>\n {checkbox ? <Text color={isMultiSelected ? \"cyan\" : \"gray\"}>{checkbox}</Text> : null}\n <TaskRow task={row.task} isSelected={selectedId === row.navId} />\n </Box>\n );\n }\n case \"activity\": {\n const ago = timeAgo(row.event.timestamp);\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\n// ── Dashboard ──\n\n// Header (1) + blank after header (0) + status bar (1) + padding (2 top+bottom)\nconst CHROME_ROWS = 4;\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 } = 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 allTasks = useMemo(\n () => (config.ticktick.enabled ? (data?.ticktick ?? []) : []),\n [data?.ticktick, config.ticktick.enabled],\n );\n const allActivity = useMemo(() => data?.activity ?? [], [data?.activity]);\n\n // UI state machine\n const ui = useUIState();\n\n // Search state (managed separately — search query persists across mode changes)\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n // Toast notification system (replaces old statusMessage)\n const { toasts, toast, handleErrorAction } = useToast();\n\n // Periodic tick to update refresh age display (every 10s)\n const [, setTick] = useState(0);\n useEffect(() => {\n const id = setInterval(() => setTick((t) => t + 1), 10_000);\n return () => clearInterval(id);\n }, []);\n\n // Filter by search query\n const repos = useMemo(() => {\n if (!searchQuery) return allRepos;\n const q = searchQuery.toLowerCase();\n return allRepos\n .map((rd) => ({ ...rd, issues: rd.issues.filter((i) => i.title.toLowerCase().includes(q)) }))\n .filter((rd) => rd.issues.length > 0);\n }, [allRepos, searchQuery]);\n\n const tasks = useMemo(() => {\n if (!searchQuery) return allTasks;\n const q = searchQuery.toLowerCase();\n return allTasks.filter((t) => t.title.toLowerCase().includes(q));\n }, [allTasks, searchQuery]);\n\n // Navigation\n const navItems = useMemo(\n () => buildNavItems(repos, tasks, allActivity.length),\n [repos, tasks, allActivity.length],\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 // Format: gh:owner/repo:number\n const parts = id.split(\":\");\n return parts.length >= 3 ? `${parts[1]}` : null;\n }\n if (id.startsWith(\"tt:\")) return \"ticktick\";\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 });\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 const handleCreateIssueWithPrompt = useCallback(\n (repo: string, title: string, labels?: string[]) => {\n actions.handleCreateIssue(repo, title, 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 } else if (id.startsWith(\"tt:\")) {\n const taskId = id.slice(3);\n const task = tasks.find((t) => t.id === taskId);\n if (task) label = task.title;\n }\n\n if (!label) return;\n setFocusLabel(label);\n ui.enterFocus();\n }, [nav.selectedId, repos, tasks, 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 // Timer restarts — just stay in focus mode (component remounts with key)\n toast.info(\"Focus restarted!\");\n setFocusLabel((prev) => prev); // no-op to preserve label\n // Force remount by toggling a counter\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 showDetailPanel = termSize.cols >= 120;\n const detailPanelWidth = showDetailPanel ? Math.floor(termSize.cols * 0.35) : 0;\n const overlayBarRows = ui.state.mode === \"search\" || ui.state.mode === \"overlay:comment\" ? 1 : 0;\n const toastRows = toasts.length;\n const viewportHeight = Math.max(5, termSize.rows - CHROME_ROWS - overlayBarRows - toastRows);\n\n // Build flat rows\n const flatRows = useMemo(\n () => buildFlatRows(repos, tasks, allActivity, nav.isCollapsed),\n [repos, tasks, allActivity, nav.isCollapsed],\n );\n\n // Scroll offset - tracks viewport position\n const scrollRef = useRef(0);\n const selectedRowIdx = flatRows.findIndex((r) => r.navId === nav.selectedId);\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 + viewportHeight) {\n scrollRef.current = selectedRowIdx - viewportHeight + 1;\n }\n }\n const maxOffset = Math.max(0, flatRows.length - viewportHeight);\n scrollRef.current = Math.max(0, Math.min(scrollRef.current, maxOffset));\n\n const visibleRows = flatRows.slice(scrollRef.current, scrollRef.current + viewportHeight);\n const hasMoreAbove = scrollRef.current > 0;\n const hasMoreBelow = scrollRef.current + viewportHeight < flatRows.length;\n const aboveCount = scrollRef.current;\n const belowCount = flatRows.length - scrollRef.current - viewportHeight;\n\n // Find selected item for detail panel and overlays\n const selectedItem = useMemo((): {\n issue: GitHubIssue | null;\n task: Task | null;\n repoName: string | null;\n } => {\n const id = nav.selectedId;\n if (!id || isHeaderId(id)) return { issue: null, task: 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)\n return { issue, task: null, repoName: rd.repo.name };\n }\n }\n }\n if (id.startsWith(\"tt:\")) {\n const taskId = id.slice(3);\n const task = tasks.find((t) => t.id === taskId);\n if (task) return { issue: null, task, repoName: null };\n }\n return { issue: null, task: null, repoName: null };\n }, [nav.selectedId, repos, tasks]);\n\n // Status options for the selected issue's repo (for status picker, single or bulk)\n const selectedRepoStatusOptions = useMemo(() => {\n // In multi-select, use the constrained repo\n const repoName = multiSelect.count > 0 ? multiSelect.constrainedRepo : selectedItem.repoName;\n if (!repoName || repoName === \"ticktick\") return [];\n const rd = repos.find((r) => r.repo.name === repoName);\n return rd?.statusOptions.filter((o) => !isTerminalStatus(o.name)) ?? [];\n }, [selectedItem.repoName, repos, multiSelect.count, multiSelect.constrainedRepo]);\n\n // Input handlers\n const handleOpen = useCallback(() => {\n const url = findSelectedUrl(repos, nav.selectedId);\n if (url) openInBrowser(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 // Multi-select selection type (for bulk action menu)\n const multiSelectType = useMemo((): \"github\" | \"ticktick\" | \"mixed\" => {\n let hasGh = false;\n let hasTt = false;\n for (const id of multiSelect.selected) {\n if (id.startsWith(\"gh:\")) hasGh = true;\n if (id.startsWith(\"tt:\")) hasTt = true;\n }\n if (hasGh && hasTt) return \"mixed\";\n if (hasTt) return \"ticktick\";\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 // Open status picker from bulk action menu — the reducer allows this transition\n ui.enterStatus();\n return; // status picker will call handleBulkStatusSelect on select\n case \"complete\":\n case \"delete\":\n toast.info(`Bulk ${action.type} not yet implemented for TickTick`);\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(); // close status picker\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 // Main input handler — active in normal mode (and multiSelect/focus for nav)\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 nav.moveDown();\n return;\n }\n if (input === \"k\" || key.upArrow) {\n nav.moveUp();\n return;\n }\n if (key.tab) {\n // Section jump clears selection (per spec: \"changing repo section\")\n if (ui.state.mode === \"multiSelect\") {\n multiSelect.clear();\n ui.clearMultiSelect();\n }\n key.shift ? nav.prevSection() : nav.nextSection();\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 && !isHeaderId(id)) {\n multiSelect.toggle(id);\n // If selection becomes empty, return to normal\n // (checked after toggle, so we need to check the new state)\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 status picker directly for bulk\n if (input === \"m\" && multiSelect.count > 0) {\n // We can't use the normal ENTER_STATUS transition from multiSelect,\n // so we'll go through bulk action menu. But for UX convenience, let's\n // handle it as a direct status picker.\n // Actually the reducer only allows overlay:status from normal mode.\n // Let's just open the bulk action menu instead.\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 // Actions (only in normal mode)\n if (ui.canAct) {\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 === \"s\") {\n handleSlack();\n return;\n }\n if (input === \"p\") {\n actions.handlePick();\n return;\n }\n if (input === \"a\") {\n actions.handleAssign();\n return;\n }\n if (input === \"u\") {\n actions.handleUnassign();\n return;\n }\n if (input === \"c\") {\n if (selectedItem.issue) {\n multiSelect.clear();\n ui.enterComment();\n }\n return;\n }\n if (input === \"m\") {\n if (selectedItem.issue && selectedRepoStatusOptions.length > 0) {\n multiSelect.clear();\n ui.enterStatus();\n } else if (selectedItem.issue) {\n toast.info(\"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\n // Space on an item: toggle selection + enter multiSelect mode\n if (input === \" \") {\n const id = nav.selectedId;\n if (id && !isHeaderId(id)) {\n multiSelect.toggle(id);\n ui.enterMultiSelect();\n } else if (isHeaderId(nav.selectedId)) {\n nav.toggleSection();\n }\n return;\n }\n\n if (key.return) {\n if (isHeaderId(nav.selectedId)) {\n nav.toggleSection();\n return;\n }\n handleOpen();\n return;\n }\n }\n },\n [\n ui,\n nav,\n exit,\n refresh,\n handleSlack,\n handleOpen,\n actions,\n selectedItem.issue,\n selectedRepoStatusOptions.length,\n toast,\n nav.selectedId,\n multiSelect,\n handleEnterFocus,\n handleErrorAction,\n ],\n );\n\n // Active when NOT in a text-input overlay\n const inputActive =\n ui.state.mode === \"normal\" || ui.state.mode === \"multiSelect\" || ui.state.mode === \"focus\";\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 ui.exitOverlay();\n setSearchQuery(\"\");\n }\n },\n [ui],\n );\n useInput(handleSearchEscape, { isActive: ui.state.mode === \"search\" });\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 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 ) : lastRefresh ? (\n <>\n <Text color={refreshAgeColor(lastRefresh)}>Updated {timeAgo(lastRefresh)}</Text>\n {consecutiveFailures > 0 ? <Text color=\"red\"> (!)</Text> : null}\n </>\n ) : null}\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 {/* Help overlay (stacks on top) */}\n {ui.state.helpVisible ? (\n <HelpOverlay currentMode={ui.state.mode} onClose={ui.toggleHelp} />\n ) : null}\n\n {/* Status picker overlay */}\n {ui.state.mode === \"overlay:status\" && selectedRepoStatusOptions.length > 0 ? (\n <StatusPicker\n options={selectedRepoStatusOptions}\n currentStatus={multiSelect.count > 0 ? undefined : selectedItem.issue?.projectStatus}\n onSelect={multiSelect.count > 0 ? handleBulkStatusSelect : actions.handleStatusChange}\n onCancel={ui.exitOverlay}\n />\n ) : null}\n\n {/* Create issue form overlay */}\n {ui.state.mode === \"overlay:create\" ? (\n <CreateIssueForm\n repos={config.repos}\n defaultRepo={selectedItem.repoName}\n onSubmit={handleCreateIssueWithPrompt}\n onCancel={ui.exitOverlay}\n />\n ) : null}\n\n {/* Confirm pick prompt (after issue create) */}\n {ui.state.mode === \"overlay:confirmPick\" ? (\n <ConfirmPrompt\n message=\"Pick this issue?\"\n onConfirm={handleConfirmPick}\n onCancel={handleCancelPick}\n />\n ) : null}\n\n {/* Bulk action menu overlay */}\n {ui.state.mode === \"overlay:bulkAction\" ? (\n <BulkActionMenu\n count={multiSelect.count}\n selectionType={multiSelectType}\n onSelect={handleBulkAction}\n onCancel={ui.exitOverlay}\n />\n ) : null}\n\n {/* Focus mode overlay */}\n {ui.state.mode === \"focus\" && focusLabel ? (\n <FocusMode\n key={focusKey}\n label={focusLabel}\n durationSec={config.board.focusDuration ?? 1500}\n onExit={handleFocusExit}\n onEndAction={handleFocusEndAction}\n />\n ) : null}\n\n {/* Main content: scrollable list + optional detail panel (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:bulkAction\" &&\n ui.state.mode !== \"overlay:confirmPick\" &&\n ui.state.mode !== \"focus\" ? (\n <Box height={viewportHeight}>\n {/* Scrollable list */}\n <Box flexDirection=\"column\" flexGrow={1}>\n {hasMoreAbove ? (\n <Text color=\"gray\" dimColor>\n {\" \"}\n {\"\\u25B2\"} {aboveCount} more above\n </Text>\n ) : null}\n\n {visibleRows.map((row) => (\n <RowRenderer\n key={row.key}\n row={row}\n selectedId={nav.selectedId}\n selfLogin={config.board.assignee}\n isMultiSelected={\n ui.state.mode === \"multiSelect\" && row.navId\n ? multiSelect.isSelected(row.navId)\n : undefined\n }\n />\n ))}\n\n {hasMoreBelow ? (\n <Text color=\"gray\" dimColor>\n {\" \"}\n {\"\\u25BC\"} {belowCount} more below\n </Text>\n ) : null}\n </Box>\n\n {/* Detail panel */}\n {showDetailPanel ? (\n <Box marginLeft={1} width={detailPanelWidth}>\n <DetailPanel\n issue={selectedItem.issue}\n task={selectedItem.task}\n width={detailPanelWidth}\n />\n </Box>\n ) : null}\n </Box>\n ) : null}\n\n {/* Search bar */}\n {ui.state.mode === \"search\" ? (\n <SearchBar defaultValue={searchQuery} onChange={setSearchQuery} onSubmit={ui.exitOverlay} />\n ) : null}\n\n {/* Comment input */}\n {ui.state.mode === \"overlay:comment\" && selectedItem.issue ? (\n <CommentInput\n issueNumber={selectedItem.issue.number}\n onSubmit={actions.handleComment}\n onCancel={ui.exitOverlay}\n />\n ) : null}\n\n {/* Toast notifications */}\n <ToastContainer toasts={toasts} />\n\n {/* Status bar */}\n <Box>\n {ui.state.mode === \"multiSelect\" ? (\n <>\n <Text color=\"cyan\" bold>\n {multiSelect.count} selected\n </Text>\n <Text color=\"gray\"> Space:toggle Enter:actions Esc:cancel</Text>\n </>\n ) : ui.state.mode === \"focus\" ? (\n <Text color=\"magenta\" bold>\n Focus mode — Esc to exit\n </Text>\n ) : (\n <>\n <Text color=\"gray\">\n j/k:nav Tab:section Enter:open Space:select /:search p:pick c:comment m:status\n a/u:assign s:slack n:new f:focus ?:help q:quit\n </Text>\n {searchQuery && ui.state.mode !== \"search\" ? (\n <Text color=\"yellow\"> filter: "{searchQuery}"</Text>\n ) : null}\n </>\n )}\n </Box>\n </Box>\n );\n}\n\nexport { Dashboard };\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\";\n\nexport async function runLiveDashboard(\n config: HogConfig,\n options: FetchOptions,\n activeProfile?: string | null,\n): Promise<void> {\n const { waitUntilExit } = render(\n <Dashboard config={config} options={options} activeProfile={activeProfile ?? null} />,\n );\n\n await 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\";\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\nfunction formatError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\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 statusOptions: StatusOption[] = [];\n try {\n const enrichMap = fetchProjectEnrichment(repo.name, repo.projectNumber);\n for (const issue of issues) {\n const e = enrichMap.get(issue.number);\n if (e?.targetDate) issue.targetDate = e.targetDate;\n if (e?.projectStatus) issue.projectStatus = e.projectStatus;\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 }\n\n // Compute Slack thread URLs from issue bodies\n for (const issue of issues) {\n const slackUrl = extractSlackUrl(issue.body);\n if (slackUrl) issue.slackThreadUrl = slackUrl;\n }\n\n return { repo, issues, 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 })),\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 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 { Command } from \"commander\";\nimport { TickTickClient } from \"./api.js\";\nimport type { CompletionAction, RepoConfig } from \"./config.js\";\nimport {\n findRepo,\n getConfig,\n loadFullConfig,\n requireAuth,\n resolveProfile,\n saveConfig,\n saveFullConfig,\n validateRepoName,\n} from \"./config.js\";\nimport { runInit } from \"./init.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\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\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 console.error(`Invalid priority: ${value}. Use: none, low, medium, high`);\n process.exit(1);\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.2.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}`, {\n task: created as unknown as Record<string, unknown>,\n });\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}`, {\n task: updated as unknown as Record<string, unknown>,\n });\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 (owner/repo format)\")\n .requiredOption(\"--project-number <n>\", \"GitHub project number\")\n .requiredOption(\"--status-field-id <id>\", \"Project status field ID\")\n .requiredOption(\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((name: string, opts: ConfigAddRepoOptions) => {\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 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(\"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// -- 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 { CONFIG_DIR, loadFullConfig, saveFullConfig } 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\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 // 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 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: 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","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>): 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 type { HogConfig, RepoConfig } from \"./config.js\";\nimport { loadFullConfig, requireAuth } from \"./config.js\";\nimport type { GitHubIssue } from \"./github.js\";\nimport {\n addLabel,\n fetchAssignedIssues,\n fetchProjectFields,\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 formatError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\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 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);\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): 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 projectFields = fetchProjectFields(\n repoConfig.name,\n issue.number,\n repoConfig.projectNumber,\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":["text","input","config","execFileSync","existsSync","readFileSync","writeFileSync","homedir","join","CONFIG_DIR","input","config","repoShortName","mapPriority","task","execFile","promisify","config","execFileAsync","useCallback","useRef","config","useCallback","useRef","useState","useCallback","useRef","select","useCallback","useRef","useState","useCallback","useReducer","INITIAL_STATE","useState","input","Box","Text","useInput","useState","jsx","jsxs","Box","Text","useInput","jsx","jsxs","input","TextInput","Box","Text","useInput","useState","jsx","jsxs","input","Box","Text","jsx","jsxs","task","PRIORITY_LABELS","Box","Text","useInput","useCallback","useEffect","useRef","useState","jsx","jsxs","input","Box","Text","useInput","jsx","jsxs","Box","Text","Fragment","jsx","jsxs","TextInput","Box","Text","jsx","jsxs","Box","Text","useInput","useState","jsx","jsxs","input","Box","Text","jsx","jsxs","truncate","task","Box","Text","Fragment","jsx","jsxs","execFileSync","Spinner","Box","Text","useInput","useCallback","useEffect","useMemo","useRef","useState","Fragment","jsx","jsxs","TERMINAL_STATUS_RE","task","timeAgo","checkbox","config","pickIssue","input","jsx","config","SLACK_URL_RE","execFileSync","formatError","config","truncate","task","printSection","existsSync","config","task","input","config","task","config","input","runLiveDashboard","fetchDashboard","renderBoardJson","renderStaticBoard","parseIssueRef","pickIssue"]}
|
|
1
|
+
{"version":3,"sources":["../src/ai.ts","../src/api.ts","../src/config.ts","../src/types.ts","../src/github.ts","../src/sync-state.ts","../src/clipboard.ts","../src/pick.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-toast.ts","../src/board/hooks/use-ui-state.ts","../src/board/components/detail-panel.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/focus-mode.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/issue-row.tsx","../src/board/components/task-row.tsx","../src/board/components/row-renderer.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":["/**\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 */\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 return null;\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 // 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 : llmResult.labels,\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> {\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 undefined as T;\n return JSON.parse(text) as T;\n }\n\n async listProjects(): Promise<Project[]> {\n return this.request<Project[]>(\"GET\", \"/project\");\n }\n\n async getProject(projectId: string): Promise<Project> {\n return this.request<Project>(\"GET\", `/project/${projectId}`);\n }\n\n async getProjectData(projectId: string): Promise<ProjectData> {\n return this.request<ProjectData>(\"GET\", `/project/${projectId}/data`);\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 return this.request<Task>(\"GET\", `/project/${projectId}/task/${taskId}`);\n }\n\n async createTask(input: CreateTaskInput): Promise<Task> {\n return this.request<Task>(\"POST\", \"/task\", input);\n }\n\n async updateTask(input: UpdateTaskInput): Promise<Task> {\n return this.request<Task>(\"POST\", `/task/${input.id}`, input);\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 { 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}\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 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// ── Legacy Repo Defaults (for migration) ──\n\nconst LEGACY_REPOS: RepoConfig[] = [];\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: LEGACY_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 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}\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","// ── 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","import { execFile, execFileSync } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface GitHubIssue {\n number: number;\n title: string;\n url: string;\n state: string;\n updatedAt: string;\n labels: { name: string }[];\n assignees?: { login: string }[];\n targetDate?: string;\n body?: string;\n projectStatus?: string;\n slackThreadUrl?: string;\n}\n\nexport interface ProjectFieldValues {\n targetDate?: string;\n status?: string;\n}\n\nexport interface RepoProjectConfig {\n projectNumber: number;\n statusFieldId: string;\n optionId: string;\n}\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 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 }\n }\n }\n }\n }\n }\n }\n `;\n\n const [owner, repoName] = repo.split(\"/\");\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 if (\"date\" in fv && fv.field?.name === \"Target date\") {\n fields.targetDate = fv.date;\n }\n if (\"name\" in fv && fv.field?.name === \"Status\") {\n fields.status = fv.name;\n }\n }\n\n return fields;\n } catch {\n return {};\n }\n}\n\nexport interface ProjectEnrichment {\n targetDate?: string;\n projectStatus?: 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 */\nexport function fetchProjectEnrichment(\n repo: string,\n projectNumber: number,\n): Map<number, ProjectEnrichment> {\n const [owner] = repo.split(\"/\");\n\n const query = `\n query($owner: String!, $projectNumber: Int!) {\n organization(login: $owner) {\n projectV2(number: $projectNumber) {\n items(first: 100) {\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 }\n }\n }\n }\n }\n }\n }\n `;\n\n try {\n const result = runGhJson<ProjectItemsResult>([\n \"api\",\n \"graphql\",\n \"-f\",\n `query=${query}`,\n \"-F\",\n `owner=${owner}`,\n \"-F\",\n `projectNumber=${String(projectNumber)}`,\n ]);\n\n const items = result?.data?.organization?.projectV2?.items?.nodes ?? [];\n const enrichMap = new Map<number, ProjectEnrichment>();\n\n for (const item of items) {\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 if (\"date\" in fv && fv.field?.name === \"Target date\" && fv.date) {\n enrichment.targetDate = fv.date;\n }\n if (\"name\" in fv && fv.field?.name === \"Status\" && fv.name) {\n enrichment.projectStatus = fv.name;\n }\n }\n enrichMap.set(item.content.number, enrichment);\n }\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\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\nexport function updateProjectItemStatus(\n repo: string,\n issueNumber: number,\n projectConfig: RepoProjectConfig,\n): void {\n const [owner, repoName] = repo.split(\"/\");\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\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 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;\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\n// Internal GraphQL response types\n\ninterface FieldValue {\n field?: { name?: string };\n date?: string;\n name?: string;\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 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`);\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","/**\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 { 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","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { useCallback, useRef } from \"react\";\nimport type { HogConfig, RepoConfig } from \"../../config.js\";\nimport type { GitHubIssue, RepoProjectConfig, StatusOption } from \"../../github.js\";\nimport { assignIssueAsync, updateProjectItemStatusAsync } from \"../../github.js\";\nimport { pickIssue } from \"../../pick.js\";\nimport type { DashboardData, RepoData } from \"../fetch.js\";\nimport type { ToastAPI } from \"./use-toast.js\";\n\nconst execFileAsync = promisify(execFile);\n\nconst TERMINAL_STATUS_RE = /^(done|shipped|won't|wont|closed|complete|completed)$/i;\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 handleUnassign: () => void;\n handleLabelChange: (addLabels: string[], removeLabels: string[]) => void;\n handleCreateIssue: (\n repo: string,\n title: string,\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: () => void;\n onOverlayDone: () => 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 execFileAsync(\"gh\", [\"issue\", \"close\", String(issueNumber), \"--repo\", repoName], {\n encoding: \"utf-8\",\n timeout: 30_000,\n });\n break;\n case \"addLabel\":\n await execFileAsync(\n \"gh\",\n [\"issue\", \"edit\", String(issueNumber), \"--repo\", repoName, \"--add-label\", action.label],\n { encoding: \"utf-8\", timeout: 30_000 },\n );\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/** 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}: 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 configRef.current = config;\n reposRef.current = repos;\n selectedIdRef.current = selectedId;\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 execFileAsync(\n \"gh\",\n [\"issue\", \"comment\", String(issue.number), \"--repo\", repoName, \"--body\", body],\n { encoding: \"utf-8\", timeout: 30_000 },\n )\n .then(() => {\n t.resolve(`Comment posted on #${issue.number}`);\n refresh();\n })\n .catch((err) => {\n t.reject(`Comment failed: ${err instanceof Error ? err.message : String(err)}`);\n })\n .finally(() => {\n onOverlayDone();\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 // Optimistic update: move issue to new section immediately\n mutateData((data) =>\n optimisticSetStatus(data, repoName, issue.number, statusOptions, optionId),\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 refresh();\n })\n .catch((err) => {\n t.reject(`Status change failed: ${err instanceof Error ? err.message : String(err)}`);\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 refresh();\n })\n .catch((err) => {\n t.reject(`Assign failed: ${err instanceof Error ? err.message : String(err)}`);\n });\n }, [toast, refresh]);\n\n const handleUnassign = 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 const selfAssigned = assignees.some((a) => a.login === configRef.current.board.assignee);\n\n if (!selfAssigned) {\n const firstAssignee = assignees[0];\n if (firstAssignee) {\n toast.info(`Assigned to @${firstAssignee.login} \\u2014 can only unassign self`);\n } else {\n toast.info(\"Not assigned\");\n }\n return;\n }\n\n const t = toast.loading(\"Unassigning...\");\n execFileAsync(\n \"gh\",\n [\"issue\", \"edit\", String(issue.number), \"--repo\", repoName, \"--remove-assignee\", \"@me\"],\n { encoding: \"utf-8\", timeout: 30_000 },\n )\n .then(() => {\n t.resolve(`Unassigned #${issue.number} from @${configRef.current.board.assignee}`);\n refresh();\n })\n .catch((err) => {\n t.reject(`Unassign failed: ${err instanceof Error ? err.message : String(err)}`);\n });\n }, [toast, refresh]);\n\n const handleCreateIssue = useCallback(\n async (\n repo: string,\n title: string,\n labels?: string[],\n ): Promise<{ repo: string; issueNumber: number } | null> => {\n const args = [\"issue\", \"create\", \"--repo\", repo, \"--title\", title];\n if (labels && labels.length > 0) {\n for (const label of labels) {\n args.push(\"--label\", label);\n }\n }\n const t = toast.loading(\"Creating...\");\n try {\n const { stdout } = await execFileAsync(\"gh\", args, { encoding: \"utf-8\", timeout: 30_000 });\n const output = stdout.trim();\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 = configRef.current.repos.find((r) => r.name === repo)?.shortName ?? repo;\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 args = [\"issue\", \"edit\", String(issue.number), \"--repo\", repoName];\n for (const label of addLabels) args.push(\"--add-label\", label);\n for (const label of removeLabels) args.push(\"--remove-label\", label);\n\n const t = toast.loading(\"Updating labels...\");\n execFileAsync(\"gh\", args, { encoding: \"utf-8\", timeout: 30_000 })\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 execFileAsync(\n \"gh\",\n [\n \"issue\",\n \"edit\",\n String(ctx.issue.number),\n \"--repo\",\n ctx.repoName,\n \"--remove-assignee\",\n \"@me\",\n ],\n { encoding: \"utf-8\", timeout: 30_000 },\n );\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\n for (const id of ids) {\n const ctx = findIssueContext(reposRef.current, id, configRef.current);\n if (ctx.issue && ctx.repoName) {\n const { issue: ctxIssue, repoName: ctxRepo, statusOptions: ctxOpts } = ctx;\n mutateData((data) =>\n optimisticSetStatus(data, ctxRepo, ctxIssue.number, ctxOpts, optionId),\n );\n }\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 = (() => {\n for (const id of ids) {\n const ctx = findIssueContext(reposRef.current, id, configRef.current);\n const name = ctx.statusOptions.find((o) => o.id === optionId)?.name;\n if (name) return name;\n }\n return optionId;\n })();\n if (failed.length === 0) {\n t.resolve(`Moved ${total} issue${total > 1 ? \"s\" : \"\"} to ${optionName}`);\n } else {\n t.reject(`${ok} moved to ${optionName}, ${failed.length} failed`);\n }\n refresh();\n return failed;\n },\n [toast, refresh, mutateData],\n );\n\n return {\n handlePick,\n handleComment,\n handleStatusChange,\n handleAssign,\n handleUnassign,\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\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\nexport function useData(\n config: HogConfig,\n options: FetchOptions,\n refreshIntervalMs: number,\n): DataState & {\n refresh: () => void;\n mutateData: (fn: (data: DashboardData) => DashboardData) => void;\n pauseAutoRefresh: () => void;\n resumeAutoRefresh: () => void;\n} {\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\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 const refresh = useCallback(() => {\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 setState((prev) => ({ ...prev, isRefreshing: true }));\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\", (msg: { type: string; data?: DashboardData; error?: string }) => {\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 data = msg.data;\n data.fetchedAt = new Date(data.fetchedAt);\n for (const ev of data.activity) {\n ev.timestamp = new Date(ev.timestamp);\n }\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 {\n setState((prev) => {\n const failures = prev.consecutiveFailures + 1;\n return {\n ...prev,\n status: prev.data ? \"success\" : \"error\",\n error: msg.error ?? \"Unknown 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();\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 return { ...state, refresh, mutateData, pauseAutoRefresh, resumeAutoRefresh };\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 { 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 handleUnassign: () => void;\n handleEnterLabel: () => void;\n handleEnterCreateNl: () => void;\n handleErrorAction: (action: \"dismiss\" | \"retry\") => boolean;\n toastInfo: (msg: string) => void;\n}\n\ninterface UseKeyboardOptions {\n ui: UseUIStateResult;\n nav: Pick<\n UseNavigationResult,\n | \"moveUp\"\n | \"moveDown\"\n | \"prevSection\"\n | \"nextSection\"\n | \"toggleSection\"\n | \"collapseAll\"\n | \"selectedId\"\n >;\n multiSelect: Pick<UseMultiSelectResult, \"count\" | \"toggle\" | \"clear\">;\n selectedIssue: GitHubIssue | null;\n selectedRepoStatusOptionsLength: number;\n actions: KeyboardActions;\n onSearchEscape: () => void;\n}\n\nfunction isHeaderId(id: string | null): boolean {\n return id != null && (id.startsWith(\"header:\") || id.startsWith(\"sub:\"));\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}: UseKeyboardOptions): void {\n const {\n exit,\n refresh,\n handleSlack,\n handleCopyLink,\n handleOpen,\n handleEnterFocus,\n handlePick,\n handleAssign,\n handleUnassign,\n handleEnterLabel,\n handleEnterCreateNl,\n handleErrorAction,\n toastInfo,\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 nav.moveDown();\n return;\n }\n if (input === \"k\" || key.upArrow) {\n nav.moveUp();\n return;\n }\n if (key.tab) {\n // Section jump clears selection (per spec: \"changing repo section\")\n if (ui.state.mode === \"multiSelect\") {\n multiSelect.clear();\n ui.clearMultiSelect();\n }\n key.shift ? nav.prevSection() : nav.nextSection();\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 && !isHeaderId(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 // Actions (only in normal mode)\n if (ui.canAct) {\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 === \"s\") {\n handleSlack();\n return;\n }\n if (input === \"y\") {\n handleCopyLink();\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 handleUnassign();\n return;\n }\n if (input === \"c\") {\n if (selectedIssue) {\n multiSelect.clear();\n ui.enterComment();\n }\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 === \"C\") {\n nav.collapseAll();\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\n // Space on an item: toggle selection + enter multiSelect mode\n if (input === \" \") {\n const id = nav.selectedId;\n if (id && !isHeaderId(id)) {\n multiSelect.toggle(id);\n ui.enterMultiSelect();\n } else if (isHeaderId(nav.selectedId)) {\n nav.toggleSection();\n }\n return;\n }\n\n if (key.return) {\n if (isHeaderId(nav.selectedId)) {\n nav.toggleSection();\n return;\n }\n handleOpen();\n return;\n }\n }\n },\n [\n ui,\n nav,\n exit,\n refresh,\n handleSlack,\n handleCopyLink,\n handleOpen,\n handlePick,\n handleAssign,\n handleUnassign,\n handleEnterLabel,\n handleEnterCreateNl,\n selectedIssue,\n selectedRepoStatusOptionsLength,\n toastInfo,\n nav.selectedId,\n multiSelect,\n handleEnterFocus,\n handleErrorAction,\n ],\n );\n\n // Active when NOT in a text-input overlay\n const inputActive =\n ui.state.mode === \"normal\" || ui.state.mode === \"multiSelect\" || ui.state.mode === \"focus\";\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}\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\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\n const collapsedSections = isFirstLoad\n ? new Set(sections.filter((s) => s === \"activity\"))\n : state.collapsedSections;\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 if (!isFirstLoad && selectionValid && arraysEqual(sections, state.sections)) {\n return state;\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 };\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 };\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 if (next.has(action.section)) {\n next.delete(action.section);\n } else {\n next.add(action.section);\n }\n return { ...state, collapsedSections: next };\n }\n case \"COLLAPSE_ALL\": {\n return { ...state, collapsedSections: new Set(state.sections) };\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 });\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 // 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, 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: (id: string) => void;\n dismissAll: () => void;\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 dismiss = useCallback(\n (id: string) => {\n removeToast(id);\n },\n [removeToast],\n );\n\n const dismissAll = useCallback(() => {\n for (const timer of timersRef.current.values()) {\n clearTimeout(timer);\n }\n timersRef.current.clear();\n setToasts([]);\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, dismiss, dismissAll, 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 | \"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: \"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 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\") return state;\n return { ...state, mode: \"overlay:comment\", previousMode: \"normal\" };\n\n case \"ENTER_STATUS\":\n if (state.mode !== \"normal\" && state.mode !== \"overlay:bulkAction\") return state;\n return {\n ...state,\n mode: \"overlay:status\",\n previousMode: state.mode === \"overlay:bulkAction\" ? \"multiSelect\" : \"normal\",\n };\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 \"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 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 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 type { GitHubIssue } from \"../../github.js\";\nimport type { Task } from \"../../types.js\";\nimport { Priority } from \"../../types.js\";\n\ninterface DetailPanelProps {\n readonly issue: GitHubIssue | null;\n readonly task: Task | null;\n readonly width: number;\n}\n\nfunction truncateLines(text: string, maxLines: number): string {\n const lines = text.split(\"\\n\").slice(0, maxLines);\n return lines.join(\"\\n\");\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\nconst PRIORITY_LABELS: Record<number, string> = {\n [Priority.High]: \"High\",\n [Priority.Medium]: \"Medium\",\n [Priority.Low]: \"Low\",\n [Priority.None]: \"None\",\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\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: conditional rendering for issue vs task\nfunction DetailPanel({ issue, task, width }: DetailPanelProps) {\n if (!(issue || task)) {\n return (\n <Box\n width={width}\n borderStyle=\"single\"\n borderColor=\"gray\"\n flexDirection=\"column\"\n paddingX={1}\n >\n <Text color=\"gray\">No item selected</Text>\n </Box>\n );\n }\n\n if (issue) {\n return (\n <Box\n width={width}\n borderStyle=\"single\"\n borderColor=\"cyan\"\n flexDirection=\"column\"\n paddingX={1}\n >\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 <Text>{\"\"}</Text>\n <Text color=\"gray\" dimColor>\n {issue.url}\n </Text>\n </Box>\n );\n }\n\n // TickTick task — task is guaranteed non-null here (early return above covers null case)\n const t = task as Task;\n return (\n <Box\n width={width}\n borderStyle=\"single\"\n borderColor=\"yellow\"\n flexDirection=\"column\"\n paddingX={1}\n >\n <Text color=\"yellow\" bold>\n {t.title}\n </Text>\n <Text>{\"\"}</Text>\n\n <Box>\n <Text color=\"gray\">Priority: </Text>\n <Text>{PRIORITY_LABELS[t.priority] ?? \"None\"}</Text>\n </Box>\n\n {t.dueDate ? (\n <Box>\n <Text color=\"gray\">Due: </Text>\n <Text>{new Date(t.dueDate).toLocaleDateString()}</Text>\n </Box>\n ) : null}\n\n {(t.tags ?? []).length > 0 ? (\n <Box>\n <Text color=\"gray\">Tags: </Text>\n <Text>{t.tags.join(\", \")}</Text>\n </Box>\n ) : null}\n\n {t.content ? (\n <>\n <Text>{\"\"}</Text>\n <Text>{truncateLines(t.content, 8)}</Text>\n </>\n ) : null}\n\n {(t.items ?? []).length > 0 ? (\n <>\n <Text>{\"\"}</Text>\n <Text color=\"gray\">Checklist:</Text>\n {t.items.slice(0, 5).map((item) => (\n <Text key={item.id}>\n {item.status === 2 ? \"\\u2611\" : \"\\u2610\"} {item.title}\n </Text>\n ))}\n {t.items.length > 5 ? <Text color=\"gray\">...and {t.items.length - 5} more</Text> : null}\n </>\n ) : null}\n </Box>\n );\n}\n\nexport { DetailPanel };\nexport type { DetailPanelProps };\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 _instance: Instance | null = null;\n\n/** Store the Ink render instance for use in editor integration ($EDITOR launch). */\nexport function setInkInstance(instance: Instance): void {\n _instance = instance;\n}\n\nexport function getInkInstance(): Instance | null {\n return _instance;\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 (tmpFile) {\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: (repo: string, title: string, labels?: string[]) => 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(selectedRepo.name, title, addLabels.length > 0 ? addLabels : undefined);\n }}\n onCancel={() => {\n // Esc skips labels and submits without them\n onSubmit(selectedRepo.name, title);\n }}\n onError={() => {\n // On fetch error, skip labels and submit\n onSubmit(selectedRepo.name, title);\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);\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 { 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 { 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 section\" },\n { key: \"Shift+Tab\", desc: \"Previous section\" },\n ],\n },\n {\n category: \"View\",\n items: [\n { key: \"Enter\", desc: \"Toggle section / Open in browser\" },\n { key: \"Space\", desc: \"Toggle section / Multi-select\" },\n { key: \"/\", desc: \"Search\" },\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\" },\n { key: \"u\", desc: \"Unassign self\" },\n { key: \"c\", desc: \"Comment on issue\" },\n { key: \"m\", desc: \"Move status\" },\n { key: \"s\", desc: \"Open Slack thread\" },\n { key: \"y\", desc: \"Copy issue link to clipboard\" },\n { key: \"n\", desc: \"Create new issue\" },\n ],\n },\n {\n category: \"Board\",\n items: [\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 { Spinner, TextInput } from \"@inkjs/ui\";\nimport { Box, Text, useInput } 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\";\n\ninterface NlCreateOverlayProps {\n readonly repos: RepoConfig[];\n readonly defaultRepoName: string | null;\n readonly labelCache: Record<string, LabelOption[]>;\n readonly onSubmit: (repo: string, title: string, labels?: string[]) => void;\n readonly onCancel: () => void;\n readonly onLlmFallback?: ((msg: string) => void) | undefined;\n}\n\nfunction NlCreateOverlay({\n repos,\n defaultRepoName,\n labelCache,\n onSubmit,\n onCancel,\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 [createError, setCreateError] = useState<string | null>(null);\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 // 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\n const selectedRepo = repos[repoIdx];\n\n useInput((inputChar, key) => {\n if (isParsing) return;\n\n if (key.escape) {\n onCancel();\n return;\n }\n\n // Preview mode controls\n if (parsed) {\n if (key.return) {\n if (submittedRef.current) return;\n submittedRef.current = true;\n if (!selectedRepo) return;\n\n setCreateError(null);\n const labels = buildLabelList(parsed);\n onSubmit(selectedRepo.name, parsed.title, labels.length > 0 ? labels : undefined);\n return;\n }\n\n if (inputChar === \"r\") {\n setRepoIdx((i) => (i + 1) % repos.length);\n return;\n }\n }\n });\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 // Filter labels against allowlist (prevents invalid gh --label calls)\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 // ── Preview view ──\n if (parsed) {\n const labels = buildLabelList(parsed);\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 {parsed.dueDate && selectedRepo && !hasDueLabelInCache(labelCache, selectedRepo.name) ? (\n <Text color=\"yellow\">\n ⚠ No due:* label in this repo — will try to create label on submit\n </Text>\n ) : null}\n {createError ? <Text color=\"red\">{createError}</Text> : null}\n <Text dimColor>Enter:create 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\">> </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 <date> Enter:parse Esc:cancel</Text>\n </Box>\n );\n}\n\n/** Build the final label list including a due:{date} label if present. */\nfunction buildLabelList(parsed: ParsedIssue): string[] {\n const labels = [...parsed.labels];\n if (parsed.dueDate) {\n labels.push(`due:${parsed.dueDate}`);\n }\n return labels;\n}\n\n/** Check whether any due:* label exists in the cache for the given repo. */\nfunction hasDueLabelInCache(labelCache: Record<string, LabelOption[]>, repoName: string): boolean {\n return (labelCache[repoName] ?? []).some((l) => l.name.startsWith(\"due:\"));\n}\n\n/** Format YYYY-MM-DD as \"Wed Feb 18 (label: due:2026-02-18)\". */\nfunction formatDue(dueDate: string): string {\n const d = new Date(`${dueDate}T12:00:00`);\n const human = d.toLocaleDateString(\"en-US\", { weekday: \"short\", month: \"short\", day: \"numeric\" });\n return `${human} (label: due:${dueDate})`;\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=\"search...\"\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\";\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\nconst TERMINAL_STATUS_RE = /^(done|shipped|won't|wont|closed|complete|completed)$/i;\n\nfunction isTerminal(name: string): boolean {\n return TERMINAL_STATUS_RE.test(name);\n}\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 // Inline confirm for terminal status with closeIssue completion action\n const [confirmingTerminal, setConfirmingTerminal] = useState(false);\n // Guard against Enter key repeat\n const submittedRef = useRef(false);\n\n useInput((input, key) => {\n if (confirmingTerminal) {\n if (input === \"y\" || input === \"Y\") {\n if (submittedRef.current) return;\n submittedRef.current = true;\n const opt = options[selectedIdx];\n if (opt) onSelect(opt.id);\n return;\n }\n if (input === \"n\" || input === \"N\" || key.escape) {\n setConfirmingTerminal(false);\n return;\n }\n return;\n }\n\n if (key.escape) return onCancel();\n if (key.return) {\n if (submittedRef.current) return;\n const opt = options[selectedIdx];\n if (!opt) return;\n if (isTerminal(opt.name) && showTerminalStatuses) {\n // Show inline confirm before executing\n setConfirmingTerminal(true);\n return;\n }\n submittedRef.current = true;\n onSelect(opt.id);\n return;\n }\n if (input === \"j\" || key.downArrow) {\n setSelectedIdx((i) => Math.min(i + 1, options.length - 1));\n }\n if (input === \"k\" || key.upArrow) {\n setSelectedIdx((i) => Math.max(i - 1, 0));\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 } from \"../../config.js\";\nimport type { GitHubIssue, LabelOption, StatusOption } from \"../../github.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 type { FocusEndAction } from \"./focus-mode.js\";\nimport { FocusMode } from \"./focus-mode.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 // 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: (repo: string, title: string, labels?: string[]) => 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}\n\n/** Renders whichever overlay is active based on uiMode. */\nfunction OverlayRenderer({\n uiState,\n config,\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}: 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 {/* 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 onLlmFallback={onLlmFallback}\n />\n ) : null}\n </>\n );\n}\n\nexport { OverlayRenderer };\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}\n\nfunction truncate(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, max - 1)}\\u2026` : s;\n}\n\nfunction formatTargetDate(dateStr: string | undefined): { text: string; color: string } {\n if (!dateStr) return { text: \"\", color: \"gray\" };\n const d = new Date(dateStr);\n const days = Math.ceil((d.getTime() - Date.now()) / 86_400_000);\n\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\nfunction timeAgo(dateStr: string): string {\n const seconds = Math.floor((Date.now() - new Date(dateStr).getTime()) / 1000);\n if (seconds < 60) return \"now\";\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h`;\n const days = Math.floor(hours / 24);\n if (days < 30) return `${days}d`;\n const months = Math.floor(days / 30);\n return `${months}mo`;\n}\n\nconst LABEL_COLORS: Record<string, string> = {\n bug: \"red\",\n enhancement: \"green\",\n feature: \"green\",\n documentation: \"blue\",\n \"good first issue\": \"magenta\",\n help: \"yellow\",\n question: \"yellow\",\n urgent: \"red\",\n wontfix: \"gray\",\n};\n\nfunction labelColor(name: string): string {\n return LABEL_COLORS[name.toLowerCase()] ?? \"cyan\";\n}\n\nconst LABEL_COL_WIDTH = 30;\n\nfunction IssueRow({ issue, selfLogin, isSelected }: 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(\", \"), 14);\n const labels = (issue.labels ?? []).slice(0, 2);\n const target = formatTargetDate(issue.targetDate);\n const titleStr = truncate(issue.title, 42).padEnd(42);\n\n return (\n <Box>\n {isSelected ? (\n <Text color=\"cyan\" bold>\n {\"\\u25B6 \"}\n </Text>\n ) : (\n <Text>{\" \"}</Text>\n )}\n <Text color=\"cyan\">#{String(issue.number).padEnd(5)}</Text>\n <Text> </Text>\n {isSelected ? (\n <Text color=\"white\" bold>\n {titleStr}\n </Text>\n ) : (\n <Text>{titleStr}</Text>\n )}\n <Text> </Text>\n <Box width={LABEL_COL_WIDTH}>\n {labels.map((l, i) => (\n <Text key={l.name}>\n {i > 0 ? \" \" : \"\"}\n <Text color={labelColor(l.name)}>[{truncate(l.name, 12)}]</Text>\n </Text>\n ))}\n </Box>\n <Text> </Text>\n <Text color={assigneeColor}>{assigneeText.padEnd(14)}</Text>\n <Text> </Text>\n <Text color=\"gray\">{timeAgo(issue.updatedAt).padStart(4)}</Text>\n {target.text ? (\n <>\n <Text> </Text>\n <Text color={target.color}>{target.text}</Text>\n </>\n ) : null}\n </Box>\n );\n}\n\nexport { IssueRow };\nexport type { IssueRowProps };\n","import { Box, Text } from \"ink\";\nimport type { Task } from \"../../types.js\";\nimport { Priority } from \"../../types.js\";\n\ninterface TaskRowProps {\n readonly task: Task;\n readonly isSelected: boolean;\n}\n\nfunction truncate(s: string, max: number): string {\n return s.length > max ? `${s.slice(0, max - 1)}\\u2026` : s;\n}\n\nfunction formatDue(dateStr: string | undefined): { text: string; color: string } {\n if (!dateStr) return { text: \"\", color: \"gray\" };\n const d = new Date(dateStr);\n const days = Math.ceil((d.getTime() - Date.now()) / 86_400_000);\n\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\nconst PRIORITY_INDICATORS: Record<number, { text: string; color: string }> = {\n [Priority.High]: { text: \"[!]\", color: \"red\" },\n [Priority.Medium]: { text: \"[~]\", color: \"yellow\" },\n [Priority.Low]: { text: \"[\\u2193]\", color: \"blue\" },\n [Priority.None]: { text: \" \", color: \"gray\" },\n};\n\nconst DEFAULT_PRIORITY = { text: \" \", color: \"gray\" };\n\nfunction TaskRow({ task, isSelected }: TaskRowProps) {\n const pri = PRIORITY_INDICATORS[task.priority] ?? DEFAULT_PRIORITY;\n const due = formatDue(task.dueDate);\n const titleStr = truncate(task.title, 45).padEnd(45);\n\n return (\n <Box>\n {isSelected ? (\n <Text color=\"cyan\" bold>\n {\"\\u25B6 \"}\n </Text>\n ) : (\n <Text>{\" \"}</Text>\n )}\n <Text color={pri.color}>{pri.text}</Text>\n <Text> </Text>\n {isSelected ? (\n <Text color=\"white\" bold>\n {titleStr}\n </Text>\n ) : (\n <Text>{titleStr}</Text>\n )}\n <Text> </Text>\n <Text color={due.color}>{due.text}</Text>\n </Box>\n );\n}\n\nexport { TaskRow };\nexport type { TaskRowProps };\n","import { Box, Text } from \"ink\";\nimport type { GitHubIssue } from \"../../github.js\";\nimport type { Task } from \"../../types.js\";\nimport type { ActivityEvent } from \"../fetch.js\";\nimport { IssueRow } from \"./issue-row.js\";\nimport { TaskRow } from \"./task-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: \"task\"; key: string; navId: string; task: Task }\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}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: many row type variants\nexport function RowRenderer({ row, selectedId, selfLogin, isMultiSelected }: 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 <Text color=\"gray\"> {row.text}</Text>;\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 issue={row.issue} selfLogin={selfLogin} isSelected={selectedId === row.navId} />\n </Box>\n );\n }\n case \"task\": {\n const checkbox = isMultiSelected != null ? (isMultiSelected ? \"\\u2611 \" : \"\\u2610 \") : \"\";\n return (\n <Box>\n {checkbox ? <Text color={isMultiSelected ? \"cyan\" : \"gray\"}>{checkbox}</Text> : null}\n <TaskRow task={row.task} isSelected={selectedId === row.navId} />\n </Box>\n );\n }\n case \"activity\": {\n const ago = timeAgo(row.event.timestamp);\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\nfunction 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","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 } from \"../../config.js\";\nimport type { GitHubIssue, LabelOption, StatusOption } from \"../../github.js\";\nimport type { Task } from \"../../types.js\";\nimport type { ActivityEvent, FetchOptions, RepoData } from \"../fetch.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 { useToast } from \"../hooks/use-toast.js\";\nimport { useUIState } from \"../hooks/use-ui-state.js\";\nimport type { BulkAction } from \"./bulk-action-menu.js\";\nimport { DetailPanel } from \"./detail-panel.js\";\nimport type { FocusEndAction } from \"./focus-mode.js\";\nimport { OverlayRenderer } from \"./overlay-renderer.js\";\nimport type { FlatRow } from \"./row-renderer.js\";\nimport { RowRenderer } from \"./row-renderer.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\nconst TERMINAL_STATUS_RE = /^(done|shipped|won't|wont|closed|complete|completed)$/i;\n\nfunction isTerminalStatus(status: string): boolean {\n return TERMINAL_STATUS_RE.test(status);\n}\n\ninterface StatusGroup {\n label: string;\n statuses: string[];\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/** Collect issues for a status group (may span multiple statuses). */\nfunction collectGroupIssues(\n statusGroup: StatusGroup,\n byStatus: Map<string, GitHubIssue[]>,\n): GitHubIssue[] {\n const issues: GitHubIssue[] = [];\n for (const status of statusGroup.statuses) {\n const list = byStatus.get(status);\n if (list) issues.push(...list);\n }\n issues.sort((a, b) => issuePriorityRank(a) - issuePriorityRank(b));\n return issues;\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: TUI navigation tree builder\nfunction buildNavItems(repos: RepoData[], tasks: Task[], activityCount: number): NavItem[] {\n const items: NavItem[] = [];\n if (activityCount > 0) {\n items.push({ id: \"header:activity\", section: \"activity\", type: \"header\" });\n }\n for (const rd of repos) {\n items.push({ id: `header:${rd.repo.shortName}`, section: rd.repo.shortName, type: \"header\" });\n const statusGroupDefs = resolveStatusGroups(rd.statusOptions, rd.repo.statusGroups);\n const byStatus = groupByStatus(rd.issues);\n const coveredStatuses = new Set<string>();\n\n for (const sg of statusGroupDefs) {\n const groupIssues = collectGroupIssues(sg, byStatus);\n if (groupIssues.length === 0) continue;\n const subId = `sub:${rd.repo.shortName}:${sg.label}`;\n items.push({ id: subId, section: rd.repo.shortName, type: \"subHeader\" });\n for (const issue of groupIssues) {\n items.push({\n id: `gh:${rd.repo.name}:${issue.number}`,\n section: rd.repo.shortName,\n type: \"item\",\n subSection: subId,\n });\n }\n for (const s of sg.statuses) coveredStatuses.add(s);\n }\n // Any issues in statuses not covered by groups (non-terminal) go at the end\n for (const [status, issues] of byStatus) {\n if (!(coveredStatuses.has(status) || isTerminalStatus(status)) && issues.length > 0) {\n const subId = `sub:${rd.repo.shortName}:${status}`;\n items.push({ id: subId, section: rd.repo.shortName, type: \"subHeader\" });\n for (const issue of issues) {\n items.push({\n id: `gh:${rd.repo.name}:${issue.number}`,\n section: rd.repo.shortName,\n type: \"item\",\n subSection: subId,\n });\n }\n }\n }\n }\n if (tasks.length > 0) {\n items.push({ id: \"header:ticktick\", section: \"ticktick\", type: \"header\" });\n for (const task of tasks) {\n items.push({ id: `tt:${task.id}`, section: \"ticktick\", type: \"item\" });\n }\n }\n return items;\n}\n\n// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: flattens nested data into rows\nfunction buildFlatRows(\n repos: RepoData[],\n tasks: Task[],\n activity: ActivityEvent[],\n isCollapsed: (section: string) => boolean,\n): FlatRow[] {\n const rows: FlatRow[] = [];\n\n // Activity section (collapsed by default)\n if (activity.length > 0) {\n const collapsed = isCollapsed(\"activity\");\n rows.push({\n type: \"sectionHeader\",\n key: \"header:activity\",\n navId: \"header:activity\",\n label: \"Recent Activity (24h)\",\n count: activity.length,\n countLabel: \"events\",\n isCollapsed: collapsed,\n });\n if (!collapsed) {\n for (const [i, event] of activity.entries()) {\n rows.push({ type: \"activity\", key: `act:${i}`, navId: null, event });\n }\n }\n }\n\n for (const rd of repos) {\n const { repo, issues, error: repoError } = rd;\n const collapsed = isCollapsed(repo.shortName);\n\n rows.push({\n type: \"sectionHeader\",\n key: `header:${repo.shortName}`,\n navId: `header:${repo.shortName}`,\n label: repo.shortName,\n count: issues.length,\n countLabel: \"issues\",\n isCollapsed: collapsed,\n });\n\n if (!collapsed) {\n if (repoError) {\n rows.push({ type: \"error\", key: `error:${repo.shortName}`, navId: null, text: repoError });\n } else if (issues.length === 0) {\n rows.push({\n type: \"subHeader\",\n key: `empty:${repo.shortName}`,\n navId: null,\n text: \"No open issues\",\n });\n } else {\n const statusGroupDefs = resolveStatusGroups(rd.statusOptions, rd.repo.statusGroups);\n const byStatus = groupByStatus(issues);\n const coveredStatuses = new Set<string>();\n let isFirstGroup = true;\n\n for (const sg of statusGroupDefs) {\n const groupIssues = collectGroupIssues(sg, byStatus);\n if (groupIssues.length === 0) continue;\n\n if (!isFirstGroup) {\n rows.push({ type: \"gap\", key: `gap:${repo.shortName}:${sg.label}`, navId: null });\n }\n isFirstGroup = false;\n\n const subId = `sub:${repo.shortName}:${sg.label}`;\n const subCollapsed = isCollapsed(subId);\n rows.push({\n type: \"subHeader\",\n key: subId,\n navId: subId,\n text: sg.label,\n count: groupIssues.length,\n isCollapsed: subCollapsed,\n });\n if (!subCollapsed) {\n for (const issue of groupIssues) {\n rows.push({\n type: \"issue\",\n key: `gh:${repo.name}:${issue.number}`,\n navId: `gh:${repo.name}:${issue.number}`,\n issue,\n repoName: repo.name,\n });\n }\n }\n for (const s of sg.statuses) coveredStatuses.add(s);\n }\n\n // Any statuses not covered by groups (non-terminal) go at the end\n for (const [status, groupIssues] of byStatus) {\n if (\n !(coveredStatuses.has(status) || isTerminalStatus(status)) &&\n groupIssues.length > 0\n ) {\n if (!isFirstGroup) {\n rows.push({ type: \"gap\", key: `gap:${repo.shortName}:${status}`, navId: null });\n }\n isFirstGroup = false;\n const subId = `sub:${repo.shortName}:${status}`;\n const subCollapsed = isCollapsed(subId);\n rows.push({\n type: \"subHeader\",\n key: subId,\n navId: subId,\n text: status,\n count: groupIssues.length,\n isCollapsed: subCollapsed,\n });\n if (!subCollapsed) {\n for (const issue of groupIssues) {\n rows.push({\n type: \"issue\",\n key: `gh:${repo.name}:${issue.number}`,\n navId: `gh:${repo.name}:${issue.number}`,\n issue,\n repoName: repo.name,\n });\n }\n }\n }\n }\n }\n }\n }\n\n if (tasks.length > 0) {\n const collapsed = isCollapsed(\"ticktick\");\n rows.push({\n type: \"sectionHeader\",\n key: \"header:ticktick\",\n navId: \"header:ticktick\",\n label: \"Personal (TickTick)\",\n count: tasks.length,\n countLabel: \"tasks\",\n isCollapsed: collapsed,\n });\n if (!collapsed) {\n for (const task of tasks) {\n rows.push({ type: \"task\", key: `tt:${task.id}`, navId: `tt:${task.id}`, task });\n }\n }\n }\n\n return rows;\n}\n\nfunction 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\nfunction openInBrowser(url: string): void {\n try {\n execFileSync(\"open\", [url], { stdio: \"ignore\" });\n } catch {\n // Silently ignore\n }\n}\n\nfunction findSelectedUrl(repos: RepoData[], selectedId: string | null): 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) return issue.url;\n }\n }\n return null;\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\nfunction isHeaderId(id: string | null): boolean {\n return id != null && (id.startsWith(\"header:\") || id.startsWith(\"sub:\"));\n}\n\n// ── Dashboard ──\n\n// Header (1) + blank after header (0) + status bar (1) + padding (2 top+bottom)\nconst CHROME_ROWS = 4;\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 } = 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 allTasks = useMemo(\n () => (config.ticktick.enabled ? (data?.ticktick ?? []) : []),\n [data?.ticktick, config.ticktick.enabled],\n );\n const allActivity = useMemo(() => data?.activity ?? [], [data?.activity]);\n\n // UI state machine\n const ui = useUIState();\n\n // Search state (managed separately — search query persists across mode changes)\n const [searchQuery, setSearchQuery] = useState(\"\");\n\n // Toast notification system (replaces old statusMessage)\n const { toasts, toast, handleErrorAction } = useToast();\n\n // Periodic tick to update refresh age display (every 10s)\n const [, setTick] = useState(0);\n useEffect(() => {\n const id = setInterval(() => setTick((t) => t + 1), 10_000);\n return () => clearInterval(id);\n }, []);\n\n // Filter by search query\n const repos = useMemo(() => {\n if (!searchQuery) return allRepos;\n const q = searchQuery.toLowerCase();\n return allRepos\n .map((rd) => ({ ...rd, issues: rd.issues.filter((i) => i.title.toLowerCase().includes(q)) }))\n .filter((rd) => rd.issues.length > 0);\n }, [allRepos, searchQuery]);\n\n const tasks = useMemo(() => {\n if (!searchQuery) return allTasks;\n const q = searchQuery.toLowerCase();\n return allTasks.filter((t) => t.title.toLowerCase().includes(q));\n }, [allTasks, searchQuery]);\n\n // Navigation\n const navItems = useMemo(\n () => buildNavItems(repos, tasks, allActivity.length),\n [repos, tasks, allActivity.length],\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 // Format: gh:owner/repo:number\n const parts = id.split(\":\");\n return parts.length >= 3 ? `${parts[1]}` : null;\n }\n if (id.startsWith(\"tt:\")) return \"ticktick\";\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 });\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 const handleCreateIssueWithPrompt = useCallback(\n (repo: string, title: string, labels?: string[]) => {\n actions.handleCreateIssue(repo, title, 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 } else if (id.startsWith(\"tt:\")) {\n const taskId = id.slice(3);\n const task = tasks.find((t) => t.id === taskId);\n if (task) label = task.title;\n }\n\n if (!label) return;\n setFocusLabel(label);\n ui.enterFocus();\n }, [nav.selectedId, repos, tasks, 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 // Timer restarts — just stay in focus mode (component remounts with key)\n toast.info(\"Focus restarted!\");\n setFocusLabel((prev) => prev); // no-op to preserve label\n // Force remount by toggling a counter\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 showDetailPanel = termSize.cols >= 120;\n const detailPanelWidth = showDetailPanel ? Math.floor(termSize.cols * 0.35) : 0;\n const overlayBarRows = ui.state.mode === \"search\" || ui.state.mode === \"overlay:comment\" ? 1 : 0;\n const toastRows = toasts.length;\n const viewportHeight = Math.max(5, termSize.rows - CHROME_ROWS - overlayBarRows - toastRows);\n\n // Build flat rows\n const flatRows = useMemo(\n () => buildFlatRows(repos, tasks, allActivity, nav.isCollapsed),\n [repos, tasks, allActivity, nav.isCollapsed],\n );\n\n // Scroll offset - tracks viewport position\n const scrollRef = useRef(0);\n const selectedRowIdx = flatRows.findIndex((r) => r.navId === nav.selectedId);\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 + viewportHeight) {\n scrollRef.current = selectedRowIdx - viewportHeight + 1;\n }\n }\n const maxOffset = Math.max(0, flatRows.length - viewportHeight);\n scrollRef.current = Math.max(0, Math.min(scrollRef.current, maxOffset));\n\n const visibleRows = flatRows.slice(scrollRef.current, scrollRef.current + viewportHeight);\n const hasMoreAbove = scrollRef.current > 0;\n const hasMoreBelow = scrollRef.current + viewportHeight < flatRows.length;\n const aboveCount = scrollRef.current;\n const belowCount = flatRows.length - scrollRef.current - viewportHeight;\n\n // Find selected item for detail panel and overlays\n const selectedItem = useMemo((): {\n issue: GitHubIssue | null;\n task: Task | null;\n repoName: string | null;\n } => {\n const id = nav.selectedId;\n if (!id || isHeaderId(id)) return { issue: null, task: 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)\n return { issue, task: null, repoName: rd.repo.name };\n }\n }\n }\n if (id.startsWith(\"tt:\")) {\n const taskId = id.slice(3);\n const task = tasks.find((t) => t.id === taskId);\n if (task) return { issue: null, task, repoName: null };\n }\n return { issue: null, task: null, repoName: null };\n }, [nav.selectedId, repos, tasks]);\n\n // Status options for the selected issue's repo (for status picker, single or bulk)\n // Terminal statuses are now included — StatusPicker renders them with a \"(Done)\" suffix\n const selectedRepoStatusOptions = useMemo(() => {\n // In multi-select, use the constrained repo\n const repoName = multiSelect.count > 0 ? multiSelect.constrainedRepo : selectedItem.repoName;\n if (!repoName || repoName === \"ticktick\") 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 url = findSelectedUrl(repos, nav.selectedId);\n if (url) openInBrowser(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 let hasGh = false;\n let hasTt = false;\n for (const id of multiSelect.selected) {\n if (id.startsWith(\"gh:\")) hasGh = true;\n if (id.startsWith(\"tt:\")) hasTt = true;\n }\n if (hasGh && hasTt) return \"mixed\";\n if (hasTt) return \"ticktick\";\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 // Open status picker from bulk action menu — the reducer allows this transition\n ui.enterStatus();\n return; // status picker will call handleBulkStatusSelect on select\n case \"complete\":\n case \"delete\":\n toast.info(`Bulk ${action.type} not yet implemented for TickTick`);\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(); // close status picker\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 // 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 handleUnassign: actions.handleUnassign,\n handleEnterLabel: ui.enterLabel,\n handleEnterCreateNl: ui.enterCreateNl,\n handleErrorAction,\n toastInfo: toast.info,\n },\n onSearchEscape,\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 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 ) : lastRefresh ? (\n <>\n <Text color={refreshAgeColor(lastRefresh)}>Updated {timeAgo(lastRefresh)}</Text>\n {consecutiveFailures > 0 ? <Text color=\"red\"> (!)</Text> : null}\n </>\n ) : null}\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 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 />\n\n {/* Main content: scrollable list + optional detail panel (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 !== \"focus\" ? (\n <Box height={viewportHeight}>\n {/* Scrollable list */}\n <Box flexDirection=\"column\" flexGrow={1}>\n {hasMoreAbove ? (\n <Text color=\"gray\" dimColor>\n {\" \"}\n {\"\\u25B2\"} {aboveCount} more above\n </Text>\n ) : null}\n\n {visibleRows.map((row) => (\n <RowRenderer\n key={row.key}\n row={row}\n selectedId={nav.selectedId}\n selfLogin={config.board.assignee}\n isMultiSelected={\n ui.state.mode === \"multiSelect\" && row.navId\n ? multiSelect.isSelected(row.navId)\n : undefined\n }\n />\n ))}\n\n {hasMoreBelow ? (\n <Text color=\"gray\" dimColor>\n {\" \"}\n {\"\\u25BC\"} {belowCount} more below\n </Text>\n ) : null}\n </Box>\n\n {/* Detail panel */}\n {showDetailPanel ? (\n <Box marginLeft={1} width={detailPanelWidth}>\n <DetailPanel\n issue={selectedItem.issue}\n task={selectedItem.task}\n width={detailPanelWidth}\n />\n </Box>\n ) : null}\n </Box>\n ) : null}\n\n {/* Toast notifications */}\n <ToastContainer toasts={toasts} />\n\n {/* Status bar */}\n <Box>\n {ui.state.mode === \"multiSelect\" ? (\n <>\n <Text color=\"cyan\" bold>\n {multiSelect.count} selected\n </Text>\n <Text color=\"gray\"> Space:toggle Enter:actions Esc:cancel</Text>\n </>\n ) : ui.state.mode === \"focus\" ? (\n <Text color=\"magenta\" bold>\n Focus mode — Esc to exit\n </Text>\n ) : (\n <>\n <Text color=\"gray\">\n j/k:nav Tab:section Enter:open Space:select /:search p:pick c:comment m:status\n a/u:assign s:slack y:copy l:labels n:new I:nlcreate C:collapse f:focus ?:help q:quit\n </Text>\n {searchQuery && ui.state.mode !== \"search\" ? (\n <Text color=\"yellow\"> filter: "{searchQuery}"</Text>\n ) : null}\n </>\n )}\n </Box>\n </Box>\n );\n}\n\nexport { Dashboard };\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\";\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\nfunction formatError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\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 statusOptions: StatusOption[] = [];\n try {\n const enrichMap = fetchProjectEnrichment(repo.name, repo.projectNumber);\n for (const issue of issues) {\n const e = enrichMap.get(issue.number);\n if (e?.targetDate) issue.targetDate = e.targetDate;\n if (e?.projectStatus) issue.projectStatus = e.projectStatus;\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 }\n\n // Compute Slack thread URLs from issue bodies\n for (const issue of issues) {\n const slackUrl = extractSlackUrl(issue.body);\n if (slackUrl) issue.slackThreadUrl = slackUrl;\n }\n\n return { repo, issues, 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 })),\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 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 { execFileSync } from \"node:child_process\";\nimport { Command } from \"commander\";\nimport { extractIssueFields, hasLlmApiKey } from \"./ai.js\";\nimport { TickTickClient } from \"./api.js\";\nimport type { CompletionAction, RepoConfig } from \"./config.js\";\nimport {\n findRepo,\n getConfig,\n loadFullConfig,\n requireAuth,\n resolveProfile,\n saveConfig,\n saveFullConfig,\n validateRepoName,\n} from \"./config.js\";\nimport { runInit } from \"./init.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\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\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 console.error(`Invalid priority: ${value}. Use: none, low, medium, high`);\n process.exit(1);\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.3.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}`, {\n task: created as unknown as Record<string, unknown>,\n });\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}`, {\n task: updated as unknown as Record<string, unknown>,\n });\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 (owner/repo format)\")\n .requiredOption(\"--project-number <n>\", \"GitHub project number\")\n .requiredOption(\"--status-field-id <id>\", \"Project status field ID\")\n .requiredOption(\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((name: string, opts: ConfigAddRepoOptions) => {\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 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(\"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?: boolean;\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];\n for (const label of labels) {\n args.push(\"--label\", label);\n }\n\n try {\n execFileSync(\"gh\", args, { stdio: \"inherit\" });\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\nprogram.addCommand(issueCommand);\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 { CONFIG_DIR, loadFullConfig, saveFullConfig } 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\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 // 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 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: 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","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>): 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 type { HogConfig, RepoConfig } from \"./config.js\";\nimport { loadFullConfig, requireAuth } from \"./config.js\";\nimport type { GitHubIssue } from \"./github.js\";\nimport {\n addLabel,\n fetchAssignedIssues,\n fetchProjectFields,\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 formatError(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\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 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);\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): 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 projectFields = fetchProjectFields(\n repoConfig.name,\n issue.number,\n repoConfig.projectNumber,\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":["input","text","input","config","execFileSync","existsSync","readFileSync","writeFileSync","homedir","join","CONFIG_DIR","input","config","repoShortName","mapPriority","task","execFile","promisify","config","execFileAsync","useCallback","useRef","config","useCallback","input","useCallback","useRef","useState","useCallback","useRef","select","useCallback","useRef","useState","useCallback","useReducer","INITIAL_STATE","task","PRIORITY_LABELS","Box","Text","useInput","useState","jsx","jsxs","input","readFileSync","writeFileSync","join","Box","Text","useInput","useEffect","useRef","useState","jsx","jsxs","Box","Text","useInput","jsx","jsxs","input","Box","Text","useInput","useEffect","useRef","useState","jsx","jsxs","input","allLabels","TextInput","Box","Text","useInput","useState","jsx","jsxs","input","Box","Text","useInput","useCallback","useEffect","useRef","useState","jsx","jsxs","input","Box","Text","useInput","jsx","jsxs","Spinner","TextInput","Box","Text","useInput","useCallback","useEffect","useRef","useState","jsx","jsxs","TextInput","Box","Text","jsx","jsxs","Box","Text","useInput","useRef","useState","jsx","jsxs","TERMINAL_STATUS_RE","input","Fragment","jsx","jsxs","config","Box","Text","Fragment","jsx","jsxs","Box","Text","jsx","jsxs","truncate","formatDue","task","Box","Text","jsx","jsxs","checkbox","timeAgo","Spinner","Box","Text","Fragment","jsx","jsxs","execFileSync","spawnSync","Spinner","Box","Text","useCallback","useEffect","useMemo","useRef","useState","Fragment","jsx","jsxs","TERMINAL_STATUS_RE","task","timeAgo","isHeaderId","config","pickIssue","jsx","config","SLACK_URL_RE","execFileSync","formatError","config","truncate","task","printSection","execFileSync","existsSync","config","task","input","config","task","config","input","runLiveDashboard","fetchDashboard","renderBoardJson","renderStaticBoard","parseIssueRef","pickIssue","execFileSync"]}
|