fifony 0.1.21 → 0.1.22
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 +7 -0
- package/app/dist/assets/{KeyboardShortcutsHelp-BTjiQe_Y.js → KeyboardShortcutsHelp-DFstgyXD.js} +1 -1
- package/app/dist/assets/OnboardingWizard-Daehu2Uj.js +1 -0
- package/app/dist/assets/analytics.lazy-C1-iSRM_.js +1 -0
- package/app/dist/assets/{createLucideIcon-DtZs0TX0.js → createLucideIcon-BWC-guQt.js} +1 -1
- package/app/dist/assets/index-DbIrs0MK.css +1 -0
- package/app/dist/assets/index-O_FDwkw6.js +43 -0
- package/app/dist/assets/vendor-BTlTWMUF.js +9 -0
- package/app/dist/index.html +4 -5
- package/app/dist/service-worker.js +1 -1
- package/bin/fifony-wrap.js +53 -0
- package/dist/agent/cli-wrapper.js +78 -0
- package/dist/agent/cli-wrapper.js.map +1 -0
- package/dist/agent/run-local.js +93 -7889
- package/dist/agent/run-local.js.map +1 -1
- package/dist/chunk-F6JEQIP2.js +449 -0
- package/dist/chunk-F6JEQIP2.js.map +1 -0
- package/dist/{chunk-SMGXYOWU.js → chunk-O665NS5E.js} +411 -9
- package/dist/chunk-O665NS5E.js.map +1 -0
- package/dist/chunk-VP6TGOMT.js +8915 -0
- package/dist/chunk-VP6TGOMT.js.map +1 -0
- package/dist/cli.js +182 -0
- package/dist/cli.js.map +1 -1
- package/dist/issue-runner-MDCJ4G26.js +11 -0
- package/dist/issue-runner-MDCJ4G26.js.map +1 -0
- package/dist/mcp/server.js +589 -595
- package/dist/mcp/server.js.map +1 -1
- package/dist/queue-workers-LAYOT4E5.js +21 -0
- package/dist/queue-workers-LAYOT4E5.js.map +1 -0
- package/package.json +10 -9
- package/app/dist/assets/OnboardingWizard-BALlquG0.js +0 -1
- package/app/dist/assets/analytics.lazy-DjSzXIey.js +0 -1
- package/app/dist/assets/index-BV11ScVl.js +0 -42
- package/app/dist/assets/index-DWbxgKSd.css +0 -1
- package/app/dist/assets/vendor-BoGBoEwT.js +0 -9
- package/app/dist/assets/zap-DpjdVd1i.js +0 -1
- package/dist/chunk-SMGXYOWU.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/agent/run-local.ts","../../src/agent/constants.ts","../../src/agent/helpers.ts","../../src/agent/logger.ts","../../src/agent/store.ts","../../src/agent/issues.ts","../../src/agent/token-ledger.ts","../../src/agent/dirty-tracker.ts","../../src/agent/metrics-cache.ts","../../src/agent/issue-state-machine.ts","../../src/agent/providers.ts","../../src/agent/adapters/commands.ts","../../src/agent/api-runtime-context.ts","../../src/agent/api-server.ts","../../src/agent/resources/runtime-state.resource.ts","../../src/agent/agent.ts","../../src/agent/skills.ts","../../src/agent/workflow.ts","../../src/agent/adapters/index.ts","../../src/agent/adapters/shared.ts","../../src/agent/adapters/plan-to-claude.ts","../../src/agent/adapters/plan-to-codex.ts","../../src/agent/settings.ts","../../src/agent/resources/issues.resource.ts","../../src/agent/resources/events.resource.ts","../../src/agent/resources/settings.resource.ts","../../src/agent/resources/agent-sessions.resource.ts","../../src/agent/resources/agent-pipelines.resource.ts","../../src/agent/resources/index.ts","../../src/agent/providers-usage.ts","../../src/agent/scheduler.ts","../../src/agent/issue-enhancer.ts","../../src/agent/openai-adapter.ts","../../src/agent/issue-planner.ts","../../src/agent/project-scanner.ts","../../src/agent/issue-scanner.ts","../../src/agent/github-sync.ts","../../src/agent/catalog.ts","../../src/agent/dev-server.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { mkdirSync } from \"node:fs\";\nimport { env, exit, argv } from \"node:process\";\nimport { CLI_ARGS, STATE_ROOT, WORKFLOW_RENDERED } from \"./constants.ts\";\nimport { debugBoot, fail, now } from \"./helpers.ts\";\nimport { initLogger, logger } from \"./logger.ts\";\nimport { initStateStore, loadPersistedState, persistState, persistStateFull, closeStateStore } from \"./store.ts\";\nimport {\n applyPersistedSettings,\n loadRuntimeSettings,\n persistDetectedProvidersSetting,\n syncRuntimeConfigSettings,\n} from \"./settings.ts\";\nimport {\n detectAvailableProviders,\n resolveDefaultProvider,\n getProviderDefaultCommand,\n} from \"./providers.ts\";\nimport { loadWorkflowDefinition, parsePort, setSkipSource } from \"./workflow.ts\";\nimport { deriveConfig, applyWorkflowConfig, buildRuntimeState, computeMetrics, addEvent, validateConfig } from \"./issues.ts\";\nimport { startApiServer } from \"./api-server.ts\";\nimport { scheduler, installGracefulShutdown } from \"./scheduler.ts\";\nimport { cleanWorkspace, isAgentStillRunning, cleanStalePidFile } from \"./agent.ts\";\nimport { startDevFrontend } from \"./dev-server.ts\";\nimport { recoverPlanningSession } from \"./issue-planner.ts\";\nimport { hydrate as hydrateTokenLedger } from \"./token-ledger.ts\";\n\nfunction usage() {\n console.log(\n `Usage: ${argv[1]} [options]\\n` +\n \"Options:\\n\" +\n \" --workspace <path> Target workspace root (default: current directory)\\n\" +\n \" --persistence <path> Persistence root (default: current directory)\\n\" +\n \" --port <n> Start local dashboard\\n\" +\n \" --concurrency <n> Maximum number of local workers\\n\" +\n \" --attempts <n> Maximum attempts per issue\\n\" +\n \" --poll <ms> Scheduler interval in ms\\n\" +\n \" --timeout <ms> Agent command timeout in ms (default: 1800000)\\n\" +\n \" --dev Start Vite dev server alongside API (HMR on port+1)\\n\" +\n \" --once Process once and exit\\n\" +\n \" --skip-source Skip source snapshot copy\\n\" +\n \" --skip-scan Skip project analysis\\n\" +\n \" --skip-recovery Skip orphaned agent recovery\\n\" +\n \" --fast-boot Equivalent to --skip-source --skip-scan --skip-recovery\\n\",\n );\n}\n\nasync function main() {\n debugBoot(\"main:start\");\n\n const args = CLI_ARGS;\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n usage();\n return;\n }\n\n mkdirSync(STATE_ROOT, { recursive: true });\n initLogger(STATE_ROOT);\n logger.info(\"[Boot] Fifony runtime starting\");\n logger.info({ stateRoot: STATE_ROOT, cwd: process.cwd() }, \"[Boot] State root initialized\");\n\n // Detect available providers\n const detectedProviders = detectAvailableProviders();\n for (const p of detectedProviders) {\n logger.info(`Provider ${p.name}: ${p.available ? `available at ${p.path}` : \"not found\"}`);\n }\n\n const interfaceMode = (env.FIFONY_INTERFACE ?? \"cli\").trim().toLowerCase();\n const runOnce = args.includes(\"--once\");\n const devMode = args.includes(\"--dev\") || env.NODE_ENV === \"development\";\n const fastBoot = args.includes(\"--fast-boot\");\n const skipSource = fastBoot || args.includes(\"--skip-source\");\n if (skipSource) setSkipSource(true);\n\n debugBoot(\"main:state-root-ready\");\n logger.debug(\"[Boot] Loading workflow definition\");\n const workflowDefinition = loadWorkflowDefinition();\n logger.info({ workflowPath: workflowDefinition.workflowPath }, \"[Boot] Workflow definition loaded\");\n debugBoot(\"main:workflow-loaded\");\n\n const port = parsePort(args);\n let config = applyWorkflowConfig(deriveConfig(args), port);\n\n // Auto-resolve provider command if not configured\n if (!config.agentCommand.trim()) {\n const defaultProvider = resolveDefaultProvider(detectedProviders);\n if (defaultProvider) {\n const defaultCommand = getProviderDefaultCommand(defaultProvider);\n if (defaultCommand) {\n config = { ...config, agentProvider: defaultProvider, agentCommand: defaultCommand };\n logger.info(`Auto-detected provider: ${defaultProvider} → ${defaultCommand}`);\n }\n }\n }\n\n const dashboardPort = port ?? (config.dashboardPort ? Number.parseInt(config.dashboardPort, 10) : undefined);\n const skipRecovery = args.includes(\"--skip-recovery\") || args.includes(\"--fast-boot\");\n\n // ── Phase B: Parallel initialization ────────────────────────────────────────\n debugBoot(\"main:phase-b-start\");\n logger.debug(\"[Boot] Initializing state store (s3db)\");\n await initStateStore();\n logger.info(\"[Boot] State store initialized\");\n debugBoot(\"main:store-initialized\");\n\n // ── Early API start: dashboard available while boot continues ─────────────\n // Build a minimal placeholder state for the early API server\n const earlyState: RuntimeState = {\n startedAt: now(),\n updatedAt: now(),\n trackerKind: \"filesystem\",\n sourceRepoUrl: \"\",\n sourceRef: \"workspace\",\n workflowPath: \"\",\n config,\n issues: [],\n events: [],\n metrics: { total: 0, queued: 0, inProgress: 0, blocked: 0, done: 0, cancelled: 0, activeWorkers: 0 },\n notes: [],\n booting: true,\n };\n\n let apiState = earlyState;\n if (dashboardPort) {\n await startApiServer(apiState, dashboardPort, workflowDefinition);\n debugBoot(\"main:api-server-early-start\");\n\n if (devMode) {\n const devPort = dashboardPort + 1;\n await startDevFrontend(dashboardPort, devPort);\n }\n }\n\n // ── Phase C: Parallel state loading ─────────────────────────────────────────\n debugBoot(\"main:phase-c-start\");\n logger.debug(\"[Boot] Loading persisted state, settings, and recovering sessions\");\n const [previous, persistedSettings] = await Promise.all([\n loadPersistedState(),\n loadRuntimeSettings(),\n persistDetectedProvidersSetting(detectedProviders),\n recoverPlanningSession(),\n ]);\n logger.info({ hadPreviousState: previous !== null, issueCount: previous?.issues?.length ?? 0, settingsCount: persistedSettings.length }, \"[Boot] State loaded from persistence\");\n debugBoot(\"main:state-loaded\");\n\n config = applyPersistedSettings(config, persistedSettings);\n await syncRuntimeConfigSettings(config, persistedSettings);\n const state = buildRuntimeState(previous, config, workflowDefinition);\n debugBoot(\"main:state-merged\");\n\n state.config.dashboardPort = dashboardPort ? String(dashboardPort) : undefined;\n state.workflowPath = WORKFLOW_RENDERED;\n state.updatedAt = now();\n state.booting = false;\n\n if (state.config.agentCommand) {\n state.notes.push(`Using agent command: ${state.config.agentCommand}`);\n }\n state.notes.push(`Agent session max turns: ${state.config.maxTurns}`);\n state.notes.push(`Agent provider: ${state.config.agentProvider}`);\n state.notes.push(`Interface mode: ${interfaceMode}`);\n\n if (!state.config.agentCommand.trim()) {\n const available = detectedProviders.filter((p) => p.available).map((p) => p.name);\n fail(\n available.length === 0\n ? \"No agent command configured and no providers (claude, codex) found in PATH.\\nInstall claude or codex, or set FIFONY_AGENT_COMMAND / configure codex.command or claude.command in WORKFLOW.md.\"\n : \"No agent command configured. Set FIFONY_AGENT_COMMAND or configure codex.command / claude.command in WORKFLOW.md.\",\n );\n }\n\n // Validate config at startup (spec §6.3)\n const configErrors = validateConfig(config);\n if (configErrors.length > 0) {\n for (const err of configErrors) logger.warn(`Config validation: ${err}`);\n }\n\n // Clean terminal workspaces in background (non-blocking boot)\n const terminalIssues = state.issues.filter((i) => i.state === \"Done\" || i.state === \"Cancelled\");\n if (terminalIssues.length > 0) {\n logger.info(`Scheduling cleanup of ${terminalIssues.length} terminal workspace(s) in background...`);\n setImmediate(async () => {\n for (const issue of terminalIssues) {\n try { await cleanWorkspace(issue.id, workflowDefinition); } catch {}\n }\n logger.info(\"Background workspace cleanup complete.\");\n });\n }\n\n // Recover orphaned agent processes from previous session\n if (!skipRecovery) {\n logger.debug({ issueCount: state.issues.filter((i) => i.state === \"Running\" || i.state === \"Interrupted\" || i.state === \"Queued\").length }, \"[Boot] Checking for orphaned agent processes\");\n for (const issue of state.issues) {\n if (issue.state === \"Running\" || issue.state === \"Interrupted\" || issue.state === \"Queued\") {\n const { alive, pid } = isAgentStillRunning(issue);\n if (alive && pid) {\n logger.info(`Agent for ${issue.identifier} still alive (PID ${pid.pid}), keeping state as Running.`);\n issue.state = \"Running\";\n addEvent(state, issue.id, \"info\", `Orphaned agent detected (PID ${pid.pid}), still alive — tracking resumed.`);\n } else {\n // Agent died — clean PID file, mark as Interrupted for resumption\n if (issue.workspacePath) cleanStalePidFile(issue.workspacePath);\n if (issue.state === \"Running\") {\n issue.state = \"Interrupted\";\n issue.history.push(`[${now()}] Agent process not found on boot — marked Interrupted.`);\n addEvent(state, issue.id, \"info\", `Agent for ${issue.identifier} not found, marked Interrupted.`);\n }\n }\n }\n }\n }\n\n state.metrics = computeMetrics(state.issues);\n await persistStateFull(state);\n\n // Update the API server to use the real state (swap reference)\n if (dashboardPort) {\n // The API server closure captures apiState — mutate it to point to real state\n Object.assign(apiState, state);\n debugBoot(\"main:api-state-swapped\");\n }\n\n const running = new Set<string>();\n installGracefulShutdown(state, running);\n\n logger.info(`Rendered local workflow: ${WORKFLOW_RENDERED}`);\n hydrateTokenLedger(state.issues);\n logger.info(`Loaded issues: ${state.issues.length}`);\n logger.info(`Worker concurrency: ${state.config.workerConcurrency}`);\n logger.info(`Max attempts: ${state.config.maxAttemptsDefault}`);\n logger.info(`Max turns: ${state.config.maxTurns}`);\n logger.info(`Agent provider: ${state.config.agentProvider}`);\n logger.info(`Interface mode: ${interfaceMode}`);\n\n try {\n addEvent(state, undefined, \"info\", `Runtime started in local-only mode (filesystem tracker).`);\n const runForever = !runOnce && (Boolean(dashboardPort) || interfaceMode === \"mcp\");\n logger.info({ runForever, runOnce, dashboardPort, interfaceMode }, \"[Boot] Entering scheduler loop\");\n await scheduler(state, running, runForever, workflowDefinition);\n } catch (error) {\n console.error(\"FATAL STACK TRACE:\", error);\n addEvent(state, undefined, \"error\", `Fatal runtime error: ${String(error)}`);\n await persistState(state);\n throw error;\n } finally {\n state.updatedAt = now();\n state.metrics = computeMetrics(state.issues);\n await persistStateFull(state);\n await closeStateStore();\n }\n}\n\nmain().catch((error) => {\n logger.error({ err: error }, `Fatal runtime error: ${String(error)}`);\n exit(1);\n});\n","import { basename, dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { env, argv, cwd as getCwd } from \"node:process\";\nimport { homedir } from \"node:os\";\nimport type { IssueState } from \"./types.ts\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nexport const PACKAGE_ROOT = resolve(__dirname, \"../..\");\nexport const CLI_ARGS = argv.slice(2);\n\nfunction readArgValue(args: string[], flag: string): string | undefined {\n const index = args.indexOf(flag);\n if (index === -1) return undefined;\n const value = args[index + 1];\n if (!value || value.startsWith(\"--\")) return undefined;\n return value;\n}\n\nfunction resolveInputPath(value: string): string {\n if (value.startsWith(\"~/\")) {\n return resolve(homedir(), value.slice(2));\n }\n return resolve(value);\n}\n\nexport function resolvePersistenceRoot(value: string): string {\n const resolved = value.startsWith(\"file://\")\n ? fileURLToPath(value)\n : resolveInputPath(value);\n\n return basename(resolved) === \".fifony\"\n ? resolved\n : join(resolved, \".fifony\");\n}\n\nconst CLI_WORKSPACE_ROOT = readArgValue(CLI_ARGS, \"--workspace\");\nconst CLI_PERSISTENCE = readArgValue(CLI_ARGS, \"--persistence\");\n\nexport const TARGET_ROOT = resolveInputPath(\n env.FIFONY_WORKSPACE_ROOT ?? CLI_WORKSPACE_ROOT ?? getCwd(),\n);\n\nexport const STATE_ROOT = resolvePersistenceRoot(\n env.FIFONY_PERSISTENCE\n ?? CLI_PERSISTENCE\n ?? env.FIFONY_BOOTSTRAP_ROOT\n ?? TARGET_ROOT,\n);\n\nexport const SOURCE_ROOT = `${STATE_ROOT}/source`;\nexport const WORKSPACE_ROOT = `${STATE_ROOT}/workspaces`;\nexport const SOURCE_MARKER = `${SOURCE_ROOT}/.fifony-local-source-ready`;\n\nexport const WORKFLOW_RENDERED = `${STATE_ROOT}/WORKFLOW.local.md`;\n\nexport const S3DB_DATABASE_PATH = `${STATE_ROOT}/s3db`;\nexport const S3DB_BUCKET = env.FIFONY_STORAGE_BUCKET ?? \"fifony\";\nexport const S3DB_KEY_PREFIX = env.FIFONY_STORAGE_KEY_PREFIX ?? \"state\";\n\nexport const S3DB_RUNTIME_RESOURCE = \"runtime_state\";\nexport const S3DB_ISSUE_RESOURCE = \"issues\";\nexport const S3DB_EVENT_RESOURCE = \"events\";\nexport const S3DB_SETTINGS_RESOURCE = \"settings\";\nexport const S3DB_AGENT_SESSION_RESOURCE = \"agent_sessions\";\nexport const S3DB_AGENT_PIPELINE_RESOURCE = \"agent_pipelines\";\nexport const S3DB_RUNTIME_RECORD_ID = \"current\";\nexport const S3DB_RUNTIME_SCHEMA_VERSION = 1;\n\nexport const FRONTEND_DIR = `${PACKAGE_ROOT}/app/dist`;\nexport const FRONTEND_INDEX = `${FRONTEND_DIR}/index.html`;\nexport const FRONTEND_MANIFEST_JSON = `${FRONTEND_DIR}/manifest.webmanifest`;\nexport const FRONTEND_SERVICE_WORKER_JS = `${FRONTEND_DIR}/service-worker.js`;\nexport const FRONTEND_ICON_SVG = `${FRONTEND_DIR}/icon.svg`;\nexport const FRONTEND_MASKABLE_ICON_SVG = `${FRONTEND_DIR}/icon-maskable.svg`;\nexport const FRONTEND_OFFLINE_HTML = `${FRONTEND_DIR}/offline.html`;\n\nexport const DEBUG_BOOT = env.FIFONY_DEBUG_BOOT === \"1\";\n\nexport const ALLOWED_STATES: IssueState[] = [\n \"Planning\",\n \"Todo\",\n \"Queued\",\n \"Running\",\n \"Interrupted\",\n \"In Review\",\n \"Blocked\",\n \"Done\",\n \"Cancelled\",\n];\n\nexport const TERMINAL_STATES = new Set<IssueState>([\"Done\", \"Cancelled\"]);\nexport const EXECUTING_STATES = new Set<IssueState>([\"Running\", \"In Review\"]);\nexport const PERSIST_EVENTS_MAX = 500;\n\n// ── CLI skip flags ──────────────────────────────────────────────────────────\nconst FAST_BOOT = CLI_ARGS.includes(\"--fast-boot\");\nexport const SKIP_SOURCE = FAST_BOOT || CLI_ARGS.includes(\"--skip-source\");\nexport const SKIP_SCAN = FAST_BOOT || CLI_ARGS.includes(\"--skip-scan\");\nexport const SKIP_RECOVERY = FAST_BOOT || CLI_ARGS.includes(\"--skip-recovery\");\n","import { env } from \"node:process\";\nimport { parse as parseYaml } from \"yaml\";\nimport type { IssueState, JsonRecord } from \"./types.ts\";\nimport { ALLOWED_STATES, DEBUG_BOOT } from \"./constants.ts\";\n\nexport function now(): string {\n return new Date().toISOString();\n}\n\n/** Returns ISO week string like \"2026-W12\" for a given date (defaults to now). */\nexport function isoWeek(date?: Date | string): string {\n const d = date ? new Date(date) : new Date();\n if (Number.isNaN(d.getTime())) return \"\";\n // ISO week: week starts Monday, week 1 contains Jan 4\n const tmp = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));\n const dayNum = tmp.getUTCDay() || 7; // Monday=1 ... Sunday=7\n tmp.setUTCDate(tmp.getUTCDate() + 4 - dayNum);\n const yearStart = new Date(Date.UTC(tmp.getUTCFullYear(), 0, 1));\n const weekNo = Math.ceil(((tmp.getTime() - yearStart.getTime()) / 86_400_000 + 1) / 7);\n return `${tmp.getUTCFullYear()}-W${String(weekNo).padStart(2, \"0\")}`;\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction resolveEnvVar(value: string): string {\n if (!value.startsWith(\"$\")) return value;\n const varName = value.slice(1);\n const resolved = env[varName];\n return resolved && resolved.trim().length > 0 ? resolved.trim() : \"\";\n}\n\nexport function toStringValue(value: unknown, fallback = \"\"): string {\n if (typeof value !== \"string\" || value.trim().length === 0) return fallback;\n const trimmed = value.trim();\n // Resolve $VAR_NAME indirection (full value is a single env var reference)\n if (trimmed.startsWith(\"$\") && /^\\$[A-Za-z_][A-Za-z0-9_]*$/.test(trimmed)) {\n const resolved = resolveEnvVar(trimmed);\n return resolved.length > 0 ? resolved : fallback;\n }\n return trimmed;\n}\n\nexport function toNumberValue(value: unknown, fallback = 1): number {\n const parsed =\n typeof value === \"number\"\n ? value\n : typeof value === \"string\"\n ? Number.parseInt(value, 10)\n : Number.NaN;\n\n return Number.isFinite(parsed) && parsed > 0 ? Math.round(parsed) : fallback;\n}\n\nexport function toBooleanValue(value: unknown, fallback: boolean): boolean {\n return typeof value === \"boolean\" ? value : fallback;\n}\n\nexport function toStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return [];\n return value\n .filter((entry): entry is string => typeof entry === \"string\" && entry.trim().length > 0)\n .map((entry) => entry.trim());\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport function normalizeState(value: unknown): IssueState {\n const raw = typeof value === \"string\" ? value.trim() : \"\";\n if ((ALLOWED_STATES as readonly string[]).includes(raw)) {\n return raw as IssueState;\n }\n return \"Todo\";\n}\n\nexport function parseEnvNumber(name: string, fallback: number): number {\n return toNumberValue(env[name], fallback);\n}\n\nexport function parseIntArg(value: string, fallback: number): number {\n const parsed = Number.parseInt(value, 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;\n}\n\nexport function parsePositiveIntEnv(name: string, fallback: number): number {\n const source = env[name];\n if (!source) return fallback;\n return parseIntArg(source, fallback);\n}\n\nexport function withRetryBackoff(attempt: number, baseDelayMs: number): number {\n return Math.min(baseDelayMs * 2 ** attempt, 5 * 60 * 1000);\n}\n\nexport function idToSafePath(value: string): string {\n return value.toLowerCase().replace(/[^a-z0-9._-]/g, \"-\");\n}\n\nexport function appendFileTail(target: string, text: string, maxLength: number): string {\n const merged = `${target}\\n${text}`;\n if (merged.length <= maxLength) return merged;\n return `…${merged.slice(-(maxLength - 1))}`;\n}\n\nexport function parseFrontMatter(source: string): { config: JsonRecord; body: string } {\n const match = source.match(/^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n?([\\s\\S]*)$/);\n if (!match) {\n return { config: {}, body: source.trim() };\n }\n\n const rawConfig = parseYaml(match[1]) as unknown;\n const config = rawConfig && typeof rawConfig === \"object\" && !Array.isArray(rawConfig)\n ? rawConfig as JsonRecord\n : {};\n\n return { config, body: match[2].trim() };\n}\n\nexport function getNestedRecord(source: unknown, key: string): JsonRecord {\n if (!source || typeof source !== \"object\" || Array.isArray(source)) return {};\n const value = (source as JsonRecord)[key];\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? value as JsonRecord\n : {};\n}\n\nexport function getNestedString(source: unknown, key: string, fallback = \"\"): string {\n if (!source || typeof source !== \"object\" || Array.isArray(source)) return fallback;\n return toStringValue((source as JsonRecord)[key], fallback);\n}\n\nexport function getNestedNumber(source: unknown, key: string, fallback: number): number {\n if (!source || typeof source !== \"object\" || Array.isArray(source)) return fallback;\n return toNumberValue((source as JsonRecord)[key], fallback);\n}\n\nexport function debugBoot(message: string): void {\n if (!DEBUG_BOOT) return;\n console.error(`[FIFONY_DEBUG_BOOT] ${message}`);\n}\n\nexport function fail(message: string): never {\n console.error(message);\n process.exit(1);\n}\n\n/** Extract top-level JSON object candidates from a text that may contain prose around them. */\nexport function extractJsonObjects(text: string): string[] {\n const results: string[] = [];\n let depth = 0;\n let start = -1;\n let inStr = false;\n let esc = false;\n\n for (let i = 0; i < text.length; i++) {\n const ch = text[i];\n if (inStr) {\n if (esc) { esc = false; continue; }\n if (ch === \"\\\\\") { esc = true; continue; }\n if (ch === \"\\\"\") { inStr = false; }\n continue;\n }\n if (ch === \"\\\"\") { inStr = true; continue; }\n if (ch === \"{\") {\n if (depth === 0) start = i;\n depth++;\n } else if (ch === \"}\") {\n depth = Math.max(0, depth - 1);\n if (depth === 0 && start >= 0) {\n results.push(text.slice(start, i + 1));\n start = -1;\n }\n }\n }\n return results;\n}\n\n/**\n * Attempt to repair truncated JSON by closing open strings, arrays, and objects.\n * Returns the repaired string or null if no valid JSON start was found.\n */\nexport function repairTruncatedJson(text: string): string | null {\n // Find the first top-level '{' to start from\n const firstBrace = text.indexOf(\"{\");\n if (firstBrace < 0) return null;\n\n let json = text.slice(firstBrace);\n\n // Track nesting to figure out what needs closing\n let inStr = false;\n let esc = false;\n const stack: string[] = []; // tracks '{' and '['\n\n for (let i = 0; i < json.length; i++) {\n const ch = json[i];\n if (inStr) {\n if (esc) { esc = false; continue; }\n if (ch === \"\\\\\") { esc = true; continue; }\n if (ch === \"\\\"\") { inStr = false; }\n continue;\n }\n if (ch === \"\\\"\") { inStr = true; continue; }\n if (ch === \"{\") stack.push(\"{\");\n else if (ch === \"[\") stack.push(\"[\");\n else if (ch === \"}\") { if (stack.length > 0 && stack[stack.length - 1] === \"{\") stack.pop(); }\n else if (ch === \"]\") { if (stack.length > 0 && stack[stack.length - 1] === \"[\") stack.pop(); }\n }\n\n // Nothing to repair — JSON is already complete\n if (!inStr && stack.length === 0) return json;\n\n // Close open string\n if (inStr) {\n // Remove trailing incomplete escape sequence\n if (json.endsWith(\"\\\\\")) json = json.slice(0, -1);\n json += \"\\\"\";\n }\n\n // Remove trailing comma or colon (invalid before closing bracket)\n json = json.replace(/[,:\\s]+$/, \"\");\n\n // Close open brackets in reverse order\n while (stack.length > 0) {\n const open = stack.pop();\n json += open === \"{\" ? \"}\" : \"]\";\n }\n\n return json;\n}\n","import pino from \"pino\";\nimport { env, stdout } from \"node:process\";\nimport { join } from \"node:path\";\n\nconst level = env.FIFONY_LOG_LEVEL ?? \"info\";\nconst pretty = env.FIFONY_LOG_PRETTY === \"1\" || (env.FIFONY_LOG_PRETTY !== \"0\" && stdout.isTTY);\n\n// Propagate pretty preference to s3db.js internal logger\n// so its pino output matches ours (must be set before s3db loads)\nif (!env.S3DB_LOG_FORMAT && !env.S3DB_LOG_PRETTY) {\n env.S3DB_LOG_PRETTY = pretty ? \"true\" : \"false\";\n}\nif (!env.S3DB_LOG_LEVEL) {\n env.S3DB_LOG_LEVEL = level;\n}\n\nfunction createTransports(logPath?: string) {\n const targets: pino.TransportTargetOptions[] = [];\n\n if (pretty) {\n targets.push({\n target: \"pino-pretty\",\n options: { colorize: true, translateTime: \"HH:MM:ss.l\", ignore: \"pid,hostname\" },\n level,\n });\n } else {\n targets.push({\n target: \"pino/file\",\n options: { destination: 1 },\n level,\n });\n }\n\n if (logPath) {\n targets.push({\n target: \"pino/file\",\n options: { destination: logPath, mkdir: true },\n level,\n });\n }\n\n return pino.transport({ targets });\n}\n\nlet _logger: pino.Logger | null = null;\nlet _logPath: string | undefined;\n\nexport function initLogger(stateRoot?: string): pino.Logger {\n _logPath = stateRoot ? join(stateRoot, \"fifony-local.log\") : undefined;\n _logger = pino({ name: \"fifony\", level }, createTransports(_logPath));\n return _logger;\n}\n\nexport function getLogger(): pino.Logger {\n if (!_logger) {\n _logger = pino({ name: \"fifony\", level }, createTransports());\n }\n return _logger;\n}\n\nexport const logger = {\n get info() { return getLogger().info.bind(getLogger()); },\n get warn() { return getLogger().warn.bind(getLogger()); },\n get error() { return getLogger().error.bind(getLogger()); },\n get debug() { return getLogger().debug.bind(getLogger()); },\n get fatal() { return getLogger().fatal.bind(getLogger()); },\n get child() { return getLogger().child.bind(getLogger()); },\n};\n","import { mkdirSync } from \"node:fs\";\nimport type {\n RuntimeState,\n RuntimeStateRecord,\n IssueEntry,\n RuntimeEvent,\n RuntimeSettingRecord,\n S3dbModule,\n S3dbDatabase,\n S3dbResource,\n} from \"./types.ts\";\nimport {\n S3DB_DATABASE_PATH,\n S3DB_BUCKET,\n S3DB_ISSUE_RESOURCE,\n S3DB_KEY_PREFIX,\n S3DB_RUNTIME_RECORD_ID,\n S3DB_RUNTIME_SCHEMA_VERSION,\n} from \"./constants.ts\";\nimport { now, debugBoot, fail } from \"./helpers.ts\";\nimport { logger } from \"./logger.ts\";\nimport { computeCapabilityCounts } from \"./issues.ts\";\nimport { getMetrics } from \"./metrics-cache.ts\";\nimport { clearApiRuntimeContext } from \"./api-runtime-context.ts\";\nimport { broadcastToWebSocketClients } from \"./api-server.ts\";\nimport { NATIVE_RESOURCE_CONFIGS, NATIVE_RESOURCE_NAMES } from \"./resources/index.ts\";\nimport {\n setIssueStateMachinePlugin,\n ISSUE_STATE_MACHINE_DEFINITION,\n ISSUE_STATE_MACHINE_ID,\n} from \"./issue-state-machine.ts\";\n\nlet loadedS3dbModule: S3dbModule | null = null;\nlet stateDb: S3dbDatabase | null = null;\nlet runtimeStateResource: S3dbResource | null = null;\nlet issueStateResource: S3dbResource | null = null;\nlet eventStateResource: S3dbResource | null = null;\nlet settingStateResource: S3dbResource | null = null;\nlet agentSessionResource: S3dbResource | null = null;\nlet agentPipelineResource: S3dbResource | null = null;\nlet activeApiPlugin: { stop?: () => Promise<void> } | null = null;\nlet activeStateMachinePlugin: { stop?: () => Promise<void> } | null = null;\nlet activeEcPlugin: S3dbModule[\"EventualConsistencyPlugin\"] extends new (...a: never[]) => infer R ? R | null : null = null;\n\nimport {\n markIssueDirty,\n markEventDirty,\n hasDirtyState,\n getDirtyIssueIds,\n getDirtyEventIds,\n clearDirtyIssueIds,\n clearDirtyEventIds,\n markAllIssuesDirty,\n markAllEventsDirty,\n} from \"./dirty-tracker.ts\";\n\nexport { markIssueDirty, markEventDirty, hasDirtyState };\n\nexport function getStateDb(): S3dbDatabase | null { return stateDb; }\nexport function getEventStateResource(): S3dbResource | null { return eventStateResource; }\nexport function getSettingStateResource(): S3dbResource | null { return settingStateResource; }\nexport function getAgentSessionResource(): S3dbResource | null { return agentSessionResource; }\nexport function getAgentPipelineResource(): S3dbResource | null { return agentPipelineResource; }\nexport function setActiveApiPlugin(plugin: { stop?: () => Promise<void> } | null): void { activeApiPlugin = plugin; }\nlet activeWebSocketPlugin: { stop?: () => Promise<void> } | null = null;\n\nexport async function loadS3dbModule(): Promise<S3dbModule> {\n if (loadedS3dbModule) return loadedS3dbModule;\n\n try {\n const imported = await import(\"s3db.js/lite\") as unknown as Record<string, unknown>;\n const pluginModule = await import(\"s3db.js/plugins/index\");\n\n let ApiPluginCtor: S3dbModule[\"ApiPlugin\"] | undefined;\n let WebSocketPluginCtor: S3dbModule[\"WebSocketPlugin\"] | undefined;\n let StateMachinePluginCtor: S3dbModule[\"StateMachinePlugin\"] | undefined;\n\n if (typeof (pluginModule as Record<string, unknown>).ApiPlugin === \"function\") {\n ApiPluginCtor = (pluginModule as { ApiPlugin: S3dbModule[\"ApiPlugin\"] }).ApiPlugin;\n } else if (typeof (pluginModule as Record<string, unknown>).loadApiPlugin === \"function\") {\n ApiPluginCtor = await (pluginModule as { loadApiPlugin: () => Promise<S3dbModule[\"ApiPlugin\"]> }).loadApiPlugin();\n }\n\n if (!ApiPluginCtor) {\n throw new Error(\"ApiPlugin export not found.\");\n }\n\n if (typeof (pluginModule as Record<string, unknown>).WebSocketPlugin === \"function\") {\n WebSocketPluginCtor = (pluginModule as { WebSocketPlugin: S3dbModule[\"WebSocketPlugin\"] }).WebSocketPlugin;\n } else if (typeof (pluginModule as Record<string, unknown>).loadWebSocketPlugin === \"function\") {\n WebSocketPluginCtor = await (pluginModule as { loadWebSocketPlugin: () => Promise<S3dbModule[\"WebSocketPlugin\"]> }).loadWebSocketPlugin();\n }\n\n if (typeof (pluginModule as Record<string, unknown>).StateMachinePlugin === \"function\") {\n StateMachinePluginCtor = (pluginModule as { StateMachinePlugin: S3dbModule[\"StateMachinePlugin\"] }).StateMachinePlugin;\n }\n\n let EventualConsistencyPluginCtor: S3dbModule[\"EventualConsistencyPlugin\"] | undefined;\n if (typeof (pluginModule as Record<string, unknown>).EventualConsistencyPlugin === \"function\") {\n EventualConsistencyPluginCtor = (pluginModule as { EventualConsistencyPlugin: S3dbModule[\"EventualConsistencyPlugin\"] }).EventualConsistencyPlugin;\n }\n\n loadedS3dbModule = {\n S3db: imported.S3db as S3dbModule[\"S3db\"],\n FileSystemClient: imported.FileSystemClient as S3dbModule[\"FileSystemClient\"],\n ApiPlugin: ApiPluginCtor,\n WebSocketPlugin: WebSocketPluginCtor,\n StateMachinePlugin: StateMachinePluginCtor,\n EventualConsistencyPlugin: EventualConsistencyPluginCtor,\n };\n return loadedS3dbModule;\n } catch (error) {\n fail(`Failed to load s3db.js: ${String(error)}`);\n }\n}\n\nexport async function initStateStore(): Promise<void> {\n debugBoot(\"initStateStore:start\");\n const { S3db, FileSystemClient, StateMachinePlugin } = await loadS3dbModule();\n debugBoot(\"initStateStore:module-loaded\");\n\n mkdirSync(S3DB_DATABASE_PATH, { recursive: true });\n\n stateDb = new S3db({\n client: new FileSystemClient({\n basePath: S3DB_DATABASE_PATH,\n bucket: S3DB_BUCKET,\n keyPrefix: S3DB_KEY_PREFIX,\n }),\n });\n\n await stateDb.connect();\n debugBoot(\"initStateStore:connected\");\n\n for (const resourceConfig of NATIVE_RESOURCE_CONFIGS) {\n await stateDb.createResource(resourceConfig);\n }\n\n if (StateMachinePlugin) {\n const stateMachinePlugin = await stateDb.usePlugin(\n new StateMachinePlugin({\n stateMachines: {\n [ISSUE_STATE_MACHINE_ID]: ISSUE_STATE_MACHINE_DEFINITION,\n },\n }) as unknown,\n \"state-machine\",\n ) as Record<string, unknown>;\n\n activeStateMachinePlugin = stateMachinePlugin as { stop?: () => Promise<void> };\n const bindPluginMethod = <T extends (...args: never[]) => unknown>(method: unknown): T | undefined => {\n return typeof method === \"function\" ? method.bind(stateMachinePlugin) as T : undefined;\n };\n setIssueStateMachinePlugin({\n send: bindPluginMethod<S3dbModule[\"StateMachinePlugin\"] extends { send?: infer T } ? T & ((...args: never[]) => unknown) : never>(stateMachinePlugin.send),\n getMachineDefinition: bindPluginMethod<S3dbModule[\"StateMachinePlugin\"] extends { getMachineDefinition?: infer T } ? T & ((...args: never[]) => unknown) : never>(stateMachinePlugin.getMachineDefinition),\n getState: bindPluginMethod<S3dbModule[\"StateMachinePlugin\"] extends { getState?: infer T } ? T & ((...args: never[]) => unknown) : never>(stateMachinePlugin.getState),\n initializeEntity: bindPluginMethod<S3dbModule[\"StateMachinePlugin\"] extends { initializeEntity?: infer T } ? T & ((...args: never[]) => unknown) : never>(stateMachinePlugin.initializeEntity),\n getValidEvents: bindPluginMethod<S3dbModule[\"StateMachinePlugin\"] extends { getValidEvents?: infer T } ? T & ((...args: never[]) => unknown) : never>(stateMachinePlugin.getValidEvents),\n });\n } else {\n logger.warn(\"StateMachinePlugin not available. Issue transitions will use local logic only.\");\n }\n\n // EventualConsistency plugin for token usage analytics\n const { EventualConsistencyPlugin } = await loadS3dbModule();\n if (EventualConsistencyPlugin) {\n try {\n const ecPlugin = new EventualConsistencyPlugin({\n resources: {\n [S3DB_ISSUE_RESOURCE]: [\n // Per-model totals (dynamic keys: { \"claude-sonnet-4-6\": 12345, \"o4-mini\": 6789 })\n { field: \"usage.tokens\", fieldPath: \"usage.tokens\", initialValue: 0, cohort: { granularity: \"day\" } },\n // Overall volume\n { field: \"tokenUsage.totalTokens\", fieldPath: \"tokenUsage.totalTokens\", initialValue: 0, cohort: { granularity: \"day\" } },\n { field: \"tokenUsage.inputTokens\", fieldPath: \"tokenUsage.inputTokens\", initialValue: 0, cohort: { granularity: \"day\" } },\n { field: \"tokenUsage.outputTokens\", fieldPath: \"tokenUsage.outputTokens\", initialValue: 0, cohort: { granularity: \"day\" } },\n // Per-phase volume\n { field: \"tokensByPhase.planner.totalTokens\", fieldPath: \"tokensByPhase.planner.totalTokens\", initialValue: 0, cohort: { granularity: \"day\" } },\n { field: \"tokensByPhase.executor.totalTokens\", fieldPath: \"tokensByPhase.executor.totalTokens\", initialValue: 0, cohort: { granularity: \"day\" } },\n { field: \"tokensByPhase.reviewer.totalTokens\", fieldPath: \"tokensByPhase.reviewer.totalTokens\", initialValue: 0, cohort: { granularity: \"day\" } },\n ],\n },\n enableAnalytics: true,\n analytics: { enabled: true },\n cohort: { granularity: \"day\", timezone: \"UTC\" },\n analyticsConfig: { rollupStrategy: \"incremental\", retentionDays: 90 },\n autoConsolidate: true,\n consolidationInterval: 30_000,\n });\n await stateDb.usePlugin(ecPlugin as unknown, \"eventual-consistency\");\n activeEcPlugin = ecPlugin as typeof activeEcPlugin;\n logger.info(\"EventualConsistency plugin installed for token usage analytics.\");\n } catch (error) {\n logger.warn(`EventualConsistency plugin failed to install: ${String(error)}`);\n }\n }\n\n const [\n runtimeStateResourceName,\n issueResourceName,\n eventResourceName,\n settingResourceName,\n agentSessionResourceName,\n agentPipelineResourceName,\n ] = NATIVE_RESOURCE_NAMES;\n runtimeStateResource = await stateDb.getResource(runtimeStateResourceName);\n issueStateResource = await stateDb.getResource(issueResourceName);\n eventStateResource = await stateDb.getResource(eventResourceName);\n settingStateResource = await stateDb.getResource(settingResourceName);\n agentSessionResource = await stateDb.getResource(agentSessionResourceName);\n agentPipelineResource = await stateDb.getResource(agentPipelineResourceName);\n debugBoot(\"initStateStore:resources-ready\");\n}\n\nexport function isStateNotFoundError(error: unknown): boolean {\n if (error instanceof Error) {\n return /not found|does not exist|no such key/i.test(error.message);\n }\n if (typeof error === \"string\") {\n return /not found|does not exist|no such key/i.test(error);\n }\n return false;\n}\n\nexport async function loadPersistedState(): Promise<RuntimeState | null> {\n if (!runtimeStateResource) {\n logger.debug(\"[Store] No runtime state resource available, skipping load\");\n return null;\n }\n\n logger.debug(\"[Store] Loading persisted state from s3db\");\n try {\n const record = await runtimeStateResource.get(S3DB_RUNTIME_RECORD_ID);\n if (record?.state && typeof record.state === \"object\") {\n const state = record.state as RuntimeState;\n if (Array.isArray(state.issues) && state.issues.length > 0) {\n return state;\n }\n // State blob has no issues — try recovering from individual issue records\n logger.warn(\"Runtime state blob has no issues, attempting recovery from issue resource...\");\n }\n } catch (error) {\n if (!isStateNotFoundError(error)) {\n logger.warn(`Could not load persisted state from s3db (will attempt issue recovery): ${String(error)}`);\n }\n }\n\n // Fallback: recover issues from individual s3db issue records\n return recoverStateFromIssueResource();\n}\n\nasync function recoverStateFromIssueResource(): Promise<RuntimeState | null> {\n if (!issueStateResource) return null;\n\n try {\n const records = await (issueStateResource as any).list({ limit: 500 });\n if (!Array.isArray(records) || records.length === 0) return null;\n\n const issues = records\n .filter((r: any) => r?.id && r?.identifier && r?.state)\n .map((r: any) => r as RuntimeState[\"issues\"][number]);\n\n if (issues.length === 0) return null;\n\n logger.info(`Recovered ${issues.length} issue(s) from s3db issue resource.`);\n\n return {\n startedAt: now(),\n updatedAt: now(),\n trackerKind: \"filesystem\",\n sourceRepoUrl: \"\",\n sourceRef: \"workspace\",\n workflowPath: \"\",\n config: {} as any,\n issues,\n events: [],\n metrics: getMetrics(issues),\n notes: [\"State recovered from individual issue records after corruption.\"],\n };\n } catch (error) {\n logger.warn(`Failed to recover issues from s3db: ${String(error)}`);\n return null;\n }\n}\n\nexport async function persistState(state: RuntimeState): Promise<void> {\n state.metrics = {\n ...getMetrics(state.issues),\n activeWorkers: state.metrics.activeWorkers,\n };\n\n if (!runtimeStateResource) return;\n\n // Only write the runtime state blob if something changed\n const dirty = hasDirtyState();\n const dirtyIssueCount = getDirtyIssueIds().size;\n const dirtyEventCount = getDirtyEventIds().size;\n if (dirty || dirtyIssueCount > 0 || dirtyEventCount > 0) {\n logger.debug({ dirty, dirtyIssues: dirtyIssueCount, dirtyEvents: dirtyEventCount }, \"[Store] Persisting state\");\n }\n\n if (dirty) {\n await runtimeStateResource.replace(S3DB_RUNTIME_RECORD_ID, {\n id: S3DB_RUNTIME_RECORD_ID,\n schemaVersion: S3DB_RUNTIME_SCHEMA_VERSION,\n trackerKind: \"filesystem\",\n runtimeTag: \"local-only\",\n updatedAt: now(),\n state,\n } satisfies RuntimeStateRecord);\n }\n\n const dirtyIssues = getDirtyIssueIds();\n if (issueStateResource && dirtyIssues.size > 0) {\n for (const issue of state.issues) {\n if (!dirtyIssues.has(issue.id)) continue;\n // s3db requires valid datetime or undefined — clean empty strings\n const clean = {\n ...issue,\n nextRetryAt: issue.nextRetryAt || undefined,\n startedAt: issue.startedAt || undefined,\n completedAt: issue.completedAt || undefined,\n workspacePreparedAt: issue.workspacePreparedAt || undefined,\n commandExitCode: typeof issue.commandExitCode === \"number\" ? issue.commandExitCode : undefined,\n };\n try {\n await issueStateResource.replace(issue.id, clean satisfies IssueEntry);\n } catch (error) {\n logger.warn(`Failed to persist issue ${issue.id}: ${String(error)}`);\n }\n }\n clearDirtyIssueIds();\n }\n\n const dirtyEvents = getDirtyEventIds();\n if (eventStateResource && dirtyEvents.size > 0) {\n for (const event of state.events) {\n if (!dirtyEvents.has(event.id)) continue;\n await eventStateResource.replace(event.id, event satisfies RuntimeEvent);\n }\n clearDirtyEventIds();\n }\n\n // Push state to connected WebSocket clients\n broadcastToWebSocketClients({\n type: \"state:update\",\n metrics: state.metrics,\n capabilities: computeCapabilityCounts(state.issues),\n issues: state.issues,\n events: state.events.slice(0, 50),\n updatedAt: state.updatedAt,\n });\n}\n\n/** Force persist all issues (used during boot and shutdown). */\nexport async function persistStateFull(state: RuntimeState): Promise<void> {\n markAllIssuesDirty(state.issues.map((i) => i.id));\n markAllEventsDirty(state.events.map((e) => e.id));\n await persistState(state);\n}\n\nexport async function loadPersistedSettings(): Promise<RuntimeSettingRecord[]> {\n if (!settingStateResource?.list) return [];\n\n try {\n const records = await settingStateResource.list({ limit: 500 });\n return Array.isArray(records)\n ? records.filter((record): record is RuntimeSettingRecord =>\n Boolean(\n record &&\n typeof record.id === \"string\" &&\n typeof record.scope === \"string\",\n ),\n )\n : [];\n } catch (error) {\n logger.warn(`Failed to load persisted settings from s3db: ${String(error)}`);\n return [];\n }\n}\n\nexport async function replacePersistedSetting(setting: RuntimeSettingRecord): Promise<void> {\n if (!settingStateResource) return;\n await settingStateResource.replace(setting.id, setting);\n}\n\nexport async function closeStateStore(): Promise<void> {\n logger.info(\"[Store] Closing state store and plugins\");\n clearApiRuntimeContext();\n if (activeEcPlugin?.stop) {\n try {\n await activeEcPlugin.stop();\n } catch (error) {\n logger.warn(`Failed to stop EventualConsistency plugin: ${String(error)}`);\n } finally {\n activeEcPlugin = null;\n }\n }\n if (activeStateMachinePlugin?.stop) {\n try {\n await activeStateMachinePlugin.stop();\n } catch (error) {\n logger.warn(`Failed to stop StateMachine plugin: ${String(error)}`);\n } finally {\n activeStateMachinePlugin = null;\n setIssueStateMachinePlugin(null);\n }\n }\n if (activeWebSocketPlugin?.stop) {\n try {\n await activeWebSocketPlugin.stop();\n } catch (error) {\n logger.warn(`Failed to stop WebSocket plugin: ${String(error)}`);\n } finally {\n activeWebSocketPlugin = null;\n }\n }\n if (activeApiPlugin?.stop) {\n try {\n await activeApiPlugin.stop();\n } catch (error) {\n logger.warn(`Failed to stop API plugin: ${String(error)}`);\n } finally {\n activeApiPlugin = null;\n }\n }\n\n if (!stateDb) return;\n\n try {\n await stateDb.disconnect();\n } catch (error) {\n logger.warn(`Failed to close s3db runtime store: ${String(error)}`);\n } finally {\n stateDb = null;\n runtimeStateResource = null;\n issueStateResource = null;\n eventStateResource = null;\n settingStateResource = null;\n agentSessionResource = null;\n agentPipelineResource = null;\n }\n}\n","import { env } from \"node:process\";\nimport * as tokenLedger from \"./token-ledger.ts\";\nimport { markIssueDirty, markEventDirty } from \"./dirty-tracker.ts\";\nimport { invalidateMetrics } from \"./metrics-cache.ts\";\nimport type {\n EffortConfig,\n IssueEntry,\n IssueState,\n JsonRecord,\n ReasoningEffort,\n RuntimeConfig,\n RuntimeEvent,\n RuntimeEventType,\n RuntimeMetrics,\n RuntimeState,\n WorkflowDefinition,\n} from \"./types.ts\";\nimport {\n ISSUE_STATE_MACHINE_ID,\n findIssueStateMachineTransitionPath,\n getIssueStateMachineDefinition,\n getIssueStateMachineInitialState,\n getIssueStateMachinePlugin,\n type IssueStateMachinePluginLike,\n} from \"./issue-state-machine.ts\";\nimport {\n ALLOWED_STATES,\n PERSIST_EVENTS_MAX,\n TERMINAL_STATES,\n STATE_ROOT,\n TARGET_ROOT,\n WORKFLOW_RENDERED,\n} from \"./constants.ts\";\nimport {\n now,\n isoWeek,\n toStringValue,\n toNumberValue,\n toBooleanValue,\n toStringArray,\n clamp,\n normalizeState,\n parseEnvNumber,\n parseIntArg,\n parsePositiveIntEnv,\n withRetryBackoff,\n getNestedRecord,\n getNestedString,\n getNestedNumber,\n fail,\n} from \"./helpers.ts\";\nimport { logger } from \"./logger.ts\";\nimport {\n normalizeAgentProvider,\n resolveAgentCommand,\n getCapabilityRoutingOptions,\n applyCapabilityMetadata,\n} from \"./providers.ts\";\nimport { resolveTaskCapabilities } from \"../routing/capability-resolver.ts\";\n\nexport function normalizeIssue(\n raw: JsonRecord,\n workflowDefinition: WorkflowDefinition | null,\n): IssueEntry | null {\n const id = toStringValue(raw.id, \"\");\n if (!id) return null;\n\n const createdAt = toStringValue(raw.created_at, now());\n const updatedAt = toStringValue(raw.updated_at, createdAt);\n const issue: IssueEntry = {\n id,\n identifier: toStringValue(raw.identifier, id),\n title: toStringValue(raw.title, `Issue ${id}`),\n description: toStringValue(raw.description, \"\"),\n priority: toNumberValue(raw.priority, 1),\n state: normalizeState(raw.state),\n branchName: toStringValue(raw.branchName) || toStringValue(raw.branch_name),\n url: toStringValue(raw.url),\n assigneeId: toStringValue(raw.assignee_id),\n labels: toStringArray(raw.labels),\n paths: toStringArray(raw.paths),\n inferredPaths: toStringArray(raw.inferredPaths),\n capabilityCategory: toStringValue(raw.capabilityCategory),\n capabilityOverlays: toStringArray(raw.capabilityOverlays),\n capabilityRationale: toStringArray(raw.capabilityRationale),\n blockedBy: toStringArray(raw.blockedBy),\n assignedToWorker: toBooleanValue(raw.assigned_to_worker, true),\n createdAt,\n updatedAt,\n history: [],\n attempts: toNumberValue(raw.attempts, 0),\n maxAttempts: toNumberValue(raw.max_attempts, 3),\n nextRetryAt: toStringValue(raw.next_retry_at),\n };\n\n if (!issue.capabilityCategory) {\n applyCapabilityMetadata(issue, resolveTaskCapabilities({\n id: issue.id,\n identifier: issue.identifier,\n title: issue.title,\n description: issue.description,\n labels: issue.labels,\n paths: issue.paths,\n }, getCapabilityRoutingOptions(workflowDefinition)));\n }\n\n return issue;\n}\n\nconst VALID_EFFORTS = new Set([\"low\", \"medium\", \"high\", \"extra-high\"]);\n\nfunction parseEffortValue(value: unknown): ReasoningEffort | undefined {\n const str = typeof value === \"string\" ? value.trim().toLowerCase() : \"\";\n return VALID_EFFORTS.has(str) ? (str as ReasoningEffort) : undefined;\n}\n\nfunction parseEffortConfig(value: unknown): EffortConfig | undefined {\n if (!value || typeof value !== \"object\") {\n // Simple string → default effort for all roles\n const simple = parseEffortValue(value);\n return simple ? { default: simple } : undefined;\n }\n const obj = value as Record<string, unknown>;\n const config: EffortConfig = {};\n const d = parseEffortValue(obj.default);\n const p = parseEffortValue(obj.planner);\n const e = parseEffortValue(obj.executor);\n const r = parseEffortValue(obj.reviewer);\n if (d) config.default = d;\n if (p) config.planner = p;\n if (e) config.executor = e;\n if (r) config.reviewer = r;\n return Object.keys(config).length > 0 ? config : undefined;\n}\n\nexport function nextLocalIssueId(issues: IssueEntry[]): string {\n const maxId = issues.reduce((current, issue) => {\n const match = issue.identifier.match(/^#(\\d+)$/);\n if (!match) return current;\n const parsed = Number.parseInt(match[1], 10);\n return Number.isFinite(parsed) ? Math.max(current, parsed) : current;\n }, 0);\n\n return `#${maxId + 1}`;\n}\n\nexport function createIssueFromPayload(\n payload: JsonRecord,\n issues: IssueEntry[],\n workflowDefinition: WorkflowDefinition | null,\n): IssueEntry {\n const identifier = toStringValue(payload.identifier, nextLocalIssueId(issues));\n const id = toStringValue(payload.id, identifier.replace(/^#/, \"issue-\"));\n logger.info({ id, identifier, title: toStringValue(payload.title, \"\").slice(0, 80) }, \"[Issues] Creating new issue\");\n const createdAt = now();\n const blockedBy = toStringArray(payload.blockedBy);\n const paths = toStringArray(payload.paths);\n\n const issue: IssueEntry = {\n id,\n identifier,\n title: toStringValue(payload.title, `Issue ${identifier}`),\n description: toStringValue(payload.description, \"\"),\n priority: clamp(toNumberValue(payload.priority, 1), 1, 10),\n state: payload.plan ? \"Todo\" : \"Planning\",\n branchName: toStringValue(payload.branchName),\n url: toStringValue(payload.url),\n assigneeId: toStringValue(payload.assigneeId),\n labels: toStringArray(payload.labels),\n paths,\n inferredPaths: [],\n capabilityCategory: \"\",\n capabilityOverlays: [],\n capabilityRationale: [],\n blockedBy,\n assignedToWorker: true,\n createdAt,\n updatedAt: createdAt,\n history: [`[${createdAt}] Issue created via API.`],\n attempts: 0,\n maxAttempts: clamp(toNumberValue(payload.maxAttempts, 3), 1, 10),\n terminalWeek: \"\",\n effort: parseEffortConfig(payload.effort),\n plan: payload.plan && typeof payload.plan === \"object\" ? payload.plan as IssueEntry[\"plan\"] : undefined,\n };\n\n // If plan provides suggestions, apply them\n if (issue.plan) {\n if (issue.plan.suggestedPaths?.length && !issue.paths?.length) {\n issue.paths = issue.plan.suggestedPaths;\n }\n if (issue.plan.suggestedLabels?.length && !issue.labels?.length) {\n issue.labels = issue.plan.suggestedLabels;\n }\n if (issue.plan.suggestedEffort && !issue.effort) {\n issue.effort = issue.plan.suggestedEffort;\n }\n }\n\n applyCapabilityMetadata(issue, resolveTaskCapabilities({\n id: issue.id,\n identifier: issue.identifier,\n title: issue.title,\n description: issue.description,\n labels: issue.labels,\n paths: issue.paths,\n }, getCapabilityRoutingOptions(workflowDefinition)));\n\n return issue;\n}\n\nexport function deriveConfig(args: string[]): RuntimeConfig {\n const parsedConcurrency = parsePositiveIntEnv(\"FIFONY_WORKER_CONCURRENCY\", 2);\n let pollIntervalMs = parseEnvNumber(\"FIFONY_POLL_INTERVAL_MS\", 1200);\n let workerConcurrency = parsedConcurrency;\n let maxAttemptsDefault = parseEnvNumber(\"FIFONY_MAX_ATTEMPTS\", 3);\n let commandTimeoutMs = parseEnvNumber(\"FIFONY_AGENT_TIMEOUT_MS\", 1_800_000);\n\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n if (arg === \"--poll\") {\n const value = args[i + 1] ?? \"\";\n if (!/^\\d+$/.test(value)) fail(`Invalid value for --poll: ${value}`);\n pollIntervalMs = parseIntArg(value, pollIntervalMs);\n }\n if (arg === \"--concurrency\") {\n const value = args[i + 1] ?? \"\";\n if (!/^\\d+$/.test(value)) fail(`Invalid value for --concurrency: ${value}`);\n workerConcurrency = parseIntArg(value, workerConcurrency);\n }\n if (arg === \"--attempts\") {\n const value = args[i + 1] ?? \"\";\n if (!/^\\d+$/.test(value)) fail(`Invalid value for --attempts: ${value}`);\n maxAttemptsDefault = parseIntArg(value, maxAttemptsDefault);\n }\n if (arg === \"--timeout\") {\n const value = args[i + 1] ?? \"\";\n if (!/^\\d+$/.test(value)) fail(`Invalid value for --timeout: ${value}`);\n commandTimeoutMs = parseIntArg(value, commandTimeoutMs);\n }\n }\n\n return {\n pollIntervalMs: clamp(pollIntervalMs, 200, 10_000),\n workerConcurrency: clamp(workerConcurrency, 1, 16),\n commandTimeoutMs: clamp(commandTimeoutMs, 1_000, 3_600_000),\n maxAttemptsDefault: clamp(maxAttemptsDefault, 1, 10),\n maxTurns: clamp(parseEnvNumber(\"FIFONY_AGENT_MAX_TURNS\", 4), 1, 16),\n retryDelayMs: parseEnvNumber(\"FIFONY_RETRY_DELAY_MS\", 3_000),\n staleInProgressTimeoutMs: parseEnvNumber(\"FIFONY_STALE_IN_PROGRESS_MS\", 2_400_000),\n logLinesTail: parseEnvNumber(\"FIFONY_LOG_TAIL_CHARS\", 12_000),\n agentProvider: normalizeAgentProvider(env.FIFONY_AGENT_PROVIDER ?? \"codex\"),\n agentCommand: toStringValue(env.FIFONY_AGENT_COMMAND, \"\"),\n defaultEffort: {\n default: parseEffortValue(env.FIFONY_REASONING_EFFORT),\n planner: parseEffortValue(env.FIFONY_PLANNER_EFFORT),\n executor: parseEffortValue(env.FIFONY_EXECUTOR_EFFORT),\n reviewer: parseEffortValue(env.FIFONY_REVIEWER_EFFORT),\n },\n maxConcurrentByState: {},\n runMode: \"filesystem\",\n };\n}\n\nexport function applyWorkflowConfig(\n config: RuntimeConfig,\n port: number | undefined,\n): RuntimeConfig {\n return {\n ...config,\n dashboardPort: port ? String(port) : config.dashboardPort,\n };\n}\n\nexport function validateConfig(config: RuntimeConfig): string[] {\n const errors: string[] = [];\n if (config.pollIntervalMs < 200) errors.push(`pollIntervalMs too low: ${config.pollIntervalMs} (min 200)`);\n if (config.workerConcurrency < 1 || config.workerConcurrency > 16) errors.push(`workerConcurrency out of range: ${config.workerConcurrency} (1-16)`);\n if (config.maxAttemptsDefault < 1 || config.maxAttemptsDefault > 10) errors.push(`maxAttemptsDefault out of range: ${config.maxAttemptsDefault} (1-10)`);\n if (config.maxTurns < 1 || config.maxTurns > 16) errors.push(`maxTurns out of range: ${config.maxTurns} (1-16)`);\n if (config.commandTimeoutMs < 1000) errors.push(`commandTimeoutMs too low: ${config.commandTimeoutMs} (min 1000)`);\n if (config.retryDelayMs < 0) errors.push(`retryDelayMs negative: ${config.retryDelayMs}`);\n for (const [stateKey, limit] of Object.entries(config.maxConcurrentByState)) {\n if (limit < 1) errors.push(`maxConcurrentByState[${stateKey}] must be >= 1, got ${limit}`);\n }\n return errors;\n}\n\nexport function dedupHistoryEntries(issues: IssueEntry[]): void {\n for (const issue of issues) {\n const seen = new Set<string>();\n issue.history = issue.history.filter((entry) => {\n const key = entry.toLowerCase();\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n }\n}\n\nexport function buildRuntimeState(\n previous: RuntimeState | null,\n config: RuntimeConfig,\n definition: WorkflowDefinition,\n): RuntimeState {\n const mergedIssues = (previous?.issues ?? [])\n .map((rawIssue) => {\n if (!rawIssue || typeof rawIssue !== \"object\") return null;\n\n const existing = rawIssue as IssueEntry;\n return {\n ...existing,\n id: toStringValue(existing.id, \"\"),\n identifier: toStringValue(existing.identifier, existing.id),\n title: toStringValue(existing.title, `Issue ${toStringValue(existing.identifier, existing.id)}`),\n description: toStringValue(existing.description, \"\"),\n state: normalizeState(existing.state),\n paths: toStringArray(existing.paths),\n inferredPaths: toStringArray(existing.inferredPaths),\n labels: toStringArray(existing.labels),\n capabilityOverlays: toStringArray(existing.capabilityOverlays),\n capabilityRationale: toStringArray(existing.capabilityRationale),\n blockedBy: toStringArray(existing.blockedBy).length > 0\n ? toStringArray(existing.blockedBy)\n : toStringArray(existing.blocked_by),\n history: Array.isArray(existing.history) ? existing.history : [],\n attempts: clamp(toNumberValue(existing.attempts, 0), 0, config.maxAttemptsDefault),\n maxAttempts: clamp(toNumberValue(existing.maxAttempts, config.maxAttemptsDefault), 1, config.maxAttemptsDefault),\n nextRetryAt: toStringValue(existing.nextRetryAt),\n updatedAt: toStringValue(existing.updatedAt, now()),\n createdAt: toStringValue(existing.createdAt, now()),\n };\n })\n .filter((issue): issue is IssueEntry => issue !== null)\n .filter((issue) => issue.id);\n\n // Backfill terminalWeek for existing terminal issues that don't have it\n for (const issue of mergedIssues) {\n if (TERMINAL_STATES.has(issue.state) && !issue.terminalWeek) {\n issue.terminalWeek = isoWeek(issue.completedAt || issue.updatedAt);\n } else if (!TERMINAL_STATES.has(issue.state)) {\n issue.terminalWeek = \"\";\n }\n }\n\n dedupHistoryEntries(mergedIssues);\n\n const metrics = computeMetrics(mergedIssues);\n\n return {\n startedAt: previous?.startedAt ?? now(),\n updatedAt: now(),\n trackerKind: \"filesystem\",\n sourceRepoUrl: TARGET_ROOT,\n sourceRef: \"workspace\",\n workflowPath: WORKFLOW_RENDERED,\n config: {\n ...config,\n dashboardPort: previous?.config.dashboardPort,\n },\n issues: mergedIssues,\n events: previous?.events ?? [],\n metrics,\n notes: previous?.notes ?? [\n \"Local TypeScript runtime bootstrapped.\",\n `Workflow loaded from ${definition.workflowPath}.`,\n \"Codex-only execution path enabled.\",\n \"No external tracker dependency (filesystem-backed local mode).\",\n ],\n };\n}\n\nexport function computeMetrics(issues: IssueEntry[]): RuntimeMetrics {\n let planning = 0;\n let queued = 0;\n let inProgress = 0;\n let blocked = 0;\n let done = 0;\n let cancelled = 0;\n const completionTimes: number[] = [];\n\n for (const issue of issues) {\n const duration = issue.durationMs;\n if (issue.state === \"Done\") {\n const candidate = typeof duration === \"number\" && Number.isFinite(duration)\n ? duration\n : Number.isFinite(Date.parse(issue.startedAt ?? \"\")) && Number.isFinite(Date.parse(issue.completedAt ?? \"\"))\n ? Date.parse(issue.completedAt) - Date.parse(issue.startedAt)\n : NaN;\n if (Number.isFinite(candidate) && candidate >= 0) {\n completionTimes.push(candidate);\n }\n }\n\n switch (issue.state) {\n case \"Planning\":\n planning += 1;\n break;\n case \"Todo\":\n queued += 1;\n break;\n case \"Queued\":\n case \"Running\":\n case \"Interrupted\":\n case \"In Review\":\n inProgress += 1;\n break;\n case \"Blocked\":\n blocked += 1;\n break;\n case \"Done\":\n done += 1;\n break;\n case \"Cancelled\":\n cancelled += 1;\n break;\n }\n }\n\n if (completionTimes.length === 0) {\n return {\n total: issues.length,\n planning,\n queued,\n inProgress,\n blocked,\n done,\n cancelled,\n activeWorkers: 0,\n };\n }\n\n const sortedCompletionTimes = completionTimes.slice().sort((a, b) => a - b);\n const totalCompletionMs = sortedCompletionTimes.reduce((acc, value) => acc + value, 0);\n const mid = Math.floor(sortedCompletionTimes.length / 2);\n const medianCompletionMs = sortedCompletionTimes.length % 2 === 1\n ? sortedCompletionTimes[mid]\n : Math.round((sortedCompletionTimes[mid - 1] + sortedCompletionTimes[mid]) / 2);\n\n return {\n total: issues.length,\n planning,\n queued,\n inProgress,\n blocked,\n done,\n cancelled,\n activeWorkers: 0,\n avgCompletionMs: Math.round(totalCompletionMs / completionTimes.length),\n medianCompletionMs,\n fastestCompletionMs: sortedCompletionTimes[0]!,\n slowestCompletionMs: sortedCompletionTimes[sortedCompletionTimes.length - 1]!,\n };\n}\n\nexport function computeCapabilityCounts(issues: IssueEntry[]): Record<string, number> {\n return issues.reduce<Record<string, number>>((accumulator, issue) => {\n const key = issue.capabilityCategory?.trim() || \"default\";\n accumulator[key] = (accumulator[key] ?? 0) + 1;\n return accumulator;\n }, {});\n}\n\nexport function addEvent(\n state: RuntimeState,\n issueId: string | undefined,\n kind: RuntimeEventType,\n message: string,\n): void {\n const event: RuntimeEvent = {\n id: `${Date.now()}-${state.events.length + 1}`,\n issueId,\n kind,\n message,\n at: now(),\n };\n\n state.events = [event, ...state.events].slice(0, PERSIST_EVENTS_MAX);\n markEventDirty(event.id);\n\n // Track event in hourly counter for sparklines\n try { tokenLedger.recordEvent(); } catch { /* non-critical */ }\n\n logger.info({ issueId, kind }, message);\n}\n\nexport function transition(issue: IssueEntry, target: IssueState, note: string): void {\n const previous = issue.state;\n logger.debug({ issueId: issue.id, identifier: issue.identifier, from: previous, to: target, note }, \"[State] Issue transition\");\n issue.state = target;\n issue.updatedAt = now();\n markIssueDirty(issue.id);\n invalidateMetrics();\n issue.history.push(`[${issue.updatedAt}] ${note}`);\n\n if (previous === \"Blocked\" && target === \"Todo\") {\n issue.lastError = undefined;\n issue.nextRetryAt = undefined;\n }\n\n if (TERMINAL_STATES.has(target)) {\n issue.completedAt = now();\n issue.nextRetryAt = undefined;\n issue.terminalWeek = isoWeek();\n }\n\n // Clear terminalWeek when leaving terminal state\n if (TERMINAL_STATES.has(previous) && !TERMINAL_STATES.has(target)) {\n issue.terminalWeek = \"\";\n }\n\n if (target === \"Todo\") {\n issue.attempts = Math.max(0, issue.attempts - 1);\n }\n\n if (target === \"Done\") {\n issue.lastError = undefined;\n }\n}\n\nexport function issueDependenciesResolved(issue: IssueEntry, allIssues: IssueEntry[]): boolean {\n if (issue.blockedBy.length === 0) return true;\n const map = new Map(allIssues.map((entry) => [entry.id, entry]));\n return issue.blockedBy.every((dependencyId) => {\n const dep = map.get(dependencyId);\n return dep?.state === \"Done\";\n });\n}\n\nexport function getNextRetryAt(issue: IssueEntry, baseMs: number): string {\n const nextAttempt = issue.attempts + 1;\n const nextDelay = withRetryBackoff(nextAttempt, baseMs);\n return new Date(Date.now() + nextDelay).toISOString();\n}\n\nasync function syncIssueWithStateMachineIfNeeded(issue: IssueEntry): Promise<void> {\n const plugin = getIssueStateMachinePlugin();\n if (!plugin || !plugin.getState || !plugin.send || !plugin.initializeEntity) {\n return;\n }\n\n let machineDefinition: unknown;\n try {\n machineDefinition = plugin.getMachineDefinition\n ? plugin.getMachineDefinition(ISSUE_STATE_MACHINE_ID)\n : getIssueStateMachineDefinition();\n } catch {\n machineDefinition = getIssueStateMachineDefinition();\n }\n const targetState = normalizeState(issue.state);\n let machineState = await plugin.getState(ISSUE_STATE_MACHINE_ID, issue.id).catch(() => null);\n\n if (!machineState) {\n await plugin.initializeEntity(ISSUE_STATE_MACHINE_ID, issue.id, {\n issueId: issue.id,\n issueIdentifier: issue.identifier,\n state: targetState,\n });\n machineState = await plugin.getState(ISSUE_STATE_MACHINE_ID, issue.id).catch(() => {\n return getIssueStateMachineInitialState(machineDefinition);\n });\n }\n\n if (machineState === targetState) {\n return;\n }\n\n const path = findIssueStateMachineTransitionPath(machineDefinition, machineState, targetState);\n if (!path) {\n throw new Error(`State machine cannot synchronize issue ${issue.id} from '${machineState}' to '${targetState}'.`);\n }\n\n for (const event of path) {\n await plugin.send(ISSUE_STATE_MACHINE_ID, issue.id, event, {\n issueId: issue.id,\n issueIdentifier: issue.identifier,\n transition: \"sync\",\n targetState,\n });\n }\n}\n\nexport async function syncIssueStateMachineState(issue: IssueEntry): Promise<void> {\n await syncIssueWithStateMachineIfNeeded(issue);\n}\n\nexport async function syncIssueStateMachineStates(issues: IssueEntry[]): Promise<void> {\n for (const issue of issues) {\n try {\n await syncIssueWithStateMachineIfNeeded(issue);\n } catch (error) {\n logger.warn(`State machine sync failed for issue ${issue.id}: ${String(error)}`);\n }\n }\n}\n\nasync function runStateMachineTransition(issue: IssueEntry, targetState: IssueState, note: string): Promise<void> {\n const plugin = getIssueStateMachinePlugin() as IssueStateMachinePluginLike | null;\n if (!plugin?.send || !plugin.getState) {\n transition(issue, targetState, note);\n return;\n }\n\n let machineDefinition: unknown;\n try {\n machineDefinition = plugin.getMachineDefinition\n ? plugin.getMachineDefinition(ISSUE_STATE_MACHINE_ID)\n : getIssueStateMachineDefinition();\n } catch {\n machineDefinition = getIssueStateMachineDefinition();\n }\n const currentRuntimeState = normalizeState(issue.state);\n const target = normalizeState(targetState);\n\n await syncIssueWithStateMachineIfNeeded(issue);\n const machineState = await plugin.getState(ISSUE_STATE_MACHINE_ID, issue.id).catch(() => currentRuntimeState);\n\n if (machineState !== currentRuntimeState) {\n throw new Error(`State machine desync while transitioning issue ${issue.id}: expected ${currentRuntimeState}, machine has ${machineState}.`);\n }\n\n if (currentRuntimeState !== target) {\n const path = findIssueStateMachineTransitionPath(machineDefinition, currentRuntimeState, target);\n if (!path) {\n throw new Error(`State machine does not allow transition from '${currentRuntimeState}' to '${target}' for issue ${issue.id}.`);\n }\n\n for (const event of path) {\n await plugin.send(ISSUE_STATE_MACHINE_ID, issue.id, event, {\n issueId: issue.id,\n issueIdentifier: issue.identifier,\n fromState: issue.state,\n toState: target,\n note,\n });\n }\n }\n\n transition(issue, target, note);\n}\n\nexport async function transitionIssueState(\n issue: IssueEntry,\n target: IssueState,\n note: string,\n options?: { fallbackToLocal?: boolean },\n): Promise<void> {\n try {\n await runStateMachineTransition(issue, target, note);\n return;\n } catch (error) {\n if (options?.fallbackToLocal || !getIssueStateMachinePlugin()) {\n logger.warn(`State machine transition failed for issue ${issue.id}, falling back to local transition: ${String(error)}`);\n transition(issue, target, note);\n return;\n }\n throw error;\n }\n}\n\nexport async function handleStatePatch(state: RuntimeState, issue: IssueEntry, payload: JsonRecord): Promise<void> {\n const nextState = normalizeState(payload.state);\n const allowed = new Set(ALLOWED_STATES);\n\n if (!allowed.has(nextState)) {\n throw new Error(`Unsupported state: ${String(payload.state)}`);\n }\n\n await transitionIssueState(issue, nextState, `Manual state update: ${nextState}`);\n if (nextState === \"Todo\") {\n issue.nextRetryAt = undefined;\n issue.lastError = undefined;\n }\n if (nextState === \"Cancelled\") {\n issue.lastError = toStringValue(payload.reason);\n }\n\n addEvent(state, issue.id, \"manual\", `Manual state transition to ${nextState}`);\n}\n","/**\n * In-memory token usage ledger.\n *\n * Updated O(1) per turn via `record()`.\n * Queried O(1) for all analytics views — no disk I/O, no scans.\n *\n * Hydrated once at startup from existing issue data,\n * then kept in sync incrementally as turns complete.\n */\n\nimport type { AgentProviderRole, AgentTokenUsage, IssueEntry } from \"./types.ts\";\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport type TokenBucket = {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n};\n\nexport type DailyBucket = TokenBucket & {\n date: string; // \"2026-03-16\"\n};\n\nexport type HourlyBucket = TokenBucket & {\n hour: string; // \"2026-03-16T14\" (ISO date + hour)\n};\n\nexport type HourlySnapshot = {\n tokensPerHour: HourlyBucket[];\n eventsPerHour: Array<{ hour: string; count: number }>;\n};\n\nexport type TokenAnalytics = {\n overall: TokenBucket;\n byPhase: Record<string, TokenBucket>;\n byModel: Record<string, TokenBucket>;\n daily: DailyBucket[];\n dailyByPhase: Record<string, DailyBucket[]>;\n dailyByModel: Record<string, DailyBucket[]>;\n topIssues: Array<{ id: string; identifier: string; title: string; totalTokens: number }>;\n};\n\n// ── Internal state ───────────────────────────────────────────────────────────\n\nconst EMPTY: TokenBucket = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n\n/** Overall aggregate */\nlet overall: TokenBucket = { ...EMPTY };\n\n/** Per-phase aggregate */\nconst byPhase = new Map<string, TokenBucket>();\n\n/** Per-model aggregate */\nconst byModel = new Map<string, TokenBucket>();\n\n/** Daily overall: date → bucket */\nconst daily = new Map<string, TokenBucket>();\n\n/** Daily per-phase: \"phase:date\" → bucket */\nconst dailyByPhase = new Map<string, TokenBucket>();\n\n/** Daily per-model: \"model:date\" → bucket */\nconst dailyByModel = new Map<string, TokenBucket>();\n\n/** Per-issue totals (for top-N) */\nconst byIssue = new Map<string, { identifier: string; title: string; totalTokens: number }>();\n\n/** Hourly token buckets: \"2026-03-16T14\" → bucket */\nconst hourly = new Map<string, TokenBucket>();\n\n/** Hourly event counter: \"2026-03-16T14\" → count */\nconst eventsHourly = new Map<string, number>();\n\nconst HOURLY_RETENTION = 48; // keep last 48 hours\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction todayDate(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nfunction currentHour(): string {\n return new Date().toISOString().slice(0, 13); // \"2026-03-16T14\"\n}\n\nfunction pruneOldHours(): void {\n if (hourly.size <= HOURLY_RETENTION && eventsHourly.size <= HOURLY_RETENTION) return;\n const cutoff = new Date(Date.now() - HOURLY_RETENTION * 3600_000).toISOString().slice(0, 13);\n for (const key of hourly.keys()) {\n if (key < cutoff) hourly.delete(key);\n }\n for (const key of eventsHourly.keys()) {\n if (key < cutoff) eventsHourly.delete(key);\n }\n}\n\nfunction addTo(target: TokenBucket, usage: AgentTokenUsage): void {\n target.inputTokens += usage.inputTokens;\n target.outputTokens += usage.outputTokens;\n target.totalTokens += usage.totalTokens;\n}\n\nfunction getOrCreate(map: Map<string, TokenBucket>, key: string): TokenBucket {\n let bucket = map.get(key);\n if (!bucket) {\n bucket = { ...EMPTY };\n map.set(key, bucket);\n }\n return bucket;\n}\n\nfunction mapToDailyArray(map: Map<string, TokenBucket>, prefix: string): DailyBucket[] {\n const result: DailyBucket[] = [];\n for (const [key, bucket] of map) {\n if (!key.startsWith(prefix)) continue;\n const date = key.slice(prefix.length);\n result.push({ ...bucket, date });\n }\n result.sort((a, b) => a.date.localeCompare(b.date));\n return result;\n}\n\n// ── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Record a token usage event. Called once per turn completion.\n * O(1) — just increments counters.\n */\nexport function record(\n issue: IssueEntry,\n usage: AgentTokenUsage,\n role?: AgentProviderRole,\n): void {\n if (!usage || usage.totalTokens === 0) return;\n\n const date = todayDate();\n const hour = currentHour();\n const model = usage.model || \"unknown\";\n\n // Overall\n addTo(overall, usage);\n\n // Daily overall\n addTo(getOrCreate(daily, date), usage);\n\n // Hourly overall\n addTo(getOrCreate(hourly, hour), usage);\n pruneOldHours();\n\n // By phase\n if (role) {\n addTo(getOrCreate(byPhase, role), usage);\n addTo(getOrCreate(dailyByPhase, `${role}:${date}`), usage);\n }\n\n // By model\n addTo(getOrCreate(byModel, model), usage);\n addTo(getOrCreate(dailyByModel, `${model}:${date}`), usage);\n\n // By issue\n const prev = byIssue.get(issue.id);\n if (prev) {\n prev.totalTokens += usage.totalTokens;\n prev.title = issue.title; // keep fresh\n } else {\n byIssue.set(issue.id, {\n identifier: issue.identifier,\n title: issue.title,\n totalTokens: usage.totalTokens,\n });\n }\n}\n\n/**\n * Record an event occurrence. Called from addEvent().\n * Tracks event frequency per hour for sparkline display.\n */\nexport function recordEvent(): void {\n const hour = currentHour();\n eventsHourly.set(hour, (eventsHourly.get(hour) || 0) + 1);\n pruneOldHours();\n}\n\n/**\n * Get hourly snapshot for sparkline display.\n * Returns last 24 hours of token usage and event counts.\n */\nexport function getHourlySnapshot(hours = 24): HourlySnapshot {\n const now = Date.now();\n const tokensPerHour: HourlyBucket[] = [];\n const eventsPerHour: Array<{ hour: string; count: number }> = [];\n\n for (let i = hours - 1; i >= 0; i--) {\n const h = new Date(now - i * 3600_000).toISOString().slice(0, 13);\n const tokenBucket = hourly.get(h);\n tokensPerHour.push({\n hour: h,\n inputTokens: tokenBucket?.inputTokens || 0,\n outputTokens: tokenBucket?.outputTokens || 0,\n totalTokens: tokenBucket?.totalTokens || 0,\n });\n eventsPerHour.push({\n hour: h,\n count: eventsHourly.get(h) || 0,\n });\n }\n\n return { tokensPerHour, eventsPerHour };\n}\n\n/**\n * Hydrate the ledger from existing issues at startup.\n * Called once. O(n) over issues — amortized at boot, never at query time.\n */\nexport function hydrate(issues: IssueEntry[]): void {\n // Reset\n overall = { ...EMPTY };\n byPhase.clear();\n byModel.clear();\n daily.clear();\n dailyByPhase.clear();\n dailyByModel.clear();\n byIssue.clear();\n\n for (const issue of issues) {\n // Per-issue totals\n if (issue.tokenUsage && issue.tokenUsage.totalTokens > 0) {\n byIssue.set(issue.id, {\n identifier: issue.identifier,\n title: issue.title,\n totalTokens: issue.tokenUsage.totalTokens,\n });\n addTo(overall, issue.tokenUsage);\n }\n\n // Per-phase\n if (issue.tokensByPhase) {\n for (const [phase, pu] of Object.entries(issue.tokensByPhase)) {\n if (pu.totalTokens > 0) addTo(getOrCreate(byPhase, phase), pu);\n }\n }\n\n // Per-model\n if (issue.tokensByModel) {\n for (const [model, mu] of Object.entries(issue.tokensByModel)) {\n if (mu.totalTokens > 0) addTo(getOrCreate(byModel, model), mu);\n }\n }\n\n // Note: daily breakdown cannot be reconstructed from issue data alone\n // (we don't store per-day history on the issue). This is fine — daily\n // data accumulates correctly from record() calls going forward.\n // Historical daily data lives in the EC plugin as a secondary source.\n }\n}\n\n/**\n * Get full analytics snapshot. O(1) — reads from pre-computed maps.\n */\nexport function getAnalytics(topN = 20): TokenAnalytics {\n // Daily overall\n const dailyArray: DailyBucket[] = [];\n for (const [date, bucket] of daily) {\n dailyArray.push({ ...bucket, date });\n }\n dailyArray.sort((a, b) => a.date.localeCompare(b.date));\n\n // Daily by phase\n const dailyByPhaseResult: Record<string, DailyBucket[]> = {};\n for (const phase of byPhase.keys()) {\n dailyByPhaseResult[phase] = mapToDailyArray(dailyByPhase, `${phase}:`);\n }\n\n // Daily by model\n const dailyByModelResult: Record<string, DailyBucket[]> = {};\n for (const model of byModel.keys()) {\n dailyByModelResult[model] = mapToDailyArray(dailyByModel, `${model}:`);\n }\n\n // Top issues\n const topIssues = [...byIssue.entries()]\n .map(([id, data]) => ({ id, ...data }))\n .sort((a, b) => b.totalTokens - a.totalTokens)\n .slice(0, topN);\n\n // Phase/model aggregates\n const byPhaseResult: Record<string, TokenBucket> = {};\n for (const [k, v] of byPhase) byPhaseResult[k] = { ...v };\n\n const byModelResult: Record<string, TokenBucket> = {};\n for (const [k, v] of byModel) byModelResult[k] = { ...v };\n\n return {\n overall: { ...overall },\n byPhase: byPhaseResult,\n byModel: byModelResult,\n daily: dailyArray,\n dailyByPhase: dailyByPhaseResult,\n dailyByModel: dailyByModelResult,\n topIssues,\n };\n}\n","/**\n * Dirty tracking for incremental persistence.\n * Tracks which issue and event IDs have been modified since last persist.\n */\n\nconst dirtyIssueIds = new Set<string>();\nconst dirtyEventIds = new Set<string>();\n\nexport function markIssueDirty(id: string): void {\n dirtyIssueIds.add(id);\n}\n\nexport function markEventDirty(id: string): void {\n dirtyEventIds.add(id);\n}\n\nexport function hasDirtyState(): boolean {\n return dirtyIssueIds.size > 0 || dirtyEventIds.size > 0;\n}\n\nexport function getDirtyIssueIds(): Set<string> {\n return dirtyIssueIds;\n}\n\nexport function getDirtyEventIds(): Set<string> {\n return dirtyEventIds;\n}\n\nexport function clearDirtyIssueIds(): void {\n dirtyIssueIds.clear();\n}\n\nexport function clearDirtyEventIds(): void {\n dirtyEventIds.clear();\n}\n\nexport function markAllIssuesDirty(ids: string[]): void {\n for (const id of ids) dirtyIssueIds.add(id);\n}\n\nexport function markAllEventsDirty(ids: string[]): void {\n for (const id of ids) dirtyEventIds.add(id);\n}\n","import type { IssueEntry, RuntimeMetrics } from \"./types.ts\";\nimport { computeMetrics } from \"./issues.ts\";\n\nlet cachedMetrics: RuntimeMetrics | null = null;\nlet metricsStale = true;\n\nexport function invalidateMetrics(): void {\n metricsStale = true;\n}\n\nexport function getMetrics(issues: IssueEntry[]): RuntimeMetrics {\n if (!metricsStale && cachedMetrics) return cachedMetrics;\n cachedMetrics = computeMetrics(issues);\n metricsStale = false;\n return cachedMetrics;\n}\n","import type { IssueState } from \"./types.ts\";\n\nexport const ISSUE_STATE_MACHINE_ID = \"issue-lifecycle\";\n\ntype IssueStateTransitionMap = Record<string, string[]>;\n\ntype IssueStateMachineDefinition = {\n initialState: string;\n states?: Record<string, { on?: Record<string, string> } | undefined>;\n};\n\nconst ISSUE_STATE_TRANSITIONS: Record<string, readonly string[]> = {\n Planning: [\"Todo\", \"Cancelled\"],\n Todo: [\"Queued\", \"Planning\", \"Cancelled\"],\n Queued: [\"Running\", \"Todo\", \"Cancelled\"],\n Running: [\"In Review\", \"Interrupted\", \"Blocked\", \"Cancelled\"],\n Interrupted: [\"Queued\", \"Running\", \"Blocked\", \"Cancelled\"],\n \"In Review\": [\"Running\", \"Done\", \"Blocked\", \"Cancelled\"],\n Blocked: [\"Planning\", \"Queued\", \"Cancelled\"],\n Done: [\"Planning\", \"Todo\", \"Cancelled\"],\n Cancelled: [\"Planning\", \"Todo\", \"Queued\"],\n};\n\nexport const ISSUE_STATE_MACHINE_DEFINITION = {\n initialState: \"Planning\",\n states: {\n Planning: {\n on: {\n Todo: \"Todo\",\n Cancelled: \"Cancelled\",\n },\n },\n Todo: {\n on: {\n Queued: \"Queued\",\n Planning: \"Planning\",\n Cancelled: \"Cancelled\",\n },\n },\n Queued: {\n on: {\n Running: \"Running\",\n Todo: \"Todo\",\n Cancelled: \"Cancelled\",\n },\n },\n Running: {\n on: {\n \"In Review\": \"In Review\",\n Interrupted: \"Interrupted\",\n Blocked: \"Blocked\",\n Cancelled: \"Cancelled\",\n },\n },\n Interrupted: {\n on: {\n Queued: \"Queued\",\n Running: \"Running\",\n Blocked: \"Blocked\",\n Cancelled: \"Cancelled\",\n },\n },\n \"In Review\": {\n on: {\n Running: \"Running\",\n Done: \"Done\",\n Blocked: \"Blocked\",\n Cancelled: \"Cancelled\",\n },\n },\n Blocked: {\n on: {\n Planning: \"Planning\",\n Queued: \"Queued\",\n Cancelled: \"Cancelled\",\n },\n },\n Done: {\n on: {\n Planning: \"Planning\",\n Todo: \"Todo\",\n Cancelled: \"Cancelled\",\n },\n },\n Cancelled: {\n on: {\n Planning: \"Planning\",\n Todo: \"Todo\",\n Queued: \"Queued\",\n },\n },\n },\n} as const;\n\ntype TransitionPayload = {\n event: string;\n context: Record<string, unknown>;\n issueId: string;\n to: string;\n from: string;\n timestamp: string;\n};\n\nexport type IssueStateMachinePluginLike = {\n getMachineDefinition?: (machineId: string) => unknown;\n getState?: (machineId: string, entityId: string) => Promise<string>;\n getValidEvents?: (machineId: string, stateOrEntityId: string) => Promise<string[]>;\n initializeEntity?: (machineId: string, entityId: string, context?: Record<string, unknown>) => Promise<unknown>;\n send?: (machineId: string, entityId: string, event: string, context?: Record<string, unknown>) => Promise<TransitionPayload>;\n};\n\nlet issueStateMachinePlugin: IssueStateMachinePluginLike | null = null;\n\nfunction normalizeMachineDefinition(machineDefinition: unknown): IssueStateMachineDefinition {\n const definition = machineDefinition as Partial<IssueStateMachineDefinition>;\n return {\n initialState: typeof definition?.initialState === \"string\" ? definition.initialState : \"Todo\",\n states: definition?.states && typeof definition.states === \"object\" && !Array.isArray(definition.states)\n ? definition.states\n : (ISSUE_STATE_MACHINE_DEFINITION as IssueStateMachineDefinition).states,\n };\n}\n\nexport function setIssueStateMachinePlugin(plugin: IssueStateMachinePluginLike | null): void {\n issueStateMachinePlugin = plugin;\n}\n\nexport function getIssueStateMachinePlugin(): IssueStateMachinePluginLike | null {\n return issueStateMachinePlugin;\n}\n\nexport function getIssueStateMachineDefinition(): unknown {\n return issueStateMachinePlugin?.getMachineDefinition?.(ISSUE_STATE_MACHINE_ID)\n || ISSUE_STATE_MACHINE_DEFINITION;\n}\n\nexport function getIssueStateMachineInitialState(machineDefinition: unknown = getIssueStateMachineDefinition()): string {\n return normalizeMachineDefinition(machineDefinition).initialState;\n}\n\nfunction getIssueTransitionsFromStateDefinition(\n machineDefinition: unknown,\n state: string,\n): string[] {\n const definition = normalizeMachineDefinition(machineDefinition);\n const direct = definition?.states?.[state]?.on;\n if (!direct || typeof direct !== \"object\") return [...ISSUE_STATE_TRANSITIONS[state as keyof typeof ISSUE_STATE_TRANSITIONS] ?? []];\n\n const next = Object.keys(direct);\n return next.length > 0 ? next : [state];\n}\n\nfunction getIssueTransitionsByState(machineDefinition: unknown): Record<string, string[]> {\n const definition = normalizeMachineDefinition(machineDefinition);\n const fallback = Object.entries(ISSUE_STATE_TRANSITIONS).reduce<Record<string, string[]>>(\n (acc, [state, states]) => {\n acc[state] = [...states];\n return acc;\n },\n {},\n );\n\n if (!definition?.states || typeof definition.states !== \"object\") {\n return fallback;\n }\n\n for (const [state, next] of Object.entries(definition.states)) {\n if (!next || typeof next !== \"object\") continue;\n const transitions = next.on;\n if (transitions && typeof transitions === \"object\") {\n fallback[state] = Object.keys(transitions);\n }\n }\n\n return fallback;\n}\n\nexport function findIssueStateMachineTransitionPath(\n machineDefinition: unknown,\n from: string,\n to: string,\n): string[] | null {\n if (from === to) return [];\n\n const definition = normalizeMachineDefinition(machineDefinition);\n const edges = definition.states || {};\n if (!edges[from] || !edges[to]) return null;\n\n const queue: string[] = [from];\n const previousState = new Map<string, string>();\n const previousEvent = new Map<string, string>();\n previousState.set(from, \"\");\n\n for (let i = 0; i < queue.length; i += 1) {\n const current = queue[i]!;\n const transitions = edges[current]?.on;\n if (!transitions || typeof transitions !== \"object\") continue;\n\n for (const [event, nextRaw] of Object.entries(transitions)) {\n if (typeof nextRaw !== \"string\") continue;\n const next = nextRaw;\n if (previousState.has(next)) continue;\n\n previousState.set(next, current);\n previousEvent.set(next, event);\n\n if (next === to) {\n const events = [];\n let cursor = next;\n while (cursor !== from) {\n const prev = previousState.get(cursor);\n const event = previousEvent.get(cursor);\n if (!prev || !event) return null;\n events.unshift(event);\n cursor = prev;\n }\n return events;\n }\n\n queue.push(next);\n }\n }\n\n return null;\n}\n\n","import { execFileSync, spawn } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type {\n AgentProviderDefinition,\n AgentProviderRole,\n DetectedProvider,\n EffortConfig,\n IssueEntry,\n JsonRecord,\n PipelineStageConfig,\n ReasoningEffort,\n RuntimeState,\n WorkflowConfig,\n WorkflowDefinition,\n} from \"./types.ts\";\nimport { TARGET_ROOT } from \"./constants.ts\";\nimport {\n toStringValue,\n toStringArray,\n toNumberValue,\n getNestedRecord,\n getNestedString,\n} from \"./helpers.ts\";\nimport { logger } from \"./logger.ts\";\nimport {\n resolveTaskCapabilities,\n mergeCapabilityProviders,\n type CapabilityResolverOptions,\n} from \"../routing/capability-resolver.ts\";\n\nexport function resolveAgentProfile(name: string): { profilePath: string; instructions: string } {\n const normalized = name.trim();\n if (!normalized) return { profilePath: \"\", instructions: \"\" };\n\n const candidates = [\n join(TARGET_ROOT, \".codex\", \"agents\", `${normalized}.md`),\n join(TARGET_ROOT, \".codex\", \"agents\", normalized, \"AGENT.md\"),\n join(TARGET_ROOT, \"agents\", `${normalized}.md`),\n join(TARGET_ROOT, \"agents\", normalized, \"AGENT.md\"),\n join(homedir(), \".codex\", \"agents\", `${normalized}.md`),\n join(homedir(), \".codex\", \"agents\", normalized, \"AGENT.md\"),\n join(homedir(), \".claude\", \"agents\", `${normalized}.md`),\n join(homedir(), \".claude\", \"agents\", normalized, \"AGENT.md\"),\n ];\n\n for (const candidate of candidates) {\n if (!existsSync(candidate)) continue;\n return {\n profilePath: candidate,\n instructions: readFileSync(candidate, \"utf8\").trim(),\n };\n }\n\n return { profilePath: \"\", instructions: \"\" };\n}\n\nexport function normalizeAgentProvider(value: string): string {\n const normalized = value.trim().toLowerCase();\n if (normalized === \"claude\" || normalized === \"codex\") return normalized;\n if (!normalized) return \"codex\";\n return normalized;\n}\n\nexport function normalizeAgentRole(value: string): AgentProviderRole {\n const normalized = value.trim().toLowerCase();\n if (normalized === \"planner\" || normalized === \"executor\" || normalized === \"reviewer\") {\n return normalized;\n }\n return \"executor\";\n}\n\nexport function resolveAgentCommand(\n provider: string,\n explicitCommand: string,\n codexCommand: string,\n claudeCommand: string,\n reasoningEffort?: string,\n): string {\n if (explicitCommand.trim()) return explicitCommand.trim();\n if (provider === \"claude\" && claudeCommand.trim()) return claudeCommand.trim();\n if (provider === \"codex\" && codexCommand.trim()) return codexCommand.trim();\n return getProviderDefaultCommand(provider, reasoningEffort);\n}\n\n/** Resolve the effective reasoning effort for a given role, considering issue override and global defaults. */\nexport function resolveEffort(\n role: string,\n issueEffort?: EffortConfig,\n globalEffort?: EffortConfig,\n): ReasoningEffort | undefined {\n // Issue-level per-role override takes highest priority\n const roleKey = role as keyof EffortConfig;\n if (issueEffort?.[roleKey]) return issueEffort[roleKey];\n // Issue-level default\n if (issueEffort?.default) return issueEffort.default;\n // Global per-role\n if (globalEffort?.[roleKey]) return globalEffort[roleKey];\n // Global default\n return globalEffort?.default;\n}\n\nimport { buildClaudeCommand, buildCodexCommand, CLAUDE_RESULT_SCHEMA } from \"./adapters/commands.ts\";\n\nexport function getProviderDefaultCommand(provider: string, reasoningEffort?: string, model?: string): string {\n if (provider === \"codex\") return buildCodexCommand({ model, reasoningEffort });\n if (provider === \"claude\") return buildClaudeCommand({ model, jsonSchema: CLAUDE_RESULT_SCHEMA });\n return \"\";\n}\n\nlet cachedProviders: DetectedProvider[] | null = null;\nlet providersCachedAt = 0;\nconst PROVIDER_CACHE_TTL = 60_000;\n\nexport function detectAvailableProviders(): DetectedProvider[] {\n if (cachedProviders && Date.now() - providersCachedAt < PROVIDER_CACHE_TTL) {\n return cachedProviders;\n }\n\n const providers: DetectedProvider[] = [];\n\n for (const name of [\"claude\", \"codex\"]) {\n try {\n const path = execFileSync(\"which\", [name], { encoding: \"utf8\", timeout: 5000 }).trim();\n providers.push({ name, available: true, path });\n } catch {\n providers.push({ name, available: false, path: \"\" });\n }\n }\n\n cachedProviders = providers;\n providersCachedAt = Date.now();\n return providers;\n}\n\nexport function invalidateProviderCache(): void {\n cachedProviders = null;\n providersCachedAt = 0;\n}\n\n// ── Model discovery ─────────────────────────────────────────────────────────\n\nexport type DiscoveredModel = {\n id: string;\n provider: string;\n label: string;\n tier: string;\n};\n\n/** Cache: { models, fetchedAt } per provider */\nconst modelCache = new Map<string, { models: DiscoveredModel[]; fetchedAt: number }>();\nconst MODEL_CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n\n/**\n * Fetch models from the OpenAI /v1/models API.\n * Filters to models relevant for Codex CLI usage (chat/reasoning models).\n */\n/**\n * Read Codex CLI's own model list from ~/.codex/models_cache.json.\n *\n * The Codex CLI fetches and caches its supported models locally.\n * This is the authoritative source — same data the /model picker uses.\n * We read it directly: zero hardcoding, always up-to-date with the CLI version.\n *\n * Falls back to OpenAI /v1/models API (filtered to gpt-5.*) if cache doesn't exist.\n */\n/**\n * Read the user's configured default model from ~/.codex/config.toml.\n * Returns the model string (e.g. \"gpt-5.4\") and reasoning effort if present.\n */\nexport function readCodexConfig(): { model?: string; reasoningEffort?: string } {\n try {\n const configPath = join(homedir(), \".codex\", \"config.toml\");\n if (!existsSync(configPath)) return {};\n const raw = readFileSync(configPath, \"utf8\");\n const model = raw.match(/^model\\s*=\\s*\"([^\"]+)\"/m)?.[1];\n const reasoningEffort = raw.match(/^model_reasoning_effort\\s*=\\s*\"([^\"]+)\"/m)?.[1];\n return { model, reasoningEffort };\n } catch {\n return {};\n }\n}\n\n/**\n * Read the user's configured default model from ~/.claude/settings.json.\n * Returns the model alias/ID (e.g. \"sonnet\", \"opus\").\n */\nfunction readClaudeConfig(): { model?: string } {\n try {\n const settingsPath = join(homedir(), \".claude\", \"settings.json\");\n if (!existsSync(settingsPath)) return {};\n const raw = readFileSync(settingsPath, \"utf8\");\n const settings = JSON.parse(raw) as { model?: string };\n return { model: typeof settings.model === \"string\" ? settings.model : undefined };\n } catch {\n return {};\n }\n}\n\nasync function fetchCodexModels(): Promise<DiscoveredModel[]> {\n // 1. Try ~/.codex/models_cache.json (authoritative — from the CLI itself)\n const cachePath = join(homedir(), \".codex\", \"models_cache.json\");\n try {\n if (existsSync(cachePath)) {\n const raw = readFileSync(cachePath, \"utf8\");\n const cache = JSON.parse(raw) as {\n models?: Array<{\n slug: string;\n display_name?: string;\n description?: string;\n visibility?: string;\n priority?: number;\n supported_reasoning_levels?: Array<{ effort: string; description?: string }>;\n }>;\n };\n\n if (Array.isArray(cache.models) && cache.models.length > 0) {\n return cache.models\n // Show \"list\" models first, then \"hide\" (legacy) — sorted by CLI priority\n .sort((a, b) => {\n const visA = a.visibility === \"list\" ? 0 : 1;\n const visB = b.visibility === \"list\" ? 0 : 1;\n if (visA !== visB) return visA - visB;\n return (a.priority ?? 99) - (b.priority ?? 99);\n })\n .map((m) => ({\n id: m.slug,\n provider: \"codex\",\n label: m.display_name || m.slug,\n tier: m.description || (m.visibility === \"list\" ? \"Supported\" : \"Legacy\"),\n }));\n }\n }\n } catch {\n // Cache unreadable — fall through to API\n }\n\n // 2. Fallback: OpenAI API filtered to gpt-5.*\n const apiKey = process.env.OPENAI_API_KEY;\n if (!apiKey) return [];\n\n try {\n const res = await fetch(\"https://api.openai.com/v1/models\", {\n headers: { Authorization: `Bearer ${apiKey}` },\n signal: AbortSignal.timeout(10_000),\n });\n if (!res.ok) return [];\n const data = (await res.json()) as { data?: Array<{ id: string }> };\n if (!Array.isArray(data.data)) return [];\n\n return data.data\n .map((m) => m.id)\n .filter((id) => /^gpt-5/i.test(id))\n .filter((id) => !/(chat-latest|search-api|-\\d{4}-\\d{2}-\\d{2}|-pro)/i.test(id))\n .sort()\n .map((id) => ({ id, provider: \"codex\", label: id, tier: \"OpenAI model\" }));\n } catch {\n return [];\n }\n}\n\n/**\n * Discover Claude models from multiple sources (no hardcoding):\n *\n * 1. Anthropic API /v1/models (if ANTHROPIC_API_KEY is set)\n * 2. Extract model IDs embedded in the Claude CLI binary via `strings`\n * — the binary contains all supported model IDs as string literals\n * 3. Parallel CLI probe as last resort (slow but works with OAuth)\n */\nasync function fetchAnthropicModels(): Promise<DiscoveredModel[]> {\n // 1. Try Anthropic API (fast, authoritative — but requires API key)\n const apiKey = process.env.ANTHROPIC_API_KEY;\n if (apiKey) {\n try {\n const res = await fetch(\"https://api.anthropic.com/v1/models\", {\n headers: { \"x-api-key\": apiKey, \"anthropic-version\": \"2023-06-01\" },\n signal: AbortSignal.timeout(10_000),\n });\n if (res.ok) {\n const data = (await res.json()) as { data?: Array<{ id: string }> };\n if (Array.isArray(data.data) && data.data.length > 0) {\n const models = extractClaudeModels(data.data.map((m) => m.id));\n if (models.length > 0) return models;\n }\n }\n } catch { /* fall through */ }\n }\n\n // 2. Extract from Claude CLI binary (fast, no network, no tokens)\n // The compiled binary embeds model IDs as string literals.\n // `strings <binary> | grep claude-` extracts them.\n try {\n // Resolve the real binary path (symlink → actual file)\n const binaryPath = execFileSync(\"readlink\", [\"-f\", execFileSync(\"which\", [\"claude\"], { encoding: \"utf8\", timeout: 3000 }).trim()], {\n encoding: \"utf8\",\n timeout: 3000,\n }).trim();\n\n if (binaryPath && existsSync(binaryPath)) {\n const stringsOutput = execFileSync(\"strings\", [binaryPath], {\n encoding: \"utf8\",\n timeout: 10_000,\n maxBuffer: 50_000_000,\n });\n\n // Extract model IDs matching \"claude-{family}-{version}\" pattern\n const modelIds = new Set<string>();\n for (const line of stringsOutput.split(\"\\n\")) {\n const trimmed = line.trim();\n // Match exact model IDs: claude-{opus|sonnet|haiku}-{version}\n if (/^claude-(opus|sonnet|haiku)-\\d+-\\d+$/.test(trimmed)) {\n modelIds.add(trimmed);\n }\n }\n\n const models = extractClaudeModels([...modelIds]);\n if (models.length > 0) return models;\n }\n } catch {\n // strings not available or binary not readable — fall through\n }\n\n // 3. Last resort: parallel CLI probe (slow ~15s, burns minimal tokens)\n try {\n const aliases = [\n { alias: \"opus\", tier: \"Most capable\" },\n { alias: \"sonnet\", tier: \"Balanced\" },\n { alias: \"haiku\", tier: \"Fast\" },\n ];\n\n const probeOne = (alias: string): Promise<string | null> =>\n new Promise((resolve) => {\n try {\n const child = spawn(\"claude\", [\n \"--print\", \"--output-format\", \"json\", \"--model\", alias,\n \"--max-turns\", \"1\", \"--no-session-persistence\", \"reply ok\",\n ], { stdio: [\"pipe\", \"pipe\", \"pipe\"], timeout: 20_000 });\n let stdout = \"\";\n child.stdout?.on(\"data\", (chunk: Buffer) => { stdout += String(chunk); });\n child.on(\"close\", () => {\n try {\n const parsed = JSON.parse(stdout.trim()) as { model?: string; modelUsage?: Record<string, unknown> };\n resolve(parsed.model || Object.keys(parsed.modelUsage || {})[0] || null);\n } catch { resolve(null); }\n });\n child.on(\"error\", () => resolve(null));\n child.stdin?.end();\n } catch { resolve(null); }\n });\n\n const results = await Promise.all(aliases.map(async ({ alias, tier }) => {\n const modelId = await probeOne(alias);\n return modelId ? { id: modelId, provider: \"claude\" as const, label: modelId, tier } : null;\n }));\n\n const discovered = results.filter((m): m is DiscoveredModel => m !== null);\n if (discovered.length > 0) return discovered;\n } catch { /* CLI not available */ }\n\n return [];\n}\n\n/**\n * Filter and classify Claude model IDs into a sorted, deduplicated list.\n * Keeps only the latest version of each family (opus, sonnet, haiku).\n */\nfunction extractClaudeModels(ids: string[]): DiscoveredModel[] {\n // Group by family, keep highest version\n const families = new Map<string, { id: string; version: number }>();\n\n for (const id of ids) {\n if (!id.startsWith(\"claude-\")) continue;\n // Skip dated snapshots and @-versioned variants\n if (/@/.test(id) || /\\[\\d+m\\]/.test(id)) continue;\n if (/\\d{8}$/.test(id)) continue; // e.g. claude-opus-4-20250514\n\n let family = \"unknown\";\n if (/opus/i.test(id)) family = \"opus\";\n else if (/sonnet/i.test(id)) family = \"sonnet\";\n else if (/haiku/i.test(id)) family = \"haiku\";\n else continue;\n\n // Extract version: claude-opus-4-6 → 4.6, claude-sonnet-4 → 4.0\n const versionMatch = id.match(/(\\d+)(?:-(\\d+))?$/);\n const version = versionMatch\n ? parseFloat(`${versionMatch[1]}.${versionMatch[2] || \"0\"}`)\n : 0;\n\n const existing = families.get(family);\n if (!existing || version > existing.version) {\n families.set(family, { id, version });\n }\n }\n\n const tierMap: Record<string, string> = {\n opus: \"Most capable\",\n sonnet: \"Balanced\",\n haiku: \"Fast\",\n };\n\n // Sort: opus first (most capable), then sonnet, then haiku\n const order = [\"opus\", \"sonnet\", \"haiku\"];\n return order\n .filter((f) => families.has(f))\n .map((f) => {\n const { id } = families.get(f)!;\n return { id, provider: \"claude\", label: id, tier: tierMap[f] || \"Standard\" };\n });\n}\n\n/**\n * Discover available models for all detected providers.\n * Results are cached for 5 minutes.\n */\nexport async function discoverModels(providers: DetectedProvider[]): Promise<Record<string, DiscoveredModel[]>> {\n const result: Record<string, DiscoveredModel[]> = {};\n\n const tasks: Array<{ name: string; fetch: () => Promise<DiscoveredModel[]> }> = [];\n\n for (const p of providers) {\n if (!p.available) continue;\n const cached = modelCache.get(p.name);\n if (cached && Date.now() - cached.fetchedAt < MODEL_CACHE_TTL_MS) {\n result[p.name] = cached.models;\n continue;\n }\n if (p.name === \"codex\") tasks.push({ name: \"codex\", fetch: fetchCodexModels });\n if (p.name === \"claude\") tasks.push({ name: \"claude\", fetch: fetchAnthropicModels });\n }\n\n const settled = await Promise.allSettled(tasks.map((t) => t.fetch()));\n for (let i = 0; i < tasks.length; i++) {\n const res = settled[i];\n let models = res.status === \"fulfilled\" ? res.value : [];\n\n // Promote the user's configured CLI default model to the top of the list\n if (tasks[i].name === \"codex\") {\n const { model: configuredModel } = readCodexConfig();\n if (configuredModel) {\n const idx = models.findIndex((m) => m.id === configuredModel);\n if (idx > 0) {\n // Move to front\n models = [models[idx], ...models.slice(0, idx), ...models.slice(idx + 1)];\n } else if (idx === -1) {\n // Not in list yet — add it\n models = [{ id: configuredModel, provider: \"codex\", label: configuredModel, tier: \"Configured default\" }, ...models];\n }\n }\n }\n\n if (tasks[i].name === \"claude\") {\n const { model: configuredModel } = readClaudeConfig();\n if (configuredModel) {\n // Claude config uses aliases (\"sonnet\", \"opus\") — find matching model by id/prefix\n const idx = models.findIndex((m) => m.id === configuredModel || m.id.includes(configuredModel));\n if (idx > 0) {\n models = [models[idx], ...models.slice(0, idx), ...models.slice(idx + 1)];\n }\n }\n }\n\n result[tasks[i].name] = models;\n modelCache.set(tasks[i].name, { models, fetchedAt: Date.now() });\n }\n\n return result;\n}\n\nexport function resolveDefaultProvider(detected: DetectedProvider[]): string {\n const available = detected.filter((p) => p.available);\n if (available.length === 0) return \"\";\n if (available.some((p) => p.name === \"codex\")) return \"codex\";\n return available[0].name;\n}\n\nexport function resolveWorkflowAgentProviders(\n config: JsonRecord,\n fallbackProvider: string,\n fallbackProfile: string,\n explicitCommand: string,\n): AgentProviderDefinition[] {\n const agentConfig = getNestedRecord(config, \"agent\");\n const codexConfig = getNestedRecord(config, \"codex\");\n const claudeConfig = getNestedRecord(config, \"claude\");\n const providersRaw = (agentConfig.providers ?? []) as unknown;\n const providers: AgentProviderDefinition[] = [];\n\n if (Array.isArray(providersRaw)) {\n for (const entry of providersRaw) {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) continue;\n const record = entry as JsonRecord;\n const provider = normalizeAgentProvider(\n toStringValue(record.provider) || toStringValue(record.name) || fallbackProvider,\n );\n const role = normalizeAgentRole(toStringValue(record.role, \"executor\"));\n const profile = toStringValue(record.profile, role === \"executor\" ? fallbackProfile : \"\");\n const resolvedProfile = resolveAgentProfile(profile);\n const command = resolveAgentCommand(\n provider,\n toStringValue(record.command),\n getNestedString(codexConfig, \"command\"),\n getNestedString(claudeConfig, \"command\"),\n );\n\n providers.push({\n provider,\n role,\n command,\n profile,\n profilePath: resolvedProfile.profilePath,\n profileInstructions: resolvedProfile.instructions,\n });\n }\n }\n\n if (providers.length > 0) return providers;\n\n const resolvedProfile = resolveAgentProfile(fallbackProfile);\n return [\n {\n provider: fallbackProvider,\n role: \"executor\",\n command: resolveAgentCommand(\n fallbackProvider,\n explicitCommand,\n getNestedString(codexConfig, \"command\"),\n getNestedString(claudeConfig, \"command\"),\n ),\n profile: fallbackProfile,\n profilePath: resolvedProfile.profilePath,\n profileInstructions: resolvedProfile.instructions,\n },\n ];\n}\n\nexport function getBaseAgentProviders(\n state: RuntimeState,\n workflowDefinition: WorkflowDefinition | null,\n): AgentProviderDefinition[] {\n if (workflowDefinition?.agentProviders?.length) {\n return workflowDefinition.agentProviders;\n }\n\n return [\n {\n provider: state.config.agentProvider,\n role: \"executor\",\n command: state.config.agentCommand,\n profile: workflowDefinition?.agentProfile ?? \"\",\n profilePath: workflowDefinition?.agentProfilePath ?? \"\",\n profileInstructions: workflowDefinition?.agentProfileInstructions ?? \"\",\n },\n ];\n}\n\nexport function getCapabilityRoutingOptions(\n workflowDefinition: WorkflowDefinition | null,\n): CapabilityResolverOptions {\n const routingConfig = workflowDefinition ? getNestedRecord(workflowDefinition.config, \"routing\") : {};\n const overridesRaw = Array.isArray(routingConfig.overrides) ? routingConfig.overrides : [];\n\n return {\n enabled: routingConfig.enabled === false ? false : true,\n overrides: overridesRaw\n .filter((entry): entry is JsonRecord => Boolean(entry) && typeof entry === \"object\" && !Array.isArray(entry))\n .map((entry) => ({\n match: {\n labels: toStringArray((entry.match as JsonRecord | undefined)?.labels),\n terms: toStringArray((entry.match as JsonRecord | undefined)?.terms),\n category: toStringValue((entry.match as JsonRecord | undefined)?.category),\n paths: toStringArray((entry.match as JsonRecord | undefined)?.paths),\n },\n category: toStringValue(entry.category),\n rationale: toStringArray(entry.rationale),\n overlays: toStringArray(entry.overlays),\n providers: Array.isArray(entry.providers)\n ? (entry.providers as unknown[])\n .filter((provider): provider is JsonRecord => Boolean(provider) && typeof provider === \"object\" && !Array.isArray(provider))\n .map((provider) => ({\n provider: normalizeAgentProvider(toStringValue(provider.provider || provider.name || \"codex\")),\n role: normalizeAgentRole(toStringValue(provider.role, \"executor\")),\n profile: toStringValue(provider.profile),\n reason: toStringValue(provider.reason, \"Workflow routing override.\"),\n }))\n : undefined,\n })),\n };\n}\n\nexport function getCapabilityPriorityMap(\n workflowDefinition: WorkflowDefinition | null,\n): Record<string, number> {\n const defaults: Record<string, number> = {\n security: 0,\n bugfix: 1,\n backend: 2,\n devops: 3,\n \"frontend-ui\": 4,\n architecture: 5,\n documentation: 6,\n default: 7,\n \"workflow-disabled\": 8,\n };\n\n const routingConfig = workflowDefinition ? getNestedRecord(workflowDefinition.config, \"routing\") : {};\n const customPriorities = getNestedRecord(routingConfig, \"priorities\");\n\n for (const [category, value] of Object.entries(customPriorities)) {\n if (typeof category !== \"string\" || !category.trim()) continue;\n defaults[category] = toNumberValue(value, defaults[category] ?? 100);\n }\n\n return defaults;\n}\n\nexport function getIssueCapabilityPriority(\n issue: IssueEntry,\n workflowDefinition: WorkflowDefinition | null,\n): number {\n const category = issue.capabilityCategory?.trim() || \"default\";\n const priorities = getCapabilityPriorityMap(workflowDefinition);\n return priorities[category] ?? 100;\n}\n\nexport function applyCapabilityMetadata(\n issue: IssueEntry,\n resolution: ReturnType<typeof resolveTaskCapabilities>,\n): void {\n issue.capabilityCategory = resolution.category;\n issue.capabilityOverlays = [...resolution.overlays];\n issue.capabilityRationale = [...resolution.rationale];\n\n const baseLabels = (issue.labels ?? []).filter((label) => !label.startsWith(\"capability:\") && !label.startsWith(\"overlay:\"));\n const derivedLabels = [\n resolution.category ? `capability:${resolution.category}` : \"\",\n ...resolution.overlays.map((overlay) => `overlay:${overlay}`),\n ].filter(Boolean);\n\n issue.labels = [...new Set([...baseLabels, ...derivedLabels])];\n}\n\n/** Map AgentProviderRole to WorkflowConfig stage key */\nfunction roleToStageKey(role: AgentProviderRole): keyof WorkflowConfig {\n switch (role) {\n case \"planner\": return \"plan\";\n case \"executor\": return \"execute\";\n case \"reviewer\": return \"review\";\n }\n}\n\n/**\n * Apply user's WorkflowConfig (from Settings → Workflow) to provider definitions.\n * Overrides provider, model, and effort for each role when a WorkflowConfig is present.\n */\nexport function applyWorkflowConfigToProviders(\n providers: AgentProviderDefinition[],\n workflowConfig: WorkflowConfig | null,\n): AgentProviderDefinition[] {\n if (!workflowConfig) return providers;\n\n return providers.map((provider) => {\n const stageKey = roleToStageKey(provider.role);\n const stageConfig: PipelineStageConfig | undefined = workflowConfig[stageKey];\n if (!stageConfig) return provider;\n\n const newProvider = stageConfig.provider || provider.provider;\n const newModel = stageConfig.model || undefined;\n const newEffort = stageConfig.effort || provider.reasoningEffort;\n\n // Rebuild command with the configured provider, model, and effort\n const command = getProviderDefaultCommand(newProvider, newEffort, newModel);\n\n return {\n ...provider,\n provider: newProvider,\n model: newModel,\n command: command || provider.command,\n reasoningEffort: newEffort,\n };\n });\n}\n\nexport function getEffectiveAgentProviders(\n state: RuntimeState,\n issue: IssueEntry,\n workflowDefinition: WorkflowDefinition | null,\n workflowConfig?: WorkflowConfig | null,\n): AgentProviderDefinition[] {\n const baseProviders = getBaseAgentProviders(state, workflowDefinition);\n const resolution = resolveTaskCapabilities(\n {\n id: issue.id,\n identifier: issue.identifier,\n title: issue.title,\n description: issue.description,\n labels: issue.labels,\n paths: issue.paths,\n },\n getCapabilityRoutingOptions(workflowDefinition),\n );\n applyCapabilityMetadata(issue, resolution);\n\n const merged = mergeCapabilityProviders(baseProviders, resolution).map((provider) => {\n const resolvedProfile = resolveAgentProfile(provider.profile ?? \"\");\n const suggestion = resolution.providers.find(\n (entry) => entry.provider === provider.provider && entry.role === provider.role,\n );\n\n const effort = resolveEffort(provider.role, issue.effort, state.config.defaultEffort);\n\n // Keep existing command (effort is metadata, not a CLI flag)\n const command = provider.command;\n\n return {\n ...provider,\n command,\n profilePath: resolvedProfile.profilePath,\n profileInstructions: resolvedProfile.instructions,\n selectionReason: suggestion?.reason ?? resolution.rationale.join(\" \"),\n overlays: resolution.overlays,\n capabilityCategory: resolution.category,\n reasoningEffort: effort,\n };\n });\n\n // Apply user's WorkflowConfig overrides (Settings → Workflow)\n return applyWorkflowConfigToProviders(merged, workflowConfig ?? null);\n}\n","/**\n * CLI command builders for each provider.\n *\n * Single source of truth for how we invoke Claude Code and Codex CLI.\n * Every caller (execution, review, planning) uses these builders\n * so flag changes only need to happen in one place.\n */\n\nimport type { IssuePlan } from \"../types.ts\";\n\n// ── Result schemas ───────────────────────────────────────────────────────────\n\nexport const CLAUDE_RESULT_SCHEMA = JSON.stringify({\n type: \"object\",\n properties: {\n status: { type: \"string\", enum: [\"done\", \"continue\", \"blocked\", \"failed\"] },\n summary: { type: \"string\" },\n nextPrompt: { type: \"string\" },\n },\n required: [\"status\"],\n});\n\nexport const REVIEW_RESULT_SCHEMA = JSON.stringify({\n type: \"object\",\n properties: {\n status: { type: \"string\", enum: [\"done\", \"continue\", \"blocked\", \"failed\"] },\n summary: { type: \"string\" },\n nextPrompt: { type: \"string\" },\n criteriaResults: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: { criterion: { type: \"string\" }, met: { type: \"boolean\" }, note: { type: \"string\" } },\n },\n },\n },\n required: [\"status\"],\n});\n\n// ── Claude command builder ───────────────────────────────────────────────────\n\nexport function buildClaudeCommand(options: {\n model?: string;\n jsonSchema?: string;\n /** Skip --dangerously-skip-permissions (e.g. for planning where tool access breaks --json-schema) */\n noToolAccess?: boolean;\n}): string {\n const parts = [\n \"claude\",\n \"--print\",\n ];\n\n if (!options.noToolAccess) {\n parts.push(\"--dangerously-skip-permissions\");\n }\n\n parts.push(\"--no-session-persistence\", \"--output-format json\");\n\n if (options.jsonSchema) {\n parts.push(`--json-schema '${options.jsonSchema}'`);\n }\n\n if (options.model && options.model !== \"claude\") {\n parts.splice(1, 0, `--model ${options.model}`);\n }\n\n parts.push(\"< \\\"$FIFONY_PROMPT_FILE\\\"\");\n return parts.join(\" \");\n}\n\n// ── Codex command builder ────────────────────────────────────────────────────\n\nexport function buildCodexCommand(options: {\n model?: string;\n addDirs?: string[];\n reasoningEffort?: string; // not supported by codex CLI, kept for API compatibility\n}): string {\n const parts = [\"codex\", \"exec\", \"--skip-git-repo-check\"];\n\n if (options.model && options.model !== \"codex\") {\n parts.push(`--model ${options.model}`);\n }\n\n if (options.addDirs?.length) {\n for (const dir of options.addDirs) {\n parts.push(`--add-dir \"${dir}\"`);\n }\n }\n\n parts.push(\"< \\\"$FIFONY_PROMPT_FILE\\\"\");\n return parts.join(\" \");\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** Extract unique directory paths from plan suggested paths (for --add-dir). */\nexport function extractPlanDirs(plan: IssuePlan): string[] {\n if (!plan.suggestedPaths?.length) return [];\n const dirs = new Set<string>();\n for (const p of plan.suggestedPaths) {\n const lastSlash = p.lastIndexOf(\"/\");\n if (lastSlash > 0) dirs.add(p.slice(0, lastSlash));\n else if (!p.includes(\".\")) dirs.add(p);\n }\n return [...dirs];\n}\n","import type { RuntimeState, WorkflowDefinition } from \"./types.ts\";\n\ntype RuntimeApiContext = {\n state: RuntimeState;\n workflowDefinition: WorkflowDefinition | null;\n};\n\nlet context: RuntimeApiContext | null = null;\n\nexport function setApiRuntimeContext(state: RuntimeState, workflowDefinition: WorkflowDefinition | null): void {\n context = { state, workflowDefinition };\n}\n\nexport function clearApiRuntimeContext(): void {\n context = null;\n}\n\nexport function getApiRuntimeContextOrThrow(): RuntimeApiContext {\n if (!context) {\n throw new Error(\"API runtime context was not initialized.\");\n }\n return context;\n}\n","import type {\n JsonRecord,\n RuntimeEvent,\n RuntimeState,\n IssueEntry,\n RuntimeSettingScope,\n RuntimeSettingSource,\n WorkflowDefinition,\n} from \"./types.ts\";\nimport { execSync } from \"node:child_process\";\nimport {\n appendFileSync,\n closeSync,\n existsSync,\n openSync,\n readFileSync,\n readSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport {\n FRONTEND_DIR,\n FRONTEND_ICON_SVG,\n FRONTEND_INDEX,\n FRONTEND_MANIFEST_JSON,\n FRONTEND_MASKABLE_ICON_SVG,\n FRONTEND_OFFLINE_HTML,\n FRONTEND_SERVICE_WORKER_JS,\n SOURCE_ROOT,\n} from \"./constants.ts\";\nimport { NATIVE_RESOURCE_CONFIGS } from \"./resources/index.ts\";\nimport { now, isoWeek, clamp, toStringValue } from \"./helpers.ts\";\nimport { isAgentStillRunning, mergeWorkspace } from \"./agent.ts\";\nimport { logger } from \"./logger.ts\";\nimport {\n loadS3dbModule,\n getStateDb,\n getEventStateResource,\n setActiveApiPlugin,\n persistState,\n} from \"./store.ts\";\nimport { markIssueDirty } from \"./dirty-tracker.ts\";\nimport {\n addEvent,\n computeCapabilityCounts,\n computeMetrics,\n createIssueFromPayload,\n handleStatePatch,\n transitionIssueState,\n} from \"./issues.ts\";\nimport { detectAvailableProviders, discoverModels } from \"./providers.ts\";\nimport { collectProvidersUsage } from \"./providers-usage.ts\";\nimport { analyzeParallelizability, wakeScheduler } from \"./scheduler.ts\";\nimport { setApiRuntimeContext } from \"./api-runtime-context.ts\";\nimport { TERMINAL_STATES } from \"./constants.ts\";\nimport { getAnalytics as getTokenAnalytics, getHourlySnapshot } from \"./token-ledger.ts\";\nimport { enhanceIssueField } from \"./issue-enhancer.ts\";\nimport { generatePlan, refinePlan, generatePlanInBackground, refinePlanInBackground, loadPlanningSession, savePlanningInput, clearPlanningSession } from \"./issue-planner.ts\";\nimport type { PlanningSessionUsage } from \"./issue-planner.ts\";\nimport {\n applyPersistedSettings,\n buildDefaultWorkflowConfig,\n getWorkflowConfig,\n inferSettingScope,\n loadRuntimeSettings,\n persistSetting,\n persistWorkerConcurrencySetting,\n persistWorkflowConfig,\n RUNTIME_CONFIG_SETTING_IDS,\n} from \"./settings.ts\";\nimport { scanProjectFiles, analyzeProjectWithCli } from \"./project-scanner.ts\";\nimport { scanForTodos, categorizeScannedIssues } from \"./issue-scanner.ts\";\nimport { fetchGitHubIssues } from \"./github-sync.ts\";\nimport {\n loadAgentCatalog,\n loadSkillCatalog,\n filterByDomains,\n installAgents,\n installSkills,\n} from \"./catalog.ts\";\nimport { TARGET_ROOT } from \"./constants.ts\";\nimport { join } from \"node:path\";\n\n// ── WebSocket broadcast (same port via listeners) ────────────────────────────\n// s3db.js 21.2.7 WebSocket contract: handlers receive (socketId, send, req)\n// instead of raw socket objects. We track socketId → send function.\n\ntype WsSendFn = (data: string) => void;\nconst wsClients = new Map<string, WsSendFn>(); // socketId → send\nlet broadcastSeq = 0;\nlet lastBroadcastIssueSnapshot: Map<string, string> = new Map(); // id → JSON\nconst VALID_SETTING_SCOPES = new Set<RuntimeSettingScope>([\"runtime\", \"providers\", \"ui\", \"system\"]);\nconst VALID_SETTING_SOURCES = new Set<RuntimeSettingSource>([\"user\", \"detected\", \"workflow\", \"system\"]);\n\nfunction sendToAllClients(data: string): void {\n for (const [socketId, send] of [...wsClients]) {\n try { send(data); } catch (error) {\n logger.debug(`WebSocket send failed for ${socketId}, removing (remaining: ${wsClients.size - 1}): ${String(error)}`);\n wsClients.delete(socketId);\n }\n }\n}\n\nexport function broadcastToWebSocketClients(message: Record<string, unknown>): void {\n if (wsClients.size === 0) return;\n\n broadcastSeq++;\n logger.debug({ seq: broadcastSeq, type: message.type, clientCount: wsClients.size }, \"[WebSocket] Broadcasting state update\");\n const issues = message.issues as Array<Record<string, unknown>> | undefined;\n\n if (issues && lastBroadcastIssueSnapshot.size > 0) {\n // Compute delta: only changed/new/removed issues\n const currentIds = new Set<string>();\n const changedIssues: Array<Record<string, unknown>> = [];\n\n for (const issue of issues) {\n const id = issue.id as string;\n currentIds.add(id);\n const serialized = JSON.stringify(issue);\n if (lastBroadcastIssueSnapshot.get(id) !== serialized) {\n changedIssues.push(issue);\n }\n }\n\n const removedIds: string[] = [];\n for (const prevId of lastBroadcastIssueSnapshot.keys()) {\n if (!currentIds.has(prevId)) {\n removedIds.push(prevId);\n }\n }\n\n // Update snapshot\n lastBroadcastIssueSnapshot = new Map(\n issues.map((issue) => [issue.id as string, JSON.stringify(issue)]),\n );\n\n // If fewer than half changed, send a delta instead of full state\n if (changedIssues.length < issues.length / 2 || changedIssues.length <= 3) {\n const delta: Record<string, unknown> = {\n type: \"state:delta\",\n seq: broadcastSeq,\n metrics: message.metrics,\n capabilities: message.capabilities,\n updatedAt: message.updatedAt,\n issuesDelta: changedIssues,\n issuesRemoved: removedIds,\n events: message.events,\n };\n sendToAllClients(JSON.stringify(delta));\n return;\n }\n }\n\n // Full state broadcast (first time or too many changes)\n if (issues) {\n lastBroadcastIssueSnapshot = new Map(\n issues.map((issue) => [issue.id as string, JSON.stringify(issue)]),\n );\n }\n\n sendToAllClients(JSON.stringify({\n ...message,\n seq: broadcastSeq,\n }));\n}\n\n// ── API server ───────────────────────────────────────────────────────────────\n\nexport async function startApiServer(\n state: RuntimeState,\n port: number,\n workflowDefinition: WorkflowDefinition | null,\n): Promise<void> {\n logger.info({ port }, \"[API] Starting API server\");\n const stateDb = getStateDb();\n if (!stateDb) {\n throw new Error(\"Cannot start API plugin before the database is initialized.\");\n }\n\n const { ApiPlugin } = await loadS3dbModule();\n const eventResource = getEventStateResource();\n\n const listEvents = async (filters: { issueId?: string; kind?: string; since?: string } = {}): Promise<RuntimeEvent[]> => {\n const { issueId, kind, since } = filters;\n\n let events: RuntimeEvent[];\n if (eventResource?.list) {\n const partition = issueId && kind ? \"byIssueIdAndKind\"\n : issueId ? \"byIssueId\"\n : kind ? \"byKind\"\n : null;\n const partitionValues = issueId && kind ? { issueId, kind }\n : issueId ? { issueId }\n : kind ? { kind }\n : {};\n events = (await eventResource.list({ partition, partitionValues, limit: 200 }))\n .map((record) => record as RuntimeEvent);\n } else {\n events = state.events.filter((event) => {\n if (issueId && event.issueId !== issueId) return false;\n if (kind && event.kind !== kind) return false;\n return true;\n });\n }\n\n return typeof since === \"string\" && since\n ? events.filter((entry) => entry.at > since)\n : events;\n };\n\n const findIssue = (issueId: string): IssueEntry | undefined =>\n state.issues.find((issue) => issue.id === issueId || issue.identifier === issueId);\n\n const parseIssue = (c: any): string | null => {\n const value = c.req?.param ? c.req.param(\"id\") : undefined;\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n return trimmed ? trimmed : null;\n };\n\n /** Apply plan token usage to issue tracking fields */\n const applyPlanUsage = (issue: IssueEntry, usage: PlanningSessionUsage) => {\n if (usage.totalTokens <= 0) return;\n const prev = issue.tokenUsage ?? { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n issue.tokenUsage = {\n inputTokens: prev.inputTokens + usage.inputTokens,\n outputTokens: prev.outputTokens + usage.outputTokens,\n totalTokens: prev.totalTokens + usage.totalTokens,\n model: usage.model || prev.model,\n };\n if (!issue.tokensByPhase) issue.tokensByPhase = {} as any;\n const prevPlanner = issue.tokensByPhase.planner ?? { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n issue.tokensByPhase.planner = {\n inputTokens: prevPlanner.inputTokens + usage.inputTokens,\n outputTokens: prevPlanner.outputTokens + usage.outputTokens,\n totalTokens: prevPlanner.totalTokens + usage.totalTokens,\n model: usage.model || prevPlanner.model,\n };\n if (!issue.tokensByModel) issue.tokensByModel = {};\n const model = usage.model || \"unknown\";\n const prevModel = issue.tokensByModel[model] ?? { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n issue.tokensByModel[model] = {\n inputTokens: prevModel.inputTokens + usage.inputTokens,\n outputTokens: prevModel.outputTokens + usage.outputTokens,\n totalTokens: prevModel.totalTokens + usage.totalTokens,\n model,\n };\n if (!issue.usage) issue.usage = { tokens: {} };\n issue.usage.tokens[model] = (issue.usage.tokens[model] || 0) + usage.totalTokens;\n };\n\n /** Apply plan suggestions to issue (paths, labels, effort) */\n const applyPlanSuggestions = (issue: IssueEntry, plan: import(\"./types.ts\").IssuePlan) => {\n if (plan.suggestedPaths?.length && !(issue.paths?.length)) issue.paths = plan.suggestedPaths;\n if (plan.suggestedLabels?.length && !issue.labels?.length) issue.labels = plan.suggestedLabels;\n if (plan.suggestedEffort && !issue.effort) issue.effort = plan.suggestedEffort;\n };\n\n const mutateIssueState = async (c: any, updater: (issue: IssueEntry) => Promise<void> | void) => {\n const issueId = parseIssue(c);\n if (!issueId) {\n return c.json({ ok: false, error: \"Issue id is required.\" }, 400);\n }\n\n const issue = findIssue(issueId);\n if (!issue) {\n return c.json({ ok: false, error: \"Issue not found\" }, 404);\n }\n\n try {\n await updater(issue);\n await persistState(state);\n wakeScheduler();\n return c.json({ ok: true, issue });\n } catch (error) {\n logger.error({ err: error, issueId }, \"[API] mutateIssueState failed\");\n return c.json({ ok: false, error: error instanceof Error ? error.message : String(error) }, 500);\n }\n };\n\n const resourceConfigs: Record<string, Record<string, unknown>> = Object.fromEntries(\n NATIVE_RESOURCE_CONFIGS.map((resourceConfig) => [\n resourceConfig.name,\n {\n ...(resourceConfig.api ?? {}),\n versionPrefix: \"api\",\n },\n ]),\n );\n const nativeResourceNames = new Set(Object.keys(resourceConfigs));\n\n const existingResources = await (stateDb as { listResources?: () => Promise<Array<{ name: string }>> }).listResources?.();\n for (const item of existingResources || []) {\n if (\n typeof item?.name === \"string\" &&\n item.name.startsWith(\"fifony_\") &&\n !nativeResourceNames.has(item.name)\n ) {\n resourceConfigs[item.name] = { enabled: false };\n }\n }\n\n setApiRuntimeContext(state, workflowDefinition);\n\n const serveTextFile = (filePath: string, contentType: string, cacheControl = \"no-cache\") => {\n if (!existsSync(filePath)) {\n return new Response(\"Not found\", { status: 404 });\n }\n return new Response(readFileSync(filePath), {\n headers: {\n \"content-type\": contentType,\n \"cache-control\": cacheControl,\n },\n });\n };\n\n const serveAppShell = () => {\n if (!existsSync(FRONTEND_INDEX)) {\n return new Response(\"Not found\", { status: 404 });\n }\n const html = readFileSync(FRONTEND_INDEX, \"utf8\")\n .replace('href=\"/assets/manifest.webmanifest\"', 'href=\"/manifest.webmanifest\"')\n .replaceAll('href=\"/assets/icon.svg\"', 'href=\"/icon.svg\"');\n return new Response(html, {\n headers: {\n \"content-type\": \"text/html; charset=utf-8\",\n \"cache-control\": \"no-cache\",\n },\n });\n };\n\n const apiPlugin = new ApiPlugin({\n port,\n host: \"0.0.0.0\",\n versionPrefix: false,\n // HTTP + WebSocket on the same port via listeners\n listeners: [{\n bind: { host: \"0.0.0.0\", port },\n protocols: {\n http: true,\n websocket: {\n enabled: true,\n path: \"/ws\",\n maxPayloadBytes: 512_000,\n onConnection: (socketId: string, send: WsSendFn) => {\n wsClients.set(socketId, send);\n logger.debug(`WebSocket client connected: ${socketId} (total: ${wsClients.size})`);\n try {\n send(JSON.stringify({\n type: \"connected\",\n seq: broadcastSeq,\n timestamp: now(),\n metrics: computeMetrics(state.issues),\n capabilities: computeCapabilityCounts(state.issues),\n issues: state.issues,\n events: state.events.slice(0, 50),\n }));\n } catch (error) {\n logger.debug(`WebSocket initial send failed for ${socketId}: ${String(error)}`);\n }\n },\n onMessage: (socketId: string, message: string | Buffer, send: WsSendFn) => {\n try {\n const msg = JSON.parse(typeof message === \"string\" ? message : message.toString(\"utf8\"));\n if (msg.type === \"ping\") {\n send(JSON.stringify({ type: \"pong\", timestamp: now() }));\n }\n } catch {}\n },\n onClose: (socketId: string) => {\n wsClients.delete(socketId);\n logger.debug(`WebSocket client disconnected: ${socketId} (total: ${wsClients.size})`);\n },\n },\n },\n }],\n rootRoute: () => new Response(null, {\n status: 302,\n headers: { location: \"/kanban\" },\n }),\n static: [{\n driver: \"filesystem\",\n path: \"/assets\",\n root: FRONTEND_DIR,\n pwa: false,\n config: { etag: true },\n }],\n docs: { enabled: true, title: \"Fifony API\", version: \"1.0.0\", description: \"Local orchestration API for Fifony\" },\n cors: { enabled: true, origin: \"*\" },\n security: { enabled: false },\n logging: { enabled: true, excludePaths: [\"/health\", \"/status\", \"/**/*.js\", \"/**/*.css\", \"/**/*.svg\"] },\n compression: { enabled: true, threshold: 1024 },\n health: { enabled: true },\n resources: {\n ...resourceConfigs,\n },\n routes: {\n \"GET /manifest.webmanifest\": () =>\n serveTextFile(FRONTEND_MANIFEST_JSON, \"application/manifest+json; charset=utf-8\"),\n \"GET /service-worker.js\": () =>\n serveTextFile(FRONTEND_SERVICE_WORKER_JS, \"application/javascript; charset=utf-8\", \"no-cache\"),\n \"GET /offline.html\": () =>\n serveTextFile(FRONTEND_OFFLINE_HTML, \"text/html; charset=utf-8\"),\n \"GET /icon.svg\": () =>\n serveTextFile(FRONTEND_ICON_SVG, \"image/svg+xml\", \"public, max-age=604800, immutable\"),\n \"GET /icon-maskable.svg\": () =>\n serveTextFile(FRONTEND_MASKABLE_ICON_SVG, \"image/svg+xml\", \"public, max-age=604800, immutable\"),\n \"GET /onboarding\": () => serveAppShell(),\n \"GET /kanban\": () => serveAppShell(),\n \"GET /issues\": () => serveAppShell(),\n \"GET /discover\": () => serveAppShell(),\n \"GET /agents\": () => serveAppShell(),\n \"GET /settings\": () => serveAppShell(),\n \"GET /settings/general\": () => serveAppShell(),\n \"GET /settings/notifications\": () => serveAppShell(),\n \"GET /settings/workflow\": () => serveAppShell(),\n \"GET /settings/providers\": () => serveAppShell(),\n \"GET /api/health\": (c: any) =>\n c.json({ status: state.booting ? \"booting\" : \"ready\" }),\n \"GET /api/state\": async (c: any) => {\n const showAll = c.req.query(\"all\") === \"1\";\n let issues = state.issues;\n\n if (!showAll) {\n // Default: active issues + terminal from this week and last week\n const thisWeek = isoWeek();\n const lastWeekDate = new Date();\n lastWeekDate.setUTCDate(lastWeekDate.getUTCDate() - 7);\n const lastWeek = isoWeek(lastWeekDate);\n const recentWeeks = new Set([thisWeek, lastWeek]);\n\n issues = state.issues.filter((i) => {\n if (!i.terminalWeek) return true; // active issue\n return recentWeeks.has(i.terminalWeek);\n });\n }\n\n return c.json({\n ...state,\n issues,\n capabilities: computeCapabilityCounts(issues),\n metrics: computeMetrics(issues),\n _filter: showAll ? \"all\" : \"recent\",\n _totalIssues: state.issues.length,\n });\n },\n \"GET /api/status\": async (c: any) =>\n c.json({\n status: \"ok\",\n updatedAt: state.updatedAt,\n config: state.config,\n trackerKind: state.trackerKind,\n }),\n \"GET /api/providers\": async (c: any) => {\n const providers = detectAvailableProviders();\n return c.json({ providers });\n },\n \"GET /api/parallelism\": async (c: any) => {\n return c.json(analyzeParallelizability(state.issues));\n },\n \"GET /api/providers/usage\": async (c: any) => {\n try {\n const usage = collectProvidersUsage();\n return c.json(usage);\n } catch (error) {\n logger.error({ err: error }, \"Failed to collect providers usage\");\n return c.json({ providers: [] }, 500);\n }\n },\n \"GET /api/settings\": async (c: any) => {\n const settings = await loadRuntimeSettings();\n return c.json({ settings });\n },\n \"GET /api/settings/:id\": async (c: any) => {\n const settingId = c.req?.param ? c.req.param(\"id\") : \"\";\n const settings = await loadRuntimeSettings();\n const setting = settings.find((entry) => entry.id === settingId);\n if (!setting) {\n return c.json({ ok: false, error: \"Setting not found\" }, 404);\n }\n return c.json({ ok: true, setting });\n },\n \"POST /api/settings/:id\": async (c: any) => {\n const settingId = c.req?.param ? c.req.param(\"id\") : \"\";\n if (!settingId) {\n return c.json({ ok: false, error: \"Setting id is required\" }, 400);\n }\n\n const payload = await c.req.json() as JsonRecord;\n const scopeValue = typeof payload.scope === \"string\" ? payload.scope : inferSettingScope(settingId);\n const sourceValue = typeof payload.source === \"string\" ? payload.source : \"user\";\n\n if (!VALID_SETTING_SCOPES.has(scopeValue as RuntimeSettingScope)) {\n return c.json({ ok: false, error: \"Invalid setting scope\" }, 400);\n }\n\n if (!VALID_SETTING_SOURCES.has(sourceValue as RuntimeSettingSource)) {\n return c.json({ ok: false, error: \"Invalid setting source\" }, 400);\n }\n\n const setting = await persistSetting(settingId, payload.value, {\n scope: scopeValue as RuntimeSettingScope,\n source: sourceValue as RuntimeSettingSource,\n });\n if (RUNTIME_CONFIG_SETTING_IDS.has(settingId)) {\n state.config = applyPersistedSettings(state.config, [setting]);\n state.updatedAt = now();\n addEvent(state, undefined, \"manual\", `Runtime setting ${settingId} updated.`);\n await persistState(state);\n }\n return c.json({ ok: true, setting });\n },\n \"POST /api/config/concurrency\": async (c: any) => {\n const payload = await c.req.json() as JsonRecord;\n const value = typeof payload.concurrency === \"number\" ? payload.concurrency : undefined;\n if (!value || value < 1 || value > 16) {\n return c.json({ ok: false, error: \"concurrency must be between 1 and 16\" }, 400);\n }\n state.config.workerConcurrency = clamp(Math.round(value), 1, 16);\n state.updatedAt = now();\n addEvent(state, undefined, \"manual\", `Worker concurrency updated to ${state.config.workerConcurrency}.`);\n await persistWorkerConcurrencySetting(state.config.workerConcurrency);\n await persistState(state);\n return c.json({ ok: true, workerConcurrency: state.config.workerConcurrency });\n },\n \"GET /api/config/workflow\": async (c: any) => {\n const settings = await loadRuntimeSettings();\n const saved = getWorkflowConfig(settings);\n const includeDetails = c.req.query(\"details\") === \"1\";\n if (!includeDetails) {\n const providers = detectAvailableProviders();\n const workflow = saved || buildDefaultWorkflowConfig(providers);\n return c.json({ ok: true, workflow, isDefault: !saved });\n }\n const providers = detectAvailableProviders();\n const models = await discoverModels(providers);\n const defaultConfig = buildDefaultWorkflowConfig(providers, models);\n return c.json({ ok: true, workflow: saved || defaultConfig, isDefault: !saved, providers, models });\n },\n \"GET /api/config/models\": async (c: any) => {\n const providers = detectAvailableProviders();\n const models = await discoverModels(providers);\n return c.json({ ok: true, models });\n },\n \"GET /api/analytics/tokens\": async (c: any) => {\n // O(1) read from in-memory ledger — no disk I/O, no scans\n return c.json({ ok: true, ...getTokenAnalytics() });\n },\n \"POST /api/config/workflow\": async (c: any) => {\n try {\n const payload = await c.req.json() as JsonRecord;\n const workflow = payload.workflow as any;\n if (!workflow?.plan?.provider || !workflow?.execute?.provider || !workflow?.review?.provider) {\n return c.json({ ok: false, error: \"Invalid workflow config. Each stage needs provider, model, and effort.\" }, 400);\n }\n await persistWorkflowConfig(workflow);\n addEvent(state, undefined, \"manual\", `Workflow config updated: plan=${workflow.plan.provider}/${workflow.plan.model}, execute=${workflow.execute.provider}/${workflow.execute.model}, review=${workflow.review.provider}/${workflow.review.model}.`);\n return c.json({ ok: true, workflow });\n } catch (error) {\n return c.json({ ok: false, error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n \"GET /api/planning/session\": async (c: any) => {\n const session = await loadPlanningSession();\n return c.json({ ok: true, session });\n },\n \"POST /api/planning/save\": async (c: any) => {\n try {\n const payload = await c.req.json() as JsonRecord;\n const title = toStringValue(payload.title);\n const description = toStringValue(payload.description);\n const session = await savePlanningInput(title, description);\n return c.json({ ok: true, session });\n } catch (error) {\n return c.json({ ok: false, error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n \"POST /api/planning/generate\": async (c: any) => {\n try {\n const payload = await c.req.json() as JsonRecord;\n const title = toStringValue(payload.title);\n const description = toStringValue(payload.description);\n if (!title) return c.json({ ok: false, error: \"Title is required.\" }, 400);\n logger.info({ title: title.slice(0, 80) }, \"[API] POST /api/planning/generate\");\n const result = await generatePlan(title, description, state.config, workflowDefinition);\n return c.json({ ok: true, plan: result.plan, usage: result.usage });\n } catch (error) {\n logger.error({ err: error }, `Plan generation failed: ${String(error)}`);\n return c.json({ ok: false, error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n \"POST /api/planning/clear\": async (c: any) => {\n await clearPlanningSession();\n return c.json({ ok: true });\n },\n \"POST /api/issues/plan\": async (c: any) => {\n // Legacy alias\n try {\n const payload = await c.req.json() as JsonRecord;\n const title = toStringValue(payload.title);\n const description = toStringValue(payload.description);\n if (!title) return c.json({ ok: false, error: \"Title is required.\" }, 400);\n const result = await generatePlan(title, description, state.config, workflowDefinition);\n return c.json({ ok: true, plan: result.plan, usage: result.usage });\n } catch (error) {\n logger.error({ err: error }, `Plan generation failed: ${String(error)}`);\n return c.json({ ok: false, error: error instanceof Error ? error.message : String(error) }, 500);\n }\n },\n \"POST /api/issues/create\": async (c: any) => {\n try {\n const payload = await c.req.json() as JsonRecord;\n logger.info({ title: toStringValue(payload.title, \"\").slice(0, 80) }, \"[API] POST /api/issues/create\");\n const issue = createIssueFromPayload(payload, state.issues, workflowDefinition);\n state.issues.push(issue);\n markIssueDirty(issue.id);\n addEvent(state, issue.id, \"info\", `Issue ${issue.identifier} created via API.`);\n if (issue.plan) {\n addEvent(state, issue.id, \"info\", `Plan: ${issue.plan.steps.length} steps, complexity: ${issue.plan.estimatedComplexity}.`);\n }\n await persistState(state);\n wakeScheduler();\n return c.json({ ok: true, issue }, 201);\n } catch (error) {\n return c.json({ ok: false, error: error instanceof Error ? error.message : String(error) }, 400);\n }\n },\n \"POST /api/issues/enhance\": async (c: any) => {\n try {\n const payload = await c.req.json() as JsonRecord;\n const field = payload.field === \"description\" ? \"description\" : payload.field === \"title\" ? \"title\" : null;\n if (!field) {\n return c.json({ ok: false, error: 'Invalid field. Expected \"title\" or \"description\".' }, 400);\n }\n\n const title = toStringValue(payload.title);\n const description = toStringValue(payload.description);\n const provider = toStringValue(payload.provider, state.config.agentProvider);\n\n const result = await enhanceIssueField(\n { field, title, description, provider },\n state.config,\n workflowDefinition,\n );\n\n return c.json({ ok: true, field: result.field, value: result.value, provider: result.provider });\n } catch (error) {\n logger.error({ err: error }, `Issue enhance failed: ${String(error)}`);\n return c.json(\n { ok: false, error: error instanceof Error ? error.message : String(error) },\n 500,\n );\n }\n },\n \"POST /api/issues/:id/state\": async (c: any) => {\n const issueId = parseIssue(c);\n if (!issueId) {\n return c.json({ ok: false, error: \"Issue id is required.\" }, 400);\n }\n\n const issue = findIssue(issueId);\n if (!issue) {\n return c.json({ ok: false, error: \"Issue not found\" }, 404);\n }\n\n try {\n const payload = await c.req.json() as JsonRecord;\n logger.info({ issueId, identifier: issue.identifier, targetState: payload.state }, \"[API] POST /api/issues/:id/state\");\n await handleStatePatch(state, issue, payload);\n await persistState(state);\n wakeScheduler();\n return c.json({ ok: true, issue });\n } catch (error) {\n return c.json({ ok: false, error: error instanceof Error ? error.message : String(error) }, 400);\n }\n },\n \"POST /api/issues/:id/retry\": async (c: any) => {\n logger.info({ issueId: parseIssue(c) }, \"[API] POST /api/issues/:id/retry\");\n return mutateIssueState(c, async (issue) => {\n if (TERMINAL_STATES.has(issue.state)) {\n await transitionIssueState(issue, \"Todo\", \"Manual retry requested.\");\n } else {\n issue.lastError = undefined;\n issue.nextRetryAt = undefined;\n issue.updatedAt = now();\n }\n\n addEvent(state, issue.id, \"manual\", `Manual retry requested for ${issue.id}.`);\n });\n },\n \"POST /api/issues/:id/cancel\": async (c: any) => {\n logger.info({ issueId: parseIssue(c) }, \"[API] POST /api/issues/:id/cancel\");\n return mutateIssueState(c, async (issue) => {\n await transitionIssueState(issue, \"Cancelled\", \"Manual cancel requested.\");\n addEvent(state, issue.id, \"manual\", `Manual cancel requested for ${issue.id}.`);\n });\n },\n \"POST /api/issues/:id/plan\": async (c: any) => {\n return mutateIssueState(c, async (issue) => {\n if (issue.state !== \"Planning\") {\n throw new Error(`Cannot plan issue in state ${issue.state}. Must be in Planning.`);\n }\n if (issue.planningStatus === \"planning\" || issue.planningStatus === \"refining\") {\n throw new Error(\"A plan is already being generated for this issue.\");\n }\n const body = await c.req.json().catch(() => ({})) as Record<string, unknown>;\n const fast = body.fast === true;\n\n // Fire-and-forget — plan runs in background, updates via WS\n generatePlanInBackground(issue, state.config, workflowDefinition, {\n addEvent: (issueId, kind, message) => addEvent(state, issueId, kind as any, message),\n persistState: () => persistState(state),\n applyUsage: (iss, usage) => applyPlanUsage(iss, usage),\n applySuggestions: (iss, plan) => applyPlanSuggestions(iss, plan),\n }, { fast });\n\n addEvent(state, issue.id, \"progress\", `${fast ? \"Fast plan\" : \"Plan\"} generation started for ${issue.identifier}.`);\n });\n },\n \"POST /api/issues/:id/approve\": async (c: any) => {\n logger.info({ issueId: parseIssue(c) }, \"[API] POST /api/issues/:id/approve\");\n return mutateIssueState(c, async (issue) => {\n if (issue.state !== \"Planning\") {\n throw new Error(`Cannot approve issue in state ${issue.state}. Must be in Planning.`);\n }\n await transitionIssueState(issue, \"Todo\", `Plan approved for ${issue.identifier}. Ready for execution.`);\n addEvent(state, issue.id, \"state\", `Plan approved — ${issue.identifier} moved to Todo.`);\n });\n },\n \"POST /api/issues/:id/merge\": async (c: any) => {\n logger.info({ issueId: parseIssue(c) }, \"[API] POST /api/issues/:id/merge\");\n try {\n const issueId = parseIssue(c);\n if (!issueId) return c.json({ ok: false, error: \"Issue id is required.\" }, 400);\n const issue = findIssue(issueId);\n if (!issue) return c.json({ ok: false, error: \"Issue not found.\" }, 404);\n const wp = issue.workspacePath;\n if (!wp || !existsSync(wp)) {\n return c.json({ ok: false, error: \"No workspace found for this issue.\" }, 400);\n }\n const result = mergeWorkspace(wp);\n const conflictMsg = result.conflicts.length > 0\n ? ` ${result.conflicts.length} conflict(s): ${result.conflicts.join(\", \")}.`\n : \"\";\n addEvent(state, issue.id, \"merge\", `Workspace merged: ${result.copied.length} file(s) copied, ${result.deleted.length} deleted.${conflictMsg}`);\n if (result.conflicts.length > 0) {\n addEvent(state, issue.id, \"error\", `Merge conflicts: ${result.conflicts.join(\", \")}`);\n }\n await persistState(state);\n return c.json({ ok: true, ...result });\n } catch (error) {\n const issueId = parseIssue(c);\n logger.error(`Failed to merge workspace for ${issueId || \"<unknown>\"}: ${String(error)}`);\n return c.json({ ok: false, error: String(error) }, 500);\n }\n },\n \"POST /api/issues/:id/plan/refine\": async (c: any) => {\n return mutateIssueState(c, async (issue) => {\n if (issue.state !== \"Planning\") {\n throw new Error(`Cannot refine plan for issue in state ${issue.state}. Must be in Planning.`);\n }\n if (!issue.plan) {\n throw new Error(\"Issue has no plan to refine. Generate a plan first.\");\n }\n if (issue.planningStatus === \"planning\" || issue.planningStatus === \"refining\") {\n throw new Error(\"A plan operation is already in progress for this issue.\");\n }\n const body = await c.req.json().catch(() => ({})) as Record<string, unknown>;\n const feedback = typeof body.feedback === \"string\" ? body.feedback.trim() : \"\";\n if (!feedback) {\n throw new Error(\"Feedback message is required.\");\n }\n\n // Fire-and-forget — refinement runs in background, updates via WS\n refinePlanInBackground(issue, feedback, state.config, workflowDefinition, {\n addEvent: (issueId, kind, message) => addEvent(state, issueId, kind as any, message),\n persistState: () => persistState(state),\n applyUsage: (iss, usage) => applyPlanUsage(iss, usage),\n applySuggestions: (iss, plan) => {\n if (plan.suggestedPaths?.length) iss.paths = plan.suggestedPaths;\n if (plan.suggestedLabels?.length) iss.labels = plan.suggestedLabels;\n if (plan.suggestedEffort) iss.effort = plan.suggestedEffort;\n },\n });\n\n addEvent(state, issue.id, \"progress\", `Plan refinement started for ${issue.identifier}.`);\n });\n },\n \"POST /api/refresh\": async (c: any) => {\n addEvent(state, undefined, \"manual\", \"Manual refresh requested via API.\");\n await persistState(state);\n return c.json({ queued: true, requestedAt: now() }, 202);\n },\n \"GET /api/live/:id\": async (c: any) => {\n try {\n const issueId = parseIssue(c);\n if (!issueId) return c.json({ ok: false, error: \"Issue id is required.\" }, 400);\n const issue = findIssue(issueId);\n if (!issue) return c.json({ ok: false, error: \"Issue not found.\" }, 404);\n\n const parseStartedAt = (value: unknown): number | null => {\n const valueText = typeof value === \"string\" ? value.trim() : \"\";\n if (!valueText) return null;\n const ts = Date.parse(valueText);\n return Number.isFinite(ts) ? ts : null;\n };\n\n const startedAtText = toStringValue(issue.startedAt, \"\");\n const updatedAtText = toStringValue(issue.updatedAt, \"\");\n const startedAtTs = parseStartedAt(startedAtText) ?? parseStartedAt(updatedAtText);\n const elapsed = startedAtTs ? Date.now() - startedAtTs : 0;\n\n const wp = issue.workspacePath;\n const liveLog = wp ? `${wp}/fifony-live-output.log` : null;\n let logTail = \"\";\n let logSize = 0;\n if (liveLog && existsSync(liveLog)) {\n try {\n const stat = statSync(liveLog);\n logSize = stat.size;\n // Read last 8KB\n const fd = openSync(liveLog, \"r\");\n const readSize = Math.min(logSize, 8192);\n const buf = Buffer.alloc(readSize);\n readSync(fd, buf, 0, readSize, Math.max(0, logSize - readSize));\n closeSync(fd);\n logTail = buf.toString(\"utf8\");\n } catch {}\n }\n const agentStatus = isAgentStillRunning(issue);\n return c.json({\n ok: true,\n issueId: issue.id,\n state: issue.state,\n running: issue.state === \"Running\" || issue.state === \"In Review\",\n agentAlive: agentStatus.alive,\n agentPid: agentStatus.pid?.pid ?? null,\n startedAt: startedAtText || updatedAtText || now(),\n elapsed: Number.isFinite(elapsed) ? elapsed : 0,\n logSize,\n logTail,\n outputTail: issue.commandOutputTail || \"\",\n });\n } catch (error) {\n const issueId = parseIssue(c);\n logger.error(`Failed to load live issue state for ${issueId || \"<unknown>\"}: ${String(error)}`);\n return c.json({ ok: false, error: \"Failed to load live issue state.\" }, 500);\n }\n },\n \"GET /api/diff/:id\": async (c: any) => {\n try {\n const issueId = parseIssue(c);\n if (!issueId) return c.json({ ok: false, error: \"Issue id is required.\" }, 400);\n const issue = findIssue(issueId);\n if (!issue) return c.json({ ok: false, error: \"Issue not found.\" }, 404);\n const wp = issue.workspacePath;\n if (!wp || !existsSync(wp)) {\n return c.json({ ok: true, files: [], diff: \"\", message: \"No workspace found.\" });\n }\n if (!existsSync(SOURCE_ROOT)) {\n return c.json({ ok: true, files: [], diff: \"\", message: \"Source root not found.\" });\n }\n let raw = \"\";\n try {\n raw = execSync(\n `git diff --no-index --no-color -- \"${SOURCE_ROOT}\" \"${wp}\"`,\n { encoding: \"utf8\", maxBuffer: 4 * 1024 * 1024, timeout: 15_000 },\n );\n } catch (err: any) {\n // git diff --no-index exits 1 when diffs exist — normal\n raw = err.stdout || \"\";\n }\n\n if (!raw.trim()) {\n return c.json({ ok: true, files: [], diff: \"\", message: \"No changes\" });\n }\n\n // Clean paths: replace absolute paths with relative a/ b/ style\n const esc = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const sourcePrefix = SOURCE_ROOT.endsWith(\"/\") ? SOURCE_ROOT : `${SOURCE_ROOT}/`;\n const wpPrefix = wp.endsWith(\"/\") ? wp : `${wp}/`;\n const cleaned = raw\n .replace(new RegExp(esc(wpPrefix), \"g\"), \"b/\")\n .replace(new RegExp(esc(sourcePrefix), \"g\"), \"a/\");\n\n // Split into per-file chunks and filter internals\n const internalRe = /^(fifony[-_]|\\.fifony-|WORKFLOW\\.local)/;\n const chunks = cleaned.split(/(?=^diff --git )/m);\n const filtered = chunks.filter((chunk) => {\n const m = chunk.match(/^diff --git a\\/(.+?) b\\//);\n if (!m) return false;\n const basename = m[1].split(\"/\").pop() || \"\";\n return !internalRe.test(basename);\n });\n\n const diff = filtered.join(\"\").trim();\n\n // Per-file summary (like GitHub PR file list)\n const files = filtered.map((chunk) => {\n const pathMatch = chunk.match(/^diff --git a\\/(.+?) b\\//);\n const path = pathMatch?.[1] || \"unknown\";\n const additions = (chunk.match(/^\\+[^+]/gm) || []).length;\n const deletions = (chunk.match(/^-[^-]/gm) || []).length;\n const isNew = chunk.includes(\"new file mode\");\n const isDeleted = chunk.includes(\"deleted file mode\");\n const status = isNew ? \"added\" : isDeleted ? \"removed\" : \"modified\";\n return { path, status, additions, deletions };\n });\n\n const totalAdditions = files.reduce((s, f) => s + f.additions, 0);\n const totalDeletions = files.reduce((s, f) => s + f.deletions, 0);\n\n return c.json({ ok: true, files, diff, totalAdditions, totalDeletions });\n } catch (error) {\n const issueId = parseIssue(c);\n logger.error(`Failed to load issue diff for ${issueId || \"<unknown>\"}: ${String(error)}`);\n return c.json({ ok: false, error: \"Failed to load issue diff.\" }, 500);\n }\n },\n // Token analytics served from in-memory ledger (primary endpoint is above)\n \"GET /api/analytics/tokens/weekly\": async (c: any) => {\n // Weekly is part of the daily data in the ledger — filter client-side\n return c.json({ ok: true, ...getTokenAnalytics() });\n },\n \"GET /api/analytics/hourly\": async (c: any) => {\n const hours = Math.min(parseInt(c.req.query(\"hours\") || \"24\", 10) || 24, 48);\n return c.json({ ok: true, ...getHourlySnapshot(hours) });\n },\n \"GET /api/events/feed\": async (c: any) => {\n const since = c.req.query(\"since\");\n const issueId = c.req.query(\"issueId\");\n const kind = c.req.query(\"kind\");\n const events = await listEvents({\n since: typeof since === \"string\" ? since : undefined,\n issueId: typeof issueId === \"string\" && issueId ? issueId : undefined,\n kind: typeof kind === \"string\" && kind ? kind : undefined,\n });\n return c.json({ events: events.slice(0, 200) });\n },\n // ── Onboarding: gitignore check ────────────────────────────────────\n \"GET /api/gitignore/status\": async (c: any) => {\n try {\n const gitignorePath = join(TARGET_ROOT, \".gitignore\");\n if (!existsSync(gitignorePath)) {\n return c.json({ exists: false, hasFifony: false });\n }\n const content = readFileSync(gitignorePath, \"utf-8\");\n const lines = content.split(\"\\n\").map((l: string) => l.trim());\n const hasFifony = lines.some((l: string) => l === \".fifony\" || l === \".fifony/\" || l === \"/.fifony\" || l === \"/.fifony/\");\n return c.json({ exists: true, hasFifony });\n } catch (error) {\n logger.error({ err: error }, \"Failed to check .gitignore\");\n return c.json({ exists: false, hasFifony: false, error: \"Failed to check .gitignore\" }, 500);\n }\n },\n \"POST /api/gitignore/add\": async (c: any) => {\n try {\n const gitignorePath = join(TARGET_ROOT, \".gitignore\");\n if (!existsSync(gitignorePath)) {\n writeFileSync(gitignorePath, \"# Fifony state directory\\n.fifony/\\n\", \"utf-8\");\n return c.json({ ok: true, created: true });\n }\n const content = readFileSync(gitignorePath, \"utf-8\");\n const lines = content.split(\"\\n\").map((l: string) => l.trim());\n const hasFifony = lines.some((l: string) => l === \".fifony\" || l === \".fifony/\" || l === \"/.fifony\" || l === \"/.fifony/\");\n if (hasFifony) {\n return c.json({ ok: true, alreadyPresent: true });\n }\n const suffix = content.endsWith(\"\\n\") ? \"\" : \"\\n\";\n appendFileSync(gitignorePath, `${suffix}\\n# Fifony state directory\\n.fifony/\\n`, \"utf-8\");\n return c.json({ ok: true, added: true });\n } catch (error) {\n logger.error({ err: error }, \"Failed to update .gitignore\");\n return c.json({ ok: false, error: \"Failed to update .gitignore\" }, 500);\n }\n },\n // ── Onboarding: project scanning & catalog ─────────────────────────\n \"GET /api/scan/project\": async (c: any) => {\n try {\n const result = scanProjectFiles(TARGET_ROOT);\n return c.json(result);\n } catch (error) {\n logger.error({ err: error }, \"Failed to scan project files\");\n return c.json({ ok: false, error: \"Failed to scan project.\" }, 500);\n }\n },\n \"POST /api/scan/analyze\": async (c: any) => {\n try {\n const payload = await c.req.json() as { provider?: string };\n const provider = typeof payload.provider === \"string\" ? payload.provider : state.config.agentProvider;\n const result = await analyzeProjectWithCli(provider, TARGET_ROOT);\n return c.json(result);\n } catch (error) {\n logger.error({ err: error }, \"Failed to analyze project with CLI\");\n return c.json({ ok: false, error: \"Failed to analyze project.\" }, 500);\n }\n },\n \"GET /api/scan/issues\": async (c: any) => {\n try {\n const todos = scanForTodos(TARGET_ROOT);\n const categorized = categorizeScannedIssues(todos, workflowDefinition);\n return c.json({ ok: true, issues: categorized, total: categorized.length });\n } catch (error) {\n logger.error({ err: error }, \"Failed to scan for TODOs\");\n return c.json({ ok: false, error: \"Failed to scan for issues.\" }, 500);\n }\n },\n \"POST /api/boot/skip-scan\": async (c: any) => {\n broadcastToWebSocketClients({ type: \"boot:scan:skipped\" });\n return c.json({ ok: true, message: \"Scan skipped.\" });\n },\n \"GET /api/scan/github-issues\": async (c: any) => {\n try {\n const issues = await fetchGitHubIssues(TARGET_ROOT);\n const categorized = categorizeScannedIssues(issues, workflowDefinition);\n return c.json({ ok: true, issues: categorized, total: categorized.length });\n } catch (error) {\n logger.error({ err: error }, \"Failed to fetch GitHub issues\");\n return c.json({ ok: false, error: \"Failed to fetch GitHub issues.\" }, 500);\n }\n },\n \"GET /api/catalog/agents\": async (c: any) => {\n const domainsParam = c.req.query(\"domains\");\n const domains = typeof domainsParam === \"string\"\n ? domainsParam.split(\",\").map((d: string) => d.trim()).filter(Boolean)\n : [];\n const catalog = loadAgentCatalog();\n return c.json({ agents: domains.length ? filterByDomains(catalog, domains) : catalog });\n },\n \"GET /api/catalog/skills\": async (c: any) => {\n const catalog = loadSkillCatalog();\n return c.json({ skills: catalog });\n },\n \"POST /api/install/agents\": async (c: any) => {\n try {\n const payload = await c.req.json() as { agents?: string[] };\n const agentNames = Array.isArray(payload.agents) ? payload.agents.filter((a): a is string => typeof a === \"string\") : [];\n if (agentNames.length === 0) {\n return c.json({ ok: false, error: \"No agent names provided.\" }, 400);\n }\n const catalog = loadAgentCatalog();\n const result = installAgents(TARGET_ROOT, agentNames, catalog);\n return c.json({ ok: true, ...result });\n } catch (error) {\n logger.error({ err: error }, \"Failed to install agents\");\n return c.json({ ok: false, error: \"Failed to install agents.\" }, 500);\n }\n },\n \"POST /api/install/skills\": async (c: any) => {\n try {\n const payload = await c.req.json() as { skills?: string[] };\n const skillNames = Array.isArray(payload.skills) ? payload.skills.filter((s): s is string => typeof s === \"string\") : [];\n if (skillNames.length === 0) {\n return c.json({ ok: false, error: \"No skill names provided.\" }, 400);\n }\n const catalog = loadSkillCatalog();\n const result = installSkills(TARGET_ROOT, skillNames, catalog);\n return c.json({ ok: true, ...result });\n } catch (error) {\n logger.error({ err: error }, \"Failed to install skills\");\n return c.json({ ok: false, error: \"Failed to install skills.\" }, 500);\n }\n },\n },\n });\n\n const plugin = await stateDb.usePlugin(apiPlugin, \"api\") as { stop?: () => Promise<void> };\n setActiveApiPlugin(plugin);\n logger.info(`Local dashboard available at http://localhost:${port}`);\n logger.info(`WebSocket available at ws://localhost:${port}/ws`);\n logger.info(`State API: http://localhost:${port}/api/state`);\n logger.info(`OpenAPI docs available at http://localhost:${port}/docs`);\n}\n","import { S3DB_RUNTIME_RESOURCE } from \"../constants.ts\";\n\nexport default {\n name: S3DB_RUNTIME_RESOURCE,\n attributes: {\n id: \"string|required\",\n schemaVersion: \"number|required\",\n trackerKind: \"string|required\",\n runtimeTag: \"string|optional\",\n updatedAt: \"datetime|required\",\n state: \"json|required\",\n },\n behavior: \"body-overflow\",\n paranoid: false,\n timestamps: false,\n api: {\n auth: false,\n methods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n description: \"Runtime state snapshots\",\n },\n};\n","import {\n appendFileSync,\n cpSync,\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport { env } from \"node:process\";\nimport { execSync, spawn } from \"node:child_process\";\nimport type {\n AgentDirective,\n AgentDirectiveStatus,\n AgentPipelineRecord,\n AgentPipelineState,\n AgentProviderDefinition,\n AgentProviderRole,\n AgentSessionRecord,\n AgentSessionResult,\n AgentSessionState,\n AgentSessionTurn,\n AgentTokenUsage,\n IssueEntry,\n JsonRecord,\n RuntimeConfig,\n RuntimeState,\n WorkflowConfig,\n WorkflowDefinition,\n} from \"./types.ts\";\nimport {\n SOURCE_ROOT,\n TARGET_ROOT,\n TERMINAL_STATES,\n WORKSPACE_ROOT,\n} from \"./constants.ts\";\nimport {\n now,\n sleep,\n toStringValue,\n toNumberValue,\n clamp,\n idToSafePath,\n appendFileTail,\n getNestedRecord,\n getNestedNumber,\n} from \"./helpers.ts\";\nimport { logger } from \"./logger.ts\";\nimport {\n getAgentSessionResource,\n getAgentPipelineResource,\n isStateNotFoundError,\n persistState,\n} from \"./store.ts\";\nimport { markIssueDirty } from \"./dirty-tracker.ts\";\nimport {\n normalizeAgentProvider,\n getEffectiveAgentProviders,\n applyCapabilityMetadata,\n} from \"./providers.ts\";\nimport {\n addEvent,\n transitionIssueState,\n computeMetrics,\n getNextRetryAt,\n} from \"./issues.ts\";\nimport {\n inferCapabilityPaths,\n resolveTaskCapabilities,\n} from \"../routing/capability-resolver.ts\";\nimport { renderPrompt, renderPromptString } from \"../prompting.ts\";\nimport { discoverSkills, buildSkillContext } from \"./skills.ts\";\nimport { ensureSourceReady } from \"./workflow.ts\";\nimport { compileExecution, compileReview, persistCompilationArtifacts, buildExecutionAudit, persistExecutionAudit } from \"./adapters/index.ts\";\nimport { getWorkflowConfig, loadRuntimeSettings } from \"./settings.ts\";\nimport { record as recordTokens } from \"./token-ledger.ts\";\n\nfunction normalizeAgentDirectiveStatus(value: unknown, fallback: AgentDirectiveStatus): AgentDirectiveStatus {\n const normalized = typeof value === \"string\" ? value.trim().toLowerCase() : \"\";\n if (normalized === \"done\" || normalized === \"continue\" || normalized === \"blocked\" || normalized === \"failed\") {\n return normalized;\n }\n return fallback;\n}\n\nfunction addTokenUsage(issue: IssueEntry, usage?: AgentTokenUsage, role?: AgentProviderRole): void {\n if (!usage || usage.totalTokens === 0) return;\n\n // 1. Aggregate overall tokenUsage summary\n const prev = issue.tokenUsage ?? { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n issue.tokenUsage = {\n inputTokens: prev.inputTokens + usage.inputTokens,\n outputTokens: prev.outputTokens + usage.outputTokens,\n totalTokens: prev.totalTokens + usage.totalTokens,\n model: usage.model || prev.model,\n };\n\n // 2. Per-phase breakdown (planner / executor / reviewer)\n if (role) {\n if (!issue.tokensByPhase) issue.tokensByPhase = {} as Record<AgentProviderRole, AgentTokenUsage>;\n const prevPhase = issue.tokensByPhase[role] ?? { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n issue.tokensByPhase[role] = {\n inputTokens: prevPhase.inputTokens + usage.inputTokens,\n outputTokens: prevPhase.outputTokens + usage.outputTokens,\n totalTokens: prevPhase.totalTokens + usage.totalTokens,\n model: usage.model || prevPhase.model,\n };\n }\n\n // 3. Per-model breakdown with full input/output detail\n const model = usage.model || issue.tokenUsage?.model || \"unknown\";\n if (!issue.tokensByModel) issue.tokensByModel = {};\n const prevModel = issue.tokensByModel[model] ?? { inputTokens: 0, outputTokens: 0, totalTokens: 0 };\n issue.tokensByModel[model] = {\n inputTokens: prevModel.inputTokens + usage.inputTokens,\n outputTokens: prevModel.outputTokens + usage.outputTokens,\n totalTokens: prevModel.totalTokens + usage.totalTokens,\n model,\n };\n\n // 4. Legacy per-model totals for EventualConsistency analytics\n if (!issue.usage) issue.usage = { tokens: {} };\n issue.usage.tokens[model] = (issue.usage.tokens[model] || 0) + usage.totalTokens;\n}\n\nfunction extractOutputMarker(output: string, name: string): string {\n const match = output.match(new RegExp(`^${name}=(.+)$`, \"im\"));\n return match?.[1]?.trim() ?? \"\";\n}\n\nfunction extractTokenUsage(output: string, jsonObj?: JsonRecord | null): AgentTokenUsage | undefined {\n if (jsonObj) {\n // 1a. Claude --output-format json: modelUsage field (richer — includes cache tokens, per-model breakdown)\n const modelUsage = jsonObj.modelUsage as Record<string, Record<string, unknown>> | undefined;\n if (modelUsage && typeof modelUsage === \"object\") {\n let totalInput = 0, totalOutput = 0, primaryModel = \"\", maxTokens = 0;\n for (const [model, data] of Object.entries(modelUsage)) {\n const inp = Number(data?.inputTokens || 0) + Number(data?.cacheReadInputTokens || 0) + Number(data?.cacheCreationInputTokens || 0);\n const out = Number(data?.outputTokens || 0);\n totalInput += inp;\n totalOutput += out;\n if (inp + out > maxTokens) { maxTokens = inp + out; primaryModel = model; }\n }\n if (totalInput > 0 || totalOutput > 0) {\n return {\n inputTokens: totalInput,\n outputTokens: totalOutput,\n totalTokens: totalInput + totalOutput,\n costUsd: typeof jsonObj.cost_usd === \"number\" ? jsonObj.cost_usd : undefined,\n model: primaryModel || (typeof jsonObj.model === \"string\" ? jsonObj.model : undefined),\n };\n }\n }\n\n // 1b. Claude --output-format json: usage field (aggregate totals)\n const usage = jsonObj.usage as Record<string, unknown> | undefined;\n if (usage && typeof usage === \"object\") {\n const inp = Number(usage.input_tokens) || 0;\n const out = Number(usage.output_tokens) || 0;\n if (inp > 0 || out > 0) {\n return {\n inputTokens: inp,\n outputTokens: out,\n totalTokens: inp + out,\n costUsd: typeof jsonObj.cost_usd === \"number\" ? jsonObj.cost_usd : undefined,\n model: typeof jsonObj.model === \"string\" ? jsonObj.model : undefined,\n };\n }\n }\n }\n\n // 2. Codex: \"tokens used\\n1,681\\n\" and \"model: gpt-5.3\" in stdout\n const codexMatch = output.match(/tokens?\\s+used\\s*\\n\\s*([\\d,]+)/i);\n if (codexMatch) {\n const total = parseInt(codexMatch[1].replace(/,/g, \"\"), 10);\n if (total > 0) {\n const modelMatch = output.match(/^model:\\s*(.+)$/im);\n return {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: total,\n model: modelMatch?.[1]?.trim() || undefined,\n };\n }\n }\n\n return undefined;\n}\n\nfunction tryParseJsonOutput(output: string): JsonRecord | null {\n const trimmed = output.trim();\n // --output-format json wraps the result in a JSON object with a \"result\" field\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n const obj = parsed as JsonRecord;\n\n // --json-schema puts structured output in .structured_output (not .result)\n if (obj.structured_output && typeof obj.structured_output === \"object\" && !Array.isArray(obj.structured_output)) {\n return obj.structured_output as JsonRecord;\n }\n\n // Claude --output-format json returns { result: \"...\" } — the result may itself be JSON\n if (typeof obj.result === \"string\") {\n try {\n const inner = JSON.parse(obj.result) as unknown;\n if (inner && typeof inner === \"object\" && !Array.isArray(inner)) {\n return inner as JsonRecord;\n }\n } catch {\n // result is plain text, not JSON\n }\n }\n // Direct JSON with status field (from --json-schema)\n if (obj.status) return obj;\n }\n } catch {\n // Not JSON output — fall through to legacy parsing\n }\n return null;\n}\n\nfunction readAgentDirective(workspacePath: string, output: string, success: boolean): AgentDirective {\n const fallbackStatus: AgentDirectiveStatus = success ? \"done\" : \"failed\";\n const resultFile = join(workspacePath, \"fifony-result.json\");\n let resultPayload: JsonRecord = {};\n\n // 1. Try structured JSON from stdout (claude --output-format json --json-schema)\n const fullJson = (() => {\n try { return JSON.parse(output.trim()) as JsonRecord; } catch { return null; }\n })();\n const jsonOutput = tryParseJsonOutput(output);\n const tokenUsage = extractTokenUsage(output, fullJson);\n\n if (jsonOutput?.status) {\n return {\n status: normalizeAgentDirectiveStatus(jsonOutput.status, fallbackStatus),\n summary: toStringValue(jsonOutput.summary) || toStringValue(jsonOutput.message) || \"\",\n nextPrompt: toStringValue(jsonOutput.nextPrompt) || toStringValue(jsonOutput.next_prompt) || \"\",\n tokenUsage,\n };\n }\n\n // 2. Try fifony-result.json file\n if (existsSync(resultFile)) {\n try {\n const parsed = JSON.parse(readFileSync(resultFile, \"utf8\")) as unknown;\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n resultPayload = parsed as JsonRecord;\n }\n } catch (error) {\n logger.warn(`Invalid fifony-result.json in ${workspacePath}: ${String(error)}`);\n }\n }\n\n // 3. Fall back to file + output marker parsing\n const status = normalizeAgentDirectiveStatus(\n resultPayload.status ?? extractOutputMarker(output, \"FIFONY_STATUS\"),\n fallbackStatus,\n );\n const summary =\n toStringValue(resultPayload.summary)\n || toStringValue(resultPayload.message)\n || extractOutputMarker(output, \"FIFONY_SUMMARY\");\n const nextPrompt =\n toStringValue(resultPayload.nextPrompt)\n || toStringValue(resultPayload.next_prompt)\n || \"\";\n\n return { status, summary, nextPrompt, tokenUsage };\n}\n\n// ── Agent PID management ────────────────────────────────────────────────────\n\ntype AgentPidInfo = {\n pid: number;\n issueId: string;\n startedAt: string;\n command: string;\n};\n\n/** Read PID file from workspace, returns null if missing/invalid. */\nexport function readAgentPid(workspacePath: string): AgentPidInfo | null {\n const pidFile = join(workspacePath, \"fifony-agent.pid\");\n if (!existsSync(pidFile)) return null;\n try {\n const data = JSON.parse(readFileSync(pidFile, \"utf8\")) as AgentPidInfo;\n if (!data?.pid || typeof data.pid !== \"number\") return null;\n return data;\n } catch {\n return null;\n }\n}\n\n/** Check if a process is still running by PID. */\nexport function isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0); // signal 0 = check existence\n return true;\n } catch {\n return false;\n }\n}\n\n/** Check if an issue's agent is still running from a previous session. */\nexport function isAgentStillRunning(issue: IssueEntry): { alive: boolean; pid: AgentPidInfo | null } {\n const wp = issue.workspacePath;\n if (!wp || !existsSync(wp)) return { alive: false, pid: null };\n const pidInfo = readAgentPid(wp);\n if (!pidInfo) return { alive: false, pid: null };\n return { alive: isProcessAlive(pidInfo.pid), pid: pidInfo };\n}\n\n/** Clean stale PID file if the process is dead. */\nexport function cleanStalePidFile(workspacePath: string): void {\n const pidInfo = readAgentPid(workspacePath);\n if (!pidInfo) return;\n if (!isProcessAlive(pidInfo.pid)) {\n try { rmSync(join(workspacePath, \"fifony-agent.pid\"), { force: true }); } catch {}\n }\n}\n\nexport function canRunIssue(issue: IssueEntry, running: Set<string>, state: RuntimeState): boolean {\n if (!issue.assignedToWorker) return false;\n if (running.has(issue.id)) return false;\n if (TERMINAL_STATES.has(issue.state)) return false;\n\n // Don't spawn a new agent if one is still alive from a previous session\n const { alive } = isAgentStillRunning(issue);\n if (alive) {\n logger.debug({ issueId: issue.id, identifier: issue.identifier }, \"[Agent] Skipping issue — agent still alive from previous session\");\n return false;\n }\n\n if (issue.state === \"Blocked\") {\n if (!issue.nextRetryAt) return false;\n if (issue.attempts >= issue.maxAttempts) {\n logger.debug({ issueId: issue.id, identifier: issue.identifier, attempts: issue.attempts, maxAttempts: issue.maxAttempts }, \"[Agent] Skipping blocked issue — max attempts reached\");\n return false;\n }\n if (Date.parse(issue.nextRetryAt) > Date.now()) return false;\n }\n\n if (!issueDepsResolved(issue, state.issues)) {\n logger.debug({ issueId: issue.id, identifier: issue.identifier, blockedBy: issue.blockedBy }, \"[Agent] Skipping issue — unresolved dependencies\");\n return false;\n }\n\n if (issue.state === \"Todo\") return true;\n if (issue.state === \"Queued\") return true;\n if (issue.state === \"Blocked\") return true;\n if (issue.state === \"Interrupted\") return true;\n if (issue.state === \"Running\" && issueHasResumableSession(issue)) return true;\n if (issue.state === \"In Review\") return true;\n\n return false;\n}\n\nfunction issueDepsResolved(issue: IssueEntry, allIssues: IssueEntry[]): boolean {\n if (issue.blockedBy.length === 0) return true;\n const map = new Map(allIssues.map((entry) => [entry.id, entry]));\n return issue.blockedBy.every((depId) => {\n const dep = map.get(depId);\n return dep?.state === \"Done\";\n });\n}\n\nfunction shouldSkipRoutingPath(relativePath: string): boolean {\n const parts = relativePath.split(\"/\");\n if (parts.some((segment) => segment === \".git\" || segment === \"node_modules\" || segment === \".fifony\")) {\n return true;\n }\n const base = parts.at(-1) ?? \"\";\n return base === \"WORKFLOW.local.md\"\n || base === \".fifony-env.sh\"\n || base.startsWith(\"fifony-\")\n || base.startsWith(\"fifony_\");\n}\n\nfunction inferChangedWorkspacePaths(workspacePath: string, limit = 32): string[] {\n if (!workspacePath || !existsSync(workspacePath) || !existsSync(SOURCE_ROOT)) return [];\n\n const changed = new Set<string>();\n\n const walk = (currentRoot: string, relativeRoot = \"\"): void => {\n if (changed.size >= limit) return;\n for (const item of readdirSync(currentRoot, { withFileTypes: true })) {\n if (changed.size >= limit) return;\n const nextRelative = relativeRoot ? `${relativeRoot}/${item.name}` : item.name;\n if (shouldSkipRoutingPath(nextRelative)) continue;\n const currentPath = join(currentRoot, item.name);\n if (item.isDirectory()) { walk(currentPath, nextRelative); continue; }\n if (!item.isFile()) continue;\n const sourcePath = join(SOURCE_ROOT, nextRelative);\n if (!existsSync(sourcePath)) { changed.add(nextRelative); continue; }\n const currentStat = statSync(currentPath);\n const sourceStat = statSync(sourcePath);\n if (currentStat.size !== sourceStat.size) { changed.add(nextRelative); continue; }\n const currentFile = readFileSync(currentPath);\n const sourceFile = readFileSync(sourcePath);\n if (!currentFile.equals(sourceFile)) changed.add(nextRelative);\n }\n };\n\n walk(workspacePath);\n return [...changed];\n}\n\n/** Compute lines added/removed/files changed from workspace diff. */\nexport function computeDiffStats(issue: IssueEntry): void {\n const wp = issue.workspacePath;\n if (!wp || !existsSync(wp) || !existsSync(SOURCE_ROOT)) return;\n\n try {\n let raw = \"\";\n try {\n raw = execSync(\n `git diff --no-index --stat -- \"${SOURCE_ROOT}\" \"${wp}\" 2>/dev/null`,\n { encoding: \"utf8\", maxBuffer: 512_000, timeout: 10_000 },\n );\n } catch (err: any) {\n raw = err.stdout || \"\";\n }\n if (!raw) return;\n\n // Parse git diff --stat output: last line is \" N files changed, M insertions(+), K deletions(-)\"\n const lines = raw.trim().split(\"\\n\");\n const summary = lines[lines.length - 1] || \"\";\n const filesMatch = summary.match(/(\\d+)\\s+files?\\s+changed/);\n const addMatch = summary.match(/(\\d+)\\s+insertions?\\(\\+\\)/);\n const delMatch = summary.match(/(\\d+)\\s+deletions?\\(-\\)/);\n\n // Filter out fifony internal files from the file count\n const internalRe = /fifony[-_]|\\.fifony-|WORKFLOW\\.local/;\n const fileLines = lines.slice(0, -1).filter((l) => {\n const name = l.trim().split(\"|\")[0]?.trim().split(\"/\").pop() || \"\";\n return !internalRe.test(name);\n });\n\n issue.filesChanged = fileLines.length || (filesMatch ? parseInt(filesMatch[1], 10) : 0);\n issue.linesAdded = addMatch ? parseInt(addMatch[1], 10) : 0;\n issue.linesRemoved = delMatch ? parseInt(delMatch[1], 10) : 0;\n } catch {\n // ignore diff failures\n }\n}\n\nexport interface MergeResult {\n copied: string[];\n deleted: string[];\n skipped: string[];\n conflicts: string[];\n}\n\n/** Check if a file in TARGET_ROOT has been modified by another worker (differs from SOURCE_ROOT). */\nfunction isConflict(relativePath: string): boolean {\n const targetPath = join(TARGET_ROOT, relativePath);\n const sourcePath = join(SOURCE_ROOT, relativePath);\n\n // File exists in target but not in source → another worker created it\n if (!existsSync(sourcePath)) return existsSync(targetPath);\n\n // File doesn't exist in target → someone deleted it, not a conflict for us\n if (!existsSync(targetPath)) return false;\n\n // Both exist → compare target vs source. If different, another worker already changed it.\n const targetStat = statSync(targetPath);\n const sourceStat = statSync(sourcePath);\n if (targetStat.size !== sourceStat.size) return true;\n return !readFileSync(targetPath).equals(readFileSync(sourcePath));\n}\n\n/**\n * Merge workspace changes back into TARGET_ROOT.\n * Copies new/modified files from the workspace and removes files deleted in the workspace.\n * Skips fifony internal files (fifony-*, .fifony-*, node_modules, .git, etc.).\n *\n * Conflict detection: if a file in TARGET_ROOT already differs from SOURCE_ROOT\n * (another worker merged first), the file is added to `conflicts` instead of being overwritten.\n */\nexport function mergeWorkspace(workspacePath: string): MergeResult {\n const result: MergeResult = { copied: [], deleted: [], skipped: [], conflicts: [] };\n\n if (!workspacePath || !existsSync(workspacePath)) {\n throw new Error(`Workspace not found: ${workspacePath}`);\n }\n\n // 1. Walk workspace and copy new/modified files to TARGET_ROOT\n const walkWorkspace = (dir: string): void => {\n for (const item of readdirSync(dir, { withFileTypes: true })) {\n const fullPath = join(dir, item.name);\n const relativePath = relative(workspacePath, fullPath);\n\n if (shouldSkipMergePath(relativePath)) {\n result.skipped.push(relativePath);\n continue;\n }\n\n if (item.isDirectory()) {\n walkWorkspace(fullPath);\n continue;\n }\n\n if (!item.isFile()) continue;\n\n const sourcePath = join(SOURCE_ROOT, relativePath);\n\n // Check if file is new or modified compared to SOURCE_ROOT\n const isNew = !existsSync(sourcePath);\n let isModified = false;\n if (!isNew) {\n const wsStat = statSync(fullPath);\n const srcStat = statSync(sourcePath);\n if (wsStat.size !== srcStat.size) {\n isModified = true;\n } else {\n const wsContent = readFileSync(fullPath);\n const srcContent = readFileSync(sourcePath);\n isModified = !wsContent.equals(srcContent);\n }\n }\n\n if (isNew || isModified) {\n // Conflict detection: another worker already changed this file in TARGET_ROOT\n if (isConflict(relativePath)) {\n result.conflicts.push(relativePath);\n continue;\n }\n\n const targetDir = join(TARGET_ROOT, relative(workspacePath, dir));\n const targetPath = join(TARGET_ROOT, relativePath);\n mkdirSync(targetDir, { recursive: true });\n cpSync(fullPath, targetPath, { force: true });\n result.copied.push(relativePath);\n }\n }\n };\n\n // 2. Walk SOURCE_ROOT to find files deleted in workspace\n const walkSource = (dir: string): void => {\n if (!existsSync(dir)) return;\n for (const item of readdirSync(dir, { withFileTypes: true })) {\n const fullPath = join(dir, item.name);\n const relativePath = relative(SOURCE_ROOT, fullPath);\n\n if (shouldSkipMergePath(relativePath)) continue;\n\n if (item.isDirectory()) {\n walkSource(fullPath);\n continue;\n }\n\n if (!item.isFile()) continue;\n\n const wsPath = join(workspacePath, relativePath);\n if (!existsSync(wsPath)) {\n // File was deleted in workspace — only remove if untouched by another worker\n const targetPath = join(TARGET_ROOT, relativePath);\n if (existsSync(targetPath)) {\n if (isConflict(relativePath)) {\n result.conflicts.push(relativePath);\n } else {\n rmSync(targetPath, { force: true });\n result.deleted.push(relativePath);\n }\n }\n }\n }\n };\n\n walkWorkspace(workspacePath);\n walkSource(SOURCE_ROOT);\n\n return result;\n}\n\nfunction shouldSkipMergePath(relativePath: string): boolean {\n const parts = relativePath.split(\"/\");\n if (parts.some((s) => s === \".git\" || s === \"node_modules\" || s === \".fifony\" || s === \"dist\" || s === \".tanstack\")) {\n return true;\n }\n const base = parts.at(-1) ?? \"\";\n return base === \"WORKFLOW.local.md\"\n || base === \".fifony-env.sh\"\n || base === \".fifony-compiled-env.sh\"\n || base === \".fifony-local-source-ready\"\n || base.startsWith(\"fifony-\")\n || base.startsWith(\"fifony_\");\n}\n\nexport function hydrateIssuePathsFromWorkspace(issue: IssueEntry): string[] {\n const inferredPaths = inferChangedWorkspacePaths(issue.workspacePath ?? \"\");\n if (inferredPaths.length === 0) return [];\n issue.paths = [...new Set([...(issue.paths ?? []), ...inferredPaths])];\n issue.inferredPaths = [...new Set([...(issue.inferredPaths ?? []), ...inferredPaths])];\n return inferredPaths;\n}\n\nexport function describeRoutingSignals(issue: IssueEntry, workspaceDerivedPaths: string[]): string {\n const explicitPaths = issue.paths ?? [];\n const textDerivedPaths = inferCapabilityPaths({\n id: issue.id,\n identifier: issue.identifier,\n title: issue.title,\n description: issue.description,\n labels: issue.labels,\n }).filter((path) => !explicitPaths.includes(path));\n\n const parts: string[] = [];\n if (explicitPaths.length > 0) parts.push(`payload paths=${explicitPaths.join(\", \")}`);\n if (textDerivedPaths.length > 0) parts.push(`text hints=${textDerivedPaths.join(\", \")}`);\n if (workspaceDerivedPaths.length > 0) parts.push(`workspace diff=${workspaceDerivedPaths.join(\", \")}`);\n return parts.join(\" | \");\n}\n\nfunction buildAgentSessionState(\n issue: IssueEntry,\n attempt: number,\n maxTurns: number,\n): AgentSessionState {\n const createdAt = now();\n return {\n issueId: issue.id,\n issueIdentifier: issue.identifier,\n attempt,\n status: \"running\",\n startedAt: createdAt,\n updatedAt: createdAt,\n maxTurns,\n turns: [],\n lastPrompt: \"\",\n lastPromptFile: \"\",\n lastOutput: \"\",\n lastCode: null,\n lastDirectiveStatus: \"continue\",\n lastDirectiveSummary: \"\",\n nextPrompt: \"\",\n };\n}\n\nasync function loadAgentSessionState(\n sessionKey: string,\n issue: IssueEntry,\n attempt: number,\n maxTurns: number,\n): Promise<{ session: AgentSessionState; key: string }> {\n const agentSessionResource = getAgentSessionResource();\n if (agentSessionResource) {\n try {\n const record = await agentSessionResource.get(sessionKey) as AgentSessionRecord;\n if (\n record?.session\n && record.issueId === issue.id\n && record.attempt === attempt\n && Array.isArray(record.session.turns)\n ) {\n return {\n session: {\n ...buildAgentSessionState(issue, attempt, maxTurns),\n ...record.session,\n maxTurns,\n turns: record.session.turns as AgentSessionTurn[],\n updatedAt: now(),\n },\n key: sessionKey,\n };\n }\n } catch (error) {\n if (!isStateNotFoundError(error)) {\n logger.warn(`Failed to load session state for ${issue.id}: ${String(error)}`);\n }\n }\n }\n\n return { session: buildAgentSessionState(issue, attempt, maxTurns), key: sessionKey };\n}\n\nasync function persistAgentSessionState(\n key: string,\n issue: IssueEntry,\n provider: AgentProviderDefinition,\n cycle: number,\n session: AgentSessionState,\n): Promise<void> {\n session.updatedAt = now();\n const agentSessionResource = getAgentSessionResource();\n if (!agentSessionResource) return;\n\n await agentSessionResource.replace(key, {\n id: key,\n issueId: issue.id,\n issueIdentifier: issue.identifier,\n attempt: session.attempt,\n cycle,\n provider: provider.provider,\n role: provider.role,\n updatedAt: session.updatedAt,\n session,\n } satisfies AgentSessionRecord);\n}\n\nexport function issueHasResumableSession(issue: IssueEntry): boolean {\n return Boolean(issue.workspacePath) && (issue.state === \"Running\" || issue.state === \"Interrupted\");\n}\n\nfunction buildProviderSessionKey(issue: IssueEntry, attempt: number, provider: AgentProviderDefinition, cycle: number): string {\n return `${idToSafePath(issue.id)}-a${attempt}-${provider.role}-${provider.provider}-c${cycle}`;\n}\n\nfunction buildPipelineKey(issue: IssueEntry, attempt: number): string {\n return `${idToSafePath(issue.id)}-a${attempt}`;\n}\n\nfunction getLatestPipelineAttempt(issue: IssueEntry): number {\n if (issue.state === \"Blocked\" || issue.state === \"Cancelled\") {\n return Math.max(1, issue.attempts);\n }\n return Math.max(1, issue.attempts + 1);\n}\n\nfunction stateConfigMaxTurnsFallback(workflowDefinition: WorkflowDefinition | null): number {\n if (!workflowDefinition) return 4;\n return clamp(getNestedNumber(getNestedRecord(workflowDefinition.config, \"agent\"), \"max_turns\", 4), 1, 16);\n}\n\nexport async function loadAgentPipelineState(\n issue: IssueEntry,\n attempt: number,\n providers: AgentProviderDefinition[],\n): Promise<{ pipeline: AgentPipelineState; key: string }> {\n const pipelineKey = buildPipelineKey(issue, attempt);\n const agentPipelineResource = getAgentPipelineResource();\n\n if (agentPipelineResource) {\n try {\n const record = await agentPipelineResource.get(pipelineKey) as AgentPipelineRecord;\n if (record?.pipeline && record.issueId === issue.id && record.attempt === attempt) {\n return {\n pipeline: {\n issueId: issue.id,\n issueIdentifier: issue.identifier,\n attempt,\n cycle: Math.max(1, toNumberValue(record.pipeline.cycle, 1)),\n activeIndex: clamp(toNumberValue(record.pipeline.activeIndex, 0), 0, Math.max(0, providers.length - 1)),\n updatedAt: now(),\n history: Array.isArray(record.pipeline.history)\n ? record.pipeline.history.filter((entry): entry is string => typeof entry === \"string\")\n : [],\n },\n key: pipelineKey,\n };\n }\n } catch (error) {\n if (!isStateNotFoundError(error)) {\n logger.warn(`Failed to load pipeline state for ${issue.id}: ${String(error)}`);\n }\n }\n }\n\n return {\n pipeline: {\n issueId: issue.id,\n issueIdentifier: issue.identifier,\n attempt,\n cycle: 1,\n activeIndex: 0,\n updatedAt: now(),\n history: [],\n },\n key: pipelineKey,\n };\n}\n\nasync function persistAgentPipelineState(key: string, pipeline: AgentPipelineState): Promise<void> {\n pipeline.updatedAt = now();\n const agentPipelineResource = getAgentPipelineResource();\n if (!agentPipelineResource) return;\n\n await agentPipelineResource.replace(key, {\n id: key,\n issueId: pipeline.issueId,\n issueIdentifier: pipeline.issueIdentifier,\n attempt: pipeline.attempt,\n updatedAt: pipeline.updatedAt,\n pipeline,\n } satisfies AgentPipelineRecord);\n}\n\nexport async function loadAgentPipelineSnapshotForIssue(\n issue: IssueEntry,\n providers: AgentProviderDefinition[],\n): Promise<AgentPipelineState | null> {\n const attempt = getLatestPipelineAttempt(issue);\n const agentPipelineResource = getAgentPipelineResource();\n\n if (agentPipelineResource?.list) {\n try {\n const records = await agentPipelineResource.list({\n partition: \"byIssueAttempt\",\n partitionValues: { issueId: issue.id, attempt },\n limit: 10,\n });\n const record = records\n .map((entry) => entry as AgentPipelineRecord)\n .find((entry) => entry.issueId === issue.id && entry.attempt === attempt && entry.pipeline);\n if (record?.pipeline) {\n return {\n issueId: issue.id,\n issueIdentifier: issue.identifier,\n attempt,\n cycle: Math.max(1, toNumberValue(record.pipeline.cycle, 1)),\n activeIndex: clamp(toNumberValue(record.pipeline.activeIndex, 0), 0, Math.max(0, providers.length - 1)),\n updatedAt: now(),\n history: Array.isArray(record.pipeline.history)\n ? record.pipeline.history.filter((entry): entry is string => typeof entry === \"string\")\n : [],\n };\n }\n } catch (error) {\n logger.warn(`Failed to load partitioned pipeline snapshot for ${issue.id}: ${String(error)}`);\n }\n }\n\n const loaded = await loadAgentPipelineState(issue, attempt, providers);\n return loaded.pipeline.history.length > 0 ? loaded.pipeline : null;\n}\n\nexport async function loadAgentSessionSnapshotsForIssue(\n issue: IssueEntry,\n providers: AgentProviderDefinition[],\n pipeline: AgentPipelineState | null,\n workflowDefinition: WorkflowDefinition | null,\n): Promise<Array<{ key: string; session: AgentSessionState; provider: string; role: string; cycle: number }>> {\n if (!pipeline) return [];\n\n const sessions: Array<{ key: string; session: AgentSessionState; provider: string; role: string; cycle: number }> = [];\n const attempt = pipeline.attempt;\n const agentSessionResource = getAgentSessionResource();\n const maxTurns = stateConfigMaxTurnsFallback(workflowDefinition);\n\n if (agentSessionResource?.list) {\n try {\n const records = await agentSessionResource.list({\n partition: \"byIssueAttempt\",\n partitionValues: { issueId: issue.id, attempt },\n limit: Math.max(12, providers.length * Math.max(1, pipeline.cycle) * 2),\n });\n const loadedSessions = records\n .map((entry) => entry as AgentSessionRecord)\n .filter((entry) => entry.issueId === issue.id && entry.attempt === attempt && entry.session && Array.isArray(entry.session.turns));\n\n for (const record of loadedSessions) {\n if (!record.session.turns.length) continue;\n sessions.push({\n key: record.id,\n session: {\n ...buildAgentSessionState(issue, attempt, maxTurns),\n ...record.session,\n maxTurns,\n turns: record.session.turns as AgentSessionTurn[],\n updatedAt: now(),\n },\n provider: record.provider,\n role: record.role,\n cycle: record.cycle,\n });\n }\n\n sessions.sort((a, b) => a.cycle !== b.cycle ? a.cycle - b.cycle : a.key.localeCompare(b.key));\n if (sessions.length > 0) return sessions;\n } catch (error) {\n logger.warn(`Failed to load partitioned session snapshots for ${issue.id}: ${String(error)}`);\n }\n }\n\n for (let cycle = 1; cycle <= pipeline.cycle; cycle += 1) {\n for (const provider of providers) {\n const key = buildProviderSessionKey(issue, attempt, provider, cycle);\n const loaded = await loadAgentSessionState(key, issue, attempt, maxTurns);\n if (loaded.session.turns.length === 0) continue;\n sessions.push({\n key,\n session: loaded.session,\n provider: provider.provider,\n role: provider.role,\n cycle,\n });\n }\n }\n\n return sessions;\n}\n\nasync function buildPrompt(issue: IssueEntry, workflowDefinition: WorkflowDefinition | null): Promise<string> {\n const template = workflowDefinition?.promptTemplate.trim();\n const rendered = template\n ? await renderPromptString(template, { issue, attempt: issue.attempts || 0 })\n : await renderPrompt(\"workflow-default\", { issue, attempt: issue.attempts || 0 });\n\n if (!issue.plan?.steps?.length) {\n return rendered;\n }\n\n const planSection = await renderPrompt(\"workflow-plan-section\", {\n estimatedComplexity: issue.plan.estimatedComplexity,\n summary: issue.plan.summary,\n steps: issue.plan.steps.map((step) => ({\n step: step.step,\n action: step.action,\n files: step.files ?? [],\n details: step.details ?? \"\",\n })),\n });\n\n return `${rendered}\\n\\n${planSection}`;\n}\n\nasync function buildTurnPrompt(\n issue: IssueEntry,\n basePrompt: string,\n previousOutput: string,\n turnIndex: number,\n maxTurns: number,\n nextPrompt: string,\n): Promise<string> {\n if (turnIndex === 1) return basePrompt;\n\n return renderPrompt(\"agent-turn\", {\n issueIdentifier: issue.identifier,\n turnIndex,\n maxTurns,\n basePrompt,\n continuation: nextPrompt.trim() || \"Continue the work, inspect the workspace, and move the issue toward completion.\",\n outputTail: previousOutput.trim() || \"No previous output captured.\",\n });\n}\n\nasync function buildProviderBasePrompt(\n provider: AgentProviderDefinition,\n issue: IssueEntry,\n basePrompt: string,\n workspacePath: string,\n skillContext: string,\n): Promise<string> {\n return renderPrompt(\"agent-provider-base\", {\n isPlanner: provider.role === \"planner\",\n isReviewer: provider.role === \"reviewer\",\n hasImpeccableOverlay: provider.overlays?.includes(\"impeccable\") ?? false,\n hasFrontendDesignOverlay: provider.overlays?.includes(\"frontend-design\") ?? false,\n profileInstructions: provider.profileInstructions || \"\",\n skillContext,\n capabilityCategory: provider.capabilityCategory || \"\",\n selectionReason: provider.selectionReason ?? \"No additional routing reason.\",\n overlays: provider.overlays ?? [],\n targetPaths: issue.paths ?? [],\n workspacePath,\n basePrompt,\n });\n}\n\nasync function runCommandWithTimeout(\n command: string,\n workspacePath: string,\n issue: IssueEntry,\n config: RuntimeConfig,\n promptText: string,\n promptFile: string,\n extraEnv: Record<string, string> = {},\n): Promise<{ success: boolean; code: number | null; output: string }> {\n return new Promise((resolve) => {\n const started = Date.now();\n const resultFile = extraEnv.FIFONY_RESULT_FILE;\n if (resultFile && extraEnv.FIFONY_PRESERVE_RESULT_FILE !== \"1\") {\n rmSync(resultFile, { force: true });\n }\n\n // Write all FIFONY_* vars to an env file and source it in the command.\n // This avoids E2BIG: child inherits process.env naturally (no ...env spread),\n // and our custom vars are loaded from a file instead of argv/env.\n const allVars: Record<string, string> = {\n FIFONY_ISSUE_ID: issue.id,\n FIFONY_ISSUE_IDENTIFIER: issue.identifier,\n FIFONY_ISSUE_TITLE: issue.title,\n FIFONY_ISSUE_PRIORITY: String(issue.priority),\n FIFONY_WORKSPACE_PATH: workspacePath,\n FIFONY_PROMPT_FILE: promptFile,\n };\n for (const [key, value] of Object.entries(extraEnv)) {\n if (value.length > 4000) {\n const valFile = join(workspacePath, `${key.toLowerCase()}.txt`);\n writeFileSync(valFile, value, \"utf8\");\n allVars[`${key}_FILE`] = valFile;\n } else {\n allVars[key] = value;\n }\n }\n\n const envFilePath = join(workspacePath, \".fifony-env.sh\");\n const envFileLines = Object.entries(allVars)\n .map(([k, v]) => `export ${k}=${JSON.stringify(v)}`)\n .join(\"\\n\");\n writeFileSync(envFilePath, envFileLines, \"utf8\");\n\n const wrappedCommand = `. \"${envFilePath}\" && ${command}`;\n const child = spawn(wrappedCommand, {\n shell: true,\n cwd: workspacePath,\n detached: true, // Survive parent death\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n // Detach from parent so child survives SIGINT/restart\n child.unref();\n\n if (child.stdin) {\n child.stdin.end();\n }\n\n // Write PID file for recovery\n const pidFile = join(workspacePath, \"fifony-agent.pid\");\n const pid = child.pid;\n if (pid) {\n logger.debug({ issueId: issue.id, pid, command: command.slice(0, 120), cwd: workspacePath }, \"[Agent] Process spawned\");\n writeFileSync(pidFile, JSON.stringify({\n pid,\n issueId: issue.id,\n startedAt: new Date(started).toISOString(),\n command: command.slice(0, 200),\n }), \"utf8\");\n }\n\n let output = \"\";\n let timedOut = false;\n let outputBytes = 0;\n const liveLogFile = join(workspacePath, \"fifony-live-output.log\");\n writeFileSync(liveLogFile, \"\", \"utf8\");\n\n const onChunk = (chunk: Buffer | string) => {\n const text = String(chunk);\n output = appendFileTail(output, text, config.logLinesTail);\n outputBytes += text.length;\n try { appendFileSync(liveLogFile, text); } catch {}\n issue.commandOutputTail = output;\n };\n\n child.stdout?.on(\"data\", onChunk);\n child.stderr?.on(\"data\", onChunk);\n\n const AGENT_STALE_OUTPUT_MS = 300_000; // 5 minutes without output growth → stuck\n\n const timer = setTimeout(() => {\n timedOut = true;\n // Kill the whole process group (detached child + its children)\n if (pid) { try { process.kill(-pid, \"SIGTERM\"); } catch {} }\n else { child.kill(\"SIGTERM\"); }\n }, config.commandTimeoutMs);\n\n // Progress watchdog: check PID alive + output growing every 30s\n let lastWatchdogBytes = 0;\n let lastOutputGrowthAt = Date.now();\n let watchdogKilled = false;\n const watchdog = setInterval(() => {\n // Check if PID is still alive\n if (pid) {\n try { process.kill(pid, 0); } catch {\n // PID died without triggering close — force resolve\n clearInterval(watchdog);\n clearTimeout(timer);\n watchdogKilled = true;\n try { rmSync(pidFile, { force: true }); } catch {}\n resolve({ success: false, code: null, output: appendFileTail(output, `\\nAgent process died unexpectedly (PID ${pid}).`, config.logLinesTail) });\n return;\n }\n }\n // Check if output is still growing\n if (outputBytes > lastWatchdogBytes) {\n lastWatchdogBytes = outputBytes;\n lastOutputGrowthAt = Date.now();\n } else if (Date.now() - lastOutputGrowthAt > AGENT_STALE_OUTPUT_MS) {\n clearInterval(watchdog);\n clearTimeout(timer);\n timedOut = true;\n watchdogKilled = true;\n if (pid) { try { process.kill(-pid, \"SIGTERM\"); } catch {} }\n else { child.kill(\"SIGTERM\"); }\n try { rmSync(pidFile, { force: true }); } catch {}\n resolve({ success: false, code: null, output: appendFileTail(output, `\\nAgent process stuck — no output for ${Math.round(AGENT_STALE_OUTPUT_MS / 60_000)} minutes.`, config.logLinesTail) });\n }\n }, 30_000);\n\n const cleanup = () => {\n clearInterval(watchdog);\n try { rmSync(pidFile, { force: true }); } catch {}\n };\n\n child.on(\"error\", () => {\n clearTimeout(timer);\n cleanup();\n if (watchdogKilled) return;\n resolve({ success: false, code: null, output: `Command execution failed for issue ${issue.id}.` });\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n cleanup();\n if (watchdogKilled) return;\n if (timedOut) {\n resolve({ success: false, code: null, output: appendFileTail(output, `\\nExecution timeout after ${config.commandTimeoutMs}ms.`, config.logLinesTail) });\n return;\n }\n const duration = Math.max(0, Date.now() - started);\n if (code === 0) {\n resolve({ success: true, code, output: appendFileTail(output, `\\nExecution succeeded in ${duration}ms.`, config.logLinesTail) });\n return;\n }\n resolve({ success: false, code, output: appendFileTail(output, `\\nCommand exit code ${code ?? \"unknown\"} after ${duration}ms.`, config.logLinesTail) });\n });\n });\n}\n\nasync function runHook(\n command: string,\n workspacePath: string,\n issue: IssueEntry,\n hookName: string,\n extraEnv: Record<string, string> = {},\n): Promise<void> {\n if (!command.trim()) return;\n\n const result = await runCommandWithTimeout(command, workspacePath, issue, {\n pollIntervalMs: 0,\n workerConcurrency: 1,\n maxConcurrentByState: {},\n commandTimeoutMs: 300_000,\n maxAttemptsDefault: 1,\n retryDelayMs: 0,\n staleInProgressTimeoutMs: 0,\n logLinesTail: 12_000,\n agentProvider: normalizeAgentProvider(env.FIFONY_AGENT_PROVIDER ?? \"codex\"),\n agentCommand: command,\n maxTurns: 1,\n runMode: \"filesystem\",\n }, \"\", \"\", { FIFONY_HOOK_NAME: hookName, ...extraEnv });\n\n if (!result.success) {\n throw new Error(`${hookName} hook failed: ${result.output}`);\n }\n}\n\nexport async function cleanWorkspace(\n issueId: string,\n workflowDefinition: WorkflowDefinition | null,\n): Promise<void> {\n const safeId = idToSafePath(issueId);\n const workspacePath = join(WORKSPACE_ROOT, safeId);\n if (!existsSync(workspacePath)) return;\n\n // Run before_remove hook (failure is logged but ignored)\n if (workflowDefinition?.beforeRemoveHook) {\n try {\n const dummyIssue = { id: issueId, identifier: issueId } as IssueEntry;\n await runHook(workflowDefinition.beforeRemoveHook, workspacePath, dummyIssue, \"before_remove\");\n } catch (error) {\n logger.warn(`before_remove hook failed for ${issueId}: ${String(error)}`);\n }\n }\n\n try {\n rmSync(workspacePath, { recursive: true, force: true });\n logger.info(`Cleaned workspace for ${issueId}: ${workspacePath}`);\n } catch (error) {\n logger.warn(`Failed to clean workspace for ${issueId}: ${String(error)}`);\n }\n}\n\nasync function prepareWorkspace(\n issue: IssueEntry,\n workflowDefinition: WorkflowDefinition | null,\n): Promise<{ workspacePath: string; promptText: string; promptFile: string }> {\n const safeId = idToSafePath(issue.id);\n const workspaceRoot = join(WORKSPACE_ROOT, safeId);\n const createdNow = !existsSync(workspaceRoot);\n\n if (createdNow) {\n logger.debug({ issueId: issue.id, identifier: issue.identifier, workspacePath: workspaceRoot }, \"[Agent] Creating new workspace\");\n mkdirSync(workspaceRoot, { recursive: true });\n if (workflowDefinition?.afterCreateHook) {\n await runHook(workflowDefinition.afterCreateHook, workspaceRoot, issue, \"after_create\");\n } else {\n // Ensure source snapshot is ready (lazy bootstrap)\n await ensureSourceReady();\n cpSync(SOURCE_ROOT, workspaceRoot, {\n recursive: true,\n force: true,\n filter: (sourcePath) => !sourcePath.startsWith(WORKSPACE_ROOT),\n });\n }\n logger.debug({ issueId: issue.id, workspacePath: workspaceRoot }, \"[Agent] Workspace created\");\n } else {\n logger.debug({ issueId: issue.id, workspacePath: workspaceRoot }, \"[Agent] Reusing existing workspace\");\n }\n\n const metaPath = join(workspaceRoot, \"fifony-issue.json\");\n const promptText = await buildPrompt(issue, workflowDefinition);\n const promptFile = join(workspaceRoot, \"fifony-prompt.md\");\n writeFileSync(metaPath, JSON.stringify({ ...issue, runtimeSource: SOURCE_ROOT, bootstrapAt: now() }, null, 2), \"utf8\");\n writeFileSync(promptFile, `${promptText}\\n`, \"utf8\");\n\n issue.workspacePath = workspaceRoot;\n issue.workspacePreparedAt = now();\n\n return { workspacePath: workspaceRoot, promptText, promptFile };\n}\n\nasync function runAgentSession(\n state: RuntimeState,\n issue: IssueEntry,\n provider: AgentProviderDefinition,\n cycle: number,\n workspacePath: string,\n basePromptText: string,\n basePromptFile: string,\n): Promise<AgentSessionResult> {\n const maxTurns = clamp(state.config.maxTurns, 1, 16);\n const attempt = issue.attempts + 1;\n const sessionLookupKey = buildProviderSessionKey(issue, attempt, provider, cycle);\n const loadedSession = await loadAgentSessionState(sessionLookupKey, issue, attempt, maxTurns);\n const sessionKey = loadedSession.key;\n const session = loadedSession.session;\n let previousOutput = session.lastOutput;\n let nextPrompt = session.nextPrompt;\n let lastCode: number | null = session.lastCode;\n let lastOutput = session.lastOutput;\n const resultFile = join(workspacePath, `fifony-result-${provider.role}-${provider.provider}.json`);\n\n if (session.status === \"done\" && session.turns.length > 0) {\n logger.debug({ issueId: issue.id, identifier: issue.identifier, provider: provider.provider, role: provider.role }, \"[Agent] Session already completed, returning cached result\");\n return { success: true, blocked: false, continueRequested: false, code: session.lastCode, output: session.lastOutput, turns: session.turns.length };\n }\n\n const turnIndex = session.turns.length + 1;\n if (turnIndex > maxTurns) {\n session.status = \"blocked\";\n session.lastOutput = appendFileTail(lastOutput, `\\nAgent requested additional turns beyond configured limit (${maxTurns}).`, state.config.logLinesTail);\n await persistAgentSessionState(sessionKey, issue, provider, cycle, session);\n return { success: false, blocked: true, continueRequested: false, code: lastCode, output: session.lastOutput, turns: session.turns.length };\n }\n\n const turnPrompt = await buildTurnPrompt(issue, basePromptText, previousOutput, turnIndex, maxTurns, nextPrompt);\n const turnPromptFile = turnIndex === 1\n ? basePromptFile\n : join(workspacePath, `fifony-turn-${String(turnIndex).padStart(2, \"0\")}.md`);\n\n if (turnIndex > 1) writeFileSync(turnPromptFile, `${turnPrompt}\\n`, \"utf8\");\n\n session.status = \"running\";\n session.lastPrompt = turnPrompt;\n session.lastPromptFile = turnPromptFile;\n session.maxTurns = maxTurns;\n await persistAgentSessionState(sessionKey, issue, provider, cycle, session);\n\n logger.info({ issueId: issue.id, identifier: issue.identifier, turn: turnIndex, maxTurns, provider: provider.provider, role: provider.role, cycle, command: provider.command.slice(0, 120) }, \"[Agent] Spawning agent command\");\n const turnStartedAt = now();\n const turnEnv = {\n FIFONY_AGENT_PROVIDER: provider.provider,\n FIFONY_AGENT_ROLE: provider.role,\n FIFONY_REASONING_EFFORT: provider.reasoningEffort || \"\",\n FIFONY_SESSION_KEY: sessionKey,\n FIFONY_SESSION_ID: `${issue.id}-attempt-${attempt}`,\n FIFONY_TURN_INDEX: String(turnIndex),\n FIFONY_MAX_TURNS: String(maxTurns),\n FIFONY_TURN_PROMPT: turnPrompt,\n FIFONY_TURN_PROMPT_FILE: turnPromptFile,\n FIFONY_CONTINUE: turnIndex > 1 ? \"1\" : \"0\",\n FIFONY_PREVIOUS_OUTPUT: previousOutput,\n FIFONY_RESULT_FILE: resultFile,\n FIFONY_AGENT_PROFILE: provider.profile,\n FIFONY_AGENT_PROFILE_FILE: provider.profilePath,\n FIFONY_AGENT_PROFILE_INSTRUCTIONS: provider.profileInstructions,\n };\n\n const workflowDefinition = state._workflowDefinition as WorkflowDefinition | null | undefined;\n if (workflowDefinition?.beforeRunHook) {\n await runHook(workflowDefinition.beforeRunHook, workspacePath, issue, \"before_run\", turnEnv);\n }\n\n addEvent(state, issue.id, \"runner\", `Turn ${turnIndex}/${maxTurns} started for ${issue.identifier}.`);\n\n const turnResult = await runCommandWithTimeout(provider.command, workspacePath, issue, state.config, turnPrompt, turnPromptFile, turnEnv);\n\n if (workflowDefinition?.afterRunHook) {\n await runHook(workflowDefinition.afterRunHook, workspacePath, issue, \"after_run\", {\n ...turnEnv,\n FIFONY_LAST_EXIT_CODE: String(turnResult.code ?? \"\"),\n FIFONY_LAST_OUTPUT: turnResult.output,\n FIFONY_PRESERVE_RESULT_FILE: \"1\",\n });\n }\n\n logger.info({ issueId: issue.id, identifier: issue.identifier, turn: turnIndex, exitCode: turnResult.code, success: turnResult.success, outputBytes: turnResult.output.length }, \"[Agent] Agent command finished\");\n const directive = readAgentDirective(workspacePath, turnResult.output, turnResult.success);\n lastCode = turnResult.code;\n lastOutput = turnResult.output;\n previousOutput = turnResult.output;\n nextPrompt = directive.nextPrompt;\n if (!directive.tokenUsage) {\n logger.warn({ issueId: issue.id, identifier: issue.identifier, turn: turnIndex, role: provider.role, outputBytes: turnResult.output.length }, \"[Agent] Token extraction failed — no usage data in CLI output\");\n }\n addTokenUsage(issue, directive.tokenUsage, provider.role);\n if (directive.tokenUsage) recordTokens(issue, directive.tokenUsage, provider.role);\n\n if (directive.tokenUsage) {\n const tu = directive.tokenUsage;\n const parts = [\n `Turn ${turnIndex} (${provider.role})`,\n `${tu.totalTokens.toLocaleString()} tokens`,\n `(in: ${tu.inputTokens.toLocaleString()}, out: ${tu.outputTokens.toLocaleString()})`,\n ];\n if (tu.model) parts.push(`[${tu.model}]`);\n // Running totals\n const cumulative = issue.tokenUsage;\n if (cumulative && cumulative.totalTokens > tu.totalTokens) {\n parts.push(`| cumulative: ${cumulative.totalTokens.toLocaleString()}`);\n }\n addEvent(state, issue.id, \"info\", parts.join(\" \"));\n }\n\n session.turns.push({\n turn: turnIndex,\n role: provider.role,\n model: directive.tokenUsage?.model || provider.model || provider.provider,\n startedAt: turnStartedAt,\n completedAt: now(),\n promptFile: turnPromptFile,\n prompt: turnPrompt,\n output: turnResult.output,\n code: turnResult.code,\n success: turnResult.success,\n directiveStatus: directive.status,\n directiveSummary: directive.summary,\n nextPrompt: directive.nextPrompt,\n tokenUsage: directive.tokenUsage,\n });\n\n session.lastCode = lastCode;\n session.lastOutput = lastOutput;\n session.lastDirectiveStatus = directive.status;\n session.lastDirectiveSummary = directive.summary;\n session.nextPrompt = nextPrompt;\n\n const directiveSummary = directive.summary ? ` ${directive.summary}` : \"\";\n addEvent(state, issue.id, \"runner\", `Turn ${turnIndex}/${maxTurns} finished with status ${directive.status}.${directiveSummary}`.trim());\n\n if (!turnResult.success || directive.status === \"failed\") {\n logger.info({ issueId: issue.id, identifier: issue.identifier, turn: turnIndex, directiveStatus: directive.status, exitCode: lastCode }, \"[Agent] Session turn failed\");\n session.status = \"failed\";\n await persistAgentSessionState(sessionKey, issue, provider, cycle, session);\n return { success: false, blocked: false, continueRequested: false, code: lastCode, output: lastOutput, turns: turnIndex };\n }\n\n if (directive.status === \"blocked\") {\n logger.info({ issueId: issue.id, identifier: issue.identifier, turn: turnIndex }, \"[Agent] Session turn blocked — manual intervention requested\");\n session.status = \"blocked\";\n await persistAgentSessionState(sessionKey, issue, provider, cycle, session);\n return { success: false, blocked: true, continueRequested: false, code: lastCode, output: lastOutput, turns: turnIndex };\n }\n\n if (directive.status === \"continue\") {\n logger.info({ issueId: issue.id, identifier: issue.identifier, turn: turnIndex, maxTurns }, \"[Agent] Session requests continuation\");\n session.status = \"running\";\n await persistAgentSessionState(sessionKey, issue, provider, cycle, session);\n return { success: false, blocked: false, continueRequested: true, code: lastCode, output: lastOutput, turns: turnIndex };\n }\n\n logger.info({ issueId: issue.id, identifier: issue.identifier, turn: turnIndex }, \"[Agent] Session completed successfully\");\n session.status = \"done\";\n await persistAgentSessionState(sessionKey, issue, provider, cycle, session);\n return { success: true, blocked: false, continueRequested: false, code: lastCode, output: lastOutput, turns: turnIndex };\n}\n\nexport async function runAgentPipeline(\n state: RuntimeState,\n issue: IssueEntry,\n workspacePath: string,\n basePromptText: string,\n basePromptFile: string,\n workflowDefinition: WorkflowDefinition | null,\n workflowConfig?: WorkflowConfig | null,\n): Promise<AgentSessionResult> {\n const providers = getEffectiveAgentProviders(state, issue, workflowDefinition, workflowConfig);\n const attempt = issue.attempts + 1;\n logger.debug({ issueId: issue.id, identifier: issue.identifier, attempt, providers: providers.map((p) => `${p.role}:${p.provider}`) }, \"[Agent] Starting pipeline\");\n const { pipeline, key: pipelineFile } = await loadAgentPipelineState(issue, attempt, providers);\n const activeProvider = providers[clamp(pipeline.activeIndex, 0, Math.max(0, providers.length - 1))];\n const executorIndex = providers.findIndex((provider) => provider.role === \"executor\");\n\n // Discover skills and build context\n const skills = discoverSkills(workspacePath);\n const skillContext = buildSkillContext(skills);\n\n // Write skills reference to workspace\n if (skillContext) {\n writeFileSync(join(workspacePath, \"fifony-skills.md\"), skillContext, \"utf8\");\n }\n\n // Compile plan-aware execution if plan exists\n const compiled = await compileExecution(issue, activeProvider, state.config, workspacePath, skillContext);\n\n let providerPrompt: string;\n let effectiveProvider = activeProvider;\n\n if (compiled) {\n providerPrompt = compiled.prompt;\n effectiveProvider = { ...activeProvider, command: compiled.command };\n // Persist compilation artifacts for audit\n persistCompilationArtifacts(workspacePath, compiled);\n addEvent(state, issue.id, \"info\",\n `Plan compiled for ${compiled.meta.adapter}: effort=${compiled.meta.reasoningEffort}, skills=[${compiled.meta.skillsActivated.join(\",\")}], subagents=[${compiled.meta.subagentsRequested.join(\",\")}].`);\n\n // Merge compiled env into issue env file\n if (Object.keys(compiled.env).length > 0) {\n const envFile = join(workspacePath, \".fifony-compiled-env.sh\");\n const envLines = Object.entries(compiled.env).map(([k, v]) => `export ${k}=${JSON.stringify(v)}`).join(\"\\n\");\n writeFileSync(envFile, envLines, \"utf8\");\n }\n } else {\n providerPrompt = await buildProviderBasePrompt(activeProvider, issue, basePromptText, workspacePath, skillContext);\n }\n\n if (!effectiveProvider.command.trim()) {\n throw new Error(`No command configured for provider ${effectiveProvider.provider} (${effectiveProvider.role}).`);\n }\n\n pipeline.history.push(`[${now()}] Running ${effectiveProvider.role}:${effectiveProvider.provider} in cycle ${pipeline.cycle}${compiled ? ` [${compiled.meta.adapter} adapter]` : \"\"}.`);\n await persistAgentPipelineState(pipelineFile, pipeline);\n\n // Attach workflowDefinition to state for session hooks\n (state as any)._workflowDefinition = workflowDefinition;\n\n const result = await runAgentSession(state, issue, effectiveProvider, pipeline.cycle, workspacePath, providerPrompt, basePromptFile);\n\n if (result.success) {\n if (pipeline.activeIndex < providers.length - 1) {\n pipeline.activeIndex += 1;\n pipeline.history.push(`[${now()}] ${activeProvider.role}:${activeProvider.provider} completed; advancing to next provider.`);\n await persistAgentPipelineState(pipelineFile, pipeline);\n return { success: false, blocked: false, continueRequested: true, code: result.code, output: result.output, turns: result.turns };\n }\n pipeline.history.push(`[${now()}] Final provider ${activeProvider.role}:${activeProvider.provider} completed the issue.`);\n await persistAgentPipelineState(pipelineFile, pipeline);\n return result;\n }\n\n if (result.continueRequested && activeProvider.role === \"reviewer\" && executorIndex >= 0) {\n pipeline.cycle += 1;\n pipeline.activeIndex = executorIndex;\n pipeline.history.push(`[${now()}] Reviewer requested rework; returning to executor for cycle ${pipeline.cycle}.`);\n await persistAgentPipelineState(pipelineFile, pipeline);\n return result;\n }\n\n if (result.continueRequested) {\n pipeline.history.push(`[${now()}] ${activeProvider.role}:${activeProvider.provider} requested another turn.`);\n await persistAgentPipelineState(pipelineFile, pipeline);\n return result;\n }\n\n if (result.blocked) {\n pipeline.history.push(`[${now()}] ${activeProvider.role}:${activeProvider.provider} blocked the pipeline.`);\n await persistAgentPipelineState(pipelineFile, pipeline);\n return result;\n }\n\n pipeline.history.push(`[${now()}] ${activeProvider.role}:${activeProvider.provider} failed the pipeline.`);\n await persistAgentPipelineState(pipelineFile, pipeline);\n return result;\n}\n\nexport async function runIssueOnce(\n state: RuntimeState,\n issue: IssueEntry,\n running: Set<string>,\n workflowDefinition: WorkflowDefinition | null,\n): Promise<void> {\n const startTs = Date.now();\n const isReview = issue.state === \"In Review\";\n const isResuming = issue.state === \"Running\" || issue.state === \"Interrupted\";\n logger.info({ issueId: issue.id, identifier: issue.identifier, state: issue.state, isReview, isResuming, attempt: issue.attempts + 1, maxAttempts: issue.maxAttempts }, \"[Agent] Starting issue execution\");\n running.add(issue.id);\n state.metrics.activeWorkers += 1;\n issue.startedAt = issue.startedAt ?? now();\n\n // Load WorkflowConfig from settings (user's Settings → Workflow configuration)\n let workflowConfig: WorkflowConfig | null = null;\n try {\n const settings = await loadRuntimeSettings();\n workflowConfig = getWorkflowConfig(settings);\n } catch {\n // Fall through — use defaults\n }\n\n if (isReview) {\n issue.updatedAt = now();\n issue.history.push(`[${issue.updatedAt}] Review stage started for ${issue.identifier}.`);\n addEvent(state, issue.id, \"progress\", `Review started for ${issue.identifier}.`);\n } else if (isResuming) {\n await transitionIssueState(issue, \"Running\", `Resuming runner for ${issue.identifier}.`);\n addEvent(state, issue.id, \"progress\", `Runner resumed for ${issue.identifier}.`);\n } else {\n // Todo / Queued / Blocked → Queued → Running\n if (issue.state !== \"Queued\") {\n await transitionIssueState(issue, \"Queued\", `Issue ${issue.identifier} queued for execution.`);\n }\n await transitionIssueState(issue, \"Running\", `Agent started for ${issue.identifier}.`);\n addEvent(state, issue.id, \"progress\", `Runner started for ${issue.identifier}.`);\n }\n\n try {\n const workspaceDerivedPaths = hydrateIssuePathsFromWorkspace(issue);\n if ((issue.paths ?? []).length > 0) {\n issue.inferredPaths = [...new Set([...(issue.inferredPaths ?? []), ...inferCapabilityPaths({\n id: issue.id,\n identifier: issue.identifier,\n title: issue.title,\n description: issue.description,\n labels: issue.labels,\n paths: issue.paths,\n })])];\n }\n\n const { workspacePath, promptText, promptFile } = await prepareWorkspace(issue, workflowDefinition);\n addEvent(state, issue.id, \"info\", `Workspace ready at ${workspacePath}.`);\n\n const routedProviders = getEffectiveAgentProviders(state, issue, workflowDefinition, workflowConfig);\n\n if (isReview) {\n // ── Review stage: run only the reviewer provider ──────────────────\n const reviewer = routedProviders.find((p) => p.role === \"reviewer\");\n if (!reviewer) {\n // No reviewer configured → auto-approve\n await transitionIssueState(issue, \"Done\", `No reviewer configured; auto-approved for ${issue.identifier}.`);\n addEvent(state, issue.id, \"runner\", `Issue ${issue.identifier} auto-approved (no reviewer provider).`);\n issue.completedAt = now();\n issue.lastError = undefined;\n return;\n }\n\n addEvent(state, issue.id, \"info\", `Review provider: ${reviewer.role}:${reviewer.provider}${reviewer.model ? `/${reviewer.model}` : \"\"}${reviewer.profile ? `:${reviewer.profile}` : \"\"}.`);\n\n // Get diff summary for the review prompt\n let diffSummary = \"\";\n try {\n const diffResult = execSync(\n `git diff --no-index --stat -- \"${SOURCE_ROOT}\" \"${workspacePath}\" 2>/dev/null`,\n { encoding: \"utf8\", maxBuffer: 512_000, timeout: 10_000 },\n );\n diffSummary = diffResult.trim();\n } catch (err: any) {\n diffSummary = (err.stdout || \"\").trim();\n }\n\n // Compile a rich review prompt with plan context, diff, and criteria\n const compiled = await compileReview(issue, reviewer, workspacePath, diffSummary);\n const effectiveReviewer = { ...reviewer, command: compiled.command || reviewer.command };\n\n const reviewPromptFile = join(workspacePath, \"fifony-review-prompt.md\");\n writeFileSync(reviewPromptFile, `${compiled.prompt}\\n`, \"utf8\");\n\n (state as any)._workflowDefinition = workflowDefinition;\n const reviewResult = await runAgentSession(state, issue, effectiveReviewer, 1, workspacePath, compiled.prompt, reviewPromptFile);\n\n issue.durationMs = (issue.durationMs ?? 0) + (Date.now() - startTs);\n issue.commandExitCode = reviewResult.code;\n issue.commandOutputTail = reviewResult.output;\n\n // Persist review audit\n const reviewAudit = buildExecutionAudit(effectiveReviewer, null, issue, Date.now() - startTs, reviewResult.success ? \"approved\" : reviewResult.continueRequested ? \"rework\" : \"rejected\");\n persistExecutionAudit(workspacePath, reviewAudit);\n\n if (reviewResult.success) {\n await transitionIssueState(issue, \"Done\", `Reviewer approved ${issue.identifier} in ${reviewResult.turns} turn(s).`);\n addEvent(state, issue.id, \"runner\", `Issue ${issue.identifier} approved by reviewer → Done.`);\n issue.completedAt = now();\n issue.lastError = undefined;\n } else if (reviewResult.continueRequested) {\n // Reviewer wants rework → back to Queued for re-execution\n await transitionIssueState(issue, \"Queued\", `Reviewer requested rework for ${issue.identifier}.`);\n issue.nextRetryAt = new Date(Date.now() + 1000).toISOString();\n issue.lastError = undefined;\n addEvent(state, issue.id, \"runner\", `Issue ${issue.identifier} sent back for rework by reviewer.`);\n } else {\n // Reviewer blocked or failed\n issue.lastError = reviewResult.output;\n issue.attempts += 1;\n if (issue.attempts >= issue.maxAttempts) {\n await transitionIssueState(issue, \"Cancelled\", `Review failed, max attempts reached for ${issue.identifier}.`);\n addEvent(state, issue.id, \"error\", `Issue ${issue.identifier} cancelled after review failure.`);\n } else {\n issue.nextRetryAt = getNextRetryAt(issue, state.config.retryDelayMs);\n await transitionIssueState(issue, \"Blocked\", `Review failed for ${issue.identifier}. Retry at ${issue.nextRetryAt}.`);\n addEvent(state, issue.id, \"error\", `Issue ${issue.identifier} blocked after review failure.`);\n }\n }\n return;\n }\n\n // ── Normal execution (Todo / In Progress / Blocked) ───────────────\n addEvent(state, issue.id, \"info\",\n `Capability routing selected ${routedProviders.map((p) => `${p.role}:${p.provider}${p.model ? `/${p.model}` : \"\"}${p.profile ? `:${p.profile}` : \"\"}${p.reasoningEffort ? ` [${p.reasoningEffort}]` : \"\"}`).join(\", \")}.`);\n\n const routingSignals = describeRoutingSignals(issue, workspaceDerivedPaths);\n if (routingSignals) {\n addEvent(state, issue.id, \"info\", `Capability routing signals: ${routingSignals}.`);\n }\n\n const runResult = await runAgentPipeline(state, issue, workspacePath, promptText, promptFile, workflowDefinition, workflowConfig);\n\n issue.durationMs = Date.now() - startTs;\n issue.commandExitCode = runResult.code;\n issue.commandOutputTail = runResult.output;\n\n if (runResult.success) {\n // Compute diff stats before transitioning\n computeDiffStats(issue);\n if (issue.filesChanged) {\n addEvent(state, issue.id, \"info\", `Diff: ${issue.filesChanged} files, +${issue.linesAdded || 0} -${issue.linesRemoved || 0} lines.`);\n }\n\n // Merge workspace into TARGET_ROOT so the code is runnable/testable before review\n try {\n const mergeResult = mergeWorkspace(workspacePath);\n issue.mergedAt = now();\n issue.mergeResult = {\n copied: mergeResult.copied.length,\n deleted: mergeResult.deleted.length,\n skipped: mergeResult.skipped.length,\n conflicts: mergeResult.conflicts.length,\n };\n const conflictMsg = mergeResult.conflicts.length > 0\n ? ` ${mergeResult.conflicts.length} conflict(s): ${mergeResult.conflicts.join(\", \")}.`\n : \"\";\n addEvent(state, issue.id, \"merge\", `Workspace merged to project: ${mergeResult.copied.length} file(s) copied, ${mergeResult.deleted.length} deleted.${conflictMsg} Code is now available in the project root.`);\n if (mergeResult.conflicts.length > 0) {\n addEvent(state, issue.id, \"error\", `Merge conflicts detected — ${mergeResult.conflicts.length} file(s) modified by another worker: ${mergeResult.conflicts.join(\", \")}`);\n }\n logger.info(`Workspace merged for ${issue.identifier}: ${mergeResult.copied.length} copied, ${mergeResult.deleted.length} deleted, ${mergeResult.conflicts.length} conflicts.`);\n } catch (mergeErr) {\n addEvent(state, issue.id, \"error\", `Merge failed: ${String(mergeErr)}`);\n logger.error(`Merge failed for ${issue.identifier}: ${String(mergeErr)}`);\n }\n\n // Persist execution audit\n const executor = routedProviders.find((p) => p.role === \"executor\") || routedProviders[0];\n if (executor && workspacePath) {\n const audit = buildExecutionAudit(executor, null, issue, Date.now() - startTs, \"success\");\n persistExecutionAudit(workspacePath, audit);\n }\n\n // Move to In Review — the reviewer will run as a separate scheduler pick\n await transitionIssueState(issue, \"In Review\", `Agent execution finished in ${runResult.turns} turn(s) for ${issue.identifier}. Awaiting review.`);\n issue.lastError = undefined;\n addEvent(state, issue.id, \"runner\", `Issue ${issue.identifier} moved to In Review.`);\n } else if (runResult.continueRequested) {\n issue.updatedAt = now();\n issue.commandExitCode = runResult.code;\n issue.commandOutputTail = runResult.output;\n issue.lastError = undefined;\n // Short continuation retry (1s) — spec §7.1, §8.4\n issue.nextRetryAt = new Date(Date.now() + 1000).toISOString();\n issue.history.push(`[${issue.updatedAt}] Agent requested another turn (${runResult.turns}/${state.config.maxTurns}).`);\n addEvent(state, issue.id, \"runner\", `Issue ${issue.identifier} queued for next turn.`);\n } else {\n issue.lastError = runResult.output;\n issue.attempts += 1;\n\n if (issue.attempts >= issue.maxAttempts) {\n issue.commandExitCode = runResult.code;\n await transitionIssueState(issue, \"Cancelled\", `Max attempts reached (${issue.attempts}/${issue.maxAttempts}).`);\n addEvent(state, issue.id, \"error\", `Issue ${issue.identifier} cancelled after repeated failures.`);\n } else {\n issue.nextRetryAt = getNextRetryAt(issue, state.config.retryDelayMs);\n await transitionIssueState(issue,\n \"Blocked\",\n `${runResult.blocked ? \"Agent requested manual intervention\" : \"Failure\"} on attempt ${issue.attempts}/${issue.maxAttempts}; retry scheduled at ${issue.nextRetryAt}.`);\n addEvent(state, issue.id, \"error\", `Issue ${issue.identifier} blocked waiting for retry.`);\n }\n }\n } catch (error) {\n issue.attempts += 1;\n issue.lastError = String(error);\n\n if (issue.attempts >= issue.maxAttempts) {\n await transitionIssueState(issue, \"Cancelled\", `Issue failed unexpectedly: ${issue.lastError}`);\n addEvent(state, issue.id, \"error\", `Issue ${issue.identifier} cancelled unexpectedly.`);\n } else {\n issue.nextRetryAt = getNextRetryAt(issue, state.config.retryDelayMs);\n await transitionIssueState(issue, \"Blocked\", `Unexpected failure. Retry scheduled at ${issue.nextRetryAt}.`);\n addEvent(state, issue.id, \"error\", `Issue ${issue.identifier} blocked after unexpected failure.`);\n }\n } finally {\n const elapsedMs = Date.now() - startTs;\n logger.info({ issueId: issue.id, identifier: issue.identifier, finalState: issue.state, elapsedMs, attempts: issue.attempts }, \"[Agent] Issue execution finished\");\n issue.updatedAt = now();\n markIssueDirty(issue.id);\n state.metrics.activeWorkers = Math.max(state.metrics.activeWorkers - 1, 0);\n running.delete(issue.id);\n state.metrics = computeMetrics(state.issues);\n state.metrics.activeWorkers = Math.max(state.metrics.activeWorkers, 0);\n state.updatedAt = now();\n await persistState(state);\n }\n}\n","import { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\n\nexport type DiscoveredSkill = {\n name: string;\n content: string;\n};\n\nexport function discoverSkills(workspacePath: string): DiscoveredSkill[] {\n const home = homedir();\n const searchPaths = [\n resolve(workspacePath, \".codex\", \"skills\"),\n resolve(workspacePath, \".claude\", \"skills\"),\n join(home, \".codex\", \"skills\"),\n join(home, \".claude\", \"skills\"),\n ];\n\n const seen = new Set<string>();\n const skills: DiscoveredSkill[] = [];\n\n for (const basePath of searchPaths) {\n if (!existsSync(basePath)) continue;\n\n for (const entry of readdirSync(basePath, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n if (seen.has(entry.name)) continue;\n\n const skillFile = join(basePath, entry.name, \"SKILL.md\");\n if (!existsSync(skillFile)) continue;\n\n try {\n const content = readFileSync(skillFile, \"utf8\").trim();\n if (content) {\n seen.add(entry.name);\n skills.push({ name: entry.name, content });\n }\n } catch {\n // skip unreadable skills\n }\n }\n }\n\n return skills;\n}\n\nexport function buildSkillContext(skills: DiscoveredSkill[]): string {\n if (skills.length === 0) return \"\";\n\n const sections = skills.map((skill) =>\n `### Skill: ${skill.name}\\n${skill.content}`\n );\n\n return `## Available Skills\\n\\n${sections.join(\"\\n\\n\")}`;\n}\n","import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { copyFile, mkdir, readdir, stat, writeFile } from \"node:fs/promises\";\nimport { extname, join } from \"node:path\";\nimport { env, argv, exit } from \"node:process\";\nimport type { WorkflowDefinition } from \"./types.ts\";\nimport {\n SOURCE_ROOT,\n SOURCE_MARKER,\n TARGET_ROOT,\n} from \"./constants.ts\";\nimport {\n now,\n fail,\n parseIntArg,\n} from \"./helpers.ts\";\nimport { logger } from \"./logger.ts\";\nimport { PROMPT_TEMPLATES } from \"../generated/prompts.ts\";\n\nconst SKIP_DIRS = new Set([\n \".git\", \".fifony\", \"node_modules\", \".venv\", \"data\",\n \"dist\", \"build\", \".turbo\", \".next\", \".nuxt\", \".tanstack\",\n \"coverage\", \"artifacts\", \"captures\", \"tmp\", \"temp\",\n]);\n\nfunction shouldSkipPath(relativePath: string): boolean {\n const parts = relativePath.split(\"/\");\n if (parts.some((segment) => SKIP_DIRS.has(segment))) return true;\n const base = parts.at(-1) ?? \"\";\n if (base.startsWith(\"map_scan_\") && extname(base) === \".json\") return true;\n if (extname(base) === \".xlsx\") return true;\n return false;\n}\n\nexport function bootstrapSource(): void {\n if (existsSync(SOURCE_MARKER)) return;\n\n logger.info(\"Creating local source snapshot for Fifony (local-only runtime)...\");\n\n const copyRecursive = (source: string, target: string, rel = \"\") => {\n mkdirSync(target, { recursive: true });\n const items = readdirSync(source, { withFileTypes: true });\n\n for (const item of items) {\n const nextRel = rel ? `${rel}/${item.name}` : item.name;\n if (shouldSkipPath(nextRel)) continue;\n\n const sourcePath = `${source}/${item.name}`;\n const targetPath = `${target}/${item.name}`;\n const itemStat = statSync(sourcePath);\n\n if (item.isDirectory()) {\n copyRecursive(sourcePath, targetPath, nextRel);\n continue;\n }\n\n if (item.isSymbolicLink() || itemStat.isSymbolicLink()) continue;\n\n if (itemStat.isFile() || itemStat.isFIFO()) {\n try {\n const file = readFileSync(sourcePath);\n writeFileSync(targetPath, file);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n logger.debug(`Skipped missing source file: ${sourcePath}`);\n } else {\n throw error;\n }\n }\n }\n }\n };\n\n mkdirSync(SOURCE_ROOT, { recursive: true });\n copyRecursive(TARGET_ROOT, SOURCE_ROOT);\n writeFileSync(SOURCE_MARKER, `${now()}\\n`, \"utf8\");\n}\n\nlet sourceReadyPromise: Promise<void> | null = null;\nlet skipSourceFlag = false;\n\nexport function setSkipSource(skip: boolean): void {\n skipSourceFlag = skip;\n}\n\n/**\n * Async, lazy version of bootstrapSource().\n * Only runs the copy once, on first call. Subsequent calls resolve immediately.\n * Emits progress via optional callback.\n */\nexport async function ensureSourceReady(\n onProgress?: (status: \"copying\" | \"ready\") => void,\n): Promise<void> {\n if (skipSourceFlag) {\n onProgress?.(\"ready\");\n return;\n }\n if (existsSync(SOURCE_MARKER)) {\n onProgress?.(\"ready\");\n return;\n }\n\n // Deduplicate concurrent calls\n if (sourceReadyPromise) return sourceReadyPromise;\n\n sourceReadyPromise = (async () => {\n onProgress?.(\"copying\");\n logger.info(\"Creating local source snapshot (async) for Fifony...\");\n\n const copyRecursiveAsync = async (source: string, target: string, rel = \"\") => {\n await mkdir(target, { recursive: true });\n const items = await readdir(source, { withFileTypes: true });\n\n for (const item of items) {\n const nextRel = rel ? `${rel}/${item.name}` : item.name;\n if (shouldSkipPath(nextRel)) continue;\n\n const sourcePath = `${source}/${item.name}`;\n const targetPath = `${target}/${item.name}`;\n const itemStat = await stat(sourcePath);\n\n if (item.isDirectory()) {\n await copyRecursiveAsync(sourcePath, targetPath, nextRel);\n continue;\n }\n\n if (item.isSymbolicLink() || itemStat.isSymbolicLink()) continue;\n\n if (itemStat.isFile() || itemStat.isFIFO()) {\n try {\n await copyFile(sourcePath, targetPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n logger.debug(`Skipped missing source file: ${sourcePath}`);\n } else {\n throw error;\n }\n }\n }\n }\n };\n\n await mkdir(SOURCE_ROOT, { recursive: true });\n await copyRecursiveAsync(TARGET_ROOT, SOURCE_ROOT);\n await writeFile(SOURCE_MARKER, `${now()}\\n`, \"utf8\");\n onProgress?.(\"ready\");\n logger.info(\"Source snapshot ready (async).\");\n })();\n\n return sourceReadyPromise;\n}\n\n/**\n * Returns an empty WorkflowDefinition.\n * WORKFLOW.md is no longer supported — all configuration lives in s3db settings\n * (Settings → Workflow in the dashboard).\n */\nexport function loadWorkflowDefinition(): WorkflowDefinition {\n const defaultPrompt = PROMPT_TEMPLATES[\"workflow-default\"];\n\n return {\n workflowPath: \"\",\n rendered: \"\",\n config: {},\n promptTemplate: defaultPrompt,\n agentProvider: \"codex\",\n agentProfile: \"\",\n agentProfilePath: \"\",\n agentProfileInstructions: \"\",\n agentProviders: [],\n afterCreateHook: \"\",\n beforeRunHook: \"\",\n afterRunHook: \"\",\n beforeRemoveHook: \"\",\n };\n}\n\nexport function parsePort(args: string[]): number | undefined {\n for (let i = 0; i < args.length; i += 1) {\n const arg = args[i];\n\n if (arg === \"--help\" || arg === \"-h\") {\n console.log(\n `Usage: ${argv[1]} [options]\\n` +\n \"Options:\\n\" +\n \" --port <n> Start local dashboard (default: no UI and single batch run)\\n\" +\n \" --workspace <path> Target workspace root (default: current directory)\\n\" +\n \" --persistence <path> Persistence root (default: current directory)\\n\" +\n \" --concurrency <n> Maximum number of parallel issue runners\\n\" +\n \" --attempts <n> Maximum attempts per issue\\n\" +\n \" --poll <ms> Polling interval for the scheduler\\n\" +\n \" --once Run one local batch and exit\\n\" +\n \" --help Show this message\",\n );\n exit(0);\n }\n\n if (arg === \"--port\") {\n const value = args[i + 1];\n if (!value || !/^\\d+$/.test(value)) {\n fail(`Invalid value for --port: ${value ?? \"<empty>\"}`);\n }\n return parseIntArg(value, 4040);\n }\n }\n\n return undefined;\n}\n\n","import { writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { IssueEntry, AgentProviderDefinition, RuntimeConfig, AgentTokenUsage } from \"../types.ts\";\nimport { compileForClaude } from \"./plan-to-claude.ts\";\nimport { compileForCodex } from \"./plan-to-codex.ts\";\nimport { buildFullPlanPrompt, buildExecutionPayload } from \"./shared.ts\";\nimport type { ExecutionPayload } from \"./shared.ts\";\nimport { buildClaudeCommand, buildCodexCommand, REVIEW_RESULT_SCHEMA } from \"./commands.ts\";\nimport { renderPrompt } from \"../../prompting.ts\";\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport type CompiledExecution = {\n prompt: string;\n command: string;\n env: Record<string, string>;\n preHooks: string[];\n postHooks: string[];\n outputSchema: string;\n payload: ExecutionPayload | null;\n meta: {\n adapter: \"claude\" | \"codex\" | \"passthrough\";\n reasoningEffort: string;\n model: string;\n skillsActivated: string[];\n subagentsRequested: string[];\n phasesCount: number;\n };\n};\n\nexport type CompiledReview = {\n prompt: string;\n command: string;\n};\n\nexport type ExecutionAudit = {\n runtime: string;\n model: string;\n effort: string;\n role: string;\n skillsActivated: string[];\n subagentsRequested: string[];\n durationMs: number;\n tokenUsage: AgentTokenUsage | null;\n diffStats: { filesChanged: number; linesAdded: number; linesRemoved: number } | null;\n result: string;\n compiledAt: string;\n completedAt: string;\n};\n\n// ── Compile execution ────────────────────────────────────────────────────────\n\nexport async function compileExecution(\n issue: IssueEntry,\n provider: AgentProviderDefinition,\n config: RuntimeConfig,\n workspacePath: string,\n skillContext: string,\n): Promise<CompiledExecution | null> {\n const plan = issue.plan;\n if (!plan?.steps?.length) return null;\n\n const payload = buildExecutionPayload(issue, provider, plan, workspacePath);\n\n let compiled: CompiledExecution | null = null;\n if (provider.provider === \"claude\") {\n compiled = await compileForClaude(issue, provider, plan, config, workspacePath, skillContext);\n } else if (provider.provider === \"codex\") {\n compiled = await compileForCodex(issue, provider, plan, config, workspacePath, skillContext);\n }\n\n if (compiled) {\n compiled.payload = payload;\n }\n\n return compiled;\n}\n\n// ── Compile review ───────────────────────────────────────────────────────────\n\nexport async function compileReview(\n issue: IssueEntry,\n reviewer: AgentProviderDefinition,\n workspacePath: string,\n diffSummary: string,\n): Promise<CompiledReview> {\n const plan = issue.plan;\n const prompt = await renderPrompt(\"compile-review\", {\n issueIdentifier: issue.identifier,\n title: issue.title,\n description: issue.description || \"(none)\",\n workspacePath,\n planPrompt: plan ? buildFullPlanPrompt(plan) : \"\",\n successCriteria: (plan?.successCriteria ?? []).map((value) => ({ value })),\n deliverables: (plan?.deliverables ?? []).map((value) => ({ value })),\n diffSummary,\n });\n\n // Build command using shared builder — single source of truth for CLI flags\n let command = reviewer.command;\n if (!command.trim() || command.includes(\"$FIFONY_PROMPT_FILE\")) {\n if (reviewer.provider === \"claude\") {\n command = buildClaudeCommand({ model: reviewer.model, jsonSchema: REVIEW_RESULT_SCHEMA });\n } else if (reviewer.provider === \"codex\") {\n command = buildCodexCommand({ model: reviewer.model, reasoningEffort: reviewer.reasoningEffort });\n }\n }\n\n return { prompt, command };\n}\n\n// ── Audit ────────────────────────────────────────────────────────────────────\n\nexport function buildExecutionAudit(\n provider: AgentProviderDefinition,\n compiled: CompiledExecution | null,\n issue: IssueEntry,\n durationMs: number,\n result: string,\n): ExecutionAudit {\n return {\n runtime: provider.provider,\n model: provider.model || compiled?.meta.model || \"default\",\n effort: provider.reasoningEffort || compiled?.meta.reasoningEffort || \"default\",\n role: provider.role,\n skillsActivated: compiled?.meta.skillsActivated || [],\n subagentsRequested: compiled?.meta.subagentsRequested || [],\n durationMs,\n tokenUsage: issue.tokenUsage ?? null,\n diffStats: issue.filesChanged != null\n ? { filesChanged: issue.filesChanged, linesAdded: issue.linesAdded || 0, linesRemoved: issue.linesRemoved || 0 }\n : null,\n result,\n compiledAt: compiled ? new Date().toISOString() : \"\",\n completedAt: new Date().toISOString(),\n };\n}\n\n// ── Persistence ──────────────────────────────────────────────────────────────\n\nexport function persistCompilationArtifacts(workspacePath: string, compiled: CompiledExecution): void {\n try {\n writeFileSync(\n join(workspacePath, \"fifony-compiled-execution.json\"),\n JSON.stringify({\n adapter: compiled.meta.adapter,\n model: compiled.meta.model,\n reasoningEffort: compiled.meta.reasoningEffort,\n skillsActivated: compiled.meta.skillsActivated,\n subagentsRequested: compiled.meta.subagentsRequested,\n phasesCount: compiled.meta.phasesCount,\n preHooks: compiled.preHooks,\n postHooks: compiled.postHooks,\n hasOutputSchema: !!compiled.outputSchema,\n hasPayload: !!compiled.payload,\n command: compiled.command,\n promptLength: compiled.prompt.length,\n compiledAt: new Date().toISOString(),\n }, null, 2),\n \"utf8\",\n );\n } catch { /* optional audit data */ }\n\n // Save full prompt for debugging\n try {\n writeFileSync(\n join(workspacePath, \"fifony-prompt.md\"),\n compiled.prompt,\n \"utf8\",\n );\n } catch { /* optional */ }\n\n if (compiled.payload) {\n try {\n writeFileSync(\n join(workspacePath, \"fifony-execution-payload.json\"),\n JSON.stringify(compiled.payload, null, 2),\n \"utf8\",\n );\n } catch { /* optional */ }\n }\n}\n\nexport function persistExecutionAudit(workspacePath: string, audit: ExecutionAudit): void {\n try {\n writeFileSync(\n join(workspacePath, \"fifony-execution-audit.json\"),\n JSON.stringify(audit, null, 2),\n \"utf8\",\n );\n } catch { /* optional audit data */ }\n}\n","import type { IssuePlan, IssuePlanStep, IssueEntry, AgentProviderDefinition, EffortConfig, AgentProviderRole } from \"../types.ts\";\n\n/** Render plan context (summary, assumptions, constraints, unknowns) */\nexport function buildPlanContextSection(plan: IssuePlan): string {\n const parts: string[] = [\"## Plan Context\", \"\", `**Summary:** ${plan.summary}`];\n\n if (plan.assumptions?.length) {\n parts.push(\"\", \"**Assumptions:**\");\n plan.assumptions.forEach((a) => parts.push(`- ${a}`));\n }\n if (plan.constraints?.length) {\n parts.push(\"\", \"**Constraints:**\");\n plan.constraints.forEach((c) => parts.push(`- ${c}`));\n }\n if (plan.unknowns?.length) {\n parts.push(\"\", \"**Unknowns to investigate:**\");\n plan.unknowns.forEach((u) => {\n parts.push(`- **${u.question}**`);\n if (u.whyItMatters) parts.push(` Why it matters: ${u.whyItMatters}`);\n if (u.howToResolve) parts.push(` How to resolve: ${u.howToResolve}`);\n });\n }\n\n return parts.join(\"\\n\");\n}\n\n/** Render execution steps or phases */\nexport function buildStepsSection(plan: IssuePlan): string {\n const parts: string[] = [\"## Execution Steps\"];\n\n if (plan.phases?.length) {\n for (const phase of plan.phases) {\n parts.push(\"\", `### Phase: ${phase.phaseName}`, `Goal: ${phase.goal}`);\n if (phase.dependencies?.length) parts.push(`Dependencies: ${phase.dependencies.join(\", \")}`);\n for (const task of phase.tasks) {\n parts.push(`${task.step}. **${task.action}**${task.ownerType ? ` [${task.ownerType}]` : \"\"}`);\n if (task.details) parts.push(` ${task.details}`);\n if (task.doneWhen) parts.push(` Done when: ${task.doneWhen}`);\n if (task.files?.length) parts.push(` Files: ${task.files.join(\", \")}`);\n }\n if (phase.outputs?.length) parts.push(`Outputs: ${phase.outputs.join(\", \")}`);\n }\n } else {\n parts.push(\"\");\n for (const step of plan.steps) {\n parts.push(`${step.step}. **${step.action}**${step.ownerType ? ` [${step.ownerType}]` : \"\"}`);\n if (step.details) parts.push(` ${step.details}`);\n if (step.doneWhen) parts.push(` Done when: ${step.doneWhen}`);\n if (step.files?.length) parts.push(` Files: ${step.files.join(\", \")}`);\n }\n }\n\n parts.push(\"\", \"Follow this plan. Complete each step in order.\");\n return parts.join(\"\\n\");\n}\n\n/** Render risks section */\nexport function buildRiskSection(plan: IssuePlan): string {\n if (!plan.risks?.length) return \"\";\n const parts = [\"## Risks\"];\n for (const r of plan.risks) {\n parts.push(`- **${r.risk}** — Impact: ${r.impact}. Mitigation: ${r.mitigation}`);\n }\n return parts.join(\"\\n\");\n}\n\n/** Render validation requirements */\nexport function buildValidationSection(plan: IssuePlan): string {\n const parts: string[] = [];\n\n if (plan.successCriteria?.length) {\n parts.push(\"## Success Criteria\");\n plan.successCriteria.forEach((c) => parts.push(`- ${c}`));\n }\n if (plan.validation?.length) {\n parts.push(\"\", \"## Validation Checks\");\n parts.push(\"Run these before marking as done:\");\n plan.validation.forEach((v) => parts.push(`- ${v}`));\n }\n if (plan.deliverables?.length) {\n parts.push(\"\", \"## Deliverables\");\n plan.deliverables.forEach((d) => parts.push(`- ${d}`));\n }\n\n return parts.join(\"\\n\");\n}\n\n/** Render tooling/delegation decisions */\nexport function buildToolingSection(plan: IssuePlan): string {\n const td = plan.toolingDecision;\n if (!td) return \"\";\n\n const parts = [\"## Tooling & Delegation Strategy\"];\n\n if (td.decisionSummary) parts.push(\"\", td.decisionSummary);\n\n if (td.shouldUseSkills && td.skillsToUse?.length) {\n parts.push(\"\", \"**Skills to activate:**\");\n td.skillsToUse.forEach((s) => parts.push(`- **${s.name}**: ${s.why}`));\n }\n\n if (td.shouldUseSubagents && td.subagentsToUse?.length) {\n parts.push(\"\", \"**Subagents to use:**\");\n td.subagentsToUse.forEach((a) => parts.push(`- **${a.name}** (${a.role}): ${a.why}`));\n }\n\n return parts.join(\"\\n\");\n}\n\n/** Render execution strategy */\nexport function buildStrategySection(plan: IssuePlan): string {\n const es = plan.executionStrategy;\n if (!es) return \"\";\n\n const parts = [\n \"## Execution Strategy\",\n \"\",\n `**Approach:** ${es.approach}`,\n `**Rationale:** ${es.whyThisApproach}`,\n ];\n\n if (es.alternativesConsidered?.length) {\n parts.push(\"\", \"Alternatives considered:\");\n es.alternativesConsidered.forEach((a) => parts.push(`- ${a}`));\n }\n\n return parts.join(\"\\n\");\n}\n\n/** Resolve effort for a given role */\nexport function resolveEffortForProvider(\n plan: IssuePlan | undefined,\n role: AgentProviderRole,\n globalEffort?: EffortConfig,\n): string | undefined {\n const planEffort = plan?.suggestedEffort;\n const roleKey = role as keyof EffortConfig;\n return planEffort?.[roleKey] as string\n || planEffort?.default as string\n || globalEffort?.[roleKey] as string\n || globalEffort?.default as string\n || undefined;\n}\n\n/** Build the complete plan section for any provider */\nexport function buildFullPlanPrompt(plan: IssuePlan): string {\n return [\n buildPlanContextSection(plan),\n buildStrategySection(plan),\n buildToolingSection(plan),\n buildStepsSection(plan),\n buildRiskSection(plan),\n buildValidationSection(plan),\n ].filter(Boolean).join(\"\\n\\n\");\n}\n\n/** Extract validation commands from plan for hooks */\nexport function extractValidationCommands(plan: IssuePlan): { pre: string[]; post: string[] } {\n const pre: string[] = [];\n const post: string[] = [];\n\n for (const v of plan.validation || []) {\n const lower = v.toLowerCase();\n if (lower.includes(\"lint\")) post.push(\"pnpm lint --quiet 2>/dev/null || true\");\n if (lower.includes(\"typecheck\") || lower.includes(\"tsc\")) post.push(\"pnpm tsc --noEmit 2>/dev/null || true\");\n if (lower.includes(\"test\")) post.push(\"pnpm test 2>/dev/null || true\");\n }\n\n // Deduplicate\n return { pre: [...new Set(pre)], post: [...new Set(post)] };\n}\n\n// ── Execution Payload ─────────────────────────────────────────────────────────\n\n/**\n * Canonical structured input for CLI execution.\n * This is the single source of truth that the prompt references.\n * The prompt provides the markdown frame (instructions, role, strategy);\n * the payload carries the structured data (plan, constraints, criteria).\n */\nexport type ExecutionPayload = {\n /** Schema version for forward compat */\n version: 1;\n\n /** Issue identity */\n issue: {\n id: string;\n identifier: string;\n title: string;\n description: string;\n priority: number;\n labels: string[];\n paths: string[];\n };\n\n /** Provider context */\n provider: {\n name: string;\n role: AgentProviderRole;\n model: string;\n effort: string;\n capabilityCategory: string;\n overlays: string[];\n };\n\n /** Execution intent — what to do and how */\n executionIntent: {\n complexity: string;\n approach: string;\n rationale: string;\n workPattern: \"sequential\" | \"phased\" | \"parallel_subtasks\";\n };\n\n /** Structured plan data */\n plan: {\n summary: string;\n steps: Array<{\n step: number;\n action: string;\n files: string[];\n ownerType: string;\n doneWhen: string;\n }>;\n phases: Array<{\n name: string;\n goal: string;\n tasks: number[];\n dependencies: string[];\n outputs: string[];\n }>;\n };\n\n /** Constraints the agent must respect */\n constraints: string[];\n\n /** Success criteria — each must be met for \"done\" */\n successCriteria: string[];\n\n /** Validation commands to run before reporting done */\n validation: string[];\n\n /** Expected deliverables */\n deliverables: string[];\n\n /** Assumptions the plan is built on */\n assumptions: string[];\n\n /** Unknowns that may need resolution */\n unknowns: Array<{ question: string; whyItMatters: string; howToResolve: string }>;\n\n /** Risks with impact and mitigation */\n risks: Array<{ risk: string; impact: string; mitigation: string }>;\n\n /** Tooling decisions */\n tooling: {\n skills: Array<{ name: string; why: string }>;\n subagents: Array<{ name: string; role: string; why: string }>;\n };\n\n /** Target paths for focused changes */\n targetPaths: string[];\n\n /** Workspace location */\n workspacePath: string;\n\n /** Timestamp */\n createdAt: string;\n};\n\n/**\n * Build the canonical execution payload from issue + plan + provider context.\n */\nexport function buildExecutionPayload(\n issue: IssueEntry,\n provider: AgentProviderDefinition,\n plan: IssuePlan,\n workspacePath: string,\n): ExecutionPayload {\n const strategy = plan.executionStrategy;\n const hasPhases = Boolean(plan.phases?.length);\n\n return {\n version: 1,\n\n issue: {\n id: issue.id,\n identifier: issue.identifier,\n title: issue.title,\n description: issue.description || \"\",\n priority: issue.priority,\n labels: issue.labels || [],\n paths: issue.paths || [],\n },\n\n provider: {\n name: provider.provider,\n role: provider.role,\n model: provider.model || \"default\",\n effort: provider.reasoningEffort || \"medium\",\n capabilityCategory: provider.capabilityCategory || \"\",\n overlays: provider.overlays || [],\n },\n\n executionIntent: {\n complexity: plan.estimatedComplexity,\n approach: strategy?.approach || \"\",\n rationale: strategy?.whyThisApproach || \"\",\n workPattern: hasPhases\n ? \"phased\"\n : plan.toolingDecision?.shouldUseSubagents\n ? \"parallel_subtasks\"\n : \"sequential\",\n },\n\n plan: {\n summary: plan.summary,\n steps: plan.steps.map((s) => ({\n step: s.step,\n action: s.action,\n files: s.files || [],\n ownerType: s.ownerType || \"agent\",\n doneWhen: s.doneWhen || \"\",\n })),\n phases: (plan.phases || []).map((p) => ({\n name: p.phaseName,\n goal: p.goal,\n tasks: p.tasks.map((t) => t.step),\n dependencies: p.dependencies || [],\n outputs: p.outputs || [],\n })),\n },\n\n constraints: plan.constraints || [],\n successCriteria: plan.successCriteria || [],\n validation: plan.validation || [],\n deliverables: plan.deliverables || [],\n assumptions: plan.assumptions || [],\n unknowns: (plan.unknowns || []).map((u) => ({\n question: u.question,\n whyItMatters: u.whyItMatters || \"\",\n howToResolve: u.howToResolve || \"\",\n })),\n risks: (plan.risks || []).map((r) => ({\n risk: r.risk,\n impact: r.impact || \"\",\n mitigation: r.mitigation || \"\",\n })),\n\n tooling: {\n skills: plan.toolingDecision?.skillsToUse || [],\n subagents: plan.toolingDecision?.subagentsToUse || [],\n },\n\n targetPaths: plan.suggestedPaths || [],\n workspacePath,\n createdAt: new Date().toISOString(),\n };\n}\n","import type { IssueEntry, AgentProviderDefinition, RuntimeConfig, IssuePlan } from \"../types.ts\";\nimport type { CompiledExecution } from \"./index.ts\";\nimport { renderPrompt } from \"../../prompting.ts\";\nimport { buildFullPlanPrompt, resolveEffortForProvider, extractValidationCommands } from \"./shared.ts\";\nimport { buildClaudeCommand, CLAUDE_RESULT_SCHEMA } from \"./commands.ts\";\n\nexport async function compileForClaude(\n issue: IssueEntry,\n provider: AgentProviderDefinition,\n plan: IssuePlan,\n config: RuntimeConfig,\n workspacePath: string,\n skillContext: string,\n): Promise<CompiledExecution> {\n const effort = resolveEffortForProvider(plan, provider.role, config.defaultEffort);\n\n const prompt = await renderPrompt(\"compile-execution-claude\", {\n isPlanner: provider.role === \"planner\",\n isReviewer: provider.role === \"reviewer\",\n profileInstructions: provider.profileInstructions || \"\",\n skillContext,\n planPrompt: buildFullPlanPrompt(plan),\n subagentsToUse: plan.toolingDecision?.shouldUseSubagents ? (plan.toolingDecision.subagentsToUse ?? []) : [],\n skillsToUse: plan.toolingDecision?.shouldUseSkills ? (plan.toolingDecision.skillsToUse ?? []) : [],\n suggestedPaths: plan.suggestedPaths ?? [],\n workspacePath,\n issueIdentifier: issue.identifier,\n title: issue.title,\n description: issue.description || \"(none)\",\n validationItems: (plan.validation ?? []).map((value) => ({ value })),\n });\n\n const command = buildClaudeCommand({\n model: provider.model,\n jsonSchema: CLAUDE_RESULT_SCHEMA,\n });\n\n const env: Record<string, string> = {\n FIFONY_PLAN_COMPLEXITY: plan.estimatedComplexity,\n FIFONY_PLAN_STEPS: String(plan.steps.length),\n FIFONY_EXECUTION_PAYLOAD_FILE: \"fifony-execution-payload.json\",\n };\n if (plan.suggestedPaths?.length) env.FIFONY_PLAN_PATHS = plan.suggestedPaths.join(\",\");\n if (plan.toolingDecision?.skillsToUse?.length) {\n env.FIFONY_PLAN_SKILLS = plan.toolingDecision.skillsToUse.map((s) => s.name).join(\",\");\n }\n\n const { pre, post } = extractValidationCommands(plan);\n\n return {\n prompt,\n command,\n env,\n preHooks: pre,\n postHooks: post,\n outputSchema: CLAUDE_RESULT_SCHEMA,\n payload: null,\n meta: {\n adapter: \"claude\",\n reasoningEffort: effort || \"default\",\n model: provider.model || \"default\",\n skillsActivated: plan.toolingDecision?.skillsToUse?.map((s) => s.name) || [],\n subagentsRequested: plan.toolingDecision?.subagentsToUse?.map((a) => a.name) || [],\n phasesCount: plan.phases?.length || 0,\n },\n };\n}\n","import { join } from \"node:path\";\nimport type { IssueEntry, AgentProviderDefinition, RuntimeConfig, IssuePlan } from \"../types.ts\";\nimport type { CompiledExecution } from \"./index.ts\";\nimport { renderPrompt } from \"../../prompting.ts\";\nimport { buildFullPlanPrompt, resolveEffortForProvider, extractValidationCommands } from \"./shared.ts\";\nimport { buildCodexCommand, extractPlanDirs } from \"./commands.ts\";\n\n// Codex uses a textual result contract embedded in the prompt (no --json-schema flag)\nconst CODEX_RESULT_CONTRACT = `\nReturn a JSON object with this exact schema when finished:\n{\n \"status\": \"done\" | \"continue\" | \"blocked\" | \"failed\",\n \"summary\": \"one paragraph summary of what was done\",\n \"root_cause\": [\"list of root causes found\"],\n \"changes_made\": [\"list of files/changes\"],\n \"validation\": { \"commands_run\": [\"...\"], \"result\": \"pass\" | \"partial\" | \"fail\" },\n \"open_questions\": [\"...\"],\n \"followups\": [\"...\"],\n \"nextPrompt\": \"guidance for next turn if status is continue\"\n}\n`.trim();\n\nexport async function compileForCodex(\n issue: IssueEntry,\n provider: AgentProviderDefinition,\n plan: IssuePlan,\n config: RuntimeConfig,\n workspacePath: string,\n skillContext: string,\n): Promise<CompiledExecution> {\n const effort = resolveEffortForProvider(plan, provider.role, config.defaultEffort) || provider.reasoningEffort;\n\n const prompt = await renderPrompt(\"compile-execution-codex\", {\n isPlanner: provider.role === \"planner\",\n isReviewer: provider.role === \"reviewer\",\n profileInstructions: provider.profileInstructions || \"\",\n skillContext,\n issueIdentifier: issue.identifier,\n title: issue.title,\n description: issue.description || \"(none)\",\n workspacePath,\n planPrompt: buildFullPlanPrompt(plan),\n phases: (plan.phases ?? []).map((phase) => ({\n phaseName: phase.phaseName,\n goal: phase.goal,\n outputs: phase.outputs ?? [],\n })),\n suggestedPaths: plan.suggestedPaths ?? [],\n skillsToUse: plan.toolingDecision?.shouldUseSkills ? (plan.toolingDecision.skillsToUse ?? []) : [],\n validationItems: (plan.validation ?? []).map((value) => ({ value })),\n outputContract: CODEX_RESULT_CONTRACT,\n });\n\n // Resolve plan dirs to absolute paths against the workspace\n const relativeDirs = extractPlanDirs(plan);\n const absoluteDirs = relativeDirs.map((d) => join(workspacePath, d));\n\n const command = buildCodexCommand({\n model: provider.model,\n addDirs: absoluteDirs,\n reasoningEffort: effort,\n });\n\n const env: Record<string, string> = {\n FIFONY_PLAN_COMPLEXITY: plan.estimatedComplexity,\n FIFONY_PLAN_STEPS: String(plan.steps.length),\n FIFONY_PLAN_PHASES: String(plan.phases?.length || 0),\n FIFONY_EXECUTION_PAYLOAD_FILE: \"fifony-execution-payload.json\",\n };\n if (plan.suggestedPaths?.length) env.FIFONY_PLAN_PATHS = plan.suggestedPaths.join(\",\");\n\n const { pre, post } = extractValidationCommands(plan);\n\n return {\n prompt,\n command,\n env,\n preHooks: pre,\n postHooks: post,\n outputSchema: \"\",\n payload: null,\n meta: {\n adapter: \"codex\",\n reasoningEffort: effort || \"default\",\n model: provider.model || \"default\",\n skillsActivated: plan.toolingDecision?.skillsToUse?.map((s) => s.name) || [],\n subagentsRequested: [],\n phasesCount: plan.phases?.length || 0,\n },\n };\n}\n","import type {\n DetectedProvider,\n EffortConfig,\n JsonRecord,\n PipelineStageConfig,\n ReasoningEffort,\n RuntimeConfig,\n RuntimeSettingRecord,\n RuntimeSettingScope,\n RuntimeSettingSource,\n WorkflowConfig,\n} from \"./types.ts\";\nimport type { DiscoveredModel } from \"./providers.ts\";\nimport { clamp, now } from \"./helpers.ts\";\nimport { loadPersistedSettings, replacePersistedSetting } from \"./store.ts\";\nimport { getProviderDefaultCommand, normalizeAgentProvider, readCodexConfig } from \"./providers.ts\";\n\nexport const SETTING_ID_POLL_INTERVAL_MS = \"runtime.pollIntervalMs\";\nexport const SETTING_ID_WORKER_CONCURRENCY = \"runtime.workerConcurrency\";\nexport const SETTING_ID_COMMAND_TIMEOUT_MS = \"runtime.commandTimeoutMs\";\nexport const SETTING_ID_MAX_ATTEMPTS_DEFAULT = \"runtime.maxAttemptsDefault\";\nexport const SETTING_ID_MAX_TURNS = \"runtime.maxTurns\";\nexport const SETTING_ID_RETRY_DELAY_MS = \"runtime.retryDelayMs\";\nexport const SETTING_ID_STALE_IN_PROGRESS_TIMEOUT_MS = \"runtime.staleInProgressTimeoutMs\";\nexport const SETTING_ID_LOG_LINES_TAIL = \"runtime.logLinesTail\";\nexport const SETTING_ID_MAX_CONCURRENT_BY_STATE = \"runtime.maxConcurrentByState\";\nexport const SETTING_ID_AGENT_PROVIDER = \"runtime.agentProvider\";\nexport const SETTING_ID_AGENT_COMMAND = \"runtime.agentCommand\";\nexport const SETTING_ID_DEFAULT_EFFORT = \"runtime.defaultEffort\";\nexport const SETTING_ID_DETECTED_PROVIDERS = \"providers.detected\";\nexport const SETTING_ID_UI_THEME = \"ui.theme\";\nexport const SETTING_ID_UI_NOTIFICATIONS_ENABLED = \"ui.notifications.enabled\";\nexport const SETTING_ID_WORKFLOW_CONFIG = \"runtime.workflowConfig\";\n\nexport async function loadRuntimeSettings(): Promise<RuntimeSettingRecord[]> {\n return loadPersistedSettings();\n}\n\nexport const RUNTIME_CONFIG_SETTING_IDS = new Set<string>([\n SETTING_ID_POLL_INTERVAL_MS,\n SETTING_ID_WORKER_CONCURRENCY,\n SETTING_ID_COMMAND_TIMEOUT_MS,\n SETTING_ID_MAX_ATTEMPTS_DEFAULT,\n SETTING_ID_MAX_TURNS,\n SETTING_ID_RETRY_DELAY_MS,\n SETTING_ID_STALE_IN_PROGRESS_TIMEOUT_MS,\n SETTING_ID_LOG_LINES_TAIL,\n SETTING_ID_MAX_CONCURRENT_BY_STATE,\n SETTING_ID_AGENT_PROVIDER,\n SETTING_ID_AGENT_COMMAND,\n SETTING_ID_DEFAULT_EFFORT,\n]);\n\nconst VALID_REASONING_EFFORTS = new Set<ReasoningEffort>([\"low\", \"medium\", \"high\", \"extra-high\"]);\n\nfunction parseIntegerSetting(value: unknown): number | null {\n const parsed = typeof value === \"number\"\n ? value\n : Number.parseInt(String(value ?? \"\"), 10);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction sanitizeMaxConcurrentByState(value: unknown): Record<string, number> | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n\n const result: Record<string, number> = {};\n for (const [key, rawLimit] of Object.entries(value as JsonRecord)) {\n const limit = parseIntegerSetting(rawLimit);\n if (!limit || limit < 1) continue;\n const normalizedKey = key.trim().toLowerCase();\n if (!normalizedKey) continue;\n result[normalizedKey] = limit;\n }\n\n return result;\n}\n\nfunction sanitizeReasoningEffort(value: unknown): ReasoningEffort | undefined {\n return typeof value === \"string\" && VALID_REASONING_EFFORTS.has(value as ReasoningEffort)\n ? value as ReasoningEffort\n : undefined;\n}\n\nfunction sanitizeDefaultEffort(value: unknown): EffortConfig | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n\n const raw = value as JsonRecord;\n const next: EffortConfig = {};\n const keys: Array<keyof EffortConfig> = [\"default\", \"planner\", \"executor\", \"reviewer\"];\n\n for (const key of keys) {\n const effort = sanitizeReasoningEffort(raw[key]);\n if (effort) {\n next[key] = effort;\n }\n }\n\n return Object.keys(next).length > 0 ? next : {};\n}\n\nfunction buildRuntimeConfigSettings(\n config: RuntimeConfig,\n source: RuntimeSettingSource,\n): RuntimeSettingRecord[] {\n const updatedAt = now();\n return [\n { id: SETTING_ID_POLL_INTERVAL_MS, scope: \"runtime\", value: config.pollIntervalMs, source, updatedAt },\n { id: SETTING_ID_WORKER_CONCURRENCY, scope: \"runtime\", value: config.workerConcurrency, source, updatedAt },\n { id: SETTING_ID_COMMAND_TIMEOUT_MS, scope: \"runtime\", value: config.commandTimeoutMs, source, updatedAt },\n { id: SETTING_ID_MAX_ATTEMPTS_DEFAULT, scope: \"runtime\", value: config.maxAttemptsDefault, source, updatedAt },\n { id: SETTING_ID_MAX_TURNS, scope: \"runtime\", value: config.maxTurns, source, updatedAt },\n { id: SETTING_ID_RETRY_DELAY_MS, scope: \"runtime\", value: config.retryDelayMs, source, updatedAt },\n {\n id: SETTING_ID_STALE_IN_PROGRESS_TIMEOUT_MS,\n scope: \"runtime\",\n value: config.staleInProgressTimeoutMs,\n source,\n updatedAt,\n },\n { id: SETTING_ID_LOG_LINES_TAIL, scope: \"runtime\", value: config.logLinesTail, source, updatedAt },\n { id: SETTING_ID_MAX_CONCURRENT_BY_STATE, scope: \"runtime\", value: config.maxConcurrentByState, source, updatedAt },\n { id: SETTING_ID_AGENT_PROVIDER, scope: \"runtime\", value: config.agentProvider, source, updatedAt },\n { id: SETTING_ID_AGENT_COMMAND, scope: \"runtime\", value: config.agentCommand, source, updatedAt },\n { id: SETTING_ID_DEFAULT_EFFORT, scope: \"runtime\", value: config.defaultEffort, source, updatedAt },\n ];\n}\n\nexport function applyPersistedSettings(config: RuntimeConfig, settings: RuntimeSettingRecord[]): RuntimeConfig {\n let nextConfig = { ...config };\n let agentProviderOverridden = false;\n let agentCommandOverridden = false;\n\n for (const setting of settings) {\n switch (setting.id) {\n case SETTING_ID_POLL_INTERVAL_MS: {\n const parsed = parseIntegerSetting(setting.value);\n if (parsed !== null) {\n nextConfig.pollIntervalMs = clamp(parsed, 200, 10_000);\n }\n break;\n }\n case SETTING_ID_WORKER_CONCURRENCY: {\n const parsed = parseIntegerSetting(setting.value);\n if (parsed !== null) {\n nextConfig.workerConcurrency = clamp(parsed, 1, 16);\n }\n break;\n }\n case SETTING_ID_COMMAND_TIMEOUT_MS: {\n const parsed = parseIntegerSetting(setting.value);\n if (parsed !== null) {\n nextConfig.commandTimeoutMs = clamp(parsed, 1_000, 3_600_000);\n }\n break;\n }\n case SETTING_ID_MAX_ATTEMPTS_DEFAULT: {\n const parsed = parseIntegerSetting(setting.value);\n if (parsed !== null) {\n nextConfig.maxAttemptsDefault = clamp(parsed, 1, 10);\n }\n break;\n }\n case SETTING_ID_MAX_TURNS: {\n const parsed = parseIntegerSetting(setting.value);\n if (parsed !== null) {\n nextConfig.maxTurns = clamp(parsed, 1, 16);\n }\n break;\n }\n case SETTING_ID_RETRY_DELAY_MS: {\n const parsed = parseIntegerSetting(setting.value);\n if (parsed !== null) {\n nextConfig.retryDelayMs = Math.max(0, parsed);\n }\n break;\n }\n case SETTING_ID_STALE_IN_PROGRESS_TIMEOUT_MS: {\n const parsed = parseIntegerSetting(setting.value);\n if (parsed !== null) {\n nextConfig.staleInProgressTimeoutMs = Math.max(0, parsed);\n }\n break;\n }\n case SETTING_ID_LOG_LINES_TAIL: {\n const parsed = parseIntegerSetting(setting.value);\n if (parsed !== null) {\n nextConfig.logLinesTail = clamp(parsed, 1_000, 200_000);\n }\n break;\n }\n case SETTING_ID_MAX_CONCURRENT_BY_STATE: {\n const parsed = sanitizeMaxConcurrentByState(setting.value);\n if (parsed) {\n nextConfig.maxConcurrentByState = parsed;\n }\n break;\n }\n case SETTING_ID_AGENT_PROVIDER: {\n if (typeof setting.value === \"string\") {\n nextConfig.agentProvider = normalizeAgentProvider(setting.value);\n agentProviderOverridden = true;\n }\n break;\n }\n case SETTING_ID_AGENT_COMMAND: {\n nextConfig.agentCommand = typeof setting.value === \"string\" ? setting.value.trim() : \"\";\n agentCommandOverridden = true;\n break;\n }\n case SETTING_ID_DEFAULT_EFFORT: {\n const parsed = sanitizeDefaultEffort(setting.value);\n if (parsed) {\n nextConfig.defaultEffort = parsed;\n }\n break;\n }\n default:\n break;\n }\n }\n\n if (agentProviderOverridden && !agentCommandOverridden) {\n nextConfig.agentCommand = getProviderDefaultCommand(\n nextConfig.agentProvider,\n nextConfig.defaultEffort?.default,\n );\n }\n\n return nextConfig;\n}\n\nexport function inferSettingScope(settingId: string): RuntimeSettingScope {\n if (settingId.startsWith(\"runtime.\")) return \"runtime\";\n if (settingId.startsWith(\"providers.\")) return \"providers\";\n if (settingId.startsWith(\"ui.\")) return \"ui\";\n return \"system\";\n}\n\nexport async function persistSetting(\n id: string,\n value: unknown,\n options: {\n scope?: RuntimeSettingScope;\n source?: RuntimeSettingSource;\n } = {},\n): Promise<RuntimeSettingRecord> {\n const setting: RuntimeSettingRecord = {\n id,\n scope: options.scope ?? inferSettingScope(id),\n value,\n source: options.source ?? \"user\",\n updatedAt: now(),\n };\n await replacePersistedSetting(setting);\n return setting;\n}\n\nexport async function persistWorkerConcurrencySetting(value: number, source: RuntimeSettingRecord[\"source\"] = \"user\"): Promise<void> {\n await persistSetting(\n SETTING_ID_WORKER_CONCURRENCY,\n clamp(Math.round(value), 1, 16),\n { scope: \"runtime\", source },\n );\n}\n\nexport async function persistDetectedProvidersSetting(providers: DetectedProvider[]): Promise<void> {\n await persistSetting(\n SETTING_ID_DETECTED_PROVIDERS,\n {\n providers,\n detectedAt: now(),\n },\n { scope: \"providers\", source: \"detected\" },\n );\n}\n\nexport async function syncRuntimeConfigSettings(\n config: RuntimeConfig,\n settings: RuntimeSettingRecord[],\n): Promise<void> {\n const existingById = new Map(settings.map((setting) => [setting.id, setting]));\n const desiredSettings = buildRuntimeConfigSettings(config, \"system\");\n\n await Promise.all(\n desiredSettings.map(async (setting) => {\n const existing = existingById.get(setting.id);\n if (existing?.source === \"user\") return;\n await replacePersistedSetting({\n ...setting,\n source: existing?.source === \"workflow\" ? \"workflow\" : \"system\",\n });\n }),\n );\n}\n\n// ── Workflow Config (pipeline stage configuration) ────────────────────────\n\nfunction isValidStage(v: unknown): v is PipelineStageConfig {\n if (!v || typeof v !== \"object\") return false;\n const s = v as Record<string, unknown>;\n // model is optional — empty string means \"use CLI default\"\n return typeof s.provider === \"string\" && typeof s.effort === \"string\";\n}\n\n/**\n * Build a default workflow config using discovered models.\n * Never hardcodes model IDs — always uses the first model from each provider's discovery.\n * Falls back to provider name as model if discovery returned nothing.\n */\nexport function buildDefaultWorkflowConfig(\n detectedProviders: DetectedProvider[],\n discoveredModels?: Record<string, DiscoveredModel[]>,\n): WorkflowConfig {\n const available = detectedProviders.filter((p) => p.available);\n const hasClaude = available.some((p) => p.name === \"claude\");\n const hasCodex = available.some((p) => p.name === \"codex\");\n\n // Pick the first discovered model per provider (discoverModels promotes the user's configured CLI default to [0])\n const claudeModel = discoveredModels?.claude?.[0]?.id || \"\";\n const codexModel = discoveredModels?.codex?.[0]?.id || \"\";\n\n // Use the effort the user already configured in ~/.codex/config.toml as the execute default\n const codexEffort = (readCodexConfig().reasoningEffort as ReasoningEffort | undefined) || \"medium\";\n\n const claudeDefault: PipelineStageConfig = { provider: \"claude\", model: claudeModel, effort: \"medium\" };\n const codexDefault: PipelineStageConfig = { provider: \"codex\", model: codexModel, effort: codexEffort };\n\n // Default: claude for plan+review (better reasoning), codex for execute (better code)\n if (hasClaude && hasCodex) {\n return {\n plan: { ...claudeDefault, effort: \"high\" },\n execute: { ...codexDefault },\n review: { ...claudeDefault },\n };\n }\n if (hasClaude) {\n return { plan: { ...claudeDefault, effort: \"high\" }, execute: claudeDefault, review: claudeDefault };\n }\n if (hasCodex) {\n return { plan: { ...codexDefault, effort: \"high\" }, execute: codexDefault, review: codexDefault };\n }\n return { plan: claudeDefault, execute: codexDefault, review: claudeDefault };\n}\n\n/** Load workflow config from settings */\nexport function getWorkflowConfig(settings: RuntimeSettingRecord[]): WorkflowConfig | null {\n const setting = settings.find((s) => s.id === SETTING_ID_WORKFLOW_CONFIG);\n if (!setting?.value || typeof setting.value !== \"object\") return null;\n const wf = setting.value as Record<string, unknown>;\n if (isValidStage(wf.plan) && isValidStage(wf.execute) && isValidStage(wf.review)) {\n return wf as unknown as WorkflowConfig;\n }\n return null;\n}\n\n/** Persist workflow config */\nexport async function persistWorkflowConfig(config: WorkflowConfig): Promise<void> {\n await persistSetting(SETTING_ID_WORKFLOW_CONFIG, config, { scope: \"runtime\", source: \"user\" });\n}\n","import { S3DB_ISSUE_RESOURCE } from \"../constants.ts\";\nimport type { JsonRecord, RuntimeState } from \"../types.ts\";\nimport { TERMINAL_STATES } from \"../constants.ts\";\nimport { loadAgentPipelineSnapshotForIssue, loadAgentSessionSnapshotsForIssue } from \"../agent.ts\";\nimport { getApiRuntimeContextOrThrow } from \"../api-runtime-context.ts\";\nimport { persistState } from \"../store.ts\";\nimport { getEffectiveAgentProviders } from \"../providers.ts\";\nimport { addEvent, createIssueFromPayload, handleStatePatch, transitionIssueState } from \"../issues.ts\";\nimport { now } from \"../helpers.ts\";\n\nfunction getIssueId(c: unknown): string | null {\n if (!c || typeof c !== \"object\" || !(\"req\" in c) || !c.req || typeof (c as { req: unknown }).req !== \"object\") {\n return null;\n }\n const req = (c as { req: { param: (name: string) => unknown } }).req;\n const value = req.param(\"id\");\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n return trimmed ? trimmed : null;\n}\n\nfunction findIssue(state: RuntimeState, issueId: string) {\n return state.issues.find((issue) => issue.id === issueId || issue.identifier === issueId);\n}\n\nasync function getIssuePipeline(c: unknown) {\n const context = getApiRuntimeContextOrThrow();\n const issueId = getIssueId(c);\n if (!issueId) {\n return { status: 400, body: { ok: false, error: \"Issue id is required.\" } };\n }\n\n const issue = findIssue(context.state, issueId);\n if (!issue) {\n return { status: 404, body: { ok: false, error: \"Issue not found\" } };\n }\n\n const providers = getEffectiveAgentProviders(context.state, issue, context.workflowDefinition);\n const pipeline = await loadAgentPipelineSnapshotForIssue(issue, providers);\n return { body: { ok: true, issueId: issue.id, pipeline } };\n}\n\nasync function getIssueSessions(c: unknown) {\n const context = getApiRuntimeContextOrThrow();\n const issueId = getIssueId(c);\n if (!issueId) {\n return { status: 400, body: { ok: false, error: \"Issue id is required.\" } };\n }\n\n const issue = findIssue(context.state, issueId);\n if (!issue) {\n return { status: 404, body: { ok: false, error: \"Issue not found\" } };\n }\n\n const providers = getEffectiveAgentProviders(context.state, issue, context.workflowDefinition);\n const pipeline = await loadAgentPipelineSnapshotForIssue(issue, providers);\n const sessions = await loadAgentSessionSnapshotsForIssue(issue, providers, pipeline, context.workflowDefinition);\n return { body: { ok: true, issueId: issue.id, pipeline, sessions } };\n}\n\nasync function patchIssueState(c: unknown) {\n const context = getApiRuntimeContextOrThrow();\n const issueId = getIssueId(c);\n if (!issueId) {\n return { status: 400, body: { ok: false, error: \"Issue id is required.\" } };\n }\n\n const issue = findIssue(context.state, issueId);\n if (!issue) {\n return { status: 404, body: { ok: false, error: \"Issue not found\" } };\n }\n\n try {\n const payload = await (c as { req: { json: () => Promise<unknown> } }).req.json() as JsonRecord;\n await handleStatePatch(context.state, issue, payload);\n await persistState(context.state);\n return { body: { ok: true, issue } };\n } catch (error) {\n return { status: 400, body: { ok: false, error: error instanceof Error ? error.message : String(error) } };\n }\n}\n\nasync function retryIssue(c: unknown) {\n const context = getApiRuntimeContextOrThrow();\n const issueId = getIssueId(c);\n if (!issueId) {\n return { status: 400, body: { ok: false, error: \"Issue id is required.\" } };\n }\n\n const issue = findIssue(context.state, issueId);\n if (!issue) {\n return { status: 404, body: { ok: false, error: \"Issue not found\" } };\n }\n\n if (TERMINAL_STATES.has(issue.state)) {\n issue.lastError = undefined;\n issue.nextRetryAt = undefined;\n await transitionIssueState(issue, \"Todo\", \"Manual retry requested.\");\n } else {\n issue.nextRetryAt = undefined;\n issue.lastError = undefined;\n issue.updatedAt = now();\n }\n\n addEvent(context.state, issue.id, \"manual\", `Manual retry requested for ${issue.id}.`);\n await persistState(context.state);\n return { body: { ok: true, issue } };\n}\n\nasync function createIssue(c: unknown) {\n const context = getApiRuntimeContextOrThrow();\n try {\n const payload = await (c as { req: { json: () => Promise<unknown> } }).req.json() as JsonRecord;\n const issue = createIssueFromPayload(payload, context.state.issues, context.workflowDefinition);\n context.state.issues.push(issue);\n addEvent(context.state, issue.id, \"info\", `Issue ${issue.identifier} created via API.`);\n await persistState(context.state);\n return { body: { ok: true, issue } };\n } catch (error) {\n return { status: 400, body: { ok: false, error: error instanceof Error ? error.message : String(error) } };\n }\n}\n\nasync function cancelIssue(c: unknown) {\n const context = getApiRuntimeContextOrThrow();\n const issueId = getIssueId(c);\n if (!issueId) {\n return { status: 400, body: { ok: false, error: \"Issue id is required.\" } };\n }\n\n const issue = findIssue(context.state, issueId);\n if (!issue) {\n return { status: 404, body: { ok: false, error: \"Issue not found\" } };\n }\n\n await transitionIssueState(issue, \"Cancelled\", \"Manual cancel requested.\");\n addEvent(context.state, issue.id, \"manual\", `Manual cancel requested for ${issue.id}.`);\n await persistState(context.state);\n return { body: { ok: true, issue } };\n}\n\nexport default {\n name: S3DB_ISSUE_RESOURCE,\n attributes: {\n id: \"string|required\",\n identifier: \"string|required\",\n title: \"string|required\",\n description: \"string|optional\",\n priority: \"number|required\",\n state: \"string|required\",\n branchName: \"string|optional\",\n url: \"string|optional\",\n assigneeId: \"string|optional\",\n labels: \"json|required\",\n paths: \"json|optional\",\n inferredPaths: \"json|optional\",\n capabilityCategory: \"string|optional\",\n capabilityOverlays: \"json|optional\",\n capabilityRationale: \"json|optional\",\n blockedBy: \"json|required\",\n assignedToWorker: \"boolean|required\",\n createdAt: \"datetime|required\",\n updatedAt: \"datetime|required\",\n history: \"json|required\",\n startedAt: \"datetime|optional\",\n completedAt: \"datetime|optional\",\n attempts: \"number|required\",\n maxAttempts: \"number|required\",\n nextRetryAt: \"datetime|optional\",\n workspacePath: \"string|optional\",\n workspacePreparedAt: \"datetime|optional\",\n lastError: \"string|optional\",\n durationMs: \"number|optional\",\n commandExitCode: \"number|optional\",\n commandOutputTail: \"string|optional\",\n terminalWeek: \"string|optional\",\n usage: \"json|optional\",\n tokenUsage: \"json|optional\",\n tokensByPhase: \"json|optional\",\n tokensByModel: \"json|optional\",\n plan: \"json|optional\",\n planningStatus: \"string|optional\",\n planningStartedAt: \"datetime|optional\",\n planningError: \"string|optional\",\n linesAdded: \"number|optional\",\n linesRemoved: \"number|optional\",\n filesChanged: \"number|optional\",\n effort: \"json|optional\",\n },\n partitions: {\n byState: { fields: { state: \"string\" } },\n byCapabilityCategory: { fields: { capabilityCategory: \"string\" } },\n byStateAndCapability: {\n fields: { state: \"string\", capabilityCategory: \"string\" },\n },\n byTerminalWeek: { fields: { terminalWeek: \"string\" } },\n },\n asyncPartitions: true,\n behavior: \"body-overflow\",\n paranoid: false,\n timestamps: true,\n api: {\n auth: false,\n methods: [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"HEAD\", \"OPTIONS\"],\n description: \"Issue registry for orchestration runtime\",\n \"POST /create\": async (c: unknown) => {\n const result = await createIssue(c);\n if (result.status) {\n return c.json(result.body, result.status);\n }\n return c.json(result.body, 201);\n },\n \"POST /\": async (c: unknown) => {\n const result = await createIssue(c);\n if (result.status) {\n return c.json(result.body, result.status);\n }\n return c.json(result.body, 201);\n },\n \"GET /:id/pipeline\": async (c: unknown) => {\n const result = await getIssuePipeline(c);\n if (result.status) {\n return c.json(result.body, result.status);\n }\n return result.body;\n },\n \"GET /:id/sessions\": async (c: unknown) => {\n const result = await getIssueSessions(c);\n if (result.status) {\n return c.json(result.body, result.status);\n }\n return result.body;\n },\n \"POST /:id/state\": async (c: unknown) => {\n const result = await patchIssueState(c);\n if (result.status) {\n return c.json(result.body, result.status);\n }\n return result.body;\n },\n \"POST /:id/retry\": async (c: unknown) => {\n const result = await retryIssue(c);\n if (result.status) {\n return c.json(result.body, result.status);\n }\n return result.body;\n },\n \"POST /:id/cancel\": async (c: unknown) => {\n const result = await cancelIssue(c);\n if (result.status) {\n return c.json(result.body, result.status);\n }\n return result.body;\n },\n },\n};\n","import { S3DB_EVENT_RESOURCE } from \"../constants.ts\";\n\nexport default {\n name: S3DB_EVENT_RESOURCE,\n attributes: {\n id: \"string|required\",\n issueId: \"string|optional\",\n kind: \"string|required\",\n message: \"string|required\",\n at: \"datetime|required\",\n },\n partitions: {\n byIssueId: { fields: { issueId: \"string\" } },\n byKind: { fields: { kind: \"string\" } },\n byIssueIdAndKind: { fields: { issueId: \"string\", kind: \"string\" } },\n },\n asyncPartitions: true,\n behavior: \"body-overflow\",\n paranoid: false,\n timestamps: false,\n api: {\n auth: false,\n methods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n description: \"Runtime event log entries\",\n },\n};\n","import { S3DB_SETTINGS_RESOURCE } from \"../constants.ts\";\n\nexport default {\n name: S3DB_SETTINGS_RESOURCE,\n attributes: {\n id: \"string|required\",\n scope: \"string|required\",\n value: \"json|required\",\n source: \"string|required\",\n updatedAt: \"datetime|required\",\n },\n partitions: {\n byScope: { fields: { scope: \"string\" } },\n },\n asyncPartitions: true,\n behavior: \"body-overflow\",\n paranoid: false,\n timestamps: false,\n api: {\n enabled: false,\n },\n};\n","import { S3DB_AGENT_SESSION_RESOURCE } from \"../constants.ts\";\n\nexport default {\n name: S3DB_AGENT_SESSION_RESOURCE,\n attributes: {\n id: \"string|required\",\n issueId: \"string|required\",\n issueIdentifier: \"string|required\",\n attempt: \"number|required\",\n cycle: \"number|required\",\n provider: \"string|required\",\n role: \"string|required\",\n updatedAt: \"datetime|required\",\n session: \"json|required\",\n },\n partitions: {\n byIssueId: { fields: { issueId: \"string\" } },\n byIssueAttempt: { fields: { issueId: \"string\", attempt: \"number\" } },\n byProviderRole: { fields: { provider: \"string\", role: \"string\" } },\n },\n asyncPartitions: true,\n behavior: \"body-overflow\",\n paranoid: false,\n timestamps: false,\n api: {\n auth: false,\n methods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n description: \"Agent session snapshots per attempt\",\n },\n};\n","import { S3DB_AGENT_PIPELINE_RESOURCE } from \"../constants.ts\";\n\nexport default {\n name: S3DB_AGENT_PIPELINE_RESOURCE,\n attributes: {\n id: \"string|required\",\n issueId: \"string|required\",\n issueIdentifier: \"string|required\",\n attempt: \"number|required\",\n updatedAt: \"datetime|required\",\n pipeline: \"json|required\",\n },\n partitions: {\n byIssueId: { fields: { issueId: \"string\" } },\n byIssueAttempt: { fields: { issueId: \"string\", attempt: \"number\" } },\n },\n asyncPartitions: true,\n behavior: \"body-overflow\",\n paranoid: false,\n timestamps: false,\n api: {\n auth: false,\n methods: [\"GET\", \"HEAD\", \"OPTIONS\"],\n description: \"Agent pipeline snapshots per attempt\",\n },\n};\n","import runtimeStateResource from \"./runtime-state.resource.ts\";\nimport issuesResource from \"./issues.resource.ts\";\nimport eventsResource from \"./events.resource.ts\";\nimport settingsResource from \"./settings.resource.ts\";\nimport agentSessionsResource from \"./agent-sessions.resource.ts\";\nimport agentPipelinesResource from \"./agent-pipelines.resource.ts\";\n\nexport const NATIVE_RESOURCE_CONFIGS = [\n runtimeStateResource,\n issuesResource,\n eventsResource,\n settingsResource,\n agentSessionsResource,\n agentPipelinesResource,\n] as const;\n\nexport const NATIVE_RESOURCE_NAMES = NATIVE_RESOURCE_CONFIGS.map((resource) => resource.name);\n","import { execSync } from \"node:child_process\";\nimport { existsSync, readFileSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { env } from \"node:process\";\nimport { logger } from \"./logger.ts\";\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\ninterface ModelInfo {\n slug: string;\n displayName: string;\n description: string;\n}\n\ninterface UsagePeriod {\n inputTokens: number;\n outputTokens: number;\n tokensUsed: number;\n sessions: number;\n since: string;\n}\n\ninterface ProviderUsage {\n name: string;\n available: boolean;\n models: ModelInfo[];\n currentModel: string;\n usage: {\n today: UsagePeriod;\n thisWeek: UsagePeriod;\n allTime: UsagePeriod;\n };\n resetInfo: string;\n nextResetAt: string;\n weeklyLimitEstimate: number | null;\n percentUsed: number | null;\n}\n\ninterface ProvidersUsageResult {\n providers: ProviderUsage[];\n collectedAt: string;\n}\n\nfunction resolveCodexHomeCandidates(): string[] {\n const homePaths = new Set<string>([\n homedir(),\n env.XDG_STATE_HOME?.trim() || \"\",\n env.XDG_DATA_HOME?.trim() || \"\",\n ]);\n\n const sudoUser = env.SUDO_USER?.trim();\n if (sudoUser && sudoUser !== \"root\") {\n homePaths.add(`/home/${sudoUser}`);\n }\n\n const direct = new Set<string>([\n env.CODEX_HOME?.trim() || \"\",\n ]);\n\n const candidates = [...homePaths, ...direct]\n .filter(Boolean)\n .flatMap((candidate) => {\n if (candidate.endsWith(\"/.codex\") || candidate.endsWith(\"/codex\")) return [candidate];\n return [join(candidate, \".codex\"), join(candidate, \"codex\")];\n });\n\n return [...new Set(candidates)];\n}\n\nfunction resolveCodexDir(): string | null {\n for (const candidate of resolveCodexHomeCandidates()) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n return null;\n}\n\nfunction findLatestCodexDb(codexDir: string): string | null {\n const explicit = join(codexDir, \"state_5.sqlite\");\n if (existsSync(explicit)) return explicit;\n\n const candidates = readdirSync(codexDir)\n .filter((name) => name.startsWith(\"state_\") && name.endsWith(\".sqlite\"))\n .sort()\n .reverse();\n\n if (candidates.length === 0) return null;\n return join(codexDir, candidates[0]);\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction computeNextMonday(): Date {\n const now = new Date();\n const utcDay = now.getUTCDay();\n const daysUntilMonday = utcDay === 0 ? 1 : utcDay === 1 ? 7 : 8 - utcDay;\n const next = new Date(now);\n next.setUTCDate(next.getUTCDate() + daysUntilMonday);\n next.setUTCHours(0, 0, 0, 0);\n return next;\n}\n\nfunction computeWeekStart(): Date {\n const d = new Date();\n d.setUTCHours(0, 0, 0, 0);\n const utcDay = d.getUTCDay();\n const daysFromMonday = utcDay === 0 ? 6 : utcDay - 1;\n d.setUTCDate(d.getUTCDate() - daysFromMonday);\n return d;\n}\n\nfunction computeTodayStart(): Date {\n const d = new Date();\n d.setUTCHours(0, 0, 0, 0);\n return d;\n}\n\nfunction makePeriod(input: number, output: number, sessions: number, since: string): UsagePeriod {\n return { inputTokens: input, outputTokens: output, tokensUsed: input + output, sessions, since };\n}\n\n// Known weekly token limits per plan (approximate, based on public info)\nconst CLAUDE_PLAN_LIMITS: Record<string, number> = {\n pro: 45_000_000, // ~45M tokens/week (Pro plan estimate)\n max: 135_000_000, // ~135M tokens/week (Max plan)\n max5x: 675_000_000, // ~675M tokens/week (Max 5x plan)\n};\n\n// ── Claude usage (from JSONL session files) ──────────────────────────────────\n\nfunction collectClaudeUsage(): ProviderUsage | null {\n const home = homedir();\n const claudeDir = join(home, \".claude\");\n if (!existsSync(claudeDir)) return null;\n\n // Check if Claude CLI is available\n let available = false;\n try {\n execSync(\"which claude\", { encoding: \"utf8\", timeout: 3000 });\n available = true;\n } catch {}\n\n // Aggregate token usage from all project session files\n const projectsDir = join(claudeDir, \"projects\");\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let totalSessions = 0;\n let todayInputTokens = 0;\n let todayOutputTokens = 0;\n let todaySessions = 0;\n let weekInputTokens = 0;\n let weekOutputTokens = 0;\n let weekSessions = 0;\n\n const todayStart = computeTodayStart();\n const todayMs = todayStart.getTime();\n const weekStart = computeWeekStart();\n const weekMs = weekStart.getTime();\n\n if (existsSync(projectsDir)) {\n try {\n const projectDirs = readdirSync(projectsDir, { withFileTypes: true });\n for (const dir of projectDirs) {\n if (!dir.isDirectory()) continue;\n const projectPath = join(projectsDir, dir.name);\n\n let sessionFiles: string[];\n try {\n sessionFiles = readdirSync(projectPath)\n .filter((f) => f.endsWith(\".jsonl\"));\n } catch {\n continue;\n }\n\n for (const file of sessionFiles) {\n const filePath = join(projectPath, file);\n let content: string;\n try {\n content = readFileSync(filePath, \"utf8\");\n } catch {\n continue;\n }\n\n let sessionCounted = false;\n let sessionTodayCounted = false;\n let sessionWeekCounted = false;\n\n for (const line of content.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n const entry = JSON.parse(line);\n if (entry.type !== \"assistant\" || !entry.message?.usage) continue;\n\n const usage = entry.message.usage;\n // Only count actual billed tokens — cache reads are free/cheap\n const inputTokens = (usage.input_tokens || 0) +\n (usage.cache_creation_input_tokens || 0);\n const outputTokens = usage.output_tokens || 0;\n\n totalInputTokens += inputTokens;\n totalOutputTokens += outputTokens;\n if (!sessionCounted) {\n totalSessions++;\n sessionCounted = true;\n }\n\n const timestamp = entry.timestamp ? new Date(entry.timestamp).getTime() : 0;\n\n if (timestamp >= todayMs) {\n todayInputTokens += inputTokens;\n todayOutputTokens += outputTokens;\n if (!sessionTodayCounted) {\n todaySessions++;\n sessionTodayCounted = true;\n }\n }\n\n if (timestamp >= weekMs) {\n weekInputTokens += inputTokens;\n weekOutputTokens += outputTokens;\n if (!sessionWeekCounted) {\n weekSessions++;\n sessionWeekCounted = true;\n }\n }\n } catch {}\n }\n }\n }\n } catch (err) {\n logger.debug(`Failed to read Claude session files: ${String(err)}`);\n }\n }\n\n // Claude models (known models for Claude Code)\n const models: ModelInfo[] = [\n { slug: \"claude-opus-4-6\", displayName: \"Claude Opus 4.6\", description: \"Most capable model for complex tasks\" },\n { slug: \"claude-sonnet-4-6\", displayName: \"Claude Sonnet 4.6\", description: \"Balanced performance and speed\" },\n { slug: \"claude-haiku-4-5\", displayName: \"Claude Haiku 4.5\", description: \"Fast and efficient model\" },\n ];\n\n // Detect subscription type from settings\n let plan = \"pro\";\n let resetInfo = \"Weekly reset (every Monday 00:00 UTC)\";\n const settingsPath = join(claudeDir, \"settings.json\");\n if (existsSync(settingsPath)) {\n try {\n const settings = JSON.parse(readFileSync(settingsPath, \"utf8\"));\n if (settings.plan === \"max\" || settings.plan === \"max5x\") {\n plan = settings.plan;\n resetInfo = `Plan: ${settings.plan.toUpperCase()} — Weekly token limit resets every Monday 00:00 UTC`;\n }\n } catch {}\n }\n\n const nextResetAt = computeNextMonday().toISOString();\n const weeklyLimit = CLAUDE_PLAN_LIMITS[plan] ?? null;\n const weeklyUsed = weekInputTokens + weekOutputTokens;\n const percentUsed = weeklyLimit ? Math.min(100, Math.round((weeklyUsed / weeklyLimit) * 100)) : null;\n\n return {\n name: \"claude\",\n available,\n models,\n currentModel: \"claude-opus-4-6\",\n usage: {\n today: makePeriod(todayInputTokens, todayOutputTokens, todaySessions, todayStart.toISOString()),\n thisWeek: makePeriod(weekInputTokens, weekOutputTokens, weekSessions, weekStart.toISOString()),\n allTime: makePeriod(totalInputTokens, totalOutputTokens, totalSessions, \"\"),\n },\n resetInfo,\n nextResetAt,\n weeklyLimitEstimate: weeklyLimit,\n percentUsed,\n };\n}\n\n// ── Codex usage (from SQLite state DB) ───────────────────────────────────────\n\nfunction collectCodexUsage(): ProviderUsage | null {\n const codexDir = resolveCodexDir();\n if (!codexDir) return null;\n\n let available = false;\n try {\n execSync(\"which codex\", { encoding: \"utf8\", timeout: 3000 });\n available = true;\n } catch {}\n\n // Read models from cache\n const models: ModelInfo[] = [];\n const modelsCachePath = join(codexDir, \"models_cache.json\");\n let currentModel = \"\";\n\n if (existsSync(modelsCachePath)) {\n try {\n const cache = JSON.parse(readFileSync(modelsCachePath, \"utf8\"));\n for (const m of cache.models || []) {\n models.push({\n slug: m.slug,\n displayName: m.display_name || m.slug,\n description: (m.description || \"\").slice(0, 80),\n });\n }\n } catch {}\n }\n\n // Read current model from config\n const configPath = join(codexDir, \"config.toml\");\n if (existsSync(configPath)) {\n try {\n const configContent = readFileSync(configPath, \"utf8\");\n const modelMatch = configContent.match(/^model\\s*=\\s*\"([^\"]+)\"/m);\n if (modelMatch) currentModel = modelMatch[1];\n } catch {}\n }\n\n const todayStart = computeTodayStart();\n const weekStart = computeWeekStart();\n const nextResetAt = computeNextMonday().toISOString();\n\n // Find the right SQLite file\n const dbPath = findLatestCodexDb(codexDir);\n if (!dbPath) {\n return {\n name: \"codex\",\n available,\n models,\n currentModel,\n usage: {\n today: makePeriod(0, 0, 0, todayStart.toISOString()),\n thisWeek: makePeriod(0, 0, 0, weekStart.toISOString()),\n allTime: makePeriod(0, 0, 0, \"\"),\n },\n resetInfo: \"Weekly rate limit resets every Monday\",\n nextResetAt,\n weeklyLimitEstimate: null,\n percentUsed: null,\n };\n }\n\n let allTimeTokens = 0;\n let allTimeSessions = 0;\n let todayTokens = 0;\n let todaySessions = 0;\n let weekTokens = 0;\n let weekSessions = 0;\n\n const todayUnix = Math.floor(todayStart.getTime() / 1000);\n const weekUnix = Math.floor(weekStart.getTime() / 1000);\n\n try {\n const query = `\n SELECT\n SUM(tokens_used) as total_tokens,\n COUNT(*) as total_sessions,\n SUM(CASE WHEN created_at >= ${todayUnix} THEN tokens_used ELSE 0 END) as today_tokens,\n SUM(CASE WHEN created_at >= ${todayUnix} THEN 1 ELSE 0 END) as today_sessions,\n SUM(CASE WHEN created_at >= ${weekUnix} THEN tokens_used ELSE 0 END) as week_tokens,\n SUM(CASE WHEN created_at >= ${weekUnix} THEN 1 ELSE 0 END) as week_sessions\n FROM threads;\n `;\n const result = execSync(`sqlite3 \"${dbPath}\" \"${query}\"`, {\n encoding: \"utf8\",\n timeout: 5000,\n }).trim();\n\n if (result) {\n const parts = result.split(\"|\");\n allTimeTokens = parseInt(parts[0], 10) || 0;\n allTimeSessions = parseInt(parts[1], 10) || 0;\n todayTokens = parseInt(parts[2], 10) || 0;\n todaySessions = parseInt(parts[3], 10) || 0;\n weekTokens = parseInt(parts[4], 10) || 0;\n weekSessions = parseInt(parts[5], 10) || 0;\n }\n } catch (err) {\n logger.debug(`Failed to query Codex SQLite: ${String(err)}`);\n }\n\n // Codex doesn't expose input/output split from SQLite, report all as input\n return {\n name: \"codex\",\n available,\n models,\n currentModel,\n usage: {\n today: makePeriod(todayTokens, 0, todaySessions, todayStart.toISOString()),\n thisWeek: makePeriod(weekTokens, 0, weekSessions, weekStart.toISOString()),\n allTime: makePeriod(allTimeTokens, 0, allTimeSessions, \"\"),\n },\n resetInfo: \"Weekly rate limit resets every Monday\",\n nextResetAt,\n weeklyLimitEstimate: null,\n percentUsed: null,\n };\n}\n\n// ── Public API ───────────────────────────────────────────────────────────────\n\nexport function collectProvidersUsage(): ProvidersUsageResult {\n const providers: ProviderUsage[] = [];\n\n const claude = collectClaudeUsage();\n if (claude) providers.push(claude);\n\n const codex = collectCodexUsage();\n if (codex) providers.push(codex);\n\n return {\n providers,\n collectedAt: new Date().toISOString(),\n };\n}\n","import type {\n IssueEntry,\n JsonRecord,\n ParallelismAnalysis,\n RuntimeState,\n WorkflowDefinition,\n} from \"./types.ts\";\nimport { EXECUTING_STATES, TERMINAL_STATES } from \"./constants.ts\";\nimport { now, sleep, normalizeState, toStringValue } from \"./helpers.ts\";\nimport { logger } from \"./logger.ts\";\nimport { persistState } from \"./store.ts\";\nimport { hasDirtyState, markIssueDirty } from \"./dirty-tracker.ts\";\nimport { detectAvailableProviders, resolveDefaultProvider, getProviderDefaultCommand } from \"./providers.ts\";\nimport {\n addEvent,\n computeMetrics,\n getNextRetryAt,\n issueDependenciesResolved,\n transitionIssueState,\n} from \"./issues.ts\";\nimport {\n getIssueCapabilityPriority,\n} from \"./providers.ts\";\nimport { canRunIssue, issueHasResumableSession, runIssueOnce, isAgentStillRunning } from \"./agent.ts\";\n\nlet shuttingDown = false;\nlet lastPersistAt = 0;\nconst PERSIST_DEBOUNCE_MS = 5000;\n\n// ── Wake signal ─────────────────────────────────────────────────────────────\nlet schedulerWakeResolve: (() => void) | null = null;\n\nexport function wakeScheduler(): void {\n schedulerWakeResolve?.();\n}\n\n// ── Adaptive polling ────────────────────────────────────────────────────────\nconst IDLE_POLL_MS = 5000;\nconst ACTIVE_POLL_MS = 500;\n\nexport function isShuttingDown(): boolean {\n return shuttingDown;\n}\n\nexport function installGracefulShutdown(\n state: RuntimeState,\n running: Set<string>,\n): void {\n const handler = async (signal: string) => {\n if (shuttingDown) {\n logger.warn(`Received ${signal} again, forcing exit.`);\n process.exit(1);\n }\n shuttingDown = true;\n logger.info(`Received ${signal}, shutting down gracefully...`);\n addEvent(state, undefined, \"info\", `Graceful shutdown initiated (${signal}).`);\n\n // Mark running issues as Interrupted so they resume on next boot\n for (const issue of state.issues) {\n if (running.has(issue.id) && (issue.state === \"Running\" || issue.state === \"In Review\")) {\n try {\n await transitionIssueState(issue, \"Interrupted\", `Interrupted by ${signal} — will resume on next start.`, { fallbackToLocal: true });\n } catch {\n // Issue may already be in a terminal state; proceed with shutdown regardless\n logger.warn(`Could not transition issue ${issue.identifier} to Interrupted during shutdown.`);\n }\n addEvent(state, issue.id, \"info\", `Issue ${issue.identifier} interrupted by shutdown.`);\n }\n }\n\n state.updatedAt = now();\n state.metrics = computeMetrics(state.issues);\n try {\n await persistState(state);\n logger.info(\"State persisted.\");\n } catch (error) {\n logger.error(`Failed to persist state during shutdown: ${String(error)}`);\n }\n logger.info(\"Goodbye.\");\n process.exit(0);\n };\n\n process.on(\"SIGINT\", () => handler(\"SIGINT\"));\n process.on(\"SIGTERM\", () => handler(\"SIGTERM\"));\n}\n\nexport function analyzeParallelizability(issues: IssueEntry[]): ParallelismAnalysis {\n const todo = issues.filter((issue) =>\n issue.state === \"Todo\"\n && issue.assignedToWorker\n && issue.blockedBy.length === 0,\n );\n\n if (todo.length === 0) {\n return {\n canParallelize: false,\n maxSafeParallelism: 0,\n reason: \"No runnable issues in Todo state.\",\n groups: [],\n };\n }\n\n // Build path overlap graph\n const getIssuePaths = (issue: IssueEntry): Set<string> =>\n new Set([...(issue.paths ?? []), ...(issue.inferredPaths ?? [])]);\n\n const hasPathOverlap = (a: IssueEntry, b: IssueEntry): boolean => {\n const pathsA = getIssuePaths(a);\n const pathsB = getIssuePaths(b);\n if (pathsA.size === 0 || pathsB.size === 0) return false;\n for (const p of pathsA) {\n if (pathsB.has(p)) return true;\n }\n return false;\n };\n\n // Build dependency graph among todo issues\n const hasDep = (a: IssueEntry, b: IssueEntry): boolean =>\n a.blockedBy.includes(b.id) || b.blockedBy.includes(a.id);\n\n // Group independent issues using greedy coloring\n const groups: string[][] = [];\n const assigned = new Set<string>();\n\n for (const issue of todo) {\n if (assigned.has(issue.id)) continue;\n\n let placed = false;\n for (const group of groups) {\n const canJoin = group.every((memberId) => {\n const member = todo.find((i) => i.id === memberId)!;\n return !hasPathOverlap(issue, member) && !hasDep(issue, member);\n });\n\n if (canJoin) {\n group.push(issue.id);\n assigned.add(issue.id);\n placed = true;\n break;\n }\n }\n\n if (!placed) {\n groups.push([issue.id]);\n assigned.add(issue.id);\n }\n }\n\n const maxSafe = Math.max(...groups.map((g) => g.length));\n const conflictingPairs = todo.filter((a, i) =>\n todo.slice(i + 1).some((b) => hasPathOverlap(a, b)),\n ).length;\n\n const reason = conflictingPairs > 0\n ? `${conflictingPairs} issue(s) share file paths with other issues. Maximum safe parallelism is ${maxSafe}.`\n : `All ${todo.length} runnable issues have independent paths. Safe to parallelize up to ${maxSafe}.`;\n\n return {\n canParallelize: maxSafe > 1,\n maxSafeParallelism: maxSafe,\n reason,\n groups,\n };\n}\n\nexport async function ensureNotStale(state: RuntimeState, staleTimeoutMs: number): Promise<void> {\n const limit = Date.now() - staleTimeoutMs;\n for (const issue of state.issues) {\n if (!EXECUTING_STATES.has(issue.state)) continue;\n if (issueHasResumableSession(issue)) continue;\n\n // Fast path: if the agent PID is dead, immediately mark as Blocked\n const agentStatus = isAgentStillRunning(issue);\n const pidDead = agentStatus.pid !== null && !agentStatus.alive;\n\n if (pidDead || Date.parse(issue.updatedAt) < limit) {\n const staleMinutes = Math.round((Date.now() - Date.parse(issue.updatedAt)) / 60_000);\n const reason = pidDead\n ? `Agent process died (PID ${agentStatus.pid!.pid}) — auto-recovering.`\n : `Issue state auto-recovered from stale execution.`;\n logger.info({ issueId: issue.id, identifier: issue.identifier, state: issue.state, updatedAt: issue.updatedAt, pidDead }, \"[Scheduler] Recovering stale issue\");\n issue.attempts += 1;\n issue.nextRetryAt = getNextRetryAt(issue, state.config.retryDelayMs);\n issue.startedAt = undefined;\n markIssueDirty(issue.id);\n await transitionIssueState(issue, \"Blocked\", reason);\n const eventMsg = pidDead\n ? `Issue ${issue.identifier} agent process died (PID ${agentStatus.pid!.pid}), moved to Blocked for retry.`\n : `Issue ${issue.identifier} was stale for over ${staleMinutes} minute(s) in ${issue.state} state, moved to Blocked for retry.`;\n addEvent(state, issue.id, \"info\", eventMsg);\n }\n }\n}\n\nfunction isPerStateFull(issue: IssueEntry, state: RuntimeState, running: Set<string>): boolean {\n const byState = state.config.maxConcurrentByState;\n if (!byState || Object.keys(byState).length === 0) return false;\n const stateKey = issue.state.toLowerCase();\n const limit = byState[stateKey];\n if (limit === undefined) return false;\n const count = state.issues.filter((i) => running.has(i.id) && i.state.toLowerCase() === stateKey).length;\n return count >= limit;\n}\n\nexport function pickNextIssues(\n state: RuntimeState,\n running: Set<string>,\n workflowDefinition: WorkflowDefinition | null,\n): IssueEntry[] {\n const candidates = state.issues\n .filter((issue) => canRunIssue(issue, running, state) && !isPerStateFull(issue, state, running));\n if (candidates.length > 0) {\n logger.debug({ candidates: candidates.map((i) => ({ id: i.identifier, state: i.state, priority: i.priority })) }, \"[Scheduler] Eligible candidates for dispatch\");\n }\n return candidates\n .sort((a, b) => {\n const stateWeight = (c: IssueEntry) => c.state === \"Running\" ? 0 : c.state === \"Blocked\" ? 2 : 1;\n const weightDiff = stateWeight(a) - stateWeight(b);\n if (weightDiff !== 0) return weightDiff;\n if (a.priority !== b.priority) return a.priority - b.priority;\n const capabilityDiff = getIssueCapabilityPriority(a, workflowDefinition) - getIssueCapabilityPriority(b, workflowDefinition);\n if (capabilityDiff !== 0) return capabilityDiff;\n return Date.parse(a.createdAt) - Date.parse(b.createdAt);\n });\n}\n\nlet lastDispatchWarning = \"\";\n\nfunction validateDispatchConfig(state: RuntimeState): string | null {\n if (!state.config.agentCommand?.trim()) {\n // Self-healing: try to auto-detect a provider\n const detected = detectAvailableProviders();\n const provider = resolveDefaultProvider(detected);\n if (provider) {\n const command = getProviderDefaultCommand(provider);\n if (command) {\n state.config.agentProvider = provider;\n state.config.agentCommand = command;\n logger.info(`Self-healed: auto-detected provider ${provider} → ${command}`);\n return null;\n }\n }\n return \"No agent command configured. Install claude or codex, or set FIFONY_AGENT_COMMAND.\";\n }\n if (state.config.workerConcurrency < 1) {\n return \"Worker concurrency must be >= 1.\";\n }\n if (state.config.maxTurns < 1) {\n return \"Max turns must be >= 1.\";\n }\n return null; // valid\n}\n\nfunction warnOncePerMessage(message: string): void {\n if (message === lastDispatchWarning) return;\n lastDispatchWarning = message;\n logger.warn(`Dispatch skipped: ${message}`);\n}\n\nexport function hasTerminalQueue(state: RuntimeState): boolean {\n return state.issues.every((issue) => TERMINAL_STATES.has(issue.state) || issue.attempts >= issue.maxAttempts);\n}\n\nexport async function scheduler(\n state: RuntimeState,\n running: Set<string>,\n runForever: boolean,\n workflowDefinition: WorkflowDefinition | null,\n): Promise<void> {\n if (runForever) {\n while (!shuttingDown) {\n await ensureNotStale(state, state.config.staleInProgressTimeoutMs);\n\n // Per-tick dispatch validation (spec §6.3)\n const validationError = validateDispatchConfig(state);\n if (validationError) {\n warnOncePerMessage(validationError);\n } else {\n const ready = pickNextIssues(state, running, workflowDefinition);\n const slots = state.config.workerConcurrency - running.size;\n if (slots > 0 && ready.length > 0) {\n const next = ready.slice(0, Math.max(0, slots));\n logger.debug({ slots, readyCount: ready.length, dispatching: next.map((i) => i.identifier) }, \"[Scheduler] Dispatching issues\");\n await Promise.all(next.map((issue) => runIssueOnce(state, issue, running, workflowDefinition)));\n } else if (ready.length > 0 && slots <= 0) {\n logger.debug({ runningCount: running.size, readyCount: ready.length, concurrency: state.config.workerConcurrency }, \"[Scheduler] No slots available, waiting\");\n }\n }\n state.updatedAt = now();\n const shouldPersist = hasDirtyState() || Date.now() - lastPersistAt > PERSIST_DEBOUNCE_MS;\n if (shouldPersist) {\n await persistState(state);\n lastPersistAt = Date.now();\n }\n logger.debug({ runningCount: running.size, issueCount: state.issues.length, dirty: hasDirtyState() }, \"[Scheduler] Tick completed\");\n const effectivePoll = running.size > 0 ? ACTIVE_POLL_MS : IDLE_POLL_MS;\n await Promise.race([\n sleep(effectivePoll),\n new Promise<void>((resolve) => { schedulerWakeResolve = resolve; }),\n ]);\n schedulerWakeResolve = null;\n }\n return;\n }\n\n while (!hasTerminalQueue(state) && !shuttingDown) {\n await ensureNotStale(state, state.config.staleInProgressTimeoutMs);\n\n const batchValidationError = validateDispatchConfig(state);\n if (batchValidationError) {\n warnOncePerMessage(batchValidationError);\n await sleep(state.config.pollIntervalMs);\n continue;\n }\n\n const ready = pickNextIssues(state, running, workflowDefinition);\n const slots = state.config.workerConcurrency - running.size;\n const next = ready.slice(0, Math.max(0, slots));\n\n if (next.length === 0 && running.size === 0) {\n if (state.issues.some((issue) => issue.state === \"Blocked\" && issue.nextRetryAt && issue.attempts < issue.maxAttempts)) {\n logger.debug(\"[Scheduler] Batch mode: waiting for blocked issues to become eligible for retry\");\n await sleep(state.config.pollIntervalMs);\n continue;\n }\n logger.debug(\"[Scheduler] Batch mode: no more work to do, exiting loop\");\n break;\n }\n\n if (next.length > 0) {\n logger.debug({ slots, dispatching: next.map((i) => i.identifier) }, \"[Scheduler] Batch mode: dispatching issues\");\n }\n await Promise.all(next.map((issue) => runIssueOnce(state, issue, running, workflowDefinition)));\n state.updatedAt = now();\n await persistState(state);\n\n if (running.size === 0) {\n await sleep(state.config.pollIntervalMs);\n }\n }\n}\n","import { appendFileTail, getNestedRecord, getNestedString, extractJsonObjects } from \"./helpers.ts\";\nimport { logger } from \"./logger.ts\";\nimport { detectAvailableProviders, normalizeAgentProvider, resolveAgentCommand } from \"./providers.ts\";\nimport type { RuntimeConfig, WorkflowDefinition } from \"./types.ts\";\nimport { renderPrompt } from \"../prompting.ts\";\nimport { env } from \"node:process\";\nimport { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { spawn } from \"node:child_process\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { callOpenAI } from \"./openai-adapter.ts\";\n\nexport type EnhancementField = \"title\" | \"description\";\n\ntype EnhanceIssuePayload = {\n field: EnhancementField;\n title: string;\n description: string;\n provider?: string;\n preferredProvider?: string;\n};\n\ntype EnhanceResult = {\n field: EnhancementField;\n value: string;\n provider: string;\n};\n\nfunction getProviderCommand(\n provider: string,\n config: RuntimeConfig,\n workflowDefinition: WorkflowDefinition | null,\n): string {\n const workflowConfig = workflowDefinition ? workflowDefinition.config : {};\n const codexCommand = getNestedString(getNestedRecord(workflowConfig, \"codex\"), \"command\");\n const claudeCommand = getNestedString(getNestedRecord(workflowConfig, \"claude\"), \"command\");\n return resolveAgentCommand(provider, config.agentCommand || \"\", codexCommand, claudeCommand);\n}\n\nasync function buildPrompt(field: EnhancementField, title: string, description: string): Promise<string> {\n const context = {\n title: title || \"(empty)\",\n description: description || \"(empty)\",\n };\n\n if (field === \"title\") {\n return renderPrompt(\"issue-enhancer-title\", context);\n }\n\n return renderPrompt(\"issue-enhancer-description\", context);\n}\n\nfunction parseEnhancerOutput(raw: string, expectedField: EnhancementField): string {\n const text = raw.trim();\n if (!text) {\n throw new Error(\"AI provider returned an empty response.\");\n }\n\n const candidates = extractJsonObjects(\n text.match(/```(?:json)?\\s*([\\s\\S]*?)\\s*```/i)?.[1]?.trim() ?? text,\n );\n for (const candidate of candidates) {\n const value = parseCandidate(candidate, expectedField);\n if (value) return value;\n }\n\n const cleanedRaw = text.trim();\n const trimmed = cleanedRaw.replace(/^\\\"|\\\"$/g, \"\").trim();\n if (trimmed) {\n const candidatesFromRaw = extractJsonObjects(trimmed);\n for (const candidate of candidatesFromRaw) {\n const value = parseCandidate(candidate, expectedField);\n if (value) return value;\n }\n }\n\n const fallback = cleanedRaw.replace(/^`+\\s*|\\s*`+$/g, \"\").trim();\n if (!fallback) {\n throw new Error(\"AI provider response could not be parsed.\");\n }\n return fallback;\n}\n\nfunction parseCandidate(raw: string, expectedField: EnhancementField): string {\n const candidate = raw.trim();\n if (!candidate) return \"\";\n\n try {\n const parsed = JSON.parse(candidate) as {\n field?: string;\n value?: unknown;\n text?: unknown;\n result?: unknown;\n };\n const value =\n typeof parsed.value === \"string\" ? parsed.value.trim() :\n typeof parsed.text === \"string\" ? parsed.text.trim() :\n \"\";\n const field = parsed.field;\n const isPlaceholder = /^\\.{2,}$/.test(value);\n if (value && !isPlaceholder && (!field || field === expectedField)) {\n return value;\n }\n if (typeof parsed.result === \"string\") {\n const nested = parsed.result.trim();\n if (nested) {\n const nestedClean = nested.replace(/^```(?:json)?\\s*|\\s*```$/g, \"\").trim();\n for (const nestedCandidate of extractJsonObjects(nestedClean)) {\n const parsedNested = parseCandidate(nestedCandidate, expectedField);\n if (parsedNested) return parsedNested;\n }\n }\n }\n } catch {\n // ignore parse errors for heuristic parsing\n }\n return \"\";\n}\n\nfunction readProviderOutput(resultFile: string, fallback: string): string {\n if (existsSync(resultFile)) {\n try {\n return readFileSync(resultFile, \"utf8\").trim();\n } catch {\n // ignore, keep fallback\n }\n }\n return fallback;\n}\n\nasync function runProviderCommand(\n command: string,\n provider: string,\n prompt: string,\n title: string,\n description: string,\n field: EnhancementField,\n timeoutMs: number,\n): Promise<string> {\n const tempDir = mkdtempSync(join(tmpdir(), \"fifony-enhance-\"));\n const promptFile = join(tempDir, \"fifony-enhance-prompt.md\");\n const issuePayloadFile = join(tempDir, \"fifony-issue.json\");\n const resultFile = join(tempDir, \"fifony-result.txt\");\n writeFileSync(promptFile, `${prompt}\\n`, \"utf8\");\n writeFileSync(issuePayloadFile, JSON.stringify({ title, description, field }, null, 2), \"utf8\");\n\n const spawnEnv = {\n ...env,\n FIFONY_ISSUE_TITLE: title,\n FIFONY_ISSUE_DESCRIPTION: description,\n FIFONY_ENHANCE_FIELD: field,\n FIFONY_PROMPT_FILE: promptFile,\n FIFONY_PROMPT: prompt,\n FIFONY_ISSUE_JSON: issuePayloadFile,\n FIFONY_AGENT_PROVIDER: provider,\n FIFONY_RESULT_FILE: resultFile,\n };\n\n return await new Promise((resolve, reject) => {\n const startedAt = Date.now();\n let output = \"\";\n let timeout = false;\n\n const child = spawn(command, {\n shell: true,\n cwd: tempDir,\n env: spawnEnv,\n });\n\n if (child.stdin) child.stdin.end();\n\n child.stdout?.on(\"data\", (chunk) => {\n output = appendFileTail(output, String(chunk), 12_000);\n });\n child.stderr?.on(\"data\", (chunk) => {\n output = appendFileTail(output, String(chunk), 12_000);\n });\n\n const timer = setTimeout(() => {\n timeout = true;\n child.kill(\"SIGTERM\");\n }, Math.max(timeoutMs, 1_000));\n\n child.on(\"error\", () => {\n clearTimeout(timer);\n rmSync(tempDir, { recursive: true, force: true });\n reject(new Error(\"Could not execute AI command.\"));\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n\n if (timeout) {\n rmSync(tempDir, { recursive: true, force: true });\n reject(new Error(`Enhance command timeout after ${Date.now() - startedAt}ms.`));\n return;\n }\n\n const commandOutput = readProviderOutput(resultFile, output);\n rmSync(tempDir, { recursive: true, force: true });\n\n if (code !== 0) {\n const providerOutput = appendFileTail(commandOutput, \"\", 12_000);\n const reason = providerOutput.trim()\n ? ` Enhance command output: ${providerOutput.slice(0, 1200)}`\n : \"\";\n reject(new Error(`Enhance command failed (exit ${code ?? \"unknown\"}).${reason}`));\n return;\n }\n resolve(commandOutput);\n });\n });\n}\n\nexport async function enhanceIssueField(\n payload: EnhanceIssuePayload,\n config: RuntimeConfig,\n workflowDefinition: WorkflowDefinition | null,\n): Promise<EnhanceResult> {\n const field: EnhancementField = payload.field === \"description\" ? \"description\" : \"title\";\n const title = typeof payload.title === \"string\" ? payload.title.trim() : \"\";\n const description = typeof payload.description === \"string\" ? payload.description.trim() : \"\";\n const requestedProvider = normalizeAgentProvider(\n typeof payload.preferredProvider === \"string\" ? payload.preferredProvider : payload.provider ?? config.agentProvider,\n );\n const providers = detectAvailableProviders();\n const availableSet = new Set(providers.filter((entry) => entry.available).map((entry) => entry.name));\n const orderedProviders: string[] = [];\n const addProvider = (candidate: string) => {\n if (availableSet.has(candidate) && !orderedProviders.includes(candidate)) {\n orderedProviders.push(candidate);\n }\n };\n\n addProvider(requestedProvider);\n addProvider(\"codex\");\n addProvider(\"claude\");\n\n if (!orderedProviders.length) {\n const known = providers.map((entry) => `${entry.name}:${entry.available ? \"available\" : \"missing\"}`).join(\", \");\n throw new Error(`No AI provider available (codex/claude). Detected: ${known}`);\n }\n\n const prompt = await buildPrompt(field, title, description);\n const errors: string[] = [];\n\n // JSON schema for structured enhance output via OpenAI API\n const enhanceSchema = {\n type: \"object\" as const,\n properties: {\n field: { type: \"string\" as const },\n value: { type: \"string\" as const },\n },\n required: [\"field\", \"value\"] as const,\n additionalProperties: false as const,\n };\n\n for (const selectedProvider of orderedProviders) {\n // ── Codex provider: call OpenAI API directly (structured output support) ──\n if (selectedProvider === \"codex\") {\n try {\n logger.debug({ provider: selectedProvider, field }, \"[Enhancer] Using OpenAI API path for Codex provider\");\n const result = await callOpenAI({\n prompt,\n jsonSchema: { name: \"issue_enhancement\", schema: enhanceSchema },\n timeoutMs: config.commandTimeoutMs || 120_000,\n });\n\n logger.info({ provider: selectedProvider, field, rawOutput: result.content.slice(0, 2000) }, \"Enhance raw output (API)\");\n\n // Parse the structured response — should be clean JSON with { field, value }\n let value: string | undefined;\n try {\n const parsed = JSON.parse(result.content) as { field?: string; value?: string };\n if (parsed.value && typeof parsed.value === \"string\") {\n value = parsed.value.trim();\n }\n } catch {\n // If JSON parse fails, fall through to the standard parser\n }\n\n if (!value) {\n value = parseEnhancerOutput(result.content, field);\n }\n\n logger.info({ provider: selectedProvider, field, parsedValue: value }, \"Enhance parsed value (API)\");\n return { field, value, provider: selectedProvider };\n } catch (error) {\n errors.push(\n `Provider \"${selectedProvider}\" (API) failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n continue;\n }\n }\n\n // ── Claude/other providers: spawn CLI process ──\n const command = getProviderCommand(selectedProvider, config, workflowDefinition);\n if (!command) {\n errors.push(`Provider \"${selectedProvider}\" has no command.`);\n continue;\n }\n\n try {\n const output = await runProviderCommand(\n command,\n selectedProvider,\n prompt,\n title,\n description,\n field,\n config.commandTimeoutMs,\n );\n logger.info({ provider: selectedProvider, field, rawOutput: output.slice(0, 2000) }, \"Enhance raw output\");\n const value = parseEnhancerOutput(output, field);\n logger.info({ provider: selectedProvider, field, parsedValue: value }, \"Enhance parsed value\");\n return { field, value, provider: selectedProvider };\n } catch (error) {\n errors.push(\n `Provider \"${selectedProvider}\" failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n throw new Error(`Could not enhance issue field. ${errors.join(\" | \")}`);\n}\n","/**\n * Lightweight OpenAI API adapter for reasoning-only operations.\n *\n * Used when the provider is \"codex\" but we need structured output (JSON schema)\n * that the Codex CLI doesn't support (no --json-schema, --output-format json, or --print).\n *\n * Calls the OpenAI chat completions API directly via native fetch (Node 23+).\n * No SDK dependency required.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { logger } from \"./logger.ts\";\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport type OpenAICallOptions = {\n prompt: string;\n model?: string;\n jsonSchema?: { name: string; schema: Record<string, unknown> };\n reasoningEffort?: string;\n timeoutMs?: number;\n};\n\nexport type OpenAICallResult = {\n content: string;\n usage: {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n };\n model: string;\n};\n\n// ── Default model discovery ──────────────────────────────────────────────────\n\n/** Read the first available model from Codex CLI's local cache. */\nfunction getDefaultCodexModel(): string {\n const cachePath = join(homedir(), \".codex\", \"models_cache.json\");\n try {\n if (existsSync(cachePath)) {\n const raw = readFileSync(cachePath, \"utf8\");\n const cache = JSON.parse(raw) as {\n models?: Array<{ slug: string; visibility?: string; priority?: number }>;\n };\n if (Array.isArray(cache.models) && cache.models.length > 0) {\n // Pick the first \"list\" model sorted by priority (same logic as providers.ts)\n const sorted = [...cache.models]\n .sort((a, b) => {\n const visA = a.visibility === \"list\" ? 0 : 1;\n const visB = b.visibility === \"list\" ? 0 : 1;\n if (visA !== visB) return visA - visB;\n return (a.priority ?? 99) - (b.priority ?? 99);\n });\n if (sorted[0]?.slug) return sorted[0].slug;\n }\n }\n } catch {\n // Cache unreadable\n }\n return \"o3-mini\"; // Safe fallback — widely available reasoning model\n}\n\n// ── API call ─────────────────────────────────────────────────────────────────\n\nexport async function callOpenAI(options: OpenAICallOptions): Promise<OpenAICallResult> {\n const apiKey = process.env.OPENAI_API_KEY;\n if (!apiKey) {\n throw new Error(\"OPENAI_API_KEY is not set. Required for OpenAI API calls when using Codex provider for reasoning operations.\");\n }\n\n const baseUrl = (process.env.OPENAI_BASE_URL || \"https://api.openai.com/v1\").replace(/\\/+$/, \"\");\n const model = options.model || getDefaultCodexModel();\n const timeoutMs = options.timeoutMs ?? 1_800_000; // 30 minutes default\n\n logger.info(\n { model, hasSchema: !!options.jsonSchema, effort: options.reasoningEffort, promptLength: options.prompt.length },\n \"[OpenAI Adapter] Starting API call\",\n );\n\n const messages: Array<{ role: string; content: string }> = [\n { role: \"user\", content: options.prompt },\n ];\n\n // Build request body\n const body: Record<string, unknown> = {\n model,\n messages,\n };\n\n // Structured output via json_schema response format\n if (options.jsonSchema) {\n body.response_format = {\n type: \"json_schema\",\n json_schema: {\n name: options.jsonSchema.name,\n schema: options.jsonSchema.schema,\n strict: true,\n },\n };\n }\n\n // Reasoning effort for o-series models\n if (options.reasoningEffort) {\n const effort = options.reasoningEffort.toLowerCase();\n if (effort === \"low\" || effort === \"medium\" || effort === \"high\") {\n body.reasoning_effort = effort;\n }\n }\n\n const startMs = Date.now();\n\n const response = await fetch(`${baseUrl}/chat/completions`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Authorization\": `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n signal: AbortSignal.timeout(timeoutMs),\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => \"(could not read error body)\");\n const durationMs = Date.now() - startMs;\n logger.error(\n { status: response.status, durationMs, errorBody: errorBody.slice(0, 500) },\n \"[OpenAI Adapter] API call failed\",\n );\n throw new Error(`OpenAI API error ${response.status}: ${errorBody.slice(0, 500)}`);\n }\n\n const data = await response.json() as {\n choices?: Array<{\n message?: { content?: string };\n finish_reason?: string;\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_tokens?: number;\n };\n model?: string;\n };\n\n const durationMs = Date.now() - startMs;\n const content = data.choices?.[0]?.message?.content ?? \"\";\n const finishReason = data.choices?.[0]?.finish_reason ?? \"unknown\";\n const usedModel = data.model ?? model;\n\n const usage = {\n inputTokens: data.usage?.prompt_tokens ?? 0,\n outputTokens: data.usage?.completion_tokens ?? 0,\n totalTokens: data.usage?.total_tokens ?? 0,\n };\n\n logger.info(\n {\n model: usedModel,\n finishReason,\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens,\n contentLength: content.length,\n durationMs,\n },\n \"[OpenAI Adapter] API call completed\",\n );\n\n return { content, usage, model: usedModel };\n}\n","import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from \"node:fs\";\nimport { spawn } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport type { IssuePlan, RuntimeConfig, WorkflowConfig, WorkflowDefinition, RuntimeState, IssueEntry } from \"./types.ts\";\nimport { appendFileTail, now, toStringArray, extractJsonObjects, repairTruncatedJson } from \"./helpers.ts\";\nimport { detectAvailableProviders } from \"./providers.ts\";\nimport { replacePersistedSetting, getSettingStateResource } from \"./store.ts\";\nimport { getWorkflowConfig, loadRuntimeSettings } from \"./settings.ts\";\nimport { logger } from \"./logger.ts\";\nimport { buildClaudeCommand, buildCodexCommand } from \"./adapters/commands.ts\";\nimport { record as recordTokens } from \"./token-ledger.ts\";\nimport type { AgentTokenUsage } from \"./types.ts\";\nimport { renderPrompt } from \"../prompting.ts\";\nimport { callOpenAI } from \"./openai-adapter.ts\";\nimport { STATE_ROOT } from \"./constants.ts\";\n\nfunction savePlanDebugFiles(slug: string, prompt: string, output: string): void {\n try {\n const debugDir = join(STATE_ROOT, \"debug\");\n mkdirSync(debugDir, { recursive: true });\n const ts = new Date().toISOString().replace(/[:.]/g, \"-\").slice(0, 19);\n writeFileSync(join(debugDir, `plan-${slug}-${ts}-prompt.md`), prompt, \"utf8\");\n if (output) writeFileSync(join(debugDir, `plan-${slug}-${ts}-output.txt`), output, \"utf8\");\n } catch {\n // non-critical\n }\n}\n\n// ── Planning session persistence ────────────────────────────────────────────\n\nexport type PlanningSessionStatus = \"input\" | \"planning\" | \"done\" | \"error\" | \"interrupted\";\n\nexport type PlanningSessionUsage = {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n model: string;\n promptChars: number;\n outputChars: number;\n durationMs: number;\n};\n\nexport type PlanningSession = {\n title: string;\n description: string;\n status: PlanningSessionStatus;\n plan: IssuePlan | null;\n error: string | null;\n pid: number | null;\n provider: string | null;\n startedAt: string | null;\n completedAt: string | null;\n updatedAt: string;\n /** Live progress: output bytes received so far (updated during planning) */\n outputBytes: number;\n /** Token usage extracted after planning completes */\n usage: PlanningSessionUsage | null;\n};\n\nconst PLANNING_SETTING_ID = \"planning:active\";\n\nfunction emptySession(): PlanningSession {\n return {\n title: \"\", description: \"\", status: \"input\",\n plan: null, error: null, pid: null, provider: null,\n startedAt: null, completedAt: null, updatedAt: now(),\n outputBytes: 0, usage: null,\n };\n}\n\nasync function persistSession(session: PlanningSession): Promise<void> {\n session.updatedAt = now();\n try {\n await replacePersistedSetting({\n id: PLANNING_SETTING_ID,\n scope: \"runtime\",\n value: session,\n source: \"system\",\n updatedAt: session.updatedAt,\n });\n } catch (error) {\n logger.warn(`Failed to persist planning session: ${String(error)}`);\n }\n}\n\nexport async function loadPlanningSession(): Promise<PlanningSession | null> {\n const resource = getSettingStateResource();\n if (!resource) return null;\n try {\n const record = await resource.get(PLANNING_SETTING_ID);\n if (record?.value && typeof record.value === \"object\") {\n return record.value as PlanningSession;\n }\n } catch {\n // not found\n }\n return null;\n}\n\nexport async function clearPlanningSession(): Promise<void> {\n await persistSession(emptySession());\n}\n\n/** Check on boot if a planning process is still alive. */\nexport async function recoverPlanningSession(): Promise<void> {\n const session = await loadPlanningSession();\n if (!session || session.status !== \"planning\") return;\n\n if (session.pid) {\n let alive = false;\n try { process.kill(session.pid, 0); alive = true; } catch {}\n\n if (alive) {\n logger.info(`Planning process still alive (PID ${session.pid}), keeping status.`);\n return;\n }\n }\n\n // Process died — mark as interrupted\n session.status = \"interrupted\";\n session.error = \"Planning process was interrupted by server restart.\";\n session.pid = null;\n await persistSession(session);\n logger.info(\"Planning session marked as interrupted (process not found).\");\n}\n\n// ── Plan JSON schema ────────────────────────────────────────────────────────\n\n// Reusable step schema (used in both steps[] and phases[].tasks[])\nconst STEP_SCHEMA = {\n type: \"object\",\n additionalProperties: false,\n required: [\"step\", \"action\", \"files\", \"details\", \"ownerType\", \"doneWhen\"],\n properties: {\n step: { type: \"number\" },\n action: { type: \"string\" },\n files: { type: \"array\", items: { type: \"string\" } },\n details: { type: \"string\" },\n ownerType: { type: \"string\", enum: [\"human\", \"agent\", \"skill\", \"subagent\", \"tool\"] },\n doneWhen: { type: \"string\" },\n },\n};\n\nconst PLAN_JSON_SCHEMA = JSON.stringify({\n type: \"object\",\n additionalProperties: false,\n required: [\"summary\", \"steps\", \"phases\", \"estimatedComplexity\", \"suggestedPaths\", \"suggestedLabels\", \"assumptions\", \"constraints\", \"unknowns\", \"successCriteria\", \"executionStrategy\", \"toolingDecision\", \"risks\", \"validation\", \"deliverables\", \"suggestedEffort\"],\n properties: {\n summary: { type: \"string\" },\n estimatedComplexity: { type: \"string\", enum: [\"trivial\", \"low\", \"medium\", \"high\"] },\n assumptions: { type: \"array\", items: { type: \"string\" } },\n constraints: { type: \"array\", items: { type: \"string\" } },\n unknowns: { type: \"array\", items: { type: \"object\", additionalProperties: false, properties: { question: { type: \"string\" }, whyItMatters: { type: \"string\" }, howToResolve: { type: \"string\" } }, required: [\"question\", \"whyItMatters\", \"howToResolve\"] } },\n successCriteria: { type: \"array\", items: { type: \"string\" } },\n executionStrategy: { type: \"object\", additionalProperties: false, required: [\"approach\", \"whyThisApproach\", \"alternativesConsidered\"], properties: { approach: { type: \"string\" }, whyThisApproach: { type: \"string\" }, alternativesConsidered: { type: \"array\", items: { type: \"string\" } } } },\n toolingDecision: { type: \"object\", additionalProperties: false, required: [\"shouldUseSkills\", \"skillsToUse\", \"shouldUseSubagents\", \"subagentsToUse\", \"decisionSummary\"], properties: {\n shouldUseSkills: { type: \"boolean\" },\n skillsToUse: { type: \"array\", items: { type: \"object\", additionalProperties: false, properties: { name: { type: \"string\" }, why: { type: \"string\" } }, required: [\"name\", \"why\"] } },\n shouldUseSubagents: { type: \"boolean\" },\n subagentsToUse: { type: \"array\", items: { type: \"object\", additionalProperties: false, properties: { name: { type: \"string\" }, role: { type: \"string\" }, why: { type: \"string\" } }, required: [\"name\", \"role\", \"why\"] } },\n decisionSummary: { type: \"string\" },\n } },\n steps: { type: \"array\", items: STEP_SCHEMA },\n phases: { type: \"array\", items: { type: \"object\", additionalProperties: false, required: [\"phaseName\", \"goal\", \"tasks\", \"dependencies\", \"outputs\"], properties: {\n phaseName: { type: \"string\" },\n goal: { type: \"string\" },\n tasks: { type: \"array\", items: STEP_SCHEMA },\n dependencies: { type: \"array\", items: { type: \"string\" } },\n outputs: { type: \"array\", items: { type: \"string\" } },\n } } },\n risks: { type: \"array\", items: { type: \"object\", additionalProperties: false, required: [\"risk\", \"impact\", \"mitigation\"], properties: { risk: { type: \"string\" }, impact: { type: \"string\" }, mitigation: { type: \"string\" } } } },\n validation: { type: \"array\", items: { type: \"string\" } },\n deliverables: { type: \"array\", items: { type: \"string\" } },\n suggestedPaths: { type: \"array\", items: { type: \"string\" } },\n suggestedLabels: { type: \"array\", items: { type: \"string\" } },\n suggestedEffort: { type: \"object\", additionalProperties: false, required: [\"default\", \"planner\", \"executor\", \"reviewer\"], properties: { default: { type: \"string\" }, planner: { type: \"string\" }, executor: { type: \"string\" }, reviewer: { type: \"string\" } } },\n },\n});\n\n/** Parsed schema object for OpenAI API json_schema response_format. */\nconst PLAN_SCHEMA_OBJECT = JSON.parse(PLAN_JSON_SCHEMA) as Record<string, unknown>;\n\n// ── OpenAI API path (for Codex provider reasoning-only operations) ───────────\n\nasync function generatePlanViaOpenAI(\n prompt: string,\n model?: string,\n effort?: string,\n): Promise<{ content: string; usage: PlanningSessionUsage; model: string }> {\n const result = await callOpenAI({\n prompt,\n model,\n jsonSchema: { name: \"issue_plan\", schema: PLAN_SCHEMA_OBJECT },\n reasoningEffort: effort,\n timeoutMs: 1_800_000, // 30 minutes\n });\n\n return {\n content: result.content,\n usage: {\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n totalTokens: result.usage.totalTokens,\n model: result.model,\n promptChars: prompt.length,\n outputChars: result.content.length,\n durationMs: 0, // Will be set by caller\n },\n model: result.model,\n };\n}\n\n// ── Prompt ───────────────────────────────────────────────────────────────────\n\nasync function buildPlanPrompt(title: string, description: string, fast = false): Promise<string> {\n return renderPrompt(\"issue-planner\", {\n title,\n description: description || \"(none provided)\",\n fast,\n });\n}\n\n// ── Provider command ─────────────────────────────────────────────────────────\n\nfunction getPlanCommand(provider: string, model?: string): string {\n if (provider === \"claude\") return buildClaudeCommand({ model, jsonSchema: PLAN_JSON_SCHEMA, noToolAccess: true });\n if (provider === \"codex\") return buildCodexCommand({ model });\n return \"\";\n}\n\n// ── Parser ───────────────────────────────────────────────────────────────────\n\nfunction tryBuildPlan(parsed: any): IssuePlan | null {\n if (!parsed || typeof parsed !== \"object\") return null;\n if (!parsed.summary || !Array.isArray(parsed.steps)) return null;\n\n const complexities = [\"trivial\", \"low\", \"medium\", \"high\"];\n\n return {\n summary: String(parsed.summary),\n estimatedComplexity: complexities.includes(parsed.estimatedComplexity) ? parsed.estimatedComplexity\n : complexities.includes(parsed.complexity) ? parsed.complexity : \"medium\",\n\n steps: parsed.steps.map((s: any, i: number) => ({\n step: s.step ?? i + 1,\n action: String(s.action || s.description || s.title || s.task_name || \"\"),\n files: toStringArray(s.files),\n details: s.details ? String(s.details) : undefined,\n ownerType: s.ownerType || s.owner_type || undefined,\n doneWhen: s.doneWhen || s.done_when || undefined,\n })),\n\n assumptions: toStringArray(parsed.assumptions),\n constraints: toStringArray(parsed.constraints),\n unknowns: Array.isArray(parsed.unknowns) ? parsed.unknowns.map((u: any) => ({\n question: String(u.question || \"\"),\n whyItMatters: String(u.whyItMatters || u.why_it_matters || \"\"),\n howToResolve: String(u.howToResolve || u.how_to_resolve || \"\"),\n })) : undefined,\n successCriteria: toStringArray(parsed.successCriteria || parsed.success_criteria),\n risks: Array.isArray(parsed.risks) ? parsed.risks.map((r: any) => ({\n risk: String(r.risk || \"\"),\n impact: String(r.impact || \"\"),\n mitigation: String(r.mitigation || \"\"),\n })) : undefined,\n validation: toStringArray(parsed.validation),\n deliverables: toStringArray(parsed.deliverables),\n\n executionStrategy: parsed.executionStrategy || parsed.execution_strategy || undefined,\n toolingDecision: parsed.toolingDecision || parsed.tooling_decision || undefined,\n\n suggestedPaths: toStringArray(parsed.suggestedPaths || parsed.suggested_paths || parsed.paths),\n suggestedLabels: toStringArray(parsed.suggestedLabels || parsed.suggested_labels || parsed.labels),\n suggestedEffort: parsed.suggestedEffort || parsed.suggested_effort || parsed.effort || { default: \"medium\" },\n\n provider: \"\",\n createdAt: now(),\n };\n}\n\nfunction parsePlanOutput(raw: string): IssuePlan | null {\n const text = raw.trim();\n if (!text) return null;\n\n const candidates: string[] = [];\n\n // 1. Try to unwrap --output-format json envelope\n try {\n const outer = JSON.parse(text);\n\n // --json-schema puts structured output in .structured_output (not .result)\n if (outer?.structured_output && typeof outer.structured_output === \"object\") {\n const plan = tryBuildPlan(outer.structured_output);\n if (plan) return plan;\n // If it didn't validate, still try as a candidate string\n candidates.push(JSON.stringify(outer.structured_output));\n }\n\n if (outer?.result && typeof outer.result === \"string\") {\n const result = outer.result;\n candidates.push(result);\n // Also extract any JSON objects embedded in the result string\n candidates.push(...extractJsonObjects(result));\n // Try code blocks inside .result\n const resultCodeBlocks = result.matchAll(/```(?:json)?\\s*([\\s\\S]*?)\\s*```/gi);\n for (const match of resultCodeBlocks) candidates.push(match[1]);\n }\n // If the outer object itself looks like a plan (no .type envelope)\n if (outer?.summary) candidates.push(text);\n } catch {}\n\n // 2. Try code blocks in full output\n const codeBlocks = text.matchAll(/```(?:json)?\\s*([\\s\\S]*?)\\s*```/gi);\n for (const match of codeBlocks) candidates.push(match[1]);\n\n // 3. Extract top-level JSON objects from full text\n candidates.push(...extractJsonObjects(text));\n\n for (const candidate of candidates) {\n try {\n const parsed = JSON.parse(candidate.trim());\n // Direct plan\n const plan = tryBuildPlan(parsed);\n if (plan) return plan;\n // Envelope with structured_output\n if (parsed?.structured_output && typeof parsed.structured_output === \"object\") {\n const innerPlan = tryBuildPlan(parsed.structured_output);\n if (innerPlan) return innerPlan;\n }\n } catch {}\n }\n\n // Last resort: try to repair truncated JSON output\n const repaired = repairTruncatedJson(text);\n if (repaired) {\n try {\n const parsed = JSON.parse(repaired);\n const plan = tryBuildPlan(parsed);\n if (plan) {\n logger.warn(\"[Planner] Plan parsed from repaired truncated JSON output\");\n return plan;\n }\n // Check for envelope\n if (parsed?.structured_output && typeof parsed.structured_output === \"object\") {\n const innerPlan = tryBuildPlan(parsed.structured_output);\n if (innerPlan) {\n logger.warn(\"[Planner] Plan parsed from repaired truncated JSON envelope\");\n return innerPlan;\n }\n }\n } catch {\n logger.debug(\"[Planner] JSON repair attempted but result still not parseable\");\n }\n }\n\n return null;\n}\n\n// ── Main: generate plan ──────────────────────────────────────────────────────\n\nexport async function savePlanningInput(title: string, description: string): Promise<PlanningSession> {\n const session: PlanningSession = {\n title, description, status: \"input\",\n plan: null, error: null, pid: null, provider: null,\n startedAt: null, completedAt: null, updatedAt: now(),\n outputBytes: 0, usage: null,\n };\n await persistSession(session);\n return session;\n}\n\n/** Extract token usage from CLI output (Claude JSON or Codex text) */\nfunction extractPlanTokenUsage(raw: string): { inputTokens: number; outputTokens: number; totalTokens: number; model: string } | null {\n // 1. Claude --output-format json: parse the outer JSON envelope\n try {\n const parsed = JSON.parse(raw.trim());\n\n // Try modelUsage field first (richer data, per-model breakdown)\n if (parsed?.modelUsage && typeof parsed.modelUsage === \"object\") {\n let totalInput = 0, totalOutput = 0, primaryModel = \"\";\n let maxTokens = 0;\n for (const [model, data] of Object.entries<any>(parsed.modelUsage)) {\n const inp = Number(data?.inputTokens || 0) + Number(data?.cacheReadInputTokens || 0) + Number(data?.cacheCreationInputTokens || 0);\n const out = Number(data?.outputTokens || 0);\n totalInput += inp;\n totalOutput += out;\n if (inp + out > maxTokens) {\n maxTokens = inp + out;\n primaryModel = model;\n }\n }\n if (totalInput > 0 || totalOutput > 0) {\n return { inputTokens: totalInput, outputTokens: totalOutput, totalTokens: totalInput + totalOutput, model: primaryModel };\n }\n }\n\n // Fallback: usage field\n const usage = parsed?.usage;\n if (usage && typeof usage === \"object\") {\n const input = Number(usage.input_tokens) || 0;\n const output = Number(usage.output_tokens) || 0;\n if (input > 0 || output > 0) {\n return {\n inputTokens: input,\n outputTokens: output,\n totalTokens: input + output,\n model: typeof parsed.model === \"string\" ? parsed.model : \"\",\n };\n }\n }\n\n // Fallback: total_cost_usd present means we can at least log the cost\n } catch { /* not JSON — try Codex format */ }\n\n // 2. Codex: \"tokens used\\n1,681\\n\"\n const codexMatch = raw.match(/tokens?\\s+used\\s*\\n\\s*([\\d,]+)/i);\n if (codexMatch) {\n const total = parseInt(codexMatch[1].replace(/,/g, \"\"), 10);\n const modelMatch = raw.match(/^model:\\s*(.+)$/im);\n if (total > 0) {\n return { inputTokens: 0, outputTokens: 0, totalTokens: total, model: modelMatch?.[1]?.trim() || \"\" };\n }\n }\n\n return null;\n}\n\nexport type GeneratePlanResult = {\n plan: IssuePlan;\n usage: PlanningSessionUsage;\n};\n\nexport async function generatePlan(\n title: string,\n description: string,\n config: RuntimeConfig,\n workflowDefinition: WorkflowDefinition | null,\n options?: { fast?: boolean },\n): Promise<GeneratePlanResult> {\n const fast = options?.fast ?? false;\n logger.info({ title: title.slice(0, 80), fast }, \"[Planner] Starting plan generation\");\n const providers = detectAvailableProviders();\n const available = providers.filter((p) => p.available).map((p) => p.name);\n\n // Load WorkflowConfig from settings to use the plan stage configuration\n let planStageProvider: string | undefined;\n let planStageModel: string | undefined;\n let planStageEffort: string | undefined;\n try {\n const settings = await loadRuntimeSettings();\n const workflowConfig = getWorkflowConfig(settings);\n if (workflowConfig?.plan) {\n planStageProvider = workflowConfig.plan.provider;\n planStageModel = workflowConfig.plan.model;\n planStageEffort = workflowConfig.plan.effort;\n }\n } catch {\n // Fall through to default provider selection\n }\n\n // Use configured plan provider if available, otherwise fall back to detection\n const preferred = planStageProvider && available.includes(planStageProvider)\n ? planStageProvider\n : available.includes(\"claude\") ? \"claude\" : available[0];\n if (!preferred) throw new Error(\"No AI provider available for planning.\");\n\n // Fast mode: same model, effort low (embedded in prompt since CLIs don't support effort flags)\n const effectiveEffort = fast ? \"low\" : (planStageEffort || \"medium\");\n\n // Persist: planning started\n const planStartMs = Date.now();\n const session: PlanningSession = {\n title, description, status: \"planning\",\n plan: null, error: null, pid: null, provider: preferred,\n startedAt: now(), completedAt: null, updatedAt: now(),\n outputBytes: 0, usage: null,\n };\n await persistSession(session);\n\n const prompt = await buildPlanPrompt(title, description, fast);\n\n let plan: IssuePlan | null = null;\n let planUsage: PlanningSessionUsage;\n\n // ── Codex provider: call OpenAI API directly (structured output support) ──\n if (preferred === \"codex\") {\n logger.debug({ provider: preferred, model: planStageModel, effort: effectiveEffort }, \"[Planner] Using OpenAI API path for Codex provider\");\n\n try {\n const apiResult = await generatePlanViaOpenAI(prompt, planStageModel, effectiveEffort);\n const durationMs = Date.now() - planStartMs;\n apiResult.usage.durationMs = durationMs;\n\n logger.info({ rawOutput: apiResult.content.slice(0, 2000) }, `Plan raw output from ${preferred} (API)`);\n savePlanDebugFiles(\"api\", prompt, apiResult.content);\n\n plan = parsePlanOutput(apiResult.content);\n if (!plan) {\n // The API enforces JSON schema, so content should be clean JSON — try direct parse\n try {\n const directParsed = JSON.parse(apiResult.content);\n plan = tryBuildPlan(directParsed);\n } catch {\n // Fall through to error handling below\n }\n }\n\n planUsage = apiResult.usage;\n planUsage.model = apiResult.model;\n } catch (err) {\n const durationMs = Date.now() - planStartMs;\n session.status = \"error\";\n session.error = `OpenAI API call failed: ${err instanceof Error ? err.message : String(err)}`;\n session.pid = null;\n await persistSession(session);\n logger.error({ err, durationMs }, \"[Planner] OpenAI API call failed for plan generation\");\n throw new Error(session.error);\n }\n }\n // ── Claude/other providers: spawn CLI process ──\n else {\n const command = getPlanCommand(preferred, planStageModel);\n if (!command) throw new Error(`No command configured for provider ${preferred}.`);\n\n logger.debug({ provider: preferred, model: planStageModel, effort: effectiveEffort, command: command.slice(0, 120) }, \"[Planner] Provider selected for plan generation\");\n\n const tempDir = mkdtempSync(join(tmpdir(), \"fifony-plan-\"));\n const promptFile = join(tempDir, \"fifony-plan-prompt.md\");\n\n writeFileSync(promptFile, `${prompt}\\n`, \"utf8\");\n\n // Track output bytes live — persist progress periodically so the UI can show it\n let lastProgressPersist = 0;\n const PROGRESS_INTERVAL_MS = 2000;\n\n const output = await new Promise<string>((resolve, reject) => {\n let stdout = \"\";\n const child = spawn(command, {\n shell: true,\n cwd: tempDir,\n detached: true,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: {\n ...process.env,\n FIFONY_PROMPT_FILE: promptFile,\n FIFONY_AGENT_PROVIDER: preferred,\n },\n });\n child.unref();\n child.stdin?.end();\n\n // Persist PID\n if (child.pid) {\n session.pid = child.pid;\n persistSession(session).catch(() => {});\n }\n\n child.stdout?.on(\"data\", (chunk) => {\n stdout = appendFileTail(stdout, String(chunk), 32_000);\n session.outputBytes += String(chunk).length;\n // Persist progress periodically so the UI can show live output size\n const elapsed = Date.now() - planStartMs;\n if (elapsed - lastProgressPersist > PROGRESS_INTERVAL_MS) {\n lastProgressPersist = elapsed;\n persistSession(session).catch(() => {});\n }\n });\n child.stderr?.on(\"data\", (chunk) => {\n stdout = appendFileTail(stdout, String(chunk), 32_000);\n session.outputBytes += String(chunk).length;\n });\n\n const PLAN_TIMEOUT_MS = 1_800_000; // 30 minutes\n const STALE_OUTPUT_MS = 300_000; // 5 minutes without output growth → stuck\n\n const timer = setTimeout(() => {\n if (child.pid) { try { process.kill(-child.pid, \"SIGTERM\"); } catch {} }\n else { child.kill(\"SIGTERM\"); }\n reject(new Error(\"Plan generation timed out after 30 minutes.\"));\n }, PLAN_TIMEOUT_MS);\n\n // Progress watchdog: check PID alive + output growing every 30s\n let lastWatchdogBytes = 0;\n let lastOutputGrowthAt = Date.now();\n const watchdog = setInterval(() => {\n // Check if PID is still alive\n if (child.pid) {\n try { process.kill(child.pid, 0); } catch {\n clearInterval(watchdog);\n clearTimeout(timer);\n reject(new Error(`Planning process died unexpectedly (PID ${child.pid}).`));\n return;\n }\n }\n // Check if output is still growing\n if (session.outputBytes > lastWatchdogBytes) {\n lastWatchdogBytes = session.outputBytes;\n lastOutputGrowthAt = Date.now();\n } else if (Date.now() - lastOutputGrowthAt > STALE_OUTPUT_MS) {\n clearInterval(watchdog);\n clearTimeout(timer);\n if (child.pid) { try { process.kill(-child.pid, \"SIGTERM\"); } catch {} }\n else { child.kill(\"SIGTERM\"); }\n reject(new Error(`Planning process stuck — no output for ${Math.round(STALE_OUTPUT_MS / 60_000)} minutes.`));\n }\n }, 30_000);\n\n child.on(\"error\", () => { clearInterval(watchdog); clearTimeout(timer); reject(new Error(\"Failed to execute planning command.\")); });\n child.on(\"close\", (code) => {\n clearInterval(watchdog);\n clearTimeout(timer);\n rmSync(tempDir, { recursive: true, force: true });\n if (code !== 0) {\n reject(new Error(`Planning failed (exit ${code}): ${stdout.slice(0, 500)}`));\n return;\n }\n resolve(stdout);\n });\n });\n\n logger.info({ rawOutput: output.slice(0, 2000) }, `Plan raw output from ${preferred}`);\n savePlanDebugFiles(\"cli\", prompt, output);\n\n logger.debug({ outputLength: output.length }, \"[Planner] Plan command completed, parsing output\");\n plan = parsePlanOutput(output);\n\n // Extract token usage from the CLI output\n const durationMs = Date.now() - planStartMs;\n const tokenInfo = extractPlanTokenUsage(output);\n planUsage = {\n inputTokens: tokenInfo?.inputTokens ?? 0,\n outputTokens: tokenInfo?.outputTokens ?? 0,\n totalTokens: tokenInfo?.totalTokens ?? 0,\n model: tokenInfo?.model || planStageModel || preferred,\n promptChars: prompt.length,\n outputChars: output.length,\n durationMs,\n };\n }\n\n if (!plan) {\n const durationMs = Date.now() - planStartMs;\n // Persist: error\n session.status = \"error\";\n session.error = `Could not parse plan from AI output. Duration: ${durationMs}ms`;\n session.pid = null;\n await persistSession(session);\n logger.error({ durationMs }, \"[Planner] Could not parse plan from AI output\");\n throw new Error(session.error);\n }\n\n plan.provider = planStageModel ? `${preferred}/${planStageModel}` : preferred;\n\n // Record planning tokens in the ledger (counted as \"planner\" phase)\n if (planUsage.totalTokens > 0) {\n const tokenUsage: AgentTokenUsage = {\n inputTokens: planUsage.inputTokens,\n outputTokens: planUsage.outputTokens,\n totalTokens: planUsage.totalTokens,\n model: planUsage.model,\n };\n // Use a synthetic issue for the ledger record\n recordTokens({ id: \"planning\", identifier: \"PLAN\", title } as IssueEntry, tokenUsage, \"planner\");\n }\n\n // Persist: done with plan + usage\n session.status = \"done\";\n session.plan = plan;\n session.pid = null;\n session.completedAt = now();\n session.error = null;\n session.usage = planUsage;\n await persistSession(session);\n\n const tokenSummary = planUsage.totalTokens > 0\n ? `, ${planUsage.totalTokens.toLocaleString()} tokens (in: ${planUsage.inputTokens.toLocaleString()}, out: ${planUsage.outputTokens.toLocaleString()})`\n : `, ${planUsage.outputChars.toLocaleString()} output chars`;\n logger.info(`Plan generated for \"${title}\" via ${planUsage.model}: ${plan.steps.length} steps, complexity: ${plan.estimatedComplexity}${tokenSummary}, ${planUsage.durationMs}ms`);\n return { plan, usage: planUsage };\n}\n\n// ── Refine plan ──────────────────────────────────────────────────────────────\n\nasync function buildRefinePrompt(\n title: string,\n description: string,\n currentPlan: IssuePlan,\n feedback: string,\n): Promise<string> {\n return renderPrompt(\"issue-planner-refine\", {\n title,\n description: description || \"(none provided)\",\n currentPlan: JSON.stringify(currentPlan, null, 2),\n feedback,\n });\n}\n\nexport type RefinePlanResult = {\n plan: IssuePlan;\n usage: PlanningSessionUsage;\n};\n\nexport async function refinePlan(\n issue: IssueEntry,\n feedback: string,\n config: RuntimeConfig,\n workflowDefinition: WorkflowDefinition | null,\n): Promise<RefinePlanResult> {\n if (!issue.plan) throw new Error(\"Issue has no plan to refine.\");\n\n const providers = detectAvailableProviders();\n const available = providers.filter((p) => p.available).map((p) => p.name);\n\n // Use the same provider/model/effort logic as generatePlan\n let planStageProvider: string | undefined;\n let planStageModel: string | undefined;\n let planStageEffort: string | undefined;\n try {\n const settings = await loadRuntimeSettings();\n const workflowConfig = getWorkflowConfig(settings);\n if (workflowConfig?.plan) {\n planStageProvider = workflowConfig.plan.provider;\n planStageModel = workflowConfig.plan.model;\n planStageEffort = workflowConfig.plan.effort;\n }\n } catch {\n // Fall through to default provider selection\n }\n\n const preferred = planStageProvider && available.includes(planStageProvider)\n ? planStageProvider\n : available.includes(\"claude\") ? \"claude\" : available[0];\n if (!preferred) throw new Error(\"No AI provider available for plan refinement.\");\n\n const refineStartMs = Date.now();\n const prompt = await buildRefinePrompt(issue.title, issue.description, issue.plan, feedback);\n\n let plan: IssuePlan | null = null;\n let refineUsage: PlanningSessionUsage;\n\n // ── Codex provider: call OpenAI API directly (structured output support) ──\n if (preferred === \"codex\") {\n logger.debug({ provider: preferred, model: planStageModel, effort: planStageEffort }, \"[Planner] Using OpenAI API path for Codex refinement\");\n\n try {\n const apiResult = await generatePlanViaOpenAI(prompt, planStageModel, planStageEffort);\n const durationMs = Date.now() - refineStartMs;\n apiResult.usage.durationMs = durationMs;\n\n logger.info({ rawOutput: apiResult.content.slice(0, 2000) }, `Refine raw output from ${preferred} (API)`);\n savePlanDebugFiles(\"refine-api\", prompt, apiResult.content);\n\n plan = parsePlanOutput(apiResult.content);\n if (!plan) {\n try {\n const directParsed = JSON.parse(apiResult.content);\n plan = tryBuildPlan(directParsed);\n } catch {\n // Fall through to error handling below\n }\n }\n\n refineUsage = apiResult.usage;\n refineUsage.model = apiResult.model;\n } catch (err) {\n logger.error({ err }, \"[Planner] OpenAI API call failed for plan refinement\");\n throw new Error(`OpenAI API call failed for plan refinement: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n // ── Claude/other providers: spawn CLI process ──\n else {\n const command = getPlanCommand(preferred, planStageModel);\n if (!command) throw new Error(`No command configured for provider ${preferred}.`);\n\n const tempDir = mkdtempSync(join(tmpdir(), \"fifony-refine-\"));\n const promptFile = join(tempDir, \"fifony-refine-prompt.md\");\n\n writeFileSync(promptFile, `${prompt}\\n`, \"utf8\");\n\n const output = await new Promise<string>((resolve, reject) => {\n let stdout = \"\";\n const child = spawn(command, {\n shell: true,\n cwd: tempDir,\n detached: true,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: {\n ...process.env,\n FIFONY_PROMPT_FILE: promptFile,\n FIFONY_AGENT_PROVIDER: preferred,\n },\n });\n child.unref();\n child.stdin?.end();\n\n let refineOutputBytes = 0;\n child.stdout?.on(\"data\", (chunk) => {\n stdout = appendFileTail(stdout, String(chunk), 32_000);\n refineOutputBytes += String(chunk).length;\n });\n child.stderr?.on(\"data\", (chunk) => {\n stdout = appendFileTail(stdout, String(chunk), 32_000);\n refineOutputBytes += String(chunk).length;\n });\n\n const REFINE_TIMEOUT_MS = 1_800_000; // 30 minutes\n const REFINE_STALE_OUTPUT_MS = 300_000; // 5 minutes without output growth\n\n const timer = setTimeout(() => {\n if (child.pid) { try { process.kill(-child.pid, \"SIGTERM\"); } catch {} }\n else { child.kill(\"SIGTERM\"); }\n reject(new Error(\"Plan refinement timed out after 30 minutes.\"));\n }, REFINE_TIMEOUT_MS);\n\n // Progress watchdog: check PID alive + output growing every 30s\n let lastRefineWatchdogBytes = 0;\n let lastRefineOutputGrowthAt = Date.now();\n const watchdog = setInterval(() => {\n // Check if PID is still alive\n if (child.pid) {\n try { process.kill(child.pid, 0); } catch {\n clearInterval(watchdog);\n clearTimeout(timer);\n reject(new Error(`Refinement process died unexpectedly (PID ${child.pid}).`));\n return;\n }\n }\n // Check if output is still growing\n if (refineOutputBytes > lastRefineWatchdogBytes) {\n lastRefineWatchdogBytes = refineOutputBytes;\n lastRefineOutputGrowthAt = Date.now();\n } else if (Date.now() - lastRefineOutputGrowthAt > REFINE_STALE_OUTPUT_MS) {\n clearInterval(watchdog);\n clearTimeout(timer);\n if (child.pid) { try { process.kill(-child.pid, \"SIGTERM\"); } catch {} }\n else { child.kill(\"SIGTERM\"); }\n reject(new Error(`Refinement process stuck — no output for ${Math.round(REFINE_STALE_OUTPUT_MS / 60_000)} minutes.`));\n }\n }, 30_000);\n\n child.on(\"error\", () => { clearInterval(watchdog); clearTimeout(timer); reject(new Error(\"Failed to execute refinement command.\")); });\n child.on(\"close\", (code) => {\n clearInterval(watchdog);\n clearTimeout(timer);\n rmSync(tempDir, { recursive: true, force: true });\n if (code !== 0) {\n reject(new Error(`Plan refinement failed (exit ${code}): ${stdout.slice(0, 500)}`));\n return;\n }\n resolve(stdout);\n });\n });\n\n logger.info({ rawOutput: output.slice(0, 2000) }, `Refine raw output from ${preferred}`);\n savePlanDebugFiles(\"refine-cli\", prompt, output);\n\n plan = parsePlanOutput(output);\n\n const durationMs = Date.now() - refineStartMs;\n const tokenInfo = extractPlanTokenUsage(output);\n refineUsage = {\n inputTokens: tokenInfo?.inputTokens ?? 0,\n outputTokens: tokenInfo?.outputTokens ?? 0,\n totalTokens: tokenInfo?.totalTokens ?? 0,\n model: tokenInfo?.model || planStageModel || preferred,\n promptChars: prompt.length,\n outputChars: output.length,\n durationMs,\n };\n }\n\n if (!plan) {\n logger.error(\"[Planner] Could not parse refined plan from AI output\");\n throw new Error(\"Could not parse refined plan from AI output.\");\n }\n\n plan.provider = planStageModel ? `${preferred}/${planStageModel}` : preferred;\n\n // Carry over refinement history from the original plan and append the new refinement\n const existingRefinements = issue.plan.refinements ?? [];\n const nextVersion = existingRefinements.length + 1;\n plan.refinements = [\n ...existingRefinements,\n { feedback, at: now(), version: nextVersion },\n ];\n\n const durationMs = Date.now() - refineStartMs;\n refineUsage.durationMs = durationMs;\n\n // Record refinement tokens in the ledger\n if (refineUsage.totalTokens > 0) {\n const tokenUsage: AgentTokenUsage = {\n inputTokens: refineUsage.inputTokens,\n outputTokens: refineUsage.outputTokens,\n totalTokens: refineUsage.totalTokens,\n model: refineUsage.model,\n };\n recordTokens({ id: issue.id, identifier: issue.identifier, title: issue.title } as IssueEntry, tokenUsage, \"planner\");\n }\n\n const tokenSummary = refineUsage.totalTokens > 0\n ? `, ${refineUsage.totalTokens.toLocaleString()} tokens (in: ${refineUsage.inputTokens.toLocaleString()}, out: ${refineUsage.outputTokens.toLocaleString()})`\n : `, ${refineUsage.outputChars.toLocaleString()} output chars`;\n logger.info(`Plan refined for \"${issue.title}\" via ${refineUsage.model}: ${plan.steps.length} steps, complexity: ${plan.estimatedComplexity}${tokenSummary}, ${durationMs}ms`);\n return { plan, usage: refineUsage };\n}\n\n// ── Fire-and-forget wrappers ────────────────────────────────────────────────\n\nexport type PlanCallbacks = {\n addEvent: (issueId: string, kind: string, message: string) => void;\n persistState: () => Promise<void>;\n applyUsage: (issue: IssueEntry, usage: PlanningSessionUsage) => void;\n applySuggestions: (issue: IssueEntry, plan: IssuePlan) => void;\n};\n\n/**\n * Start plan generation in the background. Returns immediately.\n * Updates issue.plan and broadcasts via WS when done.\n */\nexport function generatePlanInBackground(\n issue: IssueEntry,\n config: RuntimeConfig,\n workflowDefinition: WorkflowDefinition | null,\n callbacks: PlanCallbacks,\n options?: { fast?: boolean },\n): void {\n const { addEvent, persistState, applyUsage, applySuggestions } = callbacks;\n const fast = options?.fast ?? false;\n\n issue.planningStatus = \"planning\";\n issue.planningStartedAt = now();\n issue.planningError = undefined;\n issue.updatedAt = now();\n\n addEvent(issue.id, \"info\", `${fast ? \"Fast plan\" : \"Plan\"} generation starting for ${issue.identifier} (provider detection in progress).`);\n\n // Fire-and-forget — errors are caught and stored on the issue\n generatePlan(issue.title, issue.description, config, workflowDefinition, { fast })\n .then(async ({ plan, usage }) => {\n issue.plan = plan;\n issue.planningStatus = \"idle\";\n issue.planningStartedAt = undefined;\n issue.planningError = undefined;\n issue.updatedAt = now();\n\n applyUsage(issue, usage);\n applySuggestions(issue, plan);\n\n addEvent(issue.id, \"progress\", `${fast ? \"Fast plan\" : \"Plan\"} generated for ${issue.identifier}: ${plan.steps.length} steps, complexity: ${plan.estimatedComplexity}.`);\n if (usage.totalTokens > 0) {\n addEvent(issue.id, \"info\", `Plan tokens (${issue.identifier}): ${usage.totalTokens.toLocaleString()} (in: ${usage.inputTokens.toLocaleString()}, out: ${usage.outputTokens.toLocaleString()}) [${usage.model}]`);\n }\n await persistState();\n })\n .catch(async (err) => {\n issue.planningStatus = \"idle\";\n issue.planningStartedAt = undefined;\n issue.planningError = err instanceof Error ? err.message : String(err);\n issue.updatedAt = now();\n addEvent(issue.id, \"error\", `Plan generation failed for ${issue.identifier}: ${issue.planningError}`);\n await persistState();\n logger.error({ err }, `Background plan generation failed for ${issue.identifier}`);\n });\n}\n\n/**\n * Start plan refinement in the background. Returns immediately.\n * Updates issue.plan and broadcasts via WS when done.\n */\nexport function refinePlanInBackground(\n issue: IssueEntry,\n feedback: string,\n config: RuntimeConfig,\n workflowDefinition: WorkflowDefinition | null,\n callbacks: PlanCallbacks,\n): void {\n const { addEvent, persistState, applyUsage, applySuggestions } = callbacks;\n\n issue.planningStatus = \"refining\";\n issue.planningStartedAt = now();\n issue.planningError = undefined;\n issue.updatedAt = now();\n\n const feedbackSnippet = feedback.length > 60 ? `${feedback.slice(0, 57)}...` : feedback;\n addEvent(issue.id, \"info\", `Plan refinement starting for ${issue.identifier}: \"${feedbackSnippet}\".`);\n\n refinePlan(issue, feedback, config, workflowDefinition)\n .then(async ({ plan, usage }) => {\n issue.plan = plan;\n issue.planningStatus = \"idle\";\n issue.planningStartedAt = undefined;\n issue.planningError = undefined;\n issue.updatedAt = now();\n\n applyUsage(issue, usage);\n applySuggestions(issue, plan);\n\n const feedbackPreview = feedback.length > 80 ? `${feedback.slice(0, 77)}...` : feedback;\n addEvent(issue.id, \"progress\", `Plan refined for ${issue.identifier}: \"${feedbackPreview}\" → ${plan.steps.length} steps, complexity: ${plan.estimatedComplexity}.`);\n if (usage.totalTokens > 0) {\n addEvent(issue.id, \"info\", `Refinement tokens (${issue.identifier}): ${usage.totalTokens.toLocaleString()} (in: ${usage.inputTokens.toLocaleString()}, out: ${usage.outputTokens.toLocaleString()}) [${usage.model}]`);\n }\n await persistState();\n })\n .catch(async (err) => {\n issue.planningStatus = \"idle\";\n issue.planningStartedAt = undefined;\n issue.planningError = err instanceof Error ? err.message : String(err);\n issue.updatedAt = now();\n addEvent(issue.id, \"error\", `Plan refinement failed for ${issue.identifier}: ${issue.planningError}`);\n await persistState();\n logger.error({ err }, `Background plan refinement failed for ${issue.identifier}`);\n });\n}\n","import {\n existsSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { join, basename } from \"node:path\";\nimport { spawn } from \"node:child_process\";\nimport { tmpdir } from \"node:os\";\nimport { env } from \"node:process\";\nimport { logger } from \"./logger.ts\";\nimport { detectAvailableProviders } from \"./providers.ts\";\nimport { appendFileTail } from \"./helpers.ts\";\nimport { renderPrompt } from \"../prompting.ts\";\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport type ProjectScanResult = {\n root: string;\n files: {\n claudeMd: boolean;\n claudeDir: boolean;\n codexDir: boolean;\n readmeMd: boolean;\n packageJson: boolean;\n workflowMd: boolean;\n agentsMd: boolean;\n claudeAgentsDir: boolean;\n claudeSkillsDir: boolean;\n codexAgentsDir: boolean;\n codexSkillsDir: boolean;\n };\n existingAgents: string[];\n existingSkills: string[];\n readmeExcerpt: string;\n packageName: string;\n packageDescription: string;\n};\n\nexport type ProjectAnalysis = {\n description: string;\n language: string;\n domains: string[];\n stack: string[];\n suggestedAgents: string[];\n source: \"cli\" | \"fallback\";\n};\n\n// ── Filesystem scan (no CLI needed) ──────────────────────────────────────────\n\nexport function scanProjectFiles(targetRoot: string): ProjectScanResult {\n const check = (rel: string) => existsSync(join(targetRoot, rel));\n\n const files = {\n claudeMd: check(\"CLAUDE.md\"),\n claudeDir: check(\".claude\"),\n codexDir: check(\".codex\"),\n readmeMd: check(\"README.md\"),\n packageJson: check(\"package.json\"),\n cargoToml: check(\"Cargo.toml\"),\n pyprojectToml: check(\"pyproject.toml\"),\n goMod: check(\"go.mod\"),\n buildGradle: check(\"build.gradle\") || check(\"build.gradle.kts\"),\n gemfile: check(\"Gemfile\"),\n dockerfile: check(\"Dockerfile\"),\n workflowMd: check(\"WORKFLOW.md\"),\n agentsMd: check(\"AGENTS.md\"),\n claudeAgentsDir: check(\".claude/agents\"),\n claudeSkillsDir: check(\".claude/skills\"),\n codexAgentsDir: check(\".codex/agents\"),\n codexSkillsDir: check(\".codex/skills\"),\n };\n\n // List existing agents\n const existingAgents: string[] = [];\n for (const agentDir of [\".claude/agents\", \".codex/agents\"]) {\n const fullPath = join(targetRoot, agentDir);\n if (!existsSync(fullPath)) continue;\n try {\n const entries = readdirSync(fullPath);\n for (const entry of entries) {\n if (entry.endsWith(\".md\")) {\n existingAgents.push(basename(entry, \".md\"));\n }\n }\n } catch {\n // ignore read errors\n }\n }\n\n // List existing skills\n const existingSkills: string[] = [];\n for (const skillDir of [\".claude/skills\", \".codex/skills\"]) {\n const fullPath = join(targetRoot, skillDir);\n if (!existsSync(fullPath)) continue;\n try {\n const entries = readdirSync(fullPath);\n for (const entry of entries) {\n const skillFile = join(fullPath, entry, \"SKILL.md\");\n if (existsSync(skillFile)) {\n existingSkills.push(entry);\n }\n }\n } catch {\n // ignore read errors\n }\n }\n\n // Read README excerpt\n let readmeExcerpt = \"\";\n const readmePath = join(targetRoot, \"README.md\");\n if (existsSync(readmePath)) {\n try {\n const content = readFileSync(readmePath, \"utf8\");\n readmeExcerpt = content.slice(0, 200).trim();\n } catch {\n // ignore read errors\n }\n }\n\n // Read package.json name + description\n let packageName = \"\";\n let packageDescription = \"\";\n const pkgPath = join(targetRoot, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\"));\n packageName = typeof pkg.name === \"string\" ? pkg.name : \"\";\n packageDescription = typeof pkg.description === \"string\" ? pkg.description : \"\";\n } catch {\n // ignore parse errors\n }\n }\n\n return {\n root: targetRoot,\n files,\n existingAgents: [...new Set(existingAgents)],\n existingSkills: [...new Set(existingSkills)],\n readmeExcerpt,\n packageName,\n packageDescription,\n };\n}\n\n// ── CLI-based analysis ───────────────────────────────────────────────────────\n\n// Detect language from build files present in the project root\nconst BUILD_FILE_SIGNALS: Record<string, { language: string; stack: string[] }> = {\n \"package.json\": { language: \"javascript\", stack: [\"node\"] },\n \"Cargo.toml\": { language: \"rust\", stack: [\"cargo\"] },\n \"pyproject.toml\": { language: \"python\", stack: [\"python\"] },\n \"setup.py\": { language: \"python\", stack: [\"python\"] },\n \"requirements.txt\": { language: \"python\", stack: [\"pip\"] },\n \"Pipfile\": { language: \"python\", stack: [\"pipenv\"] },\n \"go.mod\": { language: \"go\", stack: [\"go\"] },\n \"build.gradle\": { language: \"java\", stack: [\"gradle\"] },\n \"build.gradle.kts\": { language: \"kotlin\", stack: [\"gradle\"] },\n \"pom.xml\": { language: \"java\", stack: [\"maven\"] },\n \"Gemfile\": { language: \"ruby\", stack: [\"bundler\"] },\n \"mix.exs\": { language: \"elixir\", stack: [\"mix\"] },\n \"pubspec.yaml\": { language: \"dart\", stack: [\"flutter\"] },\n \"CMakeLists.txt\": { language: \"c++\", stack: [\"cmake\"] },\n \"Makefile\": { language: \"unknown\", stack: [\"make\"] },\n \"Dockerfile\": { language: \"unknown\", stack: [\"docker\"] },\n \"composer.json\": { language: \"php\", stack: [\"composer\"] },\n \"Package.swift\": { language: \"swift\", stack: [\"spm\"] },\n \"deno.json\": { language: \"typescript\", stack: [\"deno\"] },\n \"bun.lockb\": { language: \"typescript\", stack: [\"bun\"] },\n};\n\nfunction buildFallbackAnalysis(targetRoot: string): ProjectAnalysis {\n // Read any available project description\n let description = \"\";\n let readmeExcerpt = \"\";\n\n for (const readmeFile of [\"README.md\", \"README.rst\", \"README.txt\", \"README\"]) {\n const p = join(targetRoot, readmeFile);\n if (existsSync(p)) {\n try {\n readmeExcerpt = readFileSync(p, \"utf8\").slice(0, 300).trim();\n break;\n } catch { /* ignore */ }\n }\n }\n\n // Try package.json description (JS/TS projects)\n const pkgPath = join(targetRoot, \"package.json\");\n if (existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\"));\n const name = typeof pkg.name === \"string\" ? pkg.name : \"\";\n const desc = typeof pkg.description === \"string\" ? pkg.description : \"\";\n if (desc) description = name ? `${name}: ${desc}` : desc;\n } catch { /* ignore */ }\n }\n\n // Try Cargo.toml description (Rust)\n const cargoPath = join(targetRoot, \"Cargo.toml\");\n if (!description && existsSync(cargoPath)) {\n try {\n const content = readFileSync(cargoPath, \"utf8\");\n const descMatch = content.match(/^description\\s*=\\s*\"([^\"]+)\"/m);\n const nameMatch = content.match(/^name\\s*=\\s*\"([^\"]+)\"/m);\n if (descMatch) description = nameMatch ? `${nameMatch[1]}: ${descMatch[1]}` : descMatch[1];\n } catch { /* ignore */ }\n }\n\n // Try pyproject.toml description (Python)\n const pyprojectPath = join(targetRoot, \"pyproject.toml\");\n if (!description && existsSync(pyprojectPath)) {\n try {\n const content = readFileSync(pyprojectPath, \"utf8\");\n const descMatch = content.match(/^description\\s*=\\s*\"([^\"]+)\"/m);\n const nameMatch = content.match(/^name\\s*=\\s*\"([^\"]+)\"/m);\n if (descMatch) description = nameMatch ? `${nameMatch[1]}: ${descMatch[1]}` : descMatch[1];\n } catch { /* ignore */ }\n }\n\n if (!description) {\n description = readmeExcerpt\n ? readmeExcerpt.split(\"\\n\").filter(Boolean).slice(0, 2).join(\". \")\n : \"A software project.\";\n }\n\n // Detect language and stack from build files\n let language = \"unknown\";\n const stack: string[] = [];\n\n for (const [file, signal] of Object.entries(BUILD_FILE_SIGNALS)) {\n if (existsSync(join(targetRoot, file))) {\n if (language === \"unknown\" && signal.language !== \"unknown\") {\n language = signal.language;\n }\n for (const s of signal.stack) {\n if (!stack.includes(s)) stack.push(s);\n }\n }\n }\n\n return {\n description,\n language,\n domains: [],\n stack: stack.length ? stack : [language],\n suggestedAgents: [\"code-reviewer\", \"software-architect\"],\n source: \"fallback\",\n };\n}\n\nfunction parseAnalysisOutput(raw: string): ProjectAnalysis | null {\n const text = raw.trim();\n if (!text) return null;\n\n // Try to extract JSON from the output (may be wrapped in markdown or Claude JSON envelope)\n let jsonText = text;\n\n // Handle Claude --output-format json envelope: { \"result\": \"...\" }\n try {\n const envelope = JSON.parse(text);\n if (typeof envelope.result === \"string\") {\n jsonText = envelope.result.trim();\n } else if (envelope.description || envelope.domains) {\n // Already the analysis object\n return validateAnalysis(envelope);\n }\n } catch {\n // not a JSON envelope, proceed\n }\n\n // Strip markdown fences if present\n const fenced = jsonText.match(/```(?:json)?\\s*([\\s\\S]*?)\\s*```/i);\n if (fenced) {\n jsonText = fenced[1].trim();\n }\n\n try {\n const parsed = JSON.parse(jsonText);\n return validateAnalysis(parsed);\n } catch {\n // try to find JSON object in the text\n const match = jsonText.match(/\\{[\\s\\S]*\\}/);\n if (match) {\n try {\n const parsed = JSON.parse(match[0]);\n return validateAnalysis(parsed);\n } catch {\n return null;\n }\n }\n return null;\n }\n}\n\nfunction validateAnalysis(parsed: Record<string, unknown>): ProjectAnalysis | null {\n if (!parsed || typeof parsed !== \"object\") return null;\n\n const description = typeof parsed.description === \"string\" ? parsed.description.trim() : \"\";\n const language = typeof parsed.language === \"string\" ? parsed.language.trim().toLowerCase() : \"\";\n const domains = Array.isArray(parsed.domains)\n ? (parsed.domains as unknown[]).filter((d): d is string => typeof d === \"string\")\n : [];\n const stack = Array.isArray(parsed.stack)\n ? (parsed.stack as unknown[]).filter((s): s is string => typeof s === \"string\")\n : [];\n const suggestedAgents = Array.isArray(parsed.suggestedAgents)\n ? (parsed.suggestedAgents as unknown[]).filter((a): a is string => typeof a === \"string\")\n : [];\n\n if (!description && domains.length === 0 && stack.length === 0) return null;\n\n return {\n description: description || \"A software project.\",\n language,\n domains,\n stack,\n suggestedAgents,\n source: \"cli\",\n };\n}\n\n// ── Analysis cache ────────────────────────────────────────────────────────────\n\nimport { createHash } from \"node:crypto\";\nimport { getSettingStateResource } from \"./store.ts\";\n\nconst ANALYSIS_CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24h\n\nfunction computeProjectHash(targetRoot: string): string {\n const buildFiles = Object.keys(BUILD_FILE_SIGNALS);\n const found = buildFiles.filter((f) => existsSync(join(targetRoot, f))).sort();\n return createHash(\"sha256\").update(found.join(\",\")).digest(\"hex\").slice(0, 16);\n}\n\nasync function loadCachedAnalysis(targetRoot: string): Promise<ProjectAnalysis | null> {\n const resource = getSettingStateResource();\n if (!resource) return null;\n const hash = computeProjectHash(targetRoot);\n const key = `project-analysis:${hash}`;\n try {\n const record = await resource.get(key);\n if (!record?.value) return null;\n const cached = record.value as { analysis: ProjectAnalysis; updatedAt: string };\n if (!cached.analysis || !cached.updatedAt) return null;\n if (Date.now() - Date.parse(cached.updatedAt) > ANALYSIS_CACHE_TTL_MS) return null;\n return cached.analysis;\n } catch {\n return null;\n }\n}\n\nasync function saveCachedAnalysis(targetRoot: string, analysis: ProjectAnalysis): Promise<void> {\n const resource = getSettingStateResource();\n if (!resource) return;\n const hash = computeProjectHash(targetRoot);\n const key = `project-analysis:${hash}`;\n try {\n await resource.replace(key, {\n id: key,\n scope: \"system\",\n source: \"detected\",\n value: { analysis, updatedAt: new Date().toISOString() },\n });\n } catch {\n // non-critical\n }\n}\n\nexport { buildFallbackAnalysis };\n\nexport async function analyzeProjectWithCli(\n provider: string,\n targetRoot: string,\n options?: { forceRefresh?: boolean },\n): Promise<ProjectAnalysis> {\n // Check cache first\n if (!options?.forceRefresh) {\n const cached = await loadCachedAnalysis(targetRoot);\n if (cached) {\n logger.info(\"Using cached project analysis.\");\n return cached;\n }\n }\n\n const normalizedProvider = provider.trim().toLowerCase();\n const providers = detectAvailableProviders();\n const providerInfo = providers.find((p) => p.name === normalizedProvider && p.available);\n\n if (!providerInfo) {\n logger.warn(\n { provider: normalizedProvider },\n \"Requested CLI provider not available, using fallback analysis\",\n );\n return buildFallbackAnalysis(targetRoot);\n }\n\n const tempDir = mkdtempSync(join(tmpdir(), \"fifony-scan-\"));\n const promptFile = join(tempDir, \"fifony-scan-prompt.txt\");\n const analysisPrompt = await renderPrompt(\"project-analysis\");\n writeFileSync(promptFile, analysisPrompt, \"utf8\");\n\n // Build environment with prompt file path\n const processEnv: Record<string, string> = {};\n for (const [key, value] of Object.entries(env)) {\n if (typeof value === \"string\") processEnv[key] = value;\n }\n processEnv.FIFONY_PROMPT_FILE = promptFile;\n\n try {\n const output = await new Promise<string>((resolve, reject) => {\n let stdout = \"\";\n let stderr = \"\";\n let timedOut = false;\n\n let args: string[];\n let command: string;\n\n if (normalizedProvider === \"claude\") {\n command = \"claude\";\n args = [\n \"--print\",\n \"--no-session-persistence\",\n \"--output-format\", \"json\",\n \"-p\", analysisPrompt,\n ];\n } else if (normalizedProvider === \"codex\") {\n command = \"sh\";\n args = [\"-c\", `codex exec --skip-git-repo-check < \"${promptFile}\"`];\n } else {\n reject(new Error(`Unsupported provider: ${normalizedProvider}`));\n return;\n }\n\n const child = spawn(command, args, {\n cwd: targetRoot,\n env: processEnv,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n if (child.stdin) child.stdin.end();\n\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n stdout = appendFileTail(stdout, chunk.toString(\"utf8\"), 64_000);\n });\n\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n stderr = appendFileTail(stderr, chunk.toString(\"utf8\"), 16_000);\n });\n\n const timer = setTimeout(() => {\n timedOut = true;\n child.kill(\"SIGTERM\");\n }, 120_000);\n\n child.on(\"error\", (err) => {\n clearTimeout(timer);\n reject(new Error(`Failed to spawn ${normalizedProvider}: ${err.message}`));\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n if (timedOut) {\n reject(new Error(`CLI analysis timed out after 120s`));\n return;\n }\n if (code !== 0) {\n logger.debug(\n { provider: normalizedProvider, code, stderr: stderr.slice(0, 500) },\n \"CLI analysis command exited with non-zero code\",\n );\n }\n resolve(stdout);\n });\n });\n\n const analysis = parseAnalysisOutput(output);\n if (analysis) {\n logger.info(\n { provider: normalizedProvider, domains: analysis.domains, stack: analysis.stack },\n \"CLI project analysis completed\",\n );\n // Cache the result for future use\n await saveCachedAnalysis(targetRoot, analysis);\n return analysis;\n }\n\n logger.warn(\n { provider: normalizedProvider, rawOutput: output.slice(0, 500) },\n \"CLI returned unparseable output, using fallback\",\n );\n return buildFallbackAnalysis(targetRoot);\n } catch (error) {\n logger.warn(\n { err: error, provider: normalizedProvider },\n \"CLI analysis failed, using fallback\",\n );\n return buildFallbackAnalysis(targetRoot);\n } finally {\n try {\n rmSync(tempDir, { recursive: true, force: true });\n } catch {\n // ignore cleanup errors\n }\n }\n}\n","import { execFileSync } from \"node:child_process\";\nimport { logger } from \"./logger.ts\";\nimport {\n resolveTaskCapabilities,\n} from \"../routing/capability-resolver.ts\";\nimport {\n getCapabilityRoutingOptions,\n} from \"./providers.ts\";\nimport type { WorkflowDefinition } from \"./types.ts\";\n\nexport type ScannedIssue = {\n source: \"todo\" | \"fixme\" | \"hack\" | \"github\";\n title: string;\n file: string;\n line: number;\n context: string;\n category?: string;\n overlays?: string[];\n rationale?: string[];\n suggestedLabels?: string[];\n suggestedPaths?: string[];\n};\n\nconst SCAN_PATTERN = /\\b(TODO|FIXME|HACK|XXX)\\b[:\\s]*(.*)/i;\n\nconst EXCLUDE_DIRS = [\n \"node_modules\", \".git\", \".fifony\", \"dist\", \"build\",\n \".turbo\", \".next\", \".nuxt\", \"coverage\", \".venv\",\n \"vendor\", \"tmp\", \"temp\", \"artifacts\",\n];\n\nexport function scanForTodos(targetRoot: string): ScannedIssue[] {\n const excludeArgs = EXCLUDE_DIRS.flatMap((dir) => [\"--exclude-dir\", dir]);\n\n let output: string;\n try {\n output = execFileSync(\"grep\", [\n \"-rn\",\n \"-E\", \"\\\\b(TODO|FIXME|HACK|XXX)\\\\b\",\n ...excludeArgs,\n \"--include=*.ts\",\n \"--include=*.tsx\",\n \"--include=*.js\",\n \"--include=*.jsx\",\n \"--include=*.py\",\n \"--include=*.rs\",\n \"--include=*.go\",\n \"--include=*.java\",\n \"--include=*.rb\",\n \"--include=*.php\",\n \"--include=*.cs\",\n \"--include=*.swift\",\n \"--include=*.kt\",\n \"--include=*.vue\",\n \"--include=*.svelte\",\n targetRoot,\n ], {\n encoding: \"utf8\",\n timeout: 15_000,\n maxBuffer: 5_000_000,\n });\n } catch (error: any) {\n // grep returns exit code 1 when no matches found\n if (error.status === 1) return [];\n if (error.stdout) output = error.stdout;\n else {\n logger.warn(`TODO scan failed: ${String(error)}`);\n return [];\n }\n }\n\n const results: ScannedIssue[] = [];\n const lines = output.split(\"\\n\").filter(Boolean);\n\n for (const line of lines) {\n // Format: file:line:content\n const match = line.match(/^(.+?):(\\d+):(.+)$/);\n if (!match) continue;\n\n const [, file, lineNo, content] = match;\n const todoMatch = content.match(SCAN_PATTERN);\n if (!todoMatch) continue;\n\n const [, tag, text] = todoMatch;\n const source = tag.toLowerCase() as ScannedIssue[\"source\"];\n const trimmedText = text.trim();\n if (!trimmedText || trimmedText.length < 5) continue;\n\n const relativePath = file.startsWith(targetRoot)\n ? file.slice(targetRoot.length + 1)\n : file;\n\n results.push({\n source: source === \"xxx\" ? \"hack\" : source,\n title: trimmedText.length > 120 ? `${trimmedText.slice(0, 117)}...` : trimmedText,\n file: relativePath,\n line: parseInt(lineNo, 10),\n context: content.trim(),\n });\n }\n\n return results;\n}\n\n/**\n * Enrich scanned issues with capability routing metadata.\n */\nexport function categorizeScannedIssues(\n issues: ScannedIssue[],\n workflowDefinition: WorkflowDefinition | null,\n): ScannedIssue[] {\n const options = getCapabilityRoutingOptions(workflowDefinition);\n\n return issues.map((issue) => {\n const resolution = resolveTaskCapabilities({\n id: `scan-${issue.file}:${issue.line}`,\n identifier: `${issue.source}:${issue.file}:${issue.line}`,\n title: issue.title,\n description: issue.context,\n labels: [issue.source],\n paths: [issue.file],\n }, options);\n\n return {\n ...issue,\n category: resolution.category,\n overlays: resolution.overlays,\n rationale: resolution.rationale,\n suggestedLabels: [\n issue.source,\n resolution.category ? `capability:${resolution.category}` : \"\",\n ].filter(Boolean),\n suggestedPaths: [issue.file],\n };\n });\n}\n","import { execFile } from \"node:child_process\";\nimport { logger } from \"./logger.ts\";\nimport type { ScannedIssue } from \"./issue-scanner.ts\";\n\ntype GitHubIssue = {\n number: number;\n title: string;\n body: string;\n labels: Array<{ name: string }>;\n state: string;\n url: string;\n};\n\n/**\n * Fetch open GitHub issues using the `gh` CLI (no API token dependency).\n * Returns them as ScannedIssue[] for uniform handling in the dashboard.\n */\nexport async function fetchGitHubIssues(targetRoot: string): Promise<ScannedIssue[]> {\n return new Promise((resolve) => {\n execFile(\n \"gh\",\n [\n \"issue\", \"list\",\n \"--json\", \"number,title,body,labels,state,url\",\n \"--state\", \"open\",\n \"--limit\", \"50\",\n ],\n {\n cwd: targetRoot,\n timeout: 15_000,\n maxBuffer: 2_000_000,\n },\n (error, stdout) => {\n if (error) {\n logger.warn(`Failed to fetch GitHub issues: ${String(error)}`);\n resolve([]);\n return;\n }\n\n try {\n const issues = JSON.parse(stdout.trim()) as GitHubIssue[];\n const results: ScannedIssue[] = issues.map((issue) => ({\n source: \"github\" as const,\n title: issue.title,\n file: \"\",\n line: 0,\n context: (issue.body || \"\").slice(0, 500),\n suggestedLabels: issue.labels.map((l) => l.name),\n suggestedPaths: [],\n }));\n resolve(results);\n } catch (parseError) {\n logger.warn(`Failed to parse GitHub issues: ${String(parseError)}`);\n resolve([]);\n }\n },\n );\n });\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { logger } from \"./logger.ts\";\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport type AgentCatalogEntry = {\n name: string;\n displayName: string;\n description: string;\n emoji: string;\n domains: string[];\n source: string;\n content: string;\n};\n\nexport type SkillCatalogEntry = {\n name: string;\n displayName: string;\n description: string;\n domains: string[];\n source: string;\n installType: \"reference\" | \"bundled\";\n url?: string;\n content?: string;\n};\n\nexport type InstallResult = {\n installed: string[];\n skipped: string[];\n errors: Array<{ name: string; error: string }>;\n};\n\n// ── Catalog loaders ──────────────────────────────────────────────────────────\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nfunction resolveFixturePath(filename: string): string {\n // In dev (ts source): src/agent/ -> src/fixtures/\n // In dist (compiled): dist/ -> src/fixtures/ (via PACKAGE_ROOT)\n const candidates = [\n join(__dirname, \"..\", \"fixtures\", filename),\n join(__dirname, \"../..\", \"src\", \"fixtures\", filename),\n join(__dirname, \"../../..\", \"src\", \"fixtures\", filename),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) return candidate;\n }\n\n // Fallback: return the first candidate path (will error on read)\n return candidates[0];\n}\n\nexport function loadAgentCatalog(): AgentCatalogEntry[] {\n try {\n const filePath = resolveFixturePath(\"agent-catalog.json\");\n const raw = readFileSync(filePath, \"utf8\");\n return JSON.parse(raw) as AgentCatalogEntry[];\n } catch (error) {\n logger.error({ err: error }, \"Failed to load agent catalog\");\n return [];\n }\n}\n\nexport function loadSkillCatalog(): SkillCatalogEntry[] {\n try {\n const filePath = resolveFixturePath(\"skill-catalog.json\");\n const raw = readFileSync(filePath, \"utf8\");\n return JSON.parse(raw) as SkillCatalogEntry[];\n } catch (error) {\n logger.error({ err: error }, \"Failed to load skill catalog\");\n return [];\n }\n}\n\n// ── Filter by domains ────────────────────────────────────────────────────────\n\nexport function filterByDomains<T extends { domains: string[] }>(\n catalog: T[],\n domains: string[],\n): T[] {\n const domainSet = new Set(domains.map((d) => d.toLowerCase().trim()));\n if (domainSet.size === 0) return catalog;\n\n const scored = catalog.map((entry) => {\n const matchCount = entry.domains.filter((d) => domainSet.has(d.toLowerCase())).length;\n return { entry, matchCount };\n });\n\n // Include only entries that match at least one domain, sorted by match count descending\n return scored\n .filter((item) => item.matchCount > 0)\n .sort((a, b) => b.matchCount - a.matchCount)\n .map((item) => item.entry);\n}\n\n// ── Install agents ───────────────────────────────────────────────────────────\n\nexport function installAgents(\n targetRoot: string,\n agentNames: string[],\n catalog: AgentCatalogEntry[],\n): InstallResult {\n const result: InstallResult = { installed: [], skipped: [], errors: [] };\n const catalogMap = new Map(catalog.map((entry) => [entry.name, entry]));\n const agentsDir = join(targetRoot, \".claude\", \"agents\");\n\n // Ensure directory exists\n try {\n mkdirSync(agentsDir, { recursive: true });\n } catch (error) {\n logger.error({ err: error, path: agentsDir }, \"Failed to create agents directory\");\n result.errors.push({ name: \"_directory\", error: `Failed to create ${agentsDir}` });\n return result;\n }\n\n for (const name of agentNames) {\n const entry = catalogMap.get(name);\n if (!entry) {\n result.errors.push({ name, error: \"Agent not found in catalog\" });\n continue;\n }\n\n const filePath = join(agentsDir, `${name}.md`);\n if (existsSync(filePath)) {\n result.skipped.push(name);\n continue;\n }\n\n try {\n writeFileSync(filePath, entry.content, \"utf8\");\n result.installed.push(name);\n logger.info({ agent: name, path: filePath }, \"Agent installed\");\n } catch (error) {\n result.errors.push({\n name,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return result;\n}\n\n// ── Install skills ───────────────────────────────────────────────────────────\n\nexport function installSkills(\n targetRoot: string,\n skillNames: string[],\n catalog: SkillCatalogEntry[],\n): InstallResult {\n const result: InstallResult = { installed: [], skipped: [], errors: [] };\n const catalogMap = new Map(catalog.map((entry) => [entry.name, entry]));\n const skillsDir = join(targetRoot, \".claude\", \"skills\");\n\n // Ensure directory exists\n try {\n mkdirSync(skillsDir, { recursive: true });\n } catch (error) {\n logger.error({ err: error, path: skillsDir }, \"Failed to create skills directory\");\n result.errors.push({ name: \"_directory\", error: `Failed to create ${skillsDir}` });\n return result;\n }\n\n for (const name of skillNames) {\n const entry = catalogMap.get(name);\n if (!entry) {\n result.errors.push({ name, error: \"Skill not found in catalog\" });\n continue;\n }\n\n const skillDir = join(skillsDir, name);\n const filePath = join(skillDir, \"SKILL.md\");\n if (existsSync(filePath)) {\n result.skipped.push(name);\n continue;\n }\n\n try {\n mkdirSync(skillDir, { recursive: true });\n\n if (entry.installType === \"bundled\" && entry.content) {\n writeFileSync(filePath, entry.content, \"utf8\");\n } else {\n // For reference skills, create a SKILL.md pointing to the external source\n const referenceContent = [\n `# ${entry.displayName}`,\n \"\",\n entry.description,\n \"\",\n `**Source**: ${entry.source}`,\n entry.url ? `**URL**: ${entry.url}` : \"\",\n \"\",\n `> This skill references an external resource. Install it from the source above.`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n writeFileSync(filePath, referenceContent, \"utf8\");\n }\n\n result.installed.push(name);\n logger.info({ skill: name, path: filePath, type: entry.installType }, \"Skill installed\");\n } catch (error) {\n result.errors.push({\n name,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return result;\n}\n","/**\n * Development server that runs Vite dev server alongside the API.\n * Uses dynamic import so vite (devDependency) is only loaded when --dev is used.\n */\nimport { resolve } from \"node:path\";\nimport { PACKAGE_ROOT } from \"./constants.ts\";\nimport { logger } from \"./logger.ts\";\n\nconst VITE_CONFIG_PATH = resolve(PACKAGE_ROOT, \"app/vite.config.js\");\n\nexport async function startDevFrontend(apiPort: number, devPort: number): Promise<void> {\n let createViteServer: typeof import(\"vite\").createServer;\n try {\n const vite = await import(\"vite\");\n createViteServer = vite.createServer;\n } catch {\n logger.warn(\"Vite not installed (devDependency). Run 'pnpm install' in the project to enable --dev mode.\");\n return;\n }\n\n try {\n const server = await createViteServer({\n configFile: VITE_CONFIG_PATH,\n server: {\n port: devPort,\n host: true,\n proxy: {\n \"/api\": `http://localhost:${apiPort}`,\n \"/ws\": { target: `ws://localhost:${apiPort}`, ws: true },\n \"/docs\": `http://localhost:${apiPort}`,\n \"/health\": `http://localhost:${apiPort}`,\n \"/manifest.webmanifest\": `http://localhost:${apiPort}`,\n \"/service-worker.js\": `http://localhost:${apiPort}`,\n \"/icon.svg\": `http://localhost:${apiPort}`,\n \"/icon-maskable.svg\": `http://localhost:${apiPort}`,\n \"/offline.html\": `http://localhost:${apiPort}`,\n },\n },\n });\n\n await server.listen();\n logger.info(`Dev frontend available at http://localhost:${devPort}`);\n } catch (error) {\n logger.warn(`Failed to start Vite dev server: ${String(error)}`);\n }\n}\n"],"mappings":"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","names":["mkdirSync","env","exit","argv","env","resolve","env","env","env","join","mkdirSync","env","usage","now","event","join","homedir","join","homedir","join","homedir","resolve","stdout","env","execSync","appendFileSync","existsSync","readFileSync","statSync","writeFileSync","existsSync","mkdirSync","readdirSync","readFileSync","statSync","writeFileSync","join","env","spawn","existsSync","readFileSync","homedir","join","resolve","existsSync","readdirSync","readFileSync","argv","existsSync","argv","writeFileSync","join","env","join","join","env","writeFileSync","join","usage","join","existsSync","readFileSync","readdirSync","statSync","mkdirSync","agentSessionResource","record","agentPipelineResource","resolve","writeFileSync","spawn","env","context","execSync","existsSync","readFileSync","readdirSync","join","homedir","env","homedir","env","join","existsSync","readdirSync","now","execSync","readFileSync","usage","resolve","env","existsSync","readFileSync","rmSync","writeFileSync","spawn","join","existsSync","readFileSync","join","homedir","join","homedir","existsSync","readFileSync","durationMs","usage","buildPrompt","context","existsSync","readFileSync","join","writeFileSync","env","resolve","spawn","rmSync","mkdtempSync","mkdirSync","writeFileSync","rmSync","spawn","join","tmpdir","join","mkdirSync","writeFileSync","record","usage","mkdtempSync","tmpdir","resolve","stdout","spawn","rmSync","durationMs","addEvent","persistState","existsSync","mkdtempSync","readdirSync","readFileSync","rmSync","writeFileSync","join","basename","spawn","tmpdir","env","existsSync","join","readdirSync","basename","readFileSync","record","mkdtempSync","join","tmpdir","writeFileSync","env","resolve","stdout","spawn","rmSync","execFileSync","execFileSync","resolve","stdout","existsSync","mkdirSync","readFileSync","writeFileSync","join","dirname","fileURLToPath","__filename","fileURLToPath","__dirname","dirname","join","existsSync","readFileSync","mkdirSync","writeFileSync","join","stateDb","record","findIssue","usage","existsSync","readFileSync","providers","stat","statSync","execSync","basename","writeFileSync","appendFileSync","mkdirSync","record","resolve","resolve","argv","mkdirSync","env","exit"]}
|
|
1
|
+
{"version":3,"sources":["../../src/agent/run-local.ts","../../src/agent/dev-server.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { mkdirSync } from \"node:fs\";\nimport { env, exit, argv } from \"node:process\";\nimport { CLI_ARGS, STATE_ROOT, TARGET_ROOT } from \"./constants.ts\";\nimport { debugBoot, fail, now } from \"./helpers.ts\";\nimport { initLogger, logger } from \"./logger.ts\";\nimport { initStateStore, loadPersistedState, persistState, persistStateFull, closeStateStore } from \"./store.ts\";\nimport { initQueueWorkers, stopQueueWorkers } from \"./queue-workers.ts\";\nimport {\n applyPersistedSettings,\n loadRuntimeSettings,\n persistDetectedProvidersSetting,\n syncRuntimeConfigSettings,\n} from \"./settings.ts\";\nimport { buildQueueTitle, detectProjectName, resolveProjectMetadata } from \"./project-meta.ts\";\nimport {\n detectAvailableProviders,\n resolveDefaultProvider,\n getProviderDefaultCommand,\n} from \"./providers.ts\";\nimport { parsePort, setSkipSource } from \"./workflow.ts\";\nimport { deriveConfig, applyWorkflowConfig, buildRuntimeState, computeMetrics, addEvent, validateConfig } from \"./issues.ts\";\nimport { startApiServer } from \"./api-server.ts\";\nimport { scheduler, installGracefulShutdown } from \"./scheduler.ts\";\nimport { cleanWorkspace, isAgentStillRunning, cleanStalePidFile } from \"./agent.ts\";\nimport { startDevFrontend } from \"./dev-server.ts\";\nimport { recoverPlanningSession } from \"./issue-planner.ts\";\nimport { hydrate as hydrateTokenLedger } from \"./token-ledger.ts\";\nimport { detectDefaultBranch } from \"./workspace-setup.ts\";\nimport type { RuntimeState } from \"./types.ts\";\n\nfunction usage() {\n console.log(\n `Usage: ${argv[1]} [options]\\n` +\n \"Options:\\n\" +\n \" --workspace <path> Target workspace root (default: current directory)\\n\" +\n \" --persistence <path> Persistence root (default: current directory)\\n\" +\n \" --port <n> Start local dashboard\\n\" +\n \" --concurrency <n> Maximum number of local workers\\n\" +\n \" --attempts <n> Maximum attempts per issue\\n\" +\n \" --poll <ms> Scheduler interval in ms\\n\" +\n \" --timeout <ms> Agent command timeout in ms (default: 1800000)\\n\" +\n \" --dev Start Vite dev server alongside API (HMR on port+1)\\n\" +\n \" --once Process once and exit\\n\" +\n \" --skip-source Skip source snapshot copy\\n\" +\n \" --skip-scan Skip project analysis\\n\" +\n \" --skip-recovery Skip orphaned agent recovery\\n\" +\n \" --fast-boot Equivalent to --skip-source --skip-scan --skip-recovery\\n\",\n );\n}\n\nasync function main() {\n debugBoot(\"main:start\");\n\n const args = CLI_ARGS;\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n usage();\n return;\n }\n\n mkdirSync(STATE_ROOT, { recursive: true });\n initLogger(STATE_ROOT);\n logger.info(\"[Boot] Fifony runtime starting\");\n logger.info({ stateRoot: STATE_ROOT, cwd: process.cwd() }, \"[Boot] State root initialized\");\n\n // Detect available providers\n const detectedProviders = detectAvailableProviders();\n for (const p of detectedProviders) {\n logger.info(`Provider ${p.name}: ${p.available ? `available at ${p.path}` : \"not found\"}`);\n }\n\n const interfaceMode = (env.FIFONY_INTERFACE ?? \"cli\").trim().toLowerCase();\n const runOnce = args.includes(\"--once\");\n const devMode = args.includes(\"--dev\") || env.NODE_ENV === \"development\";\n const fastBoot = args.includes(\"--fast-boot\");\n const skipSource = fastBoot || args.includes(\"--skip-source\");\n if (skipSource) setSkipSource(true);\n\n debugBoot(\"main:state-root-ready\");\n\n const port = parsePort(args);\n let config = applyWorkflowConfig(deriveConfig(args), port);\n\n // Auto-resolve provider command if not configured\n if (!config.agentCommand.trim()) {\n const defaultProvider = resolveDefaultProvider(detectedProviders);\n if (defaultProvider) {\n const defaultCommand = getProviderDefaultCommand(defaultProvider);\n if (defaultCommand) {\n config = { ...config, agentProvider: defaultProvider, agentCommand: defaultCommand };\n logger.info(`Auto-detected provider: ${defaultProvider} → ${defaultCommand}`);\n }\n }\n }\n\n const dashboardPort = port ?? (config.dashboardPort ? Number.parseInt(config.dashboardPort, 10) : undefined);\n const skipRecovery = args.includes(\"--skip-recovery\") || args.includes(\"--fast-boot\");\n const detectedProjectName = detectProjectName(TARGET_ROOT);\n\n // ── Phase B: Parallel initialization ────────────────────────────────────────\n debugBoot(\"main:phase-b-start\");\n logger.debug(\"[Boot] Initializing state store (s3db)\");\n await initStateStore();\n logger.info(\"[Boot] State store initialized\");\n debugBoot(\"main:store-initialized\");\n\n // ── Early API start: dashboard available while boot continues ─────────────\n // Build a minimal placeholder state for the early API server\n const earlyState: RuntimeState = {\n projectName: detectedProjectName,\n detectedProjectName,\n projectNameSource: detectedProjectName ? \"detected\" : \"missing\",\n queueTitle: buildQueueTitle(detectedProjectName),\n startedAt: now(),\n updatedAt: now(),\n trackerKind: \"filesystem\",\n sourceRepoUrl: TARGET_ROOT,\n sourceRef: \"workspace\",\n config,\n issues: [],\n events: [],\n metrics: { total: 0, planning: 0, queued: 0, inProgress: 0, blocked: 0, done: 0, cancelled: 0, activeWorkers: 0 },\n notes: [],\n booting: true,\n };\n\n let apiState = earlyState;\n if (dashboardPort) {\n await startApiServer(apiState, dashboardPort);\n debugBoot(\"main:api-server-early-start\");\n\n if (devMode) {\n const devPort = dashboardPort + 1;\n await startDevFrontend(dashboardPort, devPort);\n }\n }\n\n // ── Phase C: Parallel state loading ─────────────────────────────────────────\n debugBoot(\"main:phase-c-start\");\n logger.debug(\"[Boot] Loading persisted state, settings, and recovering sessions\");\n const [previous, persistedSettings] = await Promise.all([\n loadPersistedState(),\n loadRuntimeSettings(),\n persistDetectedProvidersSetting(detectedProviders),\n recoverPlanningSession(),\n ]);\n logger.info({ hadPreviousState: previous !== null, issueCount: previous?.issues?.length ?? 0, settingsCount: persistedSettings.length }, \"[Boot] State loaded from persistence\");\n debugBoot(\"main:state-loaded\");\n\n config = applyPersistedSettings(config, persistedSettings);\n await syncRuntimeConfigSettings(config, persistedSettings);\n const projectMetadata = resolveProjectMetadata(persistedSettings, TARGET_ROOT);\n const state = buildRuntimeState(previous, config, projectMetadata);\n debugBoot(\"main:state-merged\");\n\n state.config.dashboardPort = dashboardPort ? String(dashboardPort) : undefined;\n state.updatedAt = now();\n state.booting = false;\n\n // Detect and lock the default branch once at startup\n if (!state.config.defaultBranch) {\n try {\n const detectedBranch = detectDefaultBranch(TARGET_ROOT);\n state.config.defaultBranch = detectedBranch;\n logger.info({ defaultBranch: detectedBranch }, \"[Agent] Default branch detected\");\n } catch {\n // Not a git repo or detection failed — leave undefined\n }\n }\n\n if (state.config.agentCommand) {\n state.notes.push(`Using agent command: ${state.config.agentCommand}`);\n }\n state.notes.push(`Agent session max turns: ${state.config.maxTurns}`);\n state.notes.push(`Agent provider: ${state.config.agentProvider}`);\n state.notes.push(`Interface mode: ${interfaceMode}`);\n\n if (!state.config.agentCommand.trim()) {\n const available = detectedProviders.filter((p) => p.available).map((p) => p.name);\n fail(\n available.length === 0\n ? \"No agent command configured and no providers (claude, codex) found in PATH.\\nInstall claude or codex, or set FIFONY_AGENT_COMMAND.\"\n : \"No agent command configured. Set FIFONY_AGENT_COMMAND.\",\n );\n }\n\n // Validate config at startup (spec §6.3)\n const configErrors = validateConfig(config);\n if (configErrors.length > 0) {\n for (const err of configErrors) logger.warn(`Config validation: ${err}`);\n }\n\n // Clean terminal workspaces in background (non-blocking boot)\n const terminalIssues = state.issues.filter((i) => i.state === \"Done\" || i.state === \"Cancelled\");\n if (terminalIssues.length > 0) {\n logger.info(`Scheduling cleanup of ${terminalIssues.length} terminal workspace(s) in background...`);\n setImmediate(async () => {\n for (const issue of terminalIssues) {\n try { await cleanWorkspace(issue.id, issue, state); } catch {}\n }\n logger.info(\"Background workspace cleanup complete.\");\n });\n }\n\n // Recover orphaned agent processes from previous session\n if (!skipRecovery) {\n logger.debug({ issueCount: state.issues.filter((i) => i.state === \"Running\" || i.state === \"Queued\").length }, \"[Boot] Checking for orphaned agent processes\");\n for (const issue of state.issues) {\n if (issue.state === \"Running\" || issue.state === \"Queued\") {\n const { alive, pid } = isAgentStillRunning(issue);\n if (alive && pid) {\n logger.info(`Agent for ${issue.identifier} still alive (PID ${pid.pid}), keeping state as Running.`);\n issue.state = \"Running\";\n addEvent(state, issue.id, \"info\", `Orphaned agent detected (PID ${pid.pid}), still alive — tracking resumed.`);\n } else {\n // Agent died — clean PID file, mark as Queued for resumption\n if (issue.workspacePath) cleanStalePidFile(issue.workspacePath);\n if (issue.state === \"Running\") {\n issue.state = \"Queued\";\n issue.history.push(`[${now()}] Agent process not found on boot — marked Queued.`);\n addEvent(state, issue.id, \"info\", `Agent for ${issue.identifier} not found, marked Queued.`);\n }\n }\n }\n }\n }\n\n state.metrics = computeMetrics(state.issues);\n await persistStateFull(state);\n\n // Initialize queue workers after state is fully ready\n try {\n await initQueueWorkers(state);\n } catch (error) {\n logger.warn({ err: error }, \"[Boot] Queue workers failed to initialize — continuing without queue-based dispatch\");\n }\n\n // Update the API server to use the real state (swap reference)\n if (dashboardPort) {\n // The API server closure captures apiState — mutate it to point to real state\n Object.assign(apiState, state);\n debugBoot(\"main:api-state-swapped\");\n }\n\n const running = new Set<string>();\n installGracefulShutdown(state, running);\n\n logger.info(\"[Boot] Runtime ready\");\n hydrateTokenLedger(state.issues);\n logger.info(`Loaded issues: ${state.issues.length}`);\n logger.info(`Worker concurrency: ${state.config.workerConcurrency}`);\n logger.info(`Max attempts: ${state.config.maxAttemptsDefault}`);\n logger.info(`Max turns: ${state.config.maxTurns}`);\n logger.info(`Agent provider: ${state.config.agentProvider}`);\n logger.info(`Interface mode: ${interfaceMode}`);\n\n try {\n addEvent(state, undefined, \"info\", `Runtime started in local-only mode (filesystem tracker).`);\n const runForever = !runOnce && (Boolean(dashboardPort) || interfaceMode === \"mcp\");\n logger.info({ runForever, runOnce, dashboardPort, interfaceMode }, \"[Boot] Entering scheduler loop\");\n await scheduler(state, running, runForever);\n } catch (error) {\n console.error(\"FATAL STACK TRACE:\", error);\n addEvent(state, undefined, \"error\", `Fatal runtime error: ${String(error)}`);\n await persistState(state);\n throw error;\n } finally {\n state.updatedAt = now();\n state.metrics = computeMetrics(state.issues);\n await persistStateFull(state);\n try { await stopQueueWorkers(); } catch {}\n await closeStateStore();\n }\n}\n\nmain().catch((error) => {\n logger.error({ err: error }, `Fatal runtime error: ${String(error)}`);\n exit(1);\n});\n","/**\n * Development server that runs Vite dev server alongside the API.\n * Uses dynamic import so vite (devDependency) is only loaded when --dev is used.\n */\nimport { resolve } from \"node:path\";\nimport { PACKAGE_ROOT } from \"./constants.ts\";\nimport { logger } from \"./logger.ts\";\n\nconst VITE_CONFIG_PATH = resolve(PACKAGE_ROOT, \"app/vite.config.js\");\n\nexport async function startDevFrontend(apiPort: number, devPort: number): Promise<void> {\n let createViteServer: typeof import(\"vite\").createServer;\n try {\n const vite = await import(\"vite\");\n createViteServer = vite.createServer;\n } catch {\n logger.warn(\"Vite not installed (devDependency). Run 'pnpm install' in the project to enable --dev mode.\");\n return;\n }\n\n try {\n const server = await createViteServer({\n configFile: VITE_CONFIG_PATH,\n server: {\n port: devPort,\n host: true,\n proxy: {\n \"/api\": `http://localhost:${apiPort}`,\n \"/ws\": { target: `ws://localhost:${apiPort}`, ws: true },\n \"/docs\": `http://localhost:${apiPort}`,\n \"/health\": `http://localhost:${apiPort}`,\n \"/manifest.webmanifest\": `http://localhost:${apiPort}`,\n \"/service-worker.js\": `http://localhost:${apiPort}`,\n \"/icon.svg\": `http://localhost:${apiPort}`,\n \"/icon-maskable.svg\": `http://localhost:${apiPort}`,\n \"/offline.html\": `http://localhost:${apiPort}`,\n },\n },\n });\n\n await server.listen();\n logger.info(`Dev frontend available at http://localhost:${devPort}`);\n } catch (error) {\n logger.warn(`Failed to start Vite dev server: ${String(error)}`);\n }\n}\n"],"mappings":"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","names":[]}
|