promptpilot 0.1.8 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +147 -285
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +109 -33
- package/dist/cli.js.map +1 -1
- package/dist/index.js +61 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/errors.ts","../src/storage/fileSessionStore.ts","../src/utils/validation.ts","../src/storage/sqliteSessionStore.ts","../src/utils/logger.ts","../src/utils/json.ts","../src/core/ollamaClient.ts","../src/core/systemPrompt.ts","../src/core/tokenEstimator.ts","../src/core/contextCompressor.ts","../src/core/contextManager.ts","../src/core/modelSelector.ts","../src/core/optimizer.ts","../src/index.ts","../src/cliMenu.ts","../src/cliWelcome.ts","../src/utils/spinner.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync, realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { execSync } from \"node:child_process\";\n\nimport { createOptimizer, CLAUDE_TIER_TARGETS } from \"./index.js\";\nimport { promptClaudeTierMenu } from \"./cliMenu.js\";\nimport type { ClaudeTierChoice } from \"./cliMenu.js\";\nimport { renderWelcomeScreen } from \"./cliWelcome.js\";\nimport { toPrettyJson } from \"./utils/json.js\";\nimport { createLogger } from \"./utils/logger.js\";\nimport { createSpinner } from \"./utils/spinner.js\";\nimport type { RoutingPriority, TargetCapability, TargetModelCandidate, WorkloadBias } from \"./types.js\";\n\ntype CliWriter = {\n write(message: string): void;\n isTTY?: boolean;\n columns?: number;\n};\n\ninterface CliIO {\n stdout: CliWriter;\n stderr: CliWriter;\n stdin?: NodeJS.ReadStream;\n}\n\ninterface CliDependencies {\n createOptimizer: typeof createOptimizer;\n readStdin: (stdin?: NodeJS.ReadStream) => Promise<string>;\n getCliInfo?: (stdout: CliWriter) => { cwd: string; version: string; color: boolean; columns?: number; user?: string };\n}\n\nexport async function runCli(\n argv: string[],\n io: CliIO = { stdout: process.stdout, stderr: process.stderr, stdin: process.stdin },\n dependencies: CliDependencies = { createOptimizer, readStdin, getCliInfo }\n): Promise<number> {\n const [command, ...rest] = argv;\n\n if (!command) {\n const info = (dependencies.getCliInfo ?? getCliInfo)(io.stdout);\n if (io.stdout.isTTY) {\n io.stdout.write(`${renderWelcomeScreen(info)}\\n`);\n return 0;\n }\n io.stdout.write(`${getHelpText()}\\n`);\n return 0;\n }\n\n if (command === \"--help\" || command === \"-h\" || command === \"help\") {\n io.stdout.write(`${getHelpText()}\\n`);\n return 0;\n }\n\n if (command !== \"optimize\") {\n io.stderr.write(`Unknown command: ${command}\\n`);\n io.stderr.write(`${getHelpText()}\\n`);\n return 1;\n }\n\n const parsed = parseOptimizeArgs(rest);\n if (parsed.help) {\n io.stdout.write(`${getHelpText()}\\n`);\n return 0;\n }\n\n if (!parsed.sessionId && parsed.clearSession) {\n io.stderr.write(\"--clear-session requires --session <id>.\\n\");\n return 1;\n }\n\n const optimizer = dependencies.createOptimizer({\n provider: \"ollama\",\n ollamaModel: parsed.model,\n host: parsed.host,\n contextStore: parsed.contextStore,\n storageDir: parsed.storageDir,\n sqlitePath: parsed.sqlitePath,\n timeoutMs: parsed.timeoutMs,\n logger: createLogger(parsed.debug)\n });\n\n if (parsed.clearSession && parsed.sessionId) {\n await optimizer.clearContext(parsed.sessionId);\n if (!parsed.prompt) {\n io.stdout.write(`Cleared session ${parsed.sessionId}\\n`);\n return 0;\n }\n }\n\n if (!parsed.prompt) {\n const stdinPrompt = await dependencies.readStdin(io.stdin);\n parsed.prompt = stdinPrompt.trim() || undefined;\n }\n\n if (!parsed.prompt) {\n io.stderr.write(\"A prompt is required.\\n\");\n return 1;\n }\n\n // Show the Claude tier menu when --claude is set and we have a real TTY\n let claudeTierChoice: ClaudeTierChoice | null = null;\n if (parsed.autoClaudeTiers && io.stderr.isTTY && io.stdin) {\n claudeTierChoice = await promptClaudeTierMenu(io.stderr, io.stdin as NodeJS.ReadStream);\n if (claudeTierChoice === null) {\n // User cancelled\n return 0;\n }\n }\n\n // Resolve which targets to pass based on tier choice\n const resolvedTargets = (() => {\n if (!parsed.autoClaudeTiers) return parsed.targets;\n if (!claudeTierChoice || claudeTierChoice === \"auto\") return [...CLAUDE_TIER_TARGETS, ...parsed.targets];\n const picked = CLAUDE_TIER_TARGETS.find((t) => t.model.toLowerCase().includes(claudeTierChoice!));\n return picked ? [picked, ...parsed.targets] : [...CLAUDE_TIER_TARGETS, ...parsed.targets];\n })();\n\n const spinner = createSpinner(io.stderr, io.stderr.isTTY ?? false);\n\n try {\n spinner.start(\"optimizing\");\n\n const result = await optimizer.optimize({\n prompt: parsed.prompt,\n task: parsed.task,\n tone: parsed.tone,\n mode: parsed.mode,\n preset: parsed.preset,\n sessionId: parsed.sessionId,\n saveContext: parsed.saveContext,\n useContext: parsed.useContext,\n targetModel: parsed.targetModel ?? \"claude\",\n outputFormat: parsed.outputFormat,\n maxLength: parsed.maxLength,\n tags: parsed.tags,\n pinnedConstraints: parsed.pinnedConstraints,\n availableTargets: resolvedTargets,\n routingEnabled: parsed.routingEnabled,\n routingPriority: parsed.routingPriority,\n routingTopK: parsed.routingTopK,\n targetHints: parsed.targetHints,\n workloadBias: parsed.workloadBias,\n debug: parsed.debug,\n plainOutput: parsed.plain,\n maxTotalTokens: parsed.maxTotalTokens,\n maxContextTokens: parsed.maxContextTokens,\n maxInputTokens: parsed.maxInputTokens,\n timeoutMs: parsed.timeoutMs,\n bypassOptimization: parsed.bypassOptimization\n });\n\n spinner.stop();\n\n if (parsed.json) {\n io.stdout.write(`${toPrettyJson(result)}\\n`);\n return 0;\n }\n\n if (parsed.clipboard) {\n const copied = copyToClipboard(result.finalPrompt);\n if (copied) {\n io.stderr.write(`✓ Copied optimized prompt to clipboard\\n`);\n return 0;\n } else {\n io.stderr.write(`✗ Failed to copy to clipboard. Install xclip, xsel, or wl-copy.\\n`);\n io.stdout.write(`${result.finalPrompt}\\n`);\n return 1;\n }\n }\n\n if (parsed.plain) {\n io.stdout.write(`${result.finalPrompt}\\n`);\n return 0;\n }\n\n io.stdout.write(`${result.finalPrompt}\\n\\n`);\n io.stdout.write(`provider=${result.provider} model=${result.model} tokens=${result.estimatedTokensAfter.total} savings=${result.tokenSavings}\\n`);\n io.stdout.write(` prompt_savings=${result.promptCompressionSavings} context_savings=${result.contextCompressionSavings} wrapper_overhead=${result.wrapperOverhead}\\n`);\n if (result.selectedTarget) {\n io.stdout.write(`selected_target=${formatTarget(result.selectedTarget)}\\n`);\n }\n if (result.warnings.length > 0) {\n io.stdout.write(`warnings=${result.warnings.join(\" | \")}\\n`);\n }\n return 0;\n } catch (error) {\n spinner.stop();\n const message = error instanceof Error ? error.message : \"Unknown CLI error.\";\n io.stderr.write(`${message}\\n`);\n return 1;\n }\n}\n\nfunction parseOptimizeArgs(args: string[]) {\n const parsed: {\n prompt?: string;\n sessionId?: string;\n model?: string;\n mode?: any;\n task?: string;\n tone?: string;\n preset?: any;\n targetModel?: string;\n outputFormat?: string;\n maxLength?: number;\n tags: string[];\n pinnedConstraints: string[];\n targets: TargetModelCandidate[];\n targetHints: TargetCapability[];\n routingEnabled: boolean;\n routingPriority?: RoutingPriority;\n routingTopK?: number;\n workloadBias?: WorkloadBias;\n host?: string;\n contextStore?: \"local\" | \"sqlite\";\n storageDir?: string;\n sqlitePath?: string;\n plain: boolean;\n json: boolean;\n debug: boolean;\n clipboard: boolean;\n saveContext?: boolean;\n useContext?: boolean;\n clearSession: boolean;\n maxTotalTokens?: number;\n maxContextTokens?: number;\n maxInputTokens?: number;\n timeoutMs?: number;\n bypassOptimization: boolean;\n autoClaudeTiers: boolean;\n help: boolean;\n } = {\n plain: false,\n json: false,\n debug: false,\n clipboard: false,\n clearSession: false,\n useContext: true,\n bypassOptimization: false,\n autoClaudeTiers: false,\n help: false,\n tags: [],\n pinnedConstraints: [],\n targets: [],\n targetHints: [],\n routingEnabled: true\n };\n\n const positionals: string[] = [];\n\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n switch (arg) {\n case \"--session\":\n parsed.sessionId = args[++index];\n break;\n case \"--model\":\n parsed.model = args[++index];\n break;\n case \"--mode\":\n parsed.mode = args[++index];\n break;\n case \"--task\":\n parsed.task = args[++index];\n break;\n case \"--tone\":\n parsed.tone = args[++index];\n break;\n case \"--preset\":\n parsed.preset = args[++index];\n break;\n case \"--target-model\":\n parsed.targetModel = args[++index];\n break;\n case \"--output-format\":\n parsed.outputFormat = args[++index];\n break;\n case \"--max-length\":\n parsed.maxLength = Number(args[++index]);\n break;\n case \"--tag\":\n parsed.tags.push(args[++index]);\n break;\n case \"--pin-constraint\":\n parsed.pinnedConstraints.push(args[++index]);\n break;\n case \"--target\":\n parsed.targets.push(parseTargetCandidate(args[++index], parsed.targets.length));\n break;\n case \"--target-hint\":\n parsed.targetHints.push(args[++index] as TargetCapability);\n break;\n case \"--routing-priority\":\n parsed.routingPriority = args[++index] as RoutingPriority;\n break;\n case \"--routing-top-k\":\n parsed.routingTopK = Number(args[++index]);\n break;\n case \"--workload-bias\":\n parsed.workloadBias = args[++index] as WorkloadBias;\n break;\n case \"--no-routing\":\n parsed.routingEnabled = false;\n break;\n case \"--host\":\n parsed.host = args[++index];\n break;\n case \"--store\":\n parsed.contextStore = args[++index] as \"local\" | \"sqlite\";\n break;\n case \"--storage-dir\":\n parsed.storageDir = args[++index];\n break;\n case \"--sqlite-path\":\n parsed.sqlitePath = args[++index];\n break;\n case \"--plain\":\n parsed.plain = true;\n break;\n case \"--json\":\n parsed.json = true;\n break;\n case \"--clipboard\":\n parsed.clipboard = true;\n break;\n case \"--debug\":\n parsed.debug = true;\n break;\n case \"--save-context\":\n parsed.saveContext = true;\n break;\n case \"--no-context\":\n parsed.useContext = false;\n break;\n case \"--clear-session\":\n parsed.clearSession = true;\n break;\n case \"--max-total-tokens\":\n parsed.maxTotalTokens = Number(args[++index]);\n break;\n case \"--max-context-tokens\":\n parsed.maxContextTokens = Number(args[++index]);\n break;\n case \"--max-input-tokens\":\n parsed.maxInputTokens = Number(args[++index]);\n break;\n case \"--timeout\":\n parsed.timeoutMs = Number(args[++index]);\n break;\n case \"--bypass-optimization\":\n parsed.bypassOptimization = true;\n break;\n case \"--claude\":\n parsed.autoClaudeTiers = true;\n break;\n case \"--help\":\n case \"-h\":\n parsed.help = true;\n break;\n default:\n positionals.push(arg);\n }\n }\n\n parsed.prompt = positionals.join(\" \").trim() || undefined;\n return parsed;\n}\n\nfunction getHelpText(): string {\n return [\n \"promptpilot optimize <prompt> [options]\",\n \"\",\n \"Options:\",\n \" --session <id>\",\n \" --model <name> Override auto-selected local Ollama model\",\n \" --mode <mode>\",\n \" --task <task>\",\n \" --tone <tone>\",\n \" --preset <preset>\",\n \" --target-model <name>\",\n \" --output-format <text>\",\n \" --max-length <n>\",\n \" --tag <value> Repeatable\",\n \" --pin-constraint <text> Repeatable\",\n \" --target <provider:model> Repeatable\",\n \" --target-hint <value> Repeatable\",\n \" --routing-priority <value>\",\n \" --routing-top-k <n>\",\n \" --workload-bias <code_first>\",\n \" --no-routing\",\n \" --host <url>\",\n \" --store <local|sqlite>\",\n \" --storage-dir <path>\",\n \" --sqlite-path <path>\",\n \" --plain\",\n \" --json\",\n \" --clipboard Copy optimized prompt to clipboard\",\n \" --debug\",\n \" --save-context\",\n \" --no-context\",\n \" --clear-session\",\n \" --max-total-tokens <n>\",\n \" --max-context-tokens <n>\",\n \" --max-input-tokens <n>\",\n \" --timeout <ms>\",\n \" --bypass-optimization\",\n \" --claude Route between Haiku, Sonnet, and Opus automatically\"\n ].join(\"\\n\");\n}\n\nfunction parseTargetCandidate(raw: string, index: number): TargetModelCandidate {\n const [provider, ...modelParts] = raw.split(\":\");\n const model = modelParts.join(\":\").trim();\n return {\n provider: provider.trim(),\n model,\n label: raw,\n costRank: index + 1,\n latencyRank: index + 1\n };\n}\n\nfunction formatTarget(target: TargetModelCandidate): string {\n return target.label ?? `${target.provider}:${target.model}`;\n}\n\nasync function readStdin(stdin: NodeJS.ReadStream | undefined = process.stdin): Promise<string> {\n if (!stdin || stdin.isTTY) {\n return \"\";\n }\n\n return new Promise((resolve, reject) => {\n let data = \"\";\n stdin.setEncoding(\"utf8\");\n stdin.on(\"data\", (chunk) => {\n data += chunk;\n });\n stdin.on(\"end\", () => resolve(data));\n stdin.on(\"error\", reject);\n });\n}\n\nfunction getCliInfo(stdout: CliWriter): { cwd: string; version: string; color: boolean; columns?: number; user?: string } {\n return {\n cwd: process.cwd(),\n version: readPackageVersion(),\n color: shouldUseColor(stdout),\n columns: stdout.columns,\n user: process.env.USER ?? process.env.USERNAME\n };\n}\n\nfunction shouldUseColor(stdout: CliWriter): boolean {\n if (!stdout.isTTY) {\n return false;\n }\n if (process.env.NO_COLOR) {\n return false;\n }\n if (process.env.TERM === \"dumb\") {\n return false;\n }\n return true;\n}\n\nfunction readPackageVersion(): string {\n try {\n const packageJson = readFileSync(new URL(\"../package.json\", import.meta.url), \"utf8\");\n const parsed = JSON.parse(packageJson) as { version?: string };\n return parsed.version ?? \"dev\";\n } catch {\n return \"dev\";\n }\n}\n\nfunction copyToClipboard(text: string): boolean {\n // Try different clipboard commands based on platform\n const commands = [\n { cmd: \"xclip\", args: [\"-selection\", \"clipboard\"], platform: \"linux\" },\n { cmd: \"xsel\", args: [\"-b\"], platform: \"linux\" },\n { cmd: \"wl-copy\", args: [], platform: \"linux\" },\n { cmd: \"pbcopy\", args: [], platform: \"darwin\" }\n ];\n\n for (const { cmd } of commands) {\n try {\n execSync(`which ${cmd} > /dev/null 2>&1`);\n execSync(cmd, { input: text, stdio: [\"pipe\", \"ignore\", \"ignore\"] });\n return true;\n } catch {\n // Command not found or failed, try next one\n }\n }\n\n return false;\n}\n\nif (isMainModule()) {\n runCli(process.argv.slice(2)).then(\n (code) => {\n process.exit(code);\n },\n (error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`${message}\\n`);\n process.exit(1);\n }\n );\n}\n\nfunction isMainModule(): boolean {\n if (!process.argv[1]) {\n return false;\n }\n\n try {\n const entryPath = realpathSync(process.argv[1]);\n const thisPath = realpathSync(fileURLToPath(import.meta.url));\n return entryPath === thisPath;\n } catch {\n return false;\n }\n}\n","export class InvalidPromptError extends Error {\n constructor(message = \"Prompt must be a non-empty string.\") {\n super(message);\n this.name = \"InvalidPromptError\";\n }\n}\n\nexport class OllamaUnavailableError extends Error {\n constructor(message = \"Ollama is unavailable or returned an invalid response.\") {\n super(message);\n this.name = \"OllamaUnavailableError\";\n }\n}\n\nexport class ContextStoreError extends Error {\n constructor(message = \"Context store operation failed.\") {\n super(message);\n this.name = \"ContextStoreError\";\n }\n}\n\nexport class TokenBudgetExceededError extends Error {\n constructor(message = \"Final prompt could not be reduced to fit within the configured token budget.\") {\n super(message);\n this.name = \"TokenBudgetExceededError\";\n }\n}\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { ContextStoreError } from \"../errors.js\";\nimport type { SessionData, SessionStore } from \"../types.js\";\nimport { sanitizeSessionId } from \"../utils/validation.js\";\n\nexport class FileSessionStore implements SessionStore {\n private readonly rootDir: string;\n\n constructor(rootDir = join(homedir(), \".promptpilot\", \"sessions\")) {\n this.rootDir = rootDir;\n }\n\n async loadSession(sessionId: string): Promise<SessionData> {\n const filePath = this.getFilePath(sessionId);\n\n try {\n const contents = await readFile(filePath, \"utf8\");\n const parsed = JSON.parse(contents) as SessionData;\n return parsed;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") {\n return this.createEmptySession(sessionId);\n }\n\n throw new ContextStoreError(`Failed to load session \"${sessionId}\".`);\n }\n }\n\n async saveSession(session: SessionData): Promise<void> {\n const filePath = this.getFilePath(session.sessionId);\n\n try {\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, JSON.stringify(session, null, 2), \"utf8\");\n } catch {\n throw new ContextStoreError(`Failed to save session \"${session.sessionId}\".`);\n }\n }\n\n async clearSession(sessionId: string): Promise<void> {\n const filePath = this.getFilePath(sessionId);\n\n try {\n await rm(filePath, { force: true });\n } catch {\n throw new ContextStoreError(`Failed to clear session \"${sessionId}\".`);\n }\n }\n\n private getFilePath(sessionId: string): string {\n return join(this.rootDir, `${sanitizeSessionId(sessionId)}.json`);\n }\n\n private createEmptySession(sessionId: string): SessionData {\n const now = new Date().toISOString();\n return {\n sessionId,\n entries: [],\n summaries: [],\n createdAt: now,\n updatedAt: now\n };\n }\n}\n","import { InvalidPromptError } from \"../errors.js\";\n\nexport function normalizeWhitespace(value: string): string {\n return value\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function validatePrompt(prompt: string): string {\n if (typeof prompt !== \"string\" || normalizeWhitespace(prompt).length === 0) {\n throw new InvalidPromptError();\n }\n\n return normalizeWhitespace(prompt);\n}\n\nexport function sanitizeSessionId(sessionId: string): string {\n return sessionId.trim().replace(/[^a-zA-Z0-9._-]/g, \"-\");\n}\n","import { dirname, join } from \"node:path\";\nimport { mkdir } from \"node:fs/promises\";\n\nimport { ContextStoreError } from \"../errors.js\";\nimport type { SessionData, SessionStore } from \"../types.js\";\n\ntype DatabaseAdapter = {\n prepare(sql: string): {\n get(param?: string): { data?: string } | undefined;\n run(...params: unknown[]): void;\n };\n exec(sql: string): void;\n};\n\nexport class SQLiteSessionStore implements SessionStore {\n private dbPromise: Promise<DatabaseAdapter>;\n\n constructor(private readonly dbPath = join(process.cwd(), \".promptpilot\", \"promptpilot.db\")) {\n this.dbPromise = this.openDatabase();\n }\n\n async loadSession(sessionId: string): Promise<SessionData> {\n const db = await this.dbPromise;\n const row = db.prepare(\"SELECT data FROM sessions WHERE id = ?\").get(sessionId);\n if (!row?.data) {\n return createEmptySession(sessionId);\n }\n\n return JSON.parse(row.data) as SessionData;\n }\n\n async saveSession(session: SessionData): Promise<void> {\n const db = await this.dbPromise;\n db.prepare(\"INSERT OR REPLACE INTO sessions (id, data) VALUES (?, ?)\").run(\n session.sessionId,\n JSON.stringify(session)\n );\n }\n\n async clearSession(sessionId: string): Promise<void> {\n const db = await this.dbPromise;\n db.prepare(\"DELETE FROM sessions WHERE id = ?\").run(sessionId);\n }\n\n private async openDatabase(): Promise<DatabaseAdapter> {\n try {\n await mkdir(dirname(this.dbPath), { recursive: true });\n const nodeSqliteName = \"node:sqlite\";\n const nodeSqlite = await import(nodeSqliteName).catch(() => null);\n\n if (nodeSqlite?.DatabaseSync) {\n const db = new nodeSqlite.DatabaseSync(this.dbPath) as DatabaseAdapter;\n db.exec(\"CREATE TABLE IF NOT EXISTS sessions (id TEXT PRIMARY KEY, data TEXT NOT NULL)\");\n return db;\n }\n\n const betterSqliteName = \"better-sqlite3\";\n const betterSqlite = await import(betterSqliteName).catch(() => null);\n if (betterSqlite?.default) {\n const db = new betterSqlite.default(this.dbPath) as DatabaseAdapter;\n db.exec(\"CREATE TABLE IF NOT EXISTS sessions (id TEXT PRIMARY KEY, data TEXT NOT NULL)\");\n return db;\n }\n\n throw new ContextStoreError(\n \"SQLite store requires node:sqlite support or the better-sqlite3 package.\"\n );\n } catch (error) {\n if (error instanceof ContextStoreError) {\n throw error;\n }\n\n throw new ContextStoreError(\"Failed to initialize SQLite session store.\");\n }\n }\n}\n\nfunction createEmptySession(sessionId: string): SessionData {\n const now = new Date().toISOString();\n return {\n sessionId,\n entries: [],\n summaries: [],\n createdAt: now,\n updatedAt: now\n };\n}\n","import type { Logger } from \"../types.js\";\n\nexport const noopLogger: Logger = {\n debug: () => undefined,\n info: () => undefined,\n warn: () => undefined,\n error: () => undefined\n};\n\nexport function createLogger(debugEnabled = false): Logger {\n return {\n debug(message, meta) {\n if (debugEnabled) {\n console.debug(`[promptpilot] ${message}`, meta ?? \"\");\n }\n },\n info(message, meta) {\n if (debugEnabled) {\n console.info(`[promptpilot] ${message}`, meta ?? \"\");\n }\n },\n warn(message, meta) {\n if (debugEnabled) {\n console.warn(`[promptpilot] ${message}`, meta ?? \"\");\n }\n },\n error(message, meta) {\n if (debugEnabled) {\n console.error(`[promptpilot] ${message}`, meta ?? \"\");\n }\n }\n };\n}\n","export function safeJsonParse<T>(value: string): T | null {\n try {\n return JSON.parse(value) as T;\n } catch {\n return null;\n }\n}\n\nexport function extractFirstJsonObject(value: string): string | null {\n const start = value.indexOf(\"{\");\n if (start === -1) {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escaped = false;\n\n for (let index = start; index < value.length; index += 1) {\n const char = value[index];\n\n if (escaped) {\n escaped = false;\n continue;\n }\n\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n\n if (char === \"\\\"\") {\n inString = !inString;\n continue;\n }\n\n if (inString) {\n continue;\n }\n\n if (char === \"{\") {\n depth += 1;\n } else if (char === \"}\") {\n depth -= 1;\n if (depth === 0) {\n return value.slice(start, index + 1);\n }\n }\n }\n\n return null;\n}\n\nexport function toPrettyJson(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n","import { OllamaUnavailableError } from \"../errors.js\";\nimport type { Logger, OllamaClientLike, OllamaGenerateOptions, OllamaModelInfo } from \"../types.js\";\nimport { extractFirstJsonObject, safeJsonParse } from \"../utils/json.js\";\nimport { noopLogger } from \"../utils/logger.js\";\n\ninterface OllamaClientConfig {\n host?: string;\n model?: string;\n timeoutMs?: number;\n temperature?: number;\n logger?: Logger;\n}\n\nexport class OllamaClient implements OllamaClientLike {\n readonly host: string;\n readonly model: string;\n readonly timeoutMs: number;\n readonly temperature: number;\n readonly logger: Logger;\n\n constructor(config: OllamaClientConfig = {}) {\n this.host = config.host ?? \"http://localhost:11434\";\n this.model = config.model ?? \"qwen2.5:3b\";\n this.timeoutMs = config.timeoutMs ?? 30000;\n this.temperature = config.temperature ?? 0.1;\n this.logger = config.logger ?? noopLogger;\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n const response = await fetch(new URL(\"/api/tags\", this.host), {\n method: \"GET\"\n });\n\n return response.ok;\n } catch {\n return false;\n }\n }\n\n async listModels(): Promise<OllamaModelInfo[]> {\n try {\n const response = await fetch(new URL(\"/api/tags\", this.host), {\n method: \"GET\"\n });\n\n if (!response.ok) {\n throw new OllamaUnavailableError(`Ollama tags request failed with status ${response.status}.`);\n }\n\n const data = (await response.json()) as {\n models?: Array<{\n name?: string;\n size?: number;\n modified_at?: string;\n details?: {\n family?: string;\n parameter_size?: string;\n };\n }>;\n };\n\n return (data.models ?? [])\n .filter((model) => typeof model.name === \"string\" && model.name.length > 0)\n .map((model) => ({\n name: model.name as string,\n sizeBytes: model.size,\n family: model.details?.family,\n parameterSize: model.details?.parameter_size,\n modifiedAt: model.modified_at\n }));\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown Ollama tags error.\";\n this.logger.warn(\"ollama.list_models.failed\", { message });\n throw new OllamaUnavailableError(message);\n }\n }\n\n async generate(options: OllamaGenerateOptions): Promise<string> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs ?? this.timeoutMs);\n\n try {\n const response = await fetch(new URL(\"/api/generate\", this.host), {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({\n model: options.model ?? this.model,\n system: options.systemPrompt,\n prompt: options.prompt,\n stream: false,\n format: options.format === \"json\" ? \"json\" : undefined,\n options: {\n temperature: options.temperature ?? this.temperature\n }\n }),\n signal: controller.signal\n });\n\n if (!response.ok) {\n throw new OllamaUnavailableError(`Ollama request failed with status ${response.status}.`);\n }\n\n const data = (await response.json()) as { response?: string };\n if (!data.response || typeof data.response !== \"string\") {\n throw new OllamaUnavailableError(\"Ollama did not return a text response.\");\n }\n\n return data.response.trim();\n } catch (error) {\n if (error instanceof OllamaUnavailableError) {\n throw error;\n }\n\n const message = error instanceof Error ? error.message : \"Unknown Ollama error.\";\n this.logger.warn(\"ollama.generate.failed\", { message });\n throw new OllamaUnavailableError(message);\n } finally {\n clearTimeout(timeout);\n }\n }\n\n async generateJson<T>(options: OllamaGenerateOptions): Promise<T> {\n const raw = await this.generate({\n ...options,\n format: \"json\"\n });\n\n const direct = safeJsonParse<T>(raw);\n if (direct) {\n return direct;\n }\n\n const extracted = extractFirstJsonObject(raw);\n if (extracted) {\n const parsed = safeJsonParse<T>(extracted);\n if (parsed) {\n return parsed;\n }\n }\n\n throw new OllamaUnavailableError(\"Ollama returned JSON that could not be parsed.\");\n }\n\n async generateJsonWithTextFallback<T>(options: OllamaGenerateOptions, textFallbackHandler: (text: string) => T): Promise<T> {\n try {\n return await this.generateJson<T>(options);\n } catch {\n // Text-only model or JSON parsing failed, fall back to text output\n const raw = await this.generate({\n ...options,\n format: undefined\n });\n return textFallbackHandler(raw);\n }\n }\n}\n","import type { OptimizationMode, OptimizePromptInput, PromptPreset } from \"../types.js\";\n\nconst modeGuidance: Record<OptimizationMode, string> = {\n clarity: \"Improve clarity, remove ambiguity, and keep the request easy for a downstream model to follow.\",\n concise: \"Minimize token count while preserving user intent, constraints, and expected output.\",\n detailed: \"Make the request explicit and complete, including structure and success criteria.\",\n structured: \"Organize the request into sections only when that improves clarity or token efficiency.\",\n persuasive: \"Refine wording so the request is compelling and likely to elicit a thoughtful response.\",\n compress: \"Aggressively compress redundant wording while preserving the meaning and critical constraints.\",\n claude_cli: \"Optimize specifically for Claude CLI: compact sections, direct instructions, and minimal boilerplate.\"\n};\n\nconst presetGuidance: Record<PromptPreset, string> = {\n code: \"Favor precise technical requirements, edge cases, expected output format, and a compact inspect-plan-act-test-reflect loop for code tasks.\",\n email: \"Preserve the sender's goal, tone, and audience; aim for a realistic and usable writing request.\",\n essay: \"Preserve thesis, structure, and voice guidance while making the prompt clearer.\",\n support: \"Favor concise issue context, user impact, and desired resolution details.\",\n summarization: \"Favor strong compression while retaining key facts, structure, and takeaways.\",\n chat: \"Keep the prompt natural and conversational while preserving instructions and context.\"\n};\n\nexport function getOptimizationSystemPrompt(mode: OptimizationMode, preset?: PromptPreset): string {\n return [\n \"You are PromptPilot, a local prompt optimizer for downstream LLM workflows.\",\n \"Return strict JSON only with this shape:\",\n \"{\\\"optimizedPrompt\\\":\\\"string\\\",\\\"constraints\\\":[\\\"string\\\"],\\\"changes\\\":[\\\"string\\\"],\\\"warnings\\\":[\\\"string\\\"]}\",\n \"Rules:\",\n \"- Do not change the user's intent.\",\n \"- Do not invent new requirements.\",\n \"- Preserve critical constraints and task goals.\",\n \"- Improve clarity, structure, and downstream usefulness.\",\n \"- Keep the result compact when the mode requests compression.\",\n \"- Do not force sections when direct phrasing is shorter and equally clear.\",\n \"- Remove redundancy aggressively when the source prompt repeats the same goal multiple ways.\",\n \"- For code tasks, prefer a terse agent brief over narrative prose.\",\n \"- For code tasks, structure the prompt around a Karpathy-style loop: inspect, plan, act, test, reflect, repeat.\",\n `Mode guidance: ${modeGuidance[mode]}`,\n preset ? `Preset guidance: ${presetGuidance[preset]}` : \"Preset guidance: none\"\n ].join(\"\\n\");\n}\n\nexport function buildOptimizationPrompt(\n input: OptimizePromptInput,\n relevantContext: string,\n extractedConstraints: string[]\n): string {\n const payload = {\n prompt: input.prompt,\n task: input.task ?? null,\n tone: input.tone ?? null,\n targetModel: input.targetModel ?? \"claude\",\n outputFormat: input.outputFormat ?? null,\n maxLength: input.maxLength ?? null,\n mode: input.mode ?? \"claude_cli\",\n preset: input.preset ?? null,\n pinnedConstraints: input.pinnedConstraints ?? [],\n extractedConstraints,\n relevantContext\n };\n\n return `Optimize this prompt payload for a downstream LLM.\\n${JSON.stringify(payload, null, 2)}`;\n}\n","import type { TokenUsageEstimate } from \"../types.js\";\nimport { normalizeWhitespace } from \"../utils/validation.js\";\n\nexport class TokenEstimator {\n estimateText(text: string): number {\n const normalized = normalizeWhitespace(text);\n if (!normalized) {\n return 0;\n }\n\n const wordCount = normalized.split(/\\s+/).length;\n const charCount = normalized.length;\n return Math.max(1, Math.ceil(wordCount * 1.3), Math.ceil(charCount / 4));\n }\n\n estimateUsage(input: { prompt: string; context?: string }): TokenUsageEstimate {\n const prompt = this.estimateText(input.prompt);\n const context = this.estimateText(input.context ?? \"\");\n return {\n prompt,\n context,\n total: prompt + context\n };\n }\n\n truncateToBudget(text: string, tokenBudget: number): string {\n const normalized = normalizeWhitespace(text);\n if (tokenBudget <= 0 || !normalized) {\n return \"\";\n }\n\n if (this.estimateText(normalized) <= tokenBudget) {\n return normalized;\n }\n\n const words = normalized.split(/\\s+/);\n const selected: string[] = [];\n\n for (const word of words) {\n const candidate = [...selected, word].join(\" \");\n if (this.estimateText(candidate) > tokenBudget) {\n break;\n }\n\n selected.push(word);\n }\n\n return selected.join(\" \").trim();\n }\n}\n","import { randomUUID } from \"node:crypto\";\n\nimport type { ContextEntry, ContextSummary, Logger, OllamaClientLike } from \"../types.js\";\nimport { TokenEstimator } from \"./tokenEstimator.js\";\nimport { getOptimizationSystemPrompt } from \"./systemPrompt.js\";\nimport { noopLogger } from \"../utils/logger.js\";\n\ninterface SummarizeContextOptions {\n sessionId: string;\n entries: ContextEntry[];\n prompt: string;\n task?: string;\n budgetTokens: number;\n timeoutMs?: number;\n}\n\ninterface ContextSummaryJson {\n optimizedPrompt: string;\n constraints?: string[];\n changes?: string[];\n}\n\nexport class ContextCompressor {\n constructor(\n private readonly estimator: TokenEstimator,\n private readonly client?: OllamaClientLike,\n private readonly logger: Logger = noopLogger\n ) {}\n\n async summarizeEntries(options: SummarizeContextOptions): Promise<ContextSummary | null> {\n if (options.entries.length === 0 || options.budgetTokens <= 0) {\n return null;\n }\n\n const ollamaSummary = await this.tryOllamaSummary(options);\n if (ollamaSummary) {\n return ollamaSummary;\n }\n\n return this.heuristicSummary(options);\n }\n\n private async tryOllamaSummary(options: SummarizeContextOptions): Promise<ContextSummary | null> {\n if (!this.client || options.entries.length < 3) {\n return null;\n }\n\n try {\n const source = options.entries\n .slice(-8)\n .map((entry) => [\n `Timestamp: ${entry.timestamp}`,\n entry.task ? `Task: ${entry.task}` : \"\",\n entry.constraints?.length ? `Constraints: ${entry.constraints.join(\"; \")}` : \"\",\n `Prompt: ${entry.rawPrompt ?? entry.text}`\n ].filter(Boolean).join(\"\\n\"))\n .join(\"\\n\\n\");\n\n const response = await this.client.generateJson<ContextSummaryJson>({\n systemPrompt: getOptimizationSystemPrompt(\"compress\"),\n prompt: `Summarize this stored prompt context for reuse in later turns.\\nPrompt: ${options.prompt}\\nTask: ${options.task ?? \"unknown\"}\\nBudget tokens: ${options.budgetTokens}\\n\\n${source}`,\n timeoutMs: options.timeoutMs,\n format: \"json\"\n });\n\n const summaryText = this.estimator.truncateToBudget(response.optimizedPrompt ?? \"\", options.budgetTokens);\n if (!summaryText) {\n return null;\n }\n\n return {\n id: randomUUID(),\n sessionId: options.sessionId,\n text: summaryText,\n createdAt: new Date().toISOString(),\n sourceEntryIds: options.entries.map((entry) => entry.id),\n tokenEstimate: this.estimator.estimateText(summaryText),\n kind: \"ollama\"\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown summary failure\";\n this.logger.debug(\"context.summary.ollama_fallback\", { message });\n return null;\n }\n }\n\n private heuristicSummary(options: SummarizeContextOptions): ContextSummary {\n const constraints = Array.from(\n new Set(options.entries.flatMap((entry) => entry.constraints ?? []).filter(Boolean))\n ).slice(0, 6);\n\n const recentPrompts = options.entries\n .slice(-4)\n .map((entry) => `- ${truncateLine(entry.rawPrompt ?? entry.text, 120)}`);\n\n const lines = [\n constraints.length ? `Key constraints: ${constraints.join(\"; \")}` : \"\",\n recentPrompts.length ? `Recent focus:\\n${recentPrompts.join(\"\\n\")}` : \"\"\n ].filter(Boolean);\n\n const summaryText = this.estimator.truncateToBudget(lines.join(\"\\n\\n\"), options.budgetTokens);\n\n return {\n id: randomUUID(),\n sessionId: options.sessionId,\n text: summaryText,\n createdAt: new Date().toISOString(),\n sourceEntryIds: options.entries.map((entry) => entry.id),\n tokenEstimate: this.estimator.estimateText(summaryText),\n kind: \"heuristic\"\n };\n }\n}\n\nfunction truncateLine(value: string, maxLength: number): string {\n if (value.length <= maxLength) {\n return value;\n }\n\n return `${value.slice(0, maxLength - 3).trim()}...`;\n}\n","import { randomUUID } from \"node:crypto\";\n\nimport type {\n ContextEntry,\n ContextSummary,\n Logger,\n OptimizePromptInput,\n RelevantContextResult,\n SessionStore\n} from \"../types.js\";\nimport { TokenEstimator } from \"./tokenEstimator.js\";\nimport { ContextCompressor } from \"./contextCompressor.js\";\nimport { noopLogger } from \"../utils/logger.js\";\n\ninterface GetRelevantContextOptions {\n sessionId: string;\n prompt: string;\n task?: string;\n tags?: string[];\n pinnedConstraints?: string[];\n maxContextTokens: number;\n timeoutMs?: number;\n}\n\ninterface SaveContextOptions {\n sessionId: string;\n input: OptimizePromptInput;\n optimizedPrompt: string;\n finalPrompt: string;\n contextSummary: ContextSummary | null;\n}\n\nexport class ContextManager {\n constructor(\n private readonly store: SessionStore,\n private readonly estimator: TokenEstimator,\n private readonly compressor: ContextCompressor,\n private readonly logger: Logger = noopLogger\n ) {}\n\n async loadContext(sessionId: string) {\n return this.store.loadSession(sessionId);\n }\n\n async clearContext(sessionId: string): Promise<void> {\n await this.store.clearSession(sessionId);\n }\n\n async saveContext(options: SaveContextOptions): Promise<void> {\n const session = await this.store.loadSession(options.sessionId);\n const timestamp = new Date().toISOString();\n const constraints = Array.from(\n new Set([\n ...extractConstraints(options.input.prompt),\n ...(options.input.pinnedConstraints ?? [])\n ])\n );\n const entry: ContextEntry = {\n id: randomUUID(),\n sessionId: options.sessionId,\n text: options.optimizedPrompt,\n rawPrompt: options.input.prompt,\n optimizedPrompt: options.optimizedPrompt,\n finalPrompt: options.finalPrompt,\n task: options.input.task,\n tone: options.input.tone,\n tags: options.input.tags ?? [],\n constraints,\n entities: extractEntities(options.input.prompt),\n pinned: (options.input.pinnedConstraints?.length ?? 0) > 0,\n timestamp,\n tokenEstimate: this.estimator.estimateText(options.finalPrompt)\n };\n\n session.entries.push(entry);\n if (session.entries.length > 100) {\n session.entries = session.entries.slice(-100);\n }\n\n if (options.contextSummary) {\n session.summaries.push(options.contextSummary);\n if (session.summaries.length > 10) {\n session.summaries = session.summaries.slice(-10);\n }\n }\n\n session.updatedAt = timestamp;\n await this.store.saveSession(session);\n this.logger.debug(\"context saved\", {\n sessionId: options.sessionId,\n entryCount: session.entries.length,\n summaryCount: session.summaries.length\n });\n }\n\n async summarizeContext(\n sessionId: string,\n prompt: string,\n task: string | undefined,\n budgetTokens: number,\n timeoutMs?: number\n ): Promise<ContextSummary | null> {\n const session = await this.store.loadSession(sessionId);\n if (session.entries.length === 0) {\n return null;\n }\n\n return this.compressor.summarizeEntries({\n sessionId,\n entries: session.entries,\n prompt,\n task,\n budgetTokens,\n timeoutMs\n });\n }\n\n async getRelevantContext(options: GetRelevantContextOptions): Promise<RelevantContextResult> {\n const session = await this.store.loadSession(options.sessionId);\n if (session.entries.length === 0 && session.summaries.length === 0) {\n return {\n usedEntries: [],\n summary: null,\n warnings: [],\n debugInfo: { scores: [] }\n };\n }\n\n const scores = session.entries.map((entry, index) => ({\n entry,\n score: scoreEntry({\n entry,\n prompt: options.prompt,\n task: options.task,\n tags: options.tags,\n pinnedConstraints: options.pinnedConstraints,\n index,\n total: session.entries.length\n })\n }));\n\n const selected: ContextEntry[] = [];\n const seenFingerprints = new Set<string>();\n let selectedTokens = 0;\n\n for (const scored of scores.sort((left, right) => right.score - left.score)) {\n if (selected.find((entry) => entry.id === scored.entry.id)) {\n continue;\n }\n\n const fingerprint = createFingerprint(scored.entry);\n if (seenFingerprints.has(fingerprint)) {\n continue;\n }\n\n if (selectedTokens + scored.entry.tokenEstimate > options.maxContextTokens) {\n continue;\n }\n\n selected.push(scored.entry);\n seenFingerprints.add(fingerprint);\n selectedTokens += scored.entry.tokenEstimate;\n }\n\n const remainder = session.entries.filter(\n (entry) => !selected.find((selectedEntry) => selectedEntry.id === entry.id)\n );\n\n let summary: ContextSummary | null = null;\n if (remainder.length > 1 && selectedTokens < Math.floor(options.maxContextTokens * 0.8)) {\n summary = await this.compressor.summarizeEntries({\n sessionId: options.sessionId,\n entries: remainder,\n prompt: options.prompt,\n task: options.task,\n budgetTokens: Math.max(80, options.maxContextTokens - selectedTokens),\n timeoutMs: options.timeoutMs\n });\n } else if (session.summaries.length > 0) {\n const latest = session.summaries.at(-1) ?? null;\n if (latest && latest.tokenEstimate <= options.maxContextTokens - selectedTokens) {\n summary = latest;\n }\n }\n\n const warnings: string[] = [];\n if (remainder.length > 0) {\n warnings.push(`Dropped ${remainder.length} lower-value context item(s) to fit the token budget.`);\n }\n\n return {\n usedEntries: selected.sort((left, right) => left.timestamp.localeCompare(right.timestamp)),\n summary,\n warnings,\n debugInfo: {\n scores: scores\n .sort((left, right) => right.score - left.score)\n .map(({ entry, score }) => ({ id: entry.id, score, task: entry.task, timestamp: entry.timestamp }))\n }\n };\n }\n}\n\nfunction scoreEntry(input: {\n entry: ContextEntry;\n prompt: string;\n task?: string;\n tags?: string[];\n pinnedConstraints?: string[];\n index: number;\n total: number;\n}): number {\n const promptTerms = tokenize(input.prompt);\n const promptEntities = new Set(extractEntities(input.prompt).map((entity) => entity.toLowerCase()));\n const entryTerms = tokenize(\n [input.entry.rawPrompt, input.entry.optimizedPrompt, input.entry.constraints?.join(\" \")].filter(Boolean).join(\" \")\n );\n const entryEntities = new Set((input.entry.entities ?? []).map((entity) => entity.toLowerCase()));\n\n const overlap = Array.from(promptTerms).filter((term) => entryTerms.has(term)).length;\n const entityOverlap = Array.from(promptEntities).filter((entity) => entryEntities.has(entity)).length;\n const taskMatch = input.task && input.entry.task === input.task ? 2 : 0;\n const pinned = input.entry.pinned ? 3 : 0;\n const pinnedConstraintMatch = Array.from(new Set(input.pinnedConstraints ?? [])).filter((constraint) =>\n (input.entry.constraints ?? []).includes(constraint)\n ).length;\n const tagOverlap = Array.from(new Set(input.tags ?? [])).filter((tag) => (input.entry.tags ?? []).includes(tag)).length;\n const constraintBonus = (input.entry.constraints?.length ?? 0) > 0 ? 0.75 : 0;\n const recency = (input.index + 1) / input.total;\n\n return overlap * 0.8 + entityOverlap * 1.2 + taskMatch + pinned + pinnedConstraintMatch * 2 + tagOverlap + constraintBonus + recency;\n}\n\nfunction tokenize(value: string): Set<string> {\n return new Set(\n value\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .filter((token) => token.length > 2)\n );\n}\n\nexport function extractConstraints(value: string): string[] {\n return Array.from(\n new Set(\n value\n .split(/\\n+/)\n .flatMap((line) => line.split(/(?<=[.!?])\\s+/))\n .map((line) => line.trim().replace(/^[-*]\\s*/, \"\"))\n .filter((line) => line.length > 0 && line.length <= 180)\n .filter((line) => /(must|should|avoid|do not|don't|never|exactly|at most|under|limit|max|preserve|keep)/i.test(line))\n )\n ).slice(0, 8);\n}\n\nexport function extractEntities(value: string): string[] {\n return Array.from(\n new Set(value.match(/\\b[A-Z][a-zA-Z0-9._-]+\\b/g) ?? [])\n ).slice(0, 12);\n}\n\nfunction createFingerprint(entry: ContextEntry): string {\n return [entry.task ?? \"\", entry.rawPrompt ?? entry.text]\n .join(\"::\")\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .trim();\n}\n","import type { OllamaModelInfo, OptimizationMode, PromptPreset } from \"../types.js\";\n\nconst DEFAULT_SMALL_MODEL_PREFERENCES = [\n \"qwen2.5:3b\",\n \"phi3:mini\",\n \"llama3.2:3b\",\n \"qwen2.5:1.5b\"\n];\n\nexport interface ModelSelectionInput {\n installedModels: OllamaModelInfo[];\n mode: OptimizationMode;\n preset: PromptPreset;\n task?: string;\n preferredModels?: string[];\n}\n\nexport interface ModelSelectionResult {\n model: string;\n reason: string;\n suitableForAutoUse: boolean;\n}\n\nexport function getDefaultPreferredModels(): string[] {\n return [...DEFAULT_SMALL_MODEL_PREFERENCES];\n}\n\nexport function getSuitableAutoModels(installedModels: OllamaModelInfo[]): OllamaModelInfo[] {\n return installedModels.filter((model) => isSuitableSmallModel(model));\n}\n\nexport function getQwenRouterModel(\n installedModels: OllamaModelInfo[],\n explicitRouterModel?: string\n): string | null {\n if (explicitRouterModel) {\n const match = installedModels.find((model) => model.name === explicitRouterModel);\n return match?.name ?? null;\n }\n\n const qwenRouters = getSuitableAutoModels(installedModels)\n .filter((model) => /qwen/i.test(model.name))\n .sort((left, right) => scoreRouterModel(right) - scoreRouterModel(left));\n\n return qwenRouters[0]?.name ?? null;\n}\n\nexport function selectOllamaModel(input: ModelSelectionInput): ModelSelectionResult {\n const smallCandidates = getSuitableAutoModels(input.installedModels);\n if (smallCandidates.length === 1) {\n return {\n model: smallCandidates[0].name,\n reason: `Selected installed model \"${smallCandidates[0].name}\" because it is the only suitable small local model available.`,\n suitableForAutoUse: true\n };\n }\n\n if (smallCandidates.length > 1) {\n return {\n model: \"\",\n reason: `Multiple suitable small local models are available (${smallCandidates.map((model) => model.name).join(\", \")}), so a Qwen router must choose between them.`,\n suitableForAutoUse: false\n };\n }\n\n const oversizedRanked = [...input.installedModels]\n .filter((model) => isUsefulGenerationModel(model.name))\n .sort((left, right) => compareModelNames(left.name, right.name));\n\n if (oversizedRanked[0]) {\n return {\n model: oversizedRanked[0].name,\n reason: `Installed model \"${oversizedRanked[0].name}\" was detected, but it is larger than the preferred low-memory range for auto-use.`,\n suitableForAutoUse: false\n };\n }\n\n return {\n model: \"\",\n reason: \"No suitable local generation models were discovered for automatic routing.\",\n suitableForAutoUse: false\n };\n}\n\nfunction extractBillions(modelName: string): number | null {\n const match = modelName.match(/(\\d+(?:\\.\\d+)?)b/);\n if (!match) {\n return null;\n }\n\n return Number.parseFloat(match[1]);\n}\n\nfunction isUsefulGenerationModel(modelName: string): boolean {\n const lower = modelName.toLowerCase();\n return ![\n \"embed\",\n \"embedding\",\n \"whisper\",\n \"vision\",\n \"diffusion\",\n \"tts\",\n \"bge\",\n \"nomic-embed\"\n ].some((blocked) => lower.includes(blocked));\n}\n\nfunction isSuitableSmallModel(model: OllamaModelInfo): boolean {\n if (!isUsefulGenerationModel(model.name)) {\n return false;\n }\n\n const byParameter = extractBillions(`${model.parameterSize ?? \"\"} ${model.name}`);\n if (byParameter !== null) {\n return byParameter <= 4;\n }\n\n if (typeof model.sizeBytes === \"number\") {\n return model.sizeBytes <= 5_500_000_000;\n }\n\n return /mini|1\\.5b|2b|3b|4b/i.test(model.name);\n}\n\nfunction scoreRouterModel(model: OllamaModelInfo): number {\n const lower = model.name.toLowerCase();\n let score = 0;\n if (lower.includes(\"qwen2.5\")) {\n score += 3;\n }\n if (lower.includes(\"3b\")) {\n score += 2;\n } else if (lower.includes(\"1.5b\")) {\n score += 1;\n }\n if (lower.includes(\"coder\")) {\n score -= 1;\n }\n return score;\n}\n\nfunction compareModelNames(left: string, right: string): number {\n return left.localeCompare(right);\n}\n","import type {\n OptimizationMode,\n OptimizePromptInput,\n OptimizePromptResult,\n OptimizerConfig,\n PromptPreset,\n ProviderType,\n RelevantContextResult,\n SessionStore,\n RankedTargetCandidate,\n RoutingDecision,\n RoutingPriority,\n TargetCapability,\n TargetModelCandidate,\n WorkloadBias\n} from \"../types.js\";\nimport { TokenBudgetExceededError } from \"../errors.js\";\nimport { FileSessionStore } from \"../storage/fileSessionStore.js\";\nimport { SQLiteSessionStore } from \"../storage/sqliteSessionStore.js\";\nimport { noopLogger } from \"../utils/logger.js\";\nimport { normalizeWhitespace, validatePrompt } from \"../utils/validation.js\";\nimport { OllamaClient } from \"./ollamaClient.js\";\nimport { getOptimizationSystemPrompt, buildOptimizationPrompt } from \"./systemPrompt.js\";\nimport { TokenEstimator } from \"./tokenEstimator.js\";\nimport { ContextCompressor } from \"./contextCompressor.js\";\nimport { ContextManager, extractConstraints } from \"./contextManager.js\";\nimport {\n getDefaultPreferredModels,\n getQwenRouterModel,\n getSuitableAutoModels,\n selectOllamaModel\n} from \"./modelSelector.js\";\n\ninterface OptimizationResponse {\n optimizedPrompt?: string;\n constraints?: string[];\n changes?: string[];\n warnings?: string[];\n}\n\ninterface ModelRoutingResponse {\n selectedModel?: string;\n reason?: string;\n}\n\ninterface DownstreamRoutingResponse {\n selectedTargetId?: string;\n rankedTargetIds?: string[];\n reason?: string;\n}\n\nconst DEFAULT_MODE: OptimizationMode = \"claude_cli\";\nconst DEFAULT_PRESET: PromptPreset = \"chat\";\nconst DEFAULT_PROVIDER: ProviderType = \"ollama\";\nconst DEFAULT_MAX_INPUT_TOKENS = 1200;\nconst DEFAULT_MAX_CONTEXT_TOKENS = 800;\nconst DEFAULT_MAX_TOTAL_TOKENS = 2200;\nconst DEFAULT_ROUTING_PRIORITY: RoutingPriority = \"cheapest_adequate\";\nconst DEFAULT_ROUTING_TOP_K = 3;\nconst DEFAULT_WORKLOAD_BIAS: WorkloadBias = \"code_first\";\n\nexport class PromptOptimizer {\n readonly config: OptimizerConfig & {\n host: string;\n timeoutMs: number;\n temperature: number;\n preferredModels: string[];\n modelRoutingStrategy: \"qwen\";\n };\n\n private readonly logger;\n private readonly estimator;\n private readonly client;\n private readonly compressor;\n private readonly contextManager;\n\n constructor(config: OptimizerConfig = {}) {\n this.logger = config.logger ?? noopLogger;\n this.estimator = new TokenEstimator();\n this.client =\n config.ollamaClient ??\n new OllamaClient({\n host: config.host,\n model: config.ollamaModel,\n timeoutMs: config.timeoutMs,\n temperature: config.temperature,\n logger: this.logger\n });\n\n const store = resolveSessionStore(config);\n this.compressor = new ContextCompressor(this.estimator, this.client, this.logger);\n this.contextManager = new ContextManager(store, this.estimator, this.compressor, this.logger);\n\n this.config = {\n ...config,\n host: config.host ?? \"http://localhost:11434\",\n ollamaModel: config.ollamaModel,\n preferredModels: config.preferredModels ?? getDefaultPreferredModels(),\n modelRoutingStrategy: \"qwen\",\n timeoutMs: config.timeoutMs ?? 30000,\n temperature: config.temperature ?? 0.1\n };\n }\n\n async optimize(input: OptimizePromptInput): Promise<OptimizePromptResult> {\n const originalPrompt = validatePrompt(input.prompt);\n const mode = input.mode ?? this.config.defaultMode ?? DEFAULT_MODE;\n const preset = input.preset ?? this.config.defaultPreset ?? DEFAULT_PRESET;\n const maxInputTokens = input.maxInputTokens ?? this.config.maxInputTokens ?? DEFAULT_MAX_INPUT_TOKENS;\n const maxContextTokens = input.maxContextTokens ?? this.config.maxContextTokens ?? DEFAULT_MAX_CONTEXT_TOKENS;\n const maxTotalTokens = input.maxTotalTokens ?? this.config.maxTotalTokens ?? DEFAULT_MAX_TOTAL_TOKENS;\n const routingEnabled = input.routingEnabled !== false;\n const routingPriority = input.routingPriority ?? DEFAULT_ROUTING_PRIORITY;\n const routingTopK = input.routingTopK ?? DEFAULT_ROUTING_TOP_K;\n const workloadBias = input.workloadBias ?? DEFAULT_WORKLOAD_BIAS;\n const warnings: string[] = [];\n const changes: string[] = [];\n\n const useContext = input.useContext !== false && Boolean(input.sessionId);\n const saveContext = input.saveContext ?? Boolean(input.sessionId);\n const relevantContext = useContext && input.sessionId\n ? await this.contextManager.getRelevantContext({\n sessionId: input.sessionId,\n prompt: originalPrompt,\n task: input.task,\n tags: input.tags,\n pinnedConstraints: input.pinnedConstraints,\n maxContextTokens,\n timeoutMs: input.timeoutMs ?? this.config.timeoutMs\n })\n : emptyRelevantContext();\n\n warnings.push(...relevantContext.warnings);\n\n const contextBlock = formatContextBlock(relevantContext);\n const estimatedTokensBefore = this.estimator.estimateUsage({\n prompt: originalPrompt,\n context: contextBlock\n });\n\n if (estimatedTokensBefore.prompt > maxInputTokens) {\n warnings.push(\n `Raw prompt estimate (${estimatedTokensBefore.prompt}) exceeds maxInputTokens (${maxInputTokens}).`\n );\n }\n\n const extractedConstraints = Array.from(\n new Set([...extractConstraints(originalPrompt), ...(input.pinnedConstraints ?? [])])\n );\n\n let provider: ProviderType = input.bypassOptimization ? \"heuristic\" : this.config.provider ?? DEFAULT_PROVIDER;\n let model = provider === \"ollama\" ? this.config.ollamaModel ?? \"auto\" : \"heuristic\";\n let usedPreprocessedFallback = false;\n\n let optimizedPrompt = originalPrompt;\n let providerWarnings: string[] = [];\n let providerChanges: string[] = [];\n\n if (provider === \"ollama\") {\n const modelSelection = await this.resolveOllamaModel({\n prompt: originalPrompt,\n mode,\n preset,\n task: input.task\n });\n model = modelSelection.model;\n providerWarnings.push(...modelSelection.warnings);\n if (input.debug) {\n changes.push(modelSelection.reason);\n }\n\n if (modelSelection.forceHeuristic) {\n provider = \"heuristic\";\n model = \"heuristic\";\n }\n\n const ollamaResult = provider === \"ollama\"\n ? await this.tryOllamaOptimization({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n model,\n extractedConstraints,\n relevantContext: contextBlock\n })\n : null;\n\n if (ollamaResult) {\n optimizedPrompt = ollamaResult.optimizedPrompt;\n providerWarnings = ollamaResult.warnings;\n providerChanges = ollamaResult.changes;\n if (ollamaResult.source === \"preprocessed\") {\n provider = \"heuristic\";\n model = \"cheap-preprocess\";\n usedPreprocessedFallback = true;\n }\n } else if (provider === \"ollama\") {\n provider = \"heuristic\";\n model = \"heuristic\";\n providerWarnings = [\n `Ollama was unavailable. Falling back to deterministic local prompt shaping.`\n ];\n }\n }\n\n if (provider === \"heuristic\" && !usedPreprocessedFallback) {\n const fallback = this.heuristicOptimize({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n context: relevantContext,\n constraints: extractedConstraints\n });\n optimizedPrompt = fallback.optimizedPrompt;\n providerChanges = [...providerChanges, ...fallback.changes];\n providerWarnings = [...providerWarnings, ...fallback.warnings];\n }\n\n warnings.push(...providerWarnings);\n changes.push(...providerChanges);\n\n const routingDecision = await this.routeDownstreamTargets({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset,\n routingPriority,\n routingTopK,\n workloadBias\n },\n routingEnabled,\n routingPriority,\n routingTopK,\n workloadBias\n });\n\n warnings.push(...routingDecision.routingWarnings);\n\n let finalPrompt = composeFinalPrompt({\n optimizedPrompt,\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n context: relevantContext,\n routingDecision\n });\n\n let estimatedTokensAfter = {\n prompt: this.estimator.estimateText(optimizedPrompt),\n context: this.estimator.estimateText(formatContextBlock(relevantContext)),\n total: this.estimator.estimateText(finalPrompt)\n };\n\n if (estimatedTokensAfter.total > maxTotalTokens) {\n const reduced = await this.reduceToBudget({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n optimizedPrompt,\n context: relevantContext,\n routingDecision,\n maxTotalTokens\n });\n\n finalPrompt = reduced.finalPrompt;\n estimatedTokensAfter = reduced.estimatedTokensAfter;\n if (reduced.warning) {\n warnings.push(reduced.warning);\n }\n }\n\n if (estimatedTokensAfter.total > maxTotalTokens) {\n throw new TokenBudgetExceededError();\n }\n\n if (saveContext && input.sessionId) {\n await this.contextManager.saveContext({\n sessionId: input.sessionId,\n input: {\n ...input,\n prompt: originalPrompt\n },\n optimizedPrompt,\n finalPrompt,\n contextSummary: relevantContext.summary\n });\n }\n\n // Calculate granular token savings.\n // estimatedTokensBefore.total is raw prompt + context (no wrapper).\n // estimatedTokensAfter.total is the fully wrapped finalPrompt, so comparing them\n // directly penalises savings by wrapper overhead that was never present before.\n // tokenSavings reflects actual content reduction; wrapperOverhead is reported\n // separately so callers can account for the structural cost themselves.\n const originalPromptTokens = this.estimator.estimateText(originalPrompt);\n const promptCompressionSavings = Math.max(0, originalPromptTokens - estimatedTokensAfter.prompt);\n const contextCompressionSavings = Math.max(0, estimatedTokensBefore.context - estimatedTokensAfter.context);\n const wrapperOverhead = Math.max(0, estimatedTokensAfter.total - (estimatedTokensAfter.prompt + estimatedTokensAfter.context));\n const tokenSavings = promptCompressionSavings + contextCompressionSavings;\n\n return {\n originalPrompt,\n optimizedPrompt,\n finalPrompt,\n usedContext: relevantContext.usedEntries,\n contextSummary: relevantContext.summary,\n estimatedTokensBefore,\n estimatedTokensAfter,\n tokenSavings,\n promptCompressionSavings,\n contextCompressionSavings,\n wrapperOverhead,\n mode,\n provider,\n model,\n selectedTarget: routingDecision.selectedTarget,\n rankedTargets: routingDecision.rankedTargets,\n routingReason: routingDecision.routingReason,\n routingWarnings: routingDecision.routingWarnings,\n routingProvider: routingDecision.routingProvider,\n warnings,\n changes,\n debugInfo: input.debug\n ? {\n context: relevantContext.debugInfo,\n estimatedTokensBefore,\n estimatedTokensAfter,\n extractedConstraints,\n preset,\n selectedModel: model,\n routingDecision\n }\n : undefined\n };\n }\n\n async clearContext(sessionId: string): Promise<void> {\n await this.contextManager.clearContext(sessionId);\n }\n\n async loadContext(sessionId: string) {\n return this.contextManager.loadContext(sessionId);\n }\n\n async summarizeContext(sessionId: string, prompt: string, task?: string, budgetTokens = 200) {\n return this.contextManager.summarizeContext(sessionId, prompt, task, budgetTokens, this.config.timeoutMs);\n }\n\n async getRelevantContext(sessionId: string, prompt: string, task?: string, maxContextTokens?: number) {\n return this.contextManager.getRelevantContext({\n sessionId,\n prompt,\n task,\n maxContextTokens: maxContextTokens ?? this.config.maxContextTokens ?? DEFAULT_MAX_CONTEXT_TOKENS,\n timeoutMs: this.config.timeoutMs\n });\n }\n\n private async tryOllamaOptimization(options: {\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n model: string;\n extractedConstraints: string[];\n relevantContext: string;\n }): Promise<{ optimizedPrompt: string; changes: string[]; warnings: string[]; source: \"ollama\" | \"preprocessed\" } | null> {\n const preprocessedPrompt = cheapCompress(options.input.prompt);\n const preprocessedTokenCount = this.estimator.estimateText(preprocessedPrompt);\n const ultraMode = preprocessedTokenCount > 500;\n\n try {\n if (!(await this.client.isAvailable())) {\n return {\n optimizedPrompt: preprocessedPrompt,\n changes: [\"Applied cheap local preprocessing because Ollama was unavailable.\"],\n warnings: [\"Ollama was unavailable, so PromptPilot kept the cheap preprocessed prompt.\"],\n source: \"preprocessed\"\n };\n }\n\n const systemPrompt = ultraMode\n ? `${getOptimizationSystemPrompt(options.input.mode, options.input.preset)}\\nMode: Ultra compression. Minimize tokens aggressively.`\n : getOptimizationSystemPrompt(options.input.mode, options.input.preset);\n const optimizationPrompt = buildOptimizationPrompt(\n {\n ...options.input,\n prompt: preprocessedPrompt\n },\n options.relevantContext,\n options.extractedConstraints\n );\n\n const timeoutMs = options.input.timeoutMs ?? this.config.timeoutMs;\n\n let optimizedPrompt = \"\";\n let responseChanges: string[] = [];\n let responseWarnings: string[] = [];\n\n // Support text-only models with graceful fallback\n const generateWithFallback = this.client.generateJsonWithTextFallback\n ? async () => {\n const response = await this.client.generateJsonWithTextFallback!<OptimizationResponse>(\n {\n systemPrompt,\n prompt: optimizationPrompt,\n timeoutMs,\n model: options.model,\n temperature: this.config.temperature,\n format: \"json\"\n },\n (text: string) => ({\n optimizedPrompt: sanitizeTextOptimizationOutput(text),\n changes: [`Applied text-only Ollama optimization with ${options.model}.`],\n warnings: []\n } as OptimizationResponse)\n );\n return response;\n }\n : async () => {\n try {\n return await this.client.generateJson<OptimizationResponse>({\n systemPrompt,\n prompt: optimizationPrompt,\n timeoutMs,\n model: options.model,\n temperature: this.config.temperature,\n format: \"json\"\n });\n } catch {\n const raw = await this.client.generate({\n systemPrompt,\n prompt: optimizationPrompt,\n timeoutMs,\n model: options.model,\n temperature: this.config.temperature\n });\n\n return {\n optimizedPrompt: sanitizeTextOptimizationOutput(raw),\n changes: [`Applied text-only Ollama optimization with ${options.model}.`],\n warnings: []\n };\n }\n };\n\n const response = await generateWithFallback();\n optimizedPrompt = normalizeWhitespace(response.optimizedPrompt ?? \"\");\n responseChanges = response.changes ?? [];\n responseWarnings = response.warnings ?? [];\n\n if (!optimizedPrompt) {\n return {\n optimizedPrompt: preprocessedPrompt,\n changes: [\"Applied cheap local preprocessing because the model returned an empty optimization.\"],\n warnings: [\"The local optimizer returned an empty result, so PromptPilot kept the preprocessed prompt.\"],\n source: \"preprocessed\"\n };\n }\n\n const optimizedTokenCount = this.estimator.estimateText(optimizedPrompt);\n if (\n isCompressionSensitiveMode(options.input.mode) &&\n optimizedTokenCount >= preprocessedTokenCount\n ) {\n return {\n optimizedPrompt: preprocessedPrompt,\n changes: [\n ...responseChanges,\n \"Kept the cheap preprocessed prompt because the model output was not smaller.\"\n ],\n warnings: responseWarnings,\n source: \"preprocessed\"\n };\n }\n\n return {\n optimizedPrompt,\n changes: responseChanges.length > 0 ? responseChanges : [`Applied Ollama optimization with ${options.model}.`],\n warnings: responseWarnings,\n source: \"ollama\"\n };\n } catch {\n return {\n optimizedPrompt: preprocessedPrompt,\n changes: [\"Applied cheap local preprocessing because Ollama optimization failed.\"],\n warnings: [\"Ollama optimization failed, so PromptPilot kept the preprocessed prompt.\"],\n source: \"preprocessed\"\n };\n }\n }\n\n private async resolveOllamaModel(options: {\n prompt: string;\n mode: OptimizationMode;\n preset: PromptPreset;\n task?: string;\n }): Promise<{ model: string; warnings: string[]; reason: string; forceHeuristic: boolean }> {\n if (this.config.ollamaModel) {\n return {\n model: this.config.ollamaModel,\n warnings: [],\n reason: `Using explicitly configured model \"${this.config.ollamaModel}\".`,\n forceHeuristic: false\n };\n }\n\n if (!this.client.listModels) {\n return {\n model: \"heuristic\",\n warnings: [\n \"Model auto-selection is unavailable in the current Ollama client, so prompt optimization is falling back to deterministic heuristic formatting.\"\n ],\n reason: \"Model discovery is unsupported, so Qwen-based model routing could not run.\",\n forceHeuristic: true\n };\n }\n\n try {\n const installedModels = await this.client.listModels();\n const suitableModels = getSuitableAutoModels(installedModels);\n const selection = selectOllamaModel({\n installedModels,\n mode: options.mode,\n preset: options.preset,\n task: options.task,\n preferredModels: this.config.preferredModels\n });\n\n if (suitableModels.length === 0) {\n return {\n model: selection.model,\n warnings: [\n `No suitable small Ollama model was found for auto-use. Falling back to heuristic optimization. Install one of: ${this.config.preferredModels.join(\", \")}.`,\n selection.reason\n ],\n reason: selection.reason,\n forceHeuristic: true\n };\n }\n\n if (suitableModels.length === 1) {\n return {\n model: selection.model,\n warnings: [],\n reason: selection.reason,\n forceHeuristic: false\n };\n }\n\n if (this.config.modelRoutingStrategy === \"qwen\") {\n const routed = await this.tryQwenModelRouting({\n prompt: options.prompt,\n task: options.task,\n mode: options.mode,\n preset: options.preset,\n installedModels,\n candidateModels: suitableModels.map((model) => model.name),\n fallbackModel: selection.model\n });\n\n return {\n model: routed.model,\n warnings: routed.warnings,\n reason: routed.reason,\n forceHeuristic: routed.model === \"heuristic\"\n };\n }\n\n return {\n model: \"heuristic\",\n warnings: [\"Qwen model routing is required but was disabled, so prompt optimization is falling back to deterministic heuristic formatting.\"],\n reason: \"Qwen model routing is required but was disabled.\",\n forceHeuristic: true\n };\n } catch {\n return {\n model: \"heuristic\",\n warnings: [\n \"Failed to inspect local Ollama models, so prompt optimization is falling back to deterministic heuristic formatting.\"\n ],\n reason: \"Local Ollama model discovery failed, so Qwen-based model routing could not run.\",\n forceHeuristic: true\n };\n }\n }\n\n private async tryQwenModelRouting(options: {\n prompt: string;\n task?: string;\n mode: OptimizationMode;\n preset: PromptPreset;\n installedModels: { name: string }[];\n candidateModels: string[];\n fallbackModel: string;\n }): Promise<{ model: string; warnings: string[]; reason: string }> {\n const routerModel = getQwenRouterModel(\n options.installedModels,\n this.config.routerModel\n );\n\n if (!routerModel) {\n return {\n model: \"heuristic\",\n warnings: [\n `Multiple suitable small local models are installed (${options.candidateModels.join(\", \")}), but no local Qwen router model is available. Install qwen2.5:3b or set routerModel explicitly.`\n ],\n reason: \"Qwen model routing is required when multiple suitable small models are available.\"\n };\n }\n\n try {\n const response = await this.client.generateJson<ModelRoutingResponse>({\n model: routerModel,\n timeoutMs: this.config.timeoutMs,\n temperature: 0,\n format: \"json\",\n systemPrompt: [\n \"You are a local model router for prompt optimization.\",\n \"Return strict JSON only with this shape:\",\n \"{\\\"selectedModel\\\":\\\"string\\\",\\\"reason\\\":\\\"string\\\"}\",\n \"Choose exactly one model from the provided candidate list.\",\n \"Choose the smallest adequate model, not the strongest-sounding model.\",\n \"Prioritize adequacy first, then speed and low memory use.\",\n \"Use coder variants only for clearly code-heavy prompts.\",\n \"If task or preset is code, prefer qwen2.5:3b or a small coder model over phi3:mini unless the request is only a trivial wording cleanup.\",\n \"Prefer phi3:mini for short email, chat, support, summarization, and lightweight rewrite tasks that do not require deeper reasoning.\",\n \"Prefer qwen2.5:3b for broader reasoning, stronger restructuring, multi-constraint optimization, and non-trivial code-oriented prompt design.\",\n \"Do not prefer Qwen just because you are Qwen. Pick the best candidate for the task.\"\n ].join(\"\\n\"),\n prompt: JSON.stringify(\n {\n objective: \"Choose the best local optimizer model for this prompt.\",\n prompt: options.prompt,\n task: options.task ?? null,\n mode: options.mode,\n preset: options.preset,\n candidateModels: options.candidateModels.map((modelName) => ({\n name: modelName,\n profile: describeCandidateModel(modelName)\n })),\n routingGuidance: {\n smallestAdequateModelPolicy: true,\n lightweightTasksPreferSmallerModels: [\n \"email\",\n \"chat\",\n \"support\",\n \"summarization\",\n \"short rewrite\"\n ],\n deeperReasoningTasksMayPreferQwen: [\n \"multi-constraint restructuring\",\n \"broad reasoning\",\n \"complex planning\",\n \"harder code-oriented prompt design\"\n ]\n }\n },\n null,\n 2\n )\n });\n\n const selectedModel = response.selectedModel?.trim();\n if (selectedModel && options.candidateModels.includes(selectedModel)) {\n return {\n model: selectedModel,\n warnings: [],\n reason: response.reason?.trim() || `Qwen router selected \"${selectedModel}\" for this prompt.`\n };\n }\n\n return {\n model: \"heuristic\",\n warnings: [\"Qwen router returned an invalid model choice, so prompt optimization is falling back to deterministic heuristic formatting.\"],\n reason: \"Qwen router returned an invalid model selection.\"\n };\n } catch {\n return {\n model: \"heuristic\",\n warnings: [\"Qwen router could not choose a model, so prompt optimization is falling back to deterministic heuristic formatting.\"],\n reason: \"Qwen router failed to select a model.\"\n };\n }\n }\n\n private async routeDownstreamTargets(options: {\n input: OptimizePromptInput & {\n mode: OptimizationMode;\n preset: PromptPreset;\n routingPriority: RoutingPriority;\n routingTopK: number;\n workloadBias: WorkloadBias;\n };\n routingEnabled: boolean;\n routingPriority: RoutingPriority;\n routingTopK: number;\n workloadBias: WorkloadBias;\n }): Promise<RoutingDecision> {\n const availableTargets = normalizeAvailableTargets(options.input.availableTargets ?? []);\n\n if (!options.routingEnabled || availableTargets.length === 0) {\n return {\n selectedTarget: null,\n rankedTargets: [],\n routingReason: null,\n routingWarnings: [],\n routingProvider: null\n };\n }\n\n if (availableTargets.length === 1) {\n return {\n selectedTarget: stripInternalTargetFields(availableTargets[0]),\n rankedTargets: [\n {\n ...stripInternalTargetFields(availableTargets[0]),\n rank: 1,\n reason: \"Only one downstream target was supplied.\"\n }\n ],\n routingReason: \"Only one downstream target was supplied, so it was selected directly.\",\n routingWarnings: [],\n routingProvider: \"direct\"\n };\n }\n\n if (!this.client.listModels) {\n if (isClaudeTiersOnlyTargetSet(availableTargets)) {\n const selected = selectClaudeTierHeuristic(options.input, options.routingPriority, availableTargets);\n if (selected) {\n return {\n selectedTarget: stripInternalTargetFields(selected),\n rankedTargets: [{ ...stripInternalTargetFields(selected), rank: 1, reason: \"Selected by Claude tier heuristic (no local Qwen router available).\" }],\n routingReason: \"Selected by Claude tier heuristic (no local Qwen router available).\",\n routingWarnings: [],\n routingProvider: \"heuristic\"\n };\n }\n }\n\n return {\n selectedTarget: null,\n rankedTargets: [],\n routingReason: null,\n routingWarnings: [\n \"Downstream target routing requires local Ollama model discovery so a Qwen router can run.\"\n ],\n routingProvider: null\n };\n }\n\n try {\n const installedModels = await this.client.listModels();\n const routerModel = getQwenRouterModel(installedModels, this.config.routerModel);\n if (!routerModel) {\n return {\n selectedTarget: null,\n rankedTargets: [],\n routingReason: null,\n routingWarnings: [\n \"Downstream target routing could not run because no suitable local Qwen router model is installed.\"\n ],\n routingProvider: null\n };\n }\n\n const claudeTiersOnly = isClaudeTiersOnlyTargetSet(availableTargets);\n\n const response = await this.client.generateJson<DownstreamRoutingResponse>({\n model: routerModel,\n timeoutMs: options.input.timeoutMs ?? this.config.timeoutMs,\n temperature: 0,\n format: \"json\",\n systemPrompt: buildDownstreamRoutingSystemPrompt(options.routingPriority, options.workloadBias, claudeTiersOnly),\n prompt: JSON.stringify(\n {\n objective: \"Rank the caller-supplied downstream targets for this prompt and choose the best top target.\",\n prompt: options.input.prompt,\n task: options.input.task ?? null,\n mode: options.input.mode,\n preset: options.input.preset,\n tone: options.input.tone ?? null,\n targetHints: options.input.targetHints ?? [],\n workloadBias: options.workloadBias,\n routingPriority: options.routingPriority,\n candidateTargets: availableTargets.map((target) => ({\n id: target.id,\n provider: target.provider,\n model: target.model,\n label: target.label ?? null,\n costRank: target.costRank,\n latencyRank: target.latencyRank,\n capabilities: target.capabilities,\n profile: describeDownstreamTarget(target)\n }))\n },\n null,\n 2\n )\n });\n\n const rankedTargetIds = Array.from(\n new Set((response.rankedTargetIds ?? []).map((value) => value.trim()).filter(Boolean))\n ).slice(0, Math.max(1, options.routingTopK));\n\n const rankedTargets = rankedTargetIds\n .map((id, index) => {\n const target = availableTargets.find((candidate) => candidate.id === id);\n if (!target) {\n return null;\n }\n\n return {\n ...stripInternalTargetFields(target),\n rank: index + 1,\n reason:\n index === 0\n ? response.reason?.trim() || \"Selected by the local Qwen downstream router.\"\n : `Ranked #${index + 1} by the local Qwen downstream router.`\n } satisfies RankedTargetCandidate;\n })\n .filter((value): value is RankedTargetCandidate => value !== null);\n\n const selectedTargetId = response.selectedTargetId?.trim();\n const selectedTargetCandidate =\n (selectedTargetId && availableTargets.find((candidate) => candidate.id === selectedTargetId)) ??\n (rankedTargets[0]\n ? availableTargets.find(\n (candidate) =>\n candidate.provider === rankedTargets[0].provider &&\n candidate.model === rankedTargets[0].model &&\n candidate.label === rankedTargets[0].label\n ) ?? null\n : null);\n\n if (!selectedTargetCandidate || rankedTargets.length === 0) {\n return {\n selectedTarget: null,\n rankedTargets: [],\n routingReason: null,\n routingWarnings: [\n \"Downstream target routing returned an invalid selection, so no downstream target was chosen.\"\n ],\n routingProvider: routerModel\n };\n }\n\n return {\n selectedTarget: stripInternalTargetFields(selectedTargetCandidate),\n rankedTargets,\n routingReason: response.reason?.trim() || \"Selected by the local Qwen downstream router.\",\n routingWarnings: [],\n routingProvider: routerModel\n };\n } catch {\n if (isClaudeTiersOnlyTargetSet(availableTargets)) {\n const selected = selectClaudeTierHeuristic(options.input, options.routingPriority, availableTargets);\n if (selected) {\n return {\n selectedTarget: stripInternalTargetFields(selected),\n rankedTargets: [{ ...stripInternalTargetFields(selected), rank: 1, reason: \"Selected by Claude tier heuristic (Qwen routing failed).\" }],\n routingReason: \"Selected by Claude tier heuristic (Qwen routing failed).\",\n routingWarnings: [\"Qwen downstream routing failed; fell back to Claude tier heuristic.\"],\n routingProvider: \"heuristic\"\n };\n }\n }\n\n return {\n selectedTarget: null,\n rankedTargets: [],\n routingReason: null,\n routingWarnings: [\n \"Downstream target routing could not complete, so no downstream target was selected.\"\n ],\n routingProvider: null\n };\n }\n }\n\n private heuristicOptimize(options: {\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n context: RelevantContextResult;\n constraints: string[];\n }): { optimizedPrompt: string; changes: string[]; warnings: string[] } {\n const isCodeRequest = isCodeFirstRequest(options.input);\n const lines = isCodeRequest\n ? buildCodeFirstHeuristicPrompt(options.input, options.constraints)\n : buildGeneralHeuristicPrompt(options.input, options.constraints);\n\n const optimizedPrompt = lines.join(\"\\n\");\n const changes = isCodeRequest\n ? [\n \"Compressed the prompt into a code-agent brief.\",\n \"Removed redundant narrative phrasing.\",\n \"Applied a Karpathy-style inspect-plan-act-test-reflect loop.\"\n ]\n : [\"Normalized prompt structure for downstream model consumption.\"];\n if (options.input.mode === \"compress\" || options.input.mode === \"concise\") {\n changes.push(\"Applied concise formatting to reduce token usage.\");\n }\n\n return {\n optimizedPrompt,\n changes,\n warnings: []\n };\n }\n\n private async reduceToBudget(options: {\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n optimizedPrompt: string;\n context: RelevantContextResult;\n routingDecision: RoutingDecision;\n maxTotalTokens: number;\n }): Promise<{ finalPrompt: string; estimatedTokensAfter: { prompt: number; context: number; total: number }; warning?: string }> {\n const summaryBudget = Math.max(80, Math.floor(options.maxTotalTokens * 0.2));\n const summary = options.input.sessionId\n ? await this.summarizeContext(options.input.sessionId, options.input.prompt, options.input.task, summaryBudget)\n : null;\n\n const compactContext: RelevantContextResult = {\n ...options.context,\n usedEntries: [],\n summary\n };\n\n const finalPrompt = composeFinalPrompt({\n optimizedPrompt: this.estimator.truncateToBudget(options.optimizedPrompt, Math.floor(options.maxTotalTokens * 0.5)),\n input: options.input,\n context: compactContext,\n routingDecision: options.routingDecision\n });\n\n return {\n finalPrompt,\n estimatedTokensAfter: {\n prompt: this.estimator.estimateText(options.optimizedPrompt),\n context: this.estimator.estimateText(formatContextBlock(compactContext)),\n total: this.estimator.estimateText(finalPrompt)\n },\n warning: \"Summarized stored context further to stay within the total token budget.\"\n };\n }\n}\n\nfunction describeCandidateModel(modelName: string): string {\n const lower = modelName.toLowerCase();\n\n if (lower.includes(\"phi3:mini\")) {\n return \"Very small and fast. Good for short rewrites, lightweight email/chat tasks, and simple prompt cleanup.\";\n }\n\n if (lower.includes(\"qwen2.5:3b\")) {\n return \"Small general-purpose model with stronger reasoning and restructuring than ultra-light models. Better for broader or more complex prompt optimization.\";\n }\n\n if (lower.includes(\"coder\")) {\n return \"Code-specialized model. Use only when the prompt is clearly code-heavy or refactor-oriented.\";\n }\n\n if (lower.includes(\"llama3.2:3b\")) {\n return \"Small general chat/rewrite model. Reasonable middle option for general tasks.\";\n }\n\n return \"Local candidate model for prompt optimization.\";\n}\n\nfunction resolveSessionStore(config: OptimizerConfig): SessionStore {\n if (typeof config.contextStore === \"object\" && config.contextStore !== null) {\n return config.contextStore;\n }\n\n if (config.contextStore === \"sqlite\") {\n return new SQLiteSessionStore(config.sqlitePath);\n }\n\n return new FileSessionStore(config.storageDir);\n}\n\nfunction composeFinalPrompt(input: {\n optimizedPrompt: string;\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n context: RelevantContextResult;\n routingDecision: RoutingDecision;\n}): string {\n const sections: string[] = [];\n\n sections.push(`Task:\\n${input.optimizedPrompt}`);\n\n const contextBlock = formatContextBlock(input.context);\n if (contextBlock) {\n sections.push(`Relevant context:\\n${contextBlock}`);\n }\n\n const constraints = Array.from(\n new Set([\n ...(input.input.pinnedConstraints ?? []),\n ...extractConstraints(input.input.prompt),\n input.input.maxLength ? `Keep the response within ${input.input.maxLength} units if possible.` : \"\",\n input.input.tone ? `Maintain a ${input.input.tone} tone.` : \"\",\n input.input.outputFormat ? `Return the output as ${input.input.outputFormat}.` : \"\"\n ].filter(Boolean))\n );\n\n if (constraints.length > 0) {\n sections.push(`Constraints:\\n- ${constraints.join(\"\\n- \")}`);\n }\n\n const desiredOutput = [\n input.routingDecision.selectedTarget\n ? `Selected target: ${formatTargetLabel(input.routingDecision.selectedTarget)}`\n : input.input.targetModel\n ? `Target model: ${input.input.targetModel}`\n : \"Target model: claude\",\n `Mode: ${input.input.mode}`,\n `Preset: ${input.input.preset}`\n ];\n\n sections.push(`Desired output:\\n- ${desiredOutput.join(\"\\n- \")}`);\n\n return sections.join(\"\\n\\n\").trim();\n}\n\nfunction formatContextBlock(context: RelevantContextResult): string {\n const lines: string[] = [];\n\n if (context.summary?.text) {\n lines.push(`Summary: ${context.summary.text}`);\n }\n\n for (const entry of context.usedEntries.slice(-4)) {\n lines.push(`- ${entry.optimizedPrompt ?? entry.rawPrompt ?? entry.text}`);\n }\n\n return normalizeWhitespace(lines.join(\"\\n\"));\n}\n\nfunction emptyRelevantContext(): RelevantContextResult {\n return {\n usedEntries: [],\n summary: null,\n warnings: [],\n debugInfo: {}\n };\n}\n\ntype NormalizedTargetCandidate = TargetModelCandidate & { id: string; costRank: number; latencyRank: number };\n\nfunction normalizeAvailableTargets(targets: TargetModelCandidate[]): NormalizedTargetCandidate[] {\n return targets.map((target, index) => ({\n ...target,\n id: `${target.provider}:${target.model}:${index}`,\n label: target.label ?? `${target.provider}:${target.model}`,\n capabilities: target.capabilities ?? inferCapabilities(target),\n costRank: target.costRank ?? index + 1,\n latencyRank: target.latencyRank ?? index + 1\n }));\n}\n\nfunction stripInternalTargetFields(target: NormalizedTargetCandidate): TargetModelCandidate {\n return {\n provider: target.provider,\n model: target.model,\n label: target.label,\n capabilities: target.capabilities,\n costRank: target.costRank,\n latencyRank: target.latencyRank\n };\n}\n\nfunction buildDownstreamRoutingSystemPrompt(\n priority: RoutingPriority,\n workloadBias: WorkloadBias,\n claudeTiersOnly = false\n): string {\n const lines = [\n \"You are a downstream model router for PromptPilot.\",\n \"Return strict JSON only with this shape:\",\n \"{\\\"selectedTargetId\\\":\\\"string\\\",\\\"rankedTargetIds\\\":[\\\"string\\\"],\\\"reason\\\":\\\"string\\\"}\",\n \"Choose only from the supplied candidate target IDs.\",\n \"Rank up to the requested top targets in best-first order.\",\n `Routing priority: ${priority}.`,\n `Workload bias: ${workloadBias}.`,\n \"Code-first means ambiguous prompts should default toward coding-capable or agentic-capable targets.\",\n \"Explicit email, support, chat, and lightweight writing prompts may prefer cheaper lighter targets.\",\n \"Do not invent targets. Do not output prose outside JSON.\"\n ];\n\n if (claudeTiersOnly) {\n lines.push(\n \"You are choosing between Claude model tiers (Haiku, Sonnet, Opus).\",\n \"Haiku: fastest and cheapest. Best for email, chat, support, summarization, and simple rewrites. Avoid for deep coding or multi-step reasoning.\",\n \"Sonnet: balanced cost and capability. Best for coding, debugging, refactoring, writing, and general-purpose tasks. The default for most prompts.\",\n \"Opus: most capable and most expensive. Reserve for complex architecture decisions, multi-constraint agentic planning, long-horizon reasoning, or prompts that clearly require the strongest model.\",\n \"When routing priority is cheapest_adequate: prefer Haiku for lightweight tasks, Sonnet for most code and writing tasks, and Opus only when clearly necessary.\",\n \"When routing priority is best_quality: prefer Opus for code and reasoning, Sonnet for writing and simple code.\",\n \"When routing priority is fastest_adequate: prefer Haiku unless the task clearly needs Sonnet-level capability.\"\n );\n }\n\n return lines.join(\"\\n\");\n}\n\nexport const CLAUDE_TIER_TARGETS: TargetModelCandidate[] = [\n {\n provider: \"anthropic\",\n model: \"claude-haiku-4-5\",\n label: \"anthropic:claude-haiku-4-5\",\n capabilities: [\"writing\", \"email\", \"support\", \"chat\", \"summarization\"],\n costRank: 1,\n latencyRank: 1\n },\n {\n provider: \"anthropic\",\n model: \"claude-sonnet-4-6\",\n label: \"anthropic:claude-sonnet-4-6\",\n capabilities: [\"coding\", \"writing\", \"agentic\", \"tool_use\", \"refactor\", \"debugging\"],\n costRank: 2,\n latencyRank: 2\n },\n {\n provider: \"anthropic\",\n model: \"claude-opus-4-6\",\n label: \"anthropic:claude-opus-4-6\",\n capabilities: [\"coding\", \"agentic\", \"tool_use\", \"refactor\", \"debugging\", \"architecture\", \"writing\"],\n costRank: 3,\n latencyRank: 3\n }\n];\n\nfunction isClaudeTiersOnlyTargetSet(targets: NormalizedTargetCandidate[]): boolean {\n return (\n targets.length >= 2 &&\n targets.every(\n (t) =>\n t.provider === \"anthropic\" &&\n /haiku|sonnet|opus/i.test(t.model)\n )\n );\n}\n\nfunction selectClaudeTierHeuristic(\n input: { prompt: string; task?: string; preset?: string; targetHints?: readonly TargetCapability[] },\n priority: RoutingPriority,\n targets: NormalizedTargetCandidate[]\n): NormalizedTargetCandidate | null {\n const haiku = targets.find((t) => /haiku/i.test(t.model)) ?? null;\n const sonnet = targets.find((t) => /sonnet/i.test(t.model)) ?? null;\n const opus = targets.find((t) => /opus/i.test(t.model)) ?? null;\n\n const task = (input.task ?? \"\").toLowerCase();\n const preset = (input.preset ?? \"\").toLowerCase();\n const hints = input.targetHints ?? [];\n const prompt = input.prompt;\n\n const isLightweight =\n [\"email\", \"chat\", \"support\", \"summarization\"].includes(task) ||\n [\"email\", \"chat\", \"support\", \"summarization\"].includes(preset) ||\n hints.some((h) => [\"email\", \"support\", \"chat\", \"summarization\"].includes(h));\n\n const needsOpus =\n /\\b(architect|architecture|design system|migration plan|multi.?step|complex.*refactor|long.?horizon|agentic.*plan)\\b/i.test(prompt) ||\n hints.includes(\"architecture\") ||\n priority === \"best_quality\";\n\n if (priority === \"fastest_adequate\") {\n return isLightweight || !needsOpus ? (haiku ?? sonnet) : (sonnet ?? haiku);\n }\n\n if (needsOpus) {\n return opus ?? sonnet ?? haiku;\n }\n\n if (isLightweight && priority === \"cheapest_adequate\") {\n return haiku ?? sonnet;\n }\n\n return sonnet ?? haiku ?? opus;\n}\n\nfunction inferCapabilities(target: TargetModelCandidate): TargetCapability[] {\n const lower = `${target.provider} ${target.model} ${target.label ?? \"\"}`.toLowerCase();\n const capabilities = new Set<TargetCapability>();\n\n if (/code|codex|coder|agent|tool/.test(lower)) {\n capabilities.add(\"coding\");\n }\n if (/agent|tool/.test(lower)) {\n capabilities.add(\"agentic\");\n capabilities.add(\"tool_use\");\n }\n if (/refactor|coder|codex/.test(lower)) {\n capabilities.add(\"refactor\");\n }\n if (/debug|fix|ci/.test(lower)) {\n capabilities.add(\"debugging\");\n }\n if (/write|email|chat|sonnet|mini/.test(lower)) {\n capabilities.add(\"writing\");\n }\n if (/email/.test(lower)) {\n capabilities.add(\"email\");\n }\n\n return Array.from(capabilities);\n}\n\nfunction describeDownstreamTarget(target: NormalizedTargetCandidate): string {\n return [\n `provider=${target.provider}`,\n `model=${target.model}`,\n `label=${target.label}`,\n `costRank=${target.costRank}`,\n `latencyRank=${target.latencyRank}`,\n `capabilities=${target.capabilities?.join(\",\") || \"none\"}`\n ].join(\"; \");\n}\n\nfunction formatTargetLabel(target: TargetModelCandidate): string {\n return target.label ?? `${target.provider}:${target.model}`;\n}\n\nfunction isCompressionSensitiveMode(mode: OptimizationMode): boolean {\n return mode === \"compress\" || mode === \"concise\" || mode === \"claude_cli\";\n}\n\nfunction cheapCompress(text: string): string {\n return normalizeWhitespace(text)\n .replace(/\\b(?:please|kindly|just)\\b/gi, \"\")\n .replace(/\\bI\\s+(?:want|need|would\\s+like\\s+to)\\b/gi, \"\")\n .replace(/\\s+([,.;:!?])/g, \"$1\")\n .replace(/\\s{2,}/g, \" \")\n .trim();\n}\n\nfunction sanitizeTextOptimizationOutput(raw: string): string {\n const normalized = normalizeWhitespace(raw);\n if (!normalized) {\n return \"\";\n }\n\n // Remove common reasoning markers and thinking blocks\n let cleaned = normalized\n .replace(/<think>[\\s\\S]*?<\\/think>/gi, \"\")\n .replace(/<reasoning>[\\s\\S]*?<\\/reasoning>/gi, \"\")\n .replace(/<analysis>[\\s\\S]*?<\\/analysis>/gi, \"\")\n .replace(/^(thinking|thinking process|analysis|critique|attempt|final decision|role|task|guidelines)[:=]?[\\s\\S]*?(?=\\n\\n|\\n[A-Z]|$)/gim, \"\");\n\n if (!containsReasoningLeak(cleaned)) {\n return stripWrappingQuotes(cleaned);\n }\n\n // Fallback: split by paragraphs and extract the most relevant one\n const candidates = cleaned\n .split(/\\n{2,}/)\n .map((chunk) => stripWrappingQuotes(normalizeWhitespace(chunk)))\n .filter(Boolean)\n .filter((chunk) => !containsReasoningLeak(chunk))\n .filter((chunk) => !/^(role|task|guidelines|thinking|thinking process|attempt|critique|final decision|analysis)\\b/i.test(chunk))\n .filter((chunk) => chunk.length > 10);\n\n // Prefer the longest non-reasoning chunk as it's likely the main output\n const selected = candidates.reduce((a, b) => (a.length > b.length ? a : b), \"\");\n return selected || stripWrappingQuotes(normalized);\n}\n\nfunction containsReasoningLeak(text: string): boolean {\n return /(thinking process|analyze the request|drafting the optimized prompt|critique \\d|attempt \\d|final decision|^thinking:|^analysis:|<think>|<reasoning>|<analysis>)/i.test(text);\n}\n\nfunction stripWrappingQuotes(text: string): string {\n return text.replace(/^[\"'`]+|[\"'`]+$/g, \"\").trim();\n}\n\nfunction isCodeFirstRequest(input: Pick<OptimizePromptInput, \"task\" | \"preset\" | \"prompt\" | \"targetHints\" | \"workloadBias\">): boolean {\n if (input.task === \"code\" || input.preset === \"code\") {\n return true;\n }\n\n if ((input.targetHints ?? []).some((hint) => [\"coding\", \"agentic\", \"refactor\", \"debugging\", \"tool_use\", \"architecture\"].includes(hint))) {\n return true;\n }\n\n return /\\b(code|coding|repo|repository|refactor|patch|debug|bug|ci|test|typescript|javascript|agent|tool)\\b/i.test(\n input.prompt\n );\n}\n\nfunction buildGeneralHeuristicPrompt(\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset },\n constraints: string[]\n): string[] {\n return [\n `Request: ${summarizePrompt(input.prompt, 320)}`,\n input.task ? `Task type: ${input.task}` : \"\",\n input.tone ? `Tone: ${input.tone}` : \"\",\n input.outputFormat ? `Output format: ${input.outputFormat}` : \"\",\n input.maxLength ? `Maximum length: ${input.maxLength}` : \"\",\n constraints.length ? `Critical constraints: ${constraints.join(\"; \")}` : \"\"\n ].filter(Boolean);\n}\n\nfunction buildCodeFirstHeuristicPrompt(\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset },\n constraints: string[]\n): string[] {\n const deliverables = inferCodeDeliverables(input.prompt);\n return [\n `Goal: ${summarizeCodeGoal(input.prompt)}`,\n input.tone ? `Tone: ${input.tone}` : \"\",\n deliverables.length ? `Deliverables:\\n- ${deliverables.join(\"\\n- \")}` : \"\",\n constraints.length ? `Constraints: ${constraints.join(\"; \")}` : \"\",\n \"Use a Karpathy loop: inspect, plan, act, test, reflect, repeat.\"\n ].filter(Boolean);\n}\n\nfunction summarizePrompt(prompt: string, maxLength: number): string {\n const normalized = normalizeWhitespace(prompt);\n if (normalized.length <= maxLength) {\n return normalized;\n }\n\n return `${normalized.slice(0, maxLength - 1).trim()}…`;\n}\n\nfunction summarizeCodeGoal(prompt: string): string {\n const normalized = summarizePrompt(prompt, 220);\n const lowered = prompt.toLowerCase();\n\n if (/auth|authentication|login|token/.test(lowered)) {\n return \"Inspect the codebase, understand the authentication flow, and produce a safe incremental refactor plan.\";\n }\n\n if (/ci|debug|failing|failure|test/.test(lowered)) {\n return \"Inspect the codebase and failing signals, identify root causes, and produce a practical debugging plan.\";\n }\n\n if (/refactor/.test(lowered)) {\n return \"Inspect the codebase and produce a phased refactor plan with minimal-risk execution steps.\";\n }\n\n return normalized;\n}\n\nfunction inferCodeDeliverables(prompt: string): string[] {\n const lowered = prompt.toLowerCase();\n const deliverables: string[] = [];\n\n if (/inspect|codebase|repo|repository/.test(lowered)) {\n deliverables.push(\"Summarize the relevant modules, ownership boundaries, and current behavior.\");\n }\n if (/shared abstraction|shared abstractions|duplicate|duplicated/.test(lowered)) {\n deliverables.push(\"Identify duplicated logic and the best shared abstractions to extract.\");\n }\n if (/incremental|phase|phased|rollout|step/.test(lowered)) {\n deliverables.push(\"Propose an incremental plan with small, reversible steps.\");\n }\n if (/risk|migration|compatibility|backward/.test(lowered)) {\n deliverables.push(\"Call out migration risks, compatibility concerns, and rollback points.\");\n }\n if (/test|tests/.test(lowered)) {\n deliverables.push(\"List the tests or validation needed before and after each phase.\");\n }\n if (/avoid hand-wavy|practical|concrete/.test(lowered)) {\n deliverables.push(\"Keep the recommendations concrete, implementation-oriented, and free of vague architecture advice.\");\n }\n\n if (deliverables.length === 0) {\n deliverables.push(\"Produce a compact, execution-ready plan for the coding task.\");\n }\n\n return deliverables.slice(0, 6);\n}\n","import type { OptimizePromptInput, OptimizerConfig } from \"./types.js\";\nimport { PromptOptimizer } from \"./core/optimizer.js\";\n\nexport * from \"./types.js\";\nexport * from \"./errors.js\";\nexport { PromptOptimizer } from \"./core/optimizer.js\";\nexport { OllamaClient } from \"./core/ollamaClient.js\";\nexport { TokenEstimator } from \"./core/tokenEstimator.js\";\nexport { ContextManager } from \"./core/contextManager.js\";\nexport { ContextCompressor } from \"./core/contextCompressor.js\";\nexport { selectOllamaModel, getDefaultPreferredModels } from \"./core/modelSelector.js\";\nexport { CLAUDE_TIER_TARGETS } from \"./core/optimizer.js\";\nexport { FileSessionStore } from \"./storage/fileSessionStore.js\";\nexport { SQLiteSessionStore } from \"./storage/sqliteSessionStore.js\";\n\nexport function createOptimizer(config: OptimizerConfig = {}) {\n return new PromptOptimizer(config);\n}\n\nexport async function optimizePrompt(input: OptimizePromptInput, config: OptimizerConfig = {}) {\n const optimizer = createOptimizer(config);\n return optimizer.optimize(input);\n}\n","const ARROW_UP = \"\\x1b[A\";\nconst ARROW_DOWN = \"\\x1b[B\";\nconst ENTER = \"\\r\";\nconst CTRL_C = \"\\x03\";\nconst ESCAPE = \"\\x1b\";\n\nexport type ClaudeTierChoice = \"auto\" | \"haiku\" | \"sonnet\" | \"opus\";\n\nexport interface ClaudeTierOption {\n key: ClaudeTierChoice;\n label: string;\n badge: string;\n description: string;\n}\n\nexport const CLAUDE_TIER_OPTIONS: ClaudeTierOption[] = [\n {\n key: \"auto\",\n label: \"Auto\",\n badge: \"recommended\",\n description: \"PromptPilot picks the best tier for your prompt\"\n },\n {\n key: \"haiku\",\n label: \"Haiku\",\n badge: \"fastest · cheapest\",\n description: \"email, chat, summarization, simple rewrites\"\n },\n {\n key: \"sonnet\",\n label: \"Sonnet\",\n badge: \"balanced\",\n description: \"coding, debugging, writing, general-purpose\"\n },\n {\n key: \"opus\",\n label: \"Opus\",\n badge: \"most capable\",\n description: \"architecture, complex reasoning, agentic planning\"\n }\n];\n\nexport function renderClaudeMenu(options: ClaudeTierOption[], selected: number): string {\n const lines: string[] = [\"Select Claude model tier:\\n\"];\n for (let index = 0; index < options.length; index++) {\n const opt = options[index];\n const isSelected = index === selected;\n const cursor = isSelected ? \"❯\" : \" \";\n const label = isSelected ? `\\x1b[1m${opt.label}\\x1b[0m` : opt.label;\n const badge = `\\x1b[2m${opt.badge}\\x1b[0m`;\n const desc = `\\x1b[2m${opt.description}\\x1b[0m`;\n lines.push(` ${cursor} ${label.padEnd(isSelected ? 14 : 6)} ${badge}`);\n lines.push(` ${desc}`);\n }\n lines.push(\"\\n \\x1b[2m↑/↓ move Enter confirm q cancel\\x1b[0m\");\n return lines.join(\"\\n\");\n}\n\nexport async function promptClaudeTierMenu(\n stderr: { write(msg: string): void },\n stdin: NodeJS.ReadStream\n): Promise<ClaudeTierChoice | null> {\n return new Promise((resolve) => {\n let selected = 0;\n const options = CLAUDE_TIER_OPTIONS;\n const lineCount = options.length * 2 + 3; // header + 2 lines per option + footer\n\n const draw = (first: boolean) => {\n if (!first) {\n // Move cursor up to overwrite previous render\n stderr.write(`\\x1b[${lineCount}A`);\n }\n stderr.write(`\\x1b[?25l${renderClaudeMenu(options, selected)}\\n`);\n };\n\n const cleanup = () => {\n stderr.write(\"\\x1b[?25h\"); // restore cursor\n stdin.setRawMode(false);\n stdin.pause();\n stdin.removeListener(\"data\", onData);\n };\n\n const onData = (chunk: string) => {\n if (chunk === CTRL_C) {\n cleanup();\n process.exit(0);\n }\n\n if (chunk === \"q\" || chunk === ESCAPE) {\n cleanup();\n stderr.write(\"\\n\");\n resolve(null);\n return;\n }\n\n if (chunk === ARROW_UP) {\n selected = (selected - 1 + options.length) % options.length;\n draw(false);\n return;\n }\n\n if (chunk === ARROW_DOWN) {\n selected = (selected + 1) % options.length;\n draw(false);\n return;\n }\n\n if (chunk === ENTER) {\n cleanup();\n stderr.write(`\\n Selected: \\x1b[1m${options[selected].label}\\x1b[0m\\n\\n`);\n resolve(options[selected].key);\n }\n };\n\n stdin.setRawMode(true);\n stdin.resume();\n stdin.setEncoding(\"utf8\");\n stdin.on(\"data\", onData);\n\n draw(true);\n });\n}\n","import { basename } from \"node:path\";\n\nexport interface WelcomeScreenOptions {\n columns?: number;\n cwd: string;\n version: string;\n color?: boolean;\n user?: string;\n}\n\nconst MIN_WIDE_COLUMNS = 76;\nconst PANEL_RULE = \"__PANEL_RULE__\";\n\nexport function renderWelcomeScreen(options: WelcomeScreenOptions): string {\n const columns = Math.max(60, options.columns ?? 100);\n const color = options.color ?? false;\n const user = options.user?.trim() || \"pilot\";\n\n return columns >= MIN_WIDE_COLUMNS\n ? renderWideWelcome({ ...options, columns, color, user })\n : renderCompactWelcome({ ...options, columns, color, user });\n}\n\nfunction renderWideWelcome(options: Required<WelcomeScreenOptions>): string {\n const width = clamp(options.columns - 4, 76, 118);\n const innerWidth = width - 2;\n const leftWidth = 30;\n const rightWidth = innerWidth - leftWidth - 5;\n const title = ` PromptPilot v${options.version} `;\n\n const leftLines = [\n style(`Welcome back ${capitalize(options.user)}!`, \"bold\", options.color),\n \"\",\n ...paintSprite(options.color),\n \"\",\n style(`${options.user} • ${basename(options.cwd)}`, \"dim\", options.color),\n style(options.cwd, \"dim\", options.color)\n ];\n\n const rightLines = [\n style(\"Tips for getting started\", \"accent\", options.color),\n \"Run \" + style(\"promptpilot optimize \\\"fix this CI failure\\\" --task code --plain\", \"bold\", options.color),\n \"Pipe directly into Claude with \" + style(\"| claude\", \"bold\", options.color),\n PANEL_RULE,\n style(\"Local setup\", \"accent\", options.color),\n \"Use \" + style(\"--model promptpilot-compressor\", \"bold\", options.color) + \" for text-only local compression\",\n \"\",\n style(\"Commands\", \"accent\", options.color),\n \"optimize optimize, compress, and route prompts\",\n \"--help show the full CLI reference\"\n ];\n\n const rowCount = Math.max(leftLines.length, rightLines.length);\n const topRule = renderTopRule(title, innerWidth, options.color);\n const bottomRule = `${style(\"╰\", \"accent\", options.color)}${style(\"─\".repeat(innerWidth), \"accent\", options.color)}${style(\"╯\", \"accent\", options.color)}`;\n\n const body = new Array(rowCount).fill(null).map((_, index) => {\n const left = padVisible(leftLines[index] ?? \"\", leftWidth);\n const rightLine = rightLines[index] ?? \"\";\n const right = rightLine === PANEL_RULE\n ? style(\"─\".repeat(rightWidth), \"dim\", options.color)\n : padVisible(rightLine, rightWidth);\n return `${style(\"│\", \"accent\", options.color)} ${left} ${style(\"│\", \"accent\", options.color)} ${right} ${style(\"│\", \"accent\", options.color)}`;\n });\n\n const footer = [\n \"\",\n style(\"Ready when you are.\", \"dim\", options.color),\n `Run ${style(\"promptpilot --help\", \"bold\", options.color)} for the full option list.`\n ];\n\n return [topRule, ...body, bottomRule, ...footer].join(\"\\n\");\n}\n\nfunction renderCompactWelcome(options: Required<WelcomeScreenOptions>): string {\n const width = clamp(options.columns - 2, 58, 82);\n const innerWidth = width - 2;\n const title = ` PromptPilot v${options.version} `;\n const lines = [\n centerVisible(style(`Welcome back ${capitalize(options.user)}!`, \"bold\", options.color), innerWidth - 2),\n \"\",\n ...paintSprite(options.color).map((line) => centerVisible(line, innerWidth - 2)),\n \"\",\n style(options.cwd, \"dim\", options.color),\n \"\",\n style(\"Tips for getting started\", \"accent\", options.color),\n \"promptpilot optimize \\\"fix this CI failure\\\" --task code --plain\",\n \"promptpilot optimize \\\"...\\\" --model promptpilot-compressor\",\n \"\",\n style(\"Help\", \"accent\", options.color),\n \"promptpilot --help\"\n ];\n\n return [\n renderTopRule(title, innerWidth, options.color),\n ...lines.map((line) => `${style(\"│\", \"accent\", options.color)} ${padVisible(line, innerWidth - 2)} ${style(\"│\", \"accent\", options.color)}`),\n `${style(\"╰\", \"accent\", options.color)}${style(\"─\".repeat(innerWidth), \"accent\", options.color)}${style(\"╯\", \"accent\", options.color)}`\n ].join(\"\\n\");\n}\n\nfunction paintSprite(color: boolean): string[] {\n const ink = color ? \"\\u001b[38;5;215m\" : \"\";\n const reset = color ? \"\\u001b[0m\" : \"\";\n\n return [\n `${ink} .-''''-.${reset}`,\n `${ink} .' .--. '.${reset}`,\n `${ink} / / oo \\\\ \\\\${reset}`,\n `${ink} | \\\\_==_/ |${reset}`,\n `${ink} | .-.__.-. |${reset}`,\n `${ink} \\\\ \\\\_/ \\\\_/ /${reset}`,\n `${ink} '._/|__|\\\\_.'${reset}`,\n `${ink} /_/ \\\\_\\\\${reset}`\n ];\n}\n\nfunction style(text: string, tone: \"accent\" | \"bold\" | \"dim\", color: boolean): string {\n if (!color) {\n return text;\n }\n\n switch (tone) {\n case \"accent\":\n return `\\u001b[38;5;215m${text}\\u001b[0m`;\n case \"bold\":\n return `\\u001b[1m${text}\\u001b[0m`;\n case \"dim\":\n return `\\u001b[38;5;245m${text}\\u001b[0m`;\n }\n}\n\nfunction renderTopRule(title: string, innerWidth: number, color: boolean): string {\n const titleWidth = visibleWidth(title);\n const leftRuleWidth = Math.min(3, Math.max(0, innerWidth - titleWidth));\n const rightRuleWidth = Math.max(0, innerWidth - titleWidth - leftRuleWidth);\n return `${style(\"╭\", \"accent\", color)}${style(\"─\".repeat(leftRuleWidth), \"accent\", color)}${style(title, \"accent\", color)}${style(\"─\".repeat(rightRuleWidth), \"accent\", color)}${style(\"╮\", \"accent\", color)}`;\n}\n\nfunction padVisible(text: string, targetWidth: number): string {\n const truncated = truncateVisible(text, targetWidth);\n const padding = Math.max(0, targetWidth - visibleWidth(truncated));\n return `${truncated}${\" \".repeat(padding)}`;\n}\n\nfunction centerVisible(text: string, targetWidth: number): string {\n const truncated = truncateVisible(text, targetWidth);\n const extra = Math.max(0, targetWidth - visibleWidth(truncated));\n const leftPadding = Math.floor(extra / 2);\n const rightPadding = extra - leftPadding;\n return `${\" \".repeat(leftPadding)}${truncated}${\" \".repeat(rightPadding)}`;\n}\n\nfunction truncateVisible(text: string, targetWidth: number): string {\n if (visibleWidth(text) <= targetWidth) {\n return text;\n }\n\n let visible = 0;\n let result = \"\";\n let inEscape = false;\n\n for (const char of text) {\n result += char;\n if (char === \"\\u001b\") {\n inEscape = true;\n continue;\n }\n if (inEscape) {\n if (char === \"m\") {\n inEscape = false;\n }\n continue;\n }\n visible += 1;\n if (visible >= Math.max(0, targetWidth - 1)) {\n break;\n }\n }\n\n return `${result}…`;\n}\n\nfunction visibleWidth(text: string): number {\n return text.replace(/\\u001b\\[[0-9;]*m/g, \"\").length;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction capitalize(value: string): string {\n if (value.length === 0) {\n return value;\n }\n return value[0].toUpperCase() + value.slice(1);\n}\n","export interface SpinnerLike {\n start(message: string): void;\n stop(): void;\n}\n\nexport class Spinner implements SpinnerLike {\n private message = \"\";\n private frame = 0;\n private interval: NodeJS.Timeout | null = null;\n private writer: { write(text: string): void };\n private isTTY: boolean;\n\n private readonly frames = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\n\n constructor(writer: { write(text: string): void }, isTTY = false) {\n this.writer = writer;\n this.isTTY = isTTY;\n }\n\n start(message: string): void {\n if (!this.isTTY) {\n return;\n }\n\n this.message = message;\n this.frame = 0;\n\n this.interval = setInterval(() => {\n const spinner = this.frames[this.frame % this.frames.length];\n this.writer.write(`\\r${spinner} ${this.message}`);\n this.frame += 1;\n }, 80);\n }\n\n stop(): void {\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = null;\n }\n\n if (this.isTTY) {\n this.writer.write(\"\\r\\x1b[K\"); // Clear the line\n }\n }\n}\n\nexport function createSpinner(\n writer: { write(text: string): void },\n isTTY = false\n): SpinnerLike {\n return new Spinner(writer, isTTY);\n}\n\nexport class NoOpSpinner implements SpinnerLike {\n start(_message: string): void {}\n stop(): void {}\n}\n"],"mappings":";;;AACA,SAAS,cAAc,oBAAoB;AAC3C,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;;;ACHlB,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAC5C,YAAY,UAAU,sCAAsC;AAC1D,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAChD,YAAY,UAAU,0DAA0D;AAC9E,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC3C,YAAY,UAAU,mCAAmC;AACvD,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EAClD,YAAY,UAAU,gFAAgF;AACpG,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;;;AC1BA,SAAS,OAAO,UAAU,IAAI,iBAAiB;AAC/C,SAAS,eAAe;AACxB,SAAS,SAAS,YAAY;;;ACAvB,SAAS,oBAAoB,OAAuB;AACzD,SAAO,MACJ,QAAQ,SAAS,IAAI,EACrB,QAAQ,aAAa,IAAI,EACzB,QAAQ,WAAW,MAAM,EACzB,KAAK;AACV;AAEO,SAAS,eAAe,QAAwB;AACrD,MAAI,OAAO,WAAW,YAAY,oBAAoB,MAAM,EAAE,WAAW,GAAG;AAC1E,UAAM,IAAI,mBAAmB;AAAA,EAC/B;AAEA,SAAO,oBAAoB,MAAM;AACnC;AAEO,SAAS,kBAAkB,WAA2B;AAC3D,SAAO,UAAU,KAAK,EAAE,QAAQ,oBAAoB,GAAG;AACzD;;;ADZO,IAAM,mBAAN,MAA+C;AAAA,EACnC;AAAA,EAEjB,YAAY,UAAU,KAAK,QAAQ,GAAG,gBAAgB,UAAU,GAAG;AACjE,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAM,YAAY,WAAyC;AACzD,UAAM,WAAW,KAAK,YAAY,SAAS;AAE3C,QAAI;AACF,YAAM,WAAW,MAAM,SAAS,UAAU,MAAM;AAChD,YAAM,SAAS,KAAK,MAAM,QAAQ;AAClC,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,OAAQ,MAAgC;AAC9C,UAAI,SAAS,UAAU;AACrB,eAAO,KAAK,mBAAmB,SAAS;AAAA,MAC1C;AAEA,YAAM,IAAI,kBAAkB,2BAA2B,SAAS,IAAI;AAAA,IACtE;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,SAAqC;AACrD,UAAM,WAAW,KAAK,YAAY,QAAQ,SAAS;AAEnD,QAAI;AACF,YAAM,MAAM,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD,YAAM,UAAU,UAAU,KAAK,UAAU,SAAS,MAAM,CAAC,GAAG,MAAM;AAAA,IACpE,QAAQ;AACN,YAAM,IAAI,kBAAkB,2BAA2B,QAAQ,SAAS,IAAI;AAAA,IAC9E;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,WAAkC;AACnD,UAAM,WAAW,KAAK,YAAY,SAAS;AAE3C,QAAI;AACF,YAAM,GAAG,UAAU,EAAE,OAAO,KAAK,CAAC;AAAA,IACpC,QAAQ;AACN,YAAM,IAAI,kBAAkB,4BAA4B,SAAS,IAAI;AAAA,IACvE;AAAA,EACF;AAAA,EAEQ,YAAY,WAA2B;AAC7C,WAAO,KAAK,KAAK,SAAS,GAAG,kBAAkB,SAAS,CAAC,OAAO;AAAA,EAClE;AAAA,EAEQ,mBAAmB,WAAgC;AACzD,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,WAAO;AAAA,MACL;AAAA,MACA,SAAS,CAAC;AAAA,MACV,WAAW,CAAC;AAAA,MACZ,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAAA,EACF;AACF;;;AEnEA,SAAS,WAAAA,UAAS,QAAAC,aAAY;AAC9B,SAAS,SAAAC,cAAa;AAaf,IAAM,qBAAN,MAAiD;AAAA,EAGtD,YAA6B,SAASC,MAAK,QAAQ,IAAI,GAAG,gBAAgB,gBAAgB,GAAG;AAAhE;AAC3B,SAAK,YAAY,KAAK,aAAa;AAAA,EACrC;AAAA,EAF6B;AAAA,EAFrB;AAAA,EAMR,MAAM,YAAY,WAAyC;AACzD,UAAM,KAAK,MAAM,KAAK;AACtB,UAAM,MAAM,GAAG,QAAQ,wCAAwC,EAAE,IAAI,SAAS;AAC9E,QAAI,CAAC,KAAK,MAAM;AACd,aAAO,mBAAmB,SAAS;AAAA,IACrC;AAEA,WAAO,KAAK,MAAM,IAAI,IAAI;AAAA,EAC5B;AAAA,EAEA,MAAM,YAAY,SAAqC;AACrD,UAAM,KAAK,MAAM,KAAK;AACtB,OAAG,QAAQ,0DAA0D,EAAE;AAAA,MACrE,QAAQ;AAAA,MACR,KAAK,UAAU,OAAO;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,WAAkC;AACnD,UAAM,KAAK,MAAM,KAAK;AACtB,OAAG,QAAQ,mCAAmC,EAAE,IAAI,SAAS;AAAA,EAC/D;AAAA,EAEA,MAAc,eAAyC;AACrD,QAAI;AACF,YAAMC,OAAMC,SAAQ,KAAK,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AACrD,YAAM,iBAAiB;AACvB,YAAM,aAAa,MAAM,OAAO,gBAAgB,MAAM,MAAM,IAAI;AAEhE,UAAI,YAAY,cAAc;AAC5B,cAAM,KAAK,IAAI,WAAW,aAAa,KAAK,MAAM;AAClD,WAAG,KAAK,+EAA+E;AACvF,eAAO;AAAA,MACT;AAEA,YAAM,mBAAmB;AACzB,YAAM,eAAe,MAAM,OAAO,kBAAkB,MAAM,MAAM,IAAI;AACpE,UAAI,cAAc,SAAS;AACzB,cAAM,KAAK,IAAI,aAAa,QAAQ,KAAK,MAAM;AAC/C,WAAG,KAAK,+EAA+E;AACvF,eAAO;AAAA,MACT;AAEA,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,mBAAmB;AACtC,cAAM;AAAA,MACR;AAEA,YAAM,IAAI,kBAAkB,4CAA4C;AAAA,IAC1E;AAAA,EACF;AACF;AAEA,SAAS,mBAAmB,WAAgC;AAC1D,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAO;AAAA,IACL;AAAA,IACA,SAAS,CAAC;AAAA,IACV,WAAW,CAAC;AAAA,IACZ,WAAW;AAAA,IACX,WAAW;AAAA,EACb;AACF;;;ACpFO,IAAM,aAAqB;AAAA,EAChC,OAAO,MAAM;AAAA,EACb,MAAM,MAAM;AAAA,EACZ,MAAM,MAAM;AAAA,EACZ,OAAO,MAAM;AACf;AAEO,SAAS,aAAa,eAAe,OAAe;AACzD,SAAO;AAAA,IACL,MAAM,SAAS,MAAM;AACnB,UAAI,cAAc;AAChB,gBAAQ,MAAM,iBAAiB,OAAO,IAAI,QAAQ,EAAE;AAAA,MACtD;AAAA,IACF;AAAA,IACA,KAAK,SAAS,MAAM;AAClB,UAAI,cAAc;AAChB,gBAAQ,KAAK,iBAAiB,OAAO,IAAI,QAAQ,EAAE;AAAA,MACrD;AAAA,IACF;AAAA,IACA,KAAK,SAAS,MAAM;AAClB,UAAI,cAAc;AAChB,gBAAQ,KAAK,iBAAiB,OAAO,IAAI,QAAQ,EAAE;AAAA,MACrD;AAAA,IACF;AAAA,IACA,MAAM,SAAS,MAAM;AACnB,UAAI,cAAc;AAChB,gBAAQ,MAAM,iBAAiB,OAAO,IAAI,QAAQ,EAAE;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AACF;;;AChCO,SAAS,cAAiB,OAAyB;AACxD,MAAI;AACF,WAAO,KAAK,MAAM,KAAK;AAAA,EACzB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,uBAAuB,OAA8B;AACnE,QAAM,QAAQ,MAAM,QAAQ,GAAG;AAC/B,MAAI,UAAU,IAAI;AAChB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ;AACZ,MAAI,WAAW;AACf,MAAI,UAAU;AAEd,WAAS,QAAQ,OAAO,QAAQ,MAAM,QAAQ,SAAS,GAAG;AACxD,UAAM,OAAO,MAAM,KAAK;AAExB,QAAI,SAAS;AACX,gBAAU;AACV;AAAA,IACF;AAEA,QAAI,SAAS,MAAM;AACjB,gBAAU;AACV;AAAA,IACF;AAEA,QAAI,SAAS,KAAM;AACjB,iBAAW,CAAC;AACZ;AAAA,IACF;AAEA,QAAI,UAAU;AACZ;AAAA,IACF;AAEA,QAAI,SAAS,KAAK;AAChB,eAAS;AAAA,IACX,WAAW,SAAS,KAAK;AACvB,eAAS;AACT,UAAI,UAAU,GAAG;AACf,eAAO,MAAM,MAAM,OAAO,QAAQ,CAAC;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,aAAa,OAAwB;AACnD,SAAO,KAAK,UAAU,OAAO,MAAM,CAAC;AACtC;;;AC1CO,IAAM,eAAN,MAA+C;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAA6B,CAAC,GAAG;AAC3C,SAAK,OAAO,OAAO,QAAQ;AAC3B,SAAK,QAAQ,OAAO,SAAS;AAC7B,SAAK,YAAY,OAAO,aAAa;AACrC,SAAK,cAAc,OAAO,eAAe;AACzC,SAAK,SAAS,OAAO,UAAU;AAAA,EACjC;AAAA,EAEA,MAAM,cAAgC;AACpC,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,IAAI,IAAI,aAAa,KAAK,IAAI,GAAG;AAAA,QAC5D,QAAQ;AAAA,MACV,CAAC;AAED,aAAO,SAAS;AAAA,IAClB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,aAAyC;AAC7C,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,IAAI,IAAI,aAAa,KAAK,IAAI,GAAG;AAAA,QAC5D,QAAQ;AAAA,MACV,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,uBAAuB,0CAA0C,SAAS,MAAM,GAAG;AAAA,MAC/F;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAYlC,cAAQ,KAAK,UAAU,CAAC,GACrB,OAAO,CAAC,UAAU,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,SAAS,CAAC,EACzE,IAAI,CAAC,WAAW;AAAA,QACf,MAAM,MAAM;AAAA,QACZ,WAAW,MAAM;AAAA,QACjB,QAAQ,MAAM,SAAS;AAAA,QACvB,eAAe,MAAM,SAAS;AAAA,QAC9B,YAAY,MAAM;AAAA,MACpB,EAAE;AAAA,IACN,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAK,OAAO,KAAK,6BAA6B,EAAE,QAAQ,CAAC;AACzD,YAAM,IAAI,uBAAuB,OAAO;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,SAAiD;AAC9D,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,QAAQ,aAAa,KAAK,SAAS;AAExF,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,IAAI,IAAI,iBAAiB,KAAK,IAAI,GAAG;AAAA,QAChE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,OAAO,QAAQ,SAAS,KAAK;AAAA,UAC7B,QAAQ,QAAQ;AAAA,UAChB,QAAQ,QAAQ;AAAA,UAChB,QAAQ;AAAA,UACR,QAAQ,QAAQ,WAAW,SAAS,SAAS;AAAA,UAC7C,SAAS;AAAA,YACP,aAAa,QAAQ,eAAe,KAAK;AAAA,UAC3C;AAAA,QACF,CAAC;AAAA,QACD,QAAQ,WAAW;AAAA,MACrB,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,uBAAuB,qCAAqC,SAAS,MAAM,GAAG;AAAA,MAC1F;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,UAAI,CAAC,KAAK,YAAY,OAAO,KAAK,aAAa,UAAU;AACvD,cAAM,IAAI,uBAAuB,wCAAwC;AAAA,MAC3E;AAEA,aAAO,KAAK,SAAS,KAAK;AAAA,IAC5B,SAAS,OAAO;AACd,UAAI,iBAAiB,wBAAwB;AAC3C,cAAM;AAAA,MACR;AAEA,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAK,OAAO,KAAK,0BAA0B,EAAE,QAAQ,CAAC;AACtD,YAAM,IAAI,uBAAuB,OAAO;AAAA,IAC1C,UAAE;AACA,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,aAAgB,SAA4C;AAChE,UAAM,MAAM,MAAM,KAAK,SAAS;AAAA,MAC9B,GAAG;AAAA,MACH,QAAQ;AAAA,IACV,CAAC;AAED,UAAM,SAAS,cAAiB,GAAG;AACnC,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,uBAAuB,GAAG;AAC5C,QAAI,WAAW;AACb,YAAM,SAAS,cAAiB,SAAS;AACzC,UAAI,QAAQ;AACV,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,IAAI,uBAAuB,gDAAgD;AAAA,EACnF;AAAA,EAEA,MAAM,6BAAgC,SAAgC,qBAAsD;AAC1H,QAAI;AACF,aAAO,MAAM,KAAK,aAAgB,OAAO;AAAA,IAC3C,QAAQ;AAEN,YAAM,MAAM,MAAM,KAAK,SAAS;AAAA,QAC9B,GAAG;AAAA,QACH,QAAQ;AAAA,MACV,CAAC;AACD,aAAO,oBAAoB,GAAG;AAAA,IAChC;AAAA,EACF;AACF;;;AC5JA,IAAM,eAAiD;AAAA,EACrD,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,YAAY;AACd;AAEA,IAAM,iBAA+C;AAAA,EACnD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AAAA,EACT,eAAe;AAAA,EACf,MAAM;AACR;AAEO,SAAS,4BAA4B,MAAwB,QAA+B;AACjG,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB,aAAa,IAAI,CAAC;AAAA,IACpC,SAAS,oBAAoB,eAAe,MAAM,CAAC,KAAK;AAAA,EAC1D,EAAE,KAAK,IAAI;AACb;AAEO,SAAS,wBACd,OACA,iBACA,sBACQ;AACR,QAAM,UAAU;AAAA,IACd,QAAQ,MAAM;AAAA,IACd,MAAM,MAAM,QAAQ;AAAA,IACpB,MAAM,MAAM,QAAQ;AAAA,IACpB,aAAa,MAAM,eAAe;AAAA,IAClC,cAAc,MAAM,gBAAgB;AAAA,IACpC,WAAW,MAAM,aAAa;AAAA,IAC9B,MAAM,MAAM,QAAQ;AAAA,IACpB,QAAQ,MAAM,UAAU;AAAA,IACxB,mBAAmB,MAAM,qBAAqB,CAAC;AAAA,IAC/C;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AAAA,EAAuD,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAChG;;;AC1DO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,aAAa,MAAsB;AACjC,UAAM,aAAa,oBAAoB,IAAI;AAC3C,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,WAAW,MAAM,KAAK,EAAE;AAC1C,UAAM,YAAY,WAAW;AAC7B,WAAO,KAAK,IAAI,GAAG,KAAK,KAAK,YAAY,GAAG,GAAG,KAAK,KAAK,YAAY,CAAC,CAAC;AAAA,EACzE;AAAA,EAEA,cAAc,OAAiE;AAC7E,UAAM,SAAS,KAAK,aAAa,MAAM,MAAM;AAC7C,UAAM,UAAU,KAAK,aAAa,MAAM,WAAW,EAAE;AACrD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,OAAO,SAAS;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,iBAAiB,MAAc,aAA6B;AAC1D,UAAM,aAAa,oBAAoB,IAAI;AAC3C,QAAI,eAAe,KAAK,CAAC,YAAY;AACnC,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,aAAa,UAAU,KAAK,aAAa;AAChD,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,WAAW,MAAM,KAAK;AACpC,UAAM,WAAqB,CAAC;AAE5B,eAAW,QAAQ,OAAO;AACxB,YAAM,YAAY,CAAC,GAAG,UAAU,IAAI,EAAE,KAAK,GAAG;AAC9C,UAAI,KAAK,aAAa,SAAS,IAAI,aAAa;AAC9C;AAAA,MACF;AAEA,eAAS,KAAK,IAAI;AAAA,IACpB;AAEA,WAAO,SAAS,KAAK,GAAG,EAAE,KAAK;AAAA,EACjC;AACF;;;ACjDA,SAAS,kBAAkB;AAsBpB,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YACmB,WACA,QACA,SAAiB,YAClC;AAHiB;AACA;AACA;AAAA,EAChB;AAAA,EAHgB;AAAA,EACA;AAAA,EACA;AAAA,EAGnB,MAAM,iBAAiB,SAAkE;AACvF,QAAI,QAAQ,QAAQ,WAAW,KAAK,QAAQ,gBAAgB,GAAG;AAC7D,aAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,MAAM,KAAK,iBAAiB,OAAO;AACzD,QAAI,eAAe;AACjB,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,iBAAiB,OAAO;AAAA,EACtC;AAAA,EAEA,MAAc,iBAAiB,SAAkE;AAC/F,QAAI,CAAC,KAAK,UAAU,QAAQ,QAAQ,SAAS,GAAG;AAC9C,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,SAAS,QAAQ,QACpB,MAAM,EAAE,EACR,IAAI,CAAC,UAAU;AAAA,QACd,cAAc,MAAM,SAAS;AAAA,QAC7B,MAAM,OAAO,SAAS,MAAM,IAAI,KAAK;AAAA,QACrC,MAAM,aAAa,SAAS,gBAAgB,MAAM,YAAY,KAAK,IAAI,CAAC,KAAK;AAAA,QAC7E,WAAW,MAAM,aAAa,MAAM,IAAI;AAAA,MAC1C,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,CAAC,EAC3B,KAAK,MAAM;AAEd,YAAM,WAAW,MAAM,KAAK,OAAO,aAAiC;AAAA,QAClE,cAAc,4BAA4B,UAAU;AAAA,QACpD,QAAQ;AAAA,UAA2E,QAAQ,MAAM;AAAA,QAAW,QAAQ,QAAQ,SAAS;AAAA,iBAAoB,QAAQ,YAAY;AAAA;AAAA,EAAO,MAAM;AAAA,QAC1L,WAAW,QAAQ;AAAA,QACnB,QAAQ;AAAA,MACV,CAAC;AAED,YAAM,cAAc,KAAK,UAAU,iBAAiB,SAAS,mBAAmB,IAAI,QAAQ,YAAY;AACxG,UAAI,CAAC,aAAa;AAChB,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,QACL,IAAI,WAAW;AAAA,QACf,WAAW,QAAQ;AAAA,QACnB,MAAM;AAAA,QACN,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAClC,gBAAgB,QAAQ,QAAQ,IAAI,CAAC,UAAU,MAAM,EAAE;AAAA,QACvD,eAAe,KAAK,UAAU,aAAa,WAAW;AAAA,QACtD,MAAM;AAAA,MACR;AAAA,IACF,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAK,OAAO,MAAM,mCAAmC,EAAE,QAAQ,CAAC;AAChE,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,iBAAiB,SAAkD;AACzE,UAAM,cAAc,MAAM;AAAA,MACxB,IAAI,IAAI,QAAQ,QAAQ,QAAQ,CAAC,UAAU,MAAM,eAAe,CAAC,CAAC,EAAE,OAAO,OAAO,CAAC;AAAA,IACrF,EAAE,MAAM,GAAG,CAAC;AAEZ,UAAM,gBAAgB,QAAQ,QAC3B,MAAM,EAAE,EACR,IAAI,CAAC,UAAU,KAAK,aAAa,MAAM,aAAa,MAAM,MAAM,GAAG,CAAC,EAAE;AAEzE,UAAM,QAAQ;AAAA,MACZ,YAAY,SAAS,oBAAoB,YAAY,KAAK,IAAI,CAAC,KAAK;AAAA,MACpE,cAAc,SAAS;AAAA,EAAkB,cAAc,KAAK,IAAI,CAAC,KAAK;AAAA,IACxE,EAAE,OAAO,OAAO;AAEhB,UAAM,cAAc,KAAK,UAAU,iBAAiB,MAAM,KAAK,MAAM,GAAG,QAAQ,YAAY;AAE5F,WAAO;AAAA,MACL,IAAI,WAAW;AAAA,MACf,WAAW,QAAQ;AAAA,MACnB,MAAM;AAAA,MACN,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,gBAAgB,QAAQ,QAAQ,IAAI,CAAC,UAAU,MAAM,EAAE;AAAA,MACvD,eAAe,KAAK,UAAU,aAAa,WAAW;AAAA,MACtD,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,aAAa,OAAe,WAA2B;AAC9D,MAAI,MAAM,UAAU,WAAW;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,KAAK,CAAC;AAChD;;;ACxHA,SAAS,cAAAC,mBAAkB;AAgCpB,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YACmB,OACA,WACA,YACA,SAAiB,YAClC;AAJiB;AACA;AACA;AACA;AAAA,EAChB;AAAA,EAJgB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAGnB,MAAM,YAAY,WAAmB;AACnC,WAAO,KAAK,MAAM,YAAY,SAAS;AAAA,EACzC;AAAA,EAEA,MAAM,aAAa,WAAkC;AACnD,UAAM,KAAK,MAAM,aAAa,SAAS;AAAA,EACzC;AAAA,EAEA,MAAM,YAAY,SAA4C;AAC5D,UAAM,UAAU,MAAM,KAAK,MAAM,YAAY,QAAQ,SAAS;AAC9D,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,UAAM,cAAc,MAAM;AAAA,MACxB,oBAAI,IAAI;AAAA,QACN,GAAG,mBAAmB,QAAQ,MAAM,MAAM;AAAA,QAC1C,GAAI,QAAQ,MAAM,qBAAqB,CAAC;AAAA,MAC1C,CAAC;AAAA,IACH;AACA,UAAM,QAAsB;AAAA,MAC1B,IAAIC,YAAW;AAAA,MACf,WAAW,QAAQ;AAAA,MACnB,MAAM,QAAQ;AAAA,MACd,WAAW,QAAQ,MAAM;AAAA,MACzB,iBAAiB,QAAQ;AAAA,MACzB,aAAa,QAAQ;AAAA,MACrB,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,QAAQ,MAAM;AAAA,MACpB,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,MAC7B;AAAA,MACA,UAAU,gBAAgB,QAAQ,MAAM,MAAM;AAAA,MAC9C,SAAS,QAAQ,MAAM,mBAAmB,UAAU,KAAK;AAAA,MACzD;AAAA,MACA,eAAe,KAAK,UAAU,aAAa,QAAQ,WAAW;AAAA,IAChE;AAEA,YAAQ,QAAQ,KAAK,KAAK;AAC1B,QAAI,QAAQ,QAAQ,SAAS,KAAK;AAChC,cAAQ,UAAU,QAAQ,QAAQ,MAAM,IAAI;AAAA,IAC9C;AAEA,QAAI,QAAQ,gBAAgB;AAC1B,cAAQ,UAAU,KAAK,QAAQ,cAAc;AAC7C,UAAI,QAAQ,UAAU,SAAS,IAAI;AACjC,gBAAQ,YAAY,QAAQ,UAAU,MAAM,GAAG;AAAA,MACjD;AAAA,IACF;AAEA,YAAQ,YAAY;AACpB,UAAM,KAAK,MAAM,YAAY,OAAO;AACpC,SAAK,OAAO,MAAM,iBAAiB;AAAA,MACjC,WAAW,QAAQ;AAAA,MACnB,YAAY,QAAQ,QAAQ;AAAA,MAC5B,cAAc,QAAQ,UAAU;AAAA,IAClC,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,iBACJ,WACA,QACA,MACA,cACA,WACgC;AAChC,UAAM,UAAU,MAAM,KAAK,MAAM,YAAY,SAAS;AACtD,QAAI,QAAQ,QAAQ,WAAW,GAAG;AAChC,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,WAAW,iBAAiB;AAAA,MACtC;AAAA,MACA,SAAS,QAAQ;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,mBAAmB,SAAoE;AAC3F,UAAM,UAAU,MAAM,KAAK,MAAM,YAAY,QAAQ,SAAS;AAC9D,QAAI,QAAQ,QAAQ,WAAW,KAAK,QAAQ,UAAU,WAAW,GAAG;AAClE,aAAO;AAAA,QACL,aAAa,CAAC;AAAA,QACd,SAAS;AAAA,QACT,UAAU,CAAC;AAAA,QACX,WAAW,EAAE,QAAQ,CAAC,EAAE;AAAA,MAC1B;AAAA,IACF;AAEA,UAAM,SAAS,QAAQ,QAAQ,IAAI,CAAC,OAAO,WAAW;AAAA,MACpD;AAAA,MACA,OAAO,WAAW;AAAA,QAChB;AAAA,QACA,QAAQ,QAAQ;AAAA,QAChB,MAAM,QAAQ;AAAA,QACd,MAAM,QAAQ;AAAA,QACd,mBAAmB,QAAQ;AAAA,QAC3B;AAAA,QACA,OAAO,QAAQ,QAAQ;AAAA,MACzB,CAAC;AAAA,IACH,EAAE;AAEF,UAAM,WAA2B,CAAC;AAClC,UAAM,mBAAmB,oBAAI,IAAY;AACzC,QAAI,iBAAiB;AAErB,eAAW,UAAU,OAAO,KAAK,CAAC,MAAM,UAAU,MAAM,QAAQ,KAAK,KAAK,GAAG;AAC3E,UAAI,SAAS,KAAK,CAAC,UAAU,MAAM,OAAO,OAAO,MAAM,EAAE,GAAG;AAC1D;AAAA,MACF;AAEA,YAAM,cAAc,kBAAkB,OAAO,KAAK;AAClD,UAAI,iBAAiB,IAAI,WAAW,GAAG;AACrC;AAAA,MACF;AAEA,UAAI,iBAAiB,OAAO,MAAM,gBAAgB,QAAQ,kBAAkB;AAC1E;AAAA,MACF;AAEA,eAAS,KAAK,OAAO,KAAK;AAC1B,uBAAiB,IAAI,WAAW;AAChC,wBAAkB,OAAO,MAAM;AAAA,IACjC;AAEA,UAAM,YAAY,QAAQ,QAAQ;AAAA,MAChC,CAAC,UAAU,CAAC,SAAS,KAAK,CAAC,kBAAkB,cAAc,OAAO,MAAM,EAAE;AAAA,IAC5E;AAEA,QAAI,UAAiC;AACrC,QAAI,UAAU,SAAS,KAAK,iBAAiB,KAAK,MAAM,QAAQ,mBAAmB,GAAG,GAAG;AACvF,gBAAU,MAAM,KAAK,WAAW,iBAAiB;AAAA,QAC/C,WAAW,QAAQ;AAAA,QACnB,SAAS;AAAA,QACT,QAAQ,QAAQ;AAAA,QAChB,MAAM,QAAQ;AAAA,QACd,cAAc,KAAK,IAAI,IAAI,QAAQ,mBAAmB,cAAc;AAAA,QACpE,WAAW,QAAQ;AAAA,MACrB,CAAC;AAAA,IACH,WAAW,QAAQ,UAAU,SAAS,GAAG;AACvC,YAAM,SAAS,QAAQ,UAAU,GAAG,EAAE,KAAK;AAC3C,UAAI,UAAU,OAAO,iBAAiB,QAAQ,mBAAmB,gBAAgB;AAC/E,kBAAU;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,WAAqB,CAAC;AAC5B,QAAI,UAAU,SAAS,GAAG;AACxB,eAAS,KAAK,WAAW,UAAU,MAAM,uDAAuD;AAAA,IAClG;AAEA,WAAO;AAAA,MACL,aAAa,SAAS,KAAK,CAAC,MAAM,UAAU,KAAK,UAAU,cAAc,MAAM,SAAS,CAAC;AAAA,MACzF;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT,QAAQ,OACL,KAAK,CAAC,MAAM,UAAU,MAAM,QAAQ,KAAK,KAAK,EAC9C,IAAI,CAAC,EAAE,OAAO,MAAM,OAAO,EAAE,IAAI,MAAM,IAAI,OAAO,MAAM,MAAM,MAAM,WAAW,MAAM,UAAU,EAAE;AAAA,MACtG;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,WAAW,OAQT;AACT,QAAM,cAAc,SAAS,MAAM,MAAM;AACzC,QAAM,iBAAiB,IAAI,IAAI,gBAAgB,MAAM,MAAM,EAAE,IAAI,CAAC,WAAW,OAAO,YAAY,CAAC,CAAC;AAClG,QAAM,aAAa;AAAA,IACjB,CAAC,MAAM,MAAM,WAAW,MAAM,MAAM,iBAAiB,MAAM,MAAM,aAAa,KAAK,GAAG,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,EACnH;AACA,QAAM,gBAAgB,IAAI,KAAK,MAAM,MAAM,YAAY,CAAC,GAAG,IAAI,CAAC,WAAW,OAAO,YAAY,CAAC,CAAC;AAEhG,QAAM,UAAU,MAAM,KAAK,WAAW,EAAE,OAAO,CAAC,SAAS,WAAW,IAAI,IAAI,CAAC,EAAE;AAC/E,QAAM,gBAAgB,MAAM,KAAK,cAAc,EAAE,OAAO,CAAC,WAAW,cAAc,IAAI,MAAM,CAAC,EAAE;AAC/F,QAAM,YAAY,MAAM,QAAQ,MAAM,MAAM,SAAS,MAAM,OAAO,IAAI;AACtE,QAAM,SAAS,MAAM,MAAM,SAAS,IAAI;AACxC,QAAM,wBAAwB,MAAM,KAAK,IAAI,IAAI,MAAM,qBAAqB,CAAC,CAAC,CAAC,EAAE;AAAA,IAAO,CAAC,gBACtF,MAAM,MAAM,eAAe,CAAC,GAAG,SAAS,UAAU;AAAA,EACrD,EAAE;AACF,QAAM,aAAa,MAAM,KAAK,IAAI,IAAI,MAAM,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,MAAM,MAAM,QAAQ,CAAC,GAAG,SAAS,GAAG,CAAC,EAAE;AACjH,QAAM,mBAAmB,MAAM,MAAM,aAAa,UAAU,KAAK,IAAI,OAAO;AAC5E,QAAM,WAAW,MAAM,QAAQ,KAAK,MAAM;AAE1C,SAAO,UAAU,MAAM,gBAAgB,MAAM,YAAY,SAAS,wBAAwB,IAAI,aAAa,kBAAkB;AAC/H;AAEA,SAAS,SAAS,OAA4B;AAC5C,SAAO,IAAI;AAAA,IACT,MACG,YAAY,EACZ,MAAM,aAAa,EACnB,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AAAA,EACvC;AACF;AAEO,SAAS,mBAAmB,OAAyB;AAC1D,SAAO,MAAM;AAAA,IACX,IAAI;AAAA,MACF,MACG,MAAM,KAAK,EACX,QAAQ,CAAC,SAAS,KAAK,MAAM,eAAe,CAAC,EAC7C,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE,QAAQ,YAAY,EAAE,CAAC,EACjD,OAAO,CAAC,SAAS,KAAK,SAAS,KAAK,KAAK,UAAU,GAAG,EACtD,OAAO,CAAC,SAAS,wFAAwF,KAAK,IAAI,CAAC;AAAA,IACxH;AAAA,EACF,EAAE,MAAM,GAAG,CAAC;AACd;AAEO,SAAS,gBAAgB,OAAyB;AACvD,SAAO,MAAM;AAAA,IACX,IAAI,IAAI,MAAM,MAAM,2BAA2B,KAAK,CAAC,CAAC;AAAA,EACxD,EAAE,MAAM,GAAG,EAAE;AACf;AAEA,SAAS,kBAAkB,OAA6B;AACtD,SAAO,CAAC,MAAM,QAAQ,IAAI,MAAM,aAAa,MAAM,IAAI,EACpD,KAAK,IAAI,EACT,YAAY,EACZ,QAAQ,QAAQ,GAAG,EACnB,KAAK;AACV;;;ACzQA,IAAM,kCAAkC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAgBO,SAAS,4BAAsC;AACpD,SAAO,CAAC,GAAG,+BAA+B;AAC5C;AAEO,SAAS,sBAAsB,iBAAuD;AAC3F,SAAO,gBAAgB,OAAO,CAAC,UAAU,qBAAqB,KAAK,CAAC;AACtE;AAEO,SAAS,mBACd,iBACA,qBACe;AACf,MAAI,qBAAqB;AACvB,UAAM,QAAQ,gBAAgB,KAAK,CAAC,UAAU,MAAM,SAAS,mBAAmB;AAChF,WAAO,OAAO,QAAQ;AAAA,EACxB;AAEA,QAAM,cAAc,sBAAsB,eAAe,EACtD,OAAO,CAAC,UAAU,QAAQ,KAAK,MAAM,IAAI,CAAC,EAC1C,KAAK,CAAC,MAAM,UAAU,iBAAiB,KAAK,IAAI,iBAAiB,IAAI,CAAC;AAEzE,SAAO,YAAY,CAAC,GAAG,QAAQ;AACjC;AAEO,SAAS,kBAAkB,OAAkD;AAClF,QAAM,kBAAkB,sBAAsB,MAAM,eAAe;AACnE,MAAI,gBAAgB,WAAW,GAAG;AAChC,WAAO;AAAA,MACL,OAAO,gBAAgB,CAAC,EAAE;AAAA,MAC1B,QAAQ,6BAA6B,gBAAgB,CAAC,EAAE,IAAI;AAAA,MAC5D,oBAAoB;AAAA,IACtB;AAAA,EACF;AAEA,MAAI,gBAAgB,SAAS,GAAG;AAC9B,WAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ,uDAAuD,gBAAgB,IAAI,CAAC,UAAU,MAAM,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,MACpH,oBAAoB;AAAA,IACtB;AAAA,EACF;AAEA,QAAM,kBAAkB,CAAC,GAAG,MAAM,eAAe,EAC9C,OAAO,CAAC,UAAU,wBAAwB,MAAM,IAAI,CAAC,EACrD,KAAK,CAAC,MAAM,UAAU,kBAAkB,KAAK,MAAM,MAAM,IAAI,CAAC;AAEjE,MAAI,gBAAgB,CAAC,GAAG;AACtB,WAAO;AAAA,MACL,OAAO,gBAAgB,CAAC,EAAE;AAAA,MAC1B,QAAQ,oBAAoB,gBAAgB,CAAC,EAAE,IAAI;AAAA,MACnD,oBAAoB;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,oBAAoB;AAAA,EACtB;AACF;AAEA,SAAS,gBAAgB,WAAkC;AACzD,QAAM,QAAQ,UAAU,MAAM,kBAAkB;AAChD,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,WAAW,MAAM,CAAC,CAAC;AACnC;AAEA,SAAS,wBAAwB,WAA4B;AAC3D,QAAM,QAAQ,UAAU,YAAY;AACpC,SAAO,CAAC;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,CAAC,YAAY,MAAM,SAAS,OAAO,CAAC;AAC7C;AAEA,SAAS,qBAAqB,OAAiC;AAC7D,MAAI,CAAC,wBAAwB,MAAM,IAAI,GAAG;AACxC,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,gBAAgB,GAAG,MAAM,iBAAiB,EAAE,IAAI,MAAM,IAAI,EAAE;AAChF,MAAI,gBAAgB,MAAM;AACxB,WAAO,eAAe;AAAA,EACxB;AAEA,MAAI,OAAO,MAAM,cAAc,UAAU;AACvC,WAAO,MAAM,aAAa;AAAA,EAC5B;AAEA,SAAO,uBAAuB,KAAK,MAAM,IAAI;AAC/C;AAEA,SAAS,iBAAiB,OAAgC;AACxD,QAAM,QAAQ,MAAM,KAAK,YAAY;AACrC,MAAI,QAAQ;AACZ,MAAI,MAAM,SAAS,SAAS,GAAG;AAC7B,aAAS;AAAA,EACX;AACA,MAAI,MAAM,SAAS,IAAI,GAAG;AACxB,aAAS;AAAA,EACX,WAAW,MAAM,SAAS,MAAM,GAAG;AACjC,aAAS;AAAA,EACX;AACA,MAAI,MAAM,SAAS,OAAO,GAAG;AAC3B,aAAS;AAAA,EACX;AACA,SAAO;AACT;AAEA,SAAS,kBAAkB,MAAc,OAAuB;AAC9D,SAAO,KAAK,cAAc,KAAK;AACjC;;;AC5FA,IAAM,eAAiC;AACvC,IAAM,iBAA+B;AACrC,IAAM,mBAAiC;AACvC,IAAM,2BAA2B;AACjC,IAAM,6BAA6B;AACnC,IAAM,2BAA2B;AACjC,IAAM,2BAA4C;AAClD,IAAM,wBAAwB;AAC9B,IAAM,wBAAsC;AAErC,IAAM,kBAAN,MAAsB;AAAA,EAClB;AAAA,EAQQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAA0B,CAAC,GAAG;AACxC,SAAK,SAAS,OAAO,UAAU;AAC/B,SAAK,YAAY,IAAI,eAAe;AACpC,SAAK,SACH,OAAO,gBACP,IAAI,aAAa;AAAA,MACf,MAAM,OAAO;AAAA,MACb,OAAO,OAAO;AAAA,MACd,WAAW,OAAO;AAAA,MAClB,aAAa,OAAO;AAAA,MACpB,QAAQ,KAAK;AAAA,IACf,CAAC;AAEH,UAAM,QAAQ,oBAAoB,MAAM;AACxC,SAAK,aAAa,IAAI,kBAAkB,KAAK,WAAW,KAAK,QAAQ,KAAK,MAAM;AAChF,SAAK,iBAAiB,IAAI,eAAe,OAAO,KAAK,WAAW,KAAK,YAAY,KAAK,MAAM;AAE5F,SAAK,SAAS;AAAA,MACZ,GAAG;AAAA,MACH,MAAM,OAAO,QAAQ;AAAA,MACrB,aAAa,OAAO;AAAA,MACpB,iBAAiB,OAAO,mBAAmB,0BAA0B;AAAA,MACrE,sBAAsB;AAAA,MACtB,WAAW,OAAO,aAAa;AAAA,MAC/B,aAAa,OAAO,eAAe;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,OAA2D;AACxE,UAAM,iBAAiB,eAAe,MAAM,MAAM;AAClD,UAAM,OAAO,MAAM,QAAQ,KAAK,OAAO,eAAe;AACtD,UAAM,SAAS,MAAM,UAAU,KAAK,OAAO,iBAAiB;AAC5D,UAAM,iBAAiB,MAAM,kBAAkB,KAAK,OAAO,kBAAkB;AAC7E,UAAM,mBAAmB,MAAM,oBAAoB,KAAK,OAAO,oBAAoB;AACnF,UAAM,iBAAiB,MAAM,kBAAkB,KAAK,OAAO,kBAAkB;AAC7E,UAAM,iBAAiB,MAAM,mBAAmB;AAChD,UAAM,kBAAkB,MAAM,mBAAmB;AACjD,UAAM,cAAc,MAAM,eAAe;AACzC,UAAM,eAAe,MAAM,gBAAgB;AAC3C,UAAM,WAAqB,CAAC;AAC5B,UAAM,UAAoB,CAAC;AAE3B,UAAM,aAAa,MAAM,eAAe,SAAS,QAAQ,MAAM,SAAS;AACxE,UAAM,cAAc,MAAM,eAAe,QAAQ,MAAM,SAAS;AAChE,UAAM,kBAAkB,cAAc,MAAM,YACxC,MAAM,KAAK,eAAe,mBAAmB;AAAA,MAC3C,WAAW,MAAM;AAAA,MACjB,QAAQ;AAAA,MACR,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,mBAAmB,MAAM;AAAA,MACzB;AAAA,MACA,WAAW,MAAM,aAAa,KAAK,OAAO;AAAA,IAC5C,CAAC,IACD,qBAAqB;AAEzB,aAAS,KAAK,GAAG,gBAAgB,QAAQ;AAEzC,UAAM,eAAe,mBAAmB,eAAe;AACvD,UAAM,wBAAwB,KAAK,UAAU,cAAc;AAAA,MACzD,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAED,QAAI,sBAAsB,SAAS,gBAAgB;AACjD,eAAS;AAAA,QACP,wBAAwB,sBAAsB,MAAM,6BAA6B,cAAc;AAAA,MACjG;AAAA,IACF;AAEA,UAAM,uBAAuB,MAAM;AAAA,MACjC,oBAAI,IAAI,CAAC,GAAG,mBAAmB,cAAc,GAAG,GAAI,MAAM,qBAAqB,CAAC,CAAE,CAAC;AAAA,IACrF;AAEA,QAAI,WAAyB,MAAM,qBAAqB,cAAc,KAAK,OAAO,YAAY;AAC9F,QAAI,QAAQ,aAAa,WAAW,KAAK,OAAO,eAAe,SAAS;AACxE,QAAI,2BAA2B;AAE/B,QAAI,kBAAkB;AACtB,QAAI,mBAA6B,CAAC;AAClC,QAAI,kBAA4B,CAAC;AAEjC,QAAI,aAAa,UAAU;AACzB,YAAM,iBAAiB,MAAM,KAAK,mBAAmB;AAAA,QACnD,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,MAAM,MAAM;AAAA,MACd,CAAC;AACD,cAAQ,eAAe;AACvB,uBAAiB,KAAK,GAAG,eAAe,QAAQ;AAChD,UAAI,MAAM,OAAO;AACf,gBAAQ,KAAK,eAAe,MAAM;AAAA,MACpC;AAEA,UAAI,eAAe,gBAAgB;AACjC,mBAAW;AACX,gBAAQ;AAAA,MACV;AAEA,YAAM,eAAe,aAAa,WAC9B,MAAM,KAAK,sBAAsB;AAAA,QAC/B,OAAO;AAAA,UACL,GAAG;AAAA,UACH,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QACA;AAAA,QACA,iBAAiB;AAAA,MACnB,CAAC,IACD;AAEJ,UAAI,cAAc;AAChB,0BAAkB,aAAa;AAC/B,2BAAmB,aAAa;AAChC,0BAAkB,aAAa;AAC/B,YAAI,aAAa,WAAW,gBAAgB;AAC1C,qBAAW;AACX,kBAAQ;AACR,qCAA2B;AAAA,QAC7B;AAAA,MACF,WAAW,aAAa,UAAU;AAChC,mBAAW;AACX,gBAAQ;AACR,2BAAmB;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,aAAa,eAAe,CAAC,0BAA0B;AACzD,YAAM,WAAW,KAAK,kBAAkB;AAAA,QACtC,OAAO;AAAA,UACL,GAAG;AAAA,UACH,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,QACA,SAAS;AAAA,QACT,aAAa;AAAA,MACf,CAAC;AACD,wBAAkB,SAAS;AAC3B,wBAAkB,CAAC,GAAG,iBAAiB,GAAG,SAAS,OAAO;AAC1D,yBAAmB,CAAC,GAAG,kBAAkB,GAAG,SAAS,QAAQ;AAAA,IAC/D;AAEA,aAAS,KAAK,GAAG,gBAAgB;AACjC,YAAQ,KAAK,GAAG,eAAe;AAE/B,UAAM,kBAAkB,MAAM,KAAK,uBAAuB;AAAA,MACxD,OAAO;AAAA,QACL,GAAG;AAAA,QACH,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAED,aAAS,KAAK,GAAG,gBAAgB,eAAe;AAEhD,QAAI,cAAc,mBAAmB;AAAA,MACnC;AAAA,MACA,OAAO;AAAA,QACL,GAAG;AAAA,QACH,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IACF,CAAC;AAED,QAAI,uBAAuB;AAAA,MACzB,QAAQ,KAAK,UAAU,aAAa,eAAe;AAAA,MACnD,SAAS,KAAK,UAAU,aAAa,mBAAmB,eAAe,CAAC;AAAA,MACxE,OAAO,KAAK,UAAU,aAAa,WAAW;AAAA,IAChD;AAEA,QAAI,qBAAqB,QAAQ,gBAAgB;AAC/C,YAAM,UAAU,MAAM,KAAK,eAAe;AAAA,QACxC,OAAO;AAAA,UACL,GAAG;AAAA,UACH,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT;AAAA,QACA;AAAA,MACF,CAAC;AAED,oBAAc,QAAQ;AACtB,6BAAuB,QAAQ;AAC/B,UAAI,QAAQ,SAAS;AACnB,iBAAS,KAAK,QAAQ,OAAO;AAAA,MAC/B;AAAA,IACF;AAEA,QAAI,qBAAqB,QAAQ,gBAAgB;AAC/C,YAAM,IAAI,yBAAyB;AAAA,IACrC;AAEA,QAAI,eAAe,MAAM,WAAW;AAClC,YAAM,KAAK,eAAe,YAAY;AAAA,QACpC,WAAW,MAAM;AAAA,QACjB,OAAO;AAAA,UACL,GAAG;AAAA,UACH,QAAQ;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,gBAAgB;AAAA,MAClC,CAAC;AAAA,IACH;AAQA,UAAM,uBAAuB,KAAK,UAAU,aAAa,cAAc;AACvE,UAAM,2BAA2B,KAAK,IAAI,GAAG,uBAAuB,qBAAqB,MAAM;AAC/F,UAAM,4BAA4B,KAAK,IAAI,GAAG,sBAAsB,UAAU,qBAAqB,OAAO;AAC1G,UAAM,kBAAkB,KAAK,IAAI,GAAG,qBAAqB,SAAS,qBAAqB,SAAS,qBAAqB,QAAQ;AAC7H,UAAM,eAAe,2BAA2B;AAEhD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,gBAAgB;AAAA,MAC7B,gBAAgB,gBAAgB;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB,gBAAgB;AAAA,MAChC,eAAe,gBAAgB;AAAA,MAC/B,eAAe,gBAAgB;AAAA,MAC/B,iBAAiB,gBAAgB;AAAA,MACjC,iBAAiB,gBAAgB;AAAA,MACjC;AAAA,MACA;AAAA,MACA,WAAW,MAAM,QACb;AAAA,QACE,SAAS,gBAAgB;AAAA,QACzB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,eAAe;AAAA,QACf;AAAA,MACF,IACA;AAAA,IACN;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,WAAkC;AACnD,UAAM,KAAK,eAAe,aAAa,SAAS;AAAA,EAClD;AAAA,EAEA,MAAM,YAAY,WAAmB;AACnC,WAAO,KAAK,eAAe,YAAY,SAAS;AAAA,EAClD;AAAA,EAEA,MAAM,iBAAiB,WAAmB,QAAgB,MAAe,eAAe,KAAK;AAC3F,WAAO,KAAK,eAAe,iBAAiB,WAAW,QAAQ,MAAM,cAAc,KAAK,OAAO,SAAS;AAAA,EAC1G;AAAA,EAEA,MAAM,mBAAmB,WAAmB,QAAgB,MAAe,kBAA2B;AACpG,WAAO,KAAK,eAAe,mBAAmB;AAAA,MAC5C;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBAAkB,oBAAoB,KAAK,OAAO,oBAAoB;AAAA,MACtE,WAAW,KAAK,OAAO;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,sBAAsB,SAKsF;AACxH,UAAM,qBAAqB,cAAc,QAAQ,MAAM,MAAM;AAC7D,UAAM,yBAAyB,KAAK,UAAU,aAAa,kBAAkB;AAC7E,UAAM,YAAY,yBAAyB;AAE3C,QAAI;AACF,UAAI,CAAE,MAAM,KAAK,OAAO,YAAY,GAAI;AACtC,eAAO;AAAA,UACL,iBAAiB;AAAA,UACjB,SAAS,CAAC,mEAAmE;AAAA,UAC7E,UAAU,CAAC,4EAA4E;AAAA,UACvF,QAAQ;AAAA,QACV;AAAA,MACF;AAEA,YAAM,eAAe,YACjB,GAAG,4BAA4B,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM,CAAC;AAAA,0DACxE,4BAA4B,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM;AACxE,YAAM,qBAAqB;AAAA,QACzB;AAAA,UACE,GAAG,QAAQ;AAAA,UACX,QAAQ;AAAA,QACV;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAEA,YAAM,YAAY,QAAQ,MAAM,aAAa,KAAK,OAAO;AAEzD,UAAI,kBAAkB;AACtB,UAAI,kBAA4B,CAAC;AACjC,UAAI,mBAA6B,CAAC;AAGlC,YAAM,uBAAuB,KAAK,OAAO,+BACrC,YAAY;AACV,cAAMC,YAAW,MAAM,KAAK,OAAO;AAAA,UACjC;AAAA,YACE;AAAA,YACA,QAAQ;AAAA,YACR;AAAA,YACA,OAAO,QAAQ;AAAA,YACf,aAAa,KAAK,OAAO;AAAA,YACzB,QAAQ;AAAA,UACV;AAAA,UACA,CAAC,UAAkB;AAAA,YACjB,iBAAiB,+BAA+B,IAAI;AAAA,YACpD,SAAS,CAAC,8CAA8C,QAAQ,KAAK,GAAG;AAAA,YACxE,UAAU,CAAC;AAAA,UACb;AAAA,QACF;AACA,eAAOA;AAAA,MACT,IACA,YAAY;AACV,YAAI;AACF,iBAAO,MAAM,KAAK,OAAO,aAAmC;AAAA,YAC1D;AAAA,YACA,QAAQ;AAAA,YACR;AAAA,YACA,OAAO,QAAQ;AAAA,YACf,aAAa,KAAK,OAAO;AAAA,YACzB,QAAQ;AAAA,UACV,CAAC;AAAA,QACH,QAAQ;AACN,gBAAM,MAAM,MAAM,KAAK,OAAO,SAAS;AAAA,YACrC;AAAA,YACA,QAAQ;AAAA,YACR;AAAA,YACA,OAAO,QAAQ;AAAA,YACf,aAAa,KAAK,OAAO;AAAA,UAC3B,CAAC;AAED,iBAAO;AAAA,YACL,iBAAiB,+BAA+B,GAAG;AAAA,YACnD,SAAS,CAAC,8CAA8C,QAAQ,KAAK,GAAG;AAAA,YACxE,UAAU,CAAC;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAEJ,YAAM,WAAW,MAAM,qBAAqB;AAC5C,wBAAkB,oBAAoB,SAAS,mBAAmB,EAAE;AACpE,wBAAkB,SAAS,WAAW,CAAC;AACvC,yBAAmB,SAAS,YAAY,CAAC;AAEzC,UAAI,CAAC,iBAAiB;AACpB,eAAO;AAAA,UACL,iBAAiB;AAAA,UACjB,SAAS,CAAC,qFAAqF;AAAA,UAC/F,UAAU,CAAC,4FAA4F;AAAA,UACvG,QAAQ;AAAA,QACV;AAAA,MACF;AAEA,YAAM,sBAAsB,KAAK,UAAU,aAAa,eAAe;AACvE,UACE,2BAA2B,QAAQ,MAAM,IAAI,KAC7C,uBAAuB,wBACvB;AACA,eAAO;AAAA,UACL,iBAAiB;AAAA,UACjB,SAAS;AAAA,YACP,GAAG;AAAA,YACH;AAAA,UACF;AAAA,UACA,UAAU;AAAA,UACV,QAAQ;AAAA,QACV;AAAA,MACF;AAEA,aAAO;AAAA,QACL;AAAA,QACA,SAAS,gBAAgB,SAAS,IAAI,kBAAkB,CAAC,oCAAoC,QAAQ,KAAK,GAAG;AAAA,QAC7G,UAAU;AAAA,QACV,QAAQ;AAAA,MACV;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,QACL,iBAAiB;AAAA,QACjB,SAAS,CAAC,uEAAuE;AAAA,QACjF,UAAU,CAAC,0EAA0E;AAAA,QACrF,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,mBAAmB,SAK2D;AAC1F,QAAI,KAAK,OAAO,aAAa;AAC3B,aAAO;AAAA,QACL,OAAO,KAAK,OAAO;AAAA,QACnB,UAAU,CAAC;AAAA,QACX,QAAQ,sCAAsC,KAAK,OAAO,WAAW;AAAA,QACrE,gBAAgB;AAAA,MAClB;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,OAAO,YAAY;AAC3B,aAAO;AAAA,QACL,OAAO;AAAA,QACP,UAAU;AAAA,UACR;AAAA,QACF;AAAA,QACA,QAAQ;AAAA,QACR,gBAAgB;AAAA,MAClB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,kBAAkB,MAAM,KAAK,OAAO,WAAW;AACrD,YAAM,iBAAiB,sBAAsB,eAAe;AAC5D,YAAM,YAAY,kBAAkB;AAAA,QAClC;AAAA,QACA,MAAM,QAAQ;AAAA,QACd,QAAQ,QAAQ;AAAA,QAChB,MAAM,QAAQ;AAAA,QACd,iBAAiB,KAAK,OAAO;AAAA,MAC/B,CAAC;AAED,UAAI,eAAe,WAAW,GAAG;AAC/B,eAAO;AAAA,UACL,OAAO,UAAU;AAAA,UACjB,UAAU;AAAA,YACR,kHAAkH,KAAK,OAAO,gBAAgB,KAAK,IAAI,CAAC;AAAA,YACxJ,UAAU;AAAA,UACZ;AAAA,UACA,QAAQ,UAAU;AAAA,UAClB,gBAAgB;AAAA,QAClB;AAAA,MACF;AAEA,UAAI,eAAe,WAAW,GAAG;AAC/B,eAAO;AAAA,UACL,OAAO,UAAU;AAAA,UACjB,UAAU,CAAC;AAAA,UACX,QAAQ,UAAU;AAAA,UAClB,gBAAgB;AAAA,QAClB;AAAA,MACF;AAEA,UAAI,KAAK,OAAO,yBAAyB,QAAQ;AAC/C,cAAM,SAAS,MAAM,KAAK,oBAAoB;AAAA,UAC5C,QAAQ,QAAQ;AAAA,UAChB,MAAM,QAAQ;AAAA,UACd,MAAM,QAAQ;AAAA,UACd,QAAQ,QAAQ;AAAA,UAChB;AAAA,UACA,iBAAiB,eAAe,IAAI,CAAC,UAAU,MAAM,IAAI;AAAA,UACzD,eAAe,UAAU;AAAA,QAC3B,CAAC;AAED,eAAO;AAAA,UACL,OAAO,OAAO;AAAA,UACd,UAAU,OAAO;AAAA,UACjB,QAAQ,OAAO;AAAA,UACf,gBAAgB,OAAO,UAAU;AAAA,QACnC;AAAA,MACF;AAEA,aAAO;AAAA,QACL,OAAO;AAAA,QACP,UAAU,CAAC,gIAAgI;AAAA,QAC3I,QAAQ;AAAA,QACR,gBAAgB;AAAA,MAClB;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,QACL,OAAO;AAAA,QACP,UAAU;AAAA,UACR;AAAA,QACF;AAAA,QACA,QAAQ;AAAA,QACR,gBAAgB;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,oBAAoB,SAQiC;AACjE,UAAM,cAAc;AAAA,MAClB,QAAQ;AAAA,MACR,KAAK,OAAO;AAAA,IACd;AAEA,QAAI,CAAC,aAAa;AAChB,aAAO;AAAA,QACL,OAAO;AAAA,QACP,UAAU;AAAA,UACR,uDAAuD,QAAQ,gBAAgB,KAAK,IAAI,CAAC;AAAA,QAC3F;AAAA,QACA,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,OAAO,aAAmC;AAAA,QACpE,OAAO;AAAA,QACP,WAAW,KAAK,OAAO;AAAA,QACvB,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,cAAc;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,KAAK,IAAI;AAAA,QACX,QAAQ,KAAK;AAAA,UACX;AAAA,YACE,WAAW;AAAA,YACX,QAAQ,QAAQ;AAAA,YAChB,MAAM,QAAQ,QAAQ;AAAA,YACtB,MAAM,QAAQ;AAAA,YACd,QAAQ,QAAQ;AAAA,YAChB,iBAAiB,QAAQ,gBAAgB,IAAI,CAAC,eAAe;AAAA,cAC3D,MAAM;AAAA,cACN,SAAS,uBAAuB,SAAS;AAAA,YAC3C,EAAE;AAAA,YACF,iBAAiB;AAAA,cACf,6BAA6B;AAAA,cAC7B,qCAAqC;AAAA,gBACnC;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,cACA,mCAAmC;AAAA,gBACjC;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAED,YAAM,gBAAgB,SAAS,eAAe,KAAK;AACnD,UAAI,iBAAiB,QAAQ,gBAAgB,SAAS,aAAa,GAAG;AACpE,eAAO;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC;AAAA,UACX,QAAQ,SAAS,QAAQ,KAAK,KAAK,yBAAyB,aAAa;AAAA,QAC3E;AAAA,MACF;AAEA,aAAO;AAAA,QACL,OAAO;AAAA,QACP,UAAU,CAAC,6HAA6H;AAAA,QACxI,QAAQ;AAAA,MACV;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,QACL,OAAO;AAAA,QACP,UAAU,CAAC,qHAAqH;AAAA,QAChI,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,uBAAuB,SAYR;AAC3B,UAAM,mBAAmB,0BAA0B,QAAQ,MAAM,oBAAoB,CAAC,CAAC;AAEvF,QAAI,CAAC,QAAQ,kBAAkB,iBAAiB,WAAW,GAAG;AAC5D,aAAO;AAAA,QACL,gBAAgB;AAAA,QAChB,eAAe,CAAC;AAAA,QAChB,eAAe;AAAA,QACf,iBAAiB,CAAC;AAAA,QAClB,iBAAiB;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,iBAAiB,WAAW,GAAG;AACjC,aAAO;AAAA,QACL,gBAAgB,0BAA0B,iBAAiB,CAAC,CAAC;AAAA,QAC7D,eAAe;AAAA,UACb;AAAA,YACE,GAAG,0BAA0B,iBAAiB,CAAC,CAAC;AAAA,YAChD,MAAM;AAAA,YACN,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,QACA,eAAe;AAAA,QACf,iBAAiB,CAAC;AAAA,QAClB,iBAAiB;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,CAAC,KAAK,OAAO,YAAY;AAC3B,UAAI,2BAA2B,gBAAgB,GAAG;AAChD,cAAM,WAAW,0BAA0B,QAAQ,OAAO,QAAQ,iBAAiB,gBAAgB;AACnG,YAAI,UAAU;AACZ,iBAAO;AAAA,YACL,gBAAgB,0BAA0B,QAAQ;AAAA,YAClD,eAAe,CAAC,EAAE,GAAG,0BAA0B,QAAQ,GAAG,MAAM,GAAG,QAAQ,sEAAsE,CAAC;AAAA,YAClJ,eAAe;AAAA,YACf,iBAAiB,CAAC;AAAA,YAClB,iBAAiB;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,gBAAgB;AAAA,QAChB,eAAe,CAAC;AAAA,QAChB,eAAe;AAAA,QACf,iBAAiB;AAAA,UACf;AAAA,QACF;AAAA,QACA,iBAAiB;AAAA,MACnB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,kBAAkB,MAAM,KAAK,OAAO,WAAW;AACrD,YAAM,cAAc,mBAAmB,iBAAiB,KAAK,OAAO,WAAW;AAC/E,UAAI,CAAC,aAAa;AAChB,eAAO;AAAA,UACL,gBAAgB;AAAA,UAChB,eAAe,CAAC;AAAA,UAChB,eAAe;AAAA,UACf,iBAAiB;AAAA,YACf;AAAA,UACF;AAAA,UACA,iBAAiB;AAAA,QACnB;AAAA,MACF;AAEA,YAAM,kBAAkB,2BAA2B,gBAAgB;AAEnE,YAAM,WAAW,MAAM,KAAK,OAAO,aAAwC;AAAA,QACzE,OAAO;AAAA,QACP,WAAW,QAAQ,MAAM,aAAa,KAAK,OAAO;AAAA,QAClD,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,cAAc,mCAAmC,QAAQ,iBAAiB,QAAQ,cAAc,eAAe;AAAA,QAC/G,QAAQ,KAAK;AAAA,UACX;AAAA,YACE,WAAW;AAAA,YACX,QAAQ,QAAQ,MAAM;AAAA,YACtB,MAAM,QAAQ,MAAM,QAAQ;AAAA,YAC5B,MAAM,QAAQ,MAAM;AAAA,YACpB,QAAQ,QAAQ,MAAM;AAAA,YACtB,MAAM,QAAQ,MAAM,QAAQ;AAAA,YAC5B,aAAa,QAAQ,MAAM,eAAe,CAAC;AAAA,YAC3C,cAAc,QAAQ;AAAA,YACtB,iBAAiB,QAAQ;AAAA,YACzB,kBAAkB,iBAAiB,IAAI,CAAC,YAAY;AAAA,cAClD,IAAI,OAAO;AAAA,cACX,UAAU,OAAO;AAAA,cACjB,OAAO,OAAO;AAAA,cACd,OAAO,OAAO,SAAS;AAAA,cACvB,UAAU,OAAO;AAAA,cACjB,aAAa,OAAO;AAAA,cACpB,cAAc,OAAO;AAAA,cACrB,SAAS,yBAAyB,MAAM;AAAA,YAC1C,EAAE;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,CAAC;AAED,YAAM,kBAAkB,MAAM;AAAA,QAC5B,IAAI,KAAK,SAAS,mBAAmB,CAAC,GAAG,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC;AAAA,MACvF,EAAE,MAAM,GAAG,KAAK,IAAI,GAAG,QAAQ,WAAW,CAAC;AAE3C,YAAM,gBAAgB,gBACnB,IAAI,CAAC,IAAI,UAAU;AAClB,cAAM,SAAS,iBAAiB,KAAK,CAAC,cAAc,UAAU,OAAO,EAAE;AACvE,YAAI,CAAC,QAAQ;AACX,iBAAO;AAAA,QACT;AAEA,eAAO;AAAA,UACL,GAAG,0BAA0B,MAAM;AAAA,UACnC,MAAM,QAAQ;AAAA,UACd,QACE,UAAU,IACN,SAAS,QAAQ,KAAK,KAAK,kDAC3B,WAAW,QAAQ,CAAC;AAAA,QAC5B;AAAA,MACF,CAAC,EACA,OAAO,CAAC,UAA0C,UAAU,IAAI;AAEnE,YAAM,mBAAmB,SAAS,kBAAkB,KAAK;AACzD,YAAM,2BACH,oBAAoB,iBAAiB,KAAK,CAAC,cAAc,UAAU,OAAO,gBAAgB,OAC1F,cAAc,CAAC,IACZ,iBAAiB;AAAA,QACf,CAAC,cACC,UAAU,aAAa,cAAc,CAAC,EAAE,YACxC,UAAU,UAAU,cAAc,CAAC,EAAE,SACrC,UAAU,UAAU,cAAc,CAAC,EAAE;AAAA,MACzC,KAAK,OACL;AAEN,UAAI,CAAC,2BAA2B,cAAc,WAAW,GAAG;AAC1D,eAAO;AAAA,UACL,gBAAgB;AAAA,UAChB,eAAe,CAAC;AAAA,UAChB,eAAe;AAAA,UACf,iBAAiB;AAAA,YACf;AAAA,UACF;AAAA,UACA,iBAAiB;AAAA,QACnB;AAAA,MACF;AAEA,aAAO;AAAA,QACL,gBAAgB,0BAA0B,uBAAuB;AAAA,QACjE;AAAA,QACA,eAAe,SAAS,QAAQ,KAAK,KAAK;AAAA,QAC1C,iBAAiB,CAAC;AAAA,QAClB,iBAAiB;AAAA,MACnB;AAAA,IACF,QAAQ;AACN,UAAI,2BAA2B,gBAAgB,GAAG;AAChD,cAAM,WAAW,0BAA0B,QAAQ,OAAO,QAAQ,iBAAiB,gBAAgB;AACnG,YAAI,UAAU;AACZ,iBAAO;AAAA,YACL,gBAAgB,0BAA0B,QAAQ;AAAA,YAClD,eAAe,CAAC,EAAE,GAAG,0BAA0B,QAAQ,GAAG,MAAM,GAAG,QAAQ,2DAA2D,CAAC;AAAA,YACvI,eAAe;AAAA,YACf,iBAAiB,CAAC,qEAAqE;AAAA,YACvF,iBAAiB;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,gBAAgB;AAAA,QAChB,eAAe,CAAC;AAAA,QAChB,eAAe;AAAA,QACf,iBAAiB;AAAA,UACf;AAAA,QACF;AAAA,QACA,iBAAiB;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,kBAAkB,SAI6C;AACrE,UAAM,gBAAgB,mBAAmB,QAAQ,KAAK;AACtD,UAAM,QAAQ,gBACV,8BAA8B,QAAQ,OAAO,QAAQ,WAAW,IAChE,4BAA4B,QAAQ,OAAO,QAAQ,WAAW;AAElE,UAAM,kBAAkB,MAAM,KAAK,IAAI;AACvC,UAAM,UAAU,gBACZ;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,IACF,IACA,CAAC,+DAA+D;AACpE,QAAI,QAAQ,MAAM,SAAS,cAAc,QAAQ,MAAM,SAAS,WAAW;AACzE,cAAQ,KAAK,mDAAmD;AAAA,IAClE;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU,CAAC;AAAA,IACb;AAAA,EACF;AAAA,EAEA,MAAc,eAAe,SAMoG;AAC/H,UAAM,gBAAgB,KAAK,IAAI,IAAI,KAAK,MAAM,QAAQ,iBAAiB,GAAG,CAAC;AAC3E,UAAM,UAAU,QAAQ,MAAM,YAC1B,MAAM,KAAK,iBAAiB,QAAQ,MAAM,WAAW,QAAQ,MAAM,QAAQ,QAAQ,MAAM,MAAM,aAAa,IAC5G;AAEJ,UAAM,iBAAwC;AAAA,MAC5C,GAAG,QAAQ;AAAA,MACX,aAAa,CAAC;AAAA,MACd;AAAA,IACF;AAEA,UAAM,cAAc,mBAAmB;AAAA,MACrC,iBAAiB,KAAK,UAAU,iBAAiB,QAAQ,iBAAiB,KAAK,MAAM,QAAQ,iBAAiB,GAAG,CAAC;AAAA,MAClH,OAAO,QAAQ;AAAA,MACf,SAAS;AAAA,MACT,iBAAiB,QAAQ;AAAA,IAC3B,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA,sBAAsB;AAAA,QACpB,QAAQ,KAAK,UAAU,aAAa,QAAQ,eAAe;AAAA,QAC3D,SAAS,KAAK,UAAU,aAAa,mBAAmB,cAAc,CAAC;AAAA,QACvE,OAAO,KAAK,UAAU,aAAa,WAAW;AAAA,MAChD;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,WAA2B;AACzD,QAAM,QAAQ,UAAU,YAAY;AAEpC,MAAI,MAAM,SAAS,WAAW,GAAG;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,YAAY,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,OAAO,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,SAAS,aAAa,GAAG;AACjC,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,QAAuC;AAClE,MAAI,OAAO,OAAO,iBAAiB,YAAY,OAAO,iBAAiB,MAAM;AAC3E,WAAO,OAAO;AAAA,EAChB;AAEA,MAAI,OAAO,iBAAiB,UAAU;AACpC,WAAO,IAAI,mBAAmB,OAAO,UAAU;AAAA,EACjD;AAEA,SAAO,IAAI,iBAAiB,OAAO,UAAU;AAC/C;AAEA,SAAS,mBAAmB,OAKjB;AACT,QAAM,WAAqB,CAAC;AAE5B,WAAS,KAAK;AAAA,EAAU,MAAM,eAAe,EAAE;AAE/C,QAAM,eAAe,mBAAmB,MAAM,OAAO;AACrD,MAAI,cAAc;AAChB,aAAS,KAAK;AAAA,EAAsB,YAAY,EAAE;AAAA,EACpD;AAEA,QAAM,cAAc,MAAM;AAAA,IACxB,IAAI,IAAI;AAAA,MACN,GAAI,MAAM,MAAM,qBAAqB,CAAC;AAAA,MACtC,GAAG,mBAAmB,MAAM,MAAM,MAAM;AAAA,MACxC,MAAM,MAAM,YAAY,4BAA4B,MAAM,MAAM,SAAS,wBAAwB;AAAA,MACjG,MAAM,MAAM,OAAO,cAAc,MAAM,MAAM,IAAI,WAAW;AAAA,MAC5D,MAAM,MAAM,eAAe,wBAAwB,MAAM,MAAM,YAAY,MAAM;AAAA,IACnF,EAAE,OAAO,OAAO,CAAC;AAAA,EACnB;AAEA,MAAI,YAAY,SAAS,GAAG;AAC1B,aAAS,KAAK;AAAA,IAAmB,YAAY,KAAK,MAAM,CAAC,EAAE;AAAA,EAC7D;AAEA,QAAM,gBAAgB;AAAA,IACpB,MAAM,gBAAgB,iBAClB,oBAAoB,kBAAkB,MAAM,gBAAgB,cAAc,CAAC,KAC3E,MAAM,MAAM,cACV,iBAAiB,MAAM,MAAM,WAAW,KACxC;AAAA,IACN,SAAS,MAAM,MAAM,IAAI;AAAA,IACzB,WAAW,MAAM,MAAM,MAAM;AAAA,EAC/B;AAEA,WAAS,KAAK;AAAA,IAAsB,cAAc,KAAK,MAAM,CAAC,EAAE;AAEhE,SAAO,SAAS,KAAK,MAAM,EAAE,KAAK;AACpC;AAEA,SAAS,mBAAmB,SAAwC;AAClE,QAAM,QAAkB,CAAC;AAEzB,MAAI,QAAQ,SAAS,MAAM;AACzB,UAAM,KAAK,YAAY,QAAQ,QAAQ,IAAI,EAAE;AAAA,EAC/C;AAEA,aAAW,SAAS,QAAQ,YAAY,MAAM,EAAE,GAAG;AACjD,UAAM,KAAK,KAAK,MAAM,mBAAmB,MAAM,aAAa,MAAM,IAAI,EAAE;AAAA,EAC1E;AAEA,SAAO,oBAAoB,MAAM,KAAK,IAAI,CAAC;AAC7C;AAEA,SAAS,uBAA8C;AACrD,SAAO;AAAA,IACL,aAAa,CAAC;AAAA,IACd,SAAS;AAAA,IACT,UAAU,CAAC;AAAA,IACX,WAAW,CAAC;AAAA,EACd;AACF;AAIA,SAAS,0BAA0B,SAA8D;AAC/F,SAAO,QAAQ,IAAI,CAAC,QAAQ,WAAW;AAAA,IACrC,GAAG;AAAA,IACH,IAAI,GAAG,OAAO,QAAQ,IAAI,OAAO,KAAK,IAAI,KAAK;AAAA,IAC/C,OAAO,OAAO,SAAS,GAAG,OAAO,QAAQ,IAAI,OAAO,KAAK;AAAA,IACzD,cAAc,OAAO,gBAAgB,kBAAkB,MAAM;AAAA,IAC7D,UAAU,OAAO,YAAY,QAAQ;AAAA,IACrC,aAAa,OAAO,eAAe,QAAQ;AAAA,EAC7C,EAAE;AACJ;AAEA,SAAS,0BAA0B,QAAyD;AAC1F,SAAO;AAAA,IACL,UAAU,OAAO;AAAA,IACjB,OAAO,OAAO;AAAA,IACd,OAAO,OAAO;AAAA,IACd,cAAc,OAAO;AAAA,IACrB,UAAU,OAAO;AAAA,IACjB,aAAa,OAAO;AAAA,EACtB;AACF;AAEA,SAAS,mCACP,UACA,cACA,kBAAkB,OACV;AACR,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqB,QAAQ;AAAA,IAC7B,kBAAkB,YAAY;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,iBAAiB;AACnB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,IAAM,sBAA8C;AAAA,EACzD;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,OAAO;AAAA,IACP,cAAc,CAAC,WAAW,SAAS,WAAW,QAAQ,eAAe;AAAA,IACrE,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,OAAO;AAAA,IACP,cAAc,CAAC,UAAU,WAAW,WAAW,YAAY,YAAY,WAAW;AAAA,IAClF,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,UAAU;AAAA,IACV,OAAO;AAAA,IACP,OAAO;AAAA,IACP,cAAc,CAAC,UAAU,WAAW,YAAY,YAAY,aAAa,gBAAgB,SAAS;AAAA,IAClG,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AACF;AAEA,SAAS,2BAA2B,SAA+C;AACjF,SACE,QAAQ,UAAU,KAClB,QAAQ;AAAA,IACN,CAAC,MACC,EAAE,aAAa,eACf,qBAAqB,KAAK,EAAE,KAAK;AAAA,EACrC;AAEJ;AAEA,SAAS,0BACP,OACA,UACA,SACkC;AAClC,QAAM,QAAQ,QAAQ,KAAK,CAAC,MAAM,SAAS,KAAK,EAAE,KAAK,CAAC,KAAK;AAC7D,QAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,UAAU,KAAK,EAAE,KAAK,CAAC,KAAK;AAC/D,QAAM,OAAO,QAAQ,KAAK,CAAC,MAAM,QAAQ,KAAK,EAAE,KAAK,CAAC,KAAK;AAE3D,QAAM,QAAQ,MAAM,QAAQ,IAAI,YAAY;AAC5C,QAAM,UAAU,MAAM,UAAU,IAAI,YAAY;AAChD,QAAM,QAAQ,MAAM,eAAe,CAAC;AACpC,QAAM,SAAS,MAAM;AAErB,QAAM,gBACJ,CAAC,SAAS,QAAQ,WAAW,eAAe,EAAE,SAAS,IAAI,KAC3D,CAAC,SAAS,QAAQ,WAAW,eAAe,EAAE,SAAS,MAAM,KAC7D,MAAM,KAAK,CAAC,MAAM,CAAC,SAAS,WAAW,QAAQ,eAAe,EAAE,SAAS,CAAC,CAAC;AAE7E,QAAM,YACJ,uHAAuH,KAAK,MAAM,KAClI,MAAM,SAAS,cAAc,KAC7B,aAAa;AAEf,MAAI,aAAa,oBAAoB;AACnC,WAAO,iBAAiB,CAAC,YAAa,SAAS,SAAW,UAAU;AAAA,EACtE;AAEA,MAAI,WAAW;AACb,WAAO,QAAQ,UAAU;AAAA,EAC3B;AAEA,MAAI,iBAAiB,aAAa,qBAAqB;AACrD,WAAO,SAAS;AAAA,EAClB;AAEA,SAAO,UAAU,SAAS;AAC5B;AAEA,SAAS,kBAAkB,QAAkD;AAC3E,QAAM,QAAQ,GAAG,OAAO,QAAQ,IAAI,OAAO,KAAK,IAAI,OAAO,SAAS,EAAE,GAAG,YAAY;AACrF,QAAM,eAAe,oBAAI,IAAsB;AAE/C,MAAI,8BAA8B,KAAK,KAAK,GAAG;AAC7C,iBAAa,IAAI,QAAQ;AAAA,EAC3B;AACA,MAAI,aAAa,KAAK,KAAK,GAAG;AAC5B,iBAAa,IAAI,SAAS;AAC1B,iBAAa,IAAI,UAAU;AAAA,EAC7B;AACA,MAAI,uBAAuB,KAAK,KAAK,GAAG;AACtC,iBAAa,IAAI,UAAU;AAAA,EAC7B;AACA,MAAI,eAAe,KAAK,KAAK,GAAG;AAC9B,iBAAa,IAAI,WAAW;AAAA,EAC9B;AACA,MAAI,+BAA+B,KAAK,KAAK,GAAG;AAC9C,iBAAa,IAAI,SAAS;AAAA,EAC5B;AACA,MAAI,QAAQ,KAAK,KAAK,GAAG;AACvB,iBAAa,IAAI,OAAO;AAAA,EAC1B;AAEA,SAAO,MAAM,KAAK,YAAY;AAChC;AAEA,SAAS,yBAAyB,QAA2C;AAC3E,SAAO;AAAA,IACL,YAAY,OAAO,QAAQ;AAAA,IAC3B,SAAS,OAAO,KAAK;AAAA,IACrB,SAAS,OAAO,KAAK;AAAA,IACrB,YAAY,OAAO,QAAQ;AAAA,IAC3B,eAAe,OAAO,WAAW;AAAA,IACjC,gBAAgB,OAAO,cAAc,KAAK,GAAG,KAAK,MAAM;AAAA,EAC1D,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,kBAAkB,QAAsC;AAC/D,SAAO,OAAO,SAAS,GAAG,OAAO,QAAQ,IAAI,OAAO,KAAK;AAC3D;AAEA,SAAS,2BAA2B,MAAiC;AACnE,SAAO,SAAS,cAAc,SAAS,aAAa,SAAS;AAC/D;AAEA,SAAS,cAAc,MAAsB;AAC3C,SAAO,oBAAoB,IAAI,EAC5B,QAAQ,gCAAgC,EAAE,EAC1C,QAAQ,6CAA6C,EAAE,EACvD,QAAQ,kBAAkB,IAAI,EAC9B,QAAQ,WAAW,GAAG,EACtB,KAAK;AACV;AAEA,SAAS,+BAA+B,KAAqB;AAC3D,QAAM,aAAa,oBAAoB,GAAG;AAC1C,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAGA,MAAI,UAAU,WACX,QAAQ,8BAA8B,EAAE,EACxC,QAAQ,sCAAsC,EAAE,EAChD,QAAQ,oCAAoC,EAAE,EAC9C,QAAQ,gIAAgI,EAAE;AAE7I,MAAI,CAAC,sBAAsB,OAAO,GAAG;AACnC,WAAO,oBAAoB,OAAO;AAAA,EACpC;AAGA,QAAM,aAAa,QAChB,MAAM,QAAQ,EACd,IAAI,CAAC,UAAU,oBAAoB,oBAAoB,KAAK,CAAC,CAAC,EAC9D,OAAO,OAAO,EACd,OAAO,CAAC,UAAU,CAAC,sBAAsB,KAAK,CAAC,EAC/C,OAAO,CAAC,UAAU,CAAC,gGAAgG,KAAK,KAAK,CAAC,EAC9H,OAAO,CAAC,UAAU,MAAM,SAAS,EAAE;AAGtC,QAAM,WAAW,WAAW,OAAO,CAAC,GAAG,MAAO,EAAE,SAAS,EAAE,SAAS,IAAI,GAAI,EAAE;AAC9E,SAAO,YAAY,oBAAoB,UAAU;AACnD;AAEA,SAAS,sBAAsB,MAAuB;AACpD,SAAO,mKAAmK,KAAK,IAAI;AACrL;AAEA,SAAS,oBAAoB,MAAsB;AACjD,SAAO,KAAK,QAAQ,oBAAoB,EAAE,EAAE,KAAK;AACnD;AAEA,SAAS,mBAAmB,OAA0G;AACpI,MAAI,MAAM,SAAS,UAAU,MAAM,WAAW,QAAQ;AACpD,WAAO;AAAA,EACT;AAEA,OAAK,MAAM,eAAe,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,UAAU,WAAW,YAAY,aAAa,YAAY,cAAc,EAAE,SAAS,IAAI,CAAC,GAAG;AACvI,WAAO;AAAA,EACT;AAEA,SAAO,uGAAuG;AAAA,IAC5G,MAAM;AAAA,EACR;AACF;AAEA,SAAS,4BACP,OACA,aACU;AACV,SAAO;AAAA,IACL,YAAY,gBAAgB,MAAM,QAAQ,GAAG,CAAC;AAAA,IAC9C,MAAM,OAAO,cAAc,MAAM,IAAI,KAAK;AAAA,IAC1C,MAAM,OAAO,SAAS,MAAM,IAAI,KAAK;AAAA,IACrC,MAAM,eAAe,kBAAkB,MAAM,YAAY,KAAK;AAAA,IAC9D,MAAM,YAAY,mBAAmB,MAAM,SAAS,KAAK;AAAA,IACzD,YAAY,SAAS,yBAAyB,YAAY,KAAK,IAAI,CAAC,KAAK;AAAA,EAC3E,EAAE,OAAO,OAAO;AAClB;AAEA,SAAS,8BACP,OACA,aACU;AACV,QAAM,eAAe,sBAAsB,MAAM,MAAM;AACvD,SAAO;AAAA,IACL,SAAS,kBAAkB,MAAM,MAAM,CAAC;AAAA,IACxC,MAAM,OAAO,SAAS,MAAM,IAAI,KAAK;AAAA,IACrC,aAAa,SAAS;AAAA,IAAoB,aAAa,KAAK,MAAM,CAAC,KAAK;AAAA,IACxE,YAAY,SAAS,gBAAgB,YAAY,KAAK,IAAI,CAAC,KAAK;AAAA,IAChE;AAAA,EACF,EAAE,OAAO,OAAO;AAClB;AAEA,SAAS,gBAAgB,QAAgB,WAA2B;AAClE,QAAM,aAAa,oBAAoB,MAAM;AAC7C,MAAI,WAAW,UAAU,WAAW;AAClC,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,WAAW,MAAM,GAAG,YAAY,CAAC,EAAE,KAAK,CAAC;AACrD;AAEA,SAAS,kBAAkB,QAAwB;AACjD,QAAM,aAAa,gBAAgB,QAAQ,GAAG;AAC9C,QAAM,UAAU,OAAO,YAAY;AAEnC,MAAI,kCAAkC,KAAK,OAAO,GAAG;AACnD,WAAO;AAAA,EACT;AAEA,MAAI,gCAAgC,KAAK,OAAO,GAAG;AACjD,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,KAAK,OAAO,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,sBAAsB,QAA0B;AACvD,QAAM,UAAU,OAAO,YAAY;AACnC,QAAM,eAAyB,CAAC;AAEhC,MAAI,mCAAmC,KAAK,OAAO,GAAG;AACpD,iBAAa,KAAK,6EAA6E;AAAA,EACjG;AACA,MAAI,8DAA8D,KAAK,OAAO,GAAG;AAC/E,iBAAa,KAAK,wEAAwE;AAAA,EAC5F;AACA,MAAI,wCAAwC,KAAK,OAAO,GAAG;AACzD,iBAAa,KAAK,2DAA2D;AAAA,EAC/E;AACA,MAAI,wCAAwC,KAAK,OAAO,GAAG;AACzD,iBAAa,KAAK,wEAAwE;AAAA,EAC5F;AACA,MAAI,aAAa,KAAK,OAAO,GAAG;AAC9B,iBAAa,KAAK,kEAAkE;AAAA,EACtF;AACA,MAAI,qCAAqC,KAAK,OAAO,GAAG;AACtD,iBAAa,KAAK,oGAAoG;AAAA,EACxH;AAEA,MAAI,aAAa,WAAW,GAAG;AAC7B,iBAAa,KAAK,8DAA8D;AAAA,EAClF;AAEA,SAAO,aAAa,MAAM,GAAG,CAAC;AAChC;;;ACz1CO,SAAS,gBAAgB,SAA0B,CAAC,GAAG;AAC5D,SAAO,IAAI,gBAAgB,MAAM;AACnC;;;ACjBA,IAAM,WAAW;AACjB,IAAM,aAAa;AACnB,IAAM,QAAQ;AACd,IAAM,SAAS;AACf,IAAM,SAAS;AAWR,IAAM,sBAA0C;AAAA,EACrD;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AACF;AAEO,SAAS,iBAAiB,SAA6B,UAA0B;AACtF,QAAM,QAAkB,CAAC,6BAA6B;AACtD,WAAS,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS;AACnD,UAAM,MAAM,QAAQ,KAAK;AACzB,UAAM,aAAa,UAAU;AAC7B,UAAM,SAAS,aAAa,WAAM;AAClC,UAAM,QAAQ,aAAa,UAAU,IAAI,KAAK,YAAY,IAAI;AAC9D,UAAM,QAAQ,UAAU,IAAI,KAAK;AACjC,UAAM,OAAO,UAAU,IAAI,WAAW;AACtC,UAAM,KAAK,KAAK,MAAM,IAAI,MAAM,OAAO,aAAa,KAAK,CAAC,CAAC,KAAK,KAAK,EAAE;AACvE,UAAM,KAAK,SAAS,IAAI,EAAE;AAAA,EAC5B;AACA,QAAM,KAAK,+DAAqD;AAChE,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAsB,qBACpB,QACA,OACkC;AAClC,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAI,WAAW;AACf,UAAM,UAAU;AAChB,UAAM,YAAY,QAAQ,SAAS,IAAI;AAEvC,UAAM,OAAO,CAAC,UAAmB;AAC/B,UAAI,CAAC,OAAO;AAEV,eAAO,MAAM,QAAQ,SAAS,GAAG;AAAA,MACnC;AACA,aAAO,MAAM,YAAY,iBAAiB,SAAS,QAAQ,CAAC;AAAA,CAAI;AAAA,IAClE;AAEA,UAAM,UAAU,MAAM;AACpB,aAAO,MAAM,WAAW;AACxB,YAAM,WAAW,KAAK;AACtB,YAAM,MAAM;AACZ,YAAM,eAAe,QAAQ,MAAM;AAAA,IACrC;AAEA,UAAM,SAAS,CAAC,UAAkB;AAChC,UAAI,UAAU,QAAQ;AACpB,gBAAQ;AACR,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,UAAI,UAAU,OAAO,UAAU,QAAQ;AACrC,gBAAQ;AACR,eAAO,MAAM,IAAI;AACjB,gBAAQ,IAAI;AACZ;AAAA,MACF;AAEA,UAAI,UAAU,UAAU;AACtB,oBAAY,WAAW,IAAI,QAAQ,UAAU,QAAQ;AACrD,aAAK,KAAK;AACV;AAAA,MACF;AAEA,UAAI,UAAU,YAAY;AACxB,oBAAY,WAAW,KAAK,QAAQ;AACpC,aAAK,KAAK;AACV;AAAA,MACF;AAEA,UAAI,UAAU,OAAO;AACnB,gBAAQ;AACR,eAAO,MAAM;AAAA,qBAAwB,QAAQ,QAAQ,EAAE,KAAK;AAAA;AAAA,CAAa;AACzE,gBAAQ,QAAQ,QAAQ,EAAE,GAAG;AAAA,MAC/B;AAAA,IACF;AAEA,UAAM,WAAW,IAAI;AACrB,UAAM,OAAO;AACb,UAAM,YAAY,MAAM;AACxB,UAAM,GAAG,QAAQ,MAAM;AAEvB,SAAK,IAAI;AAAA,EACX,CAAC;AACH;;;ACzHA,SAAS,gBAAgB;AAUzB,IAAM,mBAAmB;AACzB,IAAM,aAAa;AAEZ,SAAS,oBAAoB,SAAuC;AACzE,QAAM,UAAU,KAAK,IAAI,IAAI,QAAQ,WAAW,GAAG;AACnD,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,OAAO,QAAQ,MAAM,KAAK,KAAK;AAErC,SAAO,WAAW,mBACd,kBAAkB,EAAE,GAAG,SAAS,SAAS,OAAO,KAAK,CAAC,IACtD,qBAAqB,EAAE,GAAG,SAAS,SAAS,OAAO,KAAK,CAAC;AAC/D;AAEA,SAAS,kBAAkB,SAAiD;AAC1E,QAAM,QAAQ,MAAM,QAAQ,UAAU,GAAG,IAAI,GAAG;AAChD,QAAM,aAAa,QAAQ;AAC3B,QAAM,YAAY;AAClB,QAAM,aAAa,aAAa,YAAY;AAC5C,QAAM,QAAQ,iBAAiB,QAAQ,OAAO;AAE9C,QAAM,YAAY;AAAA,IAChB,MAAM,gBAAgB,WAAW,QAAQ,IAAI,CAAC,KAAK,QAAQ,QAAQ,KAAK;AAAA,IACxE;AAAA,IACA,GAAG,YAAY,QAAQ,KAAK;AAAA,IAC5B;AAAA,IACA,MAAM,GAAG,QAAQ,IAAI,WAAM,SAAS,QAAQ,GAAG,CAAC,IAAI,OAAO,QAAQ,KAAK;AAAA,IACxE,MAAM,QAAQ,KAAK,OAAO,QAAQ,KAAK;AAAA,EACzC;AAEA,QAAM,aAAa;AAAA,IACjB,MAAM,4BAA4B,UAAU,QAAQ,KAAK;AAAA,IACzD,SAAS,MAAM,kEAAoE,QAAQ,QAAQ,KAAK;AAAA,IACxG,oCAAoC,MAAM,YAAY,QAAQ,QAAQ,KAAK;AAAA,IAC3E;AAAA,IACA,MAAM,eAAe,UAAU,QAAQ,KAAK;AAAA,IAC5C,SAAS,MAAM,kCAAkC,QAAQ,QAAQ,KAAK,IAAI;AAAA,IAC1E;AAAA,IACA,MAAM,YAAY,UAAU,QAAQ,KAAK;AAAA,IACzC;AAAA,IACA;AAAA,EACF;AAEA,QAAM,WAAW,KAAK,IAAI,UAAU,QAAQ,WAAW,MAAM;AAC7D,QAAM,UAAU,cAAc,OAAO,YAAY,QAAQ,KAAK;AAC9D,QAAM,aAAa,GAAG,MAAM,UAAK,UAAU,QAAQ,KAAK,CAAC,GAAG,MAAM,SAAI,OAAO,UAAU,GAAG,UAAU,QAAQ,KAAK,CAAC,GAAG,MAAM,UAAK,UAAU,QAAQ,KAAK,CAAC;AAExJ,QAAM,OAAO,IAAI,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,IAAI,CAAC,GAAG,UAAU;AAC5D,UAAM,OAAO,WAAW,UAAU,KAAK,KAAK,IAAI,SAAS;AACzD,UAAM,YAAY,WAAW,KAAK,KAAK;AACvC,UAAM,QAAQ,cAAc,aACxB,MAAM,SAAI,OAAO,UAAU,GAAG,OAAO,QAAQ,KAAK,IAClD,WAAW,WAAW,UAAU;AACpC,WAAO,GAAG,MAAM,UAAK,UAAU,QAAQ,KAAK,CAAC,IAAI,IAAI,IAAI,MAAM,UAAK,UAAU,QAAQ,KAAK,CAAC,IAAI,KAAK,IAAI,MAAM,UAAK,UAAU,QAAQ,KAAK,CAAC;AAAA,EAC9I,CAAC;AAED,QAAM,SAAS;AAAA,IACb;AAAA,IACA,MAAM,uBAAuB,OAAO,QAAQ,KAAK;AAAA,IACjD,OAAO,MAAM,sBAAsB,QAAQ,QAAQ,KAAK,CAAC;AAAA,EAC3D;AAEA,SAAO,CAAC,SAAS,GAAG,MAAM,YAAY,GAAG,MAAM,EAAE,KAAK,IAAI;AAC5D;AAEA,SAAS,qBAAqB,SAAiD;AAC7E,QAAM,QAAQ,MAAM,QAAQ,UAAU,GAAG,IAAI,EAAE;AAC/C,QAAM,aAAa,QAAQ;AAC3B,QAAM,QAAQ,iBAAiB,QAAQ,OAAO;AAC9C,QAAM,QAAQ;AAAA,IACZ,cAAc,MAAM,gBAAgB,WAAW,QAAQ,IAAI,CAAC,KAAK,QAAQ,QAAQ,KAAK,GAAG,aAAa,CAAC;AAAA,IACvG;AAAA,IACA,GAAG,YAAY,QAAQ,KAAK,EAAE,IAAI,CAAC,SAAS,cAAc,MAAM,aAAa,CAAC,CAAC;AAAA,IAC/E;AAAA,IACA,MAAM,QAAQ,KAAK,OAAO,QAAQ,KAAK;AAAA,IACvC;AAAA,IACA,MAAM,4BAA4B,UAAU,QAAQ,KAAK;AAAA,IACzD;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,QAAQ,UAAU,QAAQ,KAAK;AAAA,IACrC;AAAA,EACF;AAEA,SAAO;AAAA,IACL,cAAc,OAAO,YAAY,QAAQ,KAAK;AAAA,IAC9C,GAAG,MAAM,IAAI,CAAC,SAAS,GAAG,MAAM,UAAK,UAAU,QAAQ,KAAK,CAAC,IAAI,WAAW,MAAM,aAAa,CAAC,CAAC,IAAI,MAAM,UAAK,UAAU,QAAQ,KAAK,CAAC,EAAE;AAAA,IAC1I,GAAG,MAAM,UAAK,UAAU,QAAQ,KAAK,CAAC,GAAG,MAAM,SAAI,OAAO,UAAU,GAAG,UAAU,QAAQ,KAAK,CAAC,GAAG,MAAM,UAAK,UAAU,QAAQ,KAAK,CAAC;AAAA,EACvI,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,YAAY,OAA0B;AAC7C,QAAM,MAAM,QAAQ,mBAAqB;AACzC,QAAM,QAAQ,QAAQ,YAAc;AAEpC,SAAO;AAAA,IACL,GAAG,GAAG,iBAAiB,KAAK;AAAA,IAC5B,GAAG,GAAG,mBAAmB,KAAK;AAAA,IAC9B,GAAG,GAAG,sBAAsB,KAAK;AAAA,IACjC,GAAG,GAAG,sBAAsB,KAAK;AAAA,IACjC,GAAG,GAAG,qBAAqB,KAAK;AAAA,IAChC,GAAG,GAAG,uBAAuB,KAAK;AAAA,IAClC,GAAG,GAAG,oBAAoB,KAAK;AAAA,IAC/B,GAAG,GAAG,mBAAmB,KAAK;AAAA,EAChC;AACF;AAEA,SAAS,MAAM,MAAc,MAAiC,OAAwB;AACpF,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,iBAAmB,IAAI;AAAA,IAChC,KAAK;AACH,aAAO,UAAY,IAAI;AAAA,IACzB,KAAK;AACH,aAAO,iBAAmB,IAAI;AAAA,EAClC;AACF;AAEA,SAAS,cAAc,OAAe,YAAoB,OAAwB;AAChF,QAAM,aAAa,aAAa,KAAK;AACrC,QAAM,gBAAgB,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,aAAa,UAAU,CAAC;AACtE,QAAM,iBAAiB,KAAK,IAAI,GAAG,aAAa,aAAa,aAAa;AAC1E,SAAO,GAAG,MAAM,UAAK,UAAU,KAAK,CAAC,GAAG,MAAM,SAAI,OAAO,aAAa,GAAG,UAAU,KAAK,CAAC,GAAG,MAAM,OAAO,UAAU,KAAK,CAAC,GAAG,MAAM,SAAI,OAAO,cAAc,GAAG,UAAU,KAAK,CAAC,GAAG,MAAM,UAAK,UAAU,KAAK,CAAC;AAC9M;AAEA,SAAS,WAAW,MAAc,aAA6B;AAC7D,QAAM,YAAY,gBAAgB,MAAM,WAAW;AACnD,QAAM,UAAU,KAAK,IAAI,GAAG,cAAc,aAAa,SAAS,CAAC;AACjE,SAAO,GAAG,SAAS,GAAG,IAAI,OAAO,OAAO,CAAC;AAC3C;AAEA,SAAS,cAAc,MAAc,aAA6B;AAChE,QAAM,YAAY,gBAAgB,MAAM,WAAW;AACnD,QAAM,QAAQ,KAAK,IAAI,GAAG,cAAc,aAAa,SAAS,CAAC;AAC/D,QAAM,cAAc,KAAK,MAAM,QAAQ,CAAC;AACxC,QAAM,eAAe,QAAQ;AAC7B,SAAO,GAAG,IAAI,OAAO,WAAW,CAAC,GAAG,SAAS,GAAG,IAAI,OAAO,YAAY,CAAC;AAC1E;AAEA,SAAS,gBAAgB,MAAc,aAA6B;AAClE,MAAI,aAAa,IAAI,KAAK,aAAa;AACrC,WAAO;AAAA,EACT;AAEA,MAAI,UAAU;AACd,MAAI,SAAS;AACb,MAAI,WAAW;AAEf,aAAW,QAAQ,MAAM;AACvB,cAAU;AACV,QAAI,SAAS,QAAU;AACrB,iBAAW;AACX;AAAA,IACF;AACA,QAAI,UAAU;AACZ,UAAI,SAAS,KAAK;AAChB,mBAAW;AAAA,MACb;AACA;AAAA,IACF;AACA,eAAW;AACX,QAAI,WAAW,KAAK,IAAI,GAAG,cAAc,CAAC,GAAG;AAC3C;AAAA,IACF;AAAA,EACF;AAEA,SAAO,GAAG,MAAM;AAClB;AAEA,SAAS,aAAa,MAAsB;AAC1C,SAAO,KAAK,QAAQ,qBAAqB,EAAE,EAAE;AAC/C;AAEA,SAAS,MAAM,OAAe,KAAa,KAAqB;AAC9D,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AAC3C;AAEA,SAAS,WAAW,OAAuB;AACzC,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AACA,SAAO,MAAM,CAAC,EAAE,YAAY,IAAI,MAAM,MAAM,CAAC;AAC/C;;;AC9LO,IAAM,UAAN,MAAqC;AAAA,EAClC,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,WAAkC;AAAA,EAClC;AAAA,EACA;AAAA,EAES,SAAS,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAAA,EAE3E,YAAY,QAAuC,QAAQ,OAAO;AAChE,SAAK,SAAS;AACd,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,MAAM,SAAuB;AAC3B,QAAI,CAAC,KAAK,OAAO;AACf;AAAA,IACF;AAEA,SAAK,UAAU;AACf,SAAK,QAAQ;AAEb,SAAK,WAAW,YAAY,MAAM;AAChC,YAAM,UAAU,KAAK,OAAO,KAAK,QAAQ,KAAK,OAAO,MAAM;AAC3D,WAAK,OAAO,MAAM,KAAK,OAAO,IAAI,KAAK,OAAO,EAAE;AAChD,WAAK,SAAS;AAAA,IAChB,GAAG,EAAE;AAAA,EACP;AAAA,EAEA,OAAa;AACX,QAAI,KAAK,UAAU;AACjB,oBAAc,KAAK,QAAQ;AAC3B,WAAK,WAAW;AAAA,IAClB;AAEA,QAAI,KAAK,OAAO;AACd,WAAK,OAAO,MAAM,UAAU;AAAA,IAC9B;AAAA,EACF;AACF;AAEO,SAAS,cACd,QACA,QAAQ,OACK;AACb,SAAO,IAAI,QAAQ,QAAQ,KAAK;AAClC;;;AjBnBA,eAAsB,OACpB,MACA,KAAY,EAAE,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,MAAM,GACnF,eAAgC,EAAE,iBAAiB,WAAW,WAAW,GACxD;AACjB,QAAM,CAAC,SAAS,GAAG,IAAI,IAAI;AAE3B,MAAI,CAAC,SAAS;AACZ,UAAM,QAAQ,aAAa,cAAc,YAAY,GAAG,MAAM;AAC9D,QAAI,GAAG,OAAO,OAAO;AACnB,SAAG,OAAO,MAAM,GAAG,oBAAoB,IAAI,CAAC;AAAA,CAAI;AAChD,aAAO;AAAA,IACT;AACA,OAAG,OAAO,MAAM,GAAG,YAAY,CAAC;AAAA,CAAI;AACpC,WAAO;AAAA,EACT;AAEA,MAAI,YAAY,YAAY,YAAY,QAAQ,YAAY,QAAQ;AAClE,OAAG,OAAO,MAAM,GAAG,YAAY,CAAC;AAAA,CAAI;AACpC,WAAO;AAAA,EACT;AAEA,MAAI,YAAY,YAAY;AAC1B,OAAG,OAAO,MAAM,oBAAoB,OAAO;AAAA,CAAI;AAC/C,OAAG,OAAO,MAAM,GAAG,YAAY,CAAC;AAAA,CAAI;AACpC,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,kBAAkB,IAAI;AACrC,MAAI,OAAO,MAAM;AACf,OAAG,OAAO,MAAM,GAAG,YAAY,CAAC;AAAA,CAAI;AACpC,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,OAAO,aAAa,OAAO,cAAc;AAC5C,OAAG,OAAO,MAAM,4CAA4C;AAC5D,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,aAAa,gBAAgB;AAAA,IAC7C,UAAU;AAAA,IACV,aAAa,OAAO;AAAA,IACpB,MAAM,OAAO;AAAA,IACb,cAAc,OAAO;AAAA,IACrB,YAAY,OAAO;AAAA,IACnB,YAAY,OAAO;AAAA,IACnB,WAAW,OAAO;AAAA,IAClB,QAAQ,aAAa,OAAO,KAAK;AAAA,EACnC,CAAC;AAED,MAAI,OAAO,gBAAgB,OAAO,WAAW;AAC3C,UAAM,UAAU,aAAa,OAAO,SAAS;AAC7C,QAAI,CAAC,OAAO,QAAQ;AAClB,SAAG,OAAO,MAAM,mBAAmB,OAAO,SAAS;AAAA,CAAI;AACvD,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,QAAQ;AAClB,UAAM,cAAc,MAAM,aAAa,UAAU,GAAG,KAAK;AACzD,WAAO,SAAS,YAAY,KAAK,KAAK;AAAA,EACxC;AAEA,MAAI,CAAC,OAAO,QAAQ;AAClB,OAAG,OAAO,MAAM,yBAAyB;AACzC,WAAO;AAAA,EACT;AAGA,MAAI,mBAA4C;AAChD,MAAI,OAAO,mBAAmB,GAAG,OAAO,SAAS,GAAG,OAAO;AACzD,uBAAmB,MAAM,qBAAqB,GAAG,QAAQ,GAAG,KAA0B;AACtF,QAAI,qBAAqB,MAAM;AAE7B,aAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,mBAAmB,MAAM;AAC7B,QAAI,CAAC,OAAO,gBAAiB,QAAO,OAAO;AAC3C,QAAI,CAAC,oBAAoB,qBAAqB,OAAQ,QAAO,CAAC,GAAG,qBAAqB,GAAG,OAAO,OAAO;AACvG,UAAM,SAAS,oBAAoB,KAAK,CAAC,MAAM,EAAE,MAAM,YAAY,EAAE,SAAS,gBAAiB,CAAC;AAChG,WAAO,SAAS,CAAC,QAAQ,GAAG,OAAO,OAAO,IAAI,CAAC,GAAG,qBAAqB,GAAG,OAAO,OAAO;AAAA,EAC1F,GAAG;AAEH,QAAM,UAAU,cAAc,GAAG,QAAQ,GAAG,OAAO,SAAS,KAAK;AAEjE,MAAI;AACF,YAAQ,MAAM,YAAY;AAE1B,UAAM,SAAS,MAAM,UAAU,SAAS;AAAA,MACtC,QAAQ,OAAO;AAAA,MACf,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,QAAQ,OAAO;AAAA,MACf,WAAW,OAAO;AAAA,MAClB,aAAa,OAAO;AAAA,MACpB,YAAY,OAAO;AAAA,MACnB,aAAa,OAAO,eAAe;AAAA,MACnC,cAAc,OAAO;AAAA,MACrB,WAAW,OAAO;AAAA,MAClB,MAAM,OAAO;AAAA,MACb,mBAAmB,OAAO;AAAA,MAC1B,kBAAkB;AAAA,MAClB,gBAAgB,OAAO;AAAA,MACvB,iBAAiB,OAAO;AAAA,MACxB,aAAa,OAAO;AAAA,MACpB,aAAa,OAAO;AAAA,MACpB,cAAc,OAAO;AAAA,MACrB,OAAO,OAAO;AAAA,MACd,aAAa,OAAO;AAAA,MACpB,gBAAgB,OAAO;AAAA,MACvB,kBAAkB,OAAO;AAAA,MACzB,gBAAgB,OAAO;AAAA,MACvB,WAAW,OAAO;AAAA,MAClB,oBAAoB,OAAO;AAAA,IAC7B,CAAC;AAED,YAAQ,KAAK;AAEb,QAAI,OAAO,MAAM;AACf,SAAG,OAAO,MAAM,GAAG,aAAa,MAAM,CAAC;AAAA,CAAI;AAC3C,aAAO;AAAA,IACT;AAEA,QAAI,OAAO,WAAW;AACpB,YAAM,SAAS,gBAAgB,OAAO,WAAW;AACjD,UAAI,QAAQ;AACV,WAAG,OAAO,MAAM;AAAA,CAA0C;AAC1D,eAAO;AAAA,MACT,OAAO;AACL,WAAG,OAAO,MAAM;AAAA,CAAmE;AACnF,WAAG,OAAO,MAAM,GAAG,OAAO,WAAW;AAAA,CAAI;AACzC,eAAO;AAAA,MACT;AAAA,IACF;AAEA,QAAI,OAAO,OAAO;AAChB,SAAG,OAAO,MAAM,GAAG,OAAO,WAAW;AAAA,CAAI;AACzC,aAAO;AAAA,IACT;AAEA,OAAG,OAAO,MAAM,GAAG,OAAO,WAAW;AAAA;AAAA,CAAM;AAC3C,OAAG,OAAO,MAAM,YAAY,OAAO,QAAQ,UAAU,OAAO,KAAK,WAAW,OAAO,qBAAqB,KAAK,YAAY,OAAO,YAAY;AAAA,CAAI;AAChJ,OAAG,OAAO,MAAM,oBAAoB,OAAO,wBAAwB,oBAAoB,OAAO,yBAAyB,qBAAqB,OAAO,eAAe;AAAA,CAAI;AACtK,QAAI,OAAO,gBAAgB;AACzB,SAAG,OAAO,MAAM,mBAAmB,aAAa,OAAO,cAAc,CAAC;AAAA,CAAI;AAAA,IAC5E;AACA,QAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,SAAG,OAAO,MAAM,YAAY,OAAO,SAAS,KAAK,KAAK,CAAC;AAAA,CAAI;AAAA,IAC7D;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,KAAK;AACb,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,OAAG,OAAO,MAAM,GAAG,OAAO;AAAA,CAAI;AAC9B,WAAO;AAAA,EACT;AACF;AAEA,SAAS,kBAAkB,MAAgB;AACzC,QAAM,SAqCF;AAAA,IACF,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,WAAW;AAAA,IACX,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,IACjB,MAAM;AAAA,IACN,MAAM,CAAC;AAAA,IACP,mBAAmB,CAAC;AAAA,IACpB,SAAS,CAAC;AAAA,IACV,aAAa,CAAC;AAAA,IACd,gBAAgB;AAAA,EAClB;AAEA,QAAM,cAAwB,CAAC;AAE/B,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAAG;AACnD,UAAM,MAAM,KAAK,KAAK;AACtB,YAAQ,KAAK;AAAA,MACX,KAAK;AACH,eAAO,YAAY,KAAK,EAAE,KAAK;AAC/B;AAAA,MACF,KAAK;AACH,eAAO,QAAQ,KAAK,EAAE,KAAK;AAC3B;AAAA,MACF,KAAK;AACH,eAAO,OAAO,KAAK,EAAE,KAAK;AAC1B;AAAA,MACF,KAAK;AACH,eAAO,OAAO,KAAK,EAAE,KAAK;AAC1B;AAAA,MACF,KAAK;AACH,eAAO,OAAO,KAAK,EAAE,KAAK;AAC1B;AAAA,MACF,KAAK;AACH,eAAO,SAAS,KAAK,EAAE,KAAK;AAC5B;AAAA,MACF,KAAK;AACH,eAAO,cAAc,KAAK,EAAE,KAAK;AACjC;AAAA,MACF,KAAK;AACH,eAAO,eAAe,KAAK,EAAE,KAAK;AAClC;AAAA,MACF,KAAK;AACH,eAAO,YAAY,OAAO,KAAK,EAAE,KAAK,CAAC;AACvC;AAAA,MACF,KAAK;AACH,eAAO,KAAK,KAAK,KAAK,EAAE,KAAK,CAAC;AAC9B;AAAA,MACF,KAAK;AACH,eAAO,kBAAkB,KAAK,KAAK,EAAE,KAAK,CAAC;AAC3C;AAAA,MACF,KAAK;AACH,eAAO,QAAQ,KAAK,qBAAqB,KAAK,EAAE,KAAK,GAAG,OAAO,QAAQ,MAAM,CAAC;AAC9E;AAAA,MACF,KAAK;AACH,eAAO,YAAY,KAAK,KAAK,EAAE,KAAK,CAAqB;AACzD;AAAA,MACF,KAAK;AACH,eAAO,kBAAkB,KAAK,EAAE,KAAK;AACrC;AAAA,MACF,KAAK;AACH,eAAO,cAAc,OAAO,KAAK,EAAE,KAAK,CAAC;AACzC;AAAA,MACF,KAAK;AACH,eAAO,eAAe,KAAK,EAAE,KAAK;AAClC;AAAA,MACF,KAAK;AACH,eAAO,iBAAiB;AACxB;AAAA,MACF,KAAK;AACH,eAAO,OAAO,KAAK,EAAE,KAAK;AAC1B;AAAA,MACF,KAAK;AACH,eAAO,eAAe,KAAK,EAAE,KAAK;AAClC;AAAA,MACF,KAAK;AACH,eAAO,aAAa,KAAK,EAAE,KAAK;AAChC;AAAA,MACF,KAAK;AACH,eAAO,aAAa,KAAK,EAAE,KAAK;AAChC;AAAA,MACF,KAAK;AACH,eAAO,QAAQ;AACf;AAAA,MACF,KAAK;AACH,eAAO,OAAO;AACd;AAAA,MACF,KAAK;AACH,eAAO,YAAY;AACnB;AAAA,MACF,KAAK;AACH,eAAO,QAAQ;AACf;AAAA,MACF,KAAK;AACH,eAAO,cAAc;AACrB;AAAA,MACF,KAAK;AACH,eAAO,aAAa;AACpB;AAAA,MACF,KAAK;AACH,eAAO,eAAe;AACtB;AAAA,MACF,KAAK;AACH,eAAO,iBAAiB,OAAO,KAAK,EAAE,KAAK,CAAC;AAC5C;AAAA,MACF,KAAK;AACH,eAAO,mBAAmB,OAAO,KAAK,EAAE,KAAK,CAAC;AAC9C;AAAA,MACF,KAAK;AACH,eAAO,iBAAiB,OAAO,KAAK,EAAE,KAAK,CAAC;AAC5C;AAAA,MACF,KAAK;AACH,eAAO,YAAY,OAAO,KAAK,EAAE,KAAK,CAAC;AACvC;AAAA,MACF,KAAK;AACH,eAAO,qBAAqB;AAC5B;AAAA,MACF,KAAK;AACH,eAAO,kBAAkB;AACzB;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,eAAO,OAAO;AACd;AAAA,MACF;AACE,oBAAY,KAAK,GAAG;AAAA,IACxB;AAAA,EACF;AAEA,SAAO,SAAS,YAAY,KAAK,GAAG,EAAE,KAAK,KAAK;AAChD,SAAO;AACT;AAEA,SAAS,cAAsB;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,qBAAqB,KAAa,OAAqC;AAC9E,QAAM,CAAC,UAAU,GAAG,UAAU,IAAI,IAAI,MAAM,GAAG;AAC/C,QAAM,QAAQ,WAAW,KAAK,GAAG,EAAE,KAAK;AACxC,SAAO;AAAA,IACL,UAAU,SAAS,KAAK;AAAA,IACxB;AAAA,IACA,OAAO;AAAA,IACP,UAAU,QAAQ;AAAA,IAClB,aAAa,QAAQ;AAAA,EACvB;AACF;AAEA,SAAS,aAAa,QAAsC;AAC1D,SAAO,OAAO,SAAS,GAAG,OAAO,QAAQ,IAAI,OAAO,KAAK;AAC3D;AAEA,eAAe,UAAU,QAAuC,QAAQ,OAAwB;AAC9F,MAAI,CAAC,SAAS,MAAM,OAAO;AACzB,WAAO;AAAA,EACT;AAEA,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAI,OAAO;AACX,UAAM,YAAY,MAAM;AACxB,UAAM,GAAG,QAAQ,CAAC,UAAU;AAC1B,cAAQ;AAAA,IACV,CAAC;AACD,UAAM,GAAG,OAAO,MAAM,QAAQ,IAAI,CAAC;AACnC,UAAM,GAAG,SAAS,MAAM;AAAA,EAC1B,CAAC;AACH;AAEA,SAAS,WAAW,QAAsG;AACxH,SAAO;AAAA,IACL,KAAK,QAAQ,IAAI;AAAA,IACjB,SAAS,mBAAmB;AAAA,IAC5B,OAAO,eAAe,MAAM;AAAA,IAC5B,SAAS,OAAO;AAAA,IAChB,MAAM,QAAQ,IAAI,QAAQ,QAAQ,IAAI;AAAA,EACxC;AACF;AAEA,SAAS,eAAe,QAA4B;AAClD,MAAI,CAAC,OAAO,OAAO;AACjB,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,IAAI,UAAU;AACxB,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,IAAI,SAAS,QAAQ;AAC/B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,qBAA6B;AACpC,MAAI;AACF,UAAM,cAAc,aAAa,IAAI,IAAI,mBAAmB,YAAY,GAAG,GAAG,MAAM;AACpF,UAAM,SAAS,KAAK,MAAM,WAAW;AACrC,WAAO,OAAO,WAAW;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,gBAAgB,MAAuB;AAE9C,QAAM,WAAW;AAAA,IACf,EAAE,KAAK,SAAS,MAAM,CAAC,cAAc,WAAW,GAAG,UAAU,QAAQ;AAAA,IACrE,EAAE,KAAK,QAAQ,MAAM,CAAC,IAAI,GAAG,UAAU,QAAQ;AAAA,IAC/C,EAAE,KAAK,WAAW,MAAM,CAAC,GAAG,UAAU,QAAQ;AAAA,IAC9C,EAAE,KAAK,UAAU,MAAM,CAAC,GAAG,UAAU,SAAS;AAAA,EAChD;AAEA,aAAW,EAAE,IAAI,KAAK,UAAU;AAC9B,QAAI;AACF,eAAS,SAAS,GAAG,mBAAmB;AACxC,eAAS,KAAK,EAAE,OAAO,MAAM,OAAO,CAAC,QAAQ,UAAU,QAAQ,EAAE,CAAC;AAClE,aAAO;AAAA,IACT,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAI,aAAa,GAAG;AAClB,SAAO,QAAQ,KAAK,MAAM,CAAC,CAAC,EAAE;AAAA,IAC5B,CAAC,SAAS;AACR,cAAQ,KAAK,IAAI;AAAA,IACnB;AAAA,IACA,CAAC,UAAmB;AAClB,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,cAAQ,OAAO,MAAM,GAAG,OAAO;AAAA,CAAI;AACnC,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF;AAEA,SAAS,eAAwB;AAC/B,MAAI,CAAC,QAAQ,KAAK,CAAC,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,YAAY,aAAa,QAAQ,KAAK,CAAC,CAAC;AAC9C,UAAM,WAAW,aAAa,cAAc,YAAY,GAAG,CAAC;AAC5D,WAAO,cAAc;AAAA,EACvB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":["dirname","join","mkdir","join","mkdir","dirname","randomUUID","randomUUID","response"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/errors.ts","../src/storage/fileSessionStore.ts","../src/utils/validation.ts","../src/storage/sqliteSessionStore.ts","../src/utils/logger.ts","../src/utils/json.ts","../src/core/ollamaClient.ts","../src/core/systemPrompt.ts","../src/core/tokenEstimator.ts","../src/core/contextCompressor.ts","../src/core/contextManager.ts","../src/core/modelSelector.ts","../src/core/optimizer.ts","../src/index.ts","../src/cliMenu.ts","../src/cliWelcome.ts","../src/utils/spinner.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync, realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { execSync, spawn } from \"node:child_process\";\n\nimport { createOptimizer, CLAUDE_TIER_TARGETS } from \"./index.js\";\nimport { promptClaudeTierMenu } from \"./cliMenu.js\";\nimport type { ClaudeTierChoice } from \"./cliMenu.js\";\nimport { renderWelcomeScreen } from \"./cliWelcome.js\";\nimport { toPrettyJson } from \"./utils/json.js\";\nimport { createLogger } from \"./utils/logger.js\";\nimport { createSpinner } from \"./utils/spinner.js\";\nimport type { RoutingPriority, TargetCapability, TargetModelCandidate, WorkloadBias } from \"./types.js\";\n\ntype CliWriter = {\n write(message: string): void;\n isTTY?: boolean;\n columns?: number;\n};\n\ninterface CliIO {\n stdout: CliWriter;\n stderr: CliWriter;\n stdin?: NodeJS.ReadStream;\n}\n\ninterface CliDependencies {\n createOptimizer: typeof createOptimizer;\n readStdin: (stdin?: NodeJS.ReadStream) => Promise<string>;\n getCliInfo?: (stdout: CliWriter) => { cwd: string; version: string; color: boolean; columns?: number; user?: string };\n spawnClaude?: (prompt: string) => Promise<number>;\n}\n\nexport async function runCli(\n argv: string[],\n io: CliIO = { stdout: process.stdout, stderr: process.stderr, stdin: process.stdin },\n dependencies: CliDependencies = { createOptimizer, readStdin, getCliInfo }\n): Promise<number> {\n const [command, ...rest] = argv;\n\n if (!command) {\n const info = (dependencies.getCliInfo ?? getCliInfo)(io.stdout);\n if (io.stdout.isTTY) {\n io.stdout.write(`${renderWelcomeScreen(info)}\\n`);\n return 0;\n }\n io.stdout.write(`${getHelpText()}\\n`);\n return 0;\n }\n\n if (command === \"--help\" || command === \"-h\" || command === \"help\") {\n io.stdout.write(`${getHelpText()}\\n`);\n return 0;\n }\n\n if (command !== \"optimize\" && command !== \"claude\") {\n io.stderr.write(`Unknown command: ${command}\\n`);\n io.stderr.write(`${getHelpText()}\\n`);\n return 1;\n }\n\n const parsed = parseOptimizeArgs(rest);\n if (parsed.help) {\n io.stdout.write(`${getHelpText()}\\n`);\n return 0;\n }\n\n if (!parsed.sessionId && parsed.clearSession) {\n io.stderr.write(\"--clear-session requires --session <id>.\\n\");\n return 1;\n }\n\n const optimizer = dependencies.createOptimizer({\n provider: \"ollama\",\n ollamaModel: parsed.model,\n host: parsed.host,\n contextStore: parsed.contextStore,\n storageDir: parsed.storageDir,\n sqlitePath: parsed.sqlitePath,\n timeoutMs: parsed.timeoutMs,\n logger: createLogger(parsed.debug)\n });\n\n if (parsed.clearSession && parsed.sessionId) {\n await optimizer.clearContext(parsed.sessionId);\n if (!parsed.prompt) {\n io.stdout.write(`Cleared session ${parsed.sessionId}\\n`);\n return 0;\n }\n }\n\n if (!parsed.prompt) {\n const stdinPrompt = await dependencies.readStdin(io.stdin);\n parsed.prompt = stdinPrompt.trim() || undefined;\n }\n\n if (!parsed.prompt) {\n io.stderr.write(\"A prompt is required.\\n\");\n return 1;\n }\n\n // Show the Claude tier menu when using the `claude` subcommand or --claude flag, in a TTY\n const wantTierMenu = command === \"claude\" || parsed.autoClaudeTiers;\n let claudeTierChoice: ClaudeTierChoice | null = null;\n if (wantTierMenu && io.stderr.isTTY && io.stdin) {\n claudeTierChoice = await promptClaudeTierMenu(io.stderr, io.stdin as NodeJS.ReadStream);\n if (claudeTierChoice === null) {\n return 0;\n }\n }\n\n // Resolve which targets to pass based on tier choice\n const resolvedTargets = (() => {\n if (!wantTierMenu) return parsed.targets;\n if (!claudeTierChoice || claudeTierChoice === \"auto\") return [...CLAUDE_TIER_TARGETS, ...parsed.targets];\n const picked = CLAUDE_TIER_TARGETS.find((t) => t.model.toLowerCase().includes(claudeTierChoice!));\n return picked ? [picked, ...parsed.targets] : [...CLAUDE_TIER_TARGETS, ...parsed.targets];\n })();\n\n const spinner = createSpinner(io.stderr, io.stderr.isTTY ?? false);\n\n try {\n spinner.start(\"optimizing\");\n\n const result = await optimizer.optimize({\n prompt: parsed.prompt,\n task: parsed.task,\n tone: parsed.tone,\n mode: parsed.mode,\n preset: parsed.preset,\n sessionId: parsed.sessionId,\n saveContext: parsed.saveContext,\n useContext: parsed.useContext,\n targetModel: parsed.targetModel ?? \"claude\",\n outputFormat: parsed.outputFormat,\n maxLength: parsed.maxLength,\n tags: parsed.tags,\n pinnedConstraints: parsed.pinnedConstraints,\n availableTargets: resolvedTargets,\n routingEnabled: parsed.routingEnabled,\n routingPriority: parsed.routingPriority,\n routingTopK: parsed.routingTopK,\n targetHints: parsed.targetHints,\n workloadBias: parsed.workloadBias,\n debug: parsed.debug,\n plainOutput: parsed.plain,\n maxTotalTokens: parsed.maxTotalTokens,\n maxContextTokens: parsed.maxContextTokens,\n maxInputTokens: parsed.maxInputTokens,\n timeoutMs: parsed.timeoutMs,\n bypassOptimization: parsed.bypassOptimization\n });\n\n spinner.stop();\n\n if (command === \"claude\") {\n const doSpawn = dependencies.spawnClaude ?? spawnClaudeProcess;\n const exitCode = await doSpawn(result.finalPrompt);\n return exitCode;\n }\n\n if (parsed.json) {\n io.stdout.write(`${toPrettyJson(result)}\\n`);\n return 0;\n }\n\n if (parsed.clipboard) {\n const copied = copyToClipboard(result.finalPrompt);\n if (copied) {\n io.stderr.write(`✓ Copied optimized prompt to clipboard\\n`);\n return 0;\n } else {\n io.stderr.write(`✗ Failed to copy to clipboard. Install xclip, xsel, or wl-copy.\\n`);\n io.stdout.write(`${result.finalPrompt}\\n`);\n return 1;\n }\n }\n\n if (parsed.plain) {\n io.stdout.write(`${result.finalPrompt}\\n`);\n return 0;\n }\n\n io.stdout.write(`${result.finalPrompt}\\n\\n`);\n io.stdout.write(`provider=${result.provider} model=${result.model} tokens=${result.estimatedTokensAfter.total} savings=${result.tokenSavings}\\n`);\n io.stdout.write(` prompt_savings=${result.promptCompressionSavings} context_savings=${result.contextCompressionSavings} wrapper_overhead=${result.wrapperOverhead}\\n`);\n if (result.selectedTarget) {\n io.stdout.write(`selected_target=${formatTarget(result.selectedTarget)}\\n`);\n }\n if (result.warnings.length > 0) {\n io.stdout.write(`warnings=${result.warnings.join(\" | \")}\\n`);\n }\n return 0;\n } catch (error) {\n spinner.stop();\n const message = error instanceof Error ? error.message : \"Unknown CLI error.\";\n io.stderr.write(`${message}\\n`);\n return 1;\n }\n}\n\nfunction parseOptimizeArgs(args: string[]) {\n const parsed: {\n prompt?: string;\n sessionId?: string;\n model?: string;\n mode?: any;\n task?: string;\n tone?: string;\n preset?: any;\n targetModel?: string;\n outputFormat?: string;\n maxLength?: number;\n tags: string[];\n pinnedConstraints: string[];\n targets: TargetModelCandidate[];\n targetHints: TargetCapability[];\n routingEnabled: boolean;\n routingPriority?: RoutingPriority;\n routingTopK?: number;\n workloadBias?: WorkloadBias;\n host?: string;\n contextStore?: \"local\" | \"sqlite\";\n storageDir?: string;\n sqlitePath?: string;\n plain: boolean;\n json: boolean;\n debug: boolean;\n clipboard: boolean;\n saveContext?: boolean;\n useContext?: boolean;\n clearSession: boolean;\n maxTotalTokens?: number;\n maxContextTokens?: number;\n maxInputTokens?: number;\n timeoutMs?: number;\n bypassOptimization: boolean;\n autoClaudeTiers: boolean;\n help: boolean;\n } = {\n plain: false,\n json: false,\n debug: false,\n clipboard: false,\n clearSession: false,\n useContext: true,\n bypassOptimization: false,\n autoClaudeTiers: false,\n help: false,\n tags: [],\n pinnedConstraints: [],\n targets: [],\n targetHints: [],\n routingEnabled: true\n };\n\n const positionals: string[] = [];\n\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n switch (arg) {\n case \"--session\":\n parsed.sessionId = args[++index];\n break;\n case \"--model\":\n parsed.model = args[++index];\n break;\n case \"--mode\":\n parsed.mode = args[++index];\n break;\n case \"--task\":\n parsed.task = args[++index];\n break;\n case \"--tone\":\n parsed.tone = args[++index];\n break;\n case \"--preset\":\n parsed.preset = args[++index];\n break;\n case \"--target-model\":\n parsed.targetModel = args[++index];\n break;\n case \"--output-format\":\n parsed.outputFormat = args[++index];\n break;\n case \"--max-length\":\n parsed.maxLength = Number(args[++index]);\n break;\n case \"--tag\":\n parsed.tags.push(args[++index]);\n break;\n case \"--pin-constraint\":\n parsed.pinnedConstraints.push(args[++index]);\n break;\n case \"--target\":\n parsed.targets.push(parseTargetCandidate(args[++index], parsed.targets.length));\n break;\n case \"--target-hint\":\n parsed.targetHints.push(args[++index] as TargetCapability);\n break;\n case \"--routing-priority\":\n parsed.routingPriority = args[++index] as RoutingPriority;\n break;\n case \"--routing-top-k\":\n parsed.routingTopK = Number(args[++index]);\n break;\n case \"--workload-bias\":\n parsed.workloadBias = args[++index] as WorkloadBias;\n break;\n case \"--no-routing\":\n parsed.routingEnabled = false;\n break;\n case \"--host\":\n parsed.host = args[++index];\n break;\n case \"--store\":\n parsed.contextStore = args[++index] as \"local\" | \"sqlite\";\n break;\n case \"--storage-dir\":\n parsed.storageDir = args[++index];\n break;\n case \"--sqlite-path\":\n parsed.sqlitePath = args[++index];\n break;\n case \"--plain\":\n parsed.plain = true;\n break;\n case \"--json\":\n parsed.json = true;\n break;\n case \"--clipboard\":\n parsed.clipboard = true;\n break;\n case \"--debug\":\n parsed.debug = true;\n break;\n case \"--save-context\":\n parsed.saveContext = true;\n break;\n case \"--no-context\":\n parsed.useContext = false;\n break;\n case \"--clear-session\":\n parsed.clearSession = true;\n break;\n case \"--max-total-tokens\":\n parsed.maxTotalTokens = Number(args[++index]);\n break;\n case \"--max-context-tokens\":\n parsed.maxContextTokens = Number(args[++index]);\n break;\n case \"--max-input-tokens\":\n parsed.maxInputTokens = Number(args[++index]);\n break;\n case \"--timeout\":\n parsed.timeoutMs = Number(args[++index]);\n break;\n case \"--bypass-optimization\":\n parsed.bypassOptimization = true;\n break;\n case \"--claude\":\n parsed.autoClaudeTiers = true;\n break;\n case \"--help\":\n case \"-h\":\n parsed.help = true;\n break;\n default:\n positionals.push(arg);\n }\n }\n\n parsed.prompt = positionals.join(\" \").trim() || undefined;\n return parsed;\n}\n\nfunction getHelpText(): string {\n return [\n \"Usage:\",\n \"\",\n \" promptpilot claude <prompt> [options]\",\n \" Optimize your prompt and pipe it directly to the claude CLI.\",\n \" Shows a tier picker (Haiku / Sonnet / Opus / Auto) in interactive mode.\",\n \"\",\n \" promptpilot optimize <prompt> [options]\",\n \" Optimize and print the result to stdout.\",\n \"\",\n \"Options (shared):\",\n \" --session <id>\",\n \" --model <name> Override auto-selected local Ollama model\",\n \" --mode <mode>\",\n \" --task <task>\",\n \" --tone <tone>\",\n \" --preset <preset>\",\n \" --target-model <name>\",\n \" --output-format <text>\",\n \" --max-length <n>\",\n \" --tag <value> Repeatable\",\n \" --pin-constraint <text> Repeatable\",\n \" --target <provider:model> Repeatable\",\n \" --target-hint <value> Repeatable\",\n \" --routing-priority <value>\",\n \" --routing-top-k <n>\",\n \" --workload-bias <code_first>\",\n \" --no-routing\",\n \" --host <url>\",\n \" --store <local|sqlite>\",\n \" --storage-dir <path>\",\n \" --sqlite-path <path>\",\n \" --debug\",\n \" --save-context\",\n \" --no-context\",\n \" --clear-session\",\n \" --max-total-tokens <n>\",\n \" --max-context-tokens <n>\",\n \" --max-input-tokens <n>\",\n \" --timeout <ms>\",\n \" --bypass-optimization\",\n \"\",\n \"Options (optimize only):\",\n \" --plain\",\n \" --json\",\n \" --clipboard Copy optimized prompt to clipboard\",\n \" --claude Route between Haiku, Sonnet, and Opus automatically\"\n ].join(\"\\n\");\n}\n\nfunction parseTargetCandidate(raw: string, index: number): TargetModelCandidate {\n const [provider, ...modelParts] = raw.split(\":\");\n const model = modelParts.join(\":\").trim();\n return {\n provider: provider.trim(),\n model,\n label: raw,\n costRank: index + 1,\n latencyRank: index + 1\n };\n}\n\nfunction formatTarget(target: TargetModelCandidate): string {\n return target.label ?? `${target.provider}:${target.model}`;\n}\n\nasync function readStdin(stdin: NodeJS.ReadStream | undefined = process.stdin): Promise<string> {\n if (!stdin || stdin.isTTY) {\n return \"\";\n }\n\n return new Promise((resolve, reject) => {\n let data = \"\";\n stdin.setEncoding(\"utf8\");\n stdin.on(\"data\", (chunk) => {\n data += chunk;\n });\n stdin.on(\"end\", () => resolve(data));\n stdin.on(\"error\", reject);\n });\n}\n\nfunction getCliInfo(stdout: CliWriter): { cwd: string; version: string; color: boolean; columns?: number; user?: string } {\n return {\n cwd: process.cwd(),\n version: readPackageVersion(),\n color: shouldUseColor(stdout),\n columns: stdout.columns,\n user: process.env.USER ?? process.env.USERNAME\n };\n}\n\nfunction shouldUseColor(stdout: CliWriter): boolean {\n if (!stdout.isTTY) {\n return false;\n }\n if (process.env.NO_COLOR) {\n return false;\n }\n if (process.env.TERM === \"dumb\") {\n return false;\n }\n return true;\n}\n\nfunction readPackageVersion(): string {\n try {\n const packageJson = readFileSync(new URL(\"../package.json\", import.meta.url), \"utf8\");\n const parsed = JSON.parse(packageJson) as { version?: string };\n return parsed.version ?? \"dev\";\n } catch {\n return \"dev\";\n }\n}\n\nfunction spawnClaudeProcess(prompt: string): Promise<number> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"claude\", [], { stdio: [\"pipe\", \"inherit\", \"inherit\"] });\n if (!child.stdin) {\n reject(new Error(\"Failed to open stdin pipe to claude process\"));\n return;\n }\n child.stdin.write(prompt);\n child.stdin.end();\n child.on(\"close\", (code) => resolve(code ?? 1));\n child.on(\"error\", reject);\n });\n}\n\nfunction copyToClipboard(text: string): boolean {\n // Try different clipboard commands based on platform\n const commands = [\n { cmd: \"xclip\", args: [\"-selection\", \"clipboard\"], platform: \"linux\" },\n { cmd: \"xsel\", args: [\"-b\"], platform: \"linux\" },\n { cmd: \"wl-copy\", args: [], platform: \"linux\" },\n { cmd: \"pbcopy\", args: [], platform: \"darwin\" }\n ];\n\n for (const { cmd } of commands) {\n try {\n execSync(`which ${cmd} > /dev/null 2>&1`);\n execSync(cmd, { input: text, stdio: [\"pipe\", \"ignore\", \"ignore\"] });\n return true;\n } catch {\n // Command not found or failed, try next one\n }\n }\n\n return false;\n}\n\nif (isMainModule()) {\n runCli(process.argv.slice(2)).then(\n (code) => {\n process.exit(code);\n },\n (error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`${message}\\n`);\n process.exit(1);\n }\n );\n}\n\nfunction isMainModule(): boolean {\n if (!process.argv[1]) {\n return false;\n }\n\n try {\n const entryPath = realpathSync(process.argv[1]);\n const thisPath = realpathSync(fileURLToPath(import.meta.url));\n return entryPath === thisPath;\n } catch {\n return false;\n }\n}\n","export class InvalidPromptError extends Error {\n constructor(message = \"Prompt must be a non-empty string.\") {\n super(message);\n this.name = \"InvalidPromptError\";\n }\n}\n\nexport class OllamaUnavailableError extends Error {\n constructor(message = \"Ollama is unavailable or returned an invalid response.\") {\n super(message);\n this.name = \"OllamaUnavailableError\";\n }\n}\n\nexport class ContextStoreError extends Error {\n constructor(message = \"Context store operation failed.\") {\n super(message);\n this.name = \"ContextStoreError\";\n }\n}\n\nexport class TokenBudgetExceededError extends Error {\n constructor(message = \"Final prompt could not be reduced to fit within the configured token budget.\") {\n super(message);\n this.name = \"TokenBudgetExceededError\";\n }\n}\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { ContextStoreError } from \"../errors.js\";\nimport type { SessionData, SessionStore } from \"../types.js\";\nimport { sanitizeSessionId } from \"../utils/validation.js\";\n\nexport class FileSessionStore implements SessionStore {\n private readonly rootDir: string;\n\n constructor(rootDir = join(homedir(), \".promptpilot\", \"sessions\")) {\n this.rootDir = rootDir;\n }\n\n async loadSession(sessionId: string): Promise<SessionData> {\n const filePath = this.getFilePath(sessionId);\n\n try {\n const contents = await readFile(filePath, \"utf8\");\n const parsed = JSON.parse(contents) as SessionData;\n return parsed;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") {\n return this.createEmptySession(sessionId);\n }\n\n throw new ContextStoreError(`Failed to load session \"${sessionId}\".`);\n }\n }\n\n async saveSession(session: SessionData): Promise<void> {\n const filePath = this.getFilePath(session.sessionId);\n\n try {\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, JSON.stringify(session, null, 2), \"utf8\");\n } catch {\n throw new ContextStoreError(`Failed to save session \"${session.sessionId}\".`);\n }\n }\n\n async clearSession(sessionId: string): Promise<void> {\n const filePath = this.getFilePath(sessionId);\n\n try {\n await rm(filePath, { force: true });\n } catch {\n throw new ContextStoreError(`Failed to clear session \"${sessionId}\".`);\n }\n }\n\n private getFilePath(sessionId: string): string {\n return join(this.rootDir, `${sanitizeSessionId(sessionId)}.json`);\n }\n\n private createEmptySession(sessionId: string): SessionData {\n const now = new Date().toISOString();\n return {\n sessionId,\n entries: [],\n summaries: [],\n createdAt: now,\n updatedAt: now\n };\n }\n}\n","import { InvalidPromptError } from \"../errors.js\";\n\nexport function normalizeWhitespace(value: string): string {\n return value\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function validatePrompt(prompt: string): string {\n if (typeof prompt !== \"string\" || normalizeWhitespace(prompt).length === 0) {\n throw new InvalidPromptError();\n }\n\n return normalizeWhitespace(prompt);\n}\n\nexport function sanitizeSessionId(sessionId: string): string {\n return sessionId.trim().replace(/[^a-zA-Z0-9._-]/g, \"-\");\n}\n","import { dirname, join } from \"node:path\";\nimport { mkdir } from \"node:fs/promises\";\n\nimport { ContextStoreError } from \"../errors.js\";\nimport type { SessionData, SessionStore } from \"../types.js\";\n\ntype DatabaseAdapter = {\n prepare(sql: string): {\n get(param?: string): { data?: string } | undefined;\n run(...params: unknown[]): void;\n };\n exec(sql: string): void;\n};\n\nexport class SQLiteSessionStore implements SessionStore {\n private dbPromise: Promise<DatabaseAdapter>;\n\n constructor(private readonly dbPath = join(process.cwd(), \".promptpilot\", \"promptpilot.db\")) {\n this.dbPromise = this.openDatabase();\n }\n\n async loadSession(sessionId: string): Promise<SessionData> {\n const db = await this.dbPromise;\n const row = db.prepare(\"SELECT data FROM sessions WHERE id = ?\").get(sessionId);\n if (!row?.data) {\n return createEmptySession(sessionId);\n }\n\n return JSON.parse(row.data) as SessionData;\n }\n\n async saveSession(session: SessionData): Promise<void> {\n const db = await this.dbPromise;\n db.prepare(\"INSERT OR REPLACE INTO sessions (id, data) VALUES (?, ?)\").run(\n session.sessionId,\n JSON.stringify(session)\n );\n }\n\n async clearSession(sessionId: string): Promise<void> {\n const db = await this.dbPromise;\n db.prepare(\"DELETE FROM sessions WHERE id = ?\").run(sessionId);\n }\n\n private async openDatabase(): Promise<DatabaseAdapter> {\n try {\n await mkdir(dirname(this.dbPath), { recursive: true });\n const nodeSqliteName = \"node:sqlite\";\n const nodeSqlite = await import(nodeSqliteName).catch(() => null);\n\n if (nodeSqlite?.DatabaseSync) {\n const db = new nodeSqlite.DatabaseSync(this.dbPath) as DatabaseAdapter;\n db.exec(\"CREATE TABLE IF NOT EXISTS sessions (id TEXT PRIMARY KEY, data TEXT NOT NULL)\");\n return db;\n }\n\n const betterSqliteName = \"better-sqlite3\";\n const betterSqlite = await import(betterSqliteName).catch(() => null);\n if (betterSqlite?.default) {\n const db = new betterSqlite.default(this.dbPath) as DatabaseAdapter;\n db.exec(\"CREATE TABLE IF NOT EXISTS sessions (id TEXT PRIMARY KEY, data TEXT NOT NULL)\");\n return db;\n }\n\n throw new ContextStoreError(\n \"SQLite store requires node:sqlite support or the better-sqlite3 package.\"\n );\n } catch (error) {\n if (error instanceof ContextStoreError) {\n throw error;\n }\n\n throw new ContextStoreError(\"Failed to initialize SQLite session store.\");\n }\n }\n}\n\nfunction createEmptySession(sessionId: string): SessionData {\n const now = new Date().toISOString();\n return {\n sessionId,\n entries: [],\n summaries: [],\n createdAt: now,\n updatedAt: now\n };\n}\n","import type { Logger } from \"../types.js\";\n\nexport const noopLogger: Logger = {\n debug: () => undefined,\n info: () => undefined,\n warn: () => undefined,\n error: () => undefined\n};\n\nexport function createLogger(debugEnabled = false): Logger {\n return {\n debug(message, meta) {\n if (debugEnabled) {\n console.debug(`[promptpilot] ${message}`, meta ?? \"\");\n }\n },\n info(message, meta) {\n if (debugEnabled) {\n console.info(`[promptpilot] ${message}`, meta ?? \"\");\n }\n },\n warn(message, meta) {\n if (debugEnabled) {\n console.warn(`[promptpilot] ${message}`, meta ?? \"\");\n }\n },\n error(message, meta) {\n if (debugEnabled) {\n console.error(`[promptpilot] ${message}`, meta ?? \"\");\n }\n }\n };\n}\n","export function safeJsonParse<T>(value: string): T | null {\n try {\n return JSON.parse(value) as T;\n } catch {\n return null;\n }\n}\n\nexport function extractFirstJsonObject(value: string): string | null {\n const start = value.indexOf(\"{\");\n if (start === -1) {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escaped = false;\n\n for (let index = start; index < value.length; index += 1) {\n const char = value[index];\n\n if (escaped) {\n escaped = false;\n continue;\n }\n\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n\n if (char === \"\\\"\") {\n inString = !inString;\n continue;\n }\n\n if (inString) {\n continue;\n }\n\n if (char === \"{\") {\n depth += 1;\n } else if (char === \"}\") {\n depth -= 1;\n if (depth === 0) {\n return value.slice(start, index + 1);\n }\n }\n }\n\n return null;\n}\n\nexport function toPrettyJson(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n","import { OllamaUnavailableError } from \"../errors.js\";\nimport type { Logger, OllamaClientLike, OllamaGenerateOptions, OllamaModelInfo } from \"../types.js\";\nimport { extractFirstJsonObject, safeJsonParse } from \"../utils/json.js\";\nimport { noopLogger } from \"../utils/logger.js\";\n\ninterface OllamaClientConfig {\n host?: string;\n model?: string;\n timeoutMs?: number;\n temperature?: number;\n logger?: Logger;\n}\n\nexport class OllamaClient implements OllamaClientLike {\n readonly host: string;\n readonly model: string;\n readonly timeoutMs: number;\n readonly temperature: number;\n readonly logger: Logger;\n\n constructor(config: OllamaClientConfig = {}) {\n this.host = config.host ?? \"http://localhost:11434\";\n this.model = config.model ?? \"qwen2.5:3b\";\n this.timeoutMs = config.timeoutMs ?? 30000;\n this.temperature = config.temperature ?? 0.1;\n this.logger = config.logger ?? noopLogger;\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n const response = await fetch(new URL(\"/api/tags\", this.host), {\n method: \"GET\"\n });\n\n return response.ok;\n } catch {\n return false;\n }\n }\n\n async listModels(): Promise<OllamaModelInfo[]> {\n try {\n const response = await fetch(new URL(\"/api/tags\", this.host), {\n method: \"GET\"\n });\n\n if (!response.ok) {\n throw new OllamaUnavailableError(`Ollama tags request failed with status ${response.status}.`);\n }\n\n const data = (await response.json()) as {\n models?: Array<{\n name?: string;\n size?: number;\n modified_at?: string;\n details?: {\n family?: string;\n parameter_size?: string;\n };\n }>;\n };\n\n return (data.models ?? [])\n .filter((model) => typeof model.name === \"string\" && model.name.length > 0)\n .map((model) => ({\n name: model.name as string,\n sizeBytes: model.size,\n family: model.details?.family,\n parameterSize: model.details?.parameter_size,\n modifiedAt: model.modified_at\n }));\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown Ollama tags error.\";\n this.logger.warn(\"ollama.list_models.failed\", { message });\n throw new OllamaUnavailableError(message);\n }\n }\n\n async generate(options: OllamaGenerateOptions): Promise<string> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs ?? this.timeoutMs);\n\n try {\n const response = await fetch(new URL(\"/api/generate\", this.host), {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({\n model: options.model ?? this.model,\n system: options.systemPrompt,\n prompt: options.prompt,\n stream: false,\n format: options.format === \"json\" ? \"json\" : undefined,\n options: {\n temperature: options.temperature ?? this.temperature\n }\n }),\n signal: controller.signal\n });\n\n if (!response.ok) {\n throw new OllamaUnavailableError(`Ollama request failed with status ${response.status}.`);\n }\n\n const data = (await response.json()) as { response?: string };\n if (!data.response || typeof data.response !== \"string\") {\n throw new OllamaUnavailableError(\"Ollama did not return a text response.\");\n }\n\n return data.response.trim();\n } catch (error) {\n if (error instanceof OllamaUnavailableError) {\n throw error;\n }\n\n const message = error instanceof Error ? error.message : \"Unknown Ollama error.\";\n this.logger.warn(\"ollama.generate.failed\", { message });\n throw new OllamaUnavailableError(message);\n } finally {\n clearTimeout(timeout);\n }\n }\n\n async generateJson<T>(options: OllamaGenerateOptions): Promise<T> {\n const raw = await this.generate({\n ...options,\n format: \"json\"\n });\n\n const direct = safeJsonParse<T>(raw);\n if (direct) {\n return direct;\n }\n\n const extracted = extractFirstJsonObject(raw);\n if (extracted) {\n const parsed = safeJsonParse<T>(extracted);\n if (parsed) {\n return parsed;\n }\n }\n\n throw new OllamaUnavailableError(\"Ollama returned JSON that could not be parsed.\");\n }\n\n async generateJsonWithTextFallback<T>(options: OllamaGenerateOptions, textFallbackHandler: (text: string) => T): Promise<T> {\n try {\n return await this.generateJson<T>(options);\n } catch {\n // Text-only model or JSON parsing failed, fall back to text output\n const raw = await this.generate({\n ...options,\n format: undefined\n });\n return textFallbackHandler(raw);\n }\n }\n}\n","import type { OptimizationMode, OptimizePromptInput, PromptPreset } from \"../types.js\";\n\nconst modeGuidance: Record<OptimizationMode, string> = {\n clarity: \"Improve clarity, remove ambiguity, and keep the request easy for a downstream model to follow.\",\n concise: \"Minimize token count while preserving user intent, constraints, and expected output.\",\n detailed: \"Make the request explicit and complete, including structure and success criteria.\",\n structured: \"Organize the request into sections only when that improves clarity or token efficiency.\",\n persuasive: \"Refine wording so the request is compelling and likely to elicit a thoughtful response.\",\n compress: \"Aggressively compress redundant wording while preserving the meaning and critical constraints.\",\n claude_cli: \"Optimize specifically for Claude CLI: compact sections, direct instructions, and minimal boilerplate.\"\n};\n\nconst presetGuidance: Record<PromptPreset, string> = {\n code: \"Favor precise technical requirements, edge cases, expected output format, and a compact inspect-plan-act-test-reflect loop for code tasks.\",\n email: \"Preserve the sender's goal, tone, and audience; aim for a realistic and usable writing request.\",\n essay: \"Preserve thesis, structure, and voice guidance while making the prompt clearer.\",\n support: \"Favor concise issue context, user impact, and desired resolution details.\",\n summarization: \"Favor strong compression while retaining key facts, structure, and takeaways.\",\n chat: \"Keep the prompt natural and conversational while preserving instructions and context.\"\n};\n\nexport function getOptimizationSystemPrompt(mode: OptimizationMode, preset?: PromptPreset): string {\n return [\n \"You are PromptPilot, a local prompt optimizer for downstream LLM workflows.\",\n \"Return strict JSON only with this shape:\",\n \"{\\\"optimizedPrompt\\\":\\\"string\\\",\\\"constraints\\\":[\\\"string\\\"],\\\"changes\\\":[\\\"string\\\"],\\\"warnings\\\":[\\\"string\\\"]}\",\n \"Rules:\",\n \"- Do not change the user's intent.\",\n \"- Do not invent new requirements.\",\n \"- Preserve critical constraints and task goals.\",\n \"- Improve clarity, structure, and downstream usefulness.\",\n \"- Keep the result compact when the mode requests compression.\",\n \"- Do not force sections when direct phrasing is shorter and equally clear.\",\n \"- Remove redundancy aggressively when the source prompt repeats the same goal multiple ways.\",\n \"- For code tasks, prefer a terse agent brief over narrative prose.\",\n \"- For code tasks, structure the prompt around a Karpathy-style loop: inspect, plan, act, test, reflect, repeat.\",\n `Mode guidance: ${modeGuidance[mode]}`,\n preset ? `Preset guidance: ${presetGuidance[preset]}` : \"Preset guidance: none\"\n ].join(\"\\n\");\n}\n\nexport function buildOptimizationPrompt(\n input: OptimizePromptInput,\n relevantContext: string,\n extractedConstraints: string[]\n): string {\n const payload = {\n prompt: input.prompt,\n task: input.task ?? null,\n tone: input.tone ?? null,\n targetModel: input.targetModel ?? \"claude\",\n outputFormat: input.outputFormat ?? null,\n maxLength: input.maxLength ?? null,\n mode: input.mode ?? \"claude_cli\",\n preset: input.preset ?? null,\n pinnedConstraints: input.pinnedConstraints ?? [],\n extractedConstraints,\n relevantContext\n };\n\n return `Optimize this prompt payload for a downstream LLM.\\n${JSON.stringify(payload, null, 2)}`;\n}\n","import type { TokenUsageEstimate } from \"../types.js\";\nimport { normalizeWhitespace } from \"../utils/validation.js\";\n\nexport class TokenEstimator {\n estimateText(text: string): number {\n const normalized = normalizeWhitespace(text);\n if (!normalized) {\n return 0;\n }\n\n const wordCount = normalized.split(/\\s+/).length;\n const charCount = normalized.length;\n return Math.max(1, Math.ceil(wordCount * 1.3), Math.ceil(charCount / 4));\n }\n\n estimateUsage(input: { prompt: string; context?: string }): TokenUsageEstimate {\n const prompt = this.estimateText(input.prompt);\n const context = this.estimateText(input.context ?? \"\");\n return {\n prompt,\n context,\n total: prompt + context\n };\n }\n\n truncateToBudget(text: string, tokenBudget: number): string {\n const normalized = normalizeWhitespace(text);\n if (tokenBudget <= 0 || !normalized) {\n return \"\";\n }\n\n if (this.estimateText(normalized) <= tokenBudget) {\n return normalized;\n }\n\n const words = normalized.split(/\\s+/);\n const selected: string[] = [];\n\n for (const word of words) {\n const candidate = [...selected, word].join(\" \");\n if (this.estimateText(candidate) > tokenBudget) {\n break;\n }\n\n selected.push(word);\n }\n\n return selected.join(\" \").trim();\n }\n}\n","import { randomUUID } from \"node:crypto\";\n\nimport type { ContextEntry, ContextSummary, Logger, OllamaClientLike } from \"../types.js\";\nimport { TokenEstimator } from \"./tokenEstimator.js\";\nimport { getOptimizationSystemPrompt } from \"./systemPrompt.js\";\nimport { noopLogger } from \"../utils/logger.js\";\n\ninterface SummarizeContextOptions {\n sessionId: string;\n entries: ContextEntry[];\n prompt: string;\n task?: string;\n budgetTokens: number;\n timeoutMs?: number;\n}\n\ninterface ContextSummaryJson {\n optimizedPrompt: string;\n constraints?: string[];\n changes?: string[];\n}\n\nexport class ContextCompressor {\n constructor(\n private readonly estimator: TokenEstimator,\n private readonly client?: OllamaClientLike,\n private readonly logger: Logger = noopLogger\n ) {}\n\n async summarizeEntries(options: SummarizeContextOptions): Promise<ContextSummary | null> {\n if (options.entries.length === 0 || options.budgetTokens <= 0) {\n return null;\n }\n\n const ollamaSummary = await this.tryOllamaSummary(options);\n if (ollamaSummary) {\n return ollamaSummary;\n }\n\n return this.heuristicSummary(options);\n }\n\n private async tryOllamaSummary(options: SummarizeContextOptions): Promise<ContextSummary | null> {\n if (!this.client || options.entries.length < 3) {\n return null;\n }\n\n try {\n const source = options.entries\n .slice(-8)\n .map((entry) => [\n `Timestamp: ${entry.timestamp}`,\n entry.task ? `Task: ${entry.task}` : \"\",\n entry.constraints?.length ? `Constraints: ${entry.constraints.join(\"; \")}` : \"\",\n `Prompt: ${entry.rawPrompt ?? entry.text}`\n ].filter(Boolean).join(\"\\n\"))\n .join(\"\\n\\n\");\n\n const response = await this.client.generateJson<ContextSummaryJson>({\n systemPrompt: getOptimizationSystemPrompt(\"compress\"),\n prompt: `Summarize this stored prompt context for reuse in later turns.\\nPrompt: ${options.prompt}\\nTask: ${options.task ?? \"unknown\"}\\nBudget tokens: ${options.budgetTokens}\\n\\n${source}`,\n timeoutMs: options.timeoutMs,\n format: \"json\"\n });\n\n const summaryText = this.estimator.truncateToBudget(response.optimizedPrompt ?? \"\", options.budgetTokens);\n if (!summaryText) {\n return null;\n }\n\n return {\n id: randomUUID(),\n sessionId: options.sessionId,\n text: summaryText,\n createdAt: new Date().toISOString(),\n sourceEntryIds: options.entries.map((entry) => entry.id),\n tokenEstimate: this.estimator.estimateText(summaryText),\n kind: \"ollama\"\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown summary failure\";\n this.logger.debug(\"context.summary.ollama_fallback\", { message });\n return null;\n }\n }\n\n private heuristicSummary(options: SummarizeContextOptions): ContextSummary {\n const constraints = Array.from(\n new Set(options.entries.flatMap((entry) => entry.constraints ?? []).filter(Boolean))\n ).slice(0, 6);\n\n const recentPrompts = options.entries\n .slice(-4)\n .map((entry) => `- ${truncateLine(entry.rawPrompt ?? entry.text, 120)}`);\n\n const lines = [\n constraints.length ? `Key constraints: ${constraints.join(\"; \")}` : \"\",\n recentPrompts.length ? `Recent focus:\\n${recentPrompts.join(\"\\n\")}` : \"\"\n ].filter(Boolean);\n\n const summaryText = this.estimator.truncateToBudget(lines.join(\"\\n\\n\"), options.budgetTokens);\n\n return {\n id: randomUUID(),\n sessionId: options.sessionId,\n text: summaryText,\n createdAt: new Date().toISOString(),\n sourceEntryIds: options.entries.map((entry) => entry.id),\n tokenEstimate: this.estimator.estimateText(summaryText),\n kind: \"heuristic\"\n };\n }\n}\n\nfunction truncateLine(value: string, maxLength: number): string {\n if (value.length <= maxLength) {\n return value;\n }\n\n return `${value.slice(0, maxLength - 3).trim()}...`;\n}\n","import { randomUUID } from \"node:crypto\";\n\nimport type {\n ContextEntry,\n ContextSummary,\n Logger,\n OptimizePromptInput,\n RelevantContextResult,\n SessionStore\n} from \"../types.js\";\nimport { TokenEstimator } from \"./tokenEstimator.js\";\nimport { ContextCompressor } from \"./contextCompressor.js\";\nimport { noopLogger } from \"../utils/logger.js\";\n\ninterface GetRelevantContextOptions {\n sessionId: string;\n prompt: string;\n task?: string;\n tags?: string[];\n pinnedConstraints?: string[];\n maxContextTokens: number;\n timeoutMs?: number;\n}\n\ninterface SaveContextOptions {\n sessionId: string;\n input: OptimizePromptInput;\n optimizedPrompt: string;\n finalPrompt: string;\n contextSummary: ContextSummary | null;\n}\n\nexport class ContextManager {\n constructor(\n private readonly store: SessionStore,\n private readonly estimator: TokenEstimator,\n private readonly compressor: ContextCompressor,\n private readonly logger: Logger = noopLogger\n ) {}\n\n async loadContext(sessionId: string) {\n return this.store.loadSession(sessionId);\n }\n\n async clearContext(sessionId: string): Promise<void> {\n await this.store.clearSession(sessionId);\n }\n\n async saveContext(options: SaveContextOptions): Promise<void> {\n const session = await this.store.loadSession(options.sessionId);\n const timestamp = new Date().toISOString();\n const constraints = Array.from(\n new Set([\n ...extractConstraints(options.input.prompt),\n ...(options.input.pinnedConstraints ?? [])\n ])\n );\n const entry: ContextEntry = {\n id: randomUUID(),\n sessionId: options.sessionId,\n text: options.optimizedPrompt,\n rawPrompt: options.input.prompt,\n optimizedPrompt: options.optimizedPrompt,\n finalPrompt: options.finalPrompt,\n task: options.input.task,\n tone: options.input.tone,\n tags: options.input.tags ?? [],\n constraints,\n entities: extractEntities(options.input.prompt),\n pinned: (options.input.pinnedConstraints?.length ?? 0) > 0,\n timestamp,\n tokenEstimate: this.estimator.estimateText(options.finalPrompt)\n };\n\n session.entries.push(entry);\n if (session.entries.length > 100) {\n session.entries = session.entries.slice(-100);\n }\n\n if (options.contextSummary) {\n session.summaries.push(options.contextSummary);\n if (session.summaries.length > 10) {\n session.summaries = session.summaries.slice(-10);\n }\n }\n\n session.updatedAt = timestamp;\n await this.store.saveSession(session);\n this.logger.debug(\"context saved\", {\n sessionId: options.sessionId,\n entryCount: session.entries.length,\n summaryCount: session.summaries.length\n });\n }\n\n async summarizeContext(\n sessionId: string,\n prompt: string,\n task: string | undefined,\n budgetTokens: number,\n timeoutMs?: number\n ): Promise<ContextSummary | null> {\n const session = await this.store.loadSession(sessionId);\n if (session.entries.length === 0) {\n return null;\n }\n\n return this.compressor.summarizeEntries({\n sessionId,\n entries: session.entries,\n prompt,\n task,\n budgetTokens,\n timeoutMs\n });\n }\n\n async getRelevantContext(options: GetRelevantContextOptions): Promise<RelevantContextResult> {\n const session = await this.store.loadSession(options.sessionId);\n if (session.entries.length === 0 && session.summaries.length === 0) {\n return {\n usedEntries: [],\n summary: null,\n warnings: [],\n debugInfo: { scores: [] }\n };\n }\n\n const scores = session.entries.map((entry, index) => ({\n entry,\n score: scoreEntry({\n entry,\n prompt: options.prompt,\n task: options.task,\n tags: options.tags,\n pinnedConstraints: options.pinnedConstraints,\n index,\n total: session.entries.length\n })\n }));\n\n const selected: ContextEntry[] = [];\n const seenFingerprints = new Set<string>();\n let selectedTokens = 0;\n\n for (const scored of scores.sort((left, right) => right.score - left.score)) {\n if (selected.find((entry) => entry.id === scored.entry.id)) {\n continue;\n }\n\n const fingerprint = createFingerprint(scored.entry);\n if (seenFingerprints.has(fingerprint)) {\n continue;\n }\n\n if (selectedTokens + scored.entry.tokenEstimate > options.maxContextTokens) {\n continue;\n }\n\n selected.push(scored.entry);\n seenFingerprints.add(fingerprint);\n selectedTokens += scored.entry.tokenEstimate;\n }\n\n const remainder = session.entries.filter(\n (entry) => !selected.find((selectedEntry) => selectedEntry.id === entry.id)\n );\n\n let summary: ContextSummary | null = null;\n if (remainder.length > 1 && selectedTokens < Math.floor(options.maxContextTokens * 0.8)) {\n summary = await this.compressor.summarizeEntries({\n sessionId: options.sessionId,\n entries: remainder,\n prompt: options.prompt,\n task: options.task,\n budgetTokens: Math.max(80, options.maxContextTokens - selectedTokens),\n timeoutMs: options.timeoutMs\n });\n } else if (session.summaries.length > 0) {\n const latest = session.summaries.at(-1) ?? null;\n if (latest && latest.tokenEstimate <= options.maxContextTokens - selectedTokens) {\n summary = latest;\n }\n }\n\n const warnings: string[] = [];\n if (remainder.length > 0) {\n warnings.push(`Dropped ${remainder.length} lower-value context item(s) to fit the token budget.`);\n }\n\n return {\n usedEntries: selected.sort((left, right) => left.timestamp.localeCompare(right.timestamp)),\n summary,\n warnings,\n debugInfo: {\n scores: scores\n .sort((left, right) => right.score - left.score)\n .map(({ entry, score }) => ({ id: entry.id, score, task: entry.task, timestamp: entry.timestamp }))\n }\n };\n }\n}\n\nfunction scoreEntry(input: {\n entry: ContextEntry;\n prompt: string;\n task?: string;\n tags?: string[];\n pinnedConstraints?: string[];\n index: number;\n total: number;\n}): number {\n const promptTerms = tokenize(input.prompt);\n const promptEntities = new Set(extractEntities(input.prompt).map((entity) => entity.toLowerCase()));\n const entryTerms = tokenize(\n [input.entry.rawPrompt, input.entry.optimizedPrompt, input.entry.constraints?.join(\" \")].filter(Boolean).join(\" \")\n );\n const entryEntities = new Set((input.entry.entities ?? []).map((entity) => entity.toLowerCase()));\n\n const overlap = Array.from(promptTerms).filter((term) => entryTerms.has(term)).length;\n const entityOverlap = Array.from(promptEntities).filter((entity) => entryEntities.has(entity)).length;\n const taskMatch = input.task && input.entry.task === input.task ? 2 : 0;\n const pinned = input.entry.pinned ? 3 : 0;\n const pinnedConstraintMatch = Array.from(new Set(input.pinnedConstraints ?? [])).filter((constraint) =>\n (input.entry.constraints ?? []).includes(constraint)\n ).length;\n const tagOverlap = Array.from(new Set(input.tags ?? [])).filter((tag) => (input.entry.tags ?? []).includes(tag)).length;\n const constraintBonus = (input.entry.constraints?.length ?? 0) > 0 ? 0.75 : 0;\n const recency = (input.index + 1) / input.total;\n\n return overlap * 0.8 + entityOverlap * 1.2 + taskMatch + pinned + pinnedConstraintMatch * 2 + tagOverlap + constraintBonus + recency;\n}\n\nfunction tokenize(value: string): Set<string> {\n return new Set(\n value\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .filter((token) => token.length > 2)\n );\n}\n\nexport function extractConstraints(value: string): string[] {\n return Array.from(\n new Set(\n value\n .split(/\\n+/)\n .flatMap((line) => line.split(/(?<=[.!?])\\s+/))\n .map((line) => line.trim().replace(/^[-*]\\s*/, \"\"))\n .filter((line) => line.length > 0 && line.length <= 180)\n .filter((line) => /(must|should|avoid|do not|don't|never|exactly|at most|under|limit|max|preserve|keep)/i.test(line))\n )\n ).slice(0, 8);\n}\n\nexport function extractEntities(value: string): string[] {\n return Array.from(\n new Set(value.match(/\\b[A-Z][a-zA-Z0-9._-]+\\b/g) ?? [])\n ).slice(0, 12);\n}\n\nfunction createFingerprint(entry: ContextEntry): string {\n return [entry.task ?? \"\", entry.rawPrompt ?? entry.text]\n .join(\"::\")\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .trim();\n}\n","import type { OllamaModelInfo, OptimizationMode, PromptPreset } from \"../types.js\";\n\nconst DEFAULT_SMALL_MODEL_PREFERENCES = [\n \"qwen2.5:3b\",\n \"phi3:mini\",\n \"llama3.2:3b\",\n \"qwen2.5:1.5b\"\n];\n\nexport interface ModelSelectionInput {\n installedModels: OllamaModelInfo[];\n mode: OptimizationMode;\n preset: PromptPreset;\n task?: string;\n preferredModels?: string[];\n}\n\nexport interface ModelSelectionResult {\n model: string;\n reason: string;\n suitableForAutoUse: boolean;\n}\n\nexport function getDefaultPreferredModels(): string[] {\n return [...DEFAULT_SMALL_MODEL_PREFERENCES];\n}\n\nexport function getSuitableAutoModels(installedModels: OllamaModelInfo[]): OllamaModelInfo[] {\n return installedModels.filter((model) => isSuitableSmallModel(model));\n}\n\nexport function getQwenRouterModel(\n installedModels: OllamaModelInfo[],\n explicitRouterModel?: string\n): string | null {\n if (explicitRouterModel) {\n const match = installedModels.find((model) => model.name === explicitRouterModel);\n return match?.name ?? null;\n }\n\n const qwenRouters = getSuitableAutoModels(installedModels)\n .filter((model) => /qwen/i.test(model.name))\n .sort((left, right) => scoreRouterModel(right) - scoreRouterModel(left));\n\n return qwenRouters[0]?.name ?? null;\n}\n\nexport function selectOllamaModel(input: ModelSelectionInput): ModelSelectionResult {\n const smallCandidates = getSuitableAutoModels(input.installedModels);\n if (smallCandidates.length === 1) {\n return {\n model: smallCandidates[0].name,\n reason: `Selected installed model \"${smallCandidates[0].name}\" because it is the only suitable small local model available.`,\n suitableForAutoUse: true\n };\n }\n\n if (smallCandidates.length > 1) {\n return {\n model: \"\",\n reason: `Multiple suitable small local models are available (${smallCandidates.map((model) => model.name).join(\", \")}), so a Qwen router must choose between them.`,\n suitableForAutoUse: false\n };\n }\n\n const oversizedRanked = [...input.installedModels]\n .filter((model) => isUsefulGenerationModel(model.name))\n .sort((left, right) => compareModelNames(left.name, right.name));\n\n if (oversizedRanked[0]) {\n return {\n model: oversizedRanked[0].name,\n reason: `Installed model \"${oversizedRanked[0].name}\" was detected, but it is larger than the preferred low-memory range for auto-use.`,\n suitableForAutoUse: false\n };\n }\n\n return {\n model: \"\",\n reason: \"No suitable local generation models were discovered for automatic routing.\",\n suitableForAutoUse: false\n };\n}\n\nfunction extractBillions(modelName: string): number | null {\n const match = modelName.match(/(\\d+(?:\\.\\d+)?)b/);\n if (!match) {\n return null;\n }\n\n return Number.parseFloat(match[1]);\n}\n\nfunction isUsefulGenerationModel(modelName: string): boolean {\n const lower = modelName.toLowerCase();\n return ![\n \"embed\",\n \"embedding\",\n \"whisper\",\n \"vision\",\n \"diffusion\",\n \"tts\",\n \"bge\",\n \"nomic-embed\"\n ].some((blocked) => lower.includes(blocked));\n}\n\nfunction isSuitableSmallModel(model: OllamaModelInfo): boolean {\n if (!isUsefulGenerationModel(model.name)) {\n return false;\n }\n\n const byParameter = extractBillions(`${model.parameterSize ?? \"\"} ${model.name}`);\n if (byParameter !== null) {\n return byParameter <= 4;\n }\n\n if (typeof model.sizeBytes === \"number\") {\n return model.sizeBytes <= 5_500_000_000;\n }\n\n return /mini|1\\.5b|2b|3b|4b/i.test(model.name);\n}\n\nfunction scoreRouterModel(model: OllamaModelInfo): number {\n const lower = model.name.toLowerCase();\n let score = 0;\n if (lower.includes(\"qwen2.5\")) {\n score += 3;\n }\n if (lower.includes(\"3b\")) {\n score += 2;\n } else if (lower.includes(\"1.5b\")) {\n score += 1;\n }\n if (lower.includes(\"coder\")) {\n score -= 1;\n }\n return score;\n}\n\nfunction compareModelNames(left: string, right: string): number {\n return left.localeCompare(right);\n}\n","import type {\n OptimizationMode,\n OptimizePromptInput,\n OptimizePromptResult,\n OptimizerConfig,\n PromptPreset,\n ProviderType,\n RelevantContextResult,\n SessionStore,\n RankedTargetCandidate,\n RoutingDecision,\n RoutingPriority,\n TargetCapability,\n TargetModelCandidate,\n WorkloadBias\n} from \"../types.js\";\nimport { TokenBudgetExceededError } from \"../errors.js\";\nimport { FileSessionStore } from \"../storage/fileSessionStore.js\";\nimport { SQLiteSessionStore } from \"../storage/sqliteSessionStore.js\";\nimport { noopLogger } from \"../utils/logger.js\";\nimport { normalizeWhitespace, validatePrompt } from \"../utils/validation.js\";\nimport { OllamaClient } from \"./ollamaClient.js\";\nimport { getOptimizationSystemPrompt, buildOptimizationPrompt } from \"./systemPrompt.js\";\nimport { TokenEstimator } from \"./tokenEstimator.js\";\nimport { ContextCompressor } from \"./contextCompressor.js\";\nimport { ContextManager, extractConstraints } from \"./contextManager.js\";\nimport {\n getDefaultPreferredModels,\n getQwenRouterModel,\n getSuitableAutoModels,\n selectOllamaModel\n} from \"./modelSelector.js\";\n\ninterface OptimizationResponse {\n optimizedPrompt?: string;\n constraints?: string[];\n changes?: string[];\n warnings?: string[];\n}\n\ninterface ModelRoutingResponse {\n selectedModel?: string;\n reason?: string;\n}\n\ninterface DownstreamRoutingResponse {\n selectedTargetId?: string;\n rankedTargetIds?: string[];\n reason?: string;\n}\n\nconst DEFAULT_MODE: OptimizationMode = \"claude_cli\";\nconst DEFAULT_PRESET: PromptPreset = \"chat\";\nconst DEFAULT_PROVIDER: ProviderType = \"ollama\";\nconst DEFAULT_MAX_INPUT_TOKENS = 1200;\nconst DEFAULT_MAX_CONTEXT_TOKENS = 800;\nconst DEFAULT_MAX_TOTAL_TOKENS = 2200;\nconst DEFAULT_ROUTING_PRIORITY: RoutingPriority = \"cheapest_adequate\";\nconst DEFAULT_ROUTING_TOP_K = 3;\nconst DEFAULT_WORKLOAD_BIAS: WorkloadBias = \"code_first\";\n\nexport class PromptOptimizer {\n readonly config: OptimizerConfig & {\n host: string;\n timeoutMs: number;\n temperature: number;\n preferredModels: string[];\n modelRoutingStrategy: \"qwen\";\n };\n\n private readonly logger;\n private readonly estimator;\n private readonly client;\n private readonly compressor;\n private readonly contextManager;\n\n constructor(config: OptimizerConfig = {}) {\n this.logger = config.logger ?? noopLogger;\n this.estimator = new TokenEstimator();\n this.client =\n config.ollamaClient ??\n new OllamaClient({\n host: config.host,\n model: config.ollamaModel,\n timeoutMs: config.timeoutMs,\n temperature: config.temperature,\n logger: this.logger\n });\n\n const store = resolveSessionStore(config);\n this.compressor = new ContextCompressor(this.estimator, this.client, this.logger);\n this.contextManager = new ContextManager(store, this.estimator, this.compressor, this.logger);\n\n this.config = {\n ...config,\n host: config.host ?? \"http://localhost:11434\",\n ollamaModel: config.ollamaModel,\n preferredModels: config.preferredModels ?? getDefaultPreferredModels(),\n modelRoutingStrategy: \"qwen\",\n timeoutMs: config.timeoutMs ?? 30000,\n temperature: config.temperature ?? 0.1\n };\n }\n\n async optimize(input: OptimizePromptInput): Promise<OptimizePromptResult> {\n const originalPrompt = validatePrompt(input.prompt);\n const mode = input.mode ?? this.config.defaultMode ?? DEFAULT_MODE;\n const preset = input.preset ?? this.config.defaultPreset ?? DEFAULT_PRESET;\n const maxInputTokens = input.maxInputTokens ?? this.config.maxInputTokens ?? DEFAULT_MAX_INPUT_TOKENS;\n const maxContextTokens = input.maxContextTokens ?? this.config.maxContextTokens ?? DEFAULT_MAX_CONTEXT_TOKENS;\n const maxTotalTokens = input.maxTotalTokens ?? this.config.maxTotalTokens ?? DEFAULT_MAX_TOTAL_TOKENS;\n const routingEnabled = input.routingEnabled !== false;\n const routingPriority = input.routingPriority ?? DEFAULT_ROUTING_PRIORITY;\n const routingTopK = input.routingTopK ?? DEFAULT_ROUTING_TOP_K;\n const workloadBias = input.workloadBias ?? DEFAULT_WORKLOAD_BIAS;\n const warnings: string[] = [];\n const changes: string[] = [];\n\n const useContext = input.useContext !== false && Boolean(input.sessionId);\n const saveContext = input.saveContext ?? Boolean(input.sessionId);\n const relevantContext = useContext && input.sessionId\n ? await this.contextManager.getRelevantContext({\n sessionId: input.sessionId,\n prompt: originalPrompt,\n task: input.task,\n tags: input.tags,\n pinnedConstraints: input.pinnedConstraints,\n maxContextTokens,\n timeoutMs: input.timeoutMs ?? this.config.timeoutMs\n })\n : emptyRelevantContext();\n\n warnings.push(...relevantContext.warnings);\n\n const contextBlock = formatContextBlock(relevantContext);\n const estimatedTokensBefore = this.estimator.estimateUsage({\n prompt: originalPrompt,\n context: contextBlock\n });\n\n if (estimatedTokensBefore.prompt > maxInputTokens) {\n warnings.push(\n `Raw prompt estimate (${estimatedTokensBefore.prompt}) exceeds maxInputTokens (${maxInputTokens}).`\n );\n }\n\n const extractedConstraints = Array.from(\n new Set([...extractConstraints(originalPrompt), ...(input.pinnedConstraints ?? [])])\n );\n\n let provider: ProviderType = input.bypassOptimization ? \"heuristic\" : this.config.provider ?? DEFAULT_PROVIDER;\n let model = provider === \"ollama\" ? this.config.ollamaModel ?? \"auto\" : \"heuristic\";\n let usedPreprocessedFallback = false;\n\n let optimizedPrompt = originalPrompt;\n let providerWarnings: string[] = [];\n let providerChanges: string[] = [];\n\n if (provider === \"ollama\") {\n const modelSelection = await this.resolveOllamaModel({\n prompt: originalPrompt,\n mode,\n preset,\n task: input.task\n });\n model = modelSelection.model;\n providerWarnings.push(...modelSelection.warnings);\n if (input.debug) {\n changes.push(modelSelection.reason);\n }\n\n if (modelSelection.forceHeuristic) {\n provider = \"heuristic\";\n model = \"heuristic\";\n }\n\n const ollamaResult = provider === \"ollama\"\n ? await this.tryOllamaOptimization({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n model,\n extractedConstraints,\n relevantContext: contextBlock\n })\n : null;\n\n if (ollamaResult) {\n optimizedPrompt = ollamaResult.optimizedPrompt;\n providerWarnings = ollamaResult.warnings;\n providerChanges = ollamaResult.changes;\n if (ollamaResult.source === \"preprocessed\") {\n provider = \"heuristic\";\n model = \"cheap-preprocess\";\n usedPreprocessedFallback = true;\n }\n } else if (provider === \"ollama\") {\n provider = \"heuristic\";\n model = \"heuristic\";\n providerWarnings = [\n `Ollama was unavailable. Falling back to deterministic local prompt shaping.`\n ];\n }\n }\n\n if (provider === \"heuristic\" && !usedPreprocessedFallback) {\n const fallback = this.heuristicOptimize({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n context: relevantContext,\n constraints: extractedConstraints\n });\n optimizedPrompt = fallback.optimizedPrompt;\n providerChanges = [...providerChanges, ...fallback.changes];\n providerWarnings = [...providerWarnings, ...fallback.warnings];\n }\n\n warnings.push(...providerWarnings);\n changes.push(...providerChanges);\n\n const routingDecision = await this.routeDownstreamTargets({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset,\n routingPriority,\n routingTopK,\n workloadBias\n },\n routingEnabled,\n routingPriority,\n routingTopK,\n workloadBias\n });\n\n warnings.push(...routingDecision.routingWarnings);\n\n let finalPrompt = composeFinalPrompt({\n optimizedPrompt,\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n context: relevantContext,\n routingDecision\n });\n\n let estimatedTokensAfter = {\n prompt: this.estimator.estimateText(optimizedPrompt),\n context: this.estimator.estimateText(formatContextBlock(relevantContext)),\n total: this.estimator.estimateText(finalPrompt)\n };\n\n if (estimatedTokensAfter.total > maxTotalTokens) {\n const reduced = await this.reduceToBudget({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n optimizedPrompt,\n context: relevantContext,\n routingDecision,\n maxTotalTokens\n });\n\n finalPrompt = reduced.finalPrompt;\n estimatedTokensAfter = reduced.estimatedTokensAfter;\n if (reduced.warning) {\n warnings.push(reduced.warning);\n }\n }\n\n if (estimatedTokensAfter.total > maxTotalTokens) {\n throw new TokenBudgetExceededError();\n }\n\n if (saveContext && input.sessionId) {\n await this.contextManager.saveContext({\n sessionId: input.sessionId,\n input: {\n ...input,\n prompt: originalPrompt\n },\n optimizedPrompt,\n finalPrompt,\n contextSummary: relevantContext.summary\n });\n }\n\n // Calculate granular token savings.\n // estimatedTokensBefore.total is raw prompt + context (no wrapper).\n // estimatedTokensAfter.total is the fully wrapped finalPrompt, so comparing them\n // directly penalises savings by wrapper overhead that was never present before.\n // tokenSavings reflects actual content reduction; wrapperOverhead is reported\n // separately so callers can account for the structural cost themselves.\n const originalPromptTokens = this.estimator.estimateText(originalPrompt);\n const promptCompressionSavings = Math.max(0, originalPromptTokens - estimatedTokensAfter.prompt);\n const contextCompressionSavings = Math.max(0, estimatedTokensBefore.context - estimatedTokensAfter.context);\n const wrapperOverhead = Math.max(0, estimatedTokensAfter.total - (estimatedTokensAfter.prompt + estimatedTokensAfter.context));\n const tokenSavings = promptCompressionSavings + contextCompressionSavings;\n\n return {\n originalPrompt,\n optimizedPrompt,\n finalPrompt,\n usedContext: relevantContext.usedEntries,\n contextSummary: relevantContext.summary,\n estimatedTokensBefore,\n estimatedTokensAfter,\n tokenSavings,\n promptCompressionSavings,\n contextCompressionSavings,\n wrapperOverhead,\n mode,\n provider,\n model,\n selectedTarget: routingDecision.selectedTarget,\n rankedTargets: routingDecision.rankedTargets,\n routingReason: routingDecision.routingReason,\n routingWarnings: routingDecision.routingWarnings,\n routingProvider: routingDecision.routingProvider,\n warnings,\n changes,\n debugInfo: input.debug\n ? {\n context: relevantContext.debugInfo,\n estimatedTokensBefore,\n estimatedTokensAfter,\n extractedConstraints,\n preset,\n selectedModel: model,\n routingDecision\n }\n : undefined\n };\n }\n\n async clearContext(sessionId: string): Promise<void> {\n await this.contextManager.clearContext(sessionId);\n }\n\n async loadContext(sessionId: string) {\n return this.contextManager.loadContext(sessionId);\n }\n\n async summarizeContext(sessionId: string, prompt: string, task?: string, budgetTokens = 200) {\n return this.contextManager.summarizeContext(sessionId, prompt, task, budgetTokens, this.config.timeoutMs);\n }\n\n async getRelevantContext(sessionId: string, prompt: string, task?: string, maxContextTokens?: number) {\n return this.contextManager.getRelevantContext({\n sessionId,\n prompt,\n task,\n maxContextTokens: maxContextTokens ?? this.config.maxContextTokens ?? DEFAULT_MAX_CONTEXT_TOKENS,\n timeoutMs: this.config.timeoutMs\n });\n }\n\n private async tryOllamaOptimization(options: {\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n model: string;\n extractedConstraints: string[];\n relevantContext: string;\n }): Promise<{ optimizedPrompt: string; changes: string[]; warnings: string[]; source: \"ollama\" | \"preprocessed\" } | null> {\n const preprocessedPrompt = cheapCompress(options.input.prompt);\n const preprocessedTokenCount = this.estimator.estimateText(preprocessedPrompt);\n const ultraMode = preprocessedTokenCount > 500;\n\n try {\n if (!(await this.client.isAvailable())) {\n return {\n optimizedPrompt: preprocessedPrompt,\n changes: [\"Applied cheap local preprocessing because Ollama was unavailable.\"],\n warnings: [\"Ollama was unavailable, so PromptPilot kept the cheap preprocessed prompt.\"],\n source: \"preprocessed\"\n };\n }\n\n const systemPrompt = ultraMode\n ? `${getOptimizationSystemPrompt(options.input.mode, options.input.preset)}\\nMode: Ultra compression. Minimize tokens aggressively.`\n : getOptimizationSystemPrompt(options.input.mode, options.input.preset);\n const optimizationPrompt = buildOptimizationPrompt(\n {\n ...options.input,\n prompt: preprocessedPrompt\n },\n options.relevantContext,\n options.extractedConstraints\n );\n\n const timeoutMs = options.input.timeoutMs ?? this.config.timeoutMs;\n\n let optimizedPrompt = \"\";\n let responseChanges: string[] = [];\n let responseWarnings: string[] = [];\n\n // Support text-only models with graceful fallback\n const generateWithFallback = this.client.generateJsonWithTextFallback\n ? async () => {\n const response = await this.client.generateJsonWithTextFallback!<OptimizationResponse>(\n {\n systemPrompt,\n prompt: optimizationPrompt,\n timeoutMs,\n model: options.model,\n temperature: this.config.temperature,\n format: \"json\"\n },\n (text: string) => ({\n optimizedPrompt: sanitizeTextOptimizationOutput(text),\n changes: [`Applied text-only Ollama optimization with ${options.model}.`],\n warnings: []\n } as OptimizationResponse)\n );\n return response;\n }\n : async () => {\n try {\n return await this.client.generateJson<OptimizationResponse>({\n systemPrompt,\n prompt: optimizationPrompt,\n timeoutMs,\n model: options.model,\n temperature: this.config.temperature,\n format: \"json\"\n });\n } catch {\n const raw = await this.client.generate({\n systemPrompt,\n prompt: optimizationPrompt,\n timeoutMs,\n model: options.model,\n temperature: this.config.temperature\n });\n\n return {\n optimizedPrompt: sanitizeTextOptimizationOutput(raw),\n changes: [`Applied text-only Ollama optimization with ${options.model}.`],\n warnings: []\n };\n }\n };\n\n const response = await generateWithFallback();\n optimizedPrompt = normalizeWhitespace(response.optimizedPrompt ?? \"\");\n responseChanges = response.changes ?? [];\n responseWarnings = response.warnings ?? [];\n\n if (!optimizedPrompt) {\n return {\n optimizedPrompt: preprocessedPrompt,\n changes: [\"Applied cheap local preprocessing because the model returned an empty optimization.\"],\n warnings: [\"The local optimizer returned an empty result, so PromptPilot kept the preprocessed prompt.\"],\n source: \"preprocessed\"\n };\n }\n\n const optimizedTokenCount = this.estimator.estimateText(optimizedPrompt);\n if (\n isCompressionSensitiveMode(options.input.mode) &&\n optimizedTokenCount >= preprocessedTokenCount\n ) {\n return {\n optimizedPrompt: preprocessedPrompt,\n changes: [\n ...responseChanges,\n \"Kept the cheap preprocessed prompt because the model output was not smaller.\"\n ],\n warnings: responseWarnings,\n source: \"preprocessed\"\n };\n }\n\n return {\n optimizedPrompt,\n changes: responseChanges.length > 0 ? responseChanges : [`Applied Ollama optimization with ${options.model}.`],\n warnings: responseWarnings,\n source: \"ollama\"\n };\n } catch {\n return {\n optimizedPrompt: preprocessedPrompt,\n changes: [\"Applied cheap local preprocessing because Ollama optimization failed.\"],\n warnings: [\"Ollama optimization failed, so PromptPilot kept the preprocessed prompt.\"],\n source: \"preprocessed\"\n };\n }\n }\n\n private async resolveOllamaModel(options: {\n prompt: string;\n mode: OptimizationMode;\n preset: PromptPreset;\n task?: string;\n }): Promise<{ model: string; warnings: string[]; reason: string; forceHeuristic: boolean }> {\n if (this.config.ollamaModel) {\n return {\n model: this.config.ollamaModel,\n warnings: [],\n reason: `Using explicitly configured model \"${this.config.ollamaModel}\".`,\n forceHeuristic: false\n };\n }\n\n if (!this.client.listModels) {\n return {\n model: \"heuristic\",\n warnings: [\n \"Model auto-selection is unavailable in the current Ollama client, so prompt optimization is falling back to deterministic heuristic formatting.\"\n ],\n reason: \"Model discovery is unsupported, so Qwen-based model routing could not run.\",\n forceHeuristic: true\n };\n }\n\n try {\n const installedModels = await this.client.listModels();\n const suitableModels = getSuitableAutoModels(installedModels);\n const selection = selectOllamaModel({\n installedModels,\n mode: options.mode,\n preset: options.preset,\n task: options.task,\n preferredModels: this.config.preferredModels\n });\n\n if (suitableModels.length === 0) {\n return {\n model: selection.model,\n warnings: [\n `No suitable small Ollama model was found for auto-use. Falling back to heuristic optimization. Install one of: ${this.config.preferredModels.join(\", \")}.`,\n selection.reason\n ],\n reason: selection.reason,\n forceHeuristic: true\n };\n }\n\n if (suitableModels.length === 1) {\n return {\n model: selection.model,\n warnings: [],\n reason: selection.reason,\n forceHeuristic: false\n };\n }\n\n if (this.config.modelRoutingStrategy === \"qwen\") {\n const routed = await this.tryQwenModelRouting({\n prompt: options.prompt,\n task: options.task,\n mode: options.mode,\n preset: options.preset,\n installedModels,\n candidateModels: suitableModels.map((model) => model.name),\n fallbackModel: selection.model\n });\n\n return {\n model: routed.model,\n warnings: routed.warnings,\n reason: routed.reason,\n forceHeuristic: routed.model === \"heuristic\"\n };\n }\n\n return {\n model: \"heuristic\",\n warnings: [\"Qwen model routing is required but was disabled, so prompt optimization is falling back to deterministic heuristic formatting.\"],\n reason: \"Qwen model routing is required but was disabled.\",\n forceHeuristic: true\n };\n } catch {\n return {\n model: \"heuristic\",\n warnings: [\n \"Failed to inspect local Ollama models, so prompt optimization is falling back to deterministic heuristic formatting.\"\n ],\n reason: \"Local Ollama model discovery failed, so Qwen-based model routing could not run.\",\n forceHeuristic: true\n };\n }\n }\n\n private async tryQwenModelRouting(options: {\n prompt: string;\n task?: string;\n mode: OptimizationMode;\n preset: PromptPreset;\n installedModels: { name: string }[];\n candidateModels: string[];\n fallbackModel: string;\n }): Promise<{ model: string; warnings: string[]; reason: string }> {\n const routerModel = getQwenRouterModel(\n options.installedModels,\n this.config.routerModel\n );\n\n if (!routerModel) {\n return {\n model: \"heuristic\",\n warnings: [\n `Multiple suitable small local models are installed (${options.candidateModels.join(\", \")}), but no local Qwen router model is available. Install qwen2.5:3b or set routerModel explicitly.`\n ],\n reason: \"Qwen model routing is required when multiple suitable small models are available.\"\n };\n }\n\n try {\n const response = await this.client.generateJson<ModelRoutingResponse>({\n model: routerModel,\n timeoutMs: this.config.timeoutMs,\n temperature: 0,\n format: \"json\",\n systemPrompt: [\n \"You are a local model router for prompt optimization.\",\n \"Return strict JSON only with this shape:\",\n \"{\\\"selectedModel\\\":\\\"string\\\",\\\"reason\\\":\\\"string\\\"}\",\n \"Choose exactly one model from the provided candidate list.\",\n \"Choose the smallest adequate model, not the strongest-sounding model.\",\n \"Prioritize adequacy first, then speed and low memory use.\",\n \"Use coder variants only for clearly code-heavy prompts.\",\n \"If task or preset is code, prefer qwen2.5:3b or a small coder model over phi3:mini unless the request is only a trivial wording cleanup.\",\n \"Prefer phi3:mini for short email, chat, support, summarization, and lightweight rewrite tasks that do not require deeper reasoning.\",\n \"Prefer qwen2.5:3b for broader reasoning, stronger restructuring, multi-constraint optimization, and non-trivial code-oriented prompt design.\",\n \"Do not prefer Qwen just because you are Qwen. Pick the best candidate for the task.\"\n ].join(\"\\n\"),\n prompt: JSON.stringify(\n {\n objective: \"Choose the best local optimizer model for this prompt.\",\n prompt: options.prompt,\n task: options.task ?? null,\n mode: options.mode,\n preset: options.preset,\n candidateModels: options.candidateModels.map((modelName) => ({\n name: modelName,\n profile: describeCandidateModel(modelName)\n })),\n routingGuidance: {\n smallestAdequateModelPolicy: true,\n lightweightTasksPreferSmallerModels: [\n \"email\",\n \"chat\",\n \"support\",\n \"summarization\",\n \"short rewrite\"\n ],\n deeperReasoningTasksMayPreferQwen: [\n \"multi-constraint restructuring\",\n \"broad reasoning\",\n \"complex planning\",\n \"harder code-oriented prompt design\"\n ]\n }\n },\n null,\n 2\n )\n });\n\n const selectedModel = response.selectedModel?.trim();\n if (selectedModel && options.candidateModels.includes(selectedModel)) {\n return {\n model: selectedModel,\n warnings: [],\n reason: response.reason?.trim() || `Qwen router selected \"${selectedModel}\" for this prompt.`\n };\n }\n\n return {\n model: \"heuristic\",\n warnings: [\"Qwen router returned an invalid model choice, so prompt optimization is falling back to deterministic heuristic formatting.\"],\n reason: \"Qwen router returned an invalid model selection.\"\n };\n } catch {\n return {\n model: \"heuristic\",\n warnings: [\"Qwen router could not choose a model, so prompt optimization is falling back to deterministic heuristic formatting.\"],\n reason: \"Qwen router failed to select a model.\"\n };\n }\n }\n\n private async routeDownstreamTargets(options: {\n input: OptimizePromptInput & {\n mode: OptimizationMode;\n preset: PromptPreset;\n routingPriority: RoutingPriority;\n routingTopK: number;\n workloadBias: WorkloadBias;\n };\n routingEnabled: boolean;\n routingPriority: RoutingPriority;\n routingTopK: number;\n workloadBias: WorkloadBias;\n }): Promise<RoutingDecision> {\n const availableTargets = normalizeAvailableTargets(options.input.availableTargets ?? []);\n\n if (!options.routingEnabled || availableTargets.length === 0) {\n return {\n selectedTarget: null,\n rankedTargets: [],\n routingReason: null,\n routingWarnings: [],\n routingProvider: null\n };\n }\n\n if (availableTargets.length === 1) {\n return {\n selectedTarget: stripInternalTargetFields(availableTargets[0]),\n rankedTargets: [\n {\n ...stripInternalTargetFields(availableTargets[0]),\n rank: 1,\n reason: \"Only one downstream target was supplied.\"\n }\n ],\n routingReason: \"Only one downstream target was supplied, so it was selected directly.\",\n routingWarnings: [],\n routingProvider: \"direct\"\n };\n }\n\n if (!this.client.listModels) {\n if (isClaudeTiersOnlyTargetSet(availableTargets)) {\n const selected = selectClaudeTierHeuristic(options.input, options.routingPriority, availableTargets);\n if (selected) {\n return {\n selectedTarget: stripInternalTargetFields(selected),\n rankedTargets: [{ ...stripInternalTargetFields(selected), rank: 1, reason: \"Selected by Claude tier heuristic (no local Qwen router available).\" }],\n routingReason: \"Selected by Claude tier heuristic (no local Qwen router available).\",\n routingWarnings: [],\n routingProvider: \"heuristic\"\n };\n }\n }\n\n return {\n selectedTarget: null,\n rankedTargets: [],\n routingReason: null,\n routingWarnings: [\n \"Downstream target routing requires local Ollama model discovery so a Qwen router can run.\"\n ],\n routingProvider: null\n };\n }\n\n try {\n const installedModels = await this.client.listModels();\n const routerModel = getQwenRouterModel(installedModels, this.config.routerModel);\n if (!routerModel) {\n return {\n selectedTarget: null,\n rankedTargets: [],\n routingReason: null,\n routingWarnings: [\n \"Downstream target routing could not run because no suitable local Qwen router model is installed.\"\n ],\n routingProvider: null\n };\n }\n\n const claudeTiersOnly = isClaudeTiersOnlyTargetSet(availableTargets);\n\n // For Claude tier routing, pre-filter candidates so small models can't\n // override the hard capability rules (e.g. Haiku for coding tasks).\n // This is more reliable than hoping the router follows prose instructions.\n const routingCandidates = claudeTiersOnly\n ? filterClaudeTierCandidates(availableTargets, options.input, options.routingPriority)\n : availableTargets;\n\n if (routingCandidates.length === 1) {\n return {\n selectedTarget: stripInternalTargetFields(routingCandidates[0]),\n rankedTargets: [{ ...stripInternalTargetFields(routingCandidates[0]), rank: 1, reason: \"Selected by Claude tier pre-filter based on prompt signals.\" }],\n routingReason: \"Selected by Claude tier pre-filter based on prompt signals.\",\n routingWarnings: [],\n routingProvider: \"heuristic\"\n };\n }\n\n const response = await this.client.generateJson<DownstreamRoutingResponse>({\n model: routerModel,\n timeoutMs: options.input.timeoutMs ?? this.config.timeoutMs,\n temperature: 0,\n format: \"json\",\n systemPrompt: buildDownstreamRoutingSystemPrompt(options.routingPriority, options.workloadBias, claudeTiersOnly),\n prompt: JSON.stringify(\n {\n objective: \"Rank the caller-supplied downstream targets for this prompt and choose the best top target.\",\n prompt: options.input.prompt,\n task: options.input.task ?? null,\n mode: options.input.mode,\n preset: options.input.preset,\n tone: options.input.tone ?? null,\n targetHints: options.input.targetHints ?? [],\n workloadBias: options.workloadBias,\n routingPriority: options.routingPriority,\n candidateTargets: routingCandidates.map((target) => ({\n id: target.id,\n provider: target.provider,\n model: target.model,\n label: target.label ?? null,\n costRank: target.costRank,\n latencyRank: target.latencyRank,\n capabilities: target.capabilities,\n profile: describeDownstreamTarget(target)\n }))\n },\n null,\n 2\n )\n });\n\n const rankedTargetIds = Array.from(\n new Set((response.rankedTargetIds ?? []).map((value) => value.trim()).filter(Boolean))\n ).slice(0, Math.max(1, options.routingTopK));\n\n const rankedTargets = rankedTargetIds\n .map((id, index) => {\n const target = routingCandidates.find((candidate) => candidate.id === id);\n if (!target) {\n return null;\n }\n\n return {\n ...stripInternalTargetFields(target),\n rank: index + 1,\n reason:\n index === 0\n ? response.reason?.trim() || \"Selected by the local Qwen downstream router.\"\n : `Ranked #${index + 1} by the local Qwen downstream router.`\n } satisfies RankedTargetCandidate;\n })\n .filter((value): value is RankedTargetCandidate => value !== null);\n\n const selectedTargetId = response.selectedTargetId?.trim();\n const selectedTargetCandidate =\n (selectedTargetId && routingCandidates.find((candidate) => candidate.id === selectedTargetId)) ??\n (rankedTargets[0]\n ? routingCandidates.find(\n (candidate) =>\n candidate.provider === rankedTargets[0].provider &&\n candidate.model === rankedTargets[0].model &&\n candidate.label === rankedTargets[0].label\n ) ?? null\n : null);\n\n if (!selectedTargetCandidate || rankedTargets.length === 0) {\n return {\n selectedTarget: null,\n rankedTargets: [],\n routingReason: null,\n routingWarnings: [\n \"Downstream target routing returned an invalid selection, so no downstream target was chosen.\"\n ],\n routingProvider: routerModel\n };\n }\n\n return {\n selectedTarget: stripInternalTargetFields(selectedTargetCandidate),\n rankedTargets,\n routingReason: response.reason?.trim() || \"Selected by the local Qwen downstream router.\",\n routingWarnings: [],\n routingProvider: routerModel\n };\n } catch {\n if (isClaudeTiersOnlyTargetSet(availableTargets)) {\n const selected = selectClaudeTierHeuristic(options.input, options.routingPriority, availableTargets);\n if (selected) {\n return {\n selectedTarget: stripInternalTargetFields(selected),\n rankedTargets: [{ ...stripInternalTargetFields(selected), rank: 1, reason: \"Selected by Claude tier heuristic (Qwen routing failed).\" }],\n routingReason: \"Selected by Claude tier heuristic (Qwen routing failed).\",\n routingWarnings: [\"Qwen downstream routing failed; fell back to Claude tier heuristic.\"],\n routingProvider: \"heuristic\"\n };\n }\n }\n\n return {\n selectedTarget: null,\n rankedTargets: [],\n routingReason: null,\n routingWarnings: [\n \"Downstream target routing could not complete, so no downstream target was selected.\"\n ],\n routingProvider: null\n };\n }\n }\n\n private heuristicOptimize(options: {\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n context: RelevantContextResult;\n constraints: string[];\n }): { optimizedPrompt: string; changes: string[]; warnings: string[] } {\n const isCodeRequest = isCodeFirstRequest(options.input);\n const lines = isCodeRequest\n ? buildCodeFirstHeuristicPrompt(options.input, options.constraints)\n : buildGeneralHeuristicPrompt(options.input, options.constraints);\n\n const optimizedPrompt = lines.join(\"\\n\");\n const changes = isCodeRequest\n ? [\n \"Compressed the prompt into a code-agent brief.\",\n \"Removed redundant narrative phrasing.\",\n \"Applied a Karpathy-style inspect-plan-act-test-reflect loop.\"\n ]\n : [\"Normalized prompt structure for downstream model consumption.\"];\n if (options.input.mode === \"compress\" || options.input.mode === \"concise\") {\n changes.push(\"Applied concise formatting to reduce token usage.\");\n }\n\n return {\n optimizedPrompt,\n changes,\n warnings: []\n };\n }\n\n private async reduceToBudget(options: {\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n optimizedPrompt: string;\n context: RelevantContextResult;\n routingDecision: RoutingDecision;\n maxTotalTokens: number;\n }): Promise<{ finalPrompt: string; estimatedTokensAfter: { prompt: number; context: number; total: number }; warning?: string }> {\n const summaryBudget = Math.max(80, Math.floor(options.maxTotalTokens * 0.2));\n const summary = options.input.sessionId\n ? await this.summarizeContext(options.input.sessionId, options.input.prompt, options.input.task, summaryBudget)\n : null;\n\n const compactContext: RelevantContextResult = {\n ...options.context,\n usedEntries: [],\n summary\n };\n\n const finalPrompt = composeFinalPrompt({\n optimizedPrompt: this.estimator.truncateToBudget(options.optimizedPrompt, Math.floor(options.maxTotalTokens * 0.5)),\n input: options.input,\n context: compactContext,\n routingDecision: options.routingDecision\n });\n\n return {\n finalPrompt,\n estimatedTokensAfter: {\n prompt: this.estimator.estimateText(options.optimizedPrompt),\n context: this.estimator.estimateText(formatContextBlock(compactContext)),\n total: this.estimator.estimateText(finalPrompt)\n },\n warning: \"Summarized stored context further to stay within the total token budget.\"\n };\n }\n}\n\nfunction describeCandidateModel(modelName: string): string {\n const lower = modelName.toLowerCase();\n\n if (lower.includes(\"phi3:mini\")) {\n return \"Very small and fast. Good for short rewrites, lightweight email/chat tasks, and simple prompt cleanup.\";\n }\n\n if (lower.includes(\"qwen2.5:3b\")) {\n return \"Small general-purpose model with stronger reasoning and restructuring than ultra-light models. Better for broader or more complex prompt optimization.\";\n }\n\n if (lower.includes(\"coder\")) {\n return \"Code-specialized model. Use only when the prompt is clearly code-heavy or refactor-oriented.\";\n }\n\n if (lower.includes(\"llama3.2:3b\")) {\n return \"Small general chat/rewrite model. Reasonable middle option for general tasks.\";\n }\n\n return \"Local candidate model for prompt optimization.\";\n}\n\nfunction resolveSessionStore(config: OptimizerConfig): SessionStore {\n if (typeof config.contextStore === \"object\" && config.contextStore !== null) {\n return config.contextStore;\n }\n\n if (config.contextStore === \"sqlite\") {\n return new SQLiteSessionStore(config.sqlitePath);\n }\n\n return new FileSessionStore(config.storageDir);\n}\n\nfunction composeFinalPrompt(input: {\n optimizedPrompt: string;\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n context: RelevantContextResult;\n routingDecision: RoutingDecision;\n}): string {\n const sections: string[] = [];\n\n sections.push(`Task:\\n${input.optimizedPrompt}`);\n\n const contextBlock = formatContextBlock(input.context);\n if (contextBlock) {\n sections.push(`Relevant context:\\n${contextBlock}`);\n }\n\n const constraints = Array.from(\n new Set([\n ...(input.input.pinnedConstraints ?? []),\n ...extractConstraints(input.input.prompt),\n input.input.maxLength ? `Keep the response within ${input.input.maxLength} units if possible.` : \"\",\n input.input.tone ? `Maintain a ${input.input.tone} tone.` : \"\",\n input.input.outputFormat ? `Return the output as ${input.input.outputFormat}.` : \"\"\n ].filter(Boolean))\n );\n\n if (constraints.length > 0) {\n sections.push(`Constraints:\\n- ${constraints.join(\"\\n- \")}`);\n }\n\n const desiredOutput = [\n input.routingDecision.selectedTarget\n ? `Selected target: ${formatTargetLabel(input.routingDecision.selectedTarget)}`\n : input.input.targetModel\n ? `Target model: ${input.input.targetModel}`\n : \"Target model: claude\",\n `Mode: ${input.input.mode}`,\n `Preset: ${input.input.preset}`\n ];\n\n sections.push(`Desired output:\\n- ${desiredOutput.join(\"\\n- \")}`);\n\n return sections.join(\"\\n\\n\").trim();\n}\n\nfunction formatContextBlock(context: RelevantContextResult): string {\n const lines: string[] = [];\n\n if (context.summary?.text) {\n lines.push(`Summary: ${context.summary.text}`);\n }\n\n for (const entry of context.usedEntries.slice(-4)) {\n lines.push(`- ${entry.optimizedPrompt ?? entry.rawPrompt ?? entry.text}`);\n }\n\n return normalizeWhitespace(lines.join(\"\\n\"));\n}\n\nfunction emptyRelevantContext(): RelevantContextResult {\n return {\n usedEntries: [],\n summary: null,\n warnings: [],\n debugInfo: {}\n };\n}\n\ntype NormalizedTargetCandidate = TargetModelCandidate & { id: string; costRank: number; latencyRank: number };\n\nfunction normalizeAvailableTargets(targets: TargetModelCandidate[]): NormalizedTargetCandidate[] {\n return targets.map((target, index) => ({\n ...target,\n id: `${target.provider}:${target.model}:${index}`,\n label: target.label ?? `${target.provider}:${target.model}`,\n capabilities: target.capabilities ?? inferCapabilities(target),\n costRank: target.costRank ?? index + 1,\n latencyRank: target.latencyRank ?? index + 1\n }));\n}\n\nfunction stripInternalTargetFields(target: NormalizedTargetCandidate): TargetModelCandidate {\n return {\n provider: target.provider,\n model: target.model,\n label: target.label,\n capabilities: target.capabilities,\n costRank: target.costRank,\n latencyRank: target.latencyRank\n };\n}\n\nfunction buildDownstreamRoutingSystemPrompt(\n priority: RoutingPriority,\n workloadBias: WorkloadBias,\n claudeTiersOnly = false\n): string {\n const lines = [\n \"You are a downstream model router for PromptPilot.\",\n \"Return strict JSON only with this shape:\",\n \"{\\\"selectedTargetId\\\":\\\"string\\\",\\\"rankedTargetIds\\\":[\\\"string\\\"],\\\"reason\\\":\\\"string\\\"}\",\n \"Choose only from the supplied candidate target IDs.\",\n \"Rank up to the requested top targets in best-first order.\",\n `Routing priority: ${priority}.`,\n `Workload bias: ${workloadBias}.`,\n \"Code-first means ambiguous prompts should default toward coding-capable or agentic-capable targets.\",\n \"Explicit email, support, chat, and lightweight writing prompts may prefer cheaper lighter targets.\",\n \"Do not invent targets. Do not output prose outside JSON.\"\n ];\n\n if (claudeTiersOnly) {\n lines.push(\n \"You are choosing between Claude model tiers (Haiku, Sonnet, Opus).\",\n \"Haiku: fastest and cheapest. ONLY suitable for email, chat, support, summarization, and trivial one-sentence rewrites. Do NOT use Haiku for any coding, debugging, refactoring, or technical tasks.\",\n \"Sonnet: balanced cost and capability. The DEFAULT for all coding, debugging, refactoring, writing, and general-purpose tasks. If the prompt mentions code, a file, a module, a bug, or any technical work, choose Sonnet at minimum.\",\n \"Opus: most capable and most expensive. Use for complex architecture decisions, multi-constraint agentic planning, system design, long-horizon reasoning, or when the prompt explicitly requires the strongest model.\",\n \"When routing priority is cheapest_adequate: Haiku for non-technical lightweight tasks only, Sonnet for anything involving code or technical content, Opus only when clearly necessary.\",\n \"When routing priority is best_quality: Opus for all code and reasoning tasks, Sonnet for writing and non-technical tasks.\",\n \"When routing priority is fastest_adequate: Haiku only for lightweight non-technical tasks, Sonnet otherwise.\",\n \"IMPORTANT: refactor, debug, fix, auth, module, CI, test, and TypeScript are all coding signals — always choose Sonnet or Opus for these, never Haiku.\"\n );\n }\n\n return lines.join(\"\\n\");\n}\n\nexport const CLAUDE_TIER_TARGETS: TargetModelCandidate[] = [\n {\n provider: \"anthropic\",\n model: \"claude-haiku-4-5\",\n label: \"anthropic:claude-haiku-4-5\",\n capabilities: [\"writing\", \"email\", \"support\", \"chat\", \"summarization\"],\n costRank: 1,\n latencyRank: 1\n },\n {\n provider: \"anthropic\",\n model: \"claude-sonnet-4-6\",\n label: \"anthropic:claude-sonnet-4-6\",\n capabilities: [\"coding\", \"writing\", \"agentic\", \"tool_use\", \"refactor\", \"debugging\"],\n costRank: 2,\n latencyRank: 2\n },\n {\n provider: \"anthropic\",\n model: \"claude-opus-4-6\",\n label: \"anthropic:claude-opus-4-6\",\n capabilities: [\"coding\", \"agentic\", \"tool_use\", \"refactor\", \"debugging\", \"architecture\", \"writing\"],\n costRank: 3,\n latencyRank: 3\n }\n];\n\nfunction isClaudeTiersOnlyTargetSet(targets: NormalizedTargetCandidate[]): boolean {\n return (\n targets.length >= 2 &&\n targets.every(\n (t) =>\n t.provider === \"anthropic\" &&\n /haiku|sonnet|opus/i.test(t.model)\n )\n );\n}\n\nfunction isCodeSignal(input: { prompt: string; task?: string; preset?: string; targetHints?: readonly TargetCapability[] }): boolean {\n const task = (input.task ?? \"\").toLowerCase();\n const preset = (input.preset ?? \"\").toLowerCase();\n const hints = input.targetHints ?? [];\n return (\n task === \"code\" ||\n preset === \"code\" ||\n hints.some((h) => [\"coding\", \"agentic\", \"tool_use\", \"refactor\", \"debugging\", \"architecture\"].includes(h)) ||\n /\\b(refactor|debug|fix|auth|module|ci|test|typescript|javascript|function|class|api|endpoint|build|deploy|lint|migration)\\b/i.test(input.prompt)\n );\n}\n\nfunction isArchitectureSignal(input: { prompt: string; targetHints?: readonly TargetCapability[] }): boolean {\n const hints = input.targetHints ?? [];\n return (\n hints.includes(\"architecture\") ||\n /\\b(architect|architecture|design system|migration plan|multi.?step|long.?horizon|agentic.*plan|system design|microservice|monolith)\\b/i.test(input.prompt)\n );\n}\n\n// Pre-filter Claude tier candidates before sending to Qwen so the router\n// cannot pick an inadequate tier regardless of its instruction-following.\n// This avoids relying on a small model to correctly interpret prose routing rules.\nfunction filterClaudeTierCandidates(\n targets: NormalizedTargetCandidate[],\n input: { prompt: string; task?: string; preset?: string; targetHints?: readonly TargetCapability[] },\n priority: RoutingPriority\n): NormalizedTargetCandidate[] {\n if (priority === \"best_quality\") {\n // Offer only Opus and Sonnet; Qwen picks between them\n const filtered = targets.filter((t) => /opus|sonnet/i.test(t.model));\n return filtered.length > 0 ? filtered : targets;\n }\n\n if (priority === \"cheapest_adequate\") {\n if (isArchitectureSignal(input)) {\n // Complex tasks: offer Sonnet and Opus only\n const filtered = targets.filter((t) => /opus|sonnet/i.test(t.model));\n return filtered.length > 0 ? filtered : targets;\n }\n if (isCodeSignal(input)) {\n // Standard coding task: pin to Sonnet directly, skip Qwen\n const sonnet = targets.find((t) => /sonnet/i.test(t.model));\n return sonnet ? [sonnet] : targets.filter((t) => !/haiku/i.test(t.model));\n }\n // Non-code: offer Haiku and Sonnet; Qwen picks between them\n const filtered = targets.filter((t) => /haiku|sonnet/i.test(t.model));\n return filtered.length > 0 ? filtered : targets;\n }\n\n // fastest_adequate: remove Opus; offer Haiku and Sonnet\n if (priority === \"fastest_adequate\") {\n const filtered = targets.filter((t) => !/opus/i.test(t.model));\n return filtered.length > 0 ? filtered : targets;\n }\n\n return targets;\n}\n\nfunction selectClaudeTierHeuristic(\n input: { prompt: string; task?: string; preset?: string; targetHints?: readonly TargetCapability[] },\n priority: RoutingPriority,\n targets: NormalizedTargetCandidate[]\n): NormalizedTargetCandidate | null {\n const haiku = targets.find((t) => /haiku/i.test(t.model)) ?? null;\n const sonnet = targets.find((t) => /sonnet/i.test(t.model)) ?? null;\n const opus = targets.find((t) => /opus/i.test(t.model)) ?? null;\n\n const task = (input.task ?? \"\").toLowerCase();\n const preset = (input.preset ?? \"\").toLowerCase();\n const hints = input.targetHints ?? [];\n const prompt = input.prompt;\n\n const isLightweight =\n [\"email\", \"chat\", \"support\", \"summarization\"].includes(task) ||\n [\"email\", \"chat\", \"support\", \"summarization\"].includes(preset) ||\n hints.some((h) => [\"email\", \"support\", \"chat\", \"summarization\"].includes(h));\n\n const needsOpus =\n /\\b(architect|architecture|design system|migration plan|multi.?step|complex.*refactor|long.?horizon|agentic.*plan)\\b/i.test(prompt) ||\n hints.includes(\"architecture\") ||\n priority === \"best_quality\";\n\n const isCodeTask =\n [\"code\"].includes(task) ||\n [\"code\"].includes(preset) ||\n hints.some((h) => [\"coding\", \"agentic\", \"tool_use\", \"refactor\", \"debugging\", \"architecture\"].includes(h)) ||\n /\\b(refactor|debug|fix|auth|module|ci|test|typescript|javascript|function|class|api|endpoint)\\b/i.test(prompt);\n\n if (priority === \"fastest_adequate\") {\n if (needsOpus) return opus ?? sonnet;\n if (isCodeTask) return sonnet ?? opus;\n return haiku ?? sonnet;\n }\n\n if (priority === \"best_quality\") {\n return opus ?? sonnet ?? haiku;\n }\n\n // cheapest_adequate\n if (needsOpus) return opus ?? sonnet;\n if (isCodeTask) return sonnet ?? opus;\n if (isLightweight) return haiku ?? sonnet;\n return sonnet ?? haiku ?? opus;\n}\n\nfunction inferCapabilities(target: TargetModelCandidate): TargetCapability[] {\n const lower = `${target.provider} ${target.model} ${target.label ?? \"\"}`.toLowerCase();\n const capabilities = new Set<TargetCapability>();\n\n if (/code|codex|coder|agent|tool/.test(lower)) {\n capabilities.add(\"coding\");\n }\n if (/agent|tool/.test(lower)) {\n capabilities.add(\"agentic\");\n capabilities.add(\"tool_use\");\n }\n if (/refactor|coder|codex/.test(lower)) {\n capabilities.add(\"refactor\");\n }\n if (/debug|fix|ci/.test(lower)) {\n capabilities.add(\"debugging\");\n }\n if (/write|email|chat|sonnet|mini/.test(lower)) {\n capabilities.add(\"writing\");\n }\n if (/email/.test(lower)) {\n capabilities.add(\"email\");\n }\n\n return Array.from(capabilities);\n}\n\nfunction describeDownstreamTarget(target: NormalizedTargetCandidate): string {\n return [\n `provider=${target.provider}`,\n `model=${target.model}`,\n `label=${target.label}`,\n `costRank=${target.costRank}`,\n `latencyRank=${target.latencyRank}`,\n `capabilities=${target.capabilities?.join(\",\") || \"none\"}`\n ].join(\"; \");\n}\n\nfunction formatTargetLabel(target: TargetModelCandidate): string {\n return target.label ?? `${target.provider}:${target.model}`;\n}\n\nfunction isCompressionSensitiveMode(mode: OptimizationMode): boolean {\n return mode === \"compress\" || mode === \"concise\" || mode === \"claude_cli\";\n}\n\nfunction cheapCompress(text: string): string {\n return normalizeWhitespace(text)\n .replace(/\\b(?:please|kindly|just)\\b/gi, \"\")\n .replace(/\\bI\\s+(?:want|need|would\\s+like\\s+to)\\b/gi, \"\")\n .replace(/\\s+([,.;:!?])/g, \"$1\")\n .replace(/\\s{2,}/g, \" \")\n .trim();\n}\n\nfunction sanitizeTextOptimizationOutput(raw: string): string {\n const normalized = normalizeWhitespace(raw);\n if (!normalized) {\n return \"\";\n }\n\n // Remove common reasoning markers and thinking blocks\n let cleaned = normalized\n .replace(/<think>[\\s\\S]*?<\\/think>/gi, \"\")\n .replace(/<reasoning>[\\s\\S]*?<\\/reasoning>/gi, \"\")\n .replace(/<analysis>[\\s\\S]*?<\\/analysis>/gi, \"\")\n .replace(/^(thinking|thinking process|analysis|critique|attempt|final decision|role|task|guidelines)[:=]?[\\s\\S]*?(?=\\n\\n|\\n[A-Z]|$)/gim, \"\");\n\n if (!containsReasoningLeak(cleaned)) {\n return stripWrappingQuotes(cleaned);\n }\n\n // Fallback: split by paragraphs and extract the most relevant one\n const candidates = cleaned\n .split(/\\n{2,}/)\n .map((chunk) => stripWrappingQuotes(normalizeWhitespace(chunk)))\n .filter(Boolean)\n .filter((chunk) => !containsReasoningLeak(chunk))\n .filter((chunk) => !/^(role|task|guidelines|thinking|thinking process|attempt|critique|final decision|analysis)\\b/i.test(chunk))\n .filter((chunk) => chunk.length > 10);\n\n // Prefer the longest non-reasoning chunk as it's likely the main output\n const selected = candidates.reduce((a, b) => (a.length > b.length ? a : b), \"\");\n return selected || stripWrappingQuotes(normalized);\n}\n\nfunction containsReasoningLeak(text: string): boolean {\n return /(thinking process|analyze the request|drafting the optimized prompt|critique \\d|attempt \\d|final decision|^thinking:|^analysis:|<think>|<reasoning>|<analysis>)/i.test(text);\n}\n\nfunction stripWrappingQuotes(text: string): string {\n return text.replace(/^[\"'`]+|[\"'`]+$/g, \"\").trim();\n}\n\nfunction isCodeFirstRequest(input: Pick<OptimizePromptInput, \"task\" | \"preset\" | \"prompt\" | \"targetHints\" | \"workloadBias\">): boolean {\n if (input.task === \"code\" || input.preset === \"code\") {\n return true;\n }\n\n if ((input.targetHints ?? []).some((hint) => [\"coding\", \"agentic\", \"refactor\", \"debugging\", \"tool_use\", \"architecture\"].includes(hint))) {\n return true;\n }\n\n return /\\b(code|coding|repo|repository|refactor|patch|debug|bug|ci|test|typescript|javascript|agent|tool)\\b/i.test(\n input.prompt\n );\n}\n\nfunction buildGeneralHeuristicPrompt(\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset },\n constraints: string[]\n): string[] {\n return [\n `Request: ${summarizePrompt(input.prompt, 320)}`,\n input.task ? `Task type: ${input.task}` : \"\",\n input.tone ? `Tone: ${input.tone}` : \"\",\n input.outputFormat ? `Output format: ${input.outputFormat}` : \"\",\n input.maxLength ? `Maximum length: ${input.maxLength}` : \"\",\n constraints.length ? `Critical constraints: ${constraints.join(\"; \")}` : \"\"\n ].filter(Boolean);\n}\n\nfunction buildCodeFirstHeuristicPrompt(\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset },\n constraints: string[]\n): string[] {\n const deliverables = inferCodeDeliverables(input.prompt);\n return [\n `Goal: ${summarizeCodeGoal(input.prompt)}`,\n input.tone ? `Tone: ${input.tone}` : \"\",\n deliverables.length ? `Deliverables:\\n- ${deliverables.join(\"\\n- \")}` : \"\",\n constraints.length ? `Constraints: ${constraints.join(\"; \")}` : \"\",\n \"Use a Karpathy loop: inspect, plan, act, test, reflect, repeat.\"\n ].filter(Boolean);\n}\n\nfunction summarizePrompt(prompt: string, maxLength: number): string {\n const normalized = normalizeWhitespace(prompt);\n if (normalized.length <= maxLength) {\n return normalized;\n }\n\n return `${normalized.slice(0, maxLength - 1).trim()}…`;\n}\n\nfunction summarizeCodeGoal(prompt: string): string {\n const normalized = summarizePrompt(prompt, 220);\n const lowered = prompt.toLowerCase();\n\n if (/auth|authentication|login|token/.test(lowered)) {\n return \"Inspect the codebase, understand the authentication flow, and produce a safe incremental refactor plan.\";\n }\n\n if (/ci|debug|failing|failure|test/.test(lowered)) {\n return \"Inspect the codebase and failing signals, identify root causes, and produce a practical debugging plan.\";\n }\n\n if (/refactor/.test(lowered)) {\n return \"Inspect the codebase and produce a phased refactor plan with minimal-risk execution steps.\";\n }\n\n return normalized;\n}\n\nfunction inferCodeDeliverables(prompt: string): string[] {\n const lowered = prompt.toLowerCase();\n const deliverables: string[] = [];\n\n if (/inspect|codebase|repo|repository/.test(lowered)) {\n deliverables.push(\"Summarize the relevant modules, ownership boundaries, and current behavior.\");\n }\n if (/shared abstraction|shared abstractions|duplicate|duplicated/.test(lowered)) {\n deliverables.push(\"Identify duplicated logic and the best shared abstractions to extract.\");\n }\n if (/incremental|phase|phased|rollout|step/.test(lowered)) {\n deliverables.push(\"Propose an incremental plan with small, reversible steps.\");\n }\n if (/risk|migration|compatibility|backward/.test(lowered)) {\n deliverables.push(\"Call out migration risks, compatibility concerns, and rollback points.\");\n }\n if (/test|tests/.test(lowered)) {\n deliverables.push(\"List the tests or validation needed before and after each phase.\");\n }\n if (/avoid hand-wavy|practical|concrete/.test(lowered)) {\n deliverables.push(\"Keep the recommendations concrete, implementation-oriented, and free of vague architecture advice.\");\n }\n\n if (deliverables.length === 0) {\n deliverables.push(\"Produce a compact, execution-ready plan for the coding task.\");\n }\n\n return deliverables.slice(0, 6);\n}\n","import type { OptimizePromptInput, OptimizerConfig } from \"./types.js\";\nimport { PromptOptimizer } from \"./core/optimizer.js\";\n\nexport * from \"./types.js\";\nexport * from \"./errors.js\";\nexport { PromptOptimizer } from \"./core/optimizer.js\";\nexport { OllamaClient } from \"./core/ollamaClient.js\";\nexport { TokenEstimator } from \"./core/tokenEstimator.js\";\nexport { ContextManager } from \"./core/contextManager.js\";\nexport { ContextCompressor } from \"./core/contextCompressor.js\";\nexport { selectOllamaModel, getDefaultPreferredModels } from \"./core/modelSelector.js\";\nexport { CLAUDE_TIER_TARGETS } from \"./core/optimizer.js\";\nexport { FileSessionStore } from \"./storage/fileSessionStore.js\";\nexport { SQLiteSessionStore } from \"./storage/sqliteSessionStore.js\";\n\nexport function createOptimizer(config: OptimizerConfig = {}) {\n return new PromptOptimizer(config);\n}\n\nexport async function optimizePrompt(input: OptimizePromptInput, config: OptimizerConfig = {}) {\n const optimizer = createOptimizer(config);\n return optimizer.optimize(input);\n}\n","const ARROW_UP = \"\\x1b[A\";\nconst ARROW_DOWN = \"\\x1b[B\";\nconst ENTER = \"\\r\";\nconst CTRL_C = \"\\x03\";\nconst ESCAPE = \"\\x1b\";\n\nexport type ClaudeTierChoice = \"auto\" | \"haiku\" | \"sonnet\" | \"opus\";\n\nexport interface ClaudeTierOption {\n key: ClaudeTierChoice;\n label: string;\n badge: string;\n description: string;\n}\n\nexport const CLAUDE_TIER_OPTIONS: ClaudeTierOption[] = [\n {\n key: \"auto\",\n label: \"Auto\",\n badge: \"recommended\",\n description: \"PromptPilot picks the best tier for your prompt\"\n },\n {\n key: \"haiku\",\n label: \"Haiku\",\n badge: \"fastest · cheapest\",\n description: \"email, chat, summarization, simple rewrites\"\n },\n {\n key: \"sonnet\",\n label: \"Sonnet\",\n badge: \"balanced\",\n description: \"coding, debugging, writing, general-purpose\"\n },\n {\n key: \"opus\",\n label: \"Opus\",\n badge: \"most capable\",\n description: \"architecture, complex reasoning, agentic planning\"\n }\n];\n\nexport function renderClaudeMenu(options: ClaudeTierOption[], selected: number): string {\n const lines: string[] = [\"Select Claude model tier:\\n\"];\n for (let index = 0; index < options.length; index++) {\n const opt = options[index];\n const isSelected = index === selected;\n const cursor = isSelected ? \"❯\" : \" \";\n const label = isSelected ? `\\x1b[1m${opt.label}\\x1b[0m` : opt.label;\n const badge = `\\x1b[2m${opt.badge}\\x1b[0m`;\n const desc = `\\x1b[2m${opt.description}\\x1b[0m`;\n lines.push(` ${cursor} ${label.padEnd(isSelected ? 14 : 6)} ${badge}`);\n lines.push(` ${desc}`);\n }\n lines.push(\"\\n \\x1b[2m↑/↓ move Enter confirm q cancel\\x1b[0m\");\n return lines.join(\"\\n\");\n}\n\nexport async function promptClaudeTierMenu(\n stderr: { write(msg: string): void },\n stdin: NodeJS.ReadStream\n): Promise<ClaudeTierChoice | null> {\n return new Promise((resolve) => {\n let selected = 0;\n const options = CLAUDE_TIER_OPTIONS;\n const lineCount = options.length * 2 + 3; // header + 2 lines per option + footer\n\n const draw = (first: boolean) => {\n if (!first) {\n // Move cursor up to overwrite previous render\n stderr.write(`\\x1b[${lineCount}A`);\n }\n stderr.write(`\\x1b[?25l${renderClaudeMenu(options, selected)}\\n`);\n };\n\n const cleanup = () => {\n stderr.write(\"\\x1b[?25h\"); // restore cursor\n stdin.setRawMode(false);\n stdin.pause();\n stdin.removeListener(\"data\", onData);\n };\n\n const onData = (chunk: string) => {\n if (chunk === CTRL_C) {\n cleanup();\n process.exit(0);\n }\n\n if (chunk === \"q\" || chunk === ESCAPE) {\n cleanup();\n stderr.write(\"\\n\");\n resolve(null);\n return;\n }\n\n if (chunk === ARROW_UP) {\n selected = (selected - 1 + options.length) % options.length;\n draw(false);\n return;\n }\n\n if (chunk === ARROW_DOWN) {\n selected = (selected + 1) % options.length;\n draw(false);\n return;\n }\n\n if (chunk === ENTER) {\n cleanup();\n stderr.write(`\\n Selected: \\x1b[1m${options[selected].label}\\x1b[0m\\n\\n`);\n resolve(options[selected].key);\n }\n };\n\n stdin.setRawMode(true);\n stdin.resume();\n stdin.setEncoding(\"utf8\");\n stdin.on(\"data\", onData);\n\n draw(true);\n });\n}\n","import { basename } from \"node:path\";\n\nexport interface WelcomeScreenOptions {\n columns?: number;\n cwd: string;\n version: string;\n color?: boolean;\n user?: string;\n}\n\nconst MIN_WIDE_COLUMNS = 76;\nconst PANEL_RULE = \"__PANEL_RULE__\";\n\nexport function renderWelcomeScreen(options: WelcomeScreenOptions): string {\n const columns = Math.max(60, options.columns ?? 100);\n const color = options.color ?? false;\n const user = options.user?.trim() || \"pilot\";\n\n return columns >= MIN_WIDE_COLUMNS\n ? renderWideWelcome({ ...options, columns, color, user })\n : renderCompactWelcome({ ...options, columns, color, user });\n}\n\nfunction renderWideWelcome(options: Required<WelcomeScreenOptions>): string {\n const width = clamp(options.columns - 4, 76, 118);\n const innerWidth = width - 2;\n const leftWidth = 30;\n const rightWidth = innerWidth - leftWidth - 5;\n const title = ` PromptPilot v${options.version} `;\n\n const leftLines = [\n style(`Welcome back ${capitalize(options.user)}!`, \"bold\", options.color),\n \"\",\n ...paintSprite(options.color),\n \"\",\n style(`${options.user} • ${basename(options.cwd)}`, \"dim\", options.color),\n style(options.cwd, \"dim\", options.color)\n ];\n\n const rightLines = [\n style(\"Getting started\", \"accent\", options.color),\n style(\"promptpilot claude \\\"fix this CI failure\\\"\", \"bold\", options.color),\n \"Pick a Claude tier and pipe straight into Claude\",\n PANEL_RULE,\n style(\"Or optimize manually\", \"accent\", options.color),\n style(\"promptpilot optimize \\\"...\\\" --plain | claude\", \"bold\", options.color),\n \"\",\n style(\"Commands\", \"accent\", options.color),\n \"claude optimize + tier picker + pipe to claude\",\n \"optimize optimize and print to stdout\",\n \"--help show the full CLI reference\"\n ];\n\n const rowCount = Math.max(leftLines.length, rightLines.length);\n const topRule = renderTopRule(title, innerWidth, options.color);\n const bottomRule = `${style(\"╰\", \"accent\", options.color)}${style(\"─\".repeat(innerWidth), \"accent\", options.color)}${style(\"╯\", \"accent\", options.color)}`;\n\n const body = new Array(rowCount).fill(null).map((_, index) => {\n const left = padVisible(leftLines[index] ?? \"\", leftWidth);\n const rightLine = rightLines[index] ?? \"\";\n const right = rightLine === PANEL_RULE\n ? style(\"─\".repeat(rightWidth), \"dim\", options.color)\n : padVisible(rightLine, rightWidth);\n return `${style(\"│\", \"accent\", options.color)} ${left} ${style(\"│\", \"accent\", options.color)} ${right} ${style(\"│\", \"accent\", options.color)}`;\n });\n\n const footer = [\n \"\",\n style(\"Ready when you are.\", \"dim\", options.color),\n `Run ${style(\"promptpilot --help\", \"bold\", options.color)} for the full option list.`\n ];\n\n return [topRule, ...body, bottomRule, ...footer].join(\"\\n\");\n}\n\nfunction renderCompactWelcome(options: Required<WelcomeScreenOptions>): string {\n const width = clamp(options.columns - 2, 58, 82);\n const innerWidth = width - 2;\n const title = ` PromptPilot v${options.version} `;\n const lines = [\n centerVisible(style(`Welcome back ${capitalize(options.user)}!`, \"bold\", options.color), innerWidth - 2),\n \"\",\n ...paintSprite(options.color).map((line) => centerVisible(line, innerWidth - 2)),\n \"\",\n style(options.cwd, \"dim\", options.color),\n \"\",\n style(\"Getting started\", \"accent\", options.color),\n \"promptpilot claude \\\"fix this CI failure\\\"\",\n \"promptpilot optimize \\\"...\\\" --plain | claude\",\n \"\",\n style(\"Help\", \"accent\", options.color),\n \"promptpilot --help\"\n ];\n\n return [\n renderTopRule(title, innerWidth, options.color),\n ...lines.map((line) => `${style(\"│\", \"accent\", options.color)} ${padVisible(line, innerWidth - 2)} ${style(\"│\", \"accent\", options.color)}`),\n `${style(\"╰\", \"accent\", options.color)}${style(\"─\".repeat(innerWidth), \"accent\", options.color)}${style(\"╯\", \"accent\", options.color)}`\n ].join(\"\\n\");\n}\n\nfunction paintSprite(color: boolean): string[] {\n const ink = color ? \"\\u001b[38;5;215m\" : \"\";\n const reset = color ? \"\\u001b[0m\" : \"\";\n\n return [\n `${ink} .-''''-.${reset}`,\n `${ink} .' .--. '.${reset}`,\n `${ink} / / oo \\\\ \\\\${reset}`,\n `${ink} | \\\\_==_/ |${reset}`,\n `${ink} | .-.__.-. |${reset}`,\n `${ink} \\\\ \\\\_/ \\\\_/ /${reset}`,\n `${ink} '._/|__|\\\\_.'${reset}`,\n `${ink} /_/ \\\\_\\\\${reset}`\n ];\n}\n\nfunction style(text: string, tone: \"accent\" | \"bold\" | \"dim\", color: boolean): string {\n if (!color) {\n return text;\n }\n\n switch (tone) {\n case \"accent\":\n return `\\u001b[38;5;215m${text}\\u001b[0m`;\n case \"bold\":\n return `\\u001b[1m${text}\\u001b[0m`;\n case \"dim\":\n return `\\u001b[38;5;245m${text}\\u001b[0m`;\n }\n}\n\nfunction renderTopRule(title: string, innerWidth: number, color: boolean): string {\n const titleWidth = visibleWidth(title);\n const leftRuleWidth = Math.min(3, Math.max(0, innerWidth - titleWidth));\n const rightRuleWidth = Math.max(0, innerWidth - titleWidth - leftRuleWidth);\n return `${style(\"╭\", \"accent\", color)}${style(\"─\".repeat(leftRuleWidth), \"accent\", color)}${style(title, \"accent\", color)}${style(\"─\".repeat(rightRuleWidth), \"accent\", color)}${style(\"╮\", \"accent\", color)}`;\n}\n\nfunction padVisible(text: string, targetWidth: number): string {\n const truncated = truncateVisible(text, targetWidth);\n const padding = Math.max(0, targetWidth - visibleWidth(truncated));\n return `${truncated}${\" \".repeat(padding)}`;\n}\n\nfunction centerVisible(text: string, targetWidth: number): string {\n const truncated = truncateVisible(text, targetWidth);\n const extra = Math.max(0, targetWidth - visibleWidth(truncated));\n const leftPadding = Math.floor(extra / 2);\n const rightPadding = extra - leftPadding;\n return `${\" \".repeat(leftPadding)}${truncated}${\" \".repeat(rightPadding)}`;\n}\n\nfunction truncateVisible(text: string, targetWidth: number): string {\n if (visibleWidth(text) <= targetWidth) {\n return text;\n }\n\n let visible = 0;\n let result = \"\";\n let inEscape = false;\n\n for (const char of text) {\n result += char;\n if (char === \"\\u001b\") {\n inEscape = true;\n continue;\n }\n if (inEscape) {\n if (char === \"m\") {\n inEscape = false;\n }\n continue;\n }\n visible += 1;\n if (visible >= Math.max(0, targetWidth - 1)) {\n break;\n }\n }\n\n return `${result}…`;\n}\n\nfunction visibleWidth(text: string): number {\n return text.replace(/\\u001b\\[[0-9;]*m/g, \"\").length;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nfunction capitalize(value: string): string {\n if (value.length === 0) {\n return value;\n }\n return value[0].toUpperCase() + value.slice(1);\n}\n","export interface SpinnerLike {\n start(message: string): void;\n stop(): void;\n}\n\nexport class Spinner implements SpinnerLike {\n private message = \"\";\n private frame = 0;\n private interval: NodeJS.Timeout | null = null;\n private writer: { write(text: string): void };\n private isTTY: boolean;\n\n private readonly frames = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\n\n constructor(writer: { write(text: string): void }, isTTY = false) {\n this.writer = writer;\n this.isTTY = isTTY;\n }\n\n start(message: string): void {\n if (!this.isTTY) {\n return;\n }\n\n this.message = message;\n this.frame = 0;\n\n this.interval = setInterval(() => {\n const spinner = this.frames[this.frame % this.frames.length];\n this.writer.write(`\\r${spinner} ${this.message}`);\n this.frame += 1;\n }, 80);\n }\n\n stop(): void {\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = null;\n }\n\n if (this.isTTY) {\n this.writer.write(\"\\r\\x1b[K\"); // Clear the line\n }\n }\n}\n\nexport function createSpinner(\n writer: { write(text: string): void },\n isTTY = false\n): SpinnerLike {\n return new Spinner(writer, isTTY);\n}\n\nexport class NoOpSpinner implements SpinnerLike {\n start(_message: string): void {}\n stop(): void {}\n}\n"],"mappings":"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","names":["dirname","join","mkdir","join","mkdir","dirname","randomUUID","randomUUID","response","filtered"]}
|