syntaur 0.1.0 → 0.1.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.
- package/README.md +116 -0
- package/dist/dashboard/server.js +74 -24
- package/dist/dashboard/server.js.map +1 -1
- package/dist/index.js +858 -160
- package/dist/index.js.map +1 -1
- package/package.json +18 -2
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/agents/syntaur-expert.md +2 -2
- package/plugins/syntaur/.codex-plugin/plugin.json +1 -1
- package/plugins/syntaur/agents/syntaur-operator.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lifecycle/types.ts","../../src/lifecycle/state-machine.ts","../../src/lifecycle/frontmatter.ts","../../src/utils/fs.ts","../../src/utils/timestamp.ts","../../src/lifecycle/transitions.ts","../../src/lifecycle/index.ts","../../src/utils/paths.ts","../../src/utils/config.ts","../../src/dashboard/parser.ts","../../src/dashboard/help.ts","../../src/dashboard/servers.ts","../../src/dashboard/scanner.ts","../../src/dashboard/api.ts","../../src/todos/parser.ts","../../src/dashboard/server.ts","../../src/dashboard/watcher.ts","../../src/dashboard/api-write.ts","../../src/utils/slug.ts","../../src/utils/uuid.ts","../../src/dashboard/acceptance-criteria.ts","../../src/templates/manifest.ts","../../src/utils/yaml.ts","../../src/templates/mission.ts","../../src/templates/agent.ts","../../src/templates/claude.ts","../../src/templates/assignment.ts","../../src/templates/plan.ts","../../src/templates/scratchpad.ts","../../src/templates/handoff.ts","../../src/templates/decision-record.ts","../../src/templates/index-stubs.ts","../../src/templates/playbook.ts","../../src/dashboard/api-servers.ts","../../src/dashboard/api-agent-sessions.ts","../../src/dashboard/agent-sessions.ts","../../src/dashboard/session-db.ts","../../src/dashboard/api-playbooks.ts","../../src/utils/playbooks.ts","../../src/dashboard/api-todos.ts","../../src/dashboard/autodiscovery.ts"],"sourcesContent":["export type AssignmentStatus = string;\n\nexport type TransitionCommand = string;\n\nexport const DEFAULT_STATUSES = [\n 'pending',\n 'in_progress',\n 'blocked',\n 'review',\n 'completed',\n 'failed',\n] as const;\n\nexport const DEFAULT_COMMANDS = [\n 'start',\n 'complete',\n 'block',\n 'unblock',\n 'review',\n 'fail',\n 'reopen',\n 'assign',\n] as const;\n\nexport const DEFAULT_TERMINAL_STATUSES: ReadonlySet<string> = new Set([\n 'completed',\n 'failed',\n]);\n\nexport const TERMINAL_STATUSES: ReadonlySet<string> = DEFAULT_TERMINAL_STATUSES;\n\nexport interface ExternalId {\n system: string;\n id: string;\n url: string;\n}\n\nexport interface Workspace {\n repository: string | null;\n worktreePath: string | null;\n branch: string | null;\n parentBranch: string | null;\n}\n\nexport interface AssignmentFrontmatter {\n id: string;\n slug: string;\n title: string;\n status: AssignmentStatus;\n priority: 'low' | 'medium' | 'high' | 'critical';\n created: string;\n updated: string;\n assignee: string | null;\n externalIds: ExternalId[];\n dependsOn: string[];\n blockedReason: string | null;\n workspace: Workspace;\n tags: string[];\n}\n\nexport interface TransitionResult {\n success: boolean;\n message: string;\n fromStatus: AssignmentStatus;\n toStatus?: AssignmentStatus;\n warnings?: string[];\n}\n","import type { AssignmentStatus, TransitionCommand } from './types.js';\nimport { TERMINAL_STATUSES } from './types.js';\n\n/**\n * Maps a command to its target status. Commands always produce the same\n * target regardless of the current status — workflow enforcement is\n * handled via agent prompting, not code guards.\n */\nexport const DEFAULT_COMMAND_TARGETS = new Map<string, string>([\n ['start', 'in_progress'],\n ['block', 'blocked'],\n ['unblock', 'in_progress'],\n ['review', 'review'],\n ['complete', 'completed'],\n ['fail', 'failed'],\n ['reopen', 'in_progress'],\n]);\n\n/** @deprecated Transition guards removed — kept for API compat, always returns true */\nexport const DEFAULT_TRANSITION_TABLE = new Map<string, string>([\n ['pending:start', 'in_progress'],\n ['pending:block', 'blocked'],\n ['in_progress:block', 'blocked'],\n ['in_progress:review', 'review'],\n ['in_progress:complete', 'completed'],\n ['in_progress:fail', 'failed'],\n ['blocked:unblock', 'in_progress'],\n ['review:start', 'in_progress'],\n ['review:complete', 'completed'],\n ['review:fail', 'failed'],\n ['completed:reopen', 'in_progress'],\n ['failed:reopen', 'in_progress'],\n]);\n\nexport function buildTransitionTable(\n transitions: Array<{ from: string; command: string; to: string }>,\n): Map<string, string> {\n const table = new Map<string, string>();\n for (const t of transitions) {\n table.set(`${t.from}:${t.command}`, t.to);\n }\n return table;\n}\n\nexport function buildCommandTargets(\n transitions: Array<{ from: string; command: string; to: string }>,\n): Map<string, string> {\n const targets = new Map<string, string>();\n for (const t of transitions) {\n targets.set(t.command, t.to);\n }\n return targets;\n}\n\nexport function getTargetStatus(\n _from: AssignmentStatus,\n command: TransitionCommand,\n table?: Map<string, string>,\n): AssignmentStatus | null {\n // Try command-only lookup first, fall back to from:command for backwards compat\n if (!table || table === DEFAULT_TRANSITION_TABLE) {\n return DEFAULT_COMMAND_TARGETS.get(command) ?? null;\n }\n // Custom table: try command-only key first, then from:command\n return table.get(command) ?? table.get(`${_from}:${command}`) ?? null;\n}\n\n/** @deprecated Guards removed — always returns true for known commands */\nexport function canTransition(\n _from: AssignmentStatus,\n command: TransitionCommand,\n table?: Map<string, string>,\n): boolean {\n return getTargetStatus(_from, command, table) !== null;\n}\n\nexport function isTerminalStatus(\n status: AssignmentStatus,\n terminalSet?: ReadonlySet<string>,\n): boolean {\n return (terminalSet ?? TERMINAL_STATUSES).has(status);\n}\n","import type { AssignmentFrontmatter, ExternalId, Workspace } from './types.js';\n\nfunction extractFrontmatter(fileContent: string): [string, string] {\n const match = fileContent.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) {\n throw new Error('No frontmatter found in file. Expected --- delimiters.');\n }\n const frontmatterBlock = match[1];\n const body = fileContent.slice(match[0].length);\n return [frontmatterBlock, body];\n}\n\nfunction parseSimpleValue(raw: string): string | null {\n const trimmed = raw.trim();\n if (trimmed === 'null') return null;\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n return trimmed.slice(1, -1);\n }\n return trimmed;\n}\n\nfunction parseDependsOn(frontmatter: string): string[] {\n const inlineMatch = frontmatter.match(/^dependsOn:\\s*\\[\\s*\\]/m);\n if (inlineMatch) return [];\n\n const results: string[] = [];\n const blockMatch = frontmatter.match(/^dependsOn:\\s*\\n((?:\\s+-\\s+.*\\n?)*)/m);\n if (blockMatch) {\n const items = blockMatch[1].matchAll(/^\\s+-\\s+(.+)$/gm);\n for (const item of items) {\n results.push(item[1].trim());\n }\n }\n return results;\n}\n\nfunction parseExternalIds(frontmatter: string): ExternalId[] {\n const inlineMatch = frontmatter.match(/^externalIds:\\s*\\[\\s*\\]/m);\n if (inlineMatch) return [];\n\n const results: ExternalId[] = [];\n const blockMatch = frontmatter.match(\n /^externalIds:\\s*\\n((?:\\s+-\\s+[\\s\\S]*?)(?=^\\w|\\n---))/m,\n );\n if (!blockMatch) return [];\n\n const itemBlocks = blockMatch[1].split(/\\n\\s+-\\s+/).filter(Boolean);\n for (const block of itemBlocks) {\n const lines = block.split('\\n');\n const entry: Record<string, string> = {};\n for (const line of lines) {\n const colonIdx = line.indexOf(':');\n if (colonIdx < 0) continue;\n const key = line.slice(0, colonIdx).trim().replace(/^-\\s+/, '');\n const value = line.slice(colonIdx + 1).trim();\n if (key && value) {\n entry[key] = value;\n }\n }\n if (entry['system'] && entry['id'] && entry['url']) {\n results.push({\n system: entry['system'],\n id: entry['id'],\n url: entry['url'],\n });\n }\n }\n return results;\n}\n\nfunction parseWorkspace(frontmatter: string): Workspace {\n const defaults: Workspace = {\n repository: null,\n worktreePath: null,\n branch: null,\n parentBranch: null,\n };\n\n const fields = ['repository', 'worktreePath', 'branch', 'parentBranch'] as const;\n for (const field of fields) {\n const match = frontmatter.match(new RegExp(`^\\\\s+${field}:\\\\s*(.*)$`, 'm'));\n if (match) {\n defaults[field] = parseSimpleValue(match[1]);\n }\n }\n return defaults;\n}\n\nfunction parseTags(frontmatter: string): string[] {\n const inlineMatch = frontmatter.match(/^tags:\\s*\\[\\s*\\]/m);\n if (inlineMatch) return [];\n\n const results: string[] = [];\n const blockMatch = frontmatter.match(/^tags:\\s*\\n((?:\\s+-\\s+.*\\n?)*)/m);\n if (blockMatch) {\n const items = blockMatch[1].matchAll(/^\\s+-\\s+(.+)$/gm);\n for (const item of items) {\n results.push(item[1].trim());\n }\n }\n return results;\n}\n\nexport function parseAssignmentFrontmatter(fileContent: string): AssignmentFrontmatter {\n const [frontmatter] = extractFrontmatter(fileContent);\n\n function getField(key: string): string | null {\n const match = frontmatter.match(new RegExp(`^${key}:\\\\s*(.*)$`, 'm'));\n if (!match) return null;\n return parseSimpleValue(match[1]);\n }\n\n return {\n id: getField('id') ?? '',\n slug: getField('slug') ?? '',\n title: getField('title') ?? '',\n status: getField('status') ?? 'pending',\n priority: (getField('priority') ?? 'medium') as AssignmentFrontmatter['priority'],\n created: getField('created') ?? '',\n updated: getField('updated') ?? '',\n assignee: getField('assignee'),\n externalIds: parseExternalIds(frontmatter),\n dependsOn: parseDependsOn(frontmatter),\n blockedReason: getField('blockedReason'),\n workspace: parseWorkspace(frontmatter),\n tags: parseTags(frontmatter),\n };\n}\n\nfunction formatYamlValue(value: string | null): string {\n if (value === null) return 'null';\n if (/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) {\n return `\"${value}\"`;\n }\n // Quote values containing YAML-special characters that could cause parse issues\n if (/[:#{}[\\],&*?|>!%@`]/.test(value) || /^\\s|\\s$/.test(value) || value === '') {\n const escaped = value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n return `\"${escaped}\"`;\n }\n return value;\n}\n\nexport function updateAssignmentFile(\n fileContent: string,\n updates: Partial<Pick<AssignmentFrontmatter, 'status' | 'assignee' | 'blockedReason' | 'updated'>>,\n): string {\n let result = fileContent;\n\n for (const [key, value] of Object.entries(updates)) {\n if (value === undefined) continue;\n const formatted = formatYamlValue(value as string | null);\n const fieldRegex = new RegExp(`^(${key}:)\\\\s*.*$`, 'm');\n if (fieldRegex.test(result)) {\n result = result.replace(fieldRegex, `$1 ${formatted}`);\n }\n }\n\n return result;\n}\n","import { mkdir, writeFile, access, rename } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\n\nexport async function ensureDir(dir: string): Promise<void> {\n await mkdir(dir, { recursive: true });\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function writeFileSafe(\n filePath: string,\n content: string,\n): Promise<boolean> {\n if (await fileExists(filePath)) {\n return false;\n }\n await ensureDir(dirname(filePath));\n await writeFile(filePath, content, 'utf-8');\n return true;\n}\n\nexport async function writeFileForce(\n filePath: string,\n content: string,\n): Promise<void> {\n const dir = dirname(filePath);\n const tempPath = join(\n dir,\n `.${Math.random().toString(36).slice(2)}.${Date.now()}.tmp`,\n );\n await ensureDir(dir);\n await writeFile(tempPath, content, 'utf-8');\n await rename(tempPath, filePath);\n}\n","export function nowTimestamp(): string {\n return new Date().toISOString().replace(/\\.\\d{3}Z$/, 'Z');\n}\n","import { resolve } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport { fileExists, writeFileForce } from '../utils/fs.js';\nimport { nowTimestamp } from '../utils/timestamp.js';\nimport { getTargetStatus } from './state-machine.js';\nimport { parseAssignmentFrontmatter, updateAssignmentFile } from './frontmatter.js';\nimport type { TransitionCommand, TransitionResult, AssignmentFrontmatter } from './types.js';\n\nfunction resolveAssignmentPath(missionDir: string, assignmentSlug: string): string {\n return resolve(missionDir, 'assignments', assignmentSlug, 'assignment.md');\n}\n\nasync function readAssignment(\n filePath: string,\n): Promise<{ content: string; frontmatter: AssignmentFrontmatter }> {\n if (!(await fileExists(filePath))) {\n throw new Error(`Assignment file not found: ${filePath}`);\n }\n const content = await readFile(filePath, 'utf-8');\n const frontmatter = parseAssignmentFrontmatter(content);\n return { content, frontmatter };\n}\n\nasync function checkDependencies(\n missionDir: string,\n dependsOn: string[],\n terminalStatuses?: ReadonlySet<string>,\n): Promise<{ satisfied: boolean; unmet: string[] }> {\n const terminals = terminalStatuses ?? new Set(['completed']);\n const unmet: string[] = [];\n for (const depSlug of dependsOn) {\n const depPath = resolveAssignmentPath(missionDir, depSlug);\n if (!(await fileExists(depPath))) {\n unmet.push(`${depSlug} (file not found)`);\n continue;\n }\n const depContent = await readFile(depPath, 'utf-8');\n const depFrontmatter = parseAssignmentFrontmatter(depContent);\n if (!terminals.has(depFrontmatter.status)) {\n unmet.push(`${depSlug} (status: ${depFrontmatter.status})`);\n }\n }\n return { satisfied: unmet.length === 0, unmet };\n}\n\nexport interface TransitionOptions {\n reason?: string;\n agent?: string;\n transitionTable?: Map<string, string>;\n terminalStatuses?: ReadonlySet<string>;\n}\n\nexport async function executeTransition(\n missionDir: string,\n assignmentSlug: string,\n command: Exclude<TransitionCommand, 'assign'>,\n options: TransitionOptions = {},\n): Promise<TransitionResult> {\n const filePath = resolveAssignmentPath(missionDir, assignmentSlug);\n const { content, frontmatter } = await readAssignment(filePath);\n\n const targetStatus = getTargetStatus(frontmatter.status, command, options.transitionTable);\n\n if (!targetStatus) {\n return {\n success: false,\n message: `Unknown command '${command}' for assignment \"${assignmentSlug}\".`,\n fromStatus: frontmatter.status,\n };\n }\n\n const warnings: string[] = [];\n\n if (command === 'start' && frontmatter.dependsOn.length > 0) {\n const depCheck = await checkDependencies(missionDir, frontmatter.dependsOn, options.terminalStatuses);\n if (!depCheck.satisfied) {\n warnings.push(`Starting with unmet dependencies: ${depCheck.unmet.join(', ')}`);\n }\n }\n\n const updates: Partial<Pick<AssignmentFrontmatter, 'status' | 'assignee' | 'blockedReason' | 'updated'>> = {\n status: targetStatus,\n updated: nowTimestamp(),\n };\n\n if (command === 'start' && options.agent && !frontmatter.assignee) {\n updates.assignee = options.agent;\n }\n if (command === 'block') {\n updates.blockedReason = options.reason ?? null;\n }\n if (command === 'unblock') {\n updates.blockedReason = null;\n }\n\n const updatedContent = updateAssignmentFile(content, updates);\n await writeFileForce(filePath, updatedContent);\n\n return {\n success: true,\n message: `Assignment \"${assignmentSlug}\" transitioned: ${frontmatter.status} -> ${targetStatus}`,\n fromStatus: frontmatter.status,\n toStatus: targetStatus,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\nexport async function executeAssign(\n missionDir: string,\n assignmentSlug: string,\n agent: string,\n): Promise<TransitionResult> {\n const filePath = resolveAssignmentPath(missionDir, assignmentSlug);\n const { content, frontmatter } = await readAssignment(filePath);\n\n const updates: Partial<Pick<AssignmentFrontmatter, 'status' | 'assignee' | 'blockedReason' | 'updated'>> = {\n assignee: agent,\n updated: nowTimestamp(),\n };\n\n const updatedContent = updateAssignmentFile(content, updates);\n await writeFileForce(filePath, updatedContent);\n\n return {\n success: true,\n message: `Assignment \"${assignmentSlug}\" assigned to '${agent}'.`,\n fromStatus: frontmatter.status,\n };\n}\n","export type {\n AssignmentStatus,\n TransitionCommand,\n AssignmentFrontmatter,\n ExternalId,\n Workspace,\n TransitionResult,\n} from './types.js';\nexport { TERMINAL_STATUSES, DEFAULT_STATUSES, DEFAULT_COMMANDS, DEFAULT_TERMINAL_STATUSES } from './types.js';\nexport { canTransition, getTargetStatus, isTerminalStatus, DEFAULT_TRANSITION_TABLE, DEFAULT_COMMAND_TARGETS, buildTransitionTable, buildCommandTargets } from './state-machine.js';\nexport { parseAssignmentFrontmatter, updateAssignmentFile } from './frontmatter.js';\nexport { executeTransition, executeAssign } from './transitions.js';\nexport type { TransitionOptions } from './transitions.js';\n","import { homedir } from 'node:os';\nimport { resolve } from 'node:path';\n\nexport function expandHome(p: string): string {\n if (p.startsWith('~/') || p === '~') {\n return resolve(homedir(), p.slice(2));\n }\n return p;\n}\n\nexport function syntaurRoot(): string {\n return resolve(homedir(), '.syntaur');\n}\n\nexport function defaultMissionDir(): string {\n return resolve(syntaurRoot(), 'missions');\n}\n\nexport function serversDir(): string {\n return resolve(syntaurRoot(), 'servers');\n}\n\nexport function playbooksDir(): string {\n return resolve(syntaurRoot(), 'playbooks');\n}\n\nexport function todosDir(): string {\n return resolve(syntaurRoot(), 'todos');\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve, isAbsolute } from 'node:path';\nimport { syntaurRoot, defaultMissionDir, expandHome } from './paths.js';\nimport { fileExists, writeFileForce } from './fs.js';\n\nexport interface StatusDefinition {\n id: string;\n label: string;\n description?: string;\n color?: string;\n icon?: string;\n terminal?: boolean;\n}\n\nexport interface StatusTransition {\n from: string;\n command: string;\n to: string;\n label?: string;\n description?: string;\n requiresReason?: boolean;\n}\n\nexport interface StatusConfig {\n statuses: StatusDefinition[];\n order: string[];\n transitions: StatusTransition[];\n}\n\nexport interface SyntaurConfig {\n version: string;\n defaultMissionDir: string;\n agentDefaults: {\n trustLevel: 'low' | 'medium' | 'high';\n autoApprove: boolean;\n };\n statuses: StatusConfig | null;\n}\n\nconst DEFAULT_CONFIG: SyntaurConfig = {\n version: '1.0',\n defaultMissionDir: defaultMissionDir(),\n agentDefaults: {\n trustLevel: 'medium',\n autoApprove: false,\n },\n statuses: null,\n};\n\nfunction parseFrontmatter(content: string): Record<string, string> {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return {};\n const result: Record<string, string> = {};\n const lines = match[1].split('\\n');\n let currentParent: string | null = null;\n for (const line of lines) {\n if (line.trim() === '') continue;\n const indent = line.length - line.trimStart().length;\n const colonIndex = line.indexOf(':');\n if (colonIndex < 0) continue;\n const key = line.slice(0, colonIndex).trim();\n const value = line.slice(colonIndex + 1).trim();\n if (indent === 0) {\n if (value === '' || value === undefined) {\n currentParent = key;\n } else {\n currentParent = null;\n result[key] = value.replace(/^[\"']|[\"']$/g, '');\n }\n } else if (indent > 0 && currentParent) {\n result[`${currentParent}.${key}`] = value.replace(/^[\"']|[\"']$/g, '');\n }\n }\n return result;\n}\n\nfunction parseStatusConfig(content: string): StatusConfig | null {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return null;\n const fmBlock = match[1];\n\n // Check if there's a top-level statuses: section\n const statusesStart = fmBlock.match(/^statuses:\\s*$/m);\n if (!statusesStart) return null;\n\n // Extract the statuses block (everything indented after \"statuses:\")\n const startIdx = fmBlock.indexOf(statusesStart[0]) + statusesStart[0].length;\n const remaining = fmBlock.slice(startIdx);\n\n const statuses: StatusDefinition[] = [];\n const order: string[] = [];\n const transitions: StatusTransition[] = [];\n\n // Parse sub-sections: definitions, order, transitions\n let currentSection: 'definitions' | 'order' | 'transitions' | null = null;\n const lines = remaining.split('\\n');\n\n function parseListEntry(lineIdx: number, baseIndent: number): { entry: Record<string, string>; consumed: number } {\n const entry: Record<string, string> = {};\n const firstLine = lines[lineIdx].trimStart().slice(2).trim();\n const colonIdx = firstLine.indexOf(':');\n if (colonIdx > 0) {\n entry[firstLine.slice(0, colonIdx).trim()] = firstLine.slice(colonIdx + 1).trim();\n }\n let consumed = 1;\n for (let i = lineIdx + 1; i < lines.length; i++) {\n const next = lines[i];\n const nextTrimmed = next.trimStart();\n const nextIndent = next.length - nextTrimmed.length;\n if (nextIndent <= baseIndent || nextTrimmed.startsWith('- ')) break;\n const ci = nextTrimmed.indexOf(':');\n if (ci > 0) {\n entry[nextTrimmed.slice(0, ci).trim()] = nextTrimmed.slice(ci + 1).trim();\n }\n consumed++;\n }\n return { entry, consumed };\n }\n\n for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n const line = lines[lineIdx];\n const trimmed = line.trimStart();\n const indent = line.length - trimmed.length;\n\n // Top-level key under statuses (indent 2)\n if (indent === 2 && trimmed.endsWith(':')) {\n const key = trimmed.slice(0, -1).trim();\n if (key === 'definitions') currentSection = 'definitions';\n else if (key === 'order') currentSection = 'order';\n else if (key === 'transitions') currentSection = 'transitions';\n else currentSection = null;\n continue;\n }\n\n // Stop if we hit a new top-level key (no indent)\n if (indent === 0 && trimmed.includes(':')) break;\n\n if (currentSection === 'order' && indent >= 4 && trimmed.startsWith('- ')) {\n order.push(trimmed.slice(2).trim());\n continue;\n }\n\n if (currentSection === 'definitions' && indent >= 4 && trimmed.startsWith('- ')) {\n const { entry, consumed } = parseListEntry(lineIdx, indent);\n if (entry['id']) {\n statuses.push({\n id: entry['id'],\n label: entry['label'] ?? entry['id'],\n description: entry['description'],\n color: entry['color'],\n icon: entry['icon'],\n terminal: entry['terminal'] === 'true',\n });\n }\n lineIdx += consumed - 1; // skip consumed continuation lines\n continue;\n }\n\n if (currentSection === 'transitions' && indent >= 4 && trimmed.startsWith('- ')) {\n const { entry, consumed } = parseListEntry(lineIdx, indent);\n if (entry['from'] && entry['command'] && entry['to']) {\n transitions.push({\n from: entry['from'],\n command: entry['command'],\n to: entry['to'],\n label: entry['label'],\n description: entry['description'],\n requiresReason: entry['requiresReason'] === 'true',\n });\n }\n lineIdx += consumed - 1;\n continue;\n }\n }\n\n if (statuses.length === 0) return null;\n\n return {\n statuses,\n order: order.length > 0 ? order : statuses.map((s) => s.id),\n transitions,\n };\n}\n\nfunction serializeStatusConfig(statuses: StatusConfig): string {\n const lines: string[] = [];\n lines.push('statuses:');\n\n // definitions\n lines.push(' definitions:');\n for (const s of statuses.statuses) {\n lines.push(` - id: ${s.id}`);\n lines.push(` label: ${s.label}`);\n if (s.description) lines.push(` description: ${s.description}`);\n if (s.color) lines.push(` color: ${s.color}`);\n if (s.icon) lines.push(` icon: ${s.icon}`);\n if (s.terminal) lines.push(` terminal: true`);\n }\n\n // order\n lines.push(' order:');\n for (const id of statuses.order) {\n lines.push(` - ${id}`);\n }\n\n // transitions\n if (statuses.transitions.length > 0) {\n lines.push(' transitions:');\n for (const t of statuses.transitions) {\n lines.push(` - from: ${t.from}`);\n lines.push(` command: ${t.command}`);\n lines.push(` to: ${t.to}`);\n if (t.label) lines.push(` label: ${t.label}`);\n if (t.description) lines.push(` description: ${t.description}`);\n if (t.requiresReason) lines.push(` requiresReason: true`);\n }\n }\n\n return lines.join('\\n');\n}\n\nexport async function writeStatusConfig(statuses: StatusConfig): Promise<void> {\n const configPath = resolve(syntaurRoot(), 'config.md');\n const statusBlock = serializeStatusConfig(statuses);\n\n if (!(await fileExists(configPath))) {\n // Create new config file with defaults + statuses\n const content = `---\\nversion: \"1.0\"\\ndefaultMissionDir: ~/missions\\n${statusBlock}\\n---\\n`;\n await writeFileForce(configPath, content);\n return;\n }\n\n const existing = await readFile(configPath, 'utf-8');\n const fmMatch = existing.match(/^(---\\n)([\\s\\S]*?)\\n(---)/);\n if (!fmMatch) {\n // No frontmatter — wrap in new frontmatter\n const content = `---\\nversion: \"1.0\"\\n${statusBlock}\\n---\\n${existing}`;\n await writeFileForce(configPath, content);\n return;\n }\n\n const fmBlock = fmMatch[2];\n const afterFrontmatter = existing.slice(fmMatch[0].length);\n\n // Remove existing statuses: block from frontmatter\n const statusesStart = fmBlock.match(/^statuses:\\s*$/m);\n let cleanedFm: string;\n if (statusesStart) {\n const startIdx = fmBlock.indexOf(statusesStart[0]);\n const before = fmBlock.slice(0, startIdx);\n const after = fmBlock.slice(startIdx + statusesStart[0].length);\n // Skip all indented lines (belonging to statuses block)\n const remaining = after.split('\\n');\n let endIdx = 0;\n for (let i = 0; i < remaining.length; i++) {\n const line = remaining[i];\n if (line.trim() === '') { endIdx = i + 1; continue; }\n if (line.length > 0 && line[0] !== ' ') break;\n endIdx = i + 1;\n }\n cleanedFm = before + remaining.slice(endIdx).join('\\n');\n } else {\n cleanedFm = fmBlock;\n }\n\n // Trim trailing whitespace/newlines from cleaned frontmatter\n cleanedFm = cleanedFm.replace(/\\n+$/, '');\n\n const newContent = `---\\n${cleanedFm}\\n${statusBlock}\\n---${afterFrontmatter}`;\n await writeFileForce(configPath, newContent);\n}\n\nexport async function deleteStatusConfig(): Promise<void> {\n const configPath = resolve(syntaurRoot(), 'config.md');\n if (!(await fileExists(configPath))) return;\n\n const existing = await readFile(configPath, 'utf-8');\n const fmMatch = existing.match(/^(---\\n)([\\s\\S]*?)\\n(---)/);\n if (!fmMatch) return;\n\n const fmBlock = fmMatch[2];\n const afterFrontmatter = existing.slice(fmMatch[0].length);\n\n const statusesStart = fmBlock.match(/^statuses:\\s*$/m);\n if (!statusesStart) return;\n\n const startIdx = fmBlock.indexOf(statusesStart[0]);\n const before = fmBlock.slice(0, startIdx);\n const after = fmBlock.slice(startIdx + statusesStart[0].length);\n const remaining = after.split('\\n');\n let endIdx = 0;\n for (let i = 0; i < remaining.length; i++) {\n const line = remaining[i];\n if (line.trim() === '') { endIdx = i + 1; continue; }\n if (line.length > 0 && line[0] !== ' ') break;\n endIdx = i + 1;\n }\n const cleanedFm = (before + remaining.slice(endIdx).join('\\n')).replace(/\\n+$/, '');\n\n const newContent = `---\\n${cleanedFm}\\n---${afterFrontmatter}`;\n await writeFileForce(configPath, newContent);\n}\n\nexport async function readConfig(): Promise<SyntaurConfig> {\n const configPath = resolve(syntaurRoot(), 'config.md');\n if (!(await fileExists(configPath))) {\n return { ...DEFAULT_CONFIG };\n }\n const content = await readFile(configPath, 'utf-8');\n const fm = parseFrontmatter(content);\n\n if (Object.keys(fm).length === 0) {\n console.warn('Warning: ~/.syntaur/config.md has malformed frontmatter, using defaults');\n return { ...DEFAULT_CONFIG };\n }\n\n let missionDir = fm['defaultMissionDir']\n ? expandHome(String(fm['defaultMissionDir']))\n : DEFAULT_CONFIG.defaultMissionDir;\n if (!isAbsolute(missionDir)) {\n console.warn(\n `Warning: config.md defaultMissionDir is not an absolute path (\"${fm['defaultMissionDir']}\"), using default`,\n );\n missionDir = DEFAULT_CONFIG.defaultMissionDir;\n }\n\n return {\n version: fm['version'] || DEFAULT_CONFIG.version,\n defaultMissionDir: missionDir,\n agentDefaults: {\n trustLevel:\n (fm['agentDefaults.trustLevel'] as SyntaurConfig['agentDefaults']['trustLevel']) ||\n DEFAULT_CONFIG.agentDefaults.trustLevel,\n autoApprove:\n fm['agentDefaults.autoApprove'] === 'true' ||\n DEFAULT_CONFIG.agentDefaults.autoApprove,\n },\n statuses: parseStatusConfig(content),\n };\n}\n","/**\n * Generic frontmatter/markdown parser for all Syntaur file types.\n * Pattern copied from src/lifecycle/frontmatter.ts:3-23 (extractFrontmatter + parseSimpleValue).\n */\n\nexport interface ParsedFile {\n frontmatter: Record<string, string>;\n body: string;\n}\n\n/**\n * Split a markdown file into its frontmatter block and body.\n */\nexport function extractFrontmatter(fileContent: string): [string, string] {\n const match = fileContent.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) {\n return ['', fileContent];\n }\n const frontmatterBlock = match[1];\n const body = fileContent.slice(match[0].length).trim();\n return [frontmatterBlock, body];\n}\n\n/**\n * Parse a simple YAML value, handling null and quoted strings.\n */\nfunction parseSimpleValue(raw: string): string | null {\n const trimmed = raw.trim();\n if (trimmed === 'null' || trimmed === '') return null;\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n return trimmed.slice(1, -1);\n }\n return trimmed;\n}\n\n/**\n * Extract a top-level scalar field from frontmatter text.\n */\nexport function getField(frontmatter: string, key: string): string | null {\n const match = frontmatter.match(new RegExp(`^${key}:\\\\s*(.*)$`, 'm'));\n if (!match) return null;\n return parseSimpleValue(match[1]);\n}\n\n/**\n * Extract an indented scalar field (one level deep) from frontmatter text.\n */\nexport function getNestedField(frontmatter: string, parent: string, key: string): string | null {\n const parentRegex = new RegExp(`^${parent}:\\\\s*\\\\n((?:\\\\s+.*\\\\n?)*)`, 'm');\n const parentMatch = frontmatter.match(parentRegex);\n if (!parentMatch) return null;\n const block = parentMatch[1];\n const fieldMatch = block.match(new RegExp(`^\\\\s+${key}:\\\\s*(.*)$`, 'm'));\n if (!fieldMatch) return null;\n return parseSimpleValue(fieldMatch[1]);\n}\n\n/**\n * Parse a YAML list field (e.g., tags, dependsOn, relatedAssignments).\n */\nfunction parseListField(frontmatter: string, fieldName: string): string[] {\n const inlineMatch = frontmatter.match(new RegExp(`^${fieldName}:\\\\s*\\\\[\\\\s*\\\\]`, 'm'));\n if (inlineMatch) return [];\n\n const results: string[] = [];\n const blockMatch = frontmatter.match(\n new RegExp(`^${fieldName}:\\\\s*\\\\n((?:\\\\s+-\\\\s+.*\\\\n?)*)`, 'm'),\n );\n if (blockMatch) {\n let item: RegExpExecArray | null;\n const regex = /^\\s+-\\s+(.+)$/gm;\n while ((item = regex.exec(blockMatch[1])) !== null) {\n results.push(item[1].trim());\n }\n }\n return results;\n}\n\n// --- Mission Parser ---\n\nexport interface ParsedMission {\n id: string;\n slug: string;\n title: string;\n archived: boolean;\n archivedAt: string | null;\n archivedReason: string | null;\n statusOverride: string | null;\n created: string;\n updated: string;\n tags: string[];\n workspace: string | null;\n body: string;\n}\n\nexport function parseMission(fileContent: string): ParsedMission {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n id: getField(fm, 'id') ?? '',\n slug: getField(fm, 'slug') ?? '',\n title: getField(fm, 'title') ?? '',\n archived: getField(fm, 'archived') === 'true',\n archivedAt: getField(fm, 'archivedAt'),\n archivedReason: getField(fm, 'archivedReason'),\n statusOverride: getField(fm, 'statusOverride'),\n created: getField(fm, 'created') ?? '',\n updated: getField(fm, 'updated') ?? '',\n tags: parseListField(fm, 'tags'),\n workspace: getField(fm, 'workspace'),\n body,\n };\n}\n\n// --- Status Parser (for _status.md) ---\n\nexport interface ParsedStatus {\n mission: string;\n status: string;\n progress: Record<string, number> & { total: number };\n needsAttention: {\n blockedCount: number;\n failedCount: number;\n unansweredQuestions: number;\n };\n body: string;\n}\n\nexport function parseStatus(fileContent: string): ParsedStatus {\n const [fm, body] = extractFrontmatter(fileContent);\n\n // Dynamically parse progress fields\n const progress: Record<string, number> & { total: number } = { total: 0 };\n const progressMatch = fm.match(/^progress:\\s*\\n((?:\\s+.*\\n?)*)/m);\n if (progressMatch) {\n const lines = progressMatch[1].split('\\n');\n for (const line of lines) {\n const kv = line.match(/^\\s+(\\w+):\\s*(\\d+)/);\n if (kv) {\n progress[kv[1]] = parseInt(kv[2], 10);\n }\n }\n }\n\n return {\n mission: getField(fm, 'mission') ?? '',\n status: getField(fm, 'status') ?? 'pending',\n progress,\n needsAttention: {\n blockedCount: parseInt(getNestedField(fm, 'needsAttention', 'blockedCount') ?? '0', 10),\n failedCount: parseInt(getNestedField(fm, 'needsAttention', 'failedCount') ?? '0', 10),\n unansweredQuestions: parseInt(getNestedField(fm, 'needsAttention', 'unansweredQuestions') ?? '0', 10),\n },\n body,\n };\n}\n\n// --- Assignment Summary Parser ---\n\nexport interface ParsedAssignmentSummary {\n id: string;\n slug: string;\n title: string;\n status: string;\n priority: string;\n assignee: string | null;\n dependsOn: string[];\n updated: string;\n}\n\nexport function parseAssignmentSummary(fileContent: string): ParsedAssignmentSummary {\n const [fm] = extractFrontmatter(fileContent);\n return {\n id: getField(fm, 'id') ?? '',\n slug: getField(fm, 'slug') ?? '',\n title: getField(fm, 'title') ?? '',\n status: getField(fm, 'status') ?? 'pending',\n priority: getField(fm, 'priority') ?? 'medium',\n assignee: getField(fm, 'assignee'),\n dependsOn: parseListField(fm, 'dependsOn'),\n updated: getField(fm, 'updated') ?? '',\n };\n}\n\n// --- Full Assignment Parser ---\n\nexport interface ParsedAssignmentFull {\n id: string;\n slug: string;\n title: string;\n status: string;\n priority: string;\n assignee: string | null;\n dependsOn: string[];\n blockedReason: string | null;\n workspace: {\n repository: string | null;\n worktreePath: string | null;\n branch: string | null;\n parentBranch: string | null;\n };\n externalIds: Array<{ system: string; id: string; url: string }>;\n tags: string[];\n created: string;\n updated: string;\n body: string;\n}\n\nfunction parseExternalIds(frontmatter: string): Array<{ system: string; id: string; url: string }> {\n const inlineMatch = frontmatter.match(/^externalIds:\\s*\\[\\s*\\]/m);\n if (inlineMatch) return [];\n\n const results: Array<{ system: string; id: string; url: string }> = [];\n const blockMatch = frontmatter.match(\n /^externalIds:\\s*\\n((?:\\s+-\\s+[\\s\\S]*?)(?=^\\w|\\n---))/m,\n );\n if (!blockMatch) return [];\n\n const itemBlocks = blockMatch[1].split(/\\n\\s+-\\s+/).filter(Boolean);\n for (const block of itemBlocks) {\n const lines = block.split('\\n');\n const entry: Record<string, string> = {};\n for (const line of lines) {\n const colonIdx = line.indexOf(':');\n if (colonIdx < 0) continue;\n const key = line.slice(0, colonIdx).trim().replace(/^-\\s+/, '');\n const value = line.slice(colonIdx + 1).trim();\n if (key && value) {\n entry[key] = value;\n }\n }\n if (entry['system'] && entry['id'] && entry['url']) {\n results.push({\n system: entry['system'],\n id: entry['id'],\n url: entry['url'],\n });\n }\n }\n return results;\n}\n\nexport function parseAssignmentFull(fileContent: string): ParsedAssignmentFull {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n id: getField(fm, 'id') ?? '',\n slug: getField(fm, 'slug') ?? '',\n title: getField(fm, 'title') ?? '',\n status: getField(fm, 'status') ?? 'pending',\n priority: getField(fm, 'priority') ?? 'medium',\n assignee: getField(fm, 'assignee'),\n dependsOn: parseListField(fm, 'dependsOn'),\n blockedReason: getField(fm, 'blockedReason'),\n workspace: {\n repository: getNestedField(fm, 'workspace', 'repository'),\n worktreePath: getNestedField(fm, 'workspace', 'worktreePath'),\n branch: getNestedField(fm, 'workspace', 'branch'),\n parentBranch: getNestedField(fm, 'workspace', 'parentBranch'),\n },\n externalIds: parseExternalIds(fm),\n tags: parseListField(fm, 'tags'),\n created: getField(fm, 'created') ?? '',\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Plan Parser ---\n\nexport interface ParsedPlan {\n assignment: string;\n status: string;\n created: string;\n updated: string;\n body: string;\n}\n\nexport function parsePlan(fileContent: string): ParsedPlan {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n assignment: getField(fm, 'assignment') ?? '',\n status: getField(fm, 'status') ?? '',\n created: getField(fm, 'created') ?? '',\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Scratchpad Parser ---\n\nexport interface ParsedScratchpad {\n assignment: string;\n updated: string;\n body: string;\n}\n\nexport function parseScratchpad(fileContent: string): ParsedScratchpad {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n assignment: getField(fm, 'assignment') ?? '',\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Handoff Parser ---\n\nexport interface ParsedHandoff {\n assignment: string;\n handoffCount: number;\n updated: string;\n body: string;\n}\n\nexport function parseHandoff(fileContent: string): ParsedHandoff {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n assignment: getField(fm, 'assignment') ?? '',\n handoffCount: parseInt(getField(fm, 'handoffCount') ?? '0', 10),\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Decision Record Parser ---\n\nexport interface ParsedDecisionRecord {\n assignment: string;\n decisionCount: number;\n updated: string;\n body: string;\n}\n\nexport function parseDecisionRecord(fileContent: string): ParsedDecisionRecord {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n assignment: getField(fm, 'assignment') ?? '',\n decisionCount: parseInt(getField(fm, 'decisionCount') ?? '0', 10),\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Resource Parser ---\n\nexport interface ParsedResource {\n name: string;\n source: string;\n category: string;\n relatedAssignments: string[];\n created: string;\n updated: string;\n body: string;\n}\n\nexport function parseResource(fileContent: string): ParsedResource {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n name: getField(fm, 'name') ?? '',\n source: getField(fm, 'source') ?? '',\n category: getField(fm, 'category') ?? '',\n relatedAssignments: parseListField(fm, 'relatedAssignments'),\n created: getField(fm, 'created') ?? '',\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Memory Parser ---\n\nexport interface ParsedMemory {\n name: string;\n source: string;\n scope: string;\n sourceAssignment: string | null;\n relatedAssignments: string[];\n created: string;\n updated: string;\n body: string;\n}\n\nexport function parseMemory(fileContent: string): ParsedMemory {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n name: getField(fm, 'name') ?? '',\n source: getField(fm, 'source') ?? '',\n scope: getField(fm, 'scope') ?? '',\n sourceAssignment: getField(fm, 'sourceAssignment'),\n relatedAssignments: parseListField(fm, 'relatedAssignments'),\n created: getField(fm, 'created') ?? '',\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Playbook Parser ---\n\nexport interface ParsedPlaybook {\n slug: string;\n name: string;\n description: string;\n whenToUse: string;\n created: string;\n updated: string;\n tags: string[];\n body: string;\n}\n\nexport function parsePlaybook(fileContent: string): ParsedPlaybook {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n slug: getField(fm, 'slug') ?? '',\n name: getField(fm, 'name') ?? '',\n description: getField(fm, 'description') ?? '',\n whenToUse: getField(fm, 'when_to_use') ?? '',\n created: getField(fm, 'created') ?? '',\n updated: getField(fm, 'updated') ?? '',\n tags: parseListField(fm, 'tags'),\n body,\n };\n}\n\n// --- Mermaid Graph Extractor ---\n\n/**\n * Extract the mermaid code block from _status.md body content.\n * Returns null if no mermaid block is found.\n */\nexport function extractMermaidGraph(body: string): string | null {\n const match = body.match(/```mermaid\\n([\\s\\S]*?)```/);\n return match ? match[1].trim() : null;\n}\n","import type {\n HelpChecklistItem,\n HelpCommand,\n HelpResponse,\n HelpStatusGuideEntry,\n} from './types.js';\nimport { getStatusConfig } from './api.js';\n\nconst CLI_COMMANDS: HelpCommand[] = [\n // --- Core setup & scaffolding (indices 0-4) ---\n {\n command: 'syntaur setup',\n description: 'Initialize Syntaur and optionally install plugins or launch the dashboard.',\n example: 'syntaur setup',\n },\n {\n command: 'syntaur init',\n description: 'Initialize the local Syntaur home directory and config scaffolding without any prompts.',\n example: 'syntaur init',\n },\n {\n command: 'syntaur create-mission',\n description: 'Create a new mission folder with the required source and derived files.',\n example: 'syntaur create-mission \"Ship dashboard overhaul\"',\n },\n {\n command: 'syntaur create-assignment',\n description: 'Create a new assignment inside a mission.',\n example: 'syntaur create-assignment \"Implement overview API\" --mission ui-overhaul',\n },\n {\n command: 'syntaur assign',\n description: 'Set the assignee for an assignment before work begins.',\n example: 'syntaur assign implement-overview --mission ui-overhaul --agent codex-1',\n },\n\n // --- Lifecycle transitions (indices 5-11) ---\n {\n command: 'syntaur start',\n description: 'Transition an assignment to in_progress.',\n example: 'syntaur start implement-overview --mission ui-overhaul',\n },\n {\n command: 'syntaur review',\n description: 'Move active work into review once implementation is ready for inspection.',\n example: 'syntaur review implement-overview --mission ui-overhaul',\n },\n {\n command: 'syntaur complete',\n description: 'Mark an assignment completed after review or direct completion.',\n example: 'syntaur complete implement-overview --mission ui-overhaul',\n },\n {\n command: 'syntaur block',\n description: 'Mark an assignment blocked and record the explicit reason.',\n example: 'syntaur block implement-overview --mission ui-overhaul --reason \"Waiting on API spec\"',\n },\n {\n command: 'syntaur unblock',\n description: 'Move a blocked assignment back to in_progress after the blocker is cleared.',\n example: 'syntaur unblock implement-overview --mission ui-overhaul',\n },\n {\n command: 'syntaur fail',\n description: 'Mark an assignment failed when it cannot be completed as planned.',\n example: 'syntaur fail implement-overview --mission ui-overhaul',\n },\n {\n command: 'syntaur reopen',\n description: 'Reopen a completed or failed assignment back to in_progress.',\n example: 'syntaur reopen implement-overview --mission ui-overhaul',\n },\n\n // --- Dashboard (index 12) ---\n {\n command: 'syntaur dashboard',\n description: 'Start the local dashboard UI over the mission files on disk.',\n example: 'syntaur dashboard --port 4800',\n },\n\n // --- Plugin & adapter setup (indices 13-16) ---\n {\n command: 'syntaur install-plugin',\n description: 'Install the Syntaur Claude Code plugin into your home plugin directory.',\n example: 'syntaur install-plugin',\n },\n {\n command: 'syntaur install-codex-plugin',\n description: 'Install the Syntaur Codex plugin and register its local marketplace entry.',\n example: 'syntaur install-codex-plugin',\n },\n {\n command: 'syntaur uninstall',\n description: 'Remove Syntaur plugins and optionally local ~/.syntaur data.',\n example: 'syntaur uninstall --all',\n },\n {\n command: 'syntaur setup-adapter',\n description: 'Generate adapter instruction files for cursor, codex, or opencode in the current directory.',\n example: 'syntaur setup-adapter cursor --mission ui-overhaul --assignment implement-overview',\n },\n\n // --- Session & server tracking (index 17) ---\n {\n command: 'syntaur track-session',\n description: 'Register an agent session, optionally linked to a mission and assignment.',\n example: 'syntaur track-session --agent claude --mission ui-overhaul --assignment implement-overview',\n },\n\n // --- Browsing & playbooks (indices 18-20) ---\n {\n command: 'syntaur browse',\n description: 'Interactive TUI browser for missions and assignments.',\n example: 'syntaur browse',\n },\n {\n command: 'syntaur create-playbook',\n description: 'Create a new playbook with behavioral rules for agents.',\n example: 'syntaur create-playbook \"Code Review Standards\"',\n },\n {\n command: 'syntaur list-playbooks',\n description: 'List all playbooks in the Syntaur home directory.',\n example: 'syntaur list-playbooks',\n },\n];\n\nconst WORKFLOW: HelpChecklistItem[] = [\n {\n title: 'Initialize the workspace',\n detail: 'Run setup once so Syntaur can initialize its local home directory and offer plugin installation.',\n command: CLI_COMMANDS[0],\n },\n {\n title: 'Create a mission',\n detail: 'Use a mission for a higher-level objective. Missions group assignments, shared resources, and memories.',\n command: CLI_COMMANDS[2],\n href: '/create/mission',\n },\n {\n title: 'Create the first assignment',\n detail: 'Assignments are the execution unit. Create one for each concrete chunk of work inside the mission.',\n command: CLI_COMMANDS[3],\n },\n {\n title: 'Assign the work',\n detail: 'Setting an assignee before starting is recommended for clarity, but not required.',\n command: CLI_COMMANDS[4],\n },\n {\n title: 'Start, review, complete, or block through lifecycle actions',\n detail: 'Status changes happen through lifecycle actions, kanban drag-and-drop, or the status override controls.',\n command: CLI_COMMANDS[5],\n },\n {\n title: 'Use the dashboard for triage and context',\n detail: 'Overview shows the current queue, mission pages show health, assignment pages show the execution surface.',\n command: CLI_COMMANDS[12],\n href: '/',\n },\n];\n\nconst DEFAULT_STATUS_GUIDE: Record<string, { meaning: string; useWhen: string }> = {\n pending: {\n meaning: 'The assignment has not started yet.',\n useWhen: 'Use pending while waiting to start. If dependencies are unmet, pending is the normal waiting state.',\n },\n in_progress: {\n meaning: 'An assigned agent is actively working the assignment.',\n useWhen: 'Use in_progress once the work has started and dependencies are satisfied.',\n },\n blocked: {\n meaning: 'The assignment hit a manual or runtime obstacle.',\n useWhen: 'Use blocked when work hits an obstacle. Adding a blockedReason is recommended for traceability.',\n },\n review: {\n meaning: 'Implementation is ready for inspection or validation.',\n useWhen: 'Use review after active work is ready to be checked before completion.',\n },\n completed: {\n meaning: 'The assignment is done.',\n useWhen: 'Use completed when the acceptance criteria are satisfied.',\n },\n failed: {\n meaning: 'The assignment could not be completed as planned.',\n useWhen: 'Use failed when the work cannot be recovered within the current assignment.',\n },\n};\n\nasync function buildStatusGuide(): Promise<HelpStatusGuideEntry[]> {\n const config = await getStatusConfig();\n\n return config.statuses.map((s) => {\n const defaults = DEFAULT_STATUS_GUIDE[s.id];\n return {\n status: s.id,\n meaning: s.description ?? defaults?.meaning ?? `The assignment is in the \"${s.label}\" state.`,\n useWhen: defaults?.useWhen ?? `Use ${s.id} when appropriate for the \"${s.label}\" workflow state.`,\n };\n });\n}\n\nexport async function getDashboardHelp(): Promise<HelpResponse> {\n return {\n generatedAt: new Date().toISOString(),\n whatIsSyntaur: {\n summary:\n 'Syntaur is a local-first, markdown-backed agent work system. The dashboard is a live view over mission folders and files on disk.',\n bullets: [\n 'Markdown files are the source of truth.',\n 'The UI reads mission folders, assignment files, and derived indexes from the local filesystem.',\n 'Derived underscore-prefixed files are projections, not the canonical edit target.',\n ],\n },\n coreConcepts: [\n {\n term: 'Mission',\n description:\n 'A mission is the higher-level objective. It owns assignments, shared resources, and mission memories.',\n },\n {\n term: 'Assignment',\n description:\n 'An assignment is a concrete unit of execution. Assignment frontmatter is the source of truth for status, priority, assignee, and dependencies.',\n },\n {\n term: 'Resource',\n description:\n 'A mission-level shared reference file that provides source material or constraints for the work.',\n },\n {\n term: 'Memory',\n description:\n 'A mission-level learning or pattern captured during execution so future assignments can reuse it.',\n },\n {\n term: 'Manifest',\n description:\n 'A derived navigation file that points agents at the mission overview, indexes, and agent instructions.',\n },\n {\n term: 'Derived file',\n description:\n 'An underscore-prefixed file regenerated from canonical markdown sources. Read it, but do not edit it directly.',\n },\n {\n term: 'Handoff',\n description:\n 'An append-only log that records baton-passes between agents or sessions without rewriting prior history.',\n },\n {\n term: 'Decision record',\n description:\n 'An append-only record of important decisions, rationale, and follow-up consequences.',\n },\n {\n term: 'Playbook',\n description:\n 'A behavioral rule set stored in ~/.syntaur/playbooks/. Playbooks define constraints and conventions that agents must follow during execution. Manage them via the CLI or the Playbooks page.',\n },\n {\n term: 'Workspace',\n description:\n 'The repository context for an assignment, including the repository path, worktree path, branch, and parent branch. Workspace fields connect an assignment to the code being worked on and define write boundaries.',\n },\n {\n term: 'Agent Session',\n description:\n 'A tracked AI session tied to assignment work. Sessions are registered via the track-session CLI command or the Claude Code plugin and visible on the Agent Sessions page.',\n },\n {\n term: 'Server',\n description:\n 'A tracked tmux session with automatic port discovery, branch detection, and assignment linking. The Servers page shows all tracked sessions with their windows, panes, and discovered services.',\n },\n ],\n workflow: WORKFLOW,\n statusGuide: await buildStatusGuide(),\n ownershipRules: [\n {\n label: 'Human-authored files',\n files: ['mission.md', 'agent.md', 'claude.md'],\n description:\n 'These files define mission intent and instructions. The dashboard treats mission status as derived except for the archive fields.',\n },\n {\n label: 'Assignment working files',\n files: ['assignment.md', 'plan.md', 'scratchpad.md'],\n description:\n 'These are agent-writable files. The dashboard lets you edit the source markdown while preserving unsupported frontmatter keys.',\n },\n {\n label: 'Append-only logs',\n files: ['handoff.md', 'decision-record.md'],\n description:\n 'These logs preserve history. The dashboard appends new entries instead of rewriting previous ones.',\n },\n {\n label: 'Derived files',\n files: ['_status.md', '_index-assignments.md', '_index-plans.md', '_index-decisions.md'],\n description:\n 'These files are read-only projections. They can lag behind source files, so the dashboard computes source-first state.',\n },\n ],\n commands: CLI_COMMANDS,\n navigation: [\n {\n label: 'Overview',\n description: 'Triage hub showing current attention items, recent activity, progress stats, and first-run setup guidance.',\n href: '/',\n },\n {\n label: 'Missions',\n description: 'Browse, search, filter, and sort the mission directory. Create new missions and drill into mission workspaces.',\n href: '/missions',\n },\n {\n label: 'Assignments',\n description: 'Cross-mission kanban board of all assignments. Drag cards between columns to change status, or filter by mission, assignee, or status.',\n href: '/assignments',\n },\n {\n label: 'Servers',\n description: 'Tracked tmux sessions with auto-discovered ports, URLs, git branches, and links to related assignments. Register sessions manually or let autodiscovery find them.',\n href: '/servers',\n },\n {\n label: 'Agent Sessions',\n description: 'Monitor which AI agents are currently working, what assignments they are linked to, and session duration. Sessions are registered via the Claude Code plugin or track-session CLI command.',\n href: '/agent-sessions',\n },\n {\n label: 'Playbooks',\n description: 'Create, browse, and edit behavioral rules that agents must follow. The playbook manifest at ~/.syntaur/playbooks/manifest.md is auto-generated for inclusion in agent instructions.',\n href: '/playbooks',\n },\n {\n label: 'Attention',\n description: 'Focused queue of assignments that need action: blocked, failed, in review, stale, or with unmet dependencies.',\n href: '/attention',\n },\n {\n label: 'Help',\n description: 'This page. Status guide, CLI quick reference, core concepts, and FAQ.',\n href: '/help',\n },\n {\n label: 'Settings',\n description: 'Customize status definitions, labels, colors, display order, and done states. Changes apply globally across the dashboard and CLI.',\n href: '/settings',\n },\n {\n label: 'Mission page',\n description: 'The mission workspace shows health stats, assignment list, dependency graph, shared resources, and memories.',\n href: '/missions',\n },\n {\n label: 'Assignment page',\n description: 'The assignment workspace shows lifecycle actions, plan editor, scratchpad, handoff log, decision records, and agent sessions.',\n href: '/missions',\n },\n ],\n faq: [\n {\n question: 'Why are some files read-only in the dashboard?',\n answer:\n 'Underscore-prefixed files are derived projections that can be rebuilt from canonical markdown sources. Editing them would create drift, so the UI treats them as read-only.',\n },\n {\n question: 'Why can an assignment be pending even when nothing looks broken?',\n answer:\n 'Pending often just means the work has not started yet or it is waiting on declared dependencies. Blocked is reserved for exceptional runtime obstacles that need intervention.',\n },\n {\n question: 'How do I change an assignment\\'s status?',\n answer:\n 'Use lifecycle CLI commands (syntaur start, syntaur complete, etc.), drag cards on the kanban board, or use the Override Status dropdown on the assignment page. Any status can be set from any other status.',\n },\n {\n question: 'How do I customize statuses?',\n answer:\n 'Open the Settings page from the sidebar. You can add, remove, rename, recolor, and reorder statuses. You can also mark statuses as done states. Changes are saved to ~/.syntaur/config.md and take effect immediately across the dashboard.',\n },\n {\n question: 'What is a done state?',\n answer:\n 'A done state (also called terminal status) means the assignment is finished. Done states fill the completed portion of progress bars and satisfy dependency requirements. By default, \"completed\" and \"failed\" are done states. You can configure which statuses are done states in Settings.',\n },\n {\n question: 'What are playbooks and how do I use them?',\n answer:\n 'Playbooks are markdown files in ~/.syntaur/playbooks/ that define behavioral rules agents must follow. Create them via the CLI (syntaur create-playbook) or the Playbooks page. The auto-generated manifest at ~/.syntaur/playbooks/manifest.md can be included in your CLAUDE.md so agents pick up the rules.',\n },\n {\n question: 'How does agent session tracking work?',\n answer:\n 'When an AI agent starts working on an assignment, it can register a session via the track-session CLI command or the Claude Code plugin\\'s /track-session command. The Agent Sessions page shows active and completed sessions with their linked assignments and duration.',\n },\n {\n question: 'How does server tracking work?',\n answer:\n 'Syntaur tracks tmux sessions to discover running dev servers, their ports, git branches, and linked assignments. Register sessions on the Servers page or let autodiscovery find them. Pane info refreshes automatically.',\n },\n ],\n firstMissionChecklist: [\n {\n title: 'Create the mission',\n detail: 'Describe the overall objective in mission.md, then add tags and archive metadata only when needed.',\n command: CLI_COMMANDS[1],\n href: '/create/mission',\n },\n {\n title: 'Create at least one assignment',\n detail: 'Break the mission into executable work units with explicit priority and dependencies.',\n command: CLI_COMMANDS[2],\n },\n {\n title: 'Assign and start the first assignment',\n detail: 'Set an assignee, then start the assignment once prerequisites are complete.',\n command: CLI_COMMANDS[3],\n },\n {\n title: 'Use the assignment workspace for execution',\n detail: 'Keep the objective in assignment.md, the implementation plan in plan.md, and transient notes in scratchpad.md.',\n href: '/missions',\n },\n {\n title: 'Record handoffs and decisions without rewriting history',\n detail: 'Append new handoff and decision entries instead of editing prior entries.',\n },\n {\n title: 'Return to Overview for triage',\n detail: 'Overview and Attention show the queue that needs action next.',\n href: '/',\n },\n ],\n links: [\n { label: 'Overview', href: '/' },\n { label: 'Mission Directory', href: '/missions' },\n { label: 'Assignments Board', href: '/assignments' },\n { label: 'Attention Queue', href: '/attention' },\n { label: 'Servers', href: '/servers' },\n { label: 'Agent Sessions', href: '/agent-sessions' },\n { label: 'Playbooks', href: '/playbooks' },\n { label: 'Settings', href: '/settings' },\n { label: 'Create Mission', href: '/create/mission' },\n ],\n };\n}\n\nexport function getHelpCommandNames(): string[] {\n return CLI_COMMANDS.map((command) => command.command.replace(/^syntaur\\s+/, ''));\n}\n","import { readdir, readFile, unlink } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { ensureDir, fileExists, writeFileForce } from '../utils/fs.js';\nimport { extractFrontmatter, getField } from './parser.js';\nimport type { SessionFileData, SessionKind } from './types.js';\n\nexport function sanitizeSessionName(name: string): string {\n return name.replace(/[^a-zA-Z0-9_-]/g, '-');\n}\n\nfunction nowTimestamp(): string {\n return new Date().toISOString();\n}\n\nexport interface BuildSessionOptions {\n session: string;\n registered: string;\n lastRefreshed: string;\n overrides: Record<string, { mission: string; assignment: string }>;\n auto?: boolean;\n kind?: SessionKind;\n pid?: number;\n ports?: number[];\n cwd?: string;\n}\n\nexport function buildSessionContent(opts: BuildSessionOptions): string {\n const lines = [\n '---',\n `session: ${opts.session}`,\n `registered: ${opts.registered}`,\n `last_refreshed: ${opts.lastRefreshed}`,\n ];\n\n if (opts.auto != null) {\n lines.push(`auto: ${opts.auto}`);\n }\n if (opts.kind) {\n lines.push(`kind: ${opts.kind}`);\n }\n if (opts.pid != null) {\n lines.push(`pid: ${opts.pid}`);\n }\n if (opts.ports && opts.ports.length > 0) {\n lines.push(`ports: [${opts.ports.join(', ')}]`);\n }\n if (opts.cwd) {\n lines.push(`cwd: ${opts.cwd}`);\n }\n\n if (Object.keys(opts.overrides).length > 0) {\n lines.push('overrides:');\n for (const [key, val] of Object.entries(opts.overrides)) {\n lines.push(` \"${key}\": { mission: \"${val.mission}\", assignment: \"${val.assignment}\" }`);\n }\n }\n\n lines.push('---', '');\n return lines.join('\\n');\n}\n\nexport async function registerSession(dir: string, rawName: string): Promise<string> {\n const name = sanitizeSessionName(rawName);\n await ensureDir(dir);\n const now = nowTimestamp();\n const content = buildSessionContent({\n session: name, registered: now, lastRefreshed: now, overrides: {},\n });\n await writeFileForce(resolve(dir, `${name}.md`), content);\n return name;\n}\n\nexport async function listSessionFiles(dir: string): Promise<string[]> {\n if (!(await fileExists(dir))) return [];\n const entries = await readdir(dir);\n return entries\n .filter((f) => f.endsWith('.md'))\n .map((f) => f.replace(/\\.md$/, ''));\n}\n\nexport async function readSessionFile(dir: string, name: string): Promise<SessionFileData | null> {\n const filePath = resolve(dir, `${sanitizeSessionName(name)}.md`);\n if (!(await fileExists(filePath))) return null;\n\n const raw = await readFile(filePath, 'utf-8');\n const [frontmatter] = extractFrontmatter(raw);\n if (!frontmatter) return null;\n\n const session = getField(frontmatter, 'session') ?? name;\n const registered = getField(frontmatter, 'registered') ?? '';\n const lastRefreshed = getField(frontmatter, 'last_refreshed') ?? '';\n\n // Parse overrides block\n const overrides: Record<string, { mission: string; assignment: string }> = {};\n const overridesMatch = frontmatter.match(/^overrides:\\n((?:\\s+\".+\\n?)*)/m);\n if (overridesMatch) {\n const overrideLines = overridesMatch[1].matchAll(\n /^\\s+\"([^\"]+)\":\\s*\\{\\s*mission:\\s*\"([^\"]+)\",\\s*assignment:\\s*\"([^\"]+)\"\\s*\\}/gm,\n );\n for (const m of overrideLines) {\n overrides[m[1]] = { mission: m[2], assignment: m[3] };\n }\n }\n\n const autoField = getField(frontmatter, 'auto');\n const auto = autoField === 'true' ? true : autoField === 'false' ? false : undefined;\n const kind = getField(frontmatter, 'kind') as SessionKind | undefined;\n const pidField = getField(frontmatter, 'pid');\n const pid = pidField ? parseInt(pidField, 10) : undefined;\n const cwdField = getField(frontmatter, 'cwd');\n\n let ports: number[] | undefined;\n const portsMatch = frontmatter.match(/^ports:\\s*\\[([^\\]]*)\\]/m);\n if (portsMatch) {\n ports = portsMatch[1].split(',').map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n));\n }\n\n return {\n session, registered, lastRefreshed, overrides,\n ...(auto != null && { auto }),\n ...(kind && { kind }),\n ...(pid != null && !isNaN(pid) && { pid }),\n ...(ports && ports.length > 0 && { ports }),\n ...(cwdField && { cwd: cwdField }),\n };\n}\n\nexport async function removeSession(dir: string, name: string): Promise<void> {\n const filePath = resolve(dir, `${sanitizeSessionName(name)}.md`);\n if (await fileExists(filePath)) {\n await unlink(filePath);\n }\n}\n\nexport async function updateLastRefreshed(dir: string, name: string): Promise<void> {\n const data = await readSessionFile(dir, name);\n if (!data) return;\n const content = buildSessionContent({ ...data, lastRefreshed: nowTimestamp() });\n await writeFileForce(resolve(dir, `${sanitizeSessionName(name)}.md`), content);\n}\n\nexport async function setOverride(\n dir: string,\n sessionName: string,\n windowIndex: number,\n paneIndex: number,\n assignment: { mission: string; assignment: string } | null,\n): Promise<void> {\n const data = await readSessionFile(dir, sessionName);\n if (!data) return;\n const key = `${windowIndex}:${paneIndex}`;\n if (assignment) {\n data.overrides[key] = assignment;\n } else {\n delete data.overrides[key];\n }\n const content = buildSessionContent({ ...data });\n await writeFileForce(resolve(dir, `${sanitizeSessionName(sessionName)}.md`), content);\n}\n\nexport interface RegisterAutoOptions {\n kind: SessionKind;\n pid?: number;\n ports?: number[];\n cwd?: string;\n}\n\nexport async function registerAutoSession(\n dir: string,\n rawName: string,\n opts: RegisterAutoOptions,\n): Promise<string> {\n const name = sanitizeSessionName(rawName);\n await ensureDir(dir);\n const now = nowTimestamp();\n const content = buildSessionContent({\n session: name,\n registered: now,\n lastRefreshed: now,\n overrides: {},\n auto: true,\n kind: opts.kind,\n pid: opts.pid,\n ports: opts.ports,\n cwd: opts.cwd,\n });\n await writeFileForce(resolve(dir, `${name}.md`), content);\n return name;\n}\n","import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { resolve } from 'node:path';\nimport { realpath, readdir, readFile } from 'node:fs/promises';\nimport { listMissions } from './api.js';\nimport {\n readSessionFile,\n listSessionFiles,\n} from './servers.js';\nimport { extractFrontmatter, getField, getNestedField } from './parser.js';\nimport type {\n TrackedSession,\n TrackedWindow,\n TrackedPane,\n ServersResponse,\n SessionFileData,\n} from './types.js';\n\nconst exec = promisify(execFile);\n\n// --- Cache ---\nlet cache: { data: ServersResponse; expiry: number } | null = null;\nconst CACHE_TTL_MS = 10_000;\n\nexport function clearScanCache(): void {\n cache = null;\n}\n\n// --- Pure parsing functions (exported for testing) ---\n\nexport interface RawPane {\n windowIndex: number;\n windowName: string;\n paneIndex: number;\n command: string;\n cwd: string;\n pid: number;\n}\n\nexport function parseTmuxPaneOutput(output: string): RawPane[] {\n return output\n .trim()\n .split('\\n')\n .filter((line) => line.length > 0)\n .map((line) => {\n const [wi, wn, pi, cmd, cwd, pid] = line.split('|');\n return {\n windowIndex: parseInt(wi, 10),\n windowName: wn,\n paneIndex: parseInt(pi, 10),\n command: cmd,\n cwd,\n pid: parseInt(pid, 10),\n };\n });\n}\n\nexport function findListeningPorts(lsofOutput: string, pids: Set<number>): number[] {\n const ports: number[] = [];\n for (const line of lsofOutput.split('\\n')) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const pid = parseInt(parts[1], 10);\n if (!pids.has(pid)) continue;\n const tcpAddr = parts.find((p) => p.includes(':') && /:\\d+$/.test(p));\n if (tcpAddr) {\n const port = parseInt(tcpAddr.split(':').pop()!, 10);\n if (!isNaN(port) && !ports.includes(port)) {\n ports.push(port);\n }\n }\n }\n return ports;\n}\n\n// --- Shell helpers ---\n\nexport async function execQuiet(cmd: string, args: string[]): Promise<string> {\n try {\n const { stdout } = await exec(cmd, args);\n return stdout.trim();\n } catch {\n return '';\n }\n}\n\nexport async function checkTmuxAvailable(): Promise<boolean> {\n const result = await execQuiet('which', ['tmux']);\n return result.length > 0;\n}\n\nexport async function sessionAlive(name: string): Promise<boolean> {\n try {\n await exec('tmux', ['has-session', '-t', name]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function listTmuxPanes(sessionName: string): Promise<RawPane[]> {\n const output = await execQuiet('tmux', [\n 'list-panes', '-s', '-t', sessionName,\n '-F', '#{window_index}|#{window_name}|#{pane_index}|#{pane_current_command}|#{pane_current_path}|#{pane_pid}',\n ]);\n return parseTmuxPaneOutput(output);\n}\n\nexport async function getDescendantPids(rootPid: number, maxDepth: number = 4): Promise<Set<number>> {\n const all = new Set<number>([rootPid]);\n let frontier = [rootPid];\n\n for (let depth = 0; depth < maxDepth && frontier.length > 0; depth++) {\n const nextFrontier: number[] = [];\n for (const pid of frontier) {\n const output = await execQuiet('pgrep', ['-P', String(pid)]);\n for (const line of output.split('\\n')) {\n const child = parseInt(line, 10);\n if (!isNaN(child) && !all.has(child)) {\n all.add(child);\n nextFrontier.push(child);\n }\n }\n }\n frontier = nextFrontier;\n }\n\n return all;\n}\n\nexport async function getLsofOutput(): Promise<string> {\n return execQuiet('lsof', ['-i', '-P', '-n', '-sTCP:LISTEN']);\n}\n\nexport async function getGitInfo(cwd: string): Promise<{ branch: string | null; worktree: boolean }> {\n const branch = await execQuiet('git', ['-C', cwd, 'rev-parse', '--abbrev-ref', 'HEAD']);\n if (!branch) return { branch: null, worktree: false };\n\n const commonDir = await execQuiet('git', ['-C', cwd, 'rev-parse', '--git-common-dir']);\n const gitDir = await execQuiet('git', ['-C', cwd, 'rev-parse', '--git-dir']);\n\n let isWorktree = false;\n if (commonDir && gitDir && commonDir !== gitDir) {\n try {\n const resolvedCommon = await realpath(resolve(cwd, commonDir));\n const resolvedGit = await realpath(resolve(cwd, gitDir));\n isWorktree = resolvedCommon !== resolvedGit;\n } catch {\n isWorktree = false;\n }\n }\n\n return { branch: branch || null, worktree: isWorktree };\n}\n\n// --- Auto-linking ---\n\nexport interface AssignmentLink {\n mission: string;\n slug: string;\n title: string;\n}\n\nexport interface WorkspaceRecord {\n missionSlug: string;\n assignmentSlug: string;\n assignmentTitle: string;\n worktreePath: string | null;\n branch: string | null;\n}\n\nexport async function loadWorkspaceRecords(missionsDir: string): Promise<WorkspaceRecord[]> {\n const records: WorkspaceRecord[] = [];\n try {\n const missions = await listMissions(missionsDir);\n\n for (const mission of missions) {\n const assignmentsDir = resolve(missionsDir, mission.slug, 'assignments');\n let slugs: string[];\n try {\n slugs = await readdir(assignmentsDir);\n } catch {\n continue;\n }\n for (const aslug of slugs) {\n const aFile = resolve(assignmentsDir, aslug, 'assignment.md');\n try {\n const raw = await readFile(aFile, 'utf-8');\n const [fm] = extractFrontmatter(raw);\n if (!fm) continue;\n records.push({\n missionSlug: mission.slug,\n assignmentSlug: aslug,\n assignmentTitle: getField(fm, 'title') ?? aslug,\n worktreePath: getNestedField(fm, 'workspace', 'worktreePath') ?? null,\n branch: getNestedField(fm, 'workspace', 'branch') ?? null,\n });\n } catch {\n continue;\n }\n }\n }\n } catch {\n // If missions can't be loaded, auto-linking just returns no matches\n }\n return records;\n}\n\nexport async function resolveAndNormalize(p: string): Promise<string> {\n try {\n const resolved = await realpath(p);\n return resolved.replace(/\\/+$/, '');\n } catch {\n return p.replace(/\\/+$/, '');\n }\n}\n\nexport async function autoLinkPane(\n cwd: string,\n branch: string | null,\n records: WorkspaceRecord[],\n): Promise<AssignmentLink | null> {\n const normalizedCwd = await resolveAndNormalize(cwd);\n for (const rec of records) {\n if (rec.worktreePath) {\n const normalizedWt = await resolveAndNormalize(rec.worktreePath);\n if (normalizedCwd === normalizedWt) {\n return { mission: rec.missionSlug, slug: rec.assignmentSlug, title: rec.assignmentTitle };\n }\n }\n }\n if (branch) {\n for (const rec of records) {\n if (rec.branch && rec.branch === branch) {\n return { mission: rec.missionSlug, slug: rec.assignmentSlug, title: rec.assignmentTitle };\n }\n }\n }\n return null;\n}\n\n// --- Main scan function ---\n\nasync function scanSession(\n sessionData: SessionFileData,\n lsofOutput: string,\n workspaceRecords: WorkspaceRecord[],\n): Promise<TrackedSession> {\n const now = new Date().toISOString();\n const alive = await sessionAlive(sessionData.session);\n\n if (!alive) {\n return {\n name: sessionData.session,\n kind: 'tmux',\n registered: sessionData.registered,\n lastRefreshed: sessionData.lastRefreshed,\n scannedAt: now,\n alive: false,\n windows: [],\n };\n }\n\n const rawPanes = await listTmuxPanes(sessionData.session);\n\n // Group panes by window\n const windowMap = new Map<number, { name: string; panes: RawPane[] }>();\n for (const rp of rawPanes) {\n if (!windowMap.has(rp.windowIndex)) {\n windowMap.set(rp.windowIndex, { name: rp.windowName, panes: [] });\n }\n windowMap.get(rp.windowIndex)!.panes.push(rp);\n }\n\n // Get git info per unique cwd\n const cwdSet = new Set(rawPanes.map((p) => p.cwd));\n const gitInfoCache = new Map<string, { branch: string | null; worktree: boolean }>();\n for (const cwd of cwdSet) {\n gitInfoCache.set(cwd, await getGitInfo(cwd));\n }\n\n // Get all descendant PIDs for port lookup\n const pidToPaneKey = new Map<number, string>();\n for (const rp of rawPanes) {\n const descendants = await getDescendantPids(rp.pid);\n const key = `${rp.windowIndex}:${rp.paneIndex}`;\n for (const pid of descendants) {\n pidToPaneKey.set(pid, key);\n }\n }\n\n // Find ports per pane\n const panePorts = new Map<string, number[]>();\n for (const line of lsofOutput.split('\\n')) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const pid = parseInt(parts[1], 10);\n const paneKey = pidToPaneKey.get(pid);\n if (!paneKey) continue;\n const tcpAddr = parts.find((p) => p.includes(':') && /:\\d+$/.test(p));\n if (tcpAddr) {\n const port = parseInt(tcpAddr.split(':').pop()!, 10);\n if (!isNaN(port)) {\n if (!panePorts.has(paneKey)) panePorts.set(paneKey, []);\n const existing = panePorts.get(paneKey)!;\n if (!existing.includes(port)) existing.push(port);\n }\n }\n }\n\n // Build windows — use for-of loop, NOT .map() with async callback\n const windows: TrackedWindow[] = [];\n for (const [windowIndex, { name, panes: rawPanesInWindow }] of windowMap) {\n const panes: TrackedPane[] = [];\n for (const rp of rawPanesInWindow) {\n const key = `${rp.windowIndex}:${rp.paneIndex}`;\n const gitInfo = gitInfoCache.get(rp.cwd) ?? { branch: null, worktree: false };\n const ports = panePorts.get(key) ?? [];\n const urls = ports.map((p) => `http://localhost:${p}`);\n\n const override = sessionData.overrides[key];\n let assignment: AssignmentLink | null = null;\n if (override) {\n const rec = workspaceRecords.find(\n (r) => r.missionSlug === override.mission && r.assignmentSlug === override.assignment,\n );\n assignment = {\n mission: override.mission,\n slug: override.assignment,\n title: rec?.assignmentTitle ?? override.assignment,\n };\n } else {\n assignment = await autoLinkPane(rp.cwd, gitInfo.branch, workspaceRecords);\n }\n\n panes.push({\n index: rp.paneIndex,\n command: rp.command,\n cwd: rp.cwd,\n branch: gitInfo.branch,\n worktree: gitInfo.worktree,\n ports,\n urls,\n assignment,\n });\n }\n\n windows.push({ index: windowIndex, name, panes });\n }\n\n windows.sort((a, b) => a.index - b.index);\n\n return {\n name: sessionData.session,\n kind: 'tmux' as const,\n registered: sessionData.registered,\n lastRefreshed: sessionData.lastRefreshed,\n scannedAt: now,\n alive: true,\n windows,\n };\n}\n\nasync function scanProcessSession(\n sessionData: SessionFileData,\n lsofOutput: string,\n workspaceRecords: WorkspaceRecord[],\n): Promise<TrackedSession> {\n const now = new Date().toISOString();\n\n // Check if the process is still alive\n let alive = false;\n if (sessionData.pid) {\n try {\n process.kill(sessionData.pid, 0);\n alive = true;\n } catch {\n alive = false;\n }\n }\n\n if (!alive || !sessionData.cwd) {\n return {\n name: sessionData.session,\n kind: 'process',\n registered: sessionData.registered,\n lastRefreshed: sessionData.lastRefreshed,\n scannedAt: now,\n alive: false,\n windows: [],\n };\n }\n\n // Re-resolve ports from lsof for the PID\n const ports = findListeningPorts(lsofOutput, new Set([sessionData.pid!]));\n\n const gitInfo = await getGitInfo(sessionData.cwd);\n\n // Honor manual overrides (process sessions use key \"0:0\")\n const override = sessionData.overrides['0:0'];\n let assignment: AssignmentLink | null = null;\n if (override) {\n const rec = workspaceRecords.find(\n (r) => r.missionSlug === override.mission && r.assignmentSlug === override.assignment,\n );\n assignment = {\n mission: override.mission,\n slug: override.assignment,\n title: rec?.assignmentTitle ?? override.assignment,\n };\n } else {\n assignment = await autoLinkPane(sessionData.cwd, gitInfo.branch, workspaceRecords);\n }\n\n const pane: TrackedPane = {\n index: 0,\n command: sessionData.session,\n cwd: sessionData.cwd,\n branch: gitInfo.branch,\n worktree: gitInfo.worktree,\n ports,\n urls: ports.map((p) => `http://localhost:${p}`),\n assignment,\n };\n\n return {\n name: sessionData.session,\n kind: 'process' as const,\n registered: sessionData.registered,\n lastRefreshed: sessionData.lastRefreshed,\n scannedAt: now,\n alive: true,\n windows: [{ index: 0, name: 'process', panes: [pane] }],\n };\n}\n\nexport async function scanAllSessions(\n serversDir: string,\n missionsDir: string,\n options?: { bypassCache?: boolean },\n): Promise<ServersResponse> {\n if (!options?.bypassCache && cache && Date.now() < cache.expiry) {\n return cache.data;\n }\n\n const tmuxAvailable = await checkTmuxAvailable();\n const names = await listSessionFiles(serversDir);\n const lsofOutput = await getLsofOutput();\n const workspaceRecords = await loadWorkspaceRecords(missionsDir);\n\n const sessions: TrackedSession[] = [];\n for (const name of names) {\n const data = await readSessionFile(serversDir, name);\n if (!data) continue;\n\n if (data.kind === 'process') {\n sessions.push(await scanProcessSession(data, lsofOutput, workspaceRecords));\n } else if (tmuxAvailable) {\n sessions.push(await scanSession(data, lsofOutput, workspaceRecords));\n }\n // Skip tmux-kind entries when tmux is unavailable\n }\n\n const result: ServersResponse = { sessions, tmuxAvailable };\n cache = { data: result, expiry: Date.now() + CACHE_TTL_MS };\n return result;\n}\n\nexport async function scanSingleSession(\n serversDir: string,\n missionsDir: string,\n name: string,\n): Promise<TrackedSession | null> {\n const data = await readSessionFile(serversDir, name);\n if (!data) return null;\n\n const lsofOutput = await getLsofOutput();\n const workspaceRecords = await loadWorkspaceRecords(missionsDir);\n\n if (data.kind === 'process') {\n return scanProcessSession(data, lsofOutput, workspaceRecords);\n }\n return scanSession(data, lsofOutput, workspaceRecords);\n}\n","import { readdir, readFile, writeFile } from 'node:fs/promises';\nimport { resolve, dirname } from 'node:path';\nimport { getTargetStatus, DEFAULT_STATUSES, DEFAULT_TRANSITION_TABLE, buildTransitionTable } from '../lifecycle/index.js';\nimport { fileExists } from '../utils/fs.js';\nimport { readConfig, type StatusConfig, type StatusTransition } from '../utils/config.js';\nimport {\n parseMission,\n parseStatus,\n parseAssignmentFull,\n parsePlan,\n parseScratchpad,\n parseHandoff,\n parseDecisionRecord,\n parseResource,\n parseMemory,\n parsePlaybook,\n extractMermaidGraph,\n} from './parser.js';\nimport { getDashboardHelp } from './help.js';\nimport type {\n AssignmentBoardItem,\n AssignmentDetail,\n AssignmentSummary,\n AssignmentsBoardResponse,\n AssignmentTransitionAction,\n AttentionItem,\n AttentionResponse,\n EditableDocumentResponse,\n HelpResponse,\n MemorySummary,\n MissionDetail,\n MissionSummary,\n OverviewResponse,\n ProgressCounts,\n NeedsAttention,\n RecentActivityItem,\n ResourceSummary,\n PlaybookSummary,\n PlaybookDetail,\n} from './types.js';\n\nconst STALE_ASSIGNMENT_MS = 7 * 24 * 60 * 60 * 1000;\nconst ATTENTION_PAGE_LIMIT = 50;\nconst OVERVIEW_ATTENTION_LIMIT = 6;\nconst RECENT_MISSIONS_LIMIT = 6;\nconst RECENT_ACTIVITY_LIMIT = 12;\n\ntype AssignmentRecord = ReturnType<typeof parseAssignmentFull>;\n\ninterface MissionRecord {\n missionPath: string;\n mission: ReturnType<typeof parseMission>;\n assignments: AssignmentRecord[];\n summary: MissionSummary;\n dependencyGraph: string | null;\n}\n\ninterface AttentionSeverityCounts {\n critical: number;\n high: number;\n medium: number;\n low: number;\n}\n\nconst DEFAULT_TRANSITION_DEFINITIONS: Array<{\n command: string;\n label: string;\n description: string;\n requiresReason: boolean;\n}> = [\n {\n command: 'start',\n label: 'Start',\n description: 'Move pending or review work into active execution.',\n requiresReason: false,\n },\n {\n command: 'review',\n label: 'Send To Review',\n description: 'Mark the assignment ready for inspection.',\n requiresReason: false,\n },\n {\n command: 'complete',\n label: 'Complete',\n description: 'Mark the assignment done.',\n requiresReason: false,\n },\n {\n command: 'block',\n label: 'Block',\n description: 'Record an exceptional blocker and pause work.',\n requiresReason: true,\n },\n {\n command: 'unblock',\n label: 'Unblock',\n description: 'Resume active work after the blocker is cleared.',\n requiresReason: false,\n },\n {\n command: 'fail',\n label: 'Fail',\n description: 'Mark the assignment as failed when it cannot be completed as planned.',\n requiresReason: false,\n },\n {\n command: 'reopen',\n label: 'Reopen',\n description: 'Reopen a completed or failed assignment to resume work.',\n requiresReason: false,\n },\n];\n\nconst DEFAULT_STATUS_COLORS: Record<string, string> = {\n pending: 'slate',\n in_progress: 'teal',\n blocked: 'amber',\n review: 'violet',\n completed: 'emerald',\n failed: 'rose',\n};\n\nfunction toTitleCase(s: string): string {\n return s.replace(/_/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction getTransitionDefinitions(config: ResolvedStatusConfig) {\n if (!config.custom) return DEFAULT_TRANSITION_DEFINITIONS;\n // Deduplicate commands from transitions\n const seen = new Set<string>();\n return config.transitions\n .filter((t) => {\n if (seen.has(t.command)) return false;\n seen.add(t.command);\n return true;\n })\n .map((t) => ({\n command: t.command,\n label: t.label ?? toTitleCase(t.command),\n description: t.description ?? `Transition via ${t.command}.`,\n requiresReason: t.requiresReason ?? false,\n }));\n}\n\ninterface ResolvedStatusConfig {\n custom: boolean;\n statuses: Array<{ id: string; label: string; description?: string; color?: string; terminal?: boolean }>;\n order: string[];\n transitions: StatusTransition[];\n transitionTable: Map<string, string>;\n terminalStatuses: ReadonlySet<string>;\n}\n\nlet _cachedConfig: ResolvedStatusConfig | null = null;\n\nexport async function getStatusConfig(): Promise<ResolvedStatusConfig> {\n if (_cachedConfig) return _cachedConfig;\n\n const config = await readConfig();\n\n if (config.statuses) {\n const terminalSet = new Set(\n config.statuses.statuses.filter((s) => s.terminal).map((s) => s.id),\n );\n _cachedConfig = {\n custom: true,\n statuses: config.statuses.statuses,\n order: config.statuses.order,\n transitions: config.statuses.transitions,\n transitionTable: buildTransitionTable(config.statuses.transitions),\n terminalStatuses: terminalSet.size > 0 ? terminalSet : new Set(['completed', 'failed']),\n };\n } else {\n _cachedConfig = {\n custom: false,\n statuses: DEFAULT_STATUSES.map((id) => ({\n id,\n label: toTitleCase(id),\n color: DEFAULT_STATUS_COLORS[id] ?? 'gray',\n terminal: id === 'completed' || id === 'failed',\n })),\n order: [...DEFAULT_STATUSES],\n transitions: Array.from(DEFAULT_TRANSITION_TABLE.entries()).map(([key, to]) => {\n const [from, command] = key.split(':');\n return { from, command, to };\n }),\n transitionTable: DEFAULT_TRANSITION_TABLE,\n terminalStatuses: new Set(['completed', 'failed']),\n };\n }\n\n return _cachedConfig;\n}\n\nexport function clearStatusConfigCache(): void {\n _cachedConfig = null;\n}\n\n/**\n * List all missions with source-first summary data.\n * GET /api/missions\n */\nexport async function listMissions(missionsDir: string): Promise<MissionSummary[]> {\n const missionRecords = await listMissionRecords(missionsDir);\n return missionRecords.map((record) => record.summary);\n}\n\n/**\n * Read the workspace registry file (~/.syntaur/workspaces.json).\n * Returns an array of explicitly registered workspace names.\n */\nasync function readWorkspaceRegistry(missionsDir: string): Promise<string[]> {\n const registryPath = resolve(dirname(missionsDir), 'workspaces.json');\n try {\n const raw = await readFile(registryPath, 'utf-8');\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? parsed.filter((w): w is string => typeof w === 'string') : [];\n } catch {\n return [];\n }\n}\n\nasync function writeWorkspaceRegistry(missionsDir: string, workspaces: string[]): Promise<void> {\n const registryPath = resolve(dirname(missionsDir), 'workspaces.json');\n await writeFile(registryPath, JSON.stringify(workspaces, null, 2) + '\\n', 'utf-8');\n}\n\n/**\n * List all workspaces: merge registry (explicit) with discovered (from missions).\n * GET /api/workspaces\n */\nexport async function listWorkspaces(missionsDir: string): Promise<{ workspaces: string[]; hasUngrouped: boolean }> {\n const [missionRecords, registered] = await Promise.all([\n listMissionRecords(missionsDir),\n readWorkspaceRegistry(missionsDir),\n ]);\n const workspaceSet = new Set<string>(registered);\n let hasUngrouped = false;\n for (const record of missionRecords) {\n if (record.mission.workspace) {\n workspaceSet.add(record.mission.workspace);\n } else {\n hasUngrouped = true;\n }\n }\n const workspaces = Array.from(workspaceSet).sort();\n return { workspaces, hasUngrouped };\n}\n\n/**\n * Create an empty workspace by registering it.\n * POST /api/workspaces\n */\nexport async function createWorkspace(missionsDir: string, name: string): Promise<void> {\n const registered = await readWorkspaceRegistry(missionsDir);\n if (!registered.includes(name)) {\n registered.push(name);\n registered.sort();\n await writeWorkspaceRegistry(missionsDir, registered);\n }\n}\n\n/**\n * Delete a workspace from the registry.\n * DELETE /api/workspaces/:name\n */\nexport async function deleteWorkspace(missionsDir: string, name: string): Promise<void> {\n const registered = await readWorkspaceRegistry(missionsDir);\n const filtered = registered.filter((w) => w !== name);\n await writeWorkspaceRegistry(missionsDir, filtered);\n}\n\n/**\n * Get overview data used by the app landing page.\n * GET /api/overview\n */\nexport async function getOverview(missionsDir: string, serversDir?: string): Promise<OverviewResponse> {\n const missionRecords = await listMissionRecords(missionsDir);\n const attention = buildAttentionItems(missionRecords);\n const recentActivity = buildRecentActivity(missionRecords);\n\n let serverStats: OverviewResponse['serverStats'];\n if (serversDir) {\n try {\n const { scanAllSessions } = await import('./scanner.js');\n const servers = await scanAllSessions(serversDir, missionsDir);\n if (servers.tmuxAvailable) {\n const alive = servers.sessions.filter(s => s.alive).length;\n const totalPorts = servers.sessions.reduce((sum, s) =>\n sum + s.windows.reduce((ws, w) =>\n ws + w.panes.reduce((ps, p) => ps + p.ports.length, 0), 0), 0);\n serverStats = {\n trackedSessions: servers.sessions.length,\n aliveSessions: alive,\n deadSessions: servers.sessions.length - alive,\n totalPorts,\n };\n }\n } catch {\n // Server scanning failure should not break overview\n }\n }\n\n return {\n generatedAt: new Date().toISOString(),\n firstRun: missionRecords.length === 0,\n stats: {\n activeMissions: missionRecords.filter((record) => record.summary.status === 'active').length,\n inProgressAssignments: missionRecords.reduce(\n (total, record) => total + (record.summary.progress['in_progress'] ?? 0),\n 0,\n ),\n blockedAssignments: missionRecords.reduce(\n (total, record) => total + (record.summary.progress['blocked'] ?? 0),\n 0,\n ),\n reviewAssignments: missionRecords.reduce(\n (total, record) => total + (record.summary.progress['review'] ?? 0),\n 0,\n ),\n failedAssignments: missionRecords.reduce(\n (total, record) => total + (record.summary.progress['failed'] ?? 0),\n 0,\n ),\n staleAssignments: missionRecords.reduce(\n (total, record) =>\n total + record.assignments.filter((assignment) => isStale(assignment.updated)).length,\n 0,\n ),\n },\n attention: attention.slice(0, OVERVIEW_ATTENTION_LIMIT),\n recentMissions: missionRecords\n .map((record) => record.summary)\n .sort((left, right) => compareTimestamps(right.updated, left.updated))\n .slice(0, RECENT_MISSIONS_LIMIT),\n recentActivity: recentActivity.slice(0, RECENT_ACTIVITY_LIMIT),\n serverStats,\n };\n}\n\n/**\n * Get the explicit attention queue.\n * GET /api/attention\n */\nexport async function getAttention(missionsDir: string, serversDir?: string): Promise<AttentionResponse> {\n const missionRecords = await listMissionRecords(missionsDir);\n const items = buildAttentionItems(missionRecords);\n\n if (serversDir) {\n try {\n const { scanAllSessions } = await import('./scanner.js');\n const servers = await scanAllSessions(serversDir, missionsDir);\n for (const session of servers.sessions) {\n if (!session.alive) {\n items.push({\n id: `server-dead-${session.name}`,\n severity: 'low',\n missionSlug: '',\n missionTitle: '',\n assignmentSlug: '',\n assignmentTitle: `tmux: ${session.name}`,\n status: 'failed',\n reason: 'Tmux session no longer exists but is still registered',\n updated: session.lastRefreshed,\n href: '/servers',\n stale: false,\n blockedReason: null,\n });\n }\n }\n } catch {\n // Server scanning failure should not break attention\n }\n }\n\n const pagedItems = items.slice(0, ATTENTION_PAGE_LIMIT);\n const summary: AttentionSeverityCounts = {\n critical: 0,\n high: 0,\n medium: 0,\n low: 0,\n };\n\n for (const item of pagedItems) {\n summary[item.severity]++;\n }\n\n return {\n generatedAt: new Date().toISOString(),\n summary: {\n total: pagedItems.length,\n critical: summary.critical,\n high: summary.high,\n medium: summary.medium,\n low: summary.low,\n },\n items: pagedItems,\n };\n}\n\n/**\n * Get all assignments across all missions for the global kanban board.\n * GET /api/assignments\n */\nexport async function listAssignmentsBoard(missionsDir: string): Promise<AssignmentsBoardResponse> {\n const missionRecords = await listMissionRecords(missionsDir);\n const assignments = await Promise.all(\n missionRecords.flatMap(async (record) =>\n Promise.all(\n record.assignments.map(async (assignment) =>\n toAssignmentBoardItem(missionsDir, record, assignment),\n ),\n ),\n ),\n );\n\n return {\n generatedAt: new Date().toISOString(),\n assignments: assignments\n .flat()\n .sort((left, right) => compareTimestamps(right.updated, left.updated)),\n };\n}\n\n/**\n * Get the structured help model used by Help and onboarding surfaces.\n * GET /api/help\n */\nexport async function getHelp(): Promise<HelpResponse> {\n return getDashboardHelp();\n}\n\n/**\n * Get a raw editable document for dashboard editor pages.\n */\nexport async function getEditableDocument(\n missionsDir: string,\n documentType: EditableDocumentResponse['documentType'],\n missionSlug: string,\n assignmentSlug?: string,\n): Promise<EditableDocumentResponse | null> {\n const filePath = getDocumentPath(missionsDir, documentType, missionSlug, assignmentSlug);\n if (!filePath || !(await fileExists(filePath))) {\n return null;\n }\n\n const content = await readFile(filePath, 'utf-8');\n const title = getEditableDocumentTitle(documentType, missionSlug, assignmentSlug);\n\n return {\n documentType,\n title,\n content,\n missionSlug,\n assignmentSlug,\n appendOnly: documentType === 'handoff' || documentType === 'decision-record',\n };\n}\n\n/**\n * Get full mission detail with assignments, resources, and memories.\n * GET /api/missions/:slug\n */\nexport async function getMissionDetail(\n missionsDir: string,\n slug: string,\n): Promise<MissionDetail | null> {\n const missionPath = resolve(missionsDir, slug);\n const missionMdPath = resolve(missionPath, 'mission.md');\n\n if (!(await fileExists(missionMdPath))) {\n return null;\n }\n\n const missionContent = await readFile(missionMdPath, 'utf-8');\n const mission = parseMission(missionContent);\n const assignments = await listAssignmentRecords(missionPath);\n const rollup = buildMissionRollup(mission, assignments);\n const dependencyGraph = await loadDependencyGraph(missionPath, assignments);\n const resources = await listResources(missionPath);\n const memories = await listMemories(missionPath);\n const updated = getMissionActivityTimestamp(mission.updated, assignments);\n\n return {\n slug: mission.slug || slug,\n title: mission.title,\n status: rollup.status,\n statusOverride: mission.statusOverride,\n archived: mission.archived,\n archivedAt: mission.archivedAt,\n archivedReason: mission.archivedReason,\n created: mission.created,\n updated,\n tags: mission.tags,\n body: mission.body,\n progress: rollup.progress,\n needsAttention: rollup.needsAttention,\n assignments: assignments\n .map(toAssignmentSummary)\n .sort((left, right) => compareTimestamps(right.updated, left.updated)),\n resources,\n memories,\n dependencyGraph,\n workspace: mission.workspace,\n };\n}\n\n/**\n * Get full assignment detail with plan, scratchpad, handoff, and decision record.\n * GET /api/missions/:slug/assignments/:aslug\n */\nexport async function getAssignmentDetail(\n missionsDir: string,\n missionSlug: string,\n assignmentSlug: string,\n): Promise<AssignmentDetail | null> {\n const assignmentDir = resolve(missionsDir, missionSlug, 'assignments', assignmentSlug);\n const assignmentMdPath = resolve(assignmentDir, 'assignment.md');\n\n if (!(await fileExists(assignmentMdPath))) {\n return null;\n }\n\n const assignmentContent = await readFile(assignmentMdPath, 'utf-8');\n const assignment = parseAssignmentFull(assignmentContent);\n\n let plan: AssignmentDetail['plan'] = null;\n const planPath = resolve(assignmentDir, 'plan.md');\n if (await fileExists(planPath)) {\n const planContent = await readFile(planPath, 'utf-8');\n const parsed = parsePlan(planContent);\n plan = {\n status: parsed.status,\n updated: parsed.updated,\n body: parsed.body,\n };\n }\n\n let scratchpad: AssignmentDetail['scratchpad'] = null;\n const scratchpadPath = resolve(assignmentDir, 'scratchpad.md');\n if (await fileExists(scratchpadPath)) {\n const scratchpadContent = await readFile(scratchpadPath, 'utf-8');\n const parsed = parseScratchpad(scratchpadContent);\n scratchpad = {\n updated: parsed.updated,\n body: parsed.body,\n };\n }\n\n let handoff: AssignmentDetail['handoff'] = null;\n const handoffPath = resolve(assignmentDir, 'handoff.md');\n if (await fileExists(handoffPath)) {\n const handoffContent = await readFile(handoffPath, 'utf-8');\n const parsed = parseHandoff(handoffContent);\n handoff = {\n updated: parsed.updated,\n handoffCount: parsed.handoffCount,\n body: parsed.body,\n };\n }\n\n let decisionRecord: AssignmentDetail['decisionRecord'] = null;\n const decisionRecordPath = resolve(assignmentDir, 'decision-record.md');\n if (await fileExists(decisionRecordPath)) {\n const decisionRecordContent = await readFile(decisionRecordPath, 'utf-8');\n const parsed = parseDecisionRecord(decisionRecordContent);\n decisionRecord = {\n updated: parsed.updated,\n decisionCount: parsed.decisionCount,\n body: parsed.body,\n };\n }\n\n return {\n id: assignment.id,\n missionSlug,\n slug: assignment.slug || assignmentSlug,\n title: assignment.title,\n status: assignment.status,\n priority: assignment.priority as AssignmentDetail['priority'],\n assignee: assignment.assignee,\n dependsOn: assignment.dependsOn,\n blockedReason: assignment.blockedReason,\n workspace: assignment.workspace,\n externalIds: assignment.externalIds,\n tags: assignment.tags,\n created: assignment.created,\n updated: assignment.updated,\n body: assignment.body,\n plan,\n scratchpad,\n handoff,\n decisionRecord,\n availableTransitions: await getAvailableTransitions(\n missionsDir,\n missionSlug,\n assignmentSlug,\n assignment,\n ),\n };\n}\n\nasync function listMissionRecords(missionsDir: string): Promise<MissionRecord[]> {\n if (!(await fileExists(missionsDir))) {\n return [];\n }\n\n const entries = await readdir(missionsDir, { withFileTypes: true });\n const missionDirs = entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith('.'));\n const records: MissionRecord[] = [];\n\n for (const entry of missionDirs) {\n const missionPath = resolve(missionsDir, entry.name);\n const missionMdPath = resolve(missionPath, 'mission.md');\n\n if (!(await fileExists(missionMdPath))) {\n continue;\n }\n\n const missionContent = await readFile(missionMdPath, 'utf-8');\n const mission = parseMission(missionContent);\n const assignments = await listAssignmentRecords(missionPath);\n const rollup = buildMissionRollup(mission, assignments);\n const updated = getMissionActivityTimestamp(mission.updated, assignments);\n\n records.push({\n missionPath,\n mission,\n assignments,\n dependencyGraph: await loadDependencyGraph(missionPath, assignments),\n summary: {\n slug: mission.slug || entry.name,\n title: mission.title,\n status: rollup.status,\n statusOverride: mission.statusOverride,\n archived: mission.archived,\n archivedAt: mission.archivedAt,\n archivedReason: mission.archivedReason,\n created: mission.created,\n updated,\n tags: mission.tags,\n progress: rollup.progress,\n needsAttention: rollup.needsAttention,\n workspace: mission.workspace,\n },\n });\n }\n\n records.sort((left, right) => compareTimestamps(right.summary.updated, left.summary.updated));\n return records;\n}\n\nasync function listAssignmentRecords(missionPath: string): Promise<AssignmentRecord[]> {\n const assignmentsDir = resolve(missionPath, 'assignments');\n if (!(await fileExists(assignmentsDir))) {\n return [];\n }\n\n const entries = await readdir(assignmentsDir, { withFileTypes: true });\n const records: AssignmentRecord[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n continue;\n }\n\n const assignmentMd = resolve(assignmentsDir, entry.name, 'assignment.md');\n if (!(await fileExists(assignmentMd))) {\n continue;\n }\n\n const content = await readFile(assignmentMd, 'utf-8');\n records.push(parseAssignmentFull(content));\n }\n\n records.sort((left, right) => compareTimestamps(right.updated, left.updated));\n return records;\n}\n\nasync function listResources(missionPath: string): Promise<ResourceSummary[]> {\n const resourcesDir = resolve(missionPath, 'resources');\n if (!(await fileExists(resourcesDir))) {\n return [];\n }\n\n const entries = await readdir(resourcesDir, { withFileTypes: true });\n const results: ResourceSummary[] = [];\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md') || entry.name.startsWith('_')) {\n continue;\n }\n\n const filePath = resolve(resourcesDir, entry.name);\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseResource(content);\n results.push({\n name: parsed.name,\n slug: entry.name.replace(/\\.md$/, ''),\n category: parsed.category,\n source: parsed.source,\n relatedAssignments: parsed.relatedAssignments,\n updated: parsed.updated,\n });\n }\n\n results.sort((left, right) => compareTimestamps(right.updated, left.updated));\n return results;\n}\n\nasync function listMemories(missionPath: string): Promise<MemorySummary[]> {\n const memoriesDir = resolve(missionPath, 'memories');\n if (!(await fileExists(memoriesDir))) {\n return [];\n }\n\n const entries = await readdir(memoriesDir, { withFileTypes: true });\n const results: MemorySummary[] = [];\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md') || entry.name.startsWith('_')) {\n continue;\n }\n\n const filePath = resolve(memoriesDir, entry.name);\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseMemory(content);\n results.push({\n name: parsed.name,\n slug: entry.name.replace(/\\.md$/, ''),\n source: parsed.source,\n scope: parsed.scope,\n sourceAssignment: parsed.sourceAssignment,\n updated: parsed.updated,\n });\n }\n\n results.sort((left, right) => compareTimestamps(right.updated, left.updated));\n return results;\n}\n\nasync function loadDependencyGraph(\n missionPath: string,\n assignments: AssignmentRecord[],\n): Promise<string | null> {\n const statusPath = resolve(missionPath, '_status.md');\n if (await fileExists(statusPath)) {\n const statusContent = await readFile(statusPath, 'utf-8');\n const parsed = parseStatus(statusContent);\n const derivedGraph = extractMermaidGraph(parsed.body);\n if (derivedGraph) {\n return derivedGraph;\n }\n }\n\n return buildDependencyGraph(assignments);\n}\n\nfunction buildMissionRollup(\n mission: ReturnType<typeof parseMission>,\n assignments: AssignmentRecord[],\n): {\n progress: ProgressCounts;\n needsAttention: NeedsAttention;\n status: string;\n} {\n const progress: ProgressCounts = { total: assignments.length };\n\n let unansweredQuestions = 0;\n for (const assignment of assignments) {\n const s = assignment.status;\n progress[s] = (progress[s] ?? 0) + 1;\n unansweredQuestions += countPendingAnswers(assignment.body);\n }\n\n const needsAttention: NeedsAttention = {\n blockedCount: progress['blocked'] ?? 0,\n failedCount: progress['failed'] ?? 0,\n unansweredQuestions,\n };\n\n let status = 'pending';\n if (mission.statusOverride) {\n status = mission.statusOverride;\n } else if (mission.archived) {\n status = 'archived';\n } else if (progress.total > 0 && (progress['completed'] ?? 0) === progress.total) {\n status = 'completed';\n } else if ((progress['in_progress'] ?? 0) > 0 || (progress['review'] ?? 0) > 0) {\n status = 'active';\n } else if ((progress['failed'] ?? 0) > 0) {\n status = 'failed';\n } else if ((progress['blocked'] ?? 0) > 0) {\n status = 'blocked';\n } else if (progress.total === 0 || (progress['pending'] ?? 0) === progress.total) {\n status = 'pending';\n } else {\n status = 'active';\n }\n\n return { progress, needsAttention, status };\n}\n\nfunction toAssignmentSummary(assignment: AssignmentRecord): AssignmentSummary {\n return {\n id: assignment.id,\n slug: assignment.slug,\n title: assignment.title,\n status: assignment.status,\n priority: assignment.priority as AssignmentSummary['priority'],\n assignee: assignment.assignee,\n dependsOn: assignment.dependsOn,\n updated: assignment.updated,\n };\n}\n\nasync function toAssignmentBoardItem(\n missionsDir: string,\n missionRecord: MissionRecord,\n assignment: AssignmentRecord,\n): Promise<AssignmentBoardItem> {\n return {\n ...toAssignmentSummary(assignment),\n missionSlug: missionRecord.summary.slug,\n missionTitle: missionRecord.summary.title,\n blockedReason: assignment.blockedReason,\n missionWorkspace: missionRecord.mission.workspace,\n availableTransitions: await getAvailableTransitions(\n missionsDir,\n missionRecord.summary.slug,\n assignment.slug,\n assignment,\n ),\n };\n}\n\nconst DEFAULT_GRAPH_COLORS: Record<string, string> = {\n completed: 'fill:#4ea84f,stroke:#1f6b29,color:#ffffff',\n in_progress: 'fill:#1e6fd9,stroke:#0f3f8f,color:#ffffff',\n pending: 'fill:#c0ccd9,stroke:#738399,color:#163047',\n blocked: 'fill:#db5a3f,stroke:#8d2815,color:#ffffff',\n failed: 'fill:#9f2d2d,stroke:#651616,color:#ffffff',\n review: 'fill:#c6911e,stroke:#7a5a10,color:#ffffff',\n};\n\nfunction buildDependencyGraph(assignments: AssignmentRecord[]): string | null {\n const edges: string[] = [];\n const usedStatuses = new Set<string>();\n\n for (const assignment of assignments) {\n for (const dependency of assignment.dependsOn) {\n const depStatus = findAssignmentStatus(assignments, dependency);\n usedStatuses.add(depStatus);\n usedStatuses.add(assignment.status);\n edges.push(\n ` ${dependency}:::${depStatus} --> ${assignment.slug}:::${assignment.status}`,\n );\n }\n }\n\n if (edges.length === 0) {\n return null;\n }\n\n const classDefs: string[] = [];\n for (const status of usedStatuses) {\n const colors = DEFAULT_GRAPH_COLORS[status] ?? 'fill:#94a3b8,stroke:#64748b,color:#ffffff';\n classDefs.push(` classDef ${status} ${colors}`);\n }\n\n return ['graph TD', ...edges, ...classDefs].join('\\n');\n}\n\nfunction findAssignmentStatus(assignments: AssignmentRecord[], slug: string): string {\n return assignments.find((assignment) => assignment.slug === slug)?.status ?? 'pending';\n}\n\nasync function getAvailableTransitions(\n missionsDir: string,\n missionSlug: string,\n assignmentSlug: string,\n assignment: AssignmentRecord,\n): Promise<AssignmentTransitionAction[]> {\n const config = await getStatusConfig();\n const transitionDefs = getTransitionDefinitions(config);\n const actions: AssignmentTransitionAction[] = [];\n const missionPath = resolve(missionsDir, missionSlug);\n\n for (const definition of transitionDefs) {\n let warning: string | null = null;\n\n if (definition.command === 'start' && !assignment.assignee) {\n warning = 'No assignee set — consider assigning before starting.';\n }\n\n if (definition.command === 'start' && assignment.dependsOn.length > 0) {\n const unmetDependencies = await getUnmetDependencies(missionPath, assignment.dependsOn, config.terminalStatuses);\n if (unmetDependencies.length > 0) {\n warning = `Unmet dependencies: ${unmetDependencies.join(', ')}.`;\n }\n }\n\n const target = getTargetStatus(assignment.status, definition.command, config.transitionTable);\n\n actions.push({\n command: definition.command,\n label: definition.label,\n description: definition.description,\n targetStatus: target ?? definition.command,\n disabled: false,\n disabledReason: null,\n warning,\n requiresReason: definition.requiresReason,\n });\n }\n\n return actions;\n}\n\nasync function getUnmetDependencies(missionPath: string, dependsOn: string[], terminalStatuses?: ReadonlySet<string>): Promise<string[]> {\n const terminals = terminalStatuses ?? new Set(['completed']);\n const unmet: string[] = [];\n\n for (const dependency of dependsOn) {\n const dependencyPath = resolve(missionPath, 'assignments', dependency, 'assignment.md');\n if (!(await fileExists(dependencyPath))) {\n unmet.push(`${dependency} (missing)`);\n continue;\n }\n\n const content = await readFile(dependencyPath, 'utf-8');\n const parsed = parseAssignmentFull(content);\n if (!terminals.has(parsed.status)) {\n unmet.push(`${dependency} (${parsed.status})`);\n }\n }\n\n return unmet;\n}\n\nfunction buildAttentionItems(missionRecords: MissionRecord[]): AttentionItem[] {\n const items: AttentionItem[] = [];\n\n for (const record of missionRecords) {\n for (const assignment of record.assignments) {\n const stale = isStale(assignment.updated);\n const base = {\n missionSlug: record.summary.slug,\n missionTitle: record.summary.title,\n assignmentSlug: assignment.slug,\n assignmentTitle: assignment.title,\n status: assignment.status,\n updated: assignment.updated,\n href: `/missions/${record.summary.slug}/assignments/${assignment.slug}`,\n blockedReason: assignment.blockedReason,\n stale,\n };\n\n if (assignment.status === 'failed') {\n items.push({\n id: `${record.summary.slug}:${assignment.slug}:failed`,\n severity: 'critical',\n reason: 'Marked failed and needs a recovery decision.',\n ...base,\n });\n }\n\n if (assignment.status === 'blocked') {\n items.push({\n id: `${record.summary.slug}:${assignment.slug}:blocked`,\n severity: 'high',\n reason: assignment.blockedReason || 'Blocked and waiting for intervention.',\n ...base,\n });\n }\n\n if (assignment.status === 'review') {\n items.push({\n id: `${record.summary.slug}:${assignment.slug}:review`,\n severity: 'medium',\n reason: 'Ready for review.',\n ...base,\n });\n }\n\n if (stale) {\n items.push({\n id: `${record.summary.slug}:${assignment.slug}:stale`,\n severity: 'low',\n reason: 'No source updates have been recorded in the last 7 days.',\n ...base,\n });\n }\n }\n }\n\n return items.sort(compareAttentionItems);\n}\n\nfunction buildRecentActivity(missionRecords: MissionRecord[]): RecentActivityItem[] {\n const activity: RecentActivityItem[] = [];\n\n for (const record of missionRecords) {\n activity.push({\n id: `mission:${record.summary.slug}`,\n type: 'mission',\n title: record.summary.title,\n updated: record.summary.updated,\n href: `/missions/${record.summary.slug}`,\n missionSlug: record.summary.slug,\n missionTitle: record.summary.title,\n assignmentSlug: null,\n summary: `Mission status is ${record.summary.status}.`,\n });\n\n for (const assignment of record.assignments) {\n activity.push({\n id: `assignment:${record.summary.slug}:${assignment.slug}`,\n type: 'assignment',\n title: assignment.title,\n updated: assignment.updated,\n href: `/missions/${record.summary.slug}/assignments/${assignment.slug}`,\n missionSlug: record.summary.slug,\n missionTitle: record.summary.title,\n assignmentSlug: assignment.slug,\n summary: `Assignment is ${assignment.status} with ${assignment.priority} priority.`,\n });\n }\n }\n\n activity.sort((left, right) => compareTimestamps(right.updated, left.updated));\n return activity;\n}\n\nfunction compareAttentionItems(left: AttentionItem, right: AttentionItem): number {\n const severityRank = { critical: 0, high: 1, medium: 2, low: 3 };\n const severityDifference = severityRank[left.severity] - severityRank[right.severity];\n if (severityDifference !== 0) {\n return severityDifference;\n }\n return compareTimestamps(right.updated, left.updated);\n}\n\nfunction compareTimestamps(left: string, right: string): number {\n return parseTimestamp(left) - parseTimestamp(right);\n}\n\nfunction parseTimestamp(timestamp: string): number {\n const parsed = Date.parse(timestamp);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction isStale(updated: string): boolean {\n const timestamp = parseTimestamp(updated);\n if (timestamp === 0) {\n return false;\n }\n return Date.now() - timestamp > STALE_ASSIGNMENT_MS;\n}\n\nfunction countPendingAnswers(body: string): number {\n const matches = body.match(/^\\*\\*A:\\*\\*\\s+pending\\s*$/gim);\n return matches ? matches.length : 0;\n}\n\nfunction getMissionActivityTimestamp(missionUpdated: string, assignments: AssignmentRecord[]): string {\n let latest = missionUpdated;\n for (const assignment of assignments) {\n if (compareTimestamps(assignment.updated, latest) > 0) {\n latest = assignment.updated;\n }\n }\n return latest;\n}\n\nfunction getDocumentPath(\n missionsDir: string,\n documentType: EditableDocumentResponse['documentType'],\n missionSlug: string,\n assignmentSlug?: string,\n): string | null {\n switch (documentType) {\n case 'mission':\n return resolve(missionsDir, missionSlug, 'mission.md');\n case 'assignment':\n return assignmentSlug\n ? resolve(missionsDir, missionSlug, 'assignments', assignmentSlug, 'assignment.md')\n : null;\n case 'plan':\n return assignmentSlug\n ? resolve(missionsDir, missionSlug, 'assignments', assignmentSlug, 'plan.md')\n : null;\n case 'scratchpad':\n return assignmentSlug\n ? resolve(missionsDir, missionSlug, 'assignments', assignmentSlug, 'scratchpad.md')\n : null;\n case 'handoff':\n return assignmentSlug\n ? resolve(missionsDir, missionSlug, 'assignments', assignmentSlug, 'handoff.md')\n : null;\n case 'decision-record':\n return assignmentSlug\n ? resolve(missionsDir, missionSlug, 'assignments', assignmentSlug, 'decision-record.md')\n : null;\n default:\n return null;\n }\n}\n\nfunction getEditableDocumentTitle(\n documentType: EditableDocumentResponse['documentType'],\n missionSlug: string,\n assignmentSlug?: string,\n): string {\n switch (documentType) {\n case 'mission':\n return `Edit Mission: ${missionSlug}`;\n case 'assignment':\n return `Edit Assignment: ${assignmentSlug || 'assignment'}`;\n case 'plan':\n return `Edit Plan: ${assignmentSlug || 'assignment'}`;\n case 'scratchpad':\n return `Edit Scratchpad: ${assignmentSlug || 'assignment'}`;\n case 'handoff':\n return `Append Handoff: ${assignmentSlug || 'assignment'}`;\n case 'decision-record':\n return `Append Decision: ${assignmentSlug || 'assignment'}`;\n case 'playbook':\n return `Edit Playbook: ${missionSlug}`;\n default:\n return missionSlug;\n }\n}\n\n// --- Playbook API ---\n\nexport async function listPlaybooks(playbooksDir: string): Promise<PlaybookSummary[]> {\n if (!(await fileExists(playbooksDir))) return [];\n\n const entries = await readdir(playbooksDir, { withFileTypes: true });\n const playbooks: PlaybookSummary[] = [];\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md') || entry.name.startsWith('_') || entry.name === 'manifest.md') continue;\n\n const filePath = resolve(playbooksDir, entry.name);\n const raw = await readFile(filePath, 'utf-8');\n const parsed = parsePlaybook(raw);\n\n const slug = parsed.slug || entry.name.replace(/\\.md$/, '');\n playbooks.push({\n slug,\n name: parsed.name || slug,\n description: parsed.description,\n whenToUse: parsed.whenToUse,\n tags: parsed.tags,\n created: parsed.created,\n updated: parsed.updated,\n });\n }\n\n return playbooks.sort((a, b) => (b.updated || b.created).localeCompare(a.updated || a.created));\n}\n\nexport async function getPlaybookDetail(\n playbooksDir: string,\n slug: string,\n): Promise<PlaybookDetail | null> {\n const filePath = resolve(playbooksDir, `${slug}.md`);\n if (!(await fileExists(filePath))) return null;\n\n const raw = await readFile(filePath, 'utf-8');\n const parsed = parsePlaybook(raw);\n\n return {\n slug: parsed.slug || slug,\n name: parsed.name || slug,\n description: parsed.description,\n whenToUse: parsed.whenToUse,\n tags: parsed.tags,\n created: parsed.created,\n updated: parsed.updated,\n body: parsed.body,\n };\n}\n","import { randomBytes } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { extractFrontmatter, getField } from '../dashboard/parser.js';\nimport { ensureDir, fileExists, writeFileForce } from '../utils/fs.js';\nimport type {\n TodoItem,\n TodoChecklist,\n TodoStatus,\n ArchiveInterval,\n LogEntry,\n TodoLog,\n} from './types.js';\n\n// --- Short ID ---\n\nexport function generateShortId(): string {\n return randomBytes(2).toString('hex');\n}\n\nexport function generateUniqueId(existingIds: Set<string>): string {\n let id = generateShortId();\n let attempts = 0;\n while (existingIds.has(id) && attempts < 100) {\n id = generateShortId();\n attempts++;\n }\n return id;\n}\n\n// --- Checklist parsing ---\n\nconst ITEM_REGEX = /^- \\[([ x!]|>[^\\]]*)\\]\\s+(.+)$/;\nconst ID_REGEX = /\\[t:([a-f0-9]{4})\\]/;\nconst TAG_REGEX = /#([a-zA-Z0-9_-]+)/g;\n\nfunction parseStatus(marker: string): { status: TodoStatus; session: string | null } {\n if (marker === ' ') return { status: 'open', session: null };\n if (marker === 'x') return { status: 'completed', session: null };\n if (marker === '!') return { status: 'blocked', session: null };\n if (marker.startsWith('>:')) return { status: 'in_progress', session: marker.slice(2) };\n if (marker === '>') return { status: 'in_progress', session: null };\n return { status: 'open', session: null };\n}\n\nfunction sanitizeSession(session: string): string {\n // Strip characters that would break the markdown checkbox syntax\n return session.replace(/[\\[\\]]/g, '');\n}\n\nfunction statusToMarker(item: TodoItem): string {\n switch (item.status) {\n case 'open':\n return ' ';\n case 'completed':\n return 'x';\n case 'blocked':\n return '!';\n case 'in_progress':\n return item.session ? `>:${sanitizeSession(item.session)}` : '>';\n }\n}\n\nexport function parseChecklistItem(line: string): TodoItem | null {\n const match = line.match(ITEM_REGEX);\n if (!match) return null;\n\n const marker = match[1];\n const rest = match[2];\n\n const { status, session } = parseStatus(marker);\n\n const idMatch = rest.match(ID_REGEX);\n const id = idMatch ? idMatch[1] : '';\n\n const tags: string[] = [];\n let tagMatch;\n const tagRegex = new RegExp(TAG_REGEX.source, 'g');\n while ((tagMatch = tagRegex.exec(rest)) !== null) {\n tags.push(tagMatch[1]);\n }\n\n // Description is everything before the first #tag or [t:...], trimmed\n let description = rest;\n const firstTagIdx = rest.search(/#[a-zA-Z0-9_-]/);\n const firstIdIdx = rest.search(/\\[t:[a-f0-9]{4}\\]/);\n const cutPoints = [firstTagIdx, firstIdIdx].filter((i) => i >= 0);\n if (cutPoints.length > 0) {\n description = rest.slice(0, Math.min(...cutPoints)).trim();\n }\n\n return { id, description, status, tags, session };\n}\n\nexport function serializeChecklistItem(item: TodoItem): string {\n const marker = statusToMarker(item);\n const tagStr = item.tags.map((t) => `#${t}`).join(' ');\n const parts = [`- [${marker}] ${item.description}`];\n if (tagStr) parts.push(tagStr);\n parts.push(`[t:${item.id}]`);\n return parts.join(' ');\n}\n\nexport function parseChecklist(content: string): TodoChecklist {\n const [fm, body] = extractFrontmatter(content);\n const workspace = getField(fm, 'workspace') || '_global';\n const archiveIntervalRaw = getField(fm, 'archiveInterval') || 'weekly';\n const archiveInterval = (['daily', 'weekly', 'monthly', 'never'].includes(archiveIntervalRaw)\n ? archiveIntervalRaw\n : 'weekly') as ArchiveInterval;\n\n const items: TodoItem[] = [];\n for (const line of body.split('\\n')) {\n const item = parseChecklistItem(line);\n if (item) items.push(item);\n }\n\n return { workspace, archiveInterval, items };\n}\n\nexport function serializeChecklist(checklist: TodoChecklist): string {\n const fm = [\n '---',\n `workspace: ${checklist.workspace}`,\n `archiveInterval: ${checklist.archiveInterval}`,\n '---',\n ].join('\\n');\n\n const header = '# Quick Todos';\n const items = checklist.items.map(serializeChecklistItem).join('\\n');\n\n return `${fm}\\n\\n${header}\\n\\n${items}\\n`;\n}\n\n// --- Log parsing ---\n\nexport function parseLog(content: string): TodoLog {\n const [fm, body] = extractFrontmatter(content);\n const workspace = getField(fm, 'workspace') || '_global';\n\n const entries: LogEntry[] = [];\n const sections = body.split(/^### /m).filter((s) => s.match(/^\\d{4}-/));\n\n for (const section of sections) {\n const lines = section.split('\\n');\n const heading = lines[0]?.trim() || '';\n\n // Heading format: 2026-04-07T14:30:00Z — t:a3f1, t:b7c2\n const headingMatch = heading.match(/^(\\S+)\\s*—?\\s*(.*)/);\n if (!headingMatch) continue;\n\n const timestamp = headingMatch[1];\n const idsPart = headingMatch[2] || '';\n const itemIds = [...idsPart.matchAll(/t:([a-f0-9]{4})/g)].map((m) => m[1]);\n\n const entry: LogEntry = {\n timestamp,\n itemIds,\n items: '',\n session: null,\n branch: null,\n summary: '',\n blockers: null,\n status: null,\n };\n\n for (const line of lines.slice(1)) {\n const fieldMatch = line.match(/^\\*\\*(\\w+):\\*\\*\\s*(.*)/);\n if (!fieldMatch) continue;\n const key = fieldMatch[1].toLowerCase();\n const value = fieldMatch[2].trim();\n switch (key) {\n case 'items':\n entry.items = value;\n break;\n case 'session':\n entry.session = value;\n break;\n case 'branch':\n entry.branch = value;\n break;\n case 'summary':\n entry.summary = value;\n break;\n case 'blockers':\n entry.blockers = value;\n break;\n case 'status':\n entry.status = value;\n break;\n }\n }\n\n entries.push(entry);\n }\n\n return { workspace, entries };\n}\n\nexport function serializeLogEntry(entry: LogEntry): string {\n const idStr = entry.itemIds.map((id) => `t:${id}`).join(', ');\n const lines = [`### ${entry.timestamp} — ${idStr}`];\n if (entry.items) lines.push(`**Items:** ${entry.items}`);\n if (entry.session) lines.push(`**Session:** ${entry.session}`);\n if (entry.branch) lines.push(`**Branch:** ${entry.branch}`);\n if (entry.summary) lines.push(`**Summary:** ${entry.summary}`);\n if (entry.blockers) lines.push(`**Blockers:** ${entry.blockers}`);\n if (entry.status) lines.push(`**Status:** ${entry.status}`);\n return lines.join('\\n');\n}\n\n// --- File I/O ---\n\nexport function checklistPath(todosDir: string, workspace: string): string {\n return resolve(todosDir, `${workspace}.md`);\n}\n\nexport function logPath(todosDir: string, workspace: string): string {\n return resolve(todosDir, `${workspace}-log.md`);\n}\n\nexport function archivePath(\n todosDir: string,\n workspace: string,\n interval: ArchiveInterval,\n now: Date = new Date(),\n): string {\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const day = String(now.getDate()).padStart(2, '0');\n\n let suffix: string;\n switch (interval) {\n case 'daily':\n suffix = `${year}-${month}-${day}`;\n break;\n case 'weekly': {\n // ISO week number\n const jan1 = new Date(year, 0, 1);\n const days = Math.floor((now.getTime() - jan1.getTime()) / 86400000);\n const week = String(Math.ceil((days + jan1.getDay() + 1) / 7)).padStart(2, '0');\n suffix = `${year}-W${week}`;\n break;\n }\n case 'monthly':\n suffix = `${year}-${month}`;\n break;\n default:\n suffix = `${year}-${month}-${day}`;\n }\n\n return resolve(todosDir, 'archive', `${workspace}-${suffix}.md`);\n}\n\nexport async function readChecklist(todosDir: string, workspace: string): Promise<TodoChecklist> {\n const path = checklistPath(todosDir, workspace);\n if (!(await fileExists(path))) {\n return { workspace, archiveInterval: 'weekly', items: [] };\n }\n const content = await readFile(path, 'utf-8');\n return parseChecklist(content);\n}\n\nexport async function writeChecklist(todosDir: string, checklist: TodoChecklist): Promise<void> {\n await ensureDir(todosDir);\n const path = checklistPath(todosDir, checklist.workspace);\n await writeFileForce(path, serializeChecklist(checklist));\n}\n\nexport async function readLog(todosDir: string, workspace: string): Promise<TodoLog> {\n const path = logPath(todosDir, workspace);\n if (!(await fileExists(path))) {\n return { workspace, entries: [] };\n }\n const content = await readFile(path, 'utf-8');\n return parseLog(content);\n}\n\nexport async function appendLogEntry(\n todosDir: string,\n workspace: string,\n entry: LogEntry,\n): Promise<void> {\n await ensureDir(todosDir);\n const path = logPath(todosDir, workspace);\n let content: string;\n if (await fileExists(path)) {\n content = await readFile(path, 'utf-8');\n content = content.trimEnd() + '\\n\\n' + serializeLogEntry(entry) + '\\n';\n } else {\n const fm = `---\\nworkspace: ${workspace}\\n---\\n\\n# Todo Log\\n\\n`;\n content = fm + serializeLogEntry(entry) + '\\n';\n }\n await writeFileForce(path, content);\n}\n\nexport function computeCounts(items: TodoItem[]) {\n const counts = { open: 0, in_progress: 0, completed: 0, blocked: 0, total: items.length };\n for (const item of items) {\n counts[item.status]++;\n }\n return counts;\n}\n","import express from 'express';\nimport { createServer } from 'node:http';\nimport { resolve, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { writeFile, unlink } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\nimport { WebSocketServer, WebSocket } from 'ws';\nimport {\n listMissions,\n listAssignmentsBoard,\n getMissionDetail,\n getAssignmentDetail,\n getOverview,\n getAttention,\n getHelp,\n getStatusConfig,\n clearStatusConfigCache,\n listWorkspaces,\n createWorkspace,\n deleteWorkspace,\n} from './api.js';\nimport { createWatcher } from './watcher.js';\nimport { fileExists } from '../utils/fs.js';\nimport { writeStatusConfig, deleteStatusConfig } from '../utils/config.js';\nimport { createWriteRouter } from './api-write.js';\nimport { createServersRouter } from './api-servers.js';\nimport { createAgentSessionsRouter } from './api-agent-sessions.js';\nimport { createPlaybooksRouter } from './api-playbooks.js';\nimport { createTodosRouter } from './api-todos.js';\nimport { initSessionDb, migrateFromMarkdown, closeSessionDb } from './session-db.js';\nimport { startAutodiscovery, stopAutodiscovery } from './autodiscovery.js';\nimport type { WsMessage } from './types.js';\n\n// When tsup bundles with splitting:false, import.meta.url resolves to the\n// final bundle (dist/index.js), not the original file location. Use one level\n// up from the dist/ directory to find the package root reliably.\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageRoot = resolve(__dirname, '..');\n\nexport interface DashboardServerOptions {\n port: number;\n missionsDir: string;\n serversDir: string;\n playbooksDir: string;\n todosDir: string;\n serveStaticUi: boolean;\n}\n\nexport function createDashboardServer(options: DashboardServerOptions) {\n const { port, missionsDir, serversDir, playbooksDir, todosDir, serveStaticUi } = options;\n const app = express();\n const server = createServer(app);\n\n // --- WebSocket ---\n const wss = new WebSocketServer({ noServer: true });\n const clients = new Set<WebSocket>();\n\n server.on('upgrade', (request, socket, head) => {\n if (request.url === '/ws') {\n wss.handleUpgrade(request, socket, head, (ws) => {\n wss.emit('connection', ws, request);\n });\n } else {\n socket.destroy();\n }\n });\n\n wss.on('connection', (ws) => {\n clients.add(ws);\n const connectMsg: WsMessage = {\n type: 'connected',\n timestamp: new Date().toISOString(),\n };\n ws.send(JSON.stringify(connectMsg));\n\n ws.on('close', () => {\n clients.delete(ws);\n });\n });\n\n function broadcast(message: WsMessage): void {\n const data = JSON.stringify(message);\n for (const client of clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(data);\n }\n }\n }\n\n // --- Initialize session database ---\n initSessionDb();\n migrateFromMarkdown(missionsDir).catch((err) => {\n console.error('Session migration from markdown failed:', err);\n });\n\n // --- JSON body parsing ---\n app.use(express.json());\n\n // --- API Routes ---\n app.get('/api/overview', async (_req, res) => {\n try {\n const overview = await getOverview(missionsDir, serversDir);\n res.json(overview);\n } catch (error) {\n console.error('Error getting overview:', error);\n res.status(500).json({ error: 'Failed to get overview' });\n }\n });\n\n app.get('/api/attention', async (_req, res) => {\n try {\n const attention = await getAttention(missionsDir, serversDir);\n res.json(attention);\n } catch (error) {\n console.error('Error getting attention queue:', error);\n res.status(500).json({ error: 'Failed to get attention queue' });\n }\n });\n\n app.get('/api/help', async (_req, res) => {\n try {\n const help = await getHelp();\n res.json(help);\n } catch (error) {\n console.error('Error getting help content:', error);\n res.status(500).json({ error: 'Failed to get help content' });\n }\n });\n\n app.get('/api/config/statuses', async (_req, res) => {\n try {\n const config = await getStatusConfig();\n res.json({\n statuses: config.statuses,\n order: config.order,\n transitions: config.transitions,\n custom: config.custom,\n });\n } catch (error) {\n console.error('Error getting status config:', error);\n res.status(500).json({ error: 'Failed to get status config' });\n }\n });\n\n app.post('/api/config/statuses', async (req, res) => {\n try {\n const { statuses, order, transitions } = req.body;\n if (!Array.isArray(statuses) || !Array.isArray(order) || !Array.isArray(transitions)) {\n res.status(400).json({ error: 'Request body must include statuses, order, and transitions arrays' });\n return;\n }\n await writeStatusConfig({ statuses, order, transitions });\n clearStatusConfigCache();\n const config = await getStatusConfig();\n res.json({\n statuses: config.statuses,\n order: config.order,\n transitions: config.transitions,\n custom: config.custom,\n });\n } catch (error) {\n console.error('Error saving status config:', error);\n res.status(500).json({ error: 'Failed to save status config' });\n }\n });\n\n app.delete('/api/config/statuses', async (_req, res) => {\n try {\n await deleteStatusConfig();\n clearStatusConfigCache();\n const config = await getStatusConfig();\n res.json({\n statuses: config.statuses,\n order: config.order,\n transitions: config.transitions,\n custom: config.custom,\n });\n } catch (error) {\n console.error('Error resetting status config:', error);\n res.status(500).json({ error: 'Failed to reset status config' });\n }\n });\n\n app.get('/api/missions', async (req, res) => {\n try {\n let missions = await listMissions(missionsDir);\n const workspaceParam = req.query.workspace as string | undefined;\n if (workspaceParam) {\n if (workspaceParam === '_ungrouped') {\n missions = missions.filter((m) => m.workspace === null);\n } else {\n missions = missions.filter((m) => m.workspace === workspaceParam);\n }\n }\n res.json(missions);\n } catch (error) {\n console.error('Error listing missions:', error);\n res.status(500).json({ error: 'Failed to list missions' });\n }\n });\n\n app.get('/api/workspaces', async (_req, res) => {\n try {\n const result = await listWorkspaces(missionsDir);\n res.json(result);\n } catch (error) {\n console.error('Error listing workspaces:', error);\n res.status(500).json({ error: 'Failed to list workspaces' });\n }\n });\n\n app.post('/api/workspaces', async (req, res) => {\n try {\n const { name } = req.body;\n if (!name || typeof name !== 'string' || !/^[a-z0-9][a-z0-9-]*$/.test(name)) {\n res.status(400).json({ error: 'Invalid workspace name. Use lowercase letters, numbers, and hyphens.' });\n return;\n }\n await createWorkspace(missionsDir, name);\n broadcast({ type: 'mission-updated', missionSlug: '', timestamp: new Date().toISOString() });\n res.json({ name });\n } catch (error) {\n console.error('Error creating workspace:', error);\n res.status(500).json({ error: 'Failed to create workspace' });\n }\n });\n\n app.delete('/api/workspaces/:name', async (req, res) => {\n try {\n await deleteWorkspace(missionsDir, req.params.name);\n broadcast({ type: 'mission-updated', missionSlug: '', timestamp: new Date().toISOString() });\n res.json({ ok: true });\n } catch (error) {\n console.error('Error deleting workspace:', error);\n res.status(500).json({ error: 'Failed to delete workspace' });\n }\n });\n\n app.get('/api/assignments', async (req, res) => {\n try {\n const result = await listAssignmentsBoard(missionsDir);\n const workspaceParam = req.query.workspace as string | undefined;\n if (workspaceParam) {\n if (workspaceParam === '_ungrouped') {\n result.assignments = result.assignments.filter((a) => a.missionWorkspace === null);\n } else {\n result.assignments = result.assignments.filter((a) => a.missionWorkspace === workspaceParam);\n }\n }\n res.json(result);\n } catch (error) {\n console.error('Error listing assignments:', error);\n res.status(500).json({ error: 'Failed to list assignments' });\n }\n });\n\n app.get('/api/missions/:slug', async (req, res) => {\n try {\n const detail = await getMissionDetail(missionsDir, req.params.slug);\n if (!detail) {\n res.status(404).json({ error: `Mission \"${req.params.slug}\" not found` });\n return;\n }\n res.json(detail);\n } catch (error) {\n console.error('Error getting mission detail:', error);\n res.status(500).json({ error: 'Failed to get mission detail' });\n }\n });\n\n app.get('/api/missions/:slug/assignments/:aslug', async (req, res) => {\n try {\n const detail = await getAssignmentDetail(\n missionsDir,\n req.params.slug,\n req.params.aslug,\n );\n if (!detail) {\n res.status(404).json({\n error: `Assignment \"${req.params.aslug}\" not found in mission \"${req.params.slug}\"`,\n });\n return;\n }\n res.json(detail);\n } catch (error) {\n console.error('Error getting assignment detail:', error);\n res.status(500).json({ error: 'Failed to get assignment detail' });\n }\n });\n\n // --- Write API (create missions/assignments) ---\n app.use(createWriteRouter(missionsDir));\n\n // --- Servers API ---\n app.use('/api/servers', createServersRouter(serversDir, missionsDir));\n\n // --- Agent Sessions API ---\n app.use('/api/agent-sessions', createAgentSessionsRouter(missionsDir, broadcast));\n\n // --- Playbooks API ---\n app.use('/api/playbooks', createPlaybooksRouter(playbooksDir));\n\n // --- Todos API ---\n app.use('/api/todos', createTodosRouter(todosDir, broadcast));\n\n // --- Static files (production only) ---\n if (serveStaticUi) {\n const dashboardDistPath = resolve(packageRoot, 'dashboard', 'dist');\n app.use(express.static(dashboardDistPath));\n\n // SPA fallback: serve index.html for all non-API routes\n // Express 5 requires named wildcards; use '{*path}' instead of '*'\n app.get('{*path}', async (_req: any, res: any) => {\n const indexPath = resolve(dashboardDistPath, 'index.html');\n if (await fileExists(indexPath)) {\n res.sendFile(indexPath);\n } else {\n res.status(503).send(\n 'Dashboard not built. Run \"npm run build:dashboard\" first.',\n );\n }\n });\n }\n\n // --- File watcher ---\n let watcherHandle: { close: () => Promise<void> } | null = null;\n\n return {\n async start(): Promise<void> {\n watcherHandle = createWatcher({\n missionsDir,\n serversDir,\n playbooksDir,\n todosDir,\n onMessage: broadcast,\n });\n\n startAutodiscovery({ serversDir, missionsDir, excludePids: new Set([process.pid]) });\n\n return new Promise<void>((resolvePromise, reject) => {\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n reject(new Error(\n `Port ${port} is already in use. Use --port <number> to specify a different port.`,\n ));\n } else {\n reject(err);\n }\n });\n server.listen(port, () => {\n const portFile = resolve(homedir(), '.syntaur', 'dashboard-port');\n writeFile(portFile, String(port), 'utf-8').catch(() => {});\n resolvePromise();\n });\n });\n },\n\n async stop(): Promise<void> {\n await stopAutodiscovery();\n if (watcherHandle) {\n await watcherHandle.close();\n }\n closeSessionDb();\n for (const client of clients) {\n client.close();\n }\n clients.clear();\n const portFile = resolve(homedir(), '.syntaur', 'dashboard-port');\n await unlink(portFile).catch(() => {});\n return new Promise<void>((resolvePromise) => {\n server.close(() => resolvePromise());\n });\n },\n\n get port(): number {\n return port;\n },\n };\n}\n","import { watch } from 'chokidar';\nimport { relative, sep } from 'node:path';\nimport type { WsMessage } from './types.js';\n\nexport interface WatcherOptions {\n missionsDir: string;\n serversDir?: string;\n playbooksDir?: string;\n todosDir?: string;\n onMessage: (message: WsMessage) => void;\n debounceMs?: number;\n}\n\nexport function createWatcher(options: WatcherOptions): { close: () => Promise<void> } {\n const { missionsDir, serversDir, playbooksDir, todosDir, onMessage, debounceMs = 300 } = options;\n const pendingEvents = new Map<string, NodeJS.Timeout>();\n\n // --- Missions watcher (existing logic) ---\n const missionsWatcher = watch(missionsDir, {\n ignoreInitial: true,\n persistent: true,\n depth: 10,\n ignored: /(^|[\\/\\\\])\\../,\n });\n\n function handleMissionChange(filePath: string): void {\n const rel = relative(missionsDir, filePath);\n const parts = rel.split(sep);\n\n if (parts.length === 0) return;\n\n const missionSlug = parts[0];\n let assignmentSlug: string | undefined;\n\n if (parts.length >= 3 && parts[1] === 'assignments') {\n assignmentSlug = parts[2];\n }\n\n const debounceKey = assignmentSlug\n ? `${missionSlug}/${assignmentSlug}`\n : missionSlug;\n\n const existing = pendingEvents.get(debounceKey);\n if (existing) clearTimeout(existing);\n\n // Session events are now emitted by the API write path, not the file watcher\n const messageType = assignmentSlug\n ? 'assignment-updated'\n : 'mission-updated';\n\n pendingEvents.set(\n debounceKey,\n setTimeout(() => {\n pendingEvents.delete(debounceKey);\n const message: WsMessage = {\n type: messageType,\n missionSlug,\n assignmentSlug,\n timestamp: new Date().toISOString(),\n };\n onMessage(message);\n }, debounceMs),\n );\n }\n\n missionsWatcher.on('change', handleMissionChange);\n missionsWatcher.on('add', handleMissionChange);\n missionsWatcher.on('unlink', handleMissionChange);\n\n // --- Servers watcher (new) ---\n let serversWatcher: ReturnType<typeof watch> | null = null;\n\n if (serversDir) {\n serversWatcher = watch(serversDir, {\n ignoreInitial: true,\n persistent: true,\n depth: 1,\n ignored: /(^|[\\/\\\\])\\../,\n });\n\n function handleServerChange(): void {\n const debounceKey = '__servers__';\n const existing = pendingEvents.get(debounceKey);\n if (existing) clearTimeout(existing);\n\n pendingEvents.set(\n debounceKey,\n setTimeout(() => {\n pendingEvents.delete(debounceKey);\n const message: WsMessage = {\n type: 'servers-updated',\n timestamp: new Date().toISOString(),\n };\n onMessage(message);\n }, debounceMs),\n );\n }\n\n serversWatcher.on('change', handleServerChange);\n serversWatcher.on('add', handleServerChange);\n serversWatcher.on('unlink', handleServerChange);\n }\n\n // --- Playbooks watcher ---\n let playbooksWatcher: ReturnType<typeof watch> | null = null;\n\n if (playbooksDir) {\n playbooksWatcher = watch(playbooksDir, {\n ignoreInitial: true,\n persistent: true,\n depth: 1,\n ignored: /(^|[\\/\\\\])\\../,\n });\n\n function handlePlaybookChange(): void {\n const debounceKey = '__playbooks__';\n const existing = pendingEvents.get(debounceKey);\n if (existing) clearTimeout(existing);\n\n pendingEvents.set(\n debounceKey,\n setTimeout(() => {\n pendingEvents.delete(debounceKey);\n const message: WsMessage = {\n type: 'playbooks-updated',\n timestamp: new Date().toISOString(),\n };\n onMessage(message);\n }, debounceMs),\n );\n }\n\n playbooksWatcher.on('change', handlePlaybookChange);\n playbooksWatcher.on('add', handlePlaybookChange);\n playbooksWatcher.on('unlink', handlePlaybookChange);\n }\n\n // --- Todos watcher ---\n let todosWatcher: ReturnType<typeof watch> | null = null;\n\n if (todosDir) {\n todosWatcher = watch(todosDir, {\n ignoreInitial: true,\n persistent: true,\n depth: 1,\n ignored: /(^|[\\/\\\\])\\../,\n });\n\n function handleTodoChange(): void {\n const debounceKey = '__todos__';\n const existing = pendingEvents.get(debounceKey);\n if (existing) clearTimeout(existing);\n\n pendingEvents.set(\n debounceKey,\n setTimeout(() => {\n pendingEvents.delete(debounceKey);\n const message: WsMessage = {\n type: 'todos-updated',\n timestamp: new Date().toISOString(),\n };\n onMessage(message);\n }, debounceMs),\n );\n }\n\n todosWatcher.on('change', handleTodoChange);\n todosWatcher.on('add', handleTodoChange);\n todosWatcher.on('unlink', handleTodoChange);\n }\n\n return {\n close: async () => {\n pendingEvents.forEach((timeout) => {\n clearTimeout(timeout);\n });\n pendingEvents.clear();\n await missionsWatcher.close();\n if (serversWatcher) await serversWatcher.close();\n if (playbooksWatcher) await playbooksWatcher.close();\n if (todosWatcher) await todosWatcher.close();\n },\n };\n}\n","import { Router, type Request, type Response } from 'express';\nimport { resolve } from 'node:path';\nimport { rm, readFile } from 'node:fs/promises';\nimport { executeTransition } from '../lifecycle/index.js';\nimport { isValidSlug } from '../utils/slug.js';\nimport { generateId } from '../utils/uuid.js';\nimport { nowTimestamp } from '../utils/timestamp.js';\nimport { ensureDir, writeFileForce, fileExists } from '../utils/fs.js';\nimport {\n parseAssignmentFull,\n parseDecisionRecord,\n parseHandoff,\n parseMission,\n parsePlan,\n parseScratchpad,\n} from './parser.js';\nimport { toggleAcceptanceCriterion } from './acceptance-criteria.js';\nimport {\n getAssignmentDetail,\n getEditableDocument,\n getMissionDetail,\n getStatusConfig,\n} from './api.js';\nimport {\n renderMission,\n renderManifest,\n renderAgent,\n renderClaude,\n renderIndexAssignments,\n renderIndexPlans,\n renderIndexDecisions,\n renderStatus,\n renderResourcesIndex,\n renderMemoriesIndex,\n renderAssignment,\n renderPlan,\n renderScratchpad,\n renderHandoff,\n renderDecisionRecord,\n} from '../templates/index.js';\n\nfunction extractFrontmatter(content: string): Record<string, string> | null {\n const trimmed = content.trimStart();\n if (!trimmed.startsWith('---\\n') && !trimmed.startsWith('---\\r\\n')) {\n return null;\n }\n\n const afterFirst = trimmed.indexOf('\\n') + 1;\n const closingIdx = trimmed.indexOf('\\n---', afterFirst);\n if (closingIdx === -1) {\n return null;\n }\n\n const yamlBlock = trimmed.slice(afterFirst, closingIdx);\n const fields: Record<string, string> = {};\n\n for (const line of yamlBlock.split('\\n')) {\n const match = line.match(/^([a-zA-Z_][a-zA-Z0-9_]*):\\s*(.*)$/);\n if (!match) {\n continue;\n }\n\n let value = match[2].trim();\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n fields[match[1]] = value;\n }\n\n return fields;\n}\n\nfunction validateRequired(\n fields: Record<string, string>,\n required: string[],\n): { valid: true } | { valid: false; missing: string[] } {\n const missing = required.filter((key) => !fields[key] || fields[key] === 'null');\n if (missing.length > 0) {\n return { valid: false, missing };\n }\n return { valid: true };\n}\n\nfunction formatYamlValue(value: boolean | number | string | null): string {\n if (value === null) {\n return 'null';\n }\n if (typeof value === 'boolean' || typeof value === 'number') {\n return String(value);\n }\n if (/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) {\n return `\"${value}\"`;\n }\n if (value === '' || /[:#{}[\\],&*?|>!%@`]/.test(value) || /^\\s|\\s$/.test(value)) {\n return `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\n }\n return value;\n}\n\nfunction setTopLevelField(\n content: string,\n key: string,\n value: boolean | number | string | null,\n): string {\n const formatted = formatYamlValue(value);\n const fieldRegex = new RegExp(`^(${escapeRegExp(key)}:)\\\\s*.*$`, 'm');\n\n if (fieldRegex.test(content)) {\n return content.replace(fieldRegex, `$1 ${formatted}`);\n }\n\n const closingIdx = content.indexOf('\\n---', 4);\n if (closingIdx === -1) {\n return content;\n }\n\n return `${content.slice(0, closingIdx)}\\n${key}: ${formatted}${content.slice(closingIdx)}`;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction appendLogEntry(\n existingContent: string,\n countField: 'handoffCount' | 'decisionCount',\n nextCount: number,\n heading: string,\n body: string,\n emptyPlaceholder: string,\n): string {\n const timestamp = nowTimestamp();\n let next = setTopLevelField(existingContent, 'updated', timestamp);\n next = setTopLevelField(next, countField, nextCount);\n\n const entryBody = body.trim();\n const entry = `## ${heading}\\n\\n**Recorded:** ${timestamp}\\n\\n${entryBody}\\n`;\n\n if (next.includes(emptyPlaceholder)) {\n return next.replace(emptyPlaceholder, entry.trimEnd());\n }\n\n return `${next.trimEnd()}\\n\\n${entry}`;\n}\n\nfunction requireContent(req: Request, res: Response): string | null {\n const { content } = req.body || {};\n if (!content || typeof content !== 'string' || !content.trim()) {\n res.status(400).json({ error: 'content is required' });\n return null;\n }\n return content;\n}\n\nfunction getParam(value: string | string[] | undefined): string {\n if (Array.isArray(value)) {\n return value[0] ?? '';\n }\n return value ?? '';\n}\n\nasync function readCurrentDocument(filePath: string): Promise<string | null> {\n if (!(await fileExists(filePath))) {\n return null;\n }\n return readFile(filePath, 'utf-8');\n}\n\nexport function createWriteRouter(missionsDir: string): Router {\n const router = Router();\n\n router.get('/api/templates/mission', (_req: Request, res: Response) => {\n const content = renderMission({\n id: generateId(),\n slug: 'my-new-mission',\n title: 'My New Mission',\n timestamp: nowTimestamp(),\n });\n res.json({ content });\n });\n\n router.get('/api/templates/assignment', (_req: Request, res: Response) => {\n const content = renderAssignment({\n id: generateId(),\n slug: 'my-new-assignment',\n title: 'My New Assignment',\n timestamp: nowTimestamp(),\n priority: 'medium',\n dependsOn: [],\n });\n res.json({ content });\n });\n\n router.get('/api/missions/:slug/edit', async (req: Request, res: Response) => {\n const slug = getParam(req.params.slug);\n const document = await getEditableDocument(missionsDir, 'mission', slug);\n if (!document) {\n res.status(404).json({ error: `Mission \"${slug}\" not found` });\n return;\n }\n res.json(document);\n });\n\n router.get('/api/missions/:slug/assignments/:aslug/edit', async (req: Request, res: Response) => {\n const slug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const document = await getEditableDocument(\n missionsDir,\n 'assignment',\n slug,\n assignmentSlug,\n );\n if (!document) {\n res.status(404).json({ error: 'Assignment not found' });\n return;\n }\n res.json(document);\n });\n\n router.get('/api/missions/:slug/assignments/:aslug/plan/edit', async (req: Request, res: Response) => {\n const slug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const document = await getEditableDocument(\n missionsDir,\n 'plan',\n slug,\n assignmentSlug,\n );\n if (!document) {\n res.status(404).json({ error: 'Plan not found' });\n return;\n }\n res.json(document);\n });\n\n router.get('/api/missions/:slug/assignments/:aslug/scratchpad/edit', async (req: Request, res: Response) => {\n const slug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const document = await getEditableDocument(\n missionsDir,\n 'scratchpad',\n slug,\n assignmentSlug,\n );\n if (!document) {\n res.status(404).json({ error: 'Scratchpad not found' });\n return;\n }\n res.json(document);\n });\n\n router.get('/api/missions/:slug/assignments/:aslug/handoff/edit', async (req: Request, res: Response) => {\n const slug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const document = await getEditableDocument(\n missionsDir,\n 'handoff',\n slug,\n assignmentSlug,\n );\n if (!document) {\n res.status(404).json({ error: 'Handoff log not found' });\n return;\n }\n res.json(document);\n });\n\n router.get('/api/missions/:slug/assignments/:aslug/decision-record/edit', async (req: Request, res: Response) => {\n const slug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const document = await getEditableDocument(\n missionsDir,\n 'decision-record',\n slug,\n assignmentSlug,\n );\n if (!document) {\n res.status(404).json({ error: 'Decision record not found' });\n return;\n }\n res.json(document);\n });\n\n router.post('/api/missions', async (req: Request, res: Response) => {\n try {\n const content = requireContent(req, res);\n if (!content) {\n return;\n }\n\n const fields = extractFrontmatter(content);\n if (!fields) {\n res.status(400).json({ error: 'Invalid frontmatter: missing --- delimiters' });\n return;\n }\n\n const validation = validateRequired(fields, ['slug', 'title']);\n if (!validation.valid) {\n res.status(400).json({ error: `Missing required fields: ${validation.missing.join(', ')}` });\n return;\n }\n\n const slug = fields.slug;\n if (!isValidSlug(slug)) {\n res.status(400).json({ error: `Invalid slug \"${slug}\". Must be lowercase and hyphen-separated.` });\n return;\n }\n\n const missionDir = resolve(missionsDir, slug);\n if (await fileExists(missionDir)) {\n res.status(409).json({ error: `Mission \"${slug}\" already exists` });\n return;\n }\n\n const title = fields.title;\n const timestamp = fields.created || nowTimestamp();\n\n await ensureDir(resolve(missionDir, 'assignments'));\n await ensureDir(resolve(missionDir, 'resources'));\n await ensureDir(resolve(missionDir, 'memories'));\n\n await writeFileForce(resolve(missionDir, 'mission.md'), content);\n\n try {\n const companions: Array<[string, string]> = [\n [resolve(missionDir, 'manifest.md'), renderManifest({ slug, timestamp })],\n [resolve(missionDir, 'agent.md'), renderAgent({ slug, timestamp })],\n [resolve(missionDir, 'claude.md'), renderClaude({ slug })],\n [resolve(missionDir, '_index-assignments.md'), renderIndexAssignments({ slug, title, timestamp })],\n [resolve(missionDir, '_index-plans.md'), renderIndexPlans({ slug, title, timestamp })],\n [resolve(missionDir, '_index-decisions.md'), renderIndexDecisions({ slug, title, timestamp })],\n [resolve(missionDir, '_status.md'), renderStatus({ slug, title, timestamp })],\n [resolve(missionDir, 'resources', '_index.md'), renderResourcesIndex({ slug, title, timestamp })],\n [resolve(missionDir, 'memories', '_index.md'), renderMemoriesIndex({ slug, title, timestamp })],\n ];\n\n for (const [filePath, fileContent] of companions) {\n await writeFileForce(filePath, fileContent);\n }\n } catch (companionError) {\n try {\n await rm(missionDir, { recursive: true, force: true });\n } catch {\n // Best effort cleanup only.\n }\n throw companionError;\n }\n\n res.status(201).json({ slug });\n } catch (error) {\n console.error('Error creating mission:', error);\n res.status(500).json({ error: `Failed to create mission: ${(error as Error).message}` });\n }\n });\n\n router.post('/api/missions/:slug/assignments', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const missionDir = resolve(missionsDir, missionSlug);\n const missionMdPath = resolve(missionDir, 'mission.md');\n\n if (!(await fileExists(missionMdPath))) {\n res.status(404).json({ error: `Mission \"${missionSlug}\" not found` });\n return;\n }\n\n const content = requireContent(req, res);\n if (!content) {\n return;\n }\n\n const fields = extractFrontmatter(content);\n if (!fields) {\n res.status(400).json({ error: 'Invalid frontmatter: missing --- delimiters' });\n return;\n }\n\n const validation = validateRequired(fields, ['slug', 'title']);\n if (!validation.valid) {\n res.status(400).json({ error: `Missing required fields: ${validation.missing.join(', ')}` });\n return;\n }\n\n const assignmentSlug = fields.slug;\n if (!isValidSlug(assignmentSlug)) {\n res.status(400).json({ error: `Invalid slug \"${assignmentSlug}\". Must be lowercase and hyphen-separated.` });\n return;\n }\n\n const validPriorities = ['low', 'medium', 'high', 'critical'];\n const priority = fields.priority || 'medium';\n if (!validPriorities.includes(priority)) {\n res.status(400).json({ error: `Invalid priority \"${priority}\". Must be low, medium, high, or critical.` });\n return;\n }\n\n const assignmentDir = resolve(missionDir, 'assignments', assignmentSlug);\n if (await fileExists(assignmentDir)) {\n res.status(409).json({\n error: `Assignment \"${assignmentSlug}\" already exists in mission \"${missionSlug}\"`,\n });\n return;\n }\n\n const title = fields.title;\n const timestamp = fields.created || nowTimestamp();\n\n await ensureDir(assignmentDir);\n await writeFileForce(resolve(assignmentDir, 'assignment.md'), content);\n\n try {\n const companions: Array<[string, string]> = [\n [resolve(assignmentDir, 'plan.md'), renderPlan({ assignmentSlug, title, timestamp })],\n [resolve(assignmentDir, 'scratchpad.md'), renderScratchpad({ assignmentSlug, timestamp })],\n [resolve(assignmentDir, 'handoff.md'), renderHandoff({ assignmentSlug, timestamp })],\n [resolve(assignmentDir, 'decision-record.md'), renderDecisionRecord({ assignmentSlug, timestamp })],\n ];\n\n for (const [filePath, fileContent] of companions) {\n await writeFileForce(filePath, fileContent);\n }\n } catch (companionError) {\n try {\n await rm(assignmentDir, { recursive: true, force: true });\n } catch {\n // Best effort cleanup only.\n }\n throw companionError;\n }\n\n res.status(201).json({ slug: assignmentSlug, missionSlug });\n } catch (error) {\n console.error('Error creating assignment:', error);\n res.status(500).json({ error: `Failed to create assignment: ${(error as Error).message}` });\n }\n });\n\n router.patch('/api/missions/:slug', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const missionPath = resolve(missionsDir, missionSlug, 'mission.md');\n const currentContent = await readCurrentDocument(missionPath);\n if (!currentContent) {\n res.status(404).json({ error: `Mission \"${missionSlug}\" not found` });\n return;\n }\n\n const nextContentRaw = requireContent(req, res);\n if (!nextContentRaw) {\n return;\n }\n\n const current = parseMission(currentContent);\n const next = parseMission(nextContentRaw);\n\n if (!next.slug || !next.title) {\n res.status(400).json({ error: 'Mission content must include slug and title.' });\n return;\n }\n\n if (next.slug !== current.slug) {\n res.status(400).json({ error: 'Mission slug cannot be changed once created.' });\n return;\n }\n\n const nextContent = setTopLevelField(nextContentRaw, 'updated', nowTimestamp());\n await writeFileForce(missionPath, nextContent);\n\n const mission = await getMissionDetail(missionsDir, missionSlug);\n res.json({ mission, content: nextContent });\n } catch (error) {\n console.error('Error updating mission:', error);\n res.status(500).json({ error: `Failed to update mission: ${(error as Error).message}` });\n }\n });\n\n router.patch('/api/missions/:slug/assignments/:aslug', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const assignmentPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'assignment.md',\n );\n const currentContent = await readCurrentDocument(assignmentPath);\n if (!currentContent) {\n res.status(404).json({ error: 'Assignment not found' });\n return;\n }\n\n const nextContentRaw = requireContent(req, res);\n if (!nextContentRaw) {\n return;\n }\n\n const current = parseAssignmentFull(currentContent);\n const next = parseAssignmentFull(nextContentRaw);\n\n if (!next.slug || !next.title) {\n res.status(400).json({ error: 'Assignment content must include slug and title.' });\n return;\n }\n\n if (next.slug !== current.slug) {\n res.status(400).json({ error: 'Assignment slug cannot be changed once created.' });\n return;\n }\n\n let nextContent = nextContentRaw;\n\n // Clear blockedReason when status moves away from blocked\n if (next.status !== current.status && current.status === 'blocked' && next.status !== 'blocked') {\n nextContent = setTopLevelField(nextContent, 'blockedReason', null);\n }\n\n nextContent = setTopLevelField(nextContent, 'updated', nowTimestamp());\n await writeFileForce(assignmentPath, nextContent);\n\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.json({ assignment, content: nextContent });\n } catch (error) {\n console.error('Error updating assignment:', error);\n res.status(500).json({ error: `Failed to update assignment: ${(error as Error).message}` });\n }\n });\n\n router.patch('/api/missions/:slug/assignments/:aslug/acceptance-criteria/:index', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const assignmentPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'assignment.md',\n );\n const currentContent = await readCurrentDocument(assignmentPath);\n if (!currentContent) {\n res.status(404).json({ error: 'Assignment not found' });\n return;\n }\n\n const { checked } = req.body || {};\n if (typeof checked !== 'boolean') {\n res.status(400).json({ error: 'checked must be a boolean' });\n return;\n }\n\n const index = Number.parseInt(getParam(req.params.index), 10);\n const result = toggleAcceptanceCriterion(currentContent, index, checked);\n if ('error' in result) {\n res.status(400).json({ error: result.error });\n return;\n }\n\n const nextContent = setTopLevelField(result.content, 'updated', nowTimestamp());\n await writeFileForce(assignmentPath, nextContent);\n\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.json({ assignment, content: nextContent });\n } catch (error) {\n console.error('Error toggling acceptance criterion:', error);\n res.status(500).json({ error: `Failed to toggle acceptance criterion: ${(error as Error).message}` });\n }\n });\n\n router.patch('/api/missions/:slug/assignments/:aslug/plan', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const planPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'plan.md',\n );\n const currentContent = await readCurrentDocument(planPath);\n if (!currentContent) {\n res.status(404).json({ error: 'Plan not found' });\n return;\n }\n\n const nextContentRaw = requireContent(req, res);\n if (!nextContentRaw) {\n return;\n }\n\n const next = parsePlan(nextContentRaw);\n if (!next.assignment) {\n res.status(400).json({ error: 'Plan content must include the assignment field.' });\n return;\n }\n\n if (next.assignment !== assignmentSlug) {\n res.status(400).json({ error: 'Plan assignment field must match the route assignment slug.' });\n return;\n }\n\n const nextContent = setTopLevelField(nextContentRaw, 'updated', nowTimestamp());\n await writeFileForce(planPath, nextContent);\n\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.json({ assignment, content: nextContent });\n } catch (error) {\n console.error('Error updating plan:', error);\n res.status(500).json({ error: `Failed to update plan: ${(error as Error).message}` });\n }\n });\n\n router.patch('/api/missions/:slug/assignments/:aslug/scratchpad', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const scratchpadPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'scratchpad.md',\n );\n const currentContent = await readCurrentDocument(scratchpadPath);\n if (!currentContent) {\n res.status(404).json({ error: 'Scratchpad not found' });\n return;\n }\n\n const nextContentRaw = requireContent(req, res);\n if (!nextContentRaw) {\n return;\n }\n\n const next = parseScratchpad(nextContentRaw);\n if (!next.assignment) {\n res.status(400).json({ error: 'Scratchpad content must include the assignment field.' });\n return;\n }\n\n if (next.assignment !== assignmentSlug) {\n res.status(400).json({ error: 'Scratchpad assignment field must match the route assignment slug.' });\n return;\n }\n\n const nextContent = setTopLevelField(nextContentRaw, 'updated', nowTimestamp());\n await writeFileForce(scratchpadPath, nextContent);\n\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.json({ assignment, content: nextContent });\n } catch (error) {\n console.error('Error updating scratchpad:', error);\n res.status(500).json({ error: `Failed to update scratchpad: ${(error as Error).message}` });\n }\n });\n\n router.post('/api/missions/:slug/assignments/:aslug/handoff/entries', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const handoffPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'handoff.md',\n );\n const currentContent = await readCurrentDocument(handoffPath);\n if (!currentContent) {\n res.status(404).json({ error: 'Handoff log not found' });\n return;\n }\n\n const { title, body } = req.body || {};\n if (!body || typeof body !== 'string' || !body.trim()) {\n res.status(400).json({ error: 'body is required' });\n return;\n }\n\n const parsed = parseHandoff(currentContent);\n const nextContent = appendLogEntry(\n currentContent,\n 'handoffCount',\n parsed.handoffCount + 1,\n title && typeof title === 'string' && title.trim() ? title.trim() : `Handoff ${parsed.handoffCount + 1}`,\n body,\n 'No handoffs recorded yet.',\n );\n\n await writeFileForce(handoffPath, nextContent);\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.status(201).json({ assignment, content: nextContent });\n } catch (error) {\n console.error('Error appending handoff entry:', error);\n res.status(500).json({ error: `Failed to append handoff entry: ${(error as Error).message}` });\n }\n });\n\n router.post('/api/missions/:slug/assignments/:aslug/decision-record/entries', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const decisionPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'decision-record.md',\n );\n const currentContent = await readCurrentDocument(decisionPath);\n if (!currentContent) {\n res.status(404).json({ error: 'Decision record not found' });\n return;\n }\n\n const { title, body } = req.body || {};\n if (!body || typeof body !== 'string' || !body.trim()) {\n res.status(400).json({ error: 'body is required' });\n return;\n }\n\n const parsed = parseDecisionRecord(currentContent);\n const nextContent = appendLogEntry(\n currentContent,\n 'decisionCount',\n parsed.decisionCount + 1,\n title && typeof title === 'string' && title.trim() ? title.trim() : `Decision ${parsed.decisionCount + 1}`,\n body,\n 'No decisions recorded yet.',\n );\n\n await writeFileForce(decisionPath, nextContent);\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.status(201).json({ assignment, content: nextContent });\n } catch (error) {\n console.error('Error appending decision entry:', error);\n res.status(500).json({ error: `Failed to append decision entry: ${(error as Error).message}` });\n }\n });\n\n // --- Move Workspace Endpoint ---\n\n router.post('/api/missions/:slug/move-workspace', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const missionPath = resolve(missionsDir, missionSlug, 'mission.md');\n if (!(await fileExists(missionPath))) {\n res.status(404).json({ error: `Mission \"${missionSlug}\" not found` });\n return;\n }\n\n const { workspace } = req.body || {};\n if (workspace !== null && (typeof workspace !== 'string' || !workspace.trim())) {\n res.status(400).json({ error: 'workspace must be a non-empty string or null (for ungrouped).' });\n return;\n }\n\n let content = await readFile(missionPath, 'utf-8');\n content = setTopLevelField(content, 'workspace', workspace ?? null);\n content = setTopLevelField(content, 'updated', nowTimestamp());\n await writeFileForce(missionPath, content);\n\n const mission = await getMissionDetail(missionsDir, missionSlug);\n res.json({ mission });\n } catch (error) {\n console.error('Error moving mission workspace:', error);\n res.status(500).json({ error: `Failed to move workspace: ${(error as Error).message}` });\n }\n });\n\n // --- Status Override Endpoints ---\n\n router.post('/api/missions/:slug/status-override', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const missionPath = resolve(missionsDir, missionSlug, 'mission.md');\n if (!(await fileExists(missionPath))) {\n res.status(404).json({ error: `Mission \"${missionSlug}\" not found` });\n return;\n }\n\n const { status } = req.body || {};\n const config = await getStatusConfig();\n const validStatuses = ['active', 'archived', ...config.statuses.map((s) => s.id)];\n if (status !== null && (typeof status !== 'string' || !validStatuses.includes(status))) {\n res.status(400).json({ error: `Invalid status. Must be one of: ${validStatuses.join(', ')}, or null to clear.` });\n return;\n }\n\n let content = await readFile(missionPath, 'utf-8');\n content = setTopLevelField(content, 'statusOverride', status ?? null);\n content = setTopLevelField(content, 'updated', nowTimestamp());\n await writeFileForce(missionPath, content);\n\n const mission = await getMissionDetail(missionsDir, missionSlug);\n res.json({ mission });\n } catch (error) {\n console.error('Error setting mission status override:', error);\n res.status(500).json({ error: `Failed to set status override: ${(error as Error).message}` });\n }\n });\n\n router.post('/api/missions/:slug/assignments/:aslug/status-override', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const assignmentPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'assignment.md',\n );\n if (!(await fileExists(assignmentPath))) {\n res.status(404).json({ error: 'Assignment not found' });\n return;\n }\n\n const { status } = req.body || {};\n const config = await getStatusConfig();\n const validStatuses = config.statuses.map((s) => s.id);\n if (typeof status !== 'string' || !validStatuses.includes(status)) {\n res.status(400).json({ error: `Invalid status. Must be one of: ${validStatuses.join(', ')}.` });\n return;\n }\n\n let content = await readFile(assignmentPath, 'utf-8');\n content = setTopLevelField(content, 'status', status);\n content = setTopLevelField(content, 'updated', nowTimestamp());\n\n // Clear blockedReason when moving away from blocked\n if (status !== 'blocked') {\n content = setTopLevelField(content, 'blockedReason', null);\n }\n\n await writeFileForce(assignmentPath, content);\n\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.json({ assignment });\n } catch (error) {\n console.error('Error overriding assignment status:', error);\n res.status(500).json({ error: `Failed to override status: ${(error as Error).message}` });\n }\n });\n\n // --- Lifecycle Transitions ---\n\n router.post('/api/missions/:slug/assignments/:aslug/transitions/:command', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const command = req.params.command as Parameters<typeof executeTransition>[2];\n const config = await getStatusConfig();\n const validCommands = [...new Set(config.transitions.map((t) => t.command))];\n if (!validCommands.includes(command)) {\n res.status(400).json({ error: `Unsupported transition command \"${req.params.command}\"` });\n return;\n }\n\n const missionDir = resolve(missionsDir, missionSlug);\n const assignmentPath = resolve(missionDir, 'assignments', assignmentSlug, 'assignment.md');\n if (!(await fileExists(assignmentPath))) {\n res.status(404).json({ error: 'Assignment not found' });\n return;\n }\n\n const { reason } = req.body || {};\n const result = await executeTransition(missionDir, assignmentSlug, command, {\n reason: typeof reason === 'string' ? reason : undefined,\n transitionTable: config.custom ? config.transitionTable : undefined,\n terminalStatuses: config.custom ? config.terminalStatuses : undefined,\n });\n\n if (!result.success) {\n res.status(400).json({ error: result.message });\n return;\n }\n\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.json({ assignment, transition: result });\n } catch (error) {\n console.error('Error running assignment transition:', error);\n res.status(500).json({ error: `Failed to transition assignment: ${(error as Error).message}` });\n }\n });\n\n return router;\n}\n","export function slugify(title: string): string {\n return title\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n}\n\nexport function isValidSlug(slug: string): boolean {\n return /^[a-z0-9]+(-[a-z0-9]+)*$/.test(slug);\n}\n","import { randomUUID } from 'node:crypto';\n\nexport function generateId(): string {\n return randomUUID();\n}\n","export interface ToggleAcceptanceCriterionResult {\n content: string;\n}\n\nexport interface ToggleAcceptanceCriterionError {\n error: string;\n}\n\nfunction splitFrontmatter(content: string): { prefix: string; body: string } {\n const match = content.match(/^(---\\r?\\n[\\s\\S]*?\\r?\\n---\\r?\\n?)([\\s\\S]*)$/);\n if (!match) {\n return { prefix: '', body: content };\n }\n\n return {\n prefix: match[1],\n body: match[2],\n };\n}\n\nexport function toggleAcceptanceCriterion(\n content: string,\n index: number,\n checked: boolean,\n): ToggleAcceptanceCriterionResult | ToggleAcceptanceCriterionError {\n if (!Number.isInteger(index) || index < 0) {\n return { error: 'acceptance criteria index must be a non-negative integer' };\n }\n\n const { prefix, body } = splitFrontmatter(content);\n const lines = body.split('\\n');\n const sectionStart = lines.findIndex((line) => /^##\\s+Acceptance Criteria\\s*$/i.test(line.trim()));\n\n if (sectionStart === -1) {\n return { error: 'Acceptance Criteria section not found.' };\n }\n\n let sectionEnd = lines.length;\n for (let lineIndex = sectionStart + 1; lineIndex < lines.length; lineIndex += 1) {\n if (/^#{1,2}\\s+\\S/.test(lines[lineIndex].trim())) {\n sectionEnd = lineIndex;\n break;\n }\n }\n\n const checklistLines = lines\n .map((line, lineIndex) => ({ line, lineIndex }))\n .filter(({ lineIndex, line }) =>\n lineIndex > sectionStart\n && lineIndex < sectionEnd\n && /^\\s*[-*]\\s+\\[( |x|X)\\]\\s+.*$/.test(line),\n );\n\n const target = checklistLines[index];\n if (!target) {\n return { error: `Acceptance criteria item ${index} not found.` };\n }\n\n const nextLine = target.line.replace(\n /^(\\s*[-*]\\s+\\[)( |x|X)(\\]\\s+.*)$/,\n `$1${checked ? 'x' : ' '}$3`,\n );\n\n lines[target.lineIndex] = nextLine;\n return {\n content: `${prefix}${lines.join('\\n')}`,\n };\n}\n","export interface ManifestParams {\n slug: string;\n timestamp: string;\n}\n\nexport function renderManifest(params: ManifestParams): string {\n return `---\nversion: \"1.0\"\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\n---\n\n# Mission: ${params.slug}\n\n## Overview\n- [Mission Overview](./mission.md)\n\n## Indexes\n- [Assignments](./_index-assignments.md)\n- [Plans](./_index-plans.md)\n- [Decision Records](./_index-decisions.md)\n- [Status](./_status.md)\n- [Resources](./resources/_index.md)\n- [Memories](./memories/_index.md)\n\n## Config\n- [Agent Instructions](./agent.md)\n- [Claude Code Instructions](./claude.md)\n`;\n}\n","export function escapeYamlString(value: string): string {\n if (value.includes('\\n') || value.includes('\\r')) {\n throw new Error(\n `YAML string values must be single-line. Got: \"${value.slice(0, 50)}...\"`,\n );\n }\n const escaped = value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n return `\"${escaped}\"`;\n}\n","import { escapeYamlString } from '../utils/yaml.js';\n\nexport interface MissionParams {\n id: string;\n slug: string;\n title: string;\n timestamp: string;\n workspace?: string;\n}\n\nexport function renderMission(params: MissionParams): string {\n const safeTitle = escapeYamlString(params.title);\n const workspaceLine = params.workspace ? `\\nworkspace: ${params.workspace}` : '';\n return `---\nid: ${params.id}\nslug: ${params.slug}\ntitle: ${safeTitle}\narchived: false\narchivedAt: null\narchivedReason: null\ncreated: \"${params.timestamp}\"\nupdated: \"${params.timestamp}\"\nexternalIds: []\ntags: []${workspaceLine}\n---\n\n# ${params.title}\n\n## Overview\n\n<!-- Describe the mission goal, context, and success criteria here. -->\n\n## Notes\n\n<!-- Optional human notes, updates, or context. -->\n`;\n}\n","export interface AgentParams {\n slug: string;\n timestamp: string;\n}\n\nexport function renderAgent(params: AgentParams): string {\n return `---\nmission: ${params.slug}\nupdated: \"${params.timestamp}\"\n---\n\n# Agent Instructions\n\nAll agents working on this mission must follow these guidelines.\n\n## Conventions\n\n<!-- Coding conventions, naming standards, architectural patterns. -->\n\n## Boundaries\n\n<!-- What agents should NOT do. Files/systems that are off-limits. -->\n\n## Resources\n\n<!-- Links to key resources agents should consult. -->\n`;\n}\n","export interface ClaudeParams {\n slug: string;\n}\n\nexport function renderClaude(params: ClaudeParams): string {\n return `# Claude Code Instructions \\u2014 ${params.slug}\n\nRead \\`agent.md\\` first for universal conventions and boundaries.\n\n## Additional Claude Code Rules\n\n<!-- Add Claude Code-specific rules here. -->\n`;\n}\n","import { escapeYamlString } from '../utils/yaml.js';\n\nexport interface AssignmentParams {\n id: string;\n slug: string;\n title: string;\n timestamp: string;\n priority: 'low' | 'medium' | 'high' | 'critical';\n dependsOn: string[];\n}\n\nexport function renderAssignment(params: AssignmentParams): string {\n const safeTitle = escapeYamlString(params.title);\n const dependsOnYaml =\n params.dependsOn.length === 0\n ? 'dependsOn: []'\n : `dependsOn:\\n - ${params.dependsOn.join('\\n - ')}`;\n\n return `---\nid: ${params.id}\nslug: ${params.slug}\ntitle: ${safeTitle}\nstatus: pending\npriority: ${params.priority}\ncreated: \"${params.timestamp}\"\nupdated: \"${params.timestamp}\"\nassignee: null\nexternalIds: []\n${dependsOnYaml}\nblockedReason: null\nworkspace:\n repository: null\n worktreePath: null\n branch: null\n parentBranch: null\ntags: []\n---\n\n# ${params.title}\n\n## Objective\n\n<!-- Clear description of what needs to be done and why. -->\n\n## Acceptance Criteria\n\n- [ ] <!-- criterion 1 -->\n- [ ] <!-- criterion 2 -->\n- [ ] <!-- criterion 3 -->\n\n## Context\n\n<!-- Links to relevant docs, code, or other assignments. -->\n\n## Questions & Answers\n\nNo questions yet.\n\n## Progress\n\nNo progress yet.\n\n## Links\n\n- [Plan](./plan.md)\n- [Scratchpad](./scratchpad.md)\n- [Handoff](./handoff.md)\n- [Decision Record](./decision-record.md)\n`;\n}\n","export interface PlanParams {\n assignmentSlug: string;\n title: string;\n timestamp: string;\n}\n\nexport function renderPlan(params: PlanParams): string {\n return `---\nassignment: ${params.assignmentSlug}\nstatus: draft\ncreated: \"${params.timestamp}\"\nupdated: \"${params.timestamp}\"\n---\n\n# Plan: ${params.title}\n\n## Approach\n\n<!-- High-level description of how to accomplish the objective. -->\n\n## Tasks\n\n- [ ] <!-- step 1 -->\n- [ ] <!-- step 2 -->\n- [ ] <!-- step 3 -->\n\n## Risks & Mitigations\n\n| Risk | Mitigation |\n|------|------------|\n| <!-- risk --> | <!-- mitigation --> |\n`;\n}\n","export interface ScratchpadParams {\n assignmentSlug: string;\n timestamp: string;\n}\n\nexport function renderScratchpad(params: ScratchpadParams): string {\n return `---\nassignment: ${params.assignmentSlug}\nupdated: \"${params.timestamp}\"\n---\n\n# Scratchpad\n\nNo working notes yet.\n`;\n}\n","export interface HandoffParams {\n assignmentSlug: string;\n timestamp: string;\n}\n\nexport function renderHandoff(params: HandoffParams): string {\n return `---\nassignment: ${params.assignmentSlug}\nupdated: \"${params.timestamp}\"\nhandoffCount: 0\n---\n\n# Handoff Log\n\nNo handoffs recorded yet.\n`;\n}\n","export interface DecisionRecordParams {\n assignmentSlug: string;\n timestamp: string;\n}\n\nexport function renderDecisionRecord(\n params: DecisionRecordParams,\n): string {\n return `---\nassignment: ${params.assignmentSlug}\nupdated: \"${params.timestamp}\"\ndecisionCount: 0\n---\n\n# Decision Record\n\nNo decisions recorded yet.\n`;\n}\n","export interface IndexStubParams {\n slug: string;\n title: string;\n timestamp: string;\n}\n\nexport function renderIndexAssignments(params: IndexStubParams): string {\n return `---\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\ntotal: 0\nby_status:\n pending: 0\n in_progress: 0\n blocked: 0\n review: 0\n completed: 0\n failed: 0\n---\n\n# Assignments\n\n| Slug | Title | Status | Priority | Assignee | Dependencies | Updated |\n|------|-------|--------|----------|----------|--------------|---------|\n`;\n}\n\nexport function renderIndexPlans(params: IndexStubParams): string {\n return `---\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\n---\n\n# Plans\n\n| Assignment | Plan Status | Updated |\n|------------|-------------|---------|\n`;\n}\n\nexport function renderIndexDecisions(params: IndexStubParams): string {\n return `---\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\n---\n\n# Decision Records\n\n| Assignment | Count | Latest Decision | Latest Status | Updated |\n|------------|-------|-----------------|---------------|---------|\n`;\n}\n\nexport function renderStatus(params: IndexStubParams): string {\n return `---\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\nstatus: pending\nprogress:\n total: 0\n completed: 0\n in_progress: 0\n blocked: 0\n pending: 0\n review: 0\n failed: 0\nneedsAttention:\n blockedCount: 0\n failedCount: 0\n unansweredQuestions: 0\n---\n\n# Mission Status: ${params.title}\n\n**Status:** pending\n**Progress:** 0/0 assignments complete\n\n## Assignments\n\nNo assignments yet.\n\n## Dependency Graph\n\nNo dependencies yet.\n\n## Needs Attention\n\n- **0 blocked** assignments\n- **0 failed** assignments\n- **0 unanswered** questions\n`;\n}\n\nexport function renderResourcesIndex(params: IndexStubParams): string {\n return `---\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\ntotal: 0\n---\n\n# Resources\n\n| Name | Category | Source | Related Assignments | Updated |\n|------|----------|--------|---------------------|---------|\n`;\n}\n\nexport function renderMemoriesIndex(params: IndexStubParams): string {\n return `---\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\ntotal: 0\n---\n\n# Memories\n\n| Name | Source | Scope | Source Assignment | Updated |\n|------|--------|-------|------------------|---------|\n`;\n}\n","import { escapeYamlString } from '../utils/yaml.js';\n\nexport interface PlaybookParams {\n slug: string;\n name: string;\n description: string;\n whenToUse?: string;\n timestamp: string;\n}\n\nexport function renderPlaybook(params: PlaybookParams): string {\n const whenToUse = params.whenToUse\n ? escapeYamlString(params.whenToUse)\n : 'null';\n return `---\nname: ${escapeYamlString(params.name)}\nslug: ${params.slug}\ndescription: ${escapeYamlString(params.description)}\nwhen_to_use: ${whenToUse}\ncreated: \"${params.timestamp}\"\nupdated: \"${params.timestamp}\"\ntags: []\n---\n\n# ${params.name}\n\n<!-- Write imperative rules and workflows here. Keep it under 50 lines. -->\n`;\n}\n","import { Router } from 'express';\nimport {\n registerSession,\n removeSession,\n listSessionFiles,\n readSessionFile,\n updateLastRefreshed,\n setOverride,\n sanitizeSessionName,\n} from './servers.js';\nimport {\n scanAllSessions,\n scanSingleSession,\n clearScanCache,\n} from './scanner.js';\n\nexport function createServersRouter(serversDir: string, missionsDir: string): Router {\n const router = Router();\n\n // GET /api/servers — all sessions with cached scan data\n router.get('/', async (_req, res) => {\n try {\n const result = await scanAllSessions(serversDir, missionsDir);\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Scan failed' });\n }\n });\n\n // GET /api/servers/:name — single session\n router.get('/:name', async (req, res) => {\n try {\n const session = await scanSingleSession(serversDir, missionsDir, req.params.name);\n if (!session) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n res.json(session);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Scan failed' });\n }\n });\n\n // POST /api/servers — register a new session\n router.post('/', async (req, res) => {\n try {\n const { name } = req.body;\n if (!name || typeof name !== 'string') {\n res.status(400).json({ error: 'name is required' });\n return;\n }\n const sanitized = sanitizeSessionName(name);\n const existing = await readSessionFile(serversDir, sanitized);\n if (existing) {\n res.status(409).json({ error: `Session \"${sanitized}\" already registered` });\n return;\n }\n await registerSession(serversDir, name);\n clearScanCache();\n res.status(201).json({ name: sanitized });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Registration failed' });\n }\n });\n\n // DELETE /api/servers/:name — unregister\n router.delete('/:name', async (req, res) => {\n try {\n const data = await readSessionFile(serversDir, req.params.name);\n if (!data) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n await removeSession(serversDir, req.params.name);\n clearScanCache();\n res.json({ removed: req.params.name });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Removal failed' });\n }\n });\n\n // POST /api/servers/refresh — fresh scan all (must be before /:name/refresh)\n router.post('/refresh', async (_req, res) => {\n try {\n const names = await listSessionFiles(serversDir);\n for (const name of names) {\n await updateLastRefreshed(serversDir, name);\n }\n clearScanCache();\n const result = await scanAllSessions(serversDir, missionsDir, { bypassCache: true });\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Refresh failed' });\n }\n });\n\n // POST /api/servers/:name/refresh — fresh scan one\n router.post('/:name/refresh', async (req, res) => {\n try {\n const data = await readSessionFile(serversDir, req.params.name);\n if (!data) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n await updateLastRefreshed(serversDir, req.params.name);\n clearScanCache();\n const session = await scanSingleSession(serversDir, missionsDir, req.params.name);\n res.json(session);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Refresh failed' });\n }\n });\n\n // PATCH /api/servers/:name/panes/:windowIndex/:paneIndex/assignment — manual link\n router.patch('/:name/panes/:windowIndex/:paneIndex/assignment', async (req, res) => {\n try {\n const { name, windowIndex, paneIndex } = req.params;\n const data = await readSessionFile(serversDir, name);\n if (!data) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n const body = req.body;\n if (body === null || (body && body.mission && body.assignment)) {\n await setOverride(\n serversDir,\n name,\n parseInt(windowIndex, 10),\n parseInt(paneIndex, 10),\n body,\n );\n clearScanCache();\n res.json({ updated: true });\n } else {\n res.status(400).json({ error: 'Body must be { mission, assignment } or null' });\n }\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Update failed' });\n }\n });\n\n return router;\n}\n","import { Router } from 'express';\nimport { resolve } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport {\n listAllSessions,\n listMissionSessions,\n appendSession,\n updateSessionStatus,\n deleteSessions,\n reconcileActiveSessions,\n} from './agent-sessions.js';\nimport { fileExists } from '../utils/fs.js';\nimport type { AgentSessionStatus, WsMessage } from './types.js';\n\nexport function createAgentSessionsRouter(\n missionsDir: string,\n broadcast?: (msg: WsMessage) => void,\n): Router {\n const router = Router();\n\n // GET /api/agent-sessions — all sessions across all missions\n router.get('/', async (_req, res) => {\n try {\n await reconcileActiveSessions(missionsDir);\n const sessions = await listAllSessions(missionsDir);\n res.json({ sessions, generatedAt: new Date().toISOString() });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to list sessions' });\n }\n });\n\n // GET /api/agent-sessions/:missionSlug — sessions for one mission\n router.get('/:missionSlug', async (req, res) => {\n try {\n const { missionSlug } = req.params;\n const assignment = req.query.assignment as string | undefined;\n const missionDir = resolve(missionsDir, missionSlug);\n if (!(await fileExists(missionDir))) {\n res.status(404).json({ error: `Mission \"${missionSlug}\" not found` });\n return;\n }\n await reconcileActiveSessions(missionsDir);\n const sessions = await listMissionSessions(missionsDir, missionSlug, assignment);\n res.json({ sessions, generatedAt: new Date().toISOString() });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to list sessions' });\n }\n });\n\n // POST /api/agent-sessions — register a new session\n router.post('/', async (req, res) => {\n try {\n const { missionSlug, assignmentSlug, agent, sessionId, path, description } = req.body;\n\n if (!agent) {\n res.status(400).json({ error: 'agent is required' });\n return;\n }\n\n if (missionSlug) {\n const missionDir = resolve(missionsDir, missionSlug);\n if (!(await fileExists(missionDir))) {\n res.status(404).json({ error: `Mission \"${missionSlug}\" not found` });\n return;\n }\n }\n\n const id = sessionId || randomUUID();\n const session = {\n missionSlug: missionSlug || null,\n assignmentSlug: assignmentSlug || null,\n agent,\n sessionId: id,\n started: new Date().toISOString(),\n status: 'active' as AgentSessionStatus,\n path: path || '',\n description: description || null,\n };\n\n await appendSession('', session);\n broadcast?.({ type: 'agent-sessions-updated', timestamp: new Date().toISOString() });\n res.status(201).json({ sessionId: id });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Registration failed' });\n }\n });\n\n // PATCH /api/agent-sessions/:sessionId/status — update session status\n router.patch('/:sessionId/status', async (req, res) => {\n try {\n const { sessionId } = req.params;\n const { status } = req.body;\n\n if (!status) {\n res.status(400).json({ error: 'status is required' });\n return;\n }\n\n if (!['active', 'completed', 'stopped'].includes(status)) {\n res.status(400).json({ error: 'status must be active, completed, or stopped' });\n return;\n }\n\n const updated = await updateSessionStatus('', sessionId, status);\n if (!updated) {\n res.status(404).json({ error: `Session \"${sessionId}\" not found` });\n return;\n }\n\n broadcast?.({ type: 'agent-sessions-updated', timestamp: new Date().toISOString() });\n res.json({ updated: true });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Update failed' });\n }\n });\n\n // DELETE /api/agent-sessions — delete one or more sessions\n router.delete('/', async (req, res) => {\n try {\n const { sessionIds } = req.body;\n\n if (!Array.isArray(sessionIds) || sessionIds.length === 0) {\n res.status(400).json({ error: 'sessionIds must be a non-empty array' });\n return;\n }\n\n const deleted = await deleteSessions(sessionIds);\n broadcast?.({ type: 'agent-sessions-updated', timestamp: new Date().toISOString() });\n res.json({ deleted });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Delete failed' });\n }\n });\n\n return router;\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { fileExists } from '../utils/fs.js';\nimport { getSessionDb } from './session-db.js';\nimport type { AgentSession, AgentSessionStatus } from './types.js';\n\ninterface SessionRow {\n session_id: string;\n mission_slug: string | null;\n assignment_slug: string | null;\n agent: string;\n started: string;\n ended: string | null;\n status: string;\n path: string | null;\n description: string | null;\n}\n\nfunction rowToSession(row: SessionRow): AgentSession {\n return {\n sessionId: row.session_id,\n missionSlug: row.mission_slug ?? null,\n assignmentSlug: row.assignment_slug ?? null,\n agent: row.agent,\n started: row.started,\n ended: row.ended ?? null,\n status: row.status as AgentSessionStatus,\n path: row.path ?? '',\n description: row.description ?? null,\n };\n}\n\n/**\n * Query sessions for a specific mission.\n */\nexport async function parseSessionsIndex(\n _missionDir: string,\n missionSlug: string,\n): Promise<AgentSession[]> {\n const db = getSessionDb();\n const rows = db\n .prepare('SELECT * FROM sessions WHERE mission_slug = ? ORDER BY started DESC')\n .all(missionSlug) as SessionRow[];\n return rows.map(rowToSession);\n}\n\n/**\n * Insert a new session into the database.\n */\nexport async function appendSession(\n _missionDir: string,\n session: AgentSession,\n): Promise<void> {\n const db = getSessionDb();\n db.prepare(`\n INSERT INTO sessions (session_id, mission_slug, assignment_slug, agent, started, status, path, description)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n session.sessionId,\n session.missionSlug ?? null,\n session.assignmentSlug ?? null,\n session.agent,\n session.started,\n session.status,\n session.path,\n session.description ?? null,\n );\n}\n\n/**\n * Update a session's status by sessionId.\n * Sets `ended` timestamp for terminal statuses (completed, stopped).\n */\nexport async function updateSessionStatus(\n _missionDir: string,\n sessionId: string,\n status: AgentSessionStatus,\n): Promise<boolean> {\n const db = getSessionDb();\n const isTerminal = status === 'completed' || status === 'stopped';\n\n const result = isTerminal\n ? db\n .prepare(\n 'UPDATE sessions SET status = ?, ended = datetime(\\'now\\'), updated_at = datetime(\\'now\\') WHERE session_id = ?',\n )\n .run(status, sessionId)\n : db\n .prepare(\n 'UPDATE sessions SET status = ?, updated_at = datetime(\\'now\\') WHERE session_id = ?',\n )\n .run(status, sessionId);\n\n return result.changes > 0;\n}\n\n/**\n * List all sessions across all missions.\n */\nexport async function listAllSessions(_missionsDir: string): Promise<AgentSession[]> {\n const db = getSessionDb();\n const rows = db\n .prepare('SELECT * FROM sessions ORDER BY started DESC')\n .all() as SessionRow[];\n return rows.map(rowToSession);\n}\n\n/**\n * List sessions for a specific mission, optionally filtered by assignment.\n */\nexport async function listMissionSessions(\n _missionsDir: string,\n missionSlug: string,\n assignmentSlug?: string,\n): Promise<AgentSession[]> {\n const db = getSessionDb();\n\n if (assignmentSlug) {\n const rows = db\n .prepare(\n 'SELECT * FROM sessions WHERE mission_slug = ? AND assignment_slug = ? ORDER BY started DESC',\n )\n .all(missionSlug, assignmentSlug) as SessionRow[];\n return rows.map(rowToSession);\n }\n\n const rows = db\n .prepare('SELECT * FROM sessions WHERE mission_slug = ? ORDER BY started DESC')\n .all(missionSlug) as SessionRow[];\n return rows.map(rowToSession);\n}\n\n/**\n * Delete sessions by their IDs. Returns the number of rows deleted.\n */\nexport async function deleteSessions(sessionIds: string[]): Promise<number> {\n if (sessionIds.length === 0) return 0;\n const db = getSessionDb();\n const placeholders = sessionIds.map(() => '?').join(', ');\n const result = db\n .prepare(`DELETE FROM sessions WHERE session_id IN (${placeholders})`)\n .run(...sessionIds);\n return result.changes;\n}\n\n// Statuses that imply the working session is done (review means agent finished)\nconst DONE_ASSIGNMENT_STATUSES = new Set(['completed', 'failed', 'review']);\n\n/**\n * Read the status field from an assignment.md frontmatter without full parsing.\n */\nasync function readAssignmentStatus(\n missionDir: string,\n assignmentSlug: string,\n): Promise<string | null> {\n const assignmentPath = resolve(missionDir, 'assignments', assignmentSlug, 'assignment.md');\n if (!(await fileExists(assignmentPath))) return null;\n\n const raw = await readFile(assignmentPath, 'utf-8');\n const match = raw.match(/^status:\\s*(.+)$/m);\n return match ? match[1].trim() : null;\n}\n\n/**\n * Reconcile active sessions against assignment statuses.\n * Sessions whose assignments have moved to completed/failed/review are\n * marked as completed (or stopped for failed assignments).\n * Returns the number of sessions that were updated.\n */\nexport async function reconcileActiveSessions(\n missionsDir: string,\n): Promise<number> {\n const db = getSessionDb();\n\n // Get active sessions that are linked to a mission/assignment (standalone sessions have nothing to reconcile)\n const activeSessions = db\n .prepare('SELECT * FROM sessions WHERE status = \\'active\\' AND mission_slug IS NOT NULL AND assignment_slug IS NOT NULL')\n .all() as SessionRow[];\n\n if (activeSessions.length === 0) return 0;\n\n // Dedupe assignment slugs per mission for status checks\n // mission_slug and assignment_slug are guaranteed non-null by the query filter above\n const toCheck = new Map<string, Set<string>>();\n for (const session of activeSessions) {\n const slugs = toCheck.get(session.mission_slug!) ?? new Set();\n slugs.add(session.assignment_slug!);\n toCheck.set(session.mission_slug!, slugs);\n }\n\n // Read assignment statuses from disk\n const assignmentStatuses = new Map<string, string>();\n for (const [missionSlug, slugs] of toCheck) {\n const missionDir = resolve(missionsDir, missionSlug);\n for (const slug of slugs) {\n const status = await readAssignmentStatus(missionDir, slug);\n if (status) assignmentStatuses.set(`${missionSlug}/${slug}`, status);\n }\n }\n\n // Update stale sessions\n let totalUpdated = 0;\n for (const session of activeSessions) {\n const key = `${session.mission_slug}/${session.assignment_slug}`;\n const assignmentStatus = assignmentStatuses.get(key);\n if (!assignmentStatus || !DONE_ASSIGNMENT_STATUSES.has(assignmentStatus)) continue;\n\n const newStatus: AgentSessionStatus =\n assignmentStatus === 'failed' ? 'stopped' : 'completed';\n await updateSessionStatus('', session.session_id, newStatus);\n totalUpdated++;\n }\n\n return totalUpdated;\n}\n","import Database from 'better-sqlite3';\nimport { resolve } from 'node:path';\nimport { readdir } from 'node:fs/promises';\nimport { syntaurRoot } from '../utils/paths.js';\nimport { fileExists } from '../utils/fs.js';\nimport type { AgentSession, AgentSessionStatus } from './types.js';\n\nlet db: Database.Database | null = null;\n\nconst SCHEMA_VERSION = '2';\n\nconst SCHEMA_SQL = `\nCREATE TABLE IF NOT EXISTS sessions (\n session_id TEXT PRIMARY KEY,\n mission_slug TEXT,\n assignment_slug TEXT,\n agent TEXT NOT NULL,\n started TEXT NOT NULL,\n ended TEXT,\n status TEXT NOT NULL DEFAULT 'active',\n path TEXT,\n description TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_sessions_mission ON sessions(mission_slug);\nCREATE INDEX IF NOT EXISTS idx_sessions_assignment ON sessions(mission_slug, assignment_slug);\nCREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);\nCREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT);\n`;\n\n/**\n * Initialize the SQLite database for session tracking.\n * Creates the database file and schema if they don't exist.\n * @param dbPath Optional override for the database file path (used in tests).\n */\nexport function initSessionDb(dbPath?: string): Database.Database {\n if (db) return db;\n\n const finalPath = dbPath ?? resolve(syntaurRoot(), 'syntaur.db');\n db = new Database(finalPath);\n db.pragma('journal_mode = WAL');\n db.exec(SCHEMA_SQL);\n\n // Track schema version\n db.prepare('INSERT OR IGNORE INTO meta (key, value) VALUES (?, ?)').run(\n 'schema_version',\n SCHEMA_VERSION,\n );\n\n // Migrate from v1 to v2: make mission/assignment nullable, add description\n const currentVersion = db\n .prepare(\"SELECT value FROM meta WHERE key = 'schema_version'\")\n .get() as { value: string } | undefined;\n\n if (currentVersion?.value === '1') {\n db.exec(`\n CREATE TABLE sessions_v2 (\n session_id TEXT PRIMARY KEY,\n mission_slug TEXT,\n assignment_slug TEXT,\n agent TEXT NOT NULL,\n started TEXT NOT NULL,\n ended TEXT,\n status TEXT NOT NULL DEFAULT 'active',\n path TEXT,\n description TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n );\n INSERT INTO sessions_v2 SELECT session_id, mission_slug, assignment_slug, agent, started, ended, status, path, NULL, created_at, updated_at FROM sessions;\n DROP TABLE sessions;\n ALTER TABLE sessions_v2 RENAME TO sessions;\n CREATE INDEX IF NOT EXISTS idx_sessions_mission ON sessions(mission_slug);\n CREATE INDEX IF NOT EXISTS idx_sessions_assignment ON sessions(mission_slug, assignment_slug);\n CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);\n UPDATE meta SET value = '2' WHERE key = 'schema_version';\n `);\n }\n\n return db;\n}\n\n/**\n * Get the initialized database handle.\n * Throws if initSessionDb() has not been called.\n */\nexport function getSessionDb(): Database.Database {\n if (!db) {\n throw new Error(\n 'Session database not initialized. Call initSessionDb() first.',\n );\n }\n return db;\n}\n\n/**\n * Close the database connection.\n */\nexport function closeSessionDb(): void {\n if (db) {\n db.close();\n db = null;\n }\n}\n\n/**\n * Reset the singleton for testing purposes.\n */\nexport function resetSessionDb(): void {\n db = null;\n}\n\n/**\n * One-time migration: import sessions from markdown _index-sessions.md files into SQLite.\n * Only runs if the sessions table is empty and markdown files exist.\n */\nexport async function migrateFromMarkdown(missionsDir: string): Promise<number> {\n const database = getSessionDb();\n\n // Skip if sessions already exist in the database\n const count = database.prepare('SELECT COUNT(*) as count FROM sessions').get() as { count: number };\n if (count.count > 0) return 0;\n\n if (!(await fileExists(missionsDir))) return 0;\n\n const entries = await readdir(missionsDir, { withFileTypes: true });\n const allSessions: AgentSession[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const missionDir = resolve(missionsDir, entry.name);\n const indexPath = resolve(missionDir, '_index-sessions.md');\n if (!(await fileExists(indexPath))) continue;\n\n const sessions = await parseMarkdownSessionsIndex(indexPath, entry.name);\n allSessions.push(...sessions);\n }\n\n if (allSessions.length === 0) return 0;\n\n const insert = database.prepare(`\n INSERT OR IGNORE INTO sessions (session_id, mission_slug, assignment_slug, agent, started, status, path)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `);\n\n const insertAll = database.transaction((sessions: AgentSession[]) => {\n for (const s of sessions) {\n insert.run(s.sessionId, s.missionSlug, s.assignmentSlug, s.agent, s.started, s.status, s.path);\n }\n });\n\n insertAll(allSessions);\n console.log(`Migrated ${allSessions.length} sessions from markdown to SQLite.`);\n return allSessions.length;\n}\n\n/**\n * Parse an _index-sessions.md file into AgentSession objects.\n * Used only for one-time migration. This is a copy of the old parsing logic.\n */\nasync function parseMarkdownSessionsIndex(\n filePath: string,\n missionSlug: string,\n): Promise<AgentSession[]> {\n const { readFile } = await import('node:fs/promises');\n const raw = await readFile(filePath, 'utf-8');\n const sessions: AgentSession[] = [];\n\n const lines = raw.split('\\n');\n let inTable = false;\n let headerSeen = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n if (trimmed.startsWith('| Assignment') || trimmed.startsWith('|Assignment')) {\n inTable = true;\n headerSeen = false;\n continue;\n }\n\n if (inTable && !headerSeen && trimmed.match(/^\\|[-\\s|]+\\|$/)) {\n headerSeen = true;\n continue;\n }\n\n if (inTable && headerSeen && trimmed.startsWith('|')) {\n const cells = trimmed\n .split('|')\n .slice(1, -1)\n .map((c) => c.trim());\n\n if (cells.length >= 6) {\n sessions.push({\n assignmentSlug: cells[0],\n agent: cells[1],\n sessionId: cells[2],\n started: cells[3],\n status: (cells[4] as AgentSessionStatus) || 'active',\n path: cells[5],\n missionSlug,\n });\n }\n }\n }\n\n return sessions;\n}\n","import { Router } from 'express';\nimport { resolve } from 'node:path';\nimport { readFile, unlink } from 'node:fs/promises';\nimport { listPlaybooks, getPlaybookDetail } from './api.js';\nimport { parsePlaybook } from './parser.js';\nimport { isValidSlug } from '../utils/slug.js';\nimport { nowTimestamp } from '../utils/timestamp.js';\nimport { ensureDir, fileExists, writeFileForce } from '../utils/fs.js';\nimport { renderPlaybook } from '../templates/playbook.js';\nimport { rebuildPlaybookManifest } from '../utils/playbooks.js';\n\nexport function createPlaybooksRouter(playbooksDir: string): Router {\n const router = Router();\n\n // GET / — list all playbooks\n router.get('/', async (_req, res) => {\n try {\n const playbooks = await listPlaybooks(playbooksDir);\n res.json({ playbooks, generatedAt: new Date().toISOString() });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to list playbooks' });\n }\n });\n\n // GET /template/new — scaffold template (must be before /:slug to avoid param capture)\n router.get('/template/new', async (_req, res) => {\n try {\n const content = renderPlaybook({\n slug: 'my-playbook',\n name: 'My Playbook',\n description: 'A new playbook',\n timestamp: nowTimestamp(),\n });\n res.json({ content });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get template' });\n }\n });\n\n // GET /:slug — get playbook detail\n router.get('/:slug', async (req, res) => {\n try {\n const detail = await getPlaybookDetail(playbooksDir, req.params.slug);\n if (!detail) {\n res.status(404).json({ error: `Playbook \"${req.params.slug}\" not found` });\n return;\n }\n res.json(detail);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get playbook' });\n }\n });\n\n // GET /:slug/edit — raw file content for editor\n router.get('/:slug/edit', async (req, res) => {\n try {\n const filePath = resolve(playbooksDir, `${req.params.slug}.md`);\n if (!(await fileExists(filePath))) {\n res.status(404).json({ error: `Playbook \"${req.params.slug}\" not found` });\n return;\n }\n const content = await readFile(filePath, 'utf-8');\n res.json({\n documentType: 'playbook',\n title: `Edit Playbook: ${req.params.slug}`,\n content,\n slug: req.params.slug,\n });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get playbook for editing' });\n }\n });\n\n // POST / — create new playbook\n router.post('/', async (req, res) => {\n try {\n const { content } = req.body;\n if (!content || typeof content !== 'string') {\n res.status(400).json({ error: 'content is required' });\n return;\n }\n\n const parsed = parsePlaybook(content);\n const slug = parsed.slug;\n if (!slug || !isValidSlug(slug)) {\n res.status(400).json({ error: `Invalid or missing slug: \"${slug}\"` });\n return;\n }\n\n await ensureDir(playbooksDir);\n const filePath = resolve(playbooksDir, `${slug}.md`);\n if (await fileExists(filePath)) {\n res.status(409).json({ error: `Playbook \"${slug}\" already exists` });\n return;\n }\n\n await writeFileForce(filePath, content);\n await rebuildPlaybookManifest(playbooksDir);\n res.status(201).json({ slug, path: filePath });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to create playbook' });\n }\n });\n\n // PUT /:slug — update playbook content\n router.put('/:slug', async (req, res) => {\n try {\n const { content } = req.body;\n if (!content || typeof content !== 'string') {\n res.status(400).json({ error: 'content is required' });\n return;\n }\n\n const filePath = resolve(playbooksDir, `${req.params.slug}.md`);\n if (!(await fileExists(filePath))) {\n res.status(404).json({ error: `Playbook \"${req.params.slug}\" not found` });\n return;\n }\n\n await writeFileForce(filePath, content);\n await rebuildPlaybookManifest(playbooksDir);\n res.json({ slug: req.params.slug, path: filePath });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to update playbook' });\n }\n });\n\n // DELETE /:slug — delete a playbook\n router.delete('/:slug', async (req, res) => {\n try {\n if (req.params.slug === 'manifest') {\n res.status(403).json({ error: 'The playbook manifest cannot be deleted' });\n return;\n }\n\n const filePath = resolve(playbooksDir, `${req.params.slug}.md`);\n if (!(await fileExists(filePath))) {\n res.status(404).json({ error: `Playbook \"${req.params.slug}\" not found` });\n return;\n }\n\n await unlink(filePath);\n await rebuildPlaybookManifest(playbooksDir);\n res.json({ deleted: req.params.slug });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to delete playbook' });\n }\n });\n\n return router;\n}\n","import { resolve } from 'node:path';\nimport { readdir, readFile } from 'node:fs/promises';\nimport { fileExists, writeFileForce } from './fs.js';\nimport { parsePlaybook } from '../dashboard/parser.js';\nimport { nowTimestamp } from './timestamp.js';\n\nexport async function rebuildPlaybookManifest(playbooksDir: string): Promise<void> {\n if (!(await fileExists(playbooksDir))) return;\n\n const entries = await readdir(playbooksDir, { withFileTypes: true });\n const rows: Array<{ name: string; slug: string; description: string; whenToUse: string }> = [];\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md') || entry.name.startsWith('_') || entry.name === 'manifest.md') continue;\n\n const raw = await readFile(resolve(playbooksDir, entry.name), 'utf-8');\n const parsed = parsePlaybook(raw);\n const slug = parsed.slug || entry.name.replace(/\\.md$/, '');\n\n rows.push({\n name: parsed.name || slug,\n slug,\n description: parsed.description,\n whenToUse: parsed.whenToUse,\n });\n }\n\n rows.sort((a, b) => a.name.localeCompare(b.name));\n\n const timestamp = nowTimestamp();\n const lines = [\n '---',\n `generated: \"${timestamp}\"`,\n `total: ${rows.length}`,\n '---',\n '',\n '# Playbooks',\n '',\n 'Behavioral rules for AI agents. Read and follow all playbooks before starting work.',\n '',\n ];\n\n for (const row of rows) {\n lines.push(`- **[${row.name}](${row.slug}.md)** — ${row.description}`);\n if (row.whenToUse) {\n lines.push(` _When to use: ${row.whenToUse}_`);\n }\n }\n\n lines.push('');\n\n await writeFileForce(resolve(playbooksDir, 'manifest.md'), lines.join('\\n'));\n}\n","import { Router, type Request, type Response, type NextFunction } from 'express';\nimport { readdir } from 'node:fs/promises';\nimport {\n readChecklist,\n writeChecklist,\n readLog,\n appendLogEntry,\n generateUniqueId,\n computeCounts,\n} from '../todos/parser.js';\nimport { ensureDir, fileExists } from '../utils/fs.js';\nimport type { TodoItem, LogEntry } from '../todos/types.js';\nimport type { WsMessage } from './types.js';\n\nconst WORKSPACE_REGEX = /^[a-z0-9_][a-z0-9-]*$/;\n\nfunction getWorkspaceParam(value: string | string[] | undefined): string {\n if (Array.isArray(value)) {\n return value[0] ?? '';\n }\n return value ?? '';\n}\n\n// Per-workspace write lock to prevent concurrent read-modify-write races\nconst writeLocks = new Map<string, Promise<void>>();\nfunction withLock<T>(workspace: string, fn: () => Promise<T>): Promise<T> {\n const prev = writeLocks.get(workspace) ?? Promise.resolve();\n const next = prev.then(fn);\n writeLocks.set(workspace, next.then(() => {}, () => {}));\n return next;\n}\n\nexport function createTodosRouter(\n todosDir: string,\n broadcast: (msg: WsMessage) => void,\n): Router {\n const router = Router();\n\n function broadcastUpdate(): void {\n broadcast({ type: 'todos-updated', timestamp: new Date().toISOString() });\n }\n\n // Validate workspace name on all routes that use :workspace\n function validateWorkspace(req: Request, res: Response, next: NextFunction): void {\n const workspace = getWorkspaceParam(req.params.workspace);\n if (workspace && !WORKSPACE_REGEX.test(workspace)) {\n res.status(400).json({ error: `Invalid workspace name: \"${workspace}\". Use lowercase letters, numbers, hyphens, and underscores.` });\n return;\n }\n next();\n }\n\n // Apply workspace validation to all parameterized routes\n router.param('workspace', validateWorkspace as any);\n\n // GET / — aggregate all workspace checklists\n router.get('/', async (_req, res) => {\n try {\n await ensureDir(todosDir);\n const files = await readdir(todosDir).catch(() => []);\n const workspaces: Array<{\n workspace: string;\n archiveInterval: string;\n items: TodoItem[];\n counts: ReturnType<typeof computeCounts>;\n }> = [];\n\n for (const file of files) {\n if (typeof file !== 'string') continue;\n if (!file.endsWith('.md') || file.endsWith('-log.md')) continue;\n const workspace = file.replace('.md', '');\n const checklist = await readChecklist(todosDir, workspace);\n workspaces.push({\n workspace: checklist.workspace,\n archiveInterval: checklist.archiveInterval,\n items: checklist.items,\n counts: computeCounts(checklist.items),\n });\n }\n\n res.json({ workspaces });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to list todos' });\n }\n });\n\n // GET /:workspace — list items for one workspace\n router.get('/:workspace', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const checklist = await readChecklist(todosDir, workspace);\n res.json({\n workspace: checklist.workspace,\n archiveInterval: checklist.archiveInterval,\n items: checklist.items,\n counts: computeCounts(checklist.items),\n });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get todos' });\n }\n });\n\n // POST /:workspace — add item\n router.post('/:workspace', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const { description, tags } = req.body;\n if (!description || typeof description !== 'string') {\n res.status(400).json({ error: 'description is required' });\n return;\n }\n\n const item = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const existingIds = new Set(checklist.items.map((i) => i.id));\n const id = generateUniqueId(existingIds);\n\n const newItem: TodoItem = {\n id,\n description,\n status: 'open',\n tags: Array.isArray(tags) ? tags : [],\n session: null,\n };\n checklist.items.push(newItem);\n await writeChecklist(todosDir, checklist);\n return newItem;\n });\n broadcastUpdate();\n res.status(201).json(item);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to add todo' });\n }\n });\n\n // POST /:workspace/reorder — reorder items\n // Must be before /:workspace/:id to avoid param capture\n router.post('/:workspace/reorder', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const { ids } = req.body;\n if (!Array.isArray(ids) || !ids.every((id: unknown) => typeof id === 'string')) {\n res.status(400).json({ error: 'ids must be an array of strings' });\n return;\n }\n\n const items = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const itemMap = new Map(checklist.items.map((i) => [i.id, i]));\n\n // Build reordered list: requested order first, then any items not in the ids array\n const reordered: TodoItem[] = [];\n for (const id of ids) {\n const item = itemMap.get(id);\n if (item) {\n reordered.push(item);\n itemMap.delete(id);\n }\n }\n // Append any remaining items not mentioned in ids\n for (const item of itemMap.values()) {\n reordered.push(item);\n }\n\n checklist.items = reordered;\n await writeChecklist(todosDir, checklist);\n return reordered;\n });\n broadcastUpdate();\n res.json({ items });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to reorder todos' });\n }\n });\n\n // GET /:workspace/log — full log\n // Must be before /:workspace/:id to avoid param capture\n router.get('/:workspace/log', async (req, res) => {\n try {\n const log = await readLog(todosDir, getWorkspaceParam(req.params.workspace));\n res.json(log);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get log' });\n }\n });\n\n // POST /:workspace/archive — trigger archive\n router.post('/:workspace/archive', async (req, res) => {\n try {\n // Import archive logic inline to avoid circular deps\n const { archivePath } = await import('../todos/parser.js');\n const { resolve } = await import('node:path');\n const { readFile } = await import('node:fs/promises');\n const { writeFileForce } = await import('../utils/fs.js');\n\n const workspace = getWorkspaceParam(req.params.workspace);\n const checklist = await readChecklist(todosDir, workspace);\n const log = await readLog(todosDir, workspace);\n\n const completedIds = new Set(\n checklist.items.filter((i) => i.status === 'completed').map((i) => i.id),\n );\n\n if (completedIds.size === 0) {\n res.json({ archived: 0, message: 'No completed items to archive' });\n return;\n }\n\n const toArchive = log.entries.filter((e) =>\n e.itemIds.every((id) => completedIds.has(id)),\n );\n\n const archFile = archivePath(todosDir, workspace, checklist.archiveInterval);\n await ensureDir(resolve(todosDir, 'archive'));\n let archContent = '';\n if (await fileExists(archFile)) {\n archContent = await readFile(archFile, 'utf-8');\n archContent = archContent.trimEnd() + '\\n\\n';\n } else {\n archContent = `---\\nworkspace: ${workspace}\\n---\\n\\n# Archive\\n\\n`;\n }\n\n const completedItems = checklist.items.filter((i) => completedIds.has(i.id));\n for (const item of completedItems) {\n archContent += `- [x] ${item.description} ${item.tags.map((t: string) => `#${t}`).join(' ')} [t:${item.id}]\\n`;\n }\n archContent += '\\n';\n for (const entry of toArchive) {\n archContent += `### ${entry.timestamp} — ${entry.itemIds.map((i: string) => `t:${i}`).join(', ')}\\n`;\n if (entry.items) archContent += `**Items:** ${entry.items}\\n`;\n if (entry.session) archContent += `**Session:** ${entry.session}\\n`;\n if (entry.branch) archContent += `**Branch:** ${entry.branch}\\n`;\n if (entry.summary) archContent += `**Summary:** ${entry.summary}\\n`;\n if (entry.blockers) archContent += `**Blockers:** ${entry.blockers}\\n`;\n archContent += '\\n';\n }\n await writeFileForce(archFile, archContent);\n\n checklist.items = checklist.items.filter((i) => !completedIds.has(i.id));\n await writeChecklist(todosDir, checklist);\n\n broadcastUpdate();\n res.json({ archived: completedIds.size, logEntries: toArchive.length });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to archive' });\n }\n });\n\n // GET /:workspace/log/:id — log for specific item\n router.get('/:workspace/log/:id', async (req, res) => {\n try {\n const log = await readLog(todosDir, getWorkspaceParam(req.params.workspace));\n const entries = log.entries.filter((e) => e.itemIds.includes(req.params.id));\n res.json({ workspace: log.workspace, entries });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get log' });\n }\n });\n\n // GET /:workspace/:id — single item with log\n router.get('/:workspace/:id', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) {\n res.status(404).json({ error: `Todo \"${req.params.id}\" not found` });\n return;\n }\n const log = await readLog(todosDir, workspace);\n const logEntries = log.entries.filter((e) => e.itemIds.includes(req.params.id));\n res.json({ ...item, log: logEntries });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get todo' });\n }\n });\n\n // PATCH /:workspace/:id — update description or tags\n router.patch('/:workspace/:id', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const result = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) return null;\n if (req.body.description !== undefined) item.description = req.body.description;\n if (Array.isArray(req.body.tags)) item.tags = req.body.tags;\n await writeChecklist(todosDir, checklist);\n return { ...item };\n });\n if (!result) { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n broadcastUpdate();\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to update todo' });\n }\n });\n\n // DELETE /:workspace/:id\n router.delete('/:workspace/:id', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const deleted = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const idx = checklist.items.findIndex((i) => i.id === req.params.id);\n if (idx === -1) return false;\n checklist.items.splice(idx, 1);\n await writeChecklist(todosDir, checklist);\n return true;\n });\n if (!deleted) { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n broadcastUpdate();\n res.json({ deleted: req.params.id });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to delete todo' });\n }\n });\n\n // POST /:workspace/:id/start\n router.post('/:workspace/:id/start', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const result = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) return { error: 'not_found' as const };\n if (item.status === 'in_progress') return { error: 'conflict' as const, session: item.session };\n item.status = 'in_progress';\n item.session = req.body.session || null;\n await writeChecklist(todosDir, checklist);\n return { item: { ...item } };\n });\n if ('error' in result) {\n if (result.error === 'not_found') { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n res.status(409).json({ error: `Todo is already in progress (session: ${result.session})` }); return;\n }\n broadcastUpdate();\n res.json(result.item);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to start todo' });\n }\n });\n\n // POST /:workspace/:id/complete\n router.post('/:workspace/:id/complete', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const result = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) return null;\n item.status = 'completed';\n item.session = null;\n await writeChecklist(todosDir, checklist);\n\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n itemIds: [item.id],\n items: item.description,\n session: req.body.session || null,\n branch: req.body.branch || null,\n summary: req.body.summary || 'Completed.',\n blockers: null,\n status: null,\n };\n await appendLogEntry(todosDir, workspace, entry);\n return { ...item };\n });\n if (!result) { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n broadcastUpdate();\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to complete todo' });\n }\n });\n\n // POST /:workspace/:id/block\n router.post('/:workspace/:id/block', async (req, res) => {\n try {\n const reason = req.body.reason || null;\n const workspace = getWorkspaceParam(req.params.workspace);\n const result = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) return null;\n item.status = 'blocked';\n item.session = null;\n await writeChecklist(todosDir, checklist);\n\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n itemIds: [item.id],\n items: item.description,\n session: req.body.session || null,\n branch: null,\n summary: reason || 'Blocked.',\n blockers: reason,\n status: 'blocked',\n };\n await appendLogEntry(todosDir, workspace, entry);\n return { ...item };\n });\n if (!result) { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n broadcastUpdate();\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to block todo' });\n }\n });\n\n // POST /:workspace/:id/reopen — move completed back to open\n router.post('/:workspace/:id/reopen', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const result = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) return null;\n item.status = 'open';\n item.session = null;\n await writeChecklist(todosDir, checklist);\n return { ...item };\n });\n if (!result) { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n broadcastUpdate();\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to reopen todo' });\n }\n });\n\n // POST /:workspace/:id/unblock\n router.post('/:workspace/:id/unblock', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const result = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) return null;\n item.status = 'open';\n item.session = null;\n await writeChecklist(todosDir, checklist);\n return { ...item };\n });\n if (!result) { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n broadcastUpdate();\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to unblock todo' });\n }\n });\n\n return router;\n}\n","import {\n execQuiet,\n checkTmuxAvailable,\n sessionAlive,\n listTmuxPanes,\n getLsofOutput,\n loadWorkspaceRecords,\n autoLinkPane,\n getGitInfo,\n clearScanCache,\n} from './scanner.js';\nimport {\n readSessionFile,\n listSessionFiles,\n registerAutoSession,\n removeSession,\n sanitizeSessionName,\n} from './servers.js';\nimport type { SessionFileData } from './types.js';\n\n// --- Shared lsof helpers ---\n\nexport function parsePortsForPid(lsofOutput: string, targetPid: number): number[] {\n const ports: number[] = [];\n for (const line of lsofOutput.split('\\n')) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const pid = parseInt(parts[1], 10);\n if (pid !== targetPid) continue;\n const tcpAddr = parts.find((p) => p.includes(':') && /:\\d+$/.test(p));\n if (tcpAddr) {\n const port = parseInt(tcpAddr.split(':').pop()!, 10);\n if (!isNaN(port) && !ports.includes(port)) ports.push(port);\n }\n }\n return ports;\n}\n\nexport function parseLsofForListeningProcesses(lsofOutput: string): ListeningProcess[] {\n const seen = new Map<number, ListeningProcess>();\n for (const line of lsofOutput.split('\\n')) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const command = parts[0];\n const pid = parseInt(parts[1], 10);\n if (isNaN(pid)) continue;\n const tcpAddr = parts.find((p) => p.includes(':') && /:\\d+$/.test(p));\n if (!tcpAddr) continue;\n const port = parseInt(tcpAddr.split(':').pop()!, 10);\n if (isNaN(port)) continue;\n\n if (!seen.has(pid)) {\n seen.set(pid, { pid, port, command });\n }\n }\n return Array.from(seen.values());\n}\n\n// --- Singleton lifecycle ---\n\nlet timer: ReturnType<typeof setInterval> | null = null;\nlet activeReconcile: Promise<void> | null = null;\n\nexport interface AutodiscoveryOptions {\n serversDir: string;\n missionsDir: string;\n intervalMs?: number;\n excludePids?: Set<number>;\n}\n\nlet savedOptions: AutodiscoveryOptions | null = null;\n\nexport function startAutodiscovery(opts: AutodiscoveryOptions): void {\n if (timer) return;\n savedOptions = opts;\n const interval = opts.intervalMs ?? 45_000;\n // Run once immediately, then on interval\n runReconcile();\n timer = setInterval(() => {\n runReconcile();\n }, interval);\n}\n\nexport async function stopAutodiscovery(): Promise<void> {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n // Await in-flight reconcile to prevent overlap\n if (activeReconcile) {\n await activeReconcile;\n activeReconcile = null;\n }\n savedOptions = null;\n}\n\nfunction runReconcile(): void {\n if (activeReconcile || !savedOptions) return;\n const opts = savedOptions;\n activeReconcile = reconcile(opts.serversDir, opts.missionsDir, opts.excludePids)\n .catch((err) => {\n console.error('[autodiscovery] reconcile failed:', err);\n })\n .finally(() => {\n activeReconcile = null;\n });\n}\n\n// --- Tmux discovery ---\n\nexport async function listAllTmuxSessions(): Promise<string[]> {\n const output = await execQuiet('tmux', ['list-sessions', '-F', '#{session_name}']);\n if (!output) return [];\n return output.split('\\n').filter((line) => line.length > 0);\n}\n\nasync function discoverTmuxSessions(\n serversDir: string,\n missionsDir: string,\n existingNames: Set<string>,\n): Promise<boolean> {\n const tmuxAvailable = await checkTmuxAvailable();\n if (!tmuxAvailable) return false;\n\n const workspaceRecords = await loadWorkspaceRecords(missionsDir);\n if (workspaceRecords.length === 0) return false;\n\n const sessions = await listAllTmuxSessions();\n let changed = false;\n\n for (const sessionName of sessions) {\n const sanitized = sanitizeSessionName(sessionName);\n if (existingNames.has(sanitized)) {\n // Already tracked (manual or auto) — skip\n continue;\n }\n\n const panes = await listTmuxPanes(sessionName);\n if (panes.length === 0) continue;\n\n // Check if any pane matches a workspace\n let matched = false;\n const cwdGitCache = new Map<string, { branch: string | null; worktree: boolean }>();\n\n for (const pane of panes) {\n if (!cwdGitCache.has(pane.cwd)) {\n cwdGitCache.set(pane.cwd, await getGitInfo(pane.cwd));\n }\n const gitInfo = cwdGitCache.get(pane.cwd)!;\n const link = await autoLinkPane(pane.cwd, gitInfo.branch, workspaceRecords);\n if (link) {\n matched = true;\n break;\n }\n }\n\n if (matched) {\n await registerAutoSession(serversDir, sessionName, { kind: 'tmux' });\n changed = true;\n }\n }\n\n return changed;\n}\n\n// --- Non-tmux process discovery ---\n\ninterface ListeningProcess {\n pid: number;\n port: number;\n command: string;\n}\n\nasync function getProcessCwd(pid: number): Promise<string | null> {\n // macOS: use lsof to get cwd\n const output = await execQuiet('lsof', ['-a', '-d', 'cwd', '-p', String(pid), '-Fn']);\n if (!output) return null;\n // Output format: lines starting with 'n' contain the path\n for (const line of output.split('\\n')) {\n if (line.startsWith('n') && line.length > 1) {\n return line.slice(1);\n }\n }\n return null;\n}\n\nasync function discoverProcesses(\n serversDir: string,\n missionsDir: string,\n existingFiles: Map<string, SessionFileData>,\n excludePids?: Set<number>,\n): Promise<boolean> {\n const workspaceRecords = await loadWorkspaceRecords(missionsDir);\n if (workspaceRecords.length === 0) return false;\n\n const lsofOutput = await getLsofOutput();\n if (!lsofOutput) return false;\n\n const processes = parseLsofForListeningProcesses(lsofOutput);\n let changed = false;\n\n // Track which PIDs are already tracked by existing process-kind entries\n const trackedPids = new Set<number>();\n for (const data of existingFiles.values()) {\n if (data.kind === 'process' && data.pid) {\n trackedPids.add(data.pid);\n }\n }\n\n for (const proc of processes) {\n if (trackedPids.has(proc.pid)) continue;\n if (excludePids?.has(proc.pid)) continue;\n\n const cwd = await getProcessCwd(proc.pid);\n if (!cwd) continue;\n\n const gitInfo = await getGitInfo(cwd);\n const link = await autoLinkPane(cwd, gitInfo.branch, workspaceRecords);\n if (!link) continue;\n\n // Build a session name from the command and port\n const sessionName = `proc-${proc.command}-${proc.port}`;\n const sanitized = sanitizeSessionName(sessionName);\n\n // Skip if already registered under this name\n if (existingFiles.has(sanitized)) continue;\n\n const ports = parsePortsForPid(lsofOutput, proc.pid);\n await registerAutoSession(serversDir, sessionName, {\n kind: 'process',\n pid: proc.pid,\n ports: ports.length > 0 ? ports : [proc.port],\n cwd,\n });\n changed = true;\n }\n\n return changed;\n}\n\n// --- Reconciliation ---\n\nasync function cleanupDeadAutoSessions(\n serversDir: string,\n existingFiles: Map<string, SessionFileData>,\n): Promise<{ changed: boolean; removedNames: Set<string> }> {\n let changed = false;\n const removedNames = new Set<string>();\n\n // Only check tmux liveness if tmux is available\n const tmuxAvailable = await checkTmuxAvailable();\n\n for (const [name, data] of existingFiles) {\n if (!data.auto) continue;\n\n let alive = true; // Default to alive for unknown kinds\n if (data.kind === 'tmux') {\n if (!tmuxAvailable) continue; // Don't delete tmux sessions when tmux is unavailable\n alive = await sessionAlive(data.session);\n } else if (data.kind === 'process' && data.pid) {\n alive = await isProcessAlive(data.pid);\n } else {\n // Unknown kind with auto: true — leave it alone\n continue;\n }\n\n if (!alive) {\n await removeSession(serversDir, name);\n removedNames.add(name);\n changed = true;\n }\n }\n\n return { changed, removedNames };\n}\n\nexport async function isProcessAlive(pid: number): Promise<boolean> {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function reconcile(serversDir: string, missionsDir: string, excludePids?: Set<number>): Promise<void> {\n // Load all existing session files\n const names = await listSessionFiles(serversDir);\n const existingFiles = new Map<string, SessionFileData>();\n for (const name of names) {\n const data = await readSessionFile(serversDir, name);\n if (data) existingFiles.set(name, data);\n }\n\n // Clean up dead auto sessions FIRST so discovery can re-register restarted processes\n const { changed: cleanupChanged, removedNames } = await cleanupDeadAutoSessions(serversDir, existingFiles);\n\n // Remove cleaned-up entries from the maps so discovery sees them as available\n for (const name of removedNames) {\n existingFiles.delete(name);\n }\n const existingNames = new Set(existingFiles.keys());\n\n // Discover new sessions\n const tmuxChanged = await discoverTmuxSessions(serversDir, missionsDir, existingNames);\n const processChanged = await discoverProcesses(serversDir, missionsDir, existingFiles, excludePids);\n\n // Invalidate scan cache if anything changed\n if (tmuxChanged || processChanged || cleanupChanged) {\n clearScanCache();\n }\n}\n\n// --- Exports for testing ---\nexport { reconcile, getProcessCwd };\n"],"mappings":"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","names":["getField","resolve","readFile","resolve","extractFrontmatter","parseSimpleValue","parseExternalIds","readFile","resolve","nowTimestamp","extractFrontmatter","resolve","readdir","readFile","extractFrontmatter","readdir","readFile","writeFile","resolve","dirname","scanAllSessions","appendLogEntry","readFile","resolve","parseStatus","extractFrontmatter","init_parser","resolve","dirname","homedir","writeFile","unlink","handleServerChange","handlePlaybookChange","handleTodoChange","resolve","readFile","extractFrontmatter","formatYamlValue","readFile","resolve","Router","Router","resolve","randomUUID","readFile","resolve","resolve","readdir","readdir","resolve","readFile","db","rows","resolve","readFile","Router","resolve","randomUUID","Router","resolve","readFile","unlink","resolve","readdir","readFile","Router","resolve","readFile","unlink","init_parser","Router","readdir","archivePath","resolve","readFile","writeFileForce","appendLogEntry","dirname","resolve","homedir","writeFile","unlink"]}
|
|
1
|
+
{"version":3,"sources":["../../src/lifecycle/types.ts","../../src/lifecycle/state-machine.ts","../../src/lifecycle/frontmatter.ts","../../src/utils/fs.ts","../../src/utils/timestamp.ts","../../src/lifecycle/transitions.ts","../../src/lifecycle/index.ts","../../src/utils/paths.ts","../../src/templates/config.ts","../../src/utils/config.ts","../../src/dashboard/parser.ts","../../src/dashboard/help.ts","../../src/dashboard/servers.ts","../../src/dashboard/scanner.ts","../../src/dashboard/api.ts","../../src/todos/parser.ts","../../src/dashboard/server.ts","../../src/dashboard/watcher.ts","../../src/dashboard/api-write.ts","../../src/utils/slug.ts","../../src/utils/uuid.ts","../../src/dashboard/acceptance-criteria.ts","../../src/templates/index.ts","../../src/templates/manifest.ts","../../src/utils/yaml.ts","../../src/templates/mission.ts","../../src/templates/agent.ts","../../src/templates/claude.ts","../../src/templates/assignment.ts","../../src/templates/plan.ts","../../src/templates/scratchpad.ts","../../src/templates/handoff.ts","../../src/templates/decision-record.ts","../../src/templates/index-stubs.ts","../../src/templates/playbook.ts","../../src/dashboard/api-servers.ts","../../src/dashboard/api-agent-sessions.ts","../../src/dashboard/agent-sessions.ts","../../src/dashboard/session-db.ts","../../src/dashboard/api-playbooks.ts","../../src/utils/playbooks.ts","../../src/dashboard/api-todos.ts","../../src/dashboard/autodiscovery.ts"],"sourcesContent":["export type AssignmentStatus = string;\n\nexport type TransitionCommand = string;\n\nexport const DEFAULT_STATUSES = [\n 'pending',\n 'in_progress',\n 'blocked',\n 'review',\n 'completed',\n 'failed',\n] as const;\n\nexport const DEFAULT_COMMANDS = [\n 'start',\n 'complete',\n 'block',\n 'unblock',\n 'review',\n 'fail',\n 'reopen',\n 'assign',\n] as const;\n\nexport const DEFAULT_TERMINAL_STATUSES: ReadonlySet<string> = new Set([\n 'completed',\n 'failed',\n]);\n\nexport const TERMINAL_STATUSES: ReadonlySet<string> = DEFAULT_TERMINAL_STATUSES;\n\nexport interface ExternalId {\n system: string;\n id: string;\n url: string;\n}\n\nexport interface Workspace {\n repository: string | null;\n worktreePath: string | null;\n branch: string | null;\n parentBranch: string | null;\n}\n\nexport interface AssignmentFrontmatter {\n id: string;\n slug: string;\n title: string;\n status: AssignmentStatus;\n priority: 'low' | 'medium' | 'high' | 'critical';\n created: string;\n updated: string;\n assignee: string | null;\n externalIds: ExternalId[];\n dependsOn: string[];\n blockedReason: string | null;\n workspace: Workspace;\n tags: string[];\n}\n\nexport interface TransitionResult {\n success: boolean;\n message: string;\n fromStatus: AssignmentStatus;\n toStatus?: AssignmentStatus;\n warnings?: string[];\n}\n","import type { AssignmentStatus, TransitionCommand } from './types.js';\nimport { TERMINAL_STATUSES } from './types.js';\n\n/**\n * Maps a command to its target status. Commands always produce the same\n * target regardless of the current status — workflow enforcement is\n * handled via agent prompting, not code guards.\n */\nexport const DEFAULT_COMMAND_TARGETS = new Map<string, string>([\n ['start', 'in_progress'],\n ['block', 'blocked'],\n ['unblock', 'in_progress'],\n ['review', 'review'],\n ['complete', 'completed'],\n ['fail', 'failed'],\n ['reopen', 'in_progress'],\n]);\n\n/** @deprecated Transition guards removed — kept for API compat, always returns true */\nexport const DEFAULT_TRANSITION_TABLE = new Map<string, string>([\n ['pending:start', 'in_progress'],\n ['pending:block', 'blocked'],\n ['in_progress:block', 'blocked'],\n ['in_progress:review', 'review'],\n ['in_progress:complete', 'completed'],\n ['in_progress:fail', 'failed'],\n ['blocked:unblock', 'in_progress'],\n ['review:start', 'in_progress'],\n ['review:complete', 'completed'],\n ['review:fail', 'failed'],\n ['completed:reopen', 'in_progress'],\n ['failed:reopen', 'in_progress'],\n]);\n\nexport function buildTransitionTable(\n transitions: Array<{ from: string; command: string; to: string }>,\n): Map<string, string> {\n const table = new Map<string, string>();\n for (const t of transitions) {\n table.set(`${t.from}:${t.command}`, t.to);\n }\n return table;\n}\n\nexport function buildCommandTargets(\n transitions: Array<{ from: string; command: string; to: string }>,\n): Map<string, string> {\n const targets = new Map<string, string>();\n for (const t of transitions) {\n targets.set(t.command, t.to);\n }\n return targets;\n}\n\nexport function getTargetStatus(\n _from: AssignmentStatus,\n command: TransitionCommand,\n table?: Map<string, string>,\n): AssignmentStatus | null {\n // Try command-only lookup first, fall back to from:command for backwards compat\n if (!table || table === DEFAULT_TRANSITION_TABLE) {\n return DEFAULT_COMMAND_TARGETS.get(command) ?? null;\n }\n // Custom table: try command-only key first, then from:command\n return table.get(command) ?? table.get(`${_from}:${command}`) ?? null;\n}\n\n/** @deprecated Guards removed — always returns true for known commands */\nexport function canTransition(\n _from: AssignmentStatus,\n command: TransitionCommand,\n table?: Map<string, string>,\n): boolean {\n return getTargetStatus(_from, command, table) !== null;\n}\n\nexport function isTerminalStatus(\n status: AssignmentStatus,\n terminalSet?: ReadonlySet<string>,\n): boolean {\n return (terminalSet ?? TERMINAL_STATUSES).has(status);\n}\n","import type { AssignmentFrontmatter, ExternalId, Workspace } from './types.js';\n\nfunction extractFrontmatter(fileContent: string): [string, string] {\n const match = fileContent.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) {\n throw new Error('No frontmatter found in file. Expected --- delimiters.');\n }\n const frontmatterBlock = match[1];\n const body = fileContent.slice(match[0].length);\n return [frontmatterBlock, body];\n}\n\nfunction parseSimpleValue(raw: string): string | null {\n const trimmed = raw.trim();\n if (trimmed === 'null') return null;\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n return trimmed.slice(1, -1);\n }\n return trimmed;\n}\n\nfunction parseDependsOn(frontmatter: string): string[] {\n const inlineMatch = frontmatter.match(/^dependsOn:\\s*\\[\\s*\\]/m);\n if (inlineMatch) return [];\n\n const results: string[] = [];\n const blockMatch = frontmatter.match(/^dependsOn:\\s*\\n((?:\\s+-\\s+.*\\n?)*)/m);\n if (blockMatch) {\n const items = blockMatch[1].matchAll(/^\\s+-\\s+(.+)$/gm);\n for (const item of items) {\n results.push(item[1].trim());\n }\n }\n return results;\n}\n\nfunction parseExternalIds(frontmatter: string): ExternalId[] {\n const inlineMatch = frontmatter.match(/^externalIds:\\s*\\[\\s*\\]/m);\n if (inlineMatch) return [];\n\n const results: ExternalId[] = [];\n const blockMatch = frontmatter.match(\n /^externalIds:\\s*\\n((?:\\s+-\\s+[\\s\\S]*?)(?=^\\w|\\n---))/m,\n );\n if (!blockMatch) return [];\n\n const itemBlocks = blockMatch[1].split(/\\n\\s+-\\s+/).filter(Boolean);\n for (const block of itemBlocks) {\n const lines = block.split('\\n');\n const entry: Record<string, string> = {};\n for (const line of lines) {\n const colonIdx = line.indexOf(':');\n if (colonIdx < 0) continue;\n const key = line.slice(0, colonIdx).trim().replace(/^-\\s+/, '');\n const value = line.slice(colonIdx + 1).trim();\n if (key && value) {\n entry[key] = value;\n }\n }\n if (entry['system'] && entry['id'] && entry['url']) {\n results.push({\n system: entry['system'],\n id: entry['id'],\n url: entry['url'],\n });\n }\n }\n return results;\n}\n\nfunction parseWorkspace(frontmatter: string): Workspace {\n const defaults: Workspace = {\n repository: null,\n worktreePath: null,\n branch: null,\n parentBranch: null,\n };\n\n const fields = ['repository', 'worktreePath', 'branch', 'parentBranch'] as const;\n for (const field of fields) {\n const match = frontmatter.match(new RegExp(`^\\\\s+${field}:\\\\s*(.*)$`, 'm'));\n if (match) {\n defaults[field] = parseSimpleValue(match[1]);\n }\n }\n return defaults;\n}\n\nfunction parseTags(frontmatter: string): string[] {\n const inlineMatch = frontmatter.match(/^tags:\\s*\\[\\s*\\]/m);\n if (inlineMatch) return [];\n\n const results: string[] = [];\n const blockMatch = frontmatter.match(/^tags:\\s*\\n((?:\\s+-\\s+.*\\n?)*)/m);\n if (blockMatch) {\n const items = blockMatch[1].matchAll(/^\\s+-\\s+(.+)$/gm);\n for (const item of items) {\n results.push(item[1].trim());\n }\n }\n return results;\n}\n\nexport function parseAssignmentFrontmatter(fileContent: string): AssignmentFrontmatter {\n const [frontmatter] = extractFrontmatter(fileContent);\n\n function getField(key: string): string | null {\n const match = frontmatter.match(new RegExp(`^${key}:\\\\s*(.*)$`, 'm'));\n if (!match) return null;\n return parseSimpleValue(match[1]);\n }\n\n return {\n id: getField('id') ?? '',\n slug: getField('slug') ?? '',\n title: getField('title') ?? '',\n status: getField('status') ?? 'pending',\n priority: (getField('priority') ?? 'medium') as AssignmentFrontmatter['priority'],\n created: getField('created') ?? '',\n updated: getField('updated') ?? '',\n assignee: getField('assignee'),\n externalIds: parseExternalIds(frontmatter),\n dependsOn: parseDependsOn(frontmatter),\n blockedReason: getField('blockedReason'),\n workspace: parseWorkspace(frontmatter),\n tags: parseTags(frontmatter),\n };\n}\n\nfunction formatYamlValue(value: string | null): string {\n if (value === null) return 'null';\n if (/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) {\n return `\"${value}\"`;\n }\n // Quote values containing YAML-special characters that could cause parse issues\n if (/[:#{}[\\],&*?|>!%@`]/.test(value) || /^\\s|\\s$/.test(value) || value === '') {\n const escaped = value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n return `\"${escaped}\"`;\n }\n return value;\n}\n\nexport function updateAssignmentFile(\n fileContent: string,\n updates: Partial<Pick<AssignmentFrontmatter, 'status' | 'assignee' | 'blockedReason' | 'updated'>>,\n): string {\n let result = fileContent;\n\n for (const [key, value] of Object.entries(updates)) {\n if (value === undefined) continue;\n const formatted = formatYamlValue(value as string | null);\n const fieldRegex = new RegExp(`^(${key}:)\\\\s*.*$`, 'm');\n if (fieldRegex.test(result)) {\n result = result.replace(fieldRegex, `$1 ${formatted}`);\n }\n }\n\n return result;\n}\n","import { mkdir, writeFile, access, rename } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\n\nexport async function ensureDir(dir: string): Promise<void> {\n await mkdir(dir, { recursive: true });\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function writeFileSafe(\n filePath: string,\n content: string,\n): Promise<boolean> {\n if (await fileExists(filePath)) {\n return false;\n }\n await ensureDir(dirname(filePath));\n await writeFile(filePath, content, 'utf-8');\n return true;\n}\n\nexport async function writeFileForce(\n filePath: string,\n content: string,\n): Promise<void> {\n const dir = dirname(filePath);\n const tempPath = join(\n dir,\n `.${Math.random().toString(36).slice(2)}.${Date.now()}.tmp`,\n );\n await ensureDir(dir);\n await writeFile(tempPath, content, 'utf-8');\n await rename(tempPath, filePath);\n}\n","export function nowTimestamp(): string {\n return new Date().toISOString().replace(/\\.\\d{3}Z$/, 'Z');\n}\n","import { resolve } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport { fileExists, writeFileForce } from '../utils/fs.js';\nimport { nowTimestamp } from '../utils/timestamp.js';\nimport { getTargetStatus } from './state-machine.js';\nimport { parseAssignmentFrontmatter, updateAssignmentFile } from './frontmatter.js';\nimport type { TransitionCommand, TransitionResult, AssignmentFrontmatter } from './types.js';\n\nfunction resolveAssignmentPath(missionDir: string, assignmentSlug: string): string {\n return resolve(missionDir, 'assignments', assignmentSlug, 'assignment.md');\n}\n\nasync function readAssignment(\n filePath: string,\n): Promise<{ content: string; frontmatter: AssignmentFrontmatter }> {\n if (!(await fileExists(filePath))) {\n throw new Error(`Assignment file not found: ${filePath}`);\n }\n const content = await readFile(filePath, 'utf-8');\n const frontmatter = parseAssignmentFrontmatter(content);\n return { content, frontmatter };\n}\n\nasync function checkDependencies(\n missionDir: string,\n dependsOn: string[],\n terminalStatuses?: ReadonlySet<string>,\n): Promise<{ satisfied: boolean; unmet: string[] }> {\n const terminals = terminalStatuses ?? new Set(['completed']);\n const unmet: string[] = [];\n for (const depSlug of dependsOn) {\n const depPath = resolveAssignmentPath(missionDir, depSlug);\n if (!(await fileExists(depPath))) {\n unmet.push(`${depSlug} (file not found)`);\n continue;\n }\n const depContent = await readFile(depPath, 'utf-8');\n const depFrontmatter = parseAssignmentFrontmatter(depContent);\n if (!terminals.has(depFrontmatter.status)) {\n unmet.push(`${depSlug} (status: ${depFrontmatter.status})`);\n }\n }\n return { satisfied: unmet.length === 0, unmet };\n}\n\nexport interface TransitionOptions {\n reason?: string;\n agent?: string;\n transitionTable?: Map<string, string>;\n terminalStatuses?: ReadonlySet<string>;\n}\n\nexport async function executeTransition(\n missionDir: string,\n assignmentSlug: string,\n command: Exclude<TransitionCommand, 'assign'>,\n options: TransitionOptions = {},\n): Promise<TransitionResult> {\n const filePath = resolveAssignmentPath(missionDir, assignmentSlug);\n const { content, frontmatter } = await readAssignment(filePath);\n\n const targetStatus = getTargetStatus(frontmatter.status, command, options.transitionTable);\n\n if (!targetStatus) {\n return {\n success: false,\n message: `Unknown command '${command}' for assignment \"${assignmentSlug}\".`,\n fromStatus: frontmatter.status,\n };\n }\n\n const warnings: string[] = [];\n\n if (command === 'start' && frontmatter.dependsOn.length > 0) {\n const depCheck = await checkDependencies(missionDir, frontmatter.dependsOn, options.terminalStatuses);\n if (!depCheck.satisfied) {\n warnings.push(`Starting with unmet dependencies: ${depCheck.unmet.join(', ')}`);\n }\n }\n\n const updates: Partial<Pick<AssignmentFrontmatter, 'status' | 'assignee' | 'blockedReason' | 'updated'>> = {\n status: targetStatus,\n updated: nowTimestamp(),\n };\n\n if (command === 'start' && options.agent && !frontmatter.assignee) {\n updates.assignee = options.agent;\n }\n if (command === 'block') {\n updates.blockedReason = options.reason ?? null;\n }\n if (command === 'unblock') {\n updates.blockedReason = null;\n }\n\n const updatedContent = updateAssignmentFile(content, updates);\n await writeFileForce(filePath, updatedContent);\n\n return {\n success: true,\n message: `Assignment \"${assignmentSlug}\" transitioned: ${frontmatter.status} -> ${targetStatus}`,\n fromStatus: frontmatter.status,\n toStatus: targetStatus,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\nexport async function executeAssign(\n missionDir: string,\n assignmentSlug: string,\n agent: string,\n): Promise<TransitionResult> {\n const filePath = resolveAssignmentPath(missionDir, assignmentSlug);\n const { content, frontmatter } = await readAssignment(filePath);\n\n const updates: Partial<Pick<AssignmentFrontmatter, 'status' | 'assignee' | 'blockedReason' | 'updated'>> = {\n assignee: agent,\n updated: nowTimestamp(),\n };\n\n const updatedContent = updateAssignmentFile(content, updates);\n await writeFileForce(filePath, updatedContent);\n\n return {\n success: true,\n message: `Assignment \"${assignmentSlug}\" assigned to '${agent}'.`,\n fromStatus: frontmatter.status,\n };\n}\n","export type {\n AssignmentStatus,\n TransitionCommand,\n AssignmentFrontmatter,\n ExternalId,\n Workspace,\n TransitionResult,\n} from './types.js';\nexport { TERMINAL_STATUSES, DEFAULT_STATUSES, DEFAULT_COMMANDS, DEFAULT_TERMINAL_STATUSES } from './types.js';\nexport { canTransition, getTargetStatus, isTerminalStatus, DEFAULT_TRANSITION_TABLE, DEFAULT_COMMAND_TARGETS, buildTransitionTable, buildCommandTargets } from './state-machine.js';\nexport { parseAssignmentFrontmatter, updateAssignmentFile } from './frontmatter.js';\nexport { executeTransition, executeAssign } from './transitions.js';\nexport type { TransitionOptions } from './transitions.js';\n","import { homedir } from 'node:os';\nimport { resolve } from 'node:path';\n\nexport function expandHome(p: string): string {\n if (p.startsWith('~/') || p === '~') {\n return resolve(homedir(), p.slice(2));\n }\n return p;\n}\n\nexport function syntaurRoot(): string {\n return resolve(homedir(), '.syntaur');\n}\n\nexport function defaultMissionDir(): string {\n return resolve(syntaurRoot(), 'missions');\n}\n\nexport function serversDir(): string {\n return resolve(syntaurRoot(), 'servers');\n}\n\nexport function playbooksDir(): string {\n return resolve(syntaurRoot(), 'playbooks');\n}\n\nexport function todosDir(): string {\n return resolve(syntaurRoot(), 'todos');\n}\n","export interface ConfigParams {\n defaultMissionDir: string;\n}\n\nexport function renderConfig(params: ConfigParams): string {\n return `---\nversion: \"1.0\"\ndefaultMissionDir: ${params.defaultMissionDir}\nagentDefaults:\n trustLevel: medium\n autoApprove: false\nsync:\n enabled: false\n endpoint: null\n interval: 300\n---\n\n# Syntaur Configuration\n\nGlobal configuration for the Syntaur CLI.\n`;\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve, isAbsolute } from 'node:path';\nimport { syntaurRoot, defaultMissionDir, expandHome } from './paths.js';\nimport { fileExists, writeFileForce } from './fs.js';\nimport { renderConfig } from '../templates/config.js';\n\nexport interface StatusDefinition {\n id: string;\n label: string;\n description?: string;\n color?: string;\n icon?: string;\n terminal?: boolean;\n}\n\nexport interface StatusTransition {\n from: string;\n command: string;\n to: string;\n label?: string;\n description?: string;\n requiresReason?: boolean;\n}\n\nexport interface StatusConfig {\n statuses: StatusDefinition[];\n order: string[];\n transitions: StatusTransition[];\n}\n\nexport interface IntegrationConfig {\n claudePluginDir: string | null;\n codexPluginDir: string | null;\n codexMarketplacePath: string | null;\n}\n\nexport interface SyntaurConfig {\n version: string;\n defaultMissionDir: string;\n agentDefaults: {\n trustLevel: 'low' | 'medium' | 'high';\n autoApprove: boolean;\n };\n integrations: IntegrationConfig;\n statuses: StatusConfig | null;\n}\n\nconst DEFAULT_CONFIG: SyntaurConfig = {\n version: '1.0',\n defaultMissionDir: defaultMissionDir(),\n agentDefaults: {\n trustLevel: 'medium',\n autoApprove: false,\n },\n integrations: {\n claudePluginDir: null,\n codexPluginDir: null,\n codexMarketplacePath: null,\n },\n statuses: null,\n};\n\nfunction parseFrontmatter(content: string): Record<string, string> {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return {};\n const result: Record<string, string> = {};\n const lines = match[1].split('\\n');\n let currentParent: string | null = null;\n for (const line of lines) {\n if (line.trim() === '') continue;\n const indent = line.length - line.trimStart().length;\n const colonIndex = line.indexOf(':');\n if (colonIndex < 0) continue;\n const key = line.slice(0, colonIndex).trim();\n const value = line.slice(colonIndex + 1).trim();\n if (indent === 0) {\n if (value === '' || value === undefined) {\n currentParent = key;\n } else {\n currentParent = null;\n result[key] = value.replace(/^[\"']|[\"']$/g, '');\n }\n } else if (indent > 0 && currentParent) {\n result[`${currentParent}.${key}`] = value.replace(/^[\"']|[\"']$/g, '');\n }\n }\n return result;\n}\n\nfunction parseStatusConfig(content: string): StatusConfig | null {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return null;\n const fmBlock = match[1];\n\n // Check if there's a top-level statuses: section\n const statusesStart = fmBlock.match(/^statuses:\\s*$/m);\n if (!statusesStart) return null;\n\n // Extract the statuses block (everything indented after \"statuses:\")\n const startIdx = fmBlock.indexOf(statusesStart[0]) + statusesStart[0].length;\n const remaining = fmBlock.slice(startIdx);\n\n const statuses: StatusDefinition[] = [];\n const order: string[] = [];\n const transitions: StatusTransition[] = [];\n\n // Parse sub-sections: definitions, order, transitions\n let currentSection: 'definitions' | 'order' | 'transitions' | null = null;\n const lines = remaining.split('\\n');\n\n function parseListEntry(lineIdx: number, baseIndent: number): { entry: Record<string, string>; consumed: number } {\n const entry: Record<string, string> = {};\n const firstLine = lines[lineIdx].trimStart().slice(2).trim();\n const colonIdx = firstLine.indexOf(':');\n if (colonIdx > 0) {\n entry[firstLine.slice(0, colonIdx).trim()] = firstLine.slice(colonIdx + 1).trim();\n }\n let consumed = 1;\n for (let i = lineIdx + 1; i < lines.length; i++) {\n const next = lines[i];\n const nextTrimmed = next.trimStart();\n const nextIndent = next.length - nextTrimmed.length;\n if (nextIndent <= baseIndent || nextTrimmed.startsWith('- ')) break;\n const ci = nextTrimmed.indexOf(':');\n if (ci > 0) {\n entry[nextTrimmed.slice(0, ci).trim()] = nextTrimmed.slice(ci + 1).trim();\n }\n consumed++;\n }\n return { entry, consumed };\n }\n\n for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n const line = lines[lineIdx];\n const trimmed = line.trimStart();\n const indent = line.length - trimmed.length;\n\n // Top-level key under statuses (indent 2)\n if (indent === 2 && trimmed.endsWith(':')) {\n const key = trimmed.slice(0, -1).trim();\n if (key === 'definitions') currentSection = 'definitions';\n else if (key === 'order') currentSection = 'order';\n else if (key === 'transitions') currentSection = 'transitions';\n else currentSection = null;\n continue;\n }\n\n // Stop if we hit a new top-level key (no indent)\n if (indent === 0 && trimmed.includes(':')) break;\n\n if (currentSection === 'order' && indent >= 4 && trimmed.startsWith('- ')) {\n order.push(trimmed.slice(2).trim());\n continue;\n }\n\n if (currentSection === 'definitions' && indent >= 4 && trimmed.startsWith('- ')) {\n const { entry, consumed } = parseListEntry(lineIdx, indent);\n if (entry['id']) {\n statuses.push({\n id: entry['id'],\n label: entry['label'] ?? entry['id'],\n description: entry['description'],\n color: entry['color'],\n icon: entry['icon'],\n terminal: entry['terminal'] === 'true',\n });\n }\n lineIdx += consumed - 1; // skip consumed continuation lines\n continue;\n }\n\n if (currentSection === 'transitions' && indent >= 4 && trimmed.startsWith('- ')) {\n const { entry, consumed } = parseListEntry(lineIdx, indent);\n if (entry['from'] && entry['command'] && entry['to']) {\n transitions.push({\n from: entry['from'],\n command: entry['command'],\n to: entry['to'],\n label: entry['label'],\n description: entry['description'],\n requiresReason: entry['requiresReason'] === 'true',\n });\n }\n lineIdx += consumed - 1;\n continue;\n }\n }\n\n if (statuses.length === 0) return null;\n\n return {\n statuses,\n order: order.length > 0 ? order : statuses.map((s) => s.id),\n transitions,\n };\n}\n\nfunction serializeStatusConfig(statuses: StatusConfig): string {\n const lines: string[] = [];\n lines.push('statuses:');\n\n // definitions\n lines.push(' definitions:');\n for (const s of statuses.statuses) {\n lines.push(` - id: ${s.id}`);\n lines.push(` label: ${s.label}`);\n if (s.description) lines.push(` description: ${s.description}`);\n if (s.color) lines.push(` color: ${s.color}`);\n if (s.icon) lines.push(` icon: ${s.icon}`);\n if (s.terminal) lines.push(` terminal: true`);\n }\n\n // order\n lines.push(' order:');\n for (const id of statuses.order) {\n lines.push(` - ${id}`);\n }\n\n // transitions\n if (statuses.transitions.length > 0) {\n lines.push(' transitions:');\n for (const t of statuses.transitions) {\n lines.push(` - from: ${t.from}`);\n lines.push(` command: ${t.command}`);\n lines.push(` to: ${t.to}`);\n if (t.label) lines.push(` label: ${t.label}`);\n if (t.description) lines.push(` description: ${t.description}`);\n if (t.requiresReason) lines.push(` requiresReason: true`);\n }\n }\n\n return lines.join('\\n');\n}\n\nfunction serializeIntegrationConfig(integrations: IntegrationConfig): string | null {\n const lines: string[] = [];\n\n if (integrations.claudePluginDir) {\n lines.push(` claudePluginDir: ${integrations.claudePluginDir}`);\n }\n if (integrations.codexPluginDir) {\n lines.push(` codexPluginDir: ${integrations.codexPluginDir}`);\n }\n if (integrations.codexMarketplacePath) {\n lines.push(` codexMarketplacePath: ${integrations.codexMarketplacePath}`);\n }\n\n if (lines.length === 0) {\n return null;\n }\n\n return ['integrations:', ...lines].join('\\n');\n}\n\nfunction stripTopLevelBlock(fmBlock: string, key: string): string {\n const blockStart = fmBlock.match(new RegExp(`^${key}:\\\\s*$`, 'm'));\n if (!blockStart) {\n return fmBlock.replace(/\\n+$/, '');\n }\n\n const startIdx = fmBlock.indexOf(blockStart[0]);\n const before = fmBlock.slice(0, startIdx);\n const after = fmBlock.slice(startIdx + blockStart[0].length);\n const remaining = after.split('\\n');\n let endIdx = 0;\n\n for (let i = 0; i < remaining.length; i++) {\n const line = remaining[i];\n if (line.trim() === '') {\n endIdx = i + 1;\n continue;\n }\n if (line.length > 0 && line[0] !== ' ') {\n break;\n }\n endIdx = i + 1;\n }\n\n return (before + remaining.slice(endIdx).join('\\n')).replace(/\\n+$/, '');\n}\n\nfunction parseOptionalAbsolutePath(\n value: string | undefined,\n fieldName: string,\n): string | null {\n if (!value) {\n return null;\n }\n\n const expanded = expandHome(String(value));\n if (!isAbsolute(expanded)) {\n console.warn(\n `Warning: config.md ${fieldName} is not an absolute path (\"${value}\"), ignoring it`,\n );\n return null;\n }\n\n return resolve(expanded);\n}\n\nexport async function writeStatusConfig(statuses: StatusConfig): Promise<void> {\n const configPath = resolve(syntaurRoot(), 'config.md');\n const statusBlock = serializeStatusConfig(statuses);\n\n if (!(await fileExists(configPath))) {\n // Create new config file with defaults + statuses\n const content = `---\\nversion: \"1.0\"\\ndefaultMissionDir: ~/missions\\n${statusBlock}\\n---\\n`;\n await writeFileForce(configPath, content);\n return;\n }\n\n const existing = await readFile(configPath, 'utf-8');\n const fmMatch = existing.match(/^(---\\n)([\\s\\S]*?)\\n(---)/);\n if (!fmMatch) {\n // No frontmatter — wrap in new frontmatter\n const content = `---\\nversion: \"1.0\"\\n${statusBlock}\\n---\\n${existing}`;\n await writeFileForce(configPath, content);\n return;\n }\n\n const fmBlock = fmMatch[2];\n const afterFrontmatter = existing.slice(fmMatch[0].length);\n\n // Remove existing statuses: block from frontmatter\n const statusesStart = fmBlock.match(/^statuses:\\s*$/m);\n let cleanedFm: string;\n if (statusesStart) {\n const startIdx = fmBlock.indexOf(statusesStart[0]);\n const before = fmBlock.slice(0, startIdx);\n const after = fmBlock.slice(startIdx + statusesStart[0].length);\n // Skip all indented lines (belonging to statuses block)\n const remaining = after.split('\\n');\n let endIdx = 0;\n for (let i = 0; i < remaining.length; i++) {\n const line = remaining[i];\n if (line.trim() === '') { endIdx = i + 1; continue; }\n if (line.length > 0 && line[0] !== ' ') break;\n endIdx = i + 1;\n }\n cleanedFm = before + remaining.slice(endIdx).join('\\n');\n } else {\n cleanedFm = fmBlock;\n }\n\n // Trim trailing whitespace/newlines from cleaned frontmatter\n cleanedFm = cleanedFm.replace(/\\n+$/, '');\n\n const newContent = `---\\n${cleanedFm}\\n${statusBlock}\\n---${afterFrontmatter}`;\n await writeFileForce(configPath, newContent);\n}\n\nexport async function deleteStatusConfig(): Promise<void> {\n const configPath = resolve(syntaurRoot(), 'config.md');\n if (!(await fileExists(configPath))) return;\n\n const existing = await readFile(configPath, 'utf-8');\n const fmMatch = existing.match(/^(---\\n)([\\s\\S]*?)\\n(---)/);\n if (!fmMatch) return;\n\n const fmBlock = fmMatch[2];\n const afterFrontmatter = existing.slice(fmMatch[0].length);\n const cleanedFm = stripTopLevelBlock(fmBlock, 'statuses');\n\n const newContent = `---\\n${cleanedFm}\\n---${afterFrontmatter}`;\n await writeFileForce(configPath, newContent);\n}\n\nexport async function updateIntegrationConfig(\n integrations: Partial<IntegrationConfig>,\n): Promise<void> {\n const configPath = resolve(syntaurRoot(), 'config.md');\n const nextIntegrations: IntegrationConfig = {\n ...(await readConfig()).integrations,\n ...integrations,\n };\n\n const integrationBlock = serializeIntegrationConfig(nextIntegrations);\n const existing = await fileExists(configPath)\n ? await readFile(configPath, 'utf-8')\n : renderConfig({ defaultMissionDir: defaultMissionDir() });\n\n const fmMatch = existing.match(/^(---\\n)([\\s\\S]*?)\\n(---)/);\n if (!fmMatch) {\n const content = `---\\nversion: \"1.0\"\\ndefaultMissionDir: ${defaultMissionDir()}\\n${integrationBlock ?? ''}\\n---\\n${existing}`;\n await writeFileForce(configPath, content.replace(/\\n\\n---/, '\\n---'));\n return;\n }\n\n const fmBlock = fmMatch[2];\n const afterFrontmatter = existing.slice(fmMatch[0].length);\n const cleanedFm = stripTopLevelBlock(fmBlock, 'integrations');\n const newFm = integrationBlock\n ? `${cleanedFm}\\n${integrationBlock}`.replace(/^\\n+/, '')\n : cleanedFm;\n const normalizedFm = newFm.replace(/\\n+$/, '');\n const newContent = `---\\n${normalizedFm}\\n---${afterFrontmatter}`;\n await writeFileForce(configPath, newContent);\n}\n\nexport async function readConfig(): Promise<SyntaurConfig> {\n const configPath = resolve(syntaurRoot(), 'config.md');\n if (!(await fileExists(configPath))) {\n return { ...DEFAULT_CONFIG };\n }\n const content = await readFile(configPath, 'utf-8');\n const fm = parseFrontmatter(content);\n\n if (Object.keys(fm).length === 0) {\n console.warn('Warning: ~/.syntaur/config.md has malformed frontmatter, using defaults');\n return { ...DEFAULT_CONFIG };\n }\n\n let missionDir = fm['defaultMissionDir']\n ? expandHome(String(fm['defaultMissionDir']))\n : DEFAULT_CONFIG.defaultMissionDir;\n if (!isAbsolute(missionDir)) {\n console.warn(\n `Warning: config.md defaultMissionDir is not an absolute path (\"${fm['defaultMissionDir']}\"), using default`,\n );\n missionDir = DEFAULT_CONFIG.defaultMissionDir;\n }\n\n return {\n version: fm['version'] || DEFAULT_CONFIG.version,\n defaultMissionDir: missionDir,\n agentDefaults: {\n trustLevel:\n (fm['agentDefaults.trustLevel'] as SyntaurConfig['agentDefaults']['trustLevel']) ||\n DEFAULT_CONFIG.agentDefaults.trustLevel,\n autoApprove:\n fm['agentDefaults.autoApprove'] === 'true' ||\n DEFAULT_CONFIG.agentDefaults.autoApprove,\n },\n integrations: {\n claudePluginDir: parseOptionalAbsolutePath(\n fm['integrations.claudePluginDir'],\n 'integrations.claudePluginDir',\n ),\n codexPluginDir: parseOptionalAbsolutePath(\n fm['integrations.codexPluginDir'],\n 'integrations.codexPluginDir',\n ),\n codexMarketplacePath: parseOptionalAbsolutePath(\n fm['integrations.codexMarketplacePath'],\n 'integrations.codexMarketplacePath',\n ),\n },\n statuses: parseStatusConfig(content),\n };\n}\n","/**\n * Generic frontmatter/markdown parser for all Syntaur file types.\n * Pattern copied from src/lifecycle/frontmatter.ts:3-23 (extractFrontmatter + parseSimpleValue).\n */\n\nexport interface ParsedFile {\n frontmatter: Record<string, string>;\n body: string;\n}\n\n/**\n * Split a markdown file into its frontmatter block and body.\n */\nexport function extractFrontmatter(fileContent: string): [string, string] {\n const match = fileContent.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) {\n return ['', fileContent];\n }\n const frontmatterBlock = match[1];\n const body = fileContent.slice(match[0].length).trim();\n return [frontmatterBlock, body];\n}\n\n/**\n * Parse a simple YAML value, handling null and quoted strings.\n */\nfunction parseSimpleValue(raw: string): string | null {\n const trimmed = raw.trim();\n if (trimmed === 'null' || trimmed === '') return null;\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n return trimmed.slice(1, -1);\n }\n return trimmed;\n}\n\n/**\n * Extract a top-level scalar field from frontmatter text.\n */\nexport function getField(frontmatter: string, key: string): string | null {\n const match = frontmatter.match(new RegExp(`^${key}:\\\\s*(.*)$`, 'm'));\n if (!match) return null;\n return parseSimpleValue(match[1]);\n}\n\n/**\n * Extract an indented scalar field (one level deep) from frontmatter text.\n */\nexport function getNestedField(frontmatter: string, parent: string, key: string): string | null {\n const parentRegex = new RegExp(`^${parent}:\\\\s*\\\\n((?:\\\\s+.*\\\\n?)*)`, 'm');\n const parentMatch = frontmatter.match(parentRegex);\n if (!parentMatch) return null;\n const block = parentMatch[1];\n const fieldMatch = block.match(new RegExp(`^\\\\s+${key}:\\\\s*(.*)$`, 'm'));\n if (!fieldMatch) return null;\n return parseSimpleValue(fieldMatch[1]);\n}\n\n/**\n * Parse a YAML list field (e.g., tags, dependsOn, relatedAssignments).\n */\nfunction parseListField(frontmatter: string, fieldName: string): string[] {\n const inlineMatch = frontmatter.match(new RegExp(`^${fieldName}:\\\\s*\\\\[\\\\s*\\\\]`, 'm'));\n if (inlineMatch) return [];\n\n const results: string[] = [];\n const blockMatch = frontmatter.match(\n new RegExp(`^${fieldName}:\\\\s*\\\\n((?:\\\\s+-\\\\s+.*\\\\n?)*)`, 'm'),\n );\n if (blockMatch) {\n let item: RegExpExecArray | null;\n const regex = /^\\s+-\\s+(.+)$/gm;\n while ((item = regex.exec(blockMatch[1])) !== null) {\n results.push(item[1].trim());\n }\n }\n return results;\n}\n\n// --- Mission Parser ---\n\nexport interface ParsedMission {\n id: string;\n slug: string;\n title: string;\n archived: boolean;\n archivedAt: string | null;\n archivedReason: string | null;\n statusOverride: string | null;\n created: string;\n updated: string;\n tags: string[];\n workspace: string | null;\n body: string;\n}\n\nexport function parseMission(fileContent: string): ParsedMission {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n id: getField(fm, 'id') ?? '',\n slug: getField(fm, 'slug') ?? '',\n title: getField(fm, 'title') ?? '',\n archived: getField(fm, 'archived') === 'true',\n archivedAt: getField(fm, 'archivedAt'),\n archivedReason: getField(fm, 'archivedReason'),\n statusOverride: getField(fm, 'statusOverride'),\n created: getField(fm, 'created') ?? '',\n updated: getField(fm, 'updated') ?? '',\n tags: parseListField(fm, 'tags'),\n workspace: getField(fm, 'workspace'),\n body,\n };\n}\n\n// --- Status Parser (for _status.md) ---\n\nexport interface ParsedStatus {\n mission: string;\n status: string;\n progress: Record<string, number> & { total: number };\n needsAttention: {\n blockedCount: number;\n failedCount: number;\n unansweredQuestions: number;\n };\n body: string;\n}\n\nexport function parseStatus(fileContent: string): ParsedStatus {\n const [fm, body] = extractFrontmatter(fileContent);\n\n // Dynamically parse progress fields\n const progress: Record<string, number> & { total: number } = { total: 0 };\n const progressMatch = fm.match(/^progress:\\s*\\n((?:\\s+.*\\n?)*)/m);\n if (progressMatch) {\n const lines = progressMatch[1].split('\\n');\n for (const line of lines) {\n const kv = line.match(/^\\s+(\\w+):\\s*(\\d+)/);\n if (kv) {\n progress[kv[1]] = parseInt(kv[2], 10);\n }\n }\n }\n\n return {\n mission: getField(fm, 'mission') ?? '',\n status: getField(fm, 'status') ?? 'pending',\n progress,\n needsAttention: {\n blockedCount: parseInt(getNestedField(fm, 'needsAttention', 'blockedCount') ?? '0', 10),\n failedCount: parseInt(getNestedField(fm, 'needsAttention', 'failedCount') ?? '0', 10),\n unansweredQuestions: parseInt(getNestedField(fm, 'needsAttention', 'unansweredQuestions') ?? '0', 10),\n },\n body,\n };\n}\n\n// --- Assignment Summary Parser ---\n\nexport interface ParsedAssignmentSummary {\n id: string;\n slug: string;\n title: string;\n status: string;\n priority: string;\n assignee: string | null;\n dependsOn: string[];\n updated: string;\n}\n\nexport function parseAssignmentSummary(fileContent: string): ParsedAssignmentSummary {\n const [fm] = extractFrontmatter(fileContent);\n return {\n id: getField(fm, 'id') ?? '',\n slug: getField(fm, 'slug') ?? '',\n title: getField(fm, 'title') ?? '',\n status: getField(fm, 'status') ?? 'pending',\n priority: getField(fm, 'priority') ?? 'medium',\n assignee: getField(fm, 'assignee'),\n dependsOn: parseListField(fm, 'dependsOn'),\n updated: getField(fm, 'updated') ?? '',\n };\n}\n\n// --- Full Assignment Parser ---\n\nexport interface ParsedAssignmentFull {\n id: string;\n slug: string;\n title: string;\n status: string;\n priority: string;\n assignee: string | null;\n dependsOn: string[];\n blockedReason: string | null;\n workspace: {\n repository: string | null;\n worktreePath: string | null;\n branch: string | null;\n parentBranch: string | null;\n };\n externalIds: Array<{ system: string; id: string; url: string }>;\n tags: string[];\n created: string;\n updated: string;\n body: string;\n}\n\nfunction parseExternalIds(frontmatter: string): Array<{ system: string; id: string; url: string }> {\n const inlineMatch = frontmatter.match(/^externalIds:\\s*\\[\\s*\\]/m);\n if (inlineMatch) return [];\n\n const results: Array<{ system: string; id: string; url: string }> = [];\n const blockMatch = frontmatter.match(\n /^externalIds:\\s*\\n((?:\\s+-\\s+[\\s\\S]*?)(?=^\\w|\\n---))/m,\n );\n if (!blockMatch) return [];\n\n const itemBlocks = blockMatch[1].split(/\\n\\s+-\\s+/).filter(Boolean);\n for (const block of itemBlocks) {\n const lines = block.split('\\n');\n const entry: Record<string, string> = {};\n for (const line of lines) {\n const colonIdx = line.indexOf(':');\n if (colonIdx < 0) continue;\n const key = line.slice(0, colonIdx).trim().replace(/^-\\s+/, '');\n const value = line.slice(colonIdx + 1).trim();\n if (key && value) {\n entry[key] = value;\n }\n }\n if (entry['system'] && entry['id'] && entry['url']) {\n results.push({\n system: entry['system'],\n id: entry['id'],\n url: entry['url'],\n });\n }\n }\n return results;\n}\n\nexport function parseAssignmentFull(fileContent: string): ParsedAssignmentFull {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n id: getField(fm, 'id') ?? '',\n slug: getField(fm, 'slug') ?? '',\n title: getField(fm, 'title') ?? '',\n status: getField(fm, 'status') ?? 'pending',\n priority: getField(fm, 'priority') ?? 'medium',\n assignee: getField(fm, 'assignee'),\n dependsOn: parseListField(fm, 'dependsOn'),\n blockedReason: getField(fm, 'blockedReason'),\n workspace: {\n repository: getNestedField(fm, 'workspace', 'repository'),\n worktreePath: getNestedField(fm, 'workspace', 'worktreePath'),\n branch: getNestedField(fm, 'workspace', 'branch'),\n parentBranch: getNestedField(fm, 'workspace', 'parentBranch'),\n },\n externalIds: parseExternalIds(fm),\n tags: parseListField(fm, 'tags'),\n created: getField(fm, 'created') ?? '',\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Plan Parser ---\n\nexport interface ParsedPlan {\n assignment: string;\n status: string;\n created: string;\n updated: string;\n body: string;\n}\n\nexport function parsePlan(fileContent: string): ParsedPlan {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n assignment: getField(fm, 'assignment') ?? '',\n status: getField(fm, 'status') ?? '',\n created: getField(fm, 'created') ?? '',\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Scratchpad Parser ---\n\nexport interface ParsedScratchpad {\n assignment: string;\n updated: string;\n body: string;\n}\n\nexport function parseScratchpad(fileContent: string): ParsedScratchpad {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n assignment: getField(fm, 'assignment') ?? '',\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Handoff Parser ---\n\nexport interface ParsedHandoff {\n assignment: string;\n handoffCount: number;\n updated: string;\n body: string;\n}\n\nexport function parseHandoff(fileContent: string): ParsedHandoff {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n assignment: getField(fm, 'assignment') ?? '',\n handoffCount: parseInt(getField(fm, 'handoffCount') ?? '0', 10),\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Decision Record Parser ---\n\nexport interface ParsedDecisionRecord {\n assignment: string;\n decisionCount: number;\n updated: string;\n body: string;\n}\n\nexport function parseDecisionRecord(fileContent: string): ParsedDecisionRecord {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n assignment: getField(fm, 'assignment') ?? '',\n decisionCount: parseInt(getField(fm, 'decisionCount') ?? '0', 10),\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Resource Parser ---\n\nexport interface ParsedResource {\n name: string;\n source: string;\n category: string;\n relatedAssignments: string[];\n created: string;\n updated: string;\n body: string;\n}\n\nexport function parseResource(fileContent: string): ParsedResource {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n name: getField(fm, 'name') ?? '',\n source: getField(fm, 'source') ?? '',\n category: getField(fm, 'category') ?? '',\n relatedAssignments: parseListField(fm, 'relatedAssignments'),\n created: getField(fm, 'created') ?? '',\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Memory Parser ---\n\nexport interface ParsedMemory {\n name: string;\n source: string;\n scope: string;\n sourceAssignment: string | null;\n relatedAssignments: string[];\n created: string;\n updated: string;\n body: string;\n}\n\nexport function parseMemory(fileContent: string): ParsedMemory {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n name: getField(fm, 'name') ?? '',\n source: getField(fm, 'source') ?? '',\n scope: getField(fm, 'scope') ?? '',\n sourceAssignment: getField(fm, 'sourceAssignment'),\n relatedAssignments: parseListField(fm, 'relatedAssignments'),\n created: getField(fm, 'created') ?? '',\n updated: getField(fm, 'updated') ?? '',\n body,\n };\n}\n\n// --- Playbook Parser ---\n\nexport interface ParsedPlaybook {\n slug: string;\n name: string;\n description: string;\n whenToUse: string;\n created: string;\n updated: string;\n tags: string[];\n body: string;\n}\n\nexport function parsePlaybook(fileContent: string): ParsedPlaybook {\n const [fm, body] = extractFrontmatter(fileContent);\n return {\n slug: getField(fm, 'slug') ?? '',\n name: getField(fm, 'name') ?? '',\n description: getField(fm, 'description') ?? '',\n whenToUse: getField(fm, 'when_to_use') ?? '',\n created: getField(fm, 'created') ?? '',\n updated: getField(fm, 'updated') ?? '',\n tags: parseListField(fm, 'tags'),\n body,\n };\n}\n\n// --- Mermaid Graph Extractor ---\n\n/**\n * Extract the mermaid code block from _status.md body content.\n * Returns null if no mermaid block is found.\n */\nexport function extractMermaidGraph(body: string): string | null {\n const match = body.match(/```mermaid\\n([\\s\\S]*?)```/);\n return match ? match[1].trim() : null;\n}\n","import type {\n HelpChecklistItem,\n HelpCommand,\n HelpResponse,\n HelpStatusGuideEntry,\n} from './types.js';\nimport { getStatusConfig } from './api.js';\n\nconst CLI_COMMANDS: HelpCommand[] = [\n // --- Core setup & scaffolding (indices 0-4) ---\n {\n command: 'syntaur setup',\n description: 'Initialize Syntaur and optionally install plugins or launch the dashboard.',\n example: 'syntaur setup',\n },\n {\n command: 'syntaur init',\n description: 'Initialize the local Syntaur home directory and config scaffolding without any prompts.',\n example: 'syntaur init',\n },\n {\n command: 'syntaur create-mission',\n description: 'Create a new mission folder with the required source and derived files.',\n example: 'syntaur create-mission \"Ship dashboard overhaul\"',\n },\n {\n command: 'syntaur create-assignment',\n description: 'Create a new assignment inside a mission.',\n example: 'syntaur create-assignment \"Implement overview API\" --mission ui-overhaul',\n },\n {\n command: 'syntaur assign',\n description: 'Set the assignee for an assignment before work begins.',\n example: 'syntaur assign implement-overview --mission ui-overhaul --agent codex-1',\n },\n\n // --- Lifecycle transitions (indices 5-11) ---\n {\n command: 'syntaur start',\n description: 'Transition an assignment to in_progress.',\n example: 'syntaur start implement-overview --mission ui-overhaul',\n },\n {\n command: 'syntaur review',\n description: 'Move active work into review once implementation is ready for inspection.',\n example: 'syntaur review implement-overview --mission ui-overhaul',\n },\n {\n command: 'syntaur complete',\n description: 'Mark an assignment completed after review or direct completion.',\n example: 'syntaur complete implement-overview --mission ui-overhaul',\n },\n {\n command: 'syntaur block',\n description: 'Mark an assignment blocked and record the explicit reason.',\n example: 'syntaur block implement-overview --mission ui-overhaul --reason \"Waiting on API spec\"',\n },\n {\n command: 'syntaur unblock',\n description: 'Move a blocked assignment back to in_progress after the blocker is cleared.',\n example: 'syntaur unblock implement-overview --mission ui-overhaul',\n },\n {\n command: 'syntaur fail',\n description: 'Mark an assignment failed when it cannot be completed as planned.',\n example: 'syntaur fail implement-overview --mission ui-overhaul',\n },\n {\n command: 'syntaur reopen',\n description: 'Reopen a completed or failed assignment back to in_progress.',\n example: 'syntaur reopen implement-overview --mission ui-overhaul',\n },\n\n // --- Dashboard (index 12) ---\n {\n command: 'syntaur dashboard',\n description: 'Start the local dashboard UI over the mission files on disk.',\n example: 'syntaur dashboard --port 4800',\n },\n\n // --- Plugin & adapter setup (indices 13-16) ---\n {\n command: 'syntaur install-plugin',\n description: 'Install the Syntaur Claude Code plugin, detecting the local Claude marketplace when available and prompting for the target directory when interactive.',\n example: 'syntaur install-plugin --target-dir ~/.claude/plugins/marketplaces/user-plugins/plugins/syntaur',\n },\n {\n command: 'syntaur install-codex-plugin',\n description: 'Install the Syntaur Codex plugin and register its marketplace entry, prompting for both paths when interactive.',\n example: 'syntaur install-codex-plugin --target-dir ~/plugins/syntaur --marketplace-path ~/.agents/plugins/marketplace.json',\n },\n {\n command: 'syntaur uninstall',\n description: 'Remove Syntaur plugins and optionally local ~/.syntaur data.',\n example: 'syntaur uninstall --all',\n },\n {\n command: 'syntaur setup-adapter',\n description: 'Generate adapter instruction files for cursor, codex, or opencode in the current directory.',\n example: 'syntaur setup-adapter cursor --mission ui-overhaul --assignment implement-overview',\n },\n\n // --- Session & server tracking (index 17) ---\n {\n command: 'syntaur track-session',\n description: 'Register an agent session, optionally linked to a mission and assignment.',\n example: 'syntaur track-session --agent claude --mission ui-overhaul --assignment implement-overview',\n },\n\n // --- Browsing & playbooks (indices 18-20) ---\n {\n command: 'syntaur browse',\n description: 'Interactive TUI browser for missions and assignments.',\n example: 'syntaur browse',\n },\n {\n command: 'syntaur create-playbook',\n description: 'Create a new playbook with behavioral rules for agents.',\n example: 'syntaur create-playbook \"Code Review Standards\"',\n },\n {\n command: 'syntaur list-playbooks',\n description: 'List all playbooks in the Syntaur home directory.',\n example: 'syntaur list-playbooks',\n },\n];\n\nconst WORKFLOW: HelpChecklistItem[] = [\n {\n title: 'Initialize the workspace',\n detail: 'Run setup once so Syntaur can initialize its local home directory and offer plugin installation.',\n command: CLI_COMMANDS[0],\n },\n {\n title: 'Create a mission',\n detail: 'Use a mission for a higher-level objective. Missions group assignments, shared resources, and memories.',\n command: CLI_COMMANDS[2],\n href: '/create/mission',\n },\n {\n title: 'Create the first assignment',\n detail: 'Assignments are the execution unit. Create one for each concrete chunk of work inside the mission.',\n command: CLI_COMMANDS[3],\n },\n {\n title: 'Assign the work',\n detail: 'Setting an assignee before starting is recommended for clarity, but not required.',\n command: CLI_COMMANDS[4],\n },\n {\n title: 'Start, review, complete, or block through lifecycle actions',\n detail: 'Status changes happen through lifecycle actions, kanban drag-and-drop, or the status override controls.',\n command: CLI_COMMANDS[5],\n },\n {\n title: 'Use the dashboard for triage and context',\n detail: 'Overview shows the current queue, mission pages show health, assignment pages show the execution surface.',\n command: CLI_COMMANDS[12],\n href: '/',\n },\n];\n\nconst DEFAULT_STATUS_GUIDE: Record<string, { meaning: string; useWhen: string }> = {\n pending: {\n meaning: 'The assignment has not started yet.',\n useWhen: 'Use pending while waiting to start. If dependencies are unmet, pending is the normal waiting state.',\n },\n in_progress: {\n meaning: 'An assigned agent is actively working the assignment.',\n useWhen: 'Use in_progress once the work has started and dependencies are satisfied.',\n },\n blocked: {\n meaning: 'The assignment hit a manual or runtime obstacle.',\n useWhen: 'Use blocked when work hits an obstacle. Adding a blockedReason is recommended for traceability.',\n },\n review: {\n meaning: 'Implementation is ready for inspection or validation.',\n useWhen: 'Use review after active work is ready to be checked before completion.',\n },\n completed: {\n meaning: 'The assignment is done.',\n useWhen: 'Use completed when the acceptance criteria are satisfied.',\n },\n failed: {\n meaning: 'The assignment could not be completed as planned.',\n useWhen: 'Use failed when the work cannot be recovered within the current assignment.',\n },\n};\n\nasync function buildStatusGuide(): Promise<HelpStatusGuideEntry[]> {\n const config = await getStatusConfig();\n\n return config.statuses.map((s) => {\n const defaults = DEFAULT_STATUS_GUIDE[s.id];\n return {\n status: s.id,\n meaning: s.description ?? defaults?.meaning ?? `The assignment is in the \"${s.label}\" state.`,\n useWhen: defaults?.useWhen ?? `Use ${s.id} when appropriate for the \"${s.label}\" workflow state.`,\n };\n });\n}\n\nexport async function getDashboardHelp(): Promise<HelpResponse> {\n return {\n generatedAt: new Date().toISOString(),\n whatIsSyntaur: {\n summary:\n 'Syntaur is a local-first, markdown-backed agent work system. The dashboard is a live view over mission folders and files on disk.',\n bullets: [\n 'Markdown files are the source of truth.',\n 'The UI reads mission folders, assignment files, and derived indexes from the local filesystem.',\n 'Derived underscore-prefixed files are projections, not the canonical edit target.',\n ],\n },\n coreConcepts: [\n {\n term: 'Mission',\n description:\n 'A mission is the higher-level objective. It owns assignments, shared resources, and mission memories.',\n },\n {\n term: 'Assignment',\n description:\n 'An assignment is a concrete unit of execution. Assignment frontmatter is the source of truth for status, priority, assignee, and dependencies.',\n },\n {\n term: 'Resource',\n description:\n 'A mission-level shared reference file that provides source material or constraints for the work.',\n },\n {\n term: 'Memory',\n description:\n 'A mission-level learning or pattern captured during execution so future assignments can reuse it.',\n },\n {\n term: 'Manifest',\n description:\n 'A derived navigation file that points agents at the mission overview, indexes, and agent instructions.',\n },\n {\n term: 'Derived file',\n description:\n 'An underscore-prefixed file regenerated from canonical markdown sources. Read it, but do not edit it directly.',\n },\n {\n term: 'Handoff',\n description:\n 'An append-only log that records baton-passes between agents or sessions without rewriting prior history.',\n },\n {\n term: 'Decision record',\n description:\n 'An append-only record of important decisions, rationale, and follow-up consequences.',\n },\n {\n term: 'Playbook',\n description:\n 'A behavioral rule set stored in ~/.syntaur/playbooks/. Playbooks define constraints and conventions that agents must follow during execution. Manage them via the CLI or the Playbooks page.',\n },\n {\n term: 'Workspace',\n description:\n 'The repository context for an assignment, including the repository path, worktree path, branch, and parent branch. Workspace fields connect an assignment to the code being worked on and define write boundaries.',\n },\n {\n term: 'Agent Session',\n description:\n 'A tracked AI session tied to assignment work. Sessions are registered via the track-session CLI command or the Claude Code plugin and visible on the Agent Sessions page.',\n },\n {\n term: 'Server',\n description:\n 'A tracked tmux session with automatic port discovery, branch detection, and assignment linking. The Servers page shows all tracked sessions with their windows, panes, and discovered services.',\n },\n ],\n workflow: WORKFLOW,\n statusGuide: await buildStatusGuide(),\n ownershipRules: [\n {\n label: 'Human-authored files',\n files: ['mission.md', 'agent.md', 'claude.md'],\n description:\n 'These files define mission intent and instructions. The dashboard treats mission status as derived except for the archive fields.',\n },\n {\n label: 'Assignment working files',\n files: ['assignment.md', 'plan.md', 'scratchpad.md'],\n description:\n 'These are agent-writable files. The dashboard lets you edit the source markdown while preserving unsupported frontmatter keys.',\n },\n {\n label: 'Append-only logs',\n files: ['handoff.md', 'decision-record.md'],\n description:\n 'These logs preserve history. The dashboard appends new entries instead of rewriting previous ones.',\n },\n {\n label: 'Derived files',\n files: ['_status.md', '_index-assignments.md', '_index-plans.md', '_index-decisions.md'],\n description:\n 'These files are read-only projections. They can lag behind source files, so the dashboard computes source-first state.',\n },\n ],\n commands: CLI_COMMANDS,\n navigation: [\n {\n label: 'Overview',\n description: 'Triage hub showing current attention items, recent activity, progress stats, and first-run setup guidance.',\n href: '/',\n },\n {\n label: 'Missions',\n description: 'Browse, search, filter, and sort the mission directory. Create new missions and drill into mission workspaces.',\n href: '/missions',\n },\n {\n label: 'Assignments',\n description: 'Cross-mission kanban board of all assignments. Drag cards between columns to change status, or filter by mission, assignee, or status.',\n href: '/assignments',\n },\n {\n label: 'Servers',\n description: 'Tracked tmux sessions with auto-discovered ports, URLs, git branches, and links to related assignments. Register sessions manually or let autodiscovery find them.',\n href: '/servers',\n },\n {\n label: 'Agent Sessions',\n description: 'Monitor which AI agents are currently working, what assignments they are linked to, and session duration. Sessions are registered via the Claude Code plugin or track-session CLI command.',\n href: '/agent-sessions',\n },\n {\n label: 'Playbooks',\n description: 'Create, browse, and edit behavioral rules that agents must follow. The playbook manifest at ~/.syntaur/playbooks/manifest.md is auto-generated for inclusion in agent instructions.',\n href: '/playbooks',\n },\n {\n label: 'Attention',\n description: 'Focused queue of assignments that need action: blocked, failed, in review, stale, or with unmet dependencies.',\n href: '/attention',\n },\n {\n label: 'Help',\n description: 'This page. Status guide, CLI quick reference, core concepts, and FAQ.',\n href: '/help',\n },\n {\n label: 'Settings',\n description: 'Customize status definitions, labels, colors, display order, and done states. Changes apply globally across the dashboard and CLI.',\n href: '/settings',\n },\n {\n label: 'Mission page',\n description: 'The mission workspace shows health stats, assignment list, dependency graph, shared resources, and memories.',\n href: '/missions',\n },\n {\n label: 'Assignment page',\n description: 'The assignment workspace shows lifecycle actions, plan editor, scratchpad, handoff log, decision records, and agent sessions.',\n href: '/missions',\n },\n ],\n faq: [\n {\n question: 'Why are some files read-only in the dashboard?',\n answer:\n 'Underscore-prefixed files are derived projections that can be rebuilt from canonical markdown sources. Editing them would create drift, so the UI treats them as read-only.',\n },\n {\n question: 'Why can an assignment be pending even when nothing looks broken?',\n answer:\n 'Pending often just means the work has not started yet or it is waiting on declared dependencies. Blocked is reserved for exceptional runtime obstacles that need intervention.',\n },\n {\n question: 'How do I change an assignment\\'s status?',\n answer:\n 'Use lifecycle CLI commands (syntaur start, syntaur complete, etc.), drag cards on the kanban board, or use the Override Status dropdown on the assignment page. Any status can be set from any other status.',\n },\n {\n question: 'How do I customize statuses?',\n answer:\n 'Open the Settings page from the sidebar. You can add, remove, rename, recolor, and reorder statuses. You can also mark statuses as done states. Changes are saved to ~/.syntaur/config.md and take effect immediately across the dashboard.',\n },\n {\n question: 'What is a done state?',\n answer:\n 'A done state (also called terminal status) means the assignment is finished. Done states fill the completed portion of progress bars and satisfy dependency requirements. By default, \"completed\" and \"failed\" are done states. You can configure which statuses are done states in Settings.',\n },\n {\n question: 'What are playbooks and how do I use them?',\n answer:\n 'Playbooks are markdown files in ~/.syntaur/playbooks/ that define behavioral rules agents must follow. Create them via the CLI (syntaur create-playbook) or the Playbooks page. The auto-generated manifest at ~/.syntaur/playbooks/manifest.md can be included in your CLAUDE.md so agents pick up the rules.',\n },\n {\n question: 'How does agent session tracking work?',\n answer:\n 'When an AI agent starts working on an assignment, it can register a session via the track-session CLI command or the Claude Code plugin\\'s /track-session command. The Agent Sessions page shows active and completed sessions with their linked assignments and duration.',\n },\n {\n question: 'How does server tracking work?',\n answer:\n 'Syntaur tracks tmux sessions to discover running dev servers, their ports, git branches, and linked assignments. Register sessions on the Servers page or let autodiscovery find them. Pane info refreshes automatically.',\n },\n ],\n firstMissionChecklist: [\n {\n title: 'Create the mission',\n detail: 'Describe the overall objective in mission.md, then add tags and archive metadata only when needed.',\n command: CLI_COMMANDS[1],\n href: '/create/mission',\n },\n {\n title: 'Create at least one assignment',\n detail: 'Break the mission into executable work units with explicit priority and dependencies.',\n command: CLI_COMMANDS[2],\n },\n {\n title: 'Assign and start the first assignment',\n detail: 'Set an assignee, then start the assignment once prerequisites are complete.',\n command: CLI_COMMANDS[3],\n },\n {\n title: 'Use the assignment workspace for execution',\n detail: 'Keep the objective in assignment.md, the implementation plan in plan.md, and transient notes in scratchpad.md.',\n href: '/missions',\n },\n {\n title: 'Record handoffs and decisions without rewriting history',\n detail: 'Append new handoff and decision entries instead of editing prior entries.',\n },\n {\n title: 'Return to Overview for triage',\n detail: 'Overview and Attention show the queue that needs action next.',\n href: '/',\n },\n ],\n links: [\n { label: 'Overview', href: '/' },\n { label: 'Mission Directory', href: '/missions' },\n { label: 'Assignments Board', href: '/assignments' },\n { label: 'Attention Queue', href: '/attention' },\n { label: 'Servers', href: '/servers' },\n { label: 'Agent Sessions', href: '/agent-sessions' },\n { label: 'Playbooks', href: '/playbooks' },\n { label: 'Settings', href: '/settings' },\n { label: 'Create Mission', href: '/create/mission' },\n ],\n };\n}\n\nexport function getHelpCommandNames(): string[] {\n return CLI_COMMANDS.map((command) => command.command.replace(/^syntaur\\s+/, ''));\n}\n","import { readdir, readFile, unlink } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { ensureDir, fileExists, writeFileForce } from '../utils/fs.js';\nimport { extractFrontmatter, getField } from './parser.js';\nimport type { SessionFileData, SessionKind } from './types.js';\n\nexport function sanitizeSessionName(name: string): string {\n return name.replace(/[^a-zA-Z0-9_-]/g, '-');\n}\n\nfunction nowTimestamp(): string {\n return new Date().toISOString();\n}\n\nexport interface BuildSessionOptions {\n session: string;\n registered: string;\n lastRefreshed: string;\n overrides: Record<string, { mission: string; assignment: string }>;\n auto?: boolean;\n kind?: SessionKind;\n pid?: number;\n ports?: number[];\n cwd?: string;\n}\n\nexport function buildSessionContent(opts: BuildSessionOptions): string {\n const lines = [\n '---',\n `session: ${opts.session}`,\n `registered: ${opts.registered}`,\n `last_refreshed: ${opts.lastRefreshed}`,\n ];\n\n if (opts.auto != null) {\n lines.push(`auto: ${opts.auto}`);\n }\n if (opts.kind) {\n lines.push(`kind: ${opts.kind}`);\n }\n if (opts.pid != null) {\n lines.push(`pid: ${opts.pid}`);\n }\n if (opts.ports && opts.ports.length > 0) {\n lines.push(`ports: [${opts.ports.join(', ')}]`);\n }\n if (opts.cwd) {\n lines.push(`cwd: ${opts.cwd}`);\n }\n\n if (Object.keys(opts.overrides).length > 0) {\n lines.push('overrides:');\n for (const [key, val] of Object.entries(opts.overrides)) {\n lines.push(` \"${key}\": { mission: \"${val.mission}\", assignment: \"${val.assignment}\" }`);\n }\n }\n\n lines.push('---', '');\n return lines.join('\\n');\n}\n\nexport async function registerSession(dir: string, rawName: string): Promise<string> {\n const name = sanitizeSessionName(rawName);\n await ensureDir(dir);\n const now = nowTimestamp();\n const content = buildSessionContent({\n session: name, registered: now, lastRefreshed: now, overrides: {},\n });\n await writeFileForce(resolve(dir, `${name}.md`), content);\n return name;\n}\n\nexport async function listSessionFiles(dir: string): Promise<string[]> {\n if (!(await fileExists(dir))) return [];\n const entries = await readdir(dir);\n return entries\n .filter((f) => f.endsWith('.md'))\n .map((f) => f.replace(/\\.md$/, ''));\n}\n\nexport async function readSessionFile(dir: string, name: string): Promise<SessionFileData | null> {\n const filePath = resolve(dir, `${sanitizeSessionName(name)}.md`);\n if (!(await fileExists(filePath))) return null;\n\n const raw = await readFile(filePath, 'utf-8');\n const [frontmatter] = extractFrontmatter(raw);\n if (!frontmatter) return null;\n\n const session = getField(frontmatter, 'session') ?? name;\n const registered = getField(frontmatter, 'registered') ?? '';\n const lastRefreshed = getField(frontmatter, 'last_refreshed') ?? '';\n\n // Parse overrides block\n const overrides: Record<string, { mission: string; assignment: string }> = {};\n const overridesMatch = frontmatter.match(/^overrides:\\n((?:\\s+\".+\\n?)*)/m);\n if (overridesMatch) {\n const overrideLines = overridesMatch[1].matchAll(\n /^\\s+\"([^\"]+)\":\\s*\\{\\s*mission:\\s*\"([^\"]+)\",\\s*assignment:\\s*\"([^\"]+)\"\\s*\\}/gm,\n );\n for (const m of overrideLines) {\n overrides[m[1]] = { mission: m[2], assignment: m[3] };\n }\n }\n\n const autoField = getField(frontmatter, 'auto');\n const auto = autoField === 'true' ? true : autoField === 'false' ? false : undefined;\n const kind = getField(frontmatter, 'kind') as SessionKind | undefined;\n const pidField = getField(frontmatter, 'pid');\n const pid = pidField ? parseInt(pidField, 10) : undefined;\n const cwdField = getField(frontmatter, 'cwd');\n\n let ports: number[] | undefined;\n const portsMatch = frontmatter.match(/^ports:\\s*\\[([^\\]]*)\\]/m);\n if (portsMatch) {\n ports = portsMatch[1].split(',').map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n));\n }\n\n return {\n session, registered, lastRefreshed, overrides,\n ...(auto != null && { auto }),\n ...(kind && { kind }),\n ...(pid != null && !isNaN(pid) && { pid }),\n ...(ports && ports.length > 0 && { ports }),\n ...(cwdField && { cwd: cwdField }),\n };\n}\n\nexport async function removeSession(dir: string, name: string): Promise<void> {\n const filePath = resolve(dir, `${sanitizeSessionName(name)}.md`);\n if (await fileExists(filePath)) {\n await unlink(filePath);\n }\n}\n\nexport async function updateLastRefreshed(dir: string, name: string): Promise<void> {\n const data = await readSessionFile(dir, name);\n if (!data) return;\n const content = buildSessionContent({ ...data, lastRefreshed: nowTimestamp() });\n await writeFileForce(resolve(dir, `${sanitizeSessionName(name)}.md`), content);\n}\n\nexport async function setOverride(\n dir: string,\n sessionName: string,\n windowIndex: number,\n paneIndex: number,\n assignment: { mission: string; assignment: string } | null,\n): Promise<void> {\n const data = await readSessionFile(dir, sessionName);\n if (!data) return;\n const key = `${windowIndex}:${paneIndex}`;\n if (assignment) {\n data.overrides[key] = assignment;\n } else {\n delete data.overrides[key];\n }\n const content = buildSessionContent({ ...data });\n await writeFileForce(resolve(dir, `${sanitizeSessionName(sessionName)}.md`), content);\n}\n\nexport interface RegisterAutoOptions {\n kind: SessionKind;\n pid?: number;\n ports?: number[];\n cwd?: string;\n}\n\nexport async function registerAutoSession(\n dir: string,\n rawName: string,\n opts: RegisterAutoOptions,\n): Promise<string> {\n const name = sanitizeSessionName(rawName);\n await ensureDir(dir);\n const now = nowTimestamp();\n const content = buildSessionContent({\n session: name,\n registered: now,\n lastRefreshed: now,\n overrides: {},\n auto: true,\n kind: opts.kind,\n pid: opts.pid,\n ports: opts.ports,\n cwd: opts.cwd,\n });\n await writeFileForce(resolve(dir, `${name}.md`), content);\n return name;\n}\n","import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { resolve } from 'node:path';\nimport { realpath, readdir, readFile } from 'node:fs/promises';\nimport { listMissions } from './api.js';\nimport {\n readSessionFile,\n listSessionFiles,\n} from './servers.js';\nimport { extractFrontmatter, getField, getNestedField } from './parser.js';\nimport type {\n TrackedSession,\n TrackedWindow,\n TrackedPane,\n ServersResponse,\n SessionFileData,\n} from './types.js';\n\nconst exec = promisify(execFile);\n\n// --- Cache ---\nlet cache: { data: ServersResponse; expiry: number } | null = null;\nconst CACHE_TTL_MS = 10_000;\n\nexport function clearScanCache(): void {\n cache = null;\n}\n\n// --- Pure parsing functions (exported for testing) ---\n\nexport interface RawPane {\n windowIndex: number;\n windowName: string;\n paneIndex: number;\n command: string;\n cwd: string;\n pid: number;\n}\n\nexport function parseTmuxPaneOutput(output: string): RawPane[] {\n return output\n .trim()\n .split('\\n')\n .filter((line) => line.length > 0)\n .map((line) => {\n const [wi, wn, pi, cmd, cwd, pid] = line.split('|');\n return {\n windowIndex: parseInt(wi, 10),\n windowName: wn,\n paneIndex: parseInt(pi, 10),\n command: cmd,\n cwd,\n pid: parseInt(pid, 10),\n };\n });\n}\n\nexport function findListeningPorts(lsofOutput: string, pids: Set<number>): number[] {\n const ports: number[] = [];\n for (const line of lsofOutput.split('\\n')) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const pid = parseInt(parts[1], 10);\n if (!pids.has(pid)) continue;\n const tcpAddr = parts.find((p) => p.includes(':') && /:\\d+$/.test(p));\n if (tcpAddr) {\n const port = parseInt(tcpAddr.split(':').pop()!, 10);\n if (!isNaN(port) && !ports.includes(port)) {\n ports.push(port);\n }\n }\n }\n return ports;\n}\n\n// --- Shell helpers ---\n\nexport async function execQuiet(cmd: string, args: string[]): Promise<string> {\n try {\n const { stdout } = await exec(cmd, args);\n return stdout.trim();\n } catch {\n return '';\n }\n}\n\nexport async function checkTmuxAvailable(): Promise<boolean> {\n const result = await execQuiet('which', ['tmux']);\n return result.length > 0;\n}\n\nexport async function sessionAlive(name: string): Promise<boolean> {\n try {\n await exec('tmux', ['has-session', '-t', name]);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function listTmuxPanes(sessionName: string): Promise<RawPane[]> {\n const output = await execQuiet('tmux', [\n 'list-panes', '-s', '-t', sessionName,\n '-F', '#{window_index}|#{window_name}|#{pane_index}|#{pane_current_command}|#{pane_current_path}|#{pane_pid}',\n ]);\n return parseTmuxPaneOutput(output);\n}\n\nexport async function getDescendantPids(rootPid: number, maxDepth: number = 4): Promise<Set<number>> {\n const all = new Set<number>([rootPid]);\n let frontier = [rootPid];\n\n for (let depth = 0; depth < maxDepth && frontier.length > 0; depth++) {\n const nextFrontier: number[] = [];\n for (const pid of frontier) {\n const output = await execQuiet('pgrep', ['-P', String(pid)]);\n for (const line of output.split('\\n')) {\n const child = parseInt(line, 10);\n if (!isNaN(child) && !all.has(child)) {\n all.add(child);\n nextFrontier.push(child);\n }\n }\n }\n frontier = nextFrontier;\n }\n\n return all;\n}\n\nexport async function getLsofOutput(): Promise<string> {\n return execQuiet('lsof', ['-i', '-P', '-n', '-sTCP:LISTEN']);\n}\n\nexport async function getGitInfo(cwd: string): Promise<{ branch: string | null; worktree: boolean }> {\n const branch = await execQuiet('git', ['-C', cwd, 'rev-parse', '--abbrev-ref', 'HEAD']);\n if (!branch) return { branch: null, worktree: false };\n\n const commonDir = await execQuiet('git', ['-C', cwd, 'rev-parse', '--git-common-dir']);\n const gitDir = await execQuiet('git', ['-C', cwd, 'rev-parse', '--git-dir']);\n\n let isWorktree = false;\n if (commonDir && gitDir && commonDir !== gitDir) {\n try {\n const resolvedCommon = await realpath(resolve(cwd, commonDir));\n const resolvedGit = await realpath(resolve(cwd, gitDir));\n isWorktree = resolvedCommon !== resolvedGit;\n } catch {\n isWorktree = false;\n }\n }\n\n return { branch: branch || null, worktree: isWorktree };\n}\n\n// --- Auto-linking ---\n\nexport interface AssignmentLink {\n mission: string;\n slug: string;\n title: string;\n}\n\nexport interface WorkspaceRecord {\n missionSlug: string;\n assignmentSlug: string;\n assignmentTitle: string;\n worktreePath: string | null;\n branch: string | null;\n}\n\nexport async function loadWorkspaceRecords(missionsDir: string): Promise<WorkspaceRecord[]> {\n const records: WorkspaceRecord[] = [];\n try {\n const missions = await listMissions(missionsDir);\n\n for (const mission of missions) {\n const assignmentsDir = resolve(missionsDir, mission.slug, 'assignments');\n let slugs: string[];\n try {\n slugs = await readdir(assignmentsDir);\n } catch {\n continue;\n }\n for (const aslug of slugs) {\n const aFile = resolve(assignmentsDir, aslug, 'assignment.md');\n try {\n const raw = await readFile(aFile, 'utf-8');\n const [fm] = extractFrontmatter(raw);\n if (!fm) continue;\n records.push({\n missionSlug: mission.slug,\n assignmentSlug: aslug,\n assignmentTitle: getField(fm, 'title') ?? aslug,\n worktreePath: getNestedField(fm, 'workspace', 'worktreePath') ?? null,\n branch: getNestedField(fm, 'workspace', 'branch') ?? null,\n });\n } catch {\n continue;\n }\n }\n }\n } catch {\n // If missions can't be loaded, auto-linking just returns no matches\n }\n return records;\n}\n\nexport async function resolveAndNormalize(p: string): Promise<string> {\n try {\n const resolved = await realpath(p);\n return resolved.replace(/\\/+$/, '');\n } catch {\n return p.replace(/\\/+$/, '');\n }\n}\n\nexport async function autoLinkPane(\n cwd: string,\n branch: string | null,\n records: WorkspaceRecord[],\n): Promise<AssignmentLink | null> {\n const normalizedCwd = await resolveAndNormalize(cwd);\n for (const rec of records) {\n if (rec.worktreePath) {\n const normalizedWt = await resolveAndNormalize(rec.worktreePath);\n if (normalizedCwd === normalizedWt) {\n return { mission: rec.missionSlug, slug: rec.assignmentSlug, title: rec.assignmentTitle };\n }\n }\n }\n if (branch) {\n for (const rec of records) {\n if (rec.branch && rec.branch === branch) {\n return { mission: rec.missionSlug, slug: rec.assignmentSlug, title: rec.assignmentTitle };\n }\n }\n }\n return null;\n}\n\n// --- Main scan function ---\n\nasync function scanSession(\n sessionData: SessionFileData,\n lsofOutput: string,\n workspaceRecords: WorkspaceRecord[],\n): Promise<TrackedSession> {\n const now = new Date().toISOString();\n const alive = await sessionAlive(sessionData.session);\n\n if (!alive) {\n return {\n name: sessionData.session,\n kind: 'tmux',\n registered: sessionData.registered,\n lastRefreshed: sessionData.lastRefreshed,\n scannedAt: now,\n alive: false,\n windows: [],\n };\n }\n\n const rawPanes = await listTmuxPanes(sessionData.session);\n\n // Group panes by window\n const windowMap = new Map<number, { name: string; panes: RawPane[] }>();\n for (const rp of rawPanes) {\n if (!windowMap.has(rp.windowIndex)) {\n windowMap.set(rp.windowIndex, { name: rp.windowName, panes: [] });\n }\n windowMap.get(rp.windowIndex)!.panes.push(rp);\n }\n\n // Get git info per unique cwd\n const cwdSet = new Set(rawPanes.map((p) => p.cwd));\n const gitInfoCache = new Map<string, { branch: string | null; worktree: boolean }>();\n for (const cwd of cwdSet) {\n gitInfoCache.set(cwd, await getGitInfo(cwd));\n }\n\n // Get all descendant PIDs for port lookup\n const pidToPaneKey = new Map<number, string>();\n for (const rp of rawPanes) {\n const descendants = await getDescendantPids(rp.pid);\n const key = `${rp.windowIndex}:${rp.paneIndex}`;\n for (const pid of descendants) {\n pidToPaneKey.set(pid, key);\n }\n }\n\n // Find ports per pane\n const panePorts = new Map<string, number[]>();\n for (const line of lsofOutput.split('\\n')) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const pid = parseInt(parts[1], 10);\n const paneKey = pidToPaneKey.get(pid);\n if (!paneKey) continue;\n const tcpAddr = parts.find((p) => p.includes(':') && /:\\d+$/.test(p));\n if (tcpAddr) {\n const port = parseInt(tcpAddr.split(':').pop()!, 10);\n if (!isNaN(port)) {\n if (!panePorts.has(paneKey)) panePorts.set(paneKey, []);\n const existing = panePorts.get(paneKey)!;\n if (!existing.includes(port)) existing.push(port);\n }\n }\n }\n\n // Build windows — use for-of loop, NOT .map() with async callback\n const windows: TrackedWindow[] = [];\n for (const [windowIndex, { name, panes: rawPanesInWindow }] of windowMap) {\n const panes: TrackedPane[] = [];\n for (const rp of rawPanesInWindow) {\n const key = `${rp.windowIndex}:${rp.paneIndex}`;\n const gitInfo = gitInfoCache.get(rp.cwd) ?? { branch: null, worktree: false };\n const ports = panePorts.get(key) ?? [];\n const urls = ports.map((p) => `http://localhost:${p}`);\n\n const override = sessionData.overrides[key];\n let assignment: AssignmentLink | null = null;\n if (override) {\n const rec = workspaceRecords.find(\n (r) => r.missionSlug === override.mission && r.assignmentSlug === override.assignment,\n );\n assignment = {\n mission: override.mission,\n slug: override.assignment,\n title: rec?.assignmentTitle ?? override.assignment,\n };\n } else {\n assignment = await autoLinkPane(rp.cwd, gitInfo.branch, workspaceRecords);\n }\n\n panes.push({\n index: rp.paneIndex,\n command: rp.command,\n cwd: rp.cwd,\n branch: gitInfo.branch,\n worktree: gitInfo.worktree,\n ports,\n urls,\n assignment,\n });\n }\n\n windows.push({ index: windowIndex, name, panes });\n }\n\n windows.sort((a, b) => a.index - b.index);\n\n return {\n name: sessionData.session,\n kind: 'tmux' as const,\n registered: sessionData.registered,\n lastRefreshed: sessionData.lastRefreshed,\n scannedAt: now,\n alive: true,\n windows,\n };\n}\n\nasync function scanProcessSession(\n sessionData: SessionFileData,\n lsofOutput: string,\n workspaceRecords: WorkspaceRecord[],\n): Promise<TrackedSession> {\n const now = new Date().toISOString();\n\n // Check if the process is still alive\n let alive = false;\n if (sessionData.pid) {\n try {\n process.kill(sessionData.pid, 0);\n alive = true;\n } catch {\n alive = false;\n }\n }\n\n if (!alive || !sessionData.cwd) {\n return {\n name: sessionData.session,\n kind: 'process',\n registered: sessionData.registered,\n lastRefreshed: sessionData.lastRefreshed,\n scannedAt: now,\n alive: false,\n windows: [],\n };\n }\n\n // Re-resolve ports from lsof for the PID\n const ports = findListeningPorts(lsofOutput, new Set([sessionData.pid!]));\n\n const gitInfo = await getGitInfo(sessionData.cwd);\n\n // Honor manual overrides (process sessions use key \"0:0\")\n const override = sessionData.overrides['0:0'];\n let assignment: AssignmentLink | null = null;\n if (override) {\n const rec = workspaceRecords.find(\n (r) => r.missionSlug === override.mission && r.assignmentSlug === override.assignment,\n );\n assignment = {\n mission: override.mission,\n slug: override.assignment,\n title: rec?.assignmentTitle ?? override.assignment,\n };\n } else {\n assignment = await autoLinkPane(sessionData.cwd, gitInfo.branch, workspaceRecords);\n }\n\n const pane: TrackedPane = {\n index: 0,\n command: sessionData.session,\n cwd: sessionData.cwd,\n branch: gitInfo.branch,\n worktree: gitInfo.worktree,\n ports,\n urls: ports.map((p) => `http://localhost:${p}`),\n assignment,\n };\n\n return {\n name: sessionData.session,\n kind: 'process' as const,\n registered: sessionData.registered,\n lastRefreshed: sessionData.lastRefreshed,\n scannedAt: now,\n alive: true,\n windows: [{ index: 0, name: 'process', panes: [pane] }],\n };\n}\n\nexport async function scanAllSessions(\n serversDir: string,\n missionsDir: string,\n options?: { bypassCache?: boolean },\n): Promise<ServersResponse> {\n if (!options?.bypassCache && cache && Date.now() < cache.expiry) {\n return cache.data;\n }\n\n const tmuxAvailable = await checkTmuxAvailable();\n const names = await listSessionFiles(serversDir);\n const lsofOutput = await getLsofOutput();\n const workspaceRecords = await loadWorkspaceRecords(missionsDir);\n\n const sessions: TrackedSession[] = [];\n for (const name of names) {\n const data = await readSessionFile(serversDir, name);\n if (!data) continue;\n\n if (data.kind === 'process') {\n sessions.push(await scanProcessSession(data, lsofOutput, workspaceRecords));\n } else if (tmuxAvailable) {\n sessions.push(await scanSession(data, lsofOutput, workspaceRecords));\n }\n // Skip tmux-kind entries when tmux is unavailable\n }\n\n const result: ServersResponse = { sessions, tmuxAvailable };\n cache = { data: result, expiry: Date.now() + CACHE_TTL_MS };\n return result;\n}\n\nexport async function scanSingleSession(\n serversDir: string,\n missionsDir: string,\n name: string,\n): Promise<TrackedSession | null> {\n const data = await readSessionFile(serversDir, name);\n if (!data) return null;\n\n const lsofOutput = await getLsofOutput();\n const workspaceRecords = await loadWorkspaceRecords(missionsDir);\n\n if (data.kind === 'process') {\n return scanProcessSession(data, lsofOutput, workspaceRecords);\n }\n return scanSession(data, lsofOutput, workspaceRecords);\n}\n","import { readdir, readFile, writeFile } from 'node:fs/promises';\nimport { resolve, dirname } from 'node:path';\nimport { getTargetStatus, DEFAULT_STATUSES, DEFAULT_TRANSITION_TABLE, buildTransitionTable } from '../lifecycle/index.js';\nimport { fileExists } from '../utils/fs.js';\nimport { readConfig, type StatusConfig, type StatusTransition } from '../utils/config.js';\nimport {\n parseMission,\n parseStatus,\n parseAssignmentFull,\n parsePlan,\n parseScratchpad,\n parseHandoff,\n parseDecisionRecord,\n parseResource,\n parseMemory,\n parsePlaybook,\n extractMermaidGraph,\n} from './parser.js';\nimport { getDashboardHelp } from './help.js';\nimport type {\n AssignmentBoardItem,\n AssignmentDetail,\n AssignmentSummary,\n AssignmentsBoardResponse,\n AssignmentTransitionAction,\n AttentionItem,\n AttentionResponse,\n EditableDocumentResponse,\n HelpResponse,\n MemorySummary,\n MissionDetail,\n MissionSummary,\n OverviewResponse,\n ProgressCounts,\n NeedsAttention,\n RecentActivityItem,\n ResourceSummary,\n PlaybookSummary,\n PlaybookDetail,\n} from './types.js';\n\nconst STALE_ASSIGNMENT_MS = 7 * 24 * 60 * 60 * 1000;\nconst ATTENTION_PAGE_LIMIT = 50;\nconst OVERVIEW_ATTENTION_LIMIT = 6;\nconst RECENT_MISSIONS_LIMIT = 6;\nconst RECENT_ACTIVITY_LIMIT = 12;\n\ntype AssignmentRecord = ReturnType<typeof parseAssignmentFull>;\n\ninterface MissionRecord {\n missionPath: string;\n mission: ReturnType<typeof parseMission>;\n assignments: AssignmentRecord[];\n summary: MissionSummary;\n dependencyGraph: string | null;\n}\n\ninterface AttentionSeverityCounts {\n critical: number;\n high: number;\n medium: number;\n low: number;\n}\n\nconst DEFAULT_TRANSITION_DEFINITIONS: Array<{\n command: string;\n label: string;\n description: string;\n requiresReason: boolean;\n}> = [\n {\n command: 'start',\n label: 'Start',\n description: 'Move pending or review work into active execution.',\n requiresReason: false,\n },\n {\n command: 'review',\n label: 'Send To Review',\n description: 'Mark the assignment ready for inspection.',\n requiresReason: false,\n },\n {\n command: 'complete',\n label: 'Complete',\n description: 'Mark the assignment done.',\n requiresReason: false,\n },\n {\n command: 'block',\n label: 'Block',\n description: 'Record an exceptional blocker and pause work.',\n requiresReason: true,\n },\n {\n command: 'unblock',\n label: 'Unblock',\n description: 'Resume active work after the blocker is cleared.',\n requiresReason: false,\n },\n {\n command: 'fail',\n label: 'Fail',\n description: 'Mark the assignment as failed when it cannot be completed as planned.',\n requiresReason: false,\n },\n {\n command: 'reopen',\n label: 'Reopen',\n description: 'Reopen a completed or failed assignment to resume work.',\n requiresReason: false,\n },\n];\n\nconst DEFAULT_STATUS_COLORS: Record<string, string> = {\n pending: 'slate',\n in_progress: 'teal',\n blocked: 'amber',\n review: 'violet',\n completed: 'emerald',\n failed: 'rose',\n};\n\nfunction toTitleCase(s: string): string {\n return s.replace(/_/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction getTransitionDefinitions(config: ResolvedStatusConfig) {\n if (!config.custom) return DEFAULT_TRANSITION_DEFINITIONS;\n // Deduplicate commands from transitions\n const seen = new Set<string>();\n return config.transitions\n .filter((t) => {\n if (seen.has(t.command)) return false;\n seen.add(t.command);\n return true;\n })\n .map((t) => ({\n command: t.command,\n label: t.label ?? toTitleCase(t.command),\n description: t.description ?? `Transition via ${t.command}.`,\n requiresReason: t.requiresReason ?? false,\n }));\n}\n\ninterface ResolvedStatusConfig {\n custom: boolean;\n statuses: Array<{ id: string; label: string; description?: string; color?: string; terminal?: boolean }>;\n order: string[];\n transitions: StatusTransition[];\n transitionTable: Map<string, string>;\n terminalStatuses: ReadonlySet<string>;\n}\n\nlet _cachedConfig: ResolvedStatusConfig | null = null;\n\nexport async function getStatusConfig(): Promise<ResolvedStatusConfig> {\n if (_cachedConfig) return _cachedConfig;\n\n const config = await readConfig();\n\n if (config.statuses) {\n const terminalSet = new Set(\n config.statuses.statuses.filter((s) => s.terminal).map((s) => s.id),\n );\n _cachedConfig = {\n custom: true,\n statuses: config.statuses.statuses,\n order: config.statuses.order,\n transitions: config.statuses.transitions,\n transitionTable: buildTransitionTable(config.statuses.transitions),\n terminalStatuses: terminalSet.size > 0 ? terminalSet : new Set(['completed', 'failed']),\n };\n } else {\n _cachedConfig = {\n custom: false,\n statuses: DEFAULT_STATUSES.map((id) => ({\n id,\n label: toTitleCase(id),\n color: DEFAULT_STATUS_COLORS[id] ?? 'gray',\n terminal: id === 'completed' || id === 'failed',\n })),\n order: [...DEFAULT_STATUSES],\n transitions: Array.from(DEFAULT_TRANSITION_TABLE.entries()).map(([key, to]) => {\n const [from, command] = key.split(':');\n return { from, command, to };\n }),\n transitionTable: DEFAULT_TRANSITION_TABLE,\n terminalStatuses: new Set(['completed', 'failed']),\n };\n }\n\n return _cachedConfig;\n}\n\nexport function clearStatusConfigCache(): void {\n _cachedConfig = null;\n}\n\n/**\n * List all missions with source-first summary data.\n * GET /api/missions\n */\nexport async function listMissions(missionsDir: string): Promise<MissionSummary[]> {\n const missionRecords = await listMissionRecords(missionsDir);\n return missionRecords.map((record) => record.summary);\n}\n\n/**\n * Read the workspace registry file (~/.syntaur/workspaces.json).\n * Returns an array of explicitly registered workspace names.\n */\nasync function readWorkspaceRegistry(missionsDir: string): Promise<string[]> {\n const registryPath = resolve(dirname(missionsDir), 'workspaces.json');\n try {\n const raw = await readFile(registryPath, 'utf-8');\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? parsed.filter((w): w is string => typeof w === 'string') : [];\n } catch {\n return [];\n }\n}\n\nasync function writeWorkspaceRegistry(missionsDir: string, workspaces: string[]): Promise<void> {\n const registryPath = resolve(dirname(missionsDir), 'workspaces.json');\n await writeFile(registryPath, JSON.stringify(workspaces, null, 2) + '\\n', 'utf-8');\n}\n\n/**\n * List all workspaces: merge registry (explicit) with discovered (from missions).\n * GET /api/workspaces\n */\nexport async function listWorkspaces(missionsDir: string): Promise<{ workspaces: string[]; hasUngrouped: boolean }> {\n const [missionRecords, registered] = await Promise.all([\n listMissionRecords(missionsDir),\n readWorkspaceRegistry(missionsDir),\n ]);\n const workspaceSet = new Set<string>(registered);\n let hasUngrouped = false;\n for (const record of missionRecords) {\n if (record.mission.workspace) {\n workspaceSet.add(record.mission.workspace);\n } else {\n hasUngrouped = true;\n }\n }\n const workspaces = Array.from(workspaceSet).sort();\n return { workspaces, hasUngrouped };\n}\n\n/**\n * Create an empty workspace by registering it.\n * POST /api/workspaces\n */\nexport async function createWorkspace(missionsDir: string, name: string): Promise<void> {\n const registered = await readWorkspaceRegistry(missionsDir);\n if (!registered.includes(name)) {\n registered.push(name);\n registered.sort();\n await writeWorkspaceRegistry(missionsDir, registered);\n }\n}\n\n/**\n * Delete a workspace from the registry.\n * DELETE /api/workspaces/:name\n */\nexport async function deleteWorkspace(missionsDir: string, name: string): Promise<void> {\n const registered = await readWorkspaceRegistry(missionsDir);\n const filtered = registered.filter((w) => w !== name);\n await writeWorkspaceRegistry(missionsDir, filtered);\n}\n\n/**\n * Get overview data used by the app landing page.\n * GET /api/overview\n */\nexport async function getOverview(missionsDir: string, serversDir?: string): Promise<OverviewResponse> {\n const missionRecords = await listMissionRecords(missionsDir);\n const attention = buildAttentionItems(missionRecords);\n const recentActivity = buildRecentActivity(missionRecords);\n\n let serverStats: OverviewResponse['serverStats'];\n if (serversDir) {\n try {\n const { scanAllSessions } = await import('./scanner.js');\n const servers = await scanAllSessions(serversDir, missionsDir);\n if (servers.tmuxAvailable) {\n const alive = servers.sessions.filter(s => s.alive).length;\n const totalPorts = servers.sessions.reduce((sum, s) =>\n sum + s.windows.reduce((ws, w) =>\n ws + w.panes.reduce((ps, p) => ps + p.ports.length, 0), 0), 0);\n serverStats = {\n trackedSessions: servers.sessions.length,\n aliveSessions: alive,\n deadSessions: servers.sessions.length - alive,\n totalPorts,\n };\n }\n } catch {\n // Server scanning failure should not break overview\n }\n }\n\n return {\n generatedAt: new Date().toISOString(),\n firstRun: missionRecords.length === 0,\n stats: {\n activeMissions: missionRecords.filter((record) => record.summary.status === 'active').length,\n inProgressAssignments: missionRecords.reduce(\n (total, record) => total + (record.summary.progress['in_progress'] ?? 0),\n 0,\n ),\n blockedAssignments: missionRecords.reduce(\n (total, record) => total + (record.summary.progress['blocked'] ?? 0),\n 0,\n ),\n reviewAssignments: missionRecords.reduce(\n (total, record) => total + (record.summary.progress['review'] ?? 0),\n 0,\n ),\n failedAssignments: missionRecords.reduce(\n (total, record) => total + (record.summary.progress['failed'] ?? 0),\n 0,\n ),\n staleAssignments: missionRecords.reduce(\n (total, record) =>\n total + record.assignments.filter((assignment) => isStale(assignment.updated)).length,\n 0,\n ),\n },\n attention: attention.slice(0, OVERVIEW_ATTENTION_LIMIT),\n recentMissions: missionRecords\n .map((record) => record.summary)\n .sort((left, right) => compareTimestamps(right.updated, left.updated))\n .slice(0, RECENT_MISSIONS_LIMIT),\n recentActivity: recentActivity.slice(0, RECENT_ACTIVITY_LIMIT),\n serverStats,\n };\n}\n\n/**\n * Get the explicit attention queue.\n * GET /api/attention\n */\nexport async function getAttention(missionsDir: string, serversDir?: string): Promise<AttentionResponse> {\n const missionRecords = await listMissionRecords(missionsDir);\n const items = buildAttentionItems(missionRecords);\n\n if (serversDir) {\n try {\n const { scanAllSessions } = await import('./scanner.js');\n const servers = await scanAllSessions(serversDir, missionsDir);\n for (const session of servers.sessions) {\n if (!session.alive) {\n items.push({\n id: `server-dead-${session.name}`,\n severity: 'low',\n missionSlug: '',\n missionTitle: '',\n assignmentSlug: '',\n assignmentTitle: `tmux: ${session.name}`,\n status: 'failed',\n reason: 'Tmux session no longer exists but is still registered',\n updated: session.lastRefreshed,\n href: '/servers',\n stale: false,\n blockedReason: null,\n });\n }\n }\n } catch {\n // Server scanning failure should not break attention\n }\n }\n\n const pagedItems = items.slice(0, ATTENTION_PAGE_LIMIT);\n const summary: AttentionSeverityCounts = {\n critical: 0,\n high: 0,\n medium: 0,\n low: 0,\n };\n\n for (const item of pagedItems) {\n summary[item.severity]++;\n }\n\n return {\n generatedAt: new Date().toISOString(),\n summary: {\n total: pagedItems.length,\n critical: summary.critical,\n high: summary.high,\n medium: summary.medium,\n low: summary.low,\n },\n items: pagedItems,\n };\n}\n\n/**\n * Get all assignments across all missions for the global kanban board.\n * GET /api/assignments\n */\nexport async function listAssignmentsBoard(missionsDir: string): Promise<AssignmentsBoardResponse> {\n const missionRecords = await listMissionRecords(missionsDir);\n const assignments = await Promise.all(\n missionRecords.flatMap(async (record) =>\n Promise.all(\n record.assignments.map(async (assignment) =>\n toAssignmentBoardItem(missionsDir, record, assignment),\n ),\n ),\n ),\n );\n\n return {\n generatedAt: new Date().toISOString(),\n assignments: assignments\n .flat()\n .sort((left, right) => compareTimestamps(right.updated, left.updated)),\n };\n}\n\n/**\n * Get the structured help model used by Help and onboarding surfaces.\n * GET /api/help\n */\nexport async function getHelp(): Promise<HelpResponse> {\n return getDashboardHelp();\n}\n\n/**\n * Get a raw editable document for dashboard editor pages.\n */\nexport async function getEditableDocument(\n missionsDir: string,\n documentType: EditableDocumentResponse['documentType'],\n missionSlug: string,\n assignmentSlug?: string,\n): Promise<EditableDocumentResponse | null> {\n const filePath = getDocumentPath(missionsDir, documentType, missionSlug, assignmentSlug);\n if (!filePath || !(await fileExists(filePath))) {\n return null;\n }\n\n const content = await readFile(filePath, 'utf-8');\n const title = getEditableDocumentTitle(documentType, missionSlug, assignmentSlug);\n\n return {\n documentType,\n title,\n content,\n missionSlug,\n assignmentSlug,\n appendOnly: documentType === 'handoff' || documentType === 'decision-record',\n };\n}\n\n/**\n * Get full mission detail with assignments, resources, and memories.\n * GET /api/missions/:slug\n */\nexport async function getMissionDetail(\n missionsDir: string,\n slug: string,\n): Promise<MissionDetail | null> {\n const missionPath = resolve(missionsDir, slug);\n const missionMdPath = resolve(missionPath, 'mission.md');\n\n if (!(await fileExists(missionMdPath))) {\n return null;\n }\n\n const missionContent = await readFile(missionMdPath, 'utf-8');\n const mission = parseMission(missionContent);\n const assignments = await listAssignmentRecords(missionPath);\n const rollup = buildMissionRollup(mission, assignments);\n const dependencyGraph = await loadDependencyGraph(missionPath, assignments);\n const resources = await listResources(missionPath);\n const memories = await listMemories(missionPath);\n const updated = getMissionActivityTimestamp(mission.updated, assignments);\n\n return {\n slug: mission.slug || slug,\n title: mission.title,\n status: rollup.status,\n statusOverride: mission.statusOverride,\n archived: mission.archived,\n archivedAt: mission.archivedAt,\n archivedReason: mission.archivedReason,\n created: mission.created,\n updated,\n tags: mission.tags,\n body: mission.body,\n progress: rollup.progress,\n needsAttention: rollup.needsAttention,\n assignments: assignments\n .map(toAssignmentSummary)\n .sort((left, right) => compareTimestamps(right.updated, left.updated)),\n resources,\n memories,\n dependencyGraph,\n workspace: mission.workspace,\n };\n}\n\n/**\n * Get full assignment detail with plan, scratchpad, handoff, and decision record.\n * GET /api/missions/:slug/assignments/:aslug\n */\nexport async function getAssignmentDetail(\n missionsDir: string,\n missionSlug: string,\n assignmentSlug: string,\n): Promise<AssignmentDetail | null> {\n const assignmentDir = resolve(missionsDir, missionSlug, 'assignments', assignmentSlug);\n const assignmentMdPath = resolve(assignmentDir, 'assignment.md');\n\n if (!(await fileExists(assignmentMdPath))) {\n return null;\n }\n\n const assignmentContent = await readFile(assignmentMdPath, 'utf-8');\n const assignment = parseAssignmentFull(assignmentContent);\n\n let plan: AssignmentDetail['plan'] = null;\n const planPath = resolve(assignmentDir, 'plan.md');\n if (await fileExists(planPath)) {\n const planContent = await readFile(planPath, 'utf-8');\n const parsed = parsePlan(planContent);\n plan = {\n status: parsed.status,\n updated: parsed.updated,\n body: parsed.body,\n };\n }\n\n let scratchpad: AssignmentDetail['scratchpad'] = null;\n const scratchpadPath = resolve(assignmentDir, 'scratchpad.md');\n if (await fileExists(scratchpadPath)) {\n const scratchpadContent = await readFile(scratchpadPath, 'utf-8');\n const parsed = parseScratchpad(scratchpadContent);\n scratchpad = {\n updated: parsed.updated,\n body: parsed.body,\n };\n }\n\n let handoff: AssignmentDetail['handoff'] = null;\n const handoffPath = resolve(assignmentDir, 'handoff.md');\n if (await fileExists(handoffPath)) {\n const handoffContent = await readFile(handoffPath, 'utf-8');\n const parsed = parseHandoff(handoffContent);\n handoff = {\n updated: parsed.updated,\n handoffCount: parsed.handoffCount,\n body: parsed.body,\n };\n }\n\n let decisionRecord: AssignmentDetail['decisionRecord'] = null;\n const decisionRecordPath = resolve(assignmentDir, 'decision-record.md');\n if (await fileExists(decisionRecordPath)) {\n const decisionRecordContent = await readFile(decisionRecordPath, 'utf-8');\n const parsed = parseDecisionRecord(decisionRecordContent);\n decisionRecord = {\n updated: parsed.updated,\n decisionCount: parsed.decisionCount,\n body: parsed.body,\n };\n }\n\n return {\n id: assignment.id,\n missionSlug,\n slug: assignment.slug || assignmentSlug,\n title: assignment.title,\n status: assignment.status,\n priority: assignment.priority as AssignmentDetail['priority'],\n assignee: assignment.assignee,\n dependsOn: assignment.dependsOn,\n blockedReason: assignment.blockedReason,\n workspace: assignment.workspace,\n externalIds: assignment.externalIds,\n tags: assignment.tags,\n created: assignment.created,\n updated: assignment.updated,\n body: assignment.body,\n plan,\n scratchpad,\n handoff,\n decisionRecord,\n availableTransitions: await getAvailableTransitions(\n missionsDir,\n missionSlug,\n assignmentSlug,\n assignment,\n ),\n };\n}\n\nasync function listMissionRecords(missionsDir: string): Promise<MissionRecord[]> {\n if (!(await fileExists(missionsDir))) {\n return [];\n }\n\n const entries = await readdir(missionsDir, { withFileTypes: true });\n const missionDirs = entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith('.'));\n const records: MissionRecord[] = [];\n\n for (const entry of missionDirs) {\n const missionPath = resolve(missionsDir, entry.name);\n const missionMdPath = resolve(missionPath, 'mission.md');\n\n if (!(await fileExists(missionMdPath))) {\n continue;\n }\n\n const missionContent = await readFile(missionMdPath, 'utf-8');\n const mission = parseMission(missionContent);\n const assignments = await listAssignmentRecords(missionPath);\n const rollup = buildMissionRollup(mission, assignments);\n const updated = getMissionActivityTimestamp(mission.updated, assignments);\n\n records.push({\n missionPath,\n mission,\n assignments,\n dependencyGraph: await loadDependencyGraph(missionPath, assignments),\n summary: {\n slug: mission.slug || entry.name,\n title: mission.title,\n status: rollup.status,\n statusOverride: mission.statusOverride,\n archived: mission.archived,\n archivedAt: mission.archivedAt,\n archivedReason: mission.archivedReason,\n created: mission.created,\n updated,\n tags: mission.tags,\n progress: rollup.progress,\n needsAttention: rollup.needsAttention,\n workspace: mission.workspace,\n },\n });\n }\n\n records.sort((left, right) => compareTimestamps(right.summary.updated, left.summary.updated));\n return records;\n}\n\nasync function listAssignmentRecords(missionPath: string): Promise<AssignmentRecord[]> {\n const assignmentsDir = resolve(missionPath, 'assignments');\n if (!(await fileExists(assignmentsDir))) {\n return [];\n }\n\n const entries = await readdir(assignmentsDir, { withFileTypes: true });\n const records: AssignmentRecord[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n continue;\n }\n\n const assignmentMd = resolve(assignmentsDir, entry.name, 'assignment.md');\n if (!(await fileExists(assignmentMd))) {\n continue;\n }\n\n const content = await readFile(assignmentMd, 'utf-8');\n records.push(parseAssignmentFull(content));\n }\n\n records.sort((left, right) => compareTimestamps(right.updated, left.updated));\n return records;\n}\n\nasync function listResources(missionPath: string): Promise<ResourceSummary[]> {\n const resourcesDir = resolve(missionPath, 'resources');\n if (!(await fileExists(resourcesDir))) {\n return [];\n }\n\n const entries = await readdir(resourcesDir, { withFileTypes: true });\n const results: ResourceSummary[] = [];\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md') || entry.name.startsWith('_')) {\n continue;\n }\n\n const filePath = resolve(resourcesDir, entry.name);\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseResource(content);\n results.push({\n name: parsed.name,\n slug: entry.name.replace(/\\.md$/, ''),\n category: parsed.category,\n source: parsed.source,\n relatedAssignments: parsed.relatedAssignments,\n updated: parsed.updated,\n });\n }\n\n results.sort((left, right) => compareTimestamps(right.updated, left.updated));\n return results;\n}\n\nasync function listMemories(missionPath: string): Promise<MemorySummary[]> {\n const memoriesDir = resolve(missionPath, 'memories');\n if (!(await fileExists(memoriesDir))) {\n return [];\n }\n\n const entries = await readdir(memoriesDir, { withFileTypes: true });\n const results: MemorySummary[] = [];\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md') || entry.name.startsWith('_')) {\n continue;\n }\n\n const filePath = resolve(memoriesDir, entry.name);\n const content = await readFile(filePath, 'utf-8');\n const parsed = parseMemory(content);\n results.push({\n name: parsed.name,\n slug: entry.name.replace(/\\.md$/, ''),\n source: parsed.source,\n scope: parsed.scope,\n sourceAssignment: parsed.sourceAssignment,\n updated: parsed.updated,\n });\n }\n\n results.sort((left, right) => compareTimestamps(right.updated, left.updated));\n return results;\n}\n\nasync function loadDependencyGraph(\n missionPath: string,\n assignments: AssignmentRecord[],\n): Promise<string | null> {\n const statusPath = resolve(missionPath, '_status.md');\n if (await fileExists(statusPath)) {\n const statusContent = await readFile(statusPath, 'utf-8');\n const parsed = parseStatus(statusContent);\n const derivedGraph = extractMermaidGraph(parsed.body);\n if (derivedGraph) {\n return derivedGraph;\n }\n }\n\n return buildDependencyGraph(assignments);\n}\n\nfunction buildMissionRollup(\n mission: ReturnType<typeof parseMission>,\n assignments: AssignmentRecord[],\n): {\n progress: ProgressCounts;\n needsAttention: NeedsAttention;\n status: string;\n} {\n const progress: ProgressCounts = { total: assignments.length };\n\n let unansweredQuestions = 0;\n for (const assignment of assignments) {\n const s = assignment.status;\n progress[s] = (progress[s] ?? 0) + 1;\n unansweredQuestions += countPendingAnswers(assignment.body);\n }\n\n const needsAttention: NeedsAttention = {\n blockedCount: progress['blocked'] ?? 0,\n failedCount: progress['failed'] ?? 0,\n unansweredQuestions,\n };\n\n let status = 'pending';\n if (mission.statusOverride) {\n status = mission.statusOverride;\n } else if (mission.archived) {\n status = 'archived';\n } else if (progress.total > 0 && (progress['completed'] ?? 0) === progress.total) {\n status = 'completed';\n } else if ((progress['in_progress'] ?? 0) > 0 || (progress['review'] ?? 0) > 0) {\n status = 'active';\n } else if ((progress['failed'] ?? 0) > 0) {\n status = 'failed';\n } else if ((progress['blocked'] ?? 0) > 0) {\n status = 'blocked';\n } else if (progress.total === 0 || (progress['pending'] ?? 0) === progress.total) {\n status = 'pending';\n } else {\n status = 'active';\n }\n\n return { progress, needsAttention, status };\n}\n\nfunction toAssignmentSummary(assignment: AssignmentRecord): AssignmentSummary {\n return {\n id: assignment.id,\n slug: assignment.slug,\n title: assignment.title,\n status: assignment.status,\n priority: assignment.priority as AssignmentSummary['priority'],\n assignee: assignment.assignee,\n dependsOn: assignment.dependsOn,\n updated: assignment.updated,\n };\n}\n\nasync function toAssignmentBoardItem(\n missionsDir: string,\n missionRecord: MissionRecord,\n assignment: AssignmentRecord,\n): Promise<AssignmentBoardItem> {\n return {\n ...toAssignmentSummary(assignment),\n missionSlug: missionRecord.summary.slug,\n missionTitle: missionRecord.summary.title,\n blockedReason: assignment.blockedReason,\n missionWorkspace: missionRecord.mission.workspace,\n availableTransitions: await getAvailableTransitions(\n missionsDir,\n missionRecord.summary.slug,\n assignment.slug,\n assignment,\n ),\n };\n}\n\nconst DEFAULT_GRAPH_COLORS: Record<string, string> = {\n completed: 'fill:#4ea84f,stroke:#1f6b29,color:#ffffff',\n in_progress: 'fill:#1e6fd9,stroke:#0f3f8f,color:#ffffff',\n pending: 'fill:#c0ccd9,stroke:#738399,color:#163047',\n blocked: 'fill:#db5a3f,stroke:#8d2815,color:#ffffff',\n failed: 'fill:#9f2d2d,stroke:#651616,color:#ffffff',\n review: 'fill:#c6911e,stroke:#7a5a10,color:#ffffff',\n};\n\nfunction buildDependencyGraph(assignments: AssignmentRecord[]): string | null {\n const edges: string[] = [];\n const usedStatuses = new Set<string>();\n\n for (const assignment of assignments) {\n for (const dependency of assignment.dependsOn) {\n const depStatus = findAssignmentStatus(assignments, dependency);\n usedStatuses.add(depStatus);\n usedStatuses.add(assignment.status);\n edges.push(\n ` ${dependency}:::${depStatus} --> ${assignment.slug}:::${assignment.status}`,\n );\n }\n }\n\n if (edges.length === 0) {\n return null;\n }\n\n const classDefs: string[] = [];\n for (const status of usedStatuses) {\n const colors = DEFAULT_GRAPH_COLORS[status] ?? 'fill:#94a3b8,stroke:#64748b,color:#ffffff';\n classDefs.push(` classDef ${status} ${colors}`);\n }\n\n return ['graph TD', ...edges, ...classDefs].join('\\n');\n}\n\nfunction findAssignmentStatus(assignments: AssignmentRecord[], slug: string): string {\n return assignments.find((assignment) => assignment.slug === slug)?.status ?? 'pending';\n}\n\nasync function getAvailableTransitions(\n missionsDir: string,\n missionSlug: string,\n assignmentSlug: string,\n assignment: AssignmentRecord,\n): Promise<AssignmentTransitionAction[]> {\n const config = await getStatusConfig();\n const transitionDefs = getTransitionDefinitions(config);\n const actions: AssignmentTransitionAction[] = [];\n const missionPath = resolve(missionsDir, missionSlug);\n\n for (const definition of transitionDefs) {\n let warning: string | null = null;\n\n if (definition.command === 'start' && !assignment.assignee) {\n warning = 'No assignee set — consider assigning before starting.';\n }\n\n if (definition.command === 'start' && assignment.dependsOn.length > 0) {\n const unmetDependencies = await getUnmetDependencies(missionPath, assignment.dependsOn, config.terminalStatuses);\n if (unmetDependencies.length > 0) {\n warning = `Unmet dependencies: ${unmetDependencies.join(', ')}.`;\n }\n }\n\n const target = getTargetStatus(assignment.status, definition.command, config.transitionTable);\n\n actions.push({\n command: definition.command,\n label: definition.label,\n description: definition.description,\n targetStatus: target ?? definition.command,\n disabled: false,\n disabledReason: null,\n warning,\n requiresReason: definition.requiresReason,\n });\n }\n\n return actions;\n}\n\nasync function getUnmetDependencies(missionPath: string, dependsOn: string[], terminalStatuses?: ReadonlySet<string>): Promise<string[]> {\n const terminals = terminalStatuses ?? new Set(['completed']);\n const unmet: string[] = [];\n\n for (const dependency of dependsOn) {\n const dependencyPath = resolve(missionPath, 'assignments', dependency, 'assignment.md');\n if (!(await fileExists(dependencyPath))) {\n unmet.push(`${dependency} (missing)`);\n continue;\n }\n\n const content = await readFile(dependencyPath, 'utf-8');\n const parsed = parseAssignmentFull(content);\n if (!terminals.has(parsed.status)) {\n unmet.push(`${dependency} (${parsed.status})`);\n }\n }\n\n return unmet;\n}\n\nfunction buildAttentionItems(missionRecords: MissionRecord[]): AttentionItem[] {\n const items: AttentionItem[] = [];\n\n for (const record of missionRecords) {\n for (const assignment of record.assignments) {\n const stale = isStale(assignment.updated);\n const base = {\n missionSlug: record.summary.slug,\n missionTitle: record.summary.title,\n assignmentSlug: assignment.slug,\n assignmentTitle: assignment.title,\n status: assignment.status,\n updated: assignment.updated,\n href: `/missions/${record.summary.slug}/assignments/${assignment.slug}`,\n blockedReason: assignment.blockedReason,\n stale,\n };\n\n if (assignment.status === 'failed') {\n items.push({\n id: `${record.summary.slug}:${assignment.slug}:failed`,\n severity: 'critical',\n reason: 'Marked failed and needs a recovery decision.',\n ...base,\n });\n }\n\n if (assignment.status === 'blocked') {\n items.push({\n id: `${record.summary.slug}:${assignment.slug}:blocked`,\n severity: 'high',\n reason: assignment.blockedReason || 'Blocked and waiting for intervention.',\n ...base,\n });\n }\n\n if (assignment.status === 'review') {\n items.push({\n id: `${record.summary.slug}:${assignment.slug}:review`,\n severity: 'medium',\n reason: 'Ready for review.',\n ...base,\n });\n }\n\n if (stale) {\n items.push({\n id: `${record.summary.slug}:${assignment.slug}:stale`,\n severity: 'low',\n reason: 'No source updates have been recorded in the last 7 days.',\n ...base,\n });\n }\n }\n }\n\n return items.sort(compareAttentionItems);\n}\n\nfunction buildRecentActivity(missionRecords: MissionRecord[]): RecentActivityItem[] {\n const activity: RecentActivityItem[] = [];\n\n for (const record of missionRecords) {\n activity.push({\n id: `mission:${record.summary.slug}`,\n type: 'mission',\n title: record.summary.title,\n updated: record.summary.updated,\n href: `/missions/${record.summary.slug}`,\n missionSlug: record.summary.slug,\n missionTitle: record.summary.title,\n assignmentSlug: null,\n summary: `Mission status is ${record.summary.status}.`,\n });\n\n for (const assignment of record.assignments) {\n activity.push({\n id: `assignment:${record.summary.slug}:${assignment.slug}`,\n type: 'assignment',\n title: assignment.title,\n updated: assignment.updated,\n href: `/missions/${record.summary.slug}/assignments/${assignment.slug}`,\n missionSlug: record.summary.slug,\n missionTitle: record.summary.title,\n assignmentSlug: assignment.slug,\n summary: `Assignment is ${assignment.status} with ${assignment.priority} priority.`,\n });\n }\n }\n\n activity.sort((left, right) => compareTimestamps(right.updated, left.updated));\n return activity;\n}\n\nfunction compareAttentionItems(left: AttentionItem, right: AttentionItem): number {\n const severityRank = { critical: 0, high: 1, medium: 2, low: 3 };\n const severityDifference = severityRank[left.severity] - severityRank[right.severity];\n if (severityDifference !== 0) {\n return severityDifference;\n }\n return compareTimestamps(right.updated, left.updated);\n}\n\nfunction compareTimestamps(left: string, right: string): number {\n return parseTimestamp(left) - parseTimestamp(right);\n}\n\nfunction parseTimestamp(timestamp: string): number {\n const parsed = Date.parse(timestamp);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction isStale(updated: string): boolean {\n const timestamp = parseTimestamp(updated);\n if (timestamp === 0) {\n return false;\n }\n return Date.now() - timestamp > STALE_ASSIGNMENT_MS;\n}\n\nfunction countPendingAnswers(body: string): number {\n const matches = body.match(/^\\*\\*A:\\*\\*\\s+pending\\s*$/gim);\n return matches ? matches.length : 0;\n}\n\nfunction getMissionActivityTimestamp(missionUpdated: string, assignments: AssignmentRecord[]): string {\n let latest = missionUpdated;\n for (const assignment of assignments) {\n if (compareTimestamps(assignment.updated, latest) > 0) {\n latest = assignment.updated;\n }\n }\n return latest;\n}\n\nfunction getDocumentPath(\n missionsDir: string,\n documentType: EditableDocumentResponse['documentType'],\n missionSlug: string,\n assignmentSlug?: string,\n): string | null {\n switch (documentType) {\n case 'mission':\n return resolve(missionsDir, missionSlug, 'mission.md');\n case 'assignment':\n return assignmentSlug\n ? resolve(missionsDir, missionSlug, 'assignments', assignmentSlug, 'assignment.md')\n : null;\n case 'plan':\n return assignmentSlug\n ? resolve(missionsDir, missionSlug, 'assignments', assignmentSlug, 'plan.md')\n : null;\n case 'scratchpad':\n return assignmentSlug\n ? resolve(missionsDir, missionSlug, 'assignments', assignmentSlug, 'scratchpad.md')\n : null;\n case 'handoff':\n return assignmentSlug\n ? resolve(missionsDir, missionSlug, 'assignments', assignmentSlug, 'handoff.md')\n : null;\n case 'decision-record':\n return assignmentSlug\n ? resolve(missionsDir, missionSlug, 'assignments', assignmentSlug, 'decision-record.md')\n : null;\n default:\n return null;\n }\n}\n\nfunction getEditableDocumentTitle(\n documentType: EditableDocumentResponse['documentType'],\n missionSlug: string,\n assignmentSlug?: string,\n): string {\n switch (documentType) {\n case 'mission':\n return `Edit Mission: ${missionSlug}`;\n case 'assignment':\n return `Edit Assignment: ${assignmentSlug || 'assignment'}`;\n case 'plan':\n return `Edit Plan: ${assignmentSlug || 'assignment'}`;\n case 'scratchpad':\n return `Edit Scratchpad: ${assignmentSlug || 'assignment'}`;\n case 'handoff':\n return `Append Handoff: ${assignmentSlug || 'assignment'}`;\n case 'decision-record':\n return `Append Decision: ${assignmentSlug || 'assignment'}`;\n case 'playbook':\n return `Edit Playbook: ${missionSlug}`;\n default:\n return missionSlug;\n }\n}\n\n// --- Playbook API ---\n\nexport async function listPlaybooks(playbooksDir: string): Promise<PlaybookSummary[]> {\n if (!(await fileExists(playbooksDir))) return [];\n\n const entries = await readdir(playbooksDir, { withFileTypes: true });\n const playbooks: PlaybookSummary[] = [];\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md') || entry.name.startsWith('_') || entry.name === 'manifest.md') continue;\n\n const filePath = resolve(playbooksDir, entry.name);\n const raw = await readFile(filePath, 'utf-8');\n const parsed = parsePlaybook(raw);\n\n const slug = parsed.slug || entry.name.replace(/\\.md$/, '');\n playbooks.push({\n slug,\n name: parsed.name || slug,\n description: parsed.description,\n whenToUse: parsed.whenToUse,\n tags: parsed.tags,\n created: parsed.created,\n updated: parsed.updated,\n });\n }\n\n return playbooks.sort((a, b) => (b.updated || b.created).localeCompare(a.updated || a.created));\n}\n\nexport async function getPlaybookDetail(\n playbooksDir: string,\n slug: string,\n): Promise<PlaybookDetail | null> {\n const filePath = resolve(playbooksDir, `${slug}.md`);\n if (!(await fileExists(filePath))) return null;\n\n const raw = await readFile(filePath, 'utf-8');\n const parsed = parsePlaybook(raw);\n\n return {\n slug: parsed.slug || slug,\n name: parsed.name || slug,\n description: parsed.description,\n whenToUse: parsed.whenToUse,\n tags: parsed.tags,\n created: parsed.created,\n updated: parsed.updated,\n body: parsed.body,\n };\n}\n","import { randomBytes } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { extractFrontmatter, getField } from '../dashboard/parser.js';\nimport { ensureDir, fileExists, writeFileForce } from '../utils/fs.js';\nimport type {\n TodoItem,\n TodoChecklist,\n TodoStatus,\n ArchiveInterval,\n LogEntry,\n TodoLog,\n} from './types.js';\n\n// --- Short ID ---\n\nexport function generateShortId(): string {\n return randomBytes(2).toString('hex');\n}\n\nexport function generateUniqueId(existingIds: Set<string>): string {\n let id = generateShortId();\n let attempts = 0;\n while (existingIds.has(id) && attempts < 100) {\n id = generateShortId();\n attempts++;\n }\n return id;\n}\n\n// --- Checklist parsing ---\n\nconst ITEM_REGEX = /^- \\[([ x!]|>[^\\]]*)\\]\\s+(.+)$/;\nconst ID_REGEX = /\\[t:([a-f0-9]{4})\\]/;\nconst TAG_REGEX = /#([a-zA-Z0-9_-]+)/g;\n\nfunction parseStatus(marker: string): { status: TodoStatus; session: string | null } {\n if (marker === ' ') return { status: 'open', session: null };\n if (marker === 'x') return { status: 'completed', session: null };\n if (marker === '!') return { status: 'blocked', session: null };\n if (marker.startsWith('>:')) return { status: 'in_progress', session: marker.slice(2) };\n if (marker === '>') return { status: 'in_progress', session: null };\n return { status: 'open', session: null };\n}\n\nfunction sanitizeSession(session: string): string {\n // Strip characters that would break the markdown checkbox syntax\n return session.replace(/[\\[\\]]/g, '');\n}\n\nfunction statusToMarker(item: TodoItem): string {\n switch (item.status) {\n case 'open':\n return ' ';\n case 'completed':\n return 'x';\n case 'blocked':\n return '!';\n case 'in_progress':\n return item.session ? `>:${sanitizeSession(item.session)}` : '>';\n }\n}\n\nexport function parseChecklistItem(line: string): TodoItem | null {\n const match = line.match(ITEM_REGEX);\n if (!match) return null;\n\n const marker = match[1];\n const rest = match[2];\n\n const { status, session } = parseStatus(marker);\n\n const idMatch = rest.match(ID_REGEX);\n const id = idMatch ? idMatch[1] : '';\n\n const tags: string[] = [];\n let tagMatch;\n const tagRegex = new RegExp(TAG_REGEX.source, 'g');\n while ((tagMatch = tagRegex.exec(rest)) !== null) {\n tags.push(tagMatch[1]);\n }\n\n // Description is everything before the first #tag or [t:...], trimmed\n let description = rest;\n const firstTagIdx = rest.search(/#[a-zA-Z0-9_-]/);\n const firstIdIdx = rest.search(/\\[t:[a-f0-9]{4}\\]/);\n const cutPoints = [firstTagIdx, firstIdIdx].filter((i) => i >= 0);\n if (cutPoints.length > 0) {\n description = rest.slice(0, Math.min(...cutPoints)).trim();\n }\n\n return { id, description, status, tags, session };\n}\n\nexport function serializeChecklistItem(item: TodoItem): string {\n const marker = statusToMarker(item);\n const tagStr = item.tags.map((t) => `#${t}`).join(' ');\n const parts = [`- [${marker}] ${item.description}`];\n if (tagStr) parts.push(tagStr);\n parts.push(`[t:${item.id}]`);\n return parts.join(' ');\n}\n\nexport function parseChecklist(content: string): TodoChecklist {\n const [fm, body] = extractFrontmatter(content);\n const workspace = getField(fm, 'workspace') || '_global';\n const archiveIntervalRaw = getField(fm, 'archiveInterval') || 'weekly';\n const archiveInterval = (['daily', 'weekly', 'monthly', 'never'].includes(archiveIntervalRaw)\n ? archiveIntervalRaw\n : 'weekly') as ArchiveInterval;\n\n const items: TodoItem[] = [];\n for (const line of body.split('\\n')) {\n const item = parseChecklistItem(line);\n if (item) items.push(item);\n }\n\n return { workspace, archiveInterval, items };\n}\n\nexport function serializeChecklist(checklist: TodoChecklist): string {\n const fm = [\n '---',\n `workspace: ${checklist.workspace}`,\n `archiveInterval: ${checklist.archiveInterval}`,\n '---',\n ].join('\\n');\n\n const header = '# Quick Todos';\n const items = checklist.items.map(serializeChecklistItem).join('\\n');\n\n return `${fm}\\n\\n${header}\\n\\n${items}\\n`;\n}\n\n// --- Log parsing ---\n\nexport function parseLog(content: string): TodoLog {\n const [fm, body] = extractFrontmatter(content);\n const workspace = getField(fm, 'workspace') || '_global';\n\n const entries: LogEntry[] = [];\n const sections = body.split(/^### /m).filter((s) => s.match(/^\\d{4}-/));\n\n for (const section of sections) {\n const lines = section.split('\\n');\n const heading = lines[0]?.trim() || '';\n\n // Heading format: 2026-04-07T14:30:00Z — t:a3f1, t:b7c2\n const headingMatch = heading.match(/^(\\S+)\\s*—?\\s*(.*)/);\n if (!headingMatch) continue;\n\n const timestamp = headingMatch[1];\n const idsPart = headingMatch[2] || '';\n const itemIds = [...idsPart.matchAll(/t:([a-f0-9]{4})/g)].map((m) => m[1]);\n\n const entry: LogEntry = {\n timestamp,\n itemIds,\n items: '',\n session: null,\n branch: null,\n summary: '',\n blockers: null,\n status: null,\n };\n\n for (const line of lines.slice(1)) {\n const fieldMatch = line.match(/^\\*\\*(\\w+):\\*\\*\\s*(.*)/);\n if (!fieldMatch) continue;\n const key = fieldMatch[1].toLowerCase();\n const value = fieldMatch[2].trim();\n switch (key) {\n case 'items':\n entry.items = value;\n break;\n case 'session':\n entry.session = value;\n break;\n case 'branch':\n entry.branch = value;\n break;\n case 'summary':\n entry.summary = value;\n break;\n case 'blockers':\n entry.blockers = value;\n break;\n case 'status':\n entry.status = value;\n break;\n }\n }\n\n entries.push(entry);\n }\n\n return { workspace, entries };\n}\n\nexport function serializeLogEntry(entry: LogEntry): string {\n const idStr = entry.itemIds.map((id) => `t:${id}`).join(', ');\n const lines = [`### ${entry.timestamp} — ${idStr}`];\n if (entry.items) lines.push(`**Items:** ${entry.items}`);\n if (entry.session) lines.push(`**Session:** ${entry.session}`);\n if (entry.branch) lines.push(`**Branch:** ${entry.branch}`);\n if (entry.summary) lines.push(`**Summary:** ${entry.summary}`);\n if (entry.blockers) lines.push(`**Blockers:** ${entry.blockers}`);\n if (entry.status) lines.push(`**Status:** ${entry.status}`);\n return lines.join('\\n');\n}\n\n// --- File I/O ---\n\nexport function checklistPath(todosDir: string, workspace: string): string {\n return resolve(todosDir, `${workspace}.md`);\n}\n\nexport function logPath(todosDir: string, workspace: string): string {\n return resolve(todosDir, `${workspace}-log.md`);\n}\n\nexport function archivePath(\n todosDir: string,\n workspace: string,\n interval: ArchiveInterval,\n now: Date = new Date(),\n): string {\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const day = String(now.getDate()).padStart(2, '0');\n\n let suffix: string;\n switch (interval) {\n case 'daily':\n suffix = `${year}-${month}-${day}`;\n break;\n case 'weekly': {\n // ISO week number\n const jan1 = new Date(year, 0, 1);\n const days = Math.floor((now.getTime() - jan1.getTime()) / 86400000);\n const week = String(Math.ceil((days + jan1.getDay() + 1) / 7)).padStart(2, '0');\n suffix = `${year}-W${week}`;\n break;\n }\n case 'monthly':\n suffix = `${year}-${month}`;\n break;\n default:\n suffix = `${year}-${month}-${day}`;\n }\n\n return resolve(todosDir, 'archive', `${workspace}-${suffix}.md`);\n}\n\nexport async function readChecklist(todosDir: string, workspace: string): Promise<TodoChecklist> {\n const path = checklistPath(todosDir, workspace);\n if (!(await fileExists(path))) {\n return { workspace, archiveInterval: 'weekly', items: [] };\n }\n const content = await readFile(path, 'utf-8');\n return parseChecklist(content);\n}\n\nexport async function writeChecklist(todosDir: string, checklist: TodoChecklist): Promise<void> {\n await ensureDir(todosDir);\n const path = checklistPath(todosDir, checklist.workspace);\n await writeFileForce(path, serializeChecklist(checklist));\n}\n\nexport async function readLog(todosDir: string, workspace: string): Promise<TodoLog> {\n const path = logPath(todosDir, workspace);\n if (!(await fileExists(path))) {\n return { workspace, entries: [] };\n }\n const content = await readFile(path, 'utf-8');\n return parseLog(content);\n}\n\nexport async function appendLogEntry(\n todosDir: string,\n workspace: string,\n entry: LogEntry,\n): Promise<void> {\n await ensureDir(todosDir);\n const path = logPath(todosDir, workspace);\n let content: string;\n if (await fileExists(path)) {\n content = await readFile(path, 'utf-8');\n content = content.trimEnd() + '\\n\\n' + serializeLogEntry(entry) + '\\n';\n } else {\n const fm = `---\\nworkspace: ${workspace}\\n---\\n\\n# Todo Log\\n\\n`;\n content = fm + serializeLogEntry(entry) + '\\n';\n }\n await writeFileForce(path, content);\n}\n\nexport function computeCounts(items: TodoItem[]) {\n const counts = { open: 0, in_progress: 0, completed: 0, blocked: 0, total: items.length };\n for (const item of items) {\n counts[item.status]++;\n }\n return counts;\n}\n","import express from 'express';\nimport { createServer } from 'node:http';\nimport { resolve, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { writeFile, unlink } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\nimport { WebSocketServer, WebSocket } from 'ws';\nimport {\n listMissions,\n listAssignmentsBoard,\n getMissionDetail,\n getAssignmentDetail,\n getOverview,\n getAttention,\n getHelp,\n getStatusConfig,\n clearStatusConfigCache,\n listWorkspaces,\n createWorkspace,\n deleteWorkspace,\n} from './api.js';\nimport { createWatcher } from './watcher.js';\nimport { fileExists } from '../utils/fs.js';\nimport { writeStatusConfig, deleteStatusConfig } from '../utils/config.js';\nimport { createWriteRouter } from './api-write.js';\nimport { createServersRouter } from './api-servers.js';\nimport { createAgentSessionsRouter } from './api-agent-sessions.js';\nimport { createPlaybooksRouter } from './api-playbooks.js';\nimport { createTodosRouter } from './api-todos.js';\nimport { initSessionDb, migrateFromMarkdown, closeSessionDb } from './session-db.js';\nimport { startAutodiscovery, stopAutodiscovery } from './autodiscovery.js';\nimport type { WsMessage } from './types.js';\n\n// When tsup bundles with splitting:false, import.meta.url resolves to the\n// final bundle (dist/index.js), not the original file location. Use one level\n// up from the dist/ directory to find the package root reliably.\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageRoot = resolve(__dirname, '..');\n\nexport interface DashboardServerOptions {\n port: number;\n missionsDir: string;\n serversDir: string;\n playbooksDir: string;\n todosDir: string;\n serveStaticUi: boolean;\n}\n\nexport function createDashboardServer(options: DashboardServerOptions) {\n const { port, missionsDir, serversDir, playbooksDir, todosDir, serveStaticUi } = options;\n const app = express();\n const server = createServer(app);\n\n // --- WebSocket ---\n const wss = new WebSocketServer({ noServer: true });\n const clients = new Set<WebSocket>();\n\n server.on('upgrade', (request, socket, head) => {\n if (request.url === '/ws') {\n wss.handleUpgrade(request, socket, head, (ws) => {\n wss.emit('connection', ws, request);\n });\n } else {\n socket.destroy();\n }\n });\n\n wss.on('connection', (ws) => {\n clients.add(ws);\n const connectMsg: WsMessage = {\n type: 'connected',\n timestamp: new Date().toISOString(),\n };\n ws.send(JSON.stringify(connectMsg));\n\n ws.on('close', () => {\n clients.delete(ws);\n });\n });\n\n function broadcast(message: WsMessage): void {\n const data = JSON.stringify(message);\n for (const client of clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(data);\n }\n }\n }\n\n // --- Initialize session database ---\n initSessionDb();\n migrateFromMarkdown(missionsDir).catch((err) => {\n console.error('Session migration from markdown failed:', err);\n });\n\n // --- JSON body parsing ---\n app.use(express.json());\n\n // --- API Routes ---\n app.get('/api/overview', async (_req, res) => {\n try {\n const overview = await getOverview(missionsDir, serversDir);\n res.json(overview);\n } catch (error) {\n console.error('Error getting overview:', error);\n res.status(500).json({ error: 'Failed to get overview' });\n }\n });\n\n app.get('/api/attention', async (_req, res) => {\n try {\n const attention = await getAttention(missionsDir, serversDir);\n res.json(attention);\n } catch (error) {\n console.error('Error getting attention queue:', error);\n res.status(500).json({ error: 'Failed to get attention queue' });\n }\n });\n\n app.get('/api/help', async (_req, res) => {\n try {\n const help = await getHelp();\n res.json(help);\n } catch (error) {\n console.error('Error getting help content:', error);\n res.status(500).json({ error: 'Failed to get help content' });\n }\n });\n\n app.get('/api/config/statuses', async (_req, res) => {\n try {\n const config = await getStatusConfig();\n res.json({\n statuses: config.statuses,\n order: config.order,\n transitions: config.transitions,\n custom: config.custom,\n });\n } catch (error) {\n console.error('Error getting status config:', error);\n res.status(500).json({ error: 'Failed to get status config' });\n }\n });\n\n app.post('/api/config/statuses', async (req, res) => {\n try {\n const { statuses, order, transitions } = req.body;\n if (!Array.isArray(statuses) || !Array.isArray(order) || !Array.isArray(transitions)) {\n res.status(400).json({ error: 'Request body must include statuses, order, and transitions arrays' });\n return;\n }\n await writeStatusConfig({ statuses, order, transitions });\n clearStatusConfigCache();\n const config = await getStatusConfig();\n res.json({\n statuses: config.statuses,\n order: config.order,\n transitions: config.transitions,\n custom: config.custom,\n });\n } catch (error) {\n console.error('Error saving status config:', error);\n res.status(500).json({ error: 'Failed to save status config' });\n }\n });\n\n app.delete('/api/config/statuses', async (_req, res) => {\n try {\n await deleteStatusConfig();\n clearStatusConfigCache();\n const config = await getStatusConfig();\n res.json({\n statuses: config.statuses,\n order: config.order,\n transitions: config.transitions,\n custom: config.custom,\n });\n } catch (error) {\n console.error('Error resetting status config:', error);\n res.status(500).json({ error: 'Failed to reset status config' });\n }\n });\n\n app.get('/api/missions', async (req, res) => {\n try {\n let missions = await listMissions(missionsDir);\n const workspaceParam = req.query.workspace as string | undefined;\n if (workspaceParam) {\n if (workspaceParam === '_ungrouped') {\n missions = missions.filter((m) => m.workspace === null);\n } else {\n missions = missions.filter((m) => m.workspace === workspaceParam);\n }\n }\n res.json(missions);\n } catch (error) {\n console.error('Error listing missions:', error);\n res.status(500).json({ error: 'Failed to list missions' });\n }\n });\n\n app.get('/api/workspaces', async (_req, res) => {\n try {\n const result = await listWorkspaces(missionsDir);\n res.json(result);\n } catch (error) {\n console.error('Error listing workspaces:', error);\n res.status(500).json({ error: 'Failed to list workspaces' });\n }\n });\n\n app.post('/api/workspaces', async (req, res) => {\n try {\n const { name } = req.body;\n if (!name || typeof name !== 'string' || !/^[a-z0-9][a-z0-9-]*$/.test(name)) {\n res.status(400).json({ error: 'Invalid workspace name. Use lowercase letters, numbers, and hyphens.' });\n return;\n }\n await createWorkspace(missionsDir, name);\n broadcast({ type: 'mission-updated', missionSlug: '', timestamp: new Date().toISOString() });\n res.json({ name });\n } catch (error) {\n console.error('Error creating workspace:', error);\n res.status(500).json({ error: 'Failed to create workspace' });\n }\n });\n\n app.delete('/api/workspaces/:name', async (req, res) => {\n try {\n await deleteWorkspace(missionsDir, req.params.name);\n broadcast({ type: 'mission-updated', missionSlug: '', timestamp: new Date().toISOString() });\n res.json({ ok: true });\n } catch (error) {\n console.error('Error deleting workspace:', error);\n res.status(500).json({ error: 'Failed to delete workspace' });\n }\n });\n\n app.get('/api/assignments', async (req, res) => {\n try {\n const result = await listAssignmentsBoard(missionsDir);\n const workspaceParam = req.query.workspace as string | undefined;\n if (workspaceParam) {\n if (workspaceParam === '_ungrouped') {\n result.assignments = result.assignments.filter((a) => a.missionWorkspace === null);\n } else {\n result.assignments = result.assignments.filter((a) => a.missionWorkspace === workspaceParam);\n }\n }\n res.json(result);\n } catch (error) {\n console.error('Error listing assignments:', error);\n res.status(500).json({ error: 'Failed to list assignments' });\n }\n });\n\n app.get('/api/missions/:slug', async (req, res) => {\n try {\n const detail = await getMissionDetail(missionsDir, req.params.slug);\n if (!detail) {\n res.status(404).json({ error: `Mission \"${req.params.slug}\" not found` });\n return;\n }\n res.json(detail);\n } catch (error) {\n console.error('Error getting mission detail:', error);\n res.status(500).json({ error: 'Failed to get mission detail' });\n }\n });\n\n app.get('/api/missions/:slug/assignments/:aslug', async (req, res) => {\n try {\n const detail = await getAssignmentDetail(\n missionsDir,\n req.params.slug,\n req.params.aslug,\n );\n if (!detail) {\n res.status(404).json({\n error: `Assignment \"${req.params.aslug}\" not found in mission \"${req.params.slug}\"`,\n });\n return;\n }\n res.json(detail);\n } catch (error) {\n console.error('Error getting assignment detail:', error);\n res.status(500).json({ error: 'Failed to get assignment detail' });\n }\n });\n\n // --- Write API (create missions/assignments) ---\n app.use(createWriteRouter(missionsDir));\n\n // --- Servers API ---\n app.use('/api/servers', createServersRouter(serversDir, missionsDir));\n\n // --- Agent Sessions API ---\n app.use('/api/agent-sessions', createAgentSessionsRouter(missionsDir, broadcast));\n\n // --- Playbooks API ---\n app.use('/api/playbooks', createPlaybooksRouter(playbooksDir));\n\n // --- Todos API ---\n app.use('/api/todos', createTodosRouter(todosDir, broadcast));\n\n // --- Static files (production only) ---\n if (serveStaticUi) {\n const dashboardDistPath = resolve(packageRoot, 'dashboard', 'dist');\n app.use(express.static(dashboardDistPath));\n\n // SPA fallback: serve index.html for all non-API routes\n // Express 5 requires named wildcards; use '{*path}' instead of '*'\n app.get('{*path}', async (_req: any, res: any) => {\n const indexPath = resolve(dashboardDistPath, 'index.html');\n if (await fileExists(indexPath)) {\n res.sendFile(indexPath);\n } else {\n res.status(503).send(\n 'Dashboard not built. Run \"npm run build:dashboard\" first.',\n );\n }\n });\n }\n\n // --- File watcher ---\n let watcherHandle: { close: () => Promise<void> } | null = null;\n\n return {\n async start(): Promise<void> {\n watcherHandle = createWatcher({\n missionsDir,\n serversDir,\n playbooksDir,\n todosDir,\n onMessage: broadcast,\n });\n\n startAutodiscovery({ serversDir, missionsDir, excludePids: new Set([process.pid]) });\n\n return new Promise<void>((resolvePromise, reject) => {\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n reject(new Error(\n `Port ${port} is already in use. Use --port <number> to specify a different port.`,\n ));\n } else {\n reject(err);\n }\n });\n server.listen(port, () => {\n const portFile = resolve(homedir(), '.syntaur', 'dashboard-port');\n writeFile(portFile, String(port), 'utf-8').catch(() => {});\n resolvePromise();\n });\n });\n },\n\n async stop(): Promise<void> {\n await stopAutodiscovery();\n if (watcherHandle) {\n await watcherHandle.close();\n }\n closeSessionDb();\n for (const client of clients) {\n client.close();\n }\n clients.clear();\n const portFile = resolve(homedir(), '.syntaur', 'dashboard-port');\n await unlink(portFile).catch(() => {});\n return new Promise<void>((resolvePromise) => {\n server.close(() => resolvePromise());\n });\n },\n\n get port(): number {\n return port;\n },\n };\n}\n","import { watch } from 'chokidar';\nimport { relative, sep } from 'node:path';\nimport type { WsMessage } from './types.js';\n\nexport interface WatcherOptions {\n missionsDir: string;\n serversDir?: string;\n playbooksDir?: string;\n todosDir?: string;\n onMessage: (message: WsMessage) => void;\n debounceMs?: number;\n}\n\nexport function createWatcher(options: WatcherOptions): { close: () => Promise<void> } {\n const { missionsDir, serversDir, playbooksDir, todosDir, onMessage, debounceMs = 300 } = options;\n const pendingEvents = new Map<string, NodeJS.Timeout>();\n\n // --- Missions watcher (existing logic) ---\n const missionsWatcher = watch(missionsDir, {\n ignoreInitial: true,\n persistent: true,\n depth: 10,\n ignored: /(^|[\\/\\\\])\\../,\n });\n\n function handleMissionChange(filePath: string): void {\n const rel = relative(missionsDir, filePath);\n const parts = rel.split(sep);\n\n if (parts.length === 0) return;\n\n const missionSlug = parts[0];\n let assignmentSlug: string | undefined;\n\n if (parts.length >= 3 && parts[1] === 'assignments') {\n assignmentSlug = parts[2];\n }\n\n const debounceKey = assignmentSlug\n ? `${missionSlug}/${assignmentSlug}`\n : missionSlug;\n\n const existing = pendingEvents.get(debounceKey);\n if (existing) clearTimeout(existing);\n\n // Session events are now emitted by the API write path, not the file watcher\n const messageType = assignmentSlug\n ? 'assignment-updated'\n : 'mission-updated';\n\n pendingEvents.set(\n debounceKey,\n setTimeout(() => {\n pendingEvents.delete(debounceKey);\n const message: WsMessage = {\n type: messageType,\n missionSlug,\n assignmentSlug,\n timestamp: new Date().toISOString(),\n };\n onMessage(message);\n }, debounceMs),\n );\n }\n\n missionsWatcher.on('change', handleMissionChange);\n missionsWatcher.on('add', handleMissionChange);\n missionsWatcher.on('unlink', handleMissionChange);\n\n // --- Servers watcher (new) ---\n let serversWatcher: ReturnType<typeof watch> | null = null;\n\n if (serversDir) {\n serversWatcher = watch(serversDir, {\n ignoreInitial: true,\n persistent: true,\n depth: 1,\n ignored: /(^|[\\/\\\\])\\../,\n });\n\n function handleServerChange(): void {\n const debounceKey = '__servers__';\n const existing = pendingEvents.get(debounceKey);\n if (existing) clearTimeout(existing);\n\n pendingEvents.set(\n debounceKey,\n setTimeout(() => {\n pendingEvents.delete(debounceKey);\n const message: WsMessage = {\n type: 'servers-updated',\n timestamp: new Date().toISOString(),\n };\n onMessage(message);\n }, debounceMs),\n );\n }\n\n serversWatcher.on('change', handleServerChange);\n serversWatcher.on('add', handleServerChange);\n serversWatcher.on('unlink', handleServerChange);\n }\n\n // --- Playbooks watcher ---\n let playbooksWatcher: ReturnType<typeof watch> | null = null;\n\n if (playbooksDir) {\n playbooksWatcher = watch(playbooksDir, {\n ignoreInitial: true,\n persistent: true,\n depth: 1,\n ignored: /(^|[\\/\\\\])\\../,\n });\n\n function handlePlaybookChange(): void {\n const debounceKey = '__playbooks__';\n const existing = pendingEvents.get(debounceKey);\n if (existing) clearTimeout(existing);\n\n pendingEvents.set(\n debounceKey,\n setTimeout(() => {\n pendingEvents.delete(debounceKey);\n const message: WsMessage = {\n type: 'playbooks-updated',\n timestamp: new Date().toISOString(),\n };\n onMessage(message);\n }, debounceMs),\n );\n }\n\n playbooksWatcher.on('change', handlePlaybookChange);\n playbooksWatcher.on('add', handlePlaybookChange);\n playbooksWatcher.on('unlink', handlePlaybookChange);\n }\n\n // --- Todos watcher ---\n let todosWatcher: ReturnType<typeof watch> | null = null;\n\n if (todosDir) {\n todosWatcher = watch(todosDir, {\n ignoreInitial: true,\n persistent: true,\n depth: 1,\n ignored: /(^|[\\/\\\\])\\../,\n });\n\n function handleTodoChange(): void {\n const debounceKey = '__todos__';\n const existing = pendingEvents.get(debounceKey);\n if (existing) clearTimeout(existing);\n\n pendingEvents.set(\n debounceKey,\n setTimeout(() => {\n pendingEvents.delete(debounceKey);\n const message: WsMessage = {\n type: 'todos-updated',\n timestamp: new Date().toISOString(),\n };\n onMessage(message);\n }, debounceMs),\n );\n }\n\n todosWatcher.on('change', handleTodoChange);\n todosWatcher.on('add', handleTodoChange);\n todosWatcher.on('unlink', handleTodoChange);\n }\n\n return {\n close: async () => {\n pendingEvents.forEach((timeout) => {\n clearTimeout(timeout);\n });\n pendingEvents.clear();\n await missionsWatcher.close();\n if (serversWatcher) await serversWatcher.close();\n if (playbooksWatcher) await playbooksWatcher.close();\n if (todosWatcher) await todosWatcher.close();\n },\n };\n}\n","import { Router, type Request, type Response } from 'express';\nimport { resolve } from 'node:path';\nimport { rm, readFile } from 'node:fs/promises';\nimport { executeTransition } from '../lifecycle/index.js';\nimport { isValidSlug } from '../utils/slug.js';\nimport { generateId } from '../utils/uuid.js';\nimport { nowTimestamp } from '../utils/timestamp.js';\nimport { ensureDir, writeFileForce, fileExists } from '../utils/fs.js';\nimport {\n parseAssignmentFull,\n parseDecisionRecord,\n parseHandoff,\n parseMission,\n parsePlan,\n parseScratchpad,\n} from './parser.js';\nimport { toggleAcceptanceCriterion } from './acceptance-criteria.js';\nimport {\n getAssignmentDetail,\n getEditableDocument,\n getMissionDetail,\n getStatusConfig,\n} from './api.js';\nimport {\n renderMission,\n renderManifest,\n renderAgent,\n renderClaude,\n renderIndexAssignments,\n renderIndexPlans,\n renderIndexDecisions,\n renderStatus,\n renderResourcesIndex,\n renderMemoriesIndex,\n renderAssignment,\n renderPlan,\n renderScratchpad,\n renderHandoff,\n renderDecisionRecord,\n} from '../templates/index.js';\n\nfunction extractFrontmatter(content: string): Record<string, string> | null {\n const trimmed = content.trimStart();\n if (!trimmed.startsWith('---\\n') && !trimmed.startsWith('---\\r\\n')) {\n return null;\n }\n\n const afterFirst = trimmed.indexOf('\\n') + 1;\n const closingIdx = trimmed.indexOf('\\n---', afterFirst);\n if (closingIdx === -1) {\n return null;\n }\n\n const yamlBlock = trimmed.slice(afterFirst, closingIdx);\n const fields: Record<string, string> = {};\n\n for (const line of yamlBlock.split('\\n')) {\n const match = line.match(/^([a-zA-Z_][a-zA-Z0-9_]*):\\s*(.*)$/);\n if (!match) {\n continue;\n }\n\n let value = match[2].trim();\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n fields[match[1]] = value;\n }\n\n return fields;\n}\n\nfunction validateRequired(\n fields: Record<string, string>,\n required: string[],\n): { valid: true } | { valid: false; missing: string[] } {\n const missing = required.filter((key) => !fields[key] || fields[key] === 'null');\n if (missing.length > 0) {\n return { valid: false, missing };\n }\n return { valid: true };\n}\n\nfunction formatYamlValue(value: boolean | number | string | null): string {\n if (value === null) {\n return 'null';\n }\n if (typeof value === 'boolean' || typeof value === 'number') {\n return String(value);\n }\n if (/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) {\n return `\"${value}\"`;\n }\n if (value === '' || /[:#{}[\\],&*?|>!%@`]/.test(value) || /^\\s|\\s$/.test(value)) {\n return `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\n }\n return value;\n}\n\nfunction setTopLevelField(\n content: string,\n key: string,\n value: boolean | number | string | null,\n): string {\n const formatted = formatYamlValue(value);\n const fieldRegex = new RegExp(`^(${escapeRegExp(key)}:)\\\\s*.*$`, 'm');\n\n if (fieldRegex.test(content)) {\n return content.replace(fieldRegex, `$1 ${formatted}`);\n }\n\n const closingIdx = content.indexOf('\\n---', 4);\n if (closingIdx === -1) {\n return content;\n }\n\n return `${content.slice(0, closingIdx)}\\n${key}: ${formatted}${content.slice(closingIdx)}`;\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction appendLogEntry(\n existingContent: string,\n countField: 'handoffCount' | 'decisionCount',\n nextCount: number,\n heading: string,\n body: string,\n emptyPlaceholder: string,\n): string {\n const timestamp = nowTimestamp();\n let next = setTopLevelField(existingContent, 'updated', timestamp);\n next = setTopLevelField(next, countField, nextCount);\n\n const entryBody = body.trim();\n const entry = `## ${heading}\\n\\n**Recorded:** ${timestamp}\\n\\n${entryBody}\\n`;\n\n if (next.includes(emptyPlaceholder)) {\n return next.replace(emptyPlaceholder, entry.trimEnd());\n }\n\n return `${next.trimEnd()}\\n\\n${entry}`;\n}\n\nfunction requireContent(req: Request, res: Response): string | null {\n const { content } = req.body || {};\n if (!content || typeof content !== 'string' || !content.trim()) {\n res.status(400).json({ error: 'content is required' });\n return null;\n }\n return content;\n}\n\nfunction getParam(value: string | string[] | undefined): string {\n if (Array.isArray(value)) {\n return value[0] ?? '';\n }\n return value ?? '';\n}\n\nasync function readCurrentDocument(filePath: string): Promise<string | null> {\n if (!(await fileExists(filePath))) {\n return null;\n }\n return readFile(filePath, 'utf-8');\n}\n\nexport function createWriteRouter(missionsDir: string): Router {\n const router = Router();\n\n router.get('/api/templates/mission', (_req: Request, res: Response) => {\n const content = renderMission({\n id: generateId(),\n slug: 'my-new-mission',\n title: 'My New Mission',\n timestamp: nowTimestamp(),\n });\n res.json({ content });\n });\n\n router.get('/api/templates/assignment', (_req: Request, res: Response) => {\n const content = renderAssignment({\n id: generateId(),\n slug: 'my-new-assignment',\n title: 'My New Assignment',\n timestamp: nowTimestamp(),\n priority: 'medium',\n dependsOn: [],\n });\n res.json({ content });\n });\n\n router.get('/api/missions/:slug/edit', async (req: Request, res: Response) => {\n const slug = getParam(req.params.slug);\n const document = await getEditableDocument(missionsDir, 'mission', slug);\n if (!document) {\n res.status(404).json({ error: `Mission \"${slug}\" not found` });\n return;\n }\n res.json(document);\n });\n\n router.get('/api/missions/:slug/assignments/:aslug/edit', async (req: Request, res: Response) => {\n const slug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const document = await getEditableDocument(\n missionsDir,\n 'assignment',\n slug,\n assignmentSlug,\n );\n if (!document) {\n res.status(404).json({ error: 'Assignment not found' });\n return;\n }\n res.json(document);\n });\n\n router.get('/api/missions/:slug/assignments/:aslug/plan/edit', async (req: Request, res: Response) => {\n const slug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const document = await getEditableDocument(\n missionsDir,\n 'plan',\n slug,\n assignmentSlug,\n );\n if (!document) {\n res.status(404).json({ error: 'Plan not found' });\n return;\n }\n res.json(document);\n });\n\n router.get('/api/missions/:slug/assignments/:aslug/scratchpad/edit', async (req: Request, res: Response) => {\n const slug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const document = await getEditableDocument(\n missionsDir,\n 'scratchpad',\n slug,\n assignmentSlug,\n );\n if (!document) {\n res.status(404).json({ error: 'Scratchpad not found' });\n return;\n }\n res.json(document);\n });\n\n router.get('/api/missions/:slug/assignments/:aslug/handoff/edit', async (req: Request, res: Response) => {\n const slug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const document = await getEditableDocument(\n missionsDir,\n 'handoff',\n slug,\n assignmentSlug,\n );\n if (!document) {\n res.status(404).json({ error: 'Handoff log not found' });\n return;\n }\n res.json(document);\n });\n\n router.get('/api/missions/:slug/assignments/:aslug/decision-record/edit', async (req: Request, res: Response) => {\n const slug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const document = await getEditableDocument(\n missionsDir,\n 'decision-record',\n slug,\n assignmentSlug,\n );\n if (!document) {\n res.status(404).json({ error: 'Decision record not found' });\n return;\n }\n res.json(document);\n });\n\n router.post('/api/missions', async (req: Request, res: Response) => {\n try {\n const content = requireContent(req, res);\n if (!content) {\n return;\n }\n\n const fields = extractFrontmatter(content);\n if (!fields) {\n res.status(400).json({ error: 'Invalid frontmatter: missing --- delimiters' });\n return;\n }\n\n const validation = validateRequired(fields, ['slug', 'title']);\n if (!validation.valid) {\n res.status(400).json({ error: `Missing required fields: ${validation.missing.join(', ')}` });\n return;\n }\n\n const slug = fields.slug;\n if (!isValidSlug(slug)) {\n res.status(400).json({ error: `Invalid slug \"${slug}\". Must be lowercase and hyphen-separated.` });\n return;\n }\n\n const missionDir = resolve(missionsDir, slug);\n if (await fileExists(missionDir)) {\n res.status(409).json({ error: `Mission \"${slug}\" already exists` });\n return;\n }\n\n const title = fields.title;\n const timestamp = fields.created || nowTimestamp();\n\n await ensureDir(resolve(missionDir, 'assignments'));\n await ensureDir(resolve(missionDir, 'resources'));\n await ensureDir(resolve(missionDir, 'memories'));\n\n await writeFileForce(resolve(missionDir, 'mission.md'), content);\n\n try {\n const companions: Array<[string, string]> = [\n [resolve(missionDir, 'manifest.md'), renderManifest({ slug, timestamp })],\n [resolve(missionDir, 'agent.md'), renderAgent({ slug, timestamp })],\n [resolve(missionDir, 'claude.md'), renderClaude({ slug })],\n [resolve(missionDir, '_index-assignments.md'), renderIndexAssignments({ slug, title, timestamp })],\n [resolve(missionDir, '_index-plans.md'), renderIndexPlans({ slug, title, timestamp })],\n [resolve(missionDir, '_index-decisions.md'), renderIndexDecisions({ slug, title, timestamp })],\n [resolve(missionDir, '_status.md'), renderStatus({ slug, title, timestamp })],\n [resolve(missionDir, 'resources', '_index.md'), renderResourcesIndex({ slug, title, timestamp })],\n [resolve(missionDir, 'memories', '_index.md'), renderMemoriesIndex({ slug, title, timestamp })],\n ];\n\n for (const [filePath, fileContent] of companions) {\n await writeFileForce(filePath, fileContent);\n }\n } catch (companionError) {\n try {\n await rm(missionDir, { recursive: true, force: true });\n } catch {\n // Best effort cleanup only.\n }\n throw companionError;\n }\n\n res.status(201).json({ slug });\n } catch (error) {\n console.error('Error creating mission:', error);\n res.status(500).json({ error: `Failed to create mission: ${(error as Error).message}` });\n }\n });\n\n router.post('/api/missions/:slug/assignments', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const missionDir = resolve(missionsDir, missionSlug);\n const missionMdPath = resolve(missionDir, 'mission.md');\n\n if (!(await fileExists(missionMdPath))) {\n res.status(404).json({ error: `Mission \"${missionSlug}\" not found` });\n return;\n }\n\n const content = requireContent(req, res);\n if (!content) {\n return;\n }\n\n const fields = extractFrontmatter(content);\n if (!fields) {\n res.status(400).json({ error: 'Invalid frontmatter: missing --- delimiters' });\n return;\n }\n\n const validation = validateRequired(fields, ['slug', 'title']);\n if (!validation.valid) {\n res.status(400).json({ error: `Missing required fields: ${validation.missing.join(', ')}` });\n return;\n }\n\n const assignmentSlug = fields.slug;\n if (!isValidSlug(assignmentSlug)) {\n res.status(400).json({ error: `Invalid slug \"${assignmentSlug}\". Must be lowercase and hyphen-separated.` });\n return;\n }\n\n const validPriorities = ['low', 'medium', 'high', 'critical'];\n const priority = fields.priority || 'medium';\n if (!validPriorities.includes(priority)) {\n res.status(400).json({ error: `Invalid priority \"${priority}\". Must be low, medium, high, or critical.` });\n return;\n }\n\n const assignmentDir = resolve(missionDir, 'assignments', assignmentSlug);\n if (await fileExists(assignmentDir)) {\n res.status(409).json({\n error: `Assignment \"${assignmentSlug}\" already exists in mission \"${missionSlug}\"`,\n });\n return;\n }\n\n const title = fields.title;\n const timestamp = fields.created || nowTimestamp();\n\n await ensureDir(assignmentDir);\n await writeFileForce(resolve(assignmentDir, 'assignment.md'), content);\n\n try {\n const companions: Array<[string, string]> = [\n [resolve(assignmentDir, 'plan.md'), renderPlan({ assignmentSlug, title, timestamp })],\n [resolve(assignmentDir, 'scratchpad.md'), renderScratchpad({ assignmentSlug, timestamp })],\n [resolve(assignmentDir, 'handoff.md'), renderHandoff({ assignmentSlug, timestamp })],\n [resolve(assignmentDir, 'decision-record.md'), renderDecisionRecord({ assignmentSlug, timestamp })],\n ];\n\n for (const [filePath, fileContent] of companions) {\n await writeFileForce(filePath, fileContent);\n }\n } catch (companionError) {\n try {\n await rm(assignmentDir, { recursive: true, force: true });\n } catch {\n // Best effort cleanup only.\n }\n throw companionError;\n }\n\n res.status(201).json({ slug: assignmentSlug, missionSlug });\n } catch (error) {\n console.error('Error creating assignment:', error);\n res.status(500).json({ error: `Failed to create assignment: ${(error as Error).message}` });\n }\n });\n\n router.patch('/api/missions/:slug', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const missionPath = resolve(missionsDir, missionSlug, 'mission.md');\n const currentContent = await readCurrentDocument(missionPath);\n if (!currentContent) {\n res.status(404).json({ error: `Mission \"${missionSlug}\" not found` });\n return;\n }\n\n const nextContentRaw = requireContent(req, res);\n if (!nextContentRaw) {\n return;\n }\n\n const current = parseMission(currentContent);\n const next = parseMission(nextContentRaw);\n\n if (!next.slug || !next.title) {\n res.status(400).json({ error: 'Mission content must include slug and title.' });\n return;\n }\n\n if (next.slug !== current.slug) {\n res.status(400).json({ error: 'Mission slug cannot be changed once created.' });\n return;\n }\n\n const nextContent = setTopLevelField(nextContentRaw, 'updated', nowTimestamp());\n await writeFileForce(missionPath, nextContent);\n\n const mission = await getMissionDetail(missionsDir, missionSlug);\n res.json({ mission, content: nextContent });\n } catch (error) {\n console.error('Error updating mission:', error);\n res.status(500).json({ error: `Failed to update mission: ${(error as Error).message}` });\n }\n });\n\n router.patch('/api/missions/:slug/assignments/:aslug', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const assignmentPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'assignment.md',\n );\n const currentContent = await readCurrentDocument(assignmentPath);\n if (!currentContent) {\n res.status(404).json({ error: 'Assignment not found' });\n return;\n }\n\n const nextContentRaw = requireContent(req, res);\n if (!nextContentRaw) {\n return;\n }\n\n const current = parseAssignmentFull(currentContent);\n const next = parseAssignmentFull(nextContentRaw);\n\n if (!next.slug || !next.title) {\n res.status(400).json({ error: 'Assignment content must include slug and title.' });\n return;\n }\n\n if (next.slug !== current.slug) {\n res.status(400).json({ error: 'Assignment slug cannot be changed once created.' });\n return;\n }\n\n let nextContent = nextContentRaw;\n\n // Clear blockedReason when status moves away from blocked\n if (next.status !== current.status && current.status === 'blocked' && next.status !== 'blocked') {\n nextContent = setTopLevelField(nextContent, 'blockedReason', null);\n }\n\n nextContent = setTopLevelField(nextContent, 'updated', nowTimestamp());\n await writeFileForce(assignmentPath, nextContent);\n\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.json({ assignment, content: nextContent });\n } catch (error) {\n console.error('Error updating assignment:', error);\n res.status(500).json({ error: `Failed to update assignment: ${(error as Error).message}` });\n }\n });\n\n router.patch('/api/missions/:slug/assignments/:aslug/acceptance-criteria/:index', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const assignmentPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'assignment.md',\n );\n const currentContent = await readCurrentDocument(assignmentPath);\n if (!currentContent) {\n res.status(404).json({ error: 'Assignment not found' });\n return;\n }\n\n const { checked } = req.body || {};\n if (typeof checked !== 'boolean') {\n res.status(400).json({ error: 'checked must be a boolean' });\n return;\n }\n\n const index = Number.parseInt(getParam(req.params.index), 10);\n const result = toggleAcceptanceCriterion(currentContent, index, checked);\n if ('error' in result) {\n res.status(400).json({ error: result.error });\n return;\n }\n\n const nextContent = setTopLevelField(result.content, 'updated', nowTimestamp());\n await writeFileForce(assignmentPath, nextContent);\n\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.json({ assignment, content: nextContent });\n } catch (error) {\n console.error('Error toggling acceptance criterion:', error);\n res.status(500).json({ error: `Failed to toggle acceptance criterion: ${(error as Error).message}` });\n }\n });\n\n router.patch('/api/missions/:slug/assignments/:aslug/plan', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const planPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'plan.md',\n );\n const currentContent = await readCurrentDocument(planPath);\n if (!currentContent) {\n res.status(404).json({ error: 'Plan not found' });\n return;\n }\n\n const nextContentRaw = requireContent(req, res);\n if (!nextContentRaw) {\n return;\n }\n\n const next = parsePlan(nextContentRaw);\n if (!next.assignment) {\n res.status(400).json({ error: 'Plan content must include the assignment field.' });\n return;\n }\n\n if (next.assignment !== assignmentSlug) {\n res.status(400).json({ error: 'Plan assignment field must match the route assignment slug.' });\n return;\n }\n\n const nextContent = setTopLevelField(nextContentRaw, 'updated', nowTimestamp());\n await writeFileForce(planPath, nextContent);\n\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.json({ assignment, content: nextContent });\n } catch (error) {\n console.error('Error updating plan:', error);\n res.status(500).json({ error: `Failed to update plan: ${(error as Error).message}` });\n }\n });\n\n router.patch('/api/missions/:slug/assignments/:aslug/scratchpad', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const scratchpadPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'scratchpad.md',\n );\n const currentContent = await readCurrentDocument(scratchpadPath);\n if (!currentContent) {\n res.status(404).json({ error: 'Scratchpad not found' });\n return;\n }\n\n const nextContentRaw = requireContent(req, res);\n if (!nextContentRaw) {\n return;\n }\n\n const next = parseScratchpad(nextContentRaw);\n if (!next.assignment) {\n res.status(400).json({ error: 'Scratchpad content must include the assignment field.' });\n return;\n }\n\n if (next.assignment !== assignmentSlug) {\n res.status(400).json({ error: 'Scratchpad assignment field must match the route assignment slug.' });\n return;\n }\n\n const nextContent = setTopLevelField(nextContentRaw, 'updated', nowTimestamp());\n await writeFileForce(scratchpadPath, nextContent);\n\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.json({ assignment, content: nextContent });\n } catch (error) {\n console.error('Error updating scratchpad:', error);\n res.status(500).json({ error: `Failed to update scratchpad: ${(error as Error).message}` });\n }\n });\n\n router.post('/api/missions/:slug/assignments/:aslug/handoff/entries', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const handoffPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'handoff.md',\n );\n const currentContent = await readCurrentDocument(handoffPath);\n if (!currentContent) {\n res.status(404).json({ error: 'Handoff log not found' });\n return;\n }\n\n const { title, body } = req.body || {};\n if (!body || typeof body !== 'string' || !body.trim()) {\n res.status(400).json({ error: 'body is required' });\n return;\n }\n\n const parsed = parseHandoff(currentContent);\n const nextContent = appendLogEntry(\n currentContent,\n 'handoffCount',\n parsed.handoffCount + 1,\n title && typeof title === 'string' && title.trim() ? title.trim() : `Handoff ${parsed.handoffCount + 1}`,\n body,\n 'No handoffs recorded yet.',\n );\n\n await writeFileForce(handoffPath, nextContent);\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.status(201).json({ assignment, content: nextContent });\n } catch (error) {\n console.error('Error appending handoff entry:', error);\n res.status(500).json({ error: `Failed to append handoff entry: ${(error as Error).message}` });\n }\n });\n\n router.post('/api/missions/:slug/assignments/:aslug/decision-record/entries', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const decisionPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'decision-record.md',\n );\n const currentContent = await readCurrentDocument(decisionPath);\n if (!currentContent) {\n res.status(404).json({ error: 'Decision record not found' });\n return;\n }\n\n const { title, body } = req.body || {};\n if (!body || typeof body !== 'string' || !body.trim()) {\n res.status(400).json({ error: 'body is required' });\n return;\n }\n\n const parsed = parseDecisionRecord(currentContent);\n const nextContent = appendLogEntry(\n currentContent,\n 'decisionCount',\n parsed.decisionCount + 1,\n title && typeof title === 'string' && title.trim() ? title.trim() : `Decision ${parsed.decisionCount + 1}`,\n body,\n 'No decisions recorded yet.',\n );\n\n await writeFileForce(decisionPath, nextContent);\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.status(201).json({ assignment, content: nextContent });\n } catch (error) {\n console.error('Error appending decision entry:', error);\n res.status(500).json({ error: `Failed to append decision entry: ${(error as Error).message}` });\n }\n });\n\n // --- Move Workspace Endpoint ---\n\n router.post('/api/missions/:slug/move-workspace', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const missionPath = resolve(missionsDir, missionSlug, 'mission.md');\n if (!(await fileExists(missionPath))) {\n res.status(404).json({ error: `Mission \"${missionSlug}\" not found` });\n return;\n }\n\n const { workspace } = req.body || {};\n if (workspace !== null && (typeof workspace !== 'string' || !workspace.trim())) {\n res.status(400).json({ error: 'workspace must be a non-empty string or null (for ungrouped).' });\n return;\n }\n\n let content = await readFile(missionPath, 'utf-8');\n content = setTopLevelField(content, 'workspace', workspace ?? null);\n content = setTopLevelField(content, 'updated', nowTimestamp());\n await writeFileForce(missionPath, content);\n\n const mission = await getMissionDetail(missionsDir, missionSlug);\n res.json({ mission });\n } catch (error) {\n console.error('Error moving mission workspace:', error);\n res.status(500).json({ error: `Failed to move workspace: ${(error as Error).message}` });\n }\n });\n\n // --- Status Override Endpoints ---\n\n router.post('/api/missions/:slug/status-override', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const missionPath = resolve(missionsDir, missionSlug, 'mission.md');\n if (!(await fileExists(missionPath))) {\n res.status(404).json({ error: `Mission \"${missionSlug}\" not found` });\n return;\n }\n\n const { status } = req.body || {};\n const config = await getStatusConfig();\n const validStatuses = ['active', 'archived', ...config.statuses.map((s) => s.id)];\n if (status !== null && (typeof status !== 'string' || !validStatuses.includes(status))) {\n res.status(400).json({ error: `Invalid status. Must be one of: ${validStatuses.join(', ')}, or null to clear.` });\n return;\n }\n\n let content = await readFile(missionPath, 'utf-8');\n content = setTopLevelField(content, 'statusOverride', status ?? null);\n content = setTopLevelField(content, 'updated', nowTimestamp());\n await writeFileForce(missionPath, content);\n\n const mission = await getMissionDetail(missionsDir, missionSlug);\n res.json({ mission });\n } catch (error) {\n console.error('Error setting mission status override:', error);\n res.status(500).json({ error: `Failed to set status override: ${(error as Error).message}` });\n }\n });\n\n router.post('/api/missions/:slug/assignments/:aslug/status-override', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const assignmentPath = resolve(\n missionsDir,\n missionSlug,\n 'assignments',\n assignmentSlug,\n 'assignment.md',\n );\n if (!(await fileExists(assignmentPath))) {\n res.status(404).json({ error: 'Assignment not found' });\n return;\n }\n\n const { status } = req.body || {};\n const config = await getStatusConfig();\n const validStatuses = config.statuses.map((s) => s.id);\n if (typeof status !== 'string' || !validStatuses.includes(status)) {\n res.status(400).json({ error: `Invalid status. Must be one of: ${validStatuses.join(', ')}.` });\n return;\n }\n\n let content = await readFile(assignmentPath, 'utf-8');\n content = setTopLevelField(content, 'status', status);\n content = setTopLevelField(content, 'updated', nowTimestamp());\n\n // Clear blockedReason when moving away from blocked\n if (status !== 'blocked') {\n content = setTopLevelField(content, 'blockedReason', null);\n }\n\n await writeFileForce(assignmentPath, content);\n\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.json({ assignment });\n } catch (error) {\n console.error('Error overriding assignment status:', error);\n res.status(500).json({ error: `Failed to override status: ${(error as Error).message}` });\n }\n });\n\n // --- Lifecycle Transitions ---\n\n router.post('/api/missions/:slug/assignments/:aslug/transitions/:command', async (req: Request, res: Response) => {\n try {\n const missionSlug = getParam(req.params.slug);\n const assignmentSlug = getParam(req.params.aslug);\n const command = req.params.command as Parameters<typeof executeTransition>[2];\n const config = await getStatusConfig();\n const validCommands = [...new Set(config.transitions.map((t) => t.command))];\n if (!validCommands.includes(command)) {\n res.status(400).json({ error: `Unsupported transition command \"${req.params.command}\"` });\n return;\n }\n\n const missionDir = resolve(missionsDir, missionSlug);\n const assignmentPath = resolve(missionDir, 'assignments', assignmentSlug, 'assignment.md');\n if (!(await fileExists(assignmentPath))) {\n res.status(404).json({ error: 'Assignment not found' });\n return;\n }\n\n const { reason } = req.body || {};\n const result = await executeTransition(missionDir, assignmentSlug, command, {\n reason: typeof reason === 'string' ? reason : undefined,\n transitionTable: config.custom ? config.transitionTable : undefined,\n terminalStatuses: config.custom ? config.terminalStatuses : undefined,\n });\n\n if (!result.success) {\n res.status(400).json({ error: result.message });\n return;\n }\n\n const assignment = await getAssignmentDetail(missionsDir, missionSlug, assignmentSlug);\n res.json({ assignment, transition: result });\n } catch (error) {\n console.error('Error running assignment transition:', error);\n res.status(500).json({ error: `Failed to transition assignment: ${(error as Error).message}` });\n }\n });\n\n return router;\n}\n","export function slugify(title: string): string {\n return title\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n}\n\nexport function isValidSlug(slug: string): boolean {\n return /^[a-z0-9]+(-[a-z0-9]+)*$/.test(slug);\n}\n","import { randomUUID } from 'node:crypto';\n\nexport function generateId(): string {\n return randomUUID();\n}\n","export interface ToggleAcceptanceCriterionResult {\n content: string;\n}\n\nexport interface ToggleAcceptanceCriterionError {\n error: string;\n}\n\nfunction splitFrontmatter(content: string): { prefix: string; body: string } {\n const match = content.match(/^(---\\r?\\n[\\s\\S]*?\\r?\\n---\\r?\\n?)([\\s\\S]*)$/);\n if (!match) {\n return { prefix: '', body: content };\n }\n\n return {\n prefix: match[1],\n body: match[2],\n };\n}\n\nexport function toggleAcceptanceCriterion(\n content: string,\n index: number,\n checked: boolean,\n): ToggleAcceptanceCriterionResult | ToggleAcceptanceCriterionError {\n if (!Number.isInteger(index) || index < 0) {\n return { error: 'acceptance criteria index must be a non-negative integer' };\n }\n\n const { prefix, body } = splitFrontmatter(content);\n const lines = body.split('\\n');\n const sectionStart = lines.findIndex((line) => /^##\\s+Acceptance Criteria\\s*$/i.test(line.trim()));\n\n if (sectionStart === -1) {\n return { error: 'Acceptance Criteria section not found.' };\n }\n\n let sectionEnd = lines.length;\n for (let lineIndex = sectionStart + 1; lineIndex < lines.length; lineIndex += 1) {\n if (/^#{1,2}\\s+\\S/.test(lines[lineIndex].trim())) {\n sectionEnd = lineIndex;\n break;\n }\n }\n\n const checklistLines = lines\n .map((line, lineIndex) => ({ line, lineIndex }))\n .filter(({ lineIndex, line }) =>\n lineIndex > sectionStart\n && lineIndex < sectionEnd\n && /^\\s*[-*]\\s+\\[( |x|X)\\]\\s+.*$/.test(line),\n );\n\n const target = checklistLines[index];\n if (!target) {\n return { error: `Acceptance criteria item ${index} not found.` };\n }\n\n const nextLine = target.line.replace(\n /^(\\s*[-*]\\s+\\[)( |x|X)(\\]\\s+.*)$/,\n `$1${checked ? 'x' : ' '}$3`,\n );\n\n lines[target.lineIndex] = nextLine;\n return {\n content: `${prefix}${lines.join('\\n')}`,\n };\n}\n","export { renderConfig } from './config.js';\nexport type { ConfigParams } from './config.js';\n\nexport { renderManifest } from './manifest.js';\nexport type { ManifestParams } from './manifest.js';\n\nexport { renderMission } from './mission.js';\nexport type { MissionParams } from './mission.js';\n\nexport { renderAgent } from './agent.js';\nexport type { AgentParams } from './agent.js';\n\nexport { renderClaude } from './claude.js';\nexport type { ClaudeParams } from './claude.js';\n\nexport { renderAssignment } from './assignment.js';\nexport type { AssignmentParams } from './assignment.js';\n\nexport { renderPlan } from './plan.js';\nexport type { PlanParams } from './plan.js';\n\nexport { renderScratchpad } from './scratchpad.js';\nexport type { ScratchpadParams } from './scratchpad.js';\n\nexport { renderHandoff } from './handoff.js';\nexport type { HandoffParams } from './handoff.js';\n\nexport { renderDecisionRecord } from './decision-record.js';\nexport type { DecisionRecordParams } from './decision-record.js';\n\nexport {\n renderIndexAssignments,\n renderIndexPlans,\n renderIndexDecisions,\n renderStatus,\n renderResourcesIndex,\n renderMemoriesIndex,\n} from './index-stubs.js';\nexport type { IndexStubParams } from './index-stubs.js';\n\nexport { renderPlaybook } from './playbook.js';\nexport type { PlaybookParams } from './playbook.js';\n\nexport { renderCursorProtocol, renderCursorAssignment } from './cursor-rules.js';\nexport type { CursorAssignmentParams } from './cursor-rules.js';\n\nexport { renderCodexAgents } from './codex-agents.js';\nexport type { CodexAgentsParams } from './codex-agents.js';\n\nexport { renderOpenCodeConfig } from './opencode-config.js';\nexport type { OpenCodeConfigParams } from './opencode-config.js';\n","export interface ManifestParams {\n slug: string;\n timestamp: string;\n}\n\nexport function renderManifest(params: ManifestParams): string {\n return `---\nversion: \"1.0\"\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\n---\n\n# Mission: ${params.slug}\n\n## Overview\n- [Mission Overview](./mission.md)\n\n## Indexes\n- [Assignments](./_index-assignments.md)\n- [Plans](./_index-plans.md)\n- [Decision Records](./_index-decisions.md)\n- [Status](./_status.md)\n- [Resources](./resources/_index.md)\n- [Memories](./memories/_index.md)\n\n## Config\n- [Agent Instructions](./agent.md)\n- [Claude Code Instructions](./claude.md)\n`;\n}\n","export function escapeYamlString(value: string): string {\n if (value.includes('\\n') || value.includes('\\r')) {\n throw new Error(\n `YAML string values must be single-line. Got: \"${value.slice(0, 50)}...\"`,\n );\n }\n const escaped = value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n return `\"${escaped}\"`;\n}\n","import { escapeYamlString } from '../utils/yaml.js';\n\nexport interface MissionParams {\n id: string;\n slug: string;\n title: string;\n timestamp: string;\n workspace?: string;\n}\n\nexport function renderMission(params: MissionParams): string {\n const safeTitle = escapeYamlString(params.title);\n const workspaceLine = params.workspace ? `\\nworkspace: ${params.workspace}` : '';\n return `---\nid: ${params.id}\nslug: ${params.slug}\ntitle: ${safeTitle}\narchived: false\narchivedAt: null\narchivedReason: null\ncreated: \"${params.timestamp}\"\nupdated: \"${params.timestamp}\"\nexternalIds: []\ntags: []${workspaceLine}\n---\n\n# ${params.title}\n\n## Overview\n\n<!-- Describe the mission goal, context, and success criteria here. -->\n\n## Notes\n\n<!-- Optional human notes, updates, or context. -->\n`;\n}\n","export interface AgentParams {\n slug: string;\n timestamp: string;\n}\n\nexport function renderAgent(params: AgentParams): string {\n return `---\nmission: ${params.slug}\nupdated: \"${params.timestamp}\"\n---\n\n# Agent Instructions\n\nAll agents working on this mission must follow these guidelines.\n\n## Conventions\n\n<!-- Coding conventions, naming standards, architectural patterns. -->\n\n## Boundaries\n\n<!-- What agents should NOT do. Files/systems that are off-limits. -->\n\n## Resources\n\n<!-- Links to key resources agents should consult. -->\n`;\n}\n","export interface ClaudeParams {\n slug: string;\n}\n\nexport function renderClaude(params: ClaudeParams): string {\n return `# Claude Code Instructions \\u2014 ${params.slug}\n\nRead \\`agent.md\\` first for universal conventions and boundaries.\n\n## Additional Claude Code Rules\n\n<!-- Add Claude Code-specific rules here. -->\n`;\n}\n","import { escapeYamlString } from '../utils/yaml.js';\n\nexport interface AssignmentParams {\n id: string;\n slug: string;\n title: string;\n timestamp: string;\n priority: 'low' | 'medium' | 'high' | 'critical';\n dependsOn: string[];\n}\n\nexport function renderAssignment(params: AssignmentParams): string {\n const safeTitle = escapeYamlString(params.title);\n const dependsOnYaml =\n params.dependsOn.length === 0\n ? 'dependsOn: []'\n : `dependsOn:\\n - ${params.dependsOn.join('\\n - ')}`;\n\n return `---\nid: ${params.id}\nslug: ${params.slug}\ntitle: ${safeTitle}\nstatus: pending\npriority: ${params.priority}\ncreated: \"${params.timestamp}\"\nupdated: \"${params.timestamp}\"\nassignee: null\nexternalIds: []\n${dependsOnYaml}\nblockedReason: null\nworkspace:\n repository: null\n worktreePath: null\n branch: null\n parentBranch: null\ntags: []\n---\n\n# ${params.title}\n\n## Objective\n\n<!-- Clear description of what needs to be done and why. -->\n\n## Acceptance Criteria\n\n- [ ] <!-- criterion 1 -->\n- [ ] <!-- criterion 2 -->\n- [ ] <!-- criterion 3 -->\n\n## Context\n\n<!-- Links to relevant docs, code, or other assignments. -->\n\n## Questions & Answers\n\nNo questions yet.\n\n## Progress\n\nNo progress yet.\n\n## Links\n\n- [Plan](./plan.md)\n- [Scratchpad](./scratchpad.md)\n- [Handoff](./handoff.md)\n- [Decision Record](./decision-record.md)\n`;\n}\n","export interface PlanParams {\n assignmentSlug: string;\n title: string;\n timestamp: string;\n}\n\nexport function renderPlan(params: PlanParams): string {\n return `---\nassignment: ${params.assignmentSlug}\nstatus: draft\ncreated: \"${params.timestamp}\"\nupdated: \"${params.timestamp}\"\n---\n\n# Plan: ${params.title}\n\n## Approach\n\n<!-- High-level description of how to accomplish the objective. -->\n\n## Tasks\n\n- [ ] <!-- step 1 -->\n- [ ] <!-- step 2 -->\n- [ ] <!-- step 3 -->\n\n## Risks & Mitigations\n\n| Risk | Mitigation |\n|------|------------|\n| <!-- risk --> | <!-- mitigation --> |\n`;\n}\n","export interface ScratchpadParams {\n assignmentSlug: string;\n timestamp: string;\n}\n\nexport function renderScratchpad(params: ScratchpadParams): string {\n return `---\nassignment: ${params.assignmentSlug}\nupdated: \"${params.timestamp}\"\n---\n\n# Scratchpad\n\nNo working notes yet.\n`;\n}\n","export interface HandoffParams {\n assignmentSlug: string;\n timestamp: string;\n}\n\nexport function renderHandoff(params: HandoffParams): string {\n return `---\nassignment: ${params.assignmentSlug}\nupdated: \"${params.timestamp}\"\nhandoffCount: 0\n---\n\n# Handoff Log\n\nNo handoffs recorded yet.\n`;\n}\n","export interface DecisionRecordParams {\n assignmentSlug: string;\n timestamp: string;\n}\n\nexport function renderDecisionRecord(\n params: DecisionRecordParams,\n): string {\n return `---\nassignment: ${params.assignmentSlug}\nupdated: \"${params.timestamp}\"\ndecisionCount: 0\n---\n\n# Decision Record\n\nNo decisions recorded yet.\n`;\n}\n","export interface IndexStubParams {\n slug: string;\n title: string;\n timestamp: string;\n}\n\nexport function renderIndexAssignments(params: IndexStubParams): string {\n return `---\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\ntotal: 0\nby_status:\n pending: 0\n in_progress: 0\n blocked: 0\n review: 0\n completed: 0\n failed: 0\n---\n\n# Assignments\n\n| Slug | Title | Status | Priority | Assignee | Dependencies | Updated |\n|------|-------|--------|----------|----------|--------------|---------|\n`;\n}\n\nexport function renderIndexPlans(params: IndexStubParams): string {\n return `---\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\n---\n\n# Plans\n\n| Assignment | Plan Status | Updated |\n|------------|-------------|---------|\n`;\n}\n\nexport function renderIndexDecisions(params: IndexStubParams): string {\n return `---\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\n---\n\n# Decision Records\n\n| Assignment | Count | Latest Decision | Latest Status | Updated |\n|------------|-------|-----------------|---------------|---------|\n`;\n}\n\nexport function renderStatus(params: IndexStubParams): string {\n return `---\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\nstatus: pending\nprogress:\n total: 0\n completed: 0\n in_progress: 0\n blocked: 0\n pending: 0\n review: 0\n failed: 0\nneedsAttention:\n blockedCount: 0\n failedCount: 0\n unansweredQuestions: 0\n---\n\n# Mission Status: ${params.title}\n\n**Status:** pending\n**Progress:** 0/0 assignments complete\n\n## Assignments\n\nNo assignments yet.\n\n## Dependency Graph\n\nNo dependencies yet.\n\n## Needs Attention\n\n- **0 blocked** assignments\n- **0 failed** assignments\n- **0 unanswered** questions\n`;\n}\n\nexport function renderResourcesIndex(params: IndexStubParams): string {\n return `---\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\ntotal: 0\n---\n\n# Resources\n\n| Name | Category | Source | Related Assignments | Updated |\n|------|----------|--------|---------------------|---------|\n`;\n}\n\nexport function renderMemoriesIndex(params: IndexStubParams): string {\n return `---\nmission: ${params.slug}\ngenerated: \"${params.timestamp}\"\ntotal: 0\n---\n\n# Memories\n\n| Name | Source | Scope | Source Assignment | Updated |\n|------|--------|-------|------------------|---------|\n`;\n}\n","import { escapeYamlString } from '../utils/yaml.js';\n\nexport interface PlaybookParams {\n slug: string;\n name: string;\n description: string;\n whenToUse?: string;\n timestamp: string;\n}\n\nexport function renderPlaybook(params: PlaybookParams): string {\n const whenToUse = params.whenToUse\n ? escapeYamlString(params.whenToUse)\n : 'null';\n return `---\nname: ${escapeYamlString(params.name)}\nslug: ${params.slug}\ndescription: ${escapeYamlString(params.description)}\nwhen_to_use: ${whenToUse}\ncreated: \"${params.timestamp}\"\nupdated: \"${params.timestamp}\"\ntags: []\n---\n\n# ${params.name}\n\n<!-- Write imperative rules and workflows here. Keep it under 50 lines. -->\n`;\n}\n","import { Router } from 'express';\nimport {\n registerSession,\n removeSession,\n listSessionFiles,\n readSessionFile,\n updateLastRefreshed,\n setOverride,\n sanitizeSessionName,\n} from './servers.js';\nimport {\n scanAllSessions,\n scanSingleSession,\n clearScanCache,\n} from './scanner.js';\n\nexport function createServersRouter(serversDir: string, missionsDir: string): Router {\n const router = Router();\n\n // GET /api/servers — all sessions with cached scan data\n router.get('/', async (_req, res) => {\n try {\n const result = await scanAllSessions(serversDir, missionsDir);\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Scan failed' });\n }\n });\n\n // GET /api/servers/:name — single session\n router.get('/:name', async (req, res) => {\n try {\n const session = await scanSingleSession(serversDir, missionsDir, req.params.name);\n if (!session) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n res.json(session);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Scan failed' });\n }\n });\n\n // POST /api/servers — register a new session\n router.post('/', async (req, res) => {\n try {\n const { name } = req.body;\n if (!name || typeof name !== 'string') {\n res.status(400).json({ error: 'name is required' });\n return;\n }\n const sanitized = sanitizeSessionName(name);\n const existing = await readSessionFile(serversDir, sanitized);\n if (existing) {\n res.status(409).json({ error: `Session \"${sanitized}\" already registered` });\n return;\n }\n await registerSession(serversDir, name);\n clearScanCache();\n res.status(201).json({ name: sanitized });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Registration failed' });\n }\n });\n\n // DELETE /api/servers/:name — unregister\n router.delete('/:name', async (req, res) => {\n try {\n const data = await readSessionFile(serversDir, req.params.name);\n if (!data) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n await removeSession(serversDir, req.params.name);\n clearScanCache();\n res.json({ removed: req.params.name });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Removal failed' });\n }\n });\n\n // POST /api/servers/refresh — fresh scan all (must be before /:name/refresh)\n router.post('/refresh', async (_req, res) => {\n try {\n const names = await listSessionFiles(serversDir);\n for (const name of names) {\n await updateLastRefreshed(serversDir, name);\n }\n clearScanCache();\n const result = await scanAllSessions(serversDir, missionsDir, { bypassCache: true });\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Refresh failed' });\n }\n });\n\n // POST /api/servers/:name/refresh — fresh scan one\n router.post('/:name/refresh', async (req, res) => {\n try {\n const data = await readSessionFile(serversDir, req.params.name);\n if (!data) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n await updateLastRefreshed(serversDir, req.params.name);\n clearScanCache();\n const session = await scanSingleSession(serversDir, missionsDir, req.params.name);\n res.json(session);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Refresh failed' });\n }\n });\n\n // PATCH /api/servers/:name/panes/:windowIndex/:paneIndex/assignment — manual link\n router.patch('/:name/panes/:windowIndex/:paneIndex/assignment', async (req, res) => {\n try {\n const { name, windowIndex, paneIndex } = req.params;\n const data = await readSessionFile(serversDir, name);\n if (!data) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n const body = req.body;\n if (body === null || (body && body.mission && body.assignment)) {\n await setOverride(\n serversDir,\n name,\n parseInt(windowIndex, 10),\n parseInt(paneIndex, 10),\n body,\n );\n clearScanCache();\n res.json({ updated: true });\n } else {\n res.status(400).json({ error: 'Body must be { mission, assignment } or null' });\n }\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Update failed' });\n }\n });\n\n return router;\n}\n","import { Router } from 'express';\nimport { resolve } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport {\n listAllSessions,\n listMissionSessions,\n appendSession,\n updateSessionStatus,\n deleteSessions,\n reconcileActiveSessions,\n} from './agent-sessions.js';\nimport { fileExists } from '../utils/fs.js';\nimport type { AgentSessionStatus, WsMessage } from './types.js';\n\nexport function createAgentSessionsRouter(\n missionsDir: string,\n broadcast?: (msg: WsMessage) => void,\n): Router {\n const router = Router();\n\n // GET /api/agent-sessions — all sessions across all missions\n router.get('/', async (_req, res) => {\n try {\n await reconcileActiveSessions(missionsDir);\n const sessions = await listAllSessions(missionsDir);\n res.json({ sessions, generatedAt: new Date().toISOString() });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to list sessions' });\n }\n });\n\n // GET /api/agent-sessions/:missionSlug — sessions for one mission\n router.get('/:missionSlug', async (req, res) => {\n try {\n const { missionSlug } = req.params;\n const assignment = req.query.assignment as string | undefined;\n const missionDir = resolve(missionsDir, missionSlug);\n if (!(await fileExists(missionDir))) {\n res.status(404).json({ error: `Mission \"${missionSlug}\" not found` });\n return;\n }\n await reconcileActiveSessions(missionsDir);\n const sessions = await listMissionSessions(missionsDir, missionSlug, assignment);\n res.json({ sessions, generatedAt: new Date().toISOString() });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to list sessions' });\n }\n });\n\n // POST /api/agent-sessions — register a new session\n router.post('/', async (req, res) => {\n try {\n const { missionSlug, assignmentSlug, agent, sessionId, path, description } = req.body;\n\n if (!agent) {\n res.status(400).json({ error: 'agent is required' });\n return;\n }\n\n if (missionSlug) {\n const missionDir = resolve(missionsDir, missionSlug);\n if (!(await fileExists(missionDir))) {\n res.status(404).json({ error: `Mission \"${missionSlug}\" not found` });\n return;\n }\n }\n\n const id = sessionId || randomUUID();\n const session = {\n missionSlug: missionSlug || null,\n assignmentSlug: assignmentSlug || null,\n agent,\n sessionId: id,\n started: new Date().toISOString(),\n status: 'active' as AgentSessionStatus,\n path: path || '',\n description: description || null,\n };\n\n await appendSession('', session);\n broadcast?.({ type: 'agent-sessions-updated', timestamp: new Date().toISOString() });\n res.status(201).json({ sessionId: id });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Registration failed' });\n }\n });\n\n // PATCH /api/agent-sessions/:sessionId/status — update session status\n router.patch('/:sessionId/status', async (req, res) => {\n try {\n const { sessionId } = req.params;\n const { status } = req.body;\n\n if (!status) {\n res.status(400).json({ error: 'status is required' });\n return;\n }\n\n if (!['active', 'completed', 'stopped'].includes(status)) {\n res.status(400).json({ error: 'status must be active, completed, or stopped' });\n return;\n }\n\n const updated = await updateSessionStatus('', sessionId, status);\n if (!updated) {\n res.status(404).json({ error: `Session \"${sessionId}\" not found` });\n return;\n }\n\n broadcast?.({ type: 'agent-sessions-updated', timestamp: new Date().toISOString() });\n res.json({ updated: true });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Update failed' });\n }\n });\n\n // DELETE /api/agent-sessions — delete one or more sessions\n router.delete('/', async (req, res) => {\n try {\n const { sessionIds } = req.body;\n\n if (!Array.isArray(sessionIds) || sessionIds.length === 0) {\n res.status(400).json({ error: 'sessionIds must be a non-empty array' });\n return;\n }\n\n const deleted = await deleteSessions(sessionIds);\n broadcast?.({ type: 'agent-sessions-updated', timestamp: new Date().toISOString() });\n res.json({ deleted });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Delete failed' });\n }\n });\n\n return router;\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { fileExists } from '../utils/fs.js';\nimport { getSessionDb } from './session-db.js';\nimport type { AgentSession, AgentSessionStatus } from './types.js';\n\ninterface SessionRow {\n session_id: string;\n mission_slug: string | null;\n assignment_slug: string | null;\n agent: string;\n started: string;\n ended: string | null;\n status: string;\n path: string | null;\n description: string | null;\n}\n\nfunction rowToSession(row: SessionRow): AgentSession {\n return {\n sessionId: row.session_id,\n missionSlug: row.mission_slug ?? null,\n assignmentSlug: row.assignment_slug ?? null,\n agent: row.agent,\n started: row.started,\n ended: row.ended ?? null,\n status: row.status as AgentSessionStatus,\n path: row.path ?? '',\n description: row.description ?? null,\n };\n}\n\n/**\n * Query sessions for a specific mission.\n */\nexport async function parseSessionsIndex(\n _missionDir: string,\n missionSlug: string,\n): Promise<AgentSession[]> {\n const db = getSessionDb();\n const rows = db\n .prepare('SELECT * FROM sessions WHERE mission_slug = ? ORDER BY started DESC')\n .all(missionSlug) as SessionRow[];\n return rows.map(rowToSession);\n}\n\n/**\n * Insert a new session into the database.\n */\nexport async function appendSession(\n _missionDir: string,\n session: AgentSession,\n): Promise<void> {\n const db = getSessionDb();\n db.prepare(`\n INSERT INTO sessions (session_id, mission_slug, assignment_slug, agent, started, status, path, description)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n session.sessionId,\n session.missionSlug ?? null,\n session.assignmentSlug ?? null,\n session.agent,\n session.started,\n session.status,\n session.path,\n session.description ?? null,\n );\n}\n\n/**\n * Update a session's status by sessionId.\n * Sets `ended` timestamp for terminal statuses (completed, stopped).\n */\nexport async function updateSessionStatus(\n _missionDir: string,\n sessionId: string,\n status: AgentSessionStatus,\n): Promise<boolean> {\n const db = getSessionDb();\n const isTerminal = status === 'completed' || status === 'stopped';\n\n const result = isTerminal\n ? db\n .prepare(\n 'UPDATE sessions SET status = ?, ended = datetime(\\'now\\'), updated_at = datetime(\\'now\\') WHERE session_id = ?',\n )\n .run(status, sessionId)\n : db\n .prepare(\n 'UPDATE sessions SET status = ?, updated_at = datetime(\\'now\\') WHERE session_id = ?',\n )\n .run(status, sessionId);\n\n return result.changes > 0;\n}\n\n/**\n * List all sessions across all missions.\n */\nexport async function listAllSessions(_missionsDir: string): Promise<AgentSession[]> {\n const db = getSessionDb();\n const rows = db\n .prepare('SELECT * FROM sessions ORDER BY started DESC')\n .all() as SessionRow[];\n return rows.map(rowToSession);\n}\n\n/**\n * List sessions for a specific mission, optionally filtered by assignment.\n */\nexport async function listMissionSessions(\n _missionsDir: string,\n missionSlug: string,\n assignmentSlug?: string,\n): Promise<AgentSession[]> {\n const db = getSessionDb();\n\n if (assignmentSlug) {\n const rows = db\n .prepare(\n 'SELECT * FROM sessions WHERE mission_slug = ? AND assignment_slug = ? ORDER BY started DESC',\n )\n .all(missionSlug, assignmentSlug) as SessionRow[];\n return rows.map(rowToSession);\n }\n\n const rows = db\n .prepare('SELECT * FROM sessions WHERE mission_slug = ? ORDER BY started DESC')\n .all(missionSlug) as SessionRow[];\n return rows.map(rowToSession);\n}\n\n/**\n * Delete sessions by their IDs. Returns the number of rows deleted.\n */\nexport async function deleteSessions(sessionIds: string[]): Promise<number> {\n if (sessionIds.length === 0) return 0;\n const db = getSessionDb();\n const placeholders = sessionIds.map(() => '?').join(', ');\n const result = db\n .prepare(`DELETE FROM sessions WHERE session_id IN (${placeholders})`)\n .run(...sessionIds);\n return result.changes;\n}\n\n// Statuses that imply the working session is done (review means agent finished)\nconst DONE_ASSIGNMENT_STATUSES = new Set(['completed', 'failed', 'review']);\n\n/**\n * Read the status field from an assignment.md frontmatter without full parsing.\n */\nasync function readAssignmentStatus(\n missionDir: string,\n assignmentSlug: string,\n): Promise<string | null> {\n const assignmentPath = resolve(missionDir, 'assignments', assignmentSlug, 'assignment.md');\n if (!(await fileExists(assignmentPath))) return null;\n\n const raw = await readFile(assignmentPath, 'utf-8');\n const match = raw.match(/^status:\\s*(.+)$/m);\n return match ? match[1].trim() : null;\n}\n\n/**\n * Reconcile active sessions against assignment statuses.\n * Sessions whose assignments have moved to completed/failed/review are\n * marked as completed (or stopped for failed assignments).\n * Returns the number of sessions that were updated.\n */\nexport async function reconcileActiveSessions(\n missionsDir: string,\n): Promise<number> {\n const db = getSessionDb();\n\n // Get active sessions that are linked to a mission/assignment (standalone sessions have nothing to reconcile)\n const activeSessions = db\n .prepare('SELECT * FROM sessions WHERE status = \\'active\\' AND mission_slug IS NOT NULL AND assignment_slug IS NOT NULL')\n .all() as SessionRow[];\n\n if (activeSessions.length === 0) return 0;\n\n // Dedupe assignment slugs per mission for status checks\n // mission_slug and assignment_slug are guaranteed non-null by the query filter above\n const toCheck = new Map<string, Set<string>>();\n for (const session of activeSessions) {\n const slugs = toCheck.get(session.mission_slug!) ?? new Set();\n slugs.add(session.assignment_slug!);\n toCheck.set(session.mission_slug!, slugs);\n }\n\n // Read assignment statuses from disk\n const assignmentStatuses = new Map<string, string>();\n for (const [missionSlug, slugs] of toCheck) {\n const missionDir = resolve(missionsDir, missionSlug);\n for (const slug of slugs) {\n const status = await readAssignmentStatus(missionDir, slug);\n if (status) assignmentStatuses.set(`${missionSlug}/${slug}`, status);\n }\n }\n\n // Update stale sessions\n let totalUpdated = 0;\n for (const session of activeSessions) {\n const key = `${session.mission_slug}/${session.assignment_slug}`;\n const assignmentStatus = assignmentStatuses.get(key);\n if (!assignmentStatus || !DONE_ASSIGNMENT_STATUSES.has(assignmentStatus)) continue;\n\n const newStatus: AgentSessionStatus =\n assignmentStatus === 'failed' ? 'stopped' : 'completed';\n await updateSessionStatus('', session.session_id, newStatus);\n totalUpdated++;\n }\n\n return totalUpdated;\n}\n","import Database from 'better-sqlite3';\nimport { resolve } from 'node:path';\nimport { readdir } from 'node:fs/promises';\nimport { syntaurRoot } from '../utils/paths.js';\nimport { fileExists } from '../utils/fs.js';\nimport type { AgentSession, AgentSessionStatus } from './types.js';\n\nlet db: Database.Database | null = null;\n\nconst SCHEMA_VERSION = '2';\n\nconst SCHEMA_SQL = `\nCREATE TABLE IF NOT EXISTS sessions (\n session_id TEXT PRIMARY KEY,\n mission_slug TEXT,\n assignment_slug TEXT,\n agent TEXT NOT NULL,\n started TEXT NOT NULL,\n ended TEXT,\n status TEXT NOT NULL DEFAULT 'active',\n path TEXT,\n description TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_sessions_mission ON sessions(mission_slug);\nCREATE INDEX IF NOT EXISTS idx_sessions_assignment ON sessions(mission_slug, assignment_slug);\nCREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);\nCREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT);\n`;\n\n/**\n * Initialize the SQLite database for session tracking.\n * Creates the database file and schema if they don't exist.\n * @param dbPath Optional override for the database file path (used in tests).\n */\nexport function initSessionDb(dbPath?: string): Database.Database {\n if (db) return db;\n\n const finalPath = dbPath ?? resolve(syntaurRoot(), 'syntaur.db');\n db = new Database(finalPath);\n db.pragma('journal_mode = WAL');\n db.exec(SCHEMA_SQL);\n\n // Track schema version\n db.prepare('INSERT OR IGNORE INTO meta (key, value) VALUES (?, ?)').run(\n 'schema_version',\n SCHEMA_VERSION,\n );\n\n // Migrate from v1 to v2: make mission/assignment nullable, add description\n const currentVersion = db\n .prepare(\"SELECT value FROM meta WHERE key = 'schema_version'\")\n .get() as { value: string } | undefined;\n\n if (currentVersion?.value === '1') {\n db.exec(`\n CREATE TABLE sessions_v2 (\n session_id TEXT PRIMARY KEY,\n mission_slug TEXT,\n assignment_slug TEXT,\n agent TEXT NOT NULL,\n started TEXT NOT NULL,\n ended TEXT,\n status TEXT NOT NULL DEFAULT 'active',\n path TEXT,\n description TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n );\n INSERT INTO sessions_v2 SELECT session_id, mission_slug, assignment_slug, agent, started, ended, status, path, NULL, created_at, updated_at FROM sessions;\n DROP TABLE sessions;\n ALTER TABLE sessions_v2 RENAME TO sessions;\n CREATE INDEX IF NOT EXISTS idx_sessions_mission ON sessions(mission_slug);\n CREATE INDEX IF NOT EXISTS idx_sessions_assignment ON sessions(mission_slug, assignment_slug);\n CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);\n UPDATE meta SET value = '2' WHERE key = 'schema_version';\n `);\n }\n\n return db;\n}\n\n/**\n * Get the initialized database handle.\n * Throws if initSessionDb() has not been called.\n */\nexport function getSessionDb(): Database.Database {\n if (!db) {\n throw new Error(\n 'Session database not initialized. Call initSessionDb() first.',\n );\n }\n return db;\n}\n\n/**\n * Close the database connection.\n */\nexport function closeSessionDb(): void {\n if (db) {\n db.close();\n db = null;\n }\n}\n\n/**\n * Reset the singleton for testing purposes.\n */\nexport function resetSessionDb(): void {\n db = null;\n}\n\n/**\n * One-time migration: import sessions from markdown _index-sessions.md files into SQLite.\n * Only runs if the sessions table is empty and markdown files exist.\n */\nexport async function migrateFromMarkdown(missionsDir: string): Promise<number> {\n const database = getSessionDb();\n\n // Skip if sessions already exist in the database\n const count = database.prepare('SELECT COUNT(*) as count FROM sessions').get() as { count: number };\n if (count.count > 0) return 0;\n\n if (!(await fileExists(missionsDir))) return 0;\n\n const entries = await readdir(missionsDir, { withFileTypes: true });\n const allSessions: AgentSession[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const missionDir = resolve(missionsDir, entry.name);\n const indexPath = resolve(missionDir, '_index-sessions.md');\n if (!(await fileExists(indexPath))) continue;\n\n const sessions = await parseMarkdownSessionsIndex(indexPath, entry.name);\n allSessions.push(...sessions);\n }\n\n if (allSessions.length === 0) return 0;\n\n const insert = database.prepare(`\n INSERT OR IGNORE INTO sessions (session_id, mission_slug, assignment_slug, agent, started, status, path)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `);\n\n const insertAll = database.transaction((sessions: AgentSession[]) => {\n for (const s of sessions) {\n insert.run(s.sessionId, s.missionSlug, s.assignmentSlug, s.agent, s.started, s.status, s.path);\n }\n });\n\n insertAll(allSessions);\n console.log(`Migrated ${allSessions.length} sessions from markdown to SQLite.`);\n return allSessions.length;\n}\n\n/**\n * Parse an _index-sessions.md file into AgentSession objects.\n * Used only for one-time migration. This is a copy of the old parsing logic.\n */\nasync function parseMarkdownSessionsIndex(\n filePath: string,\n missionSlug: string,\n): Promise<AgentSession[]> {\n const { readFile } = await import('node:fs/promises');\n const raw = await readFile(filePath, 'utf-8');\n const sessions: AgentSession[] = [];\n\n const lines = raw.split('\\n');\n let inTable = false;\n let headerSeen = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n if (trimmed.startsWith('| Assignment') || trimmed.startsWith('|Assignment')) {\n inTable = true;\n headerSeen = false;\n continue;\n }\n\n if (inTable && !headerSeen && trimmed.match(/^\\|[-\\s|]+\\|$/)) {\n headerSeen = true;\n continue;\n }\n\n if (inTable && headerSeen && trimmed.startsWith('|')) {\n const cells = trimmed\n .split('|')\n .slice(1, -1)\n .map((c) => c.trim());\n\n if (cells.length >= 6) {\n sessions.push({\n assignmentSlug: cells[0],\n agent: cells[1],\n sessionId: cells[2],\n started: cells[3],\n status: (cells[4] as AgentSessionStatus) || 'active',\n path: cells[5],\n missionSlug,\n });\n }\n }\n }\n\n return sessions;\n}\n","import { Router } from 'express';\nimport { resolve } from 'node:path';\nimport { readFile, unlink } from 'node:fs/promises';\nimport { listPlaybooks, getPlaybookDetail } from './api.js';\nimport { parsePlaybook } from './parser.js';\nimport { isValidSlug } from '../utils/slug.js';\nimport { nowTimestamp } from '../utils/timestamp.js';\nimport { ensureDir, fileExists, writeFileForce } from '../utils/fs.js';\nimport { renderPlaybook } from '../templates/playbook.js';\nimport { rebuildPlaybookManifest } from '../utils/playbooks.js';\n\nexport function createPlaybooksRouter(playbooksDir: string): Router {\n const router = Router();\n\n // GET / — list all playbooks\n router.get('/', async (_req, res) => {\n try {\n const playbooks = await listPlaybooks(playbooksDir);\n res.json({ playbooks, generatedAt: new Date().toISOString() });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to list playbooks' });\n }\n });\n\n // GET /template/new — scaffold template (must be before /:slug to avoid param capture)\n router.get('/template/new', async (_req, res) => {\n try {\n const content = renderPlaybook({\n slug: 'my-playbook',\n name: 'My Playbook',\n description: 'A new playbook',\n timestamp: nowTimestamp(),\n });\n res.json({ content });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get template' });\n }\n });\n\n // GET /:slug — get playbook detail\n router.get('/:slug', async (req, res) => {\n try {\n const detail = await getPlaybookDetail(playbooksDir, req.params.slug);\n if (!detail) {\n res.status(404).json({ error: `Playbook \"${req.params.slug}\" not found` });\n return;\n }\n res.json(detail);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get playbook' });\n }\n });\n\n // GET /:slug/edit — raw file content for editor\n router.get('/:slug/edit', async (req, res) => {\n try {\n const filePath = resolve(playbooksDir, `${req.params.slug}.md`);\n if (!(await fileExists(filePath))) {\n res.status(404).json({ error: `Playbook \"${req.params.slug}\" not found` });\n return;\n }\n const content = await readFile(filePath, 'utf-8');\n res.json({\n documentType: 'playbook',\n title: `Edit Playbook: ${req.params.slug}`,\n content,\n slug: req.params.slug,\n });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get playbook for editing' });\n }\n });\n\n // POST / — create new playbook\n router.post('/', async (req, res) => {\n try {\n const { content } = req.body;\n if (!content || typeof content !== 'string') {\n res.status(400).json({ error: 'content is required' });\n return;\n }\n\n const parsed = parsePlaybook(content);\n const slug = parsed.slug;\n if (!slug || !isValidSlug(slug)) {\n res.status(400).json({ error: `Invalid or missing slug: \"${slug}\"` });\n return;\n }\n\n await ensureDir(playbooksDir);\n const filePath = resolve(playbooksDir, `${slug}.md`);\n if (await fileExists(filePath)) {\n res.status(409).json({ error: `Playbook \"${slug}\" already exists` });\n return;\n }\n\n await writeFileForce(filePath, content);\n await rebuildPlaybookManifest(playbooksDir);\n res.status(201).json({ slug, path: filePath });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to create playbook' });\n }\n });\n\n // PUT /:slug — update playbook content\n router.put('/:slug', async (req, res) => {\n try {\n const { content } = req.body;\n if (!content || typeof content !== 'string') {\n res.status(400).json({ error: 'content is required' });\n return;\n }\n\n const filePath = resolve(playbooksDir, `${req.params.slug}.md`);\n if (!(await fileExists(filePath))) {\n res.status(404).json({ error: `Playbook \"${req.params.slug}\" not found` });\n return;\n }\n\n await writeFileForce(filePath, content);\n await rebuildPlaybookManifest(playbooksDir);\n res.json({ slug: req.params.slug, path: filePath });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to update playbook' });\n }\n });\n\n // DELETE /:slug — delete a playbook\n router.delete('/:slug', async (req, res) => {\n try {\n if (req.params.slug === 'manifest') {\n res.status(403).json({ error: 'The playbook manifest cannot be deleted' });\n return;\n }\n\n const filePath = resolve(playbooksDir, `${req.params.slug}.md`);\n if (!(await fileExists(filePath))) {\n res.status(404).json({ error: `Playbook \"${req.params.slug}\" not found` });\n return;\n }\n\n await unlink(filePath);\n await rebuildPlaybookManifest(playbooksDir);\n res.json({ deleted: req.params.slug });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to delete playbook' });\n }\n });\n\n return router;\n}\n","import { resolve } from 'node:path';\nimport { readdir, readFile } from 'node:fs/promises';\nimport { fileExists, writeFileForce } from './fs.js';\nimport { parsePlaybook } from '../dashboard/parser.js';\nimport { nowTimestamp } from './timestamp.js';\n\nexport async function rebuildPlaybookManifest(playbooksDir: string): Promise<void> {\n if (!(await fileExists(playbooksDir))) return;\n\n const entries = await readdir(playbooksDir, { withFileTypes: true });\n const rows: Array<{ name: string; slug: string; description: string; whenToUse: string }> = [];\n\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith('.md') || entry.name.startsWith('_') || entry.name === 'manifest.md') continue;\n\n const raw = await readFile(resolve(playbooksDir, entry.name), 'utf-8');\n const parsed = parsePlaybook(raw);\n const slug = parsed.slug || entry.name.replace(/\\.md$/, '');\n\n rows.push({\n name: parsed.name || slug,\n slug,\n description: parsed.description,\n whenToUse: parsed.whenToUse,\n });\n }\n\n rows.sort((a, b) => a.name.localeCompare(b.name));\n\n const timestamp = nowTimestamp();\n const lines = [\n '---',\n `generated: \"${timestamp}\"`,\n `total: ${rows.length}`,\n '---',\n '',\n '# Playbooks',\n '',\n 'Behavioral rules for AI agents. Read and follow all playbooks before starting work.',\n '',\n ];\n\n for (const row of rows) {\n lines.push(`- **[${row.name}](${row.slug}.md)** — ${row.description}`);\n if (row.whenToUse) {\n lines.push(` _When to use: ${row.whenToUse}_`);\n }\n }\n\n lines.push('');\n\n await writeFileForce(resolve(playbooksDir, 'manifest.md'), lines.join('\\n'));\n}\n","import { Router, type Request, type Response, type NextFunction } from 'express';\nimport { readdir } from 'node:fs/promises';\nimport {\n readChecklist,\n writeChecklist,\n readLog,\n appendLogEntry,\n generateUniqueId,\n computeCounts,\n} from '../todos/parser.js';\nimport { ensureDir, fileExists } from '../utils/fs.js';\nimport type { TodoItem, LogEntry } from '../todos/types.js';\nimport type { WsMessage } from './types.js';\n\nconst WORKSPACE_REGEX = /^[a-z0-9_][a-z0-9-]*$/;\n\nfunction getWorkspaceParam(value: string | string[] | undefined): string {\n if (Array.isArray(value)) {\n return value[0] ?? '';\n }\n return value ?? '';\n}\n\n// Per-workspace write lock to prevent concurrent read-modify-write races\nconst writeLocks = new Map<string, Promise<void>>();\nfunction withLock<T>(workspace: string, fn: () => Promise<T>): Promise<T> {\n const prev = writeLocks.get(workspace) ?? Promise.resolve();\n const next = prev.then(fn);\n writeLocks.set(workspace, next.then(() => {}, () => {}));\n return next;\n}\n\nexport function createTodosRouter(\n todosDir: string,\n broadcast: (msg: WsMessage) => void,\n): Router {\n const router = Router();\n\n function broadcastUpdate(): void {\n broadcast({ type: 'todos-updated', timestamp: new Date().toISOString() });\n }\n\n // Validate workspace name on all routes that use :workspace\n function validateWorkspace(req: Request, res: Response, next: NextFunction): void {\n const workspace = getWorkspaceParam(req.params.workspace);\n if (workspace && !WORKSPACE_REGEX.test(workspace)) {\n res.status(400).json({ error: `Invalid workspace name: \"${workspace}\". Use lowercase letters, numbers, hyphens, and underscores.` });\n return;\n }\n next();\n }\n\n // Apply workspace validation to all parameterized routes\n router.param('workspace', validateWorkspace as any);\n\n // GET / — aggregate all workspace checklists\n router.get('/', async (_req, res) => {\n try {\n await ensureDir(todosDir);\n const files = await readdir(todosDir).catch(() => []);\n const workspaces: Array<{\n workspace: string;\n archiveInterval: string;\n items: TodoItem[];\n counts: ReturnType<typeof computeCounts>;\n }> = [];\n\n for (const file of files) {\n if (typeof file !== 'string') continue;\n if (!file.endsWith('.md') || file.endsWith('-log.md')) continue;\n const workspace = file.replace('.md', '');\n const checklist = await readChecklist(todosDir, workspace);\n workspaces.push({\n workspace: checklist.workspace,\n archiveInterval: checklist.archiveInterval,\n items: checklist.items,\n counts: computeCounts(checklist.items),\n });\n }\n\n res.json({ workspaces });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to list todos' });\n }\n });\n\n // GET /:workspace — list items for one workspace\n router.get('/:workspace', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const checklist = await readChecklist(todosDir, workspace);\n res.json({\n workspace: checklist.workspace,\n archiveInterval: checklist.archiveInterval,\n items: checklist.items,\n counts: computeCounts(checklist.items),\n });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get todos' });\n }\n });\n\n // POST /:workspace — add item\n router.post('/:workspace', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const { description, tags } = req.body;\n if (!description || typeof description !== 'string') {\n res.status(400).json({ error: 'description is required' });\n return;\n }\n\n const item = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const existingIds = new Set(checklist.items.map((i) => i.id));\n const id = generateUniqueId(existingIds);\n\n const newItem: TodoItem = {\n id,\n description,\n status: 'open',\n tags: Array.isArray(tags) ? tags : [],\n session: null,\n };\n checklist.items.push(newItem);\n await writeChecklist(todosDir, checklist);\n return newItem;\n });\n broadcastUpdate();\n res.status(201).json(item);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to add todo' });\n }\n });\n\n // POST /:workspace/reorder — reorder items\n // Must be before /:workspace/:id to avoid param capture\n router.post('/:workspace/reorder', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const { ids } = req.body;\n if (!Array.isArray(ids) || !ids.every((id: unknown) => typeof id === 'string')) {\n res.status(400).json({ error: 'ids must be an array of strings' });\n return;\n }\n\n const items = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const itemMap = new Map(checklist.items.map((i) => [i.id, i]));\n\n // Build reordered list: requested order first, then any items not in the ids array\n const reordered: TodoItem[] = [];\n for (const id of ids) {\n const item = itemMap.get(id);\n if (item) {\n reordered.push(item);\n itemMap.delete(id);\n }\n }\n // Append any remaining items not mentioned in ids\n for (const item of itemMap.values()) {\n reordered.push(item);\n }\n\n checklist.items = reordered;\n await writeChecklist(todosDir, checklist);\n return reordered;\n });\n broadcastUpdate();\n res.json({ items });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to reorder todos' });\n }\n });\n\n // GET /:workspace/log — full log\n // Must be before /:workspace/:id to avoid param capture\n router.get('/:workspace/log', async (req, res) => {\n try {\n const log = await readLog(todosDir, getWorkspaceParam(req.params.workspace));\n res.json(log);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get log' });\n }\n });\n\n // POST /:workspace/archive — trigger archive\n router.post('/:workspace/archive', async (req, res) => {\n try {\n // Import archive logic inline to avoid circular deps\n const { archivePath } = await import('../todos/parser.js');\n const { resolve } = await import('node:path');\n const { readFile } = await import('node:fs/promises');\n const { writeFileForce } = await import('../utils/fs.js');\n\n const workspace = getWorkspaceParam(req.params.workspace);\n const checklist = await readChecklist(todosDir, workspace);\n const log = await readLog(todosDir, workspace);\n\n const completedIds = new Set(\n checklist.items.filter((i) => i.status === 'completed').map((i) => i.id),\n );\n\n if (completedIds.size === 0) {\n res.json({ archived: 0, message: 'No completed items to archive' });\n return;\n }\n\n const toArchive = log.entries.filter((e) =>\n e.itemIds.every((id) => completedIds.has(id)),\n );\n\n const archFile = archivePath(todosDir, workspace, checklist.archiveInterval);\n await ensureDir(resolve(todosDir, 'archive'));\n let archContent = '';\n if (await fileExists(archFile)) {\n archContent = await readFile(archFile, 'utf-8');\n archContent = archContent.trimEnd() + '\\n\\n';\n } else {\n archContent = `---\\nworkspace: ${workspace}\\n---\\n\\n# Archive\\n\\n`;\n }\n\n const completedItems = checklist.items.filter((i) => completedIds.has(i.id));\n for (const item of completedItems) {\n archContent += `- [x] ${item.description} ${item.tags.map((t: string) => `#${t}`).join(' ')} [t:${item.id}]\\n`;\n }\n archContent += '\\n';\n for (const entry of toArchive) {\n archContent += `### ${entry.timestamp} — ${entry.itemIds.map((i: string) => `t:${i}`).join(', ')}\\n`;\n if (entry.items) archContent += `**Items:** ${entry.items}\\n`;\n if (entry.session) archContent += `**Session:** ${entry.session}\\n`;\n if (entry.branch) archContent += `**Branch:** ${entry.branch}\\n`;\n if (entry.summary) archContent += `**Summary:** ${entry.summary}\\n`;\n if (entry.blockers) archContent += `**Blockers:** ${entry.blockers}\\n`;\n archContent += '\\n';\n }\n await writeFileForce(archFile, archContent);\n\n checklist.items = checklist.items.filter((i) => !completedIds.has(i.id));\n await writeChecklist(todosDir, checklist);\n\n broadcastUpdate();\n res.json({ archived: completedIds.size, logEntries: toArchive.length });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to archive' });\n }\n });\n\n // GET /:workspace/log/:id — log for specific item\n router.get('/:workspace/log/:id', async (req, res) => {\n try {\n const log = await readLog(todosDir, getWorkspaceParam(req.params.workspace));\n const entries = log.entries.filter((e) => e.itemIds.includes(req.params.id));\n res.json({ workspace: log.workspace, entries });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get log' });\n }\n });\n\n // GET /:workspace/:id — single item with log\n router.get('/:workspace/:id', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) {\n res.status(404).json({ error: `Todo \"${req.params.id}\" not found` });\n return;\n }\n const log = await readLog(todosDir, workspace);\n const logEntries = log.entries.filter((e) => e.itemIds.includes(req.params.id));\n res.json({ ...item, log: logEntries });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to get todo' });\n }\n });\n\n // PATCH /:workspace/:id — update description or tags\n router.patch('/:workspace/:id', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const result = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) return null;\n if (req.body.description !== undefined) item.description = req.body.description;\n if (Array.isArray(req.body.tags)) item.tags = req.body.tags;\n await writeChecklist(todosDir, checklist);\n return { ...item };\n });\n if (!result) { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n broadcastUpdate();\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to update todo' });\n }\n });\n\n // DELETE /:workspace/:id\n router.delete('/:workspace/:id', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const deleted = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const idx = checklist.items.findIndex((i) => i.id === req.params.id);\n if (idx === -1) return false;\n checklist.items.splice(idx, 1);\n await writeChecklist(todosDir, checklist);\n return true;\n });\n if (!deleted) { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n broadcastUpdate();\n res.json({ deleted: req.params.id });\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to delete todo' });\n }\n });\n\n // POST /:workspace/:id/start\n router.post('/:workspace/:id/start', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const result = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) return { error: 'not_found' as const };\n if (item.status === 'in_progress') return { error: 'conflict' as const, session: item.session };\n item.status = 'in_progress';\n item.session = req.body.session || null;\n await writeChecklist(todosDir, checklist);\n return { item: { ...item } };\n });\n if ('error' in result) {\n if (result.error === 'not_found') { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n res.status(409).json({ error: `Todo is already in progress (session: ${result.session})` }); return;\n }\n broadcastUpdate();\n res.json(result.item);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to start todo' });\n }\n });\n\n // POST /:workspace/:id/complete\n router.post('/:workspace/:id/complete', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const result = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) return null;\n item.status = 'completed';\n item.session = null;\n await writeChecklist(todosDir, checklist);\n\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n itemIds: [item.id],\n items: item.description,\n session: req.body.session || null,\n branch: req.body.branch || null,\n summary: req.body.summary || 'Completed.',\n blockers: null,\n status: null,\n };\n await appendLogEntry(todosDir, workspace, entry);\n return { ...item };\n });\n if (!result) { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n broadcastUpdate();\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to complete todo' });\n }\n });\n\n // POST /:workspace/:id/block\n router.post('/:workspace/:id/block', async (req, res) => {\n try {\n const reason = req.body.reason || null;\n const workspace = getWorkspaceParam(req.params.workspace);\n const result = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) return null;\n item.status = 'blocked';\n item.session = null;\n await writeChecklist(todosDir, checklist);\n\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n itemIds: [item.id],\n items: item.description,\n session: req.body.session || null,\n branch: null,\n summary: reason || 'Blocked.',\n blockers: reason,\n status: 'blocked',\n };\n await appendLogEntry(todosDir, workspace, entry);\n return { ...item };\n });\n if (!result) { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n broadcastUpdate();\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to block todo' });\n }\n });\n\n // POST /:workspace/:id/reopen — move completed back to open\n router.post('/:workspace/:id/reopen', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const result = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) return null;\n item.status = 'open';\n item.session = null;\n await writeChecklist(todosDir, checklist);\n return { ...item };\n });\n if (!result) { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n broadcastUpdate();\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to reopen todo' });\n }\n });\n\n // POST /:workspace/:id/unblock\n router.post('/:workspace/:id/unblock', async (req, res) => {\n try {\n const workspace = getWorkspaceParam(req.params.workspace);\n const result = await withLock(workspace, async () => {\n const checklist = await readChecklist(todosDir, workspace);\n const item = checklist.items.find((i) => i.id === req.params.id);\n if (!item) return null;\n item.status = 'open';\n item.session = null;\n await writeChecklist(todosDir, checklist);\n return { ...item };\n });\n if (!result) { res.status(404).json({ error: `Todo \"${req.params.id}\" not found` }); return; }\n broadcastUpdate();\n res.json(result);\n } catch (error) {\n res.status(500).json({ error: error instanceof Error ? error.message : 'Failed to unblock todo' });\n }\n });\n\n return router;\n}\n","import {\n execQuiet,\n checkTmuxAvailable,\n sessionAlive,\n listTmuxPanes,\n getLsofOutput,\n loadWorkspaceRecords,\n autoLinkPane,\n getGitInfo,\n clearScanCache,\n} from './scanner.js';\nimport {\n readSessionFile,\n listSessionFiles,\n registerAutoSession,\n removeSession,\n sanitizeSessionName,\n} from './servers.js';\nimport type { SessionFileData } from './types.js';\n\n// --- Shared lsof helpers ---\n\nexport function parsePortsForPid(lsofOutput: string, targetPid: number): number[] {\n const ports: number[] = [];\n for (const line of lsofOutput.split('\\n')) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const pid = parseInt(parts[1], 10);\n if (pid !== targetPid) continue;\n const tcpAddr = parts.find((p) => p.includes(':') && /:\\d+$/.test(p));\n if (tcpAddr) {\n const port = parseInt(tcpAddr.split(':').pop()!, 10);\n if (!isNaN(port) && !ports.includes(port)) ports.push(port);\n }\n }\n return ports;\n}\n\nexport function parseLsofForListeningProcesses(lsofOutput: string): ListeningProcess[] {\n const seen = new Map<number, ListeningProcess>();\n for (const line of lsofOutput.split('\\n')) {\n const parts = line.trim().split(/\\s+/);\n if (parts.length < 9) continue;\n const command = parts[0];\n const pid = parseInt(parts[1], 10);\n if (isNaN(pid)) continue;\n const tcpAddr = parts.find((p) => p.includes(':') && /:\\d+$/.test(p));\n if (!tcpAddr) continue;\n const port = parseInt(tcpAddr.split(':').pop()!, 10);\n if (isNaN(port)) continue;\n\n if (!seen.has(pid)) {\n seen.set(pid, { pid, port, command });\n }\n }\n return Array.from(seen.values());\n}\n\n// --- Singleton lifecycle ---\n\nlet timer: ReturnType<typeof setInterval> | null = null;\nlet activeReconcile: Promise<void> | null = null;\n\nexport interface AutodiscoveryOptions {\n serversDir: string;\n missionsDir: string;\n intervalMs?: number;\n excludePids?: Set<number>;\n}\n\nlet savedOptions: AutodiscoveryOptions | null = null;\n\nexport function startAutodiscovery(opts: AutodiscoveryOptions): void {\n if (timer) return;\n savedOptions = opts;\n const interval = opts.intervalMs ?? 45_000;\n // Run once immediately, then on interval\n runReconcile();\n timer = setInterval(() => {\n runReconcile();\n }, interval);\n}\n\nexport async function stopAutodiscovery(): Promise<void> {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n // Await in-flight reconcile to prevent overlap\n if (activeReconcile) {\n await activeReconcile;\n activeReconcile = null;\n }\n savedOptions = null;\n}\n\nfunction runReconcile(): void {\n if (activeReconcile || !savedOptions) return;\n const opts = savedOptions;\n activeReconcile = reconcile(opts.serversDir, opts.missionsDir, opts.excludePids)\n .catch((err) => {\n console.error('[autodiscovery] reconcile failed:', err);\n })\n .finally(() => {\n activeReconcile = null;\n });\n}\n\n// --- Tmux discovery ---\n\nexport async function listAllTmuxSessions(): Promise<string[]> {\n const output = await execQuiet('tmux', ['list-sessions', '-F', '#{session_name}']);\n if (!output) return [];\n return output.split('\\n').filter((line) => line.length > 0);\n}\n\nasync function discoverTmuxSessions(\n serversDir: string,\n missionsDir: string,\n existingNames: Set<string>,\n): Promise<boolean> {\n const tmuxAvailable = await checkTmuxAvailable();\n if (!tmuxAvailable) return false;\n\n const workspaceRecords = await loadWorkspaceRecords(missionsDir);\n if (workspaceRecords.length === 0) return false;\n\n const sessions = await listAllTmuxSessions();\n let changed = false;\n\n for (const sessionName of sessions) {\n const sanitized = sanitizeSessionName(sessionName);\n if (existingNames.has(sanitized)) {\n // Already tracked (manual or auto) — skip\n continue;\n }\n\n const panes = await listTmuxPanes(sessionName);\n if (panes.length === 0) continue;\n\n // Check if any pane matches a workspace\n let matched = false;\n const cwdGitCache = new Map<string, { branch: string | null; worktree: boolean }>();\n\n for (const pane of panes) {\n if (!cwdGitCache.has(pane.cwd)) {\n cwdGitCache.set(pane.cwd, await getGitInfo(pane.cwd));\n }\n const gitInfo = cwdGitCache.get(pane.cwd)!;\n const link = await autoLinkPane(pane.cwd, gitInfo.branch, workspaceRecords);\n if (link) {\n matched = true;\n break;\n }\n }\n\n if (matched) {\n await registerAutoSession(serversDir, sessionName, { kind: 'tmux' });\n changed = true;\n }\n }\n\n return changed;\n}\n\n// --- Non-tmux process discovery ---\n\ninterface ListeningProcess {\n pid: number;\n port: number;\n command: string;\n}\n\nasync function getProcessCwd(pid: number): Promise<string | null> {\n // macOS: use lsof to get cwd\n const output = await execQuiet('lsof', ['-a', '-d', 'cwd', '-p', String(pid), '-Fn']);\n if (!output) return null;\n // Output format: lines starting with 'n' contain the path\n for (const line of output.split('\\n')) {\n if (line.startsWith('n') && line.length > 1) {\n return line.slice(1);\n }\n }\n return null;\n}\n\nasync function discoverProcesses(\n serversDir: string,\n missionsDir: string,\n existingFiles: Map<string, SessionFileData>,\n excludePids?: Set<number>,\n): Promise<boolean> {\n const workspaceRecords = await loadWorkspaceRecords(missionsDir);\n if (workspaceRecords.length === 0) return false;\n\n const lsofOutput = await getLsofOutput();\n if (!lsofOutput) return false;\n\n const processes = parseLsofForListeningProcesses(lsofOutput);\n let changed = false;\n\n // Track which PIDs are already tracked by existing process-kind entries\n const trackedPids = new Set<number>();\n for (const data of existingFiles.values()) {\n if (data.kind === 'process' && data.pid) {\n trackedPids.add(data.pid);\n }\n }\n\n for (const proc of processes) {\n if (trackedPids.has(proc.pid)) continue;\n if (excludePids?.has(proc.pid)) continue;\n\n const cwd = await getProcessCwd(proc.pid);\n if (!cwd) continue;\n\n const gitInfo = await getGitInfo(cwd);\n const link = await autoLinkPane(cwd, gitInfo.branch, workspaceRecords);\n if (!link) continue;\n\n // Build a session name from the command and port\n const sessionName = `proc-${proc.command}-${proc.port}`;\n const sanitized = sanitizeSessionName(sessionName);\n\n // Skip if already registered under this name\n if (existingFiles.has(sanitized)) continue;\n\n const ports = parsePortsForPid(lsofOutput, proc.pid);\n await registerAutoSession(serversDir, sessionName, {\n kind: 'process',\n pid: proc.pid,\n ports: ports.length > 0 ? ports : [proc.port],\n cwd,\n });\n changed = true;\n }\n\n return changed;\n}\n\n// --- Reconciliation ---\n\nasync function cleanupDeadAutoSessions(\n serversDir: string,\n existingFiles: Map<string, SessionFileData>,\n): Promise<{ changed: boolean; removedNames: Set<string> }> {\n let changed = false;\n const removedNames = new Set<string>();\n\n // Only check tmux liveness if tmux is available\n const tmuxAvailable = await checkTmuxAvailable();\n\n for (const [name, data] of existingFiles) {\n if (!data.auto) continue;\n\n let alive = true; // Default to alive for unknown kinds\n if (data.kind === 'tmux') {\n if (!tmuxAvailable) continue; // Don't delete tmux sessions when tmux is unavailable\n alive = await sessionAlive(data.session);\n } else if (data.kind === 'process' && data.pid) {\n alive = await isProcessAlive(data.pid);\n } else {\n // Unknown kind with auto: true — leave it alone\n continue;\n }\n\n if (!alive) {\n await removeSession(serversDir, name);\n removedNames.add(name);\n changed = true;\n }\n }\n\n return { changed, removedNames };\n}\n\nexport async function isProcessAlive(pid: number): Promise<boolean> {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function reconcile(serversDir: string, missionsDir: string, excludePids?: Set<number>): Promise<void> {\n // Load all existing session files\n const names = await listSessionFiles(serversDir);\n const existingFiles = new Map<string, SessionFileData>();\n for (const name of names) {\n const data = await readSessionFile(serversDir, name);\n if (data) existingFiles.set(name, data);\n }\n\n // Clean up dead auto sessions FIRST so discovery can re-register restarted processes\n const { changed: cleanupChanged, removedNames } = await cleanupDeadAutoSessions(serversDir, existingFiles);\n\n // Remove cleaned-up entries from the maps so discovery sees them as available\n for (const name of removedNames) {\n existingFiles.delete(name);\n }\n const existingNames = new Set(existingFiles.keys());\n\n // Discover new sessions\n const tmuxChanged = await discoverTmuxSessions(serversDir, missionsDir, existingNames);\n const processChanged = await discoverProcesses(serversDir, missionsDir, existingFiles, excludePids);\n\n // Invalidate scan cache if anything changed\n if (tmuxChanged || processChanged || cleanupChanged) {\n clearScanCache();\n }\n}\n\n// --- Exports for testing ---\nexport { reconcile, getProcessCwd };\n"],"mappings":"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","names":["getField","resolve","readFile","resolve","init_config","extractFrontmatter","parseSimpleValue","parseExternalIds","readFile","resolve","nowTimestamp","extractFrontmatter","resolve","readdir","readFile","extractFrontmatter","readdir","readFile","writeFile","resolve","dirname","scanAllSessions","init_config","appendLogEntry","readFile","resolve","parseStatus","extractFrontmatter","init_parser","resolve","dirname","homedir","writeFile","unlink","handleServerChange","handlePlaybookChange","handleTodoChange","init_config","resolve","readFile","extractFrontmatter","formatYamlValue","readFile","resolve","Router","Router","resolve","randomUUID","readFile","resolve","resolve","readdir","readdir","resolve","readFile","db","rows","resolve","readFile","Router","resolve","randomUUID","Router","resolve","readFile","unlink","resolve","readdir","readFile","Router","resolve","readFile","unlink","init_parser","Router","readdir","archivePath","resolve","readFile","writeFileForce","appendLogEntry","dirname","resolve","homedir","writeFile","unlink"]}
|