@trail-pm/cli 0.1.6 → 0.2.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/paths.ts","../src/core/task-store.ts","../src/schemas/task.ts","../src/core/compile-snapshot.ts","../src/schemas/snapshot.ts","../src/core/rebuild-snapshot.ts","../src/core/draft-id.ts","../src/schemas/config.ts","../src/core/auth.ts","../src/core/github-client.ts","../src/core/github-mapper.ts","../src/core/sync.ts","../src/core/relevant-tasks.ts","../src/core/config-update.ts","../src/core/link-draft-issue.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst MAX_TRAIL_ROOT_WALK = 20;\n\n/**\n * Walks upward from `startDir` looking for a Trail project root: a directory\n * that contains `.trail/config.json`.\n *\n * @returns The **project root** directory (the parent of the `.trail` folder),\n * or `null` if none is found within the walk limit. This is not the path to\n * `.trail` itself — use {@link trailPaths} for `.trail`-relative paths.\n */\nexport function findTrailRoot(startDir: string): string | null {\n let dir = path.resolve(startDir);\n for (let i = 0; i < MAX_TRAIL_ROOT_WALK; i++) {\n const configPath = path.join(dir, \".trail\", \"config.json\");\n if (fs.existsSync(configPath)) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) {\n break;\n }\n dir = parent;\n }\n return null;\n}\n\nexport interface TrailPaths {\n root: string;\n trailDir: string;\n tasksDir: string;\n configPath: string;\n snapshotPath: string;\n gitignorePath: string;\n}\n\n/** Resolved paths under a Trail project root (the directory that contains `.trail`). */\nexport function trailPaths(root: string): TrailPaths {\n const trailDir = path.join(root, \".trail\");\n return {\n root,\n trailDir,\n tasksDir: path.join(trailDir, \"tasks\"),\n configPath: path.join(trailDir, \"config.json\"),\n snapshotPath: path.join(trailDir, \"snapshot.json\"),\n gitignorePath: path.join(trailDir, \".gitignore\"),\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nimport type { TrailError } from \"./errors.js\";\nimport { TaskSchema, type Task } from \"../schemas/task.js\";\n\n/** Thrown by task-store when validation fails; inspect `.trailError` for `VALIDATION_FAILED`. */\nexport type TaskStoreError = Error & { trailError: TrailError };\n\nexport function toValidationError(\n zodError: z.ZodError,\n context?: string,\n): Extract<TrailError, { code: \"VALIDATION_FAILED\" }> {\n const issues = zodError.issues.map(\n (i) => `${i.path.length ? i.path.join(\".\") : \"(root)\"}: ${i.message}`,\n );\n return {\n code: \"VALIDATION_FAILED\",\n message: context\n ? `Task validation failed (${context})`\n : \"Task validation failed\",\n details: zodError.message,\n issues,\n };\n}\n\nfunction throwValidationFailed(\n err: Extract<TrailError, { code: \"VALIDATION_FAILED\" }>,\n): never {\n const e = new Error(`[VALIDATION_FAILED] ${err.message}`) as TaskStoreError;\n e.name = \"TrailError\";\n e.trailError = err;\n throw e;\n}\n\nexport function isTaskStoreValidationError(\n e: unknown,\n): e is TaskStoreError & { trailError: Extract<TrailError, { code: \"VALIDATION_FAILED\" }> } {\n return (\n e instanceof Error &&\n \"trailError\" in e &&\n typeof (e as TaskStoreError).trailError === \"object\" &&\n (e as TaskStoreError).trailError !== null &&\n \"code\" in (e as TaskStoreError).trailError &&\n (e as TaskStoreError).trailError.code === \"VALIDATION_FAILED\"\n );\n}\n\n/**\n * Lists `*.json` basenames under `tasksDir`, excluding `snapshot.json`, sorted lexicographically.\n */\nexport function listTaskFiles(tasksDir: string): string[] {\n const names = fs.readdirSync(tasksDir);\n return names\n .filter(\n (n) => n.endsWith(\".json\") && n !== \"snapshot.json\",\n )\n .sort((a, b) => a.localeCompare(b));\n}\n\nexport function readTaskFile(filePath: string): Task {\n let raw: unknown;\n try {\n raw = JSON.parse(fs.readFileSync(filePath, \"utf8\"));\n } catch (e) {\n if (e instanceof SyntaxError) {\n throwValidationFailed({\n code: \"VALIDATION_FAILED\",\n message: \"Invalid JSON in task file\",\n details: filePath,\n });\n }\n throw e;\n }\n\n const parsed = TaskSchema.safeParse(raw);\n if (!parsed.success) {\n throwValidationFailed(toValidationError(parsed.error, filePath));\n }\n return parsed.data;\n}\n\nexport function writeTaskFile(filePath: string, task: Task): void {\n const parsed = TaskSchema.safeParse(task);\n if (!parsed.success) {\n throwValidationFailed(toValidationError(parsed.error, filePath));\n }\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n const body = `${JSON.stringify(parsed.data, null, 2)}\\n`;\n fs.writeFileSync(filePath, body, \"utf8\");\n}\n\n/**\n * Loads all task JSON files from `tasksDir`. Returns an empty array if the directory is missing.\n * Stops on the first file that fails to parse or validate.\n */\nexport function loadAllTasks(tasksDir: string): Task[] {\n if (!fs.existsSync(tasksDir)) {\n return [];\n }\n const files = listTaskFiles(tasksDir);\n return files.map((name) => readTaskFile(path.join(tasksDir, name)));\n}\n\n/**\n * Resolves the task file for `id`: prefers `${id}.json` when it exists and its `id` matches;\n * otherwise scans `*.json` for a task whose `id` field equals `id`.\n */\nexport function findTaskFileById(\n tasksDir: string,\n id: string,\n): { filePath: string; task: Task } | null {\n if (!fs.existsSync(tasksDir)) {\n return null;\n }\n const direct = path.join(tasksDir, `${id}.json`);\n if (fs.existsSync(direct)) {\n const task = readTaskFile(direct);\n if (task.id === id) {\n return { filePath: direct, task };\n }\n }\n for (const name of listTaskFiles(tasksDir)) {\n const filePath = path.join(tasksDir, name);\n const task = readTaskFile(filePath);\n if (task.id === id) {\n return { filePath, task };\n }\n }\n return null;\n}\n","import { z } from \"zod\";\n\nexport const TaskStatusSchema = z.enum([\n \"draft\",\n \"todo\",\n \"in_progress\",\n \"in_review\",\n \"done\",\n \"cancelled\",\n]);\n\nexport type TaskStatus = z.infer<typeof TaskStatusSchema>;\n\n/** YYYY-MM-DD (ISO 8601 calendar date). */\nconst isoDateStringSchema = z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}$/, \"Expected ISO date string (YYYY-MM-DD)\");\n\n/**\n * GitHub issue link metadata. `null` means the task is not linked to an issue (e.g. local draft).\n */\nconst TaskGitHubSchema = z\n .object({\n issue_number: z.number().int(),\n synced_at: z.string().datetime({ offset: true }),\n url: z.string().url(),\n })\n .nullable();\n\nconst TaskAiSchema = z\n .object({\n summary: z.string().optional(),\n acceptance_criteria: z.array(z.string()).optional(),\n implementation_context: z.array(z.string()).optional(),\n test_strategy: z.array(z.string()).optional(),\n constraints: z.array(z.string()).optional(),\n })\n .strict()\n .optional();\n\nexport const TaskSchema = z\n .object({\n id: z.string(),\n title: z.string(),\n description: z.string().optional(),\n status: TaskStatusSchema,\n priority: z.enum([\"p0\", \"p1\", \"p2\", \"p3\"]).optional(),\n type: z.enum([\"feature\", \"bug\", \"chore\", \"epic\"]),\n assignee: z.string().optional(),\n milestone: z.string().optional(),\n branch: z.string().optional(),\n labels: z.array(z.string()).default([]),\n parent: z.string().nullable().optional(),\n depends_on: z.array(z.string()).default([]),\n blocks: z.array(z.string()).default([]),\n due_date: isoDateStringSchema.optional(),\n start_date: isoDateStringSchema.optional(),\n estimate: z.enum([\"xs\", \"sm\", \"md\", \"lg\", \"xl\"]).optional(),\n github: TaskGitHubSchema.optional(),\n refs: z\n .array(\n z\n .object({\n type: z.string(),\n path: z.string(),\n })\n .strict(),\n )\n .default([]),\n ai: TaskAiSchema,\n created_at: z.string().datetime({ offset: true }),\n updated_at: z.string().datetime({ offset: true }),\n })\n .strict();\n\nexport type Task = z.infer<typeof TaskSchema>;\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { Task } from \"../schemas/task.js\";\nimport { SnapshotSchema, type Snapshot } from \"../schemas/snapshot.js\";\n\nconst UNKNOWN_DEPENDENCY = \"UNKNOWN_DEPENDENCY\";\n\n/** Warning code when `depends_on` forms a directed cycle. */\nexport const DEPENDENCY_CYCLE = \"DEPENDENCY_CYCLE\";\n\n/**\n * Finds directed cycles in the dependency graph: edge `u → v` when task `u` lists `v` in `depends_on`.\n * Only vertices in `taskIds` participate; edges to ids outside `taskIds` are ignored here (handled as warnings in `compileSnapshot`).\n */\nexport function detectCycles(\n taskIds: Set<string>,\n deps: Map<string, string[]>,\n): string[][] {\n const cycles: string[][] = [];\n /** Finished nodes (BLACK). */\n const visited = new Set<string>();\n /** Nodes on the current DFS path (GRAY). */\n const visiting = new Set<string>();\n const stack: string[] = [];\n\n function recordCycle(fromIndex: number): void {\n cycles.push(stack.slice(fromIndex));\n }\n\n function dfs(u: string): void {\n visiting.add(u);\n stack.push(u);\n\n for (const v of deps.get(u) ?? []) {\n if (!taskIds.has(v)) {\n continue;\n }\n if (visiting.has(v)) {\n const i = stack.indexOf(v);\n if (i !== -1) {\n recordCycle(i);\n }\n continue;\n }\n if (!visited.has(v)) {\n dfs(v);\n }\n }\n\n stack.pop();\n visiting.delete(u);\n visited.add(u);\n }\n\n for (const id of taskIds) {\n if (!visited.has(id)) {\n dfs(id);\n }\n }\n\n return cycles;\n}\n\nfunction formatCycle(nodes: string[]): string {\n return nodes.join(\" → \");\n}\n\n/**\n * Builds a snapshot from tasks, with warnings for unknown dependency ids and dependency cycles.\n */\nexport function compileSnapshot(tasks: Task[], now?: Date): Snapshot {\n const generatedAt = (now ?? new Date()).toISOString();\n const taskList = [...tasks];\n const taskIds = new Set(taskList.map((t) => t.id));\n const deps = new Map<string, string[]>();\n for (const t of taskList) {\n deps.set(t.id, t.depends_on ?? []);\n }\n\n const warnings: Snapshot[\"warnings\"] = [];\n\n for (const t of taskList) {\n for (const depId of t.depends_on ?? []) {\n if (!taskIds.has(depId)) {\n warnings.push({\n code: UNKNOWN_DEPENDENCY,\n message: `Task \"${t.id}\" depends on unknown task id \"${depId}\"`,\n taskId: t.id,\n });\n }\n }\n }\n\n for (const cycle of detectCycles(taskIds, deps)) {\n warnings.push({\n code: DEPENDENCY_CYCLE,\n message: `Dependency cycle: ${formatCycle(cycle)}`,\n taskId: cycle[0],\n });\n }\n\n return {\n generated_at: generatedAt,\n tasks: taskList,\n warnings,\n };\n}\n\nexport function writeSnapshot(snapshotPath: string, snapshot: Snapshot): void {\n const parsed = SnapshotSchema.parse(snapshot);\n const dir = path.dirname(snapshotPath);\n fs.mkdirSync(dir, { recursive: true });\n const body = `${JSON.stringify(parsed, null, 2)}\\n`;\n fs.writeFileSync(snapshotPath, body, \"utf8\");\n}\n","import { z } from \"zod\";\n\nimport { TaskSchema } from \"./task.js\";\n\nexport const SnapshotSchema = z\n .object({\n generated_at: z.string().datetime({ offset: true }),\n tasks: z.array(TaskSchema),\n warnings: z.array(\n z\n .object({\n code: z.string(),\n message: z.string(),\n taskId: z.string().optional(),\n })\n .strict(),\n ),\n })\n .strict();\n\nexport type Snapshot = z.infer<typeof SnapshotSchema>;\n","import { compileSnapshot, writeSnapshot } from \"./compile-snapshot.js\";\nimport { loadAllTasks } from \"./task-store.js\";\nimport type { TrailPaths } from \"./paths.js\";\n\n/** Recompiles `.trail/snapshot.json` from all task files. */\nexport function rebuildSnapshot(paths: TrailPaths, now = new Date()): void {\n const tasks = loadAllTasks(paths.tasksDir);\n const snapshot = compileSnapshot(tasks, now);\n writeSnapshot(paths.snapshotPath, snapshot);\n}\n","import { randomBytes } from \"node:crypto\";\n\n/** Stable draft task id prefix + random suffix (e.g. `draft-a1b2c3d4`). */\nexport function generateDraftId(): string {\n return `draft-${randomBytes(4).toString(\"hex\")}`;\n}\n","import { z } from \"zod\";\n\nexport const TrailConfigSchema = z\n .object({\n github: z\n .object({\n owner: z.string(),\n repo: z.string(),\n })\n .strict(),\n sync: z\n .object({\n preset: z.enum([\"collaborative\", \"solo\", \"offline\"]),\n auto_sync_on_command: z.boolean(),\n ui_poll_interval_seconds: z.number(),\n ui_idle_backoff: z.boolean(),\n })\n .strict(),\n /** Last successful full sync; useful for future `trail status` and similar. */\n last_full_sync_at: z.string().datetime({ offset: true }).optional(),\n })\n .strict();\n\nexport type TrailConfig = z.infer<typeof TrailConfigSchema>;\n","import * as childProcess from \"node:child_process\";\nimport type { TrailError } from \"./errors.js\";\n\nexport type ResolveTokenResult =\n | { ok: true; token: string }\n | { ok: false; error: TrailError };\n\nconst AUTH_HINT =\n \"Set GITHUB_TOKEN or install gh and run gh auth login\";\n\nfunction authRequired(message: string): ResolveTokenResult {\n return {\n ok: false,\n error: {\n code: \"AUTH_REQUIRED\",\n message,\n hint: AUTH_HINT,\n },\n };\n}\n\n/**\n * Resolves a GitHub API token from `GITHUB_TOKEN` (trimmed) or `gh auth token`.\n */\nexport function resolveGitHubToken(\n env?: NodeJS.ProcessEnv,\n): ResolveTokenResult {\n const e = env ?? process.env;\n const fromEnv = e.GITHUB_TOKEN;\n if (typeof fromEnv === \"string\" && fromEnv.trim() !== \"\") {\n return { ok: true, token: fromEnv.trim() };\n }\n\n try {\n const out = childProcess.execFileSync(\"gh\", [\"auth\", \"token\"], {\n encoding: \"utf-8\",\n });\n const token = out.trim();\n if (token === \"\") {\n return authRequired(\"GitHub CLI returned an empty token\");\n }\n return { ok: true, token };\n } catch {\n return authRequired(\n \"No GitHub token found; could not read from environment or gh CLI\",\n );\n }\n}\n","import type { GitHubIssue } from \"./github-types.js\";\n\nconst USER_AGENT = \"trail-cli/0.0.1\";\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/$/, \"\");\n}\n\nexport class GitHubClient {\n private readonly token: string;\n private readonly baseUrl: string;\n\n constructor(token: string, baseUrl = \"https://api.github.com\") {\n this.token = token;\n this.baseUrl = normalizeBaseUrl(baseUrl);\n }\n\n private async request(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<Response> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`;\n const headers = new Headers({\n Authorization: `Bearer ${this.token}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n \"User-Agent\": USER_AGENT,\n });\n if (body !== undefined) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n return fetch(url, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n }\n\n private async parseJson<T>(response: Response): Promise<T> {\n const text = await response.text();\n if (!response.ok) {\n const snippet = text.slice(0, 200);\n throw new Error(`GitHub API ${response.status}: ${snippet}`);\n }\n return JSON.parse(text) as T;\n }\n\n async listIssues(\n owner: string,\n repo: string,\n params: {\n state: \"open\" | \"all\" | \"closed\";\n per_page: number;\n page: number;\n },\n ): Promise<GitHubIssue[]> {\n const search = new URLSearchParams({\n state: params.state,\n per_page: String(params.per_page),\n page: String(params.page),\n });\n const path = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues?${search}`;\n const response = await this.request(\"GET\", path);\n return this.parseJson<GitHubIssue[]>(response);\n }\n\n async getIssue(\n owner: string,\n repo: string,\n issueNumber: number,\n ): Promise<GitHubIssue> {\n const path = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${issueNumber}`;\n const response = await this.request(\"GET\", path);\n return this.parseJson<GitHubIssue>(response);\n }\n\n async updateIssue(\n owner: string,\n repo: string,\n issueNumber: number,\n patch: Record<string, unknown>,\n ): Promise<GitHubIssue> {\n const path = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${issueNumber}`;\n const response = await this.request(\"PATCH\", path, patch);\n return this.parseJson<GitHubIssue>(response);\n }\n\n async createIssueComment(\n owner: string,\n repo: string,\n issueNumber: number,\n body: string,\n ): Promise<{ id: number }> {\n const path = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${issueNumber}/comments`;\n const response = await this.request(\"POST\", path, { body });\n return this.parseJson<{ id: number }>(response);\n }\n\n /** Create a new issue. Returns the created issue (same shape as list/get). */\n async createIssue(\n owner: string,\n repo: string,\n input: { title: string; body?: string; labels?: string[] },\n ): Promise<GitHubIssue> {\n const path = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues`;\n const response = await this.request(\"POST\", path, {\n title: input.title,\n body: input.body ?? \"\",\n labels: input.labels ?? [],\n });\n return this.parseJson<GitHubIssue>(response);\n }\n}\n","import type { GitHubIssue } from \"./github-types.js\";\nimport { TaskSchema, type Task } from \"../schemas/task.js\";\n\nfunction statusFromIssue(issue: GitHubIssue, existing: Task | null): Task[\"status\"] {\n if (issue.state === \"closed\") {\n return \"done\";\n }\n const prev = existing?.status;\n if (prev === \"in_progress\" || prev === \"in_review\") {\n return prev;\n }\n return \"todo\";\n}\n\nfunction parseIssueTimestamp(issue: GitHubIssue, fallback: Date): string {\n if (issue.updated_at.trim() === \"\") {\n return fallback.toISOString();\n }\n return issue.updated_at;\n}\n\n/**\n * Maps a GitHub issue to a Trail task. GitHub wins for title, body, labels, assignee, milestone;\n * local-only fields are preserved from `existing` when present.\n */\nexport function issueToTask(\n issue: GitHubIssue,\n existing: Task | null,\n now: Date,\n): Task {\n const updatedAt = parseIssueTimestamp(issue, now);\n const createdAt =\n existing?.created_at ?? (issue.updated_at.trim() !== \"\" ? issue.updated_at : now.toISOString());\n\n const raw: Task = {\n id: String(issue.number),\n title: issue.title,\n description: issue.body ?? \"\",\n status: statusFromIssue(issue, existing),\n type: existing?.type ?? \"feature\",\n labels: issue.labels.map((l) => l.name),\n assignee: issue.assignee?.login,\n milestone: issue.milestone?.title,\n depends_on: existing?.depends_on ?? [],\n blocks: existing?.blocks ?? [],\n refs: existing?.refs ?? [],\n ai: existing?.ai,\n branch: existing?.branch,\n estimate: existing?.estimate,\n priority: existing?.priority,\n parent: existing?.parent,\n due_date: existing?.due_date,\n start_date: existing?.start_date,\n github: {\n issue_number: issue.number,\n synced_at: now.toISOString(),\n url: issue.html_url,\n },\n created_at: createdAt,\n updated_at: updatedAt,\n };\n\n return TaskSchema.parse(raw);\n}\n\n/**\n * Maps a Trail task to fields for `GitHubClient.updateIssue`.\n */\nexport function taskToIssueUpdate(task: Task): {\n title?: string;\n body?: string;\n state?: \"open\" | \"closed\";\n labels?: string[];\n} {\n const labels = [...task.labels];\n if (task.priority) {\n const priorityLabel = `priority:${task.priority}`;\n if (!labels.includes(priorityLabel)) {\n labels.push(priorityLabel);\n }\n }\n\n const state: \"open\" | \"closed\" =\n task.status === \"done\" || task.status === \"cancelled\" ? \"closed\" : \"open\";\n\n return {\n title: task.title,\n body: task.description ?? \"\",\n state,\n labels,\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { GitHubClient } from \"./github-client.js\";\nimport { issueToTask, taskToIssueUpdate } from \"./github-mapper.js\";\nimport { compileSnapshot, writeSnapshot } from \"./compile-snapshot.js\";\nimport { computeRelevantTaskIds } from \"./relevant-tasks.js\";\nimport { loadAllTasks, readTaskFile, writeTaskFile } from \"./task-store.js\";\nimport type { Task } from \"../schemas/task.js\";\n\nconst ISSUES_PER_PAGE = 100;\n\nexport type SyncProgress =\n | { phase: \"pull\"; page: number; issuesInPage: number; issuesSoFar: number }\n | { phase: \"push\"; index: number; total: number; taskId: string };\n\nexport async function pullSync(options: {\n client: GitHubClient;\n owner: string;\n repo: string;\n tasksDir: string;\n now?: Date;\n onProgress?: (p: SyncProgress) => void;\n}): Promise<void> {\n const { client, owner, repo, tasksDir } = options;\n const now = options.now ?? new Date();\n const onProgress = options.onProgress;\n let page = 1;\n let issuesSoFar = 0;\n\n for (;;) {\n const issues = await client.listIssues(owner, repo, {\n state: \"all\",\n per_page: ISSUES_PER_PAGE,\n page,\n });\n\n if (issues.length === 0) {\n break;\n }\n\n for (const issue of issues) {\n const filePath = path.join(tasksDir, `${issue.number}.json`);\n let existing: Task | null = null;\n if (fs.existsSync(filePath)) {\n existing = readTaskFile(filePath);\n }\n const task = issueToTask(issue, existing, now);\n writeTaskFile(filePath, task);\n }\n\n issuesSoFar += issues.length;\n onProgress?.({\n phase: \"pull\",\n page,\n issuesInPage: issues.length,\n issuesSoFar,\n });\n\n if (issues.length < ISSUES_PER_PAGE) {\n break;\n }\n page += 1;\n }\n}\n\nfunction isLinkedTask(\n task: Task,\n): task is Task & { github: NonNullable<Task[\"github\"]> } {\n return task.github != null && typeof task.github === \"object\";\n}\n\nexport async function pushSync(options: {\n client: GitHubClient;\n owner: string;\n repo: string;\n tasks: Task[];\n /** When set, only issues for these task ids are pushed (bulk sync). Omit to push every linked task. */\n onlyTaskIds?: Set<string>;\n onProgress?: (p: SyncProgress) => void;\n}): Promise<void> {\n const { client, owner, repo, tasks } = options;\n const only = options.onlyTaskIds;\n const onProgress = options.onProgress;\n\n const toPush = tasks.filter((task) => {\n if (task.status === \"draft\") {\n return false;\n }\n if (!isLinkedTask(task)) {\n return false;\n }\n if (only !== undefined && !only.has(task.id)) {\n return false;\n }\n return true;\n });\n\n let index = 0;\n for (const task of toPush) {\n if (!isLinkedTask(task)) {\n continue;\n }\n index += 1;\n onProgress?.({\n phase: \"push\",\n index,\n total: toPush.length,\n taskId: task.id,\n });\n const patch = taskToIssueUpdate(task);\n await client.updateIssue(owner, repo, task.github.issue_number, patch);\n }\n}\n\nexport async function syncFull(options: {\n client: GitHubClient;\n owner: string;\n repo: string;\n tasksDir: string;\n snapshotPath: string;\n now?: Date;\n onProgress?: (p: SyncProgress) => void;\n}): Promise<void> {\n const { client, owner, repo, tasksDir, snapshotPath, now } = options;\n await pullSync({ client, owner, repo, tasksDir, now, onProgress: options.onProgress });\n const tasks = loadAllTasks(tasksDir);\n const snapshot = compileSnapshot(tasks, now);\n writeSnapshot(snapshotPath, snapshot);\n}\n\nexport async function fullSync(options: {\n client: GitHubClient;\n owner: string;\n repo: string;\n tasksDir: string;\n snapshotPath: string;\n now?: Date;\n onProgress?: (p: SyncProgress) => void;\n}): Promise<void> {\n const { client, owner, repo, tasksDir, snapshotPath, now } = options;\n await pullSync({ client, owner, repo, tasksDir, now, onProgress: options.onProgress });\n const tasks = loadAllTasks(tasksDir);\n const relevant = computeRelevantTaskIds(tasks);\n await pushSync({\n client,\n owner,\n repo,\n tasks,\n onlyTaskIds: relevant,\n onProgress: options.onProgress,\n });\n const snapshot = compileSnapshot(tasks, now);\n writeSnapshot(snapshotPath, snapshot);\n}\n","import type { Task, TaskStatus } from \"../schemas/task.js\";\n\nconst NON_TERMINAL: TaskStatus[] = [\n \"draft\",\n \"todo\",\n \"in_progress\",\n \"in_review\",\n];\n\nfunction isNonTerminalStatus(status: TaskStatus): boolean {\n return NON_TERMINAL.includes(status);\n}\n\n/**\n * Tasks that are \"in play\" for day-to-day work: not done/cancelled.\n * Used as seeds for the relevance closure.\n */\nexport function isActiveForRelevance(task: Task): boolean {\n return isNonTerminalStatus(task.status);\n}\n\n/**\n * Collects task ids that are active (non-terminal) plus any task ids reachable via\n * `depends_on`, `blocks`, or `parent` from those seeds. Used to limit bulk `push`\n * during `trail sync` so we do not PATCH every linked issue in the repository.\n *\n * Individual commands (`trail update`, `trail done`, …) still push their target task.\n */\nexport function computeRelevantTaskIds(tasks: Task[]): Set<string> {\n const byId = new Map<string, Task>();\n for (const t of tasks) {\n byId.set(t.id, t);\n }\n\n const relevant = new Set<string>();\n const queue: string[] = [];\n\n for (const t of tasks) {\n if (isActiveForRelevance(t)) {\n if (!relevant.has(t.id)) {\n relevant.add(t.id);\n queue.push(t.id);\n }\n }\n }\n\n function enqueue(id: string): void {\n if (relevant.has(id)) return;\n relevant.add(id);\n queue.push(id);\n }\n\n while (queue.length > 0) {\n const id = queue.pop() as string;\n const task = byId.get(id);\n if (!task) continue;\n\n for (const d of task.depends_on) {\n if (byId.has(d)) enqueue(d);\n }\n for (const b of task.blocks) {\n if (byId.has(b)) enqueue(b);\n }\n if (task.parent != null && task.parent !== \"\" && byId.has(task.parent)) {\n enqueue(task.parent);\n }\n }\n\n return relevant;\n}\n","import fs from \"node:fs\";\n\nimport { TrailConfigSchema } from \"../schemas/config.js\";\nimport type { TrailPaths } from \"./paths.js\";\n\nexport function writeLastFullSyncAt(paths: TrailPaths, iso: string): void {\n const raw = fs.readFileSync(paths.configPath, \"utf-8\");\n const config = TrailConfigSchema.parse(JSON.parse(raw) as unknown);\n const next = { ...config, last_full_sync_at: iso };\n fs.writeFileSync(paths.configPath, `${JSON.stringify(next, null, 2)}\\n`, \"utf-8\");\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { GitHubClient } from \"./github-client.js\";\nimport { issueToTask } from \"./github-mapper.js\";\nimport { writeTaskFile } from \"./task-store.js\";\nimport type { Task } from \"../schemas/task.js\";\n\n/**\n * Creates a GitHub issue from a draft task, deletes the draft file, and writes\n * `{issueNumber}.json`. Mirrors `trail promote` without CLI validation.\n */\nexport async function linkDraftToNewGitHubIssue(options: {\n client: GitHubClient;\n owner: string;\n repo: string;\n draft: Task;\n draftFilePath: string;\n tasksDir: string;\n now: Date;\n}): Promise<Task> {\n const { client, owner, repo, draft, draftFilePath, tasksDir, now } = options;\n\n const issue = await client.createIssue(owner, repo, {\n title: draft.title,\n body: draft.description ?? \"\",\n labels: draft.labels,\n });\n\n const promoted = issueToTask(issue, draft, now);\n fs.unlinkSync(draftFilePath);\n const newPath = path.join(tasksDir, `${issue.number}.json`);\n writeTaskFile(newPath, promoted);\n return promoted;\n}\n"],"mappings":"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","names":["fs","path","fs","path","fs","path","z","z","path","fs","z","path","fs","path","path","fs","fs","fs","fs","path","fs","path"]}
@@ -10,7 +10,7 @@ import {
10
10
  loadTrailReadContext,
11
11
  selectNextTask,
12
12
  selectTasksForList
13
- } from "./chunk-TDIYLUKH.js";
13
+ } from "./chunk-YSTYANXJ.js";
14
14
 
