@codemoot/core 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/mcp.ts","../src/utils/constants.ts","../src/utils/id.ts","../src/utils/errors.ts","../src/utils/sleep.ts","../src/utils/retry.ts","../src/utils/logger.ts","../src/utils/verdict.ts","../src/config/defaults.ts","../src/config/schema.ts","../src/config/presets.ts","../src/config/loader.ts","../src/config/migration.ts","../src/config/review-presets.ts","../src/config/ignore.ts","../src/memory/database.ts","../src/memory/session-store.ts","../src/memory/memory-store.ts","../src/memory/artifact-store.ts","../src/memory/cost-store.ts","../src/memory/debate-store.ts","../src/memory/build-store.ts","../src/security/dlp.ts","../src/memory/message-store.ts","../src/memory/reconstruction.ts","../src/memory/token-budget.ts","../src/memory/unified-session.ts","../src/memory/job-store.ts","../src/memory/cache-store.ts","../src/models/cli-adapter.ts","../src/models/cli-detector.ts","../src/models/registry.ts","../src/security/retry.ts","../src/models/caller.ts","../src/models/fallback.ts","../src/models/cost-tracker.ts","../src/models/pricing.ts","../src/roles/prompts.ts","../src/roles/role-manager.ts","../src/engine/event-bus.ts","../src/engine/loop-controller.ts","../src/engine/orchestrator.ts","../src/context/context-builder.ts","../src/engine/debate-engine.ts","../src/engine/step-runner.ts","../src/engine/workflow-engine.ts","../src/engine/cancellation.ts","../src/engine/policy.ts","../src/cleanup/scanners.ts","../src/cleanup/merge.ts","../src/cleanup/host-schema.ts","../src/index.ts"],"sourcesContent":["// packages/core/src/types/mcp.ts — MCP tool types from approved architecture\n\nimport { z } from 'zod';\nimport { DEFAULT_TIMEOUT_SEC, MCP_CONTENT_MAX_LENGTH, MCP_TASK_MAX_LENGTH, MCP_TIMEOUT_MAX } from '../utils/constants.js';\n\n// -- Error codes from MCP_ARCHITECTURE_APPROVED §12 --\nexport enum ErrorCode {\n INVALID_INPUT = 'INVALID_INPUT',\n MODEL_UNAVAILABLE = 'MODEL_UNAVAILABLE',\n RATE_LIMITED = 'RATE_LIMITED',\n TIMEOUT = 'TIMEOUT',\n DLP_BLOCKED = 'DLP_BLOCKED',\n EGRESS_BLOCKED = 'EGRESS_BLOCKED',\n BUDGET_EXCEEDED = 'BUDGET_EXCEEDED',\n CLI_NOT_FOUND = 'CLI_NOT_FOUND',\n CLI_AUTH_FAILED = 'CLI_AUTH_FAILED',\n CANCELLED = 'CANCELLED',\n INTERNAL_ERROR = 'INTERNAL_ERROR',\n}\n\nexport enum TerminalReason {\n COMPLETED = 'COMPLETED',\n TIMEOUT = 'TIMEOUT',\n CANCELLED = 'CANCELLED',\n BUDGET_EXCEEDED = 'BUDGET_EXCEEDED',\n MAX_RETRIES = 'MAX_RETRIES',\n}\n\nexport type ResultStatus = 'success' | 'partial' | 'error';\n\nexport enum DlpReasonCode {\n SECRET_DETECTED = 'SECRET_DETECTED',\n HIGH_ENTROPY = 'HIGH_ENTROPY',\n ABSOLUTE_PATH = 'ABSOLUTE_PATH',\n CONTEXT_TRUNCATED = 'CONTEXT_TRUNCATED',\n DECODE_BLOCKED = 'DECODE_BLOCKED',\n BUDGET_EXCEEDED = 'BUDGET_EXCEEDED',\n}\n\nexport type MeteringSource = 'billed' | 'estimated' | 'sdk';\n\n// -- Result interfaces --\nexport interface ReviewResult {\n status: ResultStatus;\n score: number;\n verdict: 'approved' | 'needs_revision';\n feedback: string[];\n tokenUsage: { inputTokens: number; outputTokens: number; totalTokens: number; costUsd: number };\n latencyMs: number;\n meteringSource: MeteringSource;\n model: string;\n egressControl: 'codemoot-enforced' | 'cli-managed';\n}\n\nexport interface DebateResponse {\n model: string;\n role: string;\n text: string;\n tokenUsage: { inputTokens: number; outputTokens: number; totalTokens: number; costUsd: number };\n latencyMs: number;\n meteringSource: MeteringSource;\n error?: string;\n}\n\nexport interface DebateResult {\n status: ResultStatus;\n responses: DebateResponse[];\n synthesis?: string;\n agreement?: number;\n totalTokenUsage: {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n costUsd: number;\n };\n partialFailure?: boolean;\n egressControl: 'codemoot-enforced' | 'cli-managed';\n}\n\n// -- Zod schemas for MCP tool inputs --\nexport const reviewInputSchema = z.object({\n content: z.string().min(1).max(MCP_CONTENT_MAX_LENGTH),\n criteria: z.array(z.string()).optional(),\n model: z.string().optional(),\n strict: z.boolean().optional().default(true),\n timeout: z.number().positive().max(MCP_TIMEOUT_MAX).optional().default(DEFAULT_TIMEOUT_SEC),\n});\nexport type ReviewInput = z.infer<typeof reviewInputSchema>;\n\nexport const planInputSchema = z.object({\n task: z.string().min(1).max(MCP_TASK_MAX_LENGTH),\n maxRounds: z.number().int().positive().max(10).optional().default(3),\n stream: z.boolean().optional().default(false),\n timeout: z.number().positive().max(MCP_TIMEOUT_MAX).optional().default(DEFAULT_TIMEOUT_SEC),\n});\nexport type PlanInput = z.infer<typeof planInputSchema>;\n\nexport const debateInputSchema = z.object({\n question: z.string().min(1).max(MCP_TASK_MAX_LENGTH),\n models: z.array(z.string()).min(1).max(5).optional(),\n synthesize: z.boolean().optional().default(false),\n maxRounds: z.number().int().min(1).max(10).optional().default(3),\n timeout: z.number().positive().max(MCP_TIMEOUT_MAX).optional().default(DEFAULT_TIMEOUT_SEC),\n});\nexport type DebateInput = z.infer<typeof debateInputSchema>;\n\nexport const memoryInputSchema = z.object({\n action: z.enum(['save', 'search', 'get', 'delete']),\n content: z.string().optional(),\n query: z.string().optional(),\n memoryId: z.number().int().positive().optional(),\n category: z.enum(['decision', 'convention', 'pattern', 'issue', 'preference']).optional(),\n importance: z.number().min(0).max(1).optional().default(0.5),\n timeout: z.number().positive().max(30).optional().default(5),\n});\nexport type MemoryInput = z.infer<typeof memoryInputSchema>;\n\nexport const costInputSchema = z.object({\n scope: z.enum(['session', 'daily', 'all']).optional().default('session'),\n sessionId: z.string().optional(),\n days: z.number().int().positive().max(365).optional().default(30),\n timeout: z.number().positive().max(30).optional().default(5),\n});\nexport type CostInput = z.infer<typeof costInputSchema>;\n\n// -- Zod schemas for MCP tool outputs --\nexport const reviewOutputSchema = z.object({\n status: z.enum(['success', 'partial', 'error']),\n score: z.number(),\n verdict: z.enum(['approved', 'needs_revision']),\n feedback: z.array(z.string()),\n tokenUsage: z.object({\n inputTokens: z.number(),\n outputTokens: z.number(),\n totalTokens: z.number(),\n costUsd: z.number(),\n }),\n latencyMs: z.number(),\n meteringSource: z.enum(['billed', 'estimated', 'sdk']),\n model: z.string(),\n egressControl: z.enum(['codemoot-enforced', 'cli-managed']),\n});\n\nexport const debateOutputSchema = z.object({\n status: z.enum(['success', 'partial', 'error']),\n responses: z.array(\n z.object({\n model: z.string(),\n role: z.string(),\n text: z.string(),\n tokenUsage: z.object({\n inputTokens: z.number(),\n outputTokens: z.number(),\n totalTokens: z.number(),\n costUsd: z.number(),\n }),\n latencyMs: z.number(),\n meteringSource: z.enum(['billed', 'estimated', 'sdk']),\n error: z.string().optional(),\n }),\n ),\n synthesis: z.string().optional(),\n agreement: z.number().optional(),\n totalTokenUsage: z.object({\n inputTokens: z.number(),\n outputTokens: z.number(),\n totalTokens: z.number(),\n costUsd: z.number(),\n }),\n partialFailure: z.boolean().optional(),\n egressControl: z.enum(['codemoot-enforced', 'cli-managed']),\n});\n","// packages/core/src/utils/constants.ts — Shared magic number constants\n\n/** Default timeout for model calls in seconds */\nexport const DEFAULT_TIMEOUT_SEC = 600;\n\n/** Default cleanup scan timeout in seconds */\nexport const CLEANUP_TIMEOUT_SEC = 1200;\n\n/** Default max tokens for model output */\nexport const DEFAULT_MAX_TOKENS = 4096;\n\n/** Implementer max tokens (larger for code generation) */\nexport const IMPLEMENTER_MAX_TOKENS = 8192;\n\n/** Max content length for MCP review input */\nexport const MCP_CONTENT_MAX_LENGTH = 100000;\n\n/** Max content length for MCP task/question input */\nexport const MCP_TASK_MAX_LENGTH = 50000;\n\n/** Max timeout for MCP tool calls in seconds */\nexport const MCP_TIMEOUT_MAX = 900;\n\n/** HTTP 429 Too Many Requests status code */\nexport const HTTP_TOO_MANY_REQUESTS = 429;\n\n/** Days in a year (for cost aggregation) */\nexport const DAYS_PER_YEAR = 365;\n\n/** Max diff size sent to reviewer */\nexport const REVIEW_DIFF_MAX_CHARS = 50000;\n\n/** Max review text stored in DB */\nexport const REVIEW_TEXT_MAX_CHARS = 5000;\n\n/** Binary detection buffer size */\nexport const BINARY_SNIFF_BYTES = 512;\n\n/** Context budget defaults */\nexport const CONTEXT_ACTIVE = 8000;\nexport const CONTEXT_RETRIEVED = 4000;\nexport const CONTEXT_BUFFER = 2000;\n\n/** DLP max content length */\nexport const DLP_MAX_CONTENT = 2000;\n\n/** DLP max processing time in milliseconds */\nexport const DLP_MAX_PROCESSING_MS = 2000;\n","// packages/core/src/utils/id.ts\n\nimport { nanoid } from 'nanoid';\n\n/** Generate a session ID with \"ses_\" prefix. */\nexport function generateSessionId(): string {\n return `ses_${nanoid(21)}`;\n}\n\n/** Generate a generic unique ID. */\nexport function generateId(prefix?: string): string {\n const id = nanoid(16);\n return prefix ? `${prefix}_${id}` : id;\n}\n","// packages/core/src/utils/errors.ts\n\nexport class ConfigError extends Error {\n constructor(\n message: string,\n public readonly field?: string,\n ) {\n super(message);\n this.name = 'ConfigError';\n }\n}\n\nexport class ModelError extends Error {\n constructor(\n message: string,\n public readonly provider?: string,\n public readonly model?: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = 'ModelError';\n }\n\n get isRateLimit(): boolean {\n return this.statusCode === 429;\n }\n\n get isTimeout(): boolean {\n return this.message.includes('timeout') || this.message.includes('ETIMEDOUT');\n }\n\n get isServerError(): boolean {\n return this.statusCode !== undefined && this.statusCode >= 500;\n }\n}\n\nexport class WorkflowError extends Error {\n constructor(\n message: string,\n public readonly stepId?: string,\n ) {\n super(message);\n this.name = 'WorkflowError';\n }\n}\n\nexport class DatabaseError extends Error {\n constructor(\n message: string,\n public readonly operation?: string,\n ) {\n super(message);\n this.name = 'DatabaseError';\n }\n}\n","// packages/core/src/utils/sleep.ts — Shared async delay utility\n\n/** Promise-based delay. */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","// packages/core/src/utils/retry.ts\r\n\r\nimport { sleep } from './sleep.js';\r\n\r\nexport interface RetryOptions {\r\n attempts: number;\r\n backoff: number;\r\n retryOn?: (error: unknown) => boolean;\r\n}\r\n\r\nconst defaultOptions: RetryOptions = {\r\n attempts: 3,\r\n backoff: 1000,\r\n};\r\n\r\n/**\r\n * Retry an async function with exponential backoff.\r\n * Returns the result on success, throws the last error after all attempts exhausted.\r\n */\r\nexport async function withRetry<T>(\r\n fn: () => Promise<T>,\r\n options?: Partial<RetryOptions>,\r\n): Promise<T> {\r\n const opts = { ...defaultOptions, ...options };\r\n let lastError: unknown;\r\n\r\n for (let attempt = 1; attempt <= opts.attempts; attempt++) {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n lastError = error;\r\n\r\n if (opts.retryOn && !opts.retryOn(error)) {\r\n throw error;\r\n }\r\n\r\n if (attempt < opts.attempts) {\r\n const delay = opts.backoff * 2 ** (attempt - 1);\r\n await sleep(delay);\r\n }\r\n }\r\n }\r\n\r\n throw lastError;\r\n}\r\n\r\n","// packages/core/src/utils/logger.ts\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport interface Logger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nexport function createLogger(level: LogLevel = 'info'): Logger {\n const threshold = LOG_LEVELS[level];\n\n function log(msgLevel: LogLevel, message: string, args: unknown[]): void {\n if (LOG_LEVELS[msgLevel] >= threshold) {\n const timestamp = new Date().toISOString();\n const prefix = `[${timestamp}] ${msgLevel.toUpperCase()}:`;\n if (args.length > 0) {\n console[msgLevel === 'debug' ? 'log' : msgLevel](prefix, message, ...args);\n } else {\n console[msgLevel === 'debug' ? 'log' : msgLevel](prefix, message);\n }\n }\n }\n\n return {\n debug: (message, ...args) => log('debug', message, args),\n info: (message, ...args) => log('info', message, args),\n warn: (message, ...args) => log('warn', message, args),\n error: (message, ...args) => log('error', message, args),\n };\n}\n","// packages/core/src/utils/verdict.ts\n\nexport interface VerdictResult {\n verdict: 'approved' | 'needs_revision';\n feedback: string;\n}\n\nconst VERDICT_PATTERN = /VERDICT:\\s*(APPROVED|NEEDS_REVISION)/i;\n\n/**\n * Parse a reviewer response to extract the verdict.\n *\n * Looks for \"VERDICT: APPROVED\" or \"VERDICT: NEEDS_REVISION\" in the response.\n * If APPROVED, feedback is empty.\n * If NEEDS_REVISION, feedback is the text before the verdict line.\n * If no match, conservatively returns needs_revision with the full response as feedback.\n */\nexport function parseVerdict(response: string): VerdictResult {\n const match = VERDICT_PATTERN.exec(response);\n\n if (!match) {\n return { verdict: 'needs_revision', feedback: response.trim() };\n }\n\n const verdictStr = match[1].toUpperCase();\n\n if (verdictStr === 'APPROVED') {\n return { verdict: 'approved', feedback: '' };\n }\n\n // NEEDS_REVISION: feedback is everything before the VERDICT line\n const verdictIndex = match.index;\n const feedback = response.slice(0, verdictIndex).trim();\n return { verdict: 'needs_revision', feedback };\n}\n","// packages/core/src/config/defaults.ts\r\n\r\nimport type { ProjectConfig } from '../types/config.js';\r\nimport { CONTEXT_ACTIVE, CONTEXT_BUFFER, CONTEXT_RETRIEVED, DEFAULT_MAX_TOKENS, DEFAULT_TIMEOUT_SEC, IMPLEMENTER_MAX_TOKENS } from '../utils/constants.js';\r\n\r\nexport const DEFAULT_CONFIG: ProjectConfig = {\r\n project: {\r\n name: '',\r\n description: '',\r\n },\r\n models: {\r\n 'codex-architect': {\r\n provider: 'openai',\r\n model: 'gpt-5.3-codex',\r\n maxTokens: DEFAULT_MAX_TOKENS,\r\n temperature: 0.7,\r\n timeout: DEFAULT_TIMEOUT_SEC,\r\n },\r\n 'codex-reviewer': {\r\n provider: 'openai',\r\n model: 'gpt-5.3-codex',\r\n maxTokens: DEFAULT_MAX_TOKENS,\r\n temperature: 0.3,\r\n timeout: DEFAULT_TIMEOUT_SEC,\r\n },\r\n },\r\n roles: {\r\n architect: {\r\n model: 'codex-architect',\r\n temperature: 0.7,\r\n maxTokens: DEFAULT_MAX_TOKENS,\r\n },\r\n reviewer: {\r\n model: 'codex-reviewer',\r\n temperature: 0.3,\r\n maxTokens: DEFAULT_MAX_TOKENS,\r\n },\r\n implementer: {\r\n model: 'codex-architect',\r\n temperature: 0.4,\r\n maxTokens: IMPLEMENTER_MAX_TOKENS,\r\n },\r\n },\r\n workflow: 'plan-review-implement',\r\n mode: 'autonomous',\r\n debate: {\r\n defaultPattern: 'proposal-critique',\r\n maxRounds: 3,\r\n consensusThreshold: 0.7,\r\n },\r\n memory: {\r\n autoExtractFacts: true,\r\n contextBudget: {\r\n activeContext: CONTEXT_ACTIVE,\r\n retrievedMemory: CONTEXT_RETRIEVED,\r\n messageBuffer: CONTEXT_BUFFER,\r\n },\r\n },\r\n budget: {\r\n perSession: 5.0,\r\n perDay: 25.0,\r\n perMonth: 200.0,\r\n warningAt: 0.8,\r\n action: 'warn',\r\n },\r\n output: {\r\n saveTranscripts: true,\r\n transcriptFormat: 'markdown',\r\n transcriptDir: '.cowork/transcripts',\r\n },\r\n advanced: {\r\n retryAttempts: 3,\r\n stream: true,\r\n logLevel: 'info',\r\n },\r\n};\r\n","// packages/core/src/config/schema.ts\n\nimport { z } from 'zod';\nimport { CONTEXT_ACTIVE, CONTEXT_BUFFER, CONTEXT_RETRIEVED, DEFAULT_MAX_TOKENS, DEFAULT_TIMEOUT_SEC } from '../utils/constants.js';\nimport { ConfigError } from '../utils/errors.js';\n\nconst modelProviderSchema = z.literal('openai');\n\nconst cliAdapterConfigSchema = z.object({\n command: z.string().min(1),\n args: z.array(z.string()),\n timeout: z.number().positive(),\n outputFile: z.string().optional(),\n maxOutputBytes: z.number().int().positive().optional(),\n envAllowlist: z.array(z.string()).optional(),\n});\n\nconst modelConfigSchema = z.object({\n provider: modelProviderSchema,\n model: z.string().min(1),\n maxTokens: z.number().int().positive().default(DEFAULT_MAX_TOKENS),\n temperature: z.number().min(0).max(2).default(0.7),\n timeout: z.number().positive().default(DEFAULT_TIMEOUT_SEC),\n cliAdapter: cliAdapterConfigSchema.optional(),\n});\n\nconst roleConfigSchema = z.object({\n model: z.string().min(1),\n temperature: z.number().min(0).max(2).optional(),\n maxTokens: z.number().int().positive().optional(),\n systemPromptFile: z.string().optional(),\n});\n\nconst debatePatternSchema = z.enum([\n 'structured-rounds',\n 'proposal-critique',\n 'free-flowing',\n 'parallel-panel',\n]);\n\nconst debateConfigSchema = z.object({\n defaultPattern: debatePatternSchema.default('proposal-critique'),\n maxRounds: z.number().int().positive().max(10).default(3),\n consensusThreshold: z.number().min(0).max(1).default(0.7),\n});\n\nconst memoryConfigSchema = z.object({\n embeddingModel: z.string().optional(),\n autoExtractFacts: z.boolean().default(true),\n contextBudget: z\n .object({\n activeContext: z.number().int().positive().default(CONTEXT_ACTIVE),\n retrievedMemory: z.number().int().positive().default(CONTEXT_RETRIEVED),\n messageBuffer: z.number().int().positive().default(CONTEXT_BUFFER),\n })\n .default({}),\n});\n\nconst budgetConfigSchema = z.object({\n perSession: z.number().nonnegative().default(5.0),\n perDay: z.number().nonnegative().default(25.0),\n perMonth: z.number().nonnegative().default(200.0),\n warningAt: z.number().min(0).max(1).default(0.8),\n action: z.enum(['warn', 'pause', 'block']).default('warn'),\n});\n\nconst outputConfigSchema = z.object({\n saveTranscripts: z.boolean().default(true),\n transcriptFormat: z.enum(['markdown', 'json']).default('markdown'),\n transcriptDir: z.string().default('.cowork/transcripts'),\n});\n\nconst executionModeSchema = z.enum(['autonomous', 'interactive', 'dashboard']);\n\nconst advancedConfigSchema = z.object({\n retryAttempts: z.number().int().positive().max(10).default(3),\n stream: z.boolean().default(true),\n logLevel: z.enum(['debug', 'info', 'warn', 'error']).default('info'),\n});\n\nexport const projectConfigSchema = z\n .object({\n configVersion: z.number().int().positive().optional(),\n project: z\n .object({\n name: z.string().default(''),\n description: z.string().default(''),\n })\n .default({}),\n models: z.record(z.string(), modelConfigSchema),\n roles: z.record(z.string(), roleConfigSchema),\n workflow: z.string().default('plan-review-implement'),\n mode: executionModeSchema.default('autonomous'),\n debate: debateConfigSchema.default({}),\n memory: memoryConfigSchema.default({}),\n budget: budgetConfigSchema.default({}),\n output: outputConfigSchema.default({}),\n advanced: advancedConfigSchema.default({}),\n })\n .superRefine((data, ctx) => {\n const modelAliases = Object.keys(data.models);\n for (const [roleName, roleConfig] of Object.entries(data.roles)) {\n if (!modelAliases.includes(roleConfig.model)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['roles', roleName, 'model'],\n message: `Role \"${roleName}\" references model \"${roleConfig.model}\" which is not defined in models. Available: ${modelAliases.join(', ')}`,\n });\n }\n }\n });\n\nexport type ProjectConfigInput = z.input<typeof projectConfigSchema>;\n\n/**\n * Validate and parse a config object. Throws ConfigError on invalid input.\n */\nexport function validateConfig(config: unknown): z.output<typeof projectConfigSchema> {\n const result = projectConfigSchema.safeParse(config);\n if (!result.success) {\n const issues = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');\n throw new ConfigError(`Invalid configuration: ${issues}`);\n }\n return result.data;\n}\n","// packages/core/src/config/presets.ts\n\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { parse as parseYaml } from 'yaml';\nimport type { PresetName } from '../types/config.js';\nimport { ConfigError } from '../utils/errors.js';\n\nconst PRESETS_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..', 'presets');\n\nconst VALID_PRESETS: PresetName[] = ['cli-first'];\n\n/**\n * Load a built-in preset by name. Returns a partial config to be merged with defaults.\n */\nexport function loadPreset(name: PresetName): Record<string, unknown> {\n if (!VALID_PRESETS.includes(name)) {\n throw new ConfigError(\n `Unknown preset: \"${name}\". Valid presets: ${VALID_PRESETS.join(', ')}`,\n 'preset',\n );\n }\n\n const filePath = join(PRESETS_DIR, `${name}.yml`);\n try {\n const content = readFileSync(filePath, 'utf-8');\n return parseYaml(content) as Record<string, unknown>;\n } catch (err) {\n throw new ConfigError(\n `Failed to load preset \"${name}\": ${err instanceof Error ? err.message : String(err)}`,\n 'preset',\n );\n }\n}\n\n/** List available preset names. */\nexport function listPresets(): PresetName[] {\n return [...VALID_PRESETS];\n}\n","// packages/core/src/config/loader.ts\n\nimport { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml';\nimport type { PresetName, ProjectConfig } from '../types/config.js';\nimport { ConfigError } from '../utils/errors.js';\nimport { DEFAULT_CONFIG } from './defaults.js';\nimport { loadPreset } from './presets.js';\nimport { validateConfig } from './schema.js';\n\nconst CONFIG_FILENAME = '.cowork.yml';\n\n/**\n * Deep merge two objects. Source values overwrite target values.\n * Arrays are replaced, not merged.\n */\nfunction deepMerge<T extends Record<string, unknown>>(\n target: T,\n source: Record<string, unknown>,\n): T {\n const result = { ...target } as Record<string, unknown>;\n for (const key of Object.keys(source)) {\n const srcVal = source[key];\n const tgtVal = result[key];\n if (\n srcVal !== null &&\n typeof srcVal === 'object' &&\n !Array.isArray(srcVal) &&\n tgtVal !== null &&\n typeof tgtVal === 'object' &&\n !Array.isArray(tgtVal)\n ) {\n result[key] = deepMerge(tgtVal as Record<string, unknown>, srcVal as Record<string, unknown>);\n } else {\n result[key] = srcVal;\n }\n }\n return result as T;\n}\n\n/**\n * Load config with precedence: overrides > .cowork.yml > preset > defaults.\n *\n * 1. Start with hardcoded defaults\n * 2. If a preset name is found (in file or overrides), merge preset on top\n * 3. Merge .cowork.yml from projectDir on top\n * 4. Merge programmatic overrides on top\n * 5. Validate the final result\n */\nexport function loadConfig(options?: {\n projectDir?: string;\n preset?: PresetName;\n overrides?: Partial<ProjectConfig>;\n skipFile?: boolean;\n}): ProjectConfig {\n const projectDir = options?.projectDir ?? process.cwd();\n let merged: Record<string, unknown> = structuredClone(DEFAULT_CONFIG) as unknown as Record<\n string,\n unknown\n >;\n\n // Layer 2: Preset\n if (options?.preset) {\n const presetConfig = loadPreset(options.preset);\n merged = deepMerge(merged, presetConfig);\n }\n\n // Layer 3: Project file (.cowork.yml)\n const configPath = join(projectDir, CONFIG_FILENAME);\n if (!options?.skipFile && existsSync(configPath)) {\n try {\n const content = readFileSync(configPath, 'utf-8');\n const fileConfig = parseYaml(content) as Record<string, unknown>;\n if (fileConfig && typeof fileConfig === 'object') {\n merged = deepMerge(merged, fileConfig);\n }\n } catch (err) {\n throw new ConfigError(\n `Failed to parse ${CONFIG_FILENAME}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n // Layer 4: Programmatic overrides\n if (options?.overrides) {\n merged = deepMerge(merged, options.overrides as Record<string, unknown>);\n }\n\n return validateConfig(merged);\n}\n\n/**\n * Write a ProjectConfig to .cowork.yml in the given directory.\n * Also creates .cowork/db/ and .cowork/transcripts/ directories.\n */\nexport function writeConfig(config: ProjectConfig, dir: string): void {\n const configPath = join(dir, CONFIG_FILENAME);\n const yamlContent = stringifyYaml(config, { lineWidth: 100 });\n writeFileSync(configPath, yamlContent, 'utf-8');\n\n // Create project directories\n mkdirSync(join(dir, '.cowork', 'db'), { recursive: true });\n mkdirSync(join(dir, '.cowork', 'transcripts'), { recursive: true });\n\n // Append to .gitignore if not already there\n const gitignorePath = join(dir, '.gitignore');\n if (existsSync(gitignorePath)) {\n const content = readFileSync(gitignorePath, 'utf-8');\n if (!content.includes('.cowork/')) {\n appendFileSync(gitignorePath, '\\n.cowork/\\n');\n }\n } else {\n writeFileSync(gitignorePath, '.cowork/\\n', 'utf-8');\n }\n}\n\nexport { deepMerge };\n","// packages/core/src/config/migration.ts\n\nimport { copyFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { stringify as stringifyYaml } from 'yaml';\nimport type { ProjectConfig } from '../types/config.js';\nimport { ConfigError } from '../utils/errors.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('info');\nconst CURRENT_VERSION = 2;\n\n/**\n * Migrate a ProjectConfig from an older schema version to the current version.\n * Creates a .bak backup before writing changes if configPath is provided.\n * Returns the migrated config (always in-memory; optionally persisted to disk).\n */\nexport function migrateConfig(config: ProjectConfig, configPath?: string): ProjectConfig {\n const fromVersion = config.configVersion ?? 1;\n\n if (fromVersion > CURRENT_VERSION) {\n throw new ConfigError(\n `Config version ${fromVersion} requires a newer version of CodeMoot. Please upgrade.`,\n 'configVersion',\n );\n }\n\n if (fromVersion >= CURRENT_VERSION) return config;\n\n // Pre-migration backup\n if (configPath) {\n const backupPath = `${configPath}.bak`;\n try {\n copyFileSync(configPath, backupPath);\n log.info(`Config backup created at ${backupPath}`);\n } catch {\n log.warn('Failed to create config backup');\n }\n }\n\n let migrated = { ...config };\n\n if (fromVersion < 2) {\n migrated = migrateV1ToV2(migrated);\n }\n\n // Write back (atomic: write to temp then rename)\n if (configPath) {\n const tmpPath = `${configPath}.tmp`;\n try {\n const content = stringifyYaml(migrated, { lineWidth: 100 });\n writeFileSync(tmpPath, content, 'utf-8');\n renameSync(tmpPath, configPath);\n log.info(`Config migrated from v${fromVersion} to v${CURRENT_VERSION}`);\n } catch (err) {\n log.warn(\n `Failed to write migrated config: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n return migrated;\n}\n\nfunction migrateV1ToV2(config: ProjectConfig): ProjectConfig {\n return { ...config, configVersion: 2 };\n}\n\nexport { CURRENT_VERSION };\n","// packages/core/src/config/review-presets.ts — Named review preset configurations\n\nimport { CLEANUP_TIMEOUT_SEC, MCP_TIMEOUT_MAX } from '../utils/constants.js';\n\nexport interface ReviewPreset {\n name: string;\n focus: string;\n constraints: string[];\n timeoutSec: number;\n severityFloor: 'info' | 'warning' | 'critical';\n strictOutput: boolean;\n}\n\nexport const REVIEW_PRESETS: Record<string, ReviewPreset> = {\n 'security-audit': {\n name: 'security-audit',\n focus: 'security',\n constraints: [\n 'Prioritize exploitable paths and data flow.',\n 'Map source-to-sink paths for injection, SSRF, deserialization.',\n 'Flag missing rate limiting and audit logging.',\n 'Check for secrets, hardcoded credentials, and unsafe dependencies.',\n ],\n timeoutSec: CLEANUP_TIMEOUT_SEC,\n severityFloor: 'info',\n strictOutput: true,\n },\n performance: {\n name: 'performance',\n focus: 'performance',\n constraints: [\n 'Prefer measurable bottlenecks over speculative issues.',\n 'Flag N+1 queries, unnecessary IO, memory churn, sync blocking.',\n 'Suggest profiling points where relevant.',\n ],\n timeoutSec: MCP_TIMEOUT_MAX,\n severityFloor: 'warning',\n strictOutput: false,\n },\n 'quick-scan': {\n name: 'quick-scan',\n focus: 'bugs',\n constraints: [\n 'Return only top issues by impact.',\n 'Skip speculative findings.',\n 'Be concise — under 500 words.',\n ],\n timeoutSec: 240,\n severityFloor: 'warning',\n strictOutput: false,\n },\n 'pre-commit': {\n name: 'pre-commit',\n focus: 'bugs',\n constraints: [\n 'Only report CRITICAL and WARNING severity.',\n 'Minimize false positives — err on the side of silence.',\n 'Focus on changed code only.',\n ],\n timeoutSec: 180,\n severityFloor: 'warning',\n strictOutput: true,\n },\n 'api-review': {\n name: 'api-review',\n focus: 'all',\n constraints: [\n 'Check backward compatibility and schema drift.',\n 'Validate status codes, error shapes, and pagination.',\n 'Review auth boundaries and idempotency.',\n ],\n timeoutSec: MCP_TIMEOUT_MAX,\n severityFloor: 'info',\n strictOutput: false,\n },\n};\n\nexport function getReviewPreset(name: string): ReviewPreset | undefined {\n return REVIEW_PRESETS[name];\n}\n\nexport function listPresetNames(): string[] {\n return Object.keys(REVIEW_PRESETS);\n}\n","// packages/core/src/config/ignore.ts — .gitignore + .codemootignore aware file filtering\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport ignore, { type Ignore } from 'ignore';\n\nconst BUILTIN_IGNORES = [\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n 'target',\n 'release',\n 'out',\n '.cowork',\n '.cache',\n '.turbo',\n '.next',\n '__pycache__',\n 'vendor',\n 'coverage',\n '*.db',\n '*.db-journal',\n '*.db-wal',\n '*.db-shm',\n '.env',\n '.env.*',\n];\n\n/**\n * Load and compile all ignore patterns into a single matcher.\n * Precedence: builtins -> .gitignore -> .codemootignore\n */\nexport function createIgnoreFilter(projectDir: string, options?: { skipGitignore?: boolean }): Ignore {\n const ig = ignore();\n\n // 1. Builtins\n ig.add(BUILTIN_IGNORES);\n\n // 2. .gitignore (root only for now)\n if (!options?.skipGitignore) {\n const gitignorePath = join(projectDir, '.gitignore');\n if (existsSync(gitignorePath)) {\n const content = readFileSync(gitignorePath, 'utf-8');\n ig.add(content);\n }\n }\n\n // 3. .codemootignore (highest priority — can override builtins/.gitignore)\n const codemootIgnorePath = join(projectDir, '.codemootignore');\n if (existsSync(codemootIgnorePath)) {\n const content = readFileSync(codemootIgnorePath, 'utf-8');\n ig.add(content);\n }\n\n return ig;\n}\n\n// ── Legacy API (kept for existing tests) ──\n\nexport function loadIgnorePatterns(projectDir: string): string[] {\n const patterns = [...BUILTIN_IGNORES];\n const ignorePath = join(projectDir, '.codemootignore');\n if (existsSync(ignorePath)) {\n const content = readFileSync(ignorePath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith('#')) {\n patterns.push(trimmed);\n }\n }\n }\n return patterns;\n}\n\nexport function shouldIgnore(filePath: string, patterns: string[]): boolean {\n const normalized = filePath.replace(/\\\\/g, '/');\n for (const pattern of patterns) {\n if (pattern.startsWith('!')) continue;\n if (\n normalized.includes(`/${pattern}/`) ||\n normalized.endsWith(`/${pattern}`) ||\n normalized === pattern\n ) {\n return true;\n }\n if (pattern.startsWith('*.') && normalized.endsWith(pattern.slice(1))) {\n return true;\n }\n }\n return false;\n}\n","// packages/core/src/memory/database.ts\n\nimport Database from 'better-sqlite3';\nimport { DatabaseError } from '../utils/errors.js';\n\nconst SCHEMA_VERSION = '8';\n\nconst MIGRATIONS = [\n // Sessions\n `CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL,\n task TEXT NOT NULL,\n workflow_id TEXT NOT NULL,\n mode TEXT NOT NULL DEFAULT 'autonomous',\n status TEXT NOT NULL DEFAULT 'running',\n config_snapshot TEXT,\n current_step TEXT,\n summary TEXT,\n total_tokens INTEGER DEFAULT 0,\n total_cost REAL DEFAULT 0,\n started_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n completed_at DATETIME,\n metadata JSON\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_id)',\n 'CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status)',\n 'CREATE INDEX IF NOT EXISTS idx_sessions_started ON sessions(started_at DESC)',\n\n // Messages (transcript entries)\n `CREATE TABLE IF NOT EXISTS messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n step_id TEXT,\n iteration INTEGER,\n role TEXT NOT NULL,\n model_id TEXT,\n content TEXT NOT NULL,\n token_count INTEGER,\n cost REAL,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n metadata JSON\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id)',\n 'CREATE INDEX IF NOT EXISTS idx_messages_step ON messages(session_id, step_id)',\n 'CREATE INDEX IF NOT EXISTS idx_messages_role ON messages(session_id, role)',\n\n // Artifacts\n `CREATE TABLE IF NOT EXISTS artifacts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n step_id TEXT NOT NULL,\n iteration INTEGER NOT NULL DEFAULT 1,\n type TEXT NOT NULL,\n file_path TEXT,\n content TEXT NOT NULL,\n version INTEGER DEFAULT 1,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n metadata JSON\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_artifacts_session ON artifacts(session_id)',\n 'CREATE INDEX IF NOT EXISTS idx_artifacts_step ON artifacts(session_id, step_id)',\n\n // Decisions\n `CREATE TABLE IF NOT EXISTS decisions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n step_id TEXT NOT NULL,\n decision_type TEXT NOT NULL,\n reason TEXT,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_decisions_session ON decisions(session_id)',\n\n // Memories\n `CREATE TABLE IF NOT EXISTS memories (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n project_id TEXT NOT NULL,\n category TEXT NOT NULL,\n content TEXT NOT NULL,\n source_session_id TEXT REFERENCES sessions(id) ON DELETE SET NULL,\n importance REAL DEFAULT 0.5,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n accessed_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n access_count INTEGER DEFAULT 0\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_memories_project ON memories(project_id)',\n 'CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(project_id, category)',\n 'CREATE INDEX IF NOT EXISTS idx_memories_importance ON memories(importance DESC)',\n\n // Memories FTS5\n `CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(\n content,\n category,\n content='memories',\n content_rowid='id'\n )`,\n\n // FTS sync triggers\n `CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN\n INSERT INTO memories_fts(rowid, content, category)\n VALUES (new.id, new.content, new.category);\n END`,\n `CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, content, category)\n VALUES ('delete', old.id, old.content, old.category);\n END`,\n `CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, content, category)\n VALUES ('delete', old.id, old.content, old.category);\n INSERT INTO memories_fts(rowid, content, category)\n VALUES (new.id, new.content, new.category);\n END`,\n\n // Cost log\n `CREATE TABLE IF NOT EXISTS cost_log (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT REFERENCES sessions(id) ON DELETE SET NULL,\n step_id TEXT,\n model_id TEXT NOT NULL,\n input_tokens INTEGER NOT NULL DEFAULT 0,\n output_tokens INTEGER NOT NULL DEFAULT 0,\n cost_usd REAL NOT NULL DEFAULT 0,\n latency_ms INTEGER,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_cost_session ON cost_log(session_id)',\n 'CREATE INDEX IF NOT EXISTS idx_cost_model ON cost_log(model_id)',\n 'CREATE INDEX IF NOT EXISTS idx_cost_date ON cost_log(created_at)',\n\n // Debate turns (session resume persistence)\n `CREATE TABLE IF NOT EXISTS debate_turns (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n debate_id TEXT NOT NULL,\n role TEXT NOT NULL,\n codex_session_id TEXT,\n round INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL DEFAULT 'active',\n resume_fail_count INTEGER DEFAULT 0,\n last_activity_at INTEGER NOT NULL,\n created_at INTEGER NOT NULL,\n state_json TEXT\n )`,\n 'CREATE UNIQUE INDEX IF NOT EXISTS idx_debate_turns_unique ON debate_turns(debate_id, role)',\n 'CREATE INDEX IF NOT EXISTS idx_debate_turns_status ON debate_turns(status)',\n 'CREATE INDEX IF NOT EXISTS idx_debate_turns_activity ON debate_turns(last_activity_at)',\n\n // Build runs (automated build loop sessions)\n `CREATE TABLE IF NOT EXISTS build_runs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n build_id TEXT NOT NULL UNIQUE,\n task TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'planning',\n current_phase TEXT NOT NULL DEFAULT 'debate',\n current_loop INTEGER NOT NULL DEFAULT 0,\n last_event_seq INTEGER NOT NULL DEFAULT 0,\n phase_cursor TEXT NOT NULL DEFAULT '{}',\n debate_id TEXT,\n baseline_ref TEXT,\n plan_codex_session TEXT,\n review_codex_session TEXT,\n plan_version INTEGER DEFAULT 0,\n review_cycles INTEGER DEFAULT 0,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n completed_at INTEGER,\n metadata TEXT\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_build_runs_status ON build_runs(status)',\n 'CREATE INDEX IF NOT EXISTS idx_build_runs_updated ON build_runs(updated_at DESC)',\n\n // Build events (append-only log)\n `CREATE TABLE IF NOT EXISTS build_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n build_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n event_type TEXT NOT NULL,\n actor TEXT NOT NULL,\n phase TEXT NOT NULL,\n loop_index INTEGER DEFAULT 0,\n payload TEXT,\n codex_thread_id TEXT,\n tokens_used INTEGER DEFAULT 0,\n created_at INTEGER NOT NULL\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_build_events_build ON build_events(build_id, seq)',\n 'CREATE INDEX IF NOT EXISTS idx_build_events_type ON build_events(build_id, event_type)',\n\n // Debate messages (full conversation persistence)\n `CREATE TABLE IF NOT EXISTS debate_messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n debate_id TEXT NOT NULL,\n round INTEGER NOT NULL CHECK(round >= 0),\n role TEXT NOT NULL,\n bridge TEXT NOT NULL DEFAULT 'codex',\n model TEXT NOT NULL,\n prompt_text TEXT NOT NULL,\n response_text TEXT,\n stance TEXT CHECK(stance IN ('SUPPORT','OPPOSE','UNCERTAIN') OR stance IS NULL),\n confidence REAL CHECK(confidence IS NULL OR (confidence >= 0 AND confidence <= 1)),\n verdict_raw TEXT,\n usage_json TEXT,\n duration_ms INTEGER CHECK(duration_ms IS NULL OR duration_ms >= 0),\n session_id TEXT,\n status TEXT NOT NULL DEFAULT 'queued' CHECK(status IN ('queued','running','completed','failed')),\n error TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n completed_at INTEGER\n )`,\n 'CREATE UNIQUE INDEX IF NOT EXISTS idx_dm_unique ON debate_messages(debate_id, round, role)',\n 'CREATE INDEX IF NOT EXISTS idx_dm_debate ON debate_messages(debate_id)',\n 'CREATE INDEX IF NOT EXISTS idx_dm_status ON debate_messages(status)',\n\n // Unified sessions (one codex thread per session)\n `CREATE TABLE IF NOT EXISTS codemoot_sessions (\n id TEXT PRIMARY KEY,\n name TEXT,\n codex_thread_id TEXT,\n status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active','completed','stale')),\n token_usage INTEGER DEFAULT 0,\n max_context INTEGER DEFAULT 400000,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n completed_at INTEGER\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_csess_status ON codemoot_sessions(status)',\n 'CREATE INDEX IF NOT EXISTS idx_csess_updated ON codemoot_sessions(updated_at DESC)',\n\n // Session events (append-only audit trail of every GPT interaction)\n `CREATE TABLE IF NOT EXISTS session_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL REFERENCES codemoot_sessions(id),\n command TEXT NOT NULL,\n subcommand TEXT,\n prompt_preview TEXT,\n response_preview TEXT,\n usage_json TEXT,\n duration_ms INTEGER,\n codex_thread_id TEXT,\n created_at INTEGER NOT NULL\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_sevt_session ON session_events(session_id)',\n 'CREATE INDEX IF NOT EXISTS idx_sevt_command ON session_events(session_id, command)',\n\n // Add session_id to debate_messages (nullable for backward compat)\n // Note: SQLite doesn't support ADD COLUMN IF NOT EXISTS, so we use a pragma check approach\n // For new DBs this column is in the CREATE TABLE; for upgrades we add it via ALTER TABLE below\n\n // Jobs queue (background async work)\n `CREATE TABLE IF NOT EXISTS jobs (\n id TEXT PRIMARY KEY,\n type TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'queued',\n priority INTEGER NOT NULL DEFAULT 100,\n dedupe_key TEXT,\n payload_json TEXT NOT NULL,\n result_json TEXT,\n error_text TEXT,\n retry_count INTEGER NOT NULL DEFAULT 0,\n max_retries INTEGER NOT NULL DEFAULT 1,\n session_id TEXT,\n worker_id TEXT,\n started_at INTEGER,\n finished_at INTEGER,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_jobs_status_priority ON jobs(status, priority, created_at)',\n 'CREATE INDEX IF NOT EXISTS idx_jobs_type_status ON jobs(type, status)',\n 'CREATE INDEX IF NOT EXISTS idx_jobs_session ON jobs(session_id)',\n\n // Job logs (append-only log per job)\n `CREATE TABLE IF NOT EXISTS job_logs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n job_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n level TEXT NOT NULL DEFAULT 'info',\n event_type TEXT NOT NULL,\n message TEXT,\n payload_json TEXT,\n created_at INTEGER NOT NULL\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_job_logs_job_seq ON job_logs(job_id, seq)',\n\n // Cache entries\n `CREATE TABLE IF NOT EXISTS cache_entries (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n key TEXT NOT NULL,\n kind TEXT NOT NULL,\n content_hash TEXT NOT NULL,\n config_hash TEXT NOT NULL,\n model TEXT NOT NULL DEFAULT '',\n value_json TEXT NOT NULL,\n expires_at INTEGER NOT NULL,\n hit_count INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL\n )`,\n 'CREATE UNIQUE INDEX IF NOT EXISTS idx_cache_key ON cache_entries(key)',\n 'CREATE INDEX IF NOT EXISTS idx_cache_expires ON cache_entries(expires_at)',\n\n // Schema meta\n `CREATE TABLE IF NOT EXISTS schema_meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n )`,\n];\n\n/**\n * Open a SQLite database and run migrations.\n * Pass ':memory:' for in-memory databases (testing).\n */\nexport function openDatabase(dbPath: string): Database.Database {\n try {\n const db = new Database(dbPath);\n configurePragmas(db);\n runMigrations(db);\n return db;\n } catch (err) {\n throw new DatabaseError(\n `Failed to open database at \"${dbPath}\": ${err instanceof Error ? err.message : String(err)}`,\n 'open',\n );\n }\n}\n\nfunction configurePragmas(db: Database.Database): void {\n db.pragma('journal_mode = WAL');\n db.pragma('foreign_keys = ON');\n db.pragma('busy_timeout = 5000');\n}\n\n/**\n * Run all schema migrations. Idempotent (uses IF NOT EXISTS).\n */\nexport function runMigrations(db: Database.Database): void {\n db.transaction(() => {\n for (const sql of MIGRATIONS) {\n db.exec(sql);\n }\n // Add codemoot_session_id columns to existing tables (safe: silently fails if already exists)\n for (const table of ['debate_messages', 'build_events']) {\n try {\n db.exec(`ALTER TABLE ${table} ADD COLUMN codemoot_session_id TEXT`);\n } catch {\n // Column already exists — expected on fresh DBs\n }\n }\n\n // v8: Add full prompt/response storage to session_events\n for (const col of ['prompt_full', 'response_full']) {\n try {\n db.exec(`ALTER TABLE session_events ADD COLUMN ${col} TEXT`);\n } catch {\n // Column already exists\n }\n }\n\n // Set schema version\n db.prepare(\"INSERT OR REPLACE INTO schema_meta(key, value) VALUES ('version', ?)\").run(\n SCHEMA_VERSION,\n );\n db.prepare(\n \"INSERT OR IGNORE INTO schema_meta(key, value) VALUES ('created_at', datetime('now'))\",\n ).run();\n })();\n}\n\n/** Get the current schema version. */\nexport function getSchemaVersion(db: Database.Database): string | null {\n const row = db.prepare(\"SELECT value FROM schema_meta WHERE key = 'version'\").get() as\n | { value: string }\n | undefined;\n return row?.value ?? null;\n}\n","// packages/core/src/memory/session-store.ts\n\nimport type Database from 'better-sqlite3';\nimport type { ExecutionMode, ProjectConfig } from '../types/config.js';\nimport type { Session, SessionStatus, TranscriptEntry } from '../types/session.js';\nimport { generateSessionId } from '../utils/id.js';\n\nexport class SessionStore {\n constructor(private db: Database.Database) {}\n\n create(params: {\n projectId: string;\n workflowId: string;\n task: string;\n mode: ExecutionMode;\n config: ProjectConfig;\n }): Session {\n const id = generateSessionId();\n const now = new Date().toISOString();\n const configSnapshot = JSON.stringify(params.config);\n\n this.db\n .prepare(\n `INSERT INTO sessions (id, project_id, task, workflow_id, mode, status, config_snapshot, started_at, updated_at, metadata)\n VALUES (?, ?, ?, ?, ?, 'running', ?, ?, ?, '{}')`,\n )\n .run(\n id,\n params.projectId,\n params.task,\n params.workflowId,\n params.mode,\n configSnapshot,\n now,\n now,\n );\n\n return {\n id,\n projectId: params.projectId,\n workflowId: params.workflowId,\n task: params.task,\n status: 'running',\n mode: params.mode,\n currentStep: null,\n configSnapshot,\n startedAt: now,\n updatedAt: now,\n completedAt: null,\n summary: null,\n totalCost: 0,\n totalTokens: 0,\n metadata: {},\n };\n }\n\n get(sessionId: string): Session | null {\n const row = this.db.prepare('SELECT * FROM sessions WHERE id = ?').get(sessionId) as\n | Record<string, unknown>\n | undefined;\n return row ? this.rowToSession(row) : null;\n }\n\n list(filter?: { status?: SessionStatus; projectId?: string; limit?: number }): Session[] {\n let sql = 'SELECT * FROM sessions WHERE 1=1';\n const params: unknown[] = [];\n\n if (filter?.status) {\n sql += ' AND status = ?';\n params.push(filter.status);\n }\n if (filter?.projectId) {\n sql += ' AND project_id = ?';\n params.push(filter.projectId);\n }\n sql += ' ORDER BY started_at DESC';\n if (filter?.limit) {\n sql += ' LIMIT ?';\n params.push(filter.limit);\n }\n\n const rows = this.db.prepare(sql).all(...params) as Record<string, unknown>[];\n return rows.map((r) => this.rowToSession(r));\n }\n\n updateStatus(sessionId: string, status: SessionStatus): void {\n this.db\n .prepare(\"UPDATE sessions SET status = ?, updated_at = datetime('now') WHERE id = ?\")\n .run(status, sessionId);\n }\n\n updateCurrentStep(sessionId: string, stepId: string): void {\n this.db\n .prepare(\"UPDATE sessions SET current_step = ?, updated_at = datetime('now') WHERE id = ?\")\n .run(stepId, sessionId);\n }\n\n complete(sessionId: string, summary?: string): void {\n this.db\n .prepare(\n `UPDATE sessions SET status = 'completed', summary = ?, completed_at = datetime('now'), updated_at = datetime('now') WHERE id = ?`,\n )\n .run(summary ?? null, sessionId);\n }\n\n addUsage(sessionId: string, cost: number, tokens: number): void {\n this.db\n .prepare(\n `UPDATE sessions SET total_cost = total_cost + ?, total_tokens = total_tokens + ?, updated_at = datetime('now') WHERE id = ?`,\n )\n .run(cost, tokens, sessionId);\n }\n\n saveTranscriptEntry(entry: TranscriptEntry): void {\n this.db\n .prepare(\n `INSERT INTO messages (session_id, step_id, iteration, role, model_id, content, token_count, cost, created_at, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n entry.sessionId,\n entry.stepId,\n entry.iteration,\n entry.role,\n entry.modelId,\n entry.content,\n entry.tokenCount,\n entry.cost,\n entry.createdAt || new Date().toISOString(),\n entry.metadata ? JSON.stringify(entry.metadata) : null,\n );\n }\n\n getTranscript(sessionId: string): TranscriptEntry[] {\n const rows = this.db\n .prepare('SELECT * FROM messages WHERE session_id = ? ORDER BY created_at ASC')\n .all(sessionId) as Record<string, unknown>[];\n\n return rows.map((r) => ({\n id: r.id as number,\n sessionId: r.session_id as string,\n stepId: r.step_id as string,\n iteration: (r.iteration as number) ?? null,\n role: r.role as string,\n modelId: (r.model_id as string) ?? null,\n content: r.content as string,\n tokenCount: (r.token_count as number) ?? null,\n cost: (r.cost as number) ?? null,\n createdAt: r.created_at as string,\n metadata: r.metadata ? (JSON.parse(r.metadata as string) as Record<string, unknown>) : null,\n }));\n }\n\n private rowToSession(row: Record<string, unknown>): Session {\n return {\n id: row.id as string,\n projectId: row.project_id as string,\n workflowId: row.workflow_id as string,\n task: row.task as string,\n status: row.status as SessionStatus,\n mode: row.mode as ExecutionMode,\n currentStep: (row.current_step as string) ?? null,\n configSnapshot: (row.config_snapshot as string) ?? '',\n startedAt: row.started_at as string,\n updatedAt: row.updated_at as string,\n completedAt: (row.completed_at as string) ?? null,\n summary: (row.summary as string) ?? null,\n totalCost: (row.total_cost as number) ?? 0,\n totalTokens: (row.total_tokens as number) ?? 0,\n metadata: row.metadata ? (JSON.parse(row.metadata as string) as Record<string, unknown>) : {},\n };\n }\n}\n","// packages/core/src/memory/memory-store.ts\n\nimport type Database from 'better-sqlite3';\nimport type { MemoryCategory, MemoryRecord } from '../types/memory.js';\n\nexport class MemoryStore {\n constructor(private db: Database.Database) {}\n\n save(memory: Omit<MemoryRecord, 'id' | 'createdAt' | 'accessedAt' | 'accessCount'>): number {\n const result = this.db\n .prepare(\n `INSERT INTO memories (project_id, category, content, source_session_id, importance)\n VALUES (?, ?, ?, ?, ?)`,\n )\n .run(\n memory.projectId,\n memory.category,\n memory.content,\n memory.sourceSessionId,\n memory.importance,\n );\n return result.lastInsertRowid as number;\n }\n\n search(query: string, projectId: string, limit = 10): MemoryRecord[] {\n if (!query.trim()) return [];\n\n // Escape FTS5 special characters by wrapping each token in double quotes\n const sanitized = query\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => `\"${token.replace(/\"/g, '\"\"')}\"`)\n .join(' ');\n\n const rows = this.db\n .prepare(\n `SELECT m.*, rank\n FROM memories_fts\n JOIN memories m ON m.id = memories_fts.rowid\n WHERE memories_fts MATCH ? AND m.project_id = ?\n ORDER BY rank\n LIMIT ?`,\n )\n .all(sanitized, projectId, limit) as Record<string, unknown>[];\n\n return rows.map((r) => this.rowToMemory(r));\n }\n\n getByCategory(projectId: string, category: MemoryCategory): MemoryRecord[] {\n const rows = this.db\n .prepare(\n 'SELECT * FROM memories WHERE project_id = ? AND category = ? ORDER BY importance DESC',\n )\n .all(projectId, category) as Record<string, unknown>[];\n\n return rows.map((r) => this.rowToMemory(r));\n }\n\n getById(memoryId: number): MemoryRecord | null {\n const row = this.db.prepare('SELECT * FROM memories WHERE id = ?').get(memoryId) as\n | Record<string, unknown>\n | undefined;\n return row ? this.rowToMemory(row) : null;\n }\n\n recordAccess(memoryId: number): void {\n this.db\n .prepare(\n 'UPDATE memories SET accessed_at = CURRENT_TIMESTAMP, access_count = access_count + 1 WHERE id = ?',\n )\n .run(memoryId);\n }\n\n /** Check if a memory with matching category and content prefix already exists. */\n findByPrefix(projectId: string, category: string, contentPrefix: string): MemoryRecord | null {\n const row = this.db\n .prepare(\n 'SELECT * FROM memories WHERE project_id = ? AND category = ? AND content LIKE ? LIMIT 1',\n )\n .get(projectId, category, `${contentPrefix}%`) as Record<string, unknown> | undefined;\n return row ? this.rowToMemory(row) : null;\n }\n\n delete(memoryId: number): void {\n this.db.prepare('DELETE FROM memories WHERE id = ?').run(memoryId);\n }\n\n private rowToMemory(row: Record<string, unknown>): MemoryRecord {\n return {\n id: row.id as number,\n projectId: row.project_id as string,\n category: row.category as MemoryCategory,\n content: row.content as string,\n sourceSessionId: (row.source_session_id as string) ?? null,\n importance: row.importance as number,\n createdAt: row.created_at as string,\n accessedAt: row.accessed_at as string,\n accessCount: row.access_count as number,\n };\n }\n}\n","// packages/core/src/memory/artifact-store.ts\n\nimport type Database from 'better-sqlite3';\nimport type { ArtifactRecord, ArtifactType } from '../types/memory.js';\n\nexport class ArtifactStore {\n constructor(private db: Database.Database) {}\n\n save(artifact: Omit<ArtifactRecord, 'id' | 'createdAt'>): number {\n const result = this.db\n .prepare(\n `INSERT INTO artifacts (session_id, step_id, iteration, type, file_path, content, version, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n artifact.sessionId,\n artifact.stepId,\n artifact.iteration,\n artifact.type,\n artifact.filePath,\n artifact.content,\n artifact.version,\n artifact.metadata ? JSON.stringify(artifact.metadata) : null,\n );\n return result.lastInsertRowid as number;\n }\n\n getBySession(sessionId: string): ArtifactRecord[] {\n const rows = this.db\n .prepare('SELECT * FROM artifacts WHERE session_id = ? ORDER BY created_at ASC')\n .all(sessionId) as Record<string, unknown>[];\n return rows.map((r) => this.rowToArtifact(r));\n }\n\n getByStep(sessionId: string, stepId: string): ArtifactRecord[] {\n const rows = this.db\n .prepare('SELECT * FROM artifacts WHERE session_id = ? AND step_id = ? ORDER BY version ASC')\n .all(sessionId, stepId) as Record<string, unknown>[];\n return rows.map((r) => this.rowToArtifact(r));\n }\n\n getLatestByStep(sessionId: string, stepId: string): ArtifactRecord | null {\n const row = this.db\n .prepare(\n 'SELECT * FROM artifacts WHERE session_id = ? AND step_id = ? ORDER BY version DESC LIMIT 1',\n )\n .get(sessionId, stepId) as Record<string, unknown> | undefined;\n return row ? this.rowToArtifact(row) : null;\n }\n\n getByType(sessionId: string, type: ArtifactType): ArtifactRecord[] {\n const rows = this.db\n .prepare('SELECT * FROM artifacts WHERE session_id = ? AND type = ? ORDER BY created_at ASC')\n .all(sessionId, type) as Record<string, unknown>[];\n return rows.map((r) => this.rowToArtifact(r));\n }\n\n private rowToArtifact(row: Record<string, unknown>): ArtifactRecord {\n return {\n id: row.id as number,\n sessionId: row.session_id as string,\n stepId: row.step_id as string,\n iteration: (row.iteration as number) ?? 1,\n type: row.type as ArtifactType,\n filePath: (row.file_path as string) ?? null,\n content: row.content as string,\n version: row.version as number,\n createdAt: row.created_at as string,\n metadata: row.metadata\n ? (JSON.parse(row.metadata as string) as Record<string, unknown>)\n : null,\n };\n }\n}\n","// packages/core/src/memory/cost-store.ts\n\nimport type Database from 'better-sqlite3';\nimport type { CostLogEntry } from '../types/memory.js';\n\nexport interface CostSummary {\n modelId: string;\n callCount: number;\n totalInputTokens: number;\n totalOutputTokens: number;\n totalCost: number;\n avgLatencyMs: number;\n}\n\nexport class CostStore {\n constructor(private db: Database.Database) {}\n\n log(entry: Omit<CostLogEntry, 'id' | 'createdAt'>): number {\n const result = this.db\n .prepare(\n `INSERT INTO cost_log (session_id, step_id, model_id, input_tokens, output_tokens, cost_usd, latency_ms)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n entry.sessionId,\n entry.stepId,\n entry.modelId,\n entry.inputTokens,\n entry.outputTokens,\n entry.costUsd,\n entry.latencyMs,\n );\n return result.lastInsertRowid as number;\n }\n\n getBySession(sessionId: string): CostLogEntry[] {\n const rows = this.db\n .prepare('SELECT * FROM cost_log WHERE session_id = ? ORDER BY created_at ASC')\n .all(sessionId) as Record<string, unknown>[];\n return rows.map((r) => this.rowToEntry(r));\n }\n\n getSessionSummary(sessionId: string): CostSummary[] {\n const rows = this.db\n .prepare(\n `SELECT model_id, COUNT(*) AS call_count,\n SUM(input_tokens) AS total_input_tokens,\n SUM(output_tokens) AS total_output_tokens,\n SUM(cost_usd) AS total_cost,\n AVG(latency_ms) AS avg_latency_ms\n FROM cost_log WHERE session_id = ?\n GROUP BY model_id ORDER BY total_cost DESC`,\n )\n .all(sessionId) as Record<string, unknown>[];\n\n return rows.map((r) => ({\n modelId: r.model_id as string,\n callCount: r.call_count as number,\n totalInputTokens: r.total_input_tokens as number,\n totalOutputTokens: r.total_output_tokens as number,\n totalCost: r.total_cost as number,\n avgLatencyMs: r.avg_latency_ms as number,\n }));\n }\n\n getDailySummary(days = 30): Record<string, unknown>[] {\n return this.db\n .prepare(\n `SELECT DATE(created_at) AS day, model_id,\n SUM(input_tokens) AS input_tokens,\n SUM(output_tokens) AS output_tokens,\n SUM(cost_usd) AS cost, COUNT(*) AS api_calls\n FROM cost_log WHERE created_at >= DATE('now', ? || ' days')\n GROUP BY day, model_id ORDER BY day DESC, cost DESC`,\n )\n .all(`-${days}`) as Record<string, unknown>[];\n }\n\n private rowToEntry(row: Record<string, unknown>): CostLogEntry {\n return {\n id: row.id as number,\n sessionId: row.session_id as string,\n stepId: (row.step_id as string) ?? null,\n modelId: row.model_id as string,\n inputTokens: row.input_tokens as number,\n outputTokens: row.output_tokens as number,\n costUsd: row.cost_usd as number,\n latencyMs: row.latency_ms as number,\n createdAt: row.created_at as string,\n };\n }\n}\n","// packages/core/src/memory/debate-store.ts — CRUD for debate_turns table\n\nimport type Database from 'better-sqlite3';\nimport type { DebateEngineState } from '../types/debate.js';\n\nexport type DebateTurnStatus = 'active' | 'completed' | 'interrupted' | 'stale' | 'expired';\n\nexport interface DebateTurnRow {\n id: number;\n debateId: string;\n role: string;\n codexSessionId: string | null;\n round: number;\n status: DebateTurnStatus;\n resumeFailCount: number;\n lastActivityAt: number;\n createdAt: number;\n stateJson: string | null;\n}\n\nexport class DebateStore {\n constructor(private db: Database.Database) {}\n\n /** Create or update a debate turn (upsert on debate_id + role). */\n upsert(params: {\n debateId: string;\n role: string;\n codexSessionId?: string;\n round?: number;\n status?: DebateTurnStatus;\n stateJson?: string;\n }): void {\n const now = Date.now();\n this.db\n .prepare(\n `INSERT INTO debate_turns (debate_id, role, codex_session_id, round, status, last_activity_at, created_at, state_json)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(debate_id, role) DO UPDATE SET\n codex_session_id = COALESCE(excluded.codex_session_id, codex_session_id),\n round = excluded.round,\n status = excluded.status,\n last_activity_at = excluded.last_activity_at,\n state_json = COALESCE(excluded.state_json, state_json)`,\n )\n .run(\n params.debateId,\n params.role,\n params.codexSessionId ?? null,\n params.round ?? 0,\n params.status ?? 'active',\n now,\n now,\n params.stateJson ?? null,\n );\n }\n\n /** Get a debate turn by debate_id and role. */\n get(debateId: string, role: string): DebateTurnRow | null {\n const row = this.db\n .prepare('SELECT * FROM debate_turns WHERE debate_id = ? AND role = ?')\n .get(debateId, role) as Record<string, unknown> | undefined;\n return row ? this.toRow(row) : null;\n }\n\n /** Get all turns for a debate. */\n getByDebateId(debateId: string): DebateTurnRow[] {\n const rows = this.db\n .prepare('SELECT * FROM debate_turns WHERE debate_id = ? ORDER BY created_at ASC')\n .all(debateId) as Record<string, unknown>[];\n return rows.map((r) => this.toRow(r));\n }\n\n /** List debates, optionally filtered by status. */\n list(filter?: { status?: DebateTurnStatus; limit?: number }): DebateTurnRow[] {\n let sql = 'SELECT * FROM debate_turns WHERE 1=1';\n const params: unknown[] = [];\n\n if (filter?.status) {\n sql += ' AND status = ?';\n params.push(filter.status);\n }\n sql += ' ORDER BY last_activity_at DESC';\n if (filter?.limit) {\n sql += ' LIMIT ?';\n params.push(filter.limit);\n }\n\n const rows = this.db.prepare(sql).all(...params) as Record<string, unknown>[];\n return rows.map((r) => this.toRow(r));\n }\n\n /** Update session ID after a successful codex call. */\n updateSessionId(debateId: string, role: string, codexSessionId: string): void {\n this.db\n .prepare(\n 'UPDATE debate_turns SET codex_session_id = ?, last_activity_at = ? WHERE debate_id = ? AND role = ?',\n )\n .run(codexSessionId, Date.now(), debateId, role);\n }\n\n /** Update status (e.g., active → completed). */\n updateStatus(debateId: string, role: string, status: DebateTurnStatus): void {\n this.db\n .prepare(\n 'UPDATE debate_turns SET status = ?, last_activity_at = ? WHERE debate_id = ? AND role = ?',\n )\n .run(status, Date.now(), debateId, role);\n }\n\n /** Increment resume failure count. */\n incrementResumeFailCount(debateId: string, role: string): void {\n this.db\n .prepare(\n 'UPDATE debate_turns SET resume_fail_count = resume_fail_count + 1, last_activity_at = ? WHERE debate_id = ? AND role = ?',\n )\n .run(Date.now(), debateId, role);\n }\n\n /** Persist full debate state as JSON for crash recovery. */\n saveState(debateId: string, role: string, state: DebateEngineState): void {\n this.db\n .prepare(\n 'UPDATE debate_turns SET state_json = ?, round = ?, last_activity_at = ? WHERE debate_id = ? AND role = ?',\n )\n .run(JSON.stringify(state), state.round, Date.now(), debateId, role);\n }\n\n /** Load saved debate state from JSON. */\n loadState(debateId: string, role: string): DebateEngineState | null {\n const row = this.get(debateId, role);\n if (!row?.stateJson) return null;\n try {\n return JSON.parse(row.stateJson) as DebateEngineState;\n } catch {\n return null;\n }\n }\n\n /** Mark stale debates (active but inactive for > threshold). */\n markStale(thresholdMs: number): number {\n const cutoff = Date.now() - thresholdMs;\n const result = this.db\n .prepare(\n \"UPDATE debate_turns SET status = 'stale' WHERE status = 'active' AND last_activity_at < ?\",\n )\n .run(cutoff);\n return result.changes;\n }\n\n /** Mark expired debates (stale and older than threshold). */\n markExpired(thresholdMs: number): number {\n const cutoff = Date.now() - thresholdMs;\n const result = this.db\n .prepare(\n \"UPDATE debate_turns SET status = 'expired' WHERE status = 'stale' AND last_activity_at < ?\",\n )\n .run(cutoff);\n return result.changes;\n }\n\n private toRow(row: Record<string, unknown>): DebateTurnRow {\n return {\n id: row.id as number,\n debateId: row.debate_id as string,\n role: row.role as string,\n codexSessionId: (row.codex_session_id as string) ?? null,\n round: (row.round as number) ?? 0,\n status: (row.status as DebateTurnStatus) ?? 'active',\n resumeFailCount: (row.resume_fail_count as number) ?? 0,\n lastActivityAt: row.last_activity_at as number,\n createdAt: row.created_at as number,\n stateJson: (row.state_json as string) ?? null,\n };\n }\n}\n","// packages/core/src/memory/build-store.ts — CRUD for build_runs + build_events\n\nimport type Database from 'better-sqlite3';\nimport type {\n BuildActor,\n BuildEvent,\n BuildEventType,\n BuildPhase,\n BuildRun,\n BuildStatus,\n BuildSummary,\n PhaseCursor,\n} from '../types/build.js';\n\nexport class BuildStore {\n constructor(private db: Database.Database) {}\n\n /** Create a new build run. */\n create(params: {\n buildId: string;\n task: string;\n debateId?: string;\n baselineRef?: string;\n }): void {\n const now = Date.now();\n const cursor: PhaseCursor = {\n phase: 'debate',\n loop: 0,\n actor: 'system',\n attempt: 0,\n lastEventId: 0,\n };\n this.db\n .prepare(\n `INSERT INTO build_runs (build_id, task, status, current_phase, current_loop, last_event_seq, phase_cursor, debate_id, baseline_ref, created_at, updated_at)\n VALUES (?, ?, 'planning', 'debate', 0, 0, ?, ?, ?, ?, ?)`,\n )\n .run(params.buildId, params.task, JSON.stringify(cursor), params.debateId ?? null, params.baselineRef ?? null, now, now);\n }\n\n /** Get a build run by build_id. */\n get(buildId: string): BuildRun | null {\n const row = this.db\n .prepare('SELECT * FROM build_runs WHERE build_id = ?')\n .get(buildId) as Record<string, unknown> | undefined;\n return row ? this.toRun(row) : null;\n }\n\n /** List builds, optionally filtered by status. */\n list(filter?: { status?: BuildStatus; limit?: number }): BuildSummary[] {\n let sql = 'SELECT * FROM build_runs WHERE 1=1';\n const params: unknown[] = [];\n if (filter?.status) {\n sql += ' AND status = ?';\n params.push(filter.status);\n }\n sql += ' ORDER BY updated_at DESC';\n if (filter?.limit) {\n sql += ' LIMIT ?';\n params.push(filter.limit);\n }\n const rows = this.db.prepare(sql).all(...params) as Record<string, unknown>[];\n return rows.map((r) => ({\n buildId: r.build_id as string,\n task: r.task as string,\n status: r.status as BuildStatus,\n phase: r.current_phase as BuildPhase,\n loop: r.current_loop as number,\n reviewCycles: (r.review_cycles as number) ?? 0,\n planVersion: (r.plan_version as number) ?? 0,\n debateId: (r.debate_id as string) ?? null,\n baselineRef: (r.baseline_ref as string) ?? null,\n createdAt: r.created_at as number,\n updatedAt: r.updated_at as number,\n }));\n }\n\n /** Update build run fields atomically with event append. */\n updateWithEvent(\n buildId: string,\n updates: Partial<{\n status: BuildStatus;\n currentPhase: BuildPhase;\n currentLoop: number;\n debateId: string;\n baselineRef: string;\n planCodexSession: string;\n reviewCodexSession: string;\n planVersion: number;\n reviewCycles: number;\n completedAt: number;\n metadata: Record<string, unknown>;\n }>,\n event: {\n eventType: BuildEventType;\n actor: BuildActor;\n phase: BuildPhase;\n loopIndex?: number;\n payload?: Record<string, unknown>;\n codexThreadId?: string;\n tokensUsed?: number;\n },\n ): void {\n this.db.transaction(() => {\n // Get next seq\n const run = this.get(buildId);\n if (!run) throw new Error(`Build not found: ${buildId}`);\n const nextSeq = run.lastEventSeq + 1;\n const now = Date.now();\n\n // Insert event\n this.db\n .prepare(\n `INSERT INTO build_events (build_id, seq, event_type, actor, phase, loop_index, payload, codex_thread_id, tokens_used, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n buildId,\n nextSeq,\n event.eventType,\n event.actor,\n event.phase,\n event.loopIndex ?? 0,\n event.payload ? JSON.stringify(event.payload) : null,\n event.codexThreadId ?? null,\n event.tokensUsed ?? 0,\n now,\n );\n\n // Build SET clause dynamically\n const sets: string[] = ['last_event_seq = ?', 'updated_at = ?'];\n const values: unknown[] = [nextSeq, now];\n\n if (updates.status !== undefined) { sets.push('status = ?'); values.push(updates.status); }\n if (updates.currentPhase !== undefined) { sets.push('current_phase = ?'); values.push(updates.currentPhase); }\n if (updates.currentLoop !== undefined) { sets.push('current_loop = ?'); values.push(updates.currentLoop); }\n if (updates.debateId !== undefined) { sets.push('debate_id = ?'); values.push(updates.debateId); }\n if (updates.baselineRef !== undefined) { sets.push('baseline_ref = ?'); values.push(updates.baselineRef); }\n if (updates.planCodexSession !== undefined) { sets.push('plan_codex_session = ?'); values.push(updates.planCodexSession); }\n if (updates.reviewCodexSession !== undefined) { sets.push('review_codex_session = ?'); values.push(updates.reviewCodexSession); }\n if (updates.planVersion !== undefined) { sets.push('plan_version = ?'); values.push(updates.planVersion); }\n if (updates.reviewCycles !== undefined) { sets.push('review_cycles = ?'); values.push(updates.reviewCycles); }\n if (updates.completedAt !== undefined) { sets.push('completed_at = ?'); values.push(updates.completedAt); }\n if (updates.metadata !== undefined) { sets.push('metadata = ?'); values.push(JSON.stringify(updates.metadata)); }\n\n // Update cursor\n const cursor: PhaseCursor = {\n phase: updates.currentPhase ?? run.currentPhase,\n loop: updates.currentLoop ?? run.currentLoop,\n actor: event.actor,\n attempt: 0,\n lastEventId: nextSeq,\n baselineRef: updates.baselineRef ?? run.baselineRef ?? undefined,\n };\n sets.push('phase_cursor = ?');\n values.push(JSON.stringify(cursor));\n\n values.push(buildId);\n this.db.prepare(`UPDATE build_runs SET ${sets.join(', ')} WHERE build_id = ?`).run(...values);\n })();\n }\n\n /** Get events for a build, ordered by seq. */\n getEvents(buildId: string, afterSeq?: number): BuildEvent[] {\n let sql = 'SELECT * FROM build_events WHERE build_id = ?';\n const params: unknown[] = [buildId];\n if (afterSeq !== undefined) {\n sql += ' AND seq > ?';\n params.push(afterSeq);\n }\n sql += ' ORDER BY seq ASC';\n const rows = this.db.prepare(sql).all(...params) as Record<string, unknown>[];\n return rows.map((r) => this.toEvent(r));\n }\n\n /** Count events by type for a build. */\n countEventsByType(buildId: string, eventType: BuildEventType): number {\n const row = this.db\n .prepare('SELECT COUNT(*) as cnt FROM build_events WHERE build_id = ? AND event_type = ?')\n .get(buildId, eventType) as { cnt: number };\n return row.cnt;\n }\n\n private toRun(row: Record<string, unknown>): BuildRun {\n let cursor: PhaseCursor;\n try {\n cursor = JSON.parse((row.phase_cursor as string) || '{}');\n } catch {\n cursor = { phase: 'debate', loop: 0, actor: 'system', attempt: 0, lastEventId: 0 };\n }\n let metadata: Record<string, unknown> | null = null;\n if (row.metadata) {\n try { metadata = JSON.parse(row.metadata as string); } catch { /* ignore */ }\n }\n return {\n id: row.id as number,\n buildId: row.build_id as string,\n task: row.task as string,\n status: row.status as BuildStatus,\n currentPhase: row.current_phase as BuildPhase,\n currentLoop: (row.current_loop as number) ?? 0,\n lastEventSeq: (row.last_event_seq as number) ?? 0,\n phaseCursor: cursor,\n debateId: (row.debate_id as string) ?? null,\n baselineRef: (row.baseline_ref as string) ?? null,\n planCodexSession: (row.plan_codex_session as string) ?? null,\n reviewCodexSession: (row.review_codex_session as string) ?? null,\n planVersion: (row.plan_version as number) ?? 0,\n reviewCycles: (row.review_cycles as number) ?? 0,\n createdAt: row.created_at as number,\n updatedAt: row.updated_at as number,\n completedAt: (row.completed_at as number) ?? null,\n metadata,\n };\n }\n\n private toEvent(row: Record<string, unknown>): BuildEvent {\n let payload: Record<string, unknown> | null = null;\n if (row.payload) {\n try { payload = JSON.parse(row.payload as string); } catch { /* ignore */ }\n }\n return {\n id: row.id as number,\n buildId: row.build_id as string,\n seq: row.seq as number,\n eventType: row.event_type as BuildEventType,\n actor: row.actor as BuildActor,\n phase: row.phase as BuildPhase,\n loopIndex: (row.loop_index as number) ?? 0,\n payload,\n codexThreadId: (row.codex_thread_id as string) ?? null,\n tokensUsed: (row.tokens_used as number) ?? 0,\n createdAt: row.created_at as number,\n };\n }\n}\n","// packages/core/src/security/dlp.ts — 6-stage DLP pipeline from MCP architecture\n\nimport { DlpReasonCode } from '../types/mcp.js';\nimport { DLP_MAX_PROCESSING_MS } from '../utils/constants.js';\n\nexport type DlpMode = 'strict' | 'open';\n\nexport interface DlpRedaction {\n stage: number;\n reasonCode: DlpReasonCode;\n original: string;\n replacement: string;\n}\n\nexport interface DlpAuditEntry {\n stage: number;\n action: string;\n detail: string;\n timestamp: string;\n}\n\nexport interface DlpResult {\n sanitized: string;\n redactions: DlpRedaction[];\n truncated: boolean;\n auditLog: DlpAuditEntry[];\n}\n\nexport interface DlpConfig {\n mode: DlpMode;\n maxInputBytes: number;\n maxProcessingMs: number;\n maxRegexOps: number;\n maxTokens: number;\n}\n\nconst DEFAULT_DLP_CONFIG: DlpConfig = {\n mode: 'strict',\n maxInputBytes: 5 * 1024 * 1024,\n maxProcessingMs: DLP_MAX_PROCESSING_MS,\n maxRegexOps: 1000,\n maxTokens: 32_000,\n};\n\n// -- Secret patterns: [regex, replacement type] --\nconst SECRET_PATTERNS: Array<[RegExp, string]> = [\n [/AKIA[0-9A-Z]{16}/g, 'AWS_KEY'],\n [/sk-proj-[a-zA-Z0-9\\-_]{20,}/g, 'API_KEY'],\n [/sk-[a-zA-Z0-9]{20,}/g, 'API_KEY'],\n [/ghp_[a-zA-Z0-9]{36}/g, 'GITHUB_TOKEN'],\n [/eyJ[a-zA-Z0-9_-]+\\.eyJ[a-zA-Z0-9_-]+/g, 'JWT'],\n [/-----BEGIN [A-Z ]+ PRIVATE KEY-----/g, 'PRIVATE_KEY'],\n [/Bearer [a-zA-Z0-9._~+/=-]{20,}/g, 'BEARER_TOKEN'],\n [/[a-zA-Z]+:\\/\\/[^:]+:[^@]+@/g, 'CONNECTION_STRING'],\n];\n\n// -- Path patterns --\nconst ABSOLUTE_PATH_PATTERNS: RegExp[] = [\n /[A-Z]:\\\\[^\\s'\"`,;)}\\]]+/g,\n /\\/(?:home|Users|root|var|etc|opt|tmp)\\/[^\\s'\"`,;)}\\]]+/g,\n];\n\n/**\n * Calculate Shannon entropy for a string.\n */\nfunction shannonEntropy(str: string): number {\n if (str.length === 0) return 0;\n\n const freq = new Map<string, number>();\n for (const ch of str) {\n freq.set(ch, (freq.get(ch) ?? 0) + 1);\n }\n\n let entropy = 0;\n const len = str.length;\n for (const count of freq.values()) {\n const p = count / len;\n if (p > 0) {\n entropy -= p * Math.log2(p);\n }\n }\n return entropy;\n}\n\n/**\n * Truncate the original value to first 20 characters for audit safety.\n */\nfunction auditSnippet(value: string): string {\n if (value.length <= 20) return value;\n return `${value.slice(0, 20)}...`;\n}\n\n/**\n * Create an audit log entry.\n */\nfunction audit(stage: number, action: string, detail: string): DlpAuditEntry {\n return {\n stage,\n action,\n detail,\n timestamp: new Date().toISOString(),\n };\n}\n\n/**\n * Estimate token count using char/4 heuristic.\n */\nfunction estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Sanitize input through the 6-stage DLP pipeline.\n *\n * Stages:\n * 0: Decode — detect and skip base64/hex (budget-limited)\n * 1: Secrets — regex scan for common secret patterns\n * 2: Entropy — Shannon entropy check on long tokens (strict mode only)\n * 3: Paths — convert absolute paths to relative\n * 4: Context — truncate if exceeding token limit\n * 5: Audit — finalize audit log\n *\n * Risk-tiered defaults:\n * review/debate tools -> strict mode (external content)\n * memory/cost tools -> open mode (local data, skip stages 1-2)\n */\nexport function sanitize(input: string, config?: Partial<DlpConfig>): DlpResult {\n const cfg: DlpConfig = { ...DEFAULT_DLP_CONFIG, ...config };\n const redactions: DlpRedaction[] = [];\n const auditLog: DlpAuditEntry[] = [];\n let text = input;\n let truncated = false;\n const startTime = Date.now();\n\n /** Check if processing has exceeded the time budget. */\n const isOverBudget = () => Date.now() - startTime > cfg.maxProcessingMs;\n\n // Budget check: reject oversized input\n const inputBytes = new TextEncoder().encode(text).byteLength;\n if (inputBytes > cfg.maxInputBytes) {\n auditLog.push(audit(0, 'BUDGET_EXCEEDED', `Input size ${inputBytes} exceeds limit`));\n redactions.push({\n stage: 0,\n reasonCode: DlpReasonCode.BUDGET_EXCEEDED,\n original: auditSnippet(text),\n replacement: '[BLOCKED: input exceeds size budget]',\n });\n return {\n sanitized: '[BLOCKED: input exceeds size budget]',\n redactions,\n truncated: true,\n auditLog,\n };\n }\n\n // Handle empty input early\n if (text.length === 0) {\n return { sanitized: '', redactions: [], truncated: false, auditLog: [] };\n }\n\n let regexOps = 0;\n\n // Stage 0: Decode detection (simplified — flag base64 blocks)\n auditLog.push(audit(0, 'DECODE_CHECK', 'Scanning for encoded content'));\n // We detect large base64 blocks and flag them. Per-decode budget: 1MB/10ops/500ms.\n const base64Pattern = /(?:[A-Za-z0-9+/]{4}){16,}={0,2}/g;\n let base64Match = base64Pattern.exec(text);\n while (base64Match && regexOps < cfg.maxRegexOps) {\n regexOps++;\n const matched = base64Match[0];\n // Only flag large base64 blocks (> 64 chars)\n if (matched.length > 64) {\n auditLog.push(\n audit(0, 'DECODE_FLAGGED', `Large base64 block detected: ${matched.length} chars`),\n );\n redactions.push({\n stage: 0,\n reasonCode: DlpReasonCode.DECODE_BLOCKED,\n original: auditSnippet(matched),\n replacement: '[REDACTED:ENCODED_CONTENT]',\n });\n text = `${text.slice(0, base64Match.index)}[REDACTED:ENCODED_CONTENT]${text.slice(base64Match.index + matched.length)}`;\n // Reset regex after modifying text\n base64Pattern.lastIndex = base64Match.index + '[REDACTED:ENCODED_CONTENT]'.length;\n }\n base64Match = base64Pattern.exec(text);\n }\n\n // In open mode, skip stages 1 and 2 (local data like memory/cost)\n if (cfg.mode === 'strict') {\n // Timer check before stage 1\n if (isOverBudget()) {\n auditLog.push(audit(1, 'TIMEOUT', `Processing exceeded ${cfg.maxProcessingMs}ms budget`));\n return { sanitized: text, redactions, truncated, auditLog };\n }\n\n // Stage 1: Secret detection\n auditLog.push(audit(1, 'SECRET_SCAN', 'Scanning for secret patterns'));\n for (const [pattern, secretType] of SECRET_PATTERNS) {\n if (regexOps >= cfg.maxRegexOps) break;\n // Reset global regex\n const regex = new RegExp(pattern.source, pattern.flags);\n let match = regex.exec(text);\n while (match && regexOps < cfg.maxRegexOps) {\n regexOps++;\n const original = match[0];\n const replacement = `[REDACTED:${secretType}]`;\n redactions.push({\n stage: 1,\n reasonCode: DlpReasonCode.SECRET_DETECTED,\n original: auditSnippet(original),\n replacement,\n });\n auditLog.push(audit(1, 'SECRET_REDACTED', `${secretType} at position ${match.index}`));\n text = `${text.slice(0, match.index)}${replacement}${text.slice(match.index + original.length)}`;\n // Adjust regex position after replacement\n regex.lastIndex = match.index + replacement.length;\n match = regex.exec(text);\n }\n }\n\n // Timer check before stage 2\n if (isOverBudget()) {\n auditLog.push(audit(2, 'TIMEOUT', `Processing exceeded ${cfg.maxProcessingMs}ms budget`));\n return { sanitized: text, redactions, truncated, auditLog };\n }\n\n // Stage 2: Entropy check (strict mode only)\n auditLog.push(audit(2, 'ENTROPY_SCAN', 'Checking token entropy'));\n // Split into tokens by whitespace/punctuation and check each\n const tokenPattern = /[^\\s'\"`,;)}\\]]{21,}/g;\n const tokens: Array<{ value: string; index: number }> = [];\n let tokenMatch = tokenPattern.exec(text);\n while (tokenMatch && regexOps < cfg.maxRegexOps) {\n regexOps++;\n tokens.push({ value: tokenMatch[0], index: tokenMatch.index });\n tokenMatch = tokenPattern.exec(text);\n }\n\n // Process in reverse order so indices remain valid\n for (let i = tokens.length - 1; i >= 0; i--) {\n const token = tokens[i];\n const entropy = shannonEntropy(token.value);\n if (entropy > 4.5) {\n const replacement = '[REDACTED:HIGH_ENTROPY]';\n redactions.push({\n stage: 2,\n reasonCode: DlpReasonCode.HIGH_ENTROPY,\n original: auditSnippet(token.value),\n replacement,\n });\n auditLog.push(\n audit(\n 2,\n 'ENTROPY_REDACTED',\n `Token entropy ${entropy.toFixed(2)} at position ${token.index}`,\n ),\n );\n text = `${text.slice(0, token.index)}${replacement}${text.slice(token.index + token.value.length)}`;\n }\n }\n } else {\n auditLog.push(audit(1, 'SKIPPED', 'Open mode: secret scan skipped'));\n auditLog.push(audit(2, 'SKIPPED', 'Open mode: entropy scan skipped'));\n }\n\n // Timer check before stage 3\n if (isOverBudget()) {\n auditLog.push(audit(3, 'TIMEOUT', `Processing exceeded ${cfg.maxProcessingMs}ms budget`));\n return { sanitized: text, redactions, truncated, auditLog };\n }\n\n // Stage 3: Absolute path conversion\n auditLog.push(audit(3, 'PATH_SCAN', 'Scanning for absolute paths'));\n for (const pathPattern of ABSOLUTE_PATH_PATTERNS) {\n if (regexOps >= cfg.maxRegexOps) break;\n const regex = new RegExp(pathPattern.source, pathPattern.flags);\n let match = regex.exec(text);\n while (match && regexOps < cfg.maxRegexOps) {\n regexOps++;\n const original = match[0];\n const replacement = convertToRelative(original);\n if (replacement !== original) {\n redactions.push({\n stage: 3,\n reasonCode: DlpReasonCode.ABSOLUTE_PATH,\n original: auditSnippet(original),\n replacement,\n });\n auditLog.push(audit(3, 'PATH_CONVERTED', `Absolute path at position ${match.index}`));\n text = `${text.slice(0, match.index)}${replacement}${text.slice(match.index + original.length)}`;\n regex.lastIndex = match.index + replacement.length;\n }\n match = regex.exec(text);\n }\n }\n\n // Timer check before stage 4\n if (isOverBudget()) {\n auditLog.push(audit(4, 'TIMEOUT', `Processing exceeded ${cfg.maxProcessingMs}ms budget`));\n return { sanitized: text, redactions, truncated, auditLog };\n }\n\n // Stage 4: Context size truncation\n auditLog.push(audit(4, 'CONTEXT_CHECK', 'Checking token count'));\n const estimatedTokenCount = estimateTokens(text);\n if (estimatedTokenCount > cfg.maxTokens) {\n const maxChars = cfg.maxTokens * 4;\n const truncatedText = text.slice(0, maxChars);\n const suffix = '\\n[TRUNCATED: context exceeded token limit]';\n text = truncatedText + suffix;\n truncated = true;\n redactions.push({\n stage: 4,\n reasonCode: DlpReasonCode.CONTEXT_TRUNCATED,\n original: `Estimated ${estimatedTokenCount} tokens`,\n replacement: `Truncated to ${cfg.maxTokens} tokens`,\n });\n auditLog.push(\n audit(\n 4,\n 'CONTEXT_TRUNCATED',\n `Truncated from ${estimatedTokenCount} to ${cfg.maxTokens} tokens`,\n ),\n );\n }\n\n // Stage 5: Audit finalization\n auditLog.push(\n audit(\n 5,\n 'COMPLETE',\n `DLP pipeline complete: ${redactions.length} redactions, truncated=${String(truncated)}`,\n ),\n );\n\n return {\n sanitized: text,\n redactions,\n truncated,\n auditLog,\n };\n}\n\n/**\n * Convert an absolute path to a relative path.\n */\nfunction convertToRelative(absolutePath: string): string {\n // Windows: C:\\Users\\foo\\project\\file.ts -> ./project/file.ts\n const winMatch = /^[A-Z]:\\\\(?:Users\\\\[^\\\\]+\\\\)?(.+)$/i.exec(absolutePath);\n if (winMatch) {\n return `./${winMatch[1].replace(/\\\\/g, '/')}`;\n }\n\n // Unix: /home/user/project/file.ts -> ./project/file.ts\n const unixMatch = /^\\/(?:home|Users|root)\\/[^/]+\\/(.+)$/.exec(absolutePath);\n if (unixMatch) {\n return `./${unixMatch[1]}`;\n }\n\n // Other absolute unix paths: /var/log/app.log -> ./log/app.log\n const otherMatch = /^\\/(?:var|etc|opt|tmp)\\/(.+)$/.exec(absolutePath);\n if (otherMatch) {\n return `./${otherMatch[1]}`;\n }\n\n return absolutePath;\n}\n\nexport { DEFAULT_DLP_CONFIG, shannonEntropy, convertToRelative, estimateTokens };\n","// packages/core/src/memory/message-store.ts — CRUD for debate_messages table\n\nimport type Database from 'better-sqlite3';\nimport { sanitize } from '../security/dlp.js';\n\nexport type MessageStatus = 'queued' | 'running' | 'completed' | 'failed';\n\nexport interface DebateMessageRow {\n id: number;\n debateId: string;\n round: number;\n role: string;\n bridge: string;\n model: string;\n promptText: string;\n responseText: string | null;\n stance: string | null;\n confidence: number | null;\n verdictRaw: string | null;\n usageJson: string | null;\n durationMs: number | null;\n sessionId: string | null;\n status: MessageStatus;\n error: string | null;\n createdAt: number;\n updatedAt: number;\n completedAt: number | null;\n}\n\nexport interface ParsedVerdict {\n stance: string | null;\n confidence: number | null;\n raw: string | null;\n}\n\nconst VERDICT_BLOCK_RE = /---VERDICT---([\\s\\S]*?)---END_VERDICT---/;\nconst STANCE_RE = /(?:STANCE:\\s*|^)(SUPPORT|OPPOSE|UNCERTAIN)(?:\\s|[.,:;—\\-]|$)/im;\n\n/** Parse structured verdict from model response. */\nexport function parseDebateVerdict(text: string): ParsedVerdict {\n const VALID_STANCES = new Set(['SUPPORT', 'OPPOSE', 'UNCERTAIN']);\n\n const validateStance = (s: unknown): string | null => {\n if (typeof s !== 'string') return null;\n const upper = s.toUpperCase();\n return VALID_STANCES.has(upper) ? upper : null;\n };\n\n const validateConfidence = (c: unknown): number | null => {\n if (typeof c !== 'number' || !Number.isFinite(c)) return null;\n return c >= 0 && c <= 1 ? c : null;\n };\n\n // Try structured JSON block first\n const blockMatch = VERDICT_BLOCK_RE.exec(text);\n if (blockMatch) {\n try {\n const parsed = JSON.parse(blockMatch[1].trim());\n return {\n stance: validateStance(parsed.stance),\n confidence: validateConfidence(parsed.confidence),\n raw: sanitize(blockMatch[0], { mode: 'strict' }).sanitized,\n };\n } catch {\n // Malformed JSON in block — fall through to regex\n }\n }\n\n // Fallback to regex\n const stanceMatch = STANCE_RE.exec(text);\n if (stanceMatch) {\n return {\n stance: stanceMatch[1].toUpperCase(),\n confidence: null,\n raw: null,\n };\n }\n\n return { stance: null, confidence: null, raw: null };\n}\n\nexport class MessageStore {\n constructor(private db: Database.Database) {}\n\n /** Insert a new message in queued state. Returns the row ID. */\n insertQueued(params: {\n debateId: string;\n round: number;\n role: string;\n bridge: string;\n model: string;\n promptText: string;\n }): number {\n const now = Date.now();\n const sanitized = sanitize(params.promptText, { mode: 'strict' });\n const result = this.db\n .prepare(\n `INSERT INTO debate_messages (debate_id, round, role, bridge, model, prompt_text, status, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, 'queued', ?, ?)`,\n )\n .run(\n params.debateId,\n params.round,\n params.role,\n params.bridge,\n params.model,\n sanitized.sanitized,\n now,\n now,\n );\n return Number(result.lastInsertRowid);\n }\n\n /** Update prompt text on a queued or failed row (for retries with different prompts). */\n updatePrompt(id: number, promptText: string): boolean {\n const sanitized = sanitize(promptText, { mode: 'strict' });\n const result = this.db\n .prepare(\n `UPDATE debate_messages SET prompt_text = ?, updated_at = ?\n WHERE id = ? AND status IN ('queued', 'failed')`,\n )\n .run(sanitized.sanitized, Date.now(), id);\n return result.changes === 1;\n }\n\n /** Transition to running. Only from queued or failed. Returns true if transition succeeded. */\n markRunning(id: number): boolean {\n const result = this.db\n .prepare(\n `UPDATE debate_messages SET status = 'running', updated_at = ?\n WHERE id = ? AND status IN ('queued', 'failed')`,\n )\n .run(Date.now(), id);\n return result.changes === 1;\n }\n\n /** Transition to completed with response data. Only from running. */\n markCompleted(\n id: number,\n params: {\n responseText: string;\n verdict: ParsedVerdict;\n usageJson: string;\n durationMs: number;\n sessionId: string | null;\n },\n ): boolean {\n const now = Date.now();\n const sanitizedResponse = sanitize(params.responseText, { mode: 'strict' });\n const sanitizedError = params.verdict.raw\n ? sanitize(params.verdict.raw, { mode: 'strict' }).sanitized\n : null;\n const result = this.db\n .prepare(\n `UPDATE debate_messages SET\n status = 'completed',\n response_text = ?,\n stance = ?,\n confidence = ?,\n verdict_raw = ?,\n usage_json = ?,\n duration_ms = ?,\n session_id = ?,\n error = NULL,\n updated_at = ?,\n completed_at = ?\n WHERE id = ? AND status = 'running'`,\n )\n .run(\n sanitizedResponse.sanitized,\n params.verdict.stance,\n params.verdict.confidence,\n sanitizedError,\n params.usageJson,\n params.durationMs,\n params.sessionId,\n now,\n now,\n id,\n );\n return result.changes === 1;\n }\n\n /** Transition to failed with error. Only from running. */\n markFailed(id: number, error: string): boolean {\n const sanitizedError = sanitize(error, { mode: 'strict' });\n const result = this.db\n .prepare(\n `UPDATE debate_messages SET status = 'failed', error = ?, updated_at = ?\n WHERE id = ? AND status = 'running'`,\n )\n .run(sanitizedError.sanitized, Date.now(), id);\n return result.changes === 1;\n }\n\n /** Get a message by debate_id, round, and role (for idempotency checks). */\n getByRound(debateId: string, round: number, role: string): DebateMessageRow | null {\n const row = this.db\n .prepare('SELECT * FROM debate_messages WHERE debate_id = ? AND round = ? AND role = ? LIMIT 1')\n .get(debateId, round, role) as Record<string, unknown> | undefined;\n return row ? this.toRow(row) : null;\n }\n\n /** Get full message history for a debate, ordered by round. */\n getHistory(debateId: string): DebateMessageRow[] {\n const rows = this.db\n .prepare('SELECT * FROM debate_messages WHERE debate_id = ? ORDER BY round ASC, role ASC')\n .all(debateId) as Record<string, unknown>[];\n return rows.map(r => this.toRow(r));\n }\n\n /** Recover stale running rows older than threshold. Returns count recovered. */\n recoverStale(thresholdMs: number): number {\n const cutoff = Date.now() - thresholdMs;\n const result = this.db\n .prepare(\n `UPDATE debate_messages SET status = 'failed', error = 'STALE_RECOVERY', updated_at = ?\n WHERE status = 'running' AND updated_at < ?`,\n )\n .run(Date.now(), cutoff);\n return result.changes;\n }\n\n /** Recover stale running rows for a specific debate only. */\n recoverStaleForDebate(debateId: string, thresholdMs: number): number {\n const cutoff = Date.now() - thresholdMs;\n const result = this.db\n .prepare(\n `UPDATE debate_messages SET status = 'failed', error = 'STALE_RECOVERY', updated_at = ?\n WHERE status = 'running' AND debate_id = ? AND updated_at < ?`,\n )\n .run(Date.now(), debateId, cutoff);\n return result.changes;\n }\n\n private toRow(row: Record<string, unknown>): DebateMessageRow {\n return {\n id: row.id as number,\n debateId: row.debate_id as string,\n round: row.round as number,\n role: row.role as string,\n bridge: (row.bridge as string) ?? 'codex',\n model: row.model as string,\n promptText: row.prompt_text as string,\n responseText: (row.response_text as string) ?? null,\n stance: (row.stance as string) ?? null,\n confidence: (row.confidence as number) ?? null,\n verdictRaw: (row.verdict_raw as string) ?? null,\n usageJson: (row.usage_json as string) ?? null,\n durationMs: (row.duration_ms as number) ?? null,\n sessionId: (row.session_id as string) ?? null,\n status: (row.status as MessageStatus) ?? 'queued',\n error: (row.error as string) ?? null,\n createdAt: row.created_at as number,\n updatedAt: row.updated_at as number,\n completedAt: (row.completed_at as number) ?? null,\n };\n }\n}\n","// packages/core/src/memory/reconstruction.ts — Build reconstruction prompts from stored debate history\n\nimport type { DebateMessageRow } from './message-store.js';\n\n/**\n * Build a reconstruction preamble from stored debate messages.\n * Used when session resume fails and we need to give GPT context of previous rounds.\n *\n * Strategy:\n * - If history fits within tokenBudget: include all rounds verbatim\n * - If over budget: summarize oldest rounds, keep newest verbatim\n *\n * @param history - Previous completed messages from MessageStore.getHistory()\n * @param currentPrompt - The new prompt for this round\n * @param maxChars - Approximate character budget (rough proxy for tokens; ~4 chars/token)\n * @returns The reconstructed prompt with history preamble\n */\nexport function buildReconstructionPrompt(\n history: DebateMessageRow[],\n currentPrompt: string,\n maxChars = 100_000,\n): string {\n const completed = history.filter(m => m.status === 'completed' && m.responseText);\n\n if (completed.length === 0) {\n return currentPrompt;\n }\n\n // Build verbatim history blocks\n const blocks: string[] = [];\n for (const msg of completed) {\n blocks.push(\n `## Round ${msg.round} (${msg.role})\\n**Prompt:** ${truncate(msg.promptText, 500)}\\n**Response:** ${msg.responseText}${msg.stance ? `\\n**Stance:** ${msg.stance}` : ''}`,\n );\n }\n\n const preamble = `This is a continuation of a debate. The session was interrupted and context must be reconstructed from the conversation ledger.\\n\\n# Previous Rounds\\n\\n${blocks.join('\\n\\n')}\\n\\n# Current Round\\n\\n`;\n const full = preamble + currentPrompt;\n\n // If within budget, return full\n if (full.length <= maxChars) {\n return full;\n }\n\n // Over budget: summarize oldest rounds, keep newest verbatim\n return buildCompressedPrompt(completed, currentPrompt, maxChars);\n}\n\nfunction buildCompressedPrompt(\n history: DebateMessageRow[],\n currentPrompt: string,\n maxChars: number,\n): string {\n // Keep newest rounds verbatim, summarize oldest\n const verbatimCount = Math.max(1, Math.min(3, Math.floor(history.length / 2)));\n const toSummarize = history.slice(0, -verbatimCount);\n const toKeep = history.slice(-verbatimCount);\n\n const summaryParts: string[] = [];\n for (const msg of toSummarize) {\n const stanceStr = msg.stance ? ` (${msg.stance})` : '';\n summaryParts.push(`- Round ${msg.round}: ${truncate(msg.responseText ?? '', 200)}${stanceStr}`);\n }\n\n const verbatimParts: string[] = [];\n for (const msg of toKeep) {\n verbatimParts.push(\n `## Round ${msg.round} (${msg.role})\\n**Response:** ${msg.responseText}${msg.stance ? `\\n**Stance:** ${msg.stance}` : ''}`,\n );\n }\n\n let result = `This is a continuation of a debate. Context reconstructed from ledger.\\n\\n# Summary of Earlier Rounds\\n${summaryParts.join('\\n')}\\n\\n# Recent Rounds (verbatim)\\n\\n${verbatimParts.join('\\n\\n')}\\n\\n# Current Round\\n\\n${currentPrompt}`;\n\n // If still over budget, aggressively truncate summaries\n if (result.length > maxChars) {\n result = `Context reconstructed from ledger (truncated).\\n\\n# Most Recent Round\\n\\n${verbatimParts[verbatimParts.length - 1]}\\n\\n# Current Round\\n\\n${currentPrompt}`;\n }\n\n return result.slice(0, maxChars);\n}\n\nfunction truncate(text: string, maxLen: number): string {\n if (text.length <= maxLen) return text;\n return `${text.slice(0, maxLen)}... [truncated]`;\n}\n","// packages/core/src/memory/token-budget.ts — Token budget tracking and management for debates\n\nimport type { DebateMessageRow } from './message-store.js';\n\n/** Rough estimate: ~4 characters per token for English text. */\nconst CHARS_PER_TOKEN = 4;\n\nexport interface TokenBudgetStatus {\n /** Total tokens used across all rounds. */\n totalTokensUsed: number;\n /** Maximum context tokens for the model. */\n maxContextTokens: number;\n /** Usage as a fraction (0-1). */\n utilizationRatio: number;\n /** Whether auto-summarization is recommended (>= 70%). */\n shouldSummarize: boolean;\n /** Whether the debate should be completed (>= 90%). */\n shouldStop: boolean;\n /** Estimated tokens remaining. */\n tokensRemaining: number;\n}\n\n/** Estimate token count from character length. */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\n/**\n * Calculate total tokens used in a debate from stored messages.\n * Uses actual usage_json when available, falls back to text length estimation.\n */\nexport function calculateDebateTokens(history: DebateMessageRow[]): number {\n let total = 0;\n for (const msg of history) {\n if (msg.usageJson) {\n try {\n const usage = JSON.parse(msg.usageJson);\n total += (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0);\n continue;\n } catch {\n // Fall through to estimation\n }\n }\n // Estimate from text lengths\n total += estimateTokens(msg.promptText);\n if (msg.responseText) {\n total += estimateTokens(msg.responseText);\n }\n }\n return total;\n}\n\n/**\n * Get the current token budget status for a debate.\n */\nexport function getTokenBudgetStatus(\n history: DebateMessageRow[],\n maxContextTokens: number,\n): TokenBudgetStatus {\n const totalTokensUsed = calculateDebateTokens(history);\n const utilizationRatio = maxContextTokens > 0 ? totalTokensUsed / maxContextTokens : 0;\n\n return {\n totalTokensUsed,\n maxContextTokens,\n utilizationRatio,\n shouldSummarize: utilizationRatio >= 0.7,\n shouldStop: utilizationRatio >= 0.9,\n tokensRemaining: Math.max(0, maxContextTokens - totalTokensUsed),\n };\n}\n\n/**\n * Preflight check: estimate if a new prompt will fit within budget.\n * Returns the status AFTER the hypothetical send.\n */\nexport function preflightTokenCheck(\n history: DebateMessageRow[],\n newPrompt: string,\n maxContextTokens: number,\n): TokenBudgetStatus {\n const currentTokens = calculateDebateTokens(history);\n const promptTokens = estimateTokens(newPrompt);\n const projected = currentTokens + promptTokens;\n const utilizationRatio = maxContextTokens > 0 ? projected / maxContextTokens : 0;\n\n return {\n totalTokensUsed: projected,\n maxContextTokens,\n utilizationRatio,\n shouldSummarize: utilizationRatio >= 0.7,\n shouldStop: utilizationRatio >= 0.9,\n tokensRemaining: Math.max(0, maxContextTokens - projected),\n };\n}\n","// packages/core/src/memory/unified-session.ts — Unified session management\n\nimport type Database from 'better-sqlite3';\nimport { generateId } from '../utils/id.js';\nimport { sanitize } from '../security/dlp.js';\nimport { estimateTokens } from './token-budget.js';\n\nexport interface UnifiedSession {\n id: string;\n name: string | null;\n codexThreadId: string | null;\n status: 'active' | 'completed' | 'stale';\n tokenUsage: number;\n maxContext: number;\n createdAt: number;\n updatedAt: number;\n completedAt: number | null;\n}\n\nexport interface SessionEvent {\n id: number;\n sessionId: string;\n command: string;\n subcommand: string | null;\n promptPreview: string | null;\n responsePreview: string | null;\n usageJson: string | null;\n durationMs: number | null;\n codexThreadId: string | null;\n createdAt: number;\n}\n\nexport interface SessionOverflowStatus {\n /** Cumulative tokens (for cost tracking). */\n cumulativeTokens: number;\n /** Latest turn's input_tokens (best proxy for current context fullness). */\n lastTurnInputTokens: number;\n maxContext: number;\n /** Based on lastTurnInputTokens / maxContext. */\n utilizationRatio: number;\n shouldWarn: boolean; // > 75%\n shouldReconstruct: boolean; // > 85%\n}\n\nexport class SessionManager {\n constructor(private db: Database.Database) {}\n\n /** Create a new session. Returns the session ID. */\n create(name?: string): string {\n const id = generateId();\n const now = Date.now();\n this.db\n .prepare(\n `INSERT INTO codemoot_sessions (id, name, status, created_at, updated_at)\n VALUES (?, ?, 'active', ?, ?)`,\n )\n .run(id, name ?? null, now, now);\n return id;\n }\n\n /** Get a session by ID. */\n get(id: string): UnifiedSession | null {\n const row = this.db\n .prepare('SELECT * FROM codemoot_sessions WHERE id = ?')\n .get(id) as Record<string, unknown> | undefined;\n return row ? this.toSession(row) : null;\n }\n\n /** Get the current active session (most recently updated). */\n getActive(): UnifiedSession | null {\n const row = this.db\n .prepare(\"SELECT * FROM codemoot_sessions WHERE status = 'active' ORDER BY updated_at DESC LIMIT 1\")\n .get() as Record<string, unknown> | undefined;\n return row ? this.toSession(row) : null;\n }\n\n /** Get or create the active session. If none exists, auto-create one. */\n resolveActive(autoName?: string): UnifiedSession {\n const existing = this.getActive();\n if (existing) return existing;\n const id = this.create(autoName);\n return this.get(id) as UnifiedSession;\n }\n\n /** Update the codex thread ID for a session (after first GPT call). */\n updateThreadId(sessionId: string, threadId: string): void {\n this.db\n .prepare(\n 'UPDATE codemoot_sessions SET codex_thread_id = ?, updated_at = ? WHERE id = ?',\n )\n .run(threadId, Date.now(), sessionId);\n }\n\n /** Update token usage for a session. Ignores negative values. */\n addTokenUsage(sessionId: string, tokens: number): void {\n if (!Number.isFinite(tokens) || tokens <= 0) return;\n tokens = Math.floor(tokens);\n this.db\n .prepare(\n 'UPDATE codemoot_sessions SET token_usage = token_usage + ?, updated_at = ? WHERE id = ?',\n )\n .run(tokens, Date.now(), sessionId);\n }\n\n /**\n * Add token usage from a model call result. Uses real usage when available,\n * falls back to char/4 estimate only when usage data is missing.\n */\n addUsageFromResult(sessionId: string, usage: { totalTokens?: number; inputTokens?: number; outputTokens?: number }, promptText?: string, responseText?: string): void {\n const realTokens = usage.totalTokens || ((usage.inputTokens ?? 0) + (usage.outputTokens ?? 0));\n if (realTokens > 0) {\n this.addTokenUsage(sessionId, realTokens);\n } else if (promptText || responseText) {\n this.addTokenUsage(sessionId, this.estimateEventTokens(promptText ?? '', responseText ?? ''));\n }\n }\n\n /** Touch the updated_at timestamp. */\n touch(sessionId: string): void {\n this.db\n .prepare('UPDATE codemoot_sessions SET updated_at = ? WHERE id = ?')\n .run(Date.now(), sessionId);\n }\n\n /** Mark a session as completed. */\n complete(sessionId: string): void {\n const now = Date.now();\n this.db\n .prepare(\n \"UPDATE codemoot_sessions SET status = 'completed', updated_at = ?, completed_at = ? WHERE id = ?\",\n )\n .run(now, now, sessionId);\n }\n\n /** List sessions, optionally filtered by status. */\n list(options?: { status?: string; limit?: number }): UnifiedSession[] {\n const rawLimit = options?.limit ?? 20;\n const limit = Number.isFinite(rawLimit) && rawLimit > 0 ? Math.min(rawLimit, 100) : 20;\n let sql = 'SELECT * FROM codemoot_sessions';\n const params: unknown[] = [];\n if (options?.status) {\n sql += ' WHERE status = ?';\n params.push(options.status);\n }\n sql += ' ORDER BY updated_at DESC LIMIT ?';\n params.push(limit);\n const rows = this.db.prepare(sql).all(...params) as Record<string, unknown>[];\n return rows.map(r => this.toSession(r));\n }\n\n /** Get overflow status for a session. Uses latest turn's input_tokens as context fullness signal. */\n getOverflowStatus(sessionId: string): SessionOverflowStatus {\n const session = this.get(sessionId);\n if (!session) {\n return { cumulativeTokens: 0, lastTurnInputTokens: 0, maxContext: 400_000, utilizationRatio: 0, shouldWarn: false, shouldReconstruct: false };\n }\n // 128K was the old incorrect default; codex context is 400K\n const maxCtx = (session.maxContext > 0 && session.maxContext !== 128_000) ? session.maxContext : 400_000;\n\n // Get latest event's input_tokens as best proxy for current context size\n const latestEvents = this.getEvents(sessionId, 1);\n let lastTurnInput = 0;\n if (latestEvents.length > 0 && latestEvents[0].usageJson) {\n try {\n const usage = JSON.parse(latestEvents[0].usageJson);\n const raw = usage.inputTokens ?? usage.input_tokens ?? 0;\n lastTurnInput = typeof raw === 'number' && Number.isFinite(raw) && raw > 0 ? raw : 0;\n } catch { /* malformed JSON */ }\n }\n\n const ratio = lastTurnInput / maxCtx;\n return {\n cumulativeTokens: session.tokenUsage,\n lastTurnInputTokens: lastTurnInput,\n maxContext: maxCtx,\n utilizationRatio: ratio,\n shouldWarn: ratio > 0.75,\n shouldReconstruct: ratio > 0.85,\n };\n }\n\n /** Pre-call check: auto-rollover if session context is over threshold. Call before every codex interaction. */\n preCallOverflowCheck(sessionId: string, threshold = 0.85): { rolled: boolean; message?: string } {\n const status = this.getOverflowStatus(sessionId);\n if (status.utilizationRatio > threshold) {\n this.rolloverThread(sessionId);\n const pct = Math.round(status.utilizationRatio * 100);\n return { rolled: true, message: `Session at ${pct}%. Rolling over to new thread.` };\n }\n return { rolled: false };\n }\n\n /** Roll over to a new codex thread (on context overflow). Returns new thread info. */\n rolloverThread(sessionId: string): void {\n this.db\n .prepare(\n 'UPDATE codemoot_sessions SET codex_thread_id = NULL, updated_at = ? WHERE id = ?',\n )\n .run(Date.now(), sessionId);\n }\n\n // ── Session Events ──\n\n /** Record a GPT interaction event. Stores preview (500 chars) + optional full text. */\n recordEvent(params: {\n sessionId: string;\n command: string;\n subcommand?: string;\n promptPreview?: string;\n responsePreview?: string;\n promptFull?: string;\n responseFull?: string;\n usageJson?: string;\n durationMs?: number;\n codexThreadId?: string;\n }): number {\n const sanitizedPrompt = params.promptPreview\n ? sanitize(params.promptPreview.slice(0, 500), { mode: 'strict' }).sanitized\n : null;\n const sanitizedResponse = params.responsePreview\n ? sanitize(params.responsePreview.slice(0, 500), { mode: 'strict' }).sanitized\n : null;\n const sanitizedPromptFull = params.promptFull\n ? sanitize(params.promptFull, { mode: 'strict' }).sanitized\n : null;\n const sanitizedResponseFull = params.responseFull\n ? sanitize(params.responseFull, { mode: 'strict' }).sanitized\n : null;\n\n const result = this.db\n .prepare(\n `INSERT INTO session_events (session_id, command, subcommand, prompt_preview, response_preview, prompt_full, response_full, usage_json, duration_ms, codex_thread_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n params.sessionId,\n params.command,\n params.subcommand ?? null,\n sanitizedPrompt,\n sanitizedResponse,\n sanitizedPromptFull,\n sanitizedResponseFull,\n params.usageJson ?? null,\n params.durationMs ?? null,\n params.codexThreadId ?? null,\n Date.now(),\n );\n return Number(result.lastInsertRowid);\n }\n\n /** Get events for a session. */\n getEvents(sessionId: string, rawLimit = 50): SessionEvent[] {\n const limit = Number.isFinite(rawLimit) && rawLimit > 0 ? Math.min(rawLimit, 200) : 50;\n const rows = this.db\n .prepare('SELECT * FROM session_events WHERE session_id = ? ORDER BY created_at DESC, id DESC LIMIT ?')\n .all(sessionId, limit) as Record<string, unknown>[];\n return rows.map(r => ({\n id: r.id as number,\n sessionId: r.session_id as string,\n command: r.command as string,\n subcommand: (r.subcommand as string) ?? null,\n promptPreview: (r.prompt_preview as string) ?? null,\n responsePreview: (r.response_preview as string) ?? null,\n usageJson: (r.usage_json as string) ?? null,\n durationMs: (r.duration_ms as number) ?? null,\n codexThreadId: (r.codex_thread_id as string) ?? null,\n createdAt: r.created_at as number,\n }));\n }\n\n /** Estimate tokens from prompt + response text (for usage tracking when real usage unavailable). */\n estimateEventTokens(promptText: string, responseText: string): number {\n return estimateTokens(promptText) + estimateTokens(responseText);\n }\n\n private toSession(row: Record<string, unknown>): UnifiedSession {\n return {\n id: row.id as string,\n name: (row.name as string) ?? null,\n codexThreadId: (row.codex_thread_id as string) ?? null,\n status: (row.status as UnifiedSession['status']) ?? 'active',\n tokenUsage: (row.token_usage as number) ?? 0,\n maxContext: (row.max_context as number) ?? 400_000,\n createdAt: row.created_at as number,\n updatedAt: row.updated_at as number,\n completedAt: (row.completed_at as number) ?? null,\n };\n }\n}\n","// packages/core/src/memory/job-store.ts — SQLite-backed job queue for background async work\n\nimport type Database from 'better-sqlite3';\nimport type { EnqueueOptions, JobLogRecord, JobRecord, JobStatus, JobType } from '../types/jobs.js';\nimport { generateId } from '../utils/id.js';\n\nexport class JobStore {\n constructor(private db: Database.Database) {}\n\n /** Enqueue a new job. Returns the job ID. */\n enqueue(options: EnqueueOptions): string {\n const id = generateId();\n const now = Date.now();\n this.db\n .prepare(\n `INSERT INTO jobs (id, type, status, priority, dedupe_key, payload_json, max_retries, session_id, created_at, updated_at)\n VALUES (?, ?, 'queued', ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n id,\n options.type,\n options.priority ?? 100,\n options.dedupeKey ?? null,\n JSON.stringify(options.payload),\n options.maxRetries ?? 1,\n options.sessionId ?? null,\n now,\n now,\n );\n return id;\n }\n\n /** Get a job by ID. */\n get(id: string): JobRecord | null {\n const row = this.db\n .prepare('SELECT * FROM jobs WHERE id = ?')\n .get(id) as Record<string, unknown> | undefined;\n return row ? this.toJob(row) : null;\n }\n\n /** Atomically claim the next N queued jobs. Returns claimed jobs. */\n claimNext(workerId: string, limit = 1): JobRecord[] {\n const now = Date.now();\n // Two-step: select then update (SQLite doesn't support UPDATE...RETURNING with ORDER BY LIMIT)\n const rows = this.db\n .prepare(\n `SELECT id FROM jobs WHERE status = 'queued' ORDER BY priority ASC, created_at ASC LIMIT ?`,\n )\n .all(limit) as { id: string }[];\n\n if (rows.length === 0) return [];\n\n const claimed: JobRecord[] = [];\n const claimStmt = this.db.prepare(\n `UPDATE jobs SET status = 'running', worker_id = ?, started_at = ?, updated_at = ? WHERE id = ? AND status = 'queued'`,\n );\n\n for (const row of rows) {\n const result = claimStmt.run(workerId, now, now, row.id);\n if (result.changes > 0) {\n const job = this.get(row.id);\n if (job) claimed.push(job);\n }\n }\n return claimed;\n }\n\n /** Mark a job as succeeded. Only updates if still running (not canceled). */\n succeed(id: string, result: Record<string, unknown>): void {\n const now = Date.now();\n this.db\n .prepare(\n `UPDATE jobs SET status = 'succeeded', result_json = ?, finished_at = ?, updated_at = ? WHERE id = ? AND status = 'running'`,\n )\n .run(JSON.stringify(result), now, now, id);\n }\n\n /** Mark a job as failed. Only updates if still running (not canceled). */\n fail(id: string, error: string): void {\n const now = Date.now();\n this.db\n .prepare(\n `UPDATE jobs SET status = 'failed', error_text = ?, finished_at = ?, updated_at = ? WHERE id = ? AND status = 'running'`,\n )\n .run(error, now, now, id);\n }\n\n /** Cancel a job. */\n cancel(id: string): void {\n const now = Date.now();\n this.db\n .prepare(\n `UPDATE jobs SET status = 'canceled', finished_at = ?, updated_at = ? WHERE id = ? AND status IN ('queued', 'running')`,\n )\n .run(now, now, id);\n }\n\n /** Retry a failed/canceled job. */\n retry(id: string): boolean {\n const job = this.get(id);\n if (!job) return false;\n if (job.status !== 'failed' && job.status !== 'canceled') return false;\n if (job.retryCount >= job.maxRetries) return false;\n\n const now = Date.now();\n this.db\n .prepare(\n `UPDATE jobs SET status = 'queued', retry_count = retry_count + 1, error_text = NULL, result_json = NULL, worker_id = NULL, started_at = NULL, finished_at = NULL, updated_at = ? WHERE id = ?`,\n )\n .run(now, id);\n return true;\n }\n\n /** List jobs with optional filters. */\n list(options?: { status?: JobStatus; type?: JobType; limit?: number }): JobRecord[] {\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (options?.status) {\n conditions.push('status = ?');\n params.push(options.status);\n }\n if (options?.type) {\n conditions.push('type = ?');\n params.push(options.type);\n }\n\n const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n const limit = options?.limit ?? 50;\n params.push(limit);\n\n const rows = this.db\n .prepare(`SELECT * FROM jobs ${where} ORDER BY created_at DESC LIMIT ?`)\n .all(...params) as Record<string, unknown>[];\n\n return rows.map(r => this.toJob(r));\n }\n\n /** Check if a dedupe key already has an active (queued/running) job. */\n hasActive(dedupeKey: string): boolean {\n const row = this.db\n .prepare(`SELECT 1 FROM jobs WHERE dedupe_key = ? AND status IN ('queued', 'running') LIMIT 1`)\n .get(dedupeKey);\n return Boolean(row);\n }\n\n /** Check if any active job exists for a given type. */\n hasActiveByType(type: string): boolean {\n const row = this.db\n .prepare(`SELECT 1 FROM jobs WHERE type = ? AND status IN ('queued', 'running') LIMIT 1`)\n .get(type);\n return Boolean(row);\n }\n\n // ── Job Logs ──\n\n /** Append a log entry. */\n appendLog(jobId: string, level: JobLogRecord['level'], eventType: string, message?: string, payload?: Record<string, unknown>): void {\n const maxSeq = this.db\n .prepare('SELECT COALESCE(MAX(seq), 0) AS max_seq FROM job_logs WHERE job_id = ?')\n .get(jobId) as { max_seq: number };\n\n this.db\n .prepare(\n `INSERT INTO job_logs (job_id, seq, level, event_type, message, payload_json, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(jobId, maxSeq.max_seq + 1, level, eventType, message ?? null, payload ? JSON.stringify(payload) : null, Date.now());\n }\n\n /** Get logs for a job. */\n getLogs(jobId: string, fromSeq = 0, limit = 100): JobLogRecord[] {\n const rows = this.db\n .prepare('SELECT * FROM job_logs WHERE job_id = ? AND seq > ? ORDER BY seq ASC LIMIT ?')\n .all(jobId, fromSeq, limit) as Record<string, unknown>[];\n\n return rows.map(r => ({\n id: r.id as number,\n jobId: r.job_id as string,\n seq: r.seq as number,\n level: r.level as JobLogRecord['level'],\n eventType: r.event_type as string,\n message: (r.message as string) ?? null,\n payloadJson: (r.payload_json as string) ?? null,\n createdAt: r.created_at as number,\n }));\n }\n\n private toJob(row: Record<string, unknown>): JobRecord {\n return {\n id: row.id as string,\n type: row.type as JobType,\n status: row.status as JobStatus,\n priority: row.priority as number,\n dedupeKey: (row.dedupe_key as string) ?? null,\n payloadJson: row.payload_json as string,\n resultJson: (row.result_json as string) ?? null,\n errorText: (row.error_text as string) ?? null,\n retryCount: row.retry_count as number,\n maxRetries: row.max_retries as number,\n sessionId: (row.session_id as string) ?? null,\n workerId: (row.worker_id as string) ?? null,\n startedAt: (row.started_at as number) ?? null,\n finishedAt: (row.finished_at as number) ?? null,\n createdAt: row.created_at as number,\n updatedAt: row.updated_at as number,\n };\n }\n}\n","// packages/core/src/memory/cache-store.ts — Result caching with content+config hash\n\nimport { createHash } from 'node:crypto';\nimport type Database from 'better-sqlite3';\n\nexport interface CacheEntry {\n id: number;\n key: string;\n kind: string;\n contentHash: string;\n configHash: string;\n model: string;\n valueJson: string;\n expiresAt: number;\n hitCount: number;\n createdAt: number;\n}\n\nexport class CacheStore {\n constructor(private db: Database.Database) {}\n\n get(key: string, contentHash: string, configHash: string): CacheEntry | null {\n const row = this.db\n .prepare(\n 'SELECT id, key, kind, content_hash, config_hash, model, value_json, expires_at, hit_count, created_at FROM cache_entries WHERE key = ? AND content_hash = ? AND config_hash = ? AND expires_at > ?',\n )\n .get(key, contentHash, configHash, Date.now()) as Record<string, unknown> | undefined;\n\n if (row) {\n this.db\n .prepare('UPDATE cache_entries SET hit_count = hit_count + 1 WHERE id = ?')\n .run(row.id);\n return {\n id: row.id as number,\n key: row.key as string,\n kind: row.kind as string,\n contentHash: row.content_hash as string,\n configHash: row.config_hash as string,\n model: row.model as string,\n valueJson: row.value_json as string,\n expiresAt: row.expires_at as number,\n hitCount: row.hit_count as number,\n createdAt: row.created_at as number,\n };\n }\n return null;\n }\n\n set(entry: {\n key: string;\n kind: string;\n contentHash: string;\n configHash: string;\n model: string;\n valueJson: string;\n ttlMs: number;\n }): void {\n // Upsert: delete old entries for same key first\n this.db.prepare('DELETE FROM cache_entries WHERE key = ?').run(entry.key);\n this.db\n .prepare(\n 'INSERT INTO cache_entries (key, kind, content_hash, config_hash, model, value_json, expires_at, hit_count, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?)',\n )\n .run(\n entry.key,\n entry.kind,\n entry.contentHash,\n entry.configHash,\n entry.model,\n entry.valueJson,\n Date.now() + entry.ttlMs,\n Date.now(),\n );\n }\n\n evictExpired(): number {\n const result = this.db\n .prepare('DELETE FROM cache_entries WHERE expires_at <= ?')\n .run(Date.now());\n return result.changes;\n }\n\n clear(): number {\n const result = this.db.prepare('DELETE FROM cache_entries').run();\n return result.changes;\n }\n\n stats(): { totalEntries: number; totalHits: number; expiredCount: number } {\n const total = this.db.prepare('SELECT COUNT(*) as cnt FROM cache_entries').get() as {\n cnt: number;\n };\n const hits = this.db\n .prepare('SELECT COALESCE(SUM(hit_count), 0) as total FROM cache_entries')\n .get() as { total: number };\n const expired = this.db\n .prepare('SELECT COUNT(*) as cnt FROM cache_entries WHERE expires_at <= ?')\n .get(Date.now()) as { cnt: number };\n return { totalEntries: total.cnt, totalHits: hits.total, expiredCount: expired.cnt };\n }\n}\n\nexport function hashContent(content: string): string {\n return createHash('sha256').update(content).digest('hex').slice(0, 16);\n}\n\nexport function hashConfig(config: Record<string, unknown>): string {\n const sorted = JSON.stringify(config, Object.keys(config).sort());\n return createHash('sha256').update(sorted).digest('hex').slice(0, 16);\n}\n","// packages/core/src/models/cli-adapter.ts — CLI subprocess adapter for free model access\n\nimport { spawn } from 'node:child_process';\nimport { randomUUID } from 'node:crypto';\nimport { readFile, unlink } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport type { ModelProvider } from '../types/config.js';\nimport type { TokenUsage } from '../types/events.js';\nimport type { ModelCallResult } from '../types/models.js';\nimport { ModelError } from '../utils/errors.js';\nimport type { BridgeCapabilities, CliBridge } from './bridge.js';\n\nconst MAX_OUTPUT_BYTES = 512 * 1024; // 512KB\nconst TRUNCATION_MARKER = '\\n[TRUNCATED: output exceeded 512KB]';\n\n// Default env vars always passed to CLI subprocesses\nconst BASE_ENV_ALLOWLIST = [\n 'PATH',\n 'HOME',\n 'TEMP',\n 'TMP',\n 'USERPROFILE',\n 'SystemRoot',\n 'COMSPEC',\n 'SHELL',\n];\n\n// CLI-specific auth env vars\nconst CLI_AUTH_VARS: Record<string, string[]> = {\n codex: ['OPENAI_API_KEY'],\n};\n\n/** Progress callbacks for real-time feedback during CLI subprocess execution. */\nexport interface ProgressCallbacks {\n /** Called when the subprocess successfully spawns. */\n onSpawn?: (pid: number, command: string) => void;\n /** Called on each stderr chunk (tool calls, activity). */\n onStderr?: (chunk: string) => void;\n /** Called periodically (every 15s) with elapsed seconds. */\n onHeartbeat?: (elapsedSec: number) => void;\n /** Called on each stdout chunk for progress feedback. */\n onProgress?: (chunk: string) => void;\n}\n\nexport interface CliCallOptions extends ProgressCallbacks {\n /** Total timeout in ms. Default: 600_000 (10 min). */\n timeout?: number;\n /** Inactivity timeout — kill if no stdout for this long. Default: 120_000 (2 min). */\n idleTimeout?: number;\n maxOutputBytes?: number;\n envAllowlist?: string[];\n}\n\nexport interface ResumeCallOptions extends CliCallOptions {\n /** Codex thread_id to resume a conversation. */\n sessionId?: string;\n}\n\n/** Known context windows by model family. GPT-5 codex models have 400K. */\nconst MODEL_CONTEXT_WINDOWS: Record<string, number> = {\n 'gpt-5-codex': 400_000,\n 'gpt-5.1-codex': 400_000,\n 'gpt-5.2-codex': 400_000,\n 'gpt-5.3-codex': 400_000,\n 'codex-mini-latest': 200_000,\n};\nconst DEFAULT_CONTEXT_WINDOW = 400_000;\n\n/** Default capabilities for codex CLI bridge. */\nconst CODEX_CAPABILITIES: BridgeCapabilities = {\n supportsResume: true,\n supportsStream: true,\n maxContextTokens: DEFAULT_CONTEXT_WINDOW,\n supportsTools: true,\n supportsCwd: true,\n};\n\nexport class CliAdapter implements CliBridge {\n private command: string;\n private baseArgs: string[];\n private provider: ModelProvider;\n readonly modelId: string;\n private cliName: string;\n private projectDir: string | undefined;\n readonly capabilities: BridgeCapabilities;\n\n get name(): string { return this.cliName; }\n get model(): string { return this.modelId; }\n\n constructor(config: {\n command: string;\n args: string[];\n provider: ModelProvider;\n model: string;\n cliName: string;\n projectDir?: string;\n }) {\n this.command = config.command;\n this.baseArgs = config.args;\n this.provider = config.provider;\n this.modelId = config.model;\n this.cliName = config.cliName;\n this.projectDir = config.projectDir;\n this.capabilities = {\n ...CODEX_CAPABILITIES,\n maxContextTokens: MODEL_CONTEXT_WINDOWS[config.model] ?? DEFAULT_CONTEXT_WINDOW,\n };\n }\n\n /** CliBridge.send — send a prompt without session resume. */\n async send(prompt: string, options?: CliCallOptions): Promise<ModelCallResult> {\n return this.call(prompt, options);\n }\n\n /** CliBridge.resume — resume a session or fall back to send. */\n async resume(sessionId: string, prompt: string, options?: CliCallOptions): Promise<ModelCallResult> {\n if (!this.capabilities.supportsResume) {\n return this.send(prompt, options);\n }\n return this.callWithResume(prompt, { ...options, sessionId });\n }\n\n async call(prompt: string, options?: CliCallOptions): Promise<ModelCallResult> {\n const timeout = options?.timeout ?? 600_000;\n const maxBytes = options?.maxOutputBytes ?? MAX_OUTPUT_BYTES;\n\n // Build filtered env\n const allowlist = [\n ...BASE_ENV_ALLOWLIST,\n ...(CLI_AUTH_VARS[this.cliName] ?? []),\n ...(options?.envAllowlist ?? []),\n ];\n const env = buildFilteredEnv(allowlist);\n\n // Create temp output file\n const tmpFile = join(tmpdir(), `codemoot-cli-${randomUUID()}.txt`);\n\n // Build command args (prompt piped via stdin, not as CLI arg)\n const args = this.buildArgs(tmpFile);\n const start = Date.now();\n\n try {\n await this.runProcess(this.command, args, env, timeout, prompt, {\n idleTimeout: options?.idleTimeout,\n onProgress: options?.onProgress,\n onSpawn: options?.onSpawn,\n onStderr: options?.onStderr,\n onHeartbeat: options?.onHeartbeat,\n });\n\n // Codex writes to tmpFile via -o flag\n let output = await readFile(tmpFile, 'utf-8');\n\n if (Buffer.byteLength(output) > maxBytes) {\n output = Buffer.from(output).subarray(0, maxBytes).toString('utf-8') + TRUNCATION_MARKER;\n }\n\n const durationMs = Date.now() - start;\n const usage = estimateTokenUsage(prompt, output);\n\n return {\n text: output,\n model: this.modelId,\n provider: this.provider,\n usage,\n finishReason: 'stop',\n durationMs,\n };\n } finally {\n // Cleanup temp file\n await unlink(tmpFile).catch(() => {});\n }\n }\n\n /**\n * Call codex with session resume support via --json JSONL output.\n * If sessionId is provided, resumes the conversation. On resume failure,\n * falls back to a fresh exec and returns the new sessionId.\n */\n async callWithResume(prompt: string, options?: ResumeCallOptions): Promise<ModelCallResult> {\n const timeout = options?.timeout ?? 600_000;\n const maxBytes = options?.maxOutputBytes ?? MAX_OUTPUT_BYTES;\n\n const allowlist = [\n ...BASE_ENV_ALLOWLIST,\n ...(CLI_AUTH_VARS[this.cliName] ?? []),\n ...(options?.envAllowlist ?? []),\n ];\n const env = buildFilteredEnv(allowlist);\n\n const doCall = async (resumeId?: string): Promise<ModelCallResult> => {\n const ext = process.platform === 'win32' ? '.cmd' : '';\n\n // Always use stdin (\"-\") for prompt delivery:\n // - Fresh exec: stdin is the default prompt source\n // - Resume: positional arg breaks on Windows shell:true (spaces split into multiple args)\n // Using \"-\" tells codex to read the prompt from stdin instead\n // Build args: if we have a project dir, tell codex about it via --cd\n const cdArgs = this.projectDir ? ['-C', this.projectDir] : [];\n const args = resumeId\n ? ['exec', '--skip-git-repo-check', ...cdArgs, 'resume', resumeId, '-', '--json']\n : ['exec', '--skip-git-repo-check', ...cdArgs, '--json'];\n\n const start = Date.now();\n const stdout = await this.runProcess(`codex${ext}`, args, env, timeout, prompt, {\n idleTimeout: options?.idleTimeout,\n onProgress: options?.onProgress,\n onSpawn: options?.onSpawn,\n onStderr: options?.onStderr,\n onHeartbeat: options?.onHeartbeat,\n });\n\n // Parse JSONL output\n const parsed = parseCodexJsonl(stdout);\n\n let output = parsed.text;\n if (Buffer.byteLength(output) > maxBytes) {\n output = Buffer.from(output).subarray(0, maxBytes).toString('utf-8') + TRUNCATION_MARKER;\n }\n\n const durationMs = Date.now() - start;\n const usage = parsed.usage ?? estimateTokenUsage(prompt, output);\n\n return {\n text: output,\n model: this.modelId,\n provider: this.provider,\n usage,\n finishReason: 'stop',\n durationMs,\n sessionId: parsed.sessionId,\n };\n };\n\n // Try resume if sessionId provided\n if (options?.sessionId) {\n try {\n return await doCall(options.sessionId);\n } catch {\n // Resume failed — fall back to fresh exec\n console.error(`[codemoot] Resume failed for session ${options.sessionId}, falling back to fresh exec`);\n }\n }\n\n return doCall();\n }\n\n private buildArgs(outputFile: string): string[] {\n return [...this.baseArgs, '-o', outputFile];\n }\n\n private runProcess(\n command: string,\n args: string[],\n env: Record<string, string>,\n timeout: number,\n stdinData?: string,\n options?: { idleTimeout?: number } & ProgressCallbacks,\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n let lastActivityAt = startTime;\n\n const child = spawn(command, args, {\n cwd: this.projectDir ?? tmpdir(),\n env,\n stdio: ['pipe', 'pipe', 'pipe'],\n windowsHide: true,\n shell: process.platform === 'win32',\n });\n\n let stdout = '';\n let stderr = '';\n let stdoutBytes = 0;\n let settled = false;\n const maxCapture = MAX_OUTPUT_BYTES * 2; // Cap memory usage\n\n // Heartbeat interval — fires every 15s with elapsed time\n const heartbeatInterval = options?.onHeartbeat\n ? setInterval(() => {\n try { options.onHeartbeat?.(Math.round((Date.now() - startTime) / 1000)); } catch { /* callback error isolation */ }\n }, 15_000)\n : undefined;\n\n const cleanup = () => {\n clearTimeout(absoluteTimer);\n clearTimeout(idleTimer);\n if (heartbeatInterval) clearInterval(heartbeatInterval);\n };\n\n const fail = (err: ModelError) => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(err);\n };\n\n // Notify caller when process successfully spawns\n child.on('spawn', () => {\n try { options?.onSpawn?.(child.pid ?? 0, command); } catch { /* callback error isolation */ }\n });\n\n // Absolute timeout — hard ceiling, kills no matter what\n const elapsedMsg = () => `elapsed ${Date.now() - startTime}ms, last activity ${Date.now() - lastActivityAt}ms ago`;\n const absoluteTimer = setTimeout(() => {\n killProcessTree(child.pid);\n fail(\n new ModelError(\n `CLI subprocess absolute timeout (limit ${timeout}ms, ${elapsedMsg()})`,\n this.provider,\n this.modelId,\n ),\n );\n }, timeout);\n\n // Idle timeout — resets on every stdout/stderr chunk. Detects stalled processes.\n const idleMs = options?.idleTimeout ?? 120_000;\n let idleTimer = setTimeout(() => {\n killProcessTree(child.pid);\n fail(\n new ModelError(\n `CLI subprocess idle timeout (no output for ${idleMs}ms, total ${elapsedMsg()})`,\n this.provider,\n this.modelId,\n ),\n );\n }, idleMs);\n\n const resetIdleTimer = () => {\n lastActivityAt = Date.now();\n clearTimeout(idleTimer);\n idleTimer = setTimeout(() => {\n killProcessTree(child.pid);\n fail(\n new ModelError(\n `CLI subprocess idle timeout (no output for ${idleMs}ms, total ${elapsedMsg()})`,\n this.provider,\n this.modelId,\n ),\n );\n }, idleMs);\n };\n\n child.stdout.on('data', (data: Buffer) => {\n const chunk = data.toString();\n stdoutBytes += data.byteLength;\n if (stdoutBytes <= maxCapture) {\n stdout += chunk;\n }\n resetIdleTimer();\n try { options?.onProgress?.(chunk); } catch { /* callback error isolation */ }\n });\n child.stderr.on('data', (data: Buffer) => {\n const chunk = data.toString();\n if (stderr.length < 10_000) stderr += chunk;\n resetIdleTimer();\n try { options?.onStderr?.(chunk); } catch { /* callback error isolation */ }\n });\n\n if (stdinData) {\n child.stdin.write(stdinData);\n child.stdin.end();\n } else {\n child.stdin.end();\n }\n\n child.on('error', (err) => {\n fail(\n new ModelError(`CLI subprocess failed: ${err.message}`, this.provider, this.modelId),\n );\n });\n\n child.on('close', (code) => {\n if (settled) return;\n settled = true;\n cleanup();\n if (code !== 0) {\n reject(\n new ModelError(\n `CLI subprocess exited with code ${code}: ${stderr.slice(0, 500)}`,\n this.provider,\n this.modelId,\n ),\n );\n return;\n }\n resolve(stdout);\n });\n });\n }\n}\n\nexport function buildFilteredEnv(allowlist: string[]): Record<string, string> {\n const env: Record<string, string> = {};\n for (const key of allowlist) {\n const val = process.env[key];\n if (val !== undefined) {\n env[key] = val;\n }\n }\n return env;\n}\n\nexport function killProcessTree(pid: number | undefined): void {\n if (pid === undefined) return;\n try {\n if (process.platform === 'win32') {\n spawn('taskkill', ['/pid', String(pid), '/T', '/F'], { stdio: 'ignore' });\n } else {\n process.kill(-pid, 'SIGTERM');\n setTimeout(() => {\n try {\n process.kill(-pid, 'SIGKILL');\n } catch {\n // Process may already be dead\n }\n }, 5000);\n }\n } catch {\n // Process may already be dead\n }\n}\n\n/** Estimate tokens using char/4 heuristic. MeteringSource = 'estimated'. */\nexport function estimateTokenUsage(prompt: string, output: string): TokenUsage {\n const inputTokens = Math.ceil(prompt.length / 4);\n const outputTokens = Math.ceil(output.length / 4);\n return {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n costUsd: 0, // CLI mode = free\n };\n}\n\n/** Parse codex --json JSONL output into structured result. */\nexport function parseCodexJsonl(stdout: string): {\n sessionId?: string;\n text: string;\n usage?: TokenUsage;\n} {\n let sessionId: string | undefined;\n const textParts: string[] = [];\n let usage: TokenUsage | undefined;\n\n for (const line of stdout.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n try {\n const event = JSON.parse(trimmed);\n\n if (event.type === 'thread.started' && event.thread_id) {\n sessionId = event.thread_id;\n }\n\n if (\n event.type === 'item.completed' &&\n event.item?.type === 'agent_message' &&\n event.item.text\n ) {\n textParts.push(event.item.text);\n }\n\n if (event.type === 'turn.completed' && event.usage) {\n const u = event.usage;\n const inputTokens = (u.input_tokens ?? 0) + (u.cached_input_tokens ?? 0);\n const outputTokens = u.output_tokens ?? 0;\n usage = {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n costUsd: 0,\n };\n }\n } catch {\n // Skip malformed JSONL lines\n }\n }\n\n return { sessionId, text: textParts.join('\\n'), usage };\n}\n\nexport { MAX_OUTPUT_BYTES };\n","// packages/core/src/models/cli-detector.ts — Detect codex CLI availability\n\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\n\nexport interface CliDetectionResult {\n available: boolean;\n path?: string;\n version?: string;\n authOk?: boolean;\n detectedAt: number;\n error?: string;\n}\n\n// Cache TTL: 5 minutes\nconst CACHE_TTL = 5 * 60 * 1000;\nconst cache = new Map<string, CliDetectionResult>();\n\nexport async function detectCli(name: 'codex'): Promise<CliDetectionResult> {\n const cached = cache.get(name);\n if (cached && Date.now() - cached.detectedAt < CACHE_TTL) {\n return cached;\n }\n\n const result = await probeCliTool(name);\n cache.set(name, result);\n return result;\n}\n\nexport function clearDetectionCache(): void {\n cache.clear();\n}\n\n/** Exported for testing - get direct access to the cache */\nexport function getCacheForTesting(): Map<string, CliDetectionResult> {\n return cache;\n}\n\nasync function probeCliTool(name: 'codex'): Promise<CliDetectionResult> {\n const now = Date.now();\n\n // Step 1: Find executable\n const whichCmd = process.platform === 'win32' ? 'where' : 'which';\n let exePath: string;\n try {\n const { stdout } = await execFileAsync(whichCmd, [name], { timeout: 5000 });\n exePath = stdout.trim().split('\\n')[0];\n } catch {\n return {\n available: false,\n detectedAt: now,\n error: `${name} not found in PATH`,\n };\n }\n\n // Step 2: Get version\n let version: string | undefined;\n try {\n const { stdout } = await execFileAsync(name, ['--version'], {\n timeout: 5000,\n });\n version = stdout.trim();\n } catch {\n // Version check failed, continue without it\n }\n\n // Step 3: Smoke test (auth check)\n let authOk = false;\n try {\n await execFileAsync(name, ['exec', '--skip-git-repo-check', 'echo ok'], { timeout: 15000 });\n authOk = true;\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n return {\n available: true,\n path: exePath,\n version,\n authOk: false,\n detectedAt: now,\n error: `Auth check failed: ${errMsg}`,\n };\n }\n\n return {\n available: true,\n path: exePath,\n version,\n authOk,\n detectedAt: now,\n };\n}\n","// packages/core/src/models/registry.ts — CLI-only model registry\n\nimport type { ModelConfig, ProjectConfig } from '../types/config.js';\nimport { ModelError } from '../utils/errors.js';\nimport { CliAdapter } from './cli-adapter.js';\nimport { detectCli } from './cli-detector.js';\n\n/** All models are CLI adapters now. */\nexport type ModelAdapter = CliAdapter;\n\nexport class ModelRegistry {\n private models = new Map<string, ModelAdapter>();\n private configs = new Map<string, ModelConfig>();\n private constructor() {}\n\n /**\n * Build a registry from a ProjectConfig.\n * All models are CLI adapters (codex).\n */\n static fromConfig(config: ProjectConfig, projectDir?: string): ModelRegistry {\n const registry = new ModelRegistry();\n for (const [alias, modelConfig] of Object.entries(config.models)) {\n registry.models.set(alias, createCliAdapter(modelConfig, projectDir));\n registry.configs.set(alias, modelConfig);\n }\n return registry;\n }\n\n /**\n * Resolve auto mode — probe codex CLI availability.\n * Kept for API compatibility; all models are CLI now.\n */\n async resolveAutoMode(): Promise<void> {\n // No-op: all models are CLI adapters, no auto detection needed\n }\n\n /** Get the adapter for an alias, or null if not found. */\n tryGetAdapter(alias: string): ModelAdapter | null {\n return this.models.get(alias) ?? null;\n }\n\n /** Get the adapter for an alias. Throws if not found. */\n getAdapter(alias: string): ModelAdapter {\n const adapter = this.models.get(alias);\n if (!adapter) {\n throw new ModelError(\n `Unknown model alias: \"${alias}\". Available: ${[...this.models.keys()].join(', ')}`,\n );\n }\n return adapter;\n }\n\n /** Check if an alias is backed by CLI adapter (always true now). */\n isCliMode(_alias: string): boolean {\n return true;\n }\n\n /** Get the ModelConfig for an alias. */\n getModelConfig(alias: string): ModelConfig {\n const config = this.configs.get(alias);\n if (!config) {\n throw new ModelError(`Unknown model alias: \"${alias}\"`);\n }\n return config;\n }\n\n /** Resolve role -> alias -> ModelAdapter. */\n getAdapterForRole(role: string, config: ProjectConfig): ModelAdapter {\n const roleConfig = config.roles[role];\n if (!roleConfig) {\n throw new ModelError(\n `Unknown role: \"${role}\". Available: ${Object.keys(config.roles).join(', ')}`,\n );\n }\n return this.getAdapter(roleConfig.model);\n }\n\n /** Resolve role -> alias -> ModelConfig. */\n getModelConfigForRole(role: string, config: ProjectConfig): ModelConfig {\n const roleConfig = config.roles[role];\n if (!roleConfig) {\n throw new ModelError(`Unknown role: \"${role}\"`);\n }\n return this.getModelConfig(roleConfig.model);\n }\n\n /** List all registered model aliases. */\n listAliases(): string[] {\n return [...this.models.keys()];\n }\n\n /**\n * Health check: verify codex CLI is available and authenticated.\n */\n async healthCheckAll(): Promise<Map<string, boolean>> {\n const results = new Map<string, boolean>();\n // All models use codex — check once\n const detection = await detectCli('codex');\n const healthy = detection.available && (detection.authOk ?? false);\n for (const alias of this.configs.keys()) {\n results.set(alias, healthy);\n }\n return results;\n }\n}\n\n/** Create a CliAdapter from model config. */\nfunction createCliAdapter(config: ModelConfig, projectDir?: string): CliAdapter {\n const adapterConfig = config.cliAdapter ?? getDefaultCliConfig(projectDir);\n return new CliAdapter({\n command: adapterConfig.command,\n args: adapterConfig.args,\n provider: config.provider,\n model: config.model,\n cliName: 'codex',\n projectDir,\n });\n}\n\n/** Default codex CLI adapter config. */\nfunction getDefaultCliConfig(projectDir?: string): {\n command: string;\n args: string[];\n timeout: number;\n} {\n const ext = process.platform === 'win32' ? '.cmd' : '';\n const args = projectDir ? ['exec'] : ['exec', '--skip-git-repo-check'];\n return {\n command: `codex${ext}`,\n args,\n timeout: 600_000,\n };\n}\n\nexport { createCliAdapter };\n","// packages/core/src/security/retry.ts — Canonical retry policy from MCP architecture\r\n\r\nimport { HTTP_TOO_MANY_REQUESTS } from '../utils/constants.js';\r\nimport { sleep } from '../utils/sleep.js';\r\n\r\nexport interface RetryConfig {\r\n maxRetries: number;\r\n totalAttempts: number;\r\n toolTimeoutMs: number;\r\n onRetry?: (attempt: number, error: unknown, delayMs: number) => void;\r\n}\r\n\r\nexport interface AttemptResult<T> {\r\n result?: T;\r\n error?: Error;\r\n attempts: number;\r\n totalElapsedMs: number;\r\n}\r\n\r\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\r\n maxRetries: 3,\r\n totalAttempts: 5,\r\n toolTimeoutMs: 600_000,\r\n onRetry: undefined,\r\n};\r\n\r\n/**\r\n * Check if an error represents an HTTP 5xx or retryable network error.\r\n */\r\nexport function isRetryable(error: unknown): boolean {\r\n if (error instanceof Error) {\r\n const msg = error.message;\r\n if (msg.includes('ETIMEDOUT') || msg.includes('ECONNRESET') || msg.includes('ECONNREFUSED')) {\r\n return true;\r\n }\r\n }\r\n const status = getStatusCode(error);\r\n if (status !== undefined && status >= 500) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if an error represents an HTTP 429 rate limit.\r\n */\r\nexport function isRateLimit(error: unknown): boolean {\r\n return getStatusCode(error) === HTTP_TOO_MANY_REQUESTS;\r\n}\r\n\r\n/**\r\n * Parse the Retry-After header value from an error, clamped to 60s max.\r\n * Returns delay in milliseconds, or undefined if not found.\r\n */\r\nexport function parseRetryAfter(error: unknown): number | undefined {\r\n const headers = getHeaders(error);\r\n if (!headers) {\r\n return undefined;\r\n }\r\n\r\n const retryAfter =\r\n typeof headers.get === 'function'\r\n ? headers.get('retry-after')\r\n : (headers as Record<string, string>)['retry-after'];\r\n\r\n if (!retryAfter) {\r\n return undefined;\r\n }\r\n\r\n // Try parsing as seconds (integer)\r\n const seconds = Number(retryAfter);\r\n if (!Number.isNaN(seconds) && seconds >= 0) {\r\n return Math.min(seconds * 1000, 60_000);\r\n }\r\n\r\n // Try parsing as HTTP-date\r\n const dateMs = Date.parse(retryAfter);\r\n if (!Number.isNaN(dateMs)) {\r\n const delayMs = dateMs - Date.now();\r\n if (delayMs <= 0) {\r\n return 0;\r\n }\r\n return Math.min(delayMs, 60_000);\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Calculate exponential backoff with jitter.\r\n * Formula: min(1000 * 2^retryCount, 30000) + random jitter [0, 1000]ms\r\n */\r\nexport function calculateBackoff(retryCount: number): number {\r\n const base = Math.min(1000 * 2 ** retryCount, 30_000);\r\n const jitter = Math.floor(Math.random() * 1000);\r\n return base + jitter;\r\n}\r\n\r\n/**\r\n * Execute fn with canonical retry policy:\r\n * - totalAttempts <= 5 (absolute ceiling)\r\n * - 5xx -> retry (up to maxRetries)\r\n * - 429 -> wait-and-resume (parse Retry-After, clamp to 60s, progressive wait if missing)\r\n * - 4xx (except 429) -> fail immediately\r\n * - ETIMEDOUT, ECONNRESET, ECONNREFUSED -> retry\r\n * - Backoff: min(1000 * 2^retryCount, 30000) + random jitter [0, 1000]ms\r\n * - Timeout budget: if remaining < 5s, fail immediately\r\n */\r\nexport async function withCanonicalRetry<T>(\r\n fn: () => Promise<T>,\r\n config?: Partial<RetryConfig>,\r\n): Promise<AttemptResult<T>> {\r\n const cfg: RetryConfig = {\r\n ...DEFAULT_RETRY_CONFIG,\r\n ...config,\r\n };\r\n\r\n // Enforce absolute ceiling\r\n if (cfg.totalAttempts > 5) {\r\n cfg.totalAttempts = 5;\r\n }\r\n\r\n const startTime = Date.now();\r\n let retryCount = 0;\r\n let attemptCount = 0;\r\n\r\n while (attemptCount < cfg.totalAttempts) {\r\n // Check timeout budget before each attempt\r\n const elapsed = Date.now() - startTime;\r\n const remaining = cfg.toolTimeoutMs - elapsed;\r\n if (remaining < 5000) {\r\n return {\r\n error: new Error('Timeout budget exhausted: less than 5s remaining'),\r\n attempts: attemptCount,\r\n totalElapsedMs: Date.now() - startTime,\r\n };\r\n }\r\n\r\n attemptCount++;\r\n\r\n try {\r\n const result = await fn();\r\n return {\r\n result,\r\n attempts: attemptCount,\r\n totalElapsedMs: Date.now() - startTime,\r\n };\r\n } catch (err) {\r\n const error = err instanceof Error ? err : new Error(String(err));\r\n\r\n // 429 rate limit: wait and resume (does NOT count as a retry, but counts as attempt)\r\n if (isRateLimit(err)) {\r\n const retryAfterMs = parseRetryAfter(err);\r\n const delayMs = retryAfterMs ?? calculateBackoff(retryCount);\r\n\r\n if (cfg.onRetry) {\r\n cfg.onRetry(attemptCount, err, delayMs);\r\n }\r\n\r\n await sleep(delayMs);\r\n // Do not increment retryCount for 429\r\n continue;\r\n }\r\n\r\n // 5xx or network error: retry with backoff\r\n if (isRetryable(err) && retryCount < cfg.maxRetries) {\r\n const delayMs = calculateBackoff(retryCount);\r\n\r\n if (cfg.onRetry) {\r\n cfg.onRetry(attemptCount, err, delayMs);\r\n }\r\n\r\n retryCount++;\r\n await sleep(delayMs);\r\n continue;\r\n }\r\n\r\n // 4xx (non-429) or exhausted retries: fail immediately\r\n return {\r\n error,\r\n attempts: attemptCount,\r\n totalElapsedMs: Date.now() - startTime,\r\n };\r\n }\r\n }\r\n\r\n // Should not reach here, but safety net\r\n return {\r\n error: new Error('All attempts exhausted'),\r\n attempts: attemptCount,\r\n totalElapsedMs: Date.now() - startTime,\r\n };\r\n}\r\n\r\n// -- Internal helpers --\r\n\r\nfunction getStatusCode(error: unknown): number | undefined {\r\n if (error && typeof error === 'object') {\r\n const e = error as Record<string, unknown>;\r\n if (typeof e.status === 'number') return e.status;\r\n if (typeof e.statusCode === 'number') return e.statusCode;\r\n if (e.response && typeof e.response === 'object') {\r\n const resp = e.response as Record<string, unknown>;\r\n if (typeof resp.status === 'number') return resp.status;\r\n if (typeof resp.statusCode === 'number') return resp.statusCode;\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction getHeaders(error: unknown): Record<string, string> | Headers | undefined {\r\n if (error && typeof error === 'object') {\r\n const e = error as Record<string, unknown>;\r\n if (e.headers && typeof e.headers === 'object') {\r\n return e.headers as Record<string, string> | Headers;\r\n }\r\n if (e.response && typeof e.response === 'object') {\r\n const resp = e.response as Record<string, unknown>;\r\n if (resp.headers && typeof resp.headers === 'object') {\r\n return resp.headers as Record<string, string> | Headers;\r\n }\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\n","// packages/core/src/models/caller.ts — CLI-only model caller\r\n\r\nimport { withCanonicalRetry } from '../security/retry.js';\r\nimport type { CallModelOptions, ChatMessage, ModelCallResult } from '../types/models.js';\r\nimport { sleep } from '../utils/sleep.js';\r\nimport { CliAdapter } from './cli-adapter.js';\r\nimport type { ModelAdapter } from './registry.js';\r\n\r\n/**\r\n * Callback for receiving streaming text deltas.\r\n */\r\nexport type TextDeltaEmitter = (delta: string) => void;\r\n\r\n/**\r\n * Unified model call: routes to CLI adapter.\r\n */\r\nexport async function callModel(\r\n model: ModelAdapter,\r\n messages: ChatMessage[],\r\n options?: CallModelOptions,\r\n): Promise<ModelCallResult> {\r\n return callCliAdapter(model, messages, options);\r\n}\r\n\r\n/**\r\n * Unified streaming model call.\r\n * CLI: chunked pseudo-streaming (paragraph-split after process completes).\r\n */\r\nexport async function streamModel(\r\n model: ModelAdapter,\r\n messages: ChatMessage[],\r\n onDelta: TextDeltaEmitter,\r\n _stepId: string,\r\n _role: string,\r\n options?: CallModelOptions,\r\n): Promise<ModelCallResult> {\r\n return streamCliAdapter(model, messages, onDelta, options);\r\n}\r\n\r\nasync function callCliAdapter(\r\n adapter: CliAdapter,\r\n messages: ChatMessage[],\r\n options?: CallModelOptions,\r\n): Promise<ModelCallResult> {\r\n const prompt = messagesToPrompt(messages, options?.systemPrompt);\r\n const timeoutMs = (options?.timeout ?? 600) * 1000;\r\n\r\n const attempt = await withCanonicalRetry(() => adapter.call(prompt, { timeout: timeoutMs }), {\r\n maxRetries: 2,\r\n totalAttempts: 3,\r\n toolTimeoutMs: timeoutMs,\r\n });\r\n\r\n if (attempt.error || !attempt.result) {\r\n throw attempt.error ?? new Error('CLI adapter call failed after retries');\r\n }\r\n return { ...attempt.result, meteringSource: 'estimated' };\r\n}\r\n\r\nasync function streamCliAdapter(\r\n adapter: CliAdapter,\r\n messages: ChatMessage[],\r\n onDelta: TextDeltaEmitter,\r\n options?: CallModelOptions,\r\n): Promise<ModelCallResult> {\r\n const result = await callCliAdapter(adapter, messages, options);\r\n\r\n const chunks = result.text.split(/\\n\\n+/).filter(Boolean);\r\n for (const chunk of chunks) {\r\n onDelta(`${chunk}\\n\\n`);\r\n await sleep(50);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction messagesToPrompt(messages: ChatMessage[], systemPrompt?: string): string {\r\n const parts: string[] = [];\r\n if (systemPrompt) parts.push(systemPrompt);\r\n for (const msg of messages) {\r\n if (msg.role === 'system') {\r\n parts.push(msg.content);\r\n } else {\r\n parts.push(`${msg.role.toUpperCase()}: ${msg.content}`);\r\n }\r\n }\r\n return parts.join('\\n\\n');\r\n}\r\n\r\n","// packages/core/src/models/fallback.ts\r\n\r\nimport type { FallbackConfig, ModelCallResult } from '../types/models.js';\r\nimport { ModelError } from '../utils/errors.js';\r\nimport { sleep } from '../utils/sleep.js';\r\n\r\n/**\r\n * Execute a model call with fallback support.\r\n *\r\n * Tries the primary call first. On retryable errors, tries each fallback in order.\r\n * The `callFn` receives the model alias and must perform the actual model call.\r\n */\r\nexport async function withFallback(\r\n callFn: (modelAlias: string) => Promise<ModelCallResult>,\r\n config: FallbackConfig,\r\n): Promise<ModelCallResult> {\r\n const maxRetries = Math.max(1, config.maxRetries);\r\n const allModels = [config.primary, ...config.fallbacks];\r\n let lastError: unknown;\r\n\r\n for (const alias of allModels) {\r\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\r\n try {\r\n return await callFn(alias);\r\n } catch (error) {\r\n lastError = error;\r\n\r\n if (!isRetryable(error, config)) {\r\n throw error;\r\n }\r\n\r\n // If this was the last retry for this model, move to next fallback\r\n if (attempt === maxRetries) break;\r\n\r\n // Exponential backoff between retries\r\n await sleep(1000 * 2 ** (attempt - 1));\r\n }\r\n }\r\n }\r\n\r\n throw new ModelError(\r\n `All models failed. Tried: ${allModels.join(', ')}. Last error: ${lastError instanceof Error ? lastError.message : String(lastError)}`,\r\n );\r\n}\r\n\r\nfunction isRetryable(error: unknown, config: FallbackConfig): boolean {\r\n if (!(error instanceof ModelError)) return false;\r\n\r\n if (config.retryOn.rateLimit && error.isRateLimit) return true;\r\n if (config.retryOn.timeout && error.isTimeout) return true;\r\n if (config.retryOn.serverError && error.isServerError) return true;\r\n\r\n return false;\r\n}\r\n\r\n","// packages/core/src/models/cost-tracker.ts\n\nimport type { CostStore } from '../memory/cost-store.js';\nimport type { ModelCallResult } from '../types/models.js';\n\n/**\n * Wraps model calls and records cost/usage to the CostStore.\n * Created per-session by the Orchestrator.\n */\nexport class CostTracker {\n constructor(\n private costStore: CostStore,\n private sessionId: string,\n ) {}\n\n /**\n * Execute a model call and record its cost.\n * Usage: `costTracker.tracked(() => callModel(model, msgs, opts), 'plan')`\n */\n async tracked(fn: () => Promise<ModelCallResult>, stepId?: string): Promise<ModelCallResult> {\n const result = await fn();\n this.record(result, stepId);\n return result;\n }\n\n /** Record usage from an already-completed model call. */\n record(result: ModelCallResult, stepId?: string): void {\n this.costStore.log({\n sessionId: this.sessionId,\n stepId: stepId ?? null,\n modelId: result.model,\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n costUsd: result.usage.costUsd,\n latencyMs: result.durationMs,\n });\n }\n}\n","// packages/core/src/models/pricing.ts\n\nexport interface ModelPricing {\n inputPer1M: number;\n outputPer1M: number;\n}\n\n/**\n * Static pricing table for known models (USD per 1M tokens).\n * Updated: 2026-02.\n */\nconst PRICING: Record<string, ModelPricing> = {\n // OpenAI\n 'gpt-5': { inputPer1M: 5, outputPer1M: 15 },\n 'gpt-5-mini': { inputPer1M: 0.3, outputPer1M: 1.2 },\n o3: { inputPer1M: 10, outputPer1M: 40 },\n 'o4-mini': { inputPer1M: 1.1, outputPer1M: 4.4 },\n 'gpt-4o': { inputPer1M: 2.5, outputPer1M: 10 },\n 'gpt-4o-mini': { inputPer1M: 0.15, outputPer1M: 0.6 },\n};\n\nexport function getModelPricing(modelId: string): ModelPricing | null {\n return PRICING[modelId] ?? null;\n}\n\n/**\n * Calculate cost in USD for a model call.\n * Returns 0 if the model is not in the pricing table.\n */\nexport function calculateCost(modelId: string, inputTokens: number, outputTokens: number): number {\n const pricing = getModelPricing(modelId);\n if (!pricing) return 0;\n return (inputTokens * pricing.inputPer1M + outputTokens * pricing.outputPer1M) / 1_000_000;\n}\n","// packages/core/src/roles/prompts.ts\n\nimport type { ChatMessage } from '../types/models.js';\n\n/**\n * The 5 prompt types supported in Sprint 1.\n */\nexport type PromptType = 'plan' | 'plan-review' | 'plan-revision' | 'code' | 'code-review';\n\n/**\n * Variables passed into prompt templates.\n */\nexport interface PromptVariables {\n task: string;\n projectName?: string;\n projectDescription?: string;\n plan?: string;\n previousPlan?: string;\n feedback?: string;\n code?: string;\n}\n\n/**\n * Render a prompt template into ChatMessage[] (system + user messages).\n */\nexport function renderPrompt(type: PromptType, vars: PromptVariables): ChatMessage[] {\n const template = TEMPLATES[type];\n const projectCtx = formatProjectContext(vars.projectName, vars.projectDescription);\n\n return [\n { role: 'system', content: template.system(projectCtx) },\n { role: 'user', content: template.user(vars) },\n ];\n}\n\n// -- Template definitions --\n\ninterface PromptTemplate {\n system: (projectCtx: string) => string;\n user: (vars: PromptVariables) => string;\n}\n\nfunction formatProjectContext(name?: string, description?: string): string {\n if (name && description) return `working on \"${name}\": ${description}`;\n if (name) return `working on \"${name}\"`;\n return '';\n}\n\nconst TEMPLATES: Record<PromptType, PromptTemplate> = {\n /**\n * Architect -- Plan Generation\n */\n plan: {\n system: (ctx) =>\n [\n `You are a senior software architect ${ctx}.`.trim(),\n '',\n 'Given the following task, create a detailed implementation plan.',\n '',\n '## Your plan MUST include these sections:',\n '',\n '### 1. Overview',\n 'What this task accomplishes and why.',\n '',\n '### 2. Technical Approach',\n 'High-level strategy, key design decisions, and tradeoffs.',\n '',\n '### 3. File Changes',\n 'For each file to create or modify:',\n '- **File path**',\n '- **Action**: create | modify',\n '- **Description of changes**',\n '',\n '### 4. Implementation Details',\n 'Step-by-step implementation instructions. Include pseudocode for complex logic.',\n '',\n '### 5. Testing Strategy',\n 'How to verify the implementation works. Specific test cases.',\n '',\n '### 6. Edge Cases & Risks',\n 'Potential issues and how to handle them.',\n ].join('\\n'),\n user: (vars) => `## Task:\\n${vars.task}`,\n },\n\n /**\n * Reviewer -- Plan Review\n */\n 'plan-review': {\n system: (ctx) =>\n [\n `You are a senior technical reviewer ${ctx}.`.trim(),\n '',\n 'Review the following plan for:',\n '- **Correctness**: Is the approach technically sound?',\n '- **Completeness**: Does it address all aspects of the task?',\n '- **Quality**: Is the plan well-structured and actionable?',\n '- **Risks**: Are there overlooked edge cases or potential issues?',\n '',\n 'Provide specific, actionable feedback. Reference plan sections by name.',\n '',\n 'At the END of your review, you MUST include exactly one of these lines:',\n 'VERDICT: APPROVED',\n 'VERDICT: NEEDS_REVISION',\n ].join('\\n'),\n user: (vars) => `## Task:\\n${vars.task}\\n\\n## Plan to Review:\\n${vars.plan ?? ''}`,\n },\n\n /**\n * Architect -- Plan Revision\n */\n 'plan-revision': {\n system: (ctx) =>\n [\n `You are a senior software architect ${ctx}.`.trim(),\n '',\n \"Your previous plan was reviewed and needs revision. Address the reviewer's feedback while keeping the strengths of your original plan.\",\n '',\n 'Produce a revised plan with the same section structure (Overview, Technical Approach, File Changes, Implementation Details, Testing Strategy, Edge Cases & Risks).',\n ].join('\\n'),\n user: (vars) =>\n [\n `## Original Task:\\n${vars.task}`,\n `## Your Previous Plan:\\n${vars.previousPlan ?? ''}`,\n `## Reviewer Feedback:\\n${vars.feedback ?? ''}`,\n ].join('\\n\\n'),\n },\n\n /**\n * Implementer -- Code Generation\n */\n code: {\n system: (ctx) =>\n [\n `You are a senior software developer ${ctx}.`.trim(),\n '',\n 'Based on the following approved plan, write the complete implementation.',\n '',\n '## Rules:',\n '- Write complete file contents, not snippets',\n '- Include all imports and type definitions',\n \"- Follow the project's existing patterns\",\n '- Add comments only where logic is non-obvious',\n '- For each file, use this format:',\n '',\n '### File: path/to/file.ts',\n '```ts',\n '// complete file contents here',\n '```',\n ].join('\\n'),\n user: (vars) => `## Approved Plan:\\n${vars.plan ?? ''}`,\n },\n\n /**\n * Reviewer -- Code Review\n */\n 'code-review': {\n system: (ctx) =>\n [\n `You are a senior code reviewer ${ctx}.`.trim(),\n '',\n 'Review the following implementation for:',\n '- **Correctness**: Does it implement the plan correctly?',\n '- **Bugs**: Logic errors, off-by-one, race conditions?',\n '- **Security**: OWASP Top 10 issues?',\n '- **Performance**: Obvious performance problems?',\n '- **Quality**: Clean code, error handling, naming?',\n '',\n 'Provide specific feedback with file names and references.',\n '',\n 'At the END of your review, you MUST include exactly one of:',\n 'VERDICT: APPROVED',\n 'VERDICT: NEEDS_REVISION',\n ].join('\\n'),\n user: (vars) =>\n [\n `## Task:\\n${vars.task}`,\n `## Approved Plan:\\n${vars.plan ?? ''}`,\n `## Implementation to Review:\\n${vars.code ?? ''}`,\n ].join('\\n\\n'),\n },\n};\n","// packages/core/src/roles/role-manager.ts\n\nimport type { ProjectConfig, RoleConfig } from '../types/config.js';\nimport type { ChatMessage } from '../types/models.js';\nimport type { BuiltInRole, Role } from '../types/roles.js';\nimport { DEFAULT_MAX_TOKENS } from '../utils/constants.js';\nimport { ModelError } from '../utils/errors.js';\nimport type { PromptType, PromptVariables } from './prompts.js';\nimport { renderPrompt } from './prompts.js';\n\n/**\n * Built-in role definitions with default descriptions.\n */\nconst BUILT_IN_ROLES: Record<BuiltInRole, { description: string }> = {\n architect: { description: 'Plans implementation strategy and technical approach' },\n reviewer: { description: 'Reviews plans and code for correctness, quality, and risks' },\n implementer: { description: 'Writes production code based on approved plans' },\n};\n\n/**\n * Resolves roles from config, provides prompt rendering and message assembly.\n */\nexport class RoleManager {\n constructor(private config: ProjectConfig) {}\n\n /**\n * Resolve a role name to a fully hydrated Role object.\n * Merges built-in defaults with config overrides.\n */\n getRole(roleName: string): Role {\n const roleConfig = this.config.roles[roleName];\n if (!roleConfig) {\n throw new ModelError(\n `Unknown role: \"${roleName}\". Available: ${Object.keys(this.config.roles).join(', ')}`,\n );\n }\n\n const builtIn = BUILT_IN_ROLES[roleName as BuiltInRole];\n const modelConfig = this.config.models[roleConfig.model];\n\n return {\n id: roleName,\n description: builtIn?.description ?? `Custom role: ${roleName}`,\n modelAlias: roleConfig.model,\n systemPrompt: buildRoleIdentity(roleName, builtIn?.description),\n temperature: roleConfig.temperature ?? modelConfig?.temperature ?? 0.7,\n maxTokens: roleConfig.maxTokens ?? modelConfig?.maxTokens ?? DEFAULT_MAX_TOKENS,\n };\n }\n\n /**\n * Build a ChatMessage[] for a model call.\n * Renders the appropriate prompt template with project context and variables.\n */\n buildMessages(promptType: PromptType, vars: PromptVariables): ChatMessage[] {\n return renderPrompt(promptType, {\n ...vars,\n projectName: vars.projectName ?? this.config.project.name,\n projectDescription: vars.projectDescription ?? this.config.project.description,\n });\n }\n\n /** List all configured role names. */\n listRoles(): string[] {\n return Object.keys(this.config.roles);\n }\n\n /** Get the RoleConfig for a role name. */\n getRoleConfig(roleName: string): RoleConfig {\n const roleConfig = this.config.roles[roleName];\n if (!roleConfig) {\n throw new ModelError(`Unknown role: \"${roleName}\"`);\n }\n return roleConfig;\n }\n}\n\nfunction buildRoleIdentity(roleName: string, description?: string): string {\n if (description) {\n return `You are a ${roleName}. ${description}.`;\n }\n return `You are a ${roleName}.`;\n}\n","// packages/core/src/engine/event-bus.ts\n\nimport { EventEmitter } from 'eventemitter3';\nimport type { EngineEvent } from '../types/events.js';\n\ninterface EventBusEvents {\n event: (event: EngineEvent) => void;\n}\n\n/**\n * Typed event bus for AG-UI compatible engine events.\n * Wraps eventemitter3 with typed EngineEvent emission.\n */\nexport class EventBus extends EventEmitter<EventBusEvents> {\n /** Emit a typed AG-UI event, auto-injecting timestamp if missing. */\n emitEvent(event: EngineEvent): void {\n const timestamped =\n 'timestamp' in event && !event.timestamp\n ? { ...event, timestamp: new Date().toISOString() }\n : event;\n this.emit('event', timestamped);\n }\n}\n","// packages/core/src/engine/loop-controller.ts\n\nimport type { ResolvedStep } from '../types/workflow.js';\nimport type { EventBus } from './event-bus.js';\nimport type { StepResult, StepRunner } from './step-runner.js';\n\nexport interface LoopResult {\n finalOutput: string;\n iterations: number;\n approved: boolean;\n history: StepResult[];\n}\n\nexport class LoopController {\n async executeLoop(\n generateStep: ResolvedStep,\n reviewStep: ResolvedStep,\n inputs: Map<string, string>,\n task: string,\n maxIterations: number,\n runner: StepRunner,\n eventBus: EventBus,\n ): Promise<LoopResult> {\n const history: StepResult[] = [];\n let currentInputs = new Map(inputs);\n let approved = false;\n\n for (let iteration = 1; iteration <= maxIterations; iteration++) {\n // Run generate step\n const generateResult = await runner.execute(generateStep, currentInputs, task, iteration);\n history.push(generateResult);\n\n // Build review inputs with the generated output\n const reviewInputs = new Map<string, string>();\n reviewInputs.set(generateStep.definition.id, generateResult.output);\n\n // Run review step\n const reviewResult = await runner.execute(reviewStep, reviewInputs, task, iteration);\n history.push(reviewResult);\n\n const verdict = reviewResult.verdict ?? 'needs_revision';\n\n // Emit loop.iteration event\n eventBus.emitEvent({\n type: 'loop.iteration',\n stepId: reviewStep.definition.id,\n iteration,\n maxIterations,\n verdict,\n feedback: reviewResult.feedback,\n timestamp: '',\n });\n\n if (verdict === 'approved') {\n approved = true;\n return {\n finalOutput: generateResult.output,\n iterations: iteration,\n approved,\n history,\n };\n }\n\n // If not approved and not at max, prepare inputs for next iteration\n if (iteration < maxIterations) {\n currentInputs = new Map<string, string>();\n currentInputs.set(generateStep.definition.id, generateResult.output);\n currentInputs.set('feedback', reviewResult.feedback ?? reviewResult.output);\n }\n }\n\n // Max iterations reached without approval\n const lastGenerateResult = history[history.length - 2];\n return {\n finalOutput: lastGenerateResult.output,\n iterations: maxIterations,\n approved: false,\n history,\n };\n }\n}\n","// packages/core/src/engine/orchestrator.ts\n\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type Database from 'better-sqlite3';\nimport { EventEmitter } from 'eventemitter3';\nimport { ContextBuilder } from '../context/context-builder.js';\nimport { ArtifactStore } from '../memory/artifact-store.js';\nimport { CostStore } from '../memory/cost-store.js';\nimport { MemoryStore } from '../memory/memory-store.js';\nimport { SessionStore } from '../memory/session-store.js';\nimport { callModel } from '../models/caller.js';\nimport { CliAdapter } from '../models/cli-adapter.js';\nimport { CostTracker } from '../models/cost-tracker.js';\nimport type { ModelRegistry } from '../models/registry.js';\nimport { RoleManager } from '../roles/role-manager.js';\nimport { sanitize } from '../security/dlp.js';\nimport type { ExecutionMode, ProjectConfig } from '../types/config.js';\nimport type { DebateEngineInput, DebateEngineResult, DebateIO } from '../types/debate.js';\nimport type { EngineEvent } from '../types/events.js';\nimport type { DebateResponse, DebateResult, MeteringSource, ReviewResult } from '../types/mcp.js';\nimport { parseVerdict } from '../utils/verdict.js';\nimport type { CancellationToken } from './cancellation.js';\nimport { ProposalCritiqueEngine } from './debate-engine.js';\nimport { EventBus } from './event-bus.js';\nimport { LoopController } from './loop-controller.js';\nimport { StepRunner } from './step-runner.js';\nimport { WorkflowEngine } from './workflow-engine.js';\n\nconst currentDir = dirname(fileURLToPath(import.meta.url));\n\ninterface OrchestratorEvents {\n event: (event: EngineEvent) => void;\n}\n\nexport interface OrchestratorOptions {\n registry: ModelRegistry;\n db: Database.Database;\n config: ProjectConfig;\n workflowDir?: string;\n projectDir?: string;\n}\n\nexport interface RunOptions {\n mode?: ExecutionMode;\n maxIterations?: number;\n stream?: boolean;\n workflowDir?: string;\n}\n\nexport interface PlanOptions {\n maxRounds?: number;\n stream?: boolean;\n workflowDir?: string;\n}\n\nexport interface SessionResult {\n sessionId: string;\n status: 'completed' | 'failed';\n finalOutput: string;\n totalCost: number;\n totalTokens: number;\n durationMs: number;\n iterations: number;\n error?: string;\n lastStep?: string;\n}\n\nexport interface ReviewOptions {\n criteria?: string[];\n model?: string;\n strict?: boolean;\n timeout?: number;\n}\n\nexport interface DebateOptions {\n modelAliases?: string[];\n synthesize?: boolean;\n timeout?: number;\n maxConcurrency?: number;\n}\n\ntype SessionPhase = 'plan-review' | 'implement' | 'code-review';\n\nconst DEFAULT_MAX_CLI_CONCURRENCY = 3;\nconst DEFAULT_MAX_API_CONCURRENCY = 5;\n\n/** Promise-based semaphore — replaces busy-wait polling. */\nclass AsyncSemaphore {\n private queue: Array<() => void> = [];\n private running = 0;\n\n constructor(private max: number) {}\n\n async acquire(): Promise<void> {\n if (this.running < this.max) {\n this.running++;\n return;\n }\n return new Promise<void>((resolve) => {\n this.queue.push(() => {\n this.running++;\n resolve();\n });\n });\n }\n\n release(): void {\n this.running--;\n const next = this.queue.shift();\n if (next) next();\n }\n}\n\nexport class Orchestrator extends EventEmitter<OrchestratorEvents> {\n private registry: ModelRegistry;\n private config: ProjectConfig;\n private sessionStore: SessionStore;\n private artifactStore: ArtifactStore;\n private costStore: CostStore;\n private memoryStore: MemoryStore;\n private roleManager: RoleManager;\n private workflowEngine: WorkflowEngine;\n private eventBus: EventBus;\n private contextBuilder: ContextBuilder;\n\n constructor(options: OrchestratorOptions) {\n super();\n this.registry = options.registry;\n this.config = options.config;\n this.sessionStore = new SessionStore(options.db);\n this.artifactStore = new ArtifactStore(options.db);\n this.costStore = new CostStore(options.db);\n this.memoryStore = new MemoryStore(options.db);\n this.roleManager = new RoleManager(options.config);\n\n const resolvedDir =\n options.workflowDir ??\n (options.projectDir\n ? resolve(options.projectDir, 'workflows')\n : resolve(currentDir, '../../../workflows'));\n this.workflowEngine = new WorkflowEngine(resolvedDir);\n this.eventBus = new EventBus();\n\n // Context builder for enriching prompts with memories + codebase context\n this.contextBuilder = new ContextBuilder({\n projectDir: options.projectDir,\n projectId: options.config.project.name || 'default',\n memoryStore: this.memoryStore,\n });\n\n // Forward all events from eventBus to this orchestrator\n this.eventBus.on('event', (event) => this.emit('event', event));\n }\n\n async run(task: string, options?: RunOptions): Promise<SessionResult> {\n return this.executeSession(task, ['plan-review', 'implement', 'code-review'], {\n maxIterations: options?.maxIterations,\n stream: options?.stream,\n mode: options?.mode,\n });\n }\n\n async plan(task: string, options?: PlanOptions): Promise<SessionResult> {\n return this.executeSession(task, ['plan-review'], {\n maxIterations: options?.maxRounds,\n stream: options?.stream,\n });\n }\n\n /**\n * Review content with a single model.\n * DLP-sanitizes content first (strict mode by default).\n */\n async review(\n content: string,\n options?: ReviewOptions,\n cancellationToken?: CancellationToken,\n ): Promise<ReviewResult> {\n const start = Date.now();\n\n // DLP sanitize\n const dlpMode = options?.strict !== false ? 'strict' : 'open';\n const dlpResult = sanitize(content, { mode: dlpMode });\n const sanitizedContent = dlpResult.sanitized;\n\n // Check cancellation\n if (cancellationToken?.isCancelled) {\n throw new Error('Review cancelled');\n }\n\n // Resolve model\n const alias = options?.model ?? this.resolveReviewerAlias();\n const adapter = this.registry.getAdapter(alias);\n const isCli = adapter instanceof CliAdapter;\n const meteringSource: MeteringSource = isCli ? 'estimated' : 'billed';\n\n // Build review prompt\n const criteriaText = options?.criteria?.length\n ? `Review criteria:\\n${options.criteria.map((c) => `- ${c}`).join('\\n')}`\n : '';\n const basePrompt = [\n 'Review the following content carefully.',\n criteriaText,\n 'Provide a score from 1-10, specific feedback points, and a final VERDICT.',\n 'Format your verdict as either \"VERDICT: APPROVED\" or \"VERDICT: NEEDS_REVISION\".',\n '',\n 'Content to review:',\n sanitizedContent,\n ]\n .filter(Boolean)\n .join('\\n');\n\n // Enrich with project context and memories\n const assembled = this.contextBuilder.assemble(basePrompt, 'review');\n const messages = [{ role: 'user' as const, content: assembled.prompt }];\n\n // Call model\n const result = await callModel(adapter, messages);\n\n // Parse verdict — wrap in try/catch so LLM output variance doesn't crash\n let verdict: { verdict: 'approved' | 'needs_revision'; feedback: string };\n try {\n verdict = parseVerdict(result.text);\n } catch {\n verdict = { verdict: 'needs_revision', feedback: result.text.slice(0, 500) };\n }\n\n // Score extraction: try multiple patterns (X/10, X out of 10, score: X, Score: X.X)\n const scorePatterns = [\n /\\b(\\d+)\\s*\\/\\s*10\\b/,\n /\\b(\\d+)\\s+out\\s+of\\s+10\\b/i,\n /score[:\\s]+(\\d+(?:\\.\\d+)?)/i,\n ];\n let score: number | undefined;\n for (const pattern of scorePatterns) {\n const match = pattern.exec(result.text);\n if (match) {\n score = Math.round(Number.parseFloat(match[1]));\n break;\n }\n }\n if (score === undefined) {\n score = verdict.verdict === 'approved' ? 8 : 5;\n }\n\n const feedback = result.text\n .split('\\n')\n .filter((line) => line.trim().startsWith('-') || line.trim().startsWith('*'))\n .map((line) => line.trim().replace(/^[-*]\\s*/, ''));\n\n // Auto-save review findings as memory (with dedup)\n if (feedback.length > 0 && score <= 7) {\n const projectId = this.config.project.name || 'default';\n const memorySummary = `Review (${score}/10, ${verdict.verdict}): ${feedback.slice(0, 3).join('; ')}`;\n this.saveMemoryIfNew(projectId, 'issue', memorySummary, score <= 5 ? 0.8 : 0.5);\n }\n\n return {\n status: 'success',\n score,\n verdict: verdict.verdict,\n feedback: feedback.length > 0 ? feedback : [verdict.feedback || result.text.slice(0, 200)],\n tokenUsage: result.usage,\n latencyMs: Date.now() - start,\n meteringSource,\n model: result.model,\n egressControl: isCli ? 'cli-managed' : 'codemoot-enforced',\n };\n }\n\n /**\n * Debate a question across multiple models.\n * DLP-sanitizes question first. Runs models concurrently with async semaphore.\n */\n async debate(\n question: string,\n options?: DebateOptions,\n cancellationToken?: CancellationToken,\n ): Promise<DebateResult> {\n // DLP sanitize\n const dlpResult = sanitize(question, { mode: 'strict' });\n const sanitizedQuestion = dlpResult.sanitized;\n\n // Check cancellation\n if (cancellationToken?.isCancelled) {\n throw new Error('Debate cancelled');\n }\n\n // Resolve model aliases\n const aliases = options?.modelAliases ?? this.resolveDebateAliases();\n if (aliases.length < 1) {\n throw new Error(\n `Debate requires at least 1 model. Available: ${this.registry.listAliases().join(', ')}`,\n );\n }\n\n // Enrich question with project context and memories\n const assembled = this.contextBuilder.assemble(sanitizedQuestion, 'debate');\n const enrichedQuestion = assembled.prompt;\n\n const maxCliConcurrency =\n options?.maxConcurrency ??\n Number(process.env.CODEMOOT_MAX_CLI_CONCURRENCY ?? DEFAULT_MAX_CLI_CONCURRENCY);\n const maxApiConcurrency = DEFAULT_MAX_API_CONCURRENCY;\n\n // Async semaphores for concurrency control\n const cliSemaphore = new AsyncSemaphore(maxCliConcurrency);\n const apiSemaphore = new AsyncSemaphore(maxApiConcurrency);\n\n const callWithSemaphore = async (alias: string): Promise<DebateResponse> => {\n const adapter = this.registry.getAdapter(alias);\n const isCli = adapter instanceof CliAdapter;\n const meteringSource: MeteringSource = isCli ? 'estimated' : 'billed';\n const config = this.registry.getModelConfig(alias);\n const semaphore = isCli ? cliSemaphore : apiSemaphore;\n\n await semaphore.acquire();\n const callStart = Date.now();\n try {\n if (cancellationToken?.isCancelled) {\n throw new Error('Debate cancelled');\n }\n\n const messages = [{ role: 'user' as const, content: enrichedQuestion }];\n const result = await callModel(adapter, messages);\n\n return {\n model: config.model,\n role: alias,\n text: result.text,\n tokenUsage: result.usage,\n latencyMs: Date.now() - callStart,\n meteringSource,\n };\n } catch (err) {\n return {\n model: config.model,\n role: alias,\n text: '',\n tokenUsage: { inputTokens: 0, outputTokens: 0, totalTokens: 0, costUsd: 0 },\n latencyMs: Date.now() - callStart,\n meteringSource,\n error: err instanceof Error ? err.message : String(err),\n };\n } finally {\n semaphore.release();\n }\n };\n\n // Run all models concurrently\n const results = await Promise.allSettled(aliases.map(callWithSemaphore));\n const responses: DebateResponse[] = results.map((r) =>\n r.status === 'fulfilled'\n ? r.value\n : {\n model: 'unknown',\n role: 'unknown',\n text: '',\n tokenUsage: { inputTokens: 0, outputTokens: 0, totalTokens: 0, costUsd: 0 },\n latencyMs: 0,\n meteringSource: 'estimated' as MeteringSource,\n error: r.reason instanceof Error ? r.reason.message : String(r.reason),\n },\n );\n\n const successfulResponses = responses.filter((r) => !r.error);\n const partialFailure = successfulResponses.length < responses.length;\n\n if (successfulResponses.length === 0) {\n const errors = responses.map((r) => `${r.role}: ${r.error}`).join('; ');\n throw new Error(`All models failed in debate: ${errors}`);\n }\n\n // Aggregate token usage\n const totalTokenUsage = {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n costUsd: 0,\n };\n for (const r of responses) {\n totalTokenUsage.inputTokens += r.tokenUsage.inputTokens;\n totalTokenUsage.outputTokens += r.tokenUsage.outputTokens;\n totalTokenUsage.totalTokens += r.tokenUsage.totalTokens;\n totalTokenUsage.costUsd += r.tokenUsage.costUsd;\n }\n\n // Optional synthesis\n let synthesis: string | undefined;\n if (options?.synthesize && successfulResponses.length > 1) {\n const synthPrompt = [\n 'Synthesize the following responses into a unified answer:',\n '',\n ...successfulResponses.map((r, i) => `Response ${i + 1} (${r.model}):\\n${r.text}`),\n ].join('\\n\\n');\n\n // Use first available model for synthesis\n const synthAdapter = this.registry.getAdapter(aliases[0]);\n const synthResult = await callModel(synthAdapter, [{ role: 'user', content: synthPrompt }]);\n synthesis = synthResult.text;\n\n totalTokenUsage.inputTokens += synthResult.usage.inputTokens;\n totalTokenUsage.outputTokens += synthResult.usage.outputTokens;\n totalTokenUsage.totalTokens += synthResult.usage.totalTokens;\n totalTokenUsage.costUsd += synthResult.usage.costUsd;\n }\n\n // Determine egress control — if any model uses CLI, report mixed\n const hasCliModel = aliases.some((a) => this.registry.isCliMode(a));\n const egressControl = hasCliModel ? 'cli-managed' : 'codemoot-enforced';\n\n return {\n status: partialFailure ? 'partial' : 'success',\n responses,\n synthesis,\n totalTokenUsage,\n partialFailure,\n egressControl,\n };\n }\n\n /**\n * Multi-round debate: models see and respond to each other's arguments.\n * Uses proposal-critique pattern: proposer → critic → revise → critique → ...\n * Models iterate until convergence (critic approves) or max rounds.\n */\n async debateMultiRound(\n question: string,\n options?: {\n modelAliases?: string[];\n maxRounds?: number;\n timeout?: number;\n },\n ): Promise<DebateEngineResult> {\n // DLP sanitize\n const dlpResult = sanitize(question, { mode: 'strict' });\n const sanitizedQuestion = dlpResult.sanitized;\n\n // Enrich with project context\n const assembled = this.contextBuilder.assemble(sanitizedQuestion, 'debate');\n const enrichedQuestion = assembled.prompt;\n\n // Resolve aliases: need at least 2 for proposal-critique\n const aliases = options?.modelAliases ?? this.resolveDebateAliases();\n if (aliases.length < 2) {\n throw new Error(\n `Multi-round debate requires at least 2 models. Available: ${this.registry.listAliases().join(', ')}`,\n );\n }\n\n // Build DebateIO adapter that wraps our callModel + registry\n const io: DebateIO = {\n generate: async (modelAlias, messages, timeoutMs) => {\n const adapter = this.registry.getAdapter(modelAlias);\n const chatMessages = messages.map((m) => ({\n role: m.role as 'system' | 'user',\n content: m.content,\n }));\n const result = await callModel(adapter, chatMessages, {\n timeout: Math.ceil(timeoutMs / 1000),\n });\n return {\n text: result.text,\n promptTokens: result.usage.inputTokens,\n completionTokens: result.usage.outputTokens,\n };\n },\n };\n\n // Create and run the debate engine\n const engine = new ProposalCritiqueEngine({\n maxRounds: options?.maxRounds ?? this.config.debate.maxRounds,\n maxWallClockMs: (options?.timeout ?? 600) * 1000,\n });\n\n const input: DebateEngineInput = {\n debateId: `debate_${Date.now()}`,\n question: enrichedQuestion,\n models: aliases.slice(0, 2), // proposal-critique uses exactly 2\n };\n\n return engine.run(input, io);\n }\n\n /** Resolve the default reviewer model alias from roles config. */\n private resolveReviewerAlias(): string {\n const reviewerRole = this.config.roles.reviewer;\n if (reviewerRole) return reviewerRole.model;\n // Fallback to first available alias\n const aliases = this.registry.listAliases();\n if (aliases.length === 0) {\n throw new Error('No models configured for review');\n }\n return aliases[0];\n }\n\n /** Resolve debate aliases — all configured model aliases. */\n private resolveDebateAliases(): string[] {\n return this.registry.listAliases();\n }\n\n /**\n * Save a memory only if no similar entry already exists (content-prefix dedup).\n * Uses SQL LIKE prefix match instead of FTS5 for reliable exact matching.\n */\n private saveMemoryIfNew(\n projectId: string,\n category: 'issue' | 'convention' | 'decision' | 'pattern' | 'preference',\n content: string,\n importance: number,\n ): void {\n const prefix = content.slice(0, 80);\n const existing = this.memoryStore.findByPrefix(projectId, category, prefix);\n if (!existing) {\n this.memoryStore.save({\n projectId,\n category,\n content,\n sourceSessionId: null,\n importance,\n });\n }\n }\n\n /**\n * Shared session lifecycle for run() and plan().\n * Extracts common session creation, workflow loading, cost tracking, and completion.\n */\n private async executeSession(\n task: string,\n phases: SessionPhase[],\n options: { maxIterations?: number; stream?: boolean; mode?: ExecutionMode },\n ): Promise<SessionResult> {\n const startTime = Date.now();\n const maxIterations = options.maxIterations ?? this.config.debate.maxRounds ?? 3;\n const stream = options.stream ?? this.config.advanced.stream;\n\n // 1. Create session\n const session = this.sessionStore.create({\n projectId: this.config.project.name || 'default',\n workflowId: 'plan-review-implement',\n task,\n mode: options.mode ?? this.config.mode,\n config: this.config,\n });\n\n // 2. Emit session.started\n this.eventBus.emitEvent({\n type: 'session.started',\n sessionId: session.id,\n workflow: 'plan-review-implement',\n task,\n timestamp: new Date().toISOString(),\n });\n\n let currentStep = 'init';\n\n try {\n // 3. Load workflow\n const workflow = this.workflowEngine.load('plan-review-implement');\n const steps = this.workflowEngine.getExecutionOrder(workflow);\n\n // 4. Create step runner and cost tracker\n const costTracker = new CostTracker(this.costStore, session.id);\n const stepRunner = new StepRunner(\n this.registry,\n this.roleManager,\n costTracker,\n this.eventBus,\n this.sessionStore,\n this.config,\n session.id,\n );\n const loopController = new LoopController();\n\n // 5. Execute requested phases\n let totalIterations = 0;\n let finalOutput = '';\n const inputs = new Map<string, string>();\n\n const planStep = steps.find((s) => s.definition.id === 'plan');\n const reviewPlanStep = steps.find((s) => s.definition.id === 'review-plan');\n const implementStep = steps.find((s) => s.definition.id === 'implement');\n const codeReviewStep = steps.find((s) => s.definition.id === 'code-review');\n\n // Phase: Plan + Review Loop\n if (phases.includes('plan-review') && planStep && reviewPlanStep) {\n currentStep = 'plan';\n this.sessionStore.updateCurrentStep(session.id, 'plan');\n const planLoop = await loopController.executeLoop(\n planStep,\n reviewPlanStep,\n inputs,\n task,\n maxIterations,\n stepRunner,\n this.eventBus,\n );\n inputs.set('plan.output', planLoop.finalOutput);\n totalIterations += planLoop.iterations;\n finalOutput = planLoop.finalOutput;\n\n this.artifactStore.save({\n sessionId: session.id,\n stepId: 'plan',\n iteration: planLoop.iterations,\n type: 'plan',\n filePath: null,\n content: planLoop.finalOutput,\n version: 1,\n metadata: null,\n });\n }\n\n // Phase: Implement\n if (phases.includes('implement') && implementStep) {\n currentStep = 'implement';\n this.sessionStore.updateCurrentStep(session.id, 'implement');\n const implResult = await stepRunner.execute(implementStep, inputs, task, 1, { stream });\n inputs.set('implement.output', implResult.output);\n finalOutput = implResult.output;\n\n this.artifactStore.save({\n sessionId: session.id,\n stepId: 'implement',\n iteration: 1,\n type: 'code',\n filePath: null,\n content: implResult.output,\n version: 1,\n metadata: null,\n });\n }\n\n // Phase: Code Review Loop\n if (phases.includes('code-review') && implementStep && codeReviewStep) {\n currentStep = 'code-review';\n this.sessionStore.updateCurrentStep(session.id, 'code-review');\n const codeLoop = await loopController.executeLoop(\n implementStep,\n codeReviewStep,\n inputs,\n task,\n maxIterations,\n stepRunner,\n this.eventBus,\n );\n totalIterations += codeLoop.iterations;\n finalOutput = codeLoop.finalOutput;\n\n this.artifactStore.save({\n sessionId: session.id,\n stepId: 'code-review',\n iteration: codeLoop.iterations,\n type: 'review',\n filePath: null,\n content: codeLoop.finalOutput,\n version: 1,\n metadata: null,\n });\n }\n\n // 6. Complete session\n const costSummary = this.costStore.getSessionSummary(session.id);\n const totalCost = costSummary.reduce((sum, s) => sum + s.totalCost, 0);\n const totalTokens = costSummary.reduce(\n (sum, s) => sum + s.totalInputTokens + s.totalOutputTokens,\n 0,\n );\n\n this.sessionStore.complete(session.id, finalOutput.slice(0, 500));\n this.sessionStore.addUsage(session.id, totalCost, totalTokens);\n\n const durationMs = Date.now() - startTime;\n\n this.eventBus.emitEvent({\n type: 'session.completed',\n sessionId: session.id,\n finalOutput,\n totalCost,\n totalTokens,\n durationMs,\n timestamp: new Date().toISOString(),\n });\n\n return {\n sessionId: session.id,\n status: 'completed',\n finalOutput,\n totalCost,\n totalTokens,\n durationMs,\n iterations: totalIterations,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n this.sessionStore.updateStatus(session.id, 'failed');\n\n this.eventBus.emitEvent({\n type: 'session.failed',\n sessionId: session.id,\n error: errorMessage,\n lastStep: currentStep,\n timestamp: new Date().toISOString(),\n });\n\n return {\n sessionId: session.id,\n status: 'failed',\n finalOutput: '',\n totalCost: 0,\n totalTokens: 0,\n durationMs: Date.now() - startTime,\n iterations: 0,\n error: errorMessage,\n lastStep: currentStep,\n };\n }\n }\n}\n","// packages/core/src/context/context-builder.ts — Assembles enriched prompts with memory + codebase context\n\nimport { readFileSync, readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { MemoryStore } from '../memory/memory-store.js';\nimport type { MemoryRecord } from '../types/memory.js';\nimport { CONTEXT_ACTIVE, CONTEXT_BUFFER, CONTEXT_RETRIEVED } from '../utils/constants.js';\n\n/** Token budget tiers for context assembly. */\nexport interface ContextBudget {\n /** Max tokens for tier 1: task + memories. Default 2000 */\n tier1: number;\n /** Max tokens for tier 2: file tree + snippets. Default 4000 */\n tier2: number;\n /** Max total tokens for assembled context. Default 8000 */\n total: number;\n}\n\nexport interface ContextBuilderOptions {\n projectDir?: string;\n projectId?: string;\n memoryStore?: MemoryStore;\n budget?: Partial<ContextBudget>;\n /** Max depth for file tree traversal. Default 3 */\n maxTreeDepth?: number;\n /** Max number of files to include in tree. Default 200 */\n maxFiles?: number;\n /** File extensions to include in tree. Default: common code extensions */\n includeExtensions?: string[];\n}\n\nexport interface AssembledContext {\n /** The enriched prompt with context prepended */\n prompt: string;\n /** Memories that were injected */\n memories: MemoryRecord[];\n /** File tree summary (if generated) */\n fileTree: string;\n /** Estimated token count of the assembled context */\n estimatedTokens: number;\n}\n\nconst DEFAULT_BUDGET: ContextBudget = {\n tier1: CONTEXT_BUFFER,\n tier2: CONTEXT_RETRIEVED,\n total: CONTEXT_ACTIVE,\n};\n\nconst DEFAULT_EXTENSIONS = new Set([\n '.ts',\n '.tsx',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n '.py',\n '.rs',\n '.go',\n '.java',\n '.kt',\n '.swift',\n '.json',\n '.yaml',\n '.yml',\n '.toml',\n '.md',\n]);\n\nconst IGNORE_DIRS = new Set([\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n 'coverage',\n '.next',\n '.turbo',\n '.cache',\n '__pycache__',\n '.venv',\n 'target',\n 'vendor',\n]);\n\n/**\n * Builds enriched prompts by assembling relevant context from:\n * - Tier 1: Task framing + relevant memories from SQLite FTS\n * - Tier 2: Project file tree + relevant code snippets\n * - Tier 3: (Future) On-demand expansion when model requests more context\n */\nexport class ContextBuilder {\n private projectDir: string | undefined;\n private projectId: string;\n private memoryStore: MemoryStore | undefined;\n private budget: ContextBudget;\n private maxTreeDepth: number;\n private maxFiles: number;\n private includeExtensions: Set<string>;\n\n constructor(options: ContextBuilderOptions) {\n this.projectDir = options.projectDir;\n this.projectId = options.projectId ?? 'default';\n this.memoryStore = options.memoryStore;\n this.budget = { ...DEFAULT_BUDGET, ...options.budget };\n this.maxTreeDepth = options.maxTreeDepth ?? 3;\n this.maxFiles = options.maxFiles ?? 200;\n this.includeExtensions = options.includeExtensions\n ? new Set(options.includeExtensions)\n : DEFAULT_EXTENSIONS;\n }\n\n /**\n * Assemble enriched context for a model call.\n * @param taskPrompt The original prompt/task\n * @param taskType Context about what kind of task (review, debate, plan)\n */\n assemble(taskPrompt: string, taskType?: string): AssembledContext {\n const sections: string[] = [];\n let totalChars = 0;\n const memories: MemoryRecord[] = [];\n\n // -- Tier 1: Memories --\n if (this.memoryStore) {\n const tier1Budget = this.budget.tier1 * 4; // chars (rough token-to-char ratio)\n const relevantMemories = this.queryMemories(taskPrompt, tier1Budget);\n if (relevantMemories.length > 0) {\n const memorySection = this.formatMemories(relevantMemories);\n sections.push(memorySection);\n totalChars += memorySection.length;\n memories.push(...relevantMemories);\n }\n }\n\n // -- Tier 2: File tree + project context --\n let fileTree = '';\n if (this.projectDir && totalChars < this.budget.total * 4) {\n const tier2Budget = Math.min(this.budget.tier2 * 4, this.budget.total * 4 - totalChars);\n\n fileTree = this.buildFileTree();\n if (fileTree && fileTree.length <= tier2Budget) {\n const treeSection = `## Project Structure\\n\\`\\`\\`\\n${fileTree}\\`\\`\\``;\n sections.push(treeSection);\n totalChars += treeSection.length;\n }\n }\n\n // -- Assemble final prompt --\n const contextPrefix = sections.length > 0 ? `${sections.join('\\n\\n')}\\n\\n---\\n\\n` : '';\n\n // Add task type framing if provided\n const taskFrame = taskType ? `[Task type: ${taskType}]\\n\\n` : '';\n\n const prompt = `${contextPrefix}${taskFrame}${taskPrompt}`;\n const estimatedTokens = Math.ceil(prompt.length / 4);\n\n return {\n prompt,\n memories,\n fileTree,\n estimatedTokens,\n };\n }\n\n /** Query relevant memories using FTS5 search. */\n private queryMemories(query: string, charBudget: number): MemoryRecord[] {\n if (!this.memoryStore) return [];\n\n // Extract key terms from the query for FTS search\n const searchTerms = this.extractSearchTerms(query);\n if (!searchTerms) return [];\n\n const results = this.memoryStore.search(searchTerms, this.projectId, 10);\n\n // Select memories within budget, prioritizing by importance\n const sorted = results.sort((a, b) => b.importance - a.importance);\n const selected: MemoryRecord[] = [];\n let usedChars = 0;\n\n for (const memory of sorted) {\n const entryChars = memory.content.length + 30; // overhead for formatting\n if (usedChars + entryChars > charBudget) break;\n selected.push(memory);\n usedChars += entryChars;\n\n // Record access for memory decay tracking\n if (memory.id) {\n this.memoryStore.recordAccess(memory.id);\n }\n }\n\n return selected;\n }\n\n /** Extract meaningful search terms from a prompt. */\n private extractSearchTerms(query: string): string {\n // Remove common stop words and keep meaningful terms\n const stopWords = new Set([\n 'the',\n 'a',\n 'an',\n 'is',\n 'are',\n 'was',\n 'were',\n 'be',\n 'been',\n 'being',\n 'have',\n 'has',\n 'had',\n 'do',\n 'does',\n 'did',\n 'will',\n 'would',\n 'could',\n 'should',\n 'may',\n 'might',\n 'can',\n 'shall',\n 'to',\n 'of',\n 'in',\n 'for',\n 'on',\n 'with',\n 'at',\n 'by',\n 'from',\n 'this',\n 'that',\n 'these',\n 'those',\n 'it',\n 'its',\n 'and',\n 'or',\n 'but',\n 'not',\n 'no',\n 'if',\n 'then',\n 'else',\n 'when',\n 'how',\n 'what',\n 'which',\n 'who',\n 'whom',\n 'where',\n 'why',\n 'review',\n 'following',\n 'content',\n 'carefully',\n 'provide',\n 'score',\n 'feedback',\n 'verdict',\n ]);\n\n const terms = query\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, ' ')\n .split(/\\s+/)\n .filter((t) => t.length > 2 && !stopWords.has(t));\n\n // Take top 5 unique terms\n const unique = [...new Set(terms)].slice(0, 5);\n return unique.join(' ');\n }\n\n /** Format memories for injection into prompt. */\n private formatMemories(memories: MemoryRecord[]): string {\n const lines = memories.map((m) => `- [${m.category}] ${m.content}`);\n return `## Project Context (from memory)\\n${lines.join('\\n')}`;\n }\n\n /** Build a compact file tree of the project, capped at maxFiles entries. */\n buildFileTree(): string {\n if (!this.projectDir) return '';\n\n try {\n const lines: string[] = [];\n const counter = { value: 0 };\n this.walkDir(this.projectDir, '', 0, lines, counter);\n if (counter.value >= this.maxFiles) {\n lines.push(`[... truncated at ${this.maxFiles} files]`);\n }\n return lines.join('\\n');\n } catch {\n return '';\n }\n }\n\n private walkDir(\n dir: string,\n prefix: string,\n depth: number,\n lines: string[],\n counter: { value: number },\n ): void {\n if (depth > this.maxTreeDepth) return;\n if (counter.value >= this.maxFiles) return;\n\n let entries: string[];\n try {\n entries = readdirSync(dir).sort();\n } catch {\n return;\n }\n\n // Separate dirs and files\n const dirs: string[] = [];\n const files: string[] = [];\n\n for (const entry of entries) {\n if (entry.startsWith('.') && entry !== '.cowork.yml') continue;\n if (IGNORE_DIRS.has(entry)) continue;\n\n try {\n const fullPath = join(dir, entry);\n const stat = statSync(fullPath);\n if (stat.isDirectory()) {\n dirs.push(entry);\n } else if (this.shouldIncludeFile(entry)) {\n files.push(entry);\n }\n } catch {\n // Skip inaccessible entries\n }\n }\n\n // Print directories first, then files\n for (const d of dirs) {\n if (counter.value >= this.maxFiles) return;\n lines.push(`${prefix}${d}/`);\n this.walkDir(join(dir, d), `${prefix} `, depth + 1, lines, counter);\n }\n for (const f of files) {\n if (counter.value >= this.maxFiles) return;\n lines.push(`${prefix}${f}`);\n counter.value++;\n }\n }\n\n private shouldIncludeFile(filename: string): boolean {\n const dotIdx = filename.lastIndexOf('.');\n if (dotIdx < 0) return false;\n return this.includeExtensions.has(filename.slice(dotIdx));\n }\n\n /**\n * Read a specific file's content within token budget.\n * Useful for tier 3 on-demand context expansion.\n */\n readFileContent(filePath: string, maxChars = 8000): string | null {\n if (!this.projectDir) return null;\n try {\n const fullPath = join(this.projectDir, filePath);\n const content = readFileSync(fullPath, 'utf-8');\n if (content.length > maxChars) {\n return `${content.slice(0, maxChars)}\\n[TRUNCATED: file exceeds ${maxChars} chars]`;\n }\n return content;\n } catch {\n return null;\n }\n }\n}\n\n// ── Handoff Envelope ──\n\n/** Command types with pre-defined output contracts. */\nexport type HandoffCommand = 'review' | 'debate' | 'build-review' | 'cleanup' | 'adjudicate' | 'custom';\n\nexport interface HandoffEnvelopeOptions {\n /** The command being executed */\n command: HandoffCommand;\n /** The core task/instruction for GPT */\n task: string;\n /** Focus area or constraints */\n constraints?: string[];\n /** Whether this is a resumed session (GPT already has prior context) */\n resumed: boolean;\n /** Brief summary of what happened in prior turns (from session events) */\n priorContext?: string;\n /** Scope restriction (glob pattern) */\n scope?: string;\n}\n\n/** Output contract templates per command type. */\nconst OUTPUT_CONTRACTS: Record<HandoffCommand, string> = {\n review: `For each issue found, format as:\n- CRITICAL: <file>:<line> <description>\n- WARNING: <file>:<line> <description>\n- INFO: <file>:<line> <description>\n\nEnd with:\nVERDICT: APPROVED or VERDICT: NEEDS_REVISION\nSCORE: X/10`,\n\n 'build-review': `For each issue found, format as:\n- BUG: <description>\n- ISSUE: <description>\n\nEnd with:\n- VERDICT: APPROVED (if code is ready) or VERDICT: NEEDS_REVISION (if fixes needed)\n- SCORE: X/10`,\n\n cleanup: `For each issue found, output in this EXACT format (one per line):\nFINDING: <scope>|<confidence>|<file>|<line>|<symbol>|<description>|<recommendation>\n\nOutput SCAN_COMPLETE when done.`,\n\n adjudicate: `Respond with exactly one line:\nADJUDICATE: CONFIRMED|DISMISSED|UNCERTAIN <reason>`,\n\n debate: `State your position clearly, then end with:\nSTANCE: SUPPORT | OPPOSE | NEUTRAL\nCONFIDENCE: X/10`,\n\n custom: '',\n};\n\n/**\n * Build a structured handoff envelope for Claude→GPT communication.\n *\n * Wraps any command's raw prompt with:\n * 1. Codebase access preamble\n * 2. Resume primer (when continuing a thread)\n * 3. The core task\n * 4. Constraints & scope\n * 5. Output contract\n */\nexport function buildHandoffEnvelope(options: HandoffEnvelopeOptions): string {\n const sections: string[] = [];\n\n // ── Preamble ──\n sections.push('You have full access to this project\\'s codebase. Use tools to discover, read, and analyze relevant files as needed.');\n\n // ── Resume primer (capped at 500 chars to prevent bloat) ──\n if (options.resumed) {\n const context = options.priorContext ? options.priorContext.slice(0, 500) : '';\n const primer = context\n ? `Continue from prior thread. Prior context: ${context}\\nDo not repeat completed analysis — focus on unresolved items or the new task below.`\n : 'Continue from prior thread. Do not repeat completed analysis — focus on the new task below.';\n sections.push(primer);\n }\n\n // ── Task (capped at 60K chars — codex has 400K context but leave room for tools) ──\n sections.push(options.task.slice(0, 60_000));\n\n // ── Constraints ──\n const constraints: string[] = options.constraints ? [...options.constraints] : [];\n if (options.scope) {\n constraints.push(`Restrict exploration to files matching: ${options.scope}`);\n }\n if (constraints.length > 0) {\n sections.push(`CONSTRAINTS:\\n${constraints.map(c => `- ${c}`).join('\\n')}`);\n }\n\n // ── Output contract ──\n const contract = OUTPUT_CONTRACTS[options.command];\n if (contract) {\n sections.push(contract);\n }\n\n return sections.join('\\n\\n');\n}\n","// packages/core/src/engine/debate-engine.ts — Multi-round debate with proposal-critique pattern\n\nimport { nanoid } from 'nanoid';\nimport type {\n CompactionPolicy,\n ConvergencePolicy,\n DebateBudget,\n DebateEngineInput,\n DebateEngineResult,\n DebateEngineState,\n DebateIO,\n DebateMessage,\n DebateMessageKind,\n Stance,\n StopDecision,\n StopReason,\n} from '../types/debate.js';\n\n// ── Defaults ──\n\nconst DEFAULT_BUDGET: DebateBudget = {\n maxRounds: 3,\n maxWallClockMs: 110_000,\n perTurnTimeoutMs: 60_000,\n};\n\nconst DEFAULT_CONVERGENCE: ConvergencePolicy = {\n minRoundsBeforeCheck: 1,\n requiredStableRounds: 2,\n};\n\nconst DEFAULT_COMPACTION: CompactionPolicy = {\n keepRecentMessages: 4,\n summaryMaxTokens: 500,\n};\n\n// ── Stance detection ──\n\nconst SUPPORT_PATTERNS = [\n /\\bapproved?\\b/i,\n /\\bagree[sd]?\\b/i,\n /\\bsupport/i,\n /\\blooks?\\s+good\\b/i,\n /\\bno\\s+(major\\s+)?issues?\\b/i,\n /\\bwell[\\s-]designed\\b/i,\n /\\bverdict:\\s*approved/i,\n];\n\nconst OPPOSE_PATTERNS = [\n /\\bneeds?\\s+revision/i,\n /\\bdisagree/i,\n /\\boppose/i,\n /\\breject/i,\n /\\bfundamental(ly)?\\s+(flaw|issue|problem)/i,\n /\\bverdict:\\s*needs.revision/i,\n /\\bsignificant\\s+(concern|issue|problem)/i,\n];\n\nexport function detectStance(text: string): Stance {\n let supportScore = 0;\n let opposeScore = 0;\n\n for (const p of SUPPORT_PATTERNS) {\n if (p.test(text)) supportScore++;\n }\n for (const p of OPPOSE_PATTERNS) {\n if (p.test(text)) opposeScore++;\n }\n\n if (supportScore > opposeScore) return 'support';\n if (opposeScore > supportScore) return 'oppose';\n return 'uncertain';\n}\n\n// ── Engine ──\n\nexport class ProposalCritiqueEngine {\n private budget: DebateBudget;\n private convergence: ConvergencePolicy;\n private compaction: CompactionPolicy;\n\n constructor(\n budget?: Partial<DebateBudget>,\n convergence?: Partial<ConvergencePolicy>,\n compaction?: Partial<CompactionPolicy>,\n ) {\n this.budget = { ...DEFAULT_BUDGET, ...budget };\n this.convergence = { ...DEFAULT_CONVERGENCE, ...convergence };\n this.compaction = { ...DEFAULT_COMPACTION, ...compaction };\n }\n\n /** Initialize debate state. */\n init(input: DebateEngineInput): DebateEngineState {\n if (input.models.length < 2) {\n throw new Error('Proposal-critique debate requires at least 2 models');\n }\n return {\n debateId: input.debateId,\n question: input.question,\n models: input.models,\n round: 0,\n turn: 0,\n thread: [\n {\n id: nanoid(),\n turn: 0,\n round: 0,\n speakerId: 'user',\n kind: 'topic',\n text: input.question,\n createdAt: Date.now(),\n },\n ],\n runningSummary: '',\n stanceHistory: [],\n usage: {\n totalPromptTokens: 0,\n totalCompletionTokens: 0,\n totalCalls: 0,\n startedAt: Date.now(),\n },\n status: 'running',\n sessionIds: {},\n resumeStats: { attempted: 0, succeeded: 0, fallbacks: 0 },\n };\n }\n\n /** Run the full debate loop. */\n async run(input: DebateEngineInput, io: DebateIO): Promise<DebateEngineResult> {\n const state = this.init(input);\n\n let stopReason: StopReason = 'max_rounds';\n\n for (let round = 1; round <= this.budget.maxRounds; round++) {\n state.round = round;\n\n // Step 1: Proposer turn\n const proposerAlias = state.models[0];\n const proposerKind: DebateMessageKind = round === 1 ? 'proposal' : 'rebuttal';\n await this.executeTurn(state, io, proposerAlias, proposerKind);\n\n // Check time budget\n const timeCheck = this.checkTimeBudget(state);\n if (timeCheck.stop) {\n stopReason = 'time_budget';\n break;\n }\n\n // Step 2: Critic turn\n const criticAlias = state.models[1];\n await this.executeTurn(state, io, criticAlias, 'critique');\n\n // Check convergence\n const decision = this.shouldStop(state);\n if (decision.stop) {\n stopReason = decision.reason ?? 'converged';\n break;\n }\n\n // Step 3: Update running summary (use critic model — cheaper to ask for summary)\n if (round < this.budget.maxRounds) {\n await this.updateSummary(state, io);\n }\n }\n\n state.status = 'stopped';\n return this.finalize(state, stopReason);\n }\n\n /** Execute a single turn: build prompt, call model, record message. */\n private async executeTurn(\n state: DebateEngineState,\n io: DebateIO,\n modelAlias: string,\n kind: DebateMessageKind,\n ): Promise<DebateMessage> {\n state.turn++;\n const existingSessionId = state.sessionIds[modelAlias];\n const prompt = this.buildTurnPrompt(state, modelAlias, kind);\n\n if (existingSessionId) {\n state.resumeStats.attempted++;\n }\n\n const result = await io.generate(\n modelAlias,\n [\n { role: 'system', content: this.getSystemPrompt(kind) },\n { role: 'user', content: prompt },\n ],\n this.budget.perTurnTimeoutMs,\n existingSessionId,\n );\n\n // Track session ID for resume\n if (result.sessionId) {\n if (existingSessionId && result.sessionId === existingSessionId) {\n state.resumeStats.succeeded++;\n } else if (existingSessionId && result.sessionId !== existingSessionId) {\n state.resumeStats.fallbacks++;\n }\n state.sessionIds[modelAlias] = result.sessionId;\n }\n\n const stance = detectStance(result.text);\n const message: DebateMessage = {\n id: nanoid(),\n turn: state.turn,\n round: state.round,\n speakerId: modelAlias,\n kind,\n text: result.text,\n stance,\n confidence: this.extractConfidence(result.text),\n tokens: { prompt: result.promptTokens, completion: result.completionTokens },\n createdAt: Date.now(),\n };\n\n state.thread.push(message);\n state.stanceHistory.push({ round: state.round, speakerId: modelAlias, stance });\n state.usage.totalPromptTokens += result.promptTokens;\n state.usage.totalCompletionTokens += result.completionTokens;\n state.usage.totalCalls++;\n\n return message;\n }\n\n /** Build the prompt for a turn with compacted context. */\n private buildTurnPrompt(\n state: DebateEngineState,\n _modelAlias: string,\n kind: DebateMessageKind,\n ): string {\n const parts: string[] = [];\n\n // Always include the original question\n parts.push(`## Question\\n${state.question}`);\n\n // Include running summary if we have one (compaction)\n if (state.runningSummary) {\n parts.push(`## Discussion Summary So Far\\n${state.runningSummary}`);\n }\n\n // Include recent messages (compacted context window)\n const recentMessages = state.thread.slice(-this.compaction.keepRecentMessages);\n if (recentMessages.length > 0) {\n const msgTexts = recentMessages\n .filter((m) => m.kind !== 'topic') // topic already shown as question\n .map((m) => `**${m.speakerId}** (${m.kind}, round ${m.round}):\\n${m.text}`);\n if (msgTexts.length > 0) {\n parts.push(`## Recent Arguments\\n${msgTexts.join('\\n\\n')}`);\n }\n }\n\n // Role-specific instruction\n if (kind === 'proposal') {\n parts.push(\n '## Your Task\\nProvide a thorough proposal/plan to address the question above. Be specific and actionable.',\n );\n } else if (kind === 'rebuttal') {\n parts.push(\n '## Your Task\\nRevise your proposal based on the critique above. Address each concern specifically. If you disagree with a point, explain why.',\n );\n } else if (kind === 'critique') {\n parts.push(\n '## Your Task\\nCritique the proposal above. Identify weaknesses, missing considerations, and potential improvements. If the proposal is solid, say so explicitly with \"VERDICT: APPROVED\". Otherwise provide specific, actionable feedback.',\n );\n }\n\n // Ask for structured stance\n parts.push(\n '## Required Output Format\\nEnd your response with exactly one of:\\n- STANCE: SUPPORT (if you agree with the current direction)\\n- STANCE: OPPOSE (if you have significant concerns)\\n- STANCE: UNCERTAIN (if mixed)',\n );\n\n return parts.join('\\n\\n');\n }\n\n /** System prompt based on turn type. */\n private getSystemPrompt(kind: DebateMessageKind): string {\n if (kind === 'proposal' || kind === 'rebuttal') {\n return 'You are an expert architect. Provide clear, well-reasoned proposals. Address feedback directly. Always end with your STANCE.';\n }\n return 'You are a critical reviewer. Be thorough but fair. Approve good work, critique weak points. Always end with your STANCE.';\n }\n\n /** Check if we should stop the debate. */\n shouldStop(state: DebateEngineState): StopDecision {\n // Hard limit: time\n const timeCheck = this.checkTimeBudget(state);\n if (timeCheck.stop) return timeCheck;\n\n // Hard limit: rounds\n if (state.round >= this.budget.maxRounds) {\n return { stop: true, reason: 'max_rounds' };\n }\n\n // Convergence: check if critic supports for requiredStableRounds\n if (state.round >= this.convergence.minRoundsBeforeCheck) {\n const criticAlias = state.models[1];\n const criticStances = state.stanceHistory\n .filter((s) => s.speakerId === criticAlias)\n .slice(-this.convergence.requiredStableRounds);\n\n if (\n criticStances.length >= this.convergence.requiredStableRounds &&\n criticStances.every((s) => s.stance === 'support')\n ) {\n return {\n stop: true,\n reason: 'converged',\n diagnostics: { stableRounds: criticStances.length },\n };\n }\n }\n\n return { stop: false };\n }\n\n /** Check time budget. */\n private checkTimeBudget(state: DebateEngineState): StopDecision {\n const elapsed = Date.now() - state.usage.startedAt;\n const remaining = this.budget.maxWallClockMs - elapsed;\n if (remaining <= 0) {\n return {\n stop: true,\n reason: 'time_budget',\n diagnostics: { elapsedMs: elapsed, remainingMs: 0 },\n };\n }\n return { stop: false, diagnostics: { remainingMs: remaining } };\n }\n\n /** Update the running summary to compact older context. */\n private async updateSummary(state: DebateEngineState, io: DebateIO): Promise<void> {\n // Use the first model (proposer) to summarize\n const summarizerAlias = state.models[0];\n\n // Gather the round's messages\n const roundMessages = state.thread\n .filter((m) => m.round === state.round && m.kind !== 'topic')\n .map((m) => `${m.speakerId} (${m.kind}): ${m.text}`)\n .join('\\n\\n');\n\n const prevSummary = state.runningSummary ? `Previous summary: ${state.runningSummary}\\n\\n` : '';\n\n const prompt = `${prevSummary}New round of discussion:\\n${roundMessages}\\n\\nWrite a brief summary (max 3 paragraphs) of the current state of the debate. What has been proposed, what concerns were raised, and what remains unresolved?`;\n\n const result = await io.generate(\n summarizerAlias,\n [\n {\n role: 'system',\n content:\n 'Summarize debate progress concisely. Focus on key proposals, critiques, and unresolved points.',\n },\n { role: 'user', content: prompt },\n ],\n this.budget.perTurnTimeoutMs,\n );\n\n state.runningSummary = result.text;\n state.usage.totalPromptTokens += result.promptTokens;\n state.usage.totalCompletionTokens += result.completionTokens;\n state.usage.totalCalls++;\n\n // Record summary as a message\n state.thread.push({\n id: nanoid(),\n turn: ++state.turn,\n round: state.round,\n speakerId: 'moderator',\n kind: 'summary',\n text: result.text,\n createdAt: Date.now(),\n });\n }\n\n /** Build the final result from state. */\n private finalize(state: DebateEngineState, reason: StopReason): DebateEngineResult {\n // Find the last substantive message (proposal/rebuttal/critique) as the answer\n const substantive = state.thread.filter(\n (m) => m.kind === 'proposal' || m.kind === 'rebuttal' || m.kind === 'critique',\n );\n const lastProposal = [...substantive]\n .reverse()\n .find((m) => m.kind === 'proposal' || m.kind === 'rebuttal');\n const lastCritique = [...substantive].reverse().find((m) => m.kind === 'critique');\n\n // If converged, the last proposal is the answer. Otherwise, include the critique too.\n let answer: string;\n if (reason === 'converged' && lastProposal) {\n answer = lastProposal.text;\n } else if (lastProposal && lastCritique) {\n answer = `## Final Proposal\\n${lastProposal.text}\\n\\n## Outstanding Critique\\n${lastCritique.text}`;\n } else {\n answer = substantive.at(-1)?.text ?? state.question;\n }\n\n return {\n debateId: state.debateId,\n answer,\n reason,\n rounds: state.round,\n thread: state.thread,\n stanceHistory: state.stanceHistory,\n usage: state.usage,\n };\n }\n\n /** Extract confidence value from text if present. */\n private extractConfidence(text: string): number | undefined {\n const match = /confidence:\\s*([\\d.]+)/i.exec(text);\n if (match) {\n const val = Number.parseFloat(match[1]);\n if (val >= 0 && val <= 1) return val;\n if (val >= 0 && val <= 100) return val / 100;\n }\n return undefined;\n }\n}\n\nexport { DEFAULT_BUDGET, DEFAULT_CONVERGENCE, DEFAULT_COMPACTION };\n","// packages/core/src/engine/step-runner.ts\n\nimport type { SessionStore } from '../memory/session-store.js';\nimport { callModel, streamModel } from '../models/caller.js';\nimport type { CostTracker } from '../models/cost-tracker.js';\nimport type { ModelRegistry } from '../models/registry.js';\nimport type { PromptType, PromptVariables } from '../roles/prompts.js';\nimport type { RoleManager } from '../roles/role-manager.js';\nimport type { ProjectConfig } from '../types/config.js';\nimport type { TokenUsage } from '../types/events.js';\nimport type { ModelCallResult } from '../types/models.js';\nimport type { ResolvedStep } from '../types/workflow.js';\nimport { parseVerdict } from '../utils/verdict.js';\nimport type { EventBus } from './event-bus.js';\n\nexport interface StepResult {\n stepId: string;\n output: string;\n usage: TokenUsage;\n durationMs: number;\n verdict?: 'approved' | 'needs_revision';\n feedback?: string;\n}\n\nexport class StepRunner {\n constructor(\n private registry: ModelRegistry,\n private roleManager: RoleManager,\n private costTracker: CostTracker,\n private eventBus: EventBus,\n private sessionStore: SessionStore,\n private config: ProjectConfig,\n private sessionId: string,\n ) {}\n\n async execute(\n step: ResolvedStep,\n inputs: Map<string, string>,\n task: string,\n iteration: number,\n options?: { stream?: boolean },\n ): Promise<StepResult> {\n const stepId = step.definition.id;\n const role = step.definition.role;\n const stepType = step.definition.type;\n\n // Determine prompt type\n const promptType = this.resolvePromptType(stepType, stepId, iteration);\n\n // Build prompt variables\n const promptVars = this.buildPromptVars(promptType, task, inputs, iteration);\n\n // Build messages\n const messages = this.roleManager.buildMessages(promptType, promptVars);\n\n // Get model for role\n const model = this.registry.getAdapterForRole(role, this.config);\n const modelConfig = this.registry.getModelConfigForRole(role, this.config);\n\n // Emit step.started\n this.eventBus.emitEvent({\n type: 'step.started',\n stepId,\n role,\n model: modelConfig.model,\n iteration,\n timestamp: '',\n });\n\n const start = Date.now();\n let result: ModelCallResult;\n\n if (options?.stream) {\n result = await this.costTracker.tracked(\n () =>\n streamModel(\n model,\n messages,\n (delta) => {\n this.eventBus.emitEvent({\n type: 'text.delta',\n stepId,\n role,\n delta,\n });\n },\n stepId,\n role,\n ),\n stepId,\n );\n\n this.eventBus.emitEvent({\n type: 'text.done',\n stepId,\n role,\n fullText: result.text,\n });\n } else {\n result = await this.costTracker.tracked(() => callModel(model, messages), stepId);\n }\n\n const durationMs = Date.now() - start;\n\n // Save transcript entry\n this.sessionStore.saveTranscriptEntry({\n sessionId: this.sessionId,\n stepId,\n iteration,\n role,\n modelId: result.model,\n content: result.text,\n tokenCount: result.usage.totalTokens,\n cost: result.usage.costUsd,\n createdAt: new Date().toISOString(),\n metadata: null,\n });\n\n // Parse verdict for review steps\n let verdict: 'approved' | 'needs_revision' | undefined;\n let feedback: string | undefined;\n if (stepType === 'review') {\n const parsed = parseVerdict(result.text);\n verdict = parsed.verdict;\n feedback = parsed.feedback || undefined;\n }\n\n // Emit step.completed\n this.eventBus.emitEvent({\n type: 'step.completed',\n stepId,\n output: result.text,\n tokenUsage: result.usage,\n durationMs,\n timestamp: '',\n });\n\n return {\n stepId,\n output: result.text,\n usage: result.usage,\n durationMs,\n verdict,\n feedback,\n };\n }\n\n private resolvePromptType(stepType: string, stepId: string, iteration: number): PromptType {\n if (stepType === 'generate') {\n if (iteration > 1) {\n return stepId.includes('implement') ? 'code' : 'plan-revision';\n }\n if (stepId.includes('plan')) return 'plan';\n if (stepId.includes('implement')) return 'code';\n return 'plan';\n }\n if (stepType === 'review') {\n return stepId.includes('code') ? 'code-review' : 'plan-review';\n }\n // Fallback for other step types\n return 'plan';\n }\n\n private buildPromptVars(\n promptType: PromptType,\n task: string,\n inputs: Map<string, string>,\n _iteration: number,\n ): PromptVariables {\n const vars: PromptVariables = { task };\n\n // Get the first input value as the primary content\n const inputValues = [...inputs.values()];\n const primaryInput = inputValues[0] ?? '';\n\n switch (promptType) {\n case 'plan':\n break;\n case 'plan-review':\n vars.plan = primaryInput;\n break;\n case 'plan-revision':\n vars.previousPlan = primaryInput;\n vars.feedback = inputValues[1] ?? '';\n break;\n case 'code':\n vars.plan = primaryInput;\n break;\n case 'code-review':\n vars.plan = primaryInput;\n vars.code = inputValues[1] ?? '';\n break;\n }\n\n return vars;\n }\n}\n","// packages/core/src/engine/workflow-engine.ts\n\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport type {\n ResolvedStep,\n ResolvedWorkflow,\n StepDefinition,\n WorkflowDefinition,\n} from '../types/workflow.js';\nimport { WorkflowError } from '../utils/errors.js';\n\nconst VALID_STEP_TYPES: Set<string> = new Set<string>([\n 'generate',\n 'review',\n 'debate',\n 'transform',\n 'gate',\n 'parallel',\n 'conditional',\n]);\n\n/**\n * Loads workflow YAML files, validates them, and resolves step dependencies\n * into a topologically sorted execution order.\n */\nexport class WorkflowEngine {\n constructor(private workflowDir: string) {}\n\n /**\n * Load a workflow YAML file by name, validate it, and resolve into a DAG.\n */\n load(workflowName: string): ResolvedWorkflow {\n const filePath = join(this.workflowDir, `${workflowName}.yml`);\n let raw: string;\n try {\n raw = readFileSync(filePath, 'utf-8');\n } catch {\n throw new WorkflowError(`Workflow file not found: ${filePath}`);\n }\n\n let parsed: unknown;\n try {\n parsed = parseYaml(raw);\n } catch {\n throw new WorkflowError(`Invalid YAML in workflow: ${workflowName}`);\n }\n\n const definition = parsed as WorkflowDefinition;\n this.validateDefinition(definition, workflowName);\n\n const executionOrder = this.resolveSteps(definition.steps);\n\n return {\n name: definition.name,\n executionOrder,\n };\n }\n\n /**\n * Returns the topologically sorted steps (already computed during load).\n */\n getExecutionOrder(workflow: ResolvedWorkflow): ResolvedStep[] {\n return workflow.executionOrder;\n }\n\n private validateDefinition(def: WorkflowDefinition, workflowName: string): void {\n if (!def || typeof def !== 'object') {\n throw new WorkflowError(`Workflow \"${workflowName}\" is not a valid object`);\n }\n if (!def.name || typeof def.name !== 'string') {\n throw new WorkflowError(`Workflow \"${workflowName}\" is missing a name`);\n }\n if (!Array.isArray(def.steps) || def.steps.length === 0) {\n throw new WorkflowError(`Workflow \"${workflowName}\" has no steps`);\n }\n\n const stepIds = new Set<string>();\n for (const step of def.steps) {\n this.validateStep(step, stepIds, workflowName);\n stepIds.add(step.id);\n }\n }\n\n private validateStep(step: StepDefinition, knownIds: Set<string>, workflowName: string): void {\n if (!step.id || typeof step.id !== 'string') {\n throw new WorkflowError(`Step in \"${workflowName}\" is missing an id`);\n }\n if (knownIds.has(step.id)) {\n throw new WorkflowError(`Duplicate step id \"${step.id}\" in \"${workflowName}\"`, step.id);\n }\n if (!step.type || !VALID_STEP_TYPES.has(step.type)) {\n throw new WorkflowError(`Step \"${step.id}\" has invalid type \"${step.type}\"`, step.id);\n }\n if (!step.role || typeof step.role !== 'string') {\n throw new WorkflowError(`Step \"${step.id}\" is missing a role`, step.id);\n }\n }\n\n /**\n * Resolve steps into topological order, validating input references and loops.\n */\n private resolveSteps(steps: StepDefinition[]): ResolvedStep[] {\n const stepMap = new Map<string, StepDefinition>();\n const outputMap = new Map<string, string>(); // output ref -> step id\n\n for (const step of steps) {\n stepMap.set(step.id, step);\n if (step.output) {\n outputMap.set(step.output, step.id);\n }\n }\n\n // Build adjacency for topological sort: edges[stepId] = set of dependency step ids\n const edges = new Map<string, Set<string>>();\n for (const step of steps) {\n const deps = new Set<string>();\n\n if (step.input) {\n for (const ref of step.input) {\n const sourceStepId = outputMap.get(ref);\n if (sourceStepId === undefined) {\n throw new WorkflowError(`Step \"${step.id}\" references unknown input \"${ref}\"`, step.id);\n }\n deps.add(sourceStepId);\n }\n }\n\n if (step.loop) {\n if (!stepMap.has(step.loop.iteratesWith)) {\n throw new WorkflowError(\n `Step \"${step.id}\" loop references unknown step \"${step.loop.iteratesWith}\"`,\n step.id,\n );\n }\n }\n\n edges.set(step.id, deps);\n }\n\n // Topological sort (Kahn's algorithm)\n const inDegree = new Map<string, number>();\n for (const step of steps) {\n inDegree.set(step.id, 0);\n }\n for (const [, deps] of edges) {\n for (const dep of deps) {\n inDegree.set(dep, (inDegree.get(dep) ?? 0) + 1);\n }\n }\n\n // Kahn's: nodes with no incoming edges start the queue\n // But inDegree here tracks how many nodes depend ON each node.\n // We need it the other way: how many dependencies does each node have.\n const depCount = new Map<string, number>();\n for (const [stepId, deps] of edges) {\n depCount.set(stepId, deps.size);\n }\n\n const queue: string[] = [];\n for (const [stepId, count] of depCount) {\n if (count === 0) {\n queue.push(stepId);\n }\n }\n\n const sorted: string[] = [];\n while (queue.length > 0) {\n const current = queue.shift() as string;\n sorted.push(current);\n\n // Find all steps that depend on current\n for (const [stepId, deps] of edges) {\n if (deps.has(current)) {\n const newCount = (depCount.get(stepId) ?? 0) - 1;\n depCount.set(stepId, newCount);\n if (newCount === 0) {\n queue.push(stepId);\n }\n }\n }\n }\n\n if (sorted.length !== steps.length) {\n throw new WorkflowError('Workflow contains a cycle');\n }\n\n // Build resolved steps\n return sorted.map((stepId) => {\n const def = stepMap.get(stepId) as StepDefinition;\n const deps = edges.get(stepId) as Set<string>;\n\n return {\n definition: def,\n inputStepIds: [...deps],\n isLoopEntry: def.loop !== undefined,\n loopPartnerStepId: def.loop?.iteratesWith,\n };\n });\n }\n}\n","// packages/core/src/engine/cancellation.ts — Request cancellation support\n\nexport class CancellationToken {\n private cancelled = false;\n private callbacks = new Set<() => void>();\n\n /** Signal cancellation. Idempotent — multiple calls are safe. */\n cancel(): void {\n if (this.cancelled) return;\n this.cancelled = true;\n for (const cb of this.callbacks) {\n try {\n cb();\n } catch {\n // Swallow callback errors\n }\n }\n }\n\n get isCancelled(): boolean {\n return this.cancelled;\n }\n\n /** Throw if already cancelled. Call before starting expensive work. */\n throwIfCancelled(): void {\n if (this.cancelled) {\n throw new CancellationError('Operation was cancelled');\n }\n }\n\n /**\n * Register a callback to run on cancellation.\n * Deduplicated by reference — same function won't run twice.\n * If already cancelled, callback fires immediately.\n */\n onCancel(callback: () => void): void {\n if (this.cancelled) {\n callback();\n return;\n }\n this.callbacks.add(callback);\n }\n\n /** Remove a previously registered callback. */\n offCancel(callback: () => void): void {\n this.callbacks.delete(callback);\n }\n\n /**\n * Create a promise that resolves after `ms` but can be interrupted by cancellation.\n * Returns true if sleep completed, false if cancelled.\n */\n sleep(ms: number): Promise<boolean> {\n return new Promise((resolve) => {\n if (this.cancelled) {\n resolve(false);\n return;\n }\n\n const state = { timer: undefined as ReturnType<typeof setTimeout> | undefined };\n const onCancelHandler = () => {\n if (state.timer !== undefined) clearTimeout(state.timer);\n resolve(false);\n };\n\n state.timer = setTimeout(() => {\n this.callbacks.delete(onCancelHandler);\n resolve(true);\n }, ms);\n\n this.onCancel(onCancelHandler);\n });\n }\n}\n\nexport class CancellationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CancellationError';\n }\n}\n","// packages/core/src/engine/policy.ts — Minimal policy engine for commit gates\n\nexport type PolicyMode = 'warn' | 'enforce';\nexport type PolicyDecision = 'allow' | 'warn' | 'block';\n\nexport interface PolicyRule {\n id: string;\n when: string; // event name: 'review.completed', 'shipit.pre_commit'\n predicate: string; // built-in predicate name\n threshold?: number;\n action: 'warn' | 'block';\n message: string;\n}\n\nexport interface PolicyContext {\n criticalCount: number;\n warningCount: number;\n verdict: string; // 'approved' | 'needs_revision' | 'unknown'\n stepsCompleted: Record<string, 'passed' | 'failed' | 'skipped'>;\n cleanupHighCount: number;\n}\n\nexport interface PolicyResult {\n decision: PolicyDecision;\n violations: { ruleId: string; action: 'warn' | 'block'; message: string }[];\n}\n\nconst BUILTIN_PREDICATES: Record<string, (ctx: PolicyContext, threshold?: number) => boolean> = {\n critical_findings_gt: (ctx, t) => ctx.criticalCount > (t ?? 0),\n warning_findings_gt: (ctx, t) => ctx.warningCount > (t ?? 0),\n verdict_is_needs_revision: (ctx) => ctx.verdict === 'needs_revision',\n step_failed: (ctx) => Object.values(ctx.stepsCompleted).includes('failed'),\n cleanup_high_gt: (ctx, t) => ctx.cleanupHighCount > (t ?? 0),\n};\n\nexport const DEFAULT_RULES: PolicyRule[] = [\n {\n id: 'block-critical-review',\n when: 'review.completed',\n predicate: 'critical_findings_gt',\n threshold: 0,\n action: 'block',\n message: 'Critical findings must be fixed before commit.',\n },\n {\n id: 'warn-needs-revision',\n when: 'review.completed',\n predicate: 'verdict_is_needs_revision',\n action: 'warn',\n message: 'Review verdict is NEEDS_REVISION.',\n },\n];\n\nexport function evaluatePolicy(\n event: string,\n context: PolicyContext,\n rules: PolicyRule[],\n mode: PolicyMode = 'enforce',\n): PolicyResult {\n const violations: PolicyResult['violations'] = [];\n\n for (const rule of rules) {\n if (rule.when !== event) continue;\n\n const check = BUILTIN_PREDICATES[rule.predicate];\n if (!check) continue;\n\n if (check(context, rule.threshold)) {\n const action = mode === 'warn' ? 'warn' : rule.action;\n violations.push({ ruleId: rule.id, action, message: rule.message });\n }\n }\n\n const hasBlock = violations.some((v) => v.action === 'block');\n const hasWarn = violations.some((v) => v.action === 'warn');\n\n return {\n decision: hasBlock ? 'block' : hasWarn ? 'warn' : 'allow',\n violations,\n };\n}\n","// packages/core/src/cleanup/scanners.ts — Deterministic scanners (no LLM)\n\nimport { readFileSync, readdirSync, statSync, existsSync } from 'node:fs';\nimport { join, relative, sep } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { Ignore } from 'ignore';\nimport type { CleanupConfidence, CleanupFinding, CleanupScope } from '../types/cleanup.js';\n\n// ── Helpers ──\n\nconst SOURCE_EXTS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs']);\nconst ALL_SCAN_EXTS = new Set([...SOURCE_EXTS, '.json']);\n\nfunction normalizePath(filePath: string): string {\n return filePath.split(sep).join('/');\n}\n\n/** Walk files, respecting an optional compiled ignore filter. */\nfunction walkFiles(dir: string, exts: Set<string>, result: string[] = [], rootDir?: string, ig?: Ignore): string[] {\n const root = rootDir ?? dir;\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return result;\n }\n for (const entry of entries) {\n const full = join(dir, entry);\n const rel = normalizePath(relative(root, full));\n\n // Check ignore filter (compiled .gitignore + .codemootignore + builtins)\n if (ig && ig.ignores(rel)) continue;\n\n let stat;\n try {\n stat = statSync(full);\n } catch {\n continue;\n }\n if (stat.isDirectory()) {\n walkFiles(full, exts, result, root, ig);\n } else if (stat.isFile()) {\n const ext = full.slice(full.lastIndexOf('.'));\n if (exts.has(ext)) result.push(full);\n }\n }\n return result;\n}\n\nfunction readFileSafe(filePath: string): string {\n try {\n return readFileSync(filePath, 'utf-8');\n } catch {\n return '';\n }\n}\n\nfunction makeKey(scope: CleanupScope, file: string, symbol: string): string {\n return `${scope}:${normalizePath(file)}:${symbol}`;\n}\n\n// ── Find package.json files in monorepo ──\n\nfunction findPackageJsons(projectDir: string): { dir: string; pkg: Record<string, unknown> }[] {\n const results: { dir: string; pkg: Record<string, unknown> }[] = [];\n\n // Root package.json\n const rootPkg = join(projectDir, 'package.json');\n if (existsSync(rootPkg)) {\n try {\n results.push({ dir: projectDir, pkg: JSON.parse(readFileSafe(rootPkg)) });\n } catch { /* skip */ }\n }\n\n // packages/*/package.json (one level of workspace nesting)\n const packagesDir = join(projectDir, 'packages');\n if (existsSync(packagesDir)) {\n try {\n for (const entry of readdirSync(packagesDir)) {\n const pkgJson = join(packagesDir, entry, 'package.json');\n if (existsSync(pkgJson)) {\n try {\n results.push({\n dir: join(packagesDir, entry),\n pkg: JSON.parse(readFileSafe(pkgJson)),\n });\n } catch { /* skip */ }\n }\n }\n } catch { /* skip */ }\n }\n\n return results;\n}\n\n// ── Scanner: Unused Dependencies ──\n\nexport function scanUnusedDeps(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const packages = findPackageJsons(projectDir);\n\n for (const { dir, pkg } of packages) {\n const deps = pkg.dependencies as Record<string, string> | undefined;\n if (!deps) continue;\n\n const pkgName = (pkg.name as string) || relative(projectDir, dir);\n const files = walkFiles(dir, ALL_SCAN_EXTS, [], projectDir, ig);\n\n // Collect all file contents for searching\n const allContent = files.map(f => readFileSafe(f)).join('\\n');\n\n for (const depName of Object.keys(deps)) {\n // Check if dep is imported/required anywhere in this package\n const importPatterns = [\n `from '${depName}`,\n `from \"${depName}`,\n `require('${depName}`,\n `require(\"${depName}`,\n `import '${depName}`,\n `import \"${depName}`,\n // Scoped subpath imports\n `from '${depName}/`,\n `from \"${depName}/`,\n // Dynamic imports\n `import('${depName}`,\n `import(\"${depName}`,\n ];\n\n // Also check package.json bin/exports/scripts references (NOT dependencies itself)\n const binStr = JSON.stringify(pkg.bin ?? {});\n const exportsStr = JSON.stringify(pkg.exports ?? {});\n const scriptsStr = JSON.stringify(pkg.scripts ?? {});\n const usedInPkgJson = binStr.includes(depName) || exportsStr.includes(depName) || scriptsStr.includes(depName);\n\n const usedInSource = importPatterns.some(p => allContent.includes(p));\n\n if (!usedInSource && !usedInPkgJson) {\n const relFile = normalizePath(relative(projectDir, join(dir, 'package.json')));\n findings.push({\n key: makeKey('deps', relFile, depName),\n scope: 'deps',\n confidence: 'high',\n file: relFile,\n description: `Dependency \"${depName}\" is not imported in any source file`,\n recommendation: `Remove \"${depName}\" from dependencies`,\n deterministicEvidence: [`No import/require of \"${depName}\" found in ${files.length} files in ${pkgName}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n packageName: pkgName,\n });\n }\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Unused Exports ──\n\nexport function scanUnusedExports(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n\n // Build a map of all exported symbols and their locations\n const exports: { file: string; name: string; line: number }[] = [];\n const exportRegex = /^export\\s+(?:(?:async\\s+)?function|class|const|let|var|type|interface|enum)\\s+(\\w+)/gm;\n const namedExportRegex = /export\\s*\\{([^}]+)\\}/g;\n\n for (const file of allFiles) {\n const content = readFileSafe(file);\n const relFile = normalizePath(relative(projectDir, file));\n\n // Skip index/barrel files — they re-export\n if (relFile.endsWith('index.ts') || relFile.endsWith('index.js')) continue;\n\n let match: RegExpExecArray | null;\n\n exportRegex.lastIndex = 0;\n match = exportRegex.exec(content);\n while (match) {\n const lineNum = content.slice(0, match.index).split('\\n').length;\n exports.push({ file: relFile, name: match[1], line: lineNum });\n match = exportRegex.exec(content);\n }\n\n namedExportRegex.lastIndex = 0;\n match = namedExportRegex.exec(content);\n while (match) {\n const names = match[1].split(',').map(n => n.trim().split(/\\s+as\\s+/)[0].trim()).filter(Boolean);\n const lineNum = content.slice(0, match.index).split('\\n').length;\n for (const name of names) {\n exports.push({ file: relFile, name, line: lineNum });\n }\n match = namedExportRegex.exec(content);\n }\n }\n\n // Build all source content for import searching\n const allContent = allFiles.map(f => readFileSafe(f)).join('\\n');\n\n for (const exp of exports) {\n // Simple check: does the export name appear in an import statement in any other file?\n const isUsed = allContent.includes(`{ ${exp.name}`) ||\n allContent.includes(`{${exp.name}`) ||\n allContent.includes(`, ${exp.name}`) ||\n allContent.includes(`${exp.name},`) ||\n allContent.includes(`${exp.name} }`) ||\n allContent.includes(`${exp.name}}`);\n\n // Count occurrences — subtract the export itself\n if (!isUsed) {\n findings.push({\n key: makeKey('unused-exports', exp.file, exp.name),\n scope: 'unused-exports',\n confidence: 'medium', // Could be dynamically imported or used via barrel\n file: exp.file,\n line: exp.line,\n description: `Export \"${exp.name}\" appears unused (no import found)`,\n recommendation: `Consider removing export \"${exp.name}\" or marking as internal`,\n deterministicEvidence: [`No import of \"${exp.name}\" found across ${allFiles.length} files`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Hardcoded Values ──\n\nconst MAGIC_NUMBER_REGEX = /(?<!\\w)(\\d{4,})(?!\\w)/g; // 4+ digit numbers (3-digit too noisy)\n\n/** Numbers commonly used as config values — not magic numbers. */\nconst COMMON_NUMBERS = new Set([\n 1000, 1024, 2048, 4096, 8192, 16384, 32768, 65536,\n 1200, 1500, 2000, 3000, 5000, 8000, 8080, 8443, 9000, 9090,\n 10000, 15000, 30000, 50000, 60000, 100000, 120000, 200000, 300000, 400000, 600000,\n]);\nconst URL_REGEX = /(['\"`])(https?:\\/\\/[^\\s'\"`]+)\\1/g;\nconst CREDENTIAL_PATTERNS = [\n /(?:password|secret|token|api[_-]?key|auth)\\s*[:=]\\s*(['\"`])(?!process\\.env)[^'\"`\\n]+\\1/gi,\n];\n\nexport function scanHardcoded(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n\n for (const file of allFiles) {\n const relFile = normalizePath(relative(projectDir, file));\n\n // Skip test files for magic numbers (fixtures/mocks are expected)\n const isTest = relFile.includes('test') || relFile.includes('spec') || relFile.includes('__test');\n\n const content = readFileSafe(file);\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineNum = i + 1;\n\n // Skip comments\n if (line.trim().startsWith('//') || line.trim().startsWith('*')) continue;\n\n // Magic numbers (skip in tests, skip common values like ports, HTTP codes)\n if (!isTest) {\n const numberMatches = line.matchAll(MAGIC_NUMBER_REGEX);\n for (const m of numberMatches) {\n const num = Number.parseInt(m[1], 10);\n // Skip common legitimate values\n if (COMMON_NUMBERS.has(num)) continue;\n // Skip if it's clearly a size constant definition\n if (line.includes('const') || line.includes('=')) {\n // Allow: const MAX_SIZE = 512 * 1024\n if (/(?:const|let|var)\\s+[A-Z_]+\\s*=/.test(line)) continue;\n }\n\n findings.push({\n key: makeKey('hardcoded', relFile, `num:${m[1]}:L${lineNum}`),\n scope: 'hardcoded',\n confidence: 'medium',\n file: relFile,\n line: lineNum,\n description: `Magic number ${m[1]} found`,\n recommendation: `Extract to named constant`,\n deterministicEvidence: [`Literal number ${m[1]} at line ${lineNum}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n }\n }\n\n // Hardcoded URLs (skip in tests)\n if (!isTest) {\n const urlMatches = line.matchAll(URL_REGEX);\n for (const m of urlMatches) {\n const urlKey = m[2].replace(/^https?:\\/\\//, '').split('/')[0];\n findings.push({\n key: makeKey('hardcoded', relFile, `url:${urlKey}:L${lineNum}`),\n scope: 'hardcoded',\n confidence: 'medium',\n file: relFile,\n line: lineNum,\n description: `Hardcoded URL: ${m[2].slice(0, 60)}`,\n recommendation: `Move to configuration or environment variable`,\n deterministicEvidence: [`URL literal at line ${lineNum}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n }\n }\n\n // Credential patterns (skip in tests — mock tokens/secrets are expected)\n if (!isTest) for (const pattern of CREDENTIAL_PATTERNS) {\n pattern.lastIndex = 0;\n if (pattern.test(line)) {\n findings.push({\n key: makeKey('hardcoded', relFile, `cred:L${lineNum}`),\n scope: 'hardcoded',\n confidence: 'high',\n file: relFile,\n line: lineNum,\n description: `Possible hardcoded credential`,\n recommendation: `Move to environment variable or secret manager`,\n deterministicEvidence: [`Credential pattern matched at line ${lineNum}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n }\n }\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Duplicates (report-only) ──\n\nexport function scanDuplicates(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n\n // Extract function bodies and hash them\n const funcRegex = /(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\([^)]*\\)\\s*(?::\\s*[^{]+)?\\{/g;\n const bodyMap = new Map<string, { file: string; name: string; line: number; hash: string }[]>();\n\n for (const file of allFiles) {\n const relFile = normalizePath(relative(projectDir, file));\n const content = readFileSafe(file);\n\n funcRegex.lastIndex = 0;\n let match = funcRegex.exec(content);\n while (match) {\n const startIdx = match.index + match[0].length;\n // Find matching closing brace (simple depth counting)\n let depth = 1;\n let endIdx = startIdx;\n while (endIdx < content.length && depth > 0) {\n if (content[endIdx] === '{') depth++;\n else if (content[endIdx] === '}') depth--;\n endIdx++;\n }\n\n const body = content.slice(startIdx, endIdx - 1);\n // Normalize: strip whitespace, variable names stay\n const normalized = body.replace(/\\s+/g, ' ').trim();\n\n // Only consider non-trivial functions (>50 chars after normalization)\n if (normalized.length > 50) {\n const hash = createHash('md5').update(normalized).digest('hex');\n const lineNum = content.slice(0, match.index).split('\\n').length;\n\n if (!bodyMap.has(hash)) bodyMap.set(hash, []);\n bodyMap.get(hash)!.push({ file: relFile, name: match[1], line: lineNum, hash });\n }\n\n match = funcRegex.exec(content);\n }\n }\n\n // Report groups with 2+ matches\n for (const [hash, group] of bodyMap) {\n if (group.length < 2) continue;\n\n const groupKey = group.map(g => `${g.file}:${g.line}`).sort().join('+');\n\n for (const item of group) {\n findings.push({\n key: makeKey('duplicates', item.file, `${hash.slice(0, 8)}:${item.name}`),\n scope: 'duplicates',\n confidence: 'low',\n file: item.file,\n line: item.line,\n description: `Function \"${item.name}\" has identical body to ${group.length - 1} other function(s)`,\n recommendation: `Consider extracting shared logic to a common utility`,\n deterministicEvidence: [`Body hash ${hash.slice(0, 8)} shared by: ${group.map(g => `${g.file}:${g.name}`).join(', ')}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n groupKey,\n });\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Dead Code (report-only, intra-module) ──\n\nexport function scanDeadCode(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n\n // Find non-exported functions/variables that are only defined but never referenced\n const internalDeclRegex = /^(?!export)\\s*(?:async\\s+)?(?:function|const|let|var)\\s+(\\w+)/gm;\n\n for (const file of allFiles) {\n const relFile = normalizePath(relative(projectDir, file));\n const content = readFileSafe(file);\n\n // Skip very small files (likely stubs)\n if (content.length < 50) continue;\n\n internalDeclRegex.lastIndex = 0;\n let match = internalDeclRegex.exec(content);\n while (match) {\n const name = match[1];\n const lineNum = content.slice(0, match.index).split('\\n').length;\n\n // Skip common patterns: single-letter vars, _prefixed, ALL_CAPS constants\n if (name.length <= 1 || name.startsWith('_')) {\n match = internalDeclRegex.exec(content);\n continue;\n }\n\n // Count occurrences of this name in the file (excluding the declaration itself)\n const regex = new RegExp(`\\\\b${name}\\\\b`, 'g');\n const occurrences = (content.match(regex) || []).length;\n\n // If name appears only once (the declaration), it's likely dead\n if (occurrences <= 1) {\n findings.push({\n key: makeKey('deadcode', relFile, name),\n scope: 'deadcode',\n confidence: 'low',\n file: relFile,\n line: lineNum,\n description: `\"${name}\" is declared but never referenced in this file`,\n recommendation: `Remove if unused, or export if needed elsewhere`,\n deterministicEvidence: [`\"${name}\" appears ${occurrences} time(s) in file (declaration only)`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n }\n\n match = internalDeclRegex.exec(content);\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Security (OWASP vulnerability detection) ──\n\nconst SECURITY_PATTERNS: { regex: RegExp; cwe: string; severity: 'critical' | 'high' | 'medium'; description: string; recommendation: string }[] = [\n // CWE-94: Code Injection\n { regex: /\\beval\\s*\\(/g, cwe: 'CWE-94', severity: 'critical', description: 'eval() usage — code injection risk', recommendation: 'Replace eval() with safe alternatives (JSON.parse, Function constructor with validation, or structured parsing)' },\n { regex: /\\bnew\\s+Function\\s*\\(/g, cwe: 'CWE-94', severity: 'critical', description: 'new Function() — dynamic code execution', recommendation: 'Avoid dynamic code generation; use static dispatch or lookup tables' },\n\n // CWE-78: OS Command Injection\n { regex: /child_process.*\\bexec\\s*\\(\\s*`/g, cwe: 'CWE-78', severity: 'critical', description: 'exec() with template literal — command injection risk', recommendation: 'Use execFile() with argument array instead of exec() with string interpolation' },\n { regex: /child_process.*\\bexec\\s*\\(\\s*[^'\"`\\s]+\\s*\\+/g, cwe: 'CWE-78', severity: 'critical', description: 'exec() with string concatenation — command injection risk', recommendation: 'Use execFile() with argument array instead of exec() with concatenation' },\n { regex: /\\bexecSync\\s*\\(\\s*`/g, cwe: 'CWE-78', severity: 'critical', description: 'execSync() with template literal — command injection', recommendation: 'Use execFileSync() with argument array' },\n\n // CWE-89: SQL Injection\n { regex: /\\.(?:query|exec|run|prepare)\\s*\\(\\s*`[^`]*\\$\\{/g, cwe: 'CWE-89', severity: 'critical', description: 'SQL query with template literal interpolation', recommendation: 'Use parameterized queries with ? placeholders' },\n { regex: /\\.(?:query|exec|run)\\s*\\([^)]*\\+/g, cwe: 'CWE-89', severity: 'high', description: 'SQL query with string concatenation', recommendation: 'Use parameterized queries instead of string building' },\n\n // CWE-22: Path Traversal\n { regex: /path\\.(?:join|resolve)\\s*\\([^)]*(?:req\\.|params\\.|query\\.|body\\.)/g, cwe: 'CWE-22', severity: 'high', description: 'Path construction with user input — traversal risk', recommendation: 'Validate and normalize paths, reject .. segments, use path.normalize() + startsWith() check' },\n\n // CWE-79: Cross-Site Scripting\n { regex: /\\.innerHTML\\s*=/g, cwe: 'CWE-79', severity: 'high', description: 'innerHTML assignment — XSS risk', recommendation: 'Use textContent or a sanitization library (DOMPurify)' },\n { regex: /dangerouslySetInnerHTML/g, cwe: 'CWE-79', severity: 'medium', description: 'dangerouslySetInnerHTML — potential XSS', recommendation: 'Sanitize HTML before rendering; use DOMPurify or similar' },\n\n // CWE-601: Open Redirect\n { regex: /res\\.redirect\\s*\\(\\s*(?:req\\.(?:query|params|body)\\.|[^'\"`\\s])/g, cwe: 'CWE-601', severity: 'high', description: 'Redirect with user-controlled input — open redirect', recommendation: 'Validate redirect target against allowlist of safe URLs' },\n\n // CWE-798: Hardcoded Credentials (beyond what hardcoded scanner catches)\n { regex: /(?:jwt|bearer)\\s*[:=]\\s*['\"`][A-Za-z0-9\\-_.]+['\"`]/gi, cwe: 'CWE-798', severity: 'high', description: 'Hardcoded JWT/Bearer token', recommendation: 'Move tokens to environment variables or secret manager' },\n\n // CWE-327: Weak Cryptography\n { regex: /createHash\\s*\\(\\s*['\"`](?:md5|sha1)['\"`]\\s*\\)/g, cwe: 'CWE-327', severity: 'medium', description: 'Weak hash algorithm (MD5/SHA1)', recommendation: 'Use SHA-256 or stronger for security-sensitive hashing' },\n\n // CWE-1333: ReDoS\n { regex: /new\\s+RegExp\\s*\\(\\s*[^)]*(?:\\.\\*|\\.\\+|\\(.*\\|.*\\))\\s*[^)]*\\)/g, cwe: 'CWE-1333', severity: 'medium', description: 'Dynamic regex with potential catastrophic backtracking', recommendation: 'Audit regex for ReDoS; consider using re2 or safe-regex library' },\n\n // CWE-200: Information Exposure\n { regex: /(?:console\\.(?:log|error|warn)|res\\.(?:json|send))\\s*\\(\\s*(?:err|error|e)\\s*\\)/g, cwe: 'CWE-200', severity: 'medium', description: 'Full error object exposed — may leak stack traces/internals', recommendation: 'Log errors server-side; return sanitized error messages to clients' },\n\n // CWE-352: Missing CSRF (heuristic)\n { regex: /app\\.(?:post|put|patch|delete)\\s*\\([^)]*,\\s*(?:async\\s+)?\\([^)]*req/g, cwe: 'CWE-352', severity: 'medium', description: 'State-changing route without visible CSRF protection', recommendation: 'Add CSRF token validation middleware (csurf, csrf-csrf)' },\n];\n\nexport function scanSecurity(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n\n for (const file of allFiles) {\n const relFile = normalizePath(relative(projectDir, file));\n const isTest = relFile.includes('test') || relFile.includes('spec') || relFile.includes('__test');\n // Skip test files — mock code intentionally uses unsafe patterns\n if (isTest) continue;\n\n const content = readFileSafe(file);\n const lines = content.split('\\n');\n\n for (const pattern of SECURITY_PATTERNS) {\n pattern.regex.lastIndex = 0;\n let match = pattern.regex.exec(content);\n while (match) {\n const lineNum = content.slice(0, match.index).split('\\n').length;\n const lineContent = lines[lineNum - 1]?.trim() || '';\n\n // Skip commented lines and regex/string literals (scanner definition patterns)\n if (lineContent.startsWith('//') || lineContent.startsWith('*') ||\n lineContent.startsWith('{ regex:') || lineContent.startsWith('regex:') ||\n /^\\s*\\//.test(lineContent) || /^\\s*['\"`].*['\"`]\\s*[,;]?\\s*$/.test(lineContent)) {\n match = pattern.regex.exec(content);\n continue;\n }\n\n const confidence: CleanupConfidence = pattern.severity === 'critical' ? 'high' : pattern.severity === 'high' ? 'medium' : 'low';\n\n findings.push({\n key: makeKey('security', relFile, `${pattern.cwe}:L${lineNum}`),\n scope: 'security',\n confidence,\n file: relFile,\n line: lineNum,\n description: `[${pattern.cwe}] ${pattern.description}`,\n recommendation: pattern.recommendation,\n deterministicEvidence: [`Pattern matched at line ${lineNum}: ${lineContent.slice(0, 80)}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n\n match = pattern.regex.exec(content);\n }\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Near-Duplicates (fuzzy similarity) ──\n\n/** Tokenize a function body: strip whitespace, normalize identifiers to placeholders */\nfunction tokenize(body: string): string[] {\n return body\n .replace(/\\/\\/[^\\n]*/g, '') // strip line comments\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // strip block comments\n .replace(/\\s+/g, ' ') // collapse whitespace\n .trim()\n .split(/(\\W)/) // split on non-word chars, keep delimiters\n .filter(t => t.trim().length > 0);\n}\n\n/** Build n-gram set for Jaccard similarity */\nfunction ngramSet(tokens: string[], n: number): Set<string> {\n const set = new Set<string>();\n for (let i = 0; i <= tokens.length - n; i++) {\n set.add(tokens.slice(i, i + n).join('|'));\n }\n return set;\n}\n\n/** Jaccard similarity between two sets */\nfunction jaccard(a: Set<string>, b: Set<string>): number {\n let intersection = 0;\n for (const item of a) {\n if (b.has(item)) intersection++;\n }\n const union = a.size + b.size - intersection;\n return union === 0 ? 0 : intersection / union;\n}\n\ninterface FuncEntry {\n file: string;\n name: string;\n line: number;\n tokens: string[];\n ngrams: Set<string>;\n bodyLength: number;\n}\n\nexport function scanNearDuplicates(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n const funcRegex = /(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\([^)]*\\)\\s*(?::\\s*[^{]+)?\\{/g;\n const funcs: FuncEntry[] = [];\n\n // Extract all functions\n for (const file of allFiles) {\n const relFile = normalizePath(relative(projectDir, file));\n const content = readFileSafe(file);\n\n funcRegex.lastIndex = 0;\n let match = funcRegex.exec(content);\n while (match) {\n const startIdx = match.index + match[0].length;\n let depth = 1;\n let endIdx = startIdx;\n while (endIdx < content.length && depth > 0) {\n if (content[endIdx] === '{') depth++;\n else if (content[endIdx] === '}') depth--;\n endIdx++;\n }\n\n const body = content.slice(startIdx, endIdx - 1);\n const tokens = tokenize(body);\n\n // Only consider non-trivial functions (>20 tokens)\n if (tokens.length > 20) {\n const ngrams = ngramSet(tokens, 5);\n const lineNum = content.slice(0, match.index).split('\\n').length;\n funcs.push({ file: relFile, name: match[1], line: lineNum, tokens, ngrams, bodyLength: body.length });\n }\n\n match = funcRegex.exec(content);\n }\n }\n\n // Compare all pairs (O(n^2) — bounded by function count, not file count)\n const reported = new Set<string>();\n for (let i = 0; i < funcs.length; i++) {\n for (let j = i + 1; j < funcs.length; j++) {\n const a = funcs[i];\n const b = funcs[j];\n\n // Skip exact same file+name (already caught by duplicates scanner)\n if (a.file === b.file && a.name === b.name) continue;\n\n // Quick size filter: bodies must be within 2x of each other\n const sizeRatio = Math.min(a.bodyLength, b.bodyLength) / Math.max(a.bodyLength, b.bodyLength);\n if (sizeRatio < 0.5) continue;\n\n const sim = jaccard(a.ngrams, b.ngrams);\n\n // Skip exact duplicates (handled by duplicates scanner)\n if (sim >= 0.98) continue;\n\n if (sim >= 0.70) {\n const pairKey = [a.file, a.name, b.file, b.name].sort().join('+');\n if (reported.has(pairKey)) continue;\n reported.add(pairKey);\n\n const confidence: CleanupConfidence = sim >= 0.90 ? 'high' : sim >= 0.80 ? 'medium' : 'low';\n const simPct = Math.round(sim * 100);\n\n // Report for the first function\n findings.push({\n key: makeKey('near-duplicates', a.file, `${a.name}~${b.name}`),\n scope: 'near-duplicates',\n confidence,\n file: a.file,\n line: a.line,\n description: `\"${a.name}\" is ${simPct}% similar to \"${b.name}\" in ${b.file}:${b.line}`,\n recommendation: `Consider extracting shared logic into a common utility function`,\n deterministicEvidence: [`Jaccard 5-gram similarity: ${simPct}% between ${a.name} (${a.file}:${a.line}) and ${b.name} (${b.file}:${b.line})`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n groupKey: pairKey,\n });\n }\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Anti-Patterns (AI code smells) ──\n\nconst ANTI_PATTERNS: { regex: RegExp; name: string; description: string; recommendation: string; confidence: CleanupConfidence; skipTests: boolean }[] = [\n // Empty catch blocks\n { regex: /catch\\s*\\([^)]*\\)\\s*\\{\\s*\\}/g, name: 'empty-catch', description: 'Empty catch block swallows errors silently', recommendation: 'Log the error or re-throw; empty catches hide bugs', confidence: 'high', skipTests: false },\n { regex: /catch\\s*\\{\\s*\\}/g, name: 'empty-catch', description: 'Empty catch block (no parameter) swallows errors', recommendation: 'At minimum add a comment explaining why errors are ignored', confidence: 'high', skipTests: false },\n\n // console.log in production code\n { regex: /\\bconsole\\.log\\s*\\(/g, name: 'console-log', description: 'console.log left in production code', recommendation: 'Remove or replace with proper logger', confidence: 'medium', skipTests: true },\n\n // async function without await\n { regex: /async\\s+function\\s+(\\w+)\\s*\\([^)]*\\)\\s*(?::\\s*[^{]+)?\\{/g, name: 'async-no-await', description: 'async function may not need async keyword', recommendation: 'Remove async if function does not use await', confidence: 'low', skipTests: true },\n\n // Redundant return undefined\n { regex: /return\\s+undefined\\s*;/g, name: 'return-undefined', description: 'Redundant \"return undefined\" — functions return undefined by default', recommendation: 'Use bare \"return;\" or remove the return statement', confidence: 'medium', skipTests: false },\n\n // Nested ternaries (readability hazard)\n { regex: /\\?[^:?]*\\?/g, name: 'nested-ternary', description: 'Nested ternary operator — hard to read', recommendation: 'Refactor to if/else or extract to a helper function', confidence: 'low', skipTests: true },\n\n // Type assertion chains (TypeScript)\n { regex: /as\\s+\\w+(?:\\s*\\[\\s*\\])?\\s+as\\s+/g, name: 'double-assertion', description: 'Double type assertion (as X as Y) — type safety bypass', recommendation: 'Fix the underlying type instead of double-casting', confidence: 'high', skipTests: false },\n\n // any type usage\n { regex: /:\\s*any\\b/g, name: 'any-type', description: '\"any\" type defeats TypeScript type safety', recommendation: 'Use unknown, proper generics, or specific types', confidence: 'low', skipTests: true },\n\n // Promise constructor anti-pattern\n { regex: /new\\s+Promise\\s*\\(\\s*(?:async\\s+)?\\(\\s*resolve\\s*(?:,\\s*reject)?\\s*\\)\\s*=>\\s*\\{[^}]*await\\b/g, name: 'promise-constructor-async', description: 'Promise constructor with async executor — error handling is broken', recommendation: 'Remove Promise wrapper; async functions already return promises', confidence: 'high', skipTests: false },\n\n // setTimeout/setInterval with string argument\n { regex: /(?:setTimeout|setInterval)\\s*\\(\\s*['\"`]/g, name: 'implicit-eval', description: 'setTimeout/setInterval with string argument — implicit eval()', recommendation: 'Pass a function reference instead of a string', confidence: 'high', skipTests: false },\n];\n\nexport function scanAntiPatterns(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n\n for (const file of allFiles) {\n const relFile = normalizePath(relative(projectDir, file));\n const isTest = relFile.includes('test') || relFile.includes('spec') || relFile.includes('__test');\n const content = readFileSafe(file);\n const lines = content.split('\\n');\n\n for (const pattern of ANTI_PATTERNS) {\n if (pattern.skipTests && isTest) continue;\n\n pattern.regex.lastIndex = 0;\n\n // Special handling for async-no-await: need to check function body\n if (pattern.name === 'async-no-await') {\n let match = pattern.regex.exec(content);\n while (match) {\n const funcName = match[1];\n const startIdx = match.index + match[0].length;\n let depth = 1;\n let endIdx = startIdx;\n while (endIdx < content.length && depth > 0) {\n if (content[endIdx] === '{') depth++;\n else if (content[endIdx] === '}') depth--;\n endIdx++;\n }\n const body = content.slice(startIdx, endIdx - 1);\n if (!body.includes('await ') && !body.includes('await(') && !body.includes('for await')) {\n const lineNum = content.slice(0, match.index).split('\\n').length;\n findings.push({\n key: makeKey('anti-patterns', relFile, `${pattern.name}:${funcName}:L${lineNum}`),\n scope: 'anti-patterns',\n confidence: pattern.confidence,\n file: relFile,\n line: lineNum,\n description: `${pattern.description}: \"${funcName}\"`,\n recommendation: pattern.recommendation,\n deterministicEvidence: [`async function \"${funcName}\" at line ${lineNum} contains no await expressions`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n }\n match = pattern.regex.exec(content);\n }\n continue;\n }\n\n let match = pattern.regex.exec(content);\n while (match) {\n const lineNum = content.slice(0, match.index).split('\\n').length;\n const lineContent = lines[lineNum - 1]?.trim() || '';\n\n // Skip commented lines and regex/string literals (scanner definition patterns)\n if (lineContent.startsWith('//') || lineContent.startsWith('*') ||\n lineContent.startsWith('{ regex:') || lineContent.startsWith('regex:') ||\n /^\\s*\\//.test(lineContent)) {\n match = pattern.regex.exec(content);\n continue;\n }\n\n findings.push({\n key: makeKey('anti-patterns', relFile, `${pattern.name}:L${lineNum}`),\n scope: 'anti-patterns',\n confidence: pattern.confidence,\n file: relFile,\n line: lineNum,\n description: pattern.description,\n recommendation: pattern.recommendation,\n deterministicEvidence: [`Pattern matched at line ${lineNum}: ${lineContent.slice(0, 80)}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n\n match = pattern.regex.exec(content);\n }\n }\n }\n\n return findings;\n}\n\n// ── Run all scanners ──\n\nexport function runAllScanners(\n projectDir: string,\n scopes: CleanupScope[],\n ig?: Ignore,\n): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const ALL_SCOPES: CleanupScope[] = ['deps', 'unused-exports', 'hardcoded', 'duplicates', 'deadcode', 'security', 'near-duplicates', 'anti-patterns'];\n const activeScopes = new Set(scopes.includes('all' as CleanupScope) ? ALL_SCOPES : scopes);\n\n if (activeScopes.has('deps')) findings.push(...scanUnusedDeps(projectDir, ig));\n if (activeScopes.has('unused-exports')) findings.push(...scanUnusedExports(projectDir, ig));\n if (activeScopes.has('hardcoded')) findings.push(...scanHardcoded(projectDir, ig));\n if (activeScopes.has('duplicates')) findings.push(...scanDuplicates(projectDir, ig));\n if (activeScopes.has('deadcode')) findings.push(...scanDeadCode(projectDir, ig));\n if (activeScopes.has('security')) findings.push(...scanSecurity(projectDir, ig));\n if (activeScopes.has('near-duplicates')) findings.push(...scanNearDuplicates(projectDir, ig));\n if (activeScopes.has('anti-patterns')) findings.push(...scanAntiPatterns(projectDir, ig));\n\n // Sort by key for deterministic output\n findings.sort((a, b) => a.key.localeCompare(b.key));\n return findings;\n}\n","// packages/core/src/cleanup/merge.ts — 3-way merge logic for cleanup findings\n\nimport type { CleanupFinding, CleanupReport } from '../types/cleanup.js';\n\n/** Normalize keys: forward slashes, strip ./ prefix from each segment */\nfunction normalizeKey(key: string): string {\n return key\n .replaceAll('\\\\', '/')\n .split(':')\n .map(s => s.replace(/^\\.\\//, ''))\n .join(':');\n}\n\n/** Count unique keys in a findings array. */\nfunction uniqueKeyCount(findings: CleanupFinding[]): number {\n const seen = new Set<string>();\n for (const f of findings) seen.add(normalizeKey(f.key));\n return seen.size;\n}\n\n/**\n * Merge findings from up to 3 sources: deterministic, semantic (codex), and host (Claude).\n * Agreement rules:\n * - All 3 agree → confidence: high\n * - 2 of 3 agree → confidence: high (majority)\n * - Only 1 found → original confidence preserved, disputed: true\n */\nexport function mergeThreeWay(\n deterministic: CleanupFinding[],\n semantic: CleanupFinding[],\n host: CleanupFinding[],\n): CleanupFinding[] {\n const merged = new Map<string, CleanupFinding>();\n const sourceSet = new Map<string, Set<string>>();\n\n // Add all deterministic findings (merge duplicates within same source)\n for (const f of deterministic) {\n const nk = normalizeKey(f.key);\n const existing = merged.get(nk);\n if (existing) {\n existing.deterministicEvidence.push(...f.deterministicEvidence);\n } else {\n merged.set(nk, {\n ...f,\n key: nk,\n deterministicEvidence: [...f.deterministicEvidence],\n semanticEvidence: [],\n hostEvidence: [],\n sources: [],\n });\n sourceSet.set(nk, new Set());\n }\n (sourceSet.get(nk) as Set<string>).add('deterministic');\n }\n\n // Merge semantic findings\n for (const f of semantic) {\n const nk = normalizeKey(f.key);\n const existing = merged.get(nk);\n if (existing) {\n existing.semanticEvidence.push(...f.semanticEvidence);\n } else {\n merged.set(nk, {\n ...f,\n key: nk,\n deterministicEvidence: [],\n semanticEvidence: [...f.semanticEvidence],\n hostEvidence: [],\n sources: [],\n });\n sourceSet.set(nk, new Set());\n }\n (sourceSet.get(nk) as Set<string>).add('semantic');\n }\n\n // Merge host findings\n for (const f of host) {\n const nk = normalizeKey(f.key);\n const existing = merged.get(nk);\n if (existing) {\n existing.hostEvidence.push(...f.hostEvidence);\n } else {\n merged.set(nk, {\n ...f,\n key: nk,\n deterministicEvidence: [],\n semanticEvidence: [],\n hostEvidence: [...f.hostEvidence],\n sources: [],\n });\n sourceSet.set(nk, new Set());\n }\n (sourceSet.get(nk) as Set<string>).add('host');\n }\n\n // Apply confidence rules based on unique source count\n for (const [key, finding] of merged) {\n const sources = sourceSet.get(key) as Set<string>;\n finding.sources = Array.from(sources) as CleanupFinding['sources'];\n const count = sources.size;\n if (count >= 2) {\n finding.confidence = 'high';\n finding.disputed = false;\n } else {\n // Single source: keep original confidence, but mark as disputed\n finding.disputed = true;\n }\n }\n\n return Array.from(merged.values());\n}\n\n/**\n * Compute stats from merged findings with 3-source tracking.\n */\nexport function computeThreeWayStats(\n deterministic: CleanupFinding[],\n semantic: CleanupFinding[],\n host: CleanupFinding[],\n merged: CleanupFinding[],\n): CleanupReport['stats'] {\n return {\n deterministic: uniqueKeyCount(deterministic),\n semantic: uniqueKeyCount(semantic),\n host: uniqueKeyCount(host),\n agreed: merged.filter(f => f.sources.length >= 2).length,\n disputed: merged.filter(f => f.disputed).length,\n adjudicated: 0,\n highConfidence: merged.filter(f => f.confidence === 'high').length,\n mediumConfidence: merged.filter(f => f.confidence === 'medium').length,\n lowConfidence: merged.filter(f => f.confidence === 'low').length,\n };\n}\n\n/**\n * Legacy 2-way merge (deterministic + semantic only). Wraps mergeThreeWay with empty host.\n */\nexport function mergeTwoWay(\n deterministic: CleanupFinding[],\n semantic: CleanupFinding[],\n): CleanupFinding[] {\n return mergeThreeWay(deterministic, semantic, []);\n}\n\n/**\n * Legacy 2-way stats. Wraps computeThreeWayStats with empty host.\n */\nexport function computeTwoWayStats(\n deterministic: CleanupFinding[],\n semantic: CleanupFinding[],\n merged: CleanupFinding[],\n): CleanupReport['stats'] {\n return computeThreeWayStats(deterministic, semantic, [], merged);\n}\n\n/**\n * Recalculate stats after adjudication modifies findings in place.\n * Note: `stats.adjudicated` is managed by the caller (incremented per adjudication).\n */\nexport function recalculateConfidenceStats(\n findings: CleanupFinding[],\n stats: CleanupReport['stats'],\n): void {\n stats.highConfidence = findings.filter(f => f.confidence === 'high').length;\n stats.mediumConfidence = findings.filter(f => f.confidence === 'medium').length;\n stats.lowConfidence = findings.filter(f => f.confidence === 'low').length;\n stats.agreed = findings.filter(f => f.sources.length >= 2).length;\n stats.disputed = findings.filter(f => f.disputed).length;\n}\n","// packages/core/src/cleanup/host-schema.ts — Zod schema for host AI findings input\n\nimport { z } from 'zod';\n\nconst scopeSchema = z.enum(['deps', 'unused-exports', 'hardcoded', 'duplicates', 'deadcode']);\n\n/** Scope-specific symbol validation patterns */\nconst symbolPatterns: Record<string, RegExp> = {\n deps: /^[@a-z0-9][\\w./@-]*$/i,\n 'unused-exports': /^[$_a-z][\\w$]*$/i,\n hardcoded: /^(num:[^:]+:L\\d+|url:[^:]+:L\\d+|cred:L\\d+)$/,\n duplicates: /^[a-f0-9]{8}:[\\w$]+$/i,\n deadcode: /^[$_a-z][\\w$]*$/i,\n};\n\nconst hostFindingSchema = z.object({\n scope: scopeSchema,\n confidence: z.enum(['high', 'medium', 'low']),\n file: z.string().min(1),\n line: z.number().int().nonnegative().optional(),\n symbol: z.string().min(1),\n description: z.string().min(1),\n recommendation: z.string().min(1),\n}).refine(\n (data) => {\n const pattern = symbolPatterns[data.scope];\n return pattern ? pattern.test(data.symbol) : true;\n },\n (data) => ({\n message: `Symbol \"${data.symbol}\" does not match expected pattern for scope \"${data.scope}\"`,\n }),\n);\n\nexport const hostFindingsSchema = z.array(hostFindingSchema);\n\nexport type HostFindingInput = z.infer<typeof hostFindingSchema>;\n","// @codemoot/core - Multi-model AI orchestration engine\r\n// Sprint 1: Core engine + SQLite memory + model abstraction\r\n// Sprint 2: CLI-first hybrid + MCP types + security + cancellation\r\n\r\nexport const VERSION = '0.2.0';\r\n\r\n// Type definitions\r\nexport type {\r\n // Config\r\n ModelProvider,\r\n ModelConfig,\r\n RoleConfig,\r\n DebateConfig,\r\n DebatePattern,\r\n MemoryConfig,\r\n BudgetConfig,\r\n OutputConfig,\r\n ProjectConfig,\r\n ExecutionMode,\r\n PresetName,\r\n CliAdapterConfig,\r\n // Workflow\r\n WorkflowDefinition,\r\n StepDefinition,\r\n StepType,\r\n LoopConfig,\r\n ResolvedWorkflow,\r\n ResolvedStep,\r\n // Events\r\n SessionStartedEvent,\r\n SessionCompletedEvent,\r\n SessionFailedEvent,\r\n StepStartedEvent,\r\n StepCompletedEvent,\r\n StepFailedEvent,\r\n TextDeltaEvent,\r\n TextDoneEvent,\r\n LoopIterationEvent,\r\n CostUpdateEvent,\r\n TokenUsage,\r\n EngineEvent,\r\n // Session\r\n SessionStatus,\r\n Session,\r\n TranscriptEntry,\r\n // Memory\r\n MemoryCategory,\r\n MemoryRecord,\r\n ArtifactType,\r\n ArtifactRecord,\r\n CostLogEntry,\r\n // Models\r\n ChatMessage,\r\n CallModelOptions,\r\n ModelCallResult,\r\n FallbackConfig,\r\n // MCP types\r\n ResultStatus,\r\n MeteringSource,\r\n ReviewResult,\r\n DebateResponse,\r\n DebateResult,\r\n ReviewInput,\r\n PlanInput,\r\n DebateInput,\r\n MemoryInput,\r\n CostInput,\r\n // Roles\r\n BuiltInRole,\r\n Role,\r\n // Cleanup\r\n CleanupScope,\r\n CleanupConfidence,\r\n CleanupFinding,\r\n CleanupReport,\r\n CleanupSource,\r\n // Build\r\n BuildPhase,\r\n BuildRun,\r\n BuildSummary,\r\n // Debate engine\r\n DebateEngineState,\r\n // Jobs\r\n JobType,\r\n JobStatus,\r\n JobRecord,\r\n JobLogRecord,\r\n EnqueueOptions,\r\n} from './types/index.js';\r\n\r\nexport {\r\n ErrorCode,\r\n TerminalReason,\r\n DlpReasonCode,\r\n reviewInputSchema,\r\n planInputSchema,\r\n debateInputSchema,\r\n memoryInputSchema,\r\n costInputSchema,\r\n reviewOutputSchema,\r\n debateOutputSchema,\r\n} from './types/index.js';\r\n\r\n// Utilities\r\nexport {\r\n generateSessionId,\r\n generateId,\r\n ConfigError,\r\n ModelError,\r\n WorkflowError,\r\n DatabaseError,\r\n withRetry,\r\n createLogger,\r\n parseVerdict,\r\n sleep,\r\n} from './utils/index.js';\r\nexport type { RetryOptions, Logger, LogLevel, VerdictResult } from './utils/index.js';\r\nexport {\r\n DEFAULT_TIMEOUT_SEC,\r\n CLEANUP_TIMEOUT_SEC,\r\n DEFAULT_MAX_TOKENS,\r\n IMPLEMENTER_MAX_TOKENS,\r\n MCP_CONTENT_MAX_LENGTH,\r\n MCP_TASK_MAX_LENGTH,\r\n MCP_TIMEOUT_MAX,\r\n HTTP_TOO_MANY_REQUESTS,\r\n DAYS_PER_YEAR,\r\n REVIEW_DIFF_MAX_CHARS,\r\n REVIEW_TEXT_MAX_CHARS,\r\n BINARY_SNIFF_BYTES,\r\n CONTEXT_ACTIVE,\r\n CONTEXT_RETRIEVED,\r\n CONTEXT_BUFFER,\r\n DLP_MAX_CONTENT,\r\n DLP_MAX_PROCESSING_MS,\r\n} from './utils/constants.js';\r\n\r\n// Configuration\r\nexport {\r\n DEFAULT_CONFIG,\r\n projectConfigSchema,\r\n validateConfig,\r\n loadPreset,\r\n listPresets,\r\n loadConfig,\r\n writeConfig,\r\n migrateConfig,\r\n CURRENT_VERSION,\r\n getReviewPreset,\r\n listPresetNames,\r\n REVIEW_PRESETS,\r\n createIgnoreFilter,\r\n loadIgnorePatterns,\r\n shouldIgnore,\r\n} from './config/index.js';\r\nexport type { ProjectConfigInput, ReviewPreset } from './config/index.js';\r\n\r\n// Memory / Database\r\nexport {\r\n openDatabase,\r\n runMigrations,\r\n getSchemaVersion,\r\n SessionStore,\r\n MemoryStore,\r\n ArtifactStore,\r\n CostStore,\r\n DebateStore,\r\n BuildStore,\r\n MessageStore,\r\n parseDebateVerdict,\r\n buildReconstructionPrompt,\r\n estimateTokens,\r\n calculateDebateTokens,\r\n getTokenBudgetStatus,\r\n preflightTokenCheck,\r\n SessionManager,\r\n JobStore,\r\n CacheStore,\r\n hashContent,\r\n hashConfig,\r\n} from './memory/index.js';\r\nexport type { CostSummary, DebateTurnRow, DebateTurnStatus, DebateMessageRow, MessageStatus, ParsedVerdict, UnifiedSession, SessionEvent, SessionOverflowStatus, CacheEntry } from './memory/index.js';\r\n\r\n// Model Abstraction (CLI-only)\r\nexport {\r\n ModelRegistry,\r\n callModel,\r\n streamModel,\r\n withFallback,\r\n CostTracker,\r\n getModelPricing,\r\n calculateCost,\r\n CliAdapter,\r\n detectCli,\r\n clearDetectionCache,\r\n} from './models/index.js';\r\nexport type {\r\n TextDeltaEmitter,\r\n ModelPricing,\r\n ModelAdapter,\r\n CliCallOptions,\r\n CliDetectionResult,\r\n ProgressCallbacks,\r\n CliBridge,\r\n BridgeCapabilities,\r\n BridgeOptions,\r\n BridgeResumeOptions,\r\n} from './models/index.js';\r\n\r\n// Roles\r\nexport { RoleManager, renderPrompt } from './roles/index.js';\r\nexport type { PromptType, PromptVariables } from './roles/index.js';\r\n\r\n// Engine (Workflow + Execution)\r\nexport {\r\n EventBus,\r\n LoopController,\r\n Orchestrator,\r\n StepRunner,\r\n WorkflowEngine,\r\n CancellationToken,\r\n CancellationError,\r\n evaluatePolicy,\r\n DEFAULT_RULES,\r\n} from './engine/index.js';\r\nexport type {\r\n DebateOptions,\r\n LoopResult,\r\n OrchestratorOptions,\r\n PlanOptions,\r\n ReviewOptions,\r\n RunOptions,\r\n SessionResult,\r\n StepResult,\r\n PolicyRule,\r\n PolicyContext,\r\n PolicyResult,\r\n PolicyMode,\r\n PolicyDecision,\r\n} from './engine/index.js';\r\n\r\n// Context Builder\r\nexport { ContextBuilder, buildHandoffEnvelope } from './context/index.js';\r\nexport type {\r\n AssembledContext,\r\n ContextBudget,\r\n ContextBuilderOptions,\r\n HandoffCommand,\r\n HandoffEnvelopeOptions,\r\n} from './context/index.js';\r\n\r\n// Cleanup Scanners\r\nexport {\r\n scanUnusedDeps,\r\n scanUnusedExports,\r\n scanHardcoded,\r\n scanDuplicates,\r\n scanDeadCode,\r\n scanSecurity,\r\n scanNearDuplicates,\r\n scanAntiPatterns,\r\n runAllScanners,\r\n mergeThreeWay,\r\n mergeTwoWay,\r\n computeThreeWayStats,\r\n computeTwoWayStats,\r\n recalculateConfidenceStats,\r\n hostFindingsSchema,\r\n} from './cleanup/index.js';\r\nexport type { HostFindingInput } from './cleanup/index.js';\r\n\r\n// Security (DLP + Retry)\r\nexport {\r\n withCanonicalRetry,\r\n isRetryable,\r\n isRateLimit,\r\n sanitize,\r\n DEFAULT_DLP_CONFIG,\r\n} from './security/index.js';\r\nexport type {\r\n RetryConfig,\r\n AttemptResult,\r\n DlpMode,\r\n DlpResult,\r\n DlpRedaction,\r\n DlpAuditEntry,\r\n DlpConfig,\r\n} from './security/index.js';\r\n"],"mappings":"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","names":["ErrorCode","TerminalReason","DlpReasonCode","resolve","log","z","z","readFileSync","join","parseYaml","join","readFileSync","parseYaml","writeFileSync","stringifyYaml","stringifyYaml","writeFileSync","existsSync","readFileSync","join","estimateTokens","estimateTokens","join","join","resolve","isRetryable","dirname","fileURLToPath","EventEmitter","readFileSync","join","join","readFileSync","nanoid","DEFAULT_BUDGET","readFileSync","join","parseYaml","join","readFileSync","parseYaml","dirname","fileURLToPath","resolve","EventEmitter","resolve","readFileSync","readdirSync","statSync","existsSync","join","createHash","match","z"]}
1
+ {"version":3,"sources":["../src/types/mcp.ts","../src/utils/constants.ts","../src/utils/id.ts","../src/utils/errors.ts","../src/utils/sleep.ts","../src/utils/retry.ts","../src/utils/logger.ts","../src/utils/verdict.ts","../src/config/defaults.ts","../src/config/schema.ts","../src/config/presets.ts","../src/config/loader.ts","../src/config/migration.ts","../src/config/review-presets.ts","../src/config/ignore.ts","../src/memory/database.ts","../src/memory/session-store.ts","../src/memory/memory-store.ts","../src/memory/artifact-store.ts","../src/memory/cost-store.ts","../src/memory/debate-store.ts","../src/memory/build-store.ts","../src/security/dlp.ts","../src/memory/message-store.ts","../src/memory/reconstruction.ts","../src/memory/token-budget.ts","../src/memory/unified-session.ts","../src/memory/job-store.ts","../src/memory/cache-store.ts","../src/models/cli-adapter.ts","../src/models/cli-detector.ts","../src/models/registry.ts","../src/security/retry.ts","../src/models/caller.ts","../src/models/fallback.ts","../src/models/cost-tracker.ts","../src/models/pricing.ts","../src/roles/prompts.ts","../src/roles/role-manager.ts","../src/engine/event-bus.ts","../src/engine/loop-controller.ts","../src/engine/orchestrator.ts","../src/context/context-builder.ts","../src/engine/debate-engine.ts","../src/engine/step-runner.ts","../src/engine/workflow-engine.ts","../src/engine/cancellation.ts","../src/engine/policy.ts","../src/cleanup/scanners.ts","../src/cleanup/merge.ts","../src/cleanup/host-schema.ts","../src/index.ts"],"sourcesContent":["// packages/core/src/types/mcp.ts — MCP tool types from approved architecture\n\nimport { z } from 'zod';\nimport { DEFAULT_TIMEOUT_SEC, MCP_CONTENT_MAX_LENGTH, MCP_TASK_MAX_LENGTH, MCP_TIMEOUT_MAX } from '../utils/constants.js';\n\n// -- Error codes from MCP_ARCHITECTURE_APPROVED §12 --\nexport enum ErrorCode {\n INVALID_INPUT = 'INVALID_INPUT',\n MODEL_UNAVAILABLE = 'MODEL_UNAVAILABLE',\n RATE_LIMITED = 'RATE_LIMITED',\n TIMEOUT = 'TIMEOUT',\n DLP_BLOCKED = 'DLP_BLOCKED',\n EGRESS_BLOCKED = 'EGRESS_BLOCKED',\n BUDGET_EXCEEDED = 'BUDGET_EXCEEDED',\n CLI_NOT_FOUND = 'CLI_NOT_FOUND',\n CLI_AUTH_FAILED = 'CLI_AUTH_FAILED',\n CANCELLED = 'CANCELLED',\n INTERNAL_ERROR = 'INTERNAL_ERROR',\n}\n\nexport enum TerminalReason {\n COMPLETED = 'COMPLETED',\n TIMEOUT = 'TIMEOUT',\n CANCELLED = 'CANCELLED',\n BUDGET_EXCEEDED = 'BUDGET_EXCEEDED',\n MAX_RETRIES = 'MAX_RETRIES',\n}\n\nexport type ResultStatus = 'success' | 'partial' | 'error';\n\nexport enum DlpReasonCode {\n SECRET_DETECTED = 'SECRET_DETECTED',\n HIGH_ENTROPY = 'HIGH_ENTROPY',\n ABSOLUTE_PATH = 'ABSOLUTE_PATH',\n CONTEXT_TRUNCATED = 'CONTEXT_TRUNCATED',\n DECODE_BLOCKED = 'DECODE_BLOCKED',\n BUDGET_EXCEEDED = 'BUDGET_EXCEEDED',\n}\n\nexport type MeteringSource = 'billed' | 'estimated' | 'sdk';\n\n// -- Result interfaces --\nexport interface ReviewResult {\n status: ResultStatus;\n score: number;\n verdict: 'approved' | 'needs_revision';\n feedback: string[];\n tokenUsage: { inputTokens: number; outputTokens: number; totalTokens: number; costUsd: number };\n latencyMs: number;\n meteringSource: MeteringSource;\n model: string;\n egressControl: 'codemoot-enforced' | 'cli-managed';\n}\n\nexport interface DebateResponse {\n model: string;\n role: string;\n text: string;\n tokenUsage: { inputTokens: number; outputTokens: number; totalTokens: number; costUsd: number };\n latencyMs: number;\n meteringSource: MeteringSource;\n error?: string;\n}\n\nexport interface DebateResult {\n status: ResultStatus;\n responses: DebateResponse[];\n synthesis?: string;\n agreement?: number;\n totalTokenUsage: {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n costUsd: number;\n };\n partialFailure?: boolean;\n egressControl: 'codemoot-enforced' | 'cli-managed';\n}\n\n// -- Zod schemas for MCP tool inputs --\nexport const reviewInputSchema = z.object({\n content: z.string().min(1).max(MCP_CONTENT_MAX_LENGTH),\n criteria: z.array(z.string()).optional(),\n model: z.string().optional(),\n strict: z.boolean().optional().default(true),\n timeout: z.number().positive().max(MCP_TIMEOUT_MAX).optional().default(DEFAULT_TIMEOUT_SEC),\n});\nexport type ReviewInput = z.infer<typeof reviewInputSchema>;\n\nexport const planInputSchema = z.object({\n task: z.string().min(1).max(MCP_TASK_MAX_LENGTH),\n maxRounds: z.number().int().positive().max(10).optional().default(3),\n stream: z.boolean().optional().default(false),\n timeout: z.number().positive().max(MCP_TIMEOUT_MAX).optional().default(DEFAULT_TIMEOUT_SEC),\n});\nexport type PlanInput = z.infer<typeof planInputSchema>;\n\nexport const debateInputSchema = z.object({\n question: z.string().min(1).max(MCP_TASK_MAX_LENGTH),\n models: z.array(z.string()).min(1).max(5).optional(),\n synthesize: z.boolean().optional().default(false),\n maxRounds: z.number().int().min(1).max(10).optional().default(3),\n timeout: z.number().positive().max(MCP_TIMEOUT_MAX).optional().default(DEFAULT_TIMEOUT_SEC),\n});\nexport type DebateInput = z.infer<typeof debateInputSchema>;\n\nexport const memoryInputSchema = z.object({\n action: z.enum(['save', 'search', 'get', 'delete']),\n content: z.string().optional(),\n query: z.string().optional(),\n memoryId: z.number().int().positive().optional(),\n category: z.enum(['decision', 'convention', 'pattern', 'issue', 'preference']).optional(),\n importance: z.number().min(0).max(1).optional().default(0.5),\n timeout: z.number().positive().max(30).optional().default(5),\n});\nexport type MemoryInput = z.infer<typeof memoryInputSchema>;\n\nexport const costInputSchema = z.object({\n scope: z.enum(['session', 'daily', 'all']).optional().default('session'),\n sessionId: z.string().optional(),\n days: z.number().int().positive().max(365).optional().default(30),\n timeout: z.number().positive().max(30).optional().default(5),\n});\nexport type CostInput = z.infer<typeof costInputSchema>;\n\n// -- Zod schemas for MCP tool outputs --\nexport const reviewOutputSchema = z.object({\n status: z.enum(['success', 'partial', 'error']),\n score: z.number(),\n verdict: z.enum(['approved', 'needs_revision']),\n feedback: z.array(z.string()),\n tokenUsage: z.object({\n inputTokens: z.number(),\n outputTokens: z.number(),\n totalTokens: z.number(),\n costUsd: z.number(),\n }),\n latencyMs: z.number(),\n meteringSource: z.enum(['billed', 'estimated', 'sdk']),\n model: z.string(),\n egressControl: z.enum(['codemoot-enforced', 'cli-managed']),\n});\n\nexport const debateOutputSchema = z.object({\n status: z.enum(['success', 'partial', 'error']),\n responses: z.array(\n z.object({\n model: z.string(),\n role: z.string(),\n text: z.string(),\n tokenUsage: z.object({\n inputTokens: z.number(),\n outputTokens: z.number(),\n totalTokens: z.number(),\n costUsd: z.number(),\n }),\n latencyMs: z.number(),\n meteringSource: z.enum(['billed', 'estimated', 'sdk']),\n error: z.string().optional(),\n }),\n ),\n synthesis: z.string().optional(),\n agreement: z.number().optional(),\n totalTokenUsage: z.object({\n inputTokens: z.number(),\n outputTokens: z.number(),\n totalTokens: z.number(),\n costUsd: z.number(),\n }),\n partialFailure: z.boolean().optional(),\n egressControl: z.enum(['codemoot-enforced', 'cli-managed']),\n});\n","// packages/core/src/utils/constants.ts — Shared magic number constants\n\n/** Default timeout for model calls in seconds */\nexport const DEFAULT_TIMEOUT_SEC = 600;\n\n/** Default cleanup scan timeout in seconds */\nexport const CLEANUP_TIMEOUT_SEC = 1200;\n\n/** Default max tokens for model output */\nexport const DEFAULT_MAX_TOKENS = 4096;\n\n/** Implementer max tokens (larger for code generation) */\nexport const IMPLEMENTER_MAX_TOKENS = 8192;\n\n/** Max content length for MCP review input */\nexport const MCP_CONTENT_MAX_LENGTH = 100000;\n\n/** Max content length for MCP task/question input */\nexport const MCP_TASK_MAX_LENGTH = 50000;\n\n/** Max timeout for MCP tool calls in seconds */\nexport const MCP_TIMEOUT_MAX = 900;\n\n/** HTTP 429 Too Many Requests status code */\nexport const HTTP_TOO_MANY_REQUESTS = 429;\n\n/** Days in a year (for cost aggregation) */\nexport const DAYS_PER_YEAR = 365;\n\n/** Max diff size sent to reviewer */\nexport const REVIEW_DIFF_MAX_CHARS = 50000;\n\n/** Max review text stored in DB */\nexport const REVIEW_TEXT_MAX_CHARS = 5000;\n\n/** Binary detection buffer size */\nexport const BINARY_SNIFF_BYTES = 512;\n\n/** Context budget defaults */\nexport const CONTEXT_ACTIVE = 8000;\nexport const CONTEXT_RETRIEVED = 4000;\nexport const CONTEXT_BUFFER = 2000;\n\n/** DLP max content length */\nexport const DLP_MAX_CONTENT = 2000;\n\n/** DLP max processing time in milliseconds */\nexport const DLP_MAX_PROCESSING_MS = 2000;\n","// packages/core/src/utils/id.ts\n\nimport { nanoid } from 'nanoid';\n\n/** Generate a session ID with \"ses_\" prefix. */\nexport function generateSessionId(): string {\n return `ses_${nanoid(21)}`;\n}\n\n/** Generate a generic unique ID. */\nexport function generateId(prefix?: string): string {\n const id = nanoid(16);\n return prefix ? `${prefix}_${id}` : id;\n}\n","// packages/core/src/utils/errors.ts\n\nexport class ConfigError extends Error {\n constructor(\n message: string,\n public readonly field?: string,\n ) {\n super(message);\n this.name = 'ConfigError';\n }\n}\n\nexport class ModelError extends Error {\n constructor(\n message: string,\n public readonly provider?: string,\n public readonly model?: string,\n public readonly statusCode?: number,\n ) {\n super(message);\n this.name = 'ModelError';\n }\n\n get isRateLimit(): boolean {\n return this.statusCode === 429;\n }\n\n get isTimeout(): boolean {\n return this.message.includes('timeout') || this.message.includes('ETIMEDOUT');\n }\n\n get isServerError(): boolean {\n return this.statusCode !== undefined && this.statusCode >= 500;\n }\n}\n\nexport class WorkflowError extends Error {\n constructor(\n message: string,\n public readonly stepId?: string,\n ) {\n super(message);\n this.name = 'WorkflowError';\n }\n}\n\nexport class DatabaseError extends Error {\n constructor(\n message: string,\n public readonly operation?: string,\n ) {\n super(message);\n this.name = 'DatabaseError';\n }\n}\n","// packages/core/src/utils/sleep.ts — Shared async delay utility\n\n/** Promise-based delay. */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","// packages/core/src/utils/retry.ts\r\n\r\nimport { sleep } from './sleep.js';\r\n\r\nexport interface RetryOptions {\r\n attempts: number;\r\n backoff: number;\r\n retryOn?: (error: unknown) => boolean;\r\n}\r\n\r\nconst defaultOptions: RetryOptions = {\r\n attempts: 3,\r\n backoff: 1000,\r\n};\r\n\r\n/**\r\n * Retry an async function with exponential backoff.\r\n * Returns the result on success, throws the last error after all attempts exhausted.\r\n */\r\nexport async function withRetry<T>(\r\n fn: () => Promise<T>,\r\n options?: Partial<RetryOptions>,\r\n): Promise<T> {\r\n const opts = { ...defaultOptions, ...options };\r\n let lastError: unknown;\r\n\r\n for (let attempt = 1; attempt <= opts.attempts; attempt++) {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n lastError = error;\r\n\r\n if (opts.retryOn && !opts.retryOn(error)) {\r\n throw error;\r\n }\r\n\r\n if (attempt < opts.attempts) {\r\n const delay = opts.backoff * 2 ** (attempt - 1);\r\n await sleep(delay);\r\n }\r\n }\r\n }\r\n\r\n throw lastError;\r\n}\r\n\r\n","// packages/core/src/utils/logger.ts\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport interface Logger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nexport function createLogger(level: LogLevel = 'info'): Logger {\n const threshold = LOG_LEVELS[level];\n\n function log(msgLevel: LogLevel, message: string, args: unknown[]): void {\n if (LOG_LEVELS[msgLevel] >= threshold) {\n const timestamp = new Date().toISOString();\n const prefix = `[${timestamp}] ${msgLevel.toUpperCase()}:`;\n if (args.length > 0) {\n console[msgLevel === 'debug' ? 'log' : msgLevel](prefix, message, ...args);\n } else {\n console[msgLevel === 'debug' ? 'log' : msgLevel](prefix, message);\n }\n }\n }\n\n return {\n debug: (message, ...args) => log('debug', message, args),\n info: (message, ...args) => log('info', message, args),\n warn: (message, ...args) => log('warn', message, args),\n error: (message, ...args) => log('error', message, args),\n };\n}\n","// packages/core/src/utils/verdict.ts\n\nexport interface VerdictResult {\n verdict: 'approved' | 'needs_revision';\n feedback: string;\n}\n\nconst VERDICT_PATTERN = /VERDICT:\\s*(APPROVED|NEEDS_REVISION)/i;\n\n/**\n * Parse a reviewer response to extract the verdict.\n *\n * Looks for \"VERDICT: APPROVED\" or \"VERDICT: NEEDS_REVISION\" in the response.\n * If APPROVED, feedback is empty.\n * If NEEDS_REVISION, feedback is the text before the verdict line.\n * If no match, conservatively returns needs_revision with the full response as feedback.\n */\nexport function parseVerdict(response: string): VerdictResult {\n const match = VERDICT_PATTERN.exec(response);\n\n if (!match) {\n return { verdict: 'needs_revision', feedback: response.trim() };\n }\n\n const verdictStr = match[1].toUpperCase();\n\n if (verdictStr === 'APPROVED') {\n return { verdict: 'approved', feedback: '' };\n }\n\n // NEEDS_REVISION: feedback is everything before the VERDICT line\n const verdictIndex = match.index;\n const feedback = response.slice(0, verdictIndex).trim();\n return { verdict: 'needs_revision', feedback };\n}\n","// packages/core/src/config/defaults.ts\r\n\r\nimport type { ProjectConfig } from '../types/config.js';\r\nimport { CONTEXT_ACTIVE, CONTEXT_BUFFER, CONTEXT_RETRIEVED, DEFAULT_MAX_TOKENS, DEFAULT_TIMEOUT_SEC, IMPLEMENTER_MAX_TOKENS } from '../utils/constants.js';\r\n\r\nexport const DEFAULT_CONFIG: ProjectConfig = {\r\n project: {\r\n name: '',\r\n description: '',\r\n },\r\n models: {\r\n 'codex-architect': {\r\n provider: 'openai',\r\n model: 'gpt-5.3-codex',\r\n maxTokens: DEFAULT_MAX_TOKENS,\r\n temperature: 0.7,\r\n timeout: DEFAULT_TIMEOUT_SEC,\r\n },\r\n 'codex-reviewer': {\r\n provider: 'openai',\r\n model: 'gpt-5.3-codex',\r\n maxTokens: DEFAULT_MAX_TOKENS,\r\n temperature: 0.3,\r\n timeout: DEFAULT_TIMEOUT_SEC,\r\n },\r\n },\r\n roles: {\r\n architect: {\r\n model: 'codex-architect',\r\n temperature: 0.7,\r\n maxTokens: DEFAULT_MAX_TOKENS,\r\n },\r\n reviewer: {\r\n model: 'codex-reviewer',\r\n temperature: 0.3,\r\n maxTokens: DEFAULT_MAX_TOKENS,\r\n },\r\n implementer: {\r\n model: 'codex-architect',\r\n temperature: 0.4,\r\n maxTokens: IMPLEMENTER_MAX_TOKENS,\r\n },\r\n },\r\n workflow: 'plan-review-implement',\r\n mode: 'autonomous',\r\n debate: {\r\n defaultPattern: 'proposal-critique',\r\n maxRounds: 3,\r\n consensusThreshold: 0.7,\r\n },\r\n memory: {\r\n autoExtractFacts: true,\r\n contextBudget: {\r\n activeContext: CONTEXT_ACTIVE,\r\n retrievedMemory: CONTEXT_RETRIEVED,\r\n messageBuffer: CONTEXT_BUFFER,\r\n },\r\n },\r\n budget: {\r\n perSession: 5.0,\r\n perDay: 25.0,\r\n perMonth: 200.0,\r\n warningAt: 0.8,\r\n action: 'warn',\r\n },\r\n output: {\r\n saveTranscripts: true,\r\n transcriptFormat: 'markdown',\r\n transcriptDir: '.cowork/transcripts',\r\n },\r\n advanced: {\r\n retryAttempts: 3,\r\n stream: true,\r\n logLevel: 'info',\r\n },\r\n};\r\n","// packages/core/src/config/schema.ts\n\nimport { z } from 'zod';\nimport { CONTEXT_ACTIVE, CONTEXT_BUFFER, CONTEXT_RETRIEVED, DEFAULT_MAX_TOKENS, DEFAULT_TIMEOUT_SEC } from '../utils/constants.js';\nimport { ConfigError } from '../utils/errors.js';\n\nconst modelProviderSchema = z.literal('openai');\n\nconst cliAdapterConfigSchema = z.object({\n command: z.string().min(1),\n args: z.array(z.string()),\n timeout: z.number().positive(),\n outputFile: z.string().optional(),\n maxOutputBytes: z.number().int().positive().optional(),\n envAllowlist: z.array(z.string()).optional(),\n});\n\nconst modelConfigSchema = z.object({\n provider: modelProviderSchema,\n model: z.string().min(1),\n maxTokens: z.number().int().positive().default(DEFAULT_MAX_TOKENS),\n temperature: z.number().min(0).max(2).default(0.7),\n timeout: z.number().positive().default(DEFAULT_TIMEOUT_SEC),\n cliAdapter: cliAdapterConfigSchema.optional(),\n});\n\nconst roleConfigSchema = z.object({\n model: z.string().min(1),\n temperature: z.number().min(0).max(2).optional(),\n maxTokens: z.number().int().positive().optional(),\n systemPromptFile: z.string().optional(),\n});\n\nconst debatePatternSchema = z.enum([\n 'structured-rounds',\n 'proposal-critique',\n 'free-flowing',\n 'parallel-panel',\n]);\n\nconst debateConfigSchema = z.object({\n defaultPattern: debatePatternSchema.default('proposal-critique'),\n maxRounds: z.number().int().positive().max(10).default(3),\n consensusThreshold: z.number().min(0).max(1).default(0.7),\n});\n\nconst memoryConfigSchema = z.object({\n embeddingModel: z.string().optional(),\n autoExtractFacts: z.boolean().default(true),\n contextBudget: z\n .object({\n activeContext: z.number().int().positive().default(CONTEXT_ACTIVE),\n retrievedMemory: z.number().int().positive().default(CONTEXT_RETRIEVED),\n messageBuffer: z.number().int().positive().default(CONTEXT_BUFFER),\n })\n .default({}),\n});\n\nconst budgetConfigSchema = z.object({\n perSession: z.number().nonnegative().default(5.0),\n perDay: z.number().nonnegative().default(25.0),\n perMonth: z.number().nonnegative().default(200.0),\n warningAt: z.number().min(0).max(1).default(0.8),\n action: z.enum(['warn', 'pause', 'block']).default('warn'),\n});\n\nconst outputConfigSchema = z.object({\n saveTranscripts: z.boolean().default(true),\n transcriptFormat: z.enum(['markdown', 'json']).default('markdown'),\n transcriptDir: z.string().default('.cowork/transcripts'),\n});\n\nconst executionModeSchema = z.enum(['autonomous', 'interactive', 'dashboard']);\n\nconst advancedConfigSchema = z.object({\n retryAttempts: z.number().int().positive().max(10).default(3),\n stream: z.boolean().default(true),\n logLevel: z.enum(['debug', 'info', 'warn', 'error']).default('info'),\n});\n\nexport const projectConfigSchema = z\n .object({\n configVersion: z.number().int().positive().optional(),\n project: z\n .object({\n name: z.string().default(''),\n description: z.string().default(''),\n })\n .default({}),\n models: z.record(z.string(), modelConfigSchema),\n roles: z.record(z.string(), roleConfigSchema),\n workflow: z.string().default('plan-review-implement'),\n mode: executionModeSchema.default('autonomous'),\n debate: debateConfigSchema.default({}),\n memory: memoryConfigSchema.default({}),\n budget: budgetConfigSchema.default({}),\n output: outputConfigSchema.default({}),\n advanced: advancedConfigSchema.default({}),\n })\n .superRefine((data, ctx) => {\n const modelAliases = Object.keys(data.models);\n for (const [roleName, roleConfig] of Object.entries(data.roles)) {\n if (!modelAliases.includes(roleConfig.model)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['roles', roleName, 'model'],\n message: `Role \"${roleName}\" references model \"${roleConfig.model}\" which is not defined in models. Available: ${modelAliases.join(', ')}`,\n });\n }\n }\n });\n\nexport type ProjectConfigInput = z.input<typeof projectConfigSchema>;\n\n/**\n * Validate and parse a config object. Throws ConfigError on invalid input.\n */\nexport function validateConfig(config: unknown): z.output<typeof projectConfigSchema> {\n const result = projectConfigSchema.safeParse(config);\n if (!result.success) {\n const issues = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');\n throw new ConfigError(`Invalid configuration: ${issues}`);\n }\n return result.data;\n}\n","// packages/core/src/config/presets.ts\n\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { parse as parseYaml } from 'yaml';\nimport type { PresetName } from '../types/config.js';\nimport { ConfigError } from '../utils/errors.js';\n\nconst PRESETS_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..', 'presets');\n\nconst VALID_PRESETS: PresetName[] = ['cli-first'];\n\n/**\n * Load a built-in preset by name. Returns a partial config to be merged with defaults.\n */\nexport function loadPreset(name: PresetName): Record<string, unknown> {\n if (!VALID_PRESETS.includes(name)) {\n // Gracefully fall back to cli-first for legacy preset names (balanced, budget)\n console.error(`Warning: Unknown preset \"${name}\", falling back to \"cli-first\".`);\n name = 'cli-first';\n }\n\n const filePath = join(PRESETS_DIR, `${name}.yml`);\n try {\n const content = readFileSync(filePath, 'utf-8');\n return parseYaml(content) as Record<string, unknown>;\n } catch (err) {\n throw new ConfigError(\n `Failed to load preset \"${name}\": ${err instanceof Error ? err.message : String(err)}`,\n 'preset',\n );\n }\n}\n\n/** List available preset names. */\nexport function listPresets(): PresetName[] {\n return [...VALID_PRESETS];\n}\n","// packages/core/src/config/loader.ts\n\nimport { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml';\nimport type { PresetName, ProjectConfig } from '../types/config.js';\nimport { ConfigError } from '../utils/errors.js';\nimport { DEFAULT_CONFIG } from './defaults.js';\nimport { loadPreset } from './presets.js';\nimport { validateConfig } from './schema.js';\n\nconst CONFIG_FILENAME = '.cowork.yml';\n\n/**\n * Deep merge two objects. Source values overwrite target values.\n * Arrays are replaced, not merged.\n */\nfunction deepMerge<T extends Record<string, unknown>>(\n target: T,\n source: Record<string, unknown>,\n): T {\n const result = { ...target } as Record<string, unknown>;\n for (const key of Object.keys(source)) {\n const srcVal = source[key];\n const tgtVal = result[key];\n if (\n srcVal !== null &&\n typeof srcVal === 'object' &&\n !Array.isArray(srcVal) &&\n tgtVal !== null &&\n typeof tgtVal === 'object' &&\n !Array.isArray(tgtVal)\n ) {\n result[key] = deepMerge(tgtVal as Record<string, unknown>, srcVal as Record<string, unknown>);\n } else {\n result[key] = srcVal;\n }\n }\n return result as T;\n}\n\n/**\n * Load config with precedence: overrides > .cowork.yml > preset > defaults.\n *\n * 1. Start with hardcoded defaults\n * 2. If a preset name is found (in file or overrides), merge preset on top\n * 3. Merge .cowork.yml from projectDir on top\n * 4. Merge programmatic overrides on top\n * 5. Validate the final result\n */\nexport function loadConfig(options?: {\n projectDir?: string;\n preset?: PresetName;\n overrides?: Partial<ProjectConfig>;\n skipFile?: boolean;\n}): ProjectConfig {\n const projectDir = options?.projectDir ?? process.cwd();\n let merged: Record<string, unknown> = structuredClone(DEFAULT_CONFIG) as unknown as Record<\n string,\n unknown\n >;\n\n // Layer 2: Preset\n if (options?.preset) {\n const presetConfig = loadPreset(options.preset);\n merged = deepMerge(merged, presetConfig);\n }\n\n // Layer 3: Project file (.cowork.yml)\n const configPath = join(projectDir, CONFIG_FILENAME);\n if (!options?.skipFile && existsSync(configPath)) {\n try {\n const content = readFileSync(configPath, 'utf-8');\n const fileConfig = parseYaml(content) as Record<string, unknown>;\n if (fileConfig && typeof fileConfig === 'object') {\n merged = deepMerge(merged, fileConfig);\n }\n } catch (err) {\n throw new ConfigError(\n `Failed to parse ${CONFIG_FILENAME}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n // Layer 4: Programmatic overrides\n if (options?.overrides) {\n merged = deepMerge(merged, options.overrides as Record<string, unknown>);\n }\n\n return validateConfig(merged);\n}\n\n/**\n * Write a ProjectConfig to .cowork.yml in the given directory.\n * Also creates .cowork/db/ and .cowork/transcripts/ directories.\n */\nexport function writeConfig(config: ProjectConfig, dir: string): void {\n const configPath = join(dir, CONFIG_FILENAME);\n const yamlContent = stringifyYaml(config, { lineWidth: 100 });\n writeFileSync(configPath, yamlContent, 'utf-8');\n\n // Create project directories\n mkdirSync(join(dir, '.cowork', 'db'), { recursive: true });\n mkdirSync(join(dir, '.cowork', 'transcripts'), { recursive: true });\n\n // Append to .gitignore if not already there\n const gitignorePath = join(dir, '.gitignore');\n if (existsSync(gitignorePath)) {\n const content = readFileSync(gitignorePath, 'utf-8');\n if (!content.includes('.cowork/')) {\n appendFileSync(gitignorePath, '\\n.cowork/\\n');\n }\n } else {\n writeFileSync(gitignorePath, '.cowork/\\n', 'utf-8');\n }\n}\n\nexport { deepMerge };\n","// packages/core/src/config/migration.ts\n\nimport { copyFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { stringify as stringifyYaml } from 'yaml';\nimport type { ProjectConfig } from '../types/config.js';\nimport { ConfigError } from '../utils/errors.js';\nimport { createLogger } from '../utils/logger.js';\n\nconst log = createLogger('info');\nconst CURRENT_VERSION = 2;\n\n/**\n * Migrate a ProjectConfig from an older schema version to the current version.\n * Creates a .bak backup before writing changes if configPath is provided.\n * Returns the migrated config (always in-memory; optionally persisted to disk).\n */\nexport function migrateConfig(config: ProjectConfig, configPath?: string): ProjectConfig {\n const fromVersion = config.configVersion ?? 1;\n\n if (fromVersion > CURRENT_VERSION) {\n throw new ConfigError(\n `Config version ${fromVersion} requires a newer version of CodeMoot. Please upgrade.`,\n 'configVersion',\n );\n }\n\n if (fromVersion >= CURRENT_VERSION) return config;\n\n // Pre-migration backup\n if (configPath) {\n const backupPath = `${configPath}.bak`;\n try {\n copyFileSync(configPath, backupPath);\n log.info(`Config backup created at ${backupPath}`);\n } catch {\n log.warn('Failed to create config backup');\n }\n }\n\n let migrated = { ...config };\n\n if (fromVersion < 2) {\n migrated = migrateV1ToV2(migrated);\n }\n\n // Write back (atomic: write to temp then rename)\n if (configPath) {\n const tmpPath = `${configPath}.tmp`;\n try {\n const content = stringifyYaml(migrated, { lineWidth: 100 });\n writeFileSync(tmpPath, content, 'utf-8');\n renameSync(tmpPath, configPath);\n log.info(`Config migrated from v${fromVersion} to v${CURRENT_VERSION}`);\n } catch (err) {\n log.warn(\n `Failed to write migrated config: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n return migrated;\n}\n\nfunction migrateV1ToV2(config: ProjectConfig): ProjectConfig {\n return { ...config, configVersion: 2 };\n}\n\nexport { CURRENT_VERSION };\n","// packages/core/src/config/review-presets.ts — Named review preset configurations\n\nimport { CLEANUP_TIMEOUT_SEC, MCP_TIMEOUT_MAX } from '../utils/constants.js';\n\nexport interface ReviewPreset {\n name: string;\n focus: string;\n constraints: string[];\n timeoutSec: number;\n severityFloor: 'info' | 'warning' | 'critical';\n strictOutput: boolean;\n}\n\nexport const REVIEW_PRESETS: Record<string, ReviewPreset> = {\n 'security-audit': {\n name: 'security-audit',\n focus: 'security',\n constraints: [\n 'Prioritize exploitable paths and data flow.',\n 'Map source-to-sink paths for injection, SSRF, deserialization.',\n 'Flag missing rate limiting and audit logging.',\n 'Check for secrets, hardcoded credentials, and unsafe dependencies.',\n ],\n timeoutSec: CLEANUP_TIMEOUT_SEC,\n severityFloor: 'info',\n strictOutput: true,\n },\n performance: {\n name: 'performance',\n focus: 'performance',\n constraints: [\n 'Prefer measurable bottlenecks over speculative issues.',\n 'Flag N+1 queries, unnecessary IO, memory churn, sync blocking.',\n 'Suggest profiling points where relevant.',\n ],\n timeoutSec: MCP_TIMEOUT_MAX,\n severityFloor: 'warning',\n strictOutput: false,\n },\n 'quick-scan': {\n name: 'quick-scan',\n focus: 'bugs',\n constraints: [\n 'Return only top issues by impact.',\n 'Skip speculative findings.',\n 'Be concise — under 500 words.',\n ],\n timeoutSec: 240,\n severityFloor: 'warning',\n strictOutput: false,\n },\n 'pre-commit': {\n name: 'pre-commit',\n focus: 'bugs',\n constraints: [\n 'Only report CRITICAL and WARNING severity.',\n 'Minimize false positives — err on the side of silence.',\n 'Focus on changed code only.',\n ],\n timeoutSec: 180,\n severityFloor: 'warning',\n strictOutput: true,\n },\n 'api-review': {\n name: 'api-review',\n focus: 'all',\n constraints: [\n 'Check backward compatibility and schema drift.',\n 'Validate status codes, error shapes, and pagination.',\n 'Review auth boundaries and idempotency.',\n ],\n timeoutSec: MCP_TIMEOUT_MAX,\n severityFloor: 'info',\n strictOutput: false,\n },\n};\n\nexport function getReviewPreset(name: string): ReviewPreset | undefined {\n return REVIEW_PRESETS[name];\n}\n\nexport function listPresetNames(): string[] {\n return Object.keys(REVIEW_PRESETS);\n}\n","// packages/core/src/config/ignore.ts — .gitignore + .codemootignore aware file filtering\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport ignore, { type Ignore } from 'ignore';\n\nconst BUILTIN_IGNORES = [\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n 'target',\n 'release',\n 'out',\n '.cowork',\n '.cache',\n '.turbo',\n '.next',\n '__pycache__',\n 'vendor',\n 'coverage',\n '*.db',\n '*.db-journal',\n '*.db-wal',\n '*.db-shm',\n '.env',\n '.env.*',\n];\n\n/**\n * Load and compile all ignore patterns into a single matcher.\n * Precedence: builtins -> .gitignore -> .codemootignore\n */\nexport function createIgnoreFilter(projectDir: string, options?: { skipGitignore?: boolean }): Ignore {\n const ig = ignore();\n\n // 1. Builtins\n ig.add(BUILTIN_IGNORES);\n\n // 2. .gitignore (root only for now)\n if (!options?.skipGitignore) {\n const gitignorePath = join(projectDir, '.gitignore');\n if (existsSync(gitignorePath)) {\n const content = readFileSync(gitignorePath, 'utf-8');\n ig.add(content);\n }\n }\n\n // 3. .codemootignore (highest priority — can override builtins/.gitignore)\n const codemootIgnorePath = join(projectDir, '.codemootignore');\n if (existsSync(codemootIgnorePath)) {\n const content = readFileSync(codemootIgnorePath, 'utf-8');\n ig.add(content);\n }\n\n return ig;\n}\n\n// ── Legacy API (kept for existing tests) ──\n\nexport function loadIgnorePatterns(projectDir: string): string[] {\n const patterns = [...BUILTIN_IGNORES];\n const ignorePath = join(projectDir, '.codemootignore');\n if (existsSync(ignorePath)) {\n const content = readFileSync(ignorePath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith('#')) {\n patterns.push(trimmed);\n }\n }\n }\n return patterns;\n}\n\nexport function shouldIgnore(filePath: string, patterns: string[]): boolean {\n const normalized = filePath.replace(/\\\\/g, '/');\n for (const pattern of patterns) {\n if (pattern.startsWith('!')) continue;\n if (\n normalized.includes(`/${pattern}/`) ||\n normalized.endsWith(`/${pattern}`) ||\n normalized === pattern\n ) {\n return true;\n }\n if (pattern.startsWith('*.') && normalized.endsWith(pattern.slice(1))) {\n return true;\n }\n }\n return false;\n}\n","// packages/core/src/memory/database.ts\n\nimport Database from 'better-sqlite3';\nimport { DatabaseError } from '../utils/errors.js';\n\nconst SCHEMA_VERSION = '8';\n\nconst MIGRATIONS = [\n // Sessions\n `CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n project_id TEXT NOT NULL,\n task TEXT NOT NULL,\n workflow_id TEXT NOT NULL,\n mode TEXT NOT NULL DEFAULT 'autonomous',\n status TEXT NOT NULL DEFAULT 'running',\n config_snapshot TEXT,\n current_step TEXT,\n summary TEXT,\n total_tokens INTEGER DEFAULT 0,\n total_cost REAL DEFAULT 0,\n started_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n completed_at DATETIME,\n metadata JSON\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_id)',\n 'CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status)',\n 'CREATE INDEX IF NOT EXISTS idx_sessions_started ON sessions(started_at DESC)',\n\n // Messages (transcript entries)\n `CREATE TABLE IF NOT EXISTS messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n step_id TEXT,\n iteration INTEGER,\n role TEXT NOT NULL,\n model_id TEXT,\n content TEXT NOT NULL,\n token_count INTEGER,\n cost REAL,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n metadata JSON\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id)',\n 'CREATE INDEX IF NOT EXISTS idx_messages_step ON messages(session_id, step_id)',\n 'CREATE INDEX IF NOT EXISTS idx_messages_role ON messages(session_id, role)',\n\n // Artifacts\n `CREATE TABLE IF NOT EXISTS artifacts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n step_id TEXT NOT NULL,\n iteration INTEGER NOT NULL DEFAULT 1,\n type TEXT NOT NULL,\n file_path TEXT,\n content TEXT NOT NULL,\n version INTEGER DEFAULT 1,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n metadata JSON\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_artifacts_session ON artifacts(session_id)',\n 'CREATE INDEX IF NOT EXISTS idx_artifacts_step ON artifacts(session_id, step_id)',\n\n // Decisions\n `CREATE TABLE IF NOT EXISTS decisions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n step_id TEXT NOT NULL,\n decision_type TEXT NOT NULL,\n reason TEXT,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_decisions_session ON decisions(session_id)',\n\n // Memories\n `CREATE TABLE IF NOT EXISTS memories (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n project_id TEXT NOT NULL,\n category TEXT NOT NULL,\n content TEXT NOT NULL,\n source_session_id TEXT REFERENCES sessions(id) ON DELETE SET NULL,\n importance REAL DEFAULT 0.5,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n accessed_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n access_count INTEGER DEFAULT 0\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_memories_project ON memories(project_id)',\n 'CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(project_id, category)',\n 'CREATE INDEX IF NOT EXISTS idx_memories_importance ON memories(importance DESC)',\n\n // Memories FTS5\n `CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(\n content,\n category,\n content='memories',\n content_rowid='id'\n )`,\n\n // FTS sync triggers\n `CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN\n INSERT INTO memories_fts(rowid, content, category)\n VALUES (new.id, new.content, new.category);\n END`,\n `CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, content, category)\n VALUES ('delete', old.id, old.content, old.category);\n END`,\n `CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, content, category)\n VALUES ('delete', old.id, old.content, old.category);\n INSERT INTO memories_fts(rowid, content, category)\n VALUES (new.id, new.content, new.category);\n END`,\n\n // Cost log\n `CREATE TABLE IF NOT EXISTS cost_log (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT REFERENCES sessions(id) ON DELETE SET NULL,\n step_id TEXT,\n model_id TEXT NOT NULL,\n input_tokens INTEGER NOT NULL DEFAULT 0,\n output_tokens INTEGER NOT NULL DEFAULT 0,\n cost_usd REAL NOT NULL DEFAULT 0,\n latency_ms INTEGER,\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_cost_session ON cost_log(session_id)',\n 'CREATE INDEX IF NOT EXISTS idx_cost_model ON cost_log(model_id)',\n 'CREATE INDEX IF NOT EXISTS idx_cost_date ON cost_log(created_at)',\n\n // Debate turns (session resume persistence)\n `CREATE TABLE IF NOT EXISTS debate_turns (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n debate_id TEXT NOT NULL,\n role TEXT NOT NULL,\n codex_session_id TEXT,\n round INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL DEFAULT 'active',\n resume_fail_count INTEGER DEFAULT 0,\n last_activity_at INTEGER NOT NULL,\n created_at INTEGER NOT NULL,\n state_json TEXT\n )`,\n 'CREATE UNIQUE INDEX IF NOT EXISTS idx_debate_turns_unique ON debate_turns(debate_id, role)',\n 'CREATE INDEX IF NOT EXISTS idx_debate_turns_status ON debate_turns(status)',\n 'CREATE INDEX IF NOT EXISTS idx_debate_turns_activity ON debate_turns(last_activity_at)',\n\n // Build runs (automated build loop sessions)\n `CREATE TABLE IF NOT EXISTS build_runs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n build_id TEXT NOT NULL UNIQUE,\n task TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'planning',\n current_phase TEXT NOT NULL DEFAULT 'debate',\n current_loop INTEGER NOT NULL DEFAULT 0,\n last_event_seq INTEGER NOT NULL DEFAULT 0,\n phase_cursor TEXT NOT NULL DEFAULT '{}',\n debate_id TEXT,\n baseline_ref TEXT,\n plan_codex_session TEXT,\n review_codex_session TEXT,\n plan_version INTEGER DEFAULT 0,\n review_cycles INTEGER DEFAULT 0,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n completed_at INTEGER,\n metadata TEXT\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_build_runs_status ON build_runs(status)',\n 'CREATE INDEX IF NOT EXISTS idx_build_runs_updated ON build_runs(updated_at DESC)',\n\n // Build events (append-only log)\n `CREATE TABLE IF NOT EXISTS build_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n build_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n event_type TEXT NOT NULL,\n actor TEXT NOT NULL,\n phase TEXT NOT NULL,\n loop_index INTEGER DEFAULT 0,\n payload TEXT,\n codex_thread_id TEXT,\n tokens_used INTEGER DEFAULT 0,\n created_at INTEGER NOT NULL\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_build_events_build ON build_events(build_id, seq)',\n 'CREATE INDEX IF NOT EXISTS idx_build_events_type ON build_events(build_id, event_type)',\n\n // Debate messages (full conversation persistence)\n `CREATE TABLE IF NOT EXISTS debate_messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n debate_id TEXT NOT NULL,\n round INTEGER NOT NULL CHECK(round >= 0),\n role TEXT NOT NULL,\n bridge TEXT NOT NULL DEFAULT 'codex',\n model TEXT NOT NULL,\n prompt_text TEXT NOT NULL,\n response_text TEXT,\n stance TEXT CHECK(stance IN ('SUPPORT','OPPOSE','UNCERTAIN') OR stance IS NULL),\n confidence REAL CHECK(confidence IS NULL OR (confidence >= 0 AND confidence <= 1)),\n verdict_raw TEXT,\n usage_json TEXT,\n duration_ms INTEGER CHECK(duration_ms IS NULL OR duration_ms >= 0),\n session_id TEXT,\n status TEXT NOT NULL DEFAULT 'queued' CHECK(status IN ('queued','running','completed','failed')),\n error TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n completed_at INTEGER\n )`,\n 'CREATE UNIQUE INDEX IF NOT EXISTS idx_dm_unique ON debate_messages(debate_id, round, role)',\n 'CREATE INDEX IF NOT EXISTS idx_dm_debate ON debate_messages(debate_id)',\n 'CREATE INDEX IF NOT EXISTS idx_dm_status ON debate_messages(status)',\n\n // Unified sessions (one codex thread per session)\n `CREATE TABLE IF NOT EXISTS codemoot_sessions (\n id TEXT PRIMARY KEY,\n name TEXT,\n codex_thread_id TEXT,\n status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active','completed','stale')),\n token_usage INTEGER DEFAULT 0,\n max_context INTEGER DEFAULT 400000,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n completed_at INTEGER\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_csess_status ON codemoot_sessions(status)',\n 'CREATE INDEX IF NOT EXISTS idx_csess_updated ON codemoot_sessions(updated_at DESC)',\n\n // Session events (append-only audit trail of every GPT interaction)\n `CREATE TABLE IF NOT EXISTS session_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL REFERENCES codemoot_sessions(id),\n command TEXT NOT NULL,\n subcommand TEXT,\n prompt_preview TEXT,\n response_preview TEXT,\n usage_json TEXT,\n duration_ms INTEGER,\n codex_thread_id TEXT,\n created_at INTEGER NOT NULL\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_sevt_session ON session_events(session_id)',\n 'CREATE INDEX IF NOT EXISTS idx_sevt_command ON session_events(session_id, command)',\n\n // Add session_id to debate_messages (nullable for backward compat)\n // Note: SQLite doesn't support ADD COLUMN IF NOT EXISTS, so we use a pragma check approach\n // For new DBs this column is in the CREATE TABLE; for upgrades we add it via ALTER TABLE below\n\n // Jobs queue (background async work)\n `CREATE TABLE IF NOT EXISTS jobs (\n id TEXT PRIMARY KEY,\n type TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'queued',\n priority INTEGER NOT NULL DEFAULT 100,\n dedupe_key TEXT,\n payload_json TEXT NOT NULL,\n result_json TEXT,\n error_text TEXT,\n retry_count INTEGER NOT NULL DEFAULT 0,\n max_retries INTEGER NOT NULL DEFAULT 1,\n session_id TEXT,\n worker_id TEXT,\n started_at INTEGER,\n finished_at INTEGER,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_jobs_status_priority ON jobs(status, priority, created_at)',\n 'CREATE INDEX IF NOT EXISTS idx_jobs_type_status ON jobs(type, status)',\n 'CREATE INDEX IF NOT EXISTS idx_jobs_session ON jobs(session_id)',\n\n // Job logs (append-only log per job)\n `CREATE TABLE IF NOT EXISTS job_logs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n job_id TEXT NOT NULL,\n seq INTEGER NOT NULL,\n level TEXT NOT NULL DEFAULT 'info',\n event_type TEXT NOT NULL,\n message TEXT,\n payload_json TEXT,\n created_at INTEGER NOT NULL\n )`,\n 'CREATE INDEX IF NOT EXISTS idx_job_logs_job_seq ON job_logs(job_id, seq)',\n\n // Cache entries\n `CREATE TABLE IF NOT EXISTS cache_entries (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n key TEXT NOT NULL,\n kind TEXT NOT NULL,\n content_hash TEXT NOT NULL,\n config_hash TEXT NOT NULL,\n model TEXT NOT NULL DEFAULT '',\n value_json TEXT NOT NULL,\n expires_at INTEGER NOT NULL,\n hit_count INTEGER NOT NULL DEFAULT 0,\n created_at INTEGER NOT NULL\n )`,\n 'CREATE UNIQUE INDEX IF NOT EXISTS idx_cache_key ON cache_entries(key)',\n 'CREATE INDEX IF NOT EXISTS idx_cache_expires ON cache_entries(expires_at)',\n\n // Schema meta\n `CREATE TABLE IF NOT EXISTS schema_meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n )`,\n];\n\n/**\n * Open a SQLite database and run migrations.\n * Pass ':memory:' for in-memory databases (testing).\n */\nexport function openDatabase(dbPath: string): Database.Database {\n try {\n const db = new Database(dbPath);\n configurePragmas(db);\n runMigrations(db);\n return db;\n } catch (err) {\n throw new DatabaseError(\n `Failed to open database at \"${dbPath}\": ${err instanceof Error ? err.message : String(err)}`,\n 'open',\n );\n }\n}\n\nfunction configurePragmas(db: Database.Database): void {\n db.pragma('journal_mode = WAL');\n db.pragma('foreign_keys = ON');\n db.pragma('busy_timeout = 5000');\n}\n\n/**\n * Run all schema migrations. Idempotent (uses IF NOT EXISTS).\n */\nexport function runMigrations(db: Database.Database): void {\n db.transaction(() => {\n for (const sql of MIGRATIONS) {\n db.exec(sql);\n }\n // Add codemoot_session_id columns to existing tables (safe: silently fails if already exists)\n for (const table of ['debate_messages', 'build_events']) {\n try {\n db.exec(`ALTER TABLE ${table} ADD COLUMN codemoot_session_id TEXT`);\n } catch {\n // Column already exists — expected on fresh DBs\n }\n }\n\n // v8: Add full prompt/response storage to session_events\n for (const col of ['prompt_full', 'response_full']) {\n try {\n db.exec(`ALTER TABLE session_events ADD COLUMN ${col} TEXT`);\n } catch {\n // Column already exists\n }\n }\n\n // Set schema version\n db.prepare(\"INSERT OR REPLACE INTO schema_meta(key, value) VALUES ('version', ?)\").run(\n SCHEMA_VERSION,\n );\n db.prepare(\n \"INSERT OR IGNORE INTO schema_meta(key, value) VALUES ('created_at', datetime('now'))\",\n ).run();\n })();\n}\n\n/** Get the current schema version. */\nexport function getSchemaVersion(db: Database.Database): string | null {\n const row = db.prepare(\"SELECT value FROM schema_meta WHERE key = 'version'\").get() as\n | { value: string }\n | undefined;\n return row?.value ?? null;\n}\n","// packages/core/src/memory/session-store.ts\n\nimport type Database from 'better-sqlite3';\nimport type { ExecutionMode, ProjectConfig } from '../types/config.js';\nimport type { Session, SessionStatus, TranscriptEntry } from '../types/session.js';\nimport { generateSessionId } from '../utils/id.js';\n\nexport class SessionStore {\n constructor(private db: Database.Database) {}\n\n create(params: {\n projectId: string;\n workflowId: string;\n task: string;\n mode: ExecutionMode;\n config: ProjectConfig;\n }): Session {\n const id = generateSessionId();\n const now = new Date().toISOString();\n const configSnapshot = JSON.stringify(params.config);\n\n this.db\n .prepare(\n `INSERT INTO sessions (id, project_id, task, workflow_id, mode, status, config_snapshot, started_at, updated_at, metadata)\n VALUES (?, ?, ?, ?, ?, 'running', ?, ?, ?, '{}')`,\n )\n .run(\n id,\n params.projectId,\n params.task,\n params.workflowId,\n params.mode,\n configSnapshot,\n now,\n now,\n );\n\n return {\n id,\n projectId: params.projectId,\n workflowId: params.workflowId,\n task: params.task,\n status: 'running',\n mode: params.mode,\n currentStep: null,\n configSnapshot,\n startedAt: now,\n updatedAt: now,\n completedAt: null,\n summary: null,\n totalCost: 0,\n totalTokens: 0,\n metadata: {},\n };\n }\n\n get(sessionId: string): Session | null {\n const row = this.db.prepare('SELECT * FROM sessions WHERE id = ?').get(sessionId) as\n | Record<string, unknown>\n | undefined;\n return row ? this.rowToSession(row) : null;\n }\n\n list(filter?: { status?: SessionStatus; projectId?: string; limit?: number }): Session[] {\n let sql = 'SELECT * FROM sessions WHERE 1=1';\n const params: unknown[] = [];\n\n if (filter?.status) {\n sql += ' AND status = ?';\n params.push(filter.status);\n }\n if (filter?.projectId) {\n sql += ' AND project_id = ?';\n params.push(filter.projectId);\n }\n sql += ' ORDER BY started_at DESC';\n if (filter?.limit) {\n sql += ' LIMIT ?';\n params.push(filter.limit);\n }\n\n const rows = this.db.prepare(sql).all(...params) as Record<string, unknown>[];\n return rows.map((r) => this.rowToSession(r));\n }\n\n updateStatus(sessionId: string, status: SessionStatus): void {\n this.db\n .prepare(\"UPDATE sessions SET status = ?, updated_at = datetime('now') WHERE id = ?\")\n .run(status, sessionId);\n }\n\n updateCurrentStep(sessionId: string, stepId: string): void {\n this.db\n .prepare(\"UPDATE sessions SET current_step = ?, updated_at = datetime('now') WHERE id = ?\")\n .run(stepId, sessionId);\n }\n\n complete(sessionId: string, summary?: string): void {\n this.db\n .prepare(\n `UPDATE sessions SET status = 'completed', summary = ?, completed_at = datetime('now'), updated_at = datetime('now') WHERE id = ?`,\n )\n .run(summary ?? null, sessionId);\n }\n\n addUsage(sessionId: string, cost: number, tokens: number): void {\n this.db\n .prepare(\n `UPDATE sessions SET total_cost = total_cost + ?, total_tokens = total_tokens + ?, updated_at = datetime('now') WHERE id = ?`,\n )\n .run(cost, tokens, sessionId);\n }\n\n saveTranscriptEntry(entry: TranscriptEntry): void {\n this.db\n .prepare(\n `INSERT INTO messages (session_id, step_id, iteration, role, model_id, content, token_count, cost, created_at, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n entry.sessionId,\n entry.stepId,\n entry.iteration,\n entry.role,\n entry.modelId,\n entry.content,\n entry.tokenCount,\n entry.cost,\n entry.createdAt || new Date().toISOString(),\n entry.metadata ? JSON.stringify(entry.metadata) : null,\n );\n }\n\n getTranscript(sessionId: string): TranscriptEntry[] {\n const rows = this.db\n .prepare('SELECT * FROM messages WHERE session_id = ? ORDER BY created_at ASC')\n .all(sessionId) as Record<string, unknown>[];\n\n return rows.map((r) => ({\n id: r.id as number,\n sessionId: r.session_id as string,\n stepId: r.step_id as string,\n iteration: (r.iteration as number) ?? null,\n role: r.role as string,\n modelId: (r.model_id as string) ?? null,\n content: r.content as string,\n tokenCount: (r.token_count as number) ?? null,\n cost: (r.cost as number) ?? null,\n createdAt: r.created_at as string,\n metadata: r.metadata ? (JSON.parse(r.metadata as string) as Record<string, unknown>) : null,\n }));\n }\n\n private rowToSession(row: Record<string, unknown>): Session {\n return {\n id: row.id as string,\n projectId: row.project_id as string,\n workflowId: row.workflow_id as string,\n task: row.task as string,\n status: row.status as SessionStatus,\n mode: row.mode as ExecutionMode,\n currentStep: (row.current_step as string) ?? null,\n configSnapshot: (row.config_snapshot as string) ?? '',\n startedAt: row.started_at as string,\n updatedAt: row.updated_at as string,\n completedAt: (row.completed_at as string) ?? null,\n summary: (row.summary as string) ?? null,\n totalCost: (row.total_cost as number) ?? 0,\n totalTokens: (row.total_tokens as number) ?? 0,\n metadata: row.metadata ? (JSON.parse(row.metadata as string) as Record<string, unknown>) : {},\n };\n }\n}\n","// packages/core/src/memory/memory-store.ts\n\nimport type Database from 'better-sqlite3';\nimport type { MemoryCategory, MemoryRecord } from '../types/memory.js';\n\nexport class MemoryStore {\n constructor(private db: Database.Database) {}\n\n save(memory: Omit<MemoryRecord, 'id' | 'createdAt' | 'accessedAt' | 'accessCount'>): number {\n const result = this.db\n .prepare(\n `INSERT INTO memories (project_id, category, content, source_session_id, importance)\n VALUES (?, ?, ?, ?, ?)`,\n )\n .run(\n memory.projectId,\n memory.category,\n memory.content,\n memory.sourceSessionId,\n memory.importance,\n );\n return result.lastInsertRowid as number;\n }\n\n search(query: string, projectId: string, limit = 10): MemoryRecord[] {\n if (!query.trim()) return [];\n\n // Escape FTS5 special characters by wrapping each token in double quotes\n const sanitized = query\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => `\"${token.replace(/\"/g, '\"\"')}\"`)\n .join(' ');\n\n const rows = this.db\n .prepare(\n `SELECT m.*, rank\n FROM memories_fts\n JOIN memories m ON m.id = memories_fts.rowid\n WHERE memories_fts MATCH ? AND m.project_id = ?\n ORDER BY rank\n LIMIT ?`,\n )\n .all(sanitized, projectId, limit) as Record<string, unknown>[];\n\n return rows.map((r) => this.rowToMemory(r));\n }\n\n getByCategory(projectId: string, category: MemoryCategory): MemoryRecord[] {\n const rows = this.db\n .prepare(\n 'SELECT * FROM memories WHERE project_id = ? AND category = ? ORDER BY importance DESC',\n )\n .all(projectId, category) as Record<string, unknown>[];\n\n return rows.map((r) => this.rowToMemory(r));\n }\n\n getById(memoryId: number): MemoryRecord | null {\n const row = this.db.prepare('SELECT * FROM memories WHERE id = ?').get(memoryId) as\n | Record<string, unknown>\n | undefined;\n return row ? this.rowToMemory(row) : null;\n }\n\n recordAccess(memoryId: number): void {\n this.db\n .prepare(\n 'UPDATE memories SET accessed_at = CURRENT_TIMESTAMP, access_count = access_count + 1 WHERE id = ?',\n )\n .run(memoryId);\n }\n\n /** Check if a memory with matching category and content prefix already exists. */\n findByPrefix(projectId: string, category: string, contentPrefix: string): MemoryRecord | null {\n const row = this.db\n .prepare(\n 'SELECT * FROM memories WHERE project_id = ? AND category = ? AND content LIKE ? LIMIT 1',\n )\n .get(projectId, category, `${contentPrefix}%`) as Record<string, unknown> | undefined;\n return row ? this.rowToMemory(row) : null;\n }\n\n delete(memoryId: number): void {\n this.db.prepare('DELETE FROM memories WHERE id = ?').run(memoryId);\n }\n\n private rowToMemory(row: Record<string, unknown>): MemoryRecord {\n return {\n id: row.id as number,\n projectId: row.project_id as string,\n category: row.category as MemoryCategory,\n content: row.content as string,\n sourceSessionId: (row.source_session_id as string) ?? null,\n importance: row.importance as number,\n createdAt: row.created_at as string,\n accessedAt: row.accessed_at as string,\n accessCount: row.access_count as number,\n };\n }\n}\n","// packages/core/src/memory/artifact-store.ts\n\nimport type Database from 'better-sqlite3';\nimport type { ArtifactRecord, ArtifactType } from '../types/memory.js';\n\nexport class ArtifactStore {\n constructor(private db: Database.Database) {}\n\n save(artifact: Omit<ArtifactRecord, 'id' | 'createdAt'>): number {\n const result = this.db\n .prepare(\n `INSERT INTO artifacts (session_id, step_id, iteration, type, file_path, content, version, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n artifact.sessionId,\n artifact.stepId,\n artifact.iteration,\n artifact.type,\n artifact.filePath,\n artifact.content,\n artifact.version,\n artifact.metadata ? JSON.stringify(artifact.metadata) : null,\n );\n return result.lastInsertRowid as number;\n }\n\n getBySession(sessionId: string): ArtifactRecord[] {\n const rows = this.db\n .prepare('SELECT * FROM artifacts WHERE session_id = ? ORDER BY created_at ASC')\n .all(sessionId) as Record<string, unknown>[];\n return rows.map((r) => this.rowToArtifact(r));\n }\n\n getByStep(sessionId: string, stepId: string): ArtifactRecord[] {\n const rows = this.db\n .prepare('SELECT * FROM artifacts WHERE session_id = ? AND step_id = ? ORDER BY version ASC')\n .all(sessionId, stepId) as Record<string, unknown>[];\n return rows.map((r) => this.rowToArtifact(r));\n }\n\n getLatestByStep(sessionId: string, stepId: string): ArtifactRecord | null {\n const row = this.db\n .prepare(\n 'SELECT * FROM artifacts WHERE session_id = ? AND step_id = ? ORDER BY version DESC LIMIT 1',\n )\n .get(sessionId, stepId) as Record<string, unknown> | undefined;\n return row ? this.rowToArtifact(row) : null;\n }\n\n getByType(sessionId: string, type: ArtifactType): ArtifactRecord[] {\n const rows = this.db\n .prepare('SELECT * FROM artifacts WHERE session_id = ? AND type = ? ORDER BY created_at ASC')\n .all(sessionId, type) as Record<string, unknown>[];\n return rows.map((r) => this.rowToArtifact(r));\n }\n\n private rowToArtifact(row: Record<string, unknown>): ArtifactRecord {\n return {\n id: row.id as number,\n sessionId: row.session_id as string,\n stepId: row.step_id as string,\n iteration: (row.iteration as number) ?? 1,\n type: row.type as ArtifactType,\n filePath: (row.file_path as string) ?? null,\n content: row.content as string,\n version: row.version as number,\n createdAt: row.created_at as string,\n metadata: row.metadata\n ? (JSON.parse(row.metadata as string) as Record<string, unknown>)\n : null,\n };\n }\n}\n","// packages/core/src/memory/cost-store.ts\n\nimport type Database from 'better-sqlite3';\nimport type { CostLogEntry } from '../types/memory.js';\n\nexport interface CostSummary {\n modelId: string;\n callCount: number;\n totalInputTokens: number;\n totalOutputTokens: number;\n totalCost: number;\n avgLatencyMs: number;\n}\n\nexport class CostStore {\n constructor(private db: Database.Database) {}\n\n log(entry: Omit<CostLogEntry, 'id' | 'createdAt'>): number {\n const result = this.db\n .prepare(\n `INSERT INTO cost_log (session_id, step_id, model_id, input_tokens, output_tokens, cost_usd, latency_ms)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n entry.sessionId,\n entry.stepId,\n entry.modelId,\n entry.inputTokens,\n entry.outputTokens,\n entry.costUsd,\n entry.latencyMs,\n );\n return result.lastInsertRowid as number;\n }\n\n getBySession(sessionId: string): CostLogEntry[] {\n const rows = this.db\n .prepare('SELECT * FROM cost_log WHERE session_id = ? ORDER BY created_at ASC')\n .all(sessionId) as Record<string, unknown>[];\n return rows.map((r) => this.rowToEntry(r));\n }\n\n getSessionSummary(sessionId: string): CostSummary[] {\n const rows = this.db\n .prepare(\n `SELECT model_id, COUNT(*) AS call_count,\n SUM(input_tokens) AS total_input_tokens,\n SUM(output_tokens) AS total_output_tokens,\n SUM(cost_usd) AS total_cost,\n AVG(latency_ms) AS avg_latency_ms\n FROM cost_log WHERE session_id = ?\n GROUP BY model_id ORDER BY total_cost DESC`,\n )\n .all(sessionId) as Record<string, unknown>[];\n\n return rows.map((r) => ({\n modelId: r.model_id as string,\n callCount: r.call_count as number,\n totalInputTokens: r.total_input_tokens as number,\n totalOutputTokens: r.total_output_tokens as number,\n totalCost: r.total_cost as number,\n avgLatencyMs: r.avg_latency_ms as number,\n }));\n }\n\n getDailySummary(days = 30): Record<string, unknown>[] {\n return this.db\n .prepare(\n `SELECT DATE(created_at) AS day, model_id,\n SUM(input_tokens) AS input_tokens,\n SUM(output_tokens) AS output_tokens,\n SUM(cost_usd) AS cost, COUNT(*) AS api_calls\n FROM cost_log WHERE created_at >= DATE('now', ? || ' days')\n GROUP BY day, model_id ORDER BY day DESC, cost DESC`,\n )\n .all(`-${days}`) as Record<string, unknown>[];\n }\n\n private rowToEntry(row: Record<string, unknown>): CostLogEntry {\n return {\n id: row.id as number,\n sessionId: row.session_id as string,\n stepId: (row.step_id as string) ?? null,\n modelId: row.model_id as string,\n inputTokens: row.input_tokens as number,\n outputTokens: row.output_tokens as number,\n costUsd: row.cost_usd as number,\n latencyMs: row.latency_ms as number,\n createdAt: row.created_at as string,\n };\n }\n}\n","// packages/core/src/memory/debate-store.ts — CRUD for debate_turns table\n\nimport type Database from 'better-sqlite3';\nimport type { DebateEngineState } from '../types/debate.js';\n\nexport type DebateTurnStatus = 'active' | 'completed' | 'interrupted' | 'stale' | 'expired';\n\nexport interface DebateTurnRow {\n id: number;\n debateId: string;\n role: string;\n codexSessionId: string | null;\n round: number;\n status: DebateTurnStatus;\n resumeFailCount: number;\n lastActivityAt: number;\n createdAt: number;\n stateJson: string | null;\n}\n\nexport class DebateStore {\n constructor(private db: Database.Database) {}\n\n /** Create or update a debate turn (upsert on debate_id + role). */\n upsert(params: {\n debateId: string;\n role: string;\n codexSessionId?: string;\n round?: number;\n status?: DebateTurnStatus;\n stateJson?: string;\n }): void {\n const now = Date.now();\n this.db\n .prepare(\n `INSERT INTO debate_turns (debate_id, role, codex_session_id, round, status, last_activity_at, created_at, state_json)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(debate_id, role) DO UPDATE SET\n codex_session_id = COALESCE(excluded.codex_session_id, codex_session_id),\n round = excluded.round,\n status = excluded.status,\n last_activity_at = excluded.last_activity_at,\n state_json = COALESCE(excluded.state_json, state_json)`,\n )\n .run(\n params.debateId,\n params.role,\n params.codexSessionId ?? null,\n params.round ?? 0,\n params.status ?? 'active',\n now,\n now,\n params.stateJson ?? null,\n );\n }\n\n /** Get a debate turn by debate_id and role. */\n get(debateId: string, role: string): DebateTurnRow | null {\n const row = this.db\n .prepare('SELECT * FROM debate_turns WHERE debate_id = ? AND role = ?')\n .get(debateId, role) as Record<string, unknown> | undefined;\n return row ? this.toRow(row) : null;\n }\n\n /** Get all turns for a debate. */\n getByDebateId(debateId: string): DebateTurnRow[] {\n const rows = this.db\n .prepare('SELECT * FROM debate_turns WHERE debate_id = ? ORDER BY created_at ASC')\n .all(debateId) as Record<string, unknown>[];\n return rows.map((r) => this.toRow(r));\n }\n\n /** List debates, optionally filtered by status. */\n list(filter?: { status?: DebateTurnStatus; limit?: number }): DebateTurnRow[] {\n let sql = 'SELECT * FROM debate_turns WHERE 1=1';\n const params: unknown[] = [];\n\n if (filter?.status) {\n sql += ' AND status = ?';\n params.push(filter.status);\n }\n sql += ' ORDER BY last_activity_at DESC';\n if (filter?.limit) {\n sql += ' LIMIT ?';\n params.push(filter.limit);\n }\n\n const rows = this.db.prepare(sql).all(...params) as Record<string, unknown>[];\n return rows.map((r) => this.toRow(r));\n }\n\n /** Update session ID after a successful codex call. */\n updateSessionId(debateId: string, role: string, codexSessionId: string): void {\n this.db\n .prepare(\n 'UPDATE debate_turns SET codex_session_id = ?, last_activity_at = ? WHERE debate_id = ? AND role = ?',\n )\n .run(codexSessionId, Date.now(), debateId, role);\n }\n\n /** Update status (e.g., active → completed). */\n updateStatus(debateId: string, role: string, status: DebateTurnStatus): void {\n this.db\n .prepare(\n 'UPDATE debate_turns SET status = ?, last_activity_at = ? WHERE debate_id = ? AND role = ?',\n )\n .run(status, Date.now(), debateId, role);\n }\n\n /** Increment resume failure count. */\n incrementResumeFailCount(debateId: string, role: string): void {\n this.db\n .prepare(\n 'UPDATE debate_turns SET resume_fail_count = resume_fail_count + 1, last_activity_at = ? WHERE debate_id = ? AND role = ?',\n )\n .run(Date.now(), debateId, role);\n }\n\n /** Persist full debate state as JSON for crash recovery. */\n saveState(debateId: string, role: string, state: DebateEngineState): void {\n this.db\n .prepare(\n 'UPDATE debate_turns SET state_json = ?, round = ?, last_activity_at = ? WHERE debate_id = ? AND role = ?',\n )\n .run(JSON.stringify(state), state.round, Date.now(), debateId, role);\n }\n\n /** Load saved debate state from JSON. */\n loadState(debateId: string, role: string): DebateEngineState | null {\n const row = this.get(debateId, role);\n if (!row?.stateJson) return null;\n try {\n return JSON.parse(row.stateJson) as DebateEngineState;\n } catch {\n return null;\n }\n }\n\n /** Mark stale debates (active but inactive for > threshold). */\n markStale(thresholdMs: number): number {\n const cutoff = Date.now() - thresholdMs;\n const result = this.db\n .prepare(\n \"UPDATE debate_turns SET status = 'stale' WHERE status = 'active' AND last_activity_at < ?\",\n )\n .run(cutoff);\n return result.changes;\n }\n\n /** Mark expired debates (stale and older than threshold). */\n markExpired(thresholdMs: number): number {\n const cutoff = Date.now() - thresholdMs;\n const result = this.db\n .prepare(\n \"UPDATE debate_turns SET status = 'expired' WHERE status = 'stale' AND last_activity_at < ?\",\n )\n .run(cutoff);\n return result.changes;\n }\n\n private toRow(row: Record<string, unknown>): DebateTurnRow {\n return {\n id: row.id as number,\n debateId: row.debate_id as string,\n role: row.role as string,\n codexSessionId: (row.codex_session_id as string) ?? null,\n round: (row.round as number) ?? 0,\n status: (row.status as DebateTurnStatus) ?? 'active',\n resumeFailCount: (row.resume_fail_count as number) ?? 0,\n lastActivityAt: row.last_activity_at as number,\n createdAt: row.created_at as number,\n stateJson: (row.state_json as string) ?? null,\n };\n }\n}\n","// packages/core/src/memory/build-store.ts — CRUD for build_runs + build_events\n\nimport type Database from 'better-sqlite3';\nimport type {\n BuildActor,\n BuildEvent,\n BuildEventType,\n BuildPhase,\n BuildRun,\n BuildStatus,\n BuildSummary,\n PhaseCursor,\n} from '../types/build.js';\n\nexport class BuildStore {\n constructor(private db: Database.Database) {}\n\n /** Create a new build run. */\n create(params: {\n buildId: string;\n task: string;\n debateId?: string;\n baselineRef?: string;\n }): void {\n const now = Date.now();\n const cursor: PhaseCursor = {\n phase: 'debate',\n loop: 0,\n actor: 'system',\n attempt: 0,\n lastEventId: 0,\n };\n this.db\n .prepare(\n `INSERT INTO build_runs (build_id, task, status, current_phase, current_loop, last_event_seq, phase_cursor, debate_id, baseline_ref, created_at, updated_at)\n VALUES (?, ?, 'planning', 'debate', 0, 0, ?, ?, ?, ?, ?)`,\n )\n .run(params.buildId, params.task, JSON.stringify(cursor), params.debateId ?? null, params.baselineRef ?? null, now, now);\n }\n\n /** Get a build run by build_id. */\n get(buildId: string): BuildRun | null {\n const row = this.db\n .prepare('SELECT * FROM build_runs WHERE build_id = ?')\n .get(buildId) as Record<string, unknown> | undefined;\n return row ? this.toRun(row) : null;\n }\n\n /** List builds, optionally filtered by status. */\n list(filter?: { status?: BuildStatus; limit?: number }): BuildSummary[] {\n let sql = 'SELECT * FROM build_runs WHERE 1=1';\n const params: unknown[] = [];\n if (filter?.status) {\n sql += ' AND status = ?';\n params.push(filter.status);\n }\n sql += ' ORDER BY updated_at DESC';\n if (filter?.limit) {\n sql += ' LIMIT ?';\n params.push(filter.limit);\n }\n const rows = this.db.prepare(sql).all(...params) as Record<string, unknown>[];\n return rows.map((r) => ({\n buildId: r.build_id as string,\n task: r.task as string,\n status: r.status as BuildStatus,\n phase: r.current_phase as BuildPhase,\n loop: r.current_loop as number,\n reviewCycles: (r.review_cycles as number) ?? 0,\n planVersion: (r.plan_version as number) ?? 0,\n debateId: (r.debate_id as string) ?? null,\n baselineRef: (r.baseline_ref as string) ?? null,\n createdAt: r.created_at as number,\n updatedAt: r.updated_at as number,\n }));\n }\n\n /** Update build run fields atomically with event append. */\n updateWithEvent(\n buildId: string,\n updates: Partial<{\n status: BuildStatus;\n currentPhase: BuildPhase;\n currentLoop: number;\n debateId: string;\n baselineRef: string;\n planCodexSession: string;\n reviewCodexSession: string;\n planVersion: number;\n reviewCycles: number;\n completedAt: number;\n metadata: Record<string, unknown>;\n }>,\n event: {\n eventType: BuildEventType;\n actor: BuildActor;\n phase: BuildPhase;\n loopIndex?: number;\n payload?: Record<string, unknown>;\n codexThreadId?: string;\n tokensUsed?: number;\n },\n ): void {\n this.db.transaction(() => {\n // Get next seq\n const run = this.get(buildId);\n if (!run) throw new Error(`Build not found: ${buildId}`);\n const nextSeq = run.lastEventSeq + 1;\n const now = Date.now();\n\n // Insert event\n this.db\n .prepare(\n `INSERT INTO build_events (build_id, seq, event_type, actor, phase, loop_index, payload, codex_thread_id, tokens_used, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n buildId,\n nextSeq,\n event.eventType,\n event.actor,\n event.phase,\n event.loopIndex ?? 0,\n event.payload ? JSON.stringify(event.payload) : null,\n event.codexThreadId ?? null,\n event.tokensUsed ?? 0,\n now,\n );\n\n // Build SET clause dynamically\n const sets: string[] = ['last_event_seq = ?', 'updated_at = ?'];\n const values: unknown[] = [nextSeq, now];\n\n if (updates.status !== undefined) { sets.push('status = ?'); values.push(updates.status); }\n if (updates.currentPhase !== undefined) { sets.push('current_phase = ?'); values.push(updates.currentPhase); }\n if (updates.currentLoop !== undefined) { sets.push('current_loop = ?'); values.push(updates.currentLoop); }\n if (updates.debateId !== undefined) { sets.push('debate_id = ?'); values.push(updates.debateId); }\n if (updates.baselineRef !== undefined) { sets.push('baseline_ref = ?'); values.push(updates.baselineRef); }\n if (updates.planCodexSession !== undefined) { sets.push('plan_codex_session = ?'); values.push(updates.planCodexSession); }\n if (updates.reviewCodexSession !== undefined) { sets.push('review_codex_session = ?'); values.push(updates.reviewCodexSession); }\n if (updates.planVersion !== undefined) { sets.push('plan_version = ?'); values.push(updates.planVersion); }\n if (updates.reviewCycles !== undefined) { sets.push('review_cycles = ?'); values.push(updates.reviewCycles); }\n if (updates.completedAt !== undefined) { sets.push('completed_at = ?'); values.push(updates.completedAt); }\n if (updates.metadata !== undefined) { sets.push('metadata = ?'); values.push(JSON.stringify(updates.metadata)); }\n\n // Update cursor\n const cursor: PhaseCursor = {\n phase: updates.currentPhase ?? run.currentPhase,\n loop: updates.currentLoop ?? run.currentLoop,\n actor: event.actor,\n attempt: 0,\n lastEventId: nextSeq,\n baselineRef: updates.baselineRef ?? run.baselineRef ?? undefined,\n };\n sets.push('phase_cursor = ?');\n values.push(JSON.stringify(cursor));\n\n values.push(buildId);\n this.db.prepare(`UPDATE build_runs SET ${sets.join(', ')} WHERE build_id = ?`).run(...values);\n })();\n }\n\n /** Get events for a build, ordered by seq. */\n getEvents(buildId: string, afterSeq?: number): BuildEvent[] {\n let sql = 'SELECT * FROM build_events WHERE build_id = ?';\n const params: unknown[] = [buildId];\n if (afterSeq !== undefined) {\n sql += ' AND seq > ?';\n params.push(afterSeq);\n }\n sql += ' ORDER BY seq ASC';\n const rows = this.db.prepare(sql).all(...params) as Record<string, unknown>[];\n return rows.map((r) => this.toEvent(r));\n }\n\n /** Count events by type for a build. */\n countEventsByType(buildId: string, eventType: BuildEventType): number {\n const row = this.db\n .prepare('SELECT COUNT(*) as cnt FROM build_events WHERE build_id = ? AND event_type = ?')\n .get(buildId, eventType) as { cnt: number };\n return row.cnt;\n }\n\n private toRun(row: Record<string, unknown>): BuildRun {\n let cursor: PhaseCursor;\n try {\n cursor = JSON.parse((row.phase_cursor as string) || '{}');\n } catch {\n cursor = { phase: 'debate', loop: 0, actor: 'system', attempt: 0, lastEventId: 0 };\n }\n let metadata: Record<string, unknown> | null = null;\n if (row.metadata) {\n try { metadata = JSON.parse(row.metadata as string); } catch { /* ignore */ }\n }\n return {\n id: row.id as number,\n buildId: row.build_id as string,\n task: row.task as string,\n status: row.status as BuildStatus,\n currentPhase: row.current_phase as BuildPhase,\n currentLoop: (row.current_loop as number) ?? 0,\n lastEventSeq: (row.last_event_seq as number) ?? 0,\n phaseCursor: cursor,\n debateId: (row.debate_id as string) ?? null,\n baselineRef: (row.baseline_ref as string) ?? null,\n planCodexSession: (row.plan_codex_session as string) ?? null,\n reviewCodexSession: (row.review_codex_session as string) ?? null,\n planVersion: (row.plan_version as number) ?? 0,\n reviewCycles: (row.review_cycles as number) ?? 0,\n createdAt: row.created_at as number,\n updatedAt: row.updated_at as number,\n completedAt: (row.completed_at as number) ?? null,\n metadata,\n };\n }\n\n private toEvent(row: Record<string, unknown>): BuildEvent {\n let payload: Record<string, unknown> | null = null;\n if (row.payload) {\n try { payload = JSON.parse(row.payload as string); } catch { /* ignore */ }\n }\n return {\n id: row.id as number,\n buildId: row.build_id as string,\n seq: row.seq as number,\n eventType: row.event_type as BuildEventType,\n actor: row.actor as BuildActor,\n phase: row.phase as BuildPhase,\n loopIndex: (row.loop_index as number) ?? 0,\n payload,\n codexThreadId: (row.codex_thread_id as string) ?? null,\n tokensUsed: (row.tokens_used as number) ?? 0,\n createdAt: row.created_at as number,\n };\n }\n}\n","// packages/core/src/security/dlp.ts — 6-stage DLP pipeline from MCP architecture\n\nimport { DlpReasonCode } from '../types/mcp.js';\nimport { DLP_MAX_PROCESSING_MS } from '../utils/constants.js';\n\nexport type DlpMode = 'strict' | 'open';\n\nexport interface DlpRedaction {\n stage: number;\n reasonCode: DlpReasonCode;\n original: string;\n replacement: string;\n}\n\nexport interface DlpAuditEntry {\n stage: number;\n action: string;\n detail: string;\n timestamp: string;\n}\n\nexport interface DlpResult {\n sanitized: string;\n redactions: DlpRedaction[];\n truncated: boolean;\n auditLog: DlpAuditEntry[];\n}\n\nexport interface DlpConfig {\n mode: DlpMode;\n maxInputBytes: number;\n maxProcessingMs: number;\n maxRegexOps: number;\n maxTokens: number;\n}\n\nconst DEFAULT_DLP_CONFIG: DlpConfig = {\n mode: 'strict',\n maxInputBytes: 5 * 1024 * 1024,\n maxProcessingMs: DLP_MAX_PROCESSING_MS,\n maxRegexOps: 1000,\n maxTokens: 32_000,\n};\n\n// -- Secret patterns: [regex, replacement type] --\nconst SECRET_PATTERNS: Array<[RegExp, string]> = [\n [/AKIA[0-9A-Z]{16}/g, 'AWS_KEY'],\n [/sk-proj-[a-zA-Z0-9\\-_]{20,}/g, 'API_KEY'],\n [/sk-[a-zA-Z0-9]{20,}/g, 'API_KEY'],\n [/ghp_[a-zA-Z0-9]{36}/g, 'GITHUB_TOKEN'],\n [/eyJ[a-zA-Z0-9_-]+\\.eyJ[a-zA-Z0-9_-]+/g, 'JWT'],\n [/-----BEGIN [A-Z ]+ PRIVATE KEY-----/g, 'PRIVATE_KEY'],\n [/Bearer [a-zA-Z0-9._~+/=-]{20,}/g, 'BEARER_TOKEN'],\n [/[a-zA-Z]+:\\/\\/[^:]+:[^@]+@/g, 'CONNECTION_STRING'],\n];\n\n// -- Path patterns --\nconst ABSOLUTE_PATH_PATTERNS: RegExp[] = [\n /[A-Z]:\\\\[^\\s'\"`,;)}\\]]+/g,\n /\\/(?:home|Users|root|var|etc|opt|tmp)\\/[^\\s'\"`,;)}\\]]+/g,\n];\n\n/**\n * Calculate Shannon entropy for a string.\n */\nfunction shannonEntropy(str: string): number {\n if (str.length === 0) return 0;\n\n const freq = new Map<string, number>();\n for (const ch of str) {\n freq.set(ch, (freq.get(ch) ?? 0) + 1);\n }\n\n let entropy = 0;\n const len = str.length;\n for (const count of freq.values()) {\n const p = count / len;\n if (p > 0) {\n entropy -= p * Math.log2(p);\n }\n }\n return entropy;\n}\n\n/**\n * Truncate the original value to first 20 characters for audit safety.\n */\nfunction auditSnippet(value: string): string {\n if (value.length <= 20) return value;\n return `${value.slice(0, 20)}...`;\n}\n\n/**\n * Create an audit log entry.\n */\nfunction audit(stage: number, action: string, detail: string): DlpAuditEntry {\n return {\n stage,\n action,\n detail,\n timestamp: new Date().toISOString(),\n };\n}\n\n/**\n * Estimate token count using char/4 heuristic.\n */\nfunction estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Sanitize input through the 6-stage DLP pipeline.\n *\n * Stages:\n * 0: Decode — detect and skip base64/hex (budget-limited)\n * 1: Secrets — regex scan for common secret patterns\n * 2: Entropy — Shannon entropy check on long tokens (strict mode only)\n * 3: Paths — convert absolute paths to relative\n * 4: Context — truncate if exceeding token limit\n * 5: Audit — finalize audit log\n *\n * Risk-tiered defaults:\n * review/debate tools -> strict mode (external content)\n * memory/cost tools -> open mode (local data, skip stages 1-2)\n */\nexport function sanitize(input: string, config?: Partial<DlpConfig>): DlpResult {\n const cfg: DlpConfig = { ...DEFAULT_DLP_CONFIG, ...config };\n const redactions: DlpRedaction[] = [];\n const auditLog: DlpAuditEntry[] = [];\n let text = input;\n let truncated = false;\n const startTime = Date.now();\n\n /** Check if processing has exceeded the time budget. */\n const isOverBudget = () => Date.now() - startTime > cfg.maxProcessingMs;\n\n // Budget check: reject oversized input\n const inputBytes = new TextEncoder().encode(text).byteLength;\n if (inputBytes > cfg.maxInputBytes) {\n auditLog.push(audit(0, 'BUDGET_EXCEEDED', `Input size ${inputBytes} exceeds limit`));\n redactions.push({\n stage: 0,\n reasonCode: DlpReasonCode.BUDGET_EXCEEDED,\n original: auditSnippet(text),\n replacement: '[BLOCKED: input exceeds size budget]',\n });\n return {\n sanitized: '[BLOCKED: input exceeds size budget]',\n redactions,\n truncated: true,\n auditLog,\n };\n }\n\n // Handle empty input early\n if (text.length === 0) {\n return { sanitized: '', redactions: [], truncated: false, auditLog: [] };\n }\n\n let regexOps = 0;\n\n // Stage 0: Decode detection (simplified — flag base64 blocks)\n auditLog.push(audit(0, 'DECODE_CHECK', 'Scanning for encoded content'));\n // We detect large base64 blocks and flag them. Per-decode budget: 1MB/10ops/500ms.\n const base64Pattern = /(?:[A-Za-z0-9+/]{4}){16,}={0,2}/g;\n let base64Match = base64Pattern.exec(text);\n while (base64Match && regexOps < cfg.maxRegexOps) {\n regexOps++;\n const matched = base64Match[0];\n // Only flag large base64 blocks (> 64 chars)\n if (matched.length > 64) {\n auditLog.push(\n audit(0, 'DECODE_FLAGGED', `Large base64 block detected: ${matched.length} chars`),\n );\n redactions.push({\n stage: 0,\n reasonCode: DlpReasonCode.DECODE_BLOCKED,\n original: auditSnippet(matched),\n replacement: '[REDACTED:ENCODED_CONTENT]',\n });\n text = `${text.slice(0, base64Match.index)}[REDACTED:ENCODED_CONTENT]${text.slice(base64Match.index + matched.length)}`;\n // Reset regex after modifying text\n base64Pattern.lastIndex = base64Match.index + '[REDACTED:ENCODED_CONTENT]'.length;\n }\n base64Match = base64Pattern.exec(text);\n }\n\n // In open mode, skip stages 1 and 2 (local data like memory/cost)\n if (cfg.mode === 'strict') {\n // Timer check before stage 1\n if (isOverBudget()) {\n auditLog.push(audit(1, 'TIMEOUT', `Processing exceeded ${cfg.maxProcessingMs}ms budget`));\n return { sanitized: text, redactions, truncated, auditLog };\n }\n\n // Stage 1: Secret detection\n auditLog.push(audit(1, 'SECRET_SCAN', 'Scanning for secret patterns'));\n for (const [pattern, secretType] of SECRET_PATTERNS) {\n if (regexOps >= cfg.maxRegexOps) break;\n // Reset global regex\n const regex = new RegExp(pattern.source, pattern.flags);\n let match = regex.exec(text);\n while (match && regexOps < cfg.maxRegexOps) {\n regexOps++;\n const original = match[0];\n const replacement = `[REDACTED:${secretType}]`;\n redactions.push({\n stage: 1,\n reasonCode: DlpReasonCode.SECRET_DETECTED,\n original: auditSnippet(original),\n replacement,\n });\n auditLog.push(audit(1, 'SECRET_REDACTED', `${secretType} at position ${match.index}`));\n text = `${text.slice(0, match.index)}${replacement}${text.slice(match.index + original.length)}`;\n // Adjust regex position after replacement\n regex.lastIndex = match.index + replacement.length;\n match = regex.exec(text);\n }\n }\n\n // Timer check before stage 2\n if (isOverBudget()) {\n auditLog.push(audit(2, 'TIMEOUT', `Processing exceeded ${cfg.maxProcessingMs}ms budget`));\n return { sanitized: text, redactions, truncated, auditLog };\n }\n\n // Stage 2: Entropy check (strict mode only)\n auditLog.push(audit(2, 'ENTROPY_SCAN', 'Checking token entropy'));\n // Split into tokens by whitespace/punctuation and check each\n const tokenPattern = /[^\\s'\"`,;)}\\]]{21,}/g;\n const tokens: Array<{ value: string; index: number }> = [];\n let tokenMatch = tokenPattern.exec(text);\n while (tokenMatch && regexOps < cfg.maxRegexOps) {\n regexOps++;\n tokens.push({ value: tokenMatch[0], index: tokenMatch.index });\n tokenMatch = tokenPattern.exec(text);\n }\n\n // Process in reverse order so indices remain valid\n for (let i = tokens.length - 1; i >= 0; i--) {\n const token = tokens[i];\n const entropy = shannonEntropy(token.value);\n if (entropy > 4.5) {\n const replacement = '[REDACTED:HIGH_ENTROPY]';\n redactions.push({\n stage: 2,\n reasonCode: DlpReasonCode.HIGH_ENTROPY,\n original: auditSnippet(token.value),\n replacement,\n });\n auditLog.push(\n audit(\n 2,\n 'ENTROPY_REDACTED',\n `Token entropy ${entropy.toFixed(2)} at position ${token.index}`,\n ),\n );\n text = `${text.slice(0, token.index)}${replacement}${text.slice(token.index + token.value.length)}`;\n }\n }\n } else {\n auditLog.push(audit(1, 'SKIPPED', 'Open mode: secret scan skipped'));\n auditLog.push(audit(2, 'SKIPPED', 'Open mode: entropy scan skipped'));\n }\n\n // Timer check before stage 3\n if (isOverBudget()) {\n auditLog.push(audit(3, 'TIMEOUT', `Processing exceeded ${cfg.maxProcessingMs}ms budget`));\n return { sanitized: text, redactions, truncated, auditLog };\n }\n\n // Stage 3: Absolute path conversion\n auditLog.push(audit(3, 'PATH_SCAN', 'Scanning for absolute paths'));\n for (const pathPattern of ABSOLUTE_PATH_PATTERNS) {\n if (regexOps >= cfg.maxRegexOps) break;\n const regex = new RegExp(pathPattern.source, pathPattern.flags);\n let match = regex.exec(text);\n while (match && regexOps < cfg.maxRegexOps) {\n regexOps++;\n const original = match[0];\n const replacement = convertToRelative(original);\n if (replacement !== original) {\n redactions.push({\n stage: 3,\n reasonCode: DlpReasonCode.ABSOLUTE_PATH,\n original: auditSnippet(original),\n replacement,\n });\n auditLog.push(audit(3, 'PATH_CONVERTED', `Absolute path at position ${match.index}`));\n text = `${text.slice(0, match.index)}${replacement}${text.slice(match.index + original.length)}`;\n regex.lastIndex = match.index + replacement.length;\n }\n match = regex.exec(text);\n }\n }\n\n // Timer check before stage 4\n if (isOverBudget()) {\n auditLog.push(audit(4, 'TIMEOUT', `Processing exceeded ${cfg.maxProcessingMs}ms budget`));\n return { sanitized: text, redactions, truncated, auditLog };\n }\n\n // Stage 4: Context size truncation\n auditLog.push(audit(4, 'CONTEXT_CHECK', 'Checking token count'));\n const estimatedTokenCount = estimateTokens(text);\n if (estimatedTokenCount > cfg.maxTokens) {\n const maxChars = cfg.maxTokens * 4;\n const truncatedText = text.slice(0, maxChars);\n const suffix = '\\n[TRUNCATED: context exceeded token limit]';\n text = truncatedText + suffix;\n truncated = true;\n redactions.push({\n stage: 4,\n reasonCode: DlpReasonCode.CONTEXT_TRUNCATED,\n original: `Estimated ${estimatedTokenCount} tokens`,\n replacement: `Truncated to ${cfg.maxTokens} tokens`,\n });\n auditLog.push(\n audit(\n 4,\n 'CONTEXT_TRUNCATED',\n `Truncated from ${estimatedTokenCount} to ${cfg.maxTokens} tokens`,\n ),\n );\n }\n\n // Stage 5: Audit finalization\n auditLog.push(\n audit(\n 5,\n 'COMPLETE',\n `DLP pipeline complete: ${redactions.length} redactions, truncated=${String(truncated)}`,\n ),\n );\n\n return {\n sanitized: text,\n redactions,\n truncated,\n auditLog,\n };\n}\n\n/**\n * Convert an absolute path to a relative path.\n */\nfunction convertToRelative(absolutePath: string): string {\n // Windows: C:\\Users\\foo\\project\\file.ts -> ./project/file.ts\n const winMatch = /^[A-Z]:\\\\(?:Users\\\\[^\\\\]+\\\\)?(.+)$/i.exec(absolutePath);\n if (winMatch) {\n return `./${winMatch[1].replace(/\\\\/g, '/')}`;\n }\n\n // Unix: /home/user/project/file.ts -> ./project/file.ts\n const unixMatch = /^\\/(?:home|Users|root)\\/[^/]+\\/(.+)$/.exec(absolutePath);\n if (unixMatch) {\n return `./${unixMatch[1]}`;\n }\n\n // Other absolute unix paths: /var/log/app.log -> ./log/app.log\n const otherMatch = /^\\/(?:var|etc|opt|tmp)\\/(.+)$/.exec(absolutePath);\n if (otherMatch) {\n return `./${otherMatch[1]}`;\n }\n\n return absolutePath;\n}\n\nexport { DEFAULT_DLP_CONFIG, shannonEntropy, convertToRelative, estimateTokens };\n","// packages/core/src/memory/message-store.ts — CRUD for debate_messages table\n\nimport type Database from 'better-sqlite3';\nimport { sanitize } from '../security/dlp.js';\n\nexport type MessageStatus = 'queued' | 'running' | 'completed' | 'failed';\n\nexport interface DebateMessageRow {\n id: number;\n debateId: string;\n round: number;\n role: string;\n bridge: string;\n model: string;\n promptText: string;\n responseText: string | null;\n stance: string | null;\n confidence: number | null;\n verdictRaw: string | null;\n usageJson: string | null;\n durationMs: number | null;\n sessionId: string | null;\n status: MessageStatus;\n error: string | null;\n createdAt: number;\n updatedAt: number;\n completedAt: number | null;\n}\n\nexport interface ParsedVerdict {\n stance: string | null;\n confidence: number | null;\n raw: string | null;\n}\n\nconst VERDICT_BLOCK_RE = /---VERDICT---([\\s\\S]*?)---END_VERDICT---/;\nconst STANCE_RE = /(?:STANCE:\\s*|^)(SUPPORT|OPPOSE|UNCERTAIN)(?:\\s|[.,:;—\\-]|$)/im;\n\n/** Parse structured verdict from model response. */\nexport function parseDebateVerdict(text: string): ParsedVerdict {\n const VALID_STANCES = new Set(['SUPPORT', 'OPPOSE', 'UNCERTAIN']);\n\n const validateStance = (s: unknown): string | null => {\n if (typeof s !== 'string') return null;\n const upper = s.toUpperCase();\n return VALID_STANCES.has(upper) ? upper : null;\n };\n\n const validateConfidence = (c: unknown): number | null => {\n if (typeof c !== 'number' || !Number.isFinite(c)) return null;\n return c >= 0 && c <= 1 ? c : null;\n };\n\n // Try structured JSON block first\n const blockMatch = VERDICT_BLOCK_RE.exec(text);\n if (blockMatch) {\n try {\n const parsed = JSON.parse(blockMatch[1].trim());\n return {\n stance: validateStance(parsed.stance),\n confidence: validateConfidence(parsed.confidence),\n raw: sanitize(blockMatch[0], { mode: 'strict' }).sanitized,\n };\n } catch {\n // Malformed JSON in block — fall through to regex\n }\n }\n\n // Fallback to regex\n const stanceMatch = STANCE_RE.exec(text);\n if (stanceMatch) {\n return {\n stance: stanceMatch[1].toUpperCase(),\n confidence: null,\n raw: null,\n };\n }\n\n return { stance: null, confidence: null, raw: null };\n}\n\nexport class MessageStore {\n constructor(private db: Database.Database) {}\n\n /** Insert a new message in queued state. Returns the row ID. */\n insertQueued(params: {\n debateId: string;\n round: number;\n role: string;\n bridge: string;\n model: string;\n promptText: string;\n }): number {\n const now = Date.now();\n const sanitized = sanitize(params.promptText, { mode: 'strict' });\n const result = this.db\n .prepare(\n `INSERT INTO debate_messages (debate_id, round, role, bridge, model, prompt_text, status, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, 'queued', ?, ?)`,\n )\n .run(\n params.debateId,\n params.round,\n params.role,\n params.bridge,\n params.model,\n sanitized.sanitized,\n now,\n now,\n );\n return Number(result.lastInsertRowid);\n }\n\n /** Update prompt text on a queued or failed row (for retries with different prompts). */\n updatePrompt(id: number, promptText: string): boolean {\n const sanitized = sanitize(promptText, { mode: 'strict' });\n const result = this.db\n .prepare(\n `UPDATE debate_messages SET prompt_text = ?, updated_at = ?\n WHERE id = ? AND status IN ('queued', 'failed')`,\n )\n .run(sanitized.sanitized, Date.now(), id);\n return result.changes === 1;\n }\n\n /** Transition to running. Only from queued or failed. Returns true if transition succeeded. */\n markRunning(id: number): boolean {\n const result = this.db\n .prepare(\n `UPDATE debate_messages SET status = 'running', updated_at = ?\n WHERE id = ? AND status IN ('queued', 'failed')`,\n )\n .run(Date.now(), id);\n return result.changes === 1;\n }\n\n /** Transition to completed with response data. Only from running. */\n markCompleted(\n id: number,\n params: {\n responseText: string;\n verdict: ParsedVerdict;\n usageJson: string;\n durationMs: number;\n sessionId: string | null;\n },\n ): boolean {\n const now = Date.now();\n const sanitizedResponse = sanitize(params.responseText, { mode: 'strict' });\n const sanitizedError = params.verdict.raw\n ? sanitize(params.verdict.raw, { mode: 'strict' }).sanitized\n : null;\n const result = this.db\n .prepare(\n `UPDATE debate_messages SET\n status = 'completed',\n response_text = ?,\n stance = ?,\n confidence = ?,\n verdict_raw = ?,\n usage_json = ?,\n duration_ms = ?,\n session_id = ?,\n error = NULL,\n updated_at = ?,\n completed_at = ?\n WHERE id = ? AND status = 'running'`,\n )\n .run(\n sanitizedResponse.sanitized,\n params.verdict.stance,\n params.verdict.confidence,\n sanitizedError,\n params.usageJson,\n params.durationMs,\n params.sessionId,\n now,\n now,\n id,\n );\n return result.changes === 1;\n }\n\n /** Transition to failed with error. Only from running. */\n markFailed(id: number, error: string): boolean {\n const sanitizedError = sanitize(error, { mode: 'strict' });\n const result = this.db\n .prepare(\n `UPDATE debate_messages SET status = 'failed', error = ?, updated_at = ?\n WHERE id = ? AND status = 'running'`,\n )\n .run(sanitizedError.sanitized, Date.now(), id);\n return result.changes === 1;\n }\n\n /** Get a message by debate_id, round, and role (for idempotency checks). */\n getByRound(debateId: string, round: number, role: string): DebateMessageRow | null {\n const row = this.db\n .prepare('SELECT * FROM debate_messages WHERE debate_id = ? AND round = ? AND role = ? LIMIT 1')\n .get(debateId, round, role) as Record<string, unknown> | undefined;\n return row ? this.toRow(row) : null;\n }\n\n /** Get full message history for a debate, ordered by round. */\n getHistory(debateId: string): DebateMessageRow[] {\n const rows = this.db\n .prepare('SELECT * FROM debate_messages WHERE debate_id = ? ORDER BY round ASC, role ASC')\n .all(debateId) as Record<string, unknown>[];\n return rows.map(r => this.toRow(r));\n }\n\n /** Recover stale running rows older than threshold. Returns count recovered. */\n recoverStale(thresholdMs: number): number {\n const cutoff = Date.now() - thresholdMs;\n const result = this.db\n .prepare(\n `UPDATE debate_messages SET status = 'failed', error = 'STALE_RECOVERY', updated_at = ?\n WHERE status = 'running' AND updated_at < ?`,\n )\n .run(Date.now(), cutoff);\n return result.changes;\n }\n\n /** Recover stale running rows for a specific debate only. */\n recoverStaleForDebate(debateId: string, thresholdMs: number): number {\n const cutoff = Date.now() - thresholdMs;\n const result = this.db\n .prepare(\n `UPDATE debate_messages SET status = 'failed', error = 'STALE_RECOVERY', updated_at = ?\n WHERE status = 'running' AND debate_id = ? AND updated_at < ?`,\n )\n .run(Date.now(), debateId, cutoff);\n return result.changes;\n }\n\n private toRow(row: Record<string, unknown>): DebateMessageRow {\n return {\n id: row.id as number,\n debateId: row.debate_id as string,\n round: row.round as number,\n role: row.role as string,\n bridge: (row.bridge as string) ?? 'codex',\n model: row.model as string,\n promptText: row.prompt_text as string,\n responseText: (row.response_text as string) ?? null,\n stance: (row.stance as string) ?? null,\n confidence: (row.confidence as number) ?? null,\n verdictRaw: (row.verdict_raw as string) ?? null,\n usageJson: (row.usage_json as string) ?? null,\n durationMs: (row.duration_ms as number) ?? null,\n sessionId: (row.session_id as string) ?? null,\n status: (row.status as MessageStatus) ?? 'queued',\n error: (row.error as string) ?? null,\n createdAt: row.created_at as number,\n updatedAt: row.updated_at as number,\n completedAt: (row.completed_at as number) ?? null,\n };\n }\n}\n","// packages/core/src/memory/reconstruction.ts — Build reconstruction prompts from stored debate history\n\nimport type { DebateMessageRow } from './message-store.js';\n\n/**\n * Build a reconstruction preamble from stored debate messages.\n * Used when session resume fails and we need to give GPT context of previous rounds.\n *\n * Strategy:\n * - If history fits within tokenBudget: include all rounds verbatim\n * - If over budget: summarize oldest rounds, keep newest verbatim\n *\n * @param history - Previous completed messages from MessageStore.getHistory()\n * @param currentPrompt - The new prompt for this round\n * @param maxChars - Approximate character budget (rough proxy for tokens; ~4 chars/token)\n * @returns The reconstructed prompt with history preamble\n */\nexport function buildReconstructionPrompt(\n history: DebateMessageRow[],\n currentPrompt: string,\n maxChars = 100_000,\n): string {\n const completed = history.filter(m => m.status === 'completed' && m.responseText);\n\n if (completed.length === 0) {\n return currentPrompt;\n }\n\n // Build verbatim history blocks\n const blocks: string[] = [];\n for (const msg of completed) {\n blocks.push(\n `## Round ${msg.round} (${msg.role})\\n**Prompt:** ${truncate(msg.promptText, 500)}\\n**Response:** ${msg.responseText}${msg.stance ? `\\n**Stance:** ${msg.stance}` : ''}`,\n );\n }\n\n const preamble = `This is a continuation of a debate. The session was interrupted and context must be reconstructed from the conversation ledger.\\n\\n# Previous Rounds\\n\\n${blocks.join('\\n\\n')}\\n\\n# Current Round\\n\\n`;\n const full = preamble + currentPrompt;\n\n // If within budget, return full\n if (full.length <= maxChars) {\n return full;\n }\n\n // Over budget: summarize oldest rounds, keep newest verbatim\n return buildCompressedPrompt(completed, currentPrompt, maxChars);\n}\n\nfunction buildCompressedPrompt(\n history: DebateMessageRow[],\n currentPrompt: string,\n maxChars: number,\n): string {\n // Keep newest rounds verbatim, summarize oldest\n const verbatimCount = Math.max(1, Math.min(3, Math.floor(history.length / 2)));\n const toSummarize = history.slice(0, -verbatimCount);\n const toKeep = history.slice(-verbatimCount);\n\n const summaryParts: string[] = [];\n for (const msg of toSummarize) {\n const stanceStr = msg.stance ? ` (${msg.stance})` : '';\n summaryParts.push(`- Round ${msg.round}: ${truncate(msg.responseText ?? '', 200)}${stanceStr}`);\n }\n\n const verbatimParts: string[] = [];\n for (const msg of toKeep) {\n verbatimParts.push(\n `## Round ${msg.round} (${msg.role})\\n**Response:** ${msg.responseText}${msg.stance ? `\\n**Stance:** ${msg.stance}` : ''}`,\n );\n }\n\n let result = `This is a continuation of a debate. Context reconstructed from ledger.\\n\\n# Summary of Earlier Rounds\\n${summaryParts.join('\\n')}\\n\\n# Recent Rounds (verbatim)\\n\\n${verbatimParts.join('\\n\\n')}\\n\\n# Current Round\\n\\n${currentPrompt}`;\n\n // If still over budget, aggressively truncate summaries\n if (result.length > maxChars) {\n result = `Context reconstructed from ledger (truncated).\\n\\n# Most Recent Round\\n\\n${verbatimParts[verbatimParts.length - 1]}\\n\\n# Current Round\\n\\n${currentPrompt}`;\n }\n\n return result.slice(0, maxChars);\n}\n\nfunction truncate(text: string, maxLen: number): string {\n if (text.length <= maxLen) return text;\n return `${text.slice(0, maxLen)}... [truncated]`;\n}\n","// packages/core/src/memory/token-budget.ts — Token budget tracking and management for debates\n\nimport type { DebateMessageRow } from './message-store.js';\n\n/** Rough estimate: ~4 characters per token for English text. */\nconst CHARS_PER_TOKEN = 4;\n\nexport interface TokenBudgetStatus {\n /** Total tokens used across all rounds. */\n totalTokensUsed: number;\n /** Maximum context tokens for the model. */\n maxContextTokens: number;\n /** Usage as a fraction (0-1). */\n utilizationRatio: number;\n /** Whether auto-summarization is recommended (>= 70%). */\n shouldSummarize: boolean;\n /** Whether the debate should be completed (>= 90%). */\n shouldStop: boolean;\n /** Estimated tokens remaining. */\n tokensRemaining: number;\n}\n\n/** Estimate token count from character length. */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\n/**\n * Calculate total tokens used in a debate from stored messages.\n * Uses actual usage_json when available, falls back to text length estimation.\n */\nexport function calculateDebateTokens(history: DebateMessageRow[]): number {\n let total = 0;\n for (const msg of history) {\n if (msg.usageJson) {\n try {\n const usage = JSON.parse(msg.usageJson);\n total += (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0);\n continue;\n } catch {\n // Fall through to estimation\n }\n }\n // Estimate from text lengths\n total += estimateTokens(msg.promptText);\n if (msg.responseText) {\n total += estimateTokens(msg.responseText);\n }\n }\n return total;\n}\n\n/**\n * Get the current token budget status for a debate.\n */\nexport function getTokenBudgetStatus(\n history: DebateMessageRow[],\n maxContextTokens: number,\n): TokenBudgetStatus {\n const totalTokensUsed = calculateDebateTokens(history);\n const utilizationRatio = maxContextTokens > 0 ? totalTokensUsed / maxContextTokens : 0;\n\n return {\n totalTokensUsed,\n maxContextTokens,\n utilizationRatio,\n shouldSummarize: utilizationRatio >= 0.7,\n shouldStop: utilizationRatio >= 0.9,\n tokensRemaining: Math.max(0, maxContextTokens - totalTokensUsed),\n };\n}\n\n/**\n * Preflight check: estimate if a new prompt will fit within budget.\n * Returns the status AFTER the hypothetical send.\n */\nexport function preflightTokenCheck(\n history: DebateMessageRow[],\n newPrompt: string,\n maxContextTokens: number,\n): TokenBudgetStatus {\n const currentTokens = calculateDebateTokens(history);\n const promptTokens = estimateTokens(newPrompt);\n const projected = currentTokens + promptTokens;\n const utilizationRatio = maxContextTokens > 0 ? projected / maxContextTokens : 0;\n\n return {\n totalTokensUsed: projected,\n maxContextTokens,\n utilizationRatio,\n shouldSummarize: utilizationRatio >= 0.7,\n shouldStop: utilizationRatio >= 0.9,\n tokensRemaining: Math.max(0, maxContextTokens - projected),\n };\n}\n","// packages/core/src/memory/unified-session.ts — Unified session management\n\nimport type Database from 'better-sqlite3';\nimport { generateId } from '../utils/id.js';\nimport { sanitize } from '../security/dlp.js';\nimport { estimateTokens } from './token-budget.js';\n\nexport interface UnifiedSession {\n id: string;\n name: string | null;\n codexThreadId: string | null;\n status: 'active' | 'completed' | 'stale';\n tokenUsage: number;\n maxContext: number;\n createdAt: number;\n updatedAt: number;\n completedAt: number | null;\n}\n\nexport interface SessionEvent {\n id: number;\n sessionId: string;\n command: string;\n subcommand: string | null;\n promptPreview: string | null;\n responsePreview: string | null;\n usageJson: string | null;\n durationMs: number | null;\n codexThreadId: string | null;\n createdAt: number;\n}\n\nexport interface SessionOverflowStatus {\n /** Cumulative tokens (for cost tracking). */\n cumulativeTokens: number;\n /** Latest turn's input_tokens (best proxy for current context fullness). */\n lastTurnInputTokens: number;\n maxContext: number;\n /** Based on lastTurnInputTokens / maxContext. */\n utilizationRatio: number;\n shouldWarn: boolean; // > 75%\n shouldReconstruct: boolean; // > 85%\n}\n\nexport class SessionManager {\n constructor(private db: Database.Database) {}\n\n /** Create a new session. Returns the session ID. */\n create(name?: string): string {\n const id = generateId();\n const now = Date.now();\n this.db\n .prepare(\n `INSERT INTO codemoot_sessions (id, name, status, created_at, updated_at)\n VALUES (?, ?, 'active', ?, ?)`,\n )\n .run(id, name ?? null, now, now);\n return id;\n }\n\n /** Get a session by ID. */\n get(id: string): UnifiedSession | null {\n const row = this.db\n .prepare('SELECT * FROM codemoot_sessions WHERE id = ?')\n .get(id) as Record<string, unknown> | undefined;\n return row ? this.toSession(row) : null;\n }\n\n /** Get the current active session (most recently updated). */\n getActive(): UnifiedSession | null {\n const row = this.db\n .prepare(\"SELECT * FROM codemoot_sessions WHERE status = 'active' ORDER BY updated_at DESC LIMIT 1\")\n .get() as Record<string, unknown> | undefined;\n return row ? this.toSession(row) : null;\n }\n\n /** Get or create the active session. If none exists, auto-create one. */\n resolveActive(autoName?: string): UnifiedSession {\n const existing = this.getActive();\n if (existing) return existing;\n const id = this.create(autoName);\n return this.get(id) as UnifiedSession;\n }\n\n /** Update the codex thread ID for a session (after first GPT call). */\n updateThreadId(sessionId: string, threadId: string): void {\n this.db\n .prepare(\n 'UPDATE codemoot_sessions SET codex_thread_id = ?, updated_at = ? WHERE id = ?',\n )\n .run(threadId, Date.now(), sessionId);\n }\n\n /** Update token usage for a session. Ignores negative values. */\n addTokenUsage(sessionId: string, tokens: number): void {\n if (!Number.isFinite(tokens) || tokens <= 0) return;\n tokens = Math.floor(tokens);\n this.db\n .prepare(\n 'UPDATE codemoot_sessions SET token_usage = token_usage + ?, updated_at = ? WHERE id = ?',\n )\n .run(tokens, Date.now(), sessionId);\n }\n\n /**\n * Add token usage from a model call result. Uses real usage when available,\n * falls back to char/4 estimate only when usage data is missing.\n */\n addUsageFromResult(sessionId: string, usage: { totalTokens?: number; inputTokens?: number; outputTokens?: number }, promptText?: string, responseText?: string): void {\n const realTokens = usage.totalTokens || ((usage.inputTokens ?? 0) + (usage.outputTokens ?? 0));\n if (realTokens > 0) {\n this.addTokenUsage(sessionId, realTokens);\n } else if (promptText || responseText) {\n this.addTokenUsage(sessionId, this.estimateEventTokens(promptText ?? '', responseText ?? ''));\n }\n }\n\n /** Touch the updated_at timestamp. */\n touch(sessionId: string): void {\n this.db\n .prepare('UPDATE codemoot_sessions SET updated_at = ? WHERE id = ?')\n .run(Date.now(), sessionId);\n }\n\n /** Mark a session as completed. */\n complete(sessionId: string): void {\n const now = Date.now();\n this.db\n .prepare(\n \"UPDATE codemoot_sessions SET status = 'completed', updated_at = ?, completed_at = ? WHERE id = ?\",\n )\n .run(now, now, sessionId);\n }\n\n /** List sessions, optionally filtered by status. */\n list(options?: { status?: string; limit?: number }): UnifiedSession[] {\n const rawLimit = options?.limit ?? 20;\n const limit = Number.isFinite(rawLimit) && rawLimit > 0 ? Math.min(rawLimit, 100) : 20;\n let sql = 'SELECT * FROM codemoot_sessions';\n const params: unknown[] = [];\n if (options?.status) {\n sql += ' WHERE status = ?';\n params.push(options.status);\n }\n sql += ' ORDER BY updated_at DESC LIMIT ?';\n params.push(limit);\n const rows = this.db.prepare(sql).all(...params) as Record<string, unknown>[];\n return rows.map(r => this.toSession(r));\n }\n\n /** Get overflow status for a session. Uses latest turn's input_tokens as context fullness signal. */\n getOverflowStatus(sessionId: string): SessionOverflowStatus {\n const session = this.get(sessionId);\n if (!session) {\n return { cumulativeTokens: 0, lastTurnInputTokens: 0, maxContext: 400_000, utilizationRatio: 0, shouldWarn: false, shouldReconstruct: false };\n }\n // 128K was the old incorrect default; codex context is 400K\n const maxCtx = (session.maxContext > 0 && session.maxContext !== 128_000) ? session.maxContext : 400_000;\n\n // Get latest event's input_tokens as best proxy for current context size\n const latestEvents = this.getEvents(sessionId, 1);\n let lastTurnInput = 0;\n if (latestEvents.length > 0 && latestEvents[0].usageJson) {\n try {\n const usage = JSON.parse(latestEvents[0].usageJson);\n const raw = usage.inputTokens ?? usage.input_tokens ?? 0;\n lastTurnInput = typeof raw === 'number' && Number.isFinite(raw) && raw > 0 ? raw : 0;\n } catch { /* malformed JSON */ }\n }\n\n const ratio = lastTurnInput / maxCtx;\n return {\n cumulativeTokens: session.tokenUsage,\n lastTurnInputTokens: lastTurnInput,\n maxContext: maxCtx,\n utilizationRatio: ratio,\n shouldWarn: ratio > 0.75,\n shouldReconstruct: ratio > 0.85,\n };\n }\n\n /** Pre-call check: auto-rollover if session context is over threshold. Call before every codex interaction. */\n preCallOverflowCheck(sessionId: string, threshold = 0.85): { rolled: boolean; message?: string } {\n const status = this.getOverflowStatus(sessionId);\n if (status.utilizationRatio > threshold) {\n this.rolloverThread(sessionId);\n const pct = Math.round(status.utilizationRatio * 100);\n return { rolled: true, message: `Session at ${pct}%. Rolling over to new thread.` };\n }\n return { rolled: false };\n }\n\n /** Roll over to a new codex thread (on context overflow). Returns new thread info. */\n rolloverThread(sessionId: string): void {\n this.db\n .prepare(\n 'UPDATE codemoot_sessions SET codex_thread_id = NULL, updated_at = ? WHERE id = ?',\n )\n .run(Date.now(), sessionId);\n }\n\n // ── Session Events ──\n\n /** Record a GPT interaction event. Stores preview (500 chars) + optional full text. */\n recordEvent(params: {\n sessionId: string;\n command: string;\n subcommand?: string;\n promptPreview?: string;\n responsePreview?: string;\n promptFull?: string;\n responseFull?: string;\n usageJson?: string;\n durationMs?: number;\n codexThreadId?: string;\n }): number {\n const sanitizedPrompt = params.promptPreview\n ? sanitize(params.promptPreview.slice(0, 500), { mode: 'strict' }).sanitized\n : null;\n const sanitizedResponse = params.responsePreview\n ? sanitize(params.responsePreview.slice(0, 500), { mode: 'strict' }).sanitized\n : null;\n const sanitizedPromptFull = params.promptFull\n ? sanitize(params.promptFull, { mode: 'strict' }).sanitized\n : null;\n const sanitizedResponseFull = params.responseFull\n ? sanitize(params.responseFull, { mode: 'strict' }).sanitized\n : null;\n\n const result = this.db\n .prepare(\n `INSERT INTO session_events (session_id, command, subcommand, prompt_preview, response_preview, prompt_full, response_full, usage_json, duration_ms, codex_thread_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n params.sessionId,\n params.command,\n params.subcommand ?? null,\n sanitizedPrompt,\n sanitizedResponse,\n sanitizedPromptFull,\n sanitizedResponseFull,\n params.usageJson ?? null,\n params.durationMs ?? null,\n params.codexThreadId ?? null,\n Date.now(),\n );\n return Number(result.lastInsertRowid);\n }\n\n /** Get events for a session. */\n getEvents(sessionId: string, rawLimit = 50): SessionEvent[] {\n const limit = Number.isFinite(rawLimit) && rawLimit > 0 ? Math.min(rawLimit, 200) : 50;\n const rows = this.db\n .prepare('SELECT * FROM session_events WHERE session_id = ? ORDER BY created_at DESC, id DESC LIMIT ?')\n .all(sessionId, limit) as Record<string, unknown>[];\n return rows.map(r => ({\n id: r.id as number,\n sessionId: r.session_id as string,\n command: r.command as string,\n subcommand: (r.subcommand as string) ?? null,\n promptPreview: (r.prompt_preview as string) ?? null,\n responsePreview: (r.response_preview as string) ?? null,\n usageJson: (r.usage_json as string) ?? null,\n durationMs: (r.duration_ms as number) ?? null,\n codexThreadId: (r.codex_thread_id as string) ?? null,\n createdAt: r.created_at as number,\n }));\n }\n\n /** Estimate tokens from prompt + response text (for usage tracking when real usage unavailable). */\n estimateEventTokens(promptText: string, responseText: string): number {\n return estimateTokens(promptText) + estimateTokens(responseText);\n }\n\n private toSession(row: Record<string, unknown>): UnifiedSession {\n return {\n id: row.id as string,\n name: (row.name as string) ?? null,\n codexThreadId: (row.codex_thread_id as string) ?? null,\n status: (row.status as UnifiedSession['status']) ?? 'active',\n tokenUsage: (row.token_usage as number) ?? 0,\n maxContext: (row.max_context as number) ?? 400_000,\n createdAt: row.created_at as number,\n updatedAt: row.updated_at as number,\n completedAt: (row.completed_at as number) ?? null,\n };\n }\n}\n","// packages/core/src/memory/job-store.ts — SQLite-backed job queue for background async work\n\nimport type Database from 'better-sqlite3';\nimport type { EnqueueOptions, JobLogRecord, JobRecord, JobStatus, JobType } from '../types/jobs.js';\nimport { generateId } from '../utils/id.js';\n\nexport class JobStore {\n constructor(private db: Database.Database) {}\n\n /** Enqueue a new job. Returns the job ID. */\n enqueue(options: EnqueueOptions): string {\n const id = generateId();\n const now = Date.now();\n this.db\n .prepare(\n `INSERT INTO jobs (id, type, status, priority, dedupe_key, payload_json, max_retries, session_id, created_at, updated_at)\n VALUES (?, ?, 'queued', ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n id,\n options.type,\n options.priority ?? 100,\n options.dedupeKey ?? null,\n JSON.stringify(options.payload),\n options.maxRetries ?? 1,\n options.sessionId ?? null,\n now,\n now,\n );\n return id;\n }\n\n /** Get a job by ID. */\n get(id: string): JobRecord | null {\n const row = this.db\n .prepare('SELECT * FROM jobs WHERE id = ?')\n .get(id) as Record<string, unknown> | undefined;\n return row ? this.toJob(row) : null;\n }\n\n /** Atomically claim the next N queued jobs. Returns claimed jobs. */\n claimNext(workerId: string, limit = 1): JobRecord[] {\n const now = Date.now();\n // Two-step: select then update (SQLite doesn't support UPDATE...RETURNING with ORDER BY LIMIT)\n const rows = this.db\n .prepare(\n `SELECT id FROM jobs WHERE status = 'queued' ORDER BY priority ASC, created_at ASC LIMIT ?`,\n )\n .all(limit) as { id: string }[];\n\n if (rows.length === 0) return [];\n\n const claimed: JobRecord[] = [];\n const claimStmt = this.db.prepare(\n `UPDATE jobs SET status = 'running', worker_id = ?, started_at = ?, updated_at = ? WHERE id = ? AND status = 'queued'`,\n );\n\n for (const row of rows) {\n const result = claimStmt.run(workerId, now, now, row.id);\n if (result.changes > 0) {\n const job = this.get(row.id);\n if (job) claimed.push(job);\n }\n }\n return claimed;\n }\n\n /** Mark a job as succeeded. Only updates if still running (not canceled). */\n succeed(id: string, result: Record<string, unknown>): void {\n const now = Date.now();\n this.db\n .prepare(\n `UPDATE jobs SET status = 'succeeded', result_json = ?, finished_at = ?, updated_at = ? WHERE id = ? AND status = 'running'`,\n )\n .run(JSON.stringify(result), now, now, id);\n }\n\n /** Mark a job as failed. Only updates if still running (not canceled). */\n fail(id: string, error: string): void {\n const now = Date.now();\n this.db\n .prepare(\n `UPDATE jobs SET status = 'failed', error_text = ?, finished_at = ?, updated_at = ? WHERE id = ? AND status = 'running'`,\n )\n .run(error, now, now, id);\n }\n\n /** Cancel a job. */\n cancel(id: string): void {\n const now = Date.now();\n this.db\n .prepare(\n `UPDATE jobs SET status = 'canceled', finished_at = ?, updated_at = ? WHERE id = ? AND status IN ('queued', 'running')`,\n )\n .run(now, now, id);\n }\n\n /** Retry a failed/canceled job. */\n retry(id: string): boolean {\n const job = this.get(id);\n if (!job) return false;\n if (job.status !== 'failed' && job.status !== 'canceled') return false;\n if (job.retryCount >= job.maxRetries) return false;\n\n const now = Date.now();\n this.db\n .prepare(\n `UPDATE jobs SET status = 'queued', retry_count = retry_count + 1, error_text = NULL, result_json = NULL, worker_id = NULL, started_at = NULL, finished_at = NULL, updated_at = ? WHERE id = ?`,\n )\n .run(now, id);\n return true;\n }\n\n /** List jobs with optional filters. */\n list(options?: { status?: JobStatus; type?: JobType; limit?: number }): JobRecord[] {\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (options?.status) {\n conditions.push('status = ?');\n params.push(options.status);\n }\n if (options?.type) {\n conditions.push('type = ?');\n params.push(options.type);\n }\n\n const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n const limit = options?.limit ?? 50;\n params.push(limit);\n\n const rows = this.db\n .prepare(`SELECT * FROM jobs ${where} ORDER BY created_at DESC LIMIT ?`)\n .all(...params) as Record<string, unknown>[];\n\n return rows.map(r => this.toJob(r));\n }\n\n /** Check if a dedupe key already has an active (queued/running) job. */\n hasActive(dedupeKey: string): boolean {\n const row = this.db\n .prepare(`SELECT 1 FROM jobs WHERE dedupe_key = ? AND status IN ('queued', 'running') LIMIT 1`)\n .get(dedupeKey);\n return Boolean(row);\n }\n\n /** Check if any active job exists for a given type. */\n hasActiveByType(type: string): boolean {\n const row = this.db\n .prepare(`SELECT 1 FROM jobs WHERE type = ? AND status IN ('queued', 'running') LIMIT 1`)\n .get(type);\n return Boolean(row);\n }\n\n // ── Job Logs ──\n\n /** Append a log entry. */\n appendLog(jobId: string, level: JobLogRecord['level'], eventType: string, message?: string, payload?: Record<string, unknown>): void {\n const maxSeq = this.db\n .prepare('SELECT COALESCE(MAX(seq), 0) AS max_seq FROM job_logs WHERE job_id = ?')\n .get(jobId) as { max_seq: number };\n\n this.db\n .prepare(\n `INSERT INTO job_logs (job_id, seq, level, event_type, message, payload_json, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(jobId, maxSeq.max_seq + 1, level, eventType, message ?? null, payload ? JSON.stringify(payload) : null, Date.now());\n }\n\n /** Get logs for a job. */\n getLogs(jobId: string, fromSeq = 0, limit = 100): JobLogRecord[] {\n const rows = this.db\n .prepare('SELECT * FROM job_logs WHERE job_id = ? AND seq > ? ORDER BY seq ASC LIMIT ?')\n .all(jobId, fromSeq, limit) as Record<string, unknown>[];\n\n return rows.map(r => ({\n id: r.id as number,\n jobId: r.job_id as string,\n seq: r.seq as number,\n level: r.level as JobLogRecord['level'],\n eventType: r.event_type as string,\n message: (r.message as string) ?? null,\n payloadJson: (r.payload_json as string) ?? null,\n createdAt: r.created_at as number,\n }));\n }\n\n private toJob(row: Record<string, unknown>): JobRecord {\n return {\n id: row.id as string,\n type: row.type as JobType,\n status: row.status as JobStatus,\n priority: row.priority as number,\n dedupeKey: (row.dedupe_key as string) ?? null,\n payloadJson: row.payload_json as string,\n resultJson: (row.result_json as string) ?? null,\n errorText: (row.error_text as string) ?? null,\n retryCount: row.retry_count as number,\n maxRetries: row.max_retries as number,\n sessionId: (row.session_id as string) ?? null,\n workerId: (row.worker_id as string) ?? null,\n startedAt: (row.started_at as number) ?? null,\n finishedAt: (row.finished_at as number) ?? null,\n createdAt: row.created_at as number,\n updatedAt: row.updated_at as number,\n };\n }\n}\n","// packages/core/src/memory/cache-store.ts — Result caching with content+config hash\n\nimport { createHash } from 'node:crypto';\nimport type Database from 'better-sqlite3';\n\nexport interface CacheEntry {\n id: number;\n key: string;\n kind: string;\n contentHash: string;\n configHash: string;\n model: string;\n valueJson: string;\n expiresAt: number;\n hitCount: number;\n createdAt: number;\n}\n\nexport class CacheStore {\n constructor(private db: Database.Database) {}\n\n get(key: string, contentHash: string, configHash: string): CacheEntry | null {\n const row = this.db\n .prepare(\n 'SELECT id, key, kind, content_hash, config_hash, model, value_json, expires_at, hit_count, created_at FROM cache_entries WHERE key = ? AND content_hash = ? AND config_hash = ? AND expires_at > ?',\n )\n .get(key, contentHash, configHash, Date.now()) as Record<string, unknown> | undefined;\n\n if (row) {\n this.db\n .prepare('UPDATE cache_entries SET hit_count = hit_count + 1 WHERE id = ?')\n .run(row.id);\n return {\n id: row.id as number,\n key: row.key as string,\n kind: row.kind as string,\n contentHash: row.content_hash as string,\n configHash: row.config_hash as string,\n model: row.model as string,\n valueJson: row.value_json as string,\n expiresAt: row.expires_at as number,\n hitCount: row.hit_count as number,\n createdAt: row.created_at as number,\n };\n }\n return null;\n }\n\n set(entry: {\n key: string;\n kind: string;\n contentHash: string;\n configHash: string;\n model: string;\n valueJson: string;\n ttlMs: number;\n }): void {\n // Upsert: delete old entries for same key first\n this.db.prepare('DELETE FROM cache_entries WHERE key = ?').run(entry.key);\n this.db\n .prepare(\n 'INSERT INTO cache_entries (key, kind, content_hash, config_hash, model, value_json, expires_at, hit_count, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?)',\n )\n .run(\n entry.key,\n entry.kind,\n entry.contentHash,\n entry.configHash,\n entry.model,\n entry.valueJson,\n Date.now() + entry.ttlMs,\n Date.now(),\n );\n }\n\n evictExpired(): number {\n const result = this.db\n .prepare('DELETE FROM cache_entries WHERE expires_at <= ?')\n .run(Date.now());\n return result.changes;\n }\n\n clear(): number {\n const result = this.db.prepare('DELETE FROM cache_entries').run();\n return result.changes;\n }\n\n stats(): { totalEntries: number; totalHits: number; expiredCount: number } {\n const total = this.db.prepare('SELECT COUNT(*) as cnt FROM cache_entries').get() as {\n cnt: number;\n };\n const hits = this.db\n .prepare('SELECT COALESCE(SUM(hit_count), 0) as total FROM cache_entries')\n .get() as { total: number };\n const expired = this.db\n .prepare('SELECT COUNT(*) as cnt FROM cache_entries WHERE expires_at <= ?')\n .get(Date.now()) as { cnt: number };\n return { totalEntries: total.cnt, totalHits: hits.total, expiredCount: expired.cnt };\n }\n}\n\nexport function hashContent(content: string): string {\n return createHash('sha256').update(content).digest('hex').slice(0, 16);\n}\n\nexport function hashConfig(config: Record<string, unknown>): string {\n const sorted = JSON.stringify(config, Object.keys(config).sort());\n return createHash('sha256').update(sorted).digest('hex').slice(0, 16);\n}\n","// packages/core/src/models/cli-adapter.ts — CLI subprocess adapter for free model access\n\nimport { spawn } from 'node:child_process';\nimport { randomUUID } from 'node:crypto';\nimport { readFile, unlink } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport type { ModelProvider } from '../types/config.js';\nimport type { TokenUsage } from '../types/events.js';\nimport type { ModelCallResult } from '../types/models.js';\nimport { ModelError } from '../utils/errors.js';\nimport type { BridgeCapabilities, CliBridge } from './bridge.js';\n\nconst MAX_OUTPUT_BYTES = 512 * 1024; // 512KB\nconst TRUNCATION_MARKER = '\\n[TRUNCATED: output exceeded 512KB]';\n\n// Default env vars always passed to CLI subprocesses\nconst BASE_ENV_ALLOWLIST = [\n 'PATH',\n 'HOME',\n 'TEMP',\n 'TMP',\n 'USERPROFILE',\n 'SystemRoot',\n 'COMSPEC',\n 'SHELL',\n];\n\n// CLI-specific auth env vars\nconst CLI_AUTH_VARS: Record<string, string[]> = {\n codex: ['OPENAI_API_KEY'],\n};\n\n/** Progress callbacks for real-time feedback during CLI subprocess execution. */\nexport interface ProgressCallbacks {\n /** Called when the subprocess successfully spawns. */\n onSpawn?: (pid: number, command: string) => void;\n /** Called on each stderr chunk (tool calls, activity). */\n onStderr?: (chunk: string) => void;\n /** Called periodically (every 15s) with elapsed seconds. */\n onHeartbeat?: (elapsedSec: number) => void;\n /** Called on each stdout chunk for progress feedback. */\n onProgress?: (chunk: string) => void;\n}\n\nexport interface CliCallOptions extends ProgressCallbacks {\n /** Total timeout in ms. Default: 600_000 (10 min). */\n timeout?: number;\n /** Inactivity timeout — kill if no stdout for this long. Default: 120_000 (2 min). */\n idleTimeout?: number;\n maxOutputBytes?: number;\n envAllowlist?: string[];\n}\n\nexport interface ResumeCallOptions extends CliCallOptions {\n /** Codex thread_id to resume a conversation. */\n sessionId?: string;\n}\n\n/** Known context windows by model family. GPT-5 codex models have 400K. */\nconst MODEL_CONTEXT_WINDOWS: Record<string, number> = {\n 'gpt-5-codex': 400_000,\n 'gpt-5.1-codex': 400_000,\n 'gpt-5.2-codex': 400_000,\n 'gpt-5.3-codex': 400_000,\n 'codex-mini-latest': 200_000,\n};\nconst DEFAULT_CONTEXT_WINDOW = 400_000;\n\n/** Default capabilities for codex CLI bridge. */\nconst CODEX_CAPABILITIES: BridgeCapabilities = {\n supportsResume: true,\n supportsStream: true,\n maxContextTokens: DEFAULT_CONTEXT_WINDOW,\n supportsTools: true,\n supportsCwd: true,\n};\n\nexport class CliAdapter implements CliBridge {\n private command: string;\n private baseArgs: string[];\n private provider: ModelProvider;\n readonly modelId: string;\n private cliName: string;\n private projectDir: string | undefined;\n readonly capabilities: BridgeCapabilities;\n\n get name(): string { return this.cliName; }\n get model(): string { return this.modelId; }\n\n constructor(config: {\n command: string;\n args: string[];\n provider: ModelProvider;\n model: string;\n cliName: string;\n projectDir?: string;\n }) {\n this.command = config.command;\n this.baseArgs = config.args;\n this.provider = config.provider;\n this.modelId = config.model;\n this.cliName = config.cliName;\n this.projectDir = config.projectDir;\n this.capabilities = {\n ...CODEX_CAPABILITIES,\n maxContextTokens: MODEL_CONTEXT_WINDOWS[config.model] ?? DEFAULT_CONTEXT_WINDOW,\n };\n }\n\n /** CliBridge.send — send a prompt without session resume. */\n async send(prompt: string, options?: CliCallOptions): Promise<ModelCallResult> {\n return this.call(prompt, options);\n }\n\n /** CliBridge.resume — resume a session or fall back to send. */\n async resume(sessionId: string, prompt: string, options?: CliCallOptions): Promise<ModelCallResult> {\n if (!this.capabilities.supportsResume) {\n return this.send(prompt, options);\n }\n return this.callWithResume(prompt, { ...options, sessionId });\n }\n\n async call(prompt: string, options?: CliCallOptions): Promise<ModelCallResult> {\n const timeout = options?.timeout ?? 600_000;\n const maxBytes = options?.maxOutputBytes ?? MAX_OUTPUT_BYTES;\n\n // Build filtered env\n const allowlist = [\n ...BASE_ENV_ALLOWLIST,\n ...(CLI_AUTH_VARS[this.cliName] ?? []),\n ...(options?.envAllowlist ?? []),\n ];\n const env = buildFilteredEnv(allowlist);\n\n // Create temp output file\n const tmpFile = join(tmpdir(), `codemoot-cli-${randomUUID()}.txt`);\n\n // Build command args (prompt piped via stdin, not as CLI arg)\n const args = this.buildArgs(tmpFile);\n const start = Date.now();\n\n try {\n await this.runProcess(this.command, args, env, timeout, prompt, {\n idleTimeout: options?.idleTimeout,\n onProgress: options?.onProgress,\n onSpawn: options?.onSpawn,\n onStderr: options?.onStderr,\n onHeartbeat: options?.onHeartbeat,\n });\n\n // Codex writes to tmpFile via -o flag\n let output = await readFile(tmpFile, 'utf-8');\n\n if (Buffer.byteLength(output) > maxBytes) {\n output = Buffer.from(output).subarray(0, maxBytes).toString('utf-8') + TRUNCATION_MARKER;\n }\n\n const durationMs = Date.now() - start;\n const usage = estimateTokenUsage(prompt, output);\n\n return {\n text: output,\n model: this.modelId,\n provider: this.provider,\n usage,\n finishReason: 'stop',\n durationMs,\n };\n } finally {\n // Cleanup temp file\n await unlink(tmpFile).catch(() => {});\n }\n }\n\n /**\n * Call codex with session resume support via --json JSONL output.\n * If sessionId is provided, resumes the conversation. On resume failure,\n * falls back to a fresh exec and returns the new sessionId.\n */\n async callWithResume(prompt: string, options?: ResumeCallOptions): Promise<ModelCallResult> {\n const timeout = options?.timeout ?? 600_000;\n const maxBytes = options?.maxOutputBytes ?? MAX_OUTPUT_BYTES;\n\n const allowlist = [\n ...BASE_ENV_ALLOWLIST,\n ...(CLI_AUTH_VARS[this.cliName] ?? []),\n ...(options?.envAllowlist ?? []),\n ];\n const env = buildFilteredEnv(allowlist);\n\n const doCall = async (resumeId?: string): Promise<ModelCallResult> => {\n const ext = process.platform === 'win32' ? '.cmd' : '';\n\n // Always use stdin (\"-\") for prompt delivery:\n // - Fresh exec: stdin is the default prompt source\n // - Resume: positional arg breaks on Windows shell:true (spaces split into multiple args)\n // Using \"-\" tells codex to read the prompt from stdin instead\n // Build args: if we have a project dir, tell codex about it via --cd\n const cdArgs = this.projectDir ? ['-C', this.projectDir] : [];\n const args = resumeId\n ? ['exec', '--skip-git-repo-check', ...cdArgs, 'resume', resumeId, '-', '--json']\n : ['exec', '--skip-git-repo-check', ...cdArgs, '--json'];\n\n const start = Date.now();\n const stdout = await this.runProcess(`codex${ext}`, args, env, timeout, prompt, {\n idleTimeout: options?.idleTimeout,\n onProgress: options?.onProgress,\n onSpawn: options?.onSpawn,\n onStderr: options?.onStderr,\n onHeartbeat: options?.onHeartbeat,\n });\n\n // Parse JSONL output\n const parsed = parseCodexJsonl(stdout);\n\n let output = parsed.text;\n if (Buffer.byteLength(output) > maxBytes) {\n output = Buffer.from(output).subarray(0, maxBytes).toString('utf-8') + TRUNCATION_MARKER;\n }\n\n const durationMs = Date.now() - start;\n const usage = parsed.usage ?? estimateTokenUsage(prompt, output);\n\n return {\n text: output,\n model: this.modelId,\n provider: this.provider,\n usage,\n finishReason: 'stop',\n durationMs,\n sessionId: parsed.sessionId,\n };\n };\n\n // Try resume if sessionId provided\n if (options?.sessionId) {\n try {\n return await doCall(options.sessionId);\n } catch {\n // Resume failed — fall back to fresh exec\n console.error(`[codemoot] Resume failed for session ${options.sessionId}, falling back to fresh exec`);\n }\n }\n\n return doCall();\n }\n\n private buildArgs(outputFile: string): string[] {\n return [...this.baseArgs, '-o', outputFile];\n }\n\n private runProcess(\n command: string,\n args: string[],\n env: Record<string, string>,\n timeout: number,\n stdinData?: string,\n options?: { idleTimeout?: number } & ProgressCallbacks,\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n let lastActivityAt = startTime;\n\n const child = spawn(command, args, {\n cwd: this.projectDir ?? tmpdir(),\n env,\n stdio: ['pipe', 'pipe', 'pipe'],\n windowsHide: true,\n shell: process.platform === 'win32',\n });\n\n let stdout = '';\n let stderr = '';\n let stdoutBytes = 0;\n let settled = false;\n const maxCapture = MAX_OUTPUT_BYTES * 2; // Cap memory usage\n\n // Heartbeat interval — fires every 15s with elapsed time\n const heartbeatInterval = options?.onHeartbeat\n ? setInterval(() => {\n try { options.onHeartbeat?.(Math.round((Date.now() - startTime) / 1000)); } catch { /* callback error isolation */ }\n }, 15_000)\n : undefined;\n\n const cleanup = () => {\n clearTimeout(absoluteTimer);\n clearTimeout(idleTimer);\n if (heartbeatInterval) clearInterval(heartbeatInterval);\n };\n\n const fail = (err: ModelError) => {\n if (settled) return;\n settled = true;\n cleanup();\n reject(err);\n };\n\n // Notify caller when process successfully spawns\n child.on('spawn', () => {\n try { options?.onSpawn?.(child.pid ?? 0, command); } catch { /* callback error isolation */ }\n });\n\n // Absolute timeout — hard ceiling, kills no matter what\n const elapsedMsg = () => `elapsed ${Date.now() - startTime}ms, last activity ${Date.now() - lastActivityAt}ms ago`;\n const absoluteTimer = setTimeout(() => {\n killProcessTree(child.pid);\n fail(\n new ModelError(\n `CLI subprocess absolute timeout (limit ${timeout}ms, ${elapsedMsg()})`,\n this.provider,\n this.modelId,\n ),\n );\n }, timeout);\n\n // Idle timeout — resets on every stdout/stderr chunk. Detects stalled processes.\n const idleMs = options?.idleTimeout ?? 120_000;\n let idleTimer = setTimeout(() => {\n killProcessTree(child.pid);\n fail(\n new ModelError(\n `CLI subprocess idle timeout (no output for ${idleMs}ms, total ${elapsedMsg()})`,\n this.provider,\n this.modelId,\n ),\n );\n }, idleMs);\n\n const resetIdleTimer = () => {\n lastActivityAt = Date.now();\n clearTimeout(idleTimer);\n idleTimer = setTimeout(() => {\n killProcessTree(child.pid);\n fail(\n new ModelError(\n `CLI subprocess idle timeout (no output for ${idleMs}ms, total ${elapsedMsg()})`,\n this.provider,\n this.modelId,\n ),\n );\n }, idleMs);\n };\n\n child.stdout.on('data', (data: Buffer) => {\n const chunk = data.toString();\n stdoutBytes += data.byteLength;\n if (stdoutBytes <= maxCapture) {\n stdout += chunk;\n }\n resetIdleTimer();\n try { options?.onProgress?.(chunk); } catch { /* callback error isolation */ }\n });\n child.stderr.on('data', (data: Buffer) => {\n const chunk = data.toString();\n if (stderr.length < 10_000) stderr += chunk;\n resetIdleTimer();\n try { options?.onStderr?.(chunk); } catch { /* callback error isolation */ }\n });\n\n if (stdinData) {\n child.stdin.write(stdinData);\n child.stdin.end();\n } else {\n child.stdin.end();\n }\n\n child.on('error', (err) => {\n fail(\n new ModelError(`CLI subprocess failed: ${err.message}`, this.provider, this.modelId),\n );\n });\n\n child.on('close', (code) => {\n if (settled) return;\n settled = true;\n cleanup();\n if (code !== 0) {\n reject(\n new ModelError(\n `CLI subprocess exited with code ${code}: ${stderr.slice(0, 500)}`,\n this.provider,\n this.modelId,\n ),\n );\n return;\n }\n resolve(stdout);\n });\n });\n }\n}\n\nexport function buildFilteredEnv(allowlist: string[]): Record<string, string> {\n const env: Record<string, string> = {};\n for (const key of allowlist) {\n const val = process.env[key];\n if (val !== undefined) {\n env[key] = val;\n }\n }\n return env;\n}\n\nexport function killProcessTree(pid: number | undefined): void {\n if (pid === undefined) return;\n try {\n if (process.platform === 'win32') {\n spawn('taskkill', ['/pid', String(pid), '/T', '/F'], { stdio: 'ignore' });\n } else {\n process.kill(-pid, 'SIGTERM');\n setTimeout(() => {\n try {\n process.kill(-pid, 'SIGKILL');\n } catch {\n // Process may already be dead\n }\n }, 5000);\n }\n } catch {\n // Process may already be dead\n }\n}\n\n/** Estimate tokens using char/4 heuristic. MeteringSource = 'estimated'. */\nexport function estimateTokenUsage(prompt: string, output: string): TokenUsage {\n const inputTokens = Math.ceil(prompt.length / 4);\n const outputTokens = Math.ceil(output.length / 4);\n return {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n costUsd: 0, // CLI mode = free\n };\n}\n\n/** Parse codex --json JSONL output into structured result. */\nexport function parseCodexJsonl(stdout: string): {\n sessionId?: string;\n text: string;\n usage?: TokenUsage;\n} {\n let sessionId: string | undefined;\n const textParts: string[] = [];\n let usage: TokenUsage | undefined;\n\n for (const line of stdout.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n try {\n const event = JSON.parse(trimmed);\n\n if (event.type === 'thread.started' && event.thread_id) {\n sessionId = event.thread_id;\n }\n\n if (\n event.type === 'item.completed' &&\n event.item?.type === 'agent_message' &&\n event.item.text\n ) {\n textParts.push(event.item.text);\n }\n\n if (event.type === 'turn.completed' && event.usage) {\n const u = event.usage;\n const inputTokens = (u.input_tokens ?? 0) + (u.cached_input_tokens ?? 0);\n const outputTokens = u.output_tokens ?? 0;\n usage = {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n costUsd: 0,\n };\n }\n } catch {\n // Skip malformed JSONL lines\n }\n }\n\n return { sessionId, text: textParts.join('\\n'), usage };\n}\n\nexport { MAX_OUTPUT_BYTES };\n","// packages/core/src/models/cli-detector.ts — Detect codex CLI availability\n\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\n\nexport interface CliDetectionResult {\n available: boolean;\n path?: string;\n version?: string;\n authOk?: boolean;\n detectedAt: number;\n error?: string;\n}\n\n// Cache TTL: 5 minutes\nconst CACHE_TTL = 5 * 60 * 1000;\nconst cache = new Map<string, CliDetectionResult>();\n\nexport async function detectCli(name: 'codex'): Promise<CliDetectionResult> {\n const cached = cache.get(name);\n if (cached && Date.now() - cached.detectedAt < CACHE_TTL) {\n return cached;\n }\n\n const result = await probeCliTool(name);\n cache.set(name, result);\n return result;\n}\n\nexport function clearDetectionCache(): void {\n cache.clear();\n}\n\n/** Exported for testing - get direct access to the cache */\nexport function getCacheForTesting(): Map<string, CliDetectionResult> {\n return cache;\n}\n\nasync function probeCliTool(name: 'codex'): Promise<CliDetectionResult> {\n const now = Date.now();\n\n // Step 1: Find executable\n const whichCmd = process.platform === 'win32' ? 'where' : 'which';\n let exePath: string;\n try {\n const { stdout } = await execFileAsync(whichCmd, [name], { timeout: 5000 });\n exePath = stdout.trim().split('\\n')[0];\n } catch {\n return {\n available: false,\n detectedAt: now,\n error: `${name} not found in PATH`,\n };\n }\n\n // Step 2: Get version\n let version: string | undefined;\n try {\n const { stdout } = await execFileAsync(name, ['--version'], {\n timeout: 5000,\n });\n version = stdout.trim();\n } catch {\n // Version check failed, continue without it\n }\n\n // Step 3: Smoke test (auth check)\n let authOk = false;\n try {\n await execFileAsync(name, ['exec', '--skip-git-repo-check', 'echo ok'], { timeout: 15000 });\n authOk = true;\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n return {\n available: true,\n path: exePath,\n version,\n authOk: false,\n detectedAt: now,\n error: `Auth check failed: ${errMsg}`,\n };\n }\n\n return {\n available: true,\n path: exePath,\n version,\n authOk,\n detectedAt: now,\n };\n}\n","// packages/core/src/models/registry.ts — CLI-only model registry\n\nimport type { ModelConfig, ProjectConfig } from '../types/config.js';\nimport { ModelError } from '../utils/errors.js';\nimport { CliAdapter } from './cli-adapter.js';\nimport { detectCli } from './cli-detector.js';\n\n/** All models are CLI adapters now. */\nexport type ModelAdapter = CliAdapter;\n\nexport class ModelRegistry {\n private models = new Map<string, ModelAdapter>();\n private configs = new Map<string, ModelConfig>();\n private constructor() {}\n\n /**\n * Build a registry from a ProjectConfig.\n * All models are CLI adapters (codex).\n */\n static fromConfig(config: ProjectConfig, projectDir?: string): ModelRegistry {\n const registry = new ModelRegistry();\n for (const [alias, modelConfig] of Object.entries(config.models)) {\n registry.models.set(alias, createCliAdapter(modelConfig, projectDir));\n registry.configs.set(alias, modelConfig);\n }\n return registry;\n }\n\n /**\n * Resolve auto mode — probe codex CLI availability.\n * Kept for API compatibility; all models are CLI now.\n */\n async resolveAutoMode(): Promise<void> {\n // No-op: all models are CLI adapters, no auto detection needed\n }\n\n /** Get the adapter for an alias, or null if not found. */\n tryGetAdapter(alias: string): ModelAdapter | null {\n return this.models.get(alias) ?? null;\n }\n\n /** Get the adapter for an alias. Throws if not found. */\n getAdapter(alias: string): ModelAdapter {\n const adapter = this.models.get(alias);\n if (!adapter) {\n throw new ModelError(\n `Unknown model alias: \"${alias}\". Available: ${[...this.models.keys()].join(', ')}`,\n );\n }\n return adapter;\n }\n\n /** Check if an alias is backed by CLI adapter (always true now). */\n isCliMode(_alias: string): boolean {\n return true;\n }\n\n /** Get the ModelConfig for an alias. */\n getModelConfig(alias: string): ModelConfig {\n const config = this.configs.get(alias);\n if (!config) {\n throw new ModelError(`Unknown model alias: \"${alias}\"`);\n }\n return config;\n }\n\n /** Resolve role -> alias -> ModelAdapter. */\n getAdapterForRole(role: string, config: ProjectConfig): ModelAdapter {\n const roleConfig = config.roles[role];\n if (!roleConfig) {\n throw new ModelError(\n `Unknown role: \"${role}\". Available: ${Object.keys(config.roles).join(', ')}`,\n );\n }\n return this.getAdapter(roleConfig.model);\n }\n\n /** Resolve role -> alias -> ModelConfig. */\n getModelConfigForRole(role: string, config: ProjectConfig): ModelConfig {\n const roleConfig = config.roles[role];\n if (!roleConfig) {\n throw new ModelError(`Unknown role: \"${role}\"`);\n }\n return this.getModelConfig(roleConfig.model);\n }\n\n /** List all registered model aliases. */\n listAliases(): string[] {\n return [...this.models.keys()];\n }\n\n /**\n * Health check: verify codex CLI is available and authenticated.\n */\n async healthCheckAll(): Promise<Map<string, boolean>> {\n const results = new Map<string, boolean>();\n // All models use codex — check once\n const detection = await detectCli('codex');\n const healthy = detection.available && (detection.authOk ?? false);\n for (const alias of this.configs.keys()) {\n results.set(alias, healthy);\n }\n return results;\n }\n}\n\n/** Create a CliAdapter from model config. */\nfunction createCliAdapter(config: ModelConfig, projectDir?: string): CliAdapter {\n const adapterConfig = config.cliAdapter ?? getDefaultCliConfig(projectDir);\n return new CliAdapter({\n command: adapterConfig.command,\n args: adapterConfig.args,\n provider: config.provider,\n model: config.model,\n cliName: 'codex',\n projectDir,\n });\n}\n\n/** Default codex CLI adapter config. */\nfunction getDefaultCliConfig(projectDir?: string): {\n command: string;\n args: string[];\n timeout: number;\n} {\n const ext = process.platform === 'win32' ? '.cmd' : '';\n const args = projectDir ? ['exec'] : ['exec', '--skip-git-repo-check'];\n return {\n command: `codex${ext}`,\n args,\n timeout: 600_000,\n };\n}\n\nexport { createCliAdapter };\n","// packages/core/src/security/retry.ts — Canonical retry policy from MCP architecture\r\n\r\nimport { HTTP_TOO_MANY_REQUESTS } from '../utils/constants.js';\r\nimport { sleep } from '../utils/sleep.js';\r\n\r\nexport interface RetryConfig {\r\n maxRetries: number;\r\n totalAttempts: number;\r\n toolTimeoutMs: number;\r\n onRetry?: (attempt: number, error: unknown, delayMs: number) => void;\r\n}\r\n\r\nexport interface AttemptResult<T> {\r\n result?: T;\r\n error?: Error;\r\n attempts: number;\r\n totalElapsedMs: number;\r\n}\r\n\r\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\r\n maxRetries: 3,\r\n totalAttempts: 5,\r\n toolTimeoutMs: 600_000,\r\n onRetry: undefined,\r\n};\r\n\r\n/**\r\n * Check if an error represents an HTTP 5xx or retryable network error.\r\n */\r\nexport function isRetryable(error: unknown): boolean {\r\n if (error instanceof Error) {\r\n const msg = error.message;\r\n if (msg.includes('ETIMEDOUT') || msg.includes('ECONNRESET') || msg.includes('ECONNREFUSED')) {\r\n return true;\r\n }\r\n }\r\n const status = getStatusCode(error);\r\n if (status !== undefined && status >= 500) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if an error represents an HTTP 429 rate limit.\r\n */\r\nexport function isRateLimit(error: unknown): boolean {\r\n return getStatusCode(error) === HTTP_TOO_MANY_REQUESTS;\r\n}\r\n\r\n/**\r\n * Parse the Retry-After header value from an error, clamped to 60s max.\r\n * Returns delay in milliseconds, or undefined if not found.\r\n */\r\nexport function parseRetryAfter(error: unknown): number | undefined {\r\n const headers = getHeaders(error);\r\n if (!headers) {\r\n return undefined;\r\n }\r\n\r\n const retryAfter =\r\n typeof headers.get === 'function'\r\n ? headers.get('retry-after')\r\n : (headers as Record<string, string>)['retry-after'];\r\n\r\n if (!retryAfter) {\r\n return undefined;\r\n }\r\n\r\n // Try parsing as seconds (integer)\r\n const seconds = Number(retryAfter);\r\n if (!Number.isNaN(seconds) && seconds >= 0) {\r\n return Math.min(seconds * 1000, 60_000);\r\n }\r\n\r\n // Try parsing as HTTP-date\r\n const dateMs = Date.parse(retryAfter);\r\n if (!Number.isNaN(dateMs)) {\r\n const delayMs = dateMs - Date.now();\r\n if (delayMs <= 0) {\r\n return 0;\r\n }\r\n return Math.min(delayMs, 60_000);\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Calculate exponential backoff with jitter.\r\n * Formula: min(1000 * 2^retryCount, 30000) + random jitter [0, 1000]ms\r\n */\r\nexport function calculateBackoff(retryCount: number): number {\r\n const base = Math.min(1000 * 2 ** retryCount, 30_000);\r\n const jitter = Math.floor(Math.random() * 1000);\r\n return base + jitter;\r\n}\r\n\r\n/**\r\n * Execute fn with canonical retry policy:\r\n * - totalAttempts <= 5 (absolute ceiling)\r\n * - 5xx -> retry (up to maxRetries)\r\n * - 429 -> wait-and-resume (parse Retry-After, clamp to 60s, progressive wait if missing)\r\n * - 4xx (except 429) -> fail immediately\r\n * - ETIMEDOUT, ECONNRESET, ECONNREFUSED -> retry\r\n * - Backoff: min(1000 * 2^retryCount, 30000) + random jitter [0, 1000]ms\r\n * - Timeout budget: if remaining < 5s, fail immediately\r\n */\r\nexport async function withCanonicalRetry<T>(\r\n fn: () => Promise<T>,\r\n config?: Partial<RetryConfig>,\r\n): Promise<AttemptResult<T>> {\r\n const cfg: RetryConfig = {\r\n ...DEFAULT_RETRY_CONFIG,\r\n ...config,\r\n };\r\n\r\n // Enforce absolute ceiling\r\n if (cfg.totalAttempts > 5) {\r\n cfg.totalAttempts = 5;\r\n }\r\n\r\n const startTime = Date.now();\r\n let retryCount = 0;\r\n let attemptCount = 0;\r\n\r\n while (attemptCount < cfg.totalAttempts) {\r\n // Check timeout budget before each attempt\r\n const elapsed = Date.now() - startTime;\r\n const remaining = cfg.toolTimeoutMs - elapsed;\r\n if (remaining < 5000) {\r\n return {\r\n error: new Error('Timeout budget exhausted: less than 5s remaining'),\r\n attempts: attemptCount,\r\n totalElapsedMs: Date.now() - startTime,\r\n };\r\n }\r\n\r\n attemptCount++;\r\n\r\n try {\r\n const result = await fn();\r\n return {\r\n result,\r\n attempts: attemptCount,\r\n totalElapsedMs: Date.now() - startTime,\r\n };\r\n } catch (err) {\r\n const error = err instanceof Error ? err : new Error(String(err));\r\n\r\n // 429 rate limit: wait and resume (does NOT count as a retry, but counts as attempt)\r\n if (isRateLimit(err)) {\r\n const retryAfterMs = parseRetryAfter(err);\r\n const delayMs = retryAfterMs ?? calculateBackoff(retryCount);\r\n\r\n if (cfg.onRetry) {\r\n cfg.onRetry(attemptCount, err, delayMs);\r\n }\r\n\r\n await sleep(delayMs);\r\n // Do not increment retryCount for 429\r\n continue;\r\n }\r\n\r\n // 5xx or network error: retry with backoff\r\n if (isRetryable(err) && retryCount < cfg.maxRetries) {\r\n const delayMs = calculateBackoff(retryCount);\r\n\r\n if (cfg.onRetry) {\r\n cfg.onRetry(attemptCount, err, delayMs);\r\n }\r\n\r\n retryCount++;\r\n await sleep(delayMs);\r\n continue;\r\n }\r\n\r\n // 4xx (non-429) or exhausted retries: fail immediately\r\n return {\r\n error,\r\n attempts: attemptCount,\r\n totalElapsedMs: Date.now() - startTime,\r\n };\r\n }\r\n }\r\n\r\n // Should not reach here, but safety net\r\n return {\r\n error: new Error('All attempts exhausted'),\r\n attempts: attemptCount,\r\n totalElapsedMs: Date.now() - startTime,\r\n };\r\n}\r\n\r\n// -- Internal helpers --\r\n\r\nfunction getStatusCode(error: unknown): number | undefined {\r\n if (error && typeof error === 'object') {\r\n const e = error as Record<string, unknown>;\r\n if (typeof e.status === 'number') return e.status;\r\n if (typeof e.statusCode === 'number') return e.statusCode;\r\n if (e.response && typeof e.response === 'object') {\r\n const resp = e.response as Record<string, unknown>;\r\n if (typeof resp.status === 'number') return resp.status;\r\n if (typeof resp.statusCode === 'number') return resp.statusCode;\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction getHeaders(error: unknown): Record<string, string> | Headers | undefined {\r\n if (error && typeof error === 'object') {\r\n const e = error as Record<string, unknown>;\r\n if (e.headers && typeof e.headers === 'object') {\r\n return e.headers as Record<string, string> | Headers;\r\n }\r\n if (e.response && typeof e.response === 'object') {\r\n const resp = e.response as Record<string, unknown>;\r\n if (resp.headers && typeof resp.headers === 'object') {\r\n return resp.headers as Record<string, string> | Headers;\r\n }\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\n","// packages/core/src/models/caller.ts — CLI-only model caller\r\n\r\nimport { withCanonicalRetry } from '../security/retry.js';\r\nimport type { CallModelOptions, ChatMessage, ModelCallResult } from '../types/models.js';\r\nimport { sleep } from '../utils/sleep.js';\r\nimport { CliAdapter } from './cli-adapter.js';\r\nimport type { ModelAdapter } from './registry.js';\r\n\r\n/**\r\n * Callback for receiving streaming text deltas.\r\n */\r\nexport type TextDeltaEmitter = (delta: string) => void;\r\n\r\n/**\r\n * Unified model call: routes to CLI adapter.\r\n */\r\nexport async function callModel(\r\n model: ModelAdapter,\r\n messages: ChatMessage[],\r\n options?: CallModelOptions,\r\n): Promise<ModelCallResult> {\r\n return callCliAdapter(model, messages, options);\r\n}\r\n\r\n/**\r\n * Unified streaming model call.\r\n * CLI: chunked pseudo-streaming (paragraph-split after process completes).\r\n */\r\nexport async function streamModel(\r\n model: ModelAdapter,\r\n messages: ChatMessage[],\r\n onDelta: TextDeltaEmitter,\r\n _stepId: string,\r\n _role: string,\r\n options?: CallModelOptions,\r\n): Promise<ModelCallResult> {\r\n return streamCliAdapter(model, messages, onDelta, options);\r\n}\r\n\r\nasync function callCliAdapter(\r\n adapter: CliAdapter,\r\n messages: ChatMessage[],\r\n options?: CallModelOptions,\r\n): Promise<ModelCallResult> {\r\n const prompt = messagesToPrompt(messages, options?.systemPrompt);\r\n const timeoutMs = (options?.timeout ?? 600) * 1000;\r\n\r\n const attempt = await withCanonicalRetry(() => adapter.call(prompt, { timeout: timeoutMs }), {\r\n maxRetries: 2,\r\n totalAttempts: 3,\r\n toolTimeoutMs: timeoutMs,\r\n });\r\n\r\n if (attempt.error || !attempt.result) {\r\n throw attempt.error ?? new Error('CLI adapter call failed after retries');\r\n }\r\n return { ...attempt.result, meteringSource: 'estimated' };\r\n}\r\n\r\nasync function streamCliAdapter(\r\n adapter: CliAdapter,\r\n messages: ChatMessage[],\r\n onDelta: TextDeltaEmitter,\r\n options?: CallModelOptions,\r\n): Promise<ModelCallResult> {\r\n const result = await callCliAdapter(adapter, messages, options);\r\n\r\n const chunks = result.text.split(/\\n\\n+/).filter(Boolean);\r\n for (const chunk of chunks) {\r\n onDelta(`${chunk}\\n\\n`);\r\n await sleep(50);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction messagesToPrompt(messages: ChatMessage[], systemPrompt?: string): string {\r\n const parts: string[] = [];\r\n if (systemPrompt) parts.push(systemPrompt);\r\n for (const msg of messages) {\r\n if (msg.role === 'system') {\r\n parts.push(msg.content);\r\n } else {\r\n parts.push(`${msg.role.toUpperCase()}: ${msg.content}`);\r\n }\r\n }\r\n return parts.join('\\n\\n');\r\n}\r\n\r\n","// packages/core/src/models/fallback.ts\r\n\r\nimport type { FallbackConfig, ModelCallResult } from '../types/models.js';\r\nimport { ModelError } from '../utils/errors.js';\r\nimport { sleep } from '../utils/sleep.js';\r\n\r\n/**\r\n * Execute a model call with fallback support.\r\n *\r\n * Tries the primary call first. On retryable errors, tries each fallback in order.\r\n * The `callFn` receives the model alias and must perform the actual model call.\r\n */\r\nexport async function withFallback(\r\n callFn: (modelAlias: string) => Promise<ModelCallResult>,\r\n config: FallbackConfig,\r\n): Promise<ModelCallResult> {\r\n const maxRetries = Math.max(1, config.maxRetries);\r\n const allModels = [config.primary, ...config.fallbacks];\r\n let lastError: unknown;\r\n\r\n for (const alias of allModels) {\r\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\r\n try {\r\n return await callFn(alias);\r\n } catch (error) {\r\n lastError = error;\r\n\r\n if (!isRetryable(error, config)) {\r\n throw error;\r\n }\r\n\r\n // If this was the last retry for this model, move to next fallback\r\n if (attempt === maxRetries) break;\r\n\r\n // Exponential backoff between retries\r\n await sleep(1000 * 2 ** (attempt - 1));\r\n }\r\n }\r\n }\r\n\r\n throw new ModelError(\r\n `All models failed. Tried: ${allModels.join(', ')}. Last error: ${lastError instanceof Error ? lastError.message : String(lastError)}`,\r\n );\r\n}\r\n\r\nfunction isRetryable(error: unknown, config: FallbackConfig): boolean {\r\n if (!(error instanceof ModelError)) return false;\r\n\r\n if (config.retryOn.rateLimit && error.isRateLimit) return true;\r\n if (config.retryOn.timeout && error.isTimeout) return true;\r\n if (config.retryOn.serverError && error.isServerError) return true;\r\n\r\n return false;\r\n}\r\n\r\n","// packages/core/src/models/cost-tracker.ts\n\nimport type { CostStore } from '../memory/cost-store.js';\nimport type { ModelCallResult } from '../types/models.js';\n\n/**\n * Wraps model calls and records cost/usage to the CostStore.\n * Created per-session by the Orchestrator.\n */\nexport class CostTracker {\n constructor(\n private costStore: CostStore,\n private sessionId: string,\n ) {}\n\n /**\n * Execute a model call and record its cost.\n * Usage: `costTracker.tracked(() => callModel(model, msgs, opts), 'plan')`\n */\n async tracked(fn: () => Promise<ModelCallResult>, stepId?: string): Promise<ModelCallResult> {\n const result = await fn();\n this.record(result, stepId);\n return result;\n }\n\n /** Record usage from an already-completed model call. */\n record(result: ModelCallResult, stepId?: string): void {\n this.costStore.log({\n sessionId: this.sessionId,\n stepId: stepId ?? null,\n modelId: result.model,\n inputTokens: result.usage.inputTokens,\n outputTokens: result.usage.outputTokens,\n costUsd: result.usage.costUsd,\n latencyMs: result.durationMs,\n });\n }\n}\n","// packages/core/src/models/pricing.ts\n\nexport interface ModelPricing {\n inputPer1M: number;\n outputPer1M: number;\n}\n\n/**\n * Static pricing table for known models (USD per 1M tokens).\n * Updated: 2026-02.\n */\nconst PRICING: Record<string, ModelPricing> = {\n // OpenAI\n 'gpt-5': { inputPer1M: 5, outputPer1M: 15 },\n 'gpt-5-mini': { inputPer1M: 0.3, outputPer1M: 1.2 },\n o3: { inputPer1M: 10, outputPer1M: 40 },\n 'o4-mini': { inputPer1M: 1.1, outputPer1M: 4.4 },\n 'gpt-4o': { inputPer1M: 2.5, outputPer1M: 10 },\n 'gpt-4o-mini': { inputPer1M: 0.15, outputPer1M: 0.6 },\n};\n\nexport function getModelPricing(modelId: string): ModelPricing | null {\n return PRICING[modelId] ?? null;\n}\n\n/**\n * Calculate cost in USD for a model call.\n * Returns 0 if the model is not in the pricing table.\n */\nexport function calculateCost(modelId: string, inputTokens: number, outputTokens: number): number {\n const pricing = getModelPricing(modelId);\n if (!pricing) return 0;\n return (inputTokens * pricing.inputPer1M + outputTokens * pricing.outputPer1M) / 1_000_000;\n}\n","// packages/core/src/roles/prompts.ts\n\nimport type { ChatMessage } from '../types/models.js';\n\n/**\n * The 5 prompt types supported in Sprint 1.\n */\nexport type PromptType = 'plan' | 'plan-review' | 'plan-revision' | 'code' | 'code-review';\n\n/**\n * Variables passed into prompt templates.\n */\nexport interface PromptVariables {\n task: string;\n projectName?: string;\n projectDescription?: string;\n plan?: string;\n previousPlan?: string;\n feedback?: string;\n code?: string;\n}\n\n/**\n * Render a prompt template into ChatMessage[] (system + user messages).\n */\nexport function renderPrompt(type: PromptType, vars: PromptVariables): ChatMessage[] {\n const template = TEMPLATES[type];\n const projectCtx = formatProjectContext(vars.projectName, vars.projectDescription);\n\n return [\n { role: 'system', content: template.system(projectCtx) },\n { role: 'user', content: template.user(vars) },\n ];\n}\n\n// -- Template definitions --\n\ninterface PromptTemplate {\n system: (projectCtx: string) => string;\n user: (vars: PromptVariables) => string;\n}\n\nfunction formatProjectContext(name?: string, description?: string): string {\n if (name && description) return `working on \"${name}\": ${description}`;\n if (name) return `working on \"${name}\"`;\n return '';\n}\n\nconst TEMPLATES: Record<PromptType, PromptTemplate> = {\n /**\n * Architect -- Plan Generation\n */\n plan: {\n system: (ctx) =>\n [\n `You are a senior software architect ${ctx}.`.trim(),\n '',\n 'Given the following task, create a detailed implementation plan.',\n '',\n '## Your plan MUST include these sections:',\n '',\n '### 1. Overview',\n 'What this task accomplishes and why.',\n '',\n '### 2. Technical Approach',\n 'High-level strategy, key design decisions, and tradeoffs.',\n '',\n '### 3. File Changes',\n 'For each file to create or modify:',\n '- **File path**',\n '- **Action**: create | modify',\n '- **Description of changes**',\n '',\n '### 4. Implementation Details',\n 'Step-by-step implementation instructions. Include pseudocode for complex logic.',\n '',\n '### 5. Testing Strategy',\n 'How to verify the implementation works. Specific test cases.',\n '',\n '### 6. Edge Cases & Risks',\n 'Potential issues and how to handle them.',\n ].join('\\n'),\n user: (vars) => `## Task:\\n${vars.task}`,\n },\n\n /**\n * Reviewer -- Plan Review\n */\n 'plan-review': {\n system: (ctx) =>\n [\n `You are a senior technical reviewer ${ctx}.`.trim(),\n '',\n 'Review the following plan for:',\n '- **Correctness**: Is the approach technically sound?',\n '- **Completeness**: Does it address all aspects of the task?',\n '- **Quality**: Is the plan well-structured and actionable?',\n '- **Risks**: Are there overlooked edge cases or potential issues?',\n '',\n 'Provide specific, actionable feedback. Reference plan sections by name.',\n '',\n 'At the END of your review, you MUST include exactly one of these lines:',\n 'VERDICT: APPROVED',\n 'VERDICT: NEEDS_REVISION',\n ].join('\\n'),\n user: (vars) => `## Task:\\n${vars.task}\\n\\n## Plan to Review:\\n${vars.plan ?? ''}`,\n },\n\n /**\n * Architect -- Plan Revision\n */\n 'plan-revision': {\n system: (ctx) =>\n [\n `You are a senior software architect ${ctx}.`.trim(),\n '',\n \"Your previous plan was reviewed and needs revision. Address the reviewer's feedback while keeping the strengths of your original plan.\",\n '',\n 'Produce a revised plan with the same section structure (Overview, Technical Approach, File Changes, Implementation Details, Testing Strategy, Edge Cases & Risks).',\n ].join('\\n'),\n user: (vars) =>\n [\n `## Original Task:\\n${vars.task}`,\n `## Your Previous Plan:\\n${vars.previousPlan ?? ''}`,\n `## Reviewer Feedback:\\n${vars.feedback ?? ''}`,\n ].join('\\n\\n'),\n },\n\n /**\n * Implementer -- Code Generation\n */\n code: {\n system: (ctx) =>\n [\n `You are a senior software developer ${ctx}.`.trim(),\n '',\n 'Based on the following approved plan, write the complete implementation.',\n '',\n '## Rules:',\n '- Write complete file contents, not snippets',\n '- Include all imports and type definitions',\n \"- Follow the project's existing patterns\",\n '- Add comments only where logic is non-obvious',\n '- For each file, use this format:',\n '',\n '### File: path/to/file.ts',\n '```ts',\n '// complete file contents here',\n '```',\n ].join('\\n'),\n user: (vars) => `## Approved Plan:\\n${vars.plan ?? ''}`,\n },\n\n /**\n * Reviewer -- Code Review\n */\n 'code-review': {\n system: (ctx) =>\n [\n `You are a senior code reviewer ${ctx}.`.trim(),\n '',\n 'Review the following implementation for:',\n '- **Correctness**: Does it implement the plan correctly?',\n '- **Bugs**: Logic errors, off-by-one, race conditions?',\n '- **Security**: OWASP Top 10 issues?',\n '- **Performance**: Obvious performance problems?',\n '- **Quality**: Clean code, error handling, naming?',\n '',\n 'Provide specific feedback with file names and references.',\n '',\n 'At the END of your review, you MUST include exactly one of:',\n 'VERDICT: APPROVED',\n 'VERDICT: NEEDS_REVISION',\n ].join('\\n'),\n user: (vars) =>\n [\n `## Task:\\n${vars.task}`,\n `## Approved Plan:\\n${vars.plan ?? ''}`,\n `## Implementation to Review:\\n${vars.code ?? ''}`,\n ].join('\\n\\n'),\n },\n};\n","// packages/core/src/roles/role-manager.ts\n\nimport type { ProjectConfig, RoleConfig } from '../types/config.js';\nimport type { ChatMessage } from '../types/models.js';\nimport type { BuiltInRole, Role } from '../types/roles.js';\nimport { DEFAULT_MAX_TOKENS } from '../utils/constants.js';\nimport { ModelError } from '../utils/errors.js';\nimport type { PromptType, PromptVariables } from './prompts.js';\nimport { renderPrompt } from './prompts.js';\n\n/**\n * Built-in role definitions with default descriptions.\n */\nconst BUILT_IN_ROLES: Record<BuiltInRole, { description: string }> = {\n architect: { description: 'Plans implementation strategy and technical approach' },\n reviewer: { description: 'Reviews plans and code for correctness, quality, and risks' },\n implementer: { description: 'Writes production code based on approved plans' },\n};\n\n/**\n * Resolves roles from config, provides prompt rendering and message assembly.\n */\nexport class RoleManager {\n constructor(private config: ProjectConfig) {}\n\n /**\n * Resolve a role name to a fully hydrated Role object.\n * Merges built-in defaults with config overrides.\n */\n getRole(roleName: string): Role {\n const roleConfig = this.config.roles[roleName];\n if (!roleConfig) {\n throw new ModelError(\n `Unknown role: \"${roleName}\". Available: ${Object.keys(this.config.roles).join(', ')}`,\n );\n }\n\n const builtIn = BUILT_IN_ROLES[roleName as BuiltInRole];\n const modelConfig = this.config.models[roleConfig.model];\n\n return {\n id: roleName,\n description: builtIn?.description ?? `Custom role: ${roleName}`,\n modelAlias: roleConfig.model,\n systemPrompt: buildRoleIdentity(roleName, builtIn?.description),\n temperature: roleConfig.temperature ?? modelConfig?.temperature ?? 0.7,\n maxTokens: roleConfig.maxTokens ?? modelConfig?.maxTokens ?? DEFAULT_MAX_TOKENS,\n };\n }\n\n /**\n * Build a ChatMessage[] for a model call.\n * Renders the appropriate prompt template with project context and variables.\n */\n buildMessages(promptType: PromptType, vars: PromptVariables): ChatMessage[] {\n return renderPrompt(promptType, {\n ...vars,\n projectName: vars.projectName ?? this.config.project.name,\n projectDescription: vars.projectDescription ?? this.config.project.description,\n });\n }\n\n /** List all configured role names. */\n listRoles(): string[] {\n return Object.keys(this.config.roles);\n }\n\n /** Get the RoleConfig for a role name. */\n getRoleConfig(roleName: string): RoleConfig {\n const roleConfig = this.config.roles[roleName];\n if (!roleConfig) {\n throw new ModelError(`Unknown role: \"${roleName}\"`);\n }\n return roleConfig;\n }\n}\n\nfunction buildRoleIdentity(roleName: string, description?: string): string {\n if (description) {\n return `You are a ${roleName}. ${description}.`;\n }\n return `You are a ${roleName}.`;\n}\n","// packages/core/src/engine/event-bus.ts\n\nimport { EventEmitter } from 'eventemitter3';\nimport type { EngineEvent } from '../types/events.js';\n\ninterface EventBusEvents {\n event: (event: EngineEvent) => void;\n}\n\n/**\n * Typed event bus for AG-UI compatible engine events.\n * Wraps eventemitter3 with typed EngineEvent emission.\n */\nexport class EventBus extends EventEmitter<EventBusEvents> {\n /** Emit a typed AG-UI event, auto-injecting timestamp if missing. */\n emitEvent(event: EngineEvent): void {\n const timestamped =\n 'timestamp' in event && !event.timestamp\n ? { ...event, timestamp: new Date().toISOString() }\n : event;\n this.emit('event', timestamped);\n }\n}\n","// packages/core/src/engine/loop-controller.ts\n\nimport type { ResolvedStep } from '../types/workflow.js';\nimport type { EventBus } from './event-bus.js';\nimport type { StepResult, StepRunner } from './step-runner.js';\n\nexport interface LoopResult {\n finalOutput: string;\n iterations: number;\n approved: boolean;\n history: StepResult[];\n}\n\nexport class LoopController {\n async executeLoop(\n generateStep: ResolvedStep,\n reviewStep: ResolvedStep,\n inputs: Map<string, string>,\n task: string,\n maxIterations: number,\n runner: StepRunner,\n eventBus: EventBus,\n ): Promise<LoopResult> {\n const history: StepResult[] = [];\n let currentInputs = new Map(inputs);\n let approved = false;\n\n for (let iteration = 1; iteration <= maxIterations; iteration++) {\n // Run generate step\n const generateResult = await runner.execute(generateStep, currentInputs, task, iteration);\n history.push(generateResult);\n\n // Build review inputs with the generated output\n const reviewInputs = new Map<string, string>();\n reviewInputs.set(generateStep.definition.id, generateResult.output);\n\n // Run review step\n const reviewResult = await runner.execute(reviewStep, reviewInputs, task, iteration);\n history.push(reviewResult);\n\n const verdict = reviewResult.verdict ?? 'needs_revision';\n\n // Emit loop.iteration event\n eventBus.emitEvent({\n type: 'loop.iteration',\n stepId: reviewStep.definition.id,\n iteration,\n maxIterations,\n verdict,\n feedback: reviewResult.feedback,\n timestamp: '',\n });\n\n if (verdict === 'approved') {\n approved = true;\n return {\n finalOutput: generateResult.output,\n iterations: iteration,\n approved,\n history,\n };\n }\n\n // If not approved and not at max, prepare inputs for next iteration\n if (iteration < maxIterations) {\n currentInputs = new Map<string, string>();\n currentInputs.set(generateStep.definition.id, generateResult.output);\n currentInputs.set('feedback', reviewResult.feedback ?? reviewResult.output);\n }\n }\n\n // Max iterations reached without approval\n const lastGenerateResult = history[history.length - 2];\n return {\n finalOutput: lastGenerateResult.output,\n iterations: maxIterations,\n approved: false,\n history,\n };\n }\n}\n","// packages/core/src/engine/orchestrator.ts\n\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type Database from 'better-sqlite3';\nimport { EventEmitter } from 'eventemitter3';\nimport { ContextBuilder } from '../context/context-builder.js';\nimport { ArtifactStore } from '../memory/artifact-store.js';\nimport { CostStore } from '../memory/cost-store.js';\nimport { MemoryStore } from '../memory/memory-store.js';\nimport { SessionStore } from '../memory/session-store.js';\nimport { callModel } from '../models/caller.js';\nimport { CliAdapter } from '../models/cli-adapter.js';\nimport { CostTracker } from '../models/cost-tracker.js';\nimport type { ModelRegistry } from '../models/registry.js';\nimport { RoleManager } from '../roles/role-manager.js';\nimport { sanitize } from '../security/dlp.js';\nimport type { ExecutionMode, ProjectConfig } from '../types/config.js';\nimport type { DebateEngineInput, DebateEngineResult, DebateIO } from '../types/debate.js';\nimport type { EngineEvent } from '../types/events.js';\nimport type { DebateResponse, DebateResult, MeteringSource, ReviewResult } from '../types/mcp.js';\nimport { parseVerdict } from '../utils/verdict.js';\nimport type { CancellationToken } from './cancellation.js';\nimport { ProposalCritiqueEngine } from './debate-engine.js';\nimport { EventBus } from './event-bus.js';\nimport { LoopController } from './loop-controller.js';\nimport { StepRunner } from './step-runner.js';\nimport { WorkflowEngine } from './workflow-engine.js';\n\nconst currentDir = dirname(fileURLToPath(import.meta.url));\n\ninterface OrchestratorEvents {\n event: (event: EngineEvent) => void;\n}\n\nexport interface OrchestratorOptions {\n registry: ModelRegistry;\n db: Database.Database;\n config: ProjectConfig;\n workflowDir?: string;\n projectDir?: string;\n}\n\nexport interface RunOptions {\n mode?: ExecutionMode;\n maxIterations?: number;\n stream?: boolean;\n workflowDir?: string;\n}\n\nexport interface PlanOptions {\n maxRounds?: number;\n stream?: boolean;\n workflowDir?: string;\n}\n\nexport interface SessionResult {\n sessionId: string;\n status: 'completed' | 'failed';\n finalOutput: string;\n totalCost: number;\n totalTokens: number;\n durationMs: number;\n iterations: number;\n error?: string;\n lastStep?: string;\n}\n\nexport interface ReviewOptions {\n criteria?: string[];\n model?: string;\n strict?: boolean;\n timeout?: number;\n}\n\nexport interface DebateOptions {\n modelAliases?: string[];\n synthesize?: boolean;\n timeout?: number;\n maxConcurrency?: number;\n}\n\ntype SessionPhase = 'plan-review' | 'implement' | 'code-review';\n\nconst DEFAULT_MAX_CLI_CONCURRENCY = 3;\nconst DEFAULT_MAX_API_CONCURRENCY = 5;\n\n/** Promise-based semaphore — replaces busy-wait polling. */\nclass AsyncSemaphore {\n private queue: Array<() => void> = [];\n private running = 0;\n\n constructor(private max: number) {}\n\n async acquire(): Promise<void> {\n if (this.running < this.max) {\n this.running++;\n return;\n }\n return new Promise<void>((resolve) => {\n this.queue.push(() => {\n this.running++;\n resolve();\n });\n });\n }\n\n release(): void {\n this.running--;\n const next = this.queue.shift();\n if (next) next();\n }\n}\n\nexport class Orchestrator extends EventEmitter<OrchestratorEvents> {\n private registry: ModelRegistry;\n private config: ProjectConfig;\n private sessionStore: SessionStore;\n private artifactStore: ArtifactStore;\n private costStore: CostStore;\n private memoryStore: MemoryStore;\n private roleManager: RoleManager;\n private workflowEngine: WorkflowEngine;\n private eventBus: EventBus;\n private contextBuilder: ContextBuilder;\n\n constructor(options: OrchestratorOptions) {\n super();\n this.registry = options.registry;\n this.config = options.config;\n this.sessionStore = new SessionStore(options.db);\n this.artifactStore = new ArtifactStore(options.db);\n this.costStore = new CostStore(options.db);\n this.memoryStore = new MemoryStore(options.db);\n this.roleManager = new RoleManager(options.config);\n\n const resolvedDir =\n options.workflowDir ??\n (options.projectDir\n ? resolve(options.projectDir, 'workflows')\n : resolve(currentDir, '../../../workflows'));\n this.workflowEngine = new WorkflowEngine(resolvedDir);\n this.eventBus = new EventBus();\n\n // Context builder for enriching prompts with memories + codebase context\n this.contextBuilder = new ContextBuilder({\n projectDir: options.projectDir,\n projectId: options.config.project.name || 'default',\n memoryStore: this.memoryStore,\n });\n\n // Forward all events from eventBus to this orchestrator\n this.eventBus.on('event', (event) => this.emit('event', event));\n }\n\n async run(task: string, options?: RunOptions): Promise<SessionResult> {\n return this.executeSession(task, ['plan-review', 'implement', 'code-review'], {\n maxIterations: options?.maxIterations,\n stream: options?.stream,\n mode: options?.mode,\n });\n }\n\n async plan(task: string, options?: PlanOptions): Promise<SessionResult> {\n return this.executeSession(task, ['plan-review'], {\n maxIterations: options?.maxRounds,\n stream: options?.stream,\n });\n }\n\n /**\n * Review content with a single model.\n * DLP-sanitizes content first (strict mode by default).\n */\n async review(\n content: string,\n options?: ReviewOptions,\n cancellationToken?: CancellationToken,\n ): Promise<ReviewResult> {\n const start = Date.now();\n\n // DLP sanitize\n const dlpMode = options?.strict !== false ? 'strict' : 'open';\n const dlpResult = sanitize(content, { mode: dlpMode });\n const sanitizedContent = dlpResult.sanitized;\n\n // Check cancellation\n if (cancellationToken?.isCancelled) {\n throw new Error('Review cancelled');\n }\n\n // Resolve model\n const alias = options?.model ?? this.resolveReviewerAlias();\n const adapter = this.registry.getAdapter(alias);\n const isCli = adapter instanceof CliAdapter;\n const meteringSource: MeteringSource = isCli ? 'estimated' : 'billed';\n\n // Build review prompt\n const criteriaText = options?.criteria?.length\n ? `Review criteria:\\n${options.criteria.map((c) => `- ${c}`).join('\\n')}`\n : '';\n const basePrompt = [\n 'Review the following content carefully.',\n criteriaText,\n 'Provide a score from 1-10, specific feedback points, and a final VERDICT.',\n 'Format your verdict as either \"VERDICT: APPROVED\" or \"VERDICT: NEEDS_REVISION\".',\n '',\n 'Content to review:',\n sanitizedContent,\n ]\n .filter(Boolean)\n .join('\\n');\n\n // Enrich with project context and memories\n const assembled = this.contextBuilder.assemble(basePrompt, 'review');\n const messages = [{ role: 'user' as const, content: assembled.prompt }];\n\n // Call model\n const result = await callModel(adapter, messages);\n\n // Parse verdict — wrap in try/catch so LLM output variance doesn't crash\n let verdict: { verdict: 'approved' | 'needs_revision'; feedback: string };\n try {\n verdict = parseVerdict(result.text);\n } catch {\n verdict = { verdict: 'needs_revision', feedback: result.text.slice(0, 500) };\n }\n\n // Score extraction: try multiple patterns (X/10, X out of 10, score: X, Score: X.X)\n const scorePatterns = [\n /\\b(\\d+)\\s*\\/\\s*10\\b/,\n /\\b(\\d+)\\s+out\\s+of\\s+10\\b/i,\n /score[:\\s]+(\\d+(?:\\.\\d+)?)/i,\n ];\n let score: number | undefined;\n for (const pattern of scorePatterns) {\n const match = pattern.exec(result.text);\n if (match) {\n score = Math.round(Number.parseFloat(match[1]));\n break;\n }\n }\n if (score === undefined) {\n score = verdict.verdict === 'approved' ? 8 : 5;\n }\n\n const feedback = result.text\n .split('\\n')\n .filter((line) => line.trim().startsWith('-') || line.trim().startsWith('*'))\n .map((line) => line.trim().replace(/^[-*]\\s*/, ''));\n\n // Auto-save review findings as memory (with dedup)\n if (feedback.length > 0 && score <= 7) {\n const projectId = this.config.project.name || 'default';\n const memorySummary = `Review (${score}/10, ${verdict.verdict}): ${feedback.slice(0, 3).join('; ')}`;\n this.saveMemoryIfNew(projectId, 'issue', memorySummary, score <= 5 ? 0.8 : 0.5);\n }\n\n return {\n status: 'success',\n score,\n verdict: verdict.verdict,\n feedback: feedback.length > 0 ? feedback : [verdict.feedback || result.text.slice(0, 200)],\n tokenUsage: result.usage,\n latencyMs: Date.now() - start,\n meteringSource,\n model: result.model,\n egressControl: isCli ? 'cli-managed' : 'codemoot-enforced',\n };\n }\n\n /**\n * Debate a question across multiple models.\n * DLP-sanitizes question first. Runs models concurrently with async semaphore.\n */\n async debate(\n question: string,\n options?: DebateOptions,\n cancellationToken?: CancellationToken,\n ): Promise<DebateResult> {\n // DLP sanitize\n const dlpResult = sanitize(question, { mode: 'strict' });\n const sanitizedQuestion = dlpResult.sanitized;\n\n // Check cancellation\n if (cancellationToken?.isCancelled) {\n throw new Error('Debate cancelled');\n }\n\n // Resolve model aliases\n const aliases = options?.modelAliases ?? this.resolveDebateAliases();\n if (aliases.length < 1) {\n throw new Error(\n `Debate requires at least 1 model. Available: ${this.registry.listAliases().join(', ')}`,\n );\n }\n\n // Enrich question with project context and memories\n const assembled = this.contextBuilder.assemble(sanitizedQuestion, 'debate');\n const enrichedQuestion = assembled.prompt;\n\n const maxCliConcurrency =\n options?.maxConcurrency ??\n Number(process.env.CODEMOOT_MAX_CLI_CONCURRENCY ?? DEFAULT_MAX_CLI_CONCURRENCY);\n const maxApiConcurrency = DEFAULT_MAX_API_CONCURRENCY;\n\n // Async semaphores for concurrency control\n const cliSemaphore = new AsyncSemaphore(maxCliConcurrency);\n const apiSemaphore = new AsyncSemaphore(maxApiConcurrency);\n\n const callWithSemaphore = async (alias: string): Promise<DebateResponse> => {\n const adapter = this.registry.getAdapter(alias);\n const isCli = adapter instanceof CliAdapter;\n const meteringSource: MeteringSource = isCli ? 'estimated' : 'billed';\n const config = this.registry.getModelConfig(alias);\n const semaphore = isCli ? cliSemaphore : apiSemaphore;\n\n await semaphore.acquire();\n const callStart = Date.now();\n try {\n if (cancellationToken?.isCancelled) {\n throw new Error('Debate cancelled');\n }\n\n const messages = [{ role: 'user' as const, content: enrichedQuestion }];\n const result = await callModel(adapter, messages);\n\n return {\n model: config.model,\n role: alias,\n text: result.text,\n tokenUsage: result.usage,\n latencyMs: Date.now() - callStart,\n meteringSource,\n };\n } catch (err) {\n return {\n model: config.model,\n role: alias,\n text: '',\n tokenUsage: { inputTokens: 0, outputTokens: 0, totalTokens: 0, costUsd: 0 },\n latencyMs: Date.now() - callStart,\n meteringSource,\n error: err instanceof Error ? err.message : String(err),\n };\n } finally {\n semaphore.release();\n }\n };\n\n // Run all models concurrently\n const results = await Promise.allSettled(aliases.map(callWithSemaphore));\n const responses: DebateResponse[] = results.map((r) =>\n r.status === 'fulfilled'\n ? r.value\n : {\n model: 'unknown',\n role: 'unknown',\n text: '',\n tokenUsage: { inputTokens: 0, outputTokens: 0, totalTokens: 0, costUsd: 0 },\n latencyMs: 0,\n meteringSource: 'estimated' as MeteringSource,\n error: r.reason instanceof Error ? r.reason.message : String(r.reason),\n },\n );\n\n const successfulResponses = responses.filter((r) => !r.error);\n const partialFailure = successfulResponses.length < responses.length;\n\n if (successfulResponses.length === 0) {\n const errors = responses.map((r) => `${r.role}: ${r.error}`).join('; ');\n throw new Error(`All models failed in debate: ${errors}`);\n }\n\n // Aggregate token usage\n const totalTokenUsage = {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n costUsd: 0,\n };\n for (const r of responses) {\n totalTokenUsage.inputTokens += r.tokenUsage.inputTokens;\n totalTokenUsage.outputTokens += r.tokenUsage.outputTokens;\n totalTokenUsage.totalTokens += r.tokenUsage.totalTokens;\n totalTokenUsage.costUsd += r.tokenUsage.costUsd;\n }\n\n // Optional synthesis\n let synthesis: string | undefined;\n if (options?.synthesize && successfulResponses.length > 1) {\n const synthPrompt = [\n 'Synthesize the following responses into a unified answer:',\n '',\n ...successfulResponses.map((r, i) => `Response ${i + 1} (${r.model}):\\n${r.text}`),\n ].join('\\n\\n');\n\n // Use first available model for synthesis\n const synthAdapter = this.registry.getAdapter(aliases[0]);\n const synthResult = await callModel(synthAdapter, [{ role: 'user', content: synthPrompt }]);\n synthesis = synthResult.text;\n\n totalTokenUsage.inputTokens += synthResult.usage.inputTokens;\n totalTokenUsage.outputTokens += synthResult.usage.outputTokens;\n totalTokenUsage.totalTokens += synthResult.usage.totalTokens;\n totalTokenUsage.costUsd += synthResult.usage.costUsd;\n }\n\n // Determine egress control — if any model uses CLI, report mixed\n const hasCliModel = aliases.some((a) => this.registry.isCliMode(a));\n const egressControl = hasCliModel ? 'cli-managed' : 'codemoot-enforced';\n\n return {\n status: partialFailure ? 'partial' : 'success',\n responses,\n synthesis,\n totalTokenUsage,\n partialFailure,\n egressControl,\n };\n }\n\n /**\n * Multi-round debate: models see and respond to each other's arguments.\n * Uses proposal-critique pattern: proposer → critic → revise → critique → ...\n * Models iterate until convergence (critic approves) or max rounds.\n */\n async debateMultiRound(\n question: string,\n options?: {\n modelAliases?: string[];\n maxRounds?: number;\n timeout?: number;\n },\n ): Promise<DebateEngineResult> {\n // DLP sanitize\n const dlpResult = sanitize(question, { mode: 'strict' });\n const sanitizedQuestion = dlpResult.sanitized;\n\n // Enrich with project context\n const assembled = this.contextBuilder.assemble(sanitizedQuestion, 'debate');\n const enrichedQuestion = assembled.prompt;\n\n // Resolve aliases: need at least 2 for proposal-critique\n const aliases = options?.modelAliases ?? this.resolveDebateAliases();\n if (aliases.length < 2) {\n throw new Error(\n `Multi-round debate requires at least 2 models. Available: ${this.registry.listAliases().join(', ')}`,\n );\n }\n\n // Build DebateIO adapter that wraps our callModel + registry\n const io: DebateIO = {\n generate: async (modelAlias, messages, timeoutMs) => {\n const adapter = this.registry.getAdapter(modelAlias);\n const chatMessages = messages.map((m) => ({\n role: m.role as 'system' | 'user',\n content: m.content,\n }));\n const result = await callModel(adapter, chatMessages, {\n timeout: Math.ceil(timeoutMs / 1000),\n });\n return {\n text: result.text,\n promptTokens: result.usage.inputTokens,\n completionTokens: result.usage.outputTokens,\n };\n },\n };\n\n // Create and run the debate engine\n const engine = new ProposalCritiqueEngine({\n maxRounds: options?.maxRounds ?? this.config.debate.maxRounds,\n maxWallClockMs: (options?.timeout ?? 600) * 1000,\n });\n\n const input: DebateEngineInput = {\n debateId: `debate_${Date.now()}`,\n question: enrichedQuestion,\n models: aliases.slice(0, 2), // proposal-critique uses exactly 2\n };\n\n return engine.run(input, io);\n }\n\n /** Resolve the default reviewer model alias from roles config. */\n private resolveReviewerAlias(): string {\n const reviewerRole = this.config.roles.reviewer;\n if (reviewerRole) return reviewerRole.model;\n // Fallback to first available alias\n const aliases = this.registry.listAliases();\n if (aliases.length === 0) {\n throw new Error('No models configured for review');\n }\n return aliases[0];\n }\n\n /** Resolve debate aliases — all configured model aliases. */\n private resolveDebateAliases(): string[] {\n return this.registry.listAliases();\n }\n\n /**\n * Save a memory only if no similar entry already exists (content-prefix dedup).\n * Uses SQL LIKE prefix match instead of FTS5 for reliable exact matching.\n */\n private saveMemoryIfNew(\n projectId: string,\n category: 'issue' | 'convention' | 'decision' | 'pattern' | 'preference',\n content: string,\n importance: number,\n ): void {\n const prefix = content.slice(0, 80);\n const existing = this.memoryStore.findByPrefix(projectId, category, prefix);\n if (!existing) {\n this.memoryStore.save({\n projectId,\n category,\n content,\n sourceSessionId: null,\n importance,\n });\n }\n }\n\n /**\n * Shared session lifecycle for run() and plan().\n * Extracts common session creation, workflow loading, cost tracking, and completion.\n */\n private async executeSession(\n task: string,\n phases: SessionPhase[],\n options: { maxIterations?: number; stream?: boolean; mode?: ExecutionMode },\n ): Promise<SessionResult> {\n const startTime = Date.now();\n const maxIterations = options.maxIterations ?? this.config.debate.maxRounds ?? 3;\n const stream = options.stream ?? this.config.advanced.stream;\n\n // 1. Create session\n const session = this.sessionStore.create({\n projectId: this.config.project.name || 'default',\n workflowId: 'plan-review-implement',\n task,\n mode: options.mode ?? this.config.mode,\n config: this.config,\n });\n\n // 2. Emit session.started\n this.eventBus.emitEvent({\n type: 'session.started',\n sessionId: session.id,\n workflow: 'plan-review-implement',\n task,\n timestamp: new Date().toISOString(),\n });\n\n let currentStep = 'init';\n\n try {\n // 3. Load workflow\n const workflow = this.workflowEngine.load('plan-review-implement');\n const steps = this.workflowEngine.getExecutionOrder(workflow);\n\n // 4. Create step runner and cost tracker\n const costTracker = new CostTracker(this.costStore, session.id);\n const stepRunner = new StepRunner(\n this.registry,\n this.roleManager,\n costTracker,\n this.eventBus,\n this.sessionStore,\n this.config,\n session.id,\n );\n const loopController = new LoopController();\n\n // 5. Execute requested phases\n let totalIterations = 0;\n let finalOutput = '';\n const inputs = new Map<string, string>();\n\n const planStep = steps.find((s) => s.definition.id === 'plan');\n const reviewPlanStep = steps.find((s) => s.definition.id === 'review-plan');\n const implementStep = steps.find((s) => s.definition.id === 'implement');\n const codeReviewStep = steps.find((s) => s.definition.id === 'code-review');\n\n // Phase: Plan + Review Loop\n if (phases.includes('plan-review') && planStep && reviewPlanStep) {\n currentStep = 'plan';\n this.sessionStore.updateCurrentStep(session.id, 'plan');\n const planLoop = await loopController.executeLoop(\n planStep,\n reviewPlanStep,\n inputs,\n task,\n maxIterations,\n stepRunner,\n this.eventBus,\n );\n inputs.set('plan.output', planLoop.finalOutput);\n totalIterations += planLoop.iterations;\n finalOutput = planLoop.finalOutput;\n\n this.artifactStore.save({\n sessionId: session.id,\n stepId: 'plan',\n iteration: planLoop.iterations,\n type: 'plan',\n filePath: null,\n content: planLoop.finalOutput,\n version: 1,\n metadata: null,\n });\n }\n\n // Phase: Implement\n if (phases.includes('implement') && implementStep) {\n currentStep = 'implement';\n this.sessionStore.updateCurrentStep(session.id, 'implement');\n const implResult = await stepRunner.execute(implementStep, inputs, task, 1, { stream });\n inputs.set('implement.output', implResult.output);\n finalOutput = implResult.output;\n\n this.artifactStore.save({\n sessionId: session.id,\n stepId: 'implement',\n iteration: 1,\n type: 'code',\n filePath: null,\n content: implResult.output,\n version: 1,\n metadata: null,\n });\n }\n\n // Phase: Code Review Loop\n if (phases.includes('code-review') && implementStep && codeReviewStep) {\n currentStep = 'code-review';\n this.sessionStore.updateCurrentStep(session.id, 'code-review');\n const codeLoop = await loopController.executeLoop(\n implementStep,\n codeReviewStep,\n inputs,\n task,\n maxIterations,\n stepRunner,\n this.eventBus,\n );\n totalIterations += codeLoop.iterations;\n finalOutput = codeLoop.finalOutput;\n\n this.artifactStore.save({\n sessionId: session.id,\n stepId: 'code-review',\n iteration: codeLoop.iterations,\n type: 'review',\n filePath: null,\n content: codeLoop.finalOutput,\n version: 1,\n metadata: null,\n });\n }\n\n // 6. Complete session\n const costSummary = this.costStore.getSessionSummary(session.id);\n const totalCost = costSummary.reduce((sum, s) => sum + s.totalCost, 0);\n const totalTokens = costSummary.reduce(\n (sum, s) => sum + s.totalInputTokens + s.totalOutputTokens,\n 0,\n );\n\n this.sessionStore.complete(session.id, finalOutput.slice(0, 500));\n this.sessionStore.addUsage(session.id, totalCost, totalTokens);\n\n const durationMs = Date.now() - startTime;\n\n this.eventBus.emitEvent({\n type: 'session.completed',\n sessionId: session.id,\n finalOutput,\n totalCost,\n totalTokens,\n durationMs,\n timestamp: new Date().toISOString(),\n });\n\n return {\n sessionId: session.id,\n status: 'completed',\n finalOutput,\n totalCost,\n totalTokens,\n durationMs,\n iterations: totalIterations,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n this.sessionStore.updateStatus(session.id, 'failed');\n\n this.eventBus.emitEvent({\n type: 'session.failed',\n sessionId: session.id,\n error: errorMessage,\n lastStep: currentStep,\n timestamp: new Date().toISOString(),\n });\n\n return {\n sessionId: session.id,\n status: 'failed',\n finalOutput: '',\n totalCost: 0,\n totalTokens: 0,\n durationMs: Date.now() - startTime,\n iterations: 0,\n error: errorMessage,\n lastStep: currentStep,\n };\n }\n }\n}\n","// packages/core/src/context/context-builder.ts — Assembles enriched prompts with memory + codebase context\n\nimport { readFileSync, readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { MemoryStore } from '../memory/memory-store.js';\nimport type { MemoryRecord } from '../types/memory.js';\nimport { CONTEXT_ACTIVE, CONTEXT_BUFFER, CONTEXT_RETRIEVED } from '../utils/constants.js';\n\n/** Token budget tiers for context assembly. */\nexport interface ContextBudget {\n /** Max tokens for tier 1: task + memories. Default 2000 */\n tier1: number;\n /** Max tokens for tier 2: file tree + snippets. Default 4000 */\n tier2: number;\n /** Max total tokens for assembled context. Default 8000 */\n total: number;\n}\n\nexport interface ContextBuilderOptions {\n projectDir?: string;\n projectId?: string;\n memoryStore?: MemoryStore;\n budget?: Partial<ContextBudget>;\n /** Max depth for file tree traversal. Default 3 */\n maxTreeDepth?: number;\n /** Max number of files to include in tree. Default 200 */\n maxFiles?: number;\n /** File extensions to include in tree. Default: common code extensions */\n includeExtensions?: string[];\n}\n\nexport interface AssembledContext {\n /** The enriched prompt with context prepended */\n prompt: string;\n /** Memories that were injected */\n memories: MemoryRecord[];\n /** File tree summary (if generated) */\n fileTree: string;\n /** Estimated token count of the assembled context */\n estimatedTokens: number;\n}\n\nconst DEFAULT_BUDGET: ContextBudget = {\n tier1: CONTEXT_BUFFER,\n tier2: CONTEXT_RETRIEVED,\n total: CONTEXT_ACTIVE,\n};\n\nconst DEFAULT_EXTENSIONS = new Set([\n '.ts',\n '.tsx',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n '.py',\n '.rs',\n '.go',\n '.java',\n '.kt',\n '.swift',\n '.json',\n '.yaml',\n '.yml',\n '.toml',\n '.md',\n]);\n\nconst IGNORE_DIRS = new Set([\n 'node_modules',\n '.git',\n 'dist',\n 'build',\n 'coverage',\n '.next',\n '.turbo',\n '.cache',\n '__pycache__',\n '.venv',\n 'target',\n 'vendor',\n]);\n\n/**\n * Builds enriched prompts by assembling relevant context from:\n * - Tier 1: Task framing + relevant memories from SQLite FTS\n * - Tier 2: Project file tree + relevant code snippets\n * - Tier 3: (Future) On-demand expansion when model requests more context\n */\nexport class ContextBuilder {\n private projectDir: string | undefined;\n private projectId: string;\n private memoryStore: MemoryStore | undefined;\n private budget: ContextBudget;\n private maxTreeDepth: number;\n private maxFiles: number;\n private includeExtensions: Set<string>;\n\n constructor(options: ContextBuilderOptions) {\n this.projectDir = options.projectDir;\n this.projectId = options.projectId ?? 'default';\n this.memoryStore = options.memoryStore;\n this.budget = { ...DEFAULT_BUDGET, ...options.budget };\n this.maxTreeDepth = options.maxTreeDepth ?? 3;\n this.maxFiles = options.maxFiles ?? 200;\n this.includeExtensions = options.includeExtensions\n ? new Set(options.includeExtensions)\n : DEFAULT_EXTENSIONS;\n }\n\n /**\n * Assemble enriched context for a model call.\n * @param taskPrompt The original prompt/task\n * @param taskType Context about what kind of task (review, debate, plan)\n */\n assemble(taskPrompt: string, taskType?: string): AssembledContext {\n const sections: string[] = [];\n let totalChars = 0;\n const memories: MemoryRecord[] = [];\n\n // -- Tier 1: Memories --\n if (this.memoryStore) {\n const tier1Budget = this.budget.tier1 * 4; // chars (rough token-to-char ratio)\n const relevantMemories = this.queryMemories(taskPrompt, tier1Budget);\n if (relevantMemories.length > 0) {\n const memorySection = this.formatMemories(relevantMemories);\n sections.push(memorySection);\n totalChars += memorySection.length;\n memories.push(...relevantMemories);\n }\n }\n\n // -- Tier 2: File tree + project context --\n let fileTree = '';\n if (this.projectDir && totalChars < this.budget.total * 4) {\n const tier2Budget = Math.min(this.budget.tier2 * 4, this.budget.total * 4 - totalChars);\n\n fileTree = this.buildFileTree();\n if (fileTree && fileTree.length <= tier2Budget) {\n const treeSection = `## Project Structure\\n\\`\\`\\`\\n${fileTree}\\`\\`\\``;\n sections.push(treeSection);\n totalChars += treeSection.length;\n }\n }\n\n // -- Assemble final prompt --\n const contextPrefix = sections.length > 0 ? `${sections.join('\\n\\n')}\\n\\n---\\n\\n` : '';\n\n // Add task type framing if provided\n const taskFrame = taskType ? `[Task type: ${taskType}]\\n\\n` : '';\n\n const prompt = `${contextPrefix}${taskFrame}${taskPrompt}`;\n const estimatedTokens = Math.ceil(prompt.length / 4);\n\n return {\n prompt,\n memories,\n fileTree,\n estimatedTokens,\n };\n }\n\n /** Query relevant memories using FTS5 search. */\n private queryMemories(query: string, charBudget: number): MemoryRecord[] {\n if (!this.memoryStore) return [];\n\n // Extract key terms from the query for FTS search\n const searchTerms = this.extractSearchTerms(query);\n if (!searchTerms) return [];\n\n const results = this.memoryStore.search(searchTerms, this.projectId, 10);\n\n // Select memories within budget, prioritizing by importance\n const sorted = results.sort((a, b) => b.importance - a.importance);\n const selected: MemoryRecord[] = [];\n let usedChars = 0;\n\n for (const memory of sorted) {\n const entryChars = memory.content.length + 30; // overhead for formatting\n if (usedChars + entryChars > charBudget) break;\n selected.push(memory);\n usedChars += entryChars;\n\n // Record access for memory decay tracking\n if (memory.id) {\n this.memoryStore.recordAccess(memory.id);\n }\n }\n\n return selected;\n }\n\n /** Extract meaningful search terms from a prompt. */\n private extractSearchTerms(query: string): string {\n // Remove common stop words and keep meaningful terms\n const stopWords = new Set([\n 'the',\n 'a',\n 'an',\n 'is',\n 'are',\n 'was',\n 'were',\n 'be',\n 'been',\n 'being',\n 'have',\n 'has',\n 'had',\n 'do',\n 'does',\n 'did',\n 'will',\n 'would',\n 'could',\n 'should',\n 'may',\n 'might',\n 'can',\n 'shall',\n 'to',\n 'of',\n 'in',\n 'for',\n 'on',\n 'with',\n 'at',\n 'by',\n 'from',\n 'this',\n 'that',\n 'these',\n 'those',\n 'it',\n 'its',\n 'and',\n 'or',\n 'but',\n 'not',\n 'no',\n 'if',\n 'then',\n 'else',\n 'when',\n 'how',\n 'what',\n 'which',\n 'who',\n 'whom',\n 'where',\n 'why',\n 'review',\n 'following',\n 'content',\n 'carefully',\n 'provide',\n 'score',\n 'feedback',\n 'verdict',\n ]);\n\n const terms = query\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, ' ')\n .split(/\\s+/)\n .filter((t) => t.length > 2 && !stopWords.has(t));\n\n // Take top 5 unique terms\n const unique = [...new Set(terms)].slice(0, 5);\n return unique.join(' ');\n }\n\n /** Format memories for injection into prompt. */\n private formatMemories(memories: MemoryRecord[]): string {\n const lines = memories.map((m) => `- [${m.category}] ${m.content}`);\n return `## Project Context (from memory)\\n${lines.join('\\n')}`;\n }\n\n /** Build a compact file tree of the project, capped at maxFiles entries. */\n buildFileTree(): string {\n if (!this.projectDir) return '';\n\n try {\n const lines: string[] = [];\n const counter = { value: 0 };\n this.walkDir(this.projectDir, '', 0, lines, counter);\n if (counter.value >= this.maxFiles) {\n lines.push(`[... truncated at ${this.maxFiles} files]`);\n }\n return lines.join('\\n');\n } catch {\n return '';\n }\n }\n\n private walkDir(\n dir: string,\n prefix: string,\n depth: number,\n lines: string[],\n counter: { value: number },\n ): void {\n if (depth > this.maxTreeDepth) return;\n if (counter.value >= this.maxFiles) return;\n\n let entries: string[];\n try {\n entries = readdirSync(dir).sort();\n } catch {\n return;\n }\n\n // Separate dirs and files\n const dirs: string[] = [];\n const files: string[] = [];\n\n for (const entry of entries) {\n if (entry.startsWith('.') && entry !== '.cowork.yml') continue;\n if (IGNORE_DIRS.has(entry)) continue;\n\n try {\n const fullPath = join(dir, entry);\n const stat = statSync(fullPath);\n if (stat.isDirectory()) {\n dirs.push(entry);\n } else if (this.shouldIncludeFile(entry)) {\n files.push(entry);\n }\n } catch {\n // Skip inaccessible entries\n }\n }\n\n // Print directories first, then files\n for (const d of dirs) {\n if (counter.value >= this.maxFiles) return;\n lines.push(`${prefix}${d}/`);\n this.walkDir(join(dir, d), `${prefix} `, depth + 1, lines, counter);\n }\n for (const f of files) {\n if (counter.value >= this.maxFiles) return;\n lines.push(`${prefix}${f}`);\n counter.value++;\n }\n }\n\n private shouldIncludeFile(filename: string): boolean {\n const dotIdx = filename.lastIndexOf('.');\n if (dotIdx < 0) return false;\n return this.includeExtensions.has(filename.slice(dotIdx));\n }\n\n /**\n * Read a specific file's content within token budget.\n * Useful for tier 3 on-demand context expansion.\n */\n readFileContent(filePath: string, maxChars = 8000): string | null {\n if (!this.projectDir) return null;\n try {\n const fullPath = join(this.projectDir, filePath);\n const content = readFileSync(fullPath, 'utf-8');\n if (content.length > maxChars) {\n return `${content.slice(0, maxChars)}\\n[TRUNCATED: file exceeds ${maxChars} chars]`;\n }\n return content;\n } catch {\n return null;\n }\n }\n}\n\n// ── Handoff Envelope ──\n\n/** Command types with pre-defined output contracts. */\nexport type HandoffCommand = 'review' | 'debate' | 'build-review' | 'cleanup' | 'adjudicate' | 'custom';\n\nexport interface HandoffEnvelopeOptions {\n /** The command being executed */\n command: HandoffCommand;\n /** The core task/instruction for GPT */\n task: string;\n /** Focus area or constraints */\n constraints?: string[];\n /** Whether this is a resumed session (GPT already has prior context) */\n resumed: boolean;\n /** Brief summary of what happened in prior turns (from session events) */\n priorContext?: string;\n /** Scope restriction (glob pattern) */\n scope?: string;\n}\n\n/** Output contract templates per command type. */\nconst OUTPUT_CONTRACTS: Record<HandoffCommand, string> = {\n review: `For each issue found, format as:\n- CRITICAL: <file>:<line> <description>\n- WARNING: <file>:<line> <description>\n- INFO: <file>:<line> <description>\n\nEnd with:\nVERDICT: APPROVED or VERDICT: NEEDS_REVISION\nSCORE: X/10`,\n\n 'build-review': `For each issue found, format as:\n- BUG: <description>\n- ISSUE: <description>\n\nEnd with:\n- VERDICT: APPROVED (if code is ready) or VERDICT: NEEDS_REVISION (if fixes needed)\n- SCORE: X/10`,\n\n cleanup: `For each issue found, output in this EXACT format (one per line):\nFINDING: <scope>|<confidence>|<file>|<line>|<symbol>|<description>|<recommendation>\n\nOutput SCAN_COMPLETE when done.`,\n\n adjudicate: `Respond with exactly one line:\nADJUDICATE: CONFIRMED|DISMISSED|UNCERTAIN <reason>`,\n\n debate: `State your position clearly, then end with:\nSTANCE: SUPPORT | OPPOSE | NEUTRAL\nCONFIDENCE: X/10`,\n\n custom: '',\n};\n\n/**\n * Build a structured handoff envelope for Claude→GPT communication.\n *\n * Wraps any command's raw prompt with:\n * 1. Codebase access preamble\n * 2. Resume primer (when continuing a thread)\n * 3. The core task\n * 4. Constraints & scope\n * 5. Output contract\n */\nexport function buildHandoffEnvelope(options: HandoffEnvelopeOptions): string {\n const sections: string[] = [];\n\n // ── Preamble ──\n sections.push('You have full access to this project\\'s codebase. Use tools to discover, read, and analyze relevant files as needed.');\n\n // ── Resume primer (capped at 500 chars to prevent bloat) ──\n if (options.resumed) {\n const context = options.priorContext ? options.priorContext.slice(0, 500) : '';\n const primer = context\n ? `Continue from prior thread. Prior context: ${context}\\nDo not repeat completed analysis — focus on unresolved items or the new task below.`\n : 'Continue from prior thread. Do not repeat completed analysis — focus on the new task below.';\n sections.push(primer);\n }\n\n // ── Task (capped at 60K chars — codex has 400K context but leave room for tools) ──\n sections.push(options.task.slice(0, 60_000));\n\n // ── Constraints ──\n const constraints: string[] = options.constraints ? [...options.constraints] : [];\n if (options.scope) {\n constraints.push(`Restrict exploration to files matching: ${options.scope}`);\n }\n if (constraints.length > 0) {\n sections.push(`CONSTRAINTS:\\n${constraints.map(c => `- ${c}`).join('\\n')}`);\n }\n\n // ── Output contract ──\n const contract = OUTPUT_CONTRACTS[options.command];\n if (contract) {\n sections.push(contract);\n }\n\n return sections.join('\\n\\n');\n}\n","// packages/core/src/engine/debate-engine.ts — Multi-round debate with proposal-critique pattern\n\nimport { nanoid } from 'nanoid';\nimport type {\n CompactionPolicy,\n ConvergencePolicy,\n DebateBudget,\n DebateEngineInput,\n DebateEngineResult,\n DebateEngineState,\n DebateIO,\n DebateMessage,\n DebateMessageKind,\n Stance,\n StopDecision,\n StopReason,\n} from '../types/debate.js';\n\n// ── Defaults ──\n\nconst DEFAULT_BUDGET: DebateBudget = {\n maxRounds: 3,\n maxWallClockMs: 110_000,\n perTurnTimeoutMs: 60_000,\n};\n\nconst DEFAULT_CONVERGENCE: ConvergencePolicy = {\n minRoundsBeforeCheck: 1,\n requiredStableRounds: 2,\n};\n\nconst DEFAULT_COMPACTION: CompactionPolicy = {\n keepRecentMessages: 4,\n summaryMaxTokens: 500,\n};\n\n// ── Stance detection ──\n\nconst SUPPORT_PATTERNS = [\n /\\bapproved?\\b/i,\n /\\bagree[sd]?\\b/i,\n /\\bsupport/i,\n /\\blooks?\\s+good\\b/i,\n /\\bno\\s+(major\\s+)?issues?\\b/i,\n /\\bwell[\\s-]designed\\b/i,\n /\\bverdict:\\s*approved/i,\n];\n\nconst OPPOSE_PATTERNS = [\n /\\bneeds?\\s+revision/i,\n /\\bdisagree/i,\n /\\boppose/i,\n /\\breject/i,\n /\\bfundamental(ly)?\\s+(flaw|issue|problem)/i,\n /\\bverdict:\\s*needs.revision/i,\n /\\bsignificant\\s+(concern|issue|problem)/i,\n];\n\nexport function detectStance(text: string): Stance {\n let supportScore = 0;\n let opposeScore = 0;\n\n for (const p of SUPPORT_PATTERNS) {\n if (p.test(text)) supportScore++;\n }\n for (const p of OPPOSE_PATTERNS) {\n if (p.test(text)) opposeScore++;\n }\n\n if (supportScore > opposeScore) return 'support';\n if (opposeScore > supportScore) return 'oppose';\n return 'uncertain';\n}\n\n// ── Engine ──\n\nexport class ProposalCritiqueEngine {\n private budget: DebateBudget;\n private convergence: ConvergencePolicy;\n private compaction: CompactionPolicy;\n\n constructor(\n budget?: Partial<DebateBudget>,\n convergence?: Partial<ConvergencePolicy>,\n compaction?: Partial<CompactionPolicy>,\n ) {\n this.budget = { ...DEFAULT_BUDGET, ...budget };\n this.convergence = { ...DEFAULT_CONVERGENCE, ...convergence };\n this.compaction = { ...DEFAULT_COMPACTION, ...compaction };\n }\n\n /** Initialize debate state. */\n init(input: DebateEngineInput): DebateEngineState {\n if (input.models.length < 2) {\n throw new Error('Proposal-critique debate requires at least 2 models');\n }\n return {\n debateId: input.debateId,\n question: input.question,\n models: input.models,\n round: 0,\n turn: 0,\n thread: [\n {\n id: nanoid(),\n turn: 0,\n round: 0,\n speakerId: 'user',\n kind: 'topic',\n text: input.question,\n createdAt: Date.now(),\n },\n ],\n runningSummary: '',\n stanceHistory: [],\n usage: {\n totalPromptTokens: 0,\n totalCompletionTokens: 0,\n totalCalls: 0,\n startedAt: Date.now(),\n },\n status: 'running',\n sessionIds: {},\n resumeStats: { attempted: 0, succeeded: 0, fallbacks: 0 },\n };\n }\n\n /** Run the full debate loop. */\n async run(input: DebateEngineInput, io: DebateIO): Promise<DebateEngineResult> {\n const state = this.init(input);\n\n let stopReason: StopReason = 'max_rounds';\n\n for (let round = 1; round <= this.budget.maxRounds; round++) {\n state.round = round;\n\n // Step 1: Proposer turn\n const proposerAlias = state.models[0];\n const proposerKind: DebateMessageKind = round === 1 ? 'proposal' : 'rebuttal';\n await this.executeTurn(state, io, proposerAlias, proposerKind);\n\n // Check time budget\n const timeCheck = this.checkTimeBudget(state);\n if (timeCheck.stop) {\n stopReason = 'time_budget';\n break;\n }\n\n // Step 2: Critic turn\n const criticAlias = state.models[1];\n await this.executeTurn(state, io, criticAlias, 'critique');\n\n // Check convergence\n const decision = this.shouldStop(state);\n if (decision.stop) {\n stopReason = decision.reason ?? 'converged';\n break;\n }\n\n // Step 3: Update running summary (use critic model — cheaper to ask for summary)\n if (round < this.budget.maxRounds) {\n await this.updateSummary(state, io);\n }\n }\n\n state.status = 'stopped';\n return this.finalize(state, stopReason);\n }\n\n /** Execute a single turn: build prompt, call model, record message. */\n private async executeTurn(\n state: DebateEngineState,\n io: DebateIO,\n modelAlias: string,\n kind: DebateMessageKind,\n ): Promise<DebateMessage> {\n state.turn++;\n const existingSessionId = state.sessionIds[modelAlias];\n const prompt = this.buildTurnPrompt(state, modelAlias, kind);\n\n if (existingSessionId) {\n state.resumeStats.attempted++;\n }\n\n const result = await io.generate(\n modelAlias,\n [\n { role: 'system', content: this.getSystemPrompt(kind) },\n { role: 'user', content: prompt },\n ],\n this.budget.perTurnTimeoutMs,\n existingSessionId,\n );\n\n // Track session ID for resume\n if (result.sessionId) {\n if (existingSessionId && result.sessionId === existingSessionId) {\n state.resumeStats.succeeded++;\n } else if (existingSessionId && result.sessionId !== existingSessionId) {\n state.resumeStats.fallbacks++;\n }\n state.sessionIds[modelAlias] = result.sessionId;\n }\n\n const stance = detectStance(result.text);\n const message: DebateMessage = {\n id: nanoid(),\n turn: state.turn,\n round: state.round,\n speakerId: modelAlias,\n kind,\n text: result.text,\n stance,\n confidence: this.extractConfidence(result.text),\n tokens: { prompt: result.promptTokens, completion: result.completionTokens },\n createdAt: Date.now(),\n };\n\n state.thread.push(message);\n state.stanceHistory.push({ round: state.round, speakerId: modelAlias, stance });\n state.usage.totalPromptTokens += result.promptTokens;\n state.usage.totalCompletionTokens += result.completionTokens;\n state.usage.totalCalls++;\n\n return message;\n }\n\n /** Build the prompt for a turn with compacted context. */\n private buildTurnPrompt(\n state: DebateEngineState,\n _modelAlias: string,\n kind: DebateMessageKind,\n ): string {\n const parts: string[] = [];\n\n // Always include the original question\n parts.push(`## Question\\n${state.question}`);\n\n // Include running summary if we have one (compaction)\n if (state.runningSummary) {\n parts.push(`## Discussion Summary So Far\\n${state.runningSummary}`);\n }\n\n // Include recent messages (compacted context window)\n const recentMessages = state.thread.slice(-this.compaction.keepRecentMessages);\n if (recentMessages.length > 0) {\n const msgTexts = recentMessages\n .filter((m) => m.kind !== 'topic') // topic already shown as question\n .map((m) => `**${m.speakerId}** (${m.kind}, round ${m.round}):\\n${m.text}`);\n if (msgTexts.length > 0) {\n parts.push(`## Recent Arguments\\n${msgTexts.join('\\n\\n')}`);\n }\n }\n\n // Role-specific instruction\n if (kind === 'proposal') {\n parts.push(\n '## Your Task\\nProvide a thorough proposal/plan to address the question above. Be specific and actionable.',\n );\n } else if (kind === 'rebuttal') {\n parts.push(\n '## Your Task\\nRevise your proposal based on the critique above. Address each concern specifically. If you disagree with a point, explain why.',\n );\n } else if (kind === 'critique') {\n parts.push(\n '## Your Task\\nCritique the proposal above. Identify weaknesses, missing considerations, and potential improvements. If the proposal is solid, say so explicitly with \"VERDICT: APPROVED\". Otherwise provide specific, actionable feedback.',\n );\n }\n\n // Ask for structured stance\n parts.push(\n '## Required Output Format\\nEnd your response with exactly one of:\\n- STANCE: SUPPORT (if you agree with the current direction)\\n- STANCE: OPPOSE (if you have significant concerns)\\n- STANCE: UNCERTAIN (if mixed)',\n );\n\n return parts.join('\\n\\n');\n }\n\n /** System prompt based on turn type. */\n private getSystemPrompt(kind: DebateMessageKind): string {\n if (kind === 'proposal' || kind === 'rebuttal') {\n return 'You are an expert architect. Provide clear, well-reasoned proposals. Address feedback directly. Always end with your STANCE.';\n }\n return 'You are a critical reviewer. Be thorough but fair. Approve good work, critique weak points. Always end with your STANCE.';\n }\n\n /** Check if we should stop the debate. */\n shouldStop(state: DebateEngineState): StopDecision {\n // Hard limit: time\n const timeCheck = this.checkTimeBudget(state);\n if (timeCheck.stop) return timeCheck;\n\n // Hard limit: rounds\n if (state.round >= this.budget.maxRounds) {\n return { stop: true, reason: 'max_rounds' };\n }\n\n // Convergence: check if critic supports for requiredStableRounds\n if (state.round >= this.convergence.minRoundsBeforeCheck) {\n const criticAlias = state.models[1];\n const criticStances = state.stanceHistory\n .filter((s) => s.speakerId === criticAlias)\n .slice(-this.convergence.requiredStableRounds);\n\n if (\n criticStances.length >= this.convergence.requiredStableRounds &&\n criticStances.every((s) => s.stance === 'support')\n ) {\n return {\n stop: true,\n reason: 'converged',\n diagnostics: { stableRounds: criticStances.length },\n };\n }\n }\n\n return { stop: false };\n }\n\n /** Check time budget. */\n private checkTimeBudget(state: DebateEngineState): StopDecision {\n const elapsed = Date.now() - state.usage.startedAt;\n const remaining = this.budget.maxWallClockMs - elapsed;\n if (remaining <= 0) {\n return {\n stop: true,\n reason: 'time_budget',\n diagnostics: { elapsedMs: elapsed, remainingMs: 0 },\n };\n }\n return { stop: false, diagnostics: { remainingMs: remaining } };\n }\n\n /** Update the running summary to compact older context. */\n private async updateSummary(state: DebateEngineState, io: DebateIO): Promise<void> {\n // Use the first model (proposer) to summarize\n const summarizerAlias = state.models[0];\n\n // Gather the round's messages\n const roundMessages = state.thread\n .filter((m) => m.round === state.round && m.kind !== 'topic')\n .map((m) => `${m.speakerId} (${m.kind}): ${m.text}`)\n .join('\\n\\n');\n\n const prevSummary = state.runningSummary ? `Previous summary: ${state.runningSummary}\\n\\n` : '';\n\n const prompt = `${prevSummary}New round of discussion:\\n${roundMessages}\\n\\nWrite a brief summary (max 3 paragraphs) of the current state of the debate. What has been proposed, what concerns were raised, and what remains unresolved?`;\n\n const result = await io.generate(\n summarizerAlias,\n [\n {\n role: 'system',\n content:\n 'Summarize debate progress concisely. Focus on key proposals, critiques, and unresolved points.',\n },\n { role: 'user', content: prompt },\n ],\n this.budget.perTurnTimeoutMs,\n );\n\n state.runningSummary = result.text;\n state.usage.totalPromptTokens += result.promptTokens;\n state.usage.totalCompletionTokens += result.completionTokens;\n state.usage.totalCalls++;\n\n // Record summary as a message\n state.thread.push({\n id: nanoid(),\n turn: ++state.turn,\n round: state.round,\n speakerId: 'moderator',\n kind: 'summary',\n text: result.text,\n createdAt: Date.now(),\n });\n }\n\n /** Build the final result from state. */\n private finalize(state: DebateEngineState, reason: StopReason): DebateEngineResult {\n // Find the last substantive message (proposal/rebuttal/critique) as the answer\n const substantive = state.thread.filter(\n (m) => m.kind === 'proposal' || m.kind === 'rebuttal' || m.kind === 'critique',\n );\n const lastProposal = [...substantive]\n .reverse()\n .find((m) => m.kind === 'proposal' || m.kind === 'rebuttal');\n const lastCritique = [...substantive].reverse().find((m) => m.kind === 'critique');\n\n // If converged, the last proposal is the answer. Otherwise, include the critique too.\n let answer: string;\n if (reason === 'converged' && lastProposal) {\n answer = lastProposal.text;\n } else if (lastProposal && lastCritique) {\n answer = `## Final Proposal\\n${lastProposal.text}\\n\\n## Outstanding Critique\\n${lastCritique.text}`;\n } else {\n answer = substantive.at(-1)?.text ?? state.question;\n }\n\n return {\n debateId: state.debateId,\n answer,\n reason,\n rounds: state.round,\n thread: state.thread,\n stanceHistory: state.stanceHistory,\n usage: state.usage,\n };\n }\n\n /** Extract confidence value from text if present. */\n private extractConfidence(text: string): number | undefined {\n const match = /confidence:\\s*([\\d.]+)/i.exec(text);\n if (match) {\n const val = Number.parseFloat(match[1]);\n if (val >= 0 && val <= 1) return val;\n if (val >= 0 && val <= 100) return val / 100;\n }\n return undefined;\n }\n}\n\nexport { DEFAULT_BUDGET, DEFAULT_CONVERGENCE, DEFAULT_COMPACTION };\n","// packages/core/src/engine/step-runner.ts\n\nimport type { SessionStore } from '../memory/session-store.js';\nimport { callModel, streamModel } from '../models/caller.js';\nimport type { CostTracker } from '../models/cost-tracker.js';\nimport type { ModelRegistry } from '../models/registry.js';\nimport type { PromptType, PromptVariables } from '../roles/prompts.js';\nimport type { RoleManager } from '../roles/role-manager.js';\nimport type { ProjectConfig } from '../types/config.js';\nimport type { TokenUsage } from '../types/events.js';\nimport type { ModelCallResult } from '../types/models.js';\nimport type { ResolvedStep } from '../types/workflow.js';\nimport { parseVerdict } from '../utils/verdict.js';\nimport type { EventBus } from './event-bus.js';\n\nexport interface StepResult {\n stepId: string;\n output: string;\n usage: TokenUsage;\n durationMs: number;\n verdict?: 'approved' | 'needs_revision';\n feedback?: string;\n}\n\nexport class StepRunner {\n constructor(\n private registry: ModelRegistry,\n private roleManager: RoleManager,\n private costTracker: CostTracker,\n private eventBus: EventBus,\n private sessionStore: SessionStore,\n private config: ProjectConfig,\n private sessionId: string,\n ) {}\n\n async execute(\n step: ResolvedStep,\n inputs: Map<string, string>,\n task: string,\n iteration: number,\n options?: { stream?: boolean },\n ): Promise<StepResult> {\n const stepId = step.definition.id;\n const role = step.definition.role;\n const stepType = step.definition.type;\n\n // Determine prompt type\n const promptType = this.resolvePromptType(stepType, stepId, iteration);\n\n // Build prompt variables\n const promptVars = this.buildPromptVars(promptType, task, inputs, iteration);\n\n // Build messages\n const messages = this.roleManager.buildMessages(promptType, promptVars);\n\n // Get model for role\n const model = this.registry.getAdapterForRole(role, this.config);\n const modelConfig = this.registry.getModelConfigForRole(role, this.config);\n\n // Emit step.started\n this.eventBus.emitEvent({\n type: 'step.started',\n stepId,\n role,\n model: modelConfig.model,\n iteration,\n timestamp: '',\n });\n\n const start = Date.now();\n let result: ModelCallResult;\n\n if (options?.stream) {\n result = await this.costTracker.tracked(\n () =>\n streamModel(\n model,\n messages,\n (delta) => {\n this.eventBus.emitEvent({\n type: 'text.delta',\n stepId,\n role,\n delta,\n });\n },\n stepId,\n role,\n ),\n stepId,\n );\n\n this.eventBus.emitEvent({\n type: 'text.done',\n stepId,\n role,\n fullText: result.text,\n });\n } else {\n result = await this.costTracker.tracked(() => callModel(model, messages), stepId);\n }\n\n const durationMs = Date.now() - start;\n\n // Save transcript entry\n this.sessionStore.saveTranscriptEntry({\n sessionId: this.sessionId,\n stepId,\n iteration,\n role,\n modelId: result.model,\n content: result.text,\n tokenCount: result.usage.totalTokens,\n cost: result.usage.costUsd,\n createdAt: new Date().toISOString(),\n metadata: null,\n });\n\n // Parse verdict for review steps\n let verdict: 'approved' | 'needs_revision' | undefined;\n let feedback: string | undefined;\n if (stepType === 'review') {\n const parsed = parseVerdict(result.text);\n verdict = parsed.verdict;\n feedback = parsed.feedback || undefined;\n }\n\n // Emit step.completed\n this.eventBus.emitEvent({\n type: 'step.completed',\n stepId,\n output: result.text,\n tokenUsage: result.usage,\n durationMs,\n timestamp: '',\n });\n\n return {\n stepId,\n output: result.text,\n usage: result.usage,\n durationMs,\n verdict,\n feedback,\n };\n }\n\n private resolvePromptType(stepType: string, stepId: string, iteration: number): PromptType {\n if (stepType === 'generate') {\n if (iteration > 1) {\n return stepId.includes('implement') ? 'code' : 'plan-revision';\n }\n if (stepId.includes('plan')) return 'plan';\n if (stepId.includes('implement')) return 'code';\n return 'plan';\n }\n if (stepType === 'review') {\n return stepId.includes('code') ? 'code-review' : 'plan-review';\n }\n // Fallback for other step types\n return 'plan';\n }\n\n private buildPromptVars(\n promptType: PromptType,\n task: string,\n inputs: Map<string, string>,\n _iteration: number,\n ): PromptVariables {\n const vars: PromptVariables = { task };\n\n // Get the first input value as the primary content\n const inputValues = [...inputs.values()];\n const primaryInput = inputValues[0] ?? '';\n\n switch (promptType) {\n case 'plan':\n break;\n case 'plan-review':\n vars.plan = primaryInput;\n break;\n case 'plan-revision':\n vars.previousPlan = primaryInput;\n vars.feedback = inputValues[1] ?? '';\n break;\n case 'code':\n vars.plan = primaryInput;\n break;\n case 'code-review':\n vars.plan = primaryInput;\n vars.code = inputValues[1] ?? '';\n break;\n }\n\n return vars;\n }\n}\n","// packages/core/src/engine/workflow-engine.ts\n\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport type {\n ResolvedStep,\n ResolvedWorkflow,\n StepDefinition,\n WorkflowDefinition,\n} from '../types/workflow.js';\nimport { WorkflowError } from '../utils/errors.js';\n\nconst VALID_STEP_TYPES: Set<string> = new Set<string>([\n 'generate',\n 'review',\n 'debate',\n 'transform',\n 'gate',\n 'parallel',\n 'conditional',\n]);\n\n/**\n * Loads workflow YAML files, validates them, and resolves step dependencies\n * into a topologically sorted execution order.\n */\nexport class WorkflowEngine {\n constructor(private workflowDir: string) {}\n\n /**\n * Load a workflow YAML file by name, validate it, and resolve into a DAG.\n */\n load(workflowName: string): ResolvedWorkflow {\n const filePath = join(this.workflowDir, `${workflowName}.yml`);\n let raw: string;\n try {\n raw = readFileSync(filePath, 'utf-8');\n } catch {\n throw new WorkflowError(`Workflow file not found: ${filePath}`);\n }\n\n let parsed: unknown;\n try {\n parsed = parseYaml(raw);\n } catch {\n throw new WorkflowError(`Invalid YAML in workflow: ${workflowName}`);\n }\n\n const definition = parsed as WorkflowDefinition;\n this.validateDefinition(definition, workflowName);\n\n const executionOrder = this.resolveSteps(definition.steps);\n\n return {\n name: definition.name,\n executionOrder,\n };\n }\n\n /**\n * Returns the topologically sorted steps (already computed during load).\n */\n getExecutionOrder(workflow: ResolvedWorkflow): ResolvedStep[] {\n return workflow.executionOrder;\n }\n\n private validateDefinition(def: WorkflowDefinition, workflowName: string): void {\n if (!def || typeof def !== 'object') {\n throw new WorkflowError(`Workflow \"${workflowName}\" is not a valid object`);\n }\n if (!def.name || typeof def.name !== 'string') {\n throw new WorkflowError(`Workflow \"${workflowName}\" is missing a name`);\n }\n if (!Array.isArray(def.steps) || def.steps.length === 0) {\n throw new WorkflowError(`Workflow \"${workflowName}\" has no steps`);\n }\n\n const stepIds = new Set<string>();\n for (const step of def.steps) {\n this.validateStep(step, stepIds, workflowName);\n stepIds.add(step.id);\n }\n }\n\n private validateStep(step: StepDefinition, knownIds: Set<string>, workflowName: string): void {\n if (!step.id || typeof step.id !== 'string') {\n throw new WorkflowError(`Step in \"${workflowName}\" is missing an id`);\n }\n if (knownIds.has(step.id)) {\n throw new WorkflowError(`Duplicate step id \"${step.id}\" in \"${workflowName}\"`, step.id);\n }\n if (!step.type || !VALID_STEP_TYPES.has(step.type)) {\n throw new WorkflowError(`Step \"${step.id}\" has invalid type \"${step.type}\"`, step.id);\n }\n if (!step.role || typeof step.role !== 'string') {\n throw new WorkflowError(`Step \"${step.id}\" is missing a role`, step.id);\n }\n }\n\n /**\n * Resolve steps into topological order, validating input references and loops.\n */\n private resolveSteps(steps: StepDefinition[]): ResolvedStep[] {\n const stepMap = new Map<string, StepDefinition>();\n const outputMap = new Map<string, string>(); // output ref -> step id\n\n for (const step of steps) {\n stepMap.set(step.id, step);\n if (step.output) {\n outputMap.set(step.output, step.id);\n }\n }\n\n // Build adjacency for topological sort: edges[stepId] = set of dependency step ids\n const edges = new Map<string, Set<string>>();\n for (const step of steps) {\n const deps = new Set<string>();\n\n if (step.input) {\n for (const ref of step.input) {\n const sourceStepId = outputMap.get(ref);\n if (sourceStepId === undefined) {\n throw new WorkflowError(`Step \"${step.id}\" references unknown input \"${ref}\"`, step.id);\n }\n deps.add(sourceStepId);\n }\n }\n\n if (step.loop) {\n if (!stepMap.has(step.loop.iteratesWith)) {\n throw new WorkflowError(\n `Step \"${step.id}\" loop references unknown step \"${step.loop.iteratesWith}\"`,\n step.id,\n );\n }\n }\n\n edges.set(step.id, deps);\n }\n\n // Topological sort (Kahn's algorithm)\n const inDegree = new Map<string, number>();\n for (const step of steps) {\n inDegree.set(step.id, 0);\n }\n for (const [, deps] of edges) {\n for (const dep of deps) {\n inDegree.set(dep, (inDegree.get(dep) ?? 0) + 1);\n }\n }\n\n // Kahn's: nodes with no incoming edges start the queue\n // But inDegree here tracks how many nodes depend ON each node.\n // We need it the other way: how many dependencies does each node have.\n const depCount = new Map<string, number>();\n for (const [stepId, deps] of edges) {\n depCount.set(stepId, deps.size);\n }\n\n const queue: string[] = [];\n for (const [stepId, count] of depCount) {\n if (count === 0) {\n queue.push(stepId);\n }\n }\n\n const sorted: string[] = [];\n while (queue.length > 0) {\n const current = queue.shift() as string;\n sorted.push(current);\n\n // Find all steps that depend on current\n for (const [stepId, deps] of edges) {\n if (deps.has(current)) {\n const newCount = (depCount.get(stepId) ?? 0) - 1;\n depCount.set(stepId, newCount);\n if (newCount === 0) {\n queue.push(stepId);\n }\n }\n }\n }\n\n if (sorted.length !== steps.length) {\n throw new WorkflowError('Workflow contains a cycle');\n }\n\n // Build resolved steps\n return sorted.map((stepId) => {\n const def = stepMap.get(stepId) as StepDefinition;\n const deps = edges.get(stepId) as Set<string>;\n\n return {\n definition: def,\n inputStepIds: [...deps],\n isLoopEntry: def.loop !== undefined,\n loopPartnerStepId: def.loop?.iteratesWith,\n };\n });\n }\n}\n","// packages/core/src/engine/cancellation.ts — Request cancellation support\n\nexport class CancellationToken {\n private cancelled = false;\n private callbacks = new Set<() => void>();\n\n /** Signal cancellation. Idempotent — multiple calls are safe. */\n cancel(): void {\n if (this.cancelled) return;\n this.cancelled = true;\n for (const cb of this.callbacks) {\n try {\n cb();\n } catch {\n // Swallow callback errors\n }\n }\n }\n\n get isCancelled(): boolean {\n return this.cancelled;\n }\n\n /** Throw if already cancelled. Call before starting expensive work. */\n throwIfCancelled(): void {\n if (this.cancelled) {\n throw new CancellationError('Operation was cancelled');\n }\n }\n\n /**\n * Register a callback to run on cancellation.\n * Deduplicated by reference — same function won't run twice.\n * If already cancelled, callback fires immediately.\n */\n onCancel(callback: () => void): void {\n if (this.cancelled) {\n callback();\n return;\n }\n this.callbacks.add(callback);\n }\n\n /** Remove a previously registered callback. */\n offCancel(callback: () => void): void {\n this.callbacks.delete(callback);\n }\n\n /**\n * Create a promise that resolves after `ms` but can be interrupted by cancellation.\n * Returns true if sleep completed, false if cancelled.\n */\n sleep(ms: number): Promise<boolean> {\n return new Promise((resolve) => {\n if (this.cancelled) {\n resolve(false);\n return;\n }\n\n const state = { timer: undefined as ReturnType<typeof setTimeout> | undefined };\n const onCancelHandler = () => {\n if (state.timer !== undefined) clearTimeout(state.timer);\n resolve(false);\n };\n\n state.timer = setTimeout(() => {\n this.callbacks.delete(onCancelHandler);\n resolve(true);\n }, ms);\n\n this.onCancel(onCancelHandler);\n });\n }\n}\n\nexport class CancellationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'CancellationError';\n }\n}\n","// packages/core/src/engine/policy.ts — Minimal policy engine for commit gates\n\nexport type PolicyMode = 'warn' | 'enforce';\nexport type PolicyDecision = 'allow' | 'warn' | 'block';\n\nexport interface PolicyRule {\n id: string;\n when: string; // event name: 'review.completed', 'shipit.pre_commit'\n predicate: string; // built-in predicate name\n threshold?: number;\n action: 'warn' | 'block';\n message: string;\n}\n\nexport interface PolicyContext {\n criticalCount: number;\n warningCount: number;\n verdict: string; // 'approved' | 'needs_revision' | 'unknown'\n stepsCompleted: Record<string, 'passed' | 'failed' | 'skipped'>;\n cleanupHighCount: number;\n}\n\nexport interface PolicyResult {\n decision: PolicyDecision;\n violations: { ruleId: string; action: 'warn' | 'block'; message: string }[];\n}\n\nconst BUILTIN_PREDICATES: Record<string, (ctx: PolicyContext, threshold?: number) => boolean> = {\n critical_findings_gt: (ctx, t) => ctx.criticalCount > (t ?? 0),\n warning_findings_gt: (ctx, t) => ctx.warningCount > (t ?? 0),\n verdict_is_needs_revision: (ctx) => ctx.verdict === 'needs_revision',\n step_failed: (ctx) => Object.values(ctx.stepsCompleted).includes('failed'),\n cleanup_high_gt: (ctx, t) => ctx.cleanupHighCount > (t ?? 0),\n};\n\nexport const DEFAULT_RULES: PolicyRule[] = [\n {\n id: 'block-critical-review',\n when: 'review.completed',\n predicate: 'critical_findings_gt',\n threshold: 0,\n action: 'block',\n message: 'Critical findings must be fixed before commit.',\n },\n {\n id: 'warn-needs-revision',\n when: 'review.completed',\n predicate: 'verdict_is_needs_revision',\n action: 'warn',\n message: 'Review verdict is NEEDS_REVISION.',\n },\n];\n\nexport function evaluatePolicy(\n event: string,\n context: PolicyContext,\n rules: PolicyRule[],\n mode: PolicyMode = 'enforce',\n): PolicyResult {\n const violations: PolicyResult['violations'] = [];\n\n for (const rule of rules) {\n if (rule.when !== event) continue;\n\n const check = BUILTIN_PREDICATES[rule.predicate];\n if (!check) continue;\n\n if (check(context, rule.threshold)) {\n const action = mode === 'warn' ? 'warn' : rule.action;\n violations.push({ ruleId: rule.id, action, message: rule.message });\n }\n }\n\n const hasBlock = violations.some((v) => v.action === 'block');\n const hasWarn = violations.some((v) => v.action === 'warn');\n\n return {\n decision: hasBlock ? 'block' : hasWarn ? 'warn' : 'allow',\n violations,\n };\n}\n","// packages/core/src/cleanup/scanners.ts — Deterministic scanners (no LLM)\n\nimport { readFileSync, readdirSync, statSync, existsSync } from 'node:fs';\nimport { join, relative, sep } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { Ignore } from 'ignore';\nimport type { CleanupConfidence, CleanupFinding, CleanupScope } from '../types/cleanup.js';\n\n// ── Helpers ──\n\nconst SOURCE_EXTS = new Set(['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs']);\nconst ALL_SCAN_EXTS = new Set([...SOURCE_EXTS, '.json']);\n\nfunction normalizePath(filePath: string): string {\n return filePath.split(sep).join('/');\n}\n\n/** Walk files, respecting an optional compiled ignore filter. */\nfunction walkFiles(dir: string, exts: Set<string>, result: string[] = [], rootDir?: string, ig?: Ignore): string[] {\n const root = rootDir ?? dir;\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return result;\n }\n for (const entry of entries) {\n const full = join(dir, entry);\n const rel = normalizePath(relative(root, full));\n\n // Check ignore filter (compiled .gitignore + .codemootignore + builtins)\n if (ig && ig.ignores(rel)) continue;\n\n let stat;\n try {\n stat = statSync(full);\n } catch {\n continue;\n }\n if (stat.isDirectory()) {\n walkFiles(full, exts, result, root, ig);\n } else if (stat.isFile()) {\n const ext = full.slice(full.lastIndexOf('.'));\n if (exts.has(ext)) result.push(full);\n }\n }\n return result;\n}\n\nfunction readFileSafe(filePath: string): string {\n try {\n return readFileSync(filePath, 'utf-8');\n } catch {\n return '';\n }\n}\n\nfunction makeKey(scope: CleanupScope, file: string, symbol: string): string {\n return `${scope}:${normalizePath(file)}:${symbol}`;\n}\n\n// ── Find package.json files in monorepo ──\n\nfunction findPackageJsons(projectDir: string): { dir: string; pkg: Record<string, unknown> }[] {\n const results: { dir: string; pkg: Record<string, unknown> }[] = [];\n\n // Root package.json\n const rootPkg = join(projectDir, 'package.json');\n if (existsSync(rootPkg)) {\n try {\n results.push({ dir: projectDir, pkg: JSON.parse(readFileSafe(rootPkg)) });\n } catch { /* skip */ }\n }\n\n // packages/*/package.json (one level of workspace nesting)\n const packagesDir = join(projectDir, 'packages');\n if (existsSync(packagesDir)) {\n try {\n for (const entry of readdirSync(packagesDir)) {\n const pkgJson = join(packagesDir, entry, 'package.json');\n if (existsSync(pkgJson)) {\n try {\n results.push({\n dir: join(packagesDir, entry),\n pkg: JSON.parse(readFileSafe(pkgJson)),\n });\n } catch { /* skip */ }\n }\n }\n } catch { /* skip */ }\n }\n\n return results;\n}\n\n// ── Scanner: Unused Dependencies ──\n\nexport function scanUnusedDeps(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const packages = findPackageJsons(projectDir);\n\n for (const { dir, pkg } of packages) {\n const deps = pkg.dependencies as Record<string, string> | undefined;\n if (!deps) continue;\n\n const pkgName = (pkg.name as string) || relative(projectDir, dir);\n const files = walkFiles(dir, ALL_SCAN_EXTS, [], projectDir, ig);\n\n // Collect all file contents for searching\n const allContent = files.map(f => readFileSafe(f)).join('\\n');\n\n for (const depName of Object.keys(deps)) {\n // Check if dep is imported/required anywhere in this package\n const importPatterns = [\n `from '${depName}`,\n `from \"${depName}`,\n `require('${depName}`,\n `require(\"${depName}`,\n `import '${depName}`,\n `import \"${depName}`,\n // Scoped subpath imports\n `from '${depName}/`,\n `from \"${depName}/`,\n // Dynamic imports\n `import('${depName}`,\n `import(\"${depName}`,\n ];\n\n // Also check package.json bin/exports/scripts references (NOT dependencies itself)\n const binStr = JSON.stringify(pkg.bin ?? {});\n const exportsStr = JSON.stringify(pkg.exports ?? {});\n const scriptsStr = JSON.stringify(pkg.scripts ?? {});\n const usedInPkgJson = binStr.includes(depName) || exportsStr.includes(depName) || scriptsStr.includes(depName);\n\n const usedInSource = importPatterns.some(p => allContent.includes(p));\n\n if (!usedInSource && !usedInPkgJson) {\n const relFile = normalizePath(relative(projectDir, join(dir, 'package.json')));\n findings.push({\n key: makeKey('deps', relFile, depName),\n scope: 'deps',\n confidence: 'high',\n file: relFile,\n description: `Dependency \"${depName}\" is not imported in any source file`,\n recommendation: `Remove \"${depName}\" from dependencies`,\n deterministicEvidence: [`No import/require of \"${depName}\" found in ${files.length} files in ${pkgName}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n packageName: pkgName,\n });\n }\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Unused Exports ──\n\nexport function scanUnusedExports(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n\n // Build a map of all exported symbols and their locations\n const exports: { file: string; name: string; line: number }[] = [];\n const exportRegex = /^export\\s+(?:(?:async\\s+)?function|class|const|let|var|type|interface|enum)\\s+(\\w+)/gm;\n const namedExportRegex = /export\\s*\\{([^}]+)\\}/g;\n\n for (const file of allFiles) {\n const content = readFileSafe(file);\n const relFile = normalizePath(relative(projectDir, file));\n\n // Skip index/barrel files — they re-export\n if (relFile.endsWith('index.ts') || relFile.endsWith('index.js')) continue;\n\n let match: RegExpExecArray | null;\n\n exportRegex.lastIndex = 0;\n match = exportRegex.exec(content);\n while (match) {\n const lineNum = content.slice(0, match.index).split('\\n').length;\n exports.push({ file: relFile, name: match[1], line: lineNum });\n match = exportRegex.exec(content);\n }\n\n namedExportRegex.lastIndex = 0;\n match = namedExportRegex.exec(content);\n while (match) {\n const names = match[1].split(',').map(n => n.trim().split(/\\s+as\\s+/)[0].trim()).filter(Boolean);\n const lineNum = content.slice(0, match.index).split('\\n').length;\n for (const name of names) {\n exports.push({ file: relFile, name, line: lineNum });\n }\n match = namedExportRegex.exec(content);\n }\n }\n\n // Build all source content for import searching\n const allContent = allFiles.map(f => readFileSafe(f)).join('\\n');\n\n for (const exp of exports) {\n // Simple check: does the export name appear in an import statement in any other file?\n const isUsed = allContent.includes(`{ ${exp.name}`) ||\n allContent.includes(`{${exp.name}`) ||\n allContent.includes(`, ${exp.name}`) ||\n allContent.includes(`${exp.name},`) ||\n allContent.includes(`${exp.name} }`) ||\n allContent.includes(`${exp.name}}`);\n\n // Count occurrences — subtract the export itself\n if (!isUsed) {\n findings.push({\n key: makeKey('unused-exports', exp.file, exp.name),\n scope: 'unused-exports',\n confidence: 'medium', // Could be dynamically imported or used via barrel\n file: exp.file,\n line: exp.line,\n description: `Export \"${exp.name}\" appears unused (no import found)`,\n recommendation: `Consider removing export \"${exp.name}\" or marking as internal`,\n deterministicEvidence: [`No import of \"${exp.name}\" found across ${allFiles.length} files`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Hardcoded Values ──\n\nconst MAGIC_NUMBER_REGEX = /(?<!\\w)(\\d{4,})(?!\\w)/g; // 4+ digit numbers (3-digit too noisy)\n\n/** Numbers commonly used as config values — not magic numbers. */\nconst COMMON_NUMBERS = new Set([\n 1000, 1024, 2048, 4096, 8192, 16384, 32768, 65536,\n 1200, 1500, 2000, 3000, 5000, 8000, 8080, 8443, 9000, 9090,\n 10000, 15000, 30000, 50000, 60000, 100000, 120000, 200000, 300000, 400000, 600000,\n]);\nconst URL_REGEX = /(['\"`])(https?:\\/\\/[^\\s'\"`]+)\\1/g;\nconst CREDENTIAL_PATTERNS = [\n /(?:password|secret|token|api[_-]?key|auth)\\s*[:=]\\s*(['\"`])(?!process\\.env)[^'\"`\\n]+\\1/gi,\n];\n\nexport function scanHardcoded(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n\n for (const file of allFiles) {\n const relFile = normalizePath(relative(projectDir, file));\n\n // Skip test files for magic numbers (fixtures/mocks are expected)\n const isTest = relFile.includes('test') || relFile.includes('spec') || relFile.includes('__test');\n\n const content = readFileSafe(file);\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineNum = i + 1;\n\n // Skip comments\n if (line.trim().startsWith('//') || line.trim().startsWith('*')) continue;\n\n // Magic numbers (skip in tests, skip common values like ports, HTTP codes)\n if (!isTest) {\n const numberMatches = line.matchAll(MAGIC_NUMBER_REGEX);\n for (const m of numberMatches) {\n const num = Number.parseInt(m[1], 10);\n // Skip common legitimate values\n if (COMMON_NUMBERS.has(num)) continue;\n // Skip if it's clearly a size constant definition\n if (line.includes('const') || line.includes('=')) {\n // Allow: const MAX_SIZE = 512 * 1024\n if (/(?:const|let|var)\\s+[A-Z_]+\\s*=/.test(line)) continue;\n }\n\n findings.push({\n key: makeKey('hardcoded', relFile, `num:${m[1]}:L${lineNum}`),\n scope: 'hardcoded',\n confidence: 'medium',\n file: relFile,\n line: lineNum,\n description: `Magic number ${m[1]} found`,\n recommendation: `Extract to named constant`,\n deterministicEvidence: [`Literal number ${m[1]} at line ${lineNum}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n }\n }\n\n // Hardcoded URLs (skip in tests)\n if (!isTest) {\n const urlMatches = line.matchAll(URL_REGEX);\n for (const m of urlMatches) {\n const urlKey = m[2].replace(/^https?:\\/\\//, '').split('/')[0];\n findings.push({\n key: makeKey('hardcoded', relFile, `url:${urlKey}:L${lineNum}`),\n scope: 'hardcoded',\n confidence: 'medium',\n file: relFile,\n line: lineNum,\n description: `Hardcoded URL: ${m[2].slice(0, 60)}`,\n recommendation: `Move to configuration or environment variable`,\n deterministicEvidence: [`URL literal at line ${lineNum}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n }\n }\n\n // Credential patterns (skip in tests — mock tokens/secrets are expected)\n if (!isTest) for (const pattern of CREDENTIAL_PATTERNS) {\n pattern.lastIndex = 0;\n if (pattern.test(line)) {\n findings.push({\n key: makeKey('hardcoded', relFile, `cred:L${lineNum}`),\n scope: 'hardcoded',\n confidence: 'high',\n file: relFile,\n line: lineNum,\n description: `Possible hardcoded credential`,\n recommendation: `Move to environment variable or secret manager`,\n deterministicEvidence: [`Credential pattern matched at line ${lineNum}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n }\n }\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Duplicates (report-only) ──\n\nexport function scanDuplicates(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n\n // Extract function bodies and hash them\n const funcRegex = /(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\([^)]*\\)\\s*(?::\\s*[^{]+)?\\{/g;\n const bodyMap = new Map<string, { file: string; name: string; line: number; hash: string }[]>();\n\n for (const file of allFiles) {\n const relFile = normalizePath(relative(projectDir, file));\n const content = readFileSafe(file);\n\n funcRegex.lastIndex = 0;\n let match = funcRegex.exec(content);\n while (match) {\n const startIdx = match.index + match[0].length;\n // Find matching closing brace (simple depth counting)\n let depth = 1;\n let endIdx = startIdx;\n while (endIdx < content.length && depth > 0) {\n if (content[endIdx] === '{') depth++;\n else if (content[endIdx] === '}') depth--;\n endIdx++;\n }\n\n const body = content.slice(startIdx, endIdx - 1);\n // Normalize: strip whitespace, variable names stay\n const normalized = body.replace(/\\s+/g, ' ').trim();\n\n // Only consider non-trivial functions (>50 chars after normalization)\n if (normalized.length > 50) {\n const hash = createHash('md5').update(normalized).digest('hex');\n const lineNum = content.slice(0, match.index).split('\\n').length;\n\n if (!bodyMap.has(hash)) bodyMap.set(hash, []);\n bodyMap.get(hash)!.push({ file: relFile, name: match[1], line: lineNum, hash });\n }\n\n match = funcRegex.exec(content);\n }\n }\n\n // Report groups with 2+ matches\n for (const [hash, group] of bodyMap) {\n if (group.length < 2) continue;\n\n const groupKey = group.map(g => `${g.file}:${g.line}`).sort().join('+');\n\n for (const item of group) {\n findings.push({\n key: makeKey('duplicates', item.file, `${hash.slice(0, 8)}:${item.name}`),\n scope: 'duplicates',\n confidence: 'low',\n file: item.file,\n line: item.line,\n description: `Function \"${item.name}\" has identical body to ${group.length - 1} other function(s)`,\n recommendation: `Consider extracting shared logic to a common utility`,\n deterministicEvidence: [`Body hash ${hash.slice(0, 8)} shared by: ${group.map(g => `${g.file}:${g.name}`).join(', ')}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n groupKey,\n });\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Dead Code (report-only, intra-module) ──\n\nexport function scanDeadCode(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n\n // Find non-exported functions/variables that are only defined but never referenced\n const internalDeclRegex = /^(?!export)\\s*(?:async\\s+)?(?:function|const|let|var)\\s+(\\w+)/gm;\n\n for (const file of allFiles) {\n const relFile = normalizePath(relative(projectDir, file));\n const content = readFileSafe(file);\n\n // Skip very small files (likely stubs)\n if (content.length < 50) continue;\n\n internalDeclRegex.lastIndex = 0;\n let match = internalDeclRegex.exec(content);\n while (match) {\n const name = match[1];\n const lineNum = content.slice(0, match.index).split('\\n').length;\n\n // Skip common patterns: single-letter vars, _prefixed, ALL_CAPS constants\n if (name.length <= 1 || name.startsWith('_')) {\n match = internalDeclRegex.exec(content);\n continue;\n }\n\n // Count occurrences of this name in the file (excluding the declaration itself)\n const regex = new RegExp(`\\\\b${name}\\\\b`, 'g');\n const occurrences = (content.match(regex) || []).length;\n\n // If name appears only once (the declaration), it's likely dead\n if (occurrences <= 1) {\n findings.push({\n key: makeKey('deadcode', relFile, name),\n scope: 'deadcode',\n confidence: 'low',\n file: relFile,\n line: lineNum,\n description: `\"${name}\" is declared but never referenced in this file`,\n recommendation: `Remove if unused, or export if needed elsewhere`,\n deterministicEvidence: [`\"${name}\" appears ${occurrences} time(s) in file (declaration only)`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n }\n\n match = internalDeclRegex.exec(content);\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Security (OWASP vulnerability detection) ──\n\nconst SECURITY_PATTERNS: { regex: RegExp; cwe: string; severity: 'critical' | 'high' | 'medium'; description: string; recommendation: string }[] = [\n // CWE-94: Code Injection\n { regex: /\\beval\\s*\\(/g, cwe: 'CWE-94', severity: 'critical', description: 'eval() usage — code injection risk', recommendation: 'Replace eval() with safe alternatives (JSON.parse, Function constructor with validation, or structured parsing)' },\n { regex: /\\bnew\\s+Function\\s*\\(/g, cwe: 'CWE-94', severity: 'critical', description: 'new Function() — dynamic code execution', recommendation: 'Avoid dynamic code generation; use static dispatch or lookup tables' },\n\n // CWE-78: OS Command Injection\n { regex: /child_process.*\\bexec\\s*\\(\\s*`/g, cwe: 'CWE-78', severity: 'critical', description: 'exec() with template literal — command injection risk', recommendation: 'Use execFile() with argument array instead of exec() with string interpolation' },\n { regex: /child_process.*\\bexec\\s*\\(\\s*[^'\"`\\s]+\\s*\\+/g, cwe: 'CWE-78', severity: 'critical', description: 'exec() with string concatenation — command injection risk', recommendation: 'Use execFile() with argument array instead of exec() with concatenation' },\n { regex: /\\bexecSync\\s*\\(\\s*`/g, cwe: 'CWE-78', severity: 'critical', description: 'execSync() with template literal — command injection', recommendation: 'Use execFileSync() with argument array' },\n\n // CWE-89: SQL Injection\n { regex: /\\.(?:query|exec|run|prepare)\\s*\\(\\s*`[^`]*\\$\\{/g, cwe: 'CWE-89', severity: 'critical', description: 'SQL query with template literal interpolation', recommendation: 'Use parameterized queries with ? placeholders' },\n { regex: /\\.(?:query|exec|run)\\s*\\([^)]*\\+/g, cwe: 'CWE-89', severity: 'high', description: 'SQL query with string concatenation', recommendation: 'Use parameterized queries instead of string building' },\n\n // CWE-22: Path Traversal\n { regex: /path\\.(?:join|resolve)\\s*\\([^)]*(?:req\\.|params\\.|query\\.|body\\.)/g, cwe: 'CWE-22', severity: 'high', description: 'Path construction with user input — traversal risk', recommendation: 'Validate and normalize paths, reject .. segments, use path.normalize() + startsWith() check' },\n\n // CWE-79: Cross-Site Scripting\n { regex: /\\.innerHTML\\s*=/g, cwe: 'CWE-79', severity: 'high', description: 'innerHTML assignment — XSS risk', recommendation: 'Use textContent or a sanitization library (DOMPurify)' },\n { regex: /dangerouslySetInnerHTML/g, cwe: 'CWE-79', severity: 'medium', description: 'dangerouslySetInnerHTML — potential XSS', recommendation: 'Sanitize HTML before rendering; use DOMPurify or similar' },\n\n // CWE-601: Open Redirect\n { regex: /res\\.redirect\\s*\\(\\s*(?:req\\.(?:query|params|body)\\.|[^'\"`\\s])/g, cwe: 'CWE-601', severity: 'high', description: 'Redirect with user-controlled input — open redirect', recommendation: 'Validate redirect target against allowlist of safe URLs' },\n\n // CWE-798: Hardcoded Credentials (beyond what hardcoded scanner catches)\n { regex: /(?:jwt|bearer)\\s*[:=]\\s*['\"`][A-Za-z0-9\\-_.]+['\"`]/gi, cwe: 'CWE-798', severity: 'high', description: 'Hardcoded JWT/Bearer token', recommendation: 'Move tokens to environment variables or secret manager' },\n\n // CWE-327: Weak Cryptography\n { regex: /createHash\\s*\\(\\s*['\"`](?:md5|sha1)['\"`]\\s*\\)/g, cwe: 'CWE-327', severity: 'medium', description: 'Weak hash algorithm (MD5/SHA1)', recommendation: 'Use SHA-256 or stronger for security-sensitive hashing' },\n\n // CWE-1333: ReDoS\n { regex: /new\\s+RegExp\\s*\\(\\s*[^)]*(?:\\.\\*|\\.\\+|\\(.*\\|.*\\))\\s*[^)]*\\)/g, cwe: 'CWE-1333', severity: 'medium', description: 'Dynamic regex with potential catastrophic backtracking', recommendation: 'Audit regex for ReDoS; consider using re2 or safe-regex library' },\n\n // CWE-200: Information Exposure\n { regex: /(?:console\\.(?:log|error|warn)|res\\.(?:json|send))\\s*\\(\\s*(?:err|error|e)\\s*\\)/g, cwe: 'CWE-200', severity: 'medium', description: 'Full error object exposed — may leak stack traces/internals', recommendation: 'Log errors server-side; return sanitized error messages to clients' },\n\n // CWE-352: Missing CSRF (heuristic)\n { regex: /app\\.(?:post|put|patch|delete)\\s*\\([^)]*,\\s*(?:async\\s+)?\\([^)]*req/g, cwe: 'CWE-352', severity: 'medium', description: 'State-changing route without visible CSRF protection', recommendation: 'Add CSRF token validation middleware (csurf, csrf-csrf)' },\n];\n\nexport function scanSecurity(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n\n for (const file of allFiles) {\n const relFile = normalizePath(relative(projectDir, file));\n const isTest = relFile.includes('test') || relFile.includes('spec') || relFile.includes('__test');\n // Skip test files — mock code intentionally uses unsafe patterns\n if (isTest) continue;\n\n const content = readFileSafe(file);\n const lines = content.split('\\n');\n\n for (const pattern of SECURITY_PATTERNS) {\n pattern.regex.lastIndex = 0;\n let match = pattern.regex.exec(content);\n while (match) {\n const lineNum = content.slice(0, match.index).split('\\n').length;\n const lineContent = lines[lineNum - 1]?.trim() || '';\n\n // Skip commented lines and regex/string literals (scanner definition patterns)\n if (lineContent.startsWith('//') || lineContent.startsWith('*') ||\n lineContent.startsWith('{ regex:') || lineContent.startsWith('regex:') ||\n /^\\s*\\//.test(lineContent) || /^\\s*['\"`].*['\"`]\\s*[,;]?\\s*$/.test(lineContent)) {\n match = pattern.regex.exec(content);\n continue;\n }\n\n const confidence: CleanupConfidence = pattern.severity === 'critical' ? 'high' : pattern.severity === 'high' ? 'medium' : 'low';\n\n findings.push({\n key: makeKey('security', relFile, `${pattern.cwe}:L${lineNum}`),\n scope: 'security',\n confidence,\n file: relFile,\n line: lineNum,\n description: `[${pattern.cwe}] ${pattern.description}`,\n recommendation: pattern.recommendation,\n deterministicEvidence: [`Pattern matched at line ${lineNum}: ${lineContent.slice(0, 80)}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n\n match = pattern.regex.exec(content);\n }\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Near-Duplicates (fuzzy similarity) ──\n\n/** Tokenize a function body: strip whitespace, normalize identifiers to placeholders */\nfunction tokenize(body: string): string[] {\n return body\n .replace(/\\/\\/[^\\n]*/g, '') // strip line comments\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '') // strip block comments\n .replace(/\\s+/g, ' ') // collapse whitespace\n .trim()\n .split(/(\\W)/) // split on non-word chars, keep delimiters\n .filter(t => t.trim().length > 0);\n}\n\n/** Build n-gram set for Jaccard similarity */\nfunction ngramSet(tokens: string[], n: number): Set<string> {\n const set = new Set<string>();\n for (let i = 0; i <= tokens.length - n; i++) {\n set.add(tokens.slice(i, i + n).join('|'));\n }\n return set;\n}\n\n/** Jaccard similarity between two sets */\nfunction jaccard(a: Set<string>, b: Set<string>): number {\n let intersection = 0;\n for (const item of a) {\n if (b.has(item)) intersection++;\n }\n const union = a.size + b.size - intersection;\n return union === 0 ? 0 : intersection / union;\n}\n\ninterface FuncEntry {\n file: string;\n name: string;\n line: number;\n tokens: string[];\n ngrams: Set<string>;\n bodyLength: number;\n}\n\nexport function scanNearDuplicates(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n const funcRegex = /(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\([^)]*\\)\\s*(?::\\s*[^{]+)?\\{/g;\n const funcs: FuncEntry[] = [];\n\n // Extract all functions\n for (const file of allFiles) {\n const relFile = normalizePath(relative(projectDir, file));\n const content = readFileSafe(file);\n\n funcRegex.lastIndex = 0;\n let match = funcRegex.exec(content);\n while (match) {\n const startIdx = match.index + match[0].length;\n let depth = 1;\n let endIdx = startIdx;\n while (endIdx < content.length && depth > 0) {\n if (content[endIdx] === '{') depth++;\n else if (content[endIdx] === '}') depth--;\n endIdx++;\n }\n\n const body = content.slice(startIdx, endIdx - 1);\n const tokens = tokenize(body);\n\n // Only consider non-trivial functions (>20 tokens)\n if (tokens.length > 20) {\n const ngrams = ngramSet(tokens, 5);\n const lineNum = content.slice(0, match.index).split('\\n').length;\n funcs.push({ file: relFile, name: match[1], line: lineNum, tokens, ngrams, bodyLength: body.length });\n }\n\n match = funcRegex.exec(content);\n }\n }\n\n // Compare all pairs (O(n^2) — bounded by function count, not file count)\n const reported = new Set<string>();\n for (let i = 0; i < funcs.length; i++) {\n for (let j = i + 1; j < funcs.length; j++) {\n const a = funcs[i];\n const b = funcs[j];\n\n // Skip exact same file+name (already caught by duplicates scanner)\n if (a.file === b.file && a.name === b.name) continue;\n\n // Quick size filter: bodies must be within 2x of each other\n const sizeRatio = Math.min(a.bodyLength, b.bodyLength) / Math.max(a.bodyLength, b.bodyLength);\n if (sizeRatio < 0.5) continue;\n\n const sim = jaccard(a.ngrams, b.ngrams);\n\n // Skip exact duplicates (handled by duplicates scanner)\n if (sim >= 0.98) continue;\n\n if (sim >= 0.70) {\n const pairKey = [a.file, a.name, b.file, b.name].sort().join('+');\n if (reported.has(pairKey)) continue;\n reported.add(pairKey);\n\n const confidence: CleanupConfidence = sim >= 0.90 ? 'high' : sim >= 0.80 ? 'medium' : 'low';\n const simPct = Math.round(sim * 100);\n\n // Report for the first function\n findings.push({\n key: makeKey('near-duplicates', a.file, `${a.name}~${b.name}`),\n scope: 'near-duplicates',\n confidence,\n file: a.file,\n line: a.line,\n description: `\"${a.name}\" is ${simPct}% similar to \"${b.name}\" in ${b.file}:${b.line}`,\n recommendation: `Consider extracting shared logic into a common utility function`,\n deterministicEvidence: [`Jaccard 5-gram similarity: ${simPct}% between ${a.name} (${a.file}:${a.line}) and ${b.name} (${b.file}:${b.line})`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n groupKey: pairKey,\n });\n }\n }\n }\n\n return findings;\n}\n\n// ── Scanner: Anti-Patterns (AI code smells) ──\n\nconst ANTI_PATTERNS: { regex: RegExp; name: string; description: string; recommendation: string; confidence: CleanupConfidence; skipTests: boolean }[] = [\n // Empty catch blocks\n { regex: /catch\\s*\\([^)]*\\)\\s*\\{\\s*\\}/g, name: 'empty-catch', description: 'Empty catch block swallows errors silently', recommendation: 'Log the error or re-throw; empty catches hide bugs', confidence: 'high', skipTests: false },\n { regex: /catch\\s*\\{\\s*\\}/g, name: 'empty-catch', description: 'Empty catch block (no parameter) swallows errors', recommendation: 'At minimum add a comment explaining why errors are ignored', confidence: 'high', skipTests: false },\n\n // console.log in production code\n { regex: /\\bconsole\\.log\\s*\\(/g, name: 'console-log', description: 'console.log left in production code', recommendation: 'Remove or replace with proper logger', confidence: 'medium', skipTests: true },\n\n // async function without await\n { regex: /async\\s+function\\s+(\\w+)\\s*\\([^)]*\\)\\s*(?::\\s*[^{]+)?\\{/g, name: 'async-no-await', description: 'async function may not need async keyword', recommendation: 'Remove async if function does not use await', confidence: 'low', skipTests: true },\n\n // Redundant return undefined\n { regex: /return\\s+undefined\\s*;/g, name: 'return-undefined', description: 'Redundant \"return undefined\" — functions return undefined by default', recommendation: 'Use bare \"return;\" or remove the return statement', confidence: 'medium', skipTests: false },\n\n // Nested ternaries (readability hazard)\n { regex: /\\?[^:?]*\\?/g, name: 'nested-ternary', description: 'Nested ternary operator — hard to read', recommendation: 'Refactor to if/else or extract to a helper function', confidence: 'low', skipTests: true },\n\n // Type assertion chains (TypeScript)\n { regex: /as\\s+\\w+(?:\\s*\\[\\s*\\])?\\s+as\\s+/g, name: 'double-assertion', description: 'Double type assertion (as X as Y) — type safety bypass', recommendation: 'Fix the underlying type instead of double-casting', confidence: 'high', skipTests: false },\n\n // any type usage\n { regex: /:\\s*any\\b/g, name: 'any-type', description: '\"any\" type defeats TypeScript type safety', recommendation: 'Use unknown, proper generics, or specific types', confidence: 'low', skipTests: true },\n\n // Promise constructor anti-pattern\n { regex: /new\\s+Promise\\s*\\(\\s*(?:async\\s+)?\\(\\s*resolve\\s*(?:,\\s*reject)?\\s*\\)\\s*=>\\s*\\{[^}]*await\\b/g, name: 'promise-constructor-async', description: 'Promise constructor with async executor — error handling is broken', recommendation: 'Remove Promise wrapper; async functions already return promises', confidence: 'high', skipTests: false },\n\n // setTimeout/setInterval with string argument\n { regex: /(?:setTimeout|setInterval)\\s*\\(\\s*['\"`]/g, name: 'implicit-eval', description: 'setTimeout/setInterval with string argument — implicit eval()', recommendation: 'Pass a function reference instead of a string', confidence: 'high', skipTests: false },\n];\n\nexport function scanAntiPatterns(projectDir: string, ig?: Ignore): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const allFiles = walkFiles(projectDir, SOURCE_EXTS, [], projectDir, ig);\n\n for (const file of allFiles) {\n const relFile = normalizePath(relative(projectDir, file));\n const isTest = relFile.includes('test') || relFile.includes('spec') || relFile.includes('__test');\n const content = readFileSafe(file);\n const lines = content.split('\\n');\n\n for (const pattern of ANTI_PATTERNS) {\n if (pattern.skipTests && isTest) continue;\n\n pattern.regex.lastIndex = 0;\n\n // Special handling for async-no-await: need to check function body\n if (pattern.name === 'async-no-await') {\n let match = pattern.regex.exec(content);\n while (match) {\n const funcName = match[1];\n const startIdx = match.index + match[0].length;\n let depth = 1;\n let endIdx = startIdx;\n while (endIdx < content.length && depth > 0) {\n if (content[endIdx] === '{') depth++;\n else if (content[endIdx] === '}') depth--;\n endIdx++;\n }\n const body = content.slice(startIdx, endIdx - 1);\n if (!body.includes('await ') && !body.includes('await(') && !body.includes('for await')) {\n const lineNum = content.slice(0, match.index).split('\\n').length;\n findings.push({\n key: makeKey('anti-patterns', relFile, `${pattern.name}:${funcName}:L${lineNum}`),\n scope: 'anti-patterns',\n confidence: pattern.confidence,\n file: relFile,\n line: lineNum,\n description: `${pattern.description}: \"${funcName}\"`,\n recommendation: pattern.recommendation,\n deterministicEvidence: [`async function \"${funcName}\" at line ${lineNum} contains no await expressions`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n }\n match = pattern.regex.exec(content);\n }\n continue;\n }\n\n let match = pattern.regex.exec(content);\n while (match) {\n const lineNum = content.slice(0, match.index).split('\\n').length;\n const lineContent = lines[lineNum - 1]?.trim() || '';\n\n // Skip commented lines and regex/string literals (scanner definition patterns)\n if (lineContent.startsWith('//') || lineContent.startsWith('*') ||\n lineContent.startsWith('{ regex:') || lineContent.startsWith('regex:') ||\n /^\\s*\\//.test(lineContent)) {\n match = pattern.regex.exec(content);\n continue;\n }\n\n findings.push({\n key: makeKey('anti-patterns', relFile, `${pattern.name}:L${lineNum}`),\n scope: 'anti-patterns',\n confidence: pattern.confidence,\n file: relFile,\n line: lineNum,\n description: pattern.description,\n recommendation: pattern.recommendation,\n deterministicEvidence: [`Pattern matched at line ${lineNum}: ${lineContent.slice(0, 80)}`],\n semanticEvidence: [],\n hostEvidence: [],\n sources: ['deterministic'],\n disputed: false,\n });\n\n match = pattern.regex.exec(content);\n }\n }\n }\n\n return findings;\n}\n\n// ── Run all scanners ──\n\nexport function runAllScanners(\n projectDir: string,\n scopes: CleanupScope[],\n ig?: Ignore,\n): CleanupFinding[] {\n const findings: CleanupFinding[] = [];\n const ALL_SCOPES: CleanupScope[] = ['deps', 'unused-exports', 'hardcoded', 'duplicates', 'deadcode', 'security', 'near-duplicates', 'anti-patterns'];\n const activeScopes = new Set(scopes.includes('all' as CleanupScope) ? ALL_SCOPES : scopes);\n\n if (activeScopes.has('deps')) findings.push(...scanUnusedDeps(projectDir, ig));\n if (activeScopes.has('unused-exports')) findings.push(...scanUnusedExports(projectDir, ig));\n if (activeScopes.has('hardcoded')) findings.push(...scanHardcoded(projectDir, ig));\n if (activeScopes.has('duplicates')) findings.push(...scanDuplicates(projectDir, ig));\n if (activeScopes.has('deadcode')) findings.push(...scanDeadCode(projectDir, ig));\n if (activeScopes.has('security')) findings.push(...scanSecurity(projectDir, ig));\n if (activeScopes.has('near-duplicates')) findings.push(...scanNearDuplicates(projectDir, ig));\n if (activeScopes.has('anti-patterns')) findings.push(...scanAntiPatterns(projectDir, ig));\n\n // Sort by key for deterministic output\n findings.sort((a, b) => a.key.localeCompare(b.key));\n return findings;\n}\n","// packages/core/src/cleanup/merge.ts — 3-way merge logic for cleanup findings\n\nimport type { CleanupFinding, CleanupReport } from '../types/cleanup.js';\n\n/** Normalize keys: forward slashes, strip ./ prefix from each segment */\nfunction normalizeKey(key: string): string {\n return key\n .replaceAll('\\\\', '/')\n .split(':')\n .map(s => s.replace(/^\\.\\//, ''))\n .join(':');\n}\n\n/** Count unique keys in a findings array. */\nfunction uniqueKeyCount(findings: CleanupFinding[]): number {\n const seen = new Set<string>();\n for (const f of findings) seen.add(normalizeKey(f.key));\n return seen.size;\n}\n\n/**\n * Merge findings from up to 3 sources: deterministic, semantic (codex), and host (Claude).\n * Agreement rules:\n * - All 3 agree → confidence: high\n * - 2 of 3 agree → confidence: high (majority)\n * - Only 1 found → original confidence preserved, disputed: true\n */\nexport function mergeThreeWay(\n deterministic: CleanupFinding[],\n semantic: CleanupFinding[],\n host: CleanupFinding[],\n): CleanupFinding[] {\n const merged = new Map<string, CleanupFinding>();\n const sourceSet = new Map<string, Set<string>>();\n\n // Add all deterministic findings (merge duplicates within same source)\n for (const f of deterministic) {\n const nk = normalizeKey(f.key);\n const existing = merged.get(nk);\n if (existing) {\n existing.deterministicEvidence.push(...f.deterministicEvidence);\n } else {\n merged.set(nk, {\n ...f,\n key: nk,\n deterministicEvidence: [...f.deterministicEvidence],\n semanticEvidence: [],\n hostEvidence: [],\n sources: [],\n });\n sourceSet.set(nk, new Set());\n }\n (sourceSet.get(nk) as Set<string>).add('deterministic');\n }\n\n // Merge semantic findings\n for (const f of semantic) {\n const nk = normalizeKey(f.key);\n const existing = merged.get(nk);\n if (existing) {\n existing.semanticEvidence.push(...f.semanticEvidence);\n } else {\n merged.set(nk, {\n ...f,\n key: nk,\n deterministicEvidence: [],\n semanticEvidence: [...f.semanticEvidence],\n hostEvidence: [],\n sources: [],\n });\n sourceSet.set(nk, new Set());\n }\n (sourceSet.get(nk) as Set<string>).add('semantic');\n }\n\n // Merge host findings\n for (const f of host) {\n const nk = normalizeKey(f.key);\n const existing = merged.get(nk);\n if (existing) {\n existing.hostEvidence.push(...f.hostEvidence);\n } else {\n merged.set(nk, {\n ...f,\n key: nk,\n deterministicEvidence: [],\n semanticEvidence: [],\n hostEvidence: [...f.hostEvidence],\n sources: [],\n });\n sourceSet.set(nk, new Set());\n }\n (sourceSet.get(nk) as Set<string>).add('host');\n }\n\n // Apply confidence rules based on unique source count\n for (const [key, finding] of merged) {\n const sources = sourceSet.get(key) as Set<string>;\n finding.sources = Array.from(sources) as CleanupFinding['sources'];\n const count = sources.size;\n if (count >= 2) {\n finding.confidence = 'high';\n finding.disputed = false;\n } else {\n // Single source: keep original confidence, but mark as disputed\n finding.disputed = true;\n }\n }\n\n return Array.from(merged.values());\n}\n\n/**\n * Compute stats from merged findings with 3-source tracking.\n */\nexport function computeThreeWayStats(\n deterministic: CleanupFinding[],\n semantic: CleanupFinding[],\n host: CleanupFinding[],\n merged: CleanupFinding[],\n): CleanupReport['stats'] {\n return {\n deterministic: uniqueKeyCount(deterministic),\n semantic: uniqueKeyCount(semantic),\n host: uniqueKeyCount(host),\n agreed: merged.filter(f => f.sources.length >= 2).length,\n disputed: merged.filter(f => f.disputed).length,\n adjudicated: 0,\n highConfidence: merged.filter(f => f.confidence === 'high').length,\n mediumConfidence: merged.filter(f => f.confidence === 'medium').length,\n lowConfidence: merged.filter(f => f.confidence === 'low').length,\n };\n}\n\n/**\n * Legacy 2-way merge (deterministic + semantic only). Wraps mergeThreeWay with empty host.\n */\nexport function mergeTwoWay(\n deterministic: CleanupFinding[],\n semantic: CleanupFinding[],\n): CleanupFinding[] {\n return mergeThreeWay(deterministic, semantic, []);\n}\n\n/**\n * Legacy 2-way stats. Wraps computeThreeWayStats with empty host.\n */\nexport function computeTwoWayStats(\n deterministic: CleanupFinding[],\n semantic: CleanupFinding[],\n merged: CleanupFinding[],\n): CleanupReport['stats'] {\n return computeThreeWayStats(deterministic, semantic, [], merged);\n}\n\n/**\n * Recalculate stats after adjudication modifies findings in place.\n * Note: `stats.adjudicated` is managed by the caller (incremented per adjudication).\n */\nexport function recalculateConfidenceStats(\n findings: CleanupFinding[],\n stats: CleanupReport['stats'],\n): void {\n stats.highConfidence = findings.filter(f => f.confidence === 'high').length;\n stats.mediumConfidence = findings.filter(f => f.confidence === 'medium').length;\n stats.lowConfidence = findings.filter(f => f.confidence === 'low').length;\n stats.agreed = findings.filter(f => f.sources.length >= 2).length;\n stats.disputed = findings.filter(f => f.disputed).length;\n}\n","// packages/core/src/cleanup/host-schema.ts — Zod schema for host AI findings input\n\nimport { z } from 'zod';\n\nconst scopeSchema = z.enum(['deps', 'unused-exports', 'hardcoded', 'duplicates', 'deadcode']);\n\n/** Scope-specific symbol validation patterns */\nconst symbolPatterns: Record<string, RegExp> = {\n deps: /^[@a-z0-9][\\w./@-]*$/i,\n 'unused-exports': /^[$_a-z][\\w$]*$/i,\n hardcoded: /^(num:[^:]+:L\\d+|url:[^:]+:L\\d+|cred:L\\d+)$/,\n duplicates: /^[a-f0-9]{8}:[\\w$]+$/i,\n deadcode: /^[$_a-z][\\w$]*$/i,\n};\n\nconst hostFindingSchema = z.object({\n scope: scopeSchema,\n confidence: z.enum(['high', 'medium', 'low']),\n file: z.string().min(1),\n line: z.number().int().nonnegative().optional(),\n symbol: z.string().min(1),\n description: z.string().min(1),\n recommendation: z.string().min(1),\n}).refine(\n (data) => {\n const pattern = symbolPatterns[data.scope];\n return pattern ? pattern.test(data.symbol) : true;\n },\n (data) => ({\n message: `Symbol \"${data.symbol}\" does not match expected pattern for scope \"${data.scope}\"`,\n }),\n);\n\nexport const hostFindingsSchema = z.array(hostFindingSchema);\n\nexport type HostFindingInput = z.infer<typeof hostFindingSchema>;\n","// @codemoot/core - Multi-model AI orchestration engine\r\n// Sprint 1: Core engine + SQLite memory + model abstraction\r\n// Sprint 2: CLI-first hybrid + MCP types + security + cancellation\r\n\r\nexport const VERSION = '0.2.3';\r\n\r\n// Type definitions\r\nexport type {\r\n // Config\r\n ModelProvider,\r\n ModelConfig,\r\n RoleConfig,\r\n DebateConfig,\r\n DebatePattern,\r\n MemoryConfig,\r\n BudgetConfig,\r\n OutputConfig,\r\n ProjectConfig,\r\n ExecutionMode,\r\n PresetName,\r\n CliAdapterConfig,\r\n // Workflow\r\n WorkflowDefinition,\r\n StepDefinition,\r\n StepType,\r\n LoopConfig,\r\n ResolvedWorkflow,\r\n ResolvedStep,\r\n // Events\r\n SessionStartedEvent,\r\n SessionCompletedEvent,\r\n SessionFailedEvent,\r\n StepStartedEvent,\r\n StepCompletedEvent,\r\n StepFailedEvent,\r\n TextDeltaEvent,\r\n TextDoneEvent,\r\n LoopIterationEvent,\r\n CostUpdateEvent,\r\n TokenUsage,\r\n EngineEvent,\r\n // Session\r\n SessionStatus,\r\n Session,\r\n TranscriptEntry,\r\n // Memory\r\n MemoryCategory,\r\n MemoryRecord,\r\n ArtifactType,\r\n ArtifactRecord,\r\n CostLogEntry,\r\n // Models\r\n ChatMessage,\r\n CallModelOptions,\r\n ModelCallResult,\r\n FallbackConfig,\r\n // MCP types\r\n ResultStatus,\r\n MeteringSource,\r\n ReviewResult,\r\n DebateResponse,\r\n DebateResult,\r\n ReviewInput,\r\n PlanInput,\r\n DebateInput,\r\n MemoryInput,\r\n CostInput,\r\n // Roles\r\n BuiltInRole,\r\n Role,\r\n // Cleanup\r\n CleanupScope,\r\n CleanupConfidence,\r\n CleanupFinding,\r\n CleanupReport,\r\n CleanupSource,\r\n // Build\r\n BuildPhase,\r\n BuildRun,\r\n BuildSummary,\r\n // Debate engine\r\n DebateEngineState,\r\n // Jobs\r\n JobType,\r\n JobStatus,\r\n JobRecord,\r\n JobLogRecord,\r\n EnqueueOptions,\r\n} from './types/index.js';\r\n\r\nexport {\r\n ErrorCode,\r\n TerminalReason,\r\n DlpReasonCode,\r\n reviewInputSchema,\r\n planInputSchema,\r\n debateInputSchema,\r\n memoryInputSchema,\r\n costInputSchema,\r\n reviewOutputSchema,\r\n debateOutputSchema,\r\n} from './types/index.js';\r\n\r\n// Utilities\r\nexport {\r\n generateSessionId,\r\n generateId,\r\n ConfigError,\r\n ModelError,\r\n WorkflowError,\r\n DatabaseError,\r\n withRetry,\r\n createLogger,\r\n parseVerdict,\r\n sleep,\r\n} from './utils/index.js';\r\nexport type { RetryOptions, Logger, LogLevel, VerdictResult } from './utils/index.js';\r\nexport {\r\n DEFAULT_TIMEOUT_SEC,\r\n CLEANUP_TIMEOUT_SEC,\r\n DEFAULT_MAX_TOKENS,\r\n IMPLEMENTER_MAX_TOKENS,\r\n MCP_CONTENT_MAX_LENGTH,\r\n MCP_TASK_MAX_LENGTH,\r\n MCP_TIMEOUT_MAX,\r\n HTTP_TOO_MANY_REQUESTS,\r\n DAYS_PER_YEAR,\r\n REVIEW_DIFF_MAX_CHARS,\r\n REVIEW_TEXT_MAX_CHARS,\r\n BINARY_SNIFF_BYTES,\r\n CONTEXT_ACTIVE,\r\n CONTEXT_RETRIEVED,\r\n CONTEXT_BUFFER,\r\n DLP_MAX_CONTENT,\r\n DLP_MAX_PROCESSING_MS,\r\n} from './utils/constants.js';\r\n\r\n// Configuration\r\nexport {\r\n DEFAULT_CONFIG,\r\n projectConfigSchema,\r\n validateConfig,\r\n loadPreset,\r\n listPresets,\r\n loadConfig,\r\n writeConfig,\r\n migrateConfig,\r\n CURRENT_VERSION,\r\n getReviewPreset,\r\n listPresetNames,\r\n REVIEW_PRESETS,\r\n createIgnoreFilter,\r\n loadIgnorePatterns,\r\n shouldIgnore,\r\n} from './config/index.js';\r\nexport type { ProjectConfigInput, ReviewPreset } from './config/index.js';\r\n\r\n// Memory / Database\r\nexport {\r\n openDatabase,\r\n runMigrations,\r\n getSchemaVersion,\r\n SessionStore,\r\n MemoryStore,\r\n ArtifactStore,\r\n CostStore,\r\n DebateStore,\r\n BuildStore,\r\n MessageStore,\r\n parseDebateVerdict,\r\n buildReconstructionPrompt,\r\n estimateTokens,\r\n calculateDebateTokens,\r\n getTokenBudgetStatus,\r\n preflightTokenCheck,\r\n SessionManager,\r\n JobStore,\r\n CacheStore,\r\n hashContent,\r\n hashConfig,\r\n} from './memory/index.js';\r\nexport type { CostSummary, DebateTurnRow, DebateTurnStatus, DebateMessageRow, MessageStatus, ParsedVerdict, UnifiedSession, SessionEvent, SessionOverflowStatus, CacheEntry } from './memory/index.js';\r\n\r\n// Model Abstraction (CLI-only)\r\nexport {\r\n ModelRegistry,\r\n callModel,\r\n streamModel,\r\n withFallback,\r\n CostTracker,\r\n getModelPricing,\r\n calculateCost,\r\n CliAdapter,\r\n detectCli,\r\n clearDetectionCache,\r\n} from './models/index.js';\r\nexport type {\r\n TextDeltaEmitter,\r\n ModelPricing,\r\n ModelAdapter,\r\n CliCallOptions,\r\n CliDetectionResult,\r\n ProgressCallbacks,\r\n CliBridge,\r\n BridgeCapabilities,\r\n BridgeOptions,\r\n BridgeResumeOptions,\r\n} from './models/index.js';\r\n\r\n// Roles\r\nexport { RoleManager, renderPrompt } from './roles/index.js';\r\nexport type { PromptType, PromptVariables } from './roles/index.js';\r\n\r\n// Engine (Workflow + Execution)\r\nexport {\r\n EventBus,\r\n LoopController,\r\n Orchestrator,\r\n StepRunner,\r\n WorkflowEngine,\r\n CancellationToken,\r\n CancellationError,\r\n evaluatePolicy,\r\n DEFAULT_RULES,\r\n} from './engine/index.js';\r\nexport type {\r\n DebateOptions,\r\n LoopResult,\r\n OrchestratorOptions,\r\n PlanOptions,\r\n ReviewOptions,\r\n RunOptions,\r\n SessionResult,\r\n StepResult,\r\n PolicyRule,\r\n PolicyContext,\r\n PolicyResult,\r\n PolicyMode,\r\n PolicyDecision,\r\n} from './engine/index.js';\r\n\r\n// Context Builder\r\nexport { ContextBuilder, buildHandoffEnvelope } from './context/index.js';\r\nexport type {\r\n AssembledContext,\r\n ContextBudget,\r\n ContextBuilderOptions,\r\n HandoffCommand,\r\n HandoffEnvelopeOptions,\r\n} from './context/index.js';\r\n\r\n// Cleanup Scanners\r\nexport {\r\n scanUnusedDeps,\r\n scanUnusedExports,\r\n scanHardcoded,\r\n scanDuplicates,\r\n scanDeadCode,\r\n scanSecurity,\r\n scanNearDuplicates,\r\n scanAntiPatterns,\r\n runAllScanners,\r\n mergeThreeWay,\r\n mergeTwoWay,\r\n computeThreeWayStats,\r\n computeTwoWayStats,\r\n recalculateConfidenceStats,\r\n hostFindingsSchema,\r\n} from './cleanup/index.js';\r\nexport type { HostFindingInput } from './cleanup/index.js';\r\n\r\n// Security (DLP + Retry)\r\nexport {\r\n withCanonicalRetry,\r\n isRetryable,\r\n isRateLimit,\r\n sanitize,\r\n DEFAULT_DLP_CONFIG,\r\n} from './security/index.js';\r\nexport type {\r\n RetryConfig,\r\n AttemptResult,\r\n DlpMode,\r\n DlpResult,\r\n DlpRedaction,\r\n DlpAuditEntry,\r\n DlpConfig,\r\n} from './security/index.js';\r\n"],"mappings":"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","names":["ErrorCode","TerminalReason","DlpReasonCode","resolve","log","z","z","readFileSync","join","parseYaml","join","readFileSync","parseYaml","writeFileSync","stringifyYaml","stringifyYaml","writeFileSync","existsSync","readFileSync","join","estimateTokens","estimateTokens","join","join","resolve","isRetryable","dirname","fileURLToPath","EventEmitter","readFileSync","join","join","readFileSync","nanoid","DEFAULT_BUDGET","readFileSync","join","parseYaml","join","readFileSync","parseYaml","dirname","fileURLToPath","resolve","EventEmitter","resolve","readFileSync","readdirSync","statSync","existsSync","join","createHash","match","z"]}