15
15
  // ../../node_modules/ajv/dist/compile/codegen/code.js
16
16
  var require_code = __commonJS({
@@ -12584,4 +12584,4 @@ async function runMcpServer() {
12584
12584
  export {
12585
12585
  runMcpServer
12586
12586
  };
12587
- //# sourceMappingURL=run-mcp-server-HD7I5M7Z.js.map
12587
+ //# sourceMappingURL=run-mcp-server-NKYRI73A.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trail-pm/cli",
3
- "version": "0.1.6",
3
+ "version": "0.2.2",
4
4
  "description": "GitHub-native AI project management CLI",
5
5
  "type": "module",
6
6
  "files": [
@@ -16,6 +16,16 @@
16
16
  },
17
17
  "main": "./dist/index.js",
18
18
  "types": "./dist/index.d.ts",
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js"
23
+ },
24
+ "./lib": {
25
+ "types": "./dist/lib.d.ts",
26
+ "import": "./dist/lib.js"
27
+ }
28
+ },
19
29
  "scripts": {
20
30
  "prepublishOnly": "npm run build",
21
31
  "build": "tsup",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/compile-snapshot.ts","../src/schemas/snapshot.ts","../src/schemas/task.ts","../src/core/paths.ts","../src/core/task-store.ts","../src/cli/json.ts","../src/cli/commands/context.ts","../src/core/deps.ts","../src/cli/read-context.ts","../src/core/auth.ts","../src/core/errors.ts","../src/core/github-client.ts","../src/core/sync.ts","../src/core/github-mapper.ts","../src/core/maybe-pull.ts","../src/schemas/config.ts","../src/cli/commands/list.ts","../src/core/next-task.ts","../src/cli/run-cli.ts","../src/cli/commands/create.ts","../src/core/draft-id.ts","../src/core/rebuild-snapshot.ts","../src/cli/commands/dep.ts","../src/cli/commands/done.ts","../src/cli/commands/graph.ts","../src/cli/commands/init.ts","../src/cli/templates/user-agents.md.ts","../src/cli/commands/next.ts","../src/cli/commands/promote.ts","../src/cli/commands/show.ts","../src/cli/commands/status.ts","../src/cli/commands/sync.ts","../src/cli/commands/update.ts","../src/cli/commands/validate.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { Task } from \"../schemas/task.js\";\nimport { SnapshotSchema, type Snapshot } from \"../schemas/snapshot.js\";\n\nconst UNKNOWN_DEPENDENCY = \"UNKNOWN_DEPENDENCY\";\n\n/** Warning code when `depends_on` forms a directed cycle. */\nexport const DEPENDENCY_CYCLE = \"DEPENDENCY_CYCLE\";\n\n/**\n * Finds directed cycles in the dependency graph: edge `u → v` when task `u` lists `v` in `depends_on`.\n * Only vertices in `taskIds` participate; edges to ids outside `taskIds` are ignored here (handled as warnings in `compileSnapshot`).\n */\nexport function detectCycles(\n taskIds: Set<string>,\n deps: Map<string, string[]>,\n): string[][] {\n const cycles: string[][] = [];\n /** Finished nodes (BLACK). */\n const visited = new Set<string>();\n /** Nodes on the current DFS path (GRAY). */\n const visiting = new Set<string>();\n const stack: string[] = [];\n\n function recordCycle(fromIndex: number): void {\n cycles.push(stack.slice(fromIndex));\n }\n\n function dfs(u: string): void {\n visiting.add(u);\n stack.push(u);\n\n for (const v of deps.get(u) ?? []) {\n if (!taskIds.has(v)) {\n continue;\n }\n if (visiting.has(v)) {\n const i = stack.indexOf(v);\n if (i !== -1) {\n recordCycle(i);\n }\n continue;\n }\n if (!visited.has(v)) {\n dfs(v);\n }\n }\n\n stack.pop();\n visiting.delete(u);\n visited.add(u);\n }\n\n for (const id of taskIds) {\n if (!visited.has(id)) {\n dfs(id);\n }\n }\n\n return cycles;\n}\n\nfunction formatCycle(nodes: string[]): string {\n return nodes.join(\" → \");\n}\n\n/**\n * Builds a snapshot from tasks, with warnings for unknown dependency ids and dependency cycles.\n */\nexport function compileSnapshot(tasks: Task[], now?: Date): Snapshot {\n const generatedAt = (now ?? new Date()).toISOString();\n const taskList = [...tasks];\n const taskIds = new Set(taskList.map((t) => t.id));\n const deps = new Map<string, string[]>();\n for (const t of taskList) {\n deps.set(t.id, t.depends_on ?? []);\n }\n\n const warnings: Snapshot[\"warnings\"] = [];\n\n for (const t of taskList) {\n for (const depId of t.depends_on ?? []) {\n if (!taskIds.has(depId)) {\n warnings.push({\n code: UNKNOWN_DEPENDENCY,\n message: `Task \"${t.id}\" depends on unknown task id \"${depId}\"`,\n taskId: t.id,\n });\n }\n }\n }\n\n for (const cycle of detectCycles(taskIds, deps)) {\n warnings.push({\n code: DEPENDENCY_CYCLE,\n message: `Dependency cycle: ${formatCycle(cycle)}`,\n taskId: cycle[0],\n });\n }\n\n return {\n generated_at: generatedAt,\n tasks: taskList,\n warnings,\n };\n}\n\nexport function writeSnapshot(snapshotPath: string, snapshot: Snapshot): void {\n const parsed = SnapshotSchema.parse(snapshot);\n const dir = path.dirname(snapshotPath);\n fs.mkdirSync(dir, { recursive: true });\n const body = `${JSON.stringify(parsed, null, 2)}\\n`;\n fs.writeFileSync(snapshotPath, body, \"utf8\");\n}\n","import { z } from \"zod\";\n\nimport { TaskSchema } from \"./task.js\";\n\nexport const SnapshotSchema = z\n .object({\n generated_at: z.string().datetime({ offset: true }),\n tasks: z.array(TaskSchema),\n warnings: z.array(\n z\n .object({\n code: z.string(),\n message: z.string(),\n taskId: z.string().optional(),\n })\n .strict(),\n ),\n })\n .strict();\n\nexport type Snapshot = z.infer<typeof SnapshotSchema>;\n","import { z } from \"zod\";\n\nexport const TaskStatusSchema = z.enum([\n \"draft\",\n \"todo\",\n \"in_progress\",\n \"in_review\",\n \"done\",\n \"cancelled\",\n]);\n\nexport type TaskStatus = z.infer<typeof TaskStatusSchema>;\n\n/** YYYY-MM-DD (ISO 8601 calendar date). */\nconst isoDateStringSchema = z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}$/, \"Expected ISO date string (YYYY-MM-DD)\");\n\n/**\n * GitHub issue link metadata. `null` means the task is not linked to an issue (e.g. local draft).\n */\nconst TaskGitHubSchema = z\n .object({\n issue_number: z.number().int(),\n synced_at: z.string().datetime({ offset: true }),\n url: z.string().url(),\n })\n .nullable();\n\nconst TaskAiSchema = z\n .object({\n summary: z.string().optional(),\n acceptance_criteria: z.array(z.string()).optional(),\n implementation_context: z.array(z.string()).optional(),\n test_strategy: z.array(z.string()).optional(),\n constraints: z.array(z.string()).optional(),\n })\n .strict()\n .optional();\n\nexport const TaskSchema = z\n .object({\n id: z.string(),\n title: z.string(),\n description: z.string().optional(),\n status: TaskStatusSchema,\n priority: z.enum([\"p0\", \"p1\", \"p2\", \"p3\"]).optional(),\n type: z.enum([\"feature\", \"bug\", \"chore\", \"epic\"]),\n assignee: z.string().optional(),\n milestone: z.string().optional(),\n branch: z.string().optional(),\n labels: z.array(z.string()).default([]),\n parent: z.string().nullable().optional(),\n depends_on: z.array(z.string()).default([]),\n blocks: z.array(z.string()).default([]),\n due_date: isoDateStringSchema.optional(),\n start_date: isoDateStringSchema.optional(),\n estimate: z.enum([\"xs\", \"sm\", \"md\", \"lg\", \"xl\"]).optional(),\n github: TaskGitHubSchema.optional(),\n refs: z\n .array(\n z\n .object({\n type: z.string(),\n path: z.string(),\n })\n .strict(),\n )\n .default([]),\n ai: TaskAiSchema,\n created_at: z.string().datetime({ offset: true }),\n updated_at: z.string().datetime({ offset: true }),\n })\n .strict();\n\nexport type Task = z.infer<typeof TaskSchema>;\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst MAX_TRAIL_ROOT_WALK = 20;\n\n/**\n * Walks upward from `startDir` looking for a Trail project root: a directory\n * that contains `.trail/config.json`.\n *\n * @returns The **project root** directory (the parent of the `.trail` folder),\n * or `null` if none is found within the walk limit. This is not the path to\n * `.trail` itself — use {@link trailPaths} for `.trail`-relative paths.\n */\nexport function findTrailRoot(startDir: string): string | null {\n let dir = path.resolve(startDir);\n for (let i = 0; i < MAX_TRAIL_ROOT_WALK; i++) {\n const configPath = path.join(dir, \".trail\", \"config.json\");\n if (fs.existsSync(configPath)) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) {\n break;\n }\n dir = parent;\n }\n return null;\n}\n\nexport interface TrailPaths {\n root: string;\n trailDir: string;\n tasksDir: string;\n configPath: string;\n snapshotPath: string;\n gitignorePath: string;\n}\n\n/** Resolved paths under a Trail project root (the directory that contains `.trail`). */\nexport function trailPaths(root: string): TrailPaths {\n const trailDir = path.join(root, \".trail\");\n return {\n root,\n trailDir,\n tasksDir: path.join(trailDir, \"tasks\"),\n configPath: path.join(trailDir, \"config.json\"),\n snapshotPath: path.join(trailDir, \"snapshot.json\"),\n gitignorePath: path.join(trailDir, \".gitignore\"),\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nimport type { TrailError } from \"./errors.js\";\nimport { TaskSchema, type Task } from \"../schemas/task.js\";\n\n/** Thrown by task-store when validation fails; inspect `.trailError` for `VALIDATION_FAILED`. */\nexport type TaskStoreError = Error & { trailError: TrailError };\n\nexport function toValidationError(\n zodError: z.ZodError,\n context?: string,\n): Extract<TrailError, { code: \"VALIDATION_FAILED\" }> {\n const issues = zodError.issues.map(\n (i) => `${i.path.length ? i.path.join(\".\") : \"(root)\"}: ${i.message}`,\n );\n return {\n code: \"VALIDATION_FAILED\",\n message: context\n ? `Task validation failed (${context})`\n : \"Task validation failed\",\n details: zodError.message,\n issues,\n };\n}\n\nfunction throwValidationFailed(\n err: Extract<TrailError, { code: \"VALIDATION_FAILED\" }>,\n): never {\n const e = new Error(`[VALIDATION_FAILED] ${err.message}`) as TaskStoreError;\n e.name = \"TrailError\";\n e.trailError = err;\n throw e;\n}\n\nexport function isTaskStoreValidationError(\n e: unknown,\n): e is TaskStoreError & { trailError: Extract<TrailError, { code: \"VALIDATION_FAILED\" }> } {\n return (\n e instanceof Error &&\n \"trailError\" in e &&\n typeof (e as TaskStoreError).trailError === \"object\" &&\n (e as TaskStoreError).trailError !== null &&\n \"code\" in (e as TaskStoreError).trailError &&\n (e as TaskStoreError).trailError.code === \"VALIDATION_FAILED\"\n );\n}\n\n/**\n * Lists `*.json` basenames under `tasksDir`, excluding `snapshot.json`, sorted lexicographically.\n */\nexport function listTaskFiles(tasksDir: string): string[] {\n const names = fs.readdirSync(tasksDir);\n return names\n .filter(\n (n) => n.endsWith(\".json\") && n !== \"snapshot.json\",\n )\n .sort((a, b) => a.localeCompare(b));\n}\n\nexport function readTaskFile(filePath: string): Task {\n let raw: unknown;\n try {\n raw = JSON.parse(fs.readFileSync(filePath, \"utf8\"));\n } catch (e) {\n if (e instanceof SyntaxError) {\n throwValidationFailed({\n code: \"VALIDATION_FAILED\",\n message: \"Invalid JSON in task file\",\n details: filePath,\n });\n }\n throw e;\n }\n\n const parsed = TaskSchema.safeParse(raw);\n if (!parsed.success) {\n throwValidationFailed(toValidationError(parsed.error, filePath));\n }\n return parsed.data;\n}\n\nexport function writeTaskFile(filePath: string, task: Task): void {\n const parsed = TaskSchema.safeParse(task);\n if (!parsed.success) {\n throwValidationFailed(toValidationError(parsed.error, filePath));\n }\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n const body = `${JSON.stringify(parsed.data, null, 2)}\\n`;\n fs.writeFileSync(filePath, body, \"utf8\");\n}\n\n/**\n * Loads all task JSON files from `tasksDir`. Returns an empty array if the directory is missing.\n * Stops on the first file that fails to parse or validate.\n */\nexport function loadAllTasks(tasksDir: string): Task[] {\n if (!fs.existsSync(tasksDir)) {\n return [];\n }\n const files = listTaskFiles(tasksDir);\n return files.map((name) => readTaskFile(path.join(tasksDir, name)));\n}\n\n/**\n * Resolves the task file for `id`: prefers `${id}.json` when it exists and its `id` matches;\n * otherwise scans `*.json` for a task whose `id` field equals `id`.\n */\nexport function findTaskFileById(\n tasksDir: string,\n id: string,\n): { filePath: string; task: Task } | null {\n if (!fs.existsSync(tasksDir)) {\n return null;\n }\n const direct = path.join(tasksDir, `${id}.json`);\n if (fs.existsSync(direct)) {\n const task = readTaskFile(direct);\n if (task.id === id) {\n return { filePath: direct, task };\n }\n }\n for (const name of listTaskFiles(tasksDir)) {\n const filePath = path.join(tasksDir, name);\n const task = readTaskFile(filePath);\n if (task.id === id) {\n return { filePath, task };\n }\n }\n return null;\n}\n","export function printJson(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n}\n","import type { TrailError } from \"../../core/errors.js\";\nimport { findTrailRoot, trailPaths } from \"../../core/paths.js\";\nimport { findTaskFileById, loadAllTasks } from \"../../core/task-store.js\";\nimport type { Task } from \"../../schemas/task.js\";\nimport { printJson } from \"../json.js\";\n\n/** Compact task packet for LLM prompts (design: “context packet”). */\nexport function buildContextPacket(\n task: Task,\n allTasks: Task[],\n): Record<string, unknown> {\n const depTasks = task.depends_on\n .map((id) => allTasks.find((t) => t.id === id))\n .filter((t): t is Task => t !== undefined);\n\n return {\n id: task.id,\n title: task.title,\n status: task.status,\n priority: task.priority,\n goal: task.ai?.summary ?? task.description,\n depends_on: task.depends_on,\n depends_on_titles: Object.fromEntries(\n depTasks.map((t) => [t.id, t.title]),\n ),\n implementation_context: task.ai?.implementation_context ?? [],\n constraints: task.ai?.constraints ?? [],\n definition_of_done: task.ai?.acceptance_criteria ?? [],\n test_strategy: task.ai?.test_strategy ?? [],\n refs: task.refs,\n github: task.github,\n };\n}\n\nexport function runContext(options: { id: string }): void {\n const root = findTrailRoot(process.cwd());\n if (root === null) {\n const err: TrailError = {\n code: \"NOT_A_TRAIL_REPO\",\n message:\n \"Not a Trail repository (missing .trail/config.json). Run `trail init` first.\",\n path: process.cwd(),\n };\n throw err;\n }\n const paths = trailPaths(root);\n const resolved = findTaskFileById(paths.tasksDir, options.id);\n if (resolved === null) {\n throw new Error(`No task with id \"${options.id}\"`);\n }\n const allTasks = loadAllTasks(paths.tasksDir);\n printJson(buildContextPacket(resolved.task, allTasks));\n}\n","import type { Task } from \"../schemas/task.js\";\nimport { findTaskFileById, writeTaskFile } from \"./task-store.js\";\n\nfunction uniq(ids: string[]): string[] {\n return [...new Set(ids)];\n}\n\n/**\n * Ensures `taskId` depends on `dependsOnId` and the reverse `blocks` edge exists.\n */\nexport function addDependency(\n tasksDir: string,\n taskId: string,\n dependsOnId: string,\n updatedAtIso: string,\n): void {\n if (taskId === dependsOnId) {\n throw new Error(\"A task cannot depend on itself\");\n }\n const a = findTaskFileById(tasksDir, taskId);\n const b = findTaskFileById(tasksDir, dependsOnId);\n if (a === null) {\n throw new Error(`No task with id \"${taskId}\"`);\n }\n if (b === null) {\n throw new Error(`No task with id \"${dependsOnId}\"`);\n }\n\n const nextA: Task = {\n ...a.task,\n depends_on: uniq([...a.task.depends_on, dependsOnId]),\n updated_at: updatedAtIso,\n };\n const nextB: Task = {\n ...b.task,\n blocks: uniq([...b.task.blocks, taskId]),\n updated_at: updatedAtIso,\n };\n\n writeTaskFile(a.filePath, nextA);\n writeTaskFile(b.filePath, nextB);\n}\n\n/**\n * Removes `dependsOnId` from `taskId.depends_on` and `taskId` from `dependsOnId.blocks` if present.\n */\nexport function removeDependency(\n tasksDir: string,\n taskId: string,\n dependsOnId: string,\n updatedAtIso: string,\n): void {\n const a = findTaskFileById(tasksDir, taskId);\n const b = findTaskFileById(tasksDir, dependsOnId);\n if (a === null) {\n throw new Error(`No task with id \"${taskId}\"`);\n }\n if (b === null) {\n throw new Error(`No task with id \"${dependsOnId}\"`);\n }\n\n const nextA: Task = {\n ...a.task,\n depends_on: a.task.depends_on.filter((x) => x !== dependsOnId),\n updated_at: updatedAtIso,\n };\n const nextB: Task = {\n ...b.task,\n blocks: b.task.blocks.filter((x) => x !== taskId),\n updated_at: updatedAtIso,\n };\n\n writeTaskFile(a.filePath, nextA);\n writeTaskFile(b.filePath, nextB);\n}\n\n/** Graph edges as `{ from, to }` meaning `from` depends on `to`. */\nexport function listDependencyEdges(tasks: Task[]): Array<{ from: string; to: string }> {\n const edges: Array<{ from: string; to: string }> = [];\n for (const t of tasks) {\n for (const d of t.depends_on) {\n edges.push({ from: t.id, to: d });\n }\n }\n return edges;\n}\n","import fs from \"node:fs\";\n\nimport type { TrailError } from \"../core/errors.js\";\nimport { maybePullBeforeRead } from \"../core/maybe-pull.js\";\nimport { findTrailRoot, trailPaths, type TrailPaths } from \"../core/paths.js\";\nimport { loadAllTasks } from \"../core/task-store.js\";\nimport { TrailConfigSchema, type TrailConfig } from \"../schemas/config.js\";\nimport type { Task } from \"../schemas/task.js\";\n\nexport type TrailReadContext = {\n root: string;\n paths: TrailPaths;\n config: TrailConfig;\n tasks: Task[];\n};\n\nexport async function loadTrailReadContext(cwd: string): Promise<TrailReadContext> {\n const root = findTrailRoot(cwd);\n if (root === null) {\n const err: TrailError = {\n code: \"NOT_A_TRAIL_REPO\",\n message:\n \"Not a Trail repository (missing .trail/config.json). Run `trail init` first.\",\n path: cwd,\n };\n throw err;\n }\n\n const paths = trailPaths(root);\n const raw = fs.readFileSync(paths.configPath, \"utf-8\");\n const config = TrailConfigSchema.parse(JSON.parse(raw));\n await maybePullBeforeRead(config, paths);\n const tasks = loadAllTasks(paths.tasksDir);\n return { root, paths, config, tasks };\n}\n","import * as childProcess from \"node:child_process\";\nimport type { TrailError } from \"./errors.js\";\n\nexport type ResolveTokenResult =\n | { ok: true; token: string }\n | { ok: false; error: TrailError };\n\nconst AUTH_HINT =\n \"Set GITHUB_TOKEN or install gh and run gh auth login\";\n\nfunction authRequired(message: string): ResolveTokenResult {\n return {\n ok: false,\n error: {\n code: \"AUTH_REQUIRED\",\n message,\n hint: AUTH_HINT,\n },\n };\n}\n\n/**\n * Resolves a GitHub API token from `GITHUB_TOKEN` (trimmed) or `gh auth token`.\n */\nexport function resolveGitHubToken(\n env?: NodeJS.ProcessEnv,\n): ResolveTokenResult {\n const e = env ?? process.env;\n const fromEnv = e.GITHUB_TOKEN;\n if (typeof fromEnv === \"string\" && fromEnv.trim() !== \"\") {\n return { ok: true, token: fromEnv.trim() };\n }\n\n try {\n const out = childProcess.execFileSync(\"gh\", [\"auth\", \"token\"], {\n encoding: \"utf-8\",\n });\n const token = out.trim();\n if (token === \"\") {\n return authRequired(\"GitHub CLI returned an empty token\");\n }\n return { ok: true, token };\n } catch {\n return authRequired(\n \"No GitHub token found; could not read from environment or gh CLI\",\n );\n }\n}\n","/**\n * Discriminated union of Trail CLI errors. Narrow on `code` for type-safe handling.\n */\nexport type TrailErrorCode =\n | \"AUTH_REQUIRED\"\n | \"AUTH_FAILED\"\n | \"NOT_A_TRAIL_REPO\"\n | \"VALIDATION_FAILED\"\n | \"GITHUB_API\"\n | \"SYNC_CONFLICT\";\n\nexport type TrailError =\n | { code: \"AUTH_REQUIRED\"; message: string; hint?: string }\n | { code: \"AUTH_FAILED\"; message: string }\n | { code: \"NOT_A_TRAIL_REPO\"; message: string; path?: string }\n | {\n code: \"VALIDATION_FAILED\";\n message: string;\n details?: string;\n issues?: string[];\n }\n | { code: \"GITHUB_API\"; message: string; status?: number; body?: string }\n | { code: \"SYNC_CONFLICT\"; message: string; paths?: string[] };\n\n/**\n * Human-readable text for CLI stderr: `[CODE] message`, with optional extra lines.\n */\nexport function formatTrailError(error: TrailError): string {\n const lines: string[] = [`[${error.code}] ${error.message}`];\n\n switch (error.code) {\n case \"AUTH_REQUIRED\": {\n if (error.hint) {\n lines.push(error.hint);\n }\n break;\n }\n case \"AUTH_FAILED\": {\n break;\n }\n case \"NOT_A_TRAIL_REPO\": {\n if (error.path) {\n lines.push(`Path: ${error.path}`);\n }\n break;\n }\n case \"VALIDATION_FAILED\": {\n if (error.details) {\n lines.push(error.details);\n }\n if (error.issues && error.issues.length > 0) {\n for (const issue of error.issues) {\n lines.push(` - ${issue}`);\n }\n }\n break;\n }\n case \"GITHUB_API\": {\n if (error.status !== undefined) {\n lines.push(`HTTP status: ${error.status}`);\n }\n if (error.body) {\n lines.push(error.body);\n }\n break;\n }\n case \"SYNC_CONFLICT\": {\n if (error.paths && error.paths.length > 0) {\n lines.push(`Paths: ${error.paths.join(\", \")}`);\n }\n break;\n }\n default: {\n const _exhaustive: never = error;\n return _exhaustive;\n }\n }\n\n return lines.join(\"\\n\");\n}\n","import type { GitHubIssue } from \"./github-types.js\";\n\nconst USER_AGENT = \"trail-cli/0.0.1\";\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/$/, \"\");\n}\n\nexport class GitHubClient {\n private readonly token: string;\n private readonly baseUrl: string;\n\n constructor(token: string, baseUrl = \"https://api.github.com\") {\n this.token = token;\n this.baseUrl = normalizeBaseUrl(baseUrl);\n }\n\n private async request(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<Response> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? path : `/${path}`}`;\n const headers = new Headers({\n Authorization: `Bearer ${this.token}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n \"User-Agent\": USER_AGENT,\n });\n if (body !== undefined) {\n headers.set(\"Content-Type\", \"application/json\");\n }\n return fetch(url, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n }\n\n private async parseJson<T>(response: Response): Promise<T> {\n const text = await response.text();\n if (!response.ok) {\n const snippet = text.slice(0, 200);\n throw new Error(`GitHub API ${response.status}: ${snippet}`);\n }\n return JSON.parse(text) as T;\n }\n\n async listIssues(\n owner: string,\n repo: string,\n params: {\n state: \"open\" | \"all\" | \"closed\";\n per_page: number;\n page: number;\n },\n ): Promise<GitHubIssue[]> {\n const search = new URLSearchParams({\n state: params.state,\n per_page: String(params.per_page),\n page: String(params.page),\n });\n const path = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues?${search}`;\n const response = await this.request(\"GET\", path);\n return this.parseJson<GitHubIssue[]>(response);\n }\n\n async getIssue(\n owner: string,\n repo: string,\n issueNumber: number,\n ): Promise<GitHubIssue> {\n const path = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${issueNumber}`;\n const response = await this.request(\"GET\", path);\n return this.parseJson<GitHubIssue>(response);\n }\n\n async updateIssue(\n owner: string,\n repo: string,\n issueNumber: number,\n patch: Record<string, unknown>,\n ): Promise<GitHubIssue> {\n const path = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${issueNumber}`;\n const response = await this.request(\"PATCH\", path, patch);\n return this.parseJson<GitHubIssue>(response);\n }\n\n async createIssueComment(\n owner: string,\n repo: string,\n issueNumber: number,\n body: string,\n ): Promise<{ id: number }> {\n const path = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues/${issueNumber}/comments`;\n const response = await this.request(\"POST\", path, { body });\n return this.parseJson<{ id: number }>(response);\n }\n\n /** Create a new issue. Returns the created issue (same shape as list/get). */\n async createIssue(\n owner: string,\n repo: string,\n input: { title: string; body?: string; labels?: string[] },\n ): Promise<GitHubIssue> {\n const path = `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/issues`;\n const response = await this.request(\"POST\", path, {\n title: input.title,\n body: input.body ?? \"\",\n labels: input.labels ?? [],\n });\n return this.parseJson<GitHubIssue>(response);\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { GitHubClient } from \"./github-client.js\";\nimport { issueToTask, taskToIssueUpdate } from \"./github-mapper.js\";\nimport { compileSnapshot, writeSnapshot } from \"./compile-snapshot.js\";\nimport { loadAllTasks, readTaskFile, writeTaskFile } from \"./task-store.js\";\nimport type { Task } from \"../schemas/task.js\";\n\nconst ISSUES_PER_PAGE = 100;\n\nexport async function pullSync(options: {\n client: GitHubClient;\n owner: string;\n repo: string;\n tasksDir: string;\n now?: Date;\n}): Promise<void> {\n const { client, owner, repo, tasksDir } = options;\n const now = options.now ?? new Date();\n let page = 1;\n\n for (;;) {\n const issues = await client.listIssues(owner, repo, {\n state: \"all\",\n per_page: ISSUES_PER_PAGE,\n page,\n });\n\n if (issues.length === 0) {\n break;\n }\n\n for (const issue of issues) {\n const filePath = path.join(tasksDir, `${issue.number}.json`);\n let existing: Task | null = null;\n if (fs.existsSync(filePath)) {\n existing = readTaskFile(filePath);\n }\n const task = issueToTask(issue, existing, now);\n writeTaskFile(filePath, task);\n }\n\n if (issues.length < ISSUES_PER_PAGE) {\n break;\n }\n page += 1;\n }\n}\n\nfunction isLinkedTask(\n task: Task,\n): task is Task & { github: NonNullable<Task[\"github\"]> } {\n return task.github != null && typeof task.github === \"object\";\n}\n\nexport async function pushSync(options: {\n client: GitHubClient;\n owner: string;\n repo: string;\n tasks: Task[];\n}): Promise<void> {\n const { client, owner, repo, tasks } = options;\n\n for (const task of tasks) {\n if (task.status === \"draft\") {\n continue;\n }\n if (!isLinkedTask(task)) {\n continue;\n }\n const patch = taskToIssueUpdate(task);\n await client.updateIssue(owner, repo, task.github.issue_number, patch);\n }\n}\n\nexport async function syncFull(options: {\n client: GitHubClient;\n owner: string;\n repo: string;\n tasksDir: string;\n snapshotPath: string;\n now?: Date;\n}): Promise<void> {\n const { client, owner, repo, tasksDir, snapshotPath, now } = options;\n await pullSync({ client, owner, repo, tasksDir, now });\n const tasks = loadAllTasks(tasksDir);\n const snapshot = compileSnapshot(tasks, now);\n writeSnapshot(snapshotPath, snapshot);\n}\n\nexport async function fullSync(options: {\n client: GitHubClient;\n owner: string;\n repo: string;\n tasksDir: string;\n snapshotPath: string;\n now?: Date;\n}): Promise<void> {\n const { client, owner, repo, tasksDir, snapshotPath, now } = options;\n await pullSync({ client, owner, repo, tasksDir, now });\n const tasks = loadAllTasks(tasksDir);\n await pushSync({ client, owner, repo, tasks });\n const snapshot = compileSnapshot(tasks, now);\n writeSnapshot(snapshotPath, snapshot);\n}\n","import type { GitHubIssue } from \"./github-types.js\";\nimport { TaskSchema, type Task } from \"../schemas/task.js\";\n\nfunction statusFromIssue(issue: GitHubIssue, existing: Task | null): Task[\"status\"] {\n if (issue.state === \"closed\") {\n return \"done\";\n }\n const prev = existing?.status;\n if (prev === \"in_progress\" || prev === \"in_review\") {\n return prev;\n }\n return \"todo\";\n}\n\nfunction parseIssueTimestamp(issue: GitHubIssue, fallback: Date): string {\n if (issue.updated_at.trim() === \"\") {\n return fallback.toISOString();\n }\n return issue.updated_at;\n}\n\n/**\n * Maps a GitHub issue to a Trail task. GitHub wins for title, body, labels, assignee, milestone;\n * local-only fields are preserved from `existing` when present.\n */\nexport function issueToTask(\n issue: GitHubIssue,\n existing: Task | null,\n now: Date,\n): Task {\n const updatedAt = parseIssueTimestamp(issue, now);\n const createdAt =\n existing?.created_at ?? (issue.updated_at.trim() !== \"\" ? issue.updated_at : now.toISOString());\n\n const raw: Task = {\n id: String(issue.number),\n title: issue.title,\n description: issue.body ?? \"\",\n status: statusFromIssue(issue, existing),\n type: existing?.type ?? \"feature\",\n labels: issue.labels.map((l) => l.name),\n assignee: issue.assignee?.login,\n milestone: issue.milestone?.title,\n depends_on: existing?.depends_on ?? [],\n blocks: existing?.blocks ?? [],\n refs: existing?.refs ?? [],\n ai: existing?.ai,\n branch: existing?.branch,\n estimate: existing?.estimate,\n priority: existing?.priority,\n parent: existing?.parent,\n due_date: existing?.due_date,\n start_date: existing?.start_date,\n github: {\n issue_number: issue.number,\n synced_at: now.toISOString(),\n url: issue.html_url,\n },\n created_at: createdAt,\n updated_at: updatedAt,\n };\n\n return TaskSchema.parse(raw);\n}\n\n/**\n * Maps a Trail task to fields for `GitHubClient.updateIssue`.\n */\nexport function taskToIssueUpdate(task: Task): {\n title?: string;\n body?: string;\n state?: \"open\" | \"closed\";\n labels?: string[];\n} {\n const labels = [...task.labels];\n if (task.priority) {\n const priorityLabel = `priority:${task.priority}`;\n if (!labels.includes(priorityLabel)) {\n labels.push(priorityLabel);\n }\n }\n\n const state: \"open\" | \"closed\" =\n task.status === \"done\" || task.status === \"cancelled\" ? \"closed\" : \"open\";\n\n return {\n title: task.title,\n body: task.description ?? \"\",\n state,\n labels,\n };\n}\n","import { resolveGitHubToken } from \"./auth.js\";\nimport { formatTrailError } from \"./errors.js\";\nimport { GitHubClient } from \"./github-client.js\";\nimport type { TrailPaths } from \"./paths.js\";\nimport { pullSync } from \"./sync.js\";\nimport type { TrailConfig } from \"../schemas/config.js\";\n\n/**\n * When `auto_sync_on_command` is on and preset is not offline, attempts a pull\n * before read-only commands. On missing token or pull failure, prints a\n * warning to stderr and continues with local task files.\n */\nexport async function maybePullBeforeRead(\n config: TrailConfig,\n paths: TrailPaths,\n): Promise<void> {\n if (!config.sync.auto_sync_on_command || config.sync.preset === \"offline\") {\n return;\n }\n\n const tokenResult = resolveGitHubToken();\n if (!tokenResult.ok) {\n console.warn(\n `Warning: ${formatTrailError(tokenResult.error)} — continuing with local tasks.`,\n );\n return;\n }\n\n const client = new GitHubClient(tokenResult.token);\n const { owner, repo } = config.github;\n try {\n await pullSync({ client, owner, repo, tasksDir: paths.tasksDir });\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.warn(`Warning: auto-pull failed (${msg}) — continuing with local tasks.`);\n }\n}\n","import { z } from \"zod\";\n\nexport const TrailConfigSchema = z\n .object({\n github: z\n .object({\n owner: z.string(),\n repo: z.string(),\n })\n .strict(),\n sync: z\n .object({\n preset: z.enum([\"collaborative\", \"solo\", \"offline\"]),\n auto_sync_on_command: z.boolean(),\n ui_poll_interval_seconds: z.number(),\n ui_idle_backoff: z.boolean(),\n })\n .strict(),\n /** Last successful full sync; useful for future `trail status` and similar. */\n last_full_sync_at: z.string().datetime({ offset: true }).optional(),\n })\n .strict();\n\nexport type TrailConfig = z.infer<typeof TrailConfigSchema>;\n","import type { Task, TaskStatus } from \"../../schemas/task.js\";\nimport { printJson } from \"../json.js\";\nimport { loadTrailReadContext } from \"../read-context.js\";\n\nconst DEFAULT_LIMIT = 25;\nconst HIDDEN_BY_DEFAULT = new Set<TaskStatus>([\"done\", \"cancelled\"]);\n\nexport type ListOptions = {\n all?: boolean;\n limit?: number;\n status?: string;\n label?: string;\n json?: boolean;\n};\n\n/** Shared filter/sort/limit logic for CLI list and MCP. */\nexport function selectTasksForList(tasks: Task[], options: ListOptions): Task[] {\n const all = options.all === true;\n const limit = options.limit ?? DEFAULT_LIMIT;\n const statusFilter = options.status as TaskStatus | undefined;\n const labelFilter = options.label;\n\n let rows = tasks.filter((t) => all || !HIDDEN_BY_DEFAULT.has(t.status));\n if (statusFilter !== undefined) {\n rows = rows.filter((t) => t.status === statusFilter);\n }\n if (labelFilter !== undefined) {\n rows = rows.filter((t) => t.labels.includes(labelFilter));\n }\n\n rows.sort((a, b) => a.id.localeCompare(b.id, undefined, { numeric: true }));\n return rows.slice(0, limit);\n}\n\nfunction slimTask(t: Task) {\n return {\n id: t.id,\n title: t.title,\n status: t.status,\n priority: t.priority,\n labels: t.labels,\n };\n}\n\nfunction formatTable(tasks: Task[]): void {\n const idW = Math.max(4, ...tasks.map((t) => t.id.length), 2);\n const statusW = Math.max(6, ...tasks.map((t) => t.status.length), 6);\n const header = `${\"ID\".padEnd(idW)} ${\"STATUS\".padEnd(statusW)} TITLE`;\n console.log(header);\n console.log(\"-\".repeat(header.length));\n for (const t of tasks) {\n console.log(`${t.id.padEnd(idW)} ${t.status.padEnd(statusW)} ${t.title}`);\n }\n}\n\nexport async function runList(options: ListOptions): Promise<void> {\n const { tasks } = await loadTrailReadContext(process.cwd());\n const rows = selectTasksForList(tasks, options);\n\n if (options.json) {\n printJson(rows.map(slimTask));\n return;\n }\n\n if (rows.length === 0) {\n console.log(\"No tasks match the filters.\");\n return;\n }\n\n formatTable(rows);\n}\n","import type { Task } from \"../schemas/task.js\";\n\nconst TERMINAL: ReadonlySet<Task[\"status\"]> = new Set([\"done\", \"cancelled\"]);\n\nfunction priorityRank(p: Task[\"priority\"]): number {\n switch (p) {\n case \"p0\":\n return 0;\n case \"p1\":\n return 1;\n case \"p2\":\n return 2;\n case \"p3\":\n return 3;\n default:\n return 4;\n }\n}\n\n/** Exported for tests and any CLI that needs consistent id ordering. */\nexport function compareTaskIds(a: string, b: string): number {\n if (/^\\d+$/.test(a) && /^\\d+$/.test(b)) {\n const ba = BigInt(a);\n const bb = BigInt(b);\n return ba < bb ? -1 : ba > bb ? 1 : 0;\n }\n return a.localeCompare(b);\n}\n\nfunction dependencyResolved(dep: Task | undefined): boolean {\n if (dep === undefined) {\n return false;\n }\n return TERMINAL.has(dep.status);\n}\n\nexport function isTaskBlocked(task: Task, byId: Map<string, Task>): boolean {\n for (const depId of task.depends_on) {\n if (!dependencyResolved(byId.get(depId))) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Picks the next actionable task: not done/cancelled, not blocked by open\n * dependencies, highest priority (p0 first), then lowest id.\n */\nexport function selectNextTask(tasks: Task[]): Task | null {\n const byId = new Map(tasks.map((t) => [t.id, t]));\n const candidates = tasks.filter(\n (t) => !TERMINAL.has(t.status) && !isTaskBlocked(t, byId),\n );\n if (candidates.length === 0) {\n return null;\n }\n\n candidates.sort((a, b) => {\n const pr = priorityRank(a.priority) - priorityRank(b.priority);\n if (pr !== 0) {\n return pr;\n }\n return compareTaskIds(a.id, b.id);\n });\n\n return candidates[0] ?? null;\n}\n","import { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { Command, Option } from \"commander\";\nimport { ZodError } from \"zod\";\n\nimport { formatTrailError, type TrailError, type TrailErrorCode } from \"../core/errors.js\";\nimport { isTaskStoreValidationError } from \"../core/task-store.js\";\nimport { runCreate } from \"./commands/create.js\";\nimport { runContext } from \"./commands/context.js\";\nimport { runDepAdd, runDepRemove } from \"./commands/dep.js\";\nimport { runDone } from \"./commands/done.js\";\nimport { runGraph } from \"./commands/graph.js\";\nimport { runInit } from \"./commands/init.js\";\nimport { runList } from \"./commands/list.js\";\nimport { runNext } from \"./commands/next.js\";\nimport { runPromote } from \"./commands/promote.js\";\nimport { runShow } from \"./commands/show.js\";\nimport { runStatus } from \"./commands/status.js\";\nimport { runSync } from \"./commands/sync.js\";\nimport { runUpdate, UPDATE_STATUS_CHOICES } from \"./commands/update.js\";\nimport { runValidate } from \"./commands/validate.js\";\n\nfunction readCliVersion(): string {\n /** `package.json` lives next to `src/` and `dist/`; entry is `src/index.ts` / `dist/index.js`. */\n const pkgPath = join(dirname(fileURLToPath(import.meta.url)), \"..\", \"package.json\");\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf-8\")) as { version?: string };\n return pkg.version ?? \"0.0.0\";\n}\n\nconst TRAIL_ERROR_CODES = new Set<TrailErrorCode>([\n \"AUTH_REQUIRED\",\n \"AUTH_FAILED\",\n \"NOT_A_TRAIL_REPO\",\n \"VALIDATION_FAILED\",\n \"GITHUB_API\",\n \"SYNC_CONFLICT\",\n]);\n\nfunction isTrailError(value: unknown): value is TrailError {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n if (!(\"code\" in value) || !(\"message\" in value)) {\n return false;\n }\n const code = (value as { code: unknown }).code;\n return typeof code === \"string\" && TRAIL_ERROR_CODES.has(code as TrailErrorCode);\n}\n\n/** Maps thrown values to a stderr line for `trail` when exiting with code 1. */\nexport function getCliFailureMessage(err: unknown): string {\n if (isTrailError(err)) {\n return formatTrailError(err);\n }\n if (err instanceof Error && isTaskStoreValidationError(err)) {\n return formatTrailError(err.trailError);\n }\n if (err instanceof ZodError) {\n return err.message;\n }\n if (err instanceof Error) {\n return err.message;\n }\n return String(err);\n}\n\nexport async function runCli(argv: string[]): Promise<void> {\n const program = new Command();\n program.name(\"trail\").description(\"GitHub-native task management CLI\").version(readCliVersion());\n\n program\n .command(\"init\")\n .description(\"Initialize a Trail project in the current git repository\")\n .addOption(\n new Option(\"--preset <name>\", \"Sync preset\")\n .choices([\"solo\", \"collaborative\", \"offline\"] as const)\n .default(\"solo\"),\n )\n .option(\"--owner <name>\", \"GitHub repository owner (with --repo)\")\n .option(\"--repo <name>\", \"GitHub repository name (with --owner)\")\n .option(\"--skip-agents-md\", \"Do not write AGENTS.md at the repository root\")\n .action(\n (opts: {\n preset: \"solo\" | \"collaborative\" | \"offline\";\n owner?: string;\n repo?: string;\n skipAgentsMd?: boolean;\n }) => {\n runInit({\n preset: opts.preset,\n owner: opts.owner,\n repo: opts.repo,\n skipAgentsMd: opts.skipAgentsMd === true,\n });\n },\n );\n\n program\n .command(\"sync\")\n .description(\"Synchronize local tasks with GitHub Issues\")\n .option(\"--pull\", \"Only pull from GitHub\")\n .option(\"--push\", \"Only push to GitHub\")\n .action(async (opts: { pull?: boolean; push?: boolean }) => {\n await runSync({ pull: opts.pull, push: opts.push });\n });\n\n program\n .command(\"list\")\n .description(\"List tasks (excludes done/cancelled unless --all)\")\n .option(\"--all\", \"Include done and cancelled tasks\")\n .addOption(\n new Option(\"--limit <n>\", \"Max tasks to show\")\n .default(25)\n .argParser((v) => {\n const n = parseInt(v, 10);\n if (Number.isNaN(n) || n < 0) {\n throw new Error(\"--limit must be a non-negative integer\");\n }\n return n;\n }),\n )\n .option(\"--status <status>\", \"Filter by status\")\n .option(\"--label <label>\", \"Filter by label (must appear in task.labels)\")\n .option(\"--json\", \"Print JSON array of slim task objects\")\n .action(\n async (opts: {\n all?: boolean;\n limit: number;\n status?: string;\n label?: string;\n json?: boolean;\n }) => {\n await runList(opts);\n },\n );\n\n program\n .command(\"show\")\n .description(\"Show one task by id\")\n .argument(\"<id>\", \"Task id\")\n .option(\"--json\", \"Print full task JSON\")\n .action(async (id: string, opts: { json?: boolean }) => {\n await runShow({ id, json: opts.json });\n });\n\n program\n .command(\"status\")\n .description(\"Task counts by status and last sync time\")\n .option(\"--json\", \"Print JSON\")\n .action(async (opts: { json?: boolean }) => {\n await runStatus(opts);\n });\n\n program\n .command(\"next\")\n .description(\"Pick the next actionable task by priority and id\")\n .option(\"--json\", \"Print full task JSON or null\")\n .action(async (opts: { json?: boolean }) => {\n await runNext(opts);\n });\n\n program\n .command(\"update\")\n .description(\"Update a task (local file; pushes to GitHub when linked and online)\")\n .argument(\"<id>\", \"Task id\")\n .addOption(new Option(\"--status <status>\", \"New status\").choices(UPDATE_STATUS_CHOICES))\n .addOption(\n new Option(\"--priority <p>\", \"Priority\").choices([\"p0\", \"p1\", \"p2\", \"p3\"] as const),\n )\n .option(\"--title <text>\", \"New title\")\n .action(\n async (\n id: string,\n opts: {\n status?: (typeof UPDATE_STATUS_CHOICES)[number];\n priority?: \"p0\" | \"p1\" | \"p2\" | \"p3\";\n title?: string;\n },\n ) => {\n await runUpdate({\n id,\n status: opts.status,\n priority: opts.priority,\n title: opts.title,\n });\n },\n );\n\n program\n .command(\"done\")\n .description(\"Mark a task done, optionally comment and close the GitHub issue\")\n .argument(\"<id>\", \"Task id\")\n .argument(\"<message...>\", \"Comment body for the linked issue (and suggested commit hint)\")\n .action(async (id: string, messageParts: string[]) => {\n const message = messageParts.join(\" \").trim();\n if (message === \"\") {\n throw new Error(\"Message is required\");\n }\n await runDone({ id, message });\n });\n\n program\n .command(\"validate\")\n .description(\"Compile snapshot and print validation warnings (exit 1 on dependency cycles)\")\n .action(async () => {\n const code = await runValidate();\n process.exitCode = code;\n });\n\n program\n .command(\"create\")\n .description(\"Create a local draft task (not linked to GitHub until promoted)\")\n .requiredOption(\"--title <text>\", \"Task title\")\n .option(\"--description <text>\", \"Description body\")\n .addOption(\n new Option(\"--type <name>\", \"Task type\").choices([\"feature\", \"bug\", \"chore\", \"epic\"] as const),\n )\n .addOption(new Option(\"--priority <p>\", \"Priority\").choices([\"p0\", \"p1\", \"p2\", \"p3\"] as const))\n .action(\n (opts: {\n title: string;\n description?: string;\n type?: \"feature\" | \"bug\" | \"chore\" | \"epic\";\n priority?: \"p0\" | \"p1\" | \"p2\" | \"p3\";\n }) => {\n runCreate({\n title: opts.title,\n description: opts.description,\n type: opts.type,\n priority: opts.priority,\n });\n },\n );\n\n program\n .command(\"promote\")\n .description(\"Promote a draft task to a GitHub issue and rename the task file\")\n .argument(\"<id>\", \"Draft task id\")\n .action(async (id: string) => {\n await runPromote({ id });\n });\n\n const dep = program.command(\"dep\").description(\"Add or remove task dependencies\");\n dep\n .command(\"add\")\n .description(\"Record that task A depends on task B (updates blocks/depends_on)\")\n .argument(\"<taskId>\", \"Task id\")\n .argument(\"<dependsOnId>\", \"Id of the task that must be satisfied first\")\n .action((taskId: string, dependsOnId: string) => {\n runDepAdd(taskId, dependsOnId);\n });\n dep\n .command(\"remove\")\n .description(\"Remove a dependency edge between two tasks\")\n .argument(\"<taskId>\", \"Task id\")\n .argument(\"<dependsOnId>\", \"Other task id\")\n .action((taskId: string, dependsOnId: string) => {\n runDepRemove(taskId, dependsOnId);\n });\n\n program\n .command(\"graph\")\n .description(\"Print task dependency edges\")\n .option(\"--json\", \"Print JSON array of { from, to } edges\")\n .action((opts: { json?: boolean }) => {\n runGraph(opts);\n });\n\n program\n .command(\"context\")\n .description(\"Print a compact JSON context packet for an LLM session\")\n .argument(\"<id>\", \"Task id\")\n .action((id: string) => {\n runContext({ id });\n });\n\n program\n .command(\"mcp\")\n .description(\"Run the Trail MCP server (stdio; for editor and agent integrations)\")\n .action(async () => {\n const { runMcpServer } = await import(\"../mcp/run-mcp-server.js\");\n await runMcpServer();\n });\n\n await program.parseAsync(argv);\n}\n","import path from \"node:path\";\n\nimport type { TrailError } from \"../../core/errors.js\";\nimport { generateDraftId } from \"../../core/draft-id.js\";\nimport { findTrailRoot, trailPaths } from \"../../core/paths.js\";\nimport { rebuildSnapshot } from \"../../core/rebuild-snapshot.js\";\nimport { writeTaskFile } from \"../../core/task-store.js\";\nimport { TaskSchema, type Task } from \"../../schemas/task.js\";\n\nexport type CreateOptions = {\n title: string;\n description?: string;\n type?: \"feature\" | \"bug\" | \"chore\" | \"epic\";\n priority?: \"p0\" | \"p1\" | \"p2\" | \"p3\";\n};\n\nexport function runCreate(options: CreateOptions): void {\n const root = findTrailRoot(process.cwd());\n if (root === null) {\n const err: TrailError = {\n code: \"NOT_A_TRAIL_REPO\",\n message:\n \"Not a Trail repository (missing .trail/config.json). Run `trail init` first.\",\n path: process.cwd(),\n };\n throw err;\n }\n\n const paths = trailPaths(root);\n const now = new Date();\n const iso = now.toISOString();\n const id = generateDraftId();\n\n const raw: Task = {\n id,\n title: options.title,\n description: options.description ?? \"\",\n status: \"draft\",\n type: options.type ?? \"feature\",\n labels: [],\n depends_on: [],\n blocks: [],\n refs: [],\n created_at: iso,\n updated_at: iso,\n };\n if (options.priority !== undefined) {\n raw.priority = options.priority;\n }\n\n const task = TaskSchema.parse(raw);\n const filePath = path.join(paths.tasksDir, `${id}.json`);\n writeTaskFile(filePath, task);\n rebuildSnapshot(paths, now);\n\n console.log(`Created draft task ${id}`);\n console.log(` File: ${filePath}`);\n}\n","import { randomBytes } from \"node:crypto\";\n\n/** Stable draft task id prefix + random suffix (e.g. `draft-a1b2c3d4`). */\nexport function generateDraftId(): string {\n return `draft-${randomBytes(4).toString(\"hex\")}`;\n}\n","import { compileSnapshot, writeSnapshot } from \"./compile-snapshot.js\";\nimport { loadAllTasks } from \"./task-store.js\";\nimport type { TrailPaths } from \"./paths.js\";\n\n/** Recompiles `.trail/snapshot.json` from all task files. */\nexport function rebuildSnapshot(paths: TrailPaths, now = new Date()): void {\n const tasks = loadAllTasks(paths.tasksDir);\n const snapshot = compileSnapshot(tasks, now);\n writeSnapshot(paths.snapshotPath, snapshot);\n}\n","import type { TrailError } from \"../../core/errors.js\";\nimport { addDependency, removeDependency } from \"../../core/deps.js\";\nimport { findTrailRoot, trailPaths } from \"../../core/paths.js\";\nimport { rebuildSnapshot } from \"../../core/rebuild-snapshot.js\";\n\nexport function runDepAdd(taskId: string, dependsOnId: string): void {\n const root = findTrailRoot(process.cwd());\n if (root === null) {\n const err: TrailError = {\n code: \"NOT_A_TRAIL_REPO\",\n message:\n \"Not a Trail repository (missing .trail/config.json). Run `trail init` first.\",\n path: process.cwd(),\n };\n throw err;\n }\n const paths = trailPaths(root);\n const iso = new Date().toISOString();\n addDependency(paths.tasksDir, taskId, dependsOnId, iso);\n rebuildSnapshot(paths, new Date(iso));\n console.log(`Added dependency: ${taskId} depends on ${dependsOnId}`);\n}\n\nexport function runDepRemove(taskId: string, dependsOnId: string): void {\n const root = findTrailRoot(process.cwd());\n if (root === null) {\n const err: TrailError = {\n code: \"NOT_A_TRAIL_REPO\",\n message:\n \"Not a Trail repository (missing .trail/config.json). Run `trail init` first.\",\n path: process.cwd(),\n };\n throw err;\n }\n const paths = trailPaths(root);\n const iso = new Date().toISOString();\n removeDependency(paths.tasksDir, taskId, dependsOnId, iso);\n rebuildSnapshot(paths, new Date(iso));\n console.log(`Removed dependency: ${taskId} no longer depends on ${dependsOnId}`);\n}\n","import fs from \"node:fs\";\n\nimport { resolveGitHubToken } from \"../../core/auth.js\";\nimport type { TrailError } from \"../../core/errors.js\";\nimport { GitHubClient } from \"../../core/github-client.js\";\nimport { taskToIssueUpdate } from \"../../core/github-mapper.js\";\nimport { rebuildSnapshot } from \"../../core/rebuild-snapshot.js\";\nimport { findTrailRoot, trailPaths } from \"../../core/paths.js\";\nimport { findTaskFileById, writeTaskFile } from \"../../core/task-store.js\";\nimport { TrailConfigSchema } from \"../../schemas/config.js\";\nimport type { Task } from \"../../schemas/task.js\";\n\nexport type DoneOptions = {\n id: string;\n message: string;\n};\n\nfunction isLinkedTask(\n task: Task,\n): task is Task & { github: NonNullable<Task[\"github\"]> } {\n return task.github != null && typeof task.github === \"object\";\n}\n\nfunction conventionalPrefix(type: Task[\"type\"]): string {\n switch (type) {\n case \"bug\":\n return \"fix\";\n case \"chore\":\n return \"chore\";\n case \"epic\":\n case \"feature\":\n return \"feat\";\n default:\n return \"feat\";\n }\n}\n\nexport async function runDone(options: DoneOptions): Promise<void> {\n const root = findTrailRoot(process.cwd());\n if (root === null) {\n const err: TrailError = {\n code: \"NOT_A_TRAIL_REPO\",\n message:\n \"Not a Trail repository (missing .trail/config.json). Run `trail init` first.\",\n path: process.cwd(),\n };\n throw err;\n }\n\n const paths = trailPaths(root);\n const raw = fs.readFileSync(paths.configPath, \"utf-8\");\n const config = TrailConfigSchema.parse(JSON.parse(raw));\n\n const resolved = findTaskFileById(paths.tasksDir, options.id);\n if (resolved === null) {\n throw new Error(`No task with id \"${options.id}\"`);\n }\n\n const now = new Date();\n const iso = now.toISOString();\n let next: Task = {\n ...resolved.task,\n status: \"done\",\n updated_at: iso,\n };\n\n writeTaskFile(resolved.filePath, next);\n\n const offline = config.sync.preset === \"offline\";\n const tokenResult = resolveGitHubToken();\n if (!offline && tokenResult.ok && isLinkedTask(next)) {\n const client = new GitHubClient(tokenResult.token);\n const { owner, repo } = config.github;\n const n = next.github.issue_number;\n await client.createIssueComment(owner, repo, n, options.message);\n await client.updateIssue(\n owner,\n repo,\n n,\n taskToIssueUpdate(next) as Record<string, unknown>,\n );\n const synced: Task = {\n ...next,\n github: {\n ...next.github,\n synced_at: now.toISOString(),\n },\n };\n writeTaskFile(resolved.filePath, synced);\n next = synced;\n }\n\n rebuildSnapshot(paths, now);\n\n if (isLinkedTask(next)) {\n const prefix = conventionalPrefix(next.type);\n const oneLine = options.message.replace(/\\s+/g, \" \").trim();\n console.log(\n `Suggested commit: ${prefix}: ${oneLine} (closes #${next.github.issue_number})`,\n );\n }\n}\n","import type { TrailError } from \"../../core/errors.js\";\nimport { listDependencyEdges } from \"../../core/deps.js\";\nimport { findTrailRoot, trailPaths } from \"../../core/paths.js\";\nimport { loadAllTasks } from \"../../core/task-store.js\";\nimport { printJson } from \"../json.js\";\n\nexport function runGraph(options: { json?: boolean }): void {\n const root = findTrailRoot(process.cwd());\n if (root === null) {\n const err: TrailError = {\n code: \"NOT_A_TRAIL_REPO\",\n message:\n \"Not a Trail repository (missing .trail/config.json). Run `trail init` first.\",\n path: process.cwd(),\n };\n throw err;\n }\n const paths = trailPaths(root);\n const tasks = loadAllTasks(paths.tasksDir);\n const edges = listDependencyEdges(tasks);\n\n if (options.json) {\n printJson(edges);\n return;\n }\n\n if (edges.length === 0) {\n console.log(\"No dependencies.\");\n return;\n }\n\n for (const e of edges) {\n console.log(`${e.from} → depends on → ${e.to}`);\n }\n}\n","import * as childProcess from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { TrailConfigSchema } from \"../../schemas/config.js\";\nimport type { TrailError } from \"../../core/errors.js\";\nimport { USER_AGENTS_MD } from \"../templates/user-agents.md.js\";\n\nconst GITIGNORE_LINES = [\"snapshot.json\", \"export/\", \"*.tmp\"];\n\n/**\n * Parses a GitHub `origin` remote URL into owner and repo name.\n * Supports https and git@ SSH forms for github.com.\n */\nexport function parseRemoteUrl(remoteUrl: string): { owner: string; repo: string } | null {\n const trimmed = remoteUrl.trim();\n\n const sshMatch = /^git@github\\.com:([^/]+)\\/([^/\\s]+)$/.exec(trimmed);\n if (sshMatch) {\n const owner = sshMatch[1];\n const repoRaw = sshMatch[2];\n if (owner === undefined || repoRaw === undefined) {\n return null;\n }\n let repo = repoRaw;\n if (repo.endsWith(\".git\")) {\n repo = repo.slice(0, -\".git\".length);\n }\n return { owner, repo };\n }\n\n const httpsMatch = /^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/?#]+)/.exec(trimmed);\n if (httpsMatch) {\n const owner = httpsMatch[1];\n const repoRaw = httpsMatch[2];\n if (owner === undefined || repoRaw === undefined) {\n return null;\n }\n let repo = repoRaw;\n if (repo.endsWith(\".git\")) {\n repo = repo.slice(0, -\".git\".length);\n }\n return { owner, repo };\n }\n\n return null;\n}\n\nfunction resolveGitRepoRoot(cwd: string): string {\n try {\n const out = childProcess.execFileSync(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n cwd,\n encoding: \"utf-8\",\n });\n return out.trim();\n } catch {\n return cwd;\n }\n}\n\nfunction getOriginRemoteUrl(repoRoot: string): string | null {\n try {\n return childProcess.execFileSync(\"git\", [\"remote\", \"get-url\", \"origin\"], {\n cwd: repoRoot,\n encoding: \"utf-8\",\n }).trim();\n } catch {\n return null;\n }\n}\n\nexport type InitOptions = {\n preset: \"solo\" | \"collaborative\" | \"offline\";\n owner?: string;\n repo?: string;\n /** When true, do not write `AGENTS.md` at the repository root. */\n skipAgentsMd?: boolean;\n};\n\nexport function runInit(options: InitOptions): void {\n const cwd = process.cwd();\n const root = path.resolve(resolveGitRepoRoot(cwd));\n const configPath = path.join(root, \".trail\", \"config.json\");\n\n if (fs.existsSync(configPath)) {\n const err: TrailError = {\n code: \"VALIDATION_FAILED\",\n message: \"Trail is already initialized (.trail/config.json exists).\",\n };\n throw err;\n }\n\n const hasOwner = options.owner !== undefined && options.owner !== \"\";\n const hasRepo = options.repo !== undefined && options.repo !== \"\";\n if (hasOwner !== hasRepo) {\n const err: TrailError = {\n code: \"VALIDATION_FAILED\",\n message: \"Provide both --owner and --repo, or neither to use git remote origin.\",\n };\n throw err;\n }\n\n let owner: string;\n let repo: string;\n\n if (hasOwner && hasRepo) {\n owner = options.owner as string;\n repo = options.repo as string;\n } else {\n const remoteUrl = getOriginRemoteUrl(root);\n const parsed = remoteUrl ? parseRemoteUrl(remoteUrl) : null;\n if (!parsed) {\n const err: TrailError = {\n code: \"VALIDATION_FAILED\",\n message:\n \"Could not determine GitHub owner/repo. Set --owner and --repo or add a github.com origin remote.\",\n };\n throw err;\n }\n owner = parsed.owner;\n repo = parsed.repo;\n }\n\n const preset = options.preset;\n const config = TrailConfigSchema.parse({\n github: { owner, repo },\n sync: {\n preset,\n auto_sync_on_command: preset === \"collaborative\",\n ui_poll_interval_seconds: 30,\n ui_idle_backoff: true,\n },\n });\n\n const trailDir = path.join(root, \".trail\");\n const tasksDir = path.join(trailDir, \"tasks\");\n fs.mkdirSync(trailDir, { recursive: true });\n fs.mkdirSync(tasksDir, { recursive: true });\n\n fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\\n`, \"utf-8\");\n\n const gitignorePath = path.join(trailDir, \".gitignore\");\n fs.writeFileSync(gitignorePath, `${GITIGNORE_LINES.join(\"\\n\")}\\n`, \"utf-8\");\n\n if (options.skipAgentsMd !== true) {\n const agentsPath = path.join(root, \"AGENTS.md\");\n if (!fs.existsSync(agentsPath)) {\n fs.writeFileSync(agentsPath, USER_AGENTS_MD, \"utf-8\");\n console.log(`Wrote ${agentsPath}`);\n } else {\n console.log(`Skipped AGENTS.md (file already exists)`);\n }\n }\n\n console.log(`Initialized Trail project at ${root}`);\n}\n","/** Default AGENTS.md for consumer repos using Trail (embedded in CLI). */\nexport const USER_AGENTS_MD = `# Trail — Agent workflow\n\nThis repository uses [Trail](https://github.com/joeydekruis/trail) for GitHub-native task tracking. Task JSON lives in \\`.trail/tasks/\\`; GitHub Issues are the remote source of truth when online.\n\nIf Trail is installed **locally** (\\`npm install @trail-pm/cli\\`), prefix commands with \\`npx\\` (e.g. \\`npx trail sync\\`). If you use a **global** install (\\`npm install -g\\`), run \\`trail …\\` directly.\n\n## Before coding\n\n1. Run \\`npx trail sync\\` or \\`trail sync\\` (or rely on collaborative mode) so local tasks match GitHub.\n2. Run \\`npx trail next\\` or \\`trail next\\` (add \\`--json\\` when scripting) to pick the highest-priority unblocked task.\n3. Run \\`npx trail context <id>\\` or \\`trail context <id>\\` to load a compact JSON work packet for your session.\n\n## While working\n\n- Update status: \\`npx trail update <id> --status in_progress\\` (or \\`trail update …\\` if global).\n- Use \\`npx trail list\\`, \\`npx trail show <id>\\`, and \\`npx trail validate\\` as needed (drop \\`npx\\` if Trail is installed globally).\n\n## When finished\n\n1. \\`npx trail done <id> \"what you did\"\\` (or \\`trail done …\\`) — closes the linked GitHub issue when configured.\n2. Commit using the suggested message (includes \\`closes #N\\` when linked).\n\n## Docs\n\n- Trail design (upstream): see your fork or \\`trail\\` repo \\`docs/superpowers/specs/\\`\n`;\n","import { selectNextTask } from \"../../core/next-task.js\";\nimport { printJson } from \"../json.js\";\nimport { loadTrailReadContext } from \"../read-context.js\";\n\nexport type NextOptions = {\n json?: boolean;\n};\n\nexport async function runNext(options: NextOptions): Promise<void> {\n const { tasks } = await loadTrailReadContext(process.cwd());\n const next = selectNextTask(tasks);\n\n if (next === null) {\n if (options.json) {\n printJson(null);\n } else {\n console.log(\"No eligible next task.\");\n }\n return;\n }\n\n if (options.json) {\n printJson(next);\n return;\n }\n\n const pri = next.priority ?? \"—\";\n console.log(`Next: ${next.id} — ${next.title} (${next.status}, ${pri})`);\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport { resolveGitHubToken } from \"../../core/auth.js\";\nimport type { TrailError } from \"../../core/errors.js\";\nimport { GitHubClient } from \"../../core/github-client.js\";\nimport { issueToTask } from \"../../core/github-mapper.js\";\nimport { findTrailRoot, trailPaths } from \"../../core/paths.js\";\nimport { rebuildSnapshot } from \"../../core/rebuild-snapshot.js\";\nimport { findTaskFileById, writeTaskFile } from \"../../core/task-store.js\";\nimport { TrailConfigSchema } from \"../../schemas/config.js\";\nexport async function runPromote(options: { id: string }): Promise<void> {\n const root = findTrailRoot(process.cwd());\n if (root === null) {\n const err: TrailError = {\n code: \"NOT_A_TRAIL_REPO\",\n message:\n \"Not a Trail repository (missing .trail/config.json). Run `trail init` first.\",\n path: process.cwd(),\n };\n throw err;\n }\n\n const paths = trailPaths(root);\n const raw = fs.readFileSync(paths.configPath, \"utf-8\");\n const config = TrailConfigSchema.parse(JSON.parse(raw));\n\n if (config.sync.preset === \"offline\") {\n throw new Error(\"Cannot promote a draft in offline mode (no GitHub access).\");\n }\n\n const tokenResult = resolveGitHubToken();\n if (!tokenResult.ok) {\n throw tokenResult.error;\n }\n\n const resolved = findTaskFileById(paths.tasksDir, options.id);\n if (resolved === null) {\n throw new Error(`No task with id \"${options.id}\"`);\n }\n\n const draft = resolved.task;\n if (draft.status !== \"draft\") {\n throw new Error(`Task \"${options.id}\" is not a draft (status is ${draft.status}).`);\n }\n if (draft.github != null) {\n throw new Error(`Task \"${options.id}\" is already linked to GitHub.`);\n }\n\n const now = new Date();\n const client = new GitHubClient(tokenResult.token);\n const { owner, repo } = config.github;\n\n const issue = await client.createIssue(owner, repo, {\n title: draft.title,\n body: draft.description || \"\",\n labels: draft.labels,\n });\n\n const promoted = issueToTask(issue, draft, now);\n fs.unlinkSync(resolved.filePath);\n const newPath = path.join(paths.tasksDir, `${issue.number}.json`);\n writeTaskFile(newPath, promoted);\n rebuildSnapshot(paths, now);\n\n console.log(`Promoted ${draft.id} → GitHub issue #${issue.number}`);\n console.log(` File: ${newPath}`);\n console.log(` URL: ${issue.html_url}`);\n}\n","import { printJson } from \"../json.js\";\nimport { loadTrailReadContext } from \"../read-context.js\";\n\nexport type ShowOptions = {\n id: string;\n json?: boolean;\n};\n\nexport async function runShow(options: ShowOptions): Promise<void> {\n const { tasks } = await loadTrailReadContext(process.cwd());\n const task = tasks.find((t) => t.id === options.id);\n if (task === undefined) {\n throw new Error(`No task with id \"${options.id}\"`);\n }\n\n if (options.json) {\n printJson(task);\n return;\n }\n\n console.log(`${task.id} ${task.status} ${task.title}`);\n if (task.description) {\n console.log();\n console.log(task.description);\n }\n}\n","import { TaskStatusSchema } from \"../../schemas/task.js\";\nimport { printJson } from \"../json.js\";\nimport { loadTrailReadContext } from \"../read-context.js\";\n\nexport type StatusOptions = {\n json?: boolean;\n};\n\nexport async function runStatus(options: StatusOptions): Promise<void> {\n const { config, tasks } = await loadTrailReadContext(process.cwd());\n\n const counts: Record<string, number> = {};\n for (const s of TaskStatusSchema.options) {\n counts[s] = 0;\n }\n for (const t of tasks) {\n counts[t.status] = (counts[t.status] ?? 0) + 1;\n }\n\n const payload: {\n counts: Record<string, number>;\n last_full_sync_at?: string;\n } = { counts };\n if (config.last_full_sync_at !== undefined) {\n payload.last_full_sync_at = config.last_full_sync_at;\n }\n\n if (options.json) {\n printJson(payload);\n return;\n }\n\n console.log(\"Tasks by status:\");\n for (const s of TaskStatusSchema.options) {\n console.log(` ${s}: ${counts[s] ?? 0}`);\n }\n if (config.last_full_sync_at !== undefined) {\n console.log(`Last full sync: ${config.last_full_sync_at}`);\n } else {\n console.log(\"Last full sync: (not recorded)\");\n }\n}\n","import fs from \"node:fs\";\n\nimport { resolveGitHubToken } from \"../../core/auth.js\";\nimport { type TrailError } from \"../../core/errors.js\";\nimport { GitHubClient } from \"../../core/github-client.js\";\nimport { findTrailRoot, trailPaths } from \"../../core/paths.js\";\nimport { loadAllTasks } from \"../../core/task-store.js\";\nimport { fullSync, pullSync, pushSync } from \"../../core/sync.js\";\nimport { TrailConfigSchema } from \"../../schemas/config.js\";\n\nexport type SyncOptions = {\n pull?: boolean;\n push?: boolean;\n};\n\nexport async function runSync(options: SyncOptions): Promise<void> {\n const root = findTrailRoot(process.cwd());\n if (root === null) {\n const err: TrailError = {\n code: \"NOT_A_TRAIL_REPO\",\n message: \"Not a Trail repository (missing .trail/config.json). Run `trail init` first.\",\n path: process.cwd(),\n };\n throw err;\n }\n\n const paths = trailPaths(root);\n const raw = fs.readFileSync(paths.configPath, \"utf-8\");\n const config = TrailConfigSchema.parse(JSON.parse(raw));\n\n if (config.sync.preset === \"offline\") {\n throw new Error(\"Cannot sync in offline mode\");\n }\n\n const tokenResult = resolveGitHubToken();\n if (!tokenResult.ok) {\n throw tokenResult.error;\n }\n\n const client = new GitHubClient(tokenResult.token);\n const { owner, repo } = config.github;\n const { tasksDir, snapshotPath } = paths;\n\n const pullOnly = options.pull === true && options.push !== true;\n const pushOnly = options.push === true && options.pull !== true;\n\n if (pullOnly) {\n await pullSync({ client, owner, repo, tasksDir });\n return;\n }\n\n if (pushOnly) {\n const tasks = loadAllTasks(tasksDir);\n await pushSync({ client, owner, repo, tasks });\n return;\n }\n\n await fullSync({ client, owner, repo, tasksDir, snapshotPath });\n}\n","import fs from \"node:fs\";\n\nimport { resolveGitHubToken } from \"../../core/auth.js\";\nimport type { TrailError } from \"../../core/errors.js\";\nimport { GitHubClient } from \"../../core/github-client.js\";\nimport { taskToIssueUpdate } from \"../../core/github-mapper.js\";\nimport { rebuildSnapshot } from \"../../core/rebuild-snapshot.js\";\nimport { findTrailRoot, trailPaths } from \"../../core/paths.js\";\nimport { findTaskFileById, writeTaskFile } from \"../../core/task-store.js\";\nimport { TrailConfigSchema } from \"../../schemas/config.js\";\nimport type { Task, TaskStatus } from \"../../schemas/task.js\";\n\nconst STATUSES: TaskStatus[] = [\n \"draft\",\n \"todo\",\n \"in_progress\",\n \"in_review\",\n \"done\",\n \"cancelled\",\n];\n\nexport type UpdateOptions = {\n id: string;\n status?: TaskStatus;\n priority?: \"p0\" | \"p1\" | \"p2\" | \"p3\";\n title?: string;\n};\n\nfunction isLinkedTask(\n task: Task,\n): task is Task & { github: NonNullable<Task[\"github\"]> } {\n return task.github != null && typeof task.github === \"object\";\n}\n\nexport async function runUpdate(options: UpdateOptions): Promise<void> {\n const hasField =\n options.status !== undefined ||\n options.priority !== undefined ||\n options.title !== undefined;\n if (!hasField) {\n throw new Error(\"Specify at least one of --status, --priority, or --title\");\n }\n\n const root = findTrailRoot(process.cwd());\n if (root === null) {\n const err: TrailError = {\n code: \"NOT_A_TRAIL_REPO\",\n message:\n \"Not a Trail repository (missing .trail/config.json). Run `trail init` first.\",\n path: process.cwd(),\n };\n throw err;\n }\n\n const paths = trailPaths(root);\n const raw = fs.readFileSync(paths.configPath, \"utf-8\");\n const config = TrailConfigSchema.parse(JSON.parse(raw));\n\n const resolved = findTaskFileById(paths.tasksDir, options.id);\n if (resolved === null) {\n throw new Error(`No task with id \"${options.id}\"`);\n }\n\n const now = new Date();\n const iso = now.toISOString();\n let next: Task = {\n ...resolved.task,\n updated_at: iso,\n };\n if (options.status !== undefined) {\n next = { ...next, status: options.status };\n }\n if (options.priority !== undefined) {\n next = { ...next, priority: options.priority };\n }\n if (options.title !== undefined) {\n next = { ...next, title: options.title };\n }\n\n writeTaskFile(resolved.filePath, next);\n\n const offline = config.sync.preset === \"offline\";\n const tokenResult = resolveGitHubToken();\n if (!offline && tokenResult.ok && isLinkedTask(next)) {\n const client = new GitHubClient(tokenResult.token);\n const { owner, repo } = config.github;\n await client.updateIssue(\n owner,\n repo,\n next.github.issue_number,\n taskToIssueUpdate(next) as Record<string, unknown>,\n );\n const synced: Task = {\n ...next,\n github: {\n ...next.github,\n synced_at: now.toISOString(),\n },\n };\n writeTaskFile(resolved.filePath, synced);\n }\n\n rebuildSnapshot(paths, now);\n}\n\nexport { STATUSES as UPDATE_STATUS_CHOICES };\n","import fs from \"node:fs\";\n\nimport type { TrailError } from \"../../core/errors.js\";\nimport { compileSnapshot, DEPENDENCY_CYCLE } from \"../../core/compile-snapshot.js\";\nimport { findTrailRoot, trailPaths } from \"../../core/paths.js\";\nimport { loadAllTasks } from \"../../core/task-store.js\";\nimport { TrailConfigSchema } from \"../../schemas/config.js\";\n\n/**\n * Loads tasks, compiles snapshot, prints warnings. Returns exit code: 1 if any\n * `DEPENDENCY_CYCLE` warning, else 0.\n */\nexport async function runValidate(): Promise<number> {\n const root = findTrailRoot(process.cwd());\n if (root === null) {\n const err: TrailError = {\n code: \"NOT_A_TRAIL_REPO\",\n message:\n \"Not a Trail repository (missing .trail/config.json). Run `trail init` first.\",\n path: process.cwd(),\n };\n throw err;\n }\n\n const paths = trailPaths(root);\n const raw = fs.readFileSync(paths.configPath, \"utf-8\");\n TrailConfigSchema.parse(JSON.parse(raw));\n\n const tasks = loadAllTasks(paths.tasksDir);\n const snapshot = compileSnapshot(tasks);\n for (const w of snapshot.warnings) {\n console.log(`${w.code}: ${w.message}`);\n }\n const hasCycle = snapshot.warnings.some((w) => w.code === DEPENDENCY_CYCLE);\n return hasCycle ? 1 : 0;\n}\n"],"mappings":"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","names":["z","z","fs","path","fs","path","fs","path","fs","path","fs","path","path","fs","z","fs","path","path","fs","isLinkedTask","fs","childProcess","fs","path","path","fs","fs","path","fs","path","fs","fs","fs","isLinkedTask","fs","fs","fs"]}