@cortask/core 0.2.35 → 0.2.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/providers/openai-compatible.ts","../src/models/definitions.ts","../src/providers/anthropic.ts","../src/providers/openai.ts","../src/providers/google.ts","../src/providers/moonshot.ts","../src/providers/grok.ts","../src/providers/openrouter.ts","../src/providers/minimax.ts","../src/providers/ollama.ts","../src/providers/index.ts","../src/agent/runner.ts","../src/agent/system-prompt.ts","../src/logging/logger.ts","../src/agent/tools/read-file.ts","../src/agent/tools/write-file.ts","../src/agent/tools/list-files.ts","../src/agent/tools/bash.ts","../src/agent/tools/web-fetch.ts","../src/agent/tools/web-search.ts","../src/agent/tools/questionnaire.ts","../src/agent/tools/memory.ts","../src/agent/tools/show-file.ts","../src/agent/tools/data-file.ts","../src/data/parser.ts","../src/cron/schedule.ts","../src/agent/tools/cron.ts","../src/agent/tools/artifact.ts","../src/agent/tools/browser-manager.ts","../src/agent/tools/browser.ts","../src/agent/tools/subagent.ts","../src/agent/subagent/types.ts","../src/agent/subagent/registry.ts","../src/agent/tools/switch-workspace.ts","../src/agent/tools/skill.ts","../src/skills/writer.ts","../src/skills/loader.ts","../src/skills/credential-schema.ts","../src/skills/installer.ts","../src/agent/tools/index.ts","../src/credentials/store.ts","../src/config/schema.ts","../src/onboarding/validator.ts","../src/workspace/manager.ts","../src/session/store.ts","../src/session/migrate.ts","../src/skills/tools.ts","../src/skills/oauth2.ts","../src/cron/service.ts","../src/artifacts/store.ts","../src/usage/store.ts","../src/models/store.ts","../src/templates/store.ts"],"sourcesContent":["import OpenAI from \"openai\";\nimport type {\n LLMProvider,\n GenerateTextParams,\n GenerateTextResult,\n StreamChunk,\n EmbedParams,\n EmbedResult,\n ModelInfo,\n Message,\n ToolDefinition,\n ToolCall,\n} from \"./types.js\";\nimport { getModelDefinitions } from \"../models/definitions.js\";\n\nexport function toOpenAIMessages(\n messages: Message[],\n systemPrompt?: string,\n): OpenAI.ChatCompletionMessageParam[] {\n const result: OpenAI.ChatCompletionMessageParam[] = [];\n\n if (systemPrompt) {\n result.push({ role: \"system\", content: systemPrompt });\n }\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue;\n\n if (typeof msg.content === \"string\") {\n result.push({\n role: msg.role,\n content: msg.content,\n } as OpenAI.ChatCompletionMessageParam);\n continue;\n }\n\n // Skip thinking parts — OpenAI doesn't support them\n const filteredContent = msg.content.filter((p) => p.type !== \"thinking\");\n const toolUseParts = filteredContent.filter((p) => p.type === \"tool_use\");\n if (msg.role === \"assistant\" && toolUseParts.length > 0) {\n const textContent = filteredContent\n .filter((p) => p.type === \"text\")\n .map((p) => p.text ?? \"\")\n .join(\"\");\n result.push({\n role: \"assistant\",\n content: textContent || null,\n tool_calls: toolUseParts.map((p) => ({\n id: p.toolCallId!,\n type: \"function\" as const,\n function: {\n name: p.toolName!,\n arguments: JSON.stringify(p.toolArguments ?? {}),\n },\n })),\n });\n continue;\n }\n\n const toolResultParts = filteredContent.filter((p) => p.type === \"tool_result\");\n if (toolResultParts.length > 0) {\n for (const p of toolResultParts) {\n result.push({\n role: \"tool\",\n tool_call_id: p.toolCallId!,\n content: p.text ?? \"\",\n });\n }\n continue;\n }\n\n const parts: OpenAI.ChatCompletionContentPart[] = filteredContent.map(\n (part) => {\n if (part.type === \"image\" && part.imageBase64) {\n return {\n type: \"image_url\" as const,\n image_url: {\n url: `data:${part.mimeType ?? \"image/png\"};base64,${part.imageBase64}`,\n },\n };\n }\n return { type: \"text\" as const, text: part.text ?? \"\" };\n },\n );\n result.push({\n role: msg.role,\n content: parts,\n } as OpenAI.ChatCompletionMessageParam);\n }\n\n return result;\n}\n\nexport function toOpenAITools(\n tools: ToolDefinition[],\n): OpenAI.ChatCompletionTool[] {\n return tools.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: t.inputSchema,\n },\n }));\n}\n\nexport class OpenAICompatibleProvider implements LLMProvider {\n readonly id: string;\n protected client: OpenAI;\n\n constructor(id: string, apiKey: string, baseURL?: string) {\n this.id = id;\n this.client = new OpenAI({ apiKey, baseURL });\n }\n\n async generateText(params: GenerateTextParams): Promise<GenerateTextResult> {\n const response = await this.client.chat.completions.create({\n model: params.model,\n messages: toOpenAIMessages(params.messages, params.systemPrompt),\n tools: params.tools?.length ? toOpenAITools(params.tools) : undefined,\n temperature: params.temperature,\n max_tokens: params.maxTokens,\n });\n\n const choice = response.choices[0];\n if (!choice) {\n throw new Error(`No response from ${this.id}`);\n }\n\n const content = choice.message.content ?? \"\";\n const toolCalls: ToolCall[] = (choice.message.tool_calls ?? []).map(\n (tc) => ({\n id: tc.id,\n name: tc.function.name,\n arguments: JSON.parse(tc.function.arguments),\n }),\n );\n\n const stopReason =\n choice.finish_reason === \"tool_calls\"\n ? \"tool_use\"\n : choice.finish_reason === \"length\"\n ? \"max_tokens\"\n : \"end\";\n\n return {\n content,\n toolCalls,\n usage: {\n inputTokens: response.usage?.prompt_tokens ?? 0,\n outputTokens: response.usage?.completion_tokens ?? 0,\n },\n stopReason,\n };\n }\n\n async *generateStream(\n params: GenerateTextParams,\n ): AsyncIterable<StreamChunk> {\n const stream = await this.client.chat.completions.create({\n model: params.model,\n messages: toOpenAIMessages(params.messages, params.systemPrompt),\n tools: params.tools?.length ? toOpenAITools(params.tools) : undefined,\n temperature: params.temperature,\n max_tokens: params.maxTokens,\n stream: true,\n stream_options: { include_usage: true },\n });\n\n let inputTokens = 0;\n let outputTokens = 0;\n\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta;\n if (!delta) {\n // Final chunk may have usage without choices\n if (chunk.usage) {\n inputTokens = chunk.usage.prompt_tokens ?? 0;\n outputTokens = chunk.usage.completion_tokens ?? 0;\n }\n continue;\n }\n\n if (delta.content) {\n yield { type: \"text\", text: delta.content };\n }\n\n if (delta.tool_calls) {\n for (const tc of delta.tool_calls) {\n if (tc.id) {\n yield {\n type: \"tool_call_start\",\n toolCall: { id: tc.id, name: tc.function?.name },\n };\n }\n if (tc.function?.arguments) {\n yield { type: \"tool_call_delta\", text: tc.function.arguments };\n }\n }\n }\n\n if (chunk.usage) {\n inputTokens = chunk.usage.prompt_tokens ?? 0;\n outputTokens = chunk.usage.completion_tokens ?? 0;\n }\n }\n\n yield {\n type: \"message_end\",\n usage: { inputTokens, outputTokens },\n };\n }\n\n async embed(params: EmbedParams): Promise<EmbedResult> {\n const response = await this.client.embeddings.create({\n model: params.model,\n input: params.inputs,\n });\n\n return {\n embeddings: response.data.map((d) => d.embedding),\n usage: { totalTokens: response.usage.total_tokens },\n };\n }\n\n async listModels(): Promise<ModelInfo[]> {\n return getModelDefinitions(this.id);\n }\n}\n","import type { ModelInfo } from \"../providers/types.js\";\n\nexport type ProviderId = \"anthropic\" | \"openai\" | \"google\" | \"moonshot\" | \"grok\" | \"openrouter\" | \"minimax\";\n\n/**\n * Hardcoded model definitions with pricing (per 1M tokens in USD).\n * OpenRouter is excluded — it fetches models from its API.\n */\nexport const MODEL_DEFINITIONS: Record<string, ModelInfo[]> = {\n anthropic: [\n { id: \"claude-opus-4-6\", name: \"Claude Opus 4.6\", contextWindow: 200000, inputPricePer1m: 15, outputPricePer1m: 75 },\n { id: \"claude-sonnet-4-5-20250929\", name: \"Claude Sonnet 4.5\", contextWindow: 200000, inputPricePer1m: 3, outputPricePer1m: 15 },\n { id: \"claude-haiku-4-5-20251001\", name: \"Claude Haiku 4.5\", contextWindow: 200000, inputPricePer1m: 0.8, outputPricePer1m: 4 },\n { id: \"claude-sonnet-4-20250514\", name: \"Claude Sonnet 4\", contextWindow: 200000, inputPricePer1m: 3, outputPricePer1m: 15 },\n ],\n openai: [\n { id: \"gpt-4.1\", name: \"GPT-4.1\", contextWindow: 1047576, inputPricePer1m: 2, outputPricePer1m: 8 },\n { id: \"gpt-4.1-mini\", name: \"GPT-4.1 Mini\", contextWindow: 1047576, inputPricePer1m: 0.4, outputPricePer1m: 1.6 },\n { id: \"gpt-4.1-nano\", name: \"GPT-4.1 Nano\", contextWindow: 1047576, inputPricePer1m: 0.1, outputPricePer1m: 0.4 },\n { id: \"gpt-4o\", name: \"GPT-4o\", contextWindow: 128000, inputPricePer1m: 2.5, outputPricePer1m: 10 },\n { id: \"gpt-4o-mini\", name: \"GPT-4o Mini\", contextWindow: 128000, inputPricePer1m: 0.15, outputPricePer1m: 0.6 },\n { id: \"o3\", name: \"o3\", contextWindow: 200000, inputPricePer1m: 10, outputPricePer1m: 40 },\n { id: \"o3-mini\", name: \"o3 Mini\", contextWindow: 200000, inputPricePer1m: 1.1, outputPricePer1m: 4.4 },\n { id: \"o4-mini\", name: \"o4 Mini\", contextWindow: 200000, inputPricePer1m: 1.1, outputPricePer1m: 4.4 },\n ],\n google: [\n { id: \"gemini-2.5-pro-preview-05-06\", name: \"Gemini 2.5 Pro\", contextWindow: 1048576, inputPricePer1m: 1.25, outputPricePer1m: 10 },\n { id: \"gemini-2.5-flash-preview-05-20\", name: \"Gemini 2.5 Flash\", contextWindow: 1048576, inputPricePer1m: 0.15, outputPricePer1m: 0.6 },\n { id: \"gemini-2.0-flash\", name: \"Gemini 2.0 Flash\", contextWindow: 1048576, inputPricePer1m: 0.1, outputPricePer1m: 0.4 },\n { id: \"gemini-2.0-flash-lite\", name: \"Gemini 2.0 Flash Lite\", contextWindow: 1048576, inputPricePer1m: 0.075, outputPricePer1m: 0.3 },\n ],\n grok: [\n { id: \"grok-3\", name: \"Grok 3\", contextWindow: 131072, inputPricePer1m: 3, outputPricePer1m: 15 },\n { id: \"grok-3-fast\", name: \"Grok 3 Fast\", contextWindow: 131072, inputPricePer1m: 5, outputPricePer1m: 25 },\n { id: \"grok-3-mini\", name: \"Grok 3 Mini\", contextWindow: 131072, inputPricePer1m: 0.3, outputPricePer1m: 0.5 },\n { id: \"grok-3-mini-fast\", name: \"Grok 3 Mini Fast\", contextWindow: 131072, inputPricePer1m: 0.6, outputPricePer1m: 4 },\n ],\n moonshot: [\n { id: \"moonshot-v1-8k\", name: \"Moonshot v1 8K\", contextWindow: 8000, inputPricePer1m: 1.5, outputPricePer1m: 2 },\n { id: \"moonshot-v1-32k\", name: \"Moonshot v1 32K\", contextWindow: 32000, inputPricePer1m: 3, outputPricePer1m: 4 },\n { id: \"moonshot-v1-128k\", name: \"Moonshot v1 128K\", contextWindow: 128000, inputPricePer1m: 8, outputPricePer1m: 10 },\n { id: \"kimi-latest\", name: \"Kimi Latest\", contextWindow: 131072, inputPricePer1m: 2, outputPricePer1m: 6 },\n ],\n minimax: [\n { id: \"MiniMax-Text-01\", name: \"MiniMax Text 01\", contextWindow: 1000000, inputPricePer1m: 1, outputPricePer1m: 5 },\n { id: \"abab6.5s-chat\", name: \"ABAB 6.5s Chat\", contextWindow: 245760, inputPricePer1m: 0.5, outputPricePer1m: 1 },\n ],\n};\n\nexport function getModelDefinitions(providerId: string): ModelInfo[] {\n return MODEL_DEFINITIONS[providerId] ?? [];\n}\n","import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n LLMProvider,\n GenerateTextParams,\n GenerateTextResult,\n StreamChunk,\n EmbedParams,\n EmbedResult,\n ModelInfo,\n Message,\n ToolDefinition,\n ToolCall,\n} from \"./types.js\";\nimport { getModelDefinitions } from \"../models/definitions.js\";\n\nfunction toAnthropicMessages(\n messages: Message[],\n): Anthropic.MessageParam[] {\n return messages\n .filter((m) => m.role !== \"system\")\n .map((m) => {\n if (typeof m.content === \"string\") {\n return {\n role: m.role as \"user\" | \"assistant\",\n content: m.content,\n };\n }\n\n const content: Anthropic.ContentBlockParam[] = m.content\n .filter((part) => part.type !== \"thinking\")\n .map((part) => {\n if (part.type === \"tool_use\") {\n return {\n type: \"tool_use\" as const,\n id: part.toolCallId!,\n name: part.toolName!,\n input: part.toolArguments ?? {},\n };\n }\n if (part.type === \"tool_result\") {\n return {\n type: \"tool_result\" as const,\n tool_use_id: part.toolCallId!,\n content: part.text ?? \"\",\n is_error: part.isError ?? false,\n };\n }\n if (part.type === \"image\" && part.imageBase64) {\n return {\n type: \"image\" as const,\n source: {\n type: \"base64\" as const,\n media_type: (part.mimeType ?? \"image/png\") as\n | \"image/png\"\n | \"image/jpeg\"\n | \"image/gif\"\n | \"image/webp\",\n data: part.imageBase64,\n },\n };\n }\n return { type: \"text\" as const, text: part.text ?? \"\" };\n });\n\n return {\n role: m.role as \"user\" | \"assistant\",\n content,\n };\n });\n}\n\nfunction toAnthropicTools(tools: ToolDefinition[]): Anthropic.Tool[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.inputSchema as Anthropic.Tool[\"input_schema\"],\n }));\n}\n\nexport class AnthropicProvider implements LLMProvider {\n readonly id = \"anthropic\";\n private client: Anthropic;\n\n constructor(apiKey: string) {\n this.client = new Anthropic({ apiKey });\n }\n\n async generateText(params: GenerateTextParams): Promise<GenerateTextResult> {\n const maxTokens = params.maxTokens ?? 16000;\n const budgetTokens = 10000;\n const useThinking = maxTokens > budgetTokens;\n const response = await this.client.messages.create({\n model: params.model,\n max_tokens: maxTokens,\n temperature: 1,\n system: params.systemPrompt,\n messages: toAnthropicMessages(params.messages),\n tools: params.tools ? toAnthropicTools(params.tools) : undefined,\n ...(useThinking ? { thinking: { type: \"enabled\", budget_tokens: budgetTokens } } : {}),\n } as Anthropic.MessageCreateParams) as Anthropic.Message;\n\n let content = \"\";\n let thinking = \"\";\n const toolCalls: ToolCall[] = [];\n\n for (const block of response.content) {\n if (block.type === \"thinking\") {\n thinking += (block as unknown as { type: \"thinking\"; thinking: string }).thinking;\n } else if (block.type === \"text\") {\n content += block.text;\n } else if (block.type === \"tool_use\") {\n toolCalls.push({\n id: block.id,\n name: block.name,\n arguments: block.input as Record<string, unknown>,\n });\n }\n }\n\n const stopReason =\n response.stop_reason === \"tool_use\"\n ? \"tool_use\"\n : response.stop_reason === \"max_tokens\"\n ? \"max_tokens\"\n : \"end\";\n\n return {\n content,\n thinking: thinking || undefined,\n toolCalls,\n usage: {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n },\n stopReason,\n };\n }\n\n async *generateStream(\n params: GenerateTextParams,\n ): AsyncIterable<StreamChunk> {\n const maxTokens = params.maxTokens ?? 16000;\n const budgetTokens = 10000;\n const useThinking = maxTokens > budgetTokens;\n const stream = this.client.messages.stream({\n model: params.model,\n max_tokens: maxTokens,\n temperature: 1,\n system: params.systemPrompt,\n messages: toAnthropicMessages(params.messages),\n tools: params.tools ? toAnthropicTools(params.tools) : undefined,\n ...(useThinking ? { thinking: { type: \"enabled\", budget_tokens: budgetTokens } } : {}),\n } as Anthropic.MessageCreateParams);\n\n for await (const event of stream) {\n if (event.type === \"content_block_start\") {\n if (event.content_block.type === \"tool_use\") {\n yield {\n type: \"tool_call_start\",\n toolCall: {\n id: event.content_block.id,\n name: event.content_block.name,\n },\n };\n }\n } else if (event.type === \"content_block_delta\") {\n if (event.delta.type === \"thinking_delta\") {\n yield { type: \"thinking\", text: (event.delta as { type: \"thinking_delta\"; thinking: string }).thinking };\n } else if (event.delta.type === \"text_delta\") {\n yield { type: \"text\", text: event.delta.text };\n } else if (event.delta.type === \"input_json_delta\") {\n yield { type: \"tool_call_delta\", text: event.delta.partial_json };\n }\n } else if (event.type === \"content_block_stop\") {\n yield { type: \"tool_call_end\" };\n }\n }\n\n const finalMessage = await stream.finalMessage();\n yield {\n type: \"message_end\",\n usage: {\n inputTokens: finalMessage.usage.input_tokens,\n outputTokens: finalMessage.usage.output_tokens,\n },\n };\n }\n\n async embed(_params: EmbedParams): Promise<EmbedResult> {\n throw new Error(\n \"Anthropic does not support embeddings. Use OpenAI or Google for embeddings.\",\n );\n }\n\n async listModels(): Promise<ModelInfo[]> {\n return getModelDefinitions(\"anthropic\");\n }\n}\n","import { OpenAICompatibleProvider } from \"./openai-compatible.js\";\n\nexport class OpenAIProvider extends OpenAICompatibleProvider {\n constructor(apiKey: string) {\n super(\"openai\", apiKey);\n }\n}\n","import {\n GoogleGenerativeAI,\n type Content,\n type Part,\n type FunctionDeclaration,\n SchemaType,\n} from \"@google/generative-ai\";\nimport type {\n LLMProvider,\n GenerateTextParams,\n GenerateTextResult,\n StreamChunk,\n EmbedParams,\n EmbedResult,\n ModelInfo,\n Message,\n ToolDefinition,\n ToolCall,\n} from \"./types.js\";\nimport { getModelDefinitions } from \"../models/definitions.js\";\n\nfunction toGeminiContents(messages: Message[]): Content[] {\n const result: Content[] = [];\n\n for (const m of messages) {\n if (m.role === \"system\") continue;\n\n if (typeof m.content === \"string\") {\n result.push({\n role: m.role === \"assistant\" ? \"model\" : \"user\",\n parts: [{ text: m.content }],\n });\n continue;\n }\n\n const toolResultParts = m.content.filter((p) => p.type === \"tool_result\");\n if (toolResultParts.length > 0) {\n result.push({\n role: \"function\" as string,\n parts: toolResultParts.map(\n (p): Part => ({\n functionResponse: {\n name: p.toolName ?? \"unknown\",\n response: { result: p.text ?? \"\" },\n },\n }),\n ),\n });\n continue;\n }\n\n const parts: Part[] = [];\n for (const part of m.content) {\n if (part.type === \"thinking\") continue;\n if (part.type === \"tool_use\") {\n parts.push({\n functionCall: {\n name: part.toolName!,\n args: (part.toolArguments ?? {}) as Record<string, string>,\n },\n });\n } else if (part.type === \"image\" && part.imageBase64) {\n parts.push({\n inlineData: {\n mimeType: part.mimeType ?? \"image/png\",\n data: part.imageBase64,\n },\n });\n } else {\n parts.push({ text: part.text ?? \"\" });\n }\n }\n\n result.push({\n role: m.role === \"assistant\" ? \"model\" : \"user\",\n parts,\n });\n }\n\n return result;\n}\n\nfunction jsonSchemaTypeToGemini(type: string): SchemaType {\n switch (type) {\n case \"string\":\n return SchemaType.STRING;\n case \"number\":\n return SchemaType.NUMBER;\n case \"integer\":\n return SchemaType.INTEGER;\n case \"boolean\":\n return SchemaType.BOOLEAN;\n case \"array\":\n return SchemaType.ARRAY;\n case \"object\":\n return SchemaType.OBJECT;\n default:\n return SchemaType.STRING;\n }\n}\n\nfunction convertJsonSchemaToGemini(\n schema: Record<string, unknown>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n if (schema.type) {\n result.type = jsonSchemaTypeToGemini(schema.type as string);\n }\n if (schema.description) result.description = schema.description;\n if (schema.properties) {\n const props: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(\n schema.properties as Record<string, Record<string, unknown>>,\n )) {\n props[key] = convertJsonSchemaToGemini(val);\n }\n result.properties = props;\n }\n if (schema.required) result.required = schema.required;\n if (schema.items)\n result.items = convertJsonSchemaToGemini(\n schema.items as Record<string, unknown>,\n );\n return result;\n}\n\nfunction toGeminiTools(tools: ToolDefinition[]): FunctionDeclaration[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: convertJsonSchemaToGemini(t.inputSchema) as unknown as FunctionDeclaration[\"parameters\"],\n }));\n}\n\nexport class GoogleProvider implements LLMProvider {\n readonly id = \"google\";\n private client: GoogleGenerativeAI;\n\n constructor(apiKey: string) {\n this.client = new GoogleGenerativeAI(apiKey);\n }\n\n async generateText(params: GenerateTextParams): Promise<GenerateTextResult> {\n const model = this.client.getGenerativeModel({\n model: params.model,\n systemInstruction: params.systemPrompt,\n generationConfig: {\n temperature: params.temperature,\n maxOutputTokens: params.maxTokens,\n },\n tools: params.tools?.length\n ? [{ functionDeclarations: toGeminiTools(params.tools) }]\n : undefined,\n });\n\n const result = await model.generateContent({\n contents: toGeminiContents(params.messages),\n });\n\n const response = result.response;\n let content = \"\";\n const toolCalls: ToolCall[] = [];\n\n let thinking = \"\";\n for (const candidate of response.candidates ?? []) {\n for (const part of candidate.content.parts) {\n if ((part as { thought?: boolean }).thought && part.text) {\n thinking += part.text;\n } else if (part.text) {\n content += part.text;\n }\n if (part.functionCall) {\n toolCalls.push({\n id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n name: part.functionCall.name,\n arguments: (part.functionCall.args ?? {}) as Record<\n string,\n unknown\n >,\n });\n }\n }\n }\n\n const usageMeta = response.usageMetadata;\n const stopReason = toolCalls.length > 0 ? \"tool_use\" : \"end\";\n\n return {\n content,\n thinking: thinking || undefined,\n toolCalls,\n usage: {\n inputTokens: usageMeta?.promptTokenCount ?? 0,\n outputTokens: usageMeta?.candidatesTokenCount ?? 0,\n },\n stopReason,\n };\n }\n\n async *generateStream(\n params: GenerateTextParams,\n ): AsyncIterable<StreamChunk> {\n const model = this.client.getGenerativeModel({\n model: params.model,\n systemInstruction: params.systemPrompt,\n generationConfig: {\n temperature: params.temperature,\n maxOutputTokens: params.maxTokens,\n },\n tools: params.tools?.length\n ? [{ functionDeclarations: toGeminiTools(params.tools) }]\n : undefined,\n });\n\n const result = await model.generateContentStream({\n contents: toGeminiContents(params.messages),\n });\n\n let inputTokens = 0;\n let outputTokens = 0;\n\n for await (const chunk of result.stream) {\n if (chunk.usageMetadata) {\n inputTokens = chunk.usageMetadata.promptTokenCount ?? 0;\n outputTokens = chunk.usageMetadata.candidatesTokenCount ?? 0;\n }\n for (const candidate of chunk.candidates ?? []) {\n for (const part of candidate.content.parts) {\n if ((part as { thought?: boolean }).thought && part.text) {\n yield { type: \"thinking\", text: part.text };\n } else if (part.text) {\n yield { type: \"text\", text: part.text };\n }\n if (part.functionCall) {\n yield {\n type: \"tool_call_start\",\n toolCall: {\n id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n name: part.functionCall.name,\n arguments: (part.functionCall.args ?? {}) as Record<\n string,\n unknown\n >,\n },\n };\n yield { type: \"tool_call_end\" };\n }\n }\n }\n }\n\n yield {\n type: \"message_end\",\n usage: { inputTokens, outputTokens },\n };\n }\n\n async embed(params: EmbedParams): Promise<EmbedResult> {\n const model = this.client.getGenerativeModel({ model: params.model });\n\n const result = await model.batchEmbedContents({\n requests: params.inputs.map((input) => ({\n content: { role: \"user\", parts: [{ text: input }] },\n })),\n });\n\n return {\n embeddings: result.embeddings.map((e) => e.values),\n usage: { totalTokens: 0 },\n };\n }\n\n async listModels(): Promise<ModelInfo[]> {\n return getModelDefinitions(\"google\");\n }\n}\n","import { OpenAICompatibleProvider } from \"./openai-compatible.js\";\n\nexport class MoonshotProvider extends OpenAICompatibleProvider {\n constructor(apiKey: string) {\n super(\"moonshot\", apiKey, \"https://api.moonshot.cn/v1\");\n }\n}\n","import { OpenAICompatibleProvider } from \"./openai-compatible.js\";\n\nexport class GrokProvider extends OpenAICompatibleProvider {\n constructor(apiKey: string) {\n super(\"grok\", apiKey, \"https://api.x.ai/v1\");\n }\n}\n","import { OpenAICompatibleProvider } from \"./openai-compatible.js\";\nimport type { ModelInfo } from \"./types.js\";\n\ninterface OpenRouterModel {\n id: string;\n name: string;\n context_length?: number;\n pricing?: {\n prompt?: string;\n completion?: string;\n };\n}\n\nexport class OpenRouterProvider extends OpenAICompatibleProvider {\n private apiKeyValue: string;\n\n constructor(apiKey: string) {\n super(\"openrouter\", apiKey, \"https://openrouter.ai/api/v1\");\n this.apiKeyValue = apiKey;\n }\n\n async listModels(): Promise<ModelInfo[]> {\n const response = await fetch(\"https://openrouter.ai/api/v1/models\", {\n headers: { Authorization: `Bearer ${this.apiKeyValue}` },\n });\n if (!response.ok) {\n throw new Error(`OpenRouter models API error: ${response.status}`);\n }\n const data = (await response.json()) as { data: OpenRouterModel[] };\n return data.data.map((m) => ({\n id: m.id,\n name: m.name || m.id,\n contextWindow: m.context_length,\n inputPricePer1m: m.pricing?.prompt ? parseFloat(m.pricing.prompt) * 1_000_000 : undefined,\n outputPricePer1m: m.pricing?.completion ? parseFloat(m.pricing.completion) * 1_000_000 : undefined,\n }));\n }\n}\n","import { OpenAICompatibleProvider } from \"./openai-compatible.js\";\n\nexport class MiniMaxProvider extends OpenAICompatibleProvider {\n constructor(apiKey: string) {\n super(\"minimax\", apiKey, \"https://api.minimax.chat/v1\");\n }\n}\n","import type {\n LLMProvider,\n GenerateTextParams,\n GenerateTextResult,\n StreamChunk,\n EmbedParams,\n EmbedResult,\n ModelInfo,\n ToolCall,\n ToolDefinition,\n Message,\n} from \"./types.js\";\n\n// -- Ollama native API types (per https://docs.ollama.com) --\n\ninterface OllamaMessage {\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string;\n images?: string[];\n tool_calls?: OllamaToolCall[];\n tool_name?: string;\n}\n\ninterface OllamaToolCall {\n type: \"function\";\n function: {\n index: number;\n name: string;\n arguments: Record<string, unknown>;\n };\n}\n\ninterface OllamaTool {\n type: \"function\";\n function: {\n name: string;\n description: string;\n parameters: {\n type: \"object\";\n required?: string[];\n properties: Record<string, unknown>;\n };\n };\n}\n\ninterface OllamaChatRequest {\n model: string;\n messages: OllamaMessage[];\n stream: boolean;\n tools?: OllamaTool[];\n options?: { temperature?: number; num_ctx?: number };\n}\n\ninterface OllamaChatResponse {\n model: string;\n message: OllamaMessage;\n done: boolean;\n done_reason?: string;\n prompt_eval_count?: number;\n eval_count?: number;\n}\n\n// -- Convert our internal messages to Ollama format --\n\nfunction toOllamaMessages(messages: Message[], systemPrompt?: string): OllamaMessage[] {\n const result: OllamaMessage[] = [];\n\n if (systemPrompt) {\n result.push({ role: \"system\", content: systemPrompt });\n }\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue;\n\n if (typeof msg.content === \"string\") {\n result.push({ role: msg.role, content: msg.content });\n continue;\n }\n\n // Assistant message with tool calls\n const toolUseParts = msg.content.filter((p) => p.type === \"tool_use\");\n if (msg.role === \"assistant\" && toolUseParts.length > 0) {\n const textContent = msg.content\n .filter((p) => p.type === \"text\")\n .map((p) => p.text ?? \"\")\n .join(\"\");\n result.push({\n role: \"assistant\",\n content: textContent,\n tool_calls: toolUseParts.map((p, i) => ({\n type: \"function\" as const,\n function: {\n index: i,\n name: p.toolName!,\n arguments: (p.toolArguments ?? {}) as Record<string, unknown>,\n },\n })),\n });\n continue;\n }\n\n // Tool result messages — one per tool call, using tool_name\n const toolResultParts = msg.content.filter((p) => p.type === \"tool_result\");\n if (toolResultParts.length > 0) {\n for (const p of toolResultParts) {\n result.push({\n role: \"tool\",\n content: p.text ?? \"\",\n tool_name: p.toolName,\n });\n }\n continue;\n }\n\n // Regular user/assistant message (may contain images)\n const texts: string[] = [];\n const images: string[] = [];\n for (const part of msg.content) {\n if (part.type === \"image\" && part.imageBase64) {\n images.push(part.imageBase64);\n } else if (part.text) {\n texts.push(part.text);\n }\n }\n const ollamaMsg: OllamaMessage = {\n role: msg.role,\n content: texts.join(\"\"),\n };\n if (images.length > 0) {\n ollamaMsg.images = images;\n }\n result.push(ollamaMsg);\n }\n\n return result;\n}\n\nfunction toOllamaTools(tools: ToolDefinition[]): OllamaTool[] {\n return tools.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: {\n type: \"object\" as const,\n required: (t.inputSchema as { required?: string[] }).required,\n properties: (t.inputSchema as { properties?: Record<string, unknown> }).properties ?? {},\n },\n },\n }));\n}\n\nexport class OllamaProvider implements LLMProvider {\n readonly id = \"ollama\";\n private host: string;\n\n constructor(host: string) {\n this.host = host.replace(/\\/+$/, \"\");\n }\n\n async generateText(params: GenerateTextParams): Promise<GenerateTextResult> {\n const body: OllamaChatRequest = {\n model: params.model,\n messages: toOllamaMessages(params.messages, params.systemPrompt),\n stream: false,\n tools: params.tools?.length ? toOllamaTools(params.tools) : undefined,\n options: {\n ...(params.temperature != null ? { temperature: params.temperature } : {}),\n num_ctx: 16384,\n },\n };\n\n const response = await fetch(`${this.host}/api/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Ollama error: ${response.status} ${text}`);\n }\n\n const data = (await response.json()) as OllamaChatResponse;\n const msg = data.message;\n\n const toolCalls: ToolCall[] = (msg.tool_calls ?? []).map((tc, i) => ({\n id: `ollama_tc_${i}`,\n name: tc.function.name,\n arguments: tc.function.arguments,\n }));\n\n const stopReason = toolCalls.length > 0 ? \"tool_use\" : \"end\";\n\n return {\n content: msg.content ?? \"\",\n toolCalls,\n usage: {\n inputTokens: data.prompt_eval_count ?? 0,\n outputTokens: data.eval_count ?? 0,\n },\n stopReason,\n };\n }\n\n async *generateStream(params: GenerateTextParams): AsyncIterable<StreamChunk> {\n const body: OllamaChatRequest = {\n model: params.model,\n messages: toOllamaMessages(params.messages, params.systemPrompt),\n stream: true,\n tools: params.tools?.length ? toOllamaTools(params.tools) : undefined,\n options: {\n ...(params.temperature != null ? { temperature: params.temperature } : {}),\n num_ctx: 16384,\n },\n };\n\n const response = await fetch(`${this.host}/api/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Ollama error: ${response.status} ${text}`);\n }\n\n const reader = response.body?.getReader();\n if (!reader) throw new Error(\"No response body from Ollama\");\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n let inputTokens = 0;\n let outputTokens = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n let chunk: OllamaChatResponse;\n try {\n chunk = JSON.parse(trimmed);\n } catch {\n continue;\n }\n\n // Tool calls come as a complete object in one chunk\n if (chunk.message.tool_calls?.length) {\n for (let i = 0; i < chunk.message.tool_calls.length; i++) {\n const tc = chunk.message.tool_calls[i];\n const id = `ollama_tc_${i}`;\n yield {\n type: \"tool_call_start\",\n toolCall: { id, name: tc.function.name },\n };\n yield {\n type: \"tool_call_delta\",\n text: JSON.stringify(tc.function.arguments),\n };\n }\n continue;\n }\n\n // Text content\n if (chunk.message.content) {\n yield { type: \"text\", text: chunk.message.content };\n }\n\n // Capture usage from the final chunk\n if (chunk.done) {\n inputTokens = chunk.prompt_eval_count ?? 0;\n outputTokens = chunk.eval_count ?? 0;\n }\n }\n }\n\n // Process any remaining buffer\n if (buffer.trim()) {\n try {\n const chunk = JSON.parse(buffer.trim()) as OllamaChatResponse;\n if (chunk.message.tool_calls?.length) {\n for (let i = 0; i < chunk.message.tool_calls.length; i++) {\n const tc = chunk.message.tool_calls[i];\n yield {\n type: \"tool_call_start\",\n toolCall: { id: `ollama_tc_${i}`, name: tc.function.name },\n };\n yield {\n type: \"tool_call_delta\",\n text: JSON.stringify(tc.function.arguments),\n };\n }\n } else if (chunk.message.content) {\n yield { type: \"text\", text: chunk.message.content };\n }\n if (chunk.done) {\n inputTokens = chunk.prompt_eval_count ?? 0;\n outputTokens = chunk.eval_count ?? 0;\n }\n } catch {\n // ignore\n }\n }\n\n yield {\n type: \"message_end\",\n usage: { inputTokens, outputTokens },\n };\n }\n\n async embed(params: EmbedParams): Promise<EmbedResult> {\n const results: number[][] = [];\n let totalTokens = 0;\n\n for (const input of params.inputs) {\n const response = await fetch(`${this.host}/api/embed`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ model: params.model, input }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Ollama embed error: ${response.status} ${text}`);\n }\n\n const data = (await response.json()) as {\n embeddings: number[][];\n prompt_eval_count?: number;\n };\n results.push(...data.embeddings);\n totalTokens += data.prompt_eval_count ?? 0;\n }\n\n return { embeddings: results, usage: { totalTokens } };\n }\n\n async listModels(): Promise<ModelInfo[]> {\n const response = await fetch(`${this.host}/api/tags`);\n if (!response.ok) {\n throw new Error(`Failed to list Ollama models: ${response.statusText}`);\n }\n const data = (await response.json()) as {\n models: Array<{ name: string; size: number; details?: { parameter_size?: string } }>;\n };\n return (data.models ?? []).map((m) => ({\n id: m.name,\n name: m.name,\n inputPricePer1m: 0,\n outputPricePer1m: 0,\n }));\n }\n}\n","export * from \"./types.js\";\nexport { OpenAICompatibleProvider } from \"./openai-compatible.js\";\nexport { AnthropicProvider } from \"./anthropic.js\";\nexport { OpenAIProvider } from \"./openai.js\";\nexport { GoogleProvider } from \"./google.js\";\nexport { MoonshotProvider } from \"./moonshot.js\";\nexport { GrokProvider } from \"./grok.js\";\nexport { OpenRouterProvider } from \"./openrouter.js\";\nexport { MiniMaxProvider } from \"./minimax.js\";\nexport { OllamaProvider } from \"./ollama.js\";\n\nimport type { LLMProvider } from \"./types.js\";\nimport { AnthropicProvider } from \"./anthropic.js\";\nimport { OpenAIProvider } from \"./openai.js\";\nimport { GoogleProvider } from \"./google.js\";\nimport { MoonshotProvider } from \"./moonshot.js\";\nimport { GrokProvider } from \"./grok.js\";\nimport { OpenRouterProvider } from \"./openrouter.js\";\nimport { MiniMaxProvider } from \"./minimax.js\";\nimport { OllamaProvider } from \"./ollama.js\";\n\nexport type ProviderId = \"anthropic\" | \"openai\" | \"google\" | \"moonshot\" | \"grok\" | \"openrouter\" | \"minimax\" | \"ollama\";\n\nexport interface ProviderInfo {\n id: ProviderId;\n name: string;\n requiresApiKey: boolean;\n}\n\nexport const AVAILABLE_PROVIDERS: ProviderInfo[] = [\n { id: \"anthropic\", name: \"Anthropic (Claude)\", requiresApiKey: true },\n { id: \"openai\", name: \"OpenAI (GPT)\", requiresApiKey: true },\n { id: \"google\", name: \"Google (Gemini)\", requiresApiKey: true },\n { id: \"moonshot\", name: \"Moonshot (Kimi)\", requiresApiKey: true },\n { id: \"grok\", name: \"xAI (Grok)\", requiresApiKey: true },\n { id: \"openrouter\", name: \"OpenRouter\", requiresApiKey: true },\n { id: \"minimax\", name: \"MiniMax\", requiresApiKey: true },\n { id: \"ollama\", name: \"Ollama\", requiresApiKey: false },\n];\n\nexport function getProviderInfo(id: ProviderId): ProviderInfo | undefined {\n return AVAILABLE_PROVIDERS.find((p) => p.id === id);\n}\n\nexport function createProvider(\n id: ProviderId,\n apiKey: string,\n): LLMProvider {\n switch (id) {\n case \"anthropic\":\n return new AnthropicProvider(apiKey);\n case \"openai\":\n return new OpenAIProvider(apiKey);\n case \"google\":\n return new GoogleProvider(apiKey);\n case \"moonshot\":\n return new MoonshotProvider(apiKey);\n case \"grok\":\n return new GrokProvider(apiKey);\n case \"openrouter\":\n return new OpenRouterProvider(apiKey);\n case \"minimax\":\n return new MiniMaxProvider(apiKey);\n case \"ollama\":\n return new OllamaProvider(apiKey);\n default:\n throw new Error(`Unknown provider: ${id}`);\n }\n}\n","import crypto from \"node:crypto\";\nimport type {\n LLMProvider,\n Message,\n ContentPart,\n ToolDefinition,\n ToolCall,\n GenerateTextParams,\n ToolResult,\n} from \"../providers/types.js\";\nimport type {\n AgentRunParams,\n AgentRunResult,\n AgentStreamEvent,\n ToolHandler,\n ToolExecutionContext,\n PermissionRequest,\n QuestionnaireRequest,\n QuestionnaireResponse,\n} from \"./types.js\";\nimport { buildSystemPrompt, type SystemPromptContext } from \"./system-prompt.js\";\nimport { logger } from \"../logging/logger.js\";\n\nconst TOOL_CONCURRENCY = 5;\nconst TOOL_RESULT_HISTORY_LIMIT = 1500;\n\n/**\n * Parse JSON robustly — handles unescaped control characters inside string\n * values that LLMs sometimes produce (e.g. literal newlines in HTML content).\n */\nfunction parseToolJson(json: string): Record<string, unknown> {\n try {\n return JSON.parse(json);\n } catch {\n // Fix unescaped control characters within JSON string values\n let fixed = \"\";\n let inString = false;\n let escaped = false;\n\n for (let i = 0; i < json.length; i++) {\n const ch = json[i];\n const code = json.charCodeAt(i);\n\n if (escaped) {\n fixed += ch;\n escaped = false;\n continue;\n }\n\n if (ch === \"\\\\\" && inString) {\n fixed += ch;\n escaped = true;\n continue;\n }\n\n if (ch === '\"') {\n inString = !inString;\n fixed += ch;\n continue;\n }\n\n if (inString && code < 0x20) {\n // Escape control characters that are invalid inside JSON strings\n switch (ch) {\n case \"\\n\": fixed += \"\\\\n\"; break;\n case \"\\r\": fixed += \"\\\\r\"; break;\n case \"\\t\": fixed += \"\\\\t\"; break;\n default: fixed += \"\\\\u\" + code.toString(16).padStart(4, \"0\");\n }\n } else {\n fixed += ch;\n }\n }\n\n return JSON.parse(fixed);\n }\n}\n\n/**\n * Ensure the last assistant message's tool_use blocks have matching\n * tool_result blocks. This prevents the \"tool_use without tool_result\"\n * API error when a run is cancelled mid-stream.\n */\nfunction ensureToolResultsExist(messages: Message[]): void {\n if (messages.length === 0) return;\n\n const lastMsg = messages[messages.length - 1];\n if (lastMsg.role !== \"assistant\" || !Array.isArray(lastMsg.content)) return;\n\n const toolUseIds = lastMsg.content\n .filter((p) => p.type === \"tool_use\" && p.toolCallId)\n .map((p) => p.toolCallId!);\n\n if (toolUseIds.length === 0) return;\n\n // Check if there's already a following user message with tool_results\n // (there shouldn't be since this is the last message, but just in case)\n messages.push({\n role: \"user\",\n content: toolUseIds.map((id) => ({\n type: \"tool_result\" as const,\n toolCallId: id,\n text: \"[Cancelled]\",\n isError: true,\n })),\n });\n}\n\nfunction truncateOldToolResults(messages: Message[], startIdx: number): void {\n for (let i = 0; i < startIdx; i++) {\n const msg = messages[i];\n if (!Array.isArray(msg.content)) continue;\n for (const part of msg.content) {\n if (\n part.type === \"tool_result\" &&\n part.text &&\n part.text.length > TOOL_RESULT_HISTORY_LIMIT\n ) {\n part.text =\n part.text.slice(0, TOOL_RESULT_HISTORY_LIMIT) +\n \"\\n...(truncated — full result was processed earlier)\";\n }\n }\n }\n}\n\nasync function pLimit<T>(\n concurrency: number,\n tasks: Array<() => Promise<T>>,\n): Promise<T[]> {\n const results: T[] = new Array(tasks.length);\n let index = 0;\n\n const workers = Array.from({ length: Math.min(concurrency, tasks.length) }, async () => {\n while (index < tasks.length) {\n const i = index++;\n results[i] = await tasks[i]();\n }\n });\n\n await Promise.all(workers);\n return results;\n}\n\nexport interface AgentRunnerConfig {\n provider: LLMProvider;\n model: string;\n maxTurns: number;\n temperature?: number;\n maxTokens?: number;\n}\n\nexport interface AgentRunnerDeps {\n config: AgentRunnerConfig;\n tools: ToolHandler[];\n getWorkspacePath: () => string;\n getDataDir: () => string;\n getMemoryContent: () => Promise<string | undefined>;\n getGlobalMemoryContent: () => Promise<string | undefined>;\n getSkillPrompts: () => string[];\n getSessionMessages: (sessionId: string) => Promise<Message[]>;\n saveSessionMessages: (sessionId: string, messages: Message[]) => Promise<void>;\n channel?: { type: string; chatId: string };\n onPermissionRequest?: (req: PermissionRequest) => Promise<boolean>;\n onQuestionnaireRequest?: (\n req: QuestionnaireRequest,\n ) => Promise<QuestionnaireResponse>;\n}\n\nexport class AgentRunner {\n private deps: AgentRunnerDeps;\n\n constructor(deps: AgentRunnerDeps) {\n this.deps = deps;\n }\n\n private buildToolDefinitions(): ToolDefinition[] {\n return this.deps.tools.map((t) => t.definition);\n }\n\n private getToolHandler(name: string): ToolHandler | undefined {\n return this.deps.tools.find((t) => t.definition.name === name);\n }\n\n private async buildSystemPromptText(): Promise<string> {\n const [memoryContent, globalMemoryContent] = await Promise.all([\n this.deps.getMemoryContent(),\n this.deps.getGlobalMemoryContent(),\n ]);\n const ctx: SystemPromptContext = {\n workspacePath: this.deps.getWorkspacePath(),\n globalMemoryContent,\n memoryContent,\n skillPrompts: this.deps.getSkillPrompts(),\n toolNames: this.deps.tools.map((t) => t.definition.name),\n channel: this.deps.channel,\n };\n return buildSystemPrompt(ctx);\n }\n\n private createToolContext(sessionId: string, runId: string): ToolExecutionContext {\n return {\n workspacePath: this.deps.getWorkspacePath(),\n dataDir: this.deps.getDataDir(),\n sessionId,\n runId,\n requestPermission: async (req: PermissionRequest) => {\n if (this.deps.onPermissionRequest) {\n return this.deps.onPermissionRequest(req);\n }\n return true;\n },\n requestQuestionnaire: async (req: QuestionnaireRequest) => {\n if (this.deps.onQuestionnaireRequest) {\n return this.deps.onQuestionnaireRequest(req);\n }\n return {};\n },\n };\n }\n\n async run(params: AgentRunParams): Promise<AgentRunResult> {\n const runId = crypto.randomUUID();\n const sessionId = params.sessionId ?? crypto.randomUUID();\n const { config } = this.deps;\n\n const messages = await this.deps.getSessionMessages(sessionId);\n\n if (params.attachments?.length) {\n const parts: ContentPart[] = [\n { type: \"text\", text: params.prompt },\n ...params.attachments.map((a) => ({\n type: \"image\" as const,\n imageBase64: a.base64,\n mimeType: a.mimeType,\n })),\n ];\n messages.push({ role: \"user\", content: parts });\n } else {\n messages.push({ role: \"user\", content: params.prompt });\n }\n\n const systemPrompt = await this.buildSystemPromptText();\n const toolDefs = this.buildToolDefinitions();\n const toolContext = this.createToolContext(sessionId, runId);\n\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n const allToolCalls: ToolCall[] = [];\n let finalContent = \"\";\n\n for (let turn = 0; turn < config.maxTurns; turn++) {\n if (turn > 0) {\n truncateOldToolResults(messages, messages.length);\n }\n\n const generateParams: GenerateTextParams = {\n model: config.model,\n messages,\n systemPrompt,\n tools: toolDefs,\n temperature: config.temperature,\n maxTokens: config.maxTokens,\n };\n\n const result = await config.provider.generateText(generateParams);\n\n totalInputTokens += result.usage.inputTokens;\n totalOutputTokens += result.usage.outputTokens;\n\n logger.debug(\n `Turn ${turn}: in=${result.usage.inputTokens} out=${result.usage.outputTokens} stop=${result.stopReason}`,\n \"agent\",\n );\n\n if (result.content) {\n finalContent = result.content;\n }\n\n // Build assistant message\n if (result.content || result.thinking || result.toolCalls.length > 0) {\n const parts: ContentPart[] = [];\n if (result.thinking) {\n parts.push({ type: \"thinking\", text: result.thinking });\n }\n if (result.content) {\n parts.push({ type: \"text\", text: result.content });\n }\n for (const tc of result.toolCalls) {\n parts.push({\n type: \"tool_use\",\n toolCallId: tc.id,\n toolName: tc.name,\n toolArguments: tc.arguments,\n });\n }\n messages.push({ role: \"assistant\", content: parts });\n }\n\n // No tool calls or stop reason isn't tool_use → done\n if (result.toolCalls.length === 0 || result.stopReason !== \"tool_use\") {\n break;\n }\n\n allToolCalls.push(...result.toolCalls);\n\n // Execute tool calls with concurrency limit\n const toolResults = await pLimit(\n TOOL_CONCURRENCY,\n result.toolCalls.map((toolCall) => async () => {\n const handler = this.getToolHandler(toolCall.name);\n if (!handler) {\n return {\n toolCallId: toolCall.id,\n content: `Unknown tool: ${toolCall.name}`,\n isError: true,\n } satisfies ToolResult;\n }\n try {\n return await handler.execute(toolCall.arguments, toolContext);\n } catch (err) {\n return {\n toolCallId: toolCall.id,\n content: `Tool error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n } satisfies ToolResult;\n }\n }),\n );\n\n // Add tool results as user message\n const toolResultParts: ContentPart[] = result.toolCalls.map(\n (toolCall, i) => ({\n type: \"tool_result\" as const,\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n text: toolResults[i].content,\n isError: toolResults[i].isError,\n }),\n );\n messages.push({ role: \"user\", content: toolResultParts });\n\n // Warn when running low on turns\n const remaining = config.maxTurns - turn - 1;\n if (remaining === 2) {\n messages.push({\n role: \"user\",\n content:\n \"[System: 2 tool turns remaining. Focus on completing the task.]\",\n });\n }\n }\n\n // Ensure no dangling tool_use blocks before saving\n ensureToolResultsExist(messages);\n await this.deps.saveSessionMessages(sessionId, messages);\n\n return {\n runId,\n response: finalContent,\n toolCalls: allToolCalls,\n usage: {\n inputTokens: totalInputTokens,\n outputTokens: totalOutputTokens,\n },\n };\n }\n\n async *runStream(params: AgentRunParams): AsyncIterable<AgentStreamEvent> {\n const runId = crypto.randomUUID();\n const sessionId = params.sessionId ?? crypto.randomUUID();\n const { config } = this.deps;\n const signal = params.signal;\n\n const messages = await this.deps.getSessionMessages(sessionId);\n\n // Build user message with optional image attachments\n if (params.attachments?.length) {\n const parts: ContentPart[] = [\n { type: \"text\", text: params.prompt },\n ...params.attachments.map((a) => ({\n type: \"image\" as const,\n imageBase64: a.base64,\n mimeType: a.mimeType,\n })),\n ];\n messages.push({ role: \"user\", content: parts });\n } else {\n messages.push({ role: \"user\", content: params.prompt });\n }\n\n const systemPrompt = await this.buildSystemPromptText();\n const toolDefs = this.buildToolDefinitions();\n const toolContext = this.createToolContext(sessionId, runId);\n\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let finalContent = \"\";\n\n for (let turn = 0; turn < config.maxTurns; turn++) {\n // Check for cancellation before each turn\n if (signal?.aborted) {\n logger.debug(\"Agent run cancelled\", \"agent\");\n break;\n }\n\n if (turn > 0) {\n truncateOldToolResults(messages, messages.length);\n }\n\n const generateParams: GenerateTextParams = {\n model: config.model,\n messages,\n systemPrompt,\n tools: toolDefs,\n temperature: config.temperature,\n maxTokens: config.maxTokens,\n };\n\n // Use streaming for text output\n const parts: ContentPart[] = [];\n let currentText = \"\";\n let currentThinking = \"\";\n const toolCalls: ToolCall[] = [];\n const toolCallBuffers = new Map<number, { id: string; name: string; jsonChunks: string[] }>();\n\n // State machine for detecting <thinking> tags in text streams (fallback for non-native providers)\n let inThinkingTag = false;\n let tagBuffer = \"\";\n\n for await (const chunk of config.provider.generateStream(generateParams)) {\n if (signal?.aborted) break;\n if (chunk.type === \"thinking\" && chunk.text) {\n // Native thinking from provider (Anthropic, Gemini)\n currentThinking += chunk.text;\n yield { type: \"thinking_delta\", text: chunk.text };\n } else if (chunk.type === \"text\" && chunk.text) {\n // Process text through <thinking> tag detector for non-native providers\n let text = tagBuffer + chunk.text;\n tagBuffer = \"\";\n\n while (text.length > 0) {\n if (inThinkingTag) {\n const closeIdx = text.indexOf(\"</thinking>\");\n if (closeIdx !== -1) {\n const thinkText = text.slice(0, closeIdx);\n if (thinkText) {\n currentThinking += thinkText;\n yield { type: \"thinking_delta\", text: thinkText };\n }\n inThinkingTag = false;\n text = text.slice(closeIdx + \"</thinking>\".length);\n } else if (text.length > 11 && text.slice(-11).includes(\"<\")) {\n // Might have a partial </thinking> at the end\n const lastOpen = text.lastIndexOf(\"<\");\n const thinkText = text.slice(0, lastOpen);\n if (thinkText) {\n currentThinking += thinkText;\n yield { type: \"thinking_delta\", text: thinkText };\n }\n tagBuffer = text.slice(lastOpen);\n text = \"\";\n } else {\n currentThinking += text;\n yield { type: \"thinking_delta\", text };\n text = \"\";\n }\n } else {\n const openIdx = text.indexOf(\"<thinking>\");\n if (openIdx !== -1) {\n const before = text.slice(0, openIdx);\n if (before) {\n currentText += before;\n yield { type: \"text_delta\", text: before };\n }\n inThinkingTag = true;\n text = text.slice(openIdx + \"<thinking>\".length);\n } else if (text.length > 10 && text.slice(-10).includes(\"<\")) {\n // Might have a partial <thinking> at the end\n const lastOpen = text.lastIndexOf(\"<\");\n const before = text.slice(0, lastOpen);\n if (before) {\n currentText += before;\n yield { type: \"text_delta\", text: before };\n }\n tagBuffer = text.slice(lastOpen);\n text = \"\";\n } else {\n currentText += text;\n yield { type: \"text_delta\", text };\n text = \"\";\n }\n }\n }\n } else if (chunk.type === \"tool_call_start\" && chunk.toolCall) {\n // Flush any remaining tag buffer as text\n if (tagBuffer) {\n currentText += tagBuffer;\n yield { type: \"text_delta\", text: tagBuffer };\n tagBuffer = \"\";\n }\n const idx = toolCallBuffers.size;\n toolCallBuffers.set(idx, {\n id: chunk.toolCall.id ?? `tc_${idx}`,\n name: chunk.toolCall.name ?? \"unknown\",\n jsonChunks: [],\n });\n yield {\n type: \"tool_call_start\",\n toolName: chunk.toolCall.name,\n toolCallId: chunk.toolCall.id,\n };\n } else if (chunk.type === \"tool_call_delta\" && chunk.text) {\n const idx = toolCallBuffers.size - 1;\n const buf = toolCallBuffers.get(idx);\n if (buf) buf.jsonChunks.push(chunk.text);\n yield { type: \"tool_call_delta\", text: chunk.text };\n } else if (chunk.type === \"tool_call_end\") {\n yield { type: \"tool_call_end\" };\n } else if (chunk.type === \"message_end\" && chunk.usage) {\n totalInputTokens += chunk.usage.inputTokens;\n totalOutputTokens += chunk.usage.outputTokens;\n }\n }\n\n // Flush remaining tag buffer\n if (tagBuffer) {\n if (inThinkingTag) {\n currentThinking += tagBuffer;\n yield { type: \"thinking_delta\", text: tagBuffer };\n } else {\n currentText += tagBuffer;\n yield { type: \"text_delta\", text: tagBuffer };\n }\n }\n\n // Reconstruct tool calls from buffers\n const parseErrors: Array<{ id: string; name: string; error: string }> = [];\n for (const [, buf] of toolCallBuffers) {\n const json = buf.jsonChunks.join(\"\");\n if (!json) {\n toolCalls.push({ id: buf.id, name: buf.name, arguments: {} });\n continue;\n }\n try {\n const args = parseToolJson(json);\n toolCalls.push({ id: buf.id, name: buf.name, arguments: args });\n } catch (err) {\n parseErrors.push({\n id: buf.id,\n name: buf.name,\n error: `Invalid JSON arguments: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n }\n\n if (currentThinking) {\n parts.push({ type: \"thinking\", text: currentThinking });\n }\n if (currentText) {\n parts.push({ type: \"text\", text: currentText });\n finalContent = currentText;\n }\n // Add both valid tool calls and parse-errored ones to assistant message\n for (const tc of toolCalls) {\n parts.push({\n type: \"tool_use\",\n toolCallId: tc.id,\n toolName: tc.name,\n toolArguments: tc.arguments,\n });\n }\n for (const pe of parseErrors) {\n parts.push({\n type: \"tool_use\",\n toolCallId: pe.id,\n toolName: pe.name,\n toolArguments: {},\n });\n }\n if (parts.length > 0) {\n messages.push({ role: \"assistant\", content: parts });\n }\n\n // No tool calls and no parse errors → done\n if (toolCalls.length === 0 && parseErrors.length === 0) {\n break;\n }\n\n // Check for cancellation before executing tools\n if (signal?.aborted) {\n logger.debug(\"Agent run cancelled before tool execution\", \"agent\");\n break;\n }\n\n // Execute valid tool calls\n const toolResults = await pLimit(\n TOOL_CONCURRENCY,\n toolCalls.map((toolCall) => async () => {\n const handler = this.getToolHandler(toolCall.name);\n if (!handler) {\n return {\n toolCallId: toolCall.id,\n content: `Unknown tool: ${toolCall.name}`,\n isError: true,\n } satisfies ToolResult;\n }\n try {\n return await handler.execute(toolCall.arguments, toolContext);\n } catch (err) {\n return {\n toolCallId: toolCall.id,\n content: `Tool error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n } satisfies ToolResult;\n }\n }),\n );\n\n // Build results for parse-errored tool calls (not executed)\n const errorResults: ToolResult[] = parseErrors.map((pe) => ({\n toolCallId: pe.id,\n content: pe.error,\n isError: true,\n }));\n\n // Yield tool results and add to messages\n const allResults = [...toolResults, ...errorResults];\n const allCalls = [\n ...toolCalls,\n ...parseErrors.map((pe) => ({ id: pe.id, name: pe.name, arguments: {} })),\n ];\n\n const toolResultParts: ContentPart[] = allCalls.map((tc, i) => ({\n type: \"tool_result\" as const,\n toolCallId: tc.id,\n toolName: tc.name,\n text: allResults[i].content,\n isError: allResults[i].isError,\n }));\n\n for (let i = 0; i < allResults.length; i++) {\n yield {\n type: \"tool_result\",\n toolCallId: allCalls[i].id,\n toolName: allCalls[i].name,\n toolArgs: allCalls[i].arguments,\n toolResult: allResults[i],\n };\n }\n\n messages.push({ role: \"user\", content: toolResultParts });\n\n const remaining = config.maxTurns - turn - 1;\n if (remaining === 2) {\n messages.push({\n role: \"user\",\n content:\n \"[System: 2 tool turns remaining. Focus on completing the task.]\",\n });\n }\n }\n\n // Ensure no dangling tool_use blocks before saving\n ensureToolResultsExist(messages);\n await this.deps.saveSessionMessages(sessionId, messages);\n\n yield {\n type: \"done\",\n usage: {\n inputTokens: totalInputTokens,\n outputTokens: totalOutputTokens,\n },\n };\n }\n}\n","import type { ToolDefinition } from \"../providers/types.js\";\n\nexport interface SystemPromptContext {\n workspacePath: string;\n globalMemoryContent?: string;\n memoryContent?: string;\n skillPrompts?: string[];\n toolNames: string[];\n channel?: {\n type: string; // e.g. \"telegram\"\n chatId: string; // e.g. \"123456789\"\n };\n}\n\nexport function buildSystemPrompt(ctx: SystemPromptContext): string {\n const parts: string[] = [];\n\n parts.push(`You are Cortask, a local AI assistant that helps users manage files, automate tasks, and connect to external services.\n\nYou are working in the workspace: ${ctx.workspacePath}\n\nCurrent date and time: ${new Date().toLocaleString(\"en-US\", { weekday: \"long\", year: \"numeric\", month: \"long\", day: \"numeric\", hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\", timeZoneName: \"short\" })}\n\n## Core Capabilities\n- Read, write, and manage files within the workspace\n- Execute shell commands\n- Fetch web content and search the web\n- Schedule recurring tasks (cron jobs)\n- Use installed skills to connect to external APIs and services\n- Create artifacts (CSV, HTML, images) in chat\n\n## Guidelines\n- Always operate within the workspace directory unless explicitly asked otherwise\n- Ask for permission before writing files or executing potentially destructive commands\n- Be concise and direct in responses\n- When using tools, explain what you're doing briefly\n- If a task requires multiple steps, break it down and work through each step\n- After creating or generating a file the user would want to download (documents, images, exports, etc.), always call show_file so it appears as a downloadable card in the chat\n- When the user wants to view file contents inline (e.g. \"show me the file here\"), use the artifact tool with the path parameter to read from disk. NEVER re-output file contents as the content parameter — use path instead so it loads instantly\n- When the user shares personal info, preferences, or important context, proactively use memory_append to save it. Use global memory for user info (name, preferences), project memory for project-specific context. Don't ask — just save and briefly acknowledge.\n\n## File Organization\nWhen creating or saving files, organize them into logical subdirectories rather than dumping everything in the workspace root. Choose a clear, descriptive directory structure based on the content. For example:\n- Crawl/scrape results: \\`crawls/<source>/<YYYY-MM-DD>/\\` (e.g. \\`crawls/screaming-frog/2026-03-04/\\`)\n- Exports and reports: \\`exports/<type>/\\` or \\`reports/<YYYY-MM-DD>/\\`\n- Downloaded assets: \\`downloads/<source>/\\`\n- Generated data: \\`data/<topic>/\\`\n- Temporary/intermediate files: \\`temp/\\` — use this for any scratch files, intermediate processing artifacts, or files that are only needed briefly. Clean up when done if appropriate.\n\nUse your judgment — the goal is a clean, navigable workspace. Create directories as needed. Always use show_file after creating files so the user can access them.`);\n\n if (ctx.globalMemoryContent) {\n parts.push(`\\n## Global Memory\\nThe following is your long-term memory that applies across all projects:\\n\\n${ctx.globalMemoryContent}`);\n }\n\n if (ctx.memoryContent) {\n parts.push(`\\n## Project Memory\\nThe following is long-term memory specific to this project:\\n\\n${ctx.memoryContent}`);\n }\n\n if (ctx.skillPrompts && ctx.skillPrompts.length > 0) {\n parts.push(`\\n## Available Skills\\n${ctx.skillPrompts.join(\"\\n\\n\")}`);\n }\n\n if (ctx.channel) {\n parts.push(`\\n## Channel Context\\nThe user is messaging from **${ctx.channel.type}** (chat ID: \\`${ctx.channel.chatId}\\`). When scheduling cron jobs or reminders, use delivery_channel=\"${ctx.channel.type}\" and delivery_target=\"${ctx.channel.chatId}\" to deliver results back to them.`);\n }\n\n parts.push(`\\n## Available Tools\\n${ctx.toolNames.join(\", \")}`);\n\n return parts.join(\"\\n\");\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport type LogLevel = \"info\" | \"warn\" | \"error\" | \"debug\";\n\ninterface LogEntry {\n time: string;\n level: LogLevel;\n message: string;\n subsystem?: string;\n}\n\nclass Logger {\n private logDir: string | null = null;\n private stream: fs.WriteStream | null = null;\n private currentDate: string | null = null;\n\n init(logDir: string): void {\n this.logDir = logDir;\n fs.mkdirSync(logDir, { recursive: true });\n this.pruneOldLogs();\n }\n\n private ensureStream(): fs.WriteStream | null {\n if (!this.logDir) return null;\n\n const today = new Date().toISOString().slice(0, 10);\n if (today !== this.currentDate) {\n this.stream?.end();\n const logFile = path.join(\n this.logDir,\n `cortask-${today}.log`,\n );\n this.stream = fs.createWriteStream(logFile, { flags: \"a\" });\n this.currentDate = today;\n }\n return this.stream;\n }\n\n private write(level: LogLevel, message: string, subsystem?: string): void {\n const entry: LogEntry = {\n time: new Date().toISOString(),\n level,\n message,\n subsystem,\n };\n\n const stream = this.ensureStream();\n if (stream) {\n stream.write(JSON.stringify(entry) + \"\\n\");\n }\n }\n\n info(message: string, subsystem?: string): void {\n this.write(\"info\", message, subsystem);\n }\n\n warn(message: string, subsystem?: string): void {\n this.write(\"warn\", message, subsystem);\n }\n\n error(message: string, subsystem?: string): void {\n this.write(\"error\", message, subsystem);\n }\n\n debug(message: string, subsystem?: string): void {\n this.write(\"debug\", message, subsystem);\n }\n\n private pruneOldLogs(): void {\n if (!this.logDir) return;\n try {\n const files = fs.readdirSync(this.logDir);\n const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1000;\n for (const file of files) {\n if (!file.startsWith(\"cortask-\")) continue;\n const filePath = path.join(this.logDir, file);\n const stat = fs.statSync(filePath);\n if (stat.mtimeMs < cutoff) {\n fs.unlinkSync(filePath);\n }\n }\n } catch {\n // Non-critical\n }\n }\n\n close(): void {\n this.stream?.end();\n this.stream = null;\n }\n}\n\nexport const logger = new Logger();\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolHandler } from \"../types.js\";\n\nexport const readFileTool: ToolHandler = {\n definition: {\n name: \"read_file\",\n description:\n \"Read the contents of a file. Path is relative to the workspace root.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"File path relative to workspace root\",\n },\n },\n required: [\"path\"],\n },\n },\n async execute(args, context) {\n const filePath = path.resolve(context.workspacePath, args.path as string);\n\n // Ensure file is within workspace\n if (!filePath.startsWith(context.workspacePath)) {\n return {\n toolCallId: \"\",\n content: \"Error: Cannot read files outside the workspace\",\n isError: true,\n };\n }\n\n try {\n const content = await fs.readFile(filePath, \"utf-8\");\n return { toolCallId: \"\", content };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Error reading file: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolHandler } from \"../types.js\";\n\nexport const writeFileTool: ToolHandler = {\n definition: {\n name: \"write_file\",\n description:\n \"Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Path is relative to workspace root. Requires user permission.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"File path relative to workspace root\",\n },\n content: {\n type: \"string\",\n description: \"Content to write to the file\",\n },\n },\n required: [\"path\", \"content\"],\n },\n },\n async execute(args, context) {\n const filePath = path.resolve(context.workspacePath, args.path as string);\n\n if (!filePath.startsWith(context.workspacePath)) {\n return {\n toolCallId: \"\",\n content: \"Error: Cannot write files outside the workspace\",\n isError: true,\n };\n }\n\n const approved = await context.requestPermission({\n id: `write_${Date.now()}`,\n type: \"file_write\",\n description: `Write to file: ${args.path}`,\n details: `${(args.content as string).length} characters`,\n });\n\n if (!approved) {\n return {\n toolCallId: \"\",\n content: \"Permission denied: user rejected file write\",\n isError: true,\n };\n }\n\n try {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, args.content as string, \"utf-8\");\n return {\n toolCallId: \"\",\n content: `File written: ${args.path}`,\n };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Error writing file: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolHandler } from \"../types.js\";\n\nexport const listFilesTool: ToolHandler = {\n definition: {\n name: \"list_files\",\n description:\n \"List files and directories. Path is relative to the workspace root. Returns names with type indicators.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"Directory path relative to workspace root (default: root)\",\n },\n },\n },\n },\n async execute(args, context) {\n const dirPath = path.resolve(\n context.workspacePath,\n (args.path as string) || \".\",\n );\n\n if (!dirPath.startsWith(context.workspacePath)) {\n return {\n toolCallId: \"\",\n content: \"Error: Cannot list files outside the workspace\",\n isError: true,\n };\n }\n\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n const lines = entries.map((e) => {\n const suffix = e.isDirectory() ? \"/\" : \"\";\n return `${e.name}${suffix}`;\n });\n return {\n toolCallId: \"\",\n content: lines.length > 0 ? lines.join(\"\\n\") : \"(empty directory)\",\n };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Error listing files: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n};\n","import { exec } from \"node:child_process\";\nimport type { ToolHandler } from \"../types.js\";\n\nconst MAX_OUTPUT = 50_000;\n\nexport const bashTool: ToolHandler = {\n definition: {\n name: \"bash\",\n description:\n \"Execute a shell command in the workspace directory. Requires user permission. Output is captured and returned.\",\n inputSchema: {\n type: \"object\",\n properties: {\n command: {\n type: \"string\",\n description: \"The shell command to execute\",\n },\n },\n required: [\"command\"],\n },\n },\n async execute(args, context) {\n const command = args.command as string;\n\n const approved = await context.requestPermission({\n id: `bash_${Date.now()}`,\n type: \"bash\",\n description: `Execute command: ${command}`,\n });\n\n if (!approved) {\n return {\n toolCallId: \"\",\n content: \"Permission denied: user rejected command execution\",\n isError: true,\n };\n }\n\n return new Promise((resolve) => {\n exec(\n command,\n {\n cwd: context.workspacePath,\n timeout: 120_000,\n maxBuffer: 1024 * 1024 * 10,\n shell: process.platform === \"win32\" ? \"cmd.exe\" : \"/bin/bash\",\n },\n (error, stdout, stderr) => {\n let output = \"\";\n if (stdout) output += stdout;\n if (stderr) output += (output ? \"\\n\" : \"\") + `STDERR: ${stderr}`;\n if (error && !stderr) {\n output += (output ? \"\\n\" : \"\") + `Error: ${error.message}`;\n }\n\n if (output.length > MAX_OUTPUT) {\n output = output.slice(0, MAX_OUTPUT) + \"\\n...(truncated)\";\n }\n\n resolve({\n toolCallId: \"\",\n content: output || \"(no output)\",\n isError: !!error,\n });\n },\n );\n });\n },\n};\n","import type { ToolHandler } from \"../types.js\";\n\nconst MAX_CONTENT = 100_000;\n\nexport const webFetchTool: ToolHandler = {\n definition: {\n name: \"web_fetch\",\n description:\n \"Fetch the content of a web page. Returns the text content of the page.\",\n inputSchema: {\n type: \"object\",\n properties: {\n url: {\n type: \"string\",\n description: \"The URL to fetch\",\n },\n },\n required: [\"url\"],\n },\n },\n async execute(args) {\n const url = args.url as string;\n\n try {\n const response = await fetch(url, {\n headers: {\n \"User-Agent\": \"Cortask/0.1 (AI Assistant)\",\n Accept: \"text/html,application/json,text/plain,*/*\",\n },\n signal: AbortSignal.timeout(30_000),\n });\n\n if (!response.ok) {\n return {\n toolCallId: \"\",\n content: `HTTP ${response.status}: ${response.statusText}`,\n isError: true,\n };\n }\n\n let content = await response.text();\n if (content.length > MAX_CONTENT) {\n content = content.slice(0, MAX_CONTENT) + \"\\n...(truncated)\";\n }\n\n return { toolCallId: \"\", content };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Fetch error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n};\n","import type { ToolHandler } from \"../types.js\";\n\nconst MAX_RESULTS = 5;\n\nexport const webSearchTool: ToolHandler = {\n definition: {\n name: \"web_search\",\n description:\n \"Search the web using DuckDuckGo. Returns a list of search results with titles, URLs, and snippets.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n query: {\n type: \"string\",\n description: \"The search query\",\n },\n maxResults: {\n type: \"number\",\n description: `Maximum number of results to return (default ${MAX_RESULTS})`,\n },\n },\n required: [\"query\"],\n },\n },\n async execute(args) {\n const query = args.query as string;\n const maxResults = (args.maxResults as number) || MAX_RESULTS;\n\n try {\n // Use DuckDuckGo HTML lite (no API key needed)\n const url = `https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`;\n const response = await fetch(url, {\n headers: {\n \"User-Agent\":\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\",\n Accept: \"text/html\",\n },\n signal: AbortSignal.timeout(15_000),\n });\n\n if (!response.ok) {\n return {\n toolCallId: \"\",\n content: `Search failed: HTTP ${response.status}`,\n isError: true,\n };\n }\n\n const html = await response.text();\n const results = parseSearchResults(html, maxResults);\n\n if (results.length === 0) {\n return { toolCallId: \"\", content: \"No search results found.\" };\n }\n\n const formatted = results\n .map(\n (r, i) =>\n `${i + 1}. **${r.title}**\\n ${r.url}\\n ${r.snippet}`,\n )\n .join(\"\\n\\n\");\n\n return {\n toolCallId: \"\",\n content: `Search results for \"${query}\":\\n\\n${formatted}`,\n };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Search error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n};\n\ninterface SearchResult {\n title: string;\n url: string;\n snippet: string;\n}\n\nfunction parseSearchResults(html: string, max: number): SearchResult[] {\n const results: SearchResult[] = [];\n\n // Parse DuckDuckGo HTML lite results\n // Each result is in a <div class=\"result\"> or similar structure\n const resultBlocks = html.split(/class=\"result\\s/);\n\n for (let i = 1; i < resultBlocks.length && results.length < max; i++) {\n const block = resultBlocks[i];\n\n // Extract title from <a class=\"result__a\">\n const titleMatch = block.match(\n /class=\"result__a\"[^>]*>([^<]+)/,\n );\n const title = titleMatch?.[1]?.trim() ?? \"\";\n\n // Extract URL from href in result__a or result__url\n const urlMatch = block.match(\n /class=\"result__url\"[^>]*>([^<]+)/,\n );\n let url = urlMatch?.[1]?.trim() ?? \"\";\n if (url && !url.startsWith(\"http\")) {\n url = `https://${url}`;\n }\n\n // Fallback: extract href from the link\n if (!url) {\n const hrefMatch = block.match(/href=\"(https?:\\/\\/[^\"]+)\"/);\n url = hrefMatch?.[1] ?? \"\";\n }\n\n // Extract snippet from <a class=\"result__snippet\">\n const snippetMatch = block.match(\n /class=\"result__snippet\"[^>]*>([^<]+(?:<[^>]+>[^<]+)*)/,\n );\n let snippet = snippetMatch?.[1]?.trim() ?? \"\";\n // Strip HTML tags from snippet\n snippet = snippet.replace(/<[^>]+>/g, \"\");\n\n if (title && url) {\n results.push({ title, url, snippet });\n }\n }\n\n return results;\n}\n","import type { ToolHandler, QuestionnaireQuestion } from \"../types.js\";\n\nexport const questionnaireTool: ToolHandler = {\n definition: {\n name: \"questionnaire\",\n description:\n \"Present a multi-step questionnaire to the user to collect structured information. Use this when you need to gather multiple related pieces of information in an organized way.\",\n inputSchema: {\n type: \"object\",\n properties: {\n title: {\n type: \"string\",\n description: \"Title of the questionnaire (e.g., 'Project Setup')\",\n },\n description: {\n type: \"string\",\n description:\n \"Optional description explaining the purpose of the questionnaire\",\n },\n questions: {\n type: \"array\",\n description: \"Array of questions to ask the user\",\n items: {\n type: \"object\",\n properties: {\n id: {\n type: \"string\",\n description:\n \"Unique identifier for this question (e.g., 'framework', 'budget')\",\n },\n question: {\n type: \"string\",\n description: \"The question to ask\",\n },\n type: {\n type: \"string\",\n enum: [\"single\", \"multiple\", \"text\", \"textarea\"],\n description:\n \"Question type: 'single' (radio), 'multiple' (checkboxes), 'text' (short input), 'textarea' (long input)\",\n },\n options: {\n type: \"array\",\n description:\n \"Options for single/multiple choice questions (not needed for text/textarea)\",\n items: {\n type: \"object\",\n properties: {\n value: {\n type: \"string\",\n description: \"The value returned when selected\",\n },\n label: {\n type: \"string\",\n description: \"Display text for this option\",\n },\n description: {\n type: \"string\",\n description:\n \"Optional description explaining this option\",\n },\n },\n required: [\"value\", \"label\"],\n },\n },\n required: {\n type: \"boolean\",\n description:\n \"Whether this question must be answered (default: false)\",\n },\n placeholder: {\n type: \"string\",\n description: \"Placeholder text for text/textarea inputs\",\n },\n allowOther: {\n type: \"boolean\",\n description:\n \"For single/multiple choice: add an 'Other' option with text input\",\n },\n },\n required: [\"id\", \"question\", \"type\"],\n },\n },\n },\n required: [\"questions\"],\n },\n },\n async execute(args, context) {\n const title = (args.title as string) || \"Questionnaire\";\n const description = args.description as string | undefined;\n const questions = args.questions as QuestionnaireQuestion[];\n\n if (!questions || questions.length === 0) {\n return {\n toolCallId: \"\",\n content: \"Error: No questions provided\",\n isError: true,\n };\n }\n\n // Request the questionnaire from the user\n const responses = await context.requestQuestionnaire({\n id: `questionnaire_${Date.now()}`,\n title,\n description,\n questions,\n });\n\n // Format the responses as a readable summary\n if (Object.keys(responses).length === 0) {\n return {\n toolCallId: \"\",\n content: \"User skipped the questionnaire (no responses provided)\",\n };\n }\n\n const summary: string[] = [];\n for (const question of questions) {\n const response = responses[question.id];\n if (response !== undefined) {\n let value: string;\n if (Array.isArray(response)) {\n value = response.join(\", \");\n } else {\n value = String(response);\n }\n summary.push(`**${question.question}:** ${value}`);\n }\n }\n\n return {\n toolCallId: \"\",\n content: summary.join(\"\\n\"),\n };\n },\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\n\nconst CORTASK_DIR = \".cortask\";\n\nfunction getMemoryPath(\n scope: string,\n context: ToolExecutionContext,\n): string {\n if (scope === \"global\") {\n return path.join(context.dataDir, \"memory.md\");\n }\n return path.join(context.workspacePath, CORTASK_DIR, \"memory.md\");\n}\n\nexport const memoryReadTool: ToolHandler = {\n definition: {\n name: \"memory_read\",\n description:\n \"Read long-term memory. Use scope 'global' for user preferences that apply across all projects, or 'project' (default) for project-specific context.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n scope: {\n type: \"string\",\n enum: [\"project\", \"global\"],\n description:\n \"Which memory to read: 'project' for this workspace, 'global' for cross-project preferences.\",\n },\n },\n },\n },\n async execute(\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<ToolResult> {\n const scope = (args.scope as string) || \"project\";\n const memoryPath = getMemoryPath(scope, context);\n try {\n const content = await fs.readFile(memoryPath, \"utf-8\");\n return { toolCallId: \"\", content };\n } catch {\n return {\n toolCallId: \"\",\n content: `No ${scope} memory file found.`,\n };\n }\n },\n};\n\nexport const memorySaveTool: ToolHandler = {\n definition: {\n name: \"memory_save\",\n description:\n \"Save or replace long-term memory. Use scope 'global' for user preferences (e.g. coding style, preferred tools) that apply across all projects, or 'project' (default) for project-specific context (e.g. architecture decisions, tech stack).\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n content: {\n type: \"string\",\n description:\n \"The full content to write to memory.md (markdown format). This replaces the entire file.\",\n },\n scope: {\n type: \"string\",\n enum: [\"project\", \"global\"],\n description:\n \"Which memory to save: 'project' for this workspace, 'global' for cross-project preferences.\",\n },\n },\n required: [\"content\"],\n },\n },\n async execute(\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<ToolResult> {\n const content = args.content as string;\n if (!content) {\n return {\n toolCallId: \"\",\n content: \"Error: content is required\",\n isError: true,\n };\n }\n\n const scope = (args.scope as string) || \"project\";\n const memoryPath = getMemoryPath(scope, context);\n await fs.mkdir(path.dirname(memoryPath), { recursive: true });\n await fs.writeFile(memoryPath, content, \"utf-8\");\n return {\n toolCallId: \"\",\n content: `${scope === \"global\" ? \"Global\" : \"Project\"} memory saved (${content.length} chars)`,\n };\n },\n};\n\nexport const memoryAppendTool: ToolHandler = {\n definition: {\n name: \"memory_append\",\n description:\n \"Append a note to long-term memory. Use scope 'global' for user preferences that apply across all projects, or 'project' (default) for project-specific context.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n note: {\n type: \"string\",\n description: \"The note to append to memory.md\",\n },\n scope: {\n type: \"string\",\n enum: [\"project\", \"global\"],\n description:\n \"Which memory to append to: 'project' for this workspace, 'global' for cross-project preferences.\",\n },\n },\n required: [\"note\"],\n },\n },\n async execute(\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<ToolResult> {\n const note = args.note as string;\n if (!note) {\n return {\n toolCallId: \"\",\n content: \"Error: note is required\",\n isError: true,\n };\n }\n\n const scope = (args.scope as string) || \"project\";\n const memoryPath = getMemoryPath(scope, context);\n await fs.mkdir(path.dirname(memoryPath), { recursive: true });\n\n let existing = \"\";\n try {\n existing = await fs.readFile(memoryPath, \"utf-8\");\n } catch {\n existing = scope === \"global\"\n ? \"# Global Memory\\n\\nUser preferences and context that apply across all projects.\\n\"\n : \"# Project Memory\\n\\nThis file is used by Cortask to remember important context about this project.\\n\";\n }\n\n const updated = existing.trimEnd() + \"\\n\\n\" + note + \"\\n\";\n await fs.writeFile(memoryPath, updated, \"utf-8\");\n return {\n toolCallId: \"\",\n content: `Note appended to ${scope} memory.`,\n };\n },\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolHandler } from \"../types.js\";\n\nexport const showFileTool: ToolHandler = {\n definition: {\n name: \"show_file\",\n description:\n \"Present a file to the user as a downloadable card in the chat. Use this after creating or processing a file that the user would want to download (e.g. generated documents, images, exports). Path is relative to workspace root.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"File path relative to workspace root\",\n },\n label: {\n type: \"string\",\n description: \"Optional display label for the file card\",\n },\n },\n required: [\"path\"],\n },\n },\n async execute(args, context) {\n const filePath = path.resolve(context.workspacePath, args.path as string);\n\n if (!filePath.startsWith(context.workspacePath)) {\n return {\n toolCallId: \"\",\n content: \"Error: Cannot access files outside the workspace\",\n isError: true,\n };\n }\n\n try {\n const stat = await fs.stat(filePath);\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n __fileRef: true,\n path: args.path as string,\n size: stat.size,\n label: (args.label as string) || undefined,\n }),\n };\n } catch {\n return {\n toolCallId: \"\",\n content: `Error: File not found — ${args.path}`,\n isError: true,\n };\n }\n },\n};\n","import path from \"node:path\";\nimport fs from \"node:fs\";\nimport Database from \"better-sqlite3\";\nimport type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport {\n parseDataFile,\n detectColumnTypes,\n type TabularData,\n} from \"../../data/parser.js\";\n\nconst MAX_QUERY_ROWS = 100;\n\nexport const dataFileTool: ToolHandler = {\n definition: {\n name: \"data_file\",\n description:\n \"Inspect and query data files (CSV, TSV, JSON, XLSX) without loading them into the conversation. \" +\n \"Use 'inspect' to see column names, types, row count, and sample rows. \" +\n \"Use 'query' to run SQL queries (table is named 'data') for aggregations, filtering, and analysis. \" +\n \"For showing files to the user, use the show_file tool instead.\",\n inputSchema: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n enum: [\"inspect\", \"query\"],\n description: \"The action to perform\",\n },\n path: {\n type: \"string\",\n description:\n \"Path to the data file (relative to workspace or absolute)\",\n },\n sql: {\n type: \"string\",\n description:\n 'SQL query to run against the data (action=query only). The table is named \"data\". Example: SELECT column, COUNT(*) FROM data GROUP BY column',\n },\n },\n required: [\"action\", \"path\"],\n },\n },\n\n async execute(\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<ToolResult> {\n const action = args.action as string;\n const rawPath = args.path as string;\n\n if (!action || !rawPath) {\n return {\n toolCallId: \"\",\n content: \"action and path are required\",\n isError: true,\n };\n }\n\n // Resolve path relative to workspace\n const filePath = path.isAbsolute(rawPath)\n ? rawPath\n : path.resolve(context.workspacePath, rawPath);\n\n // Security: validate path is within workspace\n if (!filePath.startsWith(context.workspacePath)) {\n return {\n toolCallId: \"\",\n content: \"Error: Cannot access files outside the workspace\",\n isError: true,\n };\n }\n\n if (!fs.existsSync(filePath)) {\n return {\n toolCallId: \"\",\n content: `File not found: ${rawPath}`,\n isError: true,\n };\n }\n\n try {\n switch (action) {\n case \"inspect\":\n return await handleInspect(filePath);\n case \"query\":\n return await handleQuery(filePath, args.sql as string);\n default:\n return {\n toolCallId: \"\",\n content: `Unknown action: ${action}. Use \"inspect\" or \"query\".`,\n isError: true,\n };\n }\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n};\n\n// ---------------------------------------------------------------------------\n// inspect\n// ---------------------------------------------------------------------------\n\nasync function handleInspect(filePath: string): Promise<ToolResult> {\n const data = await parseDataFile(filePath);\n const types = detectColumnTypes(data);\n const fileName = path.basename(filePath);\n const ext = path.extname(filePath).toLowerCase().slice(1);\n\n const lines: string[] = [];\n lines.push(`File: ${fileName} (${ext.toUpperCase()})`);\n lines.push(`Rows: ${data.rows.length}`);\n lines.push(`Columns: ${data.headers.length}`);\n lines.push(\"\");\n\n // Column info — show quoted SQL names so the agent knows exactly how to reference them\n lines.push(\"Columns (use these quoted names in SQL):\");\n for (let i = 0; i < data.headers.length; i++) {\n lines.push(` \"${data.headers[i]}\" (${types[i]})`);\n }\n\n // Sample rows\n if (data.rows.length > 0) {\n lines.push(\"\");\n lines.push(\"Sample rows (first 3):\");\n const sampleRows = data.rows.slice(0, 3);\n for (const row of sampleRows) {\n const pairs = data.headers\n .map((h, i) => {\n const val = row[i] ?? \"\";\n return `${h}: ${val.length > 80 ? val.slice(0, 80) + \"…\" : val}`;\n })\n .join(\" | \");\n lines.push(` ${pairs}`);\n }\n }\n\n return { toolCallId: \"\", content: lines.join(\"\\n\") };\n}\n\n// ---------------------------------------------------------------------------\n// query\n// ---------------------------------------------------------------------------\n\nasync function handleQuery(\n filePath: string,\n sql: string | undefined,\n): Promise<ToolResult> {\n if (!sql) {\n return {\n toolCallId: \"\",\n content:\n 'The \"sql\" parameter is required for query action. Example: SELECT COUNT(*) FROM data',\n isError: true,\n };\n }\n\n const data = await parseDataFile(filePath);\n\n if (data.headers.length === 0) {\n return { toolCallId: \"\", content: \"File has no columns.\", isError: true };\n }\n\n const db = new Database(\":memory:\");\n\n try {\n createTable(db, data);\n insertRows(db, data);\n\n const stmt = db.prepare(sql);\n\n // Detect if query returns rows (SELECT) or is a command\n if (stmt.reader) {\n const rows = stmt.all() as Record<string, unknown>[];\n return {\n toolCallId: \"\",\n content: formatQueryResults(rows),\n };\n } else {\n const info = stmt.run();\n return {\n toolCallId: \"\",\n content: `Statement executed. Changes: ${info.changes}`,\n };\n }\n } finally {\n db.close();\n }\n}\n\nfunction escapeIdent(name: string): string {\n // Escape double quotes inside the name, then wrap in double quotes\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\nfunction createTable(db: Database.Database, data: TabularData): void {\n const types = detectColumnTypes(data);\n const columns = data.headers\n .map((h, i) => `${escapeIdent(h)} ${types[i]}`)\n .join(\", \");\n\n db.exec(`CREATE TABLE data (${columns})`);\n}\n\nfunction insertRows(db: Database.Database, data: TabularData): void {\n const types = detectColumnTypes(data);\n const placeholders = data.headers.map(() => \"?\").join(\", \");\n const insert = db.prepare(`INSERT INTO data VALUES (${placeholders})`);\n\n const insertMany = db.transaction((rows: string[][]) => {\n for (const row of rows) {\n const values = row.map((val, i) => {\n if (val === \"\") return null;\n if (types[i] === \"INTEGER\") {\n const n = parseInt(val, 10);\n return isNaN(n) ? val : n;\n }\n if (types[i] === \"REAL\") {\n const n = parseFloat(val.replace(\",\", \".\"));\n return isNaN(n) ? val : n;\n }\n return val;\n });\n insert.run(...values);\n }\n });\n\n insertMany(data.rows);\n}\n\nfunction formatQueryResults(rows: Record<string, unknown>[]): string {\n if (rows.length === 0) return \"No results.\";\n\n const limited = rows.slice(0, MAX_QUERY_ROWS);\n const keys = Object.keys(limited[0]);\n\n // Format as aligned text table\n const colWidths = keys.map((k) => {\n const maxVal = limited.reduce((max, row) => {\n const val = String(row[k] ?? \"\");\n return Math.max(max, val.length);\n }, k.length);\n return Math.min(maxVal, 40); // Cap column width\n });\n\n const header = keys\n .map((k, i) => k.padEnd(colWidths[i]))\n .join(\" | \");\n const separator = colWidths.map((w) => \"-\".repeat(w)).join(\"-+-\");\n const body = limited.map((row) =>\n keys\n .map((k, i) => {\n const val = String(row[k] ?? \"\");\n return (val.length > 40 ? val.slice(0, 37) + \"…\" : val).padEnd(\n colWidths[i],\n );\n })\n .join(\" | \"),\n );\n\n const lines = [header, separator, ...body];\n\n if (rows.length > MAX_QUERY_ROWS) {\n lines.push(`\\n... (${rows.length - MAX_QUERY_ROWS} more rows not shown)`);\n }\n\n lines.push(`\\n${rows.length} row(s)`);\n\n return lines.join(\"\\n\");\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport interface TabularData {\n headers: string[];\n rows: string[][];\n}\n\nconst MAX_RAW_SIZE = 500_000; // 500KB for CSV/JSON\nconst MAX_ROWS = 50_000;\n\n/**\n * Parse a data file into tabular form.\n * Supports CSV, JSON (array of objects), and XLSX.\n */\nexport async function parseDataFile(filePath: string): Promise<TabularData> {\n const ext = path.extname(filePath).toLowerCase();\n\n switch (ext) {\n case \".csv\":\n case \".tsv\":\n return parseCsv(filePath, ext === \".tsv\" ? \"\\t\" : undefined);\n case \".json\":\n return parseJson(filePath);\n case \".xlsx\":\n return parseXlsx(filePath);\n default:\n throw new Error(\n `Unsupported file type: ${ext}. Supported: .csv, .tsv, .json, .xlsx`,\n );\n }\n}\n\n/**\n * Detect column types by sampling the first 100 non-empty values per column.\n */\nexport function detectColumnTypes(\n data: TabularData,\n): Array<\"INTEGER\" | \"REAL\" | \"TEXT\"> {\n return data.headers.map((_, colIdx) => {\n const sample = data.rows\n .slice(0, 100)\n .map((r) => r[colIdx] ?? \"\")\n .filter((v) => v !== \"\");\n\n if (sample.length === 0) return \"TEXT\";\n if (sample.every((v) => /^-?\\d+$/.test(v))) return \"INTEGER\";\n if (sample.every((v) => /^-?\\d+[.,]?\\d*$/.test(v.replace(\",\", \".\"))))\n return \"REAL\";\n return \"TEXT\";\n });\n}\n\n// ---------------------------------------------------------------------------\n// CSV parser\n// ---------------------------------------------------------------------------\n\nfunction parseCsv(filePath: string, forceDelimiter?: string): TabularData {\n let raw = fs.readFileSync(filePath, \"utf-8\");\n if (raw.length > MAX_RAW_SIZE) {\n raw = raw.slice(0, MAX_RAW_SIZE);\n // Trim to last complete line\n const lastNewline = raw.lastIndexOf(\"\\n\");\n if (lastNewline > 0) raw = raw.slice(0, lastNewline);\n }\n\n // Strip BOM\n if (raw.startsWith(\"\\ufeff\")) raw = raw.slice(1);\n raw = raw.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n\n // Auto-detect delimiter from first line\n const firstLine = raw.split(\"\\n\")[0] ?? \"\";\n let delimiter = forceDelimiter ?? \",\";\n if (!forceDelimiter) {\n const tabs = (firstLine.match(/\\t/g) ?? []).length;\n const semicolons = (firstLine.match(/;/g) ?? []).length;\n const commas = (firstLine.match(/,/g) ?? []).length;\n if (tabs > commas && tabs > semicolons) delimiter = \"\\t\";\n else if (semicolons > commas) delimiter = \";\";\n }\n\n const lines = splitCsvLines(raw, delimiter);\n if (lines.length === 0) return { headers: [], rows: [] };\n\n const headers = lines[0];\n const rows = lines.slice(1, MAX_ROWS + 1);\n return { headers, rows };\n}\n\nfunction splitCsvLines(text: string, delimiter: string): string[][] {\n const result: string[][] = [];\n let current: string[] = [];\n let field = \"\";\n let inQuotes = false;\n\n for (let i = 0; i < text.length; i++) {\n const ch = text[i];\n if (inQuotes) {\n if (ch === '\"') {\n if (text[i + 1] === '\"') {\n field += '\"';\n i++;\n } else {\n inQuotes = false;\n }\n } else {\n field += ch;\n }\n } else {\n if (ch === '\"') {\n inQuotes = true;\n } else if (ch === delimiter) {\n current.push(field.trim());\n field = \"\";\n } else if (ch === \"\\n\") {\n current.push(field.trim());\n if (current.length > 1 || current[0] !== \"\") {\n result.push(current);\n }\n current = [];\n field = \"\";\n } else {\n field += ch;\n }\n }\n }\n\n // Last field\n current.push(field.trim());\n if (current.length > 1 || current[0] !== \"\") {\n result.push(current);\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// JSON parser\n// ---------------------------------------------------------------------------\n\nfunction parseJson(filePath: string): TabularData {\n let raw = fs.readFileSync(filePath, \"utf-8\");\n if (raw.length > MAX_RAW_SIZE) {\n throw new Error(\n `JSON file too large (${(raw.length / 1024).toFixed(0)}KB, max ${MAX_RAW_SIZE / 1024}KB). ` +\n \"Consider converting to CSV first.\",\n );\n }\n\n const parsed = JSON.parse(raw);\n\n if (!Array.isArray(parsed)) {\n throw new Error(\n \"JSON file must contain an array of objects at the top level.\",\n );\n }\n\n if (parsed.length === 0) return { headers: [], rows: [] };\n\n // Collect all keys from all objects for headers\n const keySet = new Set<string>();\n for (const obj of parsed.slice(0, 1000)) {\n if (obj && typeof obj === \"object\" && !Array.isArray(obj)) {\n for (const key of Object.keys(obj)) keySet.add(key);\n }\n }\n const headers = Array.from(keySet);\n\n const rows: string[][] = [];\n for (const obj of parsed.slice(0, MAX_ROWS)) {\n if (obj && typeof obj === \"object\" && !Array.isArray(obj)) {\n rows.push(\n headers.map((h) => {\n const val = obj[h];\n if (val === null || val === undefined) return \"\";\n if (typeof val === \"object\") return JSON.stringify(val);\n return String(val);\n }),\n );\n }\n }\n\n return { headers, rows };\n}\n\n// ---------------------------------------------------------------------------\n// XLSX parser\n// ---------------------------------------------------------------------------\n\nasync function parseXlsx(filePath: string): Promise<TabularData> {\n const ExcelJS = await import(\"exceljs\");\n const workbook = new ExcelJS.default.Workbook();\n await workbook.xlsx.readFile(filePath);\n\n const worksheet = workbook.worksheets[0];\n if (!worksheet || worksheet.rowCount === 0) {\n return { headers: [], rows: [] };\n }\n\n const headers: string[] = [];\n const firstRow = worksheet.getRow(1);\n firstRow.eachCell({ includeEmpty: true }, (cell, colNumber) => {\n while (headers.length < colNumber - 1) headers.push(\"\");\n headers.push(String(cell.value ?? \"\"));\n });\n\n const rows: string[][] = [];\n const maxRow = Math.min(worksheet.rowCount, MAX_ROWS + 1);\n\n for (let rowNum = 2; rowNum <= maxRow; rowNum++) {\n const row = worksheet.getRow(rowNum);\n const values: string[] = [];\n let hasValue = false;\n\n for (let colIdx = 0; colIdx < headers.length; colIdx++) {\n const cell = row.getCell(colIdx + 1);\n const val = cell.value;\n if (val !== null && val !== undefined) hasValue = true;\n\n if (val === null || val === undefined) {\n values.push(\"\");\n } else if (val instanceof Date) {\n values.push(val.toISOString());\n } else if (typeof val === \"object\") {\n // Handle rich text, formula results, etc.\n const result = (val as { result?: unknown }).result;\n const text = (val as { text?: unknown }).text;\n values.push(String(result ?? text ?? JSON.stringify(val)));\n } else {\n values.push(String(val));\n }\n }\n\n if (hasValue) rows.push(values);\n }\n\n return { headers, rows };\n}\n","import { Cron } from \"croner\";\nimport type { CronSchedule } from \"./types.js\";\n\n/**\n * Compute the next run time in milliseconds for a given schedule.\n * Returns null if the schedule has no future run (e.g. one-shot in the past).\n */\nexport function computeNextRunAtMs(\n schedule: CronSchedule,\n now: number = Date.now(),\n): number | null {\n switch (schedule.type) {\n case \"at\": {\n const target = new Date(schedule.datetime).getTime();\n return target > now ? target : null;\n }\n case \"every\": {\n // Next interval tick from now\n const interval = schedule.intervalMs;\n if (interval <= 0) return null;\n return now + interval;\n }\n case \"cron\": {\n try {\n const job = new Cron(schedule.expression, {\n timezone: schedule.timezone,\n });\n const next = job.nextRun();\n return next ? next.getTime() : null;\n } catch {\n return null;\n }\n }\n default:\n return null;\n }\n}\n\n/**\n * Validate a cron expression. Returns null if valid, error message if not.\n */\nexport function validateCronExpr(expression: string): string | null {\n try {\n new Cron(expression);\n return null;\n } catch (err) {\n return err instanceof Error ? err.message : \"Invalid cron expression\";\n }\n}\n","import type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport type { CronService } from \"../../cron/service.js\";\nimport type { CronSchedule, CronDelivery } from \"../../cron/types.js\";\nimport { validateCronExpr } from \"../../cron/schedule.js\";\n\n/**\n * Creates a cron tool handler bound to a CronService instance.\n * This is a factory because the cron service is initialized at runtime.\n */\nexport function createCronTool(cronService: CronService): ToolHandler {\n return {\n definition: {\n name: \"cortask_cron\",\n description:\n 'Manage scheduled jobs. To create: set action=\"create\", name, schedule_type, schedule_value, and prompt. To list all jobs: set action=\"list\". To remove: set action=\"remove\" and job_id.',\n inputSchema: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n description: \"The action to perform\",\n enum: [\"list\", \"create\", \"update\", \"remove\", \"run_now\"],\n },\n name: {\n type: \"string\",\n description: \"Job name (for create/update)\",\n },\n schedule_type: {\n type: \"string\",\n description: 'Schedule type: \"at\" for one-time (ISO datetime), \"every\" for interval (milliseconds), \"cron\" for recurring (cron expression)',\n enum: [\"at\", \"every\", \"cron\"],\n },\n schedule_value: {\n type: \"string\",\n description:\n 'The schedule value. Examples: \"2026-03-10T10:00:00\" for at, \"60000\" for every, \"0 9 * * 1\" for cron',\n },\n timezone: {\n type: \"string\",\n description: \"Timezone (e.g. Europe/Berlin)\",\n },\n prompt: {\n type: \"string\",\n description: \"The prompt/task to execute when the job runs\",\n },\n enabled: {\n type: \"boolean\",\n description: \"Whether the job is enabled\",\n },\n delivery_channel: {\n type: \"string\",\n description:\n 'Channel to deliver results to (e.g. \"telegram\", \"discord\", \"whatsapp\")',\n },\n delivery_target: {\n type: \"string\",\n description: \"Target chat/user ID for delivery\",\n },\n job_id: {\n type: \"string\",\n description: \"Job ID (for update, remove, run_now)\",\n },\n },\n required: [\"action\"],\n },\n },\n\n execute: async (\n args: Record<string, unknown>,\n _context: ToolExecutionContext,\n ): Promise<ToolResult> => {\n const action = args.action as string;\n\n try {\n switch (action) {\n case \"list\": {\n const jobs = cronService.list();\n if (jobs.length === 0) {\n return { toolCallId: \"\", content: \"No cron jobs found.\" };\n }\n const lines = jobs.map((j) => {\n const state = cronService.getState(j.id);\n const nextRun = state?.nextRunAtMs\n ? new Date(state.nextRunAtMs).toISOString()\n : \"none\";\n const status = j.enabled ? \"enabled\" : \"disabled\";\n return `- **${j.name}** (${j.id})\\n Status: ${status} | Next: ${nextRun} | Schedule: ${JSON.stringify(j.schedule)}\\n Prompt: ${j.prompt.slice(0, 100)}`;\n });\n return { toolCallId: \"\", content: lines.join(\"\\n\\n\") };\n }\n\n case \"create\": {\n const name = args.name as string;\n const prompt = args.prompt as string;\n if (!name || !prompt) {\n return {\n toolCallId: \"\",\n content: \"name and prompt are required for create\",\n isError: true,\n };\n }\n\n const schedule = buildSchedule(args);\n if (typeof schedule === \"string\") {\n return { toolCallId: \"\", content: schedule, isError: true };\n }\n\n const delivery = buildDelivery(args);\n const job = cronService.add({\n name,\n schedule,\n prompt,\n enabled: (args.enabled as boolean) ?? true,\n delivery,\n });\n\n return {\n toolCallId: \"\",\n content: `Cron job created: \"${job.name}\" (${job.id})\\nSchedule: ${JSON.stringify(job.schedule)}`,\n };\n }\n\n case \"update\": {\n const jobId = args.job_id as string;\n if (!jobId) {\n return {\n toolCallId: \"\",\n content: \"job_id is required for update\",\n isError: true,\n };\n }\n\n const updates: Record<string, unknown> = {};\n if (args.name) updates.name = args.name;\n if (args.prompt) updates.prompt = args.prompt;\n if (args.enabled !== undefined) updates.enabled = args.enabled;\n if (args.delivery_channel || args.delivery_target) {\n updates.delivery = buildDelivery(args);\n }\n if (args.schedule_type) {\n const schedule = buildSchedule(args);\n if (typeof schedule === \"string\") {\n return { toolCallId: \"\", content: schedule, isError: true };\n }\n updates.schedule = schedule;\n }\n\n const updated = cronService.update(jobId, updates);\n if (!updated) {\n return {\n toolCallId: \"\",\n content: `Job ${jobId} not found`,\n isError: true,\n };\n }\n\n return {\n toolCallId: \"\",\n content: `Job \"${updated.name}\" updated.`,\n };\n }\n\n case \"remove\": {\n const jobId = args.job_id as string;\n if (!jobId) {\n return {\n toolCallId: \"\",\n content: \"job_id is required for remove\",\n isError: true,\n };\n }\n const removed = cronService.remove(jobId);\n return {\n toolCallId: \"\",\n content: removed\n ? `Job ${jobId} removed.`\n : `Job ${jobId} not found.`,\n };\n }\n\n case \"run_now\": {\n const jobId = args.job_id as string;\n if (!jobId) {\n return {\n toolCallId: \"\",\n content: \"job_id is required for run_now\",\n isError: true,\n };\n }\n await cronService.runNow(jobId);\n return { toolCallId: \"\", content: `Job ${jobId} executed.` };\n }\n\n default:\n return {\n toolCallId: \"\",\n content: `Unknown action: ${action}`,\n isError: true,\n };\n }\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Cron error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n };\n}\n\nfunction buildDelivery(args: Record<string, unknown>): CronDelivery {\n return {\n channel: (args.delivery_channel as string) || undefined,\n target: (args.delivery_target as string) || undefined,\n };\n}\n\nfunction buildSchedule(\n args: Record<string, unknown>,\n): CronSchedule | string {\n const type = args.schedule_type as string;\n const value = args.schedule_value as string;\n\n if (!type || !value) {\n return \"schedule_type and schedule_value are required\";\n }\n\n switch (type) {\n case \"at\":\n return { type: \"at\", datetime: value };\n case \"every\": {\n const ms = parseInt(value, 10);\n if (isNaN(ms) || ms <= 0) return \"schedule_value must be a positive number of milliseconds\";\n return { type: \"every\", intervalMs: ms };\n }\n case \"cron\": {\n const err = validateCronExpr(value);\n if (err) return `Invalid cron expression: ${err}`;\n return {\n type: \"cron\",\n expression: value,\n timezone: (args.timezone as string) || undefined,\n };\n }\n default:\n return `Unknown schedule type: ${type}`;\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport type { ArtifactStore, Artifact } from \"../../artifacts/store.js\";\n\n/**\n * Creates an artifact tool handler bound to an ArtifactStore instance.\n */\nexport function createArtifactTool(artifactStore: ArtifactStore): ToolHandler {\n return {\n definition: {\n name: \"artifact\",\n description:\n \"Create rich artifacts (HTML, CSV, SVG, JSON) that will be rendered inline in the chat. Use this for tables, charts, interactive content, and structured data. You can either provide the content directly OR reference a file path to read from disk (preferred when the file already exists).\",\n inputSchema: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n description: \"The artifact type\",\n enum: [\"html\", \"csv\", \"json\", \"svg\", \"text\"],\n },\n title: {\n type: \"string\",\n description: \"A short title for the artifact\",\n },\n content: {\n type: \"string\",\n description:\n \"The artifact content (HTML, CSV, JSON, SVG, or plain text). Not needed if path is provided.\",\n },\n path: {\n type: \"string\",\n description:\n \"File path relative to workspace root. When provided, content is read from the file instead of the content parameter. Preferred when showing an existing file inline.\",\n },\n },\n required: [\"type\", \"title\"],\n },\n },\n\n execute: async (\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<ToolResult> => {\n const type = args.type as Artifact[\"type\"];\n const title = args.title as string;\n const filePath = args.path as string | undefined;\n let content = args.content as string | undefined;\n\n if (!type || !title) {\n return {\n toolCallId: \"\",\n content: \"type and title are required\",\n isError: true,\n };\n }\n\n // Read content from file if path is provided\n if (filePath) {\n const resolved = path.resolve(context.workspacePath, filePath);\n if (!resolved.startsWith(context.workspacePath)) {\n return {\n toolCallId: \"\",\n content: \"Error: Cannot access files outside the workspace\",\n isError: true,\n };\n }\n try {\n content = await fs.readFile(resolved, \"utf-8\");\n } catch {\n return {\n toolCallId: \"\",\n content: `Error: File not found — ${filePath}`,\n isError: true,\n };\n }\n }\n\n if (!content) {\n return {\n toolCallId: \"\",\n content: \"Either content or path must be provided\",\n isError: true,\n };\n }\n\n try {\n const artifact = artifactStore.create(type, title, content);\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n artifactId: artifact.id,\n type: artifact.type,\n title: artifact.title,\n mimeType: artifact.mimeType,\n }),\n };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Artifact error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n };\n}\n","// agent-browser CLI manager\n// Uses the agent-browser daemon for browser automation.\n// The daemon persists between commands so the browser stays open.\n\nimport { execFile } from \"node:child_process\";\nimport { existsSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { createRequire } from \"node:module\";\n\nconst DEFAULT_TIMEOUT = 30_000;\n\nfunction getNativeBinName(): string | null {\n const platform = process.platform;\n const arch = process.arch;\n if (platform === \"win32\" && arch === \"x64\") return \"agent-browser-win32-x64.exe\";\n if (platform === \"darwin\" && arch === \"arm64\") return \"agent-browser-darwin-arm64\";\n if (platform === \"darwin\" && arch === \"x64\") return \"agent-browser-darwin-x64\";\n if (platform === \"linux\" && arch === \"arm64\") return \"agent-browser-linux-arm64\";\n if (platform === \"linux\" && arch === \"x64\") return \"agent-browser-linux-x64\";\n return null;\n}\n\nfunction resolveCmd(): string {\n const nativeBin = getNativeBinName();\n\n // Check Electron extraResources (packaged desktop app)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const resourcesPath = (process as any).resourcesPath as string | undefined;\n if (resourcesPath && nativeBin) {\n const candidate = join(resourcesPath, \"agent-browser\", nativeBin);\n if (existsSync(candidate)) return candidate;\n }\n\n try {\n const require = createRequire(import.meta.url);\n if (nativeBin) {\n try {\n return require.resolve(`agent-browser/bin/${nativeBin}`);\n } catch {\n // fall through to .js wrapper\n }\n }\n return require.resolve(\"agent-browser/bin/agent-browser.js\");\n } catch {\n return \"agent-browser\";\n }\n}\n\nconst CMD = resolveCmd();\n\nexport interface BrowserInstance {\n run(args: string[]): Promise<string>;\n navigate(url: string): Promise<{ title: string; url: string; content: string }>;\n snapshot(interactive?: boolean): Promise<string>;\n screenshot(): Promise<Buffer>;\n click(selector: string): Promise<void>;\n fill(selector: string, text: string): Promise<void>;\n type(selector: string, text: string): Promise<void>;\n evaluate(script: string): Promise<string>;\n getContent(): Promise<{ title: string; url: string; content: string }>;\n select(selector: string, value: string): Promise<void>;\n press(key: string): Promise<void>;\n wait(target: string): Promise<void>;\n close(): Promise<void>;\n}\n\nlet instance: BrowserInstance | null = null;\n\nfunction ensureAgentBrowserHome(): string {\n if (!process.env.AGENT_BROWSER_HOME) {\n const dir = join(homedir(), \".agent-browser\");\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n // Set globally so daemon subprocesses inherit it\n process.env.AGENT_BROWSER_HOME = dir;\n }\n return process.env.AGENT_BROWSER_HOME;\n}\n\n// Set AGENT_BROWSER_HOME early so it's in process.env for all child processes\nensureAgentBrowserHome();\n\nfunction exec(args: string[], timeout = DEFAULT_TIMEOUT): Promise<string> {\n return new Promise((resolve, reject) => {\n const isScript = CMD.endsWith(\".js\");\n const cmd = isScript ? (process.env.NODE_PATH_BIN || process.execPath) : CMD;\n const finalArgs = isScript ? [CMD, ...args] : args;\n // Explicitly pass env and cwd to ensure agent-browser finds its home\n const env = { ...process.env };\n delete env.ELECTRON_RUN_AS_NODE;\n const cwd = ensureAgentBrowserHome();\n execFile(cmd, finalArgs, { timeout, maxBuffer: 5 * 1024 * 1024, env, cwd }, (err, stdout, stderr) => {\n if (err) {\n const msg = stderr?.trim() || stdout?.trim() || err.message;\n reject(new Error(msg));\n } else {\n resolve(stdout);\n }\n });\n });\n}\n\nexport async function isAgentBrowserAvailable(): Promise<boolean> {\n try {\n await exec([\"--version\"], 5000);\n return true;\n } catch {\n return false;\n }\n}\n\nlet _installed = false;\n\nexport async function ensureInstalled(): Promise<void> {\n if (_installed) return;\n try {\n await exec([\"--version\"], 5000);\n } catch {\n throw new Error(\"agent-browser is not installed. Run: npm install -g agent-browser\");\n }\n // Run install to download Chromium if not already present\n try {\n await exec([\"install\"], 120_000);\n } catch {\n // install may fail if browsers already exist — that's fine\n }\n // install leaves a stale daemon — kill it so the next open starts clean\n await exec([\"close\"], 5000).catch(() => {});\n _installed = true;\n}\n\nexport async function ensureBrowser(): Promise<BrowserInstance> {\n if (instance) return instance;\n await ensureInstalled();\n\n const inst: BrowserInstance = {\n async run(args: string[]) {\n return exec(args);\n },\n\n async navigate(url: string) {\n await exec([\"open\", url, \"--headed\"]);\n await exec([\"wait\", \"--load\", \"domcontentloaded\"]);\n const titleOut = await exec([\"get\", \"title\"]);\n const urlOut = await exec([\"get\", \"url\"]);\n const content = await exec([\"snapshot\", \"-i\", \"-c\"]);\n return {\n title: titleOut.trim(),\n url: urlOut.trim(),\n content,\n };\n },\n\n async snapshot(interactive = true) {\n const args = [\"snapshot\"];\n if (interactive) args.push(\"-i\");\n args.push(\"-c\");\n return exec(args);\n },\n\n async screenshot() {\n const tmpPath = `${process.env.TEMP || \"/tmp\"}/ab-screenshot-${Date.now()}.png`;\n await exec([\"screenshot\", tmpPath]);\n const fs = await import(\"node:fs/promises\");\n const buf = await fs.readFile(tmpPath);\n await fs.unlink(tmpPath).catch(() => {});\n return buf;\n },\n\n async click(selector: string) {\n await exec([\"click\", selector]);\n },\n\n async fill(selector: string, text: string) {\n await exec([\"fill\", selector, text]);\n },\n\n async type(selector: string, text: string) {\n await exec([\"type\", selector, text]);\n },\n\n async evaluate(script: string) {\n return exec([\"eval\", script]);\n },\n\n async getContent() {\n const titleOut = await exec([\"get\", \"title\"]);\n const urlOut = await exec([\"get\", \"url\"]);\n const content = await exec([\"snapshot\", \"-i\", \"-c\"]);\n return {\n title: titleOut.trim(),\n url: urlOut.trim(),\n content,\n };\n },\n\n async select(selector: string, value: string) {\n await exec([\"select\", selector, value]);\n },\n\n async press(key: string) {\n await exec([\"press\", key]);\n },\n\n async wait(target: string) {\n if (target.startsWith(\"http\")) {\n await exec([\"wait\", \"--url\", target]);\n } else {\n await exec([\"wait\", target]);\n }\n },\n\n async close() {\n await exec([\"close\"]).catch(() => {});\n instance = null;\n },\n };\n\n instance = inst;\n return inst;\n}\n\nexport async function closeBrowser(): Promise<void> {\n if (instance) {\n await instance.close();\n }\n}\n","import type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport type { ArtifactStore } from \"../../artifacts/store.js\";\nimport { ensureBrowser, closeBrowser } from \"./browser-manager.js\";\n\nconst MAX_CONTENT = 50_000;\n\nfunction truncate(text: string, max: number): string {\n return text.length > max ? text.slice(0, max) + \"\\n...(truncated)\" : text;\n}\n\nexport function createBrowserTool(artifactStore: ArtifactStore): ToolHandler {\n return {\n definition: {\n name: \"browser\",\n description:\n \"Control a visible browser window using agent-browser. \" +\n \"Use 'navigate' to open a URL, then 'snapshot' to see interactive elements with refs (@e1, @e2...). \" +\n \"Use those refs with click, fill, type, select actions for reliable interaction. \" +\n \"The browser is visible to the user. Prefer web_fetch for simple content retrieval.\",\n inputSchema: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n enum: [\n \"navigate\",\n \"snapshot\",\n \"screenshot\",\n \"click\",\n \"fill\",\n \"type\",\n \"select\",\n \"press\",\n \"evaluate\",\n \"get_text\",\n \"get_content\",\n \"wait\",\n \"back\",\n \"forward\",\n \"reload\",\n \"close\",\n ],\n description:\n \"navigate: go to URL. snapshot: get accessibility tree with element refs (@e1, @e2...). \" +\n \"screenshot: capture page. click: click element (use @eN ref or selector). \" +\n \"fill: clear and fill input. type: type into focused/selected element. \" +\n \"select: select dropdown option. press: press a key (Enter, Tab, etc). \" +\n \"evaluate: run JS. get_text: get text of element. get_content: get page title, URL and snapshot. \" +\n \"wait: wait for selector, text, or milliseconds. back/forward/reload: navigate history. close: close browser.\",\n },\n url: {\n type: \"string\",\n description: \"URL to navigate to (for navigate action)\",\n },\n selector: {\n type: \"string\",\n description:\n \"Element ref from snapshot (@e1, @e2...) or CSS selector (for click, fill, type, select, get_text actions)\",\n },\n text: {\n type: \"string\",\n description: \"Text to type/fill (for fill and type actions)\",\n },\n value: {\n type: \"string\",\n description: \"Value for select action\",\n },\n key: {\n type: \"string\",\n description: \"Key to press (for press action, e.g. Enter, Tab, Escape)\",\n },\n script: {\n type: \"string\",\n description: \"JavaScript to evaluate (for evaluate action)\",\n },\n target: {\n type: \"string\",\n description:\n \"Wait target: CSS selector, milliseconds, or URL pattern (for wait action)\",\n },\n },\n required: [\"action\"],\n },\n },\n\n async execute(\n args: Record<string, unknown>,\n _context: ToolExecutionContext,\n ): Promise<ToolResult> {\n const action = args.action as string;\n\n if (action === \"close\") {\n await closeBrowser();\n return { toolCallId: \"\", content: \"Browser closed.\" };\n }\n\n try {\n const browser = await ensureBrowser();\n\n switch (action) {\n case \"navigate\": {\n const url = args.url as string;\n if (!url) {\n return {\n toolCallId: \"\",\n content: \"url is required for navigate action\",\n isError: true,\n };\n }\n const result = await browser.navigate(url);\n return {\n toolCallId: \"\",\n content: truncate(\n `Navigated to: ${result.url}\\nTitle: ${result.title}\\n\\nInteractive elements:\\n${result.content}`,\n MAX_CONTENT,\n ),\n };\n }\n\n case \"snapshot\": {\n const snapshot = await browser.snapshot(true);\n return {\n toolCallId: \"\",\n content: truncate(snapshot, MAX_CONTENT),\n };\n }\n\n case \"screenshot\": {\n const buffer = await browser.screenshot();\n const base64 = buffer.toString(\"base64\");\n const artifact = artifactStore.create(\n \"image\",\n \"Browser Screenshot\",\n base64,\n );\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n artifactId: artifact.id,\n type: artifact.type,\n title: artifact.title,\n mimeType: artifact.mimeType,\n }),\n };\n }\n\n case \"click\": {\n const selector = args.selector as string;\n if (!selector) {\n return {\n toolCallId: \"\",\n content: \"selector is required for click action (use @eN ref or CSS selector)\",\n isError: true,\n };\n }\n await browser.click(selector);\n return { toolCallId: \"\", content: `Clicked: ${selector}` };\n }\n\n case \"fill\": {\n const selector = args.selector as string;\n const text = args.text as string;\n if (!selector || text == null) {\n return {\n toolCallId: \"\",\n content: \"selector and text are required for fill action\",\n isError: true,\n };\n }\n await browser.fill(selector, text);\n return {\n toolCallId: \"\",\n content: `Filled ${selector} with: ${text}`,\n };\n }\n\n case \"type\": {\n const selector = args.selector as string;\n const text = args.text as string;\n if (!selector || !text) {\n return {\n toolCallId: \"\",\n content: \"selector and text are required for type action\",\n isError: true,\n };\n }\n await browser.type(selector, text);\n return {\n toolCallId: \"\",\n content: `Typed into ${selector}: ${text}`,\n };\n }\n\n case \"select\": {\n const selector = args.selector as string;\n const value = args.value as string;\n if (!selector || !value) {\n return {\n toolCallId: \"\",\n content: \"selector and value are required for select action\",\n isError: true,\n };\n }\n await browser.select(selector, value);\n return {\n toolCallId: \"\",\n content: `Selected \"${value}\" in ${selector}`,\n };\n }\n\n case \"press\": {\n const key = args.key as string;\n if (!key) {\n return {\n toolCallId: \"\",\n content: \"key is required for press action\",\n isError: true,\n };\n }\n await browser.press(key);\n return { toolCallId: \"\", content: `Pressed: ${key}` };\n }\n\n case \"evaluate\": {\n const script = args.script as string;\n if (!script) {\n return {\n toolCallId: \"\",\n content: \"script is required for evaluate action\",\n isError: true,\n };\n }\n const result = await browser.evaluate(script);\n return {\n toolCallId: \"\",\n content: truncate(result, MAX_CONTENT),\n };\n }\n\n case \"get_text\": {\n const selector = args.selector as string;\n if (!selector) {\n return {\n toolCallId: \"\",\n content: \"selector is required for get_text action\",\n isError: true,\n };\n }\n const result = await browser.run([\"get\", \"text\", selector]);\n return {\n toolCallId: \"\",\n content: truncate(result, MAX_CONTENT),\n };\n }\n\n case \"get_content\": {\n const result = await browser.getContent();\n return {\n toolCallId: \"\",\n content: truncate(\n `URL: ${result.url}\\nTitle: ${result.title}\\n\\nInteractive elements:\\n${result.content}`,\n MAX_CONTENT,\n ),\n };\n }\n\n case \"wait\": {\n const target = (args.target as string) || \"2000\";\n await browser.wait(target);\n return { toolCallId: \"\", content: `Waited for: ${target}` };\n }\n\n case \"back\": {\n await browser.run([\"back\"]);\n return { toolCallId: \"\", content: \"Navigated back\" };\n }\n\n case \"forward\": {\n await browser.run([\"forward\"]);\n return { toolCallId: \"\", content: \"Navigated forward\" };\n }\n\n case \"reload\": {\n await browser.run([\"reload\"]);\n return { toolCallId: \"\", content: \"Page reloaded\" };\n }\n\n default:\n return {\n toolCallId: \"\",\n content: `Unknown action: ${action}`,\n isError: true,\n };\n }\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Browser error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n };\n}\n","import crypto from \"node:crypto\";\nimport type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport type { AgentRunner } from \"../runner.js\";\nimport {\n registerSubagentRun,\n completeSubagentRun,\n countActiveChildren,\n getDepthForSession,\n getSubagentRun,\n cancelSubagentRun,\n SUBAGENT_DEFAULTS,\n type SubagentRunRecord,\n} from \"../subagent/index.js\";\nimport { logger } from \"../../logging/logger.js\";\n\n// Lazy reference to AgentRunner to avoid circular dependency\nlet runnerRef: AgentRunner | null = null;\n\n/**\n * Set the AgentRunner reference for subagent spawning.\n * Must be called after AgentRunner instantiation.\n */\nexport function setSubagentRunner(runner: AgentRunner): void {\n runnerRef = runner;\n}\n\n/**\n * Create the subagent tool handler.\n * Factory pattern to allow runtime injection of dependencies.\n */\nexport function createSubagentTool(): ToolHandler {\n return {\n definition: {\n name: \"subagent\",\n description:\n \"Spawn a sub-agent to handle an independent subtask. The sub-agent runs in isolation and returns its result directly. Use for delegating research, analysis, or parallel tasks to save context. The tool waits for the subagent to complete and returns the result. Simply provide the task description.\",\n inputSchema: {\n type: \"object\",\n properties: {\n task: {\n type: \"string\",\n description:\n \"Clear description of the task for the sub-agent\",\n },\n },\n required: [\"task\"],\n },\n },\n\n execute: async (\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<ToolResult> => {\n return executeSpawn(args, context);\n },\n };\n}\n\n/**\n * Execute the spawn action - create and run a subagent.\n */\nasync function executeSpawn(\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n): Promise<ToolResult> {\n const task = args.task as string;\n if (!task?.trim()) {\n return {\n toolCallId: \"\",\n content: \"Error: task is required for spawn action\",\n isError: true,\n };\n }\n\n if (!runnerRef) {\n return {\n toolCallId: \"\",\n content:\n \"Error: Subagent spawning not available - runner not initialized. This is a system error.\",\n isError: true,\n };\n }\n\n // Check depth limit\n const currentDepth = getDepthForSession(context.sessionId);\n if (currentDepth >= SUBAGENT_DEFAULTS.maxDepth) {\n return {\n toolCallId: \"\",\n content: `Error: Maximum subagent depth reached (${currentDepth}/${SUBAGENT_DEFAULTS.maxDepth}). Cannot spawn deeper subagents. Consider completing this task directly or restructuring your approach.`,\n isError: true,\n };\n }\n\n // Check concurrency limit\n const activeChildren = countActiveChildren(context.sessionId);\n if (activeChildren >= SUBAGENT_DEFAULTS.maxChildrenPerAgent) {\n return {\n toolCallId: \"\",\n content: `Error: Maximum concurrent subagents reached (${activeChildren}/${SUBAGENT_DEFAULTS.maxChildrenPerAgent}). Wait for existing subagents to complete before spawning more.`,\n isError: true,\n };\n }\n\n const childRunId = crypto.randomUUID();\n const childSessionId = `subagent:${childRunId}`;\n\n // Create AbortController for cancellation support\n const abortController = new AbortController();\n\n // Register the subagent run\n const record: SubagentRunRecord = {\n runId: childRunId,\n childSessionId,\n parentSessionId: context.sessionId,\n parentRunId: context.runId,\n task,\n depth: currentDepth + 1,\n status: \"running\",\n createdAt: Date.now(),\n abortController,\n };\n registerSubagentRun(record);\n\n logger.info(\n `Subagent spawned: ${childRunId} (depth ${record.depth}) for parent ${context.sessionId}`,\n \"agent\",\n );\n\n // Capture runner reference for async function\n const runner = runnerRef;\n\n // Async execution function\n const runSubagent = async () => {\n try {\n // Create timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(\n () => reject(new Error(\"Subagent timeout after 2 minutes\")),\n SUBAGENT_DEFAULTS.timeoutMs,\n );\n });\n\n // Run subagent with race against timeout\n const result = await Promise.race([\n runner.run({\n prompt: `[Subagent Task] You are a subagent helping with a specific subtask. Complete this task concisely and provide a clear result.\\n\\nTask: ${task}`,\n sessionId: childSessionId,\n signal: abortController.signal,\n }),\n timeoutPromise,\n ]);\n\n // Mark as complete\n completeSubagentRun(childRunId, \"done\", result.response);\n\n logger.info(`Subagent completed: ${childRunId}`, \"agent\");\n\n return { success: true, result: result.response, usage: result.usage };\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n const isTimeout = errorMsg.includes(\"timeout\");\n const isCancelled = abortController.signal.aborted;\n\n completeSubagentRun(\n childRunId,\n isCancelled ? \"cancelled\" : isTimeout ? \"timeout\" : \"error\",\n undefined,\n errorMsg,\n );\n\n logger.error(`Subagent failed: ${childRunId} - ${errorMsg}`, \"agent\");\n\n return { success: false, error: errorMsg, isTimeout, isCancelled };\n }\n };\n\n // Wait for completion and return result directly\n const outcome = await runSubagent();\n\n if (!outcome.success) {\n return {\n toolCallId: \"\",\n content: `Subagent failed: ${outcome.error}`,\n isError: true,\n };\n }\n\n // Return the subagent's result directly to the parent agent\n return {\n toolCallId: \"\",\n content: outcome.result || \"Subagent completed with no output.\",\n };\n}\n\n/**\n * Execute the status action - check subagent status.\n */\nfunction executeStatus(args: Record<string, unknown>): ToolResult {\n const runId = args.runId as string;\n if (!runId?.trim()) {\n return {\n toolCallId: \"\",\n content: JSON.stringify({ error: \"runId is required for status action\" }),\n isError: true,\n };\n }\n\n const record = getSubagentRun(runId);\n if (!record) {\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n error: `Subagent run \"${runId}\" not found. It may have completed and been cleaned up.`,\n }),\n isError: true,\n };\n }\n\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n runId: record.runId,\n task: record.task,\n status: record.status,\n depth: record.depth,\n result: record.result,\n error: record.error,\n createdAt: new Date(record.createdAt).toISOString(),\n endedAt: record.endedAt\n ? new Date(record.endedAt).toISOString()\n : undefined,\n }),\n };\n}\n\n/**\n * Execute the cancel action - cancel a running subagent.\n */\nfunction executeCancel(args: Record<string, unknown>): ToolResult {\n const runId = args.runId as string;\n if (!runId?.trim()) {\n return {\n toolCallId: \"\",\n content: JSON.stringify({ error: \"runId is required for cancel action\" }),\n isError: true,\n };\n }\n\n const record = getSubagentRun(runId);\n if (!record) {\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n error: `Subagent run \"${runId}\" not found. It may have already completed.`,\n }),\n isError: true,\n };\n }\n\n if (record.status !== \"running\") {\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n error: `Subagent \"${runId}\" is not running (status: ${record.status}). Cannot cancel.`,\n }),\n isError: true,\n };\n }\n\n const cancelled = cancelSubagentRun(runId);\n\n if (cancelled) {\n logger.info(`Subagent cancelled: ${runId}`, \"agent\");\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n success: true,\n runId,\n message: \"Subagent cancelled successfully.\",\n }),\n };\n } else {\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n error: `Failed to cancel subagent \"${runId}\".`,\n }),\n isError: true,\n };\n }\n}\n","export interface SubagentRunRecord {\n runId: string;\n childSessionId: string; // Format: \"subagent:{runId}\"\n parentSessionId: string;\n parentRunId: string;\n task: string;\n depth: number; // 0=root, 1=child\n status: \"running\" | \"done\" | \"error\" | \"timeout\" | \"cancelled\";\n result?: string;\n error?: string;\n createdAt: number;\n endedAt?: number;\n abortController?: AbortController; // For cancellation\n}\n\nexport const SUBAGENT_DEFAULTS = {\n maxDepth: 1,\n maxChildrenPerAgent: 5,\n timeoutMs: 120_000, // 2 minutes\n} as const;\n","import type { SubagentRunRecord } from \"./types.js\";\n\nconst activeRuns = new Map<string, SubagentRunRecord>();\n\n/**\n * Register a new subagent run in the registry.\n */\nexport function registerSubagentRun(record: SubagentRunRecord): void {\n activeRuns.set(record.runId, record);\n}\n\n/**\n * Retrieve a subagent run by its ID.\n */\nexport function getSubagentRun(runId: string): SubagentRunRecord | undefined {\n return activeRuns.get(runId);\n}\n\n/**\n * Mark a subagent run as complete with result or error.\n */\nexport function completeSubagentRun(\n runId: string,\n status: \"done\" | \"error\" | \"timeout\" | \"cancelled\",\n result?: string,\n error?: string,\n): void {\n const record = activeRuns.get(runId);\n if (record) {\n record.status = status;\n record.result = result;\n record.error = error;\n record.endedAt = Date.now();\n // Clean up abort controller\n delete record.abortController;\n }\n}\n\n/**\n * Cancel a subagent run and all its children.\n */\nexport function cancelSubagentRun(runId: string): boolean {\n const record = activeRuns.get(runId);\n if (!record) return false;\n\n // Abort the controller if it exists\n if (record.abortController && !record.abortController.signal.aborted) {\n record.abortController.abort();\n }\n\n // Mark as cancelled\n completeSubagentRun(runId, \"cancelled\", undefined, \"Cancelled by user or parent\");\n\n // Recursively cancel children\n for (const [childRunId, childRecord] of activeRuns) {\n if (childRecord.parentSessionId === record.childSessionId && childRecord.status === \"running\") {\n cancelSubagentRun(childRunId);\n }\n }\n\n return true;\n}\n\n/**\n * Cancel all children of a parent session.\n */\nexport function cancelChildrenOfSession(parentSessionId: string): number {\n let count = 0;\n for (const [runId, record] of activeRuns) {\n if (record.parentSessionId === parentSessionId && record.status === \"running\") {\n if (cancelSubagentRun(runId)) {\n count++;\n }\n }\n }\n return count;\n}\n\n/**\n * Count how many active (running) children belong to a parent session.\n */\nexport function countActiveChildren(parentSessionId: string): number {\n let count = 0;\n for (const r of activeRuns.values()) {\n if (r.parentSessionId === parentSessionId && r.status === \"running\") {\n count++;\n }\n }\n return count;\n}\n\n/**\n * Get the depth of a session (0 for root, 1+ for subagents).\n */\nexport function getDepthForSession(sessionId: string): number {\n for (const r of activeRuns.values()) {\n if (r.childSessionId === sessionId) {\n return r.depth;\n }\n }\n return 0;\n}\n\n/**\n * Cleanup old completed subagent records.\n * @param maxAgeMs Maximum age in milliseconds (default: 30 minutes)\n */\nexport function cleanupSubagentRecords(maxAgeMs = 30 * 60 * 1000): void {\n const now = Date.now();\n for (const [runId, record] of activeRuns) {\n if (\n record.status !== \"running\" &&\n record.endedAt &&\n now - record.endedAt > maxAgeMs\n ) {\n activeRuns.delete(runId);\n }\n }\n}\n","import type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport type { WorkspaceManager } from \"../../workspace/manager.js\";\n\n/**\n * Creates a switch_workspace tool for channel-based runners.\n * Allows the user to list workspaces or switch to a different one.\n * Switching updates the workspace mapping so the next message uses the new workspace.\n */\nexport function createSwitchWorkspaceTool(\n workspaceManager: WorkspaceManager,\n chatKey: string,\n): ToolHandler {\n return {\n definition: {\n name: \"switch_workspace\",\n description:\n \"Switch the active workspace/project for this chat. Use 'list' to show available workspaces, or 'switch' with a workspace name to change. After switching, a fresh conversation starts in the new workspace context.\",\n inputSchema: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n description: \"The action to perform\",\n enum: [\"list\", \"switch\"],\n },\n workspace_name: {\n type: \"string\",\n description: \"The name of the workspace to switch to (case-insensitive partial match).\",\n },\n },\n required: [\"action\"],\n },\n },\n\n execute: async (\n args: Record<string, unknown>,\n _context: ToolExecutionContext,\n ): Promise<ToolResult> => {\n const action = args.action as string;\n\n try {\n const workspaces = await workspaceManager.list();\n\n if (action === \"list\") {\n if (workspaces.length === 0) {\n return { toolCallId: \"\", content: \"No workspaces configured.\" };\n }\n const currentWsId = workspaceManager.getChannelWorkspace(chatKey);\n const lines = workspaces.map((ws) => {\n const active = ws.id === currentWsId ? \" (active)\" : \"\";\n return `- **${ws.name}**${active}`;\n });\n return { toolCallId: \"\", content: `Available workspaces:\\n${lines.join(\"\\n\")}` };\n }\n\n if (action === \"switch\") {\n const name = args.workspace_name as string;\n if (!name) {\n return { toolCallId: \"\", content: \"workspace_name is required for switch.\", isError: true };\n }\n\n const query = name.toLowerCase();\n const match =\n workspaces.find((ws) => ws.name.toLowerCase() === query) ??\n workspaces.find((ws) => ws.name.toLowerCase().includes(query));\n\n if (!match) {\n const available = workspaces.map((ws) => ws.name).join(\", \");\n return { toolCallId: \"\", content: `No workspace matching \"${name}\". Available: ${available}`, isError: true };\n }\n\n workspaceManager.setChannelWorkspace(chatKey, match.id);\n return { toolCallId: \"\", content: `Switched to workspace **${match.name}**. The next message will start a fresh conversation in this workspace.` };\n }\n\n return { toolCallId: \"\", content: `Unknown action: ${action}. Use \"list\" or \"switch\".`, isError: true };\n } catch (err) {\n return { toolCallId: \"\", content: `Error: ${err instanceof Error ? err.message : String(err)}`, isError: true };\n }\n },\n };\n}\n","import fs from \"node:fs/promises\";\nimport type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport { createSkill, updateSkill, readSkillFile, validateSkillName } from \"../../skills/writer.js\";\nimport { removeSkill } from \"../../skills/installer.js\";\n\n/**\n * Creates a skill management tool bound to the user skills directory.\n */\nexport function createSkillTool(\n userSkillsDir: string,\n bundledSkillNames: string[],\n): ToolHandler {\n const bundledNames = new Set(bundledSkillNames);\n\n return {\n definition: {\n name: \"cortask_skill\",\n description:\n 'Manage custom skills. To create: set action=\"create\", name, and content (full SKILL.md with YAML frontmatter + markdown). To update: action=\"update\" with name and content. To list: action=\"list\". To remove: action=\"remove\" and name.',\n inputSchema: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n description: \"The action to perform\",\n enum: [\"create\", \"update\", \"list\", \"remove\"],\n },\n name: {\n type: \"string\",\n description: \"Skill name in kebab-case (for create/update/remove)\",\n },\n content: {\n type: \"string\",\n description:\n \"Full SKILL.md content including YAML frontmatter and markdown body (for create/update)\",\n },\n },\n required: [\"action\"],\n },\n },\n\n execute: async (\n args: Record<string, unknown>,\n _context: ToolExecutionContext,\n ): Promise<ToolResult> => {\n const action = args.action as string;\n\n try {\n switch (action) {\n case \"create\": {\n const name = args.name as string;\n const content = args.content as string;\n if (!name || !content) {\n return {\n toolCallId: \"\",\n content: \"name and content are required for create\",\n isError: true,\n };\n }\n\n const nameErr = validateSkillName(name);\n if (nameErr) {\n return { toolCallId: \"\", content: nameErr, isError: true };\n }\n\n if (bundledNames.has(name)) {\n return {\n toolCallId: \"\",\n content: `Cannot create skill \"${name}\" — a built-in skill with that name already exists. Choose a different name.`,\n isError: true,\n };\n }\n\n const result = await createSkill(userSkillsDir, name, content);\n return {\n toolCallId: \"\",\n content: `Custom skill \"${result.name}\" created at ${result.path}. It will be available in the next conversation.`,\n };\n }\n\n case \"update\": {\n const name = args.name as string;\n const content = args.content as string;\n if (!name || !content) {\n return {\n toolCallId: \"\",\n content: \"name and content are required for update\",\n isError: true,\n };\n }\n\n await updateSkill(userSkillsDir, name, content);\n return {\n toolCallId: \"\",\n content: `Custom skill \"${name}\" updated. Changes will take effect in the next conversation.`,\n };\n }\n\n case \"list\": {\n try {\n const entries = await fs.readdir(userSkillsDir, {\n withFileTypes: true,\n });\n const dirs = entries\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n\n if (dirs.length === 0) {\n return {\n toolCallId: \"\",\n content: \"No custom skills found.\",\n };\n }\n\n return {\n toolCallId: \"\",\n content: `Custom skills:\\n${dirs.map((d) => `- ${d}`).join(\"\\n\")}`,\n };\n } catch {\n return {\n toolCallId: \"\",\n content: \"No custom skills found.\",\n };\n }\n }\n\n case \"remove\": {\n const name = args.name as string;\n if (!name) {\n return {\n toolCallId: \"\",\n content: \"name is required for remove\",\n isError: true,\n };\n }\n\n await removeSkill(name, userSkillsDir);\n return {\n toolCallId: \"\",\n content: `Custom skill \"${name}\" removed.`,\n };\n }\n\n default:\n return {\n toolCallId: \"\",\n content: `Unknown action: ${action}`,\n isError: true,\n };\n }\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Skill error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n };\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { clearSkillCache } from \"./loader.js\";\n\nconst SKILL_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n/**\n * Validate a skill name (kebab-case, 2-50 chars).\n */\nexport function validateSkillName(name: string): string | null {\n if (!name || name.length < 2 || name.length > 50) {\n return \"Skill name must be 2-50 characters\";\n }\n if (!SKILL_NAME_RE.test(name)) {\n return \"Skill name must be kebab-case (lowercase letters, numbers, hyphens)\";\n }\n return null;\n}\n\n/**\n * Create a new custom skill by writing a SKILL.md file.\n */\nexport async function createSkill(\n skillsDir: string,\n name: string,\n rawContent: string,\n): Promise<{ name: string; path: string }> {\n const nameErr = validateSkillName(name);\n if (nameErr) throw new Error(nameErr);\n\n const skillDir = path.join(skillsDir, name);\n\n // Check if directory already exists\n try {\n await fs.access(skillDir);\n throw new Error(`Skill \"${name}\" already exists`);\n } catch (err) {\n if ((err as Error).message.includes(\"already exists\")) throw err;\n // Directory doesn't exist — good\n }\n\n await fs.mkdir(skillDir, { recursive: true });\n await fs.writeFile(path.join(skillDir, \"SKILL.md\"), rawContent, \"utf-8\");\n\n clearSkillCache();\n return { name, path: skillDir };\n}\n\n/**\n * Update an existing custom skill's SKILL.md file.\n */\nexport async function updateSkill(\n skillsDir: string,\n name: string,\n rawContent: string,\n): Promise<void> {\n const skillDir = path.join(skillsDir, name);\n const skillMdPath = path.join(skillDir, \"SKILL.md\");\n\n try {\n await fs.access(skillMdPath);\n } catch {\n throw new Error(`Skill \"${name}\" not found`);\n }\n\n await fs.writeFile(skillMdPath, rawContent, \"utf-8\");\n clearSkillCache();\n}\n\n/**\n * Read the raw SKILL.md content for editing.\n */\nexport async function readSkillFile(\n skillsDir: string,\n name: string,\n): Promise<string> {\n const skillMdPath = path.join(skillsDir, name, \"SKILL.md\");\n\n try {\n return await fs.readFile(skillMdPath, \"utf-8\");\n } catch {\n throw new Error(`Skill \"${name}\" not found`);\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport matter from \"gray-matter\";\nimport type {\n SkillManifest,\n SkillEntry,\n SkillSource,\n SkillInstallOption,\n CredentialSchema,\n} from \"./types.js\";\nimport { loadCredentialSchema, getCredentialStorageKey, getOAuth2StorageKeys, getInstanceRegistryKey, getInstanceStorageKey } from \"./credential-schema.js\";\nimport type { CredentialStore } from \"../credentials/store.js\";\nimport { logger } from \"../logging/logger.js\";\n\n// In-memory cache\nlet skillCache: SkillEntry[] | null = null;\n\nexport function clearSkillCache(): void {\n skillCache = null;\n}\n\n/**\n * Load all skills from bundled, user, and config directories.\n */\nexport async function loadSkills(\n bundledDir: string | null,\n userDir: string | null,\n configDirs: string[],\n credentialStore: CredentialStore | null,\n): Promise<SkillEntry[]> {\n if (skillCache) return skillCache;\n\n const skills: SkillEntry[] = [];\n\n // Load from bundled skills directory\n if (bundledDir) {\n const entries = await scanSkillDir(bundledDir, \"bundled\");\n skills.push(...entries);\n }\n\n // Load from user data directory\n if (userDir) {\n const entries = await scanSkillDir(userDir, \"user\");\n skills.push(...entries);\n }\n\n // Load from config-specified directories\n for (const dir of configDirs) {\n const entries = await scanSkillDir(dir, \"config-dir\");\n skills.push(...entries);\n }\n\n // Check eligibility and credential status for all skills\n for (const skill of skills) {\n // Load credential schema\n skill.credentialSchema = await loadCredentialSchema(skill.path);\n\n // Check eligibility\n const result = await checkEligibility(skill, credentialStore);\n skill.eligible = result.eligible;\n skill.ineligibleReason = result.reason;\n skill.credentialStatus = result.credentialStatus;\n\n // Filter install options by platform\n if (skill.manifest.install) {\n skill.installOptions = skill.manifest.install\n .filter((spec) => {\n if (!spec.os) return true;\n return spec.os.includes(process.platform);\n })\n .map((spec, i) => ({\n id: spec.id ?? `install-${i}`,\n kind: spec.kind,\n label: spec.label ?? `Install via ${spec.kind}`,\n }));\n }\n }\n\n skillCache = skills;\n return skills;\n}\n\n/**\n * Get only eligible skills.\n */\nexport function getEligibleSkills(skills: SkillEntry[]): SkillEntry[] {\n return skills.filter((s) => s.eligible);\n}\n\n/**\n * Scan a directory for skill subdirectories containing SKILL.md.\n */\nasync function scanSkillDir(\n dir: string,\n source: SkillSource,\n): Promise<SkillEntry[]> {\n const skills: SkillEntry[] = [];\n\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const skillDir = path.join(dir, entry.name);\n const skillMdPath = path.join(skillDir, \"SKILL.md\");\n\n try {\n const raw = await fs.readFile(skillMdPath, \"utf-8\");\n const parsed = matter(raw);\n const manifest = parsed.data as SkillManifest;\n\n if (!manifest.name) {\n manifest.name = entry.name;\n }\n if (!manifest.description) {\n manifest.description = \"\";\n }\n\n // Detect git-installed skills\n let skillSource = source;\n try {\n await fs.access(path.join(skillDir, \".origin\"));\n skillSource = \"git\";\n } catch {\n // Not a git skill\n }\n\n // Detect code tools (index.js)\n let hasCodeTools = false;\n try {\n await fs.access(path.join(skillDir, \"index.js\"));\n hasCodeTools = true;\n } catch {\n // No code tools\n }\n\n skills.push({\n manifest,\n content: parsed.content.trim(),\n path: skillDir,\n eligible: false, // Will be set by checkEligibility\n source: skillSource,\n editable: skillSource !== \"bundled\",\n hasCodeTools,\n });\n } catch {\n // No SKILL.md or parse error — skip\n }\n }\n } catch {\n // Directory doesn't exist — skip\n }\n\n return skills;\n}\n\ninterface EligibilityResult {\n eligible: boolean;\n reason?: string;\n credentialStatus?: Record<string, boolean>;\n}\n\n/**\n * Check if a skill is eligible to run on this system.\n */\nasync function checkEligibility(\n skill: SkillEntry,\n credentialStore: CredentialStore | null,\n): Promise<EligibilityResult> {\n const { manifest } = skill;\n\n // `always: true` bypasses all checks\n if (manifest.always) {\n return { eligible: true };\n }\n\n // OS check\n const requiredOs = manifest.compatibility?.os;\n if (requiredOs && !requiredOs.includes(process.platform)) {\n return {\n eligible: false,\n reason: `Requires OS: ${requiredOs.join(\", \")} (current: ${process.platform})`,\n };\n }\n\n // Environment variable check\n if (manifest.requires?.env) {\n for (const envVar of manifest.requires.env) {\n if (!process.env[envVar]) {\n return {\n eligible: false,\n reason: `Missing environment variable: ${envVar}`,\n };\n }\n }\n }\n\n // Binary availability check\n if (manifest.requires?.bins) {\n for (const bin of manifest.requires.bins) {\n if (!(await isBinaryAvailable(bin))) {\n return {\n eligible: false,\n reason: `Missing binary: ${bin}`,\n };\n }\n }\n }\n\n // Credential check\n if (skill.credentialSchema && credentialStore) {\n const credentialStatus: Record<string, boolean> = {};\n let allFulfilled = true;\n\n for (const cred of skill.credentialSchema.credentials) {\n if (cred.type === \"oauth2\") {\n const keys = getOAuth2StorageKeys(manifest.name, cred.id);\n const hasToken = await credentialStore.has(keys.accessToken);\n credentialStatus[cred.id] = hasToken;\n if (!hasToken) allFulfilled = false;\n } else if (cred.multiple && cred.fields) {\n // Multi-instance: eligible if at least one instance has all required fields\n const registryKey = getInstanceRegistryKey(manifest.name, cred.id, cred.storeAs);\n const raw = await credentialStore.get(registryKey);\n const instances = raw ? JSON.parse(raw) as Array<{ id: string }> : [];\n let anyInstanceFulfilled = false;\n\n for (const instance of instances) {\n let instanceOk = true;\n for (const field of cred.fields) {\n if (field.required === false) continue;\n const key = getInstanceStorageKey(\n manifest.name,\n cred.id,\n instance.id,\n field.key,\n cred.storeAs,\n );\n if (!(await credentialStore.has(key))) {\n instanceOk = false;\n break;\n }\n }\n if (instanceOk) {\n anyInstanceFulfilled = true;\n break;\n }\n }\n\n credentialStatus[cred.id] = anyInstanceFulfilled;\n if (!anyInstanceFulfilled) allFulfilled = false;\n } else if (cred.fields) {\n let fieldsFulfilled = true;\n for (const field of cred.fields) {\n if (field.required === false) continue;\n const key = getCredentialStorageKey(\n manifest.name,\n cred.id,\n field.key,\n cred.storeAs,\n );\n const exists = await credentialStore.has(key);\n if (!exists) {\n fieldsFulfilled = false;\n break;\n }\n }\n credentialStatus[cred.id] = fieldsFulfilled;\n if (!fieldsFulfilled) allFulfilled = false;\n }\n }\n\n if (!allFulfilled) {\n return {\n eligible: false,\n reason: \"Missing required credentials\",\n credentialStatus,\n };\n }\n\n return { eligible: true, credentialStatus };\n }\n\n return { eligible: true };\n}\n\n/**\n * Check if a binary is available on PATH.\n */\nasync function isBinaryAvailable(name: string): Promise<boolean> {\n const { exec } = await import(\"node:child_process\");\n const cmd = process.platform === \"win32\" ? `where ${name}` : `which ${name}`;\n\n return new Promise((resolve) => {\n exec(cmd, (error) => {\n resolve(!error);\n });\n });\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { CredentialSchema, CredentialInstance } from \"./types.js\";\n\n/**\n * Load credential schema from a skill's credentials.json file.\n */\nexport async function loadCredentialSchema(\n skillDir: string,\n): Promise<CredentialSchema | undefined> {\n const schemaPath = path.join(skillDir, \"credentials.json\");\n try {\n const raw = await fs.readFile(schemaPath, \"utf-8\");\n const parsed = JSON.parse(raw) as CredentialSchema;\n\n if (\n !parsed.credentials ||\n !Array.isArray(parsed.credentials)\n ) {\n return undefined;\n }\n\n return parsed;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Get the credential store key for a skill credential field.\n * Format: skill.{skillName}.{credentialId}.{fieldKey}\n */\nexport function getCredentialStorageKey(\n skillName: string,\n credentialId: string,\n fieldKey: string,\n storeAs?: string,\n): string {\n if (storeAs) {\n return `${storeAs}.${fieldKey}`;\n }\n return `skill.${skillName}.${credentialId}.${fieldKey}`;\n}\n\n/**\n * Get the credential store key for a multi-instance credential field.\n * Format: skill.{skillName}.{credentialId}.{instanceId}.{fieldKey}\n */\nexport function getInstanceStorageKey(\n skillName: string,\n credentialId: string,\n instanceId: string,\n fieldKey: string,\n storeAs?: string,\n): string {\n if (storeAs) {\n return `${storeAs}.${instanceId}.${fieldKey}`;\n }\n return `skill.${skillName}.${credentialId}.${instanceId}.${fieldKey}`;\n}\n\n/**\n * Get the registry key that stores the list of instances for a multi-instance credential.\n * Value is a JSON array of CredentialInstance objects.\n */\nexport function getInstanceRegistryKey(\n skillName: string,\n credentialId: string,\n storeAs?: string,\n): string {\n if (storeAs) {\n return `${storeAs}._instances`;\n }\n return `skill.${skillName}.${credentialId}._instances`;\n}\n\n/**\n * Slugify a label into a valid instance ID.\n */\nexport function slugifyInstanceLabel(label: string): string {\n return label\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\n/**\n * Get OAuth2 storage keys for a skill credential.\n */\nexport function getOAuth2StorageKeys(\n skillName: string,\n credentialId: string,\n): {\n accessToken: string;\n refreshToken: string;\n expiresAt: string;\n} {\n const prefix = `skill.${skillName}.${credentialId}.oauth2`;\n return {\n accessToken: `${prefix}.accessToken`,\n refreshToken: `${prefix}.refreshToken`,\n expiresAt: `${prefix}.expiresAt`,\n };\n}\n","import { execFile } from \"node:child_process\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { clearSkillCache } from \"./loader.js\";\nimport { logger } from \"../logging/logger.js\";\n\n/**\n * Install a skill from a git URL into the user skills directory.\n */\nexport async function installSkillFromGit(\n gitUrl: string,\n skillsDir: string,\n): Promise<{ name: string; path: string }> {\n await fs.mkdir(skillsDir, { recursive: true });\n\n // Extract repo name from URL\n const repoName = gitUrl\n .split(\"/\")\n .pop()\n ?.replace(/\\.git$/, \"\");\n\n if (!repoName) {\n throw new Error(`Invalid git URL: ${gitUrl}`);\n }\n\n // Validate URL format to prevent malicious input\n if (!/^(https?:\\/\\/|git@[\\w.-]+:|ssh:\\/\\/)/.test(gitUrl)) {\n throw new Error(`Invalid git URL format: ${gitUrl}`);\n }\n\n const targetDir = path.join(skillsDir, repoName);\n\n // Check if already installed\n try {\n await fs.access(targetDir);\n throw new Error(`Skill \"${repoName}\" is already installed`);\n } catch (err) {\n if ((err as Error).message.includes(\"already installed\")) throw err;\n // Directory doesn't exist — good\n }\n\n // Clone the repo (using execFile to prevent shell injection)\n await execFileAsync(\"git\", [\"clone\", \"--depth\", \"1\", gitUrl, targetDir]);\n\n // Verify SKILL.md exists\n try {\n await fs.access(path.join(targetDir, \"SKILL.md\"));\n } catch {\n // Clean up\n await fs.rm(targetDir, { recursive: true, force: true });\n throw new Error(\n `Invalid skill: no SKILL.md found in ${repoName}`,\n );\n }\n\n // Write .origin marker\n await fs.writeFile(\n path.join(targetDir, \".origin\"),\n gitUrl,\n \"utf-8\",\n );\n\n // Remove .git directory to save space\n try {\n await fs.rm(path.join(targetDir, \".git\"), {\n recursive: true,\n force: true,\n });\n } catch {\n // Non-critical\n }\n\n clearSkillCache();\n logger.info(`Installed skill \"${repoName}\" from ${gitUrl}`, \"skills\");\n\n return { name: repoName, path: targetDir };\n}\n\n/**\n * Remove an installed skill.\n */\nexport async function removeSkill(\n skillName: string,\n skillsDir: string,\n): Promise<void> {\n const targetDir = path.join(skillsDir, skillName);\n\n try {\n await fs.access(targetDir);\n } catch {\n throw new Error(`Skill \"${skillName}\" not found`);\n }\n\n await fs.rm(targetDir, { recursive: true, force: true });\n clearSkillCache();\n logger.info(`Removed skill \"${skillName}\"`, \"skills\");\n}\n\nfunction execFileAsync(cmd: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(cmd, args, { timeout: 60_000 }, (error, stdout, stderr) => {\n if (error) {\n reject(new Error(stderr || error.message));\n return;\n }\n resolve(stdout);\n });\n });\n}\n","import type { ToolHandler } from \"../types.js\";\nimport { readFileTool } from \"./read-file.js\";\nimport { writeFileTool } from \"./write-file.js\";\nimport { listFilesTool } from \"./list-files.js\";\nimport { bashTool } from \"./bash.js\";\nimport { webFetchTool } from \"./web-fetch.js\";\nimport { webSearchTool } from \"./web-search.js\";\nimport { questionnaireTool } from \"./questionnaire.js\";\nimport { memoryReadTool, memorySaveTool, memoryAppendTool } from \"./memory.js\";\nimport { showFileTool } from \"./show-file.js\";\nimport { dataFileTool } from \"./data-file.js\";\n\nexport const builtinTools: ToolHandler[] = [\n readFileTool,\n writeFileTool,\n listFilesTool,\n bashTool,\n webFetchTool,\n webSearchTool,\n\n questionnaireTool,\n memoryReadTool,\n memorySaveTool,\n memoryAppendTool,\n showFileTool,\n dataFileTool,\n];\n\nexport {\n readFileTool,\n writeFileTool,\n listFilesTool,\n bashTool,\n webFetchTool,\n webSearchTool,\n\n questionnaireTool,\n memoryReadTool,\n memorySaveTool,\n memoryAppendTool,\n showFileTool,\n dataFileTool,\n};\n\nexport { createCronTool } from \"./cron.js\";\nexport { createArtifactTool } from \"./artifact.js\";\nexport { createBrowserTool } from \"./browser.js\";\nexport { ensureInstalled as ensureBrowserInstalled } from \"./browser-manager.js\";\nexport { createSubagentTool, setSubagentRunner } from \"./subagent.js\";\nexport { createSwitchWorkspaceTool } from \"./switch-workspace.js\";\nexport { createSkillTool } from \"./skill.js\";\n","import crypto from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport interface CredentialStore {\n get(key: string): Promise<string | null>;\n set(key: string, value: string): Promise<void>;\n delete(key: string): Promise<void>;\n has(key: string): Promise<boolean>;\n list(): Promise<string[]>;\n}\n\ninterface EncryptedData {\n iv: string;\n data: string;\n tag: string;\n salt: string;\n}\n\ninterface StoreFile {\n version: 1;\n entries: Record<string, EncryptedData>;\n}\n\nfunction deriveKey(secret: string, salt: Buffer): Buffer {\n return crypto.scryptSync(secret, salt, 32);\n}\n\nfunction encrypt(text: string, secret: string): EncryptedData {\n const salt = crypto.randomBytes(16);\n const key = deriveKey(secret, salt);\n const iv = crypto.randomBytes(12);\n const cipher = crypto.createCipheriv(\"aes-256-gcm\", key, iv);\n const encrypted = Buffer.concat([\n cipher.update(text, \"utf-8\"),\n cipher.final(),\n ]);\n const tag = cipher.getAuthTag();\n return {\n iv: iv.toString(\"hex\"),\n data: encrypted.toString(\"hex\"),\n tag: tag.toString(\"hex\"),\n salt: salt.toString(\"hex\"),\n };\n}\n\nfunction decrypt(enc: EncryptedData, secret: string): string {\n const salt = Buffer.from(enc.salt, \"hex\");\n const key = deriveKey(secret, salt);\n const iv = Buffer.from(enc.iv, \"hex\");\n const tag = Buffer.from(enc.tag, \"hex\");\n const decipher = crypto.createDecipheriv(\"aes-256-gcm\", key, iv);\n decipher.setAuthTag(tag);\n const decrypted = Buffer.concat([\n decipher.update(Buffer.from(enc.data, \"hex\")),\n decipher.final(),\n ]);\n return decrypted.toString(\"utf-8\");\n}\n\nexport class EncryptedCredentialStore implements CredentialStore {\n private filePath: string;\n private secret: string;\n private store: StoreFile | null = null;\n\n constructor(filePath: string, secret: string) {\n this.filePath = filePath;\n this.secret = secret;\n }\n\n private async load(): Promise<StoreFile> {\n if (this.store) return this.store;\n try {\n const raw = await fs.readFile(this.filePath, \"utf-8\");\n this.store = JSON.parse(raw) as StoreFile;\n } catch {\n this.store = { version: 1, entries: {} };\n }\n return this.store;\n }\n\n private async save(): Promise<void> {\n if (!this.store) return;\n await fs.mkdir(path.dirname(this.filePath), { recursive: true });\n const tmp = `${this.filePath}.${process.pid}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(this.store, null, 2), {\n encoding: \"utf-8\",\n mode: 0o600,\n });\n await fs.rename(tmp, this.filePath);\n }\n\n async get(key: string): Promise<string | null> {\n const store = await this.load();\n const entry = store.entries[key];\n if (!entry) return null;\n try {\n return decrypt(entry, this.secret);\n } catch {\n return null;\n }\n }\n\n async set(key: string, value: string): Promise<void> {\n const store = await this.load();\n store.entries[key] = encrypt(value, this.secret);\n await this.save();\n }\n\n async delete(key: string): Promise<void> {\n const store = await this.load();\n delete store.entries[key];\n await this.save();\n }\n\n async has(key: string): Promise<boolean> {\n const store = await this.load();\n return key in store.entries;\n }\n\n async list(): Promise<string[]> {\n const store = await this.load();\n return Object.keys(store.entries);\n }\n}\n\nexport async function getOrCreateSecret(dataDir: string): Promise<string> {\n const secretFromEnv = process.env.CORTASK_SECRET;\n if (secretFromEnv) return secretFromEnv;\n\n const keyPath = path.join(dataDir, \"master.key\");\n try {\n return await fs.readFile(keyPath, \"utf-8\");\n } catch {\n const key = crypto.randomBytes(32).toString(\"hex\");\n await fs.mkdir(path.dirname(keyPath), { recursive: true });\n await fs.writeFile(keyPath, key, { mode: 0o600 });\n return key;\n }\n}\n\nexport function credentialKey(\n category: string,\n ...parts: string[]\n): string {\n return [category, ...parts].join(\".\");\n}\n","import { z } from \"zod\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nconst providerConfigSchema = z.object({\n model: z.string().optional(),\n});\n\nconst agentConfigSchema = z.object({\n maxTurns: z.number().int().min(1).max(200).default(25),\n temperature: z.number().min(0).max(2).default(0.7),\n maxTokens: z.number().int().positive().optional(),\n});\n\nconst telegramChannelSchema = z.object({\n enabled: z.boolean().default(false),\n allowedUsers: z.array(z.string()).default([]),\n});\n\nconst channelsConfigSchema = z.object({\n telegram: telegramChannelSchema.default({}),\n});\n\nconst skillsConfigSchema = z.object({\n dirs: z.array(z.string()).default([]),\n});\n\nconst spendingLimitSchema = z.object({\n enabled: z.boolean().default(false),\n maxTokens: z.number().int().nonnegative().optional(),\n maxCostUsd: z.number().nonnegative().optional(),\n period: z.enum([\"daily\", \"weekly\", \"monthly\"]).default(\"monthly\"),\n});\n\nconst serverConfigSchema = z.object({\n port: z.number().int().min(1).max(65535).default(3777),\n host: z.string().default(\"127.0.0.1\"),\n});\n\nexport const cortaskConfigSchema = z.object({\n onboarded: z.boolean().default(false),\n workspace: z\n .object({\n defaultDir: z.string().optional(),\n })\n .default({}),\n providers: z\n .object({\n default: z.string().default(\"anthropic\"),\n anthropic: providerConfigSchema.default({}),\n openai: providerConfigSchema.default({}),\n google: providerConfigSchema.default({}),\n moonshot: providerConfigSchema.default({}),\n grok: providerConfigSchema.default({}),\n openrouter: providerConfigSchema.default({}),\n minimax: providerConfigSchema.default({}),\n ollama: providerConfigSchema.default({}),\n })\n .default({}),\n agent: agentConfigSchema.default({}),\n spending: spendingLimitSchema.default({}),\n channels: channelsConfigSchema.default({}),\n skills: skillsConfigSchema.default({}),\n server: serverConfigSchema.default({}),\n});\n\nexport type CortaskConfig = z.infer<typeof cortaskConfigSchema>;\n\nexport async function loadConfig(configPath: string): Promise<CortaskConfig> {\n try {\n const raw = await fs.readFile(configPath, \"utf-8\");\n // Simple env var substitution: ${ENV_VAR}\n const resolved = raw.replace(/\\$\\{(\\w+)\\}/g, (_, name) => {\n return process.env[name] ?? \"\";\n });\n\n // Dynamic import of yaml parser — use JSON as fallback\n let parsed: unknown;\n if (configPath.endsWith(\".yaml\") || configPath.endsWith(\".yml\")) {\n // Use a simple YAML subset parser or require yaml package\n const { parse } = await import(\"yaml\" as string).catch(() => ({\n parse: (s: string) => JSON.parse(s),\n }));\n parsed = parse(resolved);\n } else {\n parsed = JSON.parse(resolved);\n }\n\n return cortaskConfigSchema.parse(parsed);\n } catch {\n // Return defaults if no config file exists\n return cortaskConfigSchema.parse({});\n }\n}\n\nexport async function saveConfig(\n configPath: string,\n config: CortaskConfig,\n): Promise<void> {\n const dir = path.dirname(configPath);\n await fs.mkdir(dir, { recursive: true });\n\n if (configPath.endsWith(\".yaml\") || configPath.endsWith(\".yml\")) {\n const { stringify } = await import(\"yaml\" as string).catch(() => ({\n stringify: (obj: unknown) => JSON.stringify(obj, null, 2),\n }));\n await fs.writeFile(configPath, stringify(config), \"utf-8\");\n } else {\n await fs.writeFile(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n }\n}\n\nexport function getDataDir(): string {\n if (process.env.CORTASK_DATA_DIR) {\n return process.env.CORTASK_DATA_DIR;\n }\n const home =\n process.env.HOME || process.env.USERPROFILE || process.cwd();\n return path.join(home, \".cortask\");\n}\n","import { createProvider, type ProviderId } from \"../providers/index.js\";\nimport type { ProviderValidationResult } from \"./types.js\";\n\nexport async function validateProvider(\n type: ProviderId,\n apiKey: string,\n): Promise<ProviderValidationResult> {\n try {\n const provider = createProvider(type, apiKey);\n\n // Test with a simple prompt\n const result = await provider.generateText({\n model: getDefaultModel(type),\n messages: [{ role: \"user\", content: \"Hi\" }],\n maxTokens: 10,\n });\n\n return {\n valid: true,\n model: getDefaultModel(type),\n };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : \"Invalid API key\",\n };\n }\n}\n\nfunction getDefaultModel(type: ProviderId): string {\n switch (type) {\n case \"anthropic\":\n return \"claude-sonnet-4-5-20250929\";\n case \"openai\":\n return \"gpt-4o\";\n case \"google\":\n return \"gemini-2.0-flash-exp\";\n case \"moonshot\":\n return \"moonshot-v1-8k\";\n case \"grok\":\n return \"grok-3-latest\";\n case \"openrouter\":\n return \"openai/gpt-4o\";\n case \"minimax\":\n return \"MiniMax-Text-01\";\n default:\n throw new Error(`Unknown provider: ${type}`);\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport Database from \"better-sqlite3\";\n\nexport interface Workspace {\n id: string;\n name: string;\n rootPath: string;\n lastAccessedAt: string;\n provider?: string;\n model?: string;\n skills?: string[];\n}\n\nconst CORTASK_DIR = \".cortask\";\n\nexport class WorkspaceManager {\n private db: Database.Database;\n private dataDir: string;\n private activeWorkspaceId: string | null = null;\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.dataDir = path.dirname(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.db.pragma(\"foreign_keys = ON\");\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS workspaces (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n root_path TEXT NOT NULL UNIQUE,\n last_accessed_at TEXT NOT NULL,\n provider TEXT,\n model TEXT,\n skills TEXT,\n sort_order INTEGER NOT NULL DEFAULT 0\n );\n CREATE TABLE IF NOT EXISTS channel_workspace_map (\n chat_key TEXT PRIMARY KEY,\n workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE\n )\n `);\n // Migration: add sort_order if missing\n const cols = this.db.pragma(\"table_info(workspaces)\") as Array<{ name: string }>;\n if (!cols.some((c) => c.name === \"sort_order\")) {\n this.db.exec(\"ALTER TABLE workspaces ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0\");\n }\n }\n\n async list(): Promise<Workspace[]> {\n const rows = this.db\n .prepare(\n \"SELECT * FROM workspaces ORDER BY sort_order ASC, last_accessed_at DESC LIMIT 20\",\n )\n .all() as Array<{\n id: string;\n name: string;\n root_path: string;\n last_accessed_at: string;\n provider: string | null;\n model: string | null;\n skills: string | null;\n sort_order: number;\n }>;\n\n return rows.map((r) => ({\n id: r.id,\n name: r.name,\n rootPath: r.root_path,\n lastAccessedAt: r.last_accessed_at,\n provider: r.provider ?? undefined,\n model: r.model ?? undefined,\n skills: r.skills ? JSON.parse(r.skills) : undefined,\n }));\n }\n\n async get(id: string): Promise<Workspace | null> {\n const row = this.db\n .prepare(\"SELECT * FROM workspaces WHERE id = ?\")\n .get(id) as {\n id: string;\n name: string;\n root_path: string;\n last_accessed_at: string;\n provider: string | null;\n model: string | null;\n skills: string | null;\n } | undefined;\n\n if (!row) return null;\n\n return {\n id: row.id,\n name: row.name,\n rootPath: row.root_path,\n lastAccessedAt: row.last_accessed_at,\n provider: row.provider ?? undefined,\n model: row.model ?? undefined,\n skills: row.skills ? JSON.parse(row.skills) : undefined,\n };\n }\n\n async create(name: string, rootPath?: string): Promise<Workspace> {\n const id = crypto.randomUUID();\n const now = new Date().toISOString();\n const absPath = rootPath\n ? path.resolve(rootPath)\n : path.join(this.dataDir, \"projects\", id);\n\n // Ensure .cortask directory exists in the workspace\n const cortaskDir = path.join(absPath, CORTASK_DIR);\n await fs.mkdir(cortaskDir, { recursive: true });\n\n // Create default memory.md\n const memoryPath = path.join(cortaskDir, \"memory.md\");\n try {\n await fs.access(memoryPath);\n } catch {\n await fs.writeFile(\n memoryPath,\n \"# Project Memory\\n\\nThis file is used by Cortask to remember important context about this project.\\n\",\n \"utf-8\",\n );\n }\n\n this.db\n .prepare(\n \"INSERT INTO workspaces (id, name, root_path, last_accessed_at) VALUES (?, ?, ?, ?)\",\n )\n .run(id, name, absPath, now);\n\n return { id, name, rootPath: absPath, lastAccessedAt: now };\n }\n\n async update(\n id: string,\n updates: Partial<Pick<Workspace, \"name\" | \"provider\" | \"model\" | \"skills\">>,\n ): Promise<void> {\n const sets: string[] = [];\n const values: unknown[] = [];\n\n if (updates.name !== undefined) {\n sets.push(\"name = ?\");\n values.push(updates.name);\n }\n if (updates.provider !== undefined) {\n sets.push(\"provider = ?\");\n values.push(updates.provider);\n }\n if (updates.model !== undefined) {\n sets.push(\"model = ?\");\n values.push(updates.model);\n }\n if (updates.skills !== undefined) {\n sets.push(\"skills = ?\");\n values.push(JSON.stringify(updates.skills));\n }\n\n if (sets.length === 0) return;\n\n values.push(id);\n this.db\n .prepare(`UPDATE workspaces SET ${sets.join(\", \")} WHERE id = ?`)\n .run(...values);\n }\n\n async reorder(orderedIds: string[]): Promise<void> {\n const update = this.db.prepare(\n \"UPDATE workspaces SET sort_order = ? WHERE id = ?\",\n );\n const transaction = this.db.transaction(() => {\n for (let i = 0; i < orderedIds.length; i++) {\n update.run(i, orderedIds[i]);\n }\n });\n transaction();\n }\n\n async delete(id: string): Promise<void> {\n this.db.prepare(\"DELETE FROM workspaces WHERE id = ?\").run(id);\n }\n\n async open(id: string): Promise<Workspace | null> {\n const workspace = await this.get(id);\n if (!workspace) return null;\n\n this.db\n .prepare(\"UPDATE workspaces SET last_accessed_at = ? WHERE id = ?\")\n .run(new Date().toISOString(), id);\n\n this.activeWorkspaceId = id;\n return workspace;\n }\n\n getActiveWorkspaceId(): string | null {\n return this.activeWorkspaceId;\n }\n\n async getActiveWorkspace(): Promise<Workspace | null> {\n if (!this.activeWorkspaceId) return null;\n return this.get(this.activeWorkspaceId);\n }\n\n async readMemory(workspacePath: string): Promise<string | undefined> {\n const memoryPath = path.join(workspacePath, CORTASK_DIR, \"memory.md\");\n try {\n return await fs.readFile(memoryPath, \"utf-8\");\n } catch {\n return undefined;\n }\n }\n\n async writeMemory(workspacePath: string, content: string): Promise<void> {\n const memoryPath = path.join(workspacePath, CORTASK_DIR, \"memory.md\");\n await fs.mkdir(path.dirname(memoryPath), { recursive: true });\n await fs.writeFile(memoryPath, content, \"utf-8\");\n }\n\n async readGlobalMemory(dataDir: string): Promise<string | undefined> {\n const memoryPath = path.join(dataDir, \"memory.md\");\n try {\n return await fs.readFile(memoryPath, \"utf-8\");\n } catch {\n return undefined;\n }\n }\n\n async writeGlobalMemory(dataDir: string, content: string): Promise<void> {\n await fs.mkdir(dataDir, { recursive: true });\n await fs.writeFile(path.join(dataDir, \"memory.md\"), content, \"utf-8\");\n }\n\n getSessionDbPath(workspacePath: string): string {\n return path.join(workspacePath, CORTASK_DIR, \"sessions.db\");\n }\n\n getChannelWorkspace(chatKey: string): string | null {\n const row = this.db\n .prepare(\"SELECT workspace_id FROM channel_workspace_map WHERE chat_key = ?\")\n .get(chatKey) as { workspace_id: string } | undefined;\n return row?.workspace_id ?? null;\n }\n\n setChannelWorkspace(chatKey: string, workspaceId: string): void {\n this.db\n .prepare(\"INSERT OR REPLACE INTO channel_workspace_map (chat_key, workspace_id) VALUES (?, ?)\")\n .run(chatKey, workspaceId);\n }\n\n close(): void {\n this.db.close();\n }\n}\n","import Database from \"better-sqlite3\";\nimport type { Message } from \"../providers/types.js\";\n\nexport type ChannelType = \"whatsapp\" | \"telegram\" | \"discord\";\n\nexport interface Session {\n id: string;\n title: string;\n createdAt: string;\n updatedAt: string;\n parentSessionId?: string;\n depth?: number;\n channel?: ChannelType;\n}\n\nexport interface SessionWithMessages extends Session {\n messages: Message[];\n}\n\nexport class SessionStore {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL DEFAULT 'New Chat',\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n parent_session_id TEXT,\n depth INTEGER DEFAULT 0,\n channel TEXT\n );\n CREATE TABLE IF NOT EXISTS messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n created_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);\n CREATE INDEX IF NOT EXISTS idx_sessions_parent ON sessions(parent_session_id);\n `);\n\n // Note: Migrations are run at server startup via migrateSessionDatabase()\n // See packages/core/src/session/migrate.ts\n }\n\n listSessions(): Session[] {\n return this.db\n .prepare(\n \"SELECT id, title, created_at as createdAt, updated_at as updatedAt, parent_session_id as parentSessionId, depth, channel FROM sessions ORDER BY updated_at DESC\",\n )\n .all() as Session[];\n }\n\n getSession(id: string): SessionWithMessages | null {\n const session = this.db\n .prepare(\n \"SELECT id, title, created_at as createdAt, updated_at as updatedAt, parent_session_id as parentSessionId, depth, channel FROM sessions WHERE id = ?\",\n )\n .get(id) as Session | undefined;\n\n if (!session) return null;\n\n const rows = this.db\n .prepare(\n \"SELECT role, content FROM messages WHERE session_id = ? ORDER BY id ASC\",\n )\n .all(id) as Array<{ role: string; content: string }>;\n\n const messages: Message[] = rows.map((r) => ({\n role: r.role as Message[\"role\"],\n content: JSON.parse(r.content),\n }));\n\n return { ...session, messages };\n }\n\n createSession(id: string, title?: string, parentSessionId?: string, depth?: number, channel?: ChannelType): Session {\n const now = new Date().toISOString();\n this.db\n .prepare(\n \"INSERT INTO sessions (id, title, created_at, updated_at, parent_session_id, depth, channel) VALUES (?, ?, ?, ?, ?, ?, ?)\",\n )\n .run(id, title ?? \"New Chat\", now, now, parentSessionId ?? null, depth ?? 0, channel ?? null);\n\n return { id, title: title ?? \"New Chat\", createdAt: now, updatedAt: now, parentSessionId, depth, channel };\n }\n\n saveMessages(sessionId: string, messages: Message[], channel?: ChannelType): void {\n // Ensure session exists\n const exists = this.db\n .prepare(\"SELECT 1 FROM sessions WHERE id = ?\")\n .get(sessionId);\n\n if (!exists) {\n this.createSession(sessionId, undefined, undefined, undefined, channel);\n }\n\n // Clear existing messages and re-insert all\n const transaction = this.db.transaction(() => {\n this.db\n .prepare(\"DELETE FROM messages WHERE session_id = ?\")\n .run(sessionId);\n\n const insert = this.db.prepare(\n \"INSERT INTO messages (session_id, role, content, created_at) VALUES (?, ?, ?, ?)\",\n );\n\n const now = new Date().toISOString();\n for (const msg of messages) {\n insert.run(\n sessionId,\n msg.role,\n JSON.stringify(msg.content),\n now,\n );\n }\n\n this.db\n .prepare(\"UPDATE sessions SET updated_at = ? WHERE id = ?\")\n .run(now, sessionId);\n });\n\n transaction();\n }\n\n getMessages(sessionId: string): Message[] {\n const rows = this.db\n .prepare(\n \"SELECT role, content FROM messages WHERE session_id = ? ORDER BY id ASC\",\n )\n .all(sessionId) as Array<{ role: string; content: string }>;\n\n return rows.map((r) => ({\n role: r.role as Message[\"role\"],\n content: JSON.parse(r.content),\n }));\n }\n\n deleteSession(id: string): void {\n this.db.prepare(\"DELETE FROM sessions WHERE id = ?\").run(id);\n }\n\n updateTitle(id: string, title: string): void {\n this.db\n .prepare(\"UPDATE sessions SET title = ? WHERE id = ?\")\n .run(title, id);\n }\n\n close(): void {\n this.db.close();\n }\n}\n","import Database from \"better-sqlite3\";\nimport fs from \"node:fs\";\nimport { logger } from \"../logging/logger.js\";\n\n/**\n * Run database migrations on a session database.\n * This is separate from SessionStore to allow running migrations at startup\n * before any SessionStore instances are cached.\n */\nexport function migrateSessionDatabase(dbPath: string): void {\n // Check if database file exists\n if (!fs.existsSync(dbPath)) {\n logger.debug(`Session database does not exist yet: ${dbPath}`, \"migration\");\n return;\n }\n\n const db = new Database(dbPath);\n\n try {\n // Get current schema\n const columns = db\n .prepare(\"PRAGMA table_info(sessions)\")\n .all() as Array<{ name: string }>;\n\n if (columns.length === 0) {\n logger.debug(`Sessions table does not exist yet in: ${dbPath}`, \"migration\");\n db.close();\n return;\n }\n\n const hasParentSessionId = columns.some((c) => c.name === \"parent_session_id\");\n const hasDepth = columns.some((c) => c.name === \"depth\");\n const hasChannel = columns.some((c) => c.name === \"channel\");\n\n let changesMade = false;\n\n // Add parent_session_id column\n if (!hasParentSessionId) {\n logger.info(`Migrating database: adding parent_session_id to ${dbPath}`, \"migration\");\n db.exec(\"ALTER TABLE sessions ADD COLUMN parent_session_id TEXT\");\n changesMade = true;\n logger.info(\"✓ Added parent_session_id column\", \"migration\");\n }\n\n // Add depth column\n if (!hasDepth) {\n logger.info(`Migrating database: adding depth to ${dbPath}`, \"migration\");\n db.exec(\"ALTER TABLE sessions ADD COLUMN depth INTEGER DEFAULT 0\");\n changesMade = true;\n logger.info(\"✓ Added depth column\", \"migration\");\n }\n\n // Add channel column\n if (!hasChannel) {\n logger.info(`Migrating database: adding channel to ${dbPath}`, \"migration\");\n db.exec(\"ALTER TABLE sessions ADD COLUMN channel TEXT\");\n changesMade = true;\n logger.info(\"✓ Added channel column\", \"migration\");\n }\n\n // Create index if we added parent_session_id\n if (!hasParentSessionId) {\n db.exec(\n \"CREATE INDEX IF NOT EXISTS idx_sessions_parent ON sessions(parent_session_id)\",\n );\n logger.info(\"✓ Created parent session index\", \"migration\");\n }\n\n if (changesMade) {\n logger.info(`Migration complete for: ${dbPath}`, \"migration\");\n } else {\n logger.debug(`No migration needed for: ${dbPath}`, \"migration\");\n }\n } catch (err) {\n logger.error(\n `Migration failed for ${dbPath}: ${err instanceof Error ? err.message : String(err)}`,\n \"migration\",\n );\n throw err;\n } finally {\n db.close();\n }\n}\n\n/**\n * Migrate all workspace session databases.\n * @param workspaces Array of workspace objects with rootPath property\n */\nexport function migrateAllWorkspaces(workspaces: Array<{ rootPath: string }>): void {\n logger.info(`Running migrations for ${workspaces.length} workspace(s)`, \"migration\");\n\n let successCount = 0;\n let errorCount = 0;\n\n for (const workspace of workspaces) {\n const dbPath = `${workspace.rootPath}/.cortask/sessions.db`;\n try {\n migrateSessionDatabase(dbPath);\n successCount++;\n } catch (err) {\n errorCount++;\n logger.error(\n `Failed to migrate workspace ${workspace.rootPath}: ${err instanceof Error ? err.message : String(err)}`,\n \"migration\",\n );\n }\n }\n\n logger.info(\n `Migration summary: ${successCount} successful, ${errorCount} failed`,\n \"migration\",\n );\n\n if (errorCount > 0) {\n throw new Error(`Migration failed for ${errorCount} workspace(s)`);\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolDefinition, ToolResult } from \"../providers/types.js\";\nimport type {\n SkillEntry,\n SkillToolTemplate,\n SkillCodeTool,\n} from \"./types.js\";\nimport {\n getCredentialStorageKey,\n getOAuth2StorageKeys,\n getInstanceRegistryKey,\n getInstanceStorageKey,\n} from \"./credential-schema.js\";\nimport type { CredentialStore } from \"../credentials/store.js\";\nimport { logger } from \"../logging/logger.js\";\n\ninterface SkillToolRegistry {\n toolDefs: ToolDefinition[];\n toolNames: Set<string>;\n handlers: Map<\n string,\n (args: Record<string, unknown>, workspacePath: string) => Promise<ToolResult>\n >;\n}\n\n/**\n * Build tool definitions and handlers from eligible skills.\n */\nexport async function buildSkillTools(\n skills: SkillEntry[],\n credentialStore: CredentialStore | null,\n): Promise<SkillToolRegistry> {\n const toolDefs: ToolDefinition[] = [];\n const toolNames = new Set<string>();\n const handlers = new Map<\n string,\n (args: Record<string, unknown>, workspacePath: string) => Promise<ToolResult>\n >();\n\n for (const skill of skills) {\n // HTTP template tools\n if (skill.manifest.tools) {\n for (const template of skill.manifest.tools) {\n const def = buildHttpToolDefinition(template);\n toolDefs.push(def);\n toolNames.add(def.name);\n\n handlers.set(def.name, async (args, workspacePath) => {\n return executeHttpTool(\n template,\n args,\n skill,\n credentialStore,\n workspacePath,\n );\n });\n }\n }\n\n // Code tools (index.js)\n if (skill.hasCodeTools) {\n try {\n const indexPath = `file://${skill.path}/index.js`;\n const mod = await import(indexPath);\n const codeTools = (mod.tools ?? []) as SkillCodeTool[];\n\n for (const ct of codeTools) {\n toolDefs.push({\n name: ct.name,\n description: ct.description,\n inputSchema: ct.inputSchema,\n });\n toolNames.add(ct.name);\n\n handlers.set(ct.name, async (args, _workspacePath) => {\n try {\n const result = await ct.execute(args, {\n credentialStore,\n skillName: skill.manifest.name,\n });\n return {\n toolCallId: \"\",\n content: result.content,\n isError: result.isError,\n };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Code tool error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n });\n }\n } catch (err) {\n logger.error(\n `Failed to load code tools for skill ${skill.manifest.name}: ${err}`,\n \"skills\",\n );\n }\n }\n }\n\n return { toolDefs, toolNames, handlers };\n}\n\n/**\n * Build a ToolDefinition from an HTTP template.\n */\nfunction buildHttpToolDefinition(\n template: SkillToolTemplate,\n): ToolDefinition {\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n\n for (const [key, input] of Object.entries(template.input)) {\n properties[key] = {\n type: input.type,\n description: input.description,\n };\n if (input.enum) {\n (properties[key] as Record<string, unknown>).enum = input.enum;\n }\n if (input.required !== false) {\n required.push(key);\n }\n }\n\n return {\n name: template.name,\n description: template.description,\n inputSchema: {\n type: \"object\",\n properties,\n required,\n },\n };\n}\n\n/**\n * Execute an HTTP template tool call.\n *\n * Supports three placeholder types in URL, headers, body:\n * - {{argName}} → from tool call arguments\n * - {{credential:fieldKey}} → from credential store\n * - {{oauth2:accessToken}} → from OAuth2 tokens\n */\nasync function executeHttpTool(\n template: SkillToolTemplate,\n args: Record<string, unknown>,\n skill: SkillEntry,\n credentialStore: CredentialStore | null,\n workspacePath: string,\n): Promise<ToolResult> {\n try {\n // Build credential values map\n const credValues = await resolveCredentials(skill, credentialStore);\n\n // Resolve URL\n const url = resolvePlaceholders(\n template.request.url,\n args,\n credValues,\n );\n\n // Resolve method\n const method = template.request.method\n ? resolvePlaceholders(template.request.method, args, credValues)\n : \"GET\";\n\n // Resolve headers\n const headers: Record<string, string> = {};\n if (template.request.headers) {\n for (const [key, value] of Object.entries(template.request.headers)) {\n headers[key] = resolvePlaceholders(value, args, credValues);\n }\n }\n if (!headers[\"Content-Type\"] && method !== \"GET\") {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n // Resolve body\n let body: string | undefined;\n if (template.request.body) {\n body = resolvePlaceholders(template.request.body, args, credValues);\n }\n\n logger.debug(\n `Skill HTTP: ${method} ${url.slice(0, 100)}`,\n \"skills\",\n );\n\n // Make the request\n const response = await fetch(url, {\n method,\n headers,\n body: method !== \"GET\" ? body : undefined,\n signal: AbortSignal.timeout(60_000),\n });\n\n const content = await response.text();\n\n if (!response.ok) {\n return {\n toolCallId: \"\",\n content: `HTTP ${response.status} ${response.statusText}: ${content.slice(0, 2000)}`,\n isError: true,\n };\n }\n\n // Save response to _temp/ and return metadata so the agent can\n // use data_file to query, artifact to display, or write_file to transform\n const tempDir = path.join(workspacePath, \"_temp\");\n await fs.mkdir(tempDir, { recursive: true });\n\n const isJson = looksLikeJson(content);\n const ext = isJson ? \"json\" : \"txt\";\n const filename = `${template.name}_${Date.now()}.${ext}`;\n const filePath = path.join(tempDir, filename);\n await fs.writeFile(filePath, content, \"utf-8\");\n\n const summary = buildResponseSummary(content, isJson);\n\n return {\n toolCallId: \"\",\n content: [\n `Data saved to: _temp/${filename}`,\n `Size: ${formatBytes(content.length)}`,\n summary,\n \"\",\n \"Use data_file to inspect or query this data, or artifact to display it.\",\n ].join(\"\\n\"),\n };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `HTTP tool error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n}\n\nfunction looksLikeJson(content: string): boolean {\n const trimmed = content.trimStart();\n return trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\");\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction buildResponseSummary(content: string, isJson: boolean): string {\n if (!isJson) {\n const lines = content.split(\"\\n\");\n return `Lines: ${lines.length}\\nPreview:\\n${lines.slice(0, 5).join(\"\\n\")}`;\n }\n\n try {\n const parsed = JSON.parse(content);\n\n // Array of objects — most common API response\n if (Array.isArray(parsed)) {\n const count = parsed.length;\n const sample = parsed[0];\n const columns = sample && typeof sample === \"object\"\n ? Object.keys(sample)\n : [];\n return [\n `Format: JSON array (${count} items)`,\n columns.length > 0 ? `Columns: ${columns.join(\", \")}` : \"\",\n count > 0 ? `Sample: ${JSON.stringify(parsed[0]).slice(0, 300)}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n }\n\n // Object with a data/results array inside\n if (typeof parsed === \"object\" && parsed !== null) {\n const keys = Object.keys(parsed);\n // Find the first array property (likely the data payload)\n const arrayKey = keys.find((k) => Array.isArray(parsed[k]));\n if (arrayKey) {\n const arr = parsed[arrayKey] as unknown[];\n const sample = arr[0];\n const columns = sample && typeof sample === \"object\" && sample !== null\n ? Object.keys(sample)\n : [];\n return [\n `Format: JSON object with ${keys.length} keys: ${keys.join(\", \")}`,\n `Data in \"${arrayKey}\": ${arr.length} items`,\n columns.length > 0 ? `Columns: ${columns.join(\", \")}` : \"\",\n arr.length > 0 ? `Sample: ${JSON.stringify(arr[0]).slice(0, 300)}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n }\n\n return `Format: JSON object with ${keys.length} keys: ${keys.join(\", \")}`;\n }\n\n return `Format: JSON (${typeof parsed})`;\n } catch {\n return \"Format: text (invalid JSON)\";\n }\n}\n\n/**\n * Resolve all credential values for a skill into a flat map.\n */\nasync function resolveCredentials(\n skill: SkillEntry,\n credentialStore: CredentialStore | null,\n): Promise<Map<string, string>> {\n const values = new Map<string, string>();\n\n if (!skill.credentialSchema || !credentialStore) return values;\n\n for (const cred of skill.credentialSchema.credentials) {\n if (cred.type === \"oauth2\") {\n const keys = getOAuth2StorageKeys(skill.manifest.name, cred.id);\n const accessToken = await credentialStore.get(keys.accessToken);\n if (accessToken) {\n values.set(\"oauth2:accessToken\", accessToken);\n }\n const refreshToken = await credentialStore.get(keys.refreshToken);\n if (refreshToken) {\n values.set(\"oauth2:refreshToken\", refreshToken);\n }\n } else if (cred.multiple && cred.fields) {\n // Multi-instance: resolve from first available instance\n const registryKey = getInstanceRegistryKey(skill.manifest.name, cred.id, cred.storeAs);\n const raw = await credentialStore.get(registryKey);\n const instances = raw ? JSON.parse(raw) as Array<{ id: string }> : [];\n if (instances.length > 0) {\n for (const field of cred.fields) {\n const key = getInstanceStorageKey(\n skill.manifest.name,\n cred.id,\n instances[0].id,\n field.key,\n cred.storeAs,\n );\n const value = await credentialStore.get(key);\n if (value) {\n values.set(`credential:${field.key}`, value);\n }\n }\n }\n } else if (cred.fields) {\n for (const field of cred.fields) {\n const key = getCredentialStorageKey(\n skill.manifest.name,\n cred.id,\n field.key,\n cred.storeAs,\n );\n const value = await credentialStore.get(key);\n if (value) {\n values.set(`credential:${field.key}`, value);\n }\n }\n }\n }\n\n return values;\n}\n\n/**\n * Replace {{placeholder}} patterns in a string.\n *\n * Priority:\n * 1. {{credential:fieldKey}} → from credential map\n * 2. {{oauth2:tokenField}} → from credential map\n * 3. {{argName}} → from tool call arguments\n */\nfunction resolvePlaceholders(\n template: string,\n args: Record<string, unknown>,\n credValues: Map<string, string>,\n): string {\n return template.replace(/\\{\\{([^}]+)\\}\\}/g, (match, key: string) => {\n // Credential placeholder\n if (key.startsWith(\"credential:\") || key.startsWith(\"oauth2:\")) {\n const value = credValues.get(key);\n if (value) return value;\n return match; // Leave unresolved\n }\n\n // Argument placeholder\n const argValue = args[key];\n if (argValue !== undefined) {\n return typeof argValue === \"string\"\n ? argValue\n : JSON.stringify(argValue);\n }\n\n return match;\n });\n}\n","import type { OAuth2Config } from \"./types.js\";\nimport type { EncryptedCredentialStore } from \"../credentials/store.js\";\nimport { getOAuth2StorageKeys, getCredentialStorageKey } from \"./credential-schema.js\";\n\n/**\n * Build the OAuth2 authorization URL for a skill.\n */\nexport function buildSkillOAuth2AuthUrl(\n skillName: string,\n oauth: OAuth2Config,\n clientId: string,\n redirectUri: string,\n state: string,\n): string {\n const params = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: \"code\",\n state,\n access_type: oauth.refreshable ? \"offline\" : \"online\",\n prompt: \"consent\",\n });\n\n if (oauth.scopes?.length) {\n params.set(\"scope\", oauth.scopes.join(\" \"));\n }\n\n return `${oauth.authorizationUrl}?${params.toString()}`;\n}\n\n/**\n * Exchange an OAuth2 authorization code for tokens and store them.\n */\nexport async function exchangeSkillOAuth2Code(\n skillName: string,\n credentialId: string,\n oauth: OAuth2Config,\n clientId: string,\n clientSecret: string,\n code: string,\n redirectUri: string,\n credentialStore: EncryptedCredentialStore,\n): Promise<void> {\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n redirect_uri: redirectUri,\n client_id: clientId,\n client_secret: clientSecret,\n });\n\n const res = await fetch(oauth.tokenUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Token exchange failed (${res.status}): ${text}`);\n }\n\n const data = (await res.json()) as {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n token_type?: string;\n };\n\n const keys = getOAuth2StorageKeys(skillName, credentialId);\n await credentialStore.set(keys.accessToken, data.access_token);\n\n if (data.refresh_token) {\n await credentialStore.set(keys.refreshToken, data.refresh_token);\n }\n\n if (data.expires_in) {\n const expiresAt = Date.now() + data.expires_in * 1000;\n await credentialStore.set(keys.expiresAt, String(expiresAt));\n }\n}\n\n/**\n * Revoke OAuth2 tokens for a skill by removing them from the credential store.\n */\nexport async function revokeSkillOAuth2(\n skillName: string,\n credentialId: string,\n credentialStore: EncryptedCredentialStore,\n): Promise<void> {\n const keys = getOAuth2StorageKeys(skillName, credentialId);\n await credentialStore.delete(keys.accessToken);\n await credentialStore.delete(keys.refreshToken);\n await credentialStore.delete(keys.expiresAt);\n}\n","import crypto from \"node:crypto\";\nimport Database from \"better-sqlite3\";\nimport { computeNextRunAtMs } from \"./schedule.js\";\nimport { logger } from \"../logging/logger.js\";\nimport type {\n CronJob,\n CronJobCreate,\n CronJobState,\n CronSchedule,\n CronEvent,\n} from \"./types.js\";\n\nconst MAX_TIMER_DELAY_MS = 60_000;\nconst MIN_REFIRE_GAP_MS = 2_000;\nconst ERROR_BACKOFF_MS = [30_000, 60_000, 300_000, 900_000, 3_600_000];\n\ntype EventHandler = (event: CronEvent) => void;\ntype JobExecutor = (job: CronJob) => Promise<string>;\n\nexport class CronService {\n private db: Database.Database;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private running = false;\n private executor: JobExecutor | null = null;\n private eventHandlers: EventHandler[] = [];\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS cron_jobs (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n enabled INTEGER NOT NULL DEFAULT 1,\n schedule TEXT NOT NULL,\n prompt TEXT NOT NULL,\n delivery TEXT NOT NULL DEFAULT '{}',\n workspace_id TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS cron_job_states (\n job_id TEXT PRIMARY KEY REFERENCES cron_jobs(id) ON DELETE CASCADE,\n next_run_at_ms INTEGER,\n last_run_at_ms INTEGER,\n last_status TEXT,\n last_error TEXT,\n consecutive_errors INTEGER NOT NULL DEFAULT 0\n );\n `);\n }\n\n setExecutor(executor: JobExecutor): void {\n this.executor = executor;\n }\n\n onEvent(handler: EventHandler): void {\n this.eventHandlers.push(handler);\n }\n\n private emit(event: CronEvent): void {\n for (const handler of this.eventHandlers) {\n try {\n handler(event);\n } catch {\n // Ignore handler errors\n }\n }\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n logger.info(\"Cron service started\", \"cron\");\n\n // Compute initial next-run for all enabled jobs missing a next_run_at_ms\n const jobs = this.list();\n for (const job of jobs) {\n if (!job.enabled) continue;\n const state = this.getState(job.id);\n if (!state || state.nextRunAtMs === null) {\n const nextMs = computeNextRunAtMs(job.schedule);\n this.upsertState(job.id, { nextRunAtMs: nextMs });\n }\n }\n\n this.scheduleNext();\n }\n\n stop(): void {\n this.running = false;\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n logger.info(\"Cron service stopped\", \"cron\");\n }\n\n private scheduleNext(): void {\n if (!this.running) return;\n\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n\n // Find the soonest job\n const row = this.db\n .prepare(\n `SELECT s.job_id, s.next_run_at_ms\n FROM cron_job_states s\n JOIN cron_jobs j ON j.id = s.job_id\n WHERE j.enabled = 1 AND s.next_run_at_ms IS NOT NULL\n ORDER BY s.next_run_at_ms ASC\n LIMIT 1`,\n )\n .get() as { job_id: string; next_run_at_ms: number } | undefined;\n\n if (!row) return;\n\n const delayMs = Math.max(0, row.next_run_at_ms - Date.now());\n const clampedDelay = Math.min(delayMs, MAX_TIMER_DELAY_MS);\n\n this.timer = setTimeout(() => {\n this.tick();\n }, clampedDelay);\n }\n\n private async tick(): Promise<void> {\n if (!this.running) return;\n\n const now = Date.now();\n\n // Get all jobs due to run\n const dueRows = this.db\n .prepare(\n `SELECT s.job_id\n FROM cron_job_states s\n JOIN cron_jobs j ON j.id = s.job_id\n WHERE j.enabled = 1\n AND s.next_run_at_ms IS NOT NULL\n AND s.next_run_at_ms <= ?`,\n )\n .all(now) as Array<{ job_id: string }>;\n\n for (const { job_id } of dueRows) {\n await this.executeJob(job_id);\n }\n\n this.scheduleNext();\n }\n\n private async executeJob(jobId: string): Promise<void> {\n const job = this.getJob(jobId);\n if (!job || !this.executor) return;\n\n const state = this.getState(jobId);\n if (state?.lastRunAtMs && Date.now() - state.lastRunAtMs < MIN_REFIRE_GAP_MS) {\n return;\n }\n\n this.emit({\n type: \"started\",\n jobId: job.id,\n jobName: job.name,\n });\n\n try {\n const result = await this.executor(job);\n\n this.upsertState(jobId, {\n lastRunAtMs: Date.now(),\n lastStatus: \"success\",\n lastError: null,\n consecutiveErrors: 0,\n nextRunAtMs: computeNextRunAtMs(job.schedule),\n });\n\n this.emit({\n type: \"finished\",\n jobId: job.id,\n jobName: job.name,\n result,\n });\n\n logger.info(`Cron job \"${job.name}\" completed`, \"cron\");\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n const currentErrors = (state?.consecutiveErrors ?? 0) + 1;\n const backoffIdx = Math.min(currentErrors - 1, ERROR_BACKOFF_MS.length - 1);\n const backoffMs = ERROR_BACKOFF_MS[backoffIdx];\n\n this.upsertState(jobId, {\n lastRunAtMs: Date.now(),\n lastStatus: \"error\",\n lastError: errorMsg,\n consecutiveErrors: currentErrors,\n nextRunAtMs: Date.now() + backoffMs,\n });\n\n this.emit({\n type: \"error\",\n jobId: job.id,\n jobName: job.name,\n error: errorMsg,\n });\n\n logger.error(\n `Cron job \"${job.name}\" failed (${currentErrors} errors): ${errorMsg}`,\n \"cron\",\n );\n }\n }\n\n // CRUD\n\n add(input: CronJobCreate): CronJob {\n const id = crypto.randomUUID();\n const now = new Date().toISOString();\n\n const job: CronJob = {\n id,\n name: input.name,\n enabled: input.enabled ?? true,\n schedule: input.schedule,\n prompt: input.prompt,\n delivery: input.delivery ?? {},\n workspaceId: input.workspaceId,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db\n .prepare(\n `INSERT INTO cron_jobs (id, name, enabled, schedule, prompt, delivery, workspace_id, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n job.id,\n job.name,\n job.enabled ? 1 : 0,\n JSON.stringify(job.schedule),\n job.prompt,\n JSON.stringify(job.delivery),\n job.workspaceId ?? null,\n job.createdAt,\n job.updatedAt,\n );\n\n // Set initial state\n const nextMs = job.enabled ? computeNextRunAtMs(job.schedule) : null;\n this.upsertState(id, { nextRunAtMs: nextMs });\n\n this.emit({ type: \"added\", jobId: id, jobName: job.name });\n\n if (this.running) this.scheduleNext();\n\n return job;\n }\n\n update(\n id: string,\n updates: Partial<Pick<CronJob, \"name\" | \"enabled\" | \"schedule\" | \"prompt\" | \"delivery\">>,\n ): CronJob | null {\n const existing = this.getJob(id);\n if (!existing) return null;\n\n const sets: string[] = [\"updated_at = ?\"];\n const values: unknown[] = [new Date().toISOString()];\n\n if (updates.name !== undefined) {\n sets.push(\"name = ?\");\n values.push(updates.name);\n }\n if (updates.enabled !== undefined) {\n sets.push(\"enabled = ?\");\n values.push(updates.enabled ? 1 : 0);\n }\n if (updates.schedule !== undefined) {\n sets.push(\"schedule = ?\");\n values.push(JSON.stringify(updates.schedule));\n }\n if (updates.prompt !== undefined) {\n sets.push(\"prompt = ?\");\n values.push(updates.prompt);\n }\n if (updates.delivery !== undefined) {\n sets.push(\"delivery = ?\");\n values.push(JSON.stringify(updates.delivery));\n }\n\n values.push(id);\n this.db\n .prepare(`UPDATE cron_jobs SET ${sets.join(\", \")} WHERE id = ?`)\n .run(...values);\n\n // Recompute next run if schedule or enabled changed\n if (updates.schedule !== undefined || updates.enabled !== undefined) {\n const updated = this.getJob(id)!;\n const nextMs = updated.enabled ? computeNextRunAtMs(updated.schedule) : null;\n this.upsertState(id, { nextRunAtMs: nextMs, consecutiveErrors: 0 });\n }\n\n if (this.running) this.scheduleNext();\n\n return this.getJob(id);\n }\n\n remove(id: string): boolean {\n const job = this.getJob(id);\n if (!job) return false;\n\n this.db.prepare(\"DELETE FROM cron_jobs WHERE id = ?\").run(id);\n this.emit({ type: \"removed\", jobId: id, jobName: job.name });\n\n if (this.running) this.scheduleNext();\n return true;\n }\n\n getJob(id: string): CronJob | null {\n const row = this.db\n .prepare(\"SELECT * FROM cron_jobs WHERE id = ?\")\n .get(id) as CronJobRow | undefined;\n\n return row ? rowToJob(row) : null;\n }\n\n list(workspaceId?: string): CronJob[] {\n let rows: CronJobRow[];\n if (workspaceId) {\n rows = this.db\n .prepare(\n \"SELECT * FROM cron_jobs WHERE workspace_id = ? ORDER BY created_at DESC\",\n )\n .all(workspaceId) as CronJobRow[];\n } else {\n rows = this.db\n .prepare(\"SELECT * FROM cron_jobs ORDER BY created_at DESC\")\n .all() as CronJobRow[];\n }\n return rows.map(rowToJob);\n }\n\n getState(jobId: string): CronJobState | null {\n const row = this.db\n .prepare(\"SELECT * FROM cron_job_states WHERE job_id = ?\")\n .get(jobId) as {\n job_id: string;\n next_run_at_ms: number | null;\n last_run_at_ms: number | null;\n last_status: string | null;\n last_error: string | null;\n consecutive_errors: number;\n } | undefined;\n\n if (!row) return null;\n\n return {\n jobId: row.job_id,\n nextRunAtMs: row.next_run_at_ms,\n lastRunAtMs: row.last_run_at_ms,\n lastStatus: row.last_status as \"success\" | \"error\" | null,\n lastError: row.last_error,\n consecutiveErrors: row.consecutive_errors,\n };\n }\n\n async runNow(id: string): Promise<void> {\n await this.executeJob(id);\n if (this.running) this.scheduleNext();\n }\n\n private upsertState(\n jobId: string,\n partial: Partial<Omit<CronJobState, \"jobId\">>,\n ): void {\n const existing = this.getState(jobId);\n\n if (existing) {\n const sets: string[] = [];\n const values: unknown[] = [];\n\n if (partial.nextRunAtMs !== undefined) {\n sets.push(\"next_run_at_ms = ?\");\n values.push(partial.nextRunAtMs);\n }\n if (partial.lastRunAtMs !== undefined) {\n sets.push(\"last_run_at_ms = ?\");\n values.push(partial.lastRunAtMs);\n }\n if (partial.lastStatus !== undefined) {\n sets.push(\"last_status = ?\");\n values.push(partial.lastStatus);\n }\n if (partial.lastError !== undefined) {\n sets.push(\"last_error = ?\");\n values.push(partial.lastError);\n }\n if (partial.consecutiveErrors !== undefined) {\n sets.push(\"consecutive_errors = ?\");\n values.push(partial.consecutiveErrors);\n }\n\n if (sets.length > 0) {\n values.push(jobId);\n this.db\n .prepare(\n `UPDATE cron_job_states SET ${sets.join(\", \")} WHERE job_id = ?`,\n )\n .run(...values);\n }\n } else {\n this.db\n .prepare(\n `INSERT INTO cron_job_states (job_id, next_run_at_ms, last_run_at_ms, last_status, last_error, consecutive_errors)\n VALUES (?, ?, ?, ?, ?, ?)`,\n )\n .run(\n jobId,\n partial.nextRunAtMs ?? null,\n partial.lastRunAtMs ?? null,\n partial.lastStatus ?? null,\n partial.lastError ?? null,\n partial.consecutiveErrors ?? 0,\n );\n }\n }\n\n close(): void {\n this.stop();\n this.db.close();\n }\n}\n\n// Internal helpers\n\ninterface CronJobRow {\n id: string;\n name: string;\n enabled: number;\n schedule: string;\n prompt: string;\n delivery: string;\n workspace_id: string | null;\n created_at: string;\n updated_at: string;\n}\n\nfunction rowToJob(row: CronJobRow): CronJob {\n return {\n id: row.id,\n name: row.name,\n enabled: row.enabled === 1,\n schedule: JSON.parse(row.schedule) as CronSchedule,\n prompt: row.prompt,\n delivery: JSON.parse(row.delivery),\n workspaceId: row.workspace_id ?? undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n","import crypto from \"node:crypto\";\n\nexport interface Artifact {\n id: string;\n type: \"html\" | \"csv\" | \"image\" | \"json\" | \"text\" | \"svg\";\n title: string;\n content: string;\n mimeType: string;\n createdAt: number;\n}\n\nconst TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\n\nexport class ArtifactStore {\n private store = new Map<string, Artifact>();\n\n create(\n type: Artifact[\"type\"],\n title: string,\n content: string,\n ): Artifact {\n this.pruneExpired();\n\n const id = crypto.randomUUID();\n const mimeType = getMimeType(type);\n const artifact: Artifact = {\n id,\n type,\n title,\n content,\n mimeType,\n createdAt: Date.now(),\n };\n this.store.set(id, artifact);\n return artifact;\n }\n\n get(id: string): Artifact | undefined {\n const artifact = this.store.get(id);\n if (artifact && Date.now() - artifact.createdAt > TTL_MS) {\n this.store.delete(id);\n return undefined;\n }\n return artifact;\n }\n\n list(): Artifact[] {\n this.pruneExpired();\n return Array.from(this.store.values()).sort(\n (a, b) => b.createdAt - a.createdAt,\n );\n }\n\n delete(id: string): boolean {\n return this.store.delete(id);\n }\n\n private pruneExpired(): void {\n const now = Date.now();\n for (const [id, artifact] of this.store) {\n if (now - artifact.createdAt > TTL_MS) {\n this.store.delete(id);\n }\n }\n }\n}\n\nfunction getMimeType(type: Artifact[\"type\"]): string {\n switch (type) {\n case \"html\":\n return \"text/html\";\n case \"csv\":\n return \"text/csv\";\n case \"image\":\n return \"image/png\";\n case \"json\":\n return \"application/json\";\n case \"svg\":\n return \"image/svg+xml\";\n case \"text\":\n default:\n return \"text/plain\";\n }\n}\n","import Database from \"better-sqlite3\";\nimport type { ModelStore } from \"../models/store.js\";\nimport { MODEL_DEFINITIONS } from \"../models/definitions.js\";\n\nexport interface UsageRecord {\n id: number;\n provider: string;\n model: string;\n inputTokens: number;\n outputTokens: number;\n costUsd: number;\n createdAt: string;\n}\n\nexport interface UsageSummary {\n totalInputTokens: number;\n totalOutputTokens: number;\n totalTokens: number;\n totalCostUsd: number;\n recordCount: number;\n}\n\nexport function estimateCost(\n inputTokens: number,\n outputTokens: number,\n pricing: { input: number; output: number },\n): number {\n const inputCost = (inputTokens / 1_000_000) * pricing.input;\n const outputCost = (outputTokens / 1_000_000) * pricing.output;\n return Math.round((inputCost + outputCost) * 1_000_000) / 1_000_000;\n}\n\nexport class UsageStore {\n private db: Database.Database;\n private modelStore: ModelStore;\n\n constructor(dbPath: string, modelStore: ModelStore) {\n this.db = new Database(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.modelStore = modelStore;\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS usage_records (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n provider TEXT NOT NULL,\n model TEXT NOT NULL,\n input_tokens INTEGER NOT NULL DEFAULT 0,\n output_tokens INTEGER NOT NULL DEFAULT 0,\n cost_usd REAL NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `);\n }\n\n record(\n provider: string,\n model: string,\n inputTokens: number,\n outputTokens: number,\n ): void {\n let pricing = this.modelStore.getPricing(provider, model);\n if (!pricing) {\n // Fall back to hardcoded model definitions when model isn't in enabled_models\n const def = MODEL_DEFINITIONS[provider]?.find((m) => m.id === model);\n if (def?.inputPricePer1m != null && def?.outputPricePer1m != null) {\n pricing = { input: def.inputPricePer1m, output: def.outputPricePer1m };\n }\n }\n const costUsd = pricing\n ? estimateCost(inputTokens, outputTokens, pricing)\n : 0;\n this.db\n .prepare(\n `INSERT INTO usage_records (provider, model, input_tokens, output_tokens, cost_usd)\n VALUES (?, ?, ?, ?, ?)`,\n )\n .run(provider, model, inputTokens, outputTokens, costUsd);\n }\n\n getSummary(period: \"daily\" | \"weekly\" | \"monthly\"): UsageSummary {\n const since = this.periodStart(period);\n const row = this.db\n .prepare(\n `SELECT\n COALESCE(SUM(input_tokens), 0) as totalInputTokens,\n COALESCE(SUM(output_tokens), 0) as totalOutputTokens,\n COALESCE(SUM(input_tokens + output_tokens), 0) as totalTokens,\n COALESCE(SUM(cost_usd), 0) as totalCostUsd,\n COUNT(*) as recordCount\n FROM usage_records\n WHERE created_at >= ?`,\n )\n .get(since) as UsageSummary;\n return row;\n }\n\n getHistory(days: number = 30): Array<{ date: string; tokens: number; costUsd: number }> {\n const since = new Date();\n since.setDate(since.getDate() - days);\n const rows = this.db\n .prepare(\n `SELECT\n date(created_at) as date,\n SUM(input_tokens + output_tokens) as tokens,\n SUM(cost_usd) as costUsd\n FROM usage_records\n WHERE created_at >= ?\n GROUP BY date(created_at)\n ORDER BY date(created_at)`,\n )\n .all(since.toISOString()) as Array<{ date: string; tokens: number; costUsd: number }>;\n return rows;\n }\n\n private periodStart(period: \"daily\" | \"weekly\" | \"monthly\"): string {\n const now = new Date();\n switch (period) {\n case \"daily\":\n now.setHours(0, 0, 0, 0);\n break;\n case \"weekly\": {\n const day = now.getDay();\n now.setDate(now.getDate() - day);\n now.setHours(0, 0, 0, 0);\n break;\n }\n case \"monthly\":\n now.setDate(1);\n now.setHours(0, 0, 0, 0);\n break;\n }\n return now.toISOString();\n }\n}\n","import Database from \"better-sqlite3\";\n\nexport interface EnabledModel {\n id: string;\n provider: string;\n modelId: string;\n label: string;\n inputPricePer1m: number;\n outputPricePer1m: number;\n enabledAt: string;\n}\n\nexport class ModelStore {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS enabled_models (\n id TEXT PRIMARY KEY,\n provider TEXT NOT NULL,\n model_id TEXT NOT NULL,\n label TEXT NOT NULL,\n input_price_per_1m REAL NOT NULL DEFAULT 0,\n output_price_per_1m REAL NOT NULL DEFAULT 0,\n enabled_at TEXT NOT NULL DEFAULT (datetime('now')),\n UNIQUE(provider, model_id)\n )\n `);\n }\n\n list(provider?: string): EnabledModel[] {\n const query = provider\n ? \"SELECT * FROM enabled_models WHERE provider = ? ORDER BY label\"\n : \"SELECT * FROM enabled_models ORDER BY provider, label\";\n const rows = (provider\n ? this.db.prepare(query).all(provider)\n : this.db.prepare(query).all()) as Array<{\n id: string;\n provider: string;\n model_id: string;\n label: string;\n input_price_per_1m: number;\n output_price_per_1m: number;\n enabled_at: string;\n }>;\n return rows.map((r) => ({\n id: r.id,\n provider: r.provider,\n modelId: r.model_id,\n label: r.label,\n inputPricePer1m: r.input_price_per_1m,\n outputPricePer1m: r.output_price_per_1m,\n enabledAt: r.enabled_at,\n }));\n }\n\n enable(\n provider: string,\n modelId: string,\n label: string,\n inputPricePer1m: number,\n outputPricePer1m: number,\n ): EnabledModel {\n const id = crypto.randomUUID();\n const now = new Date().toISOString();\n this.db\n .prepare(\n `INSERT OR REPLACE INTO enabled_models (id, provider, model_id, label, input_price_per_1m, output_price_per_1m, enabled_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(id, provider, modelId, label, inputPricePer1m, outputPricePer1m, now);\n return { id, provider, modelId, label, inputPricePer1m, outputPricePer1m, enabledAt: now };\n }\n\n disable(provider: string, modelId: string): void {\n this.db\n .prepare(\"DELETE FROM enabled_models WHERE provider = ? AND model_id = ?\")\n .run(provider, modelId);\n }\n\n updatePricing(\n provider: string,\n modelId: string,\n inputPricePer1m: number,\n outputPricePer1m: number,\n ): void {\n this.db\n .prepare(\n \"UPDATE enabled_models SET input_price_per_1m = ?, output_price_per_1m = ? WHERE provider = ? AND model_id = ?\",\n )\n .run(inputPricePer1m, outputPricePer1m, provider, modelId);\n }\n\n getPricing(provider: string, modelId: string): { input: number; output: number } | null {\n const row = this.db\n .prepare(\"SELECT input_price_per_1m, output_price_per_1m FROM enabled_models WHERE provider = ? AND model_id = ?\")\n .get(provider, modelId) as { input_price_per_1m: number; output_price_per_1m: number } | undefined;\n if (!row) return null;\n return { input: row.input_price_per_1m, output: row.output_price_per_1m };\n }\n}\n","import Database from \"better-sqlite3\";\n\nexport interface PromptTemplate {\n id: string;\n name: string;\n content: string;\n category: string;\n createdAt: string;\n updatedAt: string;\n}\n\nconst DEFAULT_TEMPLATES: Array<{ name: string; content: string; category: string }> = [\n { name: \"Summarize\", content: \"Summarize the following:\\n\\n\", category: \"General\" },\n { name: \"Explain code\", content: \"Explain this code in detail:\\n\\n\", category: \"Development\" },\n { name: \"Write email\", content: \"Write a professional email about:\\n\\n\", category: \"Writing\" },\n { name: \"Fix bug\", content: \"Help me fix this bug:\\n\\n\", category: \"Development\" },\n { name: \"Brainstorm\", content: \"Brainstorm ideas for:\\n\\n\", category: \"General\" },\n];\n\nexport class TemplateStore {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS prompt_templates (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n content TEXT NOT NULL,\n category TEXT NOT NULL DEFAULT 'General',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `);\n\n // Seed defaults if table is empty\n const count = this.db\n .prepare(\"SELECT COUNT(*) as cnt FROM prompt_templates\")\n .get() as { cnt: number };\n\n if (count.cnt === 0) {\n const insert = this.db.prepare(\n \"INSERT INTO prompt_templates (id, name, content, category, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)\",\n );\n const now = new Date().toISOString();\n for (const t of DEFAULT_TEMPLATES) {\n insert.run(crypto.randomUUID(), t.name, t.content, t.category, now, now);\n }\n }\n }\n\n list(): PromptTemplate[] {\n const rows = this.db\n .prepare(\n \"SELECT id, name, content, category, created_at, updated_at FROM prompt_templates ORDER BY category, name\",\n )\n .all() as Array<{\n id: string;\n name: string;\n content: string;\n category: string;\n created_at: string;\n updated_at: string;\n }>;\n\n return rows.map((r) => ({\n id: r.id,\n name: r.name,\n content: r.content,\n category: r.category,\n createdAt: r.created_at,\n updatedAt: r.updated_at,\n }));\n }\n\n get(id: string): PromptTemplate | null {\n const row = this.db\n .prepare(\n \"SELECT id, name, content, category, created_at, updated_at FROM prompt_templates WHERE id = ?\",\n )\n .get(id) as {\n id: string;\n name: string;\n content: string;\n category: string;\n created_at: string;\n updated_at: string;\n } | undefined;\n\n if (!row) return null;\n\n return {\n id: row.id,\n name: row.name,\n content: row.content,\n category: row.category,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n create(name: string, content: string, category?: string): PromptTemplate {\n const id = crypto.randomUUID();\n const now = new Date().toISOString();\n this.db\n .prepare(\n \"INSERT INTO prompt_templates (id, name, content, category, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)\",\n )\n .run(id, name, content, category ?? \"General\", now, now);\n\n return { id, name, content, category: category ?? \"General\", createdAt: now, updatedAt: now };\n }\n\n update(id: string, data: Partial<Pick<PromptTemplate, \"name\" | \"content\" | \"category\">>): PromptTemplate | null {\n const existing = this.get(id);\n if (!existing) return null;\n\n const now = new Date().toISOString();\n const name = data.name ?? existing.name;\n const content = data.content ?? existing.content;\n const category = data.category ?? existing.category;\n\n this.db\n .prepare(\n \"UPDATE prompt_templates SET name = ?, content = ?, category = ?, updated_at = ? WHERE id = ?\",\n )\n .run(name, content, category, now, id);\n\n return { id, name, content, category, createdAt: existing.createdAt, updatedAt: now };\n }\n\n delete(id: string): void {\n this.db.prepare(\"DELETE FROM prompt_templates WHERE id = ?\").run(id);\n }\n}\n"],"mappings":";AAAA,OAAO,YAAY;;;ACQZ,IAAM,oBAAiD;AAAA,EAC5D,WAAW;AAAA,IACT,EAAE,IAAI,mBAAmB,MAAM,mBAAmB,eAAe,KAAQ,iBAAiB,IAAI,kBAAkB,GAAG;AAAA,IACnH,EAAE,IAAI,8BAA8B,MAAM,qBAAqB,eAAe,KAAQ,iBAAiB,GAAG,kBAAkB,GAAG;AAAA,IAC/H,EAAE,IAAI,6BAA6B,MAAM,oBAAoB,eAAe,KAAQ,iBAAiB,KAAK,kBAAkB,EAAE;AAAA,IAC9H,EAAE,IAAI,4BAA4B,MAAM,mBAAmB,eAAe,KAAQ,iBAAiB,GAAG,kBAAkB,GAAG;AAAA,EAC7H;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,IAAI,WAAW,MAAM,WAAW,eAAe,SAAS,iBAAiB,GAAG,kBAAkB,EAAE;AAAA,IAClG,EAAE,IAAI,gBAAgB,MAAM,gBAAgB,eAAe,SAAS,iBAAiB,KAAK,kBAAkB,IAAI;AAAA,IAChH,EAAE,IAAI,gBAAgB,MAAM,gBAAgB,eAAe,SAAS,iBAAiB,KAAK,kBAAkB,IAAI;AAAA,IAChH,EAAE,IAAI,UAAU,MAAM,UAAU,eAAe,OAAQ,iBAAiB,KAAK,kBAAkB,GAAG;AAAA,IAClG,EAAE,IAAI,eAAe,MAAM,eAAe,eAAe,OAAQ,iBAAiB,MAAM,kBAAkB,IAAI;AAAA,IAC9G,EAAE,IAAI,MAAM,MAAM,MAAM,eAAe,KAAQ,iBAAiB,IAAI,kBAAkB,GAAG;AAAA,IACzF,EAAE,IAAI,WAAW,MAAM,WAAW,eAAe,KAAQ,iBAAiB,KAAK,kBAAkB,IAAI;AAAA,IACrG,EAAE,IAAI,WAAW,MAAM,WAAW,eAAe,KAAQ,iBAAiB,KAAK,kBAAkB,IAAI;AAAA,EACvG;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,IAAI,gCAAgC,MAAM,kBAAkB,eAAe,SAAS,iBAAiB,MAAM,kBAAkB,GAAG;AAAA,IAClI,EAAE,IAAI,kCAAkC,MAAM,oBAAoB,eAAe,SAAS,iBAAiB,MAAM,kBAAkB,IAAI;AAAA,IACvI,EAAE,IAAI,oBAAoB,MAAM,oBAAoB,eAAe,SAAS,iBAAiB,KAAK,kBAAkB,IAAI;AAAA,IACxH,EAAE,IAAI,yBAAyB,MAAM,yBAAyB,eAAe,SAAS,iBAAiB,OAAO,kBAAkB,IAAI;AAAA,EACtI;AAAA,EACA,MAAM;AAAA,IACJ,EAAE,IAAI,UAAU,MAAM,UAAU,eAAe,QAAQ,iBAAiB,GAAG,kBAAkB,GAAG;AAAA,IAChG,EAAE,IAAI,eAAe,MAAM,eAAe,eAAe,QAAQ,iBAAiB,GAAG,kBAAkB,GAAG;AAAA,IAC1G,EAAE,IAAI,eAAe,MAAM,eAAe,eAAe,QAAQ,iBAAiB,KAAK,kBAAkB,IAAI;AAAA,IAC7G,EAAE,IAAI,oBAAoB,MAAM,oBAAoB,eAAe,QAAQ,iBAAiB,KAAK,kBAAkB,EAAE;AAAA,EACvH;AAAA,EACA,UAAU;AAAA,IACR,EAAE,IAAI,kBAAkB,MAAM,kBAAkB,eAAe,KAAM,iBAAiB,KAAK,kBAAkB,EAAE;AAAA,IAC/G,EAAE,IAAI,mBAAmB,MAAM,mBAAmB,eAAe,MAAO,iBAAiB,GAAG,kBAAkB,EAAE;AAAA,IAChH,EAAE,IAAI,oBAAoB,MAAM,oBAAoB,eAAe,OAAQ,iBAAiB,GAAG,kBAAkB,GAAG;AAAA,IACpH,EAAE,IAAI,eAAe,MAAM,eAAe,eAAe,QAAQ,iBAAiB,GAAG,kBAAkB,EAAE;AAAA,EAC3G;AAAA,EACA,SAAS;AAAA,IACP,EAAE,IAAI,mBAAmB,MAAM,mBAAmB,eAAe,KAAS,iBAAiB,GAAG,kBAAkB,EAAE;AAAA,IAClH,EAAE,IAAI,iBAAiB,MAAM,kBAAkB,eAAe,QAAQ,iBAAiB,KAAK,kBAAkB,EAAE;AAAA,EAClH;AACF;AAEO,SAAS,oBAAoB,YAAiC;AACnE,SAAO,kBAAkB,UAAU,KAAK,CAAC;AAC3C;;;ADpCO,SAAS,iBACd,UACA,cACqC;AACrC,QAAM,SAA8C,CAAC;AAErD,MAAI,cAAc;AAChB,WAAO,KAAK,EAAE,MAAM,UAAU,SAAS,aAAa,CAAC;AAAA,EACvD;AAEA,aAAW,OAAO,UAAU;AAC1B,QAAI,IAAI,SAAS,SAAU;AAE3B,QAAI,OAAO,IAAI,YAAY,UAAU;AACnC,aAAO,KAAK;AAAA,QACV,MAAM,IAAI;AAAA,QACV,SAAS,IAAI;AAAA,MACf,CAAsC;AACtC;AAAA,IACF;AAGA,UAAM,kBAAkB,IAAI,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,UAAU;AACvE,UAAM,eAAe,gBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,UAAU;AACxE,QAAI,IAAI,SAAS,eAAe,aAAa,SAAS,GAAG;AACvD,YAAM,cAAc,gBACjB,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EACvB,KAAK,EAAE;AACV,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,SAAS,eAAe;AAAA,QACxB,YAAY,aAAa,IAAI,CAAC,OAAO;AAAA,UACnC,IAAI,EAAE;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,YACR,MAAM,EAAE;AAAA,YACR,WAAW,KAAK,UAAU,EAAE,iBAAiB,CAAC,CAAC;AAAA,UACjD;AAAA,QACF,EAAE;AAAA,MACJ,CAAC;AACD;AAAA,IACF;AAEA,UAAM,kBAAkB,gBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,aAAa;AAC9E,QAAI,gBAAgB,SAAS,GAAG;AAC9B,iBAAW,KAAK,iBAAiB;AAC/B,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,cAAc,EAAE;AAAA,UAChB,SAAS,EAAE,QAAQ;AAAA,QACrB,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAEA,UAAM,QAA4C,gBAAgB;AAAA,MAChE,CAAC,SAAS;AACR,YAAI,KAAK,SAAS,WAAW,KAAK,aAAa;AAC7C,iBAAO;AAAA,YACL,MAAM;AAAA,YACN,WAAW;AAAA,cACT,KAAK,QAAQ,KAAK,YAAY,WAAW,WAAW,KAAK,WAAW;AAAA,YACtE;AAAA,UACF;AAAA,QACF;AACA,eAAO,EAAE,MAAM,QAAiB,MAAM,KAAK,QAAQ,GAAG;AAAA,MACxD;AAAA,IACF;AACA,WAAO,KAAK;AAAA,MACV,MAAM,IAAI;AAAA,MACV,SAAS;AAAA,IACX,CAAsC;AAAA,EACxC;AAEA,SAAO;AACT;AAEO,SAAS,cACd,OAC6B;AAC7B,SAAO,MAAM,IAAI,CAAC,OAAO;AAAA,IACvB,MAAM;AAAA,IACN,UAAU;AAAA,MACR,MAAM,EAAE;AAAA,MACR,aAAa,EAAE;AAAA,MACf,YAAY,EAAE;AAAA,IAChB;AAAA,EACF,EAAE;AACJ;AAEO,IAAM,2BAAN,MAAsD;AAAA,EAClD;AAAA,EACC;AAAA,EAEV,YAAY,IAAY,QAAgB,SAAkB;AACxD,SAAK,KAAK;AACV,SAAK,SAAS,IAAI,OAAO,EAAE,QAAQ,QAAQ,CAAC;AAAA,EAC9C;AAAA,EAEA,MAAM,aAAa,QAAyD;AAC1E,UAAM,WAAW,MAAM,KAAK,OAAO,KAAK,YAAY,OAAO;AAAA,MACzD,OAAO,OAAO;AAAA,MACd,UAAU,iBAAiB,OAAO,UAAU,OAAO,YAAY;AAAA,MAC/D,OAAO,OAAO,OAAO,SAAS,cAAc,OAAO,KAAK,IAAI;AAAA,MAC5D,aAAa,OAAO;AAAA,MACpB,YAAY,OAAO;AAAA,IACrB,CAAC;AAED,UAAM,SAAS,SAAS,QAAQ,CAAC;AACjC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,oBAAoB,KAAK,EAAE,EAAE;AAAA,IAC/C;AAEA,UAAM,UAAU,OAAO,QAAQ,WAAW;AAC1C,UAAM,aAAyB,OAAO,QAAQ,cAAc,CAAC,GAAG;AAAA,MAC9D,CAAC,QAAQ;AAAA,QACP,IAAI,GAAG;AAAA,QACP,MAAM,GAAG,SAAS;AAAA,QAClB,WAAW,KAAK,MAAM,GAAG,SAAS,SAAS;AAAA,MAC7C;AAAA,IACF;AAEA,UAAM,aACJ,OAAO,kBAAkB,eACrB,aACA,OAAO,kBAAkB,WACvB,eACA;AAER,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,OAAO;AAAA,QACL,aAAa,SAAS,OAAO,iBAAiB;AAAA,QAC9C,cAAc,SAAS,OAAO,qBAAqB;AAAA,MACrD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,eACL,QAC4B;AAC5B,UAAM,SAAS,MAAM,KAAK,OAAO,KAAK,YAAY,OAAO;AAAA,MACvD,OAAO,OAAO;AAAA,MACd,UAAU,iBAAiB,OAAO,UAAU,OAAO,YAAY;AAAA,MAC/D,OAAO,OAAO,OAAO,SAAS,cAAc,OAAO,KAAK,IAAI;AAAA,MAC5D,aAAa,OAAO;AAAA,MACpB,YAAY,OAAO;AAAA,MACnB,QAAQ;AAAA,MACR,gBAAgB,EAAE,eAAe,KAAK;AAAA,IACxC,CAAC;AAED,QAAI,cAAc;AAClB,QAAI,eAAe;AAEnB,qBAAiB,SAAS,QAAQ;AAChC,YAAM,QAAQ,MAAM,QAAQ,CAAC,GAAG;AAChC,UAAI,CAAC,OAAO;AAEV,YAAI,MAAM,OAAO;AACf,wBAAc,MAAM,MAAM,iBAAiB;AAC3C,yBAAe,MAAM,MAAM,qBAAqB;AAAA,QAClD;AACA;AAAA,MACF;AAEA,UAAI,MAAM,SAAS;AACjB,cAAM,EAAE,MAAM,QAAQ,MAAM,MAAM,QAAQ;AAAA,MAC5C;AAEA,UAAI,MAAM,YAAY;AACpB,mBAAW,MAAM,MAAM,YAAY;AACjC,cAAI,GAAG,IAAI;AACT,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN,UAAU,EAAE,IAAI,GAAG,IAAI,MAAM,GAAG,UAAU,KAAK;AAAA,YACjD;AAAA,UACF;AACA,cAAI,GAAG,UAAU,WAAW;AAC1B,kBAAM,EAAE,MAAM,mBAAmB,MAAM,GAAG,SAAS,UAAU;AAAA,UAC/D;AAAA,QACF;AAAA,MACF;AAEA,UAAI,MAAM,OAAO;AACf,sBAAc,MAAM,MAAM,iBAAiB;AAC3C,uBAAe,MAAM,MAAM,qBAAqB;AAAA,MAClD;AAAA,IACF;AAEA,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,aAAa;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,QAA2C;AACrD,UAAM,WAAW,MAAM,KAAK,OAAO,WAAW,OAAO;AAAA,MACnD,OAAO,OAAO;AAAA,MACd,OAAO,OAAO;AAAA,IAChB,CAAC;AAED,WAAO;AAAA,MACL,YAAY,SAAS,KAAK,IAAI,CAAC,MAAM,EAAE,SAAS;AAAA,MAChD,OAAO,EAAE,aAAa,SAAS,MAAM,aAAa;AAAA,IACpD;AAAA,EACF;AAAA,EAEA,MAAM,aAAmC;AACvC,WAAO,oBAAoB,KAAK,EAAE;AAAA,EACpC;AACF;;;AEpOA,OAAO,eAAe;AAetB,SAAS,oBACP,UAC0B;AAC1B,SAAO,SACJ,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,EACjC,IAAI,CAAC,MAAM;AACV,QAAI,OAAO,EAAE,YAAY,UAAU;AACjC,aAAO;AAAA,QACL,MAAM,EAAE;AAAA,QACR,SAAS,EAAE;AAAA,MACb;AAAA,IACF;AAEA,UAAM,UAAyC,EAAE,QAC9C,OAAO,CAAC,SAAS,KAAK,SAAS,UAAU,EACzC,IAAI,CAAC,SAAS;AACb,UAAI,KAAK,SAAS,YAAY;AAC5B,eAAO;AAAA,UACL,MAAM;AAAA,UACN,IAAI,KAAK;AAAA,UACT,MAAM,KAAK;AAAA,UACX,OAAO,KAAK,iBAAiB,CAAC;AAAA,QAChC;AAAA,MACF;AACA,UAAI,KAAK,SAAS,eAAe;AAC/B,eAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa,KAAK;AAAA,UAClB,SAAS,KAAK,QAAQ;AAAA,UACtB,UAAU,KAAK,WAAW;AAAA,QAC5B;AAAA,MACF;AACA,UAAI,KAAK,SAAS,WAAW,KAAK,aAAa;AAC7C,eAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,YAAa,KAAK,YAAY;AAAA,YAK9B,MAAM,KAAK;AAAA,UACb;AAAA,QACF;AAAA,MACF;AACA,aAAO,EAAE,MAAM,QAAiB,MAAM,KAAK,QAAQ,GAAG;AAAA,IACxD,CAAC;AAEH,WAAO;AAAA,MACL,MAAM,EAAE;AAAA,MACR;AAAA,IACF;AAAA,EACF,CAAC;AACL;AAEA,SAAS,iBAAiB,OAA2C;AACnE,SAAO,MAAM,IAAI,CAAC,OAAO;AAAA,IACvB,MAAM,EAAE;AAAA,IACR,aAAa,EAAE;AAAA,IACf,cAAc,EAAE;AAAA,EAClB,EAAE;AACJ;AAEO,IAAM,oBAAN,MAA+C;AAAA,EAC3C,KAAK;AAAA,EACN;AAAA,EAER,YAAY,QAAgB;AAC1B,SAAK,SAAS,IAAI,UAAU,EAAE,OAAO,CAAC;AAAA,EACxC;AAAA,EAEA,MAAM,aAAa,QAAyD;AAC1E,UAAM,YAAY,OAAO,aAAa;AACtC,UAAM,eAAe;AACrB,UAAM,cAAc,YAAY;AAChC,UAAM,WAAW,MAAM,KAAK,OAAO,SAAS,OAAO;AAAA,MACjD,OAAO,OAAO;AAAA,MACd,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,QAAQ,OAAO;AAAA,MACf,UAAU,oBAAoB,OAAO,QAAQ;AAAA,MAC7C,OAAO,OAAO,QAAQ,iBAAiB,OAAO,KAAK,IAAI;AAAA,MACvD,GAAI,cAAc,EAAE,UAAU,EAAE,MAAM,WAAW,eAAe,aAAa,EAAE,IAAI,CAAC;AAAA,IACtF,CAAkC;AAElC,QAAI,UAAU;AACd,QAAI,WAAW;AACf,UAAM,YAAwB,CAAC;AAE/B,eAAW,SAAS,SAAS,SAAS;AACpC,UAAI,MAAM,SAAS,YAAY;AAC7B,oBAAa,MAA4D;AAAA,MAC3E,WAAW,MAAM,SAAS,QAAQ;AAChC,mBAAW,MAAM;AAAA,MACnB,WAAW,MAAM,SAAS,YAAY;AACpC,kBAAU,KAAK;AAAA,UACb,IAAI,MAAM;AAAA,UACV,MAAM,MAAM;AAAA,UACZ,WAAW,MAAM;AAAA,QACnB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,aACJ,SAAS,gBAAgB,aACrB,aACA,SAAS,gBAAgB,eACvB,eACA;AAER,WAAO;AAAA,MACL;AAAA,MACA,UAAU,YAAY;AAAA,MACtB;AAAA,MACA,OAAO;AAAA,QACL,aAAa,SAAS,MAAM;AAAA,QAC5B,cAAc,SAAS,MAAM;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,eACL,QAC4B;AAC5B,UAAM,YAAY,OAAO,aAAa;AACtC,UAAM,eAAe;AACrB,UAAM,cAAc,YAAY;AAChC,UAAM,SAAS,KAAK,OAAO,SAAS,OAAO;AAAA,MACzC,OAAO,OAAO;AAAA,MACd,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,QAAQ,OAAO;AAAA,MACf,UAAU,oBAAoB,OAAO,QAAQ;AAAA,MAC7C,OAAO,OAAO,QAAQ,iBAAiB,OAAO,KAAK,IAAI;AAAA,MACvD,GAAI,cAAc,EAAE,UAAU,EAAE,MAAM,WAAW,eAAe,aAAa,EAAE,IAAI,CAAC;AAAA,IACtF,CAAkC;AAElC,qBAAiB,SAAS,QAAQ;AAChC,UAAI,MAAM,SAAS,uBAAuB;AACxC,YAAI,MAAM,cAAc,SAAS,YAAY;AAC3C,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN,UAAU;AAAA,cACR,IAAI,MAAM,cAAc;AAAA,cACxB,MAAM,MAAM,cAAc;AAAA,YAC5B;AAAA,UACF;AAAA,QACF;AAAA,MACF,WAAW,MAAM,SAAS,uBAAuB;AAC/C,YAAI,MAAM,MAAM,SAAS,kBAAkB;AACzC,gBAAM,EAAE,MAAM,YAAY,MAAO,MAAM,MAAuD,SAAS;AAAA,QACzG,WAAW,MAAM,MAAM,SAAS,cAAc;AAC5C,gBAAM,EAAE,MAAM,QAAQ,MAAM,MAAM,MAAM,KAAK;AAAA,QAC/C,WAAW,MAAM,MAAM,SAAS,oBAAoB;AAClD,gBAAM,EAAE,MAAM,mBAAmB,MAAM,MAAM,MAAM,aAAa;AAAA,QAClE;AAAA,MACF,WAAW,MAAM,SAAS,sBAAsB;AAC9C,cAAM,EAAE,MAAM,gBAAgB;AAAA,MAChC;AAAA,IACF;AAEA,UAAM,eAAe,MAAM,OAAO,aAAa;AAC/C,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,QACL,aAAa,aAAa,MAAM;AAAA,QAChC,cAAc,aAAa,MAAM;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,SAA4C;AACtD,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,aAAmC;AACvC,WAAO,oBAAoB,WAAW;AAAA,EACxC;AACF;;;ACnMO,IAAM,iBAAN,cAA6B,yBAAyB;AAAA,EAC3D,YAAY,QAAgB;AAC1B,UAAM,UAAU,MAAM;AAAA,EACxB;AACF;;;ACNA;AAAA,EACE;AAAA,EAIA;AAAA,OACK;AAeP,SAAS,iBAAiB,UAAgC;AACxD,QAAM,SAAoB,CAAC;AAE3B,aAAW,KAAK,UAAU;AACxB,QAAI,EAAE,SAAS,SAAU;AAEzB,QAAI,OAAO,EAAE,YAAY,UAAU;AACjC,aAAO,KAAK;AAAA,QACV,MAAM,EAAE,SAAS,cAAc,UAAU;AAAA,QACzC,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC;AAAA,MAC7B,CAAC;AACD;AAAA,IACF;AAEA,UAAM,kBAAkB,EAAE,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,aAAa;AACxE,QAAI,gBAAgB,SAAS,GAAG;AAC9B,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,OAAO,gBAAgB;AAAA,UACrB,CAAC,OAAa;AAAA,YACZ,kBAAkB;AAAA,cAChB,MAAM,EAAE,YAAY;AAAA,cACpB,UAAU,EAAE,QAAQ,EAAE,QAAQ,GAAG;AAAA,YACnC;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,UAAM,QAAgB,CAAC;AACvB,eAAW,QAAQ,EAAE,SAAS;AAC5B,UAAI,KAAK,SAAS,WAAY;AAC9B,UAAI,KAAK,SAAS,YAAY;AAC5B,cAAM,KAAK;AAAA,UACT,cAAc;AAAA,YACZ,MAAM,KAAK;AAAA,YACX,MAAO,KAAK,iBAAiB,CAAC;AAAA,UAChC;AAAA,QACF,CAAC;AAAA,MACH,WAAW,KAAK,SAAS,WAAW,KAAK,aAAa;AACpD,cAAM,KAAK;AAAA,UACT,YAAY;AAAA,YACV,UAAU,KAAK,YAAY;AAAA,YAC3B,MAAM,KAAK;AAAA,UACb;AAAA,QACF,CAAC;AAAA,MACH,OAAO;AACL,cAAM,KAAK,EAAE,MAAM,KAAK,QAAQ,GAAG,CAAC;AAAA,MACtC;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,MACV,MAAM,EAAE,SAAS,cAAc,UAAU;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,uBAAuB,MAA0B;AACxD,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,WAAW;AAAA,IACpB,KAAK;AACH,aAAO,WAAW;AAAA,IACpB,KAAK;AACH,aAAO,WAAW;AAAA,IACpB,KAAK;AACH,aAAO,WAAW;AAAA,IACpB,KAAK;AACH,aAAO,WAAW;AAAA,IACpB,KAAK;AACH,aAAO,WAAW;AAAA,IACpB;AACE,aAAO,WAAW;AAAA,EACtB;AACF;AAEA,SAAS,0BACP,QACyB;AACzB,QAAM,SAAkC,CAAC;AACzC,MAAI,OAAO,MAAM;AACf,WAAO,OAAO,uBAAuB,OAAO,IAAc;AAAA,EAC5D;AACA,MAAI,OAAO,YAAa,QAAO,cAAc,OAAO;AACpD,MAAI,OAAO,YAAY;AACrB,UAAM,QAAiC,CAAC;AACxC,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO;AAAA,MAC9B,OAAO;AAAA,IACT,GAAG;AACD,YAAM,GAAG,IAAI,0BAA0B,GAAG;AAAA,IAC5C;AACA,WAAO,aAAa;AAAA,EACtB;AACA,MAAI,OAAO,SAAU,QAAO,WAAW,OAAO;AAC9C,MAAI,OAAO;AACT,WAAO,QAAQ;AAAA,MACb,OAAO;AAAA,IACT;AACF,SAAO;AACT;AAEA,SAAS,cAAc,OAAgD;AACrE,SAAO,MAAM,IAAI,CAAC,OAAO;AAAA,IACvB,MAAM,EAAE;AAAA,IACR,aAAa,EAAE;AAAA,IACf,YAAY,0BAA0B,EAAE,WAAW;AAAA,EACrD,EAAE;AACJ;AAEO,IAAM,iBAAN,MAA4C;AAAA,EACxC,KAAK;AAAA,EACN;AAAA,EAER,YAAY,QAAgB;AAC1B,SAAK,SAAS,IAAI,mBAAmB,MAAM;AAAA,EAC7C;AAAA,EAEA,MAAM,aAAa,QAAyD;AAC1E,UAAM,QAAQ,KAAK,OAAO,mBAAmB;AAAA,MAC3C,OAAO,OAAO;AAAA,MACd,mBAAmB,OAAO;AAAA,MAC1B,kBAAkB;AAAA,QAChB,aAAa,OAAO;AAAA,QACpB,iBAAiB,OAAO;AAAA,MAC1B;AAAA,MACA,OAAO,OAAO,OAAO,SACjB,CAAC,EAAE,sBAAsB,cAAc,OAAO,KAAK,EAAE,CAAC,IACtD;AAAA,IACN,CAAC;AAED,UAAM,SAAS,MAAM,MAAM,gBAAgB;AAAA,MACzC,UAAU,iBAAiB,OAAO,QAAQ;AAAA,IAC5C,CAAC;AAED,UAAM,WAAW,OAAO;AACxB,QAAI,UAAU;AACd,UAAM,YAAwB,CAAC;AAE/B,QAAI,WAAW;AACf,eAAW,aAAa,SAAS,cAAc,CAAC,GAAG;AACjD,iBAAW,QAAQ,UAAU,QAAQ,OAAO;AAC1C,YAAK,KAA+B,WAAW,KAAK,MAAM;AACxD,sBAAY,KAAK;AAAA,QACnB,WAAW,KAAK,MAAM;AACpB,qBAAW,KAAK;AAAA,QAClB;AACA,YAAI,KAAK,cAAc;AACrB,oBAAU,KAAK;AAAA,YACb,IAAI,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,YAChE,MAAM,KAAK,aAAa;AAAA,YACxB,WAAY,KAAK,aAAa,QAAQ,CAAC;AAAA,UAIzC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,SAAS;AAC3B,UAAM,aAAa,UAAU,SAAS,IAAI,aAAa;AAEvD,WAAO;AAAA,MACL;AAAA,MACA,UAAU,YAAY;AAAA,MACtB;AAAA,MACA,OAAO;AAAA,QACL,aAAa,WAAW,oBAAoB;AAAA,QAC5C,cAAc,WAAW,wBAAwB;AAAA,MACnD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,eACL,QAC4B;AAC5B,UAAM,QAAQ,KAAK,OAAO,mBAAmB;AAAA,MAC3C,OAAO,OAAO;AAAA,MACd,mBAAmB,OAAO;AAAA,MAC1B,kBAAkB;AAAA,QAChB,aAAa,OAAO;AAAA,QACpB,iBAAiB,OAAO;AAAA,MAC1B;AAAA,MACA,OAAO,OAAO,OAAO,SACjB,CAAC,EAAE,sBAAsB,cAAc,OAAO,KAAK,EAAE,CAAC,IACtD;AAAA,IACN,CAAC;AAED,UAAM,SAAS,MAAM,MAAM,sBAAsB;AAAA,MAC/C,UAAU,iBAAiB,OAAO,QAAQ;AAAA,IAC5C,CAAC;AAED,QAAI,cAAc;AAClB,QAAI,eAAe;AAEnB,qBAAiB,SAAS,OAAO,QAAQ;AACvC,UAAI,MAAM,eAAe;AACvB,sBAAc,MAAM,cAAc,oBAAoB;AACtD,uBAAe,MAAM,cAAc,wBAAwB;AAAA,MAC7D;AACA,iBAAW,aAAa,MAAM,cAAc,CAAC,GAAG;AAC9C,mBAAW,QAAQ,UAAU,QAAQ,OAAO;AAC1C,cAAK,KAA+B,WAAW,KAAK,MAAM;AACxD,kBAAM,EAAE,MAAM,YAAY,MAAM,KAAK,KAAK;AAAA,UAC5C,WAAW,KAAK,MAAM;AACpB,kBAAM,EAAE,MAAM,QAAQ,MAAM,KAAK,KAAK;AAAA,UACxC;AACA,cAAI,KAAK,cAAc;AACrB,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN,UAAU;AAAA,gBACR,IAAI,QAAQ,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAAA,gBAChE,MAAM,KAAK,aAAa;AAAA,gBACxB,WAAY,KAAK,aAAa,QAAQ,CAAC;AAAA,cAIzC;AAAA,YACF;AACA,kBAAM,EAAE,MAAM,gBAAgB;AAAA,UAChC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,aAAa;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,QAA2C;AACrD,UAAM,QAAQ,KAAK,OAAO,mBAAmB,EAAE,OAAO,OAAO,MAAM,CAAC;AAEpE,UAAM,SAAS,MAAM,MAAM,mBAAmB;AAAA,MAC5C,UAAU,OAAO,OAAO,IAAI,CAAC,WAAW;AAAA,QACtC,SAAS,EAAE,MAAM,QAAQ,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC,EAAE;AAAA,MACpD,EAAE;AAAA,IACJ,CAAC;AAED,WAAO;AAAA,MACL,YAAY,OAAO,WAAW,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,MACjD,OAAO,EAAE,aAAa,EAAE;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,MAAM,aAAmC;AACvC,WAAO,oBAAoB,QAAQ;AAAA,EACrC;AACF;;;ACjRO,IAAM,mBAAN,cAA+B,yBAAyB;AAAA,EAC7D,YAAY,QAAgB;AAC1B,UAAM,YAAY,QAAQ,4BAA4B;AAAA,EACxD;AACF;;;ACJO,IAAM,eAAN,cAA2B,yBAAyB;AAAA,EACzD,YAAY,QAAgB;AAC1B,UAAM,QAAQ,QAAQ,qBAAqB;AAAA,EAC7C;AACF;;;ACOO,IAAM,qBAAN,cAAiC,yBAAyB;AAAA,EACvD;AAAA,EAER,YAAY,QAAgB;AAC1B,UAAM,cAAc,QAAQ,8BAA8B;AAC1D,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,MAAM,aAAmC;AACvC,UAAM,WAAW,MAAM,MAAM,uCAAuC;AAAA,MAClE,SAAS,EAAE,eAAe,UAAU,KAAK,WAAW,GAAG;AAAA,IACzD,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,gCAAgC,SAAS,MAAM,EAAE;AAAA,IACnE;AACA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,KAAK,IAAI,CAAC,OAAO;AAAA,MAC3B,IAAI,EAAE;AAAA,MACN,MAAM,EAAE,QAAQ,EAAE;AAAA,MAClB,eAAe,EAAE;AAAA,MACjB,iBAAiB,EAAE,SAAS,SAAS,WAAW,EAAE,QAAQ,MAAM,IAAI,MAAY;AAAA,MAChF,kBAAkB,EAAE,SAAS,aAAa,WAAW,EAAE,QAAQ,UAAU,IAAI,MAAY;AAAA,IAC3F,EAAE;AAAA,EACJ;AACF;;;ACnCO,IAAM,kBAAN,cAA8B,yBAAyB;AAAA,EAC5D,YAAY,QAAgB;AAC1B,UAAM,WAAW,QAAQ,6BAA6B;AAAA,EACxD;AACF;;;AC0DA,SAAS,iBAAiB,UAAqB,cAAwC;AACrF,QAAM,SAA0B,CAAC;AAEjC,MAAI,cAAc;AAChB,WAAO,KAAK,EAAE,MAAM,UAAU,SAAS,aAAa,CAAC;AAAA,EACvD;AAEA,aAAW,OAAO,UAAU;AAC1B,QAAI,IAAI,SAAS,SAAU;AAE3B,QAAI,OAAO,IAAI,YAAY,UAAU;AACnC,aAAO,KAAK,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,QAAQ,CAAC;AACpD;AAAA,IACF;AAGA,UAAM,eAAe,IAAI,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,UAAU;AACpE,QAAI,IAAI,SAAS,eAAe,aAAa,SAAS,GAAG;AACvD,YAAM,cAAc,IAAI,QACrB,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM,EAC/B,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EACvB,KAAK,EAAE;AACV,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,SAAS;AAAA,QACT,YAAY,aAAa,IAAI,CAAC,GAAG,OAAO;AAAA,UACtC,MAAM;AAAA,UACN,UAAU;AAAA,YACR,OAAO;AAAA,YACP,MAAM,EAAE;AAAA,YACR,WAAY,EAAE,iBAAiB,CAAC;AAAA,UAClC;AAAA,QACF,EAAE;AAAA,MACJ,CAAC;AACD;AAAA,IACF;AAGA,UAAM,kBAAkB,IAAI,QAAQ,OAAO,CAAC,MAAM,EAAE,SAAS,aAAa;AAC1E,QAAI,gBAAgB,SAAS,GAAG;AAC9B,iBAAW,KAAK,iBAAiB;AAC/B,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,SAAS,EAAE,QAAQ;AAAA,UACnB,WAAW,EAAE;AAAA,QACf,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAGA,UAAM,QAAkB,CAAC;AACzB,UAAM,SAAmB,CAAC;AAC1B,eAAW,QAAQ,IAAI,SAAS;AAC9B,UAAI,KAAK,SAAS,WAAW,KAAK,aAAa;AAC7C,eAAO,KAAK,KAAK,WAAW;AAAA,MAC9B,WAAW,KAAK,MAAM;AACpB,cAAM,KAAK,KAAK,IAAI;AAAA,MACtB;AAAA,IACF;AACA,UAAM,YAA2B;AAAA,MAC/B,MAAM,IAAI;AAAA,MACV,SAAS,MAAM,KAAK,EAAE;AAAA,IACxB;AACA,QAAI,OAAO,SAAS,GAAG;AACrB,gBAAU,SAAS;AAAA,IACrB;AACA,WAAO,KAAK,SAAS;AAAA,EACvB;AAEA,SAAO;AACT;AAEA,SAAS,cAAc,OAAuC;AAC5D,SAAO,MAAM,IAAI,CAAC,OAAO;AAAA,IACvB,MAAM;AAAA,IACN,UAAU;AAAA,MACR,MAAM,EAAE;AAAA,MACR,aAAa,EAAE;AAAA,MACf,YAAY;AAAA,QACV,MAAM;AAAA,QACN,UAAW,EAAE,YAAwC;AAAA,QACrD,YAAa,EAAE,YAAyD,cAAc,CAAC;AAAA,MACzF;AAAA,IACF;AAAA,EACF,EAAE;AACJ;AAEO,IAAM,iBAAN,MAA4C;AAAA,EACxC,KAAK;AAAA,EACN;AAAA,EAER,YAAY,MAAc;AACxB,SAAK,OAAO,KAAK,QAAQ,QAAQ,EAAE;AAAA,EACrC;AAAA,EAEA,MAAM,aAAa,QAAyD;AAC1E,UAAM,OAA0B;AAAA,MAC9B,OAAO,OAAO;AAAA,MACd,UAAU,iBAAiB,OAAO,UAAU,OAAO,YAAY;AAAA,MAC/D,QAAQ;AAAA,MACR,OAAO,OAAO,OAAO,SAAS,cAAc,OAAO,KAAK,IAAI;AAAA,MAC5D,SAAS;AAAA,QACP,GAAI,OAAO,eAAe,OAAO,EAAE,aAAa,OAAO,YAAY,IAAI,CAAC;AAAA,QACxE,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,IAAI,aAAa;AAAA,MACpD,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,iBAAiB,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAC5D;AAEA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,UAAM,MAAM,KAAK;AAEjB,UAAM,aAAyB,IAAI,cAAc,CAAC,GAAG,IAAI,CAAC,IAAI,OAAO;AAAA,MACnE,IAAI,aAAa,CAAC;AAAA,MAClB,MAAM,GAAG,SAAS;AAAA,MAClB,WAAW,GAAG,SAAS;AAAA,IACzB,EAAE;AAEF,UAAM,aAAa,UAAU,SAAS,IAAI,aAAa;AAEvD,WAAO;AAAA,MACL,SAAS,IAAI,WAAW;AAAA,MACxB;AAAA,MACA,OAAO;AAAA,QACL,aAAa,KAAK,qBAAqB;AAAA,QACvC,cAAc,KAAK,cAAc;AAAA,MACnC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,eAAe,QAAwD;AAC5E,UAAM,OAA0B;AAAA,MAC9B,OAAO,OAAO;AAAA,MACd,UAAU,iBAAiB,OAAO,UAAU,OAAO,YAAY;AAAA,MAC/D,QAAQ;AAAA,MACR,OAAO,OAAO,OAAO,SAAS,cAAc,OAAO,KAAK,IAAI;AAAA,MAC5D,SAAS;AAAA,QACP,GAAI,OAAO,eAAe,OAAO,EAAE,aAAa,OAAO,YAAY,IAAI,CAAC;AAAA,QACxE,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,IAAI,aAAa;AAAA,MACpD,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,IAAI,MAAM,iBAAiB,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,IAC5D;AAEA,UAAM,SAAS,SAAS,MAAM,UAAU;AACxC,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,8BAA8B;AAE3D,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI,SAAS;AACb,QAAI,cAAc;AAClB,QAAI,eAAe;AAEnB,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AAEV,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,YAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,eAAS,MAAM,IAAI,KAAK;AAExB,iBAAW,QAAQ,OAAO;AACxB,cAAM,UAAU,KAAK,KAAK;AAC1B,YAAI,CAAC,QAAS;AAEd,YAAI;AACJ,YAAI;AACF,kBAAQ,KAAK,MAAM,OAAO;AAAA,QAC5B,QAAQ;AACN;AAAA,QACF;AAGA,YAAI,MAAM,QAAQ,YAAY,QAAQ;AACpC,mBAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,WAAW,QAAQ,KAAK;AACxD,kBAAM,KAAK,MAAM,QAAQ,WAAW,CAAC;AACrC,kBAAM,KAAK,aAAa,CAAC;AACzB,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN,UAAU,EAAE,IAAI,MAAM,GAAG,SAAS,KAAK;AAAA,YACzC;AACA,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN,MAAM,KAAK,UAAU,GAAG,SAAS,SAAS;AAAA,YAC5C;AAAA,UACF;AACA;AAAA,QACF;AAGA,YAAI,MAAM,QAAQ,SAAS;AACzB,gBAAM,EAAE,MAAM,QAAQ,MAAM,MAAM,QAAQ,QAAQ;AAAA,QACpD;AAGA,YAAI,MAAM,MAAM;AACd,wBAAc,MAAM,qBAAqB;AACzC,yBAAe,MAAM,cAAc;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,KAAK,GAAG;AACjB,UAAI;AACF,cAAM,QAAQ,KAAK,MAAM,OAAO,KAAK,CAAC;AACtC,YAAI,MAAM,QAAQ,YAAY,QAAQ;AACpC,mBAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,WAAW,QAAQ,KAAK;AACxD,kBAAM,KAAK,MAAM,QAAQ,WAAW,CAAC;AACrC,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN,UAAU,EAAE,IAAI,aAAa,CAAC,IAAI,MAAM,GAAG,SAAS,KAAK;AAAA,YAC3D;AACA,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN,MAAM,KAAK,UAAU,GAAG,SAAS,SAAS;AAAA,YAC5C;AAAA,UACF;AAAA,QACF,WAAW,MAAM,QAAQ,SAAS;AAChC,gBAAM,EAAE,MAAM,QAAQ,MAAM,MAAM,QAAQ,QAAQ;AAAA,QACpD;AACA,YAAI,MAAM,MAAM;AACd,wBAAc,MAAM,qBAAqB;AACzC,yBAAe,MAAM,cAAc;AAAA,QACrC;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO,EAAE,aAAa,aAAa;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,QAA2C;AACrD,UAAM,UAAsB,CAAC;AAC7B,QAAI,cAAc;AAElB,eAAW,SAAS,OAAO,QAAQ;AACjC,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,IAAI,cAAc;AAAA,QACrD,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,OAAO,OAAO,OAAO,MAAM,CAAC;AAAA,MACrD,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,cAAM,IAAI,MAAM,uBAAuB,SAAS,MAAM,IAAI,IAAI,EAAE;AAAA,MAClE;AAEA,YAAM,OAAQ,MAAM,SAAS,KAAK;AAIlC,cAAQ,KAAK,GAAG,KAAK,UAAU;AAC/B,qBAAe,KAAK,qBAAqB;AAAA,IAC3C;AAEA,WAAO,EAAE,YAAY,SAAS,OAAO,EAAE,YAAY,EAAE;AAAA,EACvD;AAAA,EAEA,MAAM,aAAmC;AACvC,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,IAAI,WAAW;AACpD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,iCAAiC,SAAS,UAAU,EAAE;AAAA,IACxE;AACA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAGlC,YAAQ,KAAK,UAAU,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,MACrC,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,IACpB,EAAE;AAAA,EACJ;AACF;;;AC5UO,IAAM,sBAAsC;AAAA,EACjD,EAAE,IAAI,aAAa,MAAM,sBAAsB,gBAAgB,KAAK;AAAA,EACpE,EAAE,IAAI,UAAU,MAAM,gBAAgB,gBAAgB,KAAK;AAAA,EAC3D,EAAE,IAAI,UAAU,MAAM,mBAAmB,gBAAgB,KAAK;AAAA,EAC9D,EAAE,IAAI,YAAY,MAAM,mBAAmB,gBAAgB,KAAK;AAAA,EAChE,EAAE,IAAI,QAAQ,MAAM,cAAc,gBAAgB,KAAK;AAAA,EACvD,EAAE,IAAI,cAAc,MAAM,cAAc,gBAAgB,KAAK;AAAA,EAC7D,EAAE,IAAI,WAAW,MAAM,WAAW,gBAAgB,KAAK;AAAA,EACvD,EAAE,IAAI,UAAU,MAAM,UAAU,gBAAgB,MAAM;AACxD;AAEO,SAAS,gBAAgB,IAA0C;AACxE,SAAO,oBAAoB,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACpD;AAEO,SAAS,eACd,IACA,QACa;AACb,UAAQ,IAAI;AAAA,IACV,KAAK;AACH,aAAO,IAAI,kBAAkB,MAAM;AAAA,IACrC,KAAK;AACH,aAAO,IAAI,eAAe,MAAM;AAAA,IAClC,KAAK;AACH,aAAO,IAAI,eAAe,MAAM;AAAA,IAClC,KAAK;AACH,aAAO,IAAI,iBAAiB,MAAM;AAAA,IACpC,KAAK;AACH,aAAO,IAAI,aAAa,MAAM;AAAA,IAChC,KAAK;AACH,aAAO,IAAI,mBAAmB,MAAM;AAAA,IACtC,KAAK;AACH,aAAO,IAAI,gBAAgB,MAAM;AAAA,IACnC,KAAK;AACH,aAAO,IAAI,eAAe,MAAM;AAAA,IAClC;AACE,YAAM,IAAI,MAAM,qBAAqB,EAAE,EAAE;AAAA,EAC7C;AACF;;;ACpEA,OAAOA,aAAY;;;ACcZ,SAAS,kBAAkB,KAAkC;AAClE,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK;AAAA;AAAA,oCAEuB,IAAI,aAAa;AAAA;AAAA,0BAE5B,oBAAI,KAAK,GAAE,eAAe,SAAS,EAAE,SAAS,QAAQ,MAAM,WAAW,OAAO,QAAQ,KAAK,WAAW,MAAM,WAAW,QAAQ,WAAW,QAAQ,WAAW,cAAc,QAAQ,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wKA4B3C;AAEjK,MAAI,IAAI,qBAAqB;AAC3B,UAAM,KAAK;AAAA;AAAA;AAAA;AAAA,EAAmG,IAAI,mBAAmB,EAAE;AAAA,EACzI;AAEA,MAAI,IAAI,eAAe;AACrB,UAAM,KAAK;AAAA;AAAA;AAAA;AAAA,EAAuF,IAAI,aAAa,EAAE;AAAA,EACvH;AAEA,MAAI,IAAI,gBAAgB,IAAI,aAAa,SAAS,GAAG;AACnD,UAAM,KAAK;AAAA;AAAA,EAA0B,IAAI,aAAa,KAAK,MAAM,CAAC,EAAE;AAAA,EACtE;AAEA,MAAI,IAAI,SAAS;AACf,UAAM,KAAK;AAAA;AAAA,+BAAsD,IAAI,QAAQ,IAAI,kBAAkB,IAAI,QAAQ,MAAM,sEAAsE,IAAI,QAAQ,IAAI,0BAA0B,IAAI,QAAQ,MAAM,oCAAoC;AAAA,EAC7R;AAEA,QAAM,KAAK;AAAA;AAAA,EAAyB,IAAI,UAAU,KAAK,IAAI,CAAC,EAAE;AAE9D,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACtEA,OAAO,QAAQ;AACf,OAAO,UAAU;AAWjB,IAAM,SAAN,MAAa;AAAA,EACH,SAAwB;AAAA,EACxB,SAAgC;AAAA,EAChC,cAA6B;AAAA,EAErC,KAAK,QAAsB;AACzB,SAAK,SAAS;AACd,OAAG,UAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AACxC,SAAK,aAAa;AAAA,EACpB;AAAA,EAEQ,eAAsC;AAC5C,QAAI,CAAC,KAAK,OAAQ,QAAO;AAEzB,UAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAClD,QAAI,UAAU,KAAK,aAAa;AAC9B,WAAK,QAAQ,IAAI;AACjB,YAAM,UAAU,KAAK;AAAA,QACnB,KAAK;AAAA,QACL,WAAW,KAAK;AAAA,MAClB;AACA,WAAK,SAAS,GAAG,kBAAkB,SAAS,EAAE,OAAO,IAAI,CAAC;AAC1D,WAAK,cAAc;AAAA,IACrB;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,MAAM,OAAiB,SAAiB,WAA0B;AACxE,UAAM,QAAkB;AAAA,MACtB,OAAM,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,SAAS,KAAK,aAAa;AACjC,QAAI,QAAQ;AACV,aAAO,MAAM,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,KAAK,SAAiB,WAA0B;AAC9C,SAAK,MAAM,QAAQ,SAAS,SAAS;AAAA,EACvC;AAAA,EAEA,KAAK,SAAiB,WAA0B;AAC9C,SAAK,MAAM,QAAQ,SAAS,SAAS;AAAA,EACvC;AAAA,EAEA,MAAM,SAAiB,WAA0B;AAC/C,SAAK,MAAM,SAAS,SAAS,SAAS;AAAA,EACxC;AAAA,EAEA,MAAM,SAAiB,WAA0B;AAC/C,SAAK,MAAM,SAAS,SAAS,SAAS;AAAA,EACxC;AAAA,EAEQ,eAAqB;AAC3B,QAAI,CAAC,KAAK,OAAQ;AAClB,QAAI;AACF,YAAM,QAAQ,GAAG,YAAY,KAAK,MAAM;AACxC,YAAM,SAAS,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,KAAK;AAC/C,iBAAW,QAAQ,OAAO;AACxB,YAAI,CAAC,KAAK,WAAW,UAAU,EAAG;AAClC,cAAM,WAAW,KAAK,KAAK,KAAK,QAAQ,IAAI;AAC5C,cAAM,OAAO,GAAG,SAAS,QAAQ;AACjC,YAAI,KAAK,UAAU,QAAQ;AACzB,aAAG,WAAW,QAAQ;AAAA,QACxB;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,SAAK,QAAQ,IAAI;AACjB,SAAK,SAAS;AAAA,EAChB;AACF;AAEO,IAAM,SAAS,IAAI,OAAO;;;AFtEjC,IAAM,mBAAmB;AACzB,IAAM,4BAA4B;AAMlC,SAAS,cAAc,MAAuC;AAC5D,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AAEN,QAAI,QAAQ;AACZ,QAAI,WAAW;AACf,QAAI,UAAU;AAEd,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,KAAK,KAAK,CAAC;AACjB,YAAM,OAAO,KAAK,WAAW,CAAC;AAE9B,UAAI,SAAS;AACX,iBAAS;AACT,kBAAU;AACV;AAAA,MACF;AAEA,UAAI,OAAO,QAAQ,UAAU;AAC3B,iBAAS;AACT,kBAAU;AACV;AAAA,MACF;AAEA,UAAI,OAAO,KAAK;AACd,mBAAW,CAAC;AACZ,iBAAS;AACT;AAAA,MACF;AAEA,UAAI,YAAY,OAAO,IAAM;AAE3B,gBAAQ,IAAI;AAAA,UACV,KAAK;AAAM,qBAAS;AAAO;AAAA,UAC3B,KAAK;AAAM,qBAAS;AAAO;AAAA,UAC3B,KAAK;AAAM,qBAAS;AAAO;AAAA,UAC3B;AAAS,qBAAS,QAAQ,KAAK,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAAA,QAC7D;AAAA,MACF,OAAO;AACL,iBAAS;AAAA,MACX;AAAA,IACF;AAEA,WAAO,KAAK,MAAM,KAAK;AAAA,EACzB;AACF;AAOA,SAAS,uBAAuB,UAA2B;AACzD,MAAI,SAAS,WAAW,EAAG;AAE3B,QAAM,UAAU,SAAS,SAAS,SAAS,CAAC;AAC5C,MAAI,QAAQ,SAAS,eAAe,CAAC,MAAM,QAAQ,QAAQ,OAAO,EAAG;AAErE,QAAM,aAAa,QAAQ,QACxB,OAAO,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,UAAU,EACnD,IAAI,CAAC,MAAM,EAAE,UAAW;AAE3B,MAAI,WAAW,WAAW,EAAG;AAI7B,WAAS,KAAK;AAAA,IACZ,MAAM;AAAA,IACN,SAAS,WAAW,IAAI,CAAC,QAAQ;AAAA,MAC/B,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,SAAS;AAAA,IACX,EAAE;AAAA,EACJ,CAAC;AACH;AAEA,SAAS,uBAAuB,UAAqB,UAAwB;AAC3E,WAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,UAAM,MAAM,SAAS,CAAC;AACtB,QAAI,CAAC,MAAM,QAAQ,IAAI,OAAO,EAAG;AACjC,eAAW,QAAQ,IAAI,SAAS;AAC9B,UACE,KAAK,SAAS,iBACd,KAAK,QACL,KAAK,KAAK,SAAS,2BACnB;AACA,aAAK,OACH,KAAK,KAAK,MAAM,GAAG,yBAAyB,IAC5C;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,OACb,aACA,OACc;AACd,QAAM,UAAe,IAAI,MAAM,MAAM,MAAM;AAC3C,MAAI,QAAQ;AAEZ,QAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,aAAa,MAAM,MAAM,EAAE,GAAG,YAAY;AACtF,WAAO,QAAQ,MAAM,QAAQ;AAC3B,YAAM,IAAI;AACV,cAAQ,CAAC,IAAI,MAAM,MAAM,CAAC,EAAE;AAAA,IAC9B;AAAA,EACF,CAAC;AAED,QAAM,QAAQ,IAAI,OAAO;AACzB,SAAO;AACT;AA2BO,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EAER,YAAY,MAAuB;AACjC,SAAK,OAAO;AAAA,EACd;AAAA,EAEQ,uBAAyC;AAC/C,WAAO,KAAK,KAAK,MAAM,IAAI,CAAC,MAAM,EAAE,UAAU;AAAA,EAChD;AAAA,EAEQ,eAAe,MAAuC;AAC5D,WAAO,KAAK,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,SAAS,IAAI;AAAA,EAC/D;AAAA,EAEA,MAAc,wBAAyC;AACrD,UAAM,CAAC,eAAe,mBAAmB,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC7D,KAAK,KAAK,iBAAiB;AAAA,MAC3B,KAAK,KAAK,uBAAuB;AAAA,IACnC,CAAC;AACD,UAAM,MAA2B;AAAA,MAC/B,eAAe,KAAK,KAAK,iBAAiB;AAAA,MAC1C;AAAA,MACA;AAAA,MACA,cAAc,KAAK,KAAK,gBAAgB;AAAA,MACxC,WAAW,KAAK,KAAK,MAAM,IAAI,CAAC,MAAM,EAAE,WAAW,IAAI;AAAA,MACvD,SAAS,KAAK,KAAK;AAAA,IACrB;AACA,WAAO,kBAAkB,GAAG;AAAA,EAC9B;AAAA,EAEQ,kBAAkB,WAAmB,OAAqC;AAChF,WAAO;AAAA,MACL,eAAe,KAAK,KAAK,iBAAiB;AAAA,MAC1C,SAAS,KAAK,KAAK,WAAW;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,mBAAmB,OAAO,QAA2B;AACnD,YAAI,KAAK,KAAK,qBAAqB;AACjC,iBAAO,KAAK,KAAK,oBAAoB,GAAG;AAAA,QAC1C;AACA,eAAO;AAAA,MACT;AAAA,MACA,sBAAsB,OAAO,QAA8B;AACzD,YAAI,KAAK,KAAK,wBAAwB;AACpC,iBAAO,KAAK,KAAK,uBAAuB,GAAG;AAAA,QAC7C;AACA,eAAO,CAAC;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,QAAiD;AACzD,UAAM,QAAQC,QAAO,WAAW;AAChC,UAAM,YAAY,OAAO,aAAaA,QAAO,WAAW;AACxD,UAAM,EAAE,OAAO,IAAI,KAAK;AAExB,UAAM,WAAW,MAAM,KAAK,KAAK,mBAAmB,SAAS;AAE7D,QAAI,OAAO,aAAa,QAAQ;AAC9B,YAAM,QAAuB;AAAA,QAC3B,EAAE,MAAM,QAAQ,MAAM,OAAO,OAAO;AAAA,QACpC,GAAG,OAAO,YAAY,IAAI,CAAC,OAAO;AAAA,UAChC,MAAM;AAAA,UACN,aAAa,EAAE;AAAA,UACf,UAAU,EAAE;AAAA,QACd,EAAE;AAAA,MACJ;AACA,eAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,MAAM,CAAC;AAAA,IAChD,OAAO;AACL,eAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,OAAO,OAAO,CAAC;AAAA,IACxD;AAEA,UAAM,eAAe,MAAM,KAAK,sBAAsB;AACtD,UAAM,WAAW,KAAK,qBAAqB;AAC3C,UAAM,cAAc,KAAK,kBAAkB,WAAW,KAAK;AAE3D,QAAI,mBAAmB;AACvB,QAAI,oBAAoB;AACxB,UAAM,eAA2B,CAAC;AAClC,QAAI,eAAe;AAEnB,aAAS,OAAO,GAAG,OAAO,OAAO,UAAU,QAAQ;AACjD,UAAI,OAAO,GAAG;AACZ,+BAAuB,UAAU,SAAS,MAAM;AAAA,MAClD;AAEA,YAAM,iBAAqC;AAAA,QACzC,OAAO,OAAO;AAAA,QACd;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,aAAa,OAAO;AAAA,QACpB,WAAW,OAAO;AAAA,MACpB;AAEA,YAAM,SAAS,MAAM,OAAO,SAAS,aAAa,cAAc;AAEhE,0BAAoB,OAAO,MAAM;AACjC,2BAAqB,OAAO,MAAM;AAElC,aAAO;AAAA,QACL,QAAQ,IAAI,QAAQ,OAAO,MAAM,WAAW,QAAQ,OAAO,MAAM,YAAY,SAAS,OAAO,UAAU;AAAA,QACvG;AAAA,MACF;AAEA,UAAI,OAAO,SAAS;AAClB,uBAAe,OAAO;AAAA,MACxB;AAGA,UAAI,OAAO,WAAW,OAAO,YAAY,OAAO,UAAU,SAAS,GAAG;AACpE,cAAM,QAAuB,CAAC;AAC9B,YAAI,OAAO,UAAU;AACnB,gBAAM,KAAK,EAAE,MAAM,YAAY,MAAM,OAAO,SAAS,CAAC;AAAA,QACxD;AACA,YAAI,OAAO,SAAS;AAClB,gBAAM,KAAK,EAAE,MAAM,QAAQ,MAAM,OAAO,QAAQ,CAAC;AAAA,QACnD;AACA,mBAAW,MAAM,OAAO,WAAW;AACjC,gBAAM,KAAK;AAAA,YACT,MAAM;AAAA,YACN,YAAY,GAAG;AAAA,YACf,UAAU,GAAG;AAAA,YACb,eAAe,GAAG;AAAA,UACpB,CAAC;AAAA,QACH;AACA,iBAAS,KAAK,EAAE,MAAM,aAAa,SAAS,MAAM,CAAC;AAAA,MACrD;AAGA,UAAI,OAAO,UAAU,WAAW,KAAK,OAAO,eAAe,YAAY;AACrE;AAAA,MACF;AAEA,mBAAa,KAAK,GAAG,OAAO,SAAS;AAGrC,YAAM,cAAc,MAAM;AAAA,QACxB;AAAA,QACA,OAAO,UAAU,IAAI,CAAC,aAAa,YAAY;AAC7C,gBAAM,UAAU,KAAK,eAAe,SAAS,IAAI;AACjD,cAAI,CAAC,SAAS;AACZ,mBAAO;AAAA,cACL,YAAY,SAAS;AAAA,cACrB,SAAS,iBAAiB,SAAS,IAAI;AAAA,cACvC,SAAS;AAAA,YACX;AAAA,UACF;AACA,cAAI;AACF,mBAAO,MAAM,QAAQ,QAAQ,SAAS,WAAW,WAAW;AAAA,UAC9D,SAAS,KAAK;AACZ,mBAAO;AAAA,cACL,YAAY,SAAS;AAAA,cACrB,SAAS,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,cACxE,SAAS;AAAA,YACX;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAGA,YAAM,kBAAiC,OAAO,UAAU;AAAA,QACtD,CAAC,UAAU,OAAO;AAAA,UAChB,MAAM;AAAA,UACN,YAAY,SAAS;AAAA,UACrB,UAAU,SAAS;AAAA,UACnB,MAAM,YAAY,CAAC,EAAE;AAAA,UACrB,SAAS,YAAY,CAAC,EAAE;AAAA,QAC1B;AAAA,MACF;AACA,eAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,gBAAgB,CAAC;AAGxD,YAAM,YAAY,OAAO,WAAW,OAAO;AAC3C,UAAI,cAAc,GAAG;AACnB,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SACE;AAAA,QACJ,CAAC;AAAA,MACH;AAAA,IACF;AAGA,2BAAuB,QAAQ;AAC/B,UAAM,KAAK,KAAK,oBAAoB,WAAW,QAAQ;AAEvD,WAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,MACV,WAAW;AAAA,MACX,OAAO;AAAA,QACL,aAAa;AAAA,QACb,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,UAAU,QAAyD;AACxE,UAAM,QAAQA,QAAO,WAAW;AAChC,UAAM,YAAY,OAAO,aAAaA,QAAO,WAAW;AACxD,UAAM,EAAE,OAAO,IAAI,KAAK;AACxB,UAAM,SAAS,OAAO;AAEtB,UAAM,WAAW,MAAM,KAAK,KAAK,mBAAmB,SAAS;AAG7D,QAAI,OAAO,aAAa,QAAQ;AAC9B,YAAM,QAAuB;AAAA,QAC3B,EAAE,MAAM,QAAQ,MAAM,OAAO,OAAO;AAAA,QACpC,GAAG,OAAO,YAAY,IAAI,CAAC,OAAO;AAAA,UAChC,MAAM;AAAA,UACN,aAAa,EAAE;AAAA,UACf,UAAU,EAAE;AAAA,QACd,EAAE;AAAA,MACJ;AACA,eAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,MAAM,CAAC;AAAA,IAChD,OAAO;AACL,eAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,OAAO,OAAO,CAAC;AAAA,IACxD;AAEA,UAAM,eAAe,MAAM,KAAK,sBAAsB;AACtD,UAAM,WAAW,KAAK,qBAAqB;AAC3C,UAAM,cAAc,KAAK,kBAAkB,WAAW,KAAK;AAE3D,QAAI,mBAAmB;AACvB,QAAI,oBAAoB;AACxB,QAAI,eAAe;AAEnB,aAAS,OAAO,GAAG,OAAO,OAAO,UAAU,QAAQ;AAEjD,UAAI,QAAQ,SAAS;AACnB,eAAO,MAAM,uBAAuB,OAAO;AAC3C;AAAA,MACF;AAEA,UAAI,OAAO,GAAG;AACZ,+BAAuB,UAAU,SAAS,MAAM;AAAA,MAClD;AAEA,YAAM,iBAAqC;AAAA,QACzC,OAAO,OAAO;AAAA,QACd;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,aAAa,OAAO;AAAA,QACpB,WAAW,OAAO;AAAA,MACpB;AAGA,YAAM,QAAuB,CAAC;AAC9B,UAAI,cAAc;AAClB,UAAI,kBAAkB;AACtB,YAAM,YAAwB,CAAC;AAC/B,YAAM,kBAAkB,oBAAI,IAAgE;AAG5F,UAAI,gBAAgB;AACpB,UAAI,YAAY;AAEhB,uBAAiB,SAAS,OAAO,SAAS,eAAe,cAAc,GAAG;AACxE,YAAI,QAAQ,QAAS;AACrB,YAAI,MAAM,SAAS,cAAc,MAAM,MAAM;AAE3C,6BAAmB,MAAM;AACzB,gBAAM,EAAE,MAAM,kBAAkB,MAAM,MAAM,KAAK;AAAA,QACnD,WAAW,MAAM,SAAS,UAAU,MAAM,MAAM;AAE9C,cAAI,OAAO,YAAY,MAAM;AAC7B,sBAAY;AAEZ,iBAAO,KAAK,SAAS,GAAG;AACtB,gBAAI,eAAe;AACjB,oBAAM,WAAW,KAAK,QAAQ,aAAa;AAC3C,kBAAI,aAAa,IAAI;AACnB,sBAAM,YAAY,KAAK,MAAM,GAAG,QAAQ;AACxC,oBAAI,WAAW;AACb,qCAAmB;AACnB,wBAAM,EAAE,MAAM,kBAAkB,MAAM,UAAU;AAAA,gBAClD;AACA,gCAAgB;AAChB,uBAAO,KAAK,MAAM,WAAW,cAAc,MAAM;AAAA,cACnD,WAAW,KAAK,SAAS,MAAM,KAAK,MAAM,GAAG,EAAE,SAAS,GAAG,GAAG;AAE5D,sBAAM,WAAW,KAAK,YAAY,GAAG;AACrC,sBAAM,YAAY,KAAK,MAAM,GAAG,QAAQ;AACxC,oBAAI,WAAW;AACb,qCAAmB;AACnB,wBAAM,EAAE,MAAM,kBAAkB,MAAM,UAAU;AAAA,gBAClD;AACA,4BAAY,KAAK,MAAM,QAAQ;AAC/B,uBAAO;AAAA,cACT,OAAO;AACL,mCAAmB;AACnB,sBAAM,EAAE,MAAM,kBAAkB,KAAK;AACrC,uBAAO;AAAA,cACT;AAAA,YACF,OAAO;AACL,oBAAM,UAAU,KAAK,QAAQ,YAAY;AACzC,kBAAI,YAAY,IAAI;AAClB,sBAAM,SAAS,KAAK,MAAM,GAAG,OAAO;AACpC,oBAAI,QAAQ;AACV,iCAAe;AACf,wBAAM,EAAE,MAAM,cAAc,MAAM,OAAO;AAAA,gBAC3C;AACA,gCAAgB;AAChB,uBAAO,KAAK,MAAM,UAAU,aAAa,MAAM;AAAA,cACjD,WAAW,KAAK,SAAS,MAAM,KAAK,MAAM,GAAG,EAAE,SAAS,GAAG,GAAG;AAE5D,sBAAM,WAAW,KAAK,YAAY,GAAG;AACrC,sBAAM,SAAS,KAAK,MAAM,GAAG,QAAQ;AACrC,oBAAI,QAAQ;AACV,iCAAe;AACf,wBAAM,EAAE,MAAM,cAAc,MAAM,OAAO;AAAA,gBAC3C;AACA,4BAAY,KAAK,MAAM,QAAQ;AAC/B,uBAAO;AAAA,cACT,OAAO;AACL,+BAAe;AACf,sBAAM,EAAE,MAAM,cAAc,KAAK;AACjC,uBAAO;AAAA,cACT;AAAA,YACF;AAAA,UACF;AAAA,QACF,WAAW,MAAM,SAAS,qBAAqB,MAAM,UAAU;AAE7D,cAAI,WAAW;AACb,2BAAe;AACf,kBAAM,EAAE,MAAM,cAAc,MAAM,UAAU;AAC5C,wBAAY;AAAA,UACd;AACA,gBAAM,MAAM,gBAAgB;AAC5B,0BAAgB,IAAI,KAAK;AAAA,YACvB,IAAI,MAAM,SAAS,MAAM,MAAM,GAAG;AAAA,YAClC,MAAM,MAAM,SAAS,QAAQ;AAAA,YAC7B,YAAY,CAAC;AAAA,UACf,CAAC;AACD,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN,UAAU,MAAM,SAAS;AAAA,YACzB,YAAY,MAAM,SAAS;AAAA,UAC7B;AAAA,QACF,WAAW,MAAM,SAAS,qBAAqB,MAAM,MAAM;AACzD,gBAAM,MAAM,gBAAgB,OAAO;AACnC,gBAAM,MAAM,gBAAgB,IAAI,GAAG;AACnC,cAAI,IAAK,KAAI,WAAW,KAAK,MAAM,IAAI;AACvC,gBAAM,EAAE,MAAM,mBAAmB,MAAM,MAAM,KAAK;AAAA,QACpD,WAAW,MAAM,SAAS,iBAAiB;AACzC,gBAAM,EAAE,MAAM,gBAAgB;AAAA,QAChC,WAAW,MAAM,SAAS,iBAAiB,MAAM,OAAO;AACtD,8BAAoB,MAAM,MAAM;AAChC,+BAAqB,MAAM,MAAM;AAAA,QACnC;AAAA,MACF;AAGA,UAAI,WAAW;AACb,YAAI,eAAe;AACjB,6BAAmB;AACnB,gBAAM,EAAE,MAAM,kBAAkB,MAAM,UAAU;AAAA,QAClD,OAAO;AACL,yBAAe;AACf,gBAAM,EAAE,MAAM,cAAc,MAAM,UAAU;AAAA,QAC9C;AAAA,MACF;AAGA,YAAM,cAAkE,CAAC;AACzE,iBAAW,CAAC,EAAE,GAAG,KAAK,iBAAiB;AACrC,cAAM,OAAO,IAAI,WAAW,KAAK,EAAE;AACnC,YAAI,CAAC,MAAM;AACT,oBAAU,KAAK,EAAE,IAAI,IAAI,IAAI,MAAM,IAAI,MAAM,WAAW,CAAC,EAAE,CAAC;AAC5D;AAAA,QACF;AACA,YAAI;AACF,gBAAM,OAAO,cAAc,IAAI;AAC/B,oBAAU,KAAK,EAAE,IAAI,IAAI,IAAI,MAAM,IAAI,MAAM,WAAW,KAAK,CAAC;AAAA,QAChE,SAAS,KAAK;AACZ,sBAAY,KAAK;AAAA,YACf,IAAI,IAAI;AAAA,YACR,MAAM,IAAI;AAAA,YACV,OAAO,2BAA2B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UACpF,CAAC;AAAA,QACH;AAAA,MACF;AAEA,UAAI,iBAAiB;AACnB,cAAM,KAAK,EAAE,MAAM,YAAY,MAAM,gBAAgB,CAAC;AAAA,MACxD;AACA,UAAI,aAAa;AACf,cAAM,KAAK,EAAE,MAAM,QAAQ,MAAM,YAAY,CAAC;AAC9C,uBAAe;AAAA,MACjB;AAEA,iBAAW,MAAM,WAAW;AAC1B,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,YAAY,GAAG;AAAA,UACf,UAAU,GAAG;AAAA,UACb,eAAe,GAAG;AAAA,QACpB,CAAC;AAAA,MACH;AACA,iBAAW,MAAM,aAAa;AAC5B,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,YAAY,GAAG;AAAA,UACf,UAAU,GAAG;AAAA,UACb,eAAe,CAAC;AAAA,QAClB,CAAC;AAAA,MACH;AACA,UAAI,MAAM,SAAS,GAAG;AACpB,iBAAS,KAAK,EAAE,MAAM,aAAa,SAAS,MAAM,CAAC;AAAA,MACrD;AAGA,UAAI,UAAU,WAAW,KAAK,YAAY,WAAW,GAAG;AACtD;AAAA,MACF;AAGA,UAAI,QAAQ,SAAS;AACnB,eAAO,MAAM,6CAA6C,OAAO;AACjE;AAAA,MACF;AAGA,YAAM,cAAc,MAAM;AAAA,QACxB;AAAA,QACA,UAAU,IAAI,CAAC,aAAa,YAAY;AACtC,gBAAM,UAAU,KAAK,eAAe,SAAS,IAAI;AACjD,cAAI,CAAC,SAAS;AACZ,mBAAO;AAAA,cACL,YAAY,SAAS;AAAA,cACrB,SAAS,iBAAiB,SAAS,IAAI;AAAA,cACvC,SAAS;AAAA,YACX;AAAA,UACF;AACA,cAAI;AACF,mBAAO,MAAM,QAAQ,QAAQ,SAAS,WAAW,WAAW;AAAA,UAC9D,SAAS,KAAK;AACZ,mBAAO;AAAA,cACL,YAAY,SAAS;AAAA,cACrB,SAAS,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,cACxE,SAAS;AAAA,YACX;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAGA,YAAM,eAA6B,YAAY,IAAI,CAAC,QAAQ;AAAA,QAC1D,YAAY,GAAG;AAAA,QACf,SAAS,GAAG;AAAA,QACZ,SAAS;AAAA,MACX,EAAE;AAGF,YAAM,aAAa,CAAC,GAAG,aAAa,GAAG,YAAY;AACnD,YAAM,WAAW;AAAA,QACf,GAAG;AAAA,QACH,GAAG,YAAY,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,EAAE;AAAA,MAC1E;AAEA,YAAM,kBAAiC,SAAS,IAAI,CAAC,IAAI,OAAO;AAAA,QAC9D,MAAM;AAAA,QACN,YAAY,GAAG;AAAA,QACf,UAAU,GAAG;AAAA,QACb,MAAM,WAAW,CAAC,EAAE;AAAA,QACpB,SAAS,WAAW,CAAC,EAAE;AAAA,MACzB,EAAE;AAEF,eAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,cAAM;AAAA,UACJ,MAAM;AAAA,UACN,YAAY,SAAS,CAAC,EAAE;AAAA,UACxB,UAAU,SAAS,CAAC,EAAE;AAAA,UACtB,UAAU,SAAS,CAAC,EAAE;AAAA,UACtB,YAAY,WAAW,CAAC;AAAA,QAC1B;AAAA,MACF;AAEA,eAAS,KAAK,EAAE,MAAM,QAAQ,SAAS,gBAAgB,CAAC;AAExD,YAAM,YAAY,OAAO,WAAW,OAAO;AAC3C,UAAI,cAAc,GAAG;AACnB,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,SACE;AAAA,QACJ,CAAC;AAAA,MACH;AAAA,IACF;AAGA,2BAAuB,QAAQ;AAC/B,UAAM,KAAK,KAAK,oBAAoB,WAAW,QAAQ;AAEvD,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,QACL,aAAa;AAAA,QACb,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACF;;;AGnqBA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAGV,IAAM,eAA4B;AAAA,EACvC,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,MAAM;AAAA,IACnB;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,MAAM,SAAS;AAC3B,UAAM,WAAWA,MAAK,QAAQ,QAAQ,eAAe,KAAK,IAAc;AAGxE,QAAI,CAAC,SAAS,WAAW,QAAQ,aAAa,GAAG;AAC/C,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,MAAMD,IAAG,SAAS,UAAU,OAAO;AACnD,aAAO,EAAE,YAAY,IAAI,QAAQ;AAAA,IACnC,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,uBAAuB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QAChF,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;;;AC3CA,OAAOE,SAAQ;AACf,OAAOC,WAAU;AAGV,IAAM,gBAA6B;AAAA,EACxC,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,QAAQ,SAAS;AAAA,IAC9B;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,MAAM,SAAS;AAC3B,UAAM,WAAWA,MAAK,QAAQ,QAAQ,eAAe,KAAK,IAAc;AAExE,QAAI,CAAC,SAAS,WAAW,QAAQ,aAAa,GAAG;AAC/C,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,QAAQ,kBAAkB;AAAA,MAC/C,IAAI,SAAS,KAAK,IAAI,CAAC;AAAA,MACvB,MAAM;AAAA,MACN,aAAa,kBAAkB,KAAK,IAAI;AAAA,MACxC,SAAS,GAAI,KAAK,QAAmB,MAAM;AAAA,IAC7C,CAAC;AAED,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAEA,QAAI;AACF,YAAMD,IAAG,MAAMC,MAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,YAAMD,IAAG,UAAU,UAAU,KAAK,SAAmB,OAAO;AAC5D,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,iBAAiB,KAAK,IAAI;AAAA,MACrC;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,uBAAuB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QAChF,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;;;ACjEA,OAAOE,SAAQ;AACf,OAAOC,WAAU;AAGV,IAAM,gBAA6B;AAAA,EACxC,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,MAAM,SAAS;AAC3B,UAAM,UAAUA,MAAK;AAAA,MACnB,QAAQ;AAAA,MACP,KAAK,QAAmB;AAAA,IAC3B;AAEA,QAAI,CAAC,QAAQ,WAAW,QAAQ,aAAa,GAAG;AAC9C,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,MAAMD,IAAG,QAAQ,SAAS,EAAE,eAAe,KAAK,CAAC;AACjE,YAAM,QAAQ,QAAQ,IAAI,CAAC,MAAM;AAC/B,cAAM,SAAS,EAAE,YAAY,IAAI,MAAM;AACvC,eAAO,GAAG,EAAE,IAAI,GAAG,MAAM;AAAA,MAC3B,CAAC;AACD,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI;AAAA,MACjD;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,wBAAwB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QACjF,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;;;ACnDA,SAAS,YAAY;AAGrB,IAAM,aAAa;AAEZ,IAAM,WAAwB;AAAA,EACnC,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,MAAM,SAAS;AAC3B,UAAM,UAAU,KAAK;AAErB,UAAM,WAAW,MAAM,QAAQ,kBAAkB;AAAA,MAC/C,IAAI,QAAQ,KAAK,IAAI,CAAC;AAAA,MACtB,MAAM;AAAA,MACN,aAAa,oBAAoB,OAAO;AAAA,IAC1C,CAAC;AAED,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAEA,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B;AAAA,QACE;AAAA,QACA;AAAA,UACE,KAAK,QAAQ;AAAA,UACb,SAAS;AAAA,UACT,WAAW,OAAO,OAAO;AAAA,UACzB,OAAO,QAAQ,aAAa,UAAU,YAAY;AAAA,QACpD;AAAA,QACA,CAAC,OAAO,QAAQ,WAAW;AACzB,cAAI,SAAS;AACb,cAAI,OAAQ,WAAU;AACtB,cAAI,OAAQ,YAAW,SAAS,OAAO,MAAM,WAAW,MAAM;AAC9D,cAAI,SAAS,CAAC,QAAQ;AACpB,uBAAW,SAAS,OAAO,MAAM,UAAU,MAAM,OAAO;AAAA,UAC1D;AAEA,cAAI,OAAO,SAAS,YAAY;AAC9B,qBAAS,OAAO,MAAM,GAAG,UAAU,IAAI;AAAA,UACzC;AAEA,kBAAQ;AAAA,YACN,YAAY;AAAA,YACZ,SAAS,UAAU;AAAA,YACnB,SAAS,CAAC,CAAC;AAAA,UACb,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AClEA,IAAM,cAAc;AAEb,IAAM,eAA4B;AAAA,EACvC,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,KAAK;AAAA,UACH,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,KAAK;AAAA,IAClB;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,MAAM;AAClB,UAAM,MAAM,KAAK;AAEjB,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,SAAS;AAAA,UACP,cAAc;AAAA,UACd,QAAQ;AAAA,QACV;AAAA,QACA,QAAQ,YAAY,QAAQ,GAAM;AAAA,MACpC,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,SAAS,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU;AAAA,UACxD,SAAS;AAAA,QACX;AAAA,MACF;AAEA,UAAI,UAAU,MAAM,SAAS,KAAK;AAClC,UAAI,QAAQ,SAAS,aAAa;AAChC,kBAAU,QAAQ,MAAM,GAAG,WAAW,IAAI;AAAA,MAC5C;AAEA,aAAO,EAAE,YAAY,IAAI,QAAQ;AAAA,IACnC,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,gBAAgB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QACzE,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;;;ACpDA,IAAM,cAAc;AAEb,IAAM,gBAA6B;AAAA,EACxC,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,YAAY;AAAA,UACV,MAAM;AAAA,UACN,aAAa,gDAAgD,WAAW;AAAA,QAC1E;AAAA,MACF;AAAA,MACA,UAAU,CAAC,OAAO;AAAA,IACpB;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,MAAM;AAClB,UAAM,QAAQ,KAAK;AACnB,UAAM,aAAc,KAAK,cAAyB;AAElD,QAAI;AAEF,YAAM,MAAM,uCAAuC,mBAAmB,KAAK,CAAC;AAC5E,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,SAAS;AAAA,UACP,cACE;AAAA,UACF,QAAQ;AAAA,QACV;AAAA,QACA,QAAQ,YAAY,QAAQ,IAAM;AAAA,MACpC,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,SAAS,uBAAuB,SAAS,MAAM;AAAA,UAC/C,SAAS;AAAA,QACX;AAAA,MACF;AAEA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,UAAU,mBAAmB,MAAM,UAAU;AAEnD,UAAI,QAAQ,WAAW,GAAG;AACxB,eAAO,EAAE,YAAY,IAAI,SAAS,2BAA2B;AAAA,MAC/D;AAEA,YAAM,YAAY,QACf;AAAA,QACC,CAAC,GAAG,MACF,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK;AAAA,KAAU,EAAE,GAAG;AAAA,KAAQ,EAAE,OAAO;AAAA,MAC1D,EACC,KAAK,MAAM;AAEd,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,uBAAuB,KAAK;AAAA;AAAA,EAAS,SAAS;AAAA,MACzD;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,iBAAiB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QAC1E,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAQA,SAAS,mBAAmB,MAAc,KAA6B;AACrE,QAAM,UAA0B,CAAC;AAIjC,QAAM,eAAe,KAAK,MAAM,iBAAiB;AAEjD,WAAS,IAAI,GAAG,IAAI,aAAa,UAAU,QAAQ,SAAS,KAAK,KAAK;AACpE,UAAM,QAAQ,aAAa,CAAC;AAG5B,UAAM,aAAa,MAAM;AAAA,MACvB;AAAA,IACF;AACA,UAAM,QAAQ,aAAa,CAAC,GAAG,KAAK,KAAK;AAGzC,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,IACF;AACA,QAAI,MAAM,WAAW,CAAC,GAAG,KAAK,KAAK;AACnC,QAAI,OAAO,CAAC,IAAI,WAAW,MAAM,GAAG;AAClC,YAAM,WAAW,GAAG;AAAA,IACtB;AAGA,QAAI,CAAC,KAAK;AACR,YAAM,YAAY,MAAM,MAAM,2BAA2B;AACzD,YAAM,YAAY,CAAC,KAAK;AAAA,IAC1B;AAGA,UAAM,eAAe,MAAM;AAAA,MACzB;AAAA,IACF;AACA,QAAI,UAAU,eAAe,CAAC,GAAG,KAAK,KAAK;AAE3C,cAAU,QAAQ,QAAQ,YAAY,EAAE;AAExC,QAAI,SAAS,KAAK;AAChB,cAAQ,KAAK,EAAE,OAAO,KAAK,QAAQ,CAAC;AAAA,IACtC;AAAA,EACF;AAEA,SAAO;AACT;;;AC7HO,IAAM,oBAAiC;AAAA,EAC5C,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,aAAa;AAAA,UACX,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,UACb,OAAO;AAAA,YACL,MAAM;AAAA,YACN,YAAY;AAAA,cACV,IAAI;AAAA,gBACF,MAAM;AAAA,gBACN,aACE;AAAA,cACJ;AAAA,cACA,UAAU;AAAA,gBACR,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,MAAM;AAAA,gBACJ,MAAM;AAAA,gBACN,MAAM,CAAC,UAAU,YAAY,QAAQ,UAAU;AAAA,gBAC/C,aACE;AAAA,cACJ;AAAA,cACA,SAAS;AAAA,gBACP,MAAM;AAAA,gBACN,aACE;AAAA,gBACF,OAAO;AAAA,kBACL,MAAM;AAAA,kBACN,YAAY;AAAA,oBACV,OAAO;AAAA,sBACL,MAAM;AAAA,sBACN,aAAa;AAAA,oBACf;AAAA,oBACA,OAAO;AAAA,sBACL,MAAM;AAAA,sBACN,aAAa;AAAA,oBACf;AAAA,oBACA,aAAa;AAAA,sBACX,MAAM;AAAA,sBACN,aACE;AAAA,oBACJ;AAAA,kBACF;AAAA,kBACA,UAAU,CAAC,SAAS,OAAO;AAAA,gBAC7B;AAAA,cACF;AAAA,cACA,UAAU;AAAA,gBACR,MAAM;AAAA,gBACN,aACE;AAAA,cACJ;AAAA,cACA,aAAa;AAAA,gBACX,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,YAAY;AAAA,gBACV,MAAM;AAAA,gBACN,aACE;AAAA,cACJ;AAAA,YACF;AAAA,YACA,UAAU,CAAC,MAAM,YAAY,MAAM;AAAA,UACrC;AAAA,QACF;AAAA,MACF;AAAA,MACA,UAAU,CAAC,WAAW;AAAA,IACxB;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,MAAM,SAAS;AAC3B,UAAM,QAAS,KAAK,SAAoB;AACxC,UAAM,cAAc,KAAK;AACzB,UAAM,YAAY,KAAK;AAEvB,QAAI,CAAC,aAAa,UAAU,WAAW,GAAG;AACxC,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAGA,UAAM,YAAY,MAAM,QAAQ,qBAAqB;AAAA,MACnD,IAAI,iBAAiB,KAAK,IAAI,CAAC;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAGD,QAAI,OAAO,KAAK,SAAS,EAAE,WAAW,GAAG;AACvC,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,UAAoB,CAAC;AAC3B,eAAW,YAAY,WAAW;AAChC,YAAM,WAAW,UAAU,SAAS,EAAE;AACtC,UAAI,aAAa,QAAW;AAC1B,YAAI;AACJ,YAAI,MAAM,QAAQ,QAAQ,GAAG;AAC3B,kBAAQ,SAAS,KAAK,IAAI;AAAA,QAC5B,OAAO;AACL,kBAAQ,OAAO,QAAQ;AAAA,QACzB;AACA,gBAAQ,KAAK,KAAK,SAAS,QAAQ,OAAO,KAAK,EAAE;AAAA,MACnD;AAAA,IACF;AAEA,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS,QAAQ,KAAK,IAAI;AAAA,IAC5B;AAAA,EACF;AACF;;;ACtIA,OAAOE,SAAQ;AACf,OAAOC,WAAU;AAIjB,IAAM,cAAc;AAEpB,SAAS,cACP,OACA,SACQ;AACR,MAAI,UAAU,UAAU;AACtB,WAAOA,MAAK,KAAK,QAAQ,SAAS,WAAW;AAAA,EAC/C;AACA,SAAOA,MAAK,KAAK,QAAQ,eAAe,aAAa,WAAW;AAClE;AAEO,IAAM,iBAA8B;AAAA,EACzC,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,OAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM,CAAC,WAAW,QAAQ;AAAA,UAC1B,aACE;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,QACJ,MACA,SACqB;AACrB,UAAM,QAAS,KAAK,SAAoB;AACxC,UAAM,aAAa,cAAc,OAAO,OAAO;AAC/C,QAAI;AACF,YAAM,UAAU,MAAMD,IAAG,SAAS,YAAY,OAAO;AACrD,aAAO,EAAE,YAAY,IAAI,QAAQ;AAAA,IACnC,QAAQ;AACN,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,MAAM,KAAK;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,iBAA8B;AAAA,EACzC,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM,CAAC,WAAW,QAAQ;AAAA,UAC1B,aACE;AAAA,QACJ;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,EACF;AAAA,EACA,MAAM,QACJ,MACA,SACqB;AACrB,UAAM,UAAU,KAAK;AACrB,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,QAAS,KAAK,SAAoB;AACxC,UAAM,aAAa,cAAc,OAAO,OAAO;AAC/C,UAAMA,IAAG,MAAMC,MAAK,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5D,UAAMD,IAAG,UAAU,YAAY,SAAS,OAAO;AAC/C,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS,GAAG,UAAU,WAAW,WAAW,SAAS,kBAAkB,QAAQ,MAAM;AAAA,IACvF;AAAA,EACF;AACF;AAEO,IAAM,mBAAgC;AAAA,EAC3C,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM,CAAC,WAAW,QAAQ;AAAA,UAC1B,aACE;AAAA,QACJ;AAAA,MACF;AAAA,MACA,UAAU,CAAC,MAAM;AAAA,IACnB;AAAA,EACF;AAAA,EACA,MAAM,QACJ,MACA,SACqB;AACrB,UAAM,OAAO,KAAK;AAClB,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,QAAS,KAAK,SAAoB;AACxC,UAAM,aAAa,cAAc,OAAO,OAAO;AAC/C,UAAMA,IAAG,MAAMC,MAAK,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAE5D,QAAI,WAAW;AACf,QAAI;AACF,iBAAW,MAAMD,IAAG,SAAS,YAAY,OAAO;AAAA,IAClD,QAAQ;AACN,iBAAW,UAAU,WACjB,sFACA;AAAA,IACN;AAEA,UAAM,UAAU,SAAS,QAAQ,IAAI,SAAS,OAAO;AACrD,UAAMA,IAAG,UAAU,YAAY,SAAS,OAAO;AAC/C,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS,oBAAoB,KAAK;AAAA,IACpC;AAAA,EACF;AACF;;;AC1JA,OAAOE,SAAQ;AACf,OAAOC,WAAU;AAGV,IAAM,eAA4B;AAAA,EACvC,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,MAAM;AAAA,IACnB;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,MAAM,SAAS;AAC3B,UAAM,WAAWA,MAAK,QAAQ,QAAQ,eAAe,KAAK,IAAc;AAExE,QAAI,CAAC,SAAS,WAAW,QAAQ,aAAa,GAAG;AAC/C,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAEA,QAAI;AACF,YAAM,OAAO,MAAMD,IAAG,KAAK,QAAQ;AACnC,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,KAAK,UAAU;AAAA,UACtB,WAAW;AAAA,UACX,MAAM,KAAK;AAAA,UACX,MAAM,KAAK;AAAA,UACX,OAAQ,KAAK,SAAoB;AAAA,QACnC,CAAC;AAAA,MACH;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,gCAA2B,KAAK,IAAI;AAAA,QAC7C,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;;;ACtDA,OAAOE,WAAU;AACjB,OAAOC,SAAQ;AACf,OAAO,cAAc;;;ACFrB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAOjB,IAAM,eAAe;AACrB,IAAM,WAAW;AAMjB,eAAsB,cAAc,UAAwC;AAC1E,QAAM,MAAMA,MAAK,QAAQ,QAAQ,EAAE,YAAY;AAE/C,UAAQ,KAAK;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AACH,aAAO,SAAS,UAAU,QAAQ,SAAS,MAAO,MAAS;AAAA,IAC7D,KAAK;AACH,aAAO,UAAU,QAAQ;AAAA,IAC3B,KAAK;AACH,aAAO,UAAU,QAAQ;AAAA,IAC3B;AACE,YAAM,IAAI;AAAA,QACR,0BAA0B,GAAG;AAAA,MAC/B;AAAA,EACJ;AACF;AAKO,SAAS,kBACd,MACoC;AACpC,SAAO,KAAK,QAAQ,IAAI,CAAC,GAAG,WAAW;AACrC,UAAM,SAAS,KAAK,KACjB,MAAM,GAAG,GAAG,EACZ,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,EAAE,EAC1B,OAAO,CAAC,MAAM,MAAM,EAAE;AAEzB,QAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAI,OAAO,MAAM,CAAC,MAAM,UAAU,KAAK,CAAC,CAAC,EAAG,QAAO;AACnD,QAAI,OAAO,MAAM,CAAC,MAAM,kBAAkB,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,CAAC;AACjE,aAAO;AACT,WAAO;AAAA,EACT,CAAC;AACH;AAMA,SAAS,SAAS,UAAkB,gBAAsC;AACxE,MAAI,MAAMD,IAAG,aAAa,UAAU,OAAO;AAC3C,MAAI,IAAI,SAAS,cAAc;AAC7B,UAAM,IAAI,MAAM,GAAG,YAAY;AAE/B,UAAM,cAAc,IAAI,YAAY,IAAI;AACxC,QAAI,cAAc,EAAG,OAAM,IAAI,MAAM,GAAG,WAAW;AAAA,EACrD;AAGA,MAAI,IAAI,WAAW,QAAQ,EAAG,OAAM,IAAI,MAAM,CAAC;AAC/C,QAAM,IAAI,QAAQ,SAAS,IAAI,EAAE,QAAQ,OAAO,IAAI;AAGpD,QAAM,YAAY,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK;AACxC,MAAI,YAAY,kBAAkB;AAClC,MAAI,CAAC,gBAAgB;AACnB,UAAM,QAAQ,UAAU,MAAM,KAAK,KAAK,CAAC,GAAG;AAC5C,UAAM,cAAc,UAAU,MAAM,IAAI,KAAK,CAAC,GAAG;AACjD,UAAM,UAAU,UAAU,MAAM,IAAI,KAAK,CAAC,GAAG;AAC7C,QAAI,OAAO,UAAU,OAAO,WAAY,aAAY;AAAA,aAC3C,aAAa,OAAQ,aAAY;AAAA,EAC5C;AAEA,QAAM,QAAQ,cAAc,KAAK,SAAS;AAC1C,MAAI,MAAM,WAAW,EAAG,QAAO,EAAE,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE;AAEvD,QAAM,UAAU,MAAM,CAAC;AACvB,QAAM,OAAO,MAAM,MAAM,GAAG,WAAW,CAAC;AACxC,SAAO,EAAE,SAAS,KAAK;AACzB;AAEA,SAAS,cAAc,MAAc,WAA+B;AAClE,QAAM,SAAqB,CAAC;AAC5B,MAAI,UAAoB,CAAC;AACzB,MAAI,QAAQ;AACZ,MAAI,WAAW;AAEf,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,KAAK,KAAK,CAAC;AACjB,QAAI,UAAU;AACZ,UAAI,OAAO,KAAK;AACd,YAAI,KAAK,IAAI,CAAC,MAAM,KAAK;AACvB,mBAAS;AACT;AAAA,QACF,OAAO;AACL,qBAAW;AAAA,QACb;AAAA,MACF,OAAO;AACL,iBAAS;AAAA,MACX;AAAA,IACF,OAAO;AACL,UAAI,OAAO,KAAK;AACd,mBAAW;AAAA,MACb,WAAW,OAAO,WAAW;AAC3B,gBAAQ,KAAK,MAAM,KAAK,CAAC;AACzB,gBAAQ;AAAA,MACV,WAAW,OAAO,MAAM;AACtB,gBAAQ,KAAK,MAAM,KAAK,CAAC;AACzB,YAAI,QAAQ,SAAS,KAAK,QAAQ,CAAC,MAAM,IAAI;AAC3C,iBAAO,KAAK,OAAO;AAAA,QACrB;AACA,kBAAU,CAAC;AACX,gBAAQ;AAAA,MACV,OAAO;AACL,iBAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAGA,UAAQ,KAAK,MAAM,KAAK,CAAC;AACzB,MAAI,QAAQ,SAAS,KAAK,QAAQ,CAAC,MAAM,IAAI;AAC3C,WAAO,KAAK,OAAO;AAAA,EACrB;AAEA,SAAO;AACT;AAMA,SAAS,UAAU,UAA+B;AAChD,MAAI,MAAMA,IAAG,aAAa,UAAU,OAAO;AAC3C,MAAI,IAAI,SAAS,cAAc;AAC7B,UAAM,IAAI;AAAA,MACR,yBAAyB,IAAI,SAAS,MAAM,QAAQ,CAAC,CAAC,WAAW,eAAe,IAAI;AAAA,IAEtF;AAAA,EACF;AAEA,QAAM,SAAS,KAAK,MAAM,GAAG;AAE7B,MAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,WAAW,EAAG,QAAO,EAAE,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE;AAGxD,QAAM,SAAS,oBAAI,IAAY;AAC/B,aAAW,OAAO,OAAO,MAAM,GAAG,GAAI,GAAG;AACvC,QAAI,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG,GAAG;AACzD,iBAAW,OAAO,OAAO,KAAK,GAAG,EAAG,QAAO,IAAI,GAAG;AAAA,IACpD;AAAA,EACF;AACA,QAAM,UAAU,MAAM,KAAK,MAAM;AAEjC,QAAM,OAAmB,CAAC;AAC1B,aAAW,OAAO,OAAO,MAAM,GAAG,QAAQ,GAAG;AAC3C,QAAI,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG,GAAG;AACzD,WAAK;AAAA,QACH,QAAQ,IAAI,CAAC,MAAM;AACjB,gBAAM,MAAM,IAAI,CAAC;AACjB,cAAI,QAAQ,QAAQ,QAAQ,OAAW,QAAO;AAC9C,cAAI,OAAO,QAAQ,SAAU,QAAO,KAAK,UAAU,GAAG;AACtD,iBAAO,OAAO,GAAG;AAAA,QACnB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,KAAK;AACzB;AAMA,eAAe,UAAU,UAAwC;AAC/D,QAAM,UAAU,MAAM,OAAO,SAAS;AACtC,QAAM,WAAW,IAAI,QAAQ,QAAQ,SAAS;AAC9C,QAAM,SAAS,KAAK,SAAS,QAAQ;AAErC,QAAM,YAAY,SAAS,WAAW,CAAC;AACvC,MAAI,CAAC,aAAa,UAAU,aAAa,GAAG;AAC1C,WAAO,EAAE,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE;AAAA,EACjC;AAEA,QAAM,UAAoB,CAAC;AAC3B,QAAM,WAAW,UAAU,OAAO,CAAC;AACnC,WAAS,SAAS,EAAE,cAAc,KAAK,GAAG,CAAC,MAAM,cAAc;AAC7D,WAAO,QAAQ,SAAS,YAAY,EAAG,SAAQ,KAAK,EAAE;AACtD,YAAQ,KAAK,OAAO,KAAK,SAAS,EAAE,CAAC;AAAA,EACvC,CAAC;AAED,QAAM,OAAmB,CAAC;AAC1B,QAAM,SAAS,KAAK,IAAI,UAAU,UAAU,WAAW,CAAC;AAExD,WAAS,SAAS,GAAG,UAAU,QAAQ,UAAU;AAC/C,UAAM,MAAM,UAAU,OAAO,MAAM;AACnC,UAAM,SAAmB,CAAC;AAC1B,QAAI,WAAW;AAEf,aAAS,SAAS,GAAG,SAAS,QAAQ,QAAQ,UAAU;AACtD,YAAM,OAAO,IAAI,QAAQ,SAAS,CAAC;AACnC,YAAM,MAAM,KAAK;AACjB,UAAI,QAAQ,QAAQ,QAAQ,OAAW,YAAW;AAElD,UAAI,QAAQ,QAAQ,QAAQ,QAAW;AACrC,eAAO,KAAK,EAAE;AAAA,MAChB,WAAW,eAAe,MAAM;AAC9B,eAAO,KAAK,IAAI,YAAY,CAAC;AAAA,MAC/B,WAAW,OAAO,QAAQ,UAAU;AAElC,cAAM,SAAU,IAA6B;AAC7C,cAAM,OAAQ,IAA2B;AACzC,eAAO,KAAK,OAAO,UAAU,QAAQ,KAAK,UAAU,GAAG,CAAC,CAAC;AAAA,MAC3D,OAAO;AACL,eAAO,KAAK,OAAO,GAAG,CAAC;AAAA,MACzB;AAAA,IACF;AAEA,QAAI,SAAU,MAAK,KAAK,MAAM;AAAA,EAChC;AAEA,SAAO,EAAE,SAAS,KAAK;AACzB;;;ADlOA,IAAM,iBAAiB;AAEhB,IAAM,eAA4B;AAAA,EACvC,YAAY;AAAA,IACV,MAAM;AAAA,IACN,aACE;AAAA,IAIF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,MAAM,CAAC,WAAW,OAAO;AAAA,UACzB,aAAa;AAAA,QACf;AAAA,QACA,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,QACA,KAAK;AAAA,UACH,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,MACF;AAAA,MACA,UAAU,CAAC,UAAU,MAAM;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,MAAM,QACJ,MACA,SACqB;AACrB,UAAM,SAAS,KAAK;AACpB,UAAM,UAAU,KAAK;AAErB,QAAI,CAAC,UAAU,CAAC,SAAS;AACvB,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAGA,UAAM,WAAWE,MAAK,WAAW,OAAO,IACpC,UACAA,MAAK,QAAQ,QAAQ,eAAe,OAAO;AAG/C,QAAI,CAAC,SAAS,WAAW,QAAQ,aAAa,GAAG;AAC/C,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAEA,QAAI,CAACC,IAAG,WAAW,QAAQ,GAAG;AAC5B,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,mBAAmB,OAAO;AAAA,QACnC,SAAS;AAAA,MACX;AAAA,IACF;AAEA,QAAI;AACF,cAAQ,QAAQ;AAAA,QACd,KAAK;AACH,iBAAO,MAAM,cAAc,QAAQ;AAAA,QACrC,KAAK;AACH,iBAAO,MAAM,YAAY,UAAU,KAAK,GAAa;AAAA,QACvD;AACE,iBAAO;AAAA,YACL,YAAY;AAAA,YACZ,SAAS,mBAAmB,MAAM;AAAA,YAClC,SAAS;AAAA,UACX;AAAA,MACJ;AAAA,IACF,SAAS,KAAK;AACZ,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QACnE,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAMA,eAAe,cAAc,UAAuC;AAClE,QAAM,OAAO,MAAM,cAAc,QAAQ;AACzC,QAAM,QAAQ,kBAAkB,IAAI;AACpC,QAAM,WAAWD,MAAK,SAAS,QAAQ;AACvC,QAAM,MAAMA,MAAK,QAAQ,QAAQ,EAAE,YAAY,EAAE,MAAM,CAAC;AAExD,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,SAAS,QAAQ,KAAK,IAAI,YAAY,CAAC,GAAG;AACrD,QAAM,KAAK,SAAS,KAAK,KAAK,MAAM,EAAE;AACtC,QAAM,KAAK,YAAY,KAAK,QAAQ,MAAM,EAAE;AAC5C,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,0CAA0C;AACrD,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK;AAC5C,UAAM,KAAK,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,GAAG;AAAA,EACnD;AAGA,MAAI,KAAK,KAAK,SAAS,GAAG;AACxB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,wBAAwB;AACnC,UAAM,aAAa,KAAK,KAAK,MAAM,GAAG,CAAC;AACvC,eAAW,OAAO,YAAY;AAC5B,YAAM,QAAQ,KAAK,QAChB,IAAI,CAAC,GAAG,MAAM;AACb,cAAM,MAAM,IAAI,CAAC,KAAK;AACtB,eAAO,GAAG,CAAC,KAAK,IAAI,SAAS,KAAK,IAAI,MAAM,GAAG,EAAE,IAAI,WAAM,GAAG;AAAA,MAChE,CAAC,EACA,KAAK,KAAK;AACb,YAAM,KAAK,KAAK,KAAK,EAAE;AAAA,IACzB;AAAA,EACF;AAEA,SAAO,EAAE,YAAY,IAAI,SAAS,MAAM,KAAK,IAAI,EAAE;AACrD;AAMA,eAAe,YACb,UACA,KACqB;AACrB,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SACE;AAAA,MACF,SAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,OAAO,MAAM,cAAc,QAAQ;AAEzC,MAAI,KAAK,QAAQ,WAAW,GAAG;AAC7B,WAAO,EAAE,YAAY,IAAI,SAAS,wBAAwB,SAAS,KAAK;AAAA,EAC1E;AAEA,QAAM,KAAK,IAAI,SAAS,UAAU;AAElC,MAAI;AACF,gBAAY,IAAI,IAAI;AACpB,eAAW,IAAI,IAAI;AAEnB,UAAM,OAAO,GAAG,QAAQ,GAAG;AAG3B,QAAI,KAAK,QAAQ;AACf,YAAM,OAAO,KAAK,IAAI;AACtB,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,mBAAmB,IAAI;AAAA,MAClC;AAAA,IACF,OAAO;AACL,YAAM,OAAO,KAAK,IAAI;AACtB,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,gCAAgC,KAAK,OAAO;AAAA,MACvD;AAAA,IACF;AAAA,EACF,UAAE;AACA,OAAG,MAAM;AAAA,EACX;AACF;AAEA,SAAS,YAAY,MAAsB;AAEzC,SAAO,IAAI,KAAK,QAAQ,MAAM,IAAI,CAAC;AACrC;AAEA,SAAS,YAAY,IAAuB,MAAyB;AACnE,QAAM,QAAQ,kBAAkB,IAAI;AACpC,QAAM,UAAU,KAAK,QAClB,IAAI,CAAC,GAAG,MAAM,GAAG,YAAY,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,EAC7C,KAAK,IAAI;AAEZ,KAAG,KAAK,sBAAsB,OAAO,GAAG;AAC1C;AAEA,SAAS,WAAW,IAAuB,MAAyB;AAClE,QAAM,QAAQ,kBAAkB,IAAI;AACpC,QAAM,eAAe,KAAK,QAAQ,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI;AAC1D,QAAM,SAAS,GAAG,QAAQ,4BAA4B,YAAY,GAAG;AAErE,QAAM,aAAa,GAAG,YAAY,CAAC,SAAqB;AACtD,eAAW,OAAO,MAAM;AACtB,YAAM,SAAS,IAAI,IAAI,CAAC,KAAK,MAAM;AACjC,YAAI,QAAQ,GAAI,QAAO;AACvB,YAAI,MAAM,CAAC,MAAM,WAAW;AAC1B,gBAAM,IAAI,SAAS,KAAK,EAAE;AAC1B,iBAAO,MAAM,CAAC,IAAI,MAAM;AAAA,QAC1B;AACA,YAAI,MAAM,CAAC,MAAM,QAAQ;AACvB,gBAAM,IAAI,WAAW,IAAI,QAAQ,KAAK,GAAG,CAAC;AAC1C,iBAAO,MAAM,CAAC,IAAI,MAAM;AAAA,QAC1B;AACA,eAAO;AAAA,MACT,CAAC;AACD,aAAO,IAAI,GAAG,MAAM;AAAA,IACtB;AAAA,EACF,CAAC;AAED,aAAW,KAAK,IAAI;AACtB;AAEA,SAAS,mBAAmB,MAAyC;AACnE,MAAI,KAAK,WAAW,EAAG,QAAO;AAE9B,QAAM,UAAU,KAAK,MAAM,GAAG,cAAc;AAC5C,QAAM,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC;AAGnC,QAAM,YAAY,KAAK,IAAI,CAAC,MAAM;AAChC,UAAM,SAAS,QAAQ,OAAO,CAAC,KAAK,QAAQ;AAC1C,YAAM,MAAM,OAAO,IAAI,CAAC,KAAK,EAAE;AAC/B,aAAO,KAAK,IAAI,KAAK,IAAI,MAAM;AAAA,IACjC,GAAG,EAAE,MAAM;AACX,WAAO,KAAK,IAAI,QAAQ,EAAE;AAAA,EAC5B,CAAC;AAED,QAAM,SAAS,KACZ,IAAI,CAAC,GAAG,MAAM,EAAE,OAAO,UAAU,CAAC,CAAC,CAAC,EACpC,KAAK,KAAK;AACb,QAAM,YAAY,UAAU,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,KAAK;AAChE,QAAM,OAAO,QAAQ;AAAA,IAAI,CAAC,QACxB,KACG,IAAI,CAAC,GAAG,MAAM;AACb,YAAM,MAAM,OAAO,IAAI,CAAC,KAAK,EAAE;AAC/B,cAAQ,IAAI,SAAS,KAAK,IAAI,MAAM,GAAG,EAAE,IAAI,WAAM,KAAK;AAAA,QACtD,UAAU,CAAC;AAAA,MACb;AAAA,IACF,CAAC,EACA,KAAK,KAAK;AAAA,EACf;AAEA,QAAM,QAAQ,CAAC,QAAQ,WAAW,GAAG,IAAI;AAEzC,MAAI,KAAK,SAAS,gBAAgB;AAChC,UAAM,KAAK;AAAA,OAAU,KAAK,SAAS,cAAc,uBAAuB;AAAA,EAC1E;AAEA,QAAM,KAAK;AAAA,EAAK,KAAK,MAAM,SAAS;AAEpC,SAAO,MAAM,KAAK,IAAI;AACxB;;;AElRA,SAAS,YAAY;AAOd,SAAS,mBACd,UACA,MAAc,KAAK,IAAI,GACR;AACf,UAAQ,SAAS,MAAM;AAAA,IACrB,KAAK,MAAM;AACT,YAAM,SAAS,IAAI,KAAK,SAAS,QAAQ,EAAE,QAAQ;AACnD,aAAO,SAAS,MAAM,SAAS;AAAA,IACjC;AAAA,IACA,KAAK,SAAS;AAEZ,YAAM,WAAW,SAAS;AAC1B,UAAI,YAAY,EAAG,QAAO;AAC1B,aAAO,MAAM;AAAA,IACf;AAAA,IACA,KAAK,QAAQ;AACX,UAAI;AACF,cAAM,MAAM,IAAI,KAAK,SAAS,YAAY;AAAA,UACxC,UAAU,SAAS;AAAA,QACrB,CAAC;AACD,cAAM,OAAO,IAAI,QAAQ;AACzB,eAAO,OAAO,KAAK,QAAQ,IAAI;AAAA,MACjC,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA;AACE,aAAO;AAAA,EACX;AACF;AAKO,SAAS,iBAAiB,YAAmC;AAClE,MAAI;AACF,QAAI,KAAK,UAAU;AACnB,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,WAAO,eAAe,QAAQ,IAAI,UAAU;AAAA,EAC9C;AACF;;;ACtCO,SAAS,eAAe,aAAuC;AACpE,SAAO;AAAA,IACL,YAAY;AAAA,MACV,MAAM;AAAA,MACN,aACE;AAAA,MACF,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,aAAa;AAAA,YACb,MAAM,CAAC,QAAQ,UAAU,UAAU,UAAU,SAAS;AAAA,UACxD;AAAA,UACA,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,eAAe;AAAA,YACb,MAAM;AAAA,YACN,aAAa;AAAA,YACb,MAAM,CAAC,MAAM,SAAS,MAAM;AAAA,UAC9B;AAAA,UACA,gBAAgB;AAAA,YACd,MAAM;AAAA,YACN,aACE;AAAA,UACJ;AAAA,UACA,UAAU;AAAA,YACR,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,SAAS;AAAA,YACP,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,kBAAkB;AAAA,YAChB,MAAM;AAAA,YACN,aACE;AAAA,UACJ;AAAA,UACA,iBAAiB;AAAA,YACf,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,QACF;AAAA,QACA,UAAU,CAAC,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,IAEA,SAAS,OACP,MACA,aACwB;AACxB,YAAM,SAAS,KAAK;AAEpB,UAAI;AACF,gBAAQ,QAAQ;AAAA,UACd,KAAK,QAAQ;AACX,kBAAM,OAAO,YAAY,KAAK;AAC9B,gBAAI,KAAK,WAAW,GAAG;AACrB,qBAAO,EAAE,YAAY,IAAI,SAAS,sBAAsB;AAAA,YAC1D;AACA,kBAAM,QAAQ,KAAK,IAAI,CAAC,MAAM;AAC5B,oBAAM,QAAQ,YAAY,SAAS,EAAE,EAAE;AACvC,oBAAM,UAAU,OAAO,cACnB,IAAI,KAAK,MAAM,WAAW,EAAE,YAAY,IACxC;AACJ,oBAAM,SAAS,EAAE,UAAU,YAAY;AACvC,qBAAO,OAAO,EAAE,IAAI,OAAO,EAAE,EAAE;AAAA,YAAgB,MAAM,YAAY,OAAO,gBAAgB,KAAK,UAAU,EAAE,QAAQ,CAAC;AAAA,YAAe,EAAE,OAAO,MAAM,GAAG,GAAG,CAAC;AAAA,YACzJ,CAAC;AACD,mBAAO,EAAE,YAAY,IAAI,SAAS,MAAM,KAAK,MAAM,EAAE;AAAA,UACvD;AAAA,UAEA,KAAK,UAAU;AACb,kBAAM,OAAO,KAAK;AAClB,kBAAM,SAAS,KAAK;AACpB,gBAAI,CAAC,QAAQ,CAAC,QAAQ;AACpB,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AAEA,kBAAM,WAAW,cAAc,IAAI;AACnC,gBAAI,OAAO,aAAa,UAAU;AAChC,qBAAO,EAAE,YAAY,IAAI,SAAS,UAAU,SAAS,KAAK;AAAA,YAC5D;AAEA,kBAAM,WAAW,cAAc,IAAI;AACnC,kBAAM,MAAM,YAAY,IAAI;AAAA,cAC1B;AAAA,cACA;AAAA,cACA;AAAA,cACA,SAAU,KAAK,WAAuB;AAAA,cACtC;AAAA,YACF,CAAC;AAED,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,sBAAsB,IAAI,IAAI,MAAM,IAAI,EAAE;AAAA,YAAgB,KAAK,UAAU,IAAI,QAAQ,CAAC;AAAA,YACjG;AAAA,UACF;AAAA,UAEA,KAAK,UAAU;AACb,kBAAM,QAAQ,KAAK;AACnB,gBAAI,CAAC,OAAO;AACV,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AAEA,kBAAM,UAAmC,CAAC;AAC1C,gBAAI,KAAK,KAAM,SAAQ,OAAO,KAAK;AACnC,gBAAI,KAAK,OAAQ,SAAQ,SAAS,KAAK;AACvC,gBAAI,KAAK,YAAY,OAAW,SAAQ,UAAU,KAAK;AACvD,gBAAI,KAAK,oBAAoB,KAAK,iBAAiB;AACjD,sBAAQ,WAAW,cAAc,IAAI;AAAA,YACvC;AACA,gBAAI,KAAK,eAAe;AACtB,oBAAM,WAAW,cAAc,IAAI;AACnC,kBAAI,OAAO,aAAa,UAAU;AAChC,uBAAO,EAAE,YAAY,IAAI,SAAS,UAAU,SAAS,KAAK;AAAA,cAC5D;AACA,sBAAQ,WAAW;AAAA,YACrB;AAEA,kBAAM,UAAU,YAAY,OAAO,OAAO,OAAO;AACjD,gBAAI,CAAC,SAAS;AACZ,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS,OAAO,KAAK;AAAA,gBACrB,SAAS;AAAA,cACX;AAAA,YACF;AAEA,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,QAAQ,QAAQ,IAAI;AAAA,YAC/B;AAAA,UACF;AAAA,UAEA,KAAK,UAAU;AACb,kBAAM,QAAQ,KAAK;AACnB,gBAAI,CAAC,OAAO;AACV,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AACA,kBAAM,UAAU,YAAY,OAAO,KAAK;AACxC,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,UACL,OAAO,KAAK,cACZ,OAAO,KAAK;AAAA,YAClB;AAAA,UACF;AAAA,UAEA,KAAK,WAAW;AACd,kBAAM,QAAQ,KAAK;AACnB,gBAAI,CAAC,OAAO;AACV,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AACA,kBAAM,YAAY,OAAO,KAAK;AAC9B,mBAAO,EAAE,YAAY,IAAI,SAAS,OAAO,KAAK,aAAa;AAAA,UAC7D;AAAA,UAEA;AACE,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,mBAAmB,MAAM;AAAA,cAClC,SAAS;AAAA,YACX;AAAA,QACJ;AAAA,MACF,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,SAAS,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UACxE,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,cAAc,MAA6C;AAClE,SAAO;AAAA,IACL,SAAU,KAAK,oBAA+B;AAAA,IAC9C,QAAS,KAAK,mBAA8B;AAAA,EAC9C;AACF;AAEA,SAAS,cACP,MACuB;AACvB,QAAM,OAAO,KAAK;AAClB,QAAM,QAAQ,KAAK;AAEnB,MAAI,CAAC,QAAQ,CAAC,OAAO;AACnB,WAAO;AAAA,EACT;AAEA,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,EAAE,MAAM,MAAM,UAAU,MAAM;AAAA,IACvC,KAAK,SAAS;AACZ,YAAM,KAAK,SAAS,OAAO,EAAE;AAC7B,UAAI,MAAM,EAAE,KAAK,MAAM,EAAG,QAAO;AACjC,aAAO,EAAE,MAAM,SAAS,YAAY,GAAG;AAAA,IACzC;AAAA,IACA,KAAK,QAAQ;AACX,YAAM,MAAM,iBAAiB,KAAK;AAClC,UAAI,IAAK,QAAO,4BAA4B,GAAG;AAC/C,aAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,UAAW,KAAK,YAAuB;AAAA,MACzC;AAAA,IACF;AAAA,IACA;AACE,aAAO,0BAA0B,IAAI;AAAA,EACzC;AACF;;;ACzPA,OAAOE,SAAQ;AACf,OAAOC,WAAU;AAQV,SAAS,mBAAmB,eAA2C;AAC5E,SAAO;AAAA,IACL,YAAY;AAAA,MACV,MAAM;AAAA,MACN,aACE;AAAA,MACF,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,aAAa;AAAA,YACb,MAAM,CAAC,QAAQ,OAAO,QAAQ,OAAO,MAAM;AAAA,UAC7C;AAAA,UACA,OAAO;AAAA,YACL,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,SAAS;AAAA,YACP,MAAM;AAAA,YACN,aACE;AAAA,UACJ;AAAA,UACA,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,aACE;AAAA,UACJ;AAAA,QACF;AAAA,QACA,UAAU,CAAC,QAAQ,OAAO;AAAA,MAC5B;AAAA,IACF;AAAA,IAEA,SAAS,OACP,MACA,YACwB;AACxB,YAAM,OAAO,KAAK;AAClB,YAAM,QAAQ,KAAK;AACnB,YAAM,WAAW,KAAK;AACtB,UAAI,UAAU,KAAK;AAEnB,UAAI,CAAC,QAAQ,CAAC,OAAO;AACnB,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF;AAGA,UAAI,UAAU;AACZ,cAAM,WAAWA,MAAK,QAAQ,QAAQ,eAAe,QAAQ;AAC7D,YAAI,CAAC,SAAS,WAAW,QAAQ,aAAa,GAAG;AAC/C,iBAAO;AAAA,YACL,YAAY;AAAA,YACZ,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,QACF;AACA,YAAI;AACF,oBAAU,MAAMD,IAAG,SAAS,UAAU,OAAO;AAAA,QAC/C,QAAQ;AACN,iBAAO;AAAA,YACL,YAAY;AAAA,YACZ,SAAS,gCAA2B,QAAQ;AAAA,YAC5C,SAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,SAAS;AACZ,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF;AAEA,UAAI;AACF,cAAM,WAAW,cAAc,OAAO,MAAM,OAAO,OAAO;AAC1D,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,SAAS,KAAK,UAAU;AAAA,YACtB,YAAY,SAAS;AAAA,YACrB,MAAM,SAAS;AAAA,YACf,OAAO,SAAS;AAAA,YAChB,UAAU,SAAS;AAAA,UACrB,CAAC;AAAA,QACH;AAAA,MACF,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,SAAS,mBAAmB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UAC5E,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACxGA,SAAS,gBAAgB;AACzB,SAAS,YAAY,iBAAiB;AACtC,SAAS,YAAY;AACrB,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAE9B,IAAM,kBAAkB;AAExB,SAAS,mBAAkC;AACzC,QAAM,WAAW,QAAQ;AACzB,QAAM,OAAO,QAAQ;AACrB,MAAI,aAAa,WAAW,SAAS,MAAO,QAAO;AACnD,MAAI,aAAa,YAAY,SAAS,QAAS,QAAO;AACtD,MAAI,aAAa,YAAY,SAAS,MAAO,QAAO;AACpD,MAAI,aAAa,WAAW,SAAS,QAAS,QAAO;AACrD,MAAI,aAAa,WAAW,SAAS,MAAO,QAAO;AACnD,SAAO;AACT;AAEA,SAAS,aAAqB;AAC5B,QAAM,YAAY,iBAAiB;AAInC,QAAM,gBAAiB,QAAgB;AACvC,MAAI,iBAAiB,WAAW;AAC9B,UAAM,YAAY,KAAK,eAAe,iBAAiB,SAAS;AAChE,QAAI,WAAW,SAAS,EAAG,QAAO;AAAA,EACpC;AAEA,MAAI;AACF,UAAME,WAAU,cAAc,YAAY,GAAG;AAC7C,QAAI,WAAW;AACb,UAAI;AACF,eAAOA,SAAQ,QAAQ,qBAAqB,SAAS,EAAE;AAAA,MACzD,QAAQ;AAAA,MAER;AAAA,IACF;AACA,WAAOA,SAAQ,QAAQ,oCAAoC;AAAA,EAC7D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,MAAM,WAAW;AAkBvB,IAAI,WAAmC;AAEvC,SAAS,yBAAiC;AACxC,MAAI,CAAC,QAAQ,IAAI,oBAAoB;AACnC,UAAM,MAAM,KAAK,QAAQ,GAAG,gBAAgB;AAC5C,QAAI,CAAC,WAAW,GAAG,EAAG,WAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAExD,YAAQ,IAAI,qBAAqB;AAAA,EACnC;AACA,SAAO,QAAQ,IAAI;AACrB;AAGA,uBAAuB;AAEvB,SAASC,MAAK,MAAgB,UAAU,iBAAkC;AACxE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,WAAW,IAAI,SAAS,KAAK;AACnC,UAAM,MAAM,WAAY,QAAQ,IAAI,iBAAiB,QAAQ,WAAY;AACzE,UAAM,YAAY,WAAW,CAAC,KAAK,GAAG,IAAI,IAAI;AAE9C,UAAM,MAAM,EAAE,GAAG,QAAQ,IAAI;AAC7B,WAAO,IAAI;AACX,UAAM,MAAM,uBAAuB;AACnC,aAAS,KAAK,WAAW,EAAE,SAAS,WAAW,IAAI,OAAO,MAAM,KAAK,IAAI,GAAG,CAAC,KAAK,QAAQ,WAAW;AACnG,UAAI,KAAK;AACP,cAAM,MAAM,QAAQ,KAAK,KAAK,QAAQ,KAAK,KAAK,IAAI;AACpD,eAAO,IAAI,MAAM,GAAG,CAAC;AAAA,MACvB,OAAO;AACL,gBAAQ,MAAM;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AAWA,IAAI,aAAa;AAEjB,eAAsB,kBAAiC;AACrD,MAAI,WAAY;AAChB,MAAI;AACF,UAAMC,MAAK,CAAC,WAAW,GAAG,GAAI;AAAA,EAChC,QAAQ;AACN,UAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AAEA,MAAI;AACF,UAAMA,MAAK,CAAC,SAAS,GAAG,IAAO;AAAA,EACjC,QAAQ;AAAA,EAER;AAEA,QAAMA,MAAK,CAAC,OAAO,GAAG,GAAI,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AAC1C,eAAa;AACf;AAEA,eAAsB,gBAA0C;AAC9D,MAAI,SAAU,QAAO;AACrB,QAAM,gBAAgB;AAEtB,QAAM,OAAwB;AAAA,IAC5B,MAAM,IAAI,MAAgB;AACxB,aAAOA,MAAK,IAAI;AAAA,IAClB;AAAA,IAEA,MAAM,SAAS,KAAa;AAC1B,YAAMA,MAAK,CAAC,QAAQ,KAAK,UAAU,CAAC;AACpC,YAAMA,MAAK,CAAC,QAAQ,UAAU,kBAAkB,CAAC;AACjD,YAAM,WAAW,MAAMA,MAAK,CAAC,OAAO,OAAO,CAAC;AAC5C,YAAM,SAAS,MAAMA,MAAK,CAAC,OAAO,KAAK,CAAC;AACxC,YAAM,UAAU,MAAMA,MAAK,CAAC,YAAY,MAAM,IAAI,CAAC;AACnD,aAAO;AAAA,QACL,OAAO,SAAS,KAAK;AAAA,QACrB,KAAK,OAAO,KAAK;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,SAAS,cAAc,MAAM;AACjC,YAAM,OAAO,CAAC,UAAU;AACxB,UAAI,YAAa,MAAK,KAAK,IAAI;AAC/B,WAAK,KAAK,IAAI;AACd,aAAOA,MAAK,IAAI;AAAA,IAClB;AAAA,IAEA,MAAM,aAAa;AACjB,YAAM,UAAU,GAAG,QAAQ,IAAI,QAAQ,MAAM,kBAAkB,KAAK,IAAI,CAAC;AACzE,YAAMA,MAAK,CAAC,cAAc,OAAO,CAAC;AAClC,YAAMC,OAAK,MAAM,OAAO,aAAkB;AAC1C,YAAM,MAAM,MAAMA,KAAG,SAAS,OAAO;AACrC,YAAMA,KAAG,OAAO,OAAO,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACvC,aAAO;AAAA,IACT;AAAA,IAEA,MAAM,MAAM,UAAkB;AAC5B,YAAMD,MAAK,CAAC,SAAS,QAAQ,CAAC;AAAA,IAChC;AAAA,IAEA,MAAM,KAAK,UAAkB,MAAc;AACzC,YAAMA,MAAK,CAAC,QAAQ,UAAU,IAAI,CAAC;AAAA,IACrC;AAAA,IAEA,MAAM,KAAK,UAAkB,MAAc;AACzC,YAAMA,MAAK,CAAC,QAAQ,UAAU,IAAI,CAAC;AAAA,IACrC;AAAA,IAEA,MAAM,SAAS,QAAgB;AAC7B,aAAOA,MAAK,CAAC,QAAQ,MAAM,CAAC;AAAA,IAC9B;AAAA,IAEA,MAAM,aAAa;AACjB,YAAM,WAAW,MAAMA,MAAK,CAAC,OAAO,OAAO,CAAC;AAC5C,YAAM,SAAS,MAAMA,MAAK,CAAC,OAAO,KAAK,CAAC;AACxC,YAAM,UAAU,MAAMA,MAAK,CAAC,YAAY,MAAM,IAAI,CAAC;AACnD,aAAO;AAAA,QACL,OAAO,SAAS,KAAK;AAAA,QACrB,KAAK,OAAO,KAAK;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,OAAO,UAAkB,OAAe;AAC5C,YAAMA,MAAK,CAAC,UAAU,UAAU,KAAK,CAAC;AAAA,IACxC;AAAA,IAEA,MAAM,MAAM,KAAa;AACvB,YAAMA,MAAK,CAAC,SAAS,GAAG,CAAC;AAAA,IAC3B;AAAA,IAEA,MAAM,KAAK,QAAgB;AACzB,UAAI,OAAO,WAAW,MAAM,GAAG;AAC7B,cAAMA,MAAK,CAAC,QAAQ,SAAS,MAAM,CAAC;AAAA,MACtC,OAAO;AACL,cAAMA,MAAK,CAAC,QAAQ,MAAM,CAAC;AAAA,MAC7B;AAAA,IACF;AAAA,IAEA,MAAM,QAAQ;AACZ,YAAMA,MAAK,CAAC,OAAO,CAAC,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACpC,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,aAAW;AACX,SAAO;AACT;AAEA,eAAsB,eAA8B;AAClD,MAAI,UAAU;AACZ,UAAM,SAAS,MAAM;AAAA,EACvB;AACF;;;AC7NA,IAAME,eAAc;AAEpB,SAAS,SAAS,MAAc,KAAqB;AACnD,SAAO,KAAK,SAAS,MAAM,KAAK,MAAM,GAAG,GAAG,IAAI,qBAAqB;AACvE;AAEO,SAAS,kBAAkB,eAA2C;AAC3E,SAAO;AAAA,IACL,YAAY;AAAA,MACV,MAAM;AAAA,MACN,aACE;AAAA,MAIF,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,cACJ;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,YACA,aACE;AAAA,UAMJ;AAAA,UACA,KAAK;AAAA,YACH,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,UAAU;AAAA,YACR,MAAM;AAAA,YACN,aACE;AAAA,UACJ;AAAA,UACA,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,OAAO;AAAA,YACL,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,KAAK;AAAA,YACH,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,aACE;AAAA,UACJ;AAAA,QACF;AAAA,QACA,UAAU,CAAC,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,IAEA,MAAM,QACJ,MACA,UACqB;AACrB,YAAM,SAAS,KAAK;AAEpB,UAAI,WAAW,SAAS;AACtB,cAAM,aAAa;AACnB,eAAO,EAAE,YAAY,IAAI,SAAS,kBAAkB;AAAA,MACtD;AAEA,UAAI;AACF,cAAM,UAAU,MAAM,cAAc;AAEpC,gBAAQ,QAAQ;AAAA,UACd,KAAK,YAAY;AACf,kBAAM,MAAM,KAAK;AACjB,gBAAI,CAAC,KAAK;AACR,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AACA,kBAAM,SAAS,MAAM,QAAQ,SAAS,GAAG;AACzC,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS;AAAA,gBACP,iBAAiB,OAAO,GAAG;AAAA,SAAY,OAAO,KAAK;AAAA;AAAA;AAAA,EAA8B,OAAO,OAAO;AAAA,gBAC/FA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,UAEA,KAAK,YAAY;AACf,kBAAM,WAAW,MAAM,QAAQ,SAAS,IAAI;AAC5C,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,SAAS,UAAUA,YAAW;AAAA,YACzC;AAAA,UACF;AAAA,UAEA,KAAK,cAAc;AACjB,kBAAM,SAAS,MAAM,QAAQ,WAAW;AACxC,kBAAM,SAAS,OAAO,SAAS,QAAQ;AACvC,kBAAM,WAAW,cAAc;AAAA,cAC7B;AAAA,cACA;AAAA,cACA;AAAA,YACF;AACA,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,KAAK,UAAU;AAAA,gBACtB,YAAY,SAAS;AAAA,gBACrB,MAAM,SAAS;AAAA,gBACf,OAAO,SAAS;AAAA,gBAChB,UAAU,SAAS;AAAA,cACrB,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UAEA,KAAK,SAAS;AACZ,kBAAM,WAAW,KAAK;AACtB,gBAAI,CAAC,UAAU;AACb,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AACA,kBAAM,QAAQ,MAAM,QAAQ;AAC5B,mBAAO,EAAE,YAAY,IAAI,SAAS,YAAY,QAAQ,GAAG;AAAA,UAC3D;AAAA,UAEA,KAAK,QAAQ;AACX,kBAAM,WAAW,KAAK;AACtB,kBAAM,OAAO,KAAK;AAClB,gBAAI,CAAC,YAAY,QAAQ,MAAM;AAC7B,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AACA,kBAAM,QAAQ,KAAK,UAAU,IAAI;AACjC,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,UAAU,QAAQ,UAAU,IAAI;AAAA,YAC3C;AAAA,UACF;AAAA,UAEA,KAAK,QAAQ;AACX,kBAAM,WAAW,KAAK;AACtB,kBAAM,OAAO,KAAK;AAClB,gBAAI,CAAC,YAAY,CAAC,MAAM;AACtB,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AACA,kBAAM,QAAQ,KAAK,UAAU,IAAI;AACjC,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,cAAc,QAAQ,KAAK,IAAI;AAAA,YAC1C;AAAA,UACF;AAAA,UAEA,KAAK,UAAU;AACb,kBAAM,WAAW,KAAK;AACtB,kBAAM,QAAQ,KAAK;AACnB,gBAAI,CAAC,YAAY,CAAC,OAAO;AACvB,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AACA,kBAAM,QAAQ,OAAO,UAAU,KAAK;AACpC,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,aAAa,KAAK,QAAQ,QAAQ;AAAA,YAC7C;AAAA,UACF;AAAA,UAEA,KAAK,SAAS;AACZ,kBAAM,MAAM,KAAK;AACjB,gBAAI,CAAC,KAAK;AACR,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AACA,kBAAM,QAAQ,MAAM,GAAG;AACvB,mBAAO,EAAE,YAAY,IAAI,SAAS,YAAY,GAAG,GAAG;AAAA,UACtD;AAAA,UAEA,KAAK,YAAY;AACf,kBAAM,SAAS,KAAK;AACpB,gBAAI,CAAC,QAAQ;AACX,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AACA,kBAAM,SAAS,MAAM,QAAQ,SAAS,MAAM;AAC5C,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,SAAS,QAAQA,YAAW;AAAA,YACvC;AAAA,UACF;AAAA,UAEA,KAAK,YAAY;AACf,kBAAM,WAAW,KAAK;AACtB,gBAAI,CAAC,UAAU;AACb,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AACA,kBAAM,SAAS,MAAM,QAAQ,IAAI,CAAC,OAAO,QAAQ,QAAQ,CAAC;AAC1D,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,SAAS,QAAQA,YAAW;AAAA,YACvC;AAAA,UACF;AAAA,UAEA,KAAK,eAAe;AAClB,kBAAM,SAAS,MAAM,QAAQ,WAAW;AACxC,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS;AAAA,gBACP,QAAQ,OAAO,GAAG;AAAA,SAAY,OAAO,KAAK;AAAA;AAAA;AAAA,EAA8B,OAAO,OAAO;AAAA,gBACtFA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,UAEA,KAAK,QAAQ;AACX,kBAAM,SAAU,KAAK,UAAqB;AAC1C,kBAAM,QAAQ,KAAK,MAAM;AACzB,mBAAO,EAAE,YAAY,IAAI,SAAS,eAAe,MAAM,GAAG;AAAA,UAC5D;AAAA,UAEA,KAAK,QAAQ;AACX,kBAAM,QAAQ,IAAI,CAAC,MAAM,CAAC;AAC1B,mBAAO,EAAE,YAAY,IAAI,SAAS,iBAAiB;AAAA,UACrD;AAAA,UAEA,KAAK,WAAW;AACd,kBAAM,QAAQ,IAAI,CAAC,SAAS,CAAC;AAC7B,mBAAO,EAAE,YAAY,IAAI,SAAS,oBAAoB;AAAA,UACxD;AAAA,UAEA,KAAK,UAAU;AACb,kBAAM,QAAQ,IAAI,CAAC,QAAQ,CAAC;AAC5B,mBAAO,EAAE,YAAY,IAAI,SAAS,gBAAgB;AAAA,UACpD;AAAA,UAEA;AACE,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,mBAAmB,MAAM;AAAA,cAClC,SAAS;AAAA,YACX;AAAA,QACJ;AAAA,MACF,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,SAAS,kBAAkB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UAC3E,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AChTA,OAAOC,aAAY;;;ACeZ,IAAM,oBAAoB;AAAA,EAC/B,UAAU;AAAA,EACV,qBAAqB;AAAA,EACrB,WAAW;AAAA;AACb;;;ACjBA,IAAM,aAAa,oBAAI,IAA+B;AAK/C,SAAS,oBAAoB,QAAiC;AACnE,aAAW,IAAI,OAAO,OAAO,MAAM;AACrC;AAKO,SAAS,eAAe,OAA8C;AAC3E,SAAO,WAAW,IAAI,KAAK;AAC7B;AAKO,SAAS,oBACd,OACA,QACA,QACA,OACM;AACN,QAAM,SAAS,WAAW,IAAI,KAAK;AACnC,MAAI,QAAQ;AACV,WAAO,SAAS;AAChB,WAAO,SAAS;AAChB,WAAO,QAAQ;AACf,WAAO,UAAU,KAAK,IAAI;AAE1B,WAAO,OAAO;AAAA,EAChB;AACF;AAKO,SAAS,kBAAkB,OAAwB;AACxD,QAAM,SAAS,WAAW,IAAI,KAAK;AACnC,MAAI,CAAC,OAAQ,QAAO;AAGpB,MAAI,OAAO,mBAAmB,CAAC,OAAO,gBAAgB,OAAO,SAAS;AACpE,WAAO,gBAAgB,MAAM;AAAA,EAC/B;AAGA,sBAAoB,OAAO,aAAa,QAAW,6BAA6B;AAGhF,aAAW,CAAC,YAAY,WAAW,KAAK,YAAY;AAClD,QAAI,YAAY,oBAAoB,OAAO,kBAAkB,YAAY,WAAW,WAAW;AAC7F,wBAAkB,UAAU;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,wBAAwB,iBAAiC;AACvE,MAAI,QAAQ;AACZ,aAAW,CAAC,OAAO,MAAM,KAAK,YAAY;AACxC,QAAI,OAAO,oBAAoB,mBAAmB,OAAO,WAAW,WAAW;AAC7E,UAAI,kBAAkB,KAAK,GAAG;AAC5B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAKO,SAAS,oBAAoB,iBAAiC;AACnE,MAAI,QAAQ;AACZ,aAAW,KAAK,WAAW,OAAO,GAAG;AACnC,QAAI,EAAE,oBAAoB,mBAAmB,EAAE,WAAW,WAAW;AACnE;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAKO,SAAS,mBAAmB,WAA2B;AAC5D,aAAW,KAAK,WAAW,OAAO,GAAG;AACnC,QAAI,EAAE,mBAAmB,WAAW;AAClC,aAAO,EAAE;AAAA,IACX;AAAA,EACF;AACA,SAAO;AACT;AAMO,SAAS,uBAAuB,WAAW,KAAK,KAAK,KAAY;AACtE,QAAM,MAAM,KAAK,IAAI;AACrB,aAAW,CAAC,OAAO,MAAM,KAAK,YAAY;AACxC,QACE,OAAO,WAAW,aAClB,OAAO,WACP,MAAM,OAAO,UAAU,UACvB;AACA,iBAAW,OAAO,KAAK;AAAA,IACzB;AAAA,EACF;AACF;;;AFrGA,IAAI,YAAgC;AAM7B,SAAS,kBAAkB,QAA2B;AAC3D,cAAY;AACd;AAMO,SAAS,qBAAkC;AAChD,SAAO;AAAA,IACL,YAAY;AAAA,MACV,MAAM;AAAA,MACN,aACE;AAAA,MACF,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,aACE;AAAA,UACJ;AAAA,QACF;AAAA,QACA,UAAU,CAAC,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,IAEA,SAAS,OACP,MACA,YACwB;AACxB,aAAO,aAAa,MAAM,OAAO;AAAA,IACnC;AAAA,EACF;AACF;AAKA,eAAe,aACb,MACA,SACqB;AACrB,QAAM,OAAO,KAAK;AAClB,MAAI,CAAC,MAAM,KAAK,GAAG;AACjB,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF;AAEA,MAAI,CAAC,WAAW;AACd,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SACE;AAAA,MACF,SAAS;AAAA,IACX;AAAA,EACF;AAGA,QAAM,eAAe,mBAAmB,QAAQ,SAAS;AACzD,MAAI,gBAAgB,kBAAkB,UAAU;AAC9C,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS,0CAA0C,YAAY,IAAI,kBAAkB,QAAQ;AAAA,MAC7F,SAAS;AAAA,IACX;AAAA,EACF;AAGA,QAAM,iBAAiB,oBAAoB,QAAQ,SAAS;AAC5D,MAAI,kBAAkB,kBAAkB,qBAAqB;AAC3D,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS,gDAAgD,cAAc,IAAI,kBAAkB,mBAAmB;AAAA,MAChH,SAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,aAAaC,QAAO,WAAW;AACrC,QAAM,iBAAiB,YAAY,UAAU;AAG7C,QAAM,kBAAkB,IAAI,gBAAgB;AAG5C,QAAM,SAA4B;AAAA,IAChC,OAAO;AAAA,IACP;AAAA,IACA,iBAAiB,QAAQ;AAAA,IACzB,aAAa,QAAQ;AAAA,IACrB;AAAA,IACA,OAAO,eAAe;AAAA,IACtB,QAAQ;AAAA,IACR,WAAW,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AACA,sBAAoB,MAAM;AAE1B,SAAO;AAAA,IACL,qBAAqB,UAAU,WAAW,OAAO,KAAK,gBAAgB,QAAQ,SAAS;AAAA,IACvF;AAAA,EACF;AAGA,QAAM,SAAS;AAGf,QAAM,cAAc,YAAY;AAC9B,QAAI;AAEF,YAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD;AAAA,UACE,MAAM,OAAO,IAAI,MAAM,kCAAkC,CAAC;AAAA,UAC1D,kBAAkB;AAAA,QACpB;AAAA,MACF,CAAC;AAGD,YAAM,SAAS,MAAM,QAAQ,KAAK;AAAA,QAChC,OAAO,IAAI;AAAA,UACT,QAAQ;AAAA;AAAA,QAAyI,IAAI;AAAA,UACrJ,WAAW;AAAA,UACX,QAAQ,gBAAgB;AAAA,QAC1B,CAAC;AAAA,QACD;AAAA,MACF,CAAC;AAGD,0BAAoB,YAAY,QAAQ,OAAO,QAAQ;AAEvD,aAAO,KAAK,uBAAuB,UAAU,IAAI,OAAO;AAExD,aAAO,EAAE,SAAS,MAAM,QAAQ,OAAO,UAAU,OAAO,OAAO,MAAM;AAAA,IACvE,SAAS,KAAK;AACZ,YAAM,WAAW,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAChE,YAAM,YAAY,SAAS,SAAS,SAAS;AAC7C,YAAM,cAAc,gBAAgB,OAAO;AAE3C;AAAA,QACE;AAAA,QACA,cAAc,cAAc,YAAY,YAAY;AAAA,QACpD;AAAA,QACA;AAAA,MACF;AAEA,aAAO,MAAM,oBAAoB,UAAU,MAAM,QAAQ,IAAI,OAAO;AAEpE,aAAO,EAAE,SAAS,OAAO,OAAO,UAAU,WAAW,YAAY;AAAA,IACnE;AAAA,EACF;AAGA,QAAM,UAAU,MAAM,YAAY;AAElC,MAAI,CAAC,QAAQ,SAAS;AACpB,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS,oBAAoB,QAAQ,KAAK;AAAA,MAC1C,SAAS;AAAA,IACX;AAAA,EACF;AAGA,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,SAAS,QAAQ,UAAU;AAAA,EAC7B;AACF;;;AGxLO,SAAS,0BACd,kBACA,SACa;AACb,SAAO;AAAA,IACL,YAAY;AAAA,MACV,MAAM;AAAA,MACN,aACE;AAAA,MACF,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,aAAa;AAAA,YACb,MAAM,CAAC,QAAQ,QAAQ;AAAA,UACzB;AAAA,UACA,gBAAgB;AAAA,YACd,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,QACF;AAAA,QACA,UAAU,CAAC,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,IAEA,SAAS,OACP,MACA,aACwB;AACxB,YAAM,SAAS,KAAK;AAEpB,UAAI;AACF,cAAM,aAAa,MAAM,iBAAiB,KAAK;AAE/C,YAAI,WAAW,QAAQ;AACrB,cAAI,WAAW,WAAW,GAAG;AAC3B,mBAAO,EAAE,YAAY,IAAI,SAAS,4BAA4B;AAAA,UAChE;AACA,gBAAM,cAAc,iBAAiB,oBAAoB,OAAO;AAChE,gBAAM,QAAQ,WAAW,IAAI,CAAC,OAAO;AACnC,kBAAM,SAAS,GAAG,OAAO,cAAc,cAAc;AACrD,mBAAO,OAAO,GAAG,IAAI,KAAK,MAAM;AAAA,UAClC,CAAC;AACD,iBAAO,EAAE,YAAY,IAAI,SAAS;AAAA,EAA0B,MAAM,KAAK,IAAI,CAAC,GAAG;AAAA,QACjF;AAEA,YAAI,WAAW,UAAU;AACvB,gBAAM,OAAO,KAAK;AAClB,cAAI,CAAC,MAAM;AACT,mBAAO,EAAE,YAAY,IAAI,SAAS,0CAA0C,SAAS,KAAK;AAAA,UAC5F;AAEA,gBAAM,QAAQ,KAAK,YAAY;AAC/B,gBAAM,QACJ,WAAW,KAAK,CAAC,OAAO,GAAG,KAAK,YAAY,MAAM,KAAK,KACvD,WAAW,KAAK,CAAC,OAAO,GAAG,KAAK,YAAY,EAAE,SAAS,KAAK,CAAC;AAE/D,cAAI,CAAC,OAAO;AACV,kBAAM,YAAY,WAAW,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,KAAK,IAAI;AAC3D,mBAAO,EAAE,YAAY,IAAI,SAAS,0BAA0B,IAAI,iBAAiB,SAAS,IAAI,SAAS,KAAK;AAAA,UAC9G;AAEA,2BAAiB,oBAAoB,SAAS,MAAM,EAAE;AACtD,iBAAO,EAAE,YAAY,IAAI,SAAS,2BAA2B,MAAM,IAAI,0EAA0E;AAAA,QACnJ;AAEA,eAAO,EAAE,YAAY,IAAI,SAAS,mBAAmB,MAAM,6BAA6B,SAAS,KAAK;AAAA,MACxG,SAAS,KAAK;AACZ,eAAO,EAAE,YAAY,IAAI,SAAS,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,IAAI,SAAS,KAAK;AAAA,MAChH;AAAA,IACF;AAAA,EACF;AACF;;;AClFA,OAAOC,UAAQ;;;ACAf,OAAOC,UAAQ;AACf,OAAOC,YAAU;;;ACDjB,OAAOC,UAAQ;AACf,OAAOC,YAAU;AACjB,OAAO,YAAY;;;ACFnB,OAAOC,UAAQ;AACf,OAAOC,YAAU;AAMjB,eAAsB,qBACpB,UACuC;AACvC,QAAM,aAAaA,OAAK,KAAK,UAAU,kBAAkB;AACzD,MAAI;AACF,UAAM,MAAM,MAAMD,KAAG,SAAS,YAAY,OAAO;AACjD,UAAM,SAAS,KAAK,MAAM,GAAG;AAE7B,QACE,CAAC,OAAO,eACR,CAAC,MAAM,QAAQ,OAAO,WAAW,GACjC;AACA,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMO,SAAS,wBACd,WACA,cACA,UACA,SACQ;AACR,MAAI,SAAS;AACX,WAAO,GAAG,OAAO,IAAI,QAAQ;AAAA,EAC/B;AACA,SAAO,SAAS,SAAS,IAAI,YAAY,IAAI,QAAQ;AACvD;AAMO,SAAS,sBACd,WACA,cACA,YACA,UACA,SACQ;AACR,MAAI,SAAS;AACX,WAAO,GAAG,OAAO,IAAI,UAAU,IAAI,QAAQ;AAAA,EAC7C;AACA,SAAO,SAAS,SAAS,IAAI,YAAY,IAAI,UAAU,IAAI,QAAQ;AACrE;AAMO,SAAS,uBACd,WACA,cACA,SACQ;AACR,MAAI,SAAS;AACX,WAAO,GAAG,OAAO;AAAA,EACnB;AACA,SAAO,SAAS,SAAS,IAAI,YAAY;AAC3C;AAeO,SAAS,qBACd,WACA,cAKA;AACA,QAAM,SAAS,SAAS,SAAS,IAAI,YAAY;AACjD,SAAO;AAAA,IACL,aAAa,GAAG,MAAM;AAAA,IACtB,cAAc,GAAG,MAAM;AAAA,IACvB,WAAW,GAAG,MAAM;AAAA,EACtB;AACF;;;ADxFA,IAAI,aAAkC;AAE/B,SAAS,kBAAwB;AACtC,eAAa;AACf;AAKA,eAAsB,WACpB,YACA,SACA,YACA,iBACuB;AACvB,MAAI,WAAY,QAAO;AAEvB,QAAM,SAAuB,CAAC;AAG9B,MAAI,YAAY;AACd,UAAM,UAAU,MAAM,aAAa,YAAY,SAAS;AACxD,WAAO,KAAK,GAAG,OAAO;AAAA,EACxB;AAGA,MAAI,SAAS;AACX,UAAM,UAAU,MAAM,aAAa,SAAS,MAAM;AAClD,WAAO,KAAK,GAAG,OAAO;AAAA,EACxB;AAGA,aAAW,OAAO,YAAY;AAC5B,UAAM,UAAU,MAAM,aAAa,KAAK,YAAY;AACpD,WAAO,KAAK,GAAG,OAAO;AAAA,EACxB;AAGA,aAAW,SAAS,QAAQ;AAE1B,UAAM,mBAAmB,MAAM,qBAAqB,MAAM,IAAI;AAG9D,UAAM,SAAS,MAAM,iBAAiB,OAAO,eAAe;AAC5D,UAAM,WAAW,OAAO;AACxB,UAAM,mBAAmB,OAAO;AAChC,UAAM,mBAAmB,OAAO;AAGhC,QAAI,MAAM,SAAS,SAAS;AAC1B,YAAM,iBAAiB,MAAM,SAAS,QACnC,OAAO,CAAC,SAAS;AAChB,YAAI,CAAC,KAAK,GAAI,QAAO;AACrB,eAAO,KAAK,GAAG,SAAS,QAAQ,QAAQ;AAAA,MAC1C,CAAC,EACA,IAAI,CAAC,MAAM,OAAO;AAAA,QACjB,IAAI,KAAK,MAAM,WAAW,CAAC;AAAA,QAC3B,MAAM,KAAK;AAAA,QACX,OAAO,KAAK,SAAS,eAAe,KAAK,IAAI;AAAA,MAC/C,EAAE;AAAA,IACN;AAAA,EACF;AAEA,eAAa;AACb,SAAO;AACT;AAKO,SAAS,kBAAkB,QAAoC;AACpE,SAAO,OAAO,OAAO,CAAC,MAAM,EAAE,QAAQ;AACxC;AAKA,eAAe,aACb,KACA,QACuB;AACvB,QAAM,SAAuB,CAAC;AAE9B,MAAI;AACF,UAAM,UAAU,MAAME,KAAG,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAE7D,eAAW,SAAS,SAAS;AAC3B,UAAI,CAAC,MAAM,YAAY,EAAG;AAE1B,YAAM,WAAWC,OAAK,KAAK,KAAK,MAAM,IAAI;AAC1C,YAAM,cAAcA,OAAK,KAAK,UAAU,UAAU;AAElD,UAAI;AACF,cAAM,MAAM,MAAMD,KAAG,SAAS,aAAa,OAAO;AAClD,cAAM,SAAS,OAAO,GAAG;AACzB,cAAM,WAAW,OAAO;AAExB,YAAI,CAAC,SAAS,MAAM;AAClB,mBAAS,OAAO,MAAM;AAAA,QACxB;AACA,YAAI,CAAC,SAAS,aAAa;AACzB,mBAAS,cAAc;AAAA,QACzB;AAGA,YAAI,cAAc;AAClB,YAAI;AACF,gBAAMA,KAAG,OAAOC,OAAK,KAAK,UAAU,SAAS,CAAC;AAC9C,wBAAc;AAAA,QAChB,QAAQ;AAAA,QAER;AAGA,YAAI,eAAe;AACnB,YAAI;AACF,gBAAMD,KAAG,OAAOC,OAAK,KAAK,UAAU,UAAU,CAAC;AAC/C,yBAAe;AAAA,QACjB,QAAQ;AAAA,QAER;AAEA,eAAO,KAAK;AAAA,UACV;AAAA,UACA,SAAS,OAAO,QAAQ,KAAK;AAAA,UAC7B,MAAM;AAAA,UACN,UAAU;AAAA;AAAA,UACV,QAAQ;AAAA,UACR,UAAU,gBAAgB;AAAA,UAC1B;AAAA,QACF,CAAC;AAAA,MACH,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;AAWA,eAAe,iBACb,OACA,iBAC4B;AAC5B,QAAM,EAAE,SAAS,IAAI;AAGrB,MAAI,SAAS,QAAQ;AACnB,WAAO,EAAE,UAAU,KAAK;AAAA,EAC1B;AAGA,QAAM,aAAa,SAAS,eAAe;AAC3C,MAAI,cAAc,CAAC,WAAW,SAAS,QAAQ,QAAQ,GAAG;AACxD,WAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ,gBAAgB,WAAW,KAAK,IAAI,CAAC,cAAc,QAAQ,QAAQ;AAAA,IAC7E;AAAA,EACF;AAGA,MAAI,SAAS,UAAU,KAAK;AAC1B,eAAW,UAAU,SAAS,SAAS,KAAK;AAC1C,UAAI,CAAC,QAAQ,IAAI,MAAM,GAAG;AACxB,eAAO;AAAA,UACL,UAAU;AAAA,UACV,QAAQ,iCAAiC,MAAM;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,SAAS,UAAU,MAAM;AAC3B,eAAW,OAAO,SAAS,SAAS,MAAM;AACxC,UAAI,CAAE,MAAM,kBAAkB,GAAG,GAAI;AACnC,eAAO;AAAA,UACL,UAAU;AAAA,UACV,QAAQ,mBAAmB,GAAG;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,MAAM,oBAAoB,iBAAiB;AAC7C,UAAM,mBAA4C,CAAC;AACnD,QAAI,eAAe;AAEnB,eAAW,QAAQ,MAAM,iBAAiB,aAAa;AACrD,UAAI,KAAK,SAAS,UAAU;AAC1B,cAAM,OAAO,qBAAqB,SAAS,MAAM,KAAK,EAAE;AACxD,cAAM,WAAW,MAAM,gBAAgB,IAAI,KAAK,WAAW;AAC3D,yBAAiB,KAAK,EAAE,IAAI;AAC5B,YAAI,CAAC,SAAU,gBAAe;AAAA,MAChC,WAAW,KAAK,YAAY,KAAK,QAAQ;AAEvC,cAAM,cAAc,uBAAuB,SAAS,MAAM,KAAK,IAAI,KAAK,OAAO;AAC/E,cAAM,MAAM,MAAM,gBAAgB,IAAI,WAAW;AACjD,cAAM,YAAY,MAAM,KAAK,MAAM,GAAG,IAA6B,CAAC;AACpE,YAAI,uBAAuB;AAE3B,mBAAWC,aAAY,WAAW;AAChC,cAAI,aAAa;AACjB,qBAAW,SAAS,KAAK,QAAQ;AAC/B,gBAAI,MAAM,aAAa,MAAO;AAC9B,kBAAM,MAAM;AAAA,cACV,SAAS;AAAA,cACT,KAAK;AAAA,cACLA,UAAS;AAAA,cACT,MAAM;AAAA,cACN,KAAK;AAAA,YACP;AACA,gBAAI,CAAE,MAAM,gBAAgB,IAAI,GAAG,GAAI;AACrC,2BAAa;AACb;AAAA,YACF;AAAA,UACF;AACA,cAAI,YAAY;AACd,mCAAuB;AACvB;AAAA,UACF;AAAA,QACF;AAEA,yBAAiB,KAAK,EAAE,IAAI;AAC5B,YAAI,CAAC,qBAAsB,gBAAe;AAAA,MAC5C,WAAW,KAAK,QAAQ;AACtB,YAAI,kBAAkB;AACtB,mBAAW,SAAS,KAAK,QAAQ;AAC/B,cAAI,MAAM,aAAa,MAAO;AAC9B,gBAAM,MAAM;AAAA,YACV,SAAS;AAAA,YACT,KAAK;AAAA,YACL,MAAM;AAAA,YACN,KAAK;AAAA,UACP;AACA,gBAAM,SAAS,MAAM,gBAAgB,IAAI,GAAG;AAC5C,cAAI,CAAC,QAAQ;AACX,8BAAkB;AAClB;AAAA,UACF;AAAA,QACF;AACA,yBAAiB,KAAK,EAAE,IAAI;AAC5B,YAAI,CAAC,gBAAiB,gBAAe;AAAA,MACvC;AAAA,IACF;AAEA,QAAI,CAAC,cAAc;AACjB,aAAO;AAAA,QACL,UAAU;AAAA,QACV,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,UAAU,MAAM,iBAAiB;AAAA,EAC5C;AAEA,SAAO,EAAE,UAAU,KAAK;AAC1B;AAKA,eAAe,kBAAkB,MAAgC;AAC/D,QAAM,EAAE,MAAAC,MAAK,IAAI,MAAM,OAAO,eAAoB;AAClD,QAAM,MAAM,QAAQ,aAAa,UAAU,SAAS,IAAI,KAAK,SAAS,IAAI;AAE1E,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,IAAAA,MAAK,KAAK,CAAC,UAAU;AACnB,cAAQ,CAAC,KAAK;AAAA,IAChB,CAAC;AAAA,EACH,CAAC;AACH;;;ADvSA,IAAM,gBAAgB;AAKf,SAAS,kBAAkB,MAA6B;AAC7D,MAAI,CAAC,QAAQ,KAAK,SAAS,KAAK,KAAK,SAAS,IAAI;AAChD,WAAO;AAAA,EACT;AACA,MAAI,CAAC,cAAc,KAAK,IAAI,GAAG;AAC7B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKA,eAAsB,YACpB,WACA,MACA,YACyC;AACzC,QAAM,UAAU,kBAAkB,IAAI;AACtC,MAAI,QAAS,OAAM,IAAI,MAAM,OAAO;AAEpC,QAAM,WAAWC,OAAK,KAAK,WAAW,IAAI;AAG1C,MAAI;AACF,UAAMC,KAAG,OAAO,QAAQ;AACxB,UAAM,IAAI,MAAM,UAAU,IAAI,kBAAkB;AAAA,EAClD,SAAS,KAAK;AACZ,QAAK,IAAc,QAAQ,SAAS,gBAAgB,EAAG,OAAM;AAAA,EAE/D;AAEA,QAAMA,KAAG,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAC5C,QAAMA,KAAG,UAAUD,OAAK,KAAK,UAAU,UAAU,GAAG,YAAY,OAAO;AAEvE,kBAAgB;AAChB,SAAO,EAAE,MAAM,MAAM,SAAS;AAChC;AAKA,eAAsB,YACpB,WACA,MACA,YACe;AACf,QAAM,WAAWA,OAAK,KAAK,WAAW,IAAI;AAC1C,QAAM,cAAcA,OAAK,KAAK,UAAU,UAAU;AAElD,MAAI;AACF,UAAMC,KAAG,OAAO,WAAW;AAAA,EAC7B,QAAQ;AACN,UAAM,IAAI,MAAM,UAAU,IAAI,aAAa;AAAA,EAC7C;AAEA,QAAMA,KAAG,UAAU,aAAa,YAAY,OAAO;AACnD,kBAAgB;AAClB;AAKA,eAAsB,cACpB,WACA,MACiB;AACjB,QAAM,cAAcD,OAAK,KAAK,WAAW,MAAM,UAAU;AAEzD,MAAI;AACF,WAAO,MAAMC,KAAG,SAAS,aAAa,OAAO;AAAA,EAC/C,QAAQ;AACN,UAAM,IAAI,MAAM,UAAU,IAAI,aAAa;AAAA,EAC7C;AACF;;;AGnFA,SAAS,YAAAC,iBAAgB;AACzB,OAAOC,UAAQ;AACf,OAAOC,YAAU;AAOjB,eAAsB,oBACpB,QACA,WACyC;AACzC,QAAMC,KAAG,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAG7C,QAAM,WAAW,OACd,MAAM,GAAG,EACT,IAAI,GACH,QAAQ,UAAU,EAAE;AAExB,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,oBAAoB,MAAM,EAAE;AAAA,EAC9C;AAGA,MAAI,CAAC,uCAAuC,KAAK,MAAM,GAAG;AACxD,UAAM,IAAI,MAAM,2BAA2B,MAAM,EAAE;AAAA,EACrD;AAEA,QAAM,YAAYC,OAAK,KAAK,WAAW,QAAQ;AAG/C,MAAI;AACF,UAAMD,KAAG,OAAO,SAAS;AACzB,UAAM,IAAI,MAAM,UAAU,QAAQ,wBAAwB;AAAA,EAC5D,SAAS,KAAK;AACZ,QAAK,IAAc,QAAQ,SAAS,mBAAmB,EAAG,OAAM;AAAA,EAElE;AAGA,QAAM,cAAc,OAAO,CAAC,SAAS,WAAW,KAAK,QAAQ,SAAS,CAAC;AAGvE,MAAI;AACF,UAAMA,KAAG,OAAOC,OAAK,KAAK,WAAW,UAAU,CAAC;AAAA,EAClD,QAAQ;AAEN,UAAMD,KAAG,GAAG,WAAW,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACvD,UAAM,IAAI;AAAA,MACR,uCAAuC,QAAQ;AAAA,IACjD;AAAA,EACF;AAGA,QAAMA,KAAG;AAAA,IACPC,OAAK,KAAK,WAAW,SAAS;AAAA,IAC9B;AAAA,IACA;AAAA,EACF;AAGA,MAAI;AACF,UAAMD,KAAG,GAAGC,OAAK,KAAK,WAAW,MAAM,GAAG;AAAA,MACxC,WAAW;AAAA,MACX,OAAO;AAAA,IACT,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AAEA,kBAAgB;AAChB,SAAO,KAAK,oBAAoB,QAAQ,UAAU,MAAM,IAAI,QAAQ;AAEpE,SAAO,EAAE,MAAM,UAAU,MAAM,UAAU;AAC3C;AAKA,eAAsB,YACpB,WACA,WACe;AACf,QAAM,YAAYA,OAAK,KAAK,WAAW,SAAS;AAEhD,MAAI;AACF,UAAMD,KAAG,OAAO,SAAS;AAAA,EAC3B,QAAQ;AACN,UAAM,IAAI,MAAM,UAAU,SAAS,aAAa;AAAA,EAClD;AAEA,QAAMA,KAAG,GAAG,WAAW,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AACvD,kBAAgB;AAChB,SAAO,KAAK,kBAAkB,SAAS,KAAK,QAAQ;AACtD;AAEA,SAAS,cAAc,KAAa,MAAiC;AACnE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,IAAAE,UAAS,KAAK,MAAM,EAAE,SAAS,IAAO,GAAG,CAAC,OAAO,QAAQ,WAAW;AAClE,UAAI,OAAO;AACT,eAAO,IAAI,MAAM,UAAU,MAAM,OAAO,CAAC;AACzC;AAAA,MACF;AACA,cAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,EACH,CAAC;AACH;;;AJnGO,SAAS,gBACd,eACA,mBACa;AACb,QAAM,eAAe,IAAI,IAAI,iBAAiB;AAE9C,SAAO;AAAA,IACL,YAAY;AAAA,MACV,MAAM;AAAA,MACN,aACE;AAAA,MACF,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,aAAa;AAAA,YACb,MAAM,CAAC,UAAU,UAAU,QAAQ,QAAQ;AAAA,UAC7C;AAAA,UACA,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,SAAS;AAAA,YACP,MAAM;AAAA,YACN,aACE;AAAA,UACJ;AAAA,QACF;AAAA,QACA,UAAU,CAAC,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,IAEA,SAAS,OACP,MACA,aACwB;AACxB,YAAM,SAAS,KAAK;AAEpB,UAAI;AACF,gBAAQ,QAAQ;AAAA,UACd,KAAK,UAAU;AACb,kBAAM,OAAO,KAAK;AAClB,kBAAM,UAAU,KAAK;AACrB,gBAAI,CAAC,QAAQ,CAAC,SAAS;AACrB,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AAEA,kBAAM,UAAU,kBAAkB,IAAI;AACtC,gBAAI,SAAS;AACX,qBAAO,EAAE,YAAY,IAAI,SAAS,SAAS,SAAS,KAAK;AAAA,YAC3D;AAEA,gBAAI,aAAa,IAAI,IAAI,GAAG;AAC1B,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS,wBAAwB,IAAI;AAAA,gBACrC,SAAS;AAAA,cACX;AAAA,YACF;AAEA,kBAAM,SAAS,MAAM,YAAY,eAAe,MAAM,OAAO;AAC7D,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,iBAAiB,OAAO,IAAI,gBAAgB,OAAO,IAAI;AAAA,YAClE;AAAA,UACF;AAAA,UAEA,KAAK,UAAU;AACb,kBAAM,OAAO,KAAK;AAClB,kBAAM,UAAU,KAAK;AACrB,gBAAI,CAAC,QAAQ,CAAC,SAAS;AACrB,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AAEA,kBAAM,YAAY,eAAe,MAAM,OAAO;AAC9C,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,iBAAiB,IAAI;AAAA,YAChC;AAAA,UACF;AAAA,UAEA,KAAK,QAAQ;AACX,gBAAI;AACF,oBAAM,UAAU,MAAMC,KAAG,QAAQ,eAAe;AAAA,gBAC9C,eAAe;AAAA,cACjB,CAAC;AACD,oBAAM,OAAO,QACV,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,EAC7B,IAAI,CAAC,MAAM,EAAE,IAAI;AAEpB,kBAAI,KAAK,WAAW,GAAG;AACrB,uBAAO;AAAA,kBACL,YAAY;AAAA,kBACZ,SAAS;AAAA,gBACX;AAAA,cACF;AAEA,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,EAAmB,KAAK,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,cAClE;AAAA,YACF,QAAQ;AACN,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,cACX;AAAA,YACF;AAAA,UACF;AAAA,UAEA,KAAK,UAAU;AACb,kBAAM,OAAO,KAAK;AAClB,gBAAI,CAAC,MAAM;AACT,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,YACF;AAEA,kBAAM,YAAY,MAAM,aAAa;AACrC,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,iBAAiB,IAAI;AAAA,YAChC;AAAA,UACF;AAAA,UAEA;AACE,mBAAO;AAAA,cACL,YAAY;AAAA,cACZ,SAAS,mBAAmB,MAAM;AAAA,cAClC,SAAS;AAAA,YACX;AAAA,QACJ;AAAA,MACF,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,SAAS,gBAAgB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,UACzE,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AKpJO,IAAM,eAA8B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC1BA,OAAOC,aAAY;AACnB,OAAOC,UAAQ;AACf,OAAOC,YAAU;AAsBjB,SAAS,UAAU,QAAgB,MAAsB;AACvD,SAAOF,QAAO,WAAW,QAAQ,MAAM,EAAE;AAC3C;AAEA,SAAS,QAAQ,MAAc,QAA+B;AAC5D,QAAM,OAAOA,QAAO,YAAY,EAAE;AAClC,QAAM,MAAM,UAAU,QAAQ,IAAI;AAClC,QAAM,KAAKA,QAAO,YAAY,EAAE;AAChC,QAAM,SAASA,QAAO,eAAe,eAAe,KAAK,EAAE;AAC3D,QAAM,YAAY,OAAO,OAAO;AAAA,IAC9B,OAAO,OAAO,MAAM,OAAO;AAAA,IAC3B,OAAO,MAAM;AAAA,EACf,CAAC;AACD,QAAM,MAAM,OAAO,WAAW;AAC9B,SAAO;AAAA,IACL,IAAI,GAAG,SAAS,KAAK;AAAA,IACrB,MAAM,UAAU,SAAS,KAAK;AAAA,IAC9B,KAAK,IAAI,SAAS,KAAK;AAAA,IACvB,MAAM,KAAK,SAAS,KAAK;AAAA,EAC3B;AACF;AAEA,SAAS,QAAQ,KAAoB,QAAwB;AAC3D,QAAM,OAAO,OAAO,KAAK,IAAI,MAAM,KAAK;AACxC,QAAM,MAAM,UAAU,QAAQ,IAAI;AAClC,QAAM,KAAK,OAAO,KAAK,IAAI,IAAI,KAAK;AACpC,QAAM,MAAM,OAAO,KAAK,IAAI,KAAK,KAAK;AACtC,QAAM,WAAWA,QAAO,iBAAiB,eAAe,KAAK,EAAE;AAC/D,WAAS,WAAW,GAAG;AACvB,QAAM,YAAY,OAAO,OAAO;AAAA,IAC9B,SAAS,OAAO,OAAO,KAAK,IAAI,MAAM,KAAK,CAAC;AAAA,IAC5C,SAAS,MAAM;AAAA,EACjB,CAAC;AACD,SAAO,UAAU,SAAS,OAAO;AACnC;AAEO,IAAM,2BAAN,MAA0D;AAAA,EACvD;AAAA,EACA;AAAA,EACA,QAA0B;AAAA,EAElC,YAAY,UAAkB,QAAgB;AAC5C,SAAK,WAAW;AAChB,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAc,OAA2B;AACvC,QAAI,KAAK,MAAO,QAAO,KAAK;AAC5B,QAAI;AACF,YAAM,MAAM,MAAMC,KAAG,SAAS,KAAK,UAAU,OAAO;AACpD,WAAK,QAAQ,KAAK,MAAM,GAAG;AAAA,IAC7B,QAAQ;AACN,WAAK,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC,EAAE;AAAA,IACzC;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,OAAsB;AAClC,QAAI,CAAC,KAAK,MAAO;AACjB,UAAMA,KAAG,MAAMC,OAAK,QAAQ,KAAK,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAC/D,UAAM,MAAM,GAAG,KAAK,QAAQ,IAAI,QAAQ,GAAG;AAC3C,UAAMD,KAAG,UAAU,KAAK,KAAK,UAAU,KAAK,OAAO,MAAM,CAAC,GAAG;AAAA,MAC3D,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AACD,UAAMA,KAAG,OAAO,KAAK,KAAK,QAAQ;AAAA,EACpC;AAAA,EAEA,MAAM,IAAI,KAAqC;AAC7C,UAAM,QAAQ,MAAM,KAAK,KAAK;AAC9B,UAAM,QAAQ,MAAM,QAAQ,GAAG;AAC/B,QAAI,CAAC,MAAO,QAAO;AACnB,QAAI;AACF,aAAO,QAAQ,OAAO,KAAK,MAAM;AAAA,IACnC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,KAAa,OAA8B;AACnD,UAAM,QAAQ,MAAM,KAAK,KAAK;AAC9B,UAAM,QAAQ,GAAG,IAAI,QAAQ,OAAO,KAAK,MAAM;AAC/C,UAAM,KAAK,KAAK;AAAA,EAClB;AAAA,EAEA,MAAM,OAAO,KAA4B;AACvC,UAAM,QAAQ,MAAM,KAAK,KAAK;AAC9B,WAAO,MAAM,QAAQ,GAAG;AACxB,UAAM,KAAK,KAAK;AAAA,EAClB;AAAA,EAEA,MAAM,IAAI,KAA+B;AACvC,UAAM,QAAQ,MAAM,KAAK,KAAK;AAC9B,WAAO,OAAO,MAAM;AAAA,EACtB;AAAA,EAEA,MAAM,OAA0B;AAC9B,UAAM,QAAQ,MAAM,KAAK,KAAK;AAC9B,WAAO,OAAO,KAAK,MAAM,OAAO;AAAA,EAClC;AACF;AAEA,eAAsB,kBAAkB,SAAkC;AACxE,QAAM,gBAAgB,QAAQ,IAAI;AAClC,MAAI,cAAe,QAAO;AAE1B,QAAM,UAAUC,OAAK,KAAK,SAAS,YAAY;AAC/C,MAAI;AACF,WAAO,MAAMD,KAAG,SAAS,SAAS,OAAO;AAAA,EAC3C,QAAQ;AACN,UAAM,MAAMD,QAAO,YAAY,EAAE,EAAE,SAAS,KAAK;AACjD,UAAMC,KAAG,MAAMC,OAAK,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AACzD,UAAMD,KAAG,UAAU,SAAS,KAAK,EAAE,MAAM,IAAM,CAAC;AAChD,WAAO;AAAA,EACT;AACF;AAEO,SAAS,cACd,aACG,OACK;AACR,SAAO,CAAC,UAAU,GAAG,KAAK,EAAE,KAAK,GAAG;AACtC;;;AClJA,SAAS,SAAS;AAClB,OAAOE,UAAQ;AACf,OAAOC,YAAU;AAEjB,IAAM,uBAAuB,EAAE,OAAO;AAAA,EACpC,OAAO,EAAE,OAAO,EAAE,SAAS;AAC7B,CAAC;AAED,IAAM,oBAAoB,EAAE,OAAO;AAAA,EACjC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE;AAAA,EACrD,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;AAAA,EACjD,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAClD,CAAC;AAED,IAAM,wBAAwB,EAAE,OAAO;AAAA,EACrC,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAClC,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED,IAAM,uBAAuB,EAAE,OAAO;AAAA,EACpC,UAAU,sBAAsB,QAAQ,CAAC,CAAC;AAC5C,CAAC;AAED,IAAM,qBAAqB,EAAE,OAAO;AAAA,EAClC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED,IAAM,sBAAsB,EAAE,OAAO;AAAA,EACnC,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EAClC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,EACnD,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,SAAS;AAAA,EAC9C,QAAQ,EAAE,KAAK,CAAC,SAAS,UAAU,SAAS,CAAC,EAAE,QAAQ,SAAS;AAClE,CAAC;AAED,IAAM,qBAAqB,EAAE,OAAO;AAAA,EAClC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,KAAK,EAAE,QAAQ,IAAI;AAAA,EACrD,MAAM,EAAE,OAAO,EAAE,QAAQ,WAAW;AACtC,CAAC;AAEM,IAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,WAAW,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACpC,WAAW,EACR,OAAO;AAAA,IACN,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAClC,CAAC,EACA,QAAQ,CAAC,CAAC;AAAA,EACb,WAAW,EACR,OAAO;AAAA,IACN,SAAS,EAAE,OAAO,EAAE,QAAQ,WAAW;AAAA,IACvC,WAAW,qBAAqB,QAAQ,CAAC,CAAC;AAAA,IAC1C,QAAQ,qBAAqB,QAAQ,CAAC,CAAC;AAAA,IACvC,QAAQ,qBAAqB,QAAQ,CAAC,CAAC;AAAA,IACvC,UAAU,qBAAqB,QAAQ,CAAC,CAAC;AAAA,IACzC,MAAM,qBAAqB,QAAQ,CAAC,CAAC;AAAA,IACrC,YAAY,qBAAqB,QAAQ,CAAC,CAAC;AAAA,IAC3C,SAAS,qBAAqB,QAAQ,CAAC,CAAC;AAAA,IACxC,QAAQ,qBAAqB,QAAQ,CAAC,CAAC;AAAA,EACzC,CAAC,EACA,QAAQ,CAAC,CAAC;AAAA,EACb,OAAO,kBAAkB,QAAQ,CAAC,CAAC;AAAA,EACnC,UAAU,oBAAoB,QAAQ,CAAC,CAAC;AAAA,EACxC,UAAU,qBAAqB,QAAQ,CAAC,CAAC;AAAA,EACzC,QAAQ,mBAAmB,QAAQ,CAAC,CAAC;AAAA,EACrC,QAAQ,mBAAmB,QAAQ,CAAC,CAAC;AACvC,CAAC;AAID,eAAsB,WAAW,YAA4C;AAC3E,MAAI;AACF,UAAM,MAAM,MAAMD,KAAG,SAAS,YAAY,OAAO;AAEjD,UAAM,WAAW,IAAI,QAAQ,gBAAgB,CAAC,GAAG,SAAS;AACxD,aAAO,QAAQ,IAAI,IAAI,KAAK;AAAA,IAC9B,CAAC;AAGD,QAAI;AACJ,QAAI,WAAW,SAAS,OAAO,KAAK,WAAW,SAAS,MAAM,GAAG;AAE/D,YAAM,EAAE,MAAM,IAAI,MAAM,OAAO,MAAgB,EAAE,MAAM,OAAO;AAAA,QAC5D,OAAO,CAAC,MAAc,KAAK,MAAM,CAAC;AAAA,MACpC,EAAE;AACF,eAAS,MAAM,QAAQ;AAAA,IACzB,OAAO;AACL,eAAS,KAAK,MAAM,QAAQ;AAAA,IAC9B;AAEA,WAAO,oBAAoB,MAAM,MAAM;AAAA,EACzC,QAAQ;AAEN,WAAO,oBAAoB,MAAM,CAAC,CAAC;AAAA,EACrC;AACF;AAEA,eAAsB,WACpB,YACA,QACe;AACf,QAAM,MAAMC,OAAK,QAAQ,UAAU;AACnC,QAAMD,KAAG,MAAM,KAAK,EAAE,WAAW,KAAK,CAAC;AAEvC,MAAI,WAAW,SAAS,OAAO,KAAK,WAAW,SAAS,MAAM,GAAG;AAC/D,UAAM,EAAE,UAAU,IAAI,MAAM,OAAO,MAAgB,EAAE,MAAM,OAAO;AAAA,MAChE,WAAW,CAAC,QAAiB,KAAK,UAAU,KAAK,MAAM,CAAC;AAAA,IAC1D,EAAE;AACF,UAAMA,KAAG,UAAU,YAAY,UAAU,MAAM,GAAG,OAAO;AAAA,EAC3D,OAAO;AACL,UAAMA,KAAG,UAAU,YAAY,KAAK,UAAU,QAAQ,MAAM,CAAC,GAAG,OAAO;AAAA,EACzE;AACF;AAEO,SAAS,aAAqB;AACnC,MAAI,QAAQ,IAAI,kBAAkB;AAChC,WAAO,QAAQ,IAAI;AAAA,EACrB;AACA,QAAM,OACJ,QAAQ,IAAI,QAAQ,QAAQ,IAAI,eAAe,QAAQ,IAAI;AAC7D,SAAOC,OAAK,KAAK,MAAM,UAAU;AACnC;;;ACpHA,eAAsB,iBACpB,MACA,QACmC;AACnC,MAAI;AACF,UAAM,WAAW,eAAe,MAAM,MAAM;AAG5C,UAAM,SAAS,MAAM,SAAS,aAAa;AAAA,MACzC,OAAO,gBAAgB,IAAI;AAAA,MAC3B,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,MAC1C,WAAW;AAAA,IACb,CAAC;AAED,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO,gBAAgB,IAAI;AAAA,IAC7B;AAAA,EACF,SAAS,OAAO;AACd,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAClD;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,MAA0B;AACjD,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,YAAM,IAAI,MAAM,qBAAqB,IAAI,EAAE;AAAA,EAC/C;AACF;;;AChDA,OAAOC,UAAQ;AACf,OAAOC,YAAU;AACjB,OAAOC,eAAc;AAYrB,IAAMC,eAAc;AAEb,IAAM,mBAAN,MAAuB;AAAA,EACpB;AAAA,EACA;AAAA,EACA,oBAAmC;AAAA,EAE3C,YAAY,QAAgB;AAC1B,SAAK,KAAK,IAAID,UAAS,MAAM;AAC7B,SAAK,UAAUD,OAAK,QAAQ,MAAM;AAClC,SAAK,GAAG,OAAO,oBAAoB;AACnC,SAAK,GAAG,OAAO,mBAAmB;AAClC,SAAK,WAAW;AAAA,EAClB;AAAA,EAEQ,aAAmB;AACzB,SAAK,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAeZ;AAED,UAAM,OAAO,KAAK,GAAG,OAAO,wBAAwB;AACpD,QAAI,CAAC,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,YAAY,GAAG;AAC9C,WAAK,GAAG,KAAK,yEAAyE;AAAA,IACxF;AAAA,EACF;AAAA,EAEA,MAAM,OAA6B;AACjC,UAAM,OAAO,KAAK,GACf;AAAA,MACC;AAAA,IACF,EACC,IAAI;AAWP,WAAO,KAAK,IAAI,CAAC,OAAO;AAAA,MACtB,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,UAAU,EAAE;AAAA,MACZ,gBAAgB,EAAE;AAAA,MAClB,UAAU,EAAE,YAAY;AAAA,MACxB,OAAO,EAAE,SAAS;AAAA,MAClB,QAAQ,EAAE,SAAS,KAAK,MAAM,EAAE,MAAM,IAAI;AAAA,IAC5C,EAAE;AAAA,EACJ;AAAA,EAEA,MAAM,IAAI,IAAuC;AAC/C,UAAM,MAAM,KAAK,GACd,QAAQ,uCAAuC,EAC/C,IAAI,EAAE;AAUT,QAAI,CAAC,IAAK,QAAO;AAEjB,WAAO;AAAA,MACL,IAAI,IAAI;AAAA,MACR,MAAM,IAAI;AAAA,MACV,UAAU,IAAI;AAAA,MACd,gBAAgB,IAAI;AAAA,MACpB,UAAU,IAAI,YAAY;AAAA,MAC1B,OAAO,IAAI,SAAS;AAAA,MACpB,QAAQ,IAAI,SAAS,KAAK,MAAM,IAAI,MAAM,IAAI;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,MAAc,UAAuC;AAChE,UAAM,KAAK,OAAO,WAAW;AAC7B,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAM,UAAU,WACZA,OAAK,QAAQ,QAAQ,IACrBA,OAAK,KAAK,KAAK,SAAS,YAAY,EAAE;AAG1C,UAAM,aAAaA,OAAK,KAAK,SAASE,YAAW;AACjD,UAAMH,KAAG,MAAM,YAAY,EAAE,WAAW,KAAK,CAAC;AAG9C,UAAM,aAAaC,OAAK,KAAK,YAAY,WAAW;AACpD,QAAI;AACF,YAAMD,KAAG,OAAO,UAAU;AAAA,IAC5B,QAAQ;AACN,YAAMA,KAAG;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,SAAK,GACF;AAAA,MACC;AAAA,IACF,EACC,IAAI,IAAI,MAAM,SAAS,GAAG;AAE7B,WAAO,EAAE,IAAI,MAAM,UAAU,SAAS,gBAAgB,IAAI;AAAA,EAC5D;AAAA,EAEA,MAAM,OACJ,IACA,SACe;AACf,UAAM,OAAiB,CAAC;AACxB,UAAM,SAAoB,CAAC;AAE3B,QAAI,QAAQ,SAAS,QAAW;AAC9B,WAAK,KAAK,UAAU;AACpB,aAAO,KAAK,QAAQ,IAAI;AAAA,IAC1B;AACA,QAAI,QAAQ,aAAa,QAAW;AAClC,WAAK,KAAK,cAAc;AACxB,aAAO,KAAK,QAAQ,QAAQ;AAAA,IAC9B;AACA,QAAI,QAAQ,UAAU,QAAW;AAC/B,WAAK,KAAK,WAAW;AACrB,aAAO,KAAK,QAAQ,KAAK;AAAA,IAC3B;AACA,QAAI,QAAQ,WAAW,QAAW;AAChC,WAAK,KAAK,YAAY;AACtB,aAAO,KAAK,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,IAC5C;AAEA,QAAI,KAAK,WAAW,EAAG;AAEvB,WAAO,KAAK,EAAE;AACd,SAAK,GACF,QAAQ,yBAAyB,KAAK,KAAK,IAAI,CAAC,eAAe,EAC/D,IAAI,GAAG,MAAM;AAAA,EAClB;AAAA,EAEA,MAAM,QAAQ,YAAqC;AACjD,UAAM,SAAS,KAAK,GAAG;AAAA,MACrB;AAAA,IACF;AACA,UAAM,cAAc,KAAK,GAAG,YAAY,MAAM;AAC5C,eAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,eAAO,IAAI,GAAG,WAAW,CAAC,CAAC;AAAA,MAC7B;AAAA,IACF,CAAC;AACD,gBAAY;AAAA,EACd;AAAA,EAEA,MAAM,OAAO,IAA2B;AACtC,SAAK,GAAG,QAAQ,qCAAqC,EAAE,IAAI,EAAE;AAAA,EAC/D;AAAA,EAEA,MAAM,KAAK,IAAuC;AAChD,UAAM,YAAY,MAAM,KAAK,IAAI,EAAE;AACnC,QAAI,CAAC,UAAW,QAAO;AAEvB,SAAK,GACF,QAAQ,yDAAyD,EACjE,KAAI,oBAAI,KAAK,GAAE,YAAY,GAAG,EAAE;AAEnC,SAAK,oBAAoB;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,uBAAsC;AACpC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,qBAAgD;AACpD,QAAI,CAAC,KAAK,kBAAmB,QAAO;AACpC,WAAO,KAAK,IAAI,KAAK,iBAAiB;AAAA,EACxC;AAAA,EAEA,MAAM,WAAW,eAAoD;AACnE,UAAM,aAAaC,OAAK,KAAK,eAAeE,cAAa,WAAW;AACpE,QAAI;AACF,aAAO,MAAMH,KAAG,SAAS,YAAY,OAAO;AAAA,IAC9C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,eAAuB,SAAgC;AACvE,UAAM,aAAaC,OAAK,KAAK,eAAeE,cAAa,WAAW;AACpE,UAAMH,KAAG,MAAMC,OAAK,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5D,UAAMD,KAAG,UAAU,YAAY,SAAS,OAAO;AAAA,EACjD;AAAA,EAEA,MAAM,iBAAiB,SAA8C;AACnE,UAAM,aAAaC,OAAK,KAAK,SAAS,WAAW;AACjD,QAAI;AACF,aAAO,MAAMD,KAAG,SAAS,YAAY,OAAO;AAAA,IAC9C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,kBAAkB,SAAiB,SAAgC;AACvE,UAAMA,KAAG,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AAC3C,UAAMA,KAAG,UAAUC,OAAK,KAAK,SAAS,WAAW,GAAG,SAAS,OAAO;AAAA,EACtE;AAAA,EAEA,iBAAiB,eAA+B;AAC9C,WAAOA,OAAK,KAAK,eAAeE,cAAa,aAAa;AAAA,EAC5D;AAAA,EAEA,oBAAoB,SAAgC;AAClD,UAAM,MAAM,KAAK,GACd,QAAQ,mEAAmE,EAC3E,IAAI,OAAO;AACd,WAAO,KAAK,gBAAgB;AAAA,EAC9B;AAAA,EAEA,oBAAoB,SAAiB,aAA2B;AAC9D,SAAK,GACF,QAAQ,qFAAqF,EAC7F,IAAI,SAAS,WAAW;AAAA,EAC7B;AAAA,EAEA,QAAc;AACZ,SAAK,GAAG,MAAM;AAAA,EAChB;AACF;;;AChQA,OAAOC,eAAc;AAmBd,IAAM,eAAN,MAAmB;AAAA,EAChB;AAAA,EAER,YAAY,QAAgB;AAC1B,SAAK,KAAK,IAAIA,UAAS,MAAM;AAC7B,SAAK,GAAG,OAAO,oBAAoB;AACnC,SAAK,WAAW;AAAA,EAClB;AAAA,EAEQ,aAAmB;AACzB,SAAK,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAmBZ;AAAA,EAIH;AAAA,EAEA,eAA0B;AACxB,WAAO,KAAK,GACT;AAAA,MACC;AAAA,IACF,EACC,IAAI;AAAA,EACT;AAAA,EAEA,WAAW,IAAwC;AACjD,UAAM,UAAU,KAAK,GAClB;AAAA,MACC;AAAA,IACF,EACC,IAAI,EAAE;AAET,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,OAAO,KAAK,GACf;AAAA,MACC;AAAA,IACF,EACC,IAAI,EAAE;AAET,UAAM,WAAsB,KAAK,IAAI,CAAC,OAAO;AAAA,MAC3C,MAAM,EAAE;AAAA,MACR,SAAS,KAAK,MAAM,EAAE,OAAO;AAAA,IAC/B,EAAE;AAEF,WAAO,EAAE,GAAG,SAAS,SAAS;AAAA,EAChC;AAAA,EAEA,cAAc,IAAY,OAAgB,iBAA0B,OAAgB,SAAgC;AAClH,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAK,GACF;AAAA,MACC;AAAA,IACF,EACC,IAAI,IAAI,SAAS,YAAY,KAAK,KAAK,mBAAmB,MAAM,SAAS,GAAG,WAAW,IAAI;AAE9F,WAAO,EAAE,IAAI,OAAO,SAAS,YAAY,WAAW,KAAK,WAAW,KAAK,iBAAiB,OAAO,QAAQ;AAAA,EAC3G;AAAA,EAEA,aAAa,WAAmB,UAAqB,SAA6B;AAEhF,UAAM,SAAS,KAAK,GACjB,QAAQ,qCAAqC,EAC7C,IAAI,SAAS;AAEhB,QAAI,CAAC,QAAQ;AACX,WAAK,cAAc,WAAW,QAAW,QAAW,QAAW,OAAO;AAAA,IACxE;AAGA,UAAM,cAAc,KAAK,GAAG,YAAY,MAAM;AAC5C,WAAK,GACF,QAAQ,2CAA2C,EACnD,IAAI,SAAS;AAEhB,YAAM,SAAS,KAAK,GAAG;AAAA,QACrB;AAAA,MACF;AAEA,YAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,iBAAW,OAAO,UAAU;AAC1B,eAAO;AAAA,UACL;AAAA,UACA,IAAI;AAAA,UACJ,KAAK,UAAU,IAAI,OAAO;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAEA,WAAK,GACF,QAAQ,iDAAiD,EACzD,IAAI,KAAK,SAAS;AAAA,IACvB,CAAC;AAED,gBAAY;AAAA,EACd;AAAA,EAEA,YAAY,WAA8B;AACxC,UAAM,OAAO,KAAK,GACf;AAAA,MACC;AAAA,IACF,EACC,IAAI,SAAS;AAEhB,WAAO,KAAK,IAAI,CAAC,OAAO;AAAA,MACtB,MAAM,EAAE;AAAA,MACR,SAAS,KAAK,MAAM,EAAE,OAAO;AAAA,IAC/B,EAAE;AAAA,EACJ;AAAA,EAEA,cAAc,IAAkB;AAC9B,SAAK,GAAG,QAAQ,mCAAmC,EAAE,IAAI,EAAE;AAAA,EAC7D;AAAA,EAEA,YAAY,IAAY,OAAqB;AAC3C,SAAK,GACF,QAAQ,4CAA4C,EACpD,IAAI,OAAO,EAAE;AAAA,EAClB;AAAA,EAEA,QAAc;AACZ,SAAK,GAAG,MAAM;AAAA,EAChB;AACF;;;AChKA,OAAOC,eAAc;AACrB,OAAOC,UAAQ;AAQR,SAAS,uBAAuB,QAAsB;AAE3D,MAAI,CAACC,KAAG,WAAW,MAAM,GAAG;AAC1B,WAAO,MAAM,wCAAwC,MAAM,IAAI,WAAW;AAC1E;AAAA,EACF;AAEA,QAAM,KAAK,IAAIC,UAAS,MAAM;AAE9B,MAAI;AAEF,UAAM,UAAU,GACb,QAAQ,6BAA6B,EACrC,IAAI;AAEP,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,MAAM,yCAAyC,MAAM,IAAI,WAAW;AAC3E,SAAG,MAAM;AACT;AAAA,IACF;AAEA,UAAM,qBAAqB,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,mBAAmB;AAC7E,UAAM,WAAW,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AACvD,UAAM,aAAa,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS;AAE3D,QAAI,cAAc;AAGlB,QAAI,CAAC,oBAAoB;AACvB,aAAO,KAAK,mDAAmD,MAAM,IAAI,WAAW;AACpF,SAAG,KAAK,wDAAwD;AAChE,oBAAc;AACd,aAAO,KAAK,yCAAoC,WAAW;AAAA,IAC7D;AAGA,QAAI,CAAC,UAAU;AACb,aAAO,KAAK,uCAAuC,MAAM,IAAI,WAAW;AACxE,SAAG,KAAK,yDAAyD;AACjE,oBAAc;AACd,aAAO,KAAK,6BAAwB,WAAW;AAAA,IACjD;AAGA,QAAI,CAAC,YAAY;AACf,aAAO,KAAK,yCAAyC,MAAM,IAAI,WAAW;AAC1E,SAAG,KAAK,8CAA8C;AACtD,oBAAc;AACd,aAAO,KAAK,+BAA0B,WAAW;AAAA,IACnD;AAGA,QAAI,CAAC,oBAAoB;AACvB,SAAG;AAAA,QACD;AAAA,MACF;AACA,aAAO,KAAK,uCAAkC,WAAW;AAAA,IAC3D;AAEA,QAAI,aAAa;AACf,aAAO,KAAK,2BAA2B,MAAM,IAAI,WAAW;AAAA,IAC9D,OAAO;AACL,aAAO,MAAM,4BAA4B,MAAM,IAAI,WAAW;AAAA,IAChE;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,wBAAwB,MAAM,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MACnF;AAAA,IACF;AACA,UAAM;AAAA,EACR,UAAE;AACA,OAAG,MAAM;AAAA,EACX;AACF;AAMO,SAAS,qBAAqB,YAA+C;AAClF,SAAO,KAAK,0BAA0B,WAAW,MAAM,iBAAiB,WAAW;AAEnF,MAAI,eAAe;AACnB,MAAI,aAAa;AAEjB,aAAW,aAAa,YAAY;AAClC,UAAM,SAAS,GAAG,UAAU,QAAQ;AACpC,QAAI;AACF,6BAAuB,MAAM;AAC7B;AAAA,IACF,SAAS,KAAK;AACZ;AACA,aAAO;AAAA,QACL,+BAA+B,UAAU,QAAQ,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QACtG;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,sBAAsB,YAAY,gBAAgB,UAAU;AAAA,IAC5D;AAAA,EACF;AAEA,MAAI,aAAa,GAAG;AAClB,UAAM,IAAI,MAAM,wBAAwB,UAAU,eAAe;AAAA,EACnE;AACF;;;ACpHA,OAAOC,UAAQ;AACf,OAAOC,YAAU;AA4BjB,eAAsB,gBACpB,QACA,iBAC4B;AAC5B,QAAM,WAA6B,CAAC;AACpC,QAAM,YAAY,oBAAI,IAAY;AAClC,QAAM,WAAW,oBAAI,IAGnB;AAEF,aAAW,SAAS,QAAQ;AAE1B,QAAI,MAAM,SAAS,OAAO;AACxB,iBAAW,YAAY,MAAM,SAAS,OAAO;AAC3C,cAAM,MAAM,wBAAwB,QAAQ;AAC5C,iBAAS,KAAK,GAAG;AACjB,kBAAU,IAAI,IAAI,IAAI;AAEtB,iBAAS,IAAI,IAAI,MAAM,OAAO,MAAM,kBAAkB;AACpD,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,MAAM,cAAc;AACtB,UAAI;AACF,cAAM,YAAY,UAAU,MAAM,IAAI;AACtC,cAAM,MAAM,MAAM,OAAO;AACzB,cAAM,YAAa,IAAI,SAAS,CAAC;AAEjC,mBAAW,MAAM,WAAW;AAC1B,mBAAS,KAAK;AAAA,YACZ,MAAM,GAAG;AAAA,YACT,aAAa,GAAG;AAAA,YAChB,aAAa,GAAG;AAAA,UAClB,CAAC;AACD,oBAAU,IAAI,GAAG,IAAI;AAErB,mBAAS,IAAI,GAAG,MAAM,OAAO,MAAM,mBAAmB;AACpD,gBAAI;AACF,oBAAM,SAAS,MAAM,GAAG,QAAQ,MAAM;AAAA,gBACpC;AAAA,gBACA,WAAW,MAAM,SAAS;AAAA,cAC5B,CAAC;AACD,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS,OAAO;AAAA,gBAChB,SAAS,OAAO;AAAA,cAClB;AAAA,YACF,SAAS,KAAK;AACZ,qBAAO;AAAA,gBACL,YAAY;AAAA,gBACZ,SAAS,oBAAoB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,gBAC7E,SAAS;AAAA,cACX;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,uCAAuC,MAAM,SAAS,IAAI,KAAK,GAAG;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,UAAU,WAAW,SAAS;AACzC;AAKA,SAAS,wBACP,UACgB;AAChB,QAAM,aAAsC,CAAC;AAC7C,QAAM,WAAqB,CAAC;AAE5B,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,SAAS,KAAK,GAAG;AACzD,eAAW,GAAG,IAAI;AAAA,MAChB,MAAM,MAAM;AAAA,MACZ,aAAa,MAAM;AAAA,IACrB;AACA,QAAI,MAAM,MAAM;AACd,MAAC,WAAW,GAAG,EAA8B,OAAO,MAAM;AAAA,IAC5D;AACA,QAAI,MAAM,aAAa,OAAO;AAC5B,eAAS,KAAK,GAAG;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,SAAS;AAAA,IACf,aAAa,SAAS;AAAA,IACtB,aAAa;AAAA,MACX,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAUA,eAAe,gBACb,UACA,MACA,OACA,iBACA,eACqB;AACrB,MAAI;AAEF,UAAM,aAAa,MAAM,mBAAmB,OAAO,eAAe;AAGlE,UAAM,MAAM;AAAA,MACV,SAAS,QAAQ;AAAA,MACjB;AAAA,MACA;AAAA,IACF;AAGA,UAAM,SAAS,SAAS,QAAQ,SAC5B,oBAAoB,SAAS,QAAQ,QAAQ,MAAM,UAAU,IAC7D;AAGJ,UAAM,UAAkC,CAAC;AACzC,QAAI,SAAS,QAAQ,SAAS;AAC5B,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,SAAS,QAAQ,OAAO,GAAG;AACnE,gBAAQ,GAAG,IAAI,oBAAoB,OAAO,MAAM,UAAU;AAAA,MAC5D;AAAA,IACF;AACA,QAAI,CAAC,QAAQ,cAAc,KAAK,WAAW,OAAO;AAChD,cAAQ,cAAc,IAAI;AAAA,IAC5B;AAGA,QAAI;AACJ,QAAI,SAAS,QAAQ,MAAM;AACzB,aAAO,oBAAoB,SAAS,QAAQ,MAAM,MAAM,UAAU;AAAA,IACpE;AAEA,WAAO;AAAA,MACL,eAAe,MAAM,IAAI,IAAI,MAAM,GAAG,GAAG,CAAC;AAAA,MAC1C;AAAA,IACF;AAGA,UAAM,WAAW,MAAM,MAAM,KAAK;AAAA,MAChC;AAAA,MACA;AAAA,MACA,MAAM,WAAW,QAAQ,OAAO;AAAA,MAChC,QAAQ,YAAY,QAAQ,GAAM;AAAA,IACpC,CAAC;AAED,UAAM,UAAU,MAAM,SAAS,KAAK;AAEpC,QAAI,CAAC,SAAS,IAAI;AAChB,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,SAAS,QAAQ,SAAS,MAAM,IAAI,SAAS,UAAU,KAAK,QAAQ,MAAM,GAAG,GAAI,CAAC;AAAA,QAClF,SAAS;AAAA,MACX;AAAA,IACF;AAIA,UAAM,UAAUC,OAAK,KAAK,eAAe,OAAO;AAChD,UAAMC,KAAG,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AAE3C,UAAM,SAAS,cAAc,OAAO;AACpC,UAAM,MAAM,SAAS,SAAS;AAC9B,UAAM,WAAW,GAAG,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG;AACtD,UAAM,WAAWD,OAAK,KAAK,SAAS,QAAQ;AAC5C,UAAMC,KAAG,UAAU,UAAU,SAAS,OAAO;AAE7C,UAAM,UAAU,qBAAqB,SAAS,MAAM;AAEpD,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS;AAAA,QACP,wBAAwB,QAAQ;AAAA,QAChC,SAAS,YAAY,QAAQ,MAAM,CAAC;AAAA,QACpC;AAAA,QACA;AAAA,QACA;AAAA,MACF,EAAE,KAAK,IAAI;AAAA,IACb;AAAA,EACF,SAAS,KAAK;AACZ,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS,oBAAoB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MAC7E,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAEA,SAAS,cAAc,SAA0B;AAC/C,QAAM,UAAU,QAAQ,UAAU;AAClC,SAAO,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,GAAG;AAC1D;AAEA,SAAS,YAAY,OAAuB;AAC1C,MAAI,QAAQ,KAAM,QAAO,GAAG,KAAK;AACjC,MAAI,QAAQ,OAAO,KAAM,QAAO,IAAI,QAAQ,MAAM,QAAQ,CAAC,CAAC;AAC5D,SAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,CAAC,CAAC;AAC9C;AAEA,SAAS,qBAAqB,SAAiB,QAAyB;AACtE,MAAI,CAAC,QAAQ;AACX,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,WAAO,UAAU,MAAM,MAAM;AAAA;AAAA,EAAe,MAAM,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,EAC1E;AAEA,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,OAAO;AAGjC,QAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,YAAM,QAAQ,OAAO;AACrB,YAAM,SAAS,OAAO,CAAC;AACvB,YAAM,UAAU,UAAU,OAAO,WAAW,WACxC,OAAO,KAAK,MAAM,IAClB,CAAC;AACL,aAAO;AAAA,QACL,uBAAuB,KAAK;AAAA,QAC5B,QAAQ,SAAS,IAAI,YAAY,QAAQ,KAAK,IAAI,CAAC,KAAK;AAAA,QACxD,QAAQ,IAAI,WAAW,KAAK,UAAU,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,KAAK;AAAA,MACrE,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAAA,IAC7B;AAGA,QAAI,OAAO,WAAW,YAAY,WAAW,MAAM;AACjD,YAAM,OAAO,OAAO,KAAK,MAAM;AAE/B,YAAM,WAAW,KAAK,KAAK,CAAC,MAAM,MAAM,QAAQ,OAAO,CAAC,CAAC,CAAC;AAC1D,UAAI,UAAU;AACZ,cAAM,MAAM,OAAO,QAAQ;AAC3B,cAAM,SAAS,IAAI,CAAC;AACpB,cAAM,UAAU,UAAU,OAAO,WAAW,YAAY,WAAW,OAC/D,OAAO,KAAK,MAAM,IAClB,CAAC;AACL,eAAO;AAAA,UACL,4BAA4B,KAAK,MAAM,UAAU,KAAK,KAAK,IAAI,CAAC;AAAA,UAChE,YAAY,QAAQ,MAAM,IAAI,MAAM;AAAA,UACpC,QAAQ,SAAS,IAAI,YAAY,QAAQ,KAAK,IAAI,CAAC,KAAK;AAAA,UACxD,IAAI,SAAS,IAAI,WAAW,KAAK,UAAU,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,KAAK;AAAA,QACvE,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAAA,MAC7B;AAEA,aAAO,4BAA4B,KAAK,MAAM,UAAU,KAAK,KAAK,IAAI,CAAC;AAAA,IACzE;AAEA,WAAO,iBAAiB,OAAO,MAAM;AAAA,EACvC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAe,mBACb,OACA,iBAC8B;AAC9B,QAAM,SAAS,oBAAI,IAAoB;AAEvC,MAAI,CAAC,MAAM,oBAAoB,CAAC,gBAAiB,QAAO;AAExD,aAAW,QAAQ,MAAM,iBAAiB,aAAa;AACrD,QAAI,KAAK,SAAS,UAAU;AAC1B,YAAM,OAAO,qBAAqB,MAAM,SAAS,MAAM,KAAK,EAAE;AAC9D,YAAM,cAAc,MAAM,gBAAgB,IAAI,KAAK,WAAW;AAC9D,UAAI,aAAa;AACf,eAAO,IAAI,sBAAsB,WAAW;AAAA,MAC9C;AACA,YAAM,eAAe,MAAM,gBAAgB,IAAI,KAAK,YAAY;AAChE,UAAI,cAAc;AAChB,eAAO,IAAI,uBAAuB,YAAY;AAAA,MAChD;AAAA,IACF,WAAW,KAAK,YAAY,KAAK,QAAQ;AAEvC,YAAM,cAAc,uBAAuB,MAAM,SAAS,MAAM,KAAK,IAAI,KAAK,OAAO;AACrF,YAAM,MAAM,MAAM,gBAAgB,IAAI,WAAW;AACjD,YAAM,YAAY,MAAM,KAAK,MAAM,GAAG,IAA6B,CAAC;AACpE,UAAI,UAAU,SAAS,GAAG;AACxB,mBAAW,SAAS,KAAK,QAAQ;AAC/B,gBAAM,MAAM;AAAA,YACV,MAAM,SAAS;AAAA,YACf,KAAK;AAAA,YACL,UAAU,CAAC,EAAE;AAAA,YACb,MAAM;AAAA,YACN,KAAK;AAAA,UACP;AACA,gBAAM,QAAQ,MAAM,gBAAgB,IAAI,GAAG;AAC3C,cAAI,OAAO;AACT,mBAAO,IAAI,cAAc,MAAM,GAAG,IAAI,KAAK;AAAA,UAC7C;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,KAAK,QAAQ;AACtB,iBAAW,SAAS,KAAK,QAAQ;AAC/B,cAAM,MAAM;AAAA,UACV,MAAM,SAAS;AAAA,UACf,KAAK;AAAA,UACL,MAAM;AAAA,UACN,KAAK;AAAA,QACP;AACA,cAAM,QAAQ,MAAM,gBAAgB,IAAI,GAAG;AAC3C,YAAI,OAAO;AACT,iBAAO,IAAI,cAAc,MAAM,GAAG,IAAI,KAAK;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAUA,SAAS,oBACP,UACA,MACA,YACQ;AACR,SAAO,SAAS,QAAQ,oBAAoB,CAAC,OAAO,QAAgB;AAElE,QAAI,IAAI,WAAW,aAAa,KAAK,IAAI,WAAW,SAAS,GAAG;AAC9D,YAAM,QAAQ,WAAW,IAAI,GAAG;AAChC,UAAI,MAAO,QAAO;AAClB,aAAO;AAAA,IACT;AAGA,UAAM,WAAW,KAAK,GAAG;AACzB,QAAI,aAAa,QAAW;AAC1B,aAAO,OAAO,aAAa,WACvB,WACA,KAAK,UAAU,QAAQ;AAAA,IAC7B;AAEA,WAAO;AAAA,EACT,CAAC;AACH;;;ACtYO,SAAS,wBACd,WACA,OACA,UACA,aACA,OACQ;AACR,QAAM,SAAS,IAAI,gBAAgB;AAAA,IACjC,WAAW;AAAA,IACX,cAAc;AAAA,IACd,eAAe;AAAA,IACf;AAAA,IACA,aAAa,MAAM,cAAc,YAAY;AAAA,IAC7C,QAAQ;AAAA,EACV,CAAC;AAED,MAAI,MAAM,QAAQ,QAAQ;AACxB,WAAO,IAAI,SAAS,MAAM,OAAO,KAAK,GAAG,CAAC;AAAA,EAC5C;AAEA,SAAO,GAAG,MAAM,gBAAgB,IAAI,OAAO,SAAS,CAAC;AACvD;AAKA,eAAsB,wBACpB,WACA,cACA,OACA,UACA,cACA,MACA,aACA,iBACe;AACf,QAAM,OAAO,IAAI,gBAAgB;AAAA,IAC/B,YAAY;AAAA,IACZ;AAAA,IACA,cAAc;AAAA,IACd,WAAW;AAAA,IACX,eAAe;AAAA,EACjB,CAAC;AAED,QAAM,MAAM,MAAM,MAAM,MAAM,UAAU;AAAA,IACtC,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,oCAAoC;AAAA,IAC/D,MAAM,KAAK,SAAS;AAAA,EACtB,CAAC;AAED,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAM,IAAI,MAAM,0BAA0B,IAAI,MAAM,MAAM,IAAI,EAAE;AAAA,EAClE;AAEA,QAAM,OAAQ,MAAM,IAAI,KAAK;AAO7B,QAAM,OAAO,qBAAqB,WAAW,YAAY;AACzD,QAAM,gBAAgB,IAAI,KAAK,aAAa,KAAK,YAAY;AAE7D,MAAI,KAAK,eAAe;AACtB,UAAM,gBAAgB,IAAI,KAAK,cAAc,KAAK,aAAa;AAAA,EACjE;AAEA,MAAI,KAAK,YAAY;AACnB,UAAM,YAAY,KAAK,IAAI,IAAI,KAAK,aAAa;AACjD,UAAM,gBAAgB,IAAI,KAAK,WAAW,OAAO,SAAS,CAAC;AAAA,EAC7D;AACF;AAKA,eAAsB,kBACpB,WACA,cACA,iBACe;AACf,QAAM,OAAO,qBAAqB,WAAW,YAAY;AACzD,QAAM,gBAAgB,OAAO,KAAK,WAAW;AAC7C,QAAM,gBAAgB,OAAO,KAAK,YAAY;AAC9C,QAAM,gBAAgB,OAAO,KAAK,SAAS;AAC7C;;;AC9FA,OAAOC,aAAY;AACnB,OAAOC,eAAc;AAWrB,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB;AAC1B,IAAM,mBAAmB,CAAC,KAAQ,KAAQ,KAAS,KAAS,IAAS;AAK9D,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EACA,QAA8C;AAAA,EAC9C,UAAU;AAAA,EACV,WAA+B;AAAA,EAC/B,gBAAgC,CAAC;AAAA,EAEzC,YAAY,QAAgB;AAC1B,SAAK,KAAK,IAAIC,UAAS,MAAM;AAC7B,SAAK,GAAG,OAAO,oBAAoB;AACnC,SAAK,WAAW;AAAA,EAClB;AAAA,EAEQ,aAAmB;AACzB,SAAK,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAqBZ;AAAA,EACH;AAAA,EAEA,YAAY,UAA6B;AACvC,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,QAAQ,SAA6B;AACnC,SAAK,cAAc,KAAK,OAAO;AAAA,EACjC;AAAA,EAEQ,KAAK,OAAwB;AACnC,eAAW,WAAW,KAAK,eAAe;AACxC,UAAI;AACF,gBAAQ,KAAK;AAAA,MACf,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,QAAI,KAAK,QAAS;AAClB,SAAK,UAAU;AACf,WAAO,KAAK,wBAAwB,MAAM;AAG1C,UAAM,OAAO,KAAK,KAAK;AACvB,eAAW,OAAO,MAAM;AACtB,UAAI,CAAC,IAAI,QAAS;AAClB,YAAM,QAAQ,KAAK,SAAS,IAAI,EAAE;AAClC,UAAI,CAAC,SAAS,MAAM,gBAAgB,MAAM;AACxC,cAAM,SAAS,mBAAmB,IAAI,QAAQ;AAC9C,aAAK,YAAY,IAAI,IAAI,EAAE,aAAa,OAAO,CAAC;AAAA,MAClD;AAAA,IACF;AAEA,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,OAAa;AACX,SAAK,UAAU;AACf,QAAI,KAAK,OAAO;AACd,mBAAa,KAAK,KAAK;AACvB,WAAK,QAAQ;AAAA,IACf;AACA,WAAO,KAAK,wBAAwB,MAAM;AAAA,EAC5C;AAAA,EAEQ,eAAqB;AAC3B,QAAI,CAAC,KAAK,QAAS;AAEnB,QAAI,KAAK,OAAO;AACd,mBAAa,KAAK,KAAK;AACvB,WAAK,QAAQ;AAAA,IACf;AAGA,UAAM,MAAM,KAAK,GACd;AAAA,MACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMF,EACC,IAAI;AAEP,QAAI,CAAC,IAAK;AAEV,UAAM,UAAU,KAAK,IAAI,GAAG,IAAI,iBAAiB,KAAK,IAAI,CAAC;AAC3D,UAAM,eAAe,KAAK,IAAI,SAAS,kBAAkB;AAEzD,SAAK,QAAQ,WAAW,MAAM;AAC5B,WAAK,KAAK;AAAA,IACZ,GAAG,YAAY;AAAA,EACjB;AAAA,EAEA,MAAc,OAAsB;AAClC,QAAI,CAAC,KAAK,QAAS;AAEnB,UAAM,MAAM,KAAK,IAAI;AAGrB,UAAM,UAAU,KAAK,GAClB;AAAA,MACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMF,EACC,IAAI,GAAG;AAEV,eAAW,EAAE,OAAO,KAAK,SAAS;AAChC,YAAM,KAAK,WAAW,MAAM;AAAA,IAC9B;AAEA,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,MAAc,WAAW,OAA8B;AACrD,UAAM,MAAM,KAAK,OAAO,KAAK;AAC7B,QAAI,CAAC,OAAO,CAAC,KAAK,SAAU;AAE5B,UAAM,QAAQ,KAAK,SAAS,KAAK;AACjC,QAAI,OAAO,eAAe,KAAK,IAAI,IAAI,MAAM,cAAc,mBAAmB;AAC5E;AAAA,IACF;AAEA,SAAK,KAAK;AAAA,MACR,MAAM;AAAA,MACN,OAAO,IAAI;AAAA,MACX,SAAS,IAAI;AAAA,IACf,CAAC;AAED,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,SAAS,GAAG;AAEtC,WAAK,YAAY,OAAO;AAAA,QACtB,aAAa,KAAK,IAAI;AAAA,QACtB,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,mBAAmB;AAAA,QACnB,aAAa,mBAAmB,IAAI,QAAQ;AAAA,MAC9C,CAAC;AAED,WAAK,KAAK;AAAA,QACR,MAAM;AAAA,QACN,OAAO,IAAI;AAAA,QACX,SAAS,IAAI;AAAA,QACb;AAAA,MACF,CAAC;AAED,aAAO,KAAK,aAAa,IAAI,IAAI,eAAe,MAAM;AAAA,IACxD,SAAS,KAAK;AACZ,YAAM,WAAW,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAChE,YAAM,iBAAiB,OAAO,qBAAqB,KAAK;AACxD,YAAM,aAAa,KAAK,IAAI,gBAAgB,GAAG,iBAAiB,SAAS,CAAC;AAC1E,YAAM,YAAY,iBAAiB,UAAU;AAE7C,WAAK,YAAY,OAAO;AAAA,QACtB,aAAa,KAAK,IAAI;AAAA,QACtB,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,mBAAmB;AAAA,QACnB,aAAa,KAAK,IAAI,IAAI;AAAA,MAC5B,CAAC;AAED,WAAK,KAAK;AAAA,QACR,MAAM;AAAA,QACN,OAAO,IAAI;AAAA,QACX,SAAS,IAAI;AAAA,QACb,OAAO;AAAA,MACT,CAAC;AAED,aAAO;AAAA,QACL,aAAa,IAAI,IAAI,aAAa,aAAa,aAAa,QAAQ;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,IAAI,OAA+B;AACjC,UAAM,KAAKC,QAAO,WAAW;AAC7B,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AAEnC,UAAM,MAAe;AAAA,MACnB;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM,WAAW;AAAA,MAC1B,UAAU,MAAM;AAAA,MAChB,QAAQ,MAAM;AAAA,MACd,UAAU,MAAM,YAAY,CAAC;AAAA,MAC7B,aAAa,MAAM;AAAA,MACnB,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAEA,SAAK,GACF;AAAA,MACC;AAAA;AAAA,IAEF,EACC;AAAA,MACC,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI,UAAU,IAAI;AAAA,MAClB,KAAK,UAAU,IAAI,QAAQ;AAAA,MAC3B,IAAI;AAAA,MACJ,KAAK,UAAU,IAAI,QAAQ;AAAA,MAC3B,IAAI,eAAe;AAAA,MACnB,IAAI;AAAA,MACJ,IAAI;AAAA,IACN;AAGF,UAAM,SAAS,IAAI,UAAU,mBAAmB,IAAI,QAAQ,IAAI;AAChE,SAAK,YAAY,IAAI,EAAE,aAAa,OAAO,CAAC;AAE5C,SAAK,KAAK,EAAE,MAAM,SAAS,OAAO,IAAI,SAAS,IAAI,KAAK,CAAC;AAEzD,QAAI,KAAK,QAAS,MAAK,aAAa;AAEpC,WAAO;AAAA,EACT;AAAA,EAEA,OACE,IACA,SACgB;AAChB,UAAM,WAAW,KAAK,OAAO,EAAE;AAC/B,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,OAAiB,CAAC,gBAAgB;AACxC,UAAM,SAAoB,EAAC,oBAAI,KAAK,GAAE,YAAY,CAAC;AAEnD,QAAI,QAAQ,SAAS,QAAW;AAC9B,WAAK,KAAK,UAAU;AACpB,aAAO,KAAK,QAAQ,IAAI;AAAA,IAC1B;AACA,QAAI,QAAQ,YAAY,QAAW;AACjC,WAAK,KAAK,aAAa;AACvB,aAAO,KAAK,QAAQ,UAAU,IAAI,CAAC;AAAA,IACrC;AACA,QAAI,QAAQ,aAAa,QAAW;AAClC,WAAK,KAAK,cAAc;AACxB,aAAO,KAAK,KAAK,UAAU,QAAQ,QAAQ,CAAC;AAAA,IAC9C;AACA,QAAI,QAAQ,WAAW,QAAW;AAChC,WAAK,KAAK,YAAY;AACtB,aAAO,KAAK,QAAQ,MAAM;AAAA,IAC5B;AACA,QAAI,QAAQ,aAAa,QAAW;AAClC,WAAK,KAAK,cAAc;AACxB,aAAO,KAAK,KAAK,UAAU,QAAQ,QAAQ,CAAC;AAAA,IAC9C;AAEA,WAAO,KAAK,EAAE;AACd,SAAK,GACF,QAAQ,wBAAwB,KAAK,KAAK,IAAI,CAAC,eAAe,EAC9D,IAAI,GAAG,MAAM;AAGhB,QAAI,QAAQ,aAAa,UAAa,QAAQ,YAAY,QAAW;AACnE,YAAM,UAAU,KAAK,OAAO,EAAE;AAC9B,YAAM,SAAS,QAAQ,UAAU,mBAAmB,QAAQ,QAAQ,IAAI;AACxE,WAAK,YAAY,IAAI,EAAE,aAAa,QAAQ,mBAAmB,EAAE,CAAC;AAAA,IACpE;AAEA,QAAI,KAAK,QAAS,MAAK,aAAa;AAEpC,WAAO,KAAK,OAAO,EAAE;AAAA,EACvB;AAAA,EAEA,OAAO,IAAqB;AAC1B,UAAM,MAAM,KAAK,OAAO,EAAE;AAC1B,QAAI,CAAC,IAAK,QAAO;AAEjB,SAAK,GAAG,QAAQ,oCAAoC,EAAE,IAAI,EAAE;AAC5D,SAAK,KAAK,EAAE,MAAM,WAAW,OAAO,IAAI,SAAS,IAAI,KAAK,CAAC;AAE3D,QAAI,KAAK,QAAS,MAAK,aAAa;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,IAA4B;AACjC,UAAM,MAAM,KAAK,GACd,QAAQ,sCAAsC,EAC9C,IAAI,EAAE;AAET,WAAO,MAAM,SAAS,GAAG,IAAI;AAAA,EAC/B;AAAA,EAEA,KAAK,aAAiC;AACpC,QAAI;AACJ,QAAI,aAAa;AACf,aAAO,KAAK,GACT;AAAA,QACC;AAAA,MACF,EACC,IAAI,WAAW;AAAA,IACpB,OAAO;AACL,aAAO,KAAK,GACT,QAAQ,kDAAkD,EAC1D,IAAI;AAAA,IACT;AACA,WAAO,KAAK,IAAI,QAAQ;AAAA,EAC1B;AAAA,EAEA,SAAS,OAAoC;AAC3C,UAAM,MAAM,KAAK,GACd,QAAQ,gDAAgD,EACxD,IAAI,KAAK;AASZ,QAAI,CAAC,IAAK,QAAO;AAEjB,WAAO;AAAA,MACL,OAAO,IAAI;AAAA,MACX,aAAa,IAAI;AAAA,MACjB,aAAa,IAAI;AAAA,MACjB,YAAY,IAAI;AAAA,MAChB,WAAW,IAAI;AAAA,MACf,mBAAmB,IAAI;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,IAA2B;AACtC,UAAM,KAAK,WAAW,EAAE;AACxB,QAAI,KAAK,QAAS,MAAK,aAAa;AAAA,EACtC;AAAA,EAEQ,YACN,OACA,SACM;AACN,UAAM,WAAW,KAAK,SAAS,KAAK;AAEpC,QAAI,UAAU;AACZ,YAAM,OAAiB,CAAC;AACxB,YAAM,SAAoB,CAAC;AAE3B,UAAI,QAAQ,gBAAgB,QAAW;AACrC,aAAK,KAAK,oBAAoB;AAC9B,eAAO,KAAK,QAAQ,WAAW;AAAA,MACjC;AACA,UAAI,QAAQ,gBAAgB,QAAW;AACrC,aAAK,KAAK,oBAAoB;AAC9B,eAAO,KAAK,QAAQ,WAAW;AAAA,MACjC;AACA,UAAI,QAAQ,eAAe,QAAW;AACpC,aAAK,KAAK,iBAAiB;AAC3B,eAAO,KAAK,QAAQ,UAAU;AAAA,MAChC;AACA,UAAI,QAAQ,cAAc,QAAW;AACnC,aAAK,KAAK,gBAAgB;AAC1B,eAAO,KAAK,QAAQ,SAAS;AAAA,MAC/B;AACA,UAAI,QAAQ,sBAAsB,QAAW;AAC3C,aAAK,KAAK,wBAAwB;AAClC,eAAO,KAAK,QAAQ,iBAAiB;AAAA,MACvC;AAEA,UAAI,KAAK,SAAS,GAAG;AACnB,eAAO,KAAK,KAAK;AACjB,aAAK,GACF;AAAA,UACC,8BAA8B,KAAK,KAAK,IAAI,CAAC;AAAA,QAC/C,EACC,IAAI,GAAG,MAAM;AAAA,MAClB;AAAA,IACF,OAAO;AACL,WAAK,GACF;AAAA,QACC;AAAA;AAAA,MAEF,EACC;AAAA,QACC;AAAA,QACA,QAAQ,eAAe;AAAA,QACvB,QAAQ,eAAe;AAAA,QACvB,QAAQ,cAAc;AAAA,QACtB,QAAQ,aAAa;AAAA,QACrB,QAAQ,qBAAqB;AAAA,MAC/B;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,SAAK,KAAK;AACV,SAAK,GAAG,MAAM;AAAA,EAChB;AACF;AAgBA,SAAS,SAAS,KAA0B;AAC1C,SAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,MAAM,IAAI;AAAA,IACV,SAAS,IAAI,YAAY;AAAA,IACzB,UAAU,KAAK,MAAM,IAAI,QAAQ;AAAA,IACjC,QAAQ,IAAI;AAAA,IACZ,UAAU,KAAK,MAAM,IAAI,QAAQ;AAAA,IACjC,aAAa,IAAI,gBAAgB;AAAA,IACjC,WAAW,IAAI;AAAA,IACf,WAAW,IAAI;AAAA,EACjB;AACF;;;ACjdA,OAAOC,aAAY;AAWnB,IAAM,SAAS,KAAK,KAAK,KAAK;AAEvB,IAAM,gBAAN,MAAoB;AAAA,EACjB,QAAQ,oBAAI,IAAsB;AAAA,EAE1C,OACE,MACA,OACA,SACU;AACV,SAAK,aAAa;AAElB,UAAM,KAAKA,QAAO,WAAW;AAC7B,UAAM,WAAW,YAAY,IAAI;AACjC,UAAM,WAAqB;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,KAAK,IAAI;AAAA,IACtB;AACA,SAAK,MAAM,IAAI,IAAI,QAAQ;AAC3B,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,IAAkC;AACpC,UAAM,WAAW,KAAK,MAAM,IAAI,EAAE;AAClC,QAAI,YAAY,KAAK,IAAI,IAAI,SAAS,YAAY,QAAQ;AACxD,WAAK,MAAM,OAAO,EAAE;AACpB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,OAAmB;AACjB,SAAK,aAAa;AAClB,WAAO,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC,EAAE;AAAA,MACrC,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE;AAAA,IAC5B;AAAA,EACF;AAAA,EAEA,OAAO,IAAqB;AAC1B,WAAO,KAAK,MAAM,OAAO,EAAE;AAAA,EAC7B;AAAA,EAEQ,eAAqB;AAC3B,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,CAAC,IAAI,QAAQ,KAAK,KAAK,OAAO;AACvC,UAAI,MAAM,SAAS,YAAY,QAAQ;AACrC,aAAK,MAAM,OAAO,EAAE;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,YAAY,MAAgC;AACnD,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;;;ACnFA,OAAOC,eAAc;AAsBd,SAAS,aACd,aACA,cACA,SACQ;AACR,QAAM,YAAa,cAAc,MAAa,QAAQ;AACtD,QAAM,aAAc,eAAe,MAAa,QAAQ;AACxD,SAAO,KAAK,OAAO,YAAY,cAAc,GAAS,IAAI;AAC5D;AAEO,IAAM,aAAN,MAAiB;AAAA,EACd;AAAA,EACA;AAAA,EAER,YAAY,QAAgB,YAAwB;AAClD,SAAK,KAAK,IAAIC,UAAS,MAAM;AAC7B,SAAK,GAAG,OAAO,oBAAoB;AACnC,SAAK,aAAa;AAClB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEQ,aAAmB;AACzB,SAAK,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAUZ;AAAA,EACH;AAAA,EAEA,OACE,UACA,OACA,aACA,cACM;AACN,QAAI,UAAU,KAAK,WAAW,WAAW,UAAU,KAAK;AACxD,QAAI,CAAC,SAAS;AAEZ,YAAM,MAAM,kBAAkB,QAAQ,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK;AACnE,UAAI,KAAK,mBAAmB,QAAQ,KAAK,oBAAoB,MAAM;AACjE,kBAAU,EAAE,OAAO,IAAI,iBAAiB,QAAQ,IAAI,iBAAiB;AAAA,MACvE;AAAA,IACF;AACA,UAAM,UAAU,UACZ,aAAa,aAAa,cAAc,OAAO,IAC/C;AACJ,SAAK,GACF;AAAA,MACC;AAAA;AAAA,IAEF,EACC,IAAI,UAAU,OAAO,aAAa,cAAc,OAAO;AAAA,EAC5D;AAAA,EAEA,WAAW,QAAsD;AAC/D,UAAM,QAAQ,KAAK,YAAY,MAAM;AACrC,UAAM,MAAM,KAAK,GACd;AAAA,MACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQF,EACC,IAAI,KAAK;AACZ,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,OAAe,IAA8D;AACtF,UAAM,QAAQ,oBAAI,KAAK;AACvB,UAAM,QAAQ,MAAM,QAAQ,IAAI,IAAI;AACpC,UAAM,OAAO,KAAK,GACf;AAAA,MACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQF,EACC,IAAI,MAAM,YAAY,CAAC;AAC1B,WAAO;AAAA,EACT;AAAA,EAEQ,YAAY,QAAgD;AAClE,UAAM,MAAM,oBAAI,KAAK;AACrB,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,YAAI,SAAS,GAAG,GAAG,GAAG,CAAC;AACvB;AAAA,MACF,KAAK,UAAU;AACb,cAAM,MAAM,IAAI,OAAO;AACvB,YAAI,QAAQ,IAAI,QAAQ,IAAI,GAAG;AAC/B,YAAI,SAAS,GAAG,GAAG,GAAG,CAAC;AACvB;AAAA,MACF;AAAA,MACA,KAAK;AACH,YAAI,QAAQ,CAAC;AACb,YAAI,SAAS,GAAG,GAAG,GAAG,CAAC;AACvB;AAAA,IACJ;AACA,WAAO,IAAI,YAAY;AAAA,EACzB;AACF;;;ACxIA,OAAOC,eAAc;AAYd,IAAM,aAAN,MAAiB;AAAA,EACd;AAAA,EAER,YAAY,QAAgB;AAC1B,SAAK,KAAK,IAAIA,UAAS,MAAM;AAC7B,SAAK,GAAG,OAAO,oBAAoB;AACnC,SAAK,WAAW;AAAA,EAClB;AAAA,EAEQ,aAAmB;AACzB,SAAK,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAWZ;AAAA,EACH;AAAA,EAEA,KAAK,UAAmC;AACtC,UAAM,QAAQ,WACV,mEACA;AACJ,UAAM,OAAQ,WACV,KAAK,GAAG,QAAQ,KAAK,EAAE,IAAI,QAAQ,IACnC,KAAK,GAAG,QAAQ,KAAK,EAAE,IAAI;AAS/B,WAAO,KAAK,IAAI,CAAC,OAAO;AAAA,MACtB,IAAI,EAAE;AAAA,MACN,UAAU,EAAE;AAAA,MACZ,SAAS,EAAE;AAAA,MACX,OAAO,EAAE;AAAA,MACT,iBAAiB,EAAE;AAAA,MACnB,kBAAkB,EAAE;AAAA,MACpB,WAAW,EAAE;AAAA,IACf,EAAE;AAAA,EACJ;AAAA,EAEA,OACE,UACA,SACA,OACA,iBACA,kBACc;AACd,UAAM,KAAK,OAAO,WAAW;AAC7B,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAK,GACF;AAAA,MACC;AAAA;AAAA,IAEF,EACC,IAAI,IAAI,UAAU,SAAS,OAAO,iBAAiB,kBAAkB,GAAG;AAC3E,WAAO,EAAE,IAAI,UAAU,SAAS,OAAO,iBAAiB,kBAAkB,WAAW,IAAI;AAAA,EAC3F;AAAA,EAEA,QAAQ,UAAkB,SAAuB;AAC/C,SAAK,GACF,QAAQ,gEAAgE,EACxE,IAAI,UAAU,OAAO;AAAA,EAC1B;AAAA,EAEA,cACE,UACA,SACA,iBACA,kBACM;AACN,SAAK,GACF;AAAA,MACC;AAAA,IACF,EACC,IAAI,iBAAiB,kBAAkB,UAAU,OAAO;AAAA,EAC7D;AAAA,EAEA,WAAW,UAAkB,SAA2D;AACtF,UAAM,MAAM,KAAK,GACd,QAAQ,wGAAwG,EAChH,IAAI,UAAU,OAAO;AACxB,QAAI,CAAC,IAAK,QAAO;AACjB,WAAO,EAAE,OAAO,IAAI,oBAAoB,QAAQ,IAAI,oBAAoB;AAAA,EAC1E;AACF;;;AC1GA,OAAOC,eAAc;AAWrB,IAAM,oBAAgF;AAAA,EACpF,EAAE,MAAM,aAAa,SAAS,gCAAgC,UAAU,UAAU;AAAA,EAClF,EAAE,MAAM,gBAAgB,SAAS,oCAAoC,UAAU,cAAc;AAAA,EAC7F,EAAE,MAAM,eAAe,SAAS,yCAAyC,UAAU,UAAU;AAAA,EAC7F,EAAE,MAAM,WAAW,SAAS,6BAA6B,UAAU,cAAc;AAAA,EACjF,EAAE,MAAM,cAAc,SAAS,6BAA6B,UAAU,UAAU;AAClF;AAEO,IAAM,gBAAN,MAAoB;AAAA,EACjB;AAAA,EAER,YAAY,QAAgB;AAC1B,SAAK,KAAK,IAAIA,UAAS,MAAM;AAC7B,SAAK,GAAG,OAAO,oBAAoB;AACnC,SAAK,WAAW;AAAA,EAClB;AAAA,EAEQ,aAAmB;AACzB,SAAK,GAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KASZ;AAGD,UAAM,QAAQ,KAAK,GAChB,QAAQ,8CAA8C,EACtD,IAAI;AAEP,QAAI,MAAM,QAAQ,GAAG;AACnB,YAAM,SAAS,KAAK,GAAG;AAAA,QACrB;AAAA,MACF;AACA,YAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,iBAAW,KAAK,mBAAmB;AACjC,eAAO,IAAI,OAAO,WAAW,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,KAAK,GAAG;AAAA,MACzE;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAyB;AACvB,UAAM,OAAO,KAAK,GACf;AAAA,MACC;AAAA,IACF,EACC,IAAI;AASP,WAAO,KAAK,IAAI,CAAC,OAAO;AAAA,MACtB,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,SAAS,EAAE;AAAA,MACX,UAAU,EAAE;AAAA,MACZ,WAAW,EAAE;AAAA,MACb,WAAW,EAAE;AAAA,IACf,EAAE;AAAA,EACJ;AAAA,EAEA,IAAI,IAAmC;AACrC,UAAM,MAAM,KAAK,GACd;AAAA,MACC;AAAA,IACF,EACC,IAAI,EAAE;AAST,QAAI,CAAC,IAAK,QAAO;AAEjB,WAAO;AAAA,MACL,IAAI,IAAI;AAAA,MACR,MAAM,IAAI;AAAA,MACV,SAAS,IAAI;AAAA,MACb,UAAU,IAAI;AAAA,MACd,WAAW,IAAI;AAAA,MACf,WAAW,IAAI;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,OAAO,MAAc,SAAiB,UAAmC;AACvE,UAAM,KAAK,OAAO,WAAW;AAC7B,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAK,GACF;AAAA,MACC;AAAA,IACF,EACC,IAAI,IAAI,MAAM,SAAS,YAAY,WAAW,KAAK,GAAG;AAEzD,WAAO,EAAE,IAAI,MAAM,SAAS,UAAU,YAAY,WAAW,WAAW,KAAK,WAAW,IAAI;AAAA,EAC9F;AAAA,EAEA,OAAO,IAAY,MAA6F;AAC9G,UAAM,WAAW,KAAK,IAAI,EAAE;AAC5B,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAM,OAAO,KAAK,QAAQ,SAAS;AACnC,UAAM,UAAU,KAAK,WAAW,SAAS;AACzC,UAAM,WAAW,KAAK,YAAY,SAAS;AAE3C,SAAK,GACF;AAAA,MACC;AAAA,IACF,EACC,IAAI,MAAM,SAAS,UAAU,KAAK,EAAE;AAEvC,WAAO,EAAE,IAAI,MAAM,SAAS,UAAU,WAAW,SAAS,WAAW,WAAW,IAAI;AAAA,EACtF;AAAA,EAEA,OAAO,IAAkB;AACvB,SAAK,GAAG,QAAQ,2CAA2C,EAAE,IAAI,EAAE;AAAA,EACrE;AACF;","names":["crypto","crypto","fs","path","fs","path","fs","path","fs","path","fs","path","path","fs","fs","path","path","fs","fs","path","require","exec","exec","fs","MAX_CONTENT","crypto","crypto","fs","fs","path","fs","path","fs","path","fs","path","instance","exec","path","fs","execFile","fs","path","fs","path","execFile","fs","crypto","fs","path","fs","path","fs","path","Database","CORTASK_DIR","Database","Database","fs","fs","Database","fs","path","path","fs","crypto","Database","Database","crypto","crypto","Database","Database","Database","Database"]}
1
+ {"version":3,"sources":["../src/providers/openai-compatible.ts","../src/models/definitions.ts","../src/providers/anthropic.ts","../src/providers/openai.ts","../src/providers/google.ts","../src/providers/moonshot.ts","../src/providers/grok.ts","../src/providers/openrouter.ts","../src/providers/minimax.ts","../src/providers/ollama.ts","../src/providers/index.ts","../src/agent/runner.ts","../src/agent/system-prompt.ts","../src/logging/logger.ts","../src/agent/tools/read-file.ts","../src/agent/tools/write-file.ts","../src/agent/tools/list-files.ts","../src/agent/tools/bash.ts","../src/agent/tools/web-fetch.ts","../src/agent/tools/web-search.ts","../src/agent/tools/questionnaire.ts","../src/agent/tools/memory.ts","../src/agent/tools/show-file.ts","../src/agent/tools/data-file.ts","../src/data/parser.ts","../src/cron/schedule.ts","../src/agent/tools/cron.ts","../src/agent/tools/artifact.ts","../src/agent/tools/browser-manager.ts","../src/agent/tools/browser.ts","../src/agent/tools/subagent.ts","../src/agent/subagent/types.ts","../src/agent/subagent/registry.ts","../src/agent/tools/switch-workspace.ts","../src/agent/tools/skill.ts","../src/skills/writer.ts","../src/skills/loader.ts","../src/skills/credential-schema.ts","../src/skills/installer.ts","../src/agent/tools/index.ts","../src/credentials/store.ts","../src/config/schema.ts","../src/onboarding/validator.ts","../src/workspace/manager.ts","../src/session/store.ts","../src/session/migrate.ts","../src/skills/tools.ts","../src/skills/oauth2.ts","../src/cron/service.ts","../src/artifacts/store.ts","../src/usage/store.ts","../src/models/store.ts","../src/templates/store.ts"],"sourcesContent":["import OpenAI from \"openai\";\nimport type {\n LLMProvider,\n GenerateTextParams,\n GenerateTextResult,\n StreamChunk,\n EmbedParams,\n EmbedResult,\n ModelInfo,\n Message,\n ToolDefinition,\n ToolCall,\n} from \"./types.js\";\nimport { getModelDefinitions } from \"../models/definitions.js\";\n\nexport function toOpenAIMessages(\n messages: Message[],\n systemPrompt?: string,\n): OpenAI.ChatCompletionMessageParam[] {\n const result: OpenAI.ChatCompletionMessageParam[] = [];\n\n if (systemPrompt) {\n result.push({ role: \"system\", content: systemPrompt });\n }\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue;\n\n if (typeof msg.content === \"string\") {\n result.push({\n role: msg.role,\n content: msg.content,\n } as OpenAI.ChatCompletionMessageParam);\n continue;\n }\n\n // Skip thinking parts — OpenAI doesn't support them\n const filteredContent = msg.content.filter((p) => p.type !== \"thinking\");\n const toolUseParts = filteredContent.filter((p) => p.type === \"tool_use\");\n if (msg.role === \"assistant\" && toolUseParts.length > 0) {\n const textContent = filteredContent\n .filter((p) => p.type === \"text\")\n .map((p) => p.text ?? \"\")\n .join(\"\");\n result.push({\n role: \"assistant\",\n content: textContent || null,\n tool_calls: toolUseParts.map((p) => ({\n id: p.toolCallId!,\n type: \"function\" as const,\n function: {\n name: p.toolName!,\n arguments: JSON.stringify(p.toolArguments ?? {}),\n },\n })),\n });\n continue;\n }\n\n const toolResultParts = filteredContent.filter((p) => p.type === \"tool_result\");\n if (toolResultParts.length > 0) {\n for (const p of toolResultParts) {\n result.push({\n role: \"tool\",\n tool_call_id: p.toolCallId!,\n content: p.text ?? \"\",\n });\n }\n continue;\n }\n\n const parts: OpenAI.ChatCompletionContentPart[] = filteredContent.map(\n (part) => {\n if (part.type === \"image\" && part.imageBase64) {\n return {\n type: \"image_url\" as const,\n image_url: {\n url: `data:${part.mimeType ?? \"image/png\"};base64,${part.imageBase64}`,\n },\n };\n }\n return { type: \"text\" as const, text: part.text ?? \"\" };\n },\n );\n result.push({\n role: msg.role,\n content: parts,\n } as OpenAI.ChatCompletionMessageParam);\n }\n\n return result;\n}\n\nexport function toOpenAITools(\n tools: ToolDefinition[],\n): OpenAI.ChatCompletionTool[] {\n return tools.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: t.inputSchema,\n },\n }));\n}\n\nexport class OpenAICompatibleProvider implements LLMProvider {\n readonly id: string;\n protected client: OpenAI;\n\n constructor(id: string, apiKey: string, baseURL?: string) {\n this.id = id;\n this.client = new OpenAI({ apiKey, baseURL });\n }\n\n async generateText(params: GenerateTextParams): Promise<GenerateTextResult> {\n const response = await this.client.chat.completions.create({\n model: params.model,\n messages: toOpenAIMessages(params.messages, params.systemPrompt),\n tools: params.tools?.length ? toOpenAITools(params.tools) : undefined,\n temperature: params.temperature,\n max_tokens: params.maxTokens,\n });\n\n const choice = response.choices[0];\n if (!choice) {\n throw new Error(`No response from ${this.id}`);\n }\n\n const content = choice.message.content ?? \"\";\n const toolCalls: ToolCall[] = (choice.message.tool_calls ?? []).map(\n (tc) => ({\n id: tc.id,\n name: tc.function.name,\n arguments: JSON.parse(tc.function.arguments),\n }),\n );\n\n const stopReason =\n choice.finish_reason === \"tool_calls\"\n ? \"tool_use\"\n : choice.finish_reason === \"length\"\n ? \"max_tokens\"\n : \"end\";\n\n return {\n content,\n toolCalls,\n usage: {\n inputTokens: response.usage?.prompt_tokens ?? 0,\n outputTokens: response.usage?.completion_tokens ?? 0,\n },\n stopReason,\n };\n }\n\n async *generateStream(\n params: GenerateTextParams,\n ): AsyncIterable<StreamChunk> {\n const stream = await this.client.chat.completions.create({\n model: params.model,\n messages: toOpenAIMessages(params.messages, params.systemPrompt),\n tools: params.tools?.length ? toOpenAITools(params.tools) : undefined,\n temperature: params.temperature,\n max_tokens: params.maxTokens,\n stream: true,\n stream_options: { include_usage: true },\n });\n\n let inputTokens = 0;\n let outputTokens = 0;\n\n for await (const chunk of stream) {\n const delta = chunk.choices[0]?.delta;\n if (!delta) {\n // Final chunk may have usage without choices\n if (chunk.usage) {\n inputTokens = chunk.usage.prompt_tokens ?? 0;\n outputTokens = chunk.usage.completion_tokens ?? 0;\n }\n continue;\n }\n\n if (delta.content) {\n yield { type: \"text\", text: delta.content };\n }\n\n if (delta.tool_calls) {\n for (const tc of delta.tool_calls) {\n if (tc.id) {\n yield {\n type: \"tool_call_start\",\n toolCall: { id: tc.id, name: tc.function?.name },\n };\n }\n if (tc.function?.arguments) {\n yield { type: \"tool_call_delta\", text: tc.function.arguments };\n }\n }\n }\n\n if (chunk.usage) {\n inputTokens = chunk.usage.prompt_tokens ?? 0;\n outputTokens = chunk.usage.completion_tokens ?? 0;\n }\n }\n\n yield {\n type: \"message_end\",\n usage: { inputTokens, outputTokens },\n };\n }\n\n async embed(params: EmbedParams): Promise<EmbedResult> {\n const response = await this.client.embeddings.create({\n model: params.model,\n input: params.inputs,\n });\n\n return {\n embeddings: response.data.map((d) => d.embedding),\n usage: { totalTokens: response.usage.total_tokens },\n };\n }\n\n async listModels(): Promise<ModelInfo[]> {\n return getModelDefinitions(this.id);\n }\n}\n","import type { ModelInfo } from \"../providers/types.js\";\n\nexport type ProviderId = \"anthropic\" | \"openai\" | \"google\" | \"moonshot\" | \"grok\" | \"openrouter\" | \"minimax\";\n\n/**\n * Hardcoded model definitions with pricing (per 1M tokens in USD).\n * OpenRouter is excluded — it fetches models from its API.\n */\nexport const MODEL_DEFINITIONS: Record<string, ModelInfo[]> = {\n anthropic: [\n { id: \"claude-opus-4-6\", name: \"Claude Opus 4.6\", contextWindow: 200000, inputPricePer1m: 15, outputPricePer1m: 75 },\n { id: \"claude-sonnet-4-5-20250929\", name: \"Claude Sonnet 4.5\", contextWindow: 200000, inputPricePer1m: 3, outputPricePer1m: 15 },\n { id: \"claude-haiku-4-5-20251001\", name: \"Claude Haiku 4.5\", contextWindow: 200000, inputPricePer1m: 0.8, outputPricePer1m: 4 },\n { id: \"claude-sonnet-4-20250514\", name: \"Claude Sonnet 4\", contextWindow: 200000, inputPricePer1m: 3, outputPricePer1m: 15 },\n ],\n openai: [\n { id: \"gpt-4.1\", name: \"GPT-4.1\", contextWindow: 1047576, inputPricePer1m: 2, outputPricePer1m: 8 },\n { id: \"gpt-4.1-mini\", name: \"GPT-4.1 Mini\", contextWindow: 1047576, inputPricePer1m: 0.4, outputPricePer1m: 1.6 },\n { id: \"gpt-4.1-nano\", name: \"GPT-4.1 Nano\", contextWindow: 1047576, inputPricePer1m: 0.1, outputPricePer1m: 0.4 },\n { id: \"gpt-4o\", name: \"GPT-4o\", contextWindow: 128000, inputPricePer1m: 2.5, outputPricePer1m: 10 },\n { id: \"gpt-4o-mini\", name: \"GPT-4o Mini\", contextWindow: 128000, inputPricePer1m: 0.15, outputPricePer1m: 0.6 },\n { id: \"o3\", name: \"o3\", contextWindow: 200000, inputPricePer1m: 10, outputPricePer1m: 40 },\n { id: \"o3-mini\", name: \"o3 Mini\", contextWindow: 200000, inputPricePer1m: 1.1, outputPricePer1m: 4.4 },\n { id: \"o4-mini\", name: \"o4 Mini\", contextWindow: 200000, inputPricePer1m: 1.1, outputPricePer1m: 4.4 },\n ],\n google: [\n { id: \"gemini-2.5-pro-preview-05-06\", name: \"Gemini 2.5 Pro\", contextWindow: 1048576, inputPricePer1m: 1.25, outputPricePer1m: 10 },\n { id: \"gemini-2.5-flash-preview-05-20\", name: \"Gemini 2.5 Flash\", contextWindow: 1048576, inputPricePer1m: 0.15, outputPricePer1m: 0.6 },\n { id: \"gemini-2.0-flash\", name: \"Gemini 2.0 Flash\", contextWindow: 1048576, inputPricePer1m: 0.1, outputPricePer1m: 0.4 },\n { id: \"gemini-2.0-flash-lite\", name: \"Gemini 2.0 Flash Lite\", contextWindow: 1048576, inputPricePer1m: 0.075, outputPricePer1m: 0.3 },\n ],\n grok: [\n { id: \"grok-3\", name: \"Grok 3\", contextWindow: 131072, inputPricePer1m: 3, outputPricePer1m: 15 },\n { id: \"grok-3-fast\", name: \"Grok 3 Fast\", contextWindow: 131072, inputPricePer1m: 5, outputPricePer1m: 25 },\n { id: \"grok-3-mini\", name: \"Grok 3 Mini\", contextWindow: 131072, inputPricePer1m: 0.3, outputPricePer1m: 0.5 },\n { id: \"grok-3-mini-fast\", name: \"Grok 3 Mini Fast\", contextWindow: 131072, inputPricePer1m: 0.6, outputPricePer1m: 4 },\n ],\n moonshot: [\n { id: \"moonshot-v1-8k\", name: \"Moonshot v1 8K\", contextWindow: 8000, inputPricePer1m: 1.5, outputPricePer1m: 2 },\n { id: \"moonshot-v1-32k\", name: \"Moonshot v1 32K\", contextWindow: 32000, inputPricePer1m: 3, outputPricePer1m: 4 },\n { id: \"moonshot-v1-128k\", name: \"Moonshot v1 128K\", contextWindow: 128000, inputPricePer1m: 8, outputPricePer1m: 10 },\n { id: \"kimi-latest\", name: \"Kimi Latest\", contextWindow: 131072, inputPricePer1m: 2, outputPricePer1m: 6 },\n ],\n minimax: [\n { id: \"MiniMax-Text-01\", name: \"MiniMax Text 01\", contextWindow: 1000000, inputPricePer1m: 1, outputPricePer1m: 5 },\n { id: \"abab6.5s-chat\", name: \"ABAB 6.5s Chat\", contextWindow: 245760, inputPricePer1m: 0.5, outputPricePer1m: 1 },\n ],\n};\n\nexport function getModelDefinitions(providerId: string): ModelInfo[] {\n return MODEL_DEFINITIONS[providerId] ?? [];\n}\n","import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n LLMProvider,\n GenerateTextParams,\n GenerateTextResult,\n StreamChunk,\n EmbedParams,\n EmbedResult,\n ModelInfo,\n Message,\n ToolDefinition,\n ToolCall,\n} from \"./types.js\";\nimport { getModelDefinitions } from \"../models/definitions.js\";\n\nfunction toAnthropicMessages(\n messages: Message[],\n): Anthropic.MessageParam[] {\n return messages\n .filter((m) => m.role !== \"system\")\n .map((m) => {\n if (typeof m.content === \"string\") {\n return {\n role: m.role as \"user\" | \"assistant\",\n content: m.content,\n };\n }\n\n const content: Anthropic.ContentBlockParam[] = m.content\n .filter((part) => part.type !== \"thinking\")\n .map((part) => {\n if (part.type === \"tool_use\") {\n return {\n type: \"tool_use\" as const,\n id: part.toolCallId!,\n name: part.toolName!,\n input: part.toolArguments ?? {},\n };\n }\n if (part.type === \"tool_result\") {\n return {\n type: \"tool_result\" as const,\n tool_use_id: part.toolCallId!,\n content: part.text ?? \"\",\n is_error: part.isError ?? false,\n };\n }\n if (part.type === \"image\" && part.imageBase64) {\n return {\n type: \"image\" as const,\n source: {\n type: \"base64\" as const,\n media_type: (part.mimeType ?? \"image/png\") as\n | \"image/png\"\n | \"image/jpeg\"\n | \"image/gif\"\n | \"image/webp\",\n data: part.imageBase64,\n },\n };\n }\n return { type: \"text\" as const, text: part.text ?? \"\" };\n });\n\n return {\n role: m.role as \"user\" | \"assistant\",\n content,\n };\n });\n}\n\nfunction toAnthropicTools(tools: ToolDefinition[]): Anthropic.Tool[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.inputSchema as Anthropic.Tool[\"input_schema\"],\n }));\n}\n\nexport class AnthropicProvider implements LLMProvider {\n readonly id = \"anthropic\";\n private client: Anthropic;\n\n constructor(apiKey: string) {\n this.client = new Anthropic({ apiKey });\n }\n\n async generateText(params: GenerateTextParams): Promise<GenerateTextResult> {\n const maxTokens = params.maxTokens ?? 16000;\n const budgetTokens = 10000;\n const useThinking = maxTokens > budgetTokens;\n const response = await this.client.messages.create({\n model: params.model,\n max_tokens: maxTokens,\n temperature: 1,\n system: params.systemPrompt,\n messages: toAnthropicMessages(params.messages),\n tools: params.tools ? toAnthropicTools(params.tools) : undefined,\n ...(useThinking ? { thinking: { type: \"enabled\", budget_tokens: budgetTokens } } : {}),\n } as Anthropic.MessageCreateParams) as Anthropic.Message;\n\n let content = \"\";\n let thinking = \"\";\n const toolCalls: ToolCall[] = [];\n\n for (const block of response.content) {\n if (block.type === \"thinking\") {\n thinking += (block as unknown as { type: \"thinking\"; thinking: string }).thinking;\n } else if (block.type === \"text\") {\n content += block.text;\n } else if (block.type === \"tool_use\") {\n toolCalls.push({\n id: block.id,\n name: block.name,\n arguments: block.input as Record<string, unknown>,\n });\n }\n }\n\n const stopReason =\n response.stop_reason === \"tool_use\"\n ? \"tool_use\"\n : response.stop_reason === \"max_tokens\"\n ? \"max_tokens\"\n : \"end\";\n\n return {\n content,\n thinking: thinking || undefined,\n toolCalls,\n usage: {\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n },\n stopReason,\n };\n }\n\n async *generateStream(\n params: GenerateTextParams,\n ): AsyncIterable<StreamChunk> {\n const maxTokens = params.maxTokens ?? 16000;\n const budgetTokens = 10000;\n const useThinking = maxTokens > budgetTokens;\n const stream = this.client.messages.stream({\n model: params.model,\n max_tokens: maxTokens,\n temperature: 1,\n system: params.systemPrompt,\n messages: toAnthropicMessages(params.messages),\n tools: params.tools ? toAnthropicTools(params.tools) : undefined,\n ...(useThinking ? { thinking: { type: \"enabled\", budget_tokens: budgetTokens } } : {}),\n } as Anthropic.MessageCreateParams);\n\n for await (const event of stream) {\n if (event.type === \"content_block_start\") {\n if (event.content_block.type === \"tool_use\") {\n yield {\n type: \"tool_call_start\",\n toolCall: {\n id: event.content_block.id,\n name: event.content_block.name,\n },\n };\n }\n } else if (event.type === \"content_block_delta\") {\n if (event.delta.type === \"thinking_delta\") {\n yield { type: \"thinking\", text: (event.delta as { type: \"thinking_delta\"; thinking: string }).thinking };\n } else if (event.delta.type === \"text_delta\") {\n yield { type: \"text\", text: event.delta.text };\n } else if (event.delta.type === \"input_json_delta\") {\n yield { type: \"tool_call_delta\", text: event.delta.partial_json };\n }\n } else if (event.type === \"content_block_stop\") {\n yield { type: \"tool_call_end\" };\n }\n }\n\n const finalMessage = await stream.finalMessage();\n yield {\n type: \"message_end\",\n usage: {\n inputTokens: finalMessage.usage.input_tokens,\n outputTokens: finalMessage.usage.output_tokens,\n },\n };\n }\n\n async embed(_params: EmbedParams): Promise<EmbedResult> {\n throw new Error(\n \"Anthropic does not support embeddings. Use OpenAI or Google for embeddings.\",\n );\n }\n\n async listModels(): Promise<ModelInfo[]> {\n return getModelDefinitions(\"anthropic\");\n }\n}\n","import { OpenAICompatibleProvider } from \"./openai-compatible.js\";\n\nexport class OpenAIProvider extends OpenAICompatibleProvider {\n constructor(apiKey: string) {\n super(\"openai\", apiKey);\n }\n}\n","import {\n GoogleGenerativeAI,\n type Content,\n type Part,\n type FunctionDeclaration,\n SchemaType,\n} from \"@google/generative-ai\";\nimport type {\n LLMProvider,\n GenerateTextParams,\n GenerateTextResult,\n StreamChunk,\n EmbedParams,\n EmbedResult,\n ModelInfo,\n Message,\n ToolDefinition,\n ToolCall,\n} from \"./types.js\";\nimport { getModelDefinitions } from \"../models/definitions.js\";\n\nfunction toGeminiContents(messages: Message[]): Content[] {\n const result: Content[] = [];\n\n for (const m of messages) {\n if (m.role === \"system\") continue;\n\n if (typeof m.content === \"string\") {\n result.push({\n role: m.role === \"assistant\" ? \"model\" : \"user\",\n parts: [{ text: m.content }],\n });\n continue;\n }\n\n const toolResultParts = m.content.filter((p) => p.type === \"tool_result\");\n if (toolResultParts.length > 0) {\n result.push({\n role: \"function\" as string,\n parts: toolResultParts.map(\n (p): Part => ({\n functionResponse: {\n name: p.toolName ?? \"unknown\",\n response: { result: p.text ?? \"\" },\n },\n }),\n ),\n });\n continue;\n }\n\n const parts: Part[] = [];\n for (const part of m.content) {\n if (part.type === \"thinking\") continue;\n if (part.type === \"tool_use\") {\n parts.push({\n functionCall: {\n name: part.toolName!,\n args: (part.toolArguments ?? {}) as Record<string, string>,\n },\n });\n } else if (part.type === \"image\" && part.imageBase64) {\n parts.push({\n inlineData: {\n mimeType: part.mimeType ?? \"image/png\",\n data: part.imageBase64,\n },\n });\n } else {\n parts.push({ text: part.text ?? \"\" });\n }\n }\n\n result.push({\n role: m.role === \"assistant\" ? \"model\" : \"user\",\n parts,\n });\n }\n\n return result;\n}\n\nfunction jsonSchemaTypeToGemini(type: string): SchemaType {\n switch (type) {\n case \"string\":\n return SchemaType.STRING;\n case \"number\":\n return SchemaType.NUMBER;\n case \"integer\":\n return SchemaType.INTEGER;\n case \"boolean\":\n return SchemaType.BOOLEAN;\n case \"array\":\n return SchemaType.ARRAY;\n case \"object\":\n return SchemaType.OBJECT;\n default:\n return SchemaType.STRING;\n }\n}\n\nfunction convertJsonSchemaToGemini(\n schema: Record<string, unknown>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n if (schema.type) {\n result.type = jsonSchemaTypeToGemini(schema.type as string);\n }\n if (schema.description) result.description = schema.description;\n if (schema.properties) {\n const props: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(\n schema.properties as Record<string, Record<string, unknown>>,\n )) {\n props[key] = convertJsonSchemaToGemini(val);\n }\n result.properties = props;\n }\n if (schema.required) result.required = schema.required;\n if (schema.items)\n result.items = convertJsonSchemaToGemini(\n schema.items as Record<string, unknown>,\n );\n return result;\n}\n\nfunction toGeminiTools(tools: ToolDefinition[]): FunctionDeclaration[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: convertJsonSchemaToGemini(t.inputSchema) as unknown as FunctionDeclaration[\"parameters\"],\n }));\n}\n\nexport class GoogleProvider implements LLMProvider {\n readonly id = \"google\";\n private client: GoogleGenerativeAI;\n\n constructor(apiKey: string) {\n this.client = new GoogleGenerativeAI(apiKey);\n }\n\n async generateText(params: GenerateTextParams): Promise<GenerateTextResult> {\n const model = this.client.getGenerativeModel({\n model: params.model,\n systemInstruction: params.systemPrompt,\n generationConfig: {\n temperature: params.temperature,\n maxOutputTokens: params.maxTokens,\n },\n tools: params.tools?.length\n ? [{ functionDeclarations: toGeminiTools(params.tools) }]\n : undefined,\n });\n\n const result = await model.generateContent({\n contents: toGeminiContents(params.messages),\n });\n\n const response = result.response;\n let content = \"\";\n const toolCalls: ToolCall[] = [];\n\n let thinking = \"\";\n for (const candidate of response.candidates ?? []) {\n for (const part of candidate.content.parts) {\n if ((part as { thought?: boolean }).thought && part.text) {\n thinking += part.text;\n } else if (part.text) {\n content += part.text;\n }\n if (part.functionCall) {\n toolCalls.push({\n id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n name: part.functionCall.name,\n arguments: (part.functionCall.args ?? {}) as Record<\n string,\n unknown\n >,\n });\n }\n }\n }\n\n const usageMeta = response.usageMetadata;\n const stopReason = toolCalls.length > 0 ? \"tool_use\" : \"end\";\n\n return {\n content,\n thinking: thinking || undefined,\n toolCalls,\n usage: {\n inputTokens: usageMeta?.promptTokenCount ?? 0,\n outputTokens: usageMeta?.candidatesTokenCount ?? 0,\n },\n stopReason,\n };\n }\n\n async *generateStream(\n params: GenerateTextParams,\n ): AsyncIterable<StreamChunk> {\n const model = this.client.getGenerativeModel({\n model: params.model,\n systemInstruction: params.systemPrompt,\n generationConfig: {\n temperature: params.temperature,\n maxOutputTokens: params.maxTokens,\n },\n tools: params.tools?.length\n ? [{ functionDeclarations: toGeminiTools(params.tools) }]\n : undefined,\n });\n\n const result = await model.generateContentStream({\n contents: toGeminiContents(params.messages),\n });\n\n let inputTokens = 0;\n let outputTokens = 0;\n\n for await (const chunk of result.stream) {\n if (chunk.usageMetadata) {\n inputTokens = chunk.usageMetadata.promptTokenCount ?? 0;\n outputTokens = chunk.usageMetadata.candidatesTokenCount ?? 0;\n }\n for (const candidate of chunk.candidates ?? []) {\n for (const part of candidate.content.parts) {\n if ((part as { thought?: boolean }).thought && part.text) {\n yield { type: \"thinking\", text: part.text };\n } else if (part.text) {\n yield { type: \"text\", text: part.text };\n }\n if (part.functionCall) {\n yield {\n type: \"tool_call_start\",\n toolCall: {\n id: `call_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n name: part.functionCall.name,\n arguments: (part.functionCall.args ?? {}) as Record<\n string,\n unknown\n >,\n },\n };\n yield { type: \"tool_call_end\" };\n }\n }\n }\n }\n\n yield {\n type: \"message_end\",\n usage: { inputTokens, outputTokens },\n };\n }\n\n async embed(params: EmbedParams): Promise<EmbedResult> {\n const model = this.client.getGenerativeModel({ model: params.model });\n\n const result = await model.batchEmbedContents({\n requests: params.inputs.map((input) => ({\n content: { role: \"user\", parts: [{ text: input }] },\n })),\n });\n\n return {\n embeddings: result.embeddings.map((e) => e.values),\n usage: { totalTokens: 0 },\n };\n }\n\n async listModels(): Promise<ModelInfo[]> {\n return getModelDefinitions(\"google\");\n }\n}\n","import { OpenAICompatibleProvider } from \"./openai-compatible.js\";\n\nexport class MoonshotProvider extends OpenAICompatibleProvider {\n constructor(apiKey: string) {\n super(\"moonshot\", apiKey, \"https://api.moonshot.cn/v1\");\n }\n}\n","import { OpenAICompatibleProvider } from \"./openai-compatible.js\";\n\nexport class GrokProvider extends OpenAICompatibleProvider {\n constructor(apiKey: string) {\n super(\"grok\", apiKey, \"https://api.x.ai/v1\");\n }\n}\n","import { OpenAICompatibleProvider } from \"./openai-compatible.js\";\nimport type { ModelInfo } from \"./types.js\";\n\ninterface OpenRouterModel {\n id: string;\n name: string;\n context_length?: number;\n pricing?: {\n prompt?: string;\n completion?: string;\n };\n}\n\nexport class OpenRouterProvider extends OpenAICompatibleProvider {\n private apiKeyValue: string;\n\n constructor(apiKey: string) {\n super(\"openrouter\", apiKey, \"https://openrouter.ai/api/v1\");\n this.apiKeyValue = apiKey;\n }\n\n async listModels(): Promise<ModelInfo[]> {\n const response = await fetch(\"https://openrouter.ai/api/v1/models\", {\n headers: { Authorization: `Bearer ${this.apiKeyValue}` },\n });\n if (!response.ok) {\n throw new Error(`OpenRouter models API error: ${response.status}`);\n }\n const data = (await response.json()) as { data: OpenRouterModel[] };\n return data.data.map((m) => ({\n id: m.id,\n name: m.name || m.id,\n contextWindow: m.context_length,\n inputPricePer1m: m.pricing?.prompt ? parseFloat(m.pricing.prompt) * 1_000_000 : undefined,\n outputPricePer1m: m.pricing?.completion ? parseFloat(m.pricing.completion) * 1_000_000 : undefined,\n }));\n }\n}\n","import { OpenAICompatibleProvider } from \"./openai-compatible.js\";\n\nexport class MiniMaxProvider extends OpenAICompatibleProvider {\n constructor(apiKey: string) {\n super(\"minimax\", apiKey, \"https://api.minimax.chat/v1\");\n }\n}\n","import type {\n LLMProvider,\n GenerateTextParams,\n GenerateTextResult,\n StreamChunk,\n EmbedParams,\n EmbedResult,\n ModelInfo,\n ToolCall,\n ToolDefinition,\n Message,\n} from \"./types.js\";\n\n// -- Ollama native API types (per https://docs.ollama.com) --\n\ninterface OllamaMessage {\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string;\n images?: string[];\n tool_calls?: OllamaToolCall[];\n tool_name?: string;\n}\n\ninterface OllamaToolCall {\n type: \"function\";\n function: {\n index: number;\n name: string;\n arguments: Record<string, unknown>;\n };\n}\n\ninterface OllamaTool {\n type: \"function\";\n function: {\n name: string;\n description: string;\n parameters: {\n type: \"object\";\n required?: string[];\n properties: Record<string, unknown>;\n };\n };\n}\n\ninterface OllamaChatRequest {\n model: string;\n messages: OllamaMessage[];\n stream: boolean;\n tools?: OllamaTool[];\n options?: { temperature?: number; num_ctx?: number };\n}\n\ninterface OllamaChatResponse {\n model: string;\n message: OllamaMessage;\n done: boolean;\n done_reason?: string;\n prompt_eval_count?: number;\n eval_count?: number;\n}\n\n// -- Convert our internal messages to Ollama format --\n\nfunction toOllamaMessages(messages: Message[], systemPrompt?: string): OllamaMessage[] {\n const result: OllamaMessage[] = [];\n\n if (systemPrompt) {\n result.push({ role: \"system\", content: systemPrompt });\n }\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue;\n\n if (typeof msg.content === \"string\") {\n result.push({ role: msg.role, content: msg.content });\n continue;\n }\n\n // Assistant message with tool calls\n const toolUseParts = msg.content.filter((p) => p.type === \"tool_use\");\n if (msg.role === \"assistant\" && toolUseParts.length > 0) {\n const textContent = msg.content\n .filter((p) => p.type === \"text\")\n .map((p) => p.text ?? \"\")\n .join(\"\");\n result.push({\n role: \"assistant\",\n content: textContent,\n tool_calls: toolUseParts.map((p, i) => ({\n type: \"function\" as const,\n function: {\n index: i,\n name: p.toolName!,\n arguments: (p.toolArguments ?? {}) as Record<string, unknown>,\n },\n })),\n });\n continue;\n }\n\n // Tool result messages — one per tool call, using tool_name\n const toolResultParts = msg.content.filter((p) => p.type === \"tool_result\");\n if (toolResultParts.length > 0) {\n for (const p of toolResultParts) {\n result.push({\n role: \"tool\",\n content: p.text ?? \"\",\n tool_name: p.toolName,\n });\n }\n continue;\n }\n\n // Regular user/assistant message (may contain images)\n const texts: string[] = [];\n const images: string[] = [];\n for (const part of msg.content) {\n if (part.type === \"image\" && part.imageBase64) {\n images.push(part.imageBase64);\n } else if (part.text) {\n texts.push(part.text);\n }\n }\n const ollamaMsg: OllamaMessage = {\n role: msg.role,\n content: texts.join(\"\"),\n };\n if (images.length > 0) {\n ollamaMsg.images = images;\n }\n result.push(ollamaMsg);\n }\n\n return result;\n}\n\nfunction toOllamaTools(tools: ToolDefinition[]): OllamaTool[] {\n return tools.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: {\n type: \"object\" as const,\n required: (t.inputSchema as { required?: string[] }).required,\n properties: (t.inputSchema as { properties?: Record<string, unknown> }).properties ?? {},\n },\n },\n }));\n}\n\nexport class OllamaProvider implements LLMProvider {\n readonly id = \"ollama\";\n private host: string;\n\n constructor(host: string) {\n this.host = host.replace(/\\/+$/, \"\");\n }\n\n async generateText(params: GenerateTextParams): Promise<GenerateTextResult> {\n const body: OllamaChatRequest = {\n model: params.model,\n messages: toOllamaMessages(params.messages, params.systemPrompt),\n stream: false,\n tools: params.tools?.length ? toOllamaTools(params.tools) : undefined,\n options: {\n ...(params.temperature != null ? { temperature: params.temperature } : {}),\n num_ctx: 16384,\n },\n };\n\n const response = await fetch(`${this.host}/api/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Ollama error: ${response.status} ${text}`);\n }\n\n const data = (await response.json()) as OllamaChatResponse;\n const msg = data.message;\n\n const toolCalls: ToolCall[] = (msg.tool_calls ?? []).map((tc, i) => ({\n id: `ollama_tc_${i}`,\n name: tc.function.name,\n arguments: tc.function.arguments,\n }));\n\n const stopReason = toolCalls.length > 0 ? \"tool_use\" : \"end\";\n\n return {\n content: msg.content ?? \"\",\n toolCalls,\n usage: {\n inputTokens: data.prompt_eval_count ?? 0,\n outputTokens: data.eval_count ?? 0,\n },\n stopReason,\n };\n }\n\n async *generateStream(params: GenerateTextParams): AsyncIterable<StreamChunk> {\n const body: OllamaChatRequest = {\n model: params.model,\n messages: toOllamaMessages(params.messages, params.systemPrompt),\n stream: true,\n tools: params.tools?.length ? toOllamaTools(params.tools) : undefined,\n options: {\n ...(params.temperature != null ? { temperature: params.temperature } : {}),\n num_ctx: 16384,\n },\n };\n\n const response = await fetch(`${this.host}/api/chat`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Ollama error: ${response.status} ${text}`);\n }\n\n const reader = response.body?.getReader();\n if (!reader) throw new Error(\"No response body from Ollama\");\n\n const decoder = new TextDecoder();\n let buffer = \"\";\n let inputTokens = 0;\n let outputTokens = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n let chunk: OllamaChatResponse;\n try {\n chunk = JSON.parse(trimmed);\n } catch {\n continue;\n }\n\n // Tool calls come as a complete object in one chunk\n if (chunk.message.tool_calls?.length) {\n for (let i = 0; i < chunk.message.tool_calls.length; i++) {\n const tc = chunk.message.tool_calls[i];\n const id = `ollama_tc_${i}`;\n yield {\n type: \"tool_call_start\",\n toolCall: { id, name: tc.function.name },\n };\n yield {\n type: \"tool_call_delta\",\n text: JSON.stringify(tc.function.arguments),\n };\n }\n continue;\n }\n\n // Text content\n if (chunk.message.content) {\n yield { type: \"text\", text: chunk.message.content };\n }\n\n // Capture usage from the final chunk\n if (chunk.done) {\n inputTokens = chunk.prompt_eval_count ?? 0;\n outputTokens = chunk.eval_count ?? 0;\n }\n }\n }\n\n // Process any remaining buffer\n if (buffer.trim()) {\n try {\n const chunk = JSON.parse(buffer.trim()) as OllamaChatResponse;\n if (chunk.message.tool_calls?.length) {\n for (let i = 0; i < chunk.message.tool_calls.length; i++) {\n const tc = chunk.message.tool_calls[i];\n yield {\n type: \"tool_call_start\",\n toolCall: { id: `ollama_tc_${i}`, name: tc.function.name },\n };\n yield {\n type: \"tool_call_delta\",\n text: JSON.stringify(tc.function.arguments),\n };\n }\n } else if (chunk.message.content) {\n yield { type: \"text\", text: chunk.message.content };\n }\n if (chunk.done) {\n inputTokens = chunk.prompt_eval_count ?? 0;\n outputTokens = chunk.eval_count ?? 0;\n }\n } catch {\n // ignore\n }\n }\n\n yield {\n type: \"message_end\",\n usage: { inputTokens, outputTokens },\n };\n }\n\n async embed(params: EmbedParams): Promise<EmbedResult> {\n const results: number[][] = [];\n let totalTokens = 0;\n\n for (const input of params.inputs) {\n const response = await fetch(`${this.host}/api/embed`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ model: params.model, input }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Ollama embed error: ${response.status} ${text}`);\n }\n\n const data = (await response.json()) as {\n embeddings: number[][];\n prompt_eval_count?: number;\n };\n results.push(...data.embeddings);\n totalTokens += data.prompt_eval_count ?? 0;\n }\n\n return { embeddings: results, usage: { totalTokens } };\n }\n\n async listModels(): Promise<ModelInfo[]> {\n const response = await fetch(`${this.host}/api/tags`);\n if (!response.ok) {\n throw new Error(`Failed to list Ollama models: ${response.statusText}`);\n }\n const data = (await response.json()) as {\n models: Array<{ name: string; size: number; details?: { parameter_size?: string } }>;\n };\n return (data.models ?? []).map((m) => ({\n id: m.name,\n name: m.name,\n inputPricePer1m: 0,\n outputPricePer1m: 0,\n }));\n }\n}\n","export * from \"./types.js\";\nexport { OpenAICompatibleProvider } from \"./openai-compatible.js\";\nexport { AnthropicProvider } from \"./anthropic.js\";\nexport { OpenAIProvider } from \"./openai.js\";\nexport { GoogleProvider } from \"./google.js\";\nexport { MoonshotProvider } from \"./moonshot.js\";\nexport { GrokProvider } from \"./grok.js\";\nexport { OpenRouterProvider } from \"./openrouter.js\";\nexport { MiniMaxProvider } from \"./minimax.js\";\nexport { OllamaProvider } from \"./ollama.js\";\n\nimport type { LLMProvider } from \"./types.js\";\nimport { AnthropicProvider } from \"./anthropic.js\";\nimport { OpenAIProvider } from \"./openai.js\";\nimport { GoogleProvider } from \"./google.js\";\nimport { MoonshotProvider } from \"./moonshot.js\";\nimport { GrokProvider } from \"./grok.js\";\nimport { OpenRouterProvider } from \"./openrouter.js\";\nimport { MiniMaxProvider } from \"./minimax.js\";\nimport { OllamaProvider } from \"./ollama.js\";\n\nexport type ProviderId = \"anthropic\" | \"openai\" | \"google\" | \"moonshot\" | \"grok\" | \"openrouter\" | \"minimax\" | \"ollama\";\n\nexport interface ProviderInfo {\n id: ProviderId;\n name: string;\n requiresApiKey: boolean;\n}\n\nexport const AVAILABLE_PROVIDERS: ProviderInfo[] = [\n { id: \"anthropic\", name: \"Anthropic (Claude)\", requiresApiKey: true },\n { id: \"openai\", name: \"OpenAI (GPT)\", requiresApiKey: true },\n { id: \"google\", name: \"Google (Gemini)\", requiresApiKey: true },\n { id: \"moonshot\", name: \"Moonshot (Kimi)\", requiresApiKey: true },\n { id: \"grok\", name: \"xAI (Grok)\", requiresApiKey: true },\n { id: \"openrouter\", name: \"OpenRouter\", requiresApiKey: true },\n { id: \"minimax\", name: \"MiniMax\", requiresApiKey: true },\n { id: \"ollama\", name: \"Ollama\", requiresApiKey: false },\n];\n\nexport function getProviderInfo(id: ProviderId): ProviderInfo | undefined {\n return AVAILABLE_PROVIDERS.find((p) => p.id === id);\n}\n\nexport function createProvider(\n id: ProviderId,\n apiKey: string,\n): LLMProvider {\n switch (id) {\n case \"anthropic\":\n return new AnthropicProvider(apiKey);\n case \"openai\":\n return new OpenAIProvider(apiKey);\n case \"google\":\n return new GoogleProvider(apiKey);\n case \"moonshot\":\n return new MoonshotProvider(apiKey);\n case \"grok\":\n return new GrokProvider(apiKey);\n case \"openrouter\":\n return new OpenRouterProvider(apiKey);\n case \"minimax\":\n return new MiniMaxProvider(apiKey);\n case \"ollama\":\n return new OllamaProvider(apiKey);\n default:\n throw new Error(`Unknown provider: ${id}`);\n }\n}\n","import crypto from \"node:crypto\";\nimport type {\n LLMProvider,\n Message,\n ContentPart,\n ToolDefinition,\n ToolCall,\n GenerateTextParams,\n ToolResult,\n} from \"../providers/types.js\";\nimport type {\n AgentRunParams,\n AgentRunResult,\n AgentStreamEvent,\n ToolHandler,\n ToolExecutionContext,\n PermissionRequest,\n QuestionnaireRequest,\n QuestionnaireResponse,\n} from \"./types.js\";\nimport { buildSystemPrompt, type SystemPromptContext } from \"./system-prompt.js\";\nimport { logger } from \"../logging/logger.js\";\n\nconst TOOL_CONCURRENCY = 5;\nconst TOOL_RESULT_HISTORY_LIMIT = 1500;\n\n/**\n * Parse JSON robustly — handles unescaped control characters inside string\n * values that LLMs sometimes produce (e.g. literal newlines in HTML content).\n */\nfunction parseToolJson(json: string): Record<string, unknown> {\n try {\n return JSON.parse(json);\n } catch {\n // Fix unescaped control characters within JSON string values\n let fixed = \"\";\n let inString = false;\n let escaped = false;\n\n for (let i = 0; i < json.length; i++) {\n const ch = json[i];\n const code = json.charCodeAt(i);\n\n if (escaped) {\n fixed += ch;\n escaped = false;\n continue;\n }\n\n if (ch === \"\\\\\" && inString) {\n fixed += ch;\n escaped = true;\n continue;\n }\n\n if (ch === '\"') {\n inString = !inString;\n fixed += ch;\n continue;\n }\n\n if (inString && code < 0x20) {\n // Escape control characters that are invalid inside JSON strings\n switch (ch) {\n case \"\\n\": fixed += \"\\\\n\"; break;\n case \"\\r\": fixed += \"\\\\r\"; break;\n case \"\\t\": fixed += \"\\\\t\"; break;\n default: fixed += \"\\\\u\" + code.toString(16).padStart(4, \"0\");\n }\n } else {\n fixed += ch;\n }\n }\n\n return JSON.parse(fixed);\n }\n}\n\n/**\n * Ensure the last assistant message's tool_use blocks have matching\n * tool_result blocks. This prevents the \"tool_use without tool_result\"\n * API error when a run is cancelled mid-stream.\n */\nfunction ensureToolResultsExist(messages: Message[]): void {\n if (messages.length === 0) return;\n\n const lastMsg = messages[messages.length - 1];\n if (lastMsg.role !== \"assistant\" || !Array.isArray(lastMsg.content)) return;\n\n const toolUseIds = lastMsg.content\n .filter((p) => p.type === \"tool_use\" && p.toolCallId)\n .map((p) => p.toolCallId!);\n\n if (toolUseIds.length === 0) return;\n\n // Check if there's already a following user message with tool_results\n // (there shouldn't be since this is the last message, but just in case)\n messages.push({\n role: \"user\",\n content: toolUseIds.map((id) => ({\n type: \"tool_result\" as const,\n toolCallId: id,\n text: \"[Cancelled]\",\n isError: true,\n })),\n });\n}\n\nfunction truncateOldToolResults(messages: Message[], startIdx: number): void {\n for (let i = 0; i < startIdx; i++) {\n const msg = messages[i];\n if (!Array.isArray(msg.content)) continue;\n for (const part of msg.content) {\n if (\n part.type === \"tool_result\" &&\n part.text &&\n part.text.length > TOOL_RESULT_HISTORY_LIMIT\n ) {\n part.text =\n part.text.slice(0, TOOL_RESULT_HISTORY_LIMIT) +\n \"\\n...(truncated — full result was processed earlier)\";\n }\n }\n }\n}\n\nasync function pLimit<T>(\n concurrency: number,\n tasks: Array<() => Promise<T>>,\n): Promise<T[]> {\n const results: T[] = new Array(tasks.length);\n let index = 0;\n\n const workers = Array.from({ length: Math.min(concurrency, tasks.length) }, async () => {\n while (index < tasks.length) {\n const i = index++;\n results[i] = await tasks[i]();\n }\n });\n\n await Promise.all(workers);\n return results;\n}\n\nexport interface AgentRunnerConfig {\n provider: LLMProvider;\n model: string;\n maxTurns: number;\n temperature?: number;\n maxTokens?: number;\n}\n\nexport interface AgentRunnerDeps {\n config: AgentRunnerConfig;\n tools: ToolHandler[];\n getWorkspacePath: () => string;\n getDataDir: () => string;\n getMemoryContent: () => Promise<string | undefined>;\n getGlobalMemoryContent: () => Promise<string | undefined>;\n getSkillPrompts: () => string[];\n getSessionMessages: (sessionId: string) => Promise<Message[]>;\n saveSessionMessages: (sessionId: string, messages: Message[]) => Promise<void>;\n channel?: { type: string; chatId: string };\n onPermissionRequest?: (req: PermissionRequest) => Promise<boolean>;\n onQuestionnaireRequest?: (\n req: QuestionnaireRequest,\n ) => Promise<QuestionnaireResponse>;\n}\n\nexport class AgentRunner {\n private deps: AgentRunnerDeps;\n\n constructor(deps: AgentRunnerDeps) {\n this.deps = deps;\n }\n\n private buildToolDefinitions(): ToolDefinition[] {\n return this.deps.tools.map((t) => t.definition);\n }\n\n private getToolHandler(name: string): ToolHandler | undefined {\n return this.deps.tools.find((t) => t.definition.name === name);\n }\n\n private async buildSystemPromptText(): Promise<string> {\n const [memoryContent, globalMemoryContent] = await Promise.all([\n this.deps.getMemoryContent(),\n this.deps.getGlobalMemoryContent(),\n ]);\n const ctx: SystemPromptContext = {\n workspacePath: this.deps.getWorkspacePath(),\n globalMemoryContent,\n memoryContent,\n skillPrompts: this.deps.getSkillPrompts(),\n toolNames: this.deps.tools.map((t) => t.definition.name),\n channel: this.deps.channel,\n };\n return buildSystemPrompt(ctx);\n }\n\n private createToolContext(sessionId: string, runId: string): ToolExecutionContext {\n return {\n workspacePath: this.deps.getWorkspacePath(),\n dataDir: this.deps.getDataDir(),\n sessionId,\n runId,\n requestPermission: async (req: PermissionRequest) => {\n if (this.deps.onPermissionRequest) {\n return this.deps.onPermissionRequest(req);\n }\n return true;\n },\n requestQuestionnaire: async (req: QuestionnaireRequest) => {\n if (this.deps.onQuestionnaireRequest) {\n return this.deps.onQuestionnaireRequest(req);\n }\n return {};\n },\n };\n }\n\n async run(params: AgentRunParams): Promise<AgentRunResult> {\n const runId = crypto.randomUUID();\n const sessionId = params.sessionId ?? crypto.randomUUID();\n const { config } = this.deps;\n\n const messages = await this.deps.getSessionMessages(sessionId);\n\n if (params.attachments?.length) {\n const parts: ContentPart[] = [\n { type: \"text\", text: params.prompt },\n ...params.attachments.map((a) => ({\n type: \"image\" as const,\n imageBase64: a.base64,\n mimeType: a.mimeType,\n })),\n ];\n messages.push({ role: \"user\", content: parts });\n } else {\n messages.push({ role: \"user\", content: params.prompt });\n }\n\n const systemPrompt = await this.buildSystemPromptText();\n const toolDefs = this.buildToolDefinitions();\n const toolContext = this.createToolContext(sessionId, runId);\n\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n const allToolCalls: ToolCall[] = [];\n let finalContent = \"\";\n\n for (let turn = 0; turn < config.maxTurns; turn++) {\n if (turn > 0) {\n truncateOldToolResults(messages, messages.length);\n }\n\n const generateParams: GenerateTextParams = {\n model: config.model,\n messages,\n systemPrompt,\n tools: toolDefs,\n temperature: config.temperature,\n maxTokens: config.maxTokens,\n };\n\n const result = await config.provider.generateText(generateParams);\n\n totalInputTokens += result.usage.inputTokens;\n totalOutputTokens += result.usage.outputTokens;\n\n logger.debug(\n `Turn ${turn}: in=${result.usage.inputTokens} out=${result.usage.outputTokens} stop=${result.stopReason}`,\n \"agent\",\n );\n\n if (result.content) {\n finalContent = result.content;\n }\n\n // Build assistant message\n if (result.content || result.thinking || result.toolCalls.length > 0) {\n const parts: ContentPart[] = [];\n if (result.thinking) {\n parts.push({ type: \"thinking\", text: result.thinking });\n }\n if (result.content) {\n parts.push({ type: \"text\", text: result.content });\n }\n for (const tc of result.toolCalls) {\n parts.push({\n type: \"tool_use\",\n toolCallId: tc.id,\n toolName: tc.name,\n toolArguments: tc.arguments,\n });\n }\n messages.push({ role: \"assistant\", content: parts });\n }\n\n // No tool calls or stop reason isn't tool_use → done\n if (result.toolCalls.length === 0 || result.stopReason !== \"tool_use\") {\n break;\n }\n\n allToolCalls.push(...result.toolCalls);\n\n // Execute tool calls with concurrency limit\n const toolResults = await pLimit(\n TOOL_CONCURRENCY,\n result.toolCalls.map((toolCall) => async () => {\n const handler = this.getToolHandler(toolCall.name);\n if (!handler) {\n return {\n toolCallId: toolCall.id,\n content: `Unknown tool: ${toolCall.name}`,\n isError: true,\n } satisfies ToolResult;\n }\n try {\n return await handler.execute(toolCall.arguments, toolContext);\n } catch (err) {\n return {\n toolCallId: toolCall.id,\n content: `Tool error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n } satisfies ToolResult;\n }\n }),\n );\n\n // Add tool results as user message\n const toolResultParts: ContentPart[] = result.toolCalls.map(\n (toolCall, i) => ({\n type: \"tool_result\" as const,\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n text: toolResults[i].content,\n isError: toolResults[i].isError,\n }),\n );\n messages.push({ role: \"user\", content: toolResultParts });\n\n // Warn when running low on turns\n const remaining = config.maxTurns - turn - 1;\n if (remaining === 2) {\n messages.push({\n role: \"user\",\n content:\n \"[System: 2 tool turns remaining. Focus on completing the task.]\",\n });\n }\n }\n\n // Ensure no dangling tool_use blocks before saving\n ensureToolResultsExist(messages);\n await this.deps.saveSessionMessages(sessionId, messages);\n\n return {\n runId,\n response: finalContent,\n toolCalls: allToolCalls,\n usage: {\n inputTokens: totalInputTokens,\n outputTokens: totalOutputTokens,\n },\n };\n }\n\n async *runStream(params: AgentRunParams): AsyncIterable<AgentStreamEvent> {\n const runId = crypto.randomUUID();\n const sessionId = params.sessionId ?? crypto.randomUUID();\n const { config } = this.deps;\n const signal = params.signal;\n\n const messages = await this.deps.getSessionMessages(sessionId);\n\n // Build user message with optional image attachments\n if (params.attachments?.length) {\n const parts: ContentPart[] = [\n { type: \"text\", text: params.prompt },\n ...params.attachments.map((a) => ({\n type: \"image\" as const,\n imageBase64: a.base64,\n mimeType: a.mimeType,\n })),\n ];\n messages.push({ role: \"user\", content: parts });\n } else {\n messages.push({ role: \"user\", content: params.prompt });\n }\n\n const systemPrompt = await this.buildSystemPromptText();\n const toolDefs = this.buildToolDefinitions();\n const toolContext = this.createToolContext(sessionId, runId);\n\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let finalContent = \"\";\n\n for (let turn = 0; turn < config.maxTurns; turn++) {\n // Check for cancellation before each turn\n if (signal?.aborted) {\n logger.debug(\"Agent run cancelled\", \"agent\");\n break;\n }\n\n if (turn > 0) {\n truncateOldToolResults(messages, messages.length);\n }\n\n const generateParams: GenerateTextParams = {\n model: config.model,\n messages,\n systemPrompt,\n tools: toolDefs,\n temperature: config.temperature,\n maxTokens: config.maxTokens,\n };\n\n // Use streaming for text output\n const parts: ContentPart[] = [];\n let currentText = \"\";\n let currentThinking = \"\";\n const toolCalls: ToolCall[] = [];\n const toolCallBuffers = new Map<number, { id: string; name: string; jsonChunks: string[] }>();\n\n // State machine for detecting <thinking> tags in text streams (fallback for non-native providers)\n let inThinkingTag = false;\n let tagBuffer = \"\";\n\n for await (const chunk of config.provider.generateStream(generateParams)) {\n if (signal?.aborted) break;\n if (chunk.type === \"thinking\" && chunk.text) {\n // Native thinking from provider (Anthropic, Gemini)\n currentThinking += chunk.text;\n yield { type: \"thinking_delta\", text: chunk.text };\n } else if (chunk.type === \"text\" && chunk.text) {\n // Process text through <thinking> tag detector for non-native providers\n let text = tagBuffer + chunk.text;\n tagBuffer = \"\";\n\n while (text.length > 0) {\n if (inThinkingTag) {\n const closeIdx = text.indexOf(\"</thinking>\");\n if (closeIdx !== -1) {\n const thinkText = text.slice(0, closeIdx);\n if (thinkText) {\n currentThinking += thinkText;\n yield { type: \"thinking_delta\", text: thinkText };\n }\n inThinkingTag = false;\n text = text.slice(closeIdx + \"</thinking>\".length);\n } else if (text.length > 11 && text.slice(-11).includes(\"<\")) {\n // Might have a partial </thinking> at the end\n const lastOpen = text.lastIndexOf(\"<\");\n const thinkText = text.slice(0, lastOpen);\n if (thinkText) {\n currentThinking += thinkText;\n yield { type: \"thinking_delta\", text: thinkText };\n }\n tagBuffer = text.slice(lastOpen);\n text = \"\";\n } else {\n currentThinking += text;\n yield { type: \"thinking_delta\", text };\n text = \"\";\n }\n } else {\n const openIdx = text.indexOf(\"<thinking>\");\n if (openIdx !== -1) {\n const before = text.slice(0, openIdx);\n if (before) {\n currentText += before;\n yield { type: \"text_delta\", text: before };\n }\n inThinkingTag = true;\n text = text.slice(openIdx + \"<thinking>\".length);\n } else if (text.length > 10 && text.slice(-10).includes(\"<\")) {\n // Might have a partial <thinking> at the end\n const lastOpen = text.lastIndexOf(\"<\");\n const before = text.slice(0, lastOpen);\n if (before) {\n currentText += before;\n yield { type: \"text_delta\", text: before };\n }\n tagBuffer = text.slice(lastOpen);\n text = \"\";\n } else {\n currentText += text;\n yield { type: \"text_delta\", text };\n text = \"\";\n }\n }\n }\n } else if (chunk.type === \"tool_call_start\" && chunk.toolCall) {\n // Flush any remaining tag buffer as text\n if (tagBuffer) {\n currentText += tagBuffer;\n yield { type: \"text_delta\", text: tagBuffer };\n tagBuffer = \"\";\n }\n const idx = toolCallBuffers.size;\n toolCallBuffers.set(idx, {\n id: chunk.toolCall.id ?? `tc_${idx}`,\n name: chunk.toolCall.name ?? \"unknown\",\n jsonChunks: [],\n });\n yield {\n type: \"tool_call_start\",\n toolName: chunk.toolCall.name,\n toolCallId: chunk.toolCall.id,\n };\n } else if (chunk.type === \"tool_call_delta\" && chunk.text) {\n const idx = toolCallBuffers.size - 1;\n const buf = toolCallBuffers.get(idx);\n if (buf) buf.jsonChunks.push(chunk.text);\n yield { type: \"tool_call_delta\", text: chunk.text };\n } else if (chunk.type === \"tool_call_end\") {\n yield { type: \"tool_call_end\" };\n } else if (chunk.type === \"message_end\" && chunk.usage) {\n totalInputTokens += chunk.usage.inputTokens;\n totalOutputTokens += chunk.usage.outputTokens;\n }\n }\n\n // Flush remaining tag buffer\n if (tagBuffer) {\n if (inThinkingTag) {\n currentThinking += tagBuffer;\n yield { type: \"thinking_delta\", text: tagBuffer };\n } else {\n currentText += tagBuffer;\n yield { type: \"text_delta\", text: tagBuffer };\n }\n }\n\n // Reconstruct tool calls from buffers\n const parseErrors: Array<{ id: string; name: string; error: string }> = [];\n for (const [, buf] of toolCallBuffers) {\n const json = buf.jsonChunks.join(\"\");\n if (!json) {\n toolCalls.push({ id: buf.id, name: buf.name, arguments: {} });\n continue;\n }\n try {\n const args = parseToolJson(json);\n toolCalls.push({ id: buf.id, name: buf.name, arguments: args });\n } catch (err) {\n parseErrors.push({\n id: buf.id,\n name: buf.name,\n error: `Invalid JSON arguments: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n }\n\n if (currentThinking) {\n parts.push({ type: \"thinking\", text: currentThinking });\n }\n if (currentText) {\n parts.push({ type: \"text\", text: currentText });\n finalContent = currentText;\n }\n // Add both valid tool calls and parse-errored ones to assistant message\n for (const tc of toolCalls) {\n parts.push({\n type: \"tool_use\",\n toolCallId: tc.id,\n toolName: tc.name,\n toolArguments: tc.arguments,\n });\n }\n for (const pe of parseErrors) {\n parts.push({\n type: \"tool_use\",\n toolCallId: pe.id,\n toolName: pe.name,\n toolArguments: {},\n });\n }\n if (parts.length > 0) {\n messages.push({ role: \"assistant\", content: parts });\n }\n\n // No tool calls and no parse errors → done\n if (toolCalls.length === 0 && parseErrors.length === 0) {\n break;\n }\n\n // Check for cancellation before executing tools\n if (signal?.aborted) {\n logger.debug(\"Agent run cancelled before tool execution\", \"agent\");\n break;\n }\n\n // Execute valid tool calls\n const toolResults = await pLimit(\n TOOL_CONCURRENCY,\n toolCalls.map((toolCall) => async () => {\n const handler = this.getToolHandler(toolCall.name);\n if (!handler) {\n return {\n toolCallId: toolCall.id,\n content: `Unknown tool: ${toolCall.name}`,\n isError: true,\n } satisfies ToolResult;\n }\n try {\n return await handler.execute(toolCall.arguments, toolContext);\n } catch (err) {\n return {\n toolCallId: toolCall.id,\n content: `Tool error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n } satisfies ToolResult;\n }\n }),\n );\n\n // Build results for parse-errored tool calls (not executed)\n const errorResults: ToolResult[] = parseErrors.map((pe) => ({\n toolCallId: pe.id,\n content: pe.error,\n isError: true,\n }));\n\n // Yield tool results and add to messages\n const allResults = [...toolResults, ...errorResults];\n const allCalls = [\n ...toolCalls,\n ...parseErrors.map((pe) => ({ id: pe.id, name: pe.name, arguments: {} })),\n ];\n\n const toolResultParts: ContentPart[] = allCalls.map((tc, i) => ({\n type: \"tool_result\" as const,\n toolCallId: tc.id,\n toolName: tc.name,\n text: allResults[i].content,\n isError: allResults[i].isError,\n }));\n\n for (let i = 0; i < allResults.length; i++) {\n yield {\n type: \"tool_result\",\n toolCallId: allCalls[i].id,\n toolName: allCalls[i].name,\n toolArgs: allCalls[i].arguments,\n toolResult: allResults[i],\n };\n }\n\n messages.push({ role: \"user\", content: toolResultParts });\n\n const remaining = config.maxTurns - turn - 1;\n if (remaining === 2) {\n messages.push({\n role: \"user\",\n content:\n \"[System: 2 tool turns remaining. Focus on completing the task.]\",\n });\n }\n }\n\n // Ensure no dangling tool_use blocks before saving\n ensureToolResultsExist(messages);\n await this.deps.saveSessionMessages(sessionId, messages);\n\n yield {\n type: \"done\",\n usage: {\n inputTokens: totalInputTokens,\n outputTokens: totalOutputTokens,\n },\n };\n }\n}\n","import type { ToolDefinition } from \"../providers/types.js\";\n\nexport interface SystemPromptContext {\n workspacePath: string;\n globalMemoryContent?: string;\n memoryContent?: string;\n skillPrompts?: string[];\n toolNames: string[];\n channel?: {\n type: string; // e.g. \"telegram\"\n chatId: string; // e.g. \"123456789\"\n };\n}\n\nexport function buildSystemPrompt(ctx: SystemPromptContext): string {\n const parts: string[] = [];\n\n parts.push(`You are Cortask, a local AI assistant that helps users manage files, automate tasks, and connect to external services.\n\nYou are working in the workspace: ${ctx.workspacePath}\n\nCurrent date and time: ${new Date().toLocaleString(\"en-US\", { weekday: \"long\", year: \"numeric\", month: \"long\", day: \"numeric\", hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\", timeZoneName: \"short\" })}\n\n## Core Capabilities\n- Read, write, and manage files within the workspace\n- Execute shell commands\n- Fetch web content and search the web\n- Schedule recurring tasks (cron jobs)\n- Use installed skills to connect to external APIs and services\n- Create artifacts (CSV, HTML, images) in chat\n\n## Guidelines\n- Always operate within the workspace directory unless explicitly asked otherwise\n- Ask for permission before writing files or executing potentially destructive commands\n- Be concise and direct in responses\n- When using tools, explain what you're doing briefly\n- If a task requires multiple steps, break it down and work through each step\n- After creating or generating a file the user would want to download (documents, images, exports, etc.), always call show_file so it appears as a downloadable card in the chat\n- When the user wants to view file contents inline (e.g. \"show me the file here\"), use the artifact tool with the path parameter to read from disk. NEVER re-output file contents as the content parameter — use path instead so it loads instantly\n- When the user shares personal info, preferences, or important context, proactively use memory_append to save it. Use global memory for user info (name, preferences), project memory for project-specific context. Don't ask — just save and briefly acknowledge.\n\n## File Organization\nWhen creating or saving files, organize them into logical subdirectories rather than dumping everything in the workspace root. Choose a clear, descriptive directory structure based on the content. For example:\n- Crawl/scrape results: \\`crawls/<source>/<YYYY-MM-DD>/\\` (e.g. \\`crawls/screaming-frog/2026-03-04/\\`)\n- Exports and reports: \\`exports/<type>/\\` or \\`reports/<YYYY-MM-DD>/\\`\n- Downloaded assets: \\`downloads/<source>/\\`\n- Generated data: \\`data/<topic>/\\`\n- Temporary/intermediate files: \\`temp/\\` — use this for any scratch files, intermediate processing artifacts, or files that are only needed briefly. Clean up when done if appropriate.\n\nUse your judgment — the goal is a clean, navigable workspace. Create directories as needed. Always use show_file after creating files so the user can access them.`);\n\n if (ctx.globalMemoryContent) {\n parts.push(`\\n## Global Memory\\nThe following is your long-term memory that applies across all projects:\\n\\n${ctx.globalMemoryContent}`);\n }\n\n if (ctx.memoryContent) {\n parts.push(`\\n## Project Memory\\nThe following is long-term memory specific to this project:\\n\\n${ctx.memoryContent}`);\n }\n\n if (ctx.skillPrompts && ctx.skillPrompts.length > 0) {\n parts.push(`\\n## Available Skills\\n${ctx.skillPrompts.join(\"\\n\\n\")}`);\n }\n\n if (ctx.channel) {\n parts.push(`\\n## Channel Context\\nThe user is messaging from **${ctx.channel.type}** (chat ID: \\`${ctx.channel.chatId}\\`). When scheduling cron jobs or reminders, use delivery_channel=\"${ctx.channel.type}\" and delivery_target=\"${ctx.channel.chatId}\" to deliver results back to them.`);\n }\n\n parts.push(`\\n## Available Tools\\n${ctx.toolNames.join(\", \")}`);\n\n return parts.join(\"\\n\");\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport type LogLevel = \"info\" | \"warn\" | \"error\" | \"debug\";\n\ninterface LogEntry {\n time: string;\n level: LogLevel;\n message: string;\n subsystem?: string;\n}\n\nclass Logger {\n private logDir: string | null = null;\n private stream: fs.WriteStream | null = null;\n private currentDate: string | null = null;\n\n init(logDir: string): void {\n this.logDir = logDir;\n fs.mkdirSync(logDir, { recursive: true });\n this.pruneOldLogs();\n }\n\n private ensureStream(): fs.WriteStream | null {\n if (!this.logDir) return null;\n\n const today = new Date().toISOString().slice(0, 10);\n if (today !== this.currentDate) {\n this.stream?.end();\n const logFile = path.join(\n this.logDir,\n `cortask-${today}.log`,\n );\n this.stream = fs.createWriteStream(logFile, { flags: \"a\" });\n this.currentDate = today;\n }\n return this.stream;\n }\n\n private write(level: LogLevel, message: string, subsystem?: string): void {\n const entry: LogEntry = {\n time: new Date().toISOString(),\n level,\n message,\n subsystem,\n };\n\n const stream = this.ensureStream();\n if (stream) {\n stream.write(JSON.stringify(entry) + \"\\n\");\n }\n }\n\n info(message: string, subsystem?: string): void {\n this.write(\"info\", message, subsystem);\n }\n\n warn(message: string, subsystem?: string): void {\n this.write(\"warn\", message, subsystem);\n }\n\n error(message: string, subsystem?: string): void {\n this.write(\"error\", message, subsystem);\n }\n\n debug(message: string, subsystem?: string): void {\n this.write(\"debug\", message, subsystem);\n }\n\n private pruneOldLogs(): void {\n if (!this.logDir) return;\n try {\n const files = fs.readdirSync(this.logDir);\n const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1000;\n for (const file of files) {\n if (!file.startsWith(\"cortask-\")) continue;\n const filePath = path.join(this.logDir, file);\n const stat = fs.statSync(filePath);\n if (stat.mtimeMs < cutoff) {\n fs.unlinkSync(filePath);\n }\n }\n } catch {\n // Non-critical\n }\n }\n\n close(): void {\n this.stream?.end();\n this.stream = null;\n }\n}\n\nexport const logger = new Logger();\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolHandler } from \"../types.js\";\n\nexport const readFileTool: ToolHandler = {\n definition: {\n name: \"read_file\",\n description:\n \"Read the contents of a file. Path is relative to the workspace root.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"File path relative to workspace root\",\n },\n },\n required: [\"path\"],\n },\n },\n async execute(args, context) {\n const filePath = path.resolve(context.workspacePath, args.path as string);\n\n // Ensure file is within workspace\n if (!filePath.startsWith(context.workspacePath)) {\n return {\n toolCallId: \"\",\n content: \"Error: Cannot read files outside the workspace\",\n isError: true,\n };\n }\n\n try {\n const content = await fs.readFile(filePath, \"utf-8\");\n return { toolCallId: \"\", content };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Error reading file: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolHandler } from \"../types.js\";\n\nexport const writeFileTool: ToolHandler = {\n definition: {\n name: \"write_file\",\n description:\n \"Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Path is relative to workspace root. Requires user permission.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"File path relative to workspace root\",\n },\n content: {\n type: \"string\",\n description: \"Content to write to the file\",\n },\n },\n required: [\"path\", \"content\"],\n },\n },\n async execute(args, context) {\n const filePath = path.resolve(context.workspacePath, args.path as string);\n\n if (!filePath.startsWith(context.workspacePath)) {\n return {\n toolCallId: \"\",\n content: \"Error: Cannot write files outside the workspace\",\n isError: true,\n };\n }\n\n const approved = await context.requestPermission({\n id: `write_${Date.now()}`,\n type: \"file_write\",\n description: `Write to file: ${args.path}`,\n details: `${(args.content as string).length} characters`,\n });\n\n if (!approved) {\n return {\n toolCallId: \"\",\n content: \"Permission denied: user rejected file write\",\n isError: true,\n };\n }\n\n try {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, args.content as string, \"utf-8\");\n return {\n toolCallId: \"\",\n content: `File written: ${args.path}`,\n };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Error writing file: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolHandler } from \"../types.js\";\n\nexport const listFilesTool: ToolHandler = {\n definition: {\n name: \"list_files\",\n description:\n \"List files and directories. Path is relative to the workspace root. Returns names with type indicators.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"Directory path relative to workspace root (default: root)\",\n },\n },\n },\n },\n async execute(args, context) {\n const dirPath = path.resolve(\n context.workspacePath,\n (args.path as string) || \".\",\n );\n\n if (!dirPath.startsWith(context.workspacePath)) {\n return {\n toolCallId: \"\",\n content: \"Error: Cannot list files outside the workspace\",\n isError: true,\n };\n }\n\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n const lines = entries.map((e) => {\n const suffix = e.isDirectory() ? \"/\" : \"\";\n return `${e.name}${suffix}`;\n });\n return {\n toolCallId: \"\",\n content: lines.length > 0 ? lines.join(\"\\n\") : \"(empty directory)\",\n };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Error listing files: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n};\n","import { exec } from \"node:child_process\";\nimport type { ToolHandler } from \"../types.js\";\n\nconst MAX_OUTPUT = 50_000;\n\nexport const bashTool: ToolHandler = {\n definition: {\n name: \"bash\",\n description:\n \"Execute a shell command in the workspace directory. Requires user permission. Output is captured and returned.\",\n inputSchema: {\n type: \"object\",\n properties: {\n command: {\n type: \"string\",\n description: \"The shell command to execute\",\n },\n },\n required: [\"command\"],\n },\n },\n async execute(args, context) {\n const command = args.command as string;\n\n const approved = await context.requestPermission({\n id: `bash_${Date.now()}`,\n type: \"bash\",\n description: `Execute command: ${command}`,\n });\n\n if (!approved) {\n return {\n toolCallId: \"\",\n content: \"Permission denied: user rejected command execution\",\n isError: true,\n };\n }\n\n return new Promise((resolve) => {\n exec(\n command,\n {\n cwd: context.workspacePath,\n timeout: 120_000,\n maxBuffer: 1024 * 1024 * 10,\n shell: process.platform === \"win32\" ? \"cmd.exe\" : \"/bin/bash\",\n },\n (error, stdout, stderr) => {\n let output = \"\";\n if (stdout) output += stdout;\n if (stderr) output += (output ? \"\\n\" : \"\") + `STDERR: ${stderr}`;\n if (error && !stderr) {\n output += (output ? \"\\n\" : \"\") + `Error: ${error.message}`;\n }\n\n if (output.length > MAX_OUTPUT) {\n output = output.slice(0, MAX_OUTPUT) + \"\\n...(truncated)\";\n }\n\n resolve({\n toolCallId: \"\",\n content: output || \"(no output)\",\n isError: !!error,\n });\n },\n );\n });\n },\n};\n","import type { ToolHandler } from \"../types.js\";\n\nconst MAX_CONTENT = 100_000;\n\nexport const webFetchTool: ToolHandler = {\n definition: {\n name: \"web_fetch\",\n description:\n \"Fetch the content of a web page. Returns the text content of the page.\",\n inputSchema: {\n type: \"object\",\n properties: {\n url: {\n type: \"string\",\n description: \"The URL to fetch\",\n },\n },\n required: [\"url\"],\n },\n },\n async execute(args) {\n const url = args.url as string;\n\n try {\n const response = await fetch(url, {\n headers: {\n \"User-Agent\": \"Cortask/0.1 (AI Assistant)\",\n Accept: \"text/html,application/json,text/plain,*/*\",\n },\n signal: AbortSignal.timeout(30_000),\n });\n\n if (!response.ok) {\n return {\n toolCallId: \"\",\n content: `HTTP ${response.status}: ${response.statusText}`,\n isError: true,\n };\n }\n\n let content = await response.text();\n if (content.length > MAX_CONTENT) {\n content = content.slice(0, MAX_CONTENT) + \"\\n...(truncated)\";\n }\n\n return { toolCallId: \"\", content };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Fetch error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n};\n","import type { ToolHandler } from \"../types.js\";\n\nconst MAX_RESULTS = 5;\n\nexport const webSearchTool: ToolHandler = {\n definition: {\n name: \"web_search\",\n description:\n \"Search the web using DuckDuckGo. Returns a list of search results with titles, URLs, and snippets.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n query: {\n type: \"string\",\n description: \"The search query\",\n },\n maxResults: {\n type: \"number\",\n description: `Maximum number of results to return (default ${MAX_RESULTS})`,\n },\n },\n required: [\"query\"],\n },\n },\n async execute(args) {\n const query = args.query as string;\n const maxResults = (args.maxResults as number) || MAX_RESULTS;\n\n try {\n // Use DuckDuckGo HTML lite (no API key needed)\n const url = `https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`;\n const response = await fetch(url, {\n headers: {\n \"User-Agent\":\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\",\n Accept: \"text/html\",\n },\n signal: AbortSignal.timeout(15_000),\n });\n\n if (!response.ok) {\n return {\n toolCallId: \"\",\n content: `Search failed: HTTP ${response.status}`,\n isError: true,\n };\n }\n\n const html = await response.text();\n const results = parseSearchResults(html, maxResults);\n\n if (results.length === 0) {\n return { toolCallId: \"\", content: \"No search results found.\" };\n }\n\n const formatted = results\n .map(\n (r, i) =>\n `${i + 1}. **${r.title}**\\n ${r.url}\\n ${r.snippet}`,\n )\n .join(\"\\n\\n\");\n\n return {\n toolCallId: \"\",\n content: `Search results for \"${query}\":\\n\\n${formatted}`,\n };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Search error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n};\n\ninterface SearchResult {\n title: string;\n url: string;\n snippet: string;\n}\n\nfunction parseSearchResults(html: string, max: number): SearchResult[] {\n const results: SearchResult[] = [];\n\n // Parse DuckDuckGo HTML lite results\n // Each result is in a <div class=\"result\"> or similar structure\n const resultBlocks = html.split(/class=\"result\\s/);\n\n for (let i = 1; i < resultBlocks.length && results.length < max; i++) {\n const block = resultBlocks[i];\n\n // Extract title from <a class=\"result__a\">\n const titleMatch = block.match(\n /class=\"result__a\"[^>]*>([^<]+)/,\n );\n const title = titleMatch?.[1]?.trim() ?? \"\";\n\n // Extract URL from href in result__a or result__url\n const urlMatch = block.match(\n /class=\"result__url\"[^>]*>([^<]+)/,\n );\n let url = urlMatch?.[1]?.trim() ?? \"\";\n if (url && !url.startsWith(\"http\")) {\n url = `https://${url}`;\n }\n\n // Fallback: extract href from the link\n if (!url) {\n const hrefMatch = block.match(/href=\"(https?:\\/\\/[^\"]+)\"/);\n url = hrefMatch?.[1] ?? \"\";\n }\n\n // Extract snippet from <a class=\"result__snippet\">\n const snippetMatch = block.match(\n /class=\"result__snippet\"[^>]*>([^<]+(?:<[^>]+>[^<]+)*)/,\n );\n let snippet = snippetMatch?.[1]?.trim() ?? \"\";\n // Strip HTML tags from snippet\n snippet = snippet.replace(/<[^>]+>/g, \"\");\n\n if (title && url) {\n results.push({ title, url, snippet });\n }\n }\n\n return results;\n}\n","import type { ToolHandler, QuestionnaireQuestion } from \"../types.js\";\n\nexport const questionnaireTool: ToolHandler = {\n definition: {\n name: \"questionnaire\",\n description:\n \"Present a multi-step questionnaire to the user to collect structured information. Use this when you need to gather multiple related pieces of information in an organized way.\",\n inputSchema: {\n type: \"object\",\n properties: {\n title: {\n type: \"string\",\n description: \"Title of the questionnaire (e.g., 'Project Setup')\",\n },\n description: {\n type: \"string\",\n description:\n \"Optional description explaining the purpose of the questionnaire\",\n },\n questions: {\n type: \"array\",\n description: \"Array of questions to ask the user\",\n items: {\n type: \"object\",\n properties: {\n id: {\n type: \"string\",\n description:\n \"Unique identifier for this question (e.g., 'framework', 'budget')\",\n },\n question: {\n type: \"string\",\n description: \"The question to ask\",\n },\n type: {\n type: \"string\",\n enum: [\"single\", \"multiple\", \"text\", \"textarea\"],\n description:\n \"Question type: 'single' (radio), 'multiple' (checkboxes), 'text' (short input), 'textarea' (long input)\",\n },\n options: {\n type: \"array\",\n description:\n \"Options for single/multiple choice questions (not needed for text/textarea)\",\n items: {\n type: \"object\",\n properties: {\n value: {\n type: \"string\",\n description: \"The value returned when selected\",\n },\n label: {\n type: \"string\",\n description: \"Display text for this option\",\n },\n description: {\n type: \"string\",\n description:\n \"Optional description explaining this option\",\n },\n },\n required: [\"value\", \"label\"],\n },\n },\n required: {\n type: \"boolean\",\n description:\n \"Whether this question must be answered (default: false)\",\n },\n placeholder: {\n type: \"string\",\n description: \"Placeholder text for text/textarea inputs\",\n },\n allowOther: {\n type: \"boolean\",\n description:\n \"For single/multiple choice: add an 'Other' option with text input\",\n },\n },\n required: [\"id\", \"question\", \"type\"],\n },\n },\n },\n required: [\"questions\"],\n },\n },\n async execute(args, context) {\n const title = (args.title as string) || \"Questionnaire\";\n const description = args.description as string | undefined;\n const questions = args.questions as QuestionnaireQuestion[];\n\n if (!questions || questions.length === 0) {\n return {\n toolCallId: \"\",\n content: \"Error: No questions provided\",\n isError: true,\n };\n }\n\n // Request the questionnaire from the user\n const responses = await context.requestQuestionnaire({\n id: `questionnaire_${Date.now()}`,\n title,\n description,\n questions,\n });\n\n // Format the responses as a readable summary\n if (Object.keys(responses).length === 0) {\n return {\n toolCallId: \"\",\n content: \"User skipped the questionnaire (no responses provided)\",\n };\n }\n\n const summary: string[] = [];\n for (const question of questions) {\n const response = responses[question.id];\n if (response !== undefined) {\n let value: string;\n if (Array.isArray(response)) {\n value = response.join(\", \");\n } else {\n value = String(response);\n }\n summary.push(`**${question.question}:** ${value}`);\n }\n }\n\n return {\n toolCallId: \"\",\n content: summary.join(\"\\n\"),\n };\n },\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\n\nconst CORTASK_DIR = \".cortask\";\n\nfunction getMemoryPath(\n scope: string,\n context: ToolExecutionContext,\n): string {\n if (scope === \"global\") {\n return path.join(context.dataDir, \"memory.md\");\n }\n return path.join(context.workspacePath, CORTASK_DIR, \"memory.md\");\n}\n\nexport const memoryReadTool: ToolHandler = {\n definition: {\n name: \"memory_read\",\n description:\n \"Read long-term memory. Use scope 'global' for user preferences that apply across all projects, or 'project' (default) for project-specific context.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n scope: {\n type: \"string\",\n enum: [\"project\", \"global\"],\n description:\n \"Which memory to read: 'project' for this workspace, 'global' for cross-project preferences.\",\n },\n },\n },\n },\n async execute(\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<ToolResult> {\n const scope = (args.scope as string) || \"project\";\n const memoryPath = getMemoryPath(scope, context);\n try {\n const content = await fs.readFile(memoryPath, \"utf-8\");\n return { toolCallId: \"\", content };\n } catch {\n return {\n toolCallId: \"\",\n content: `No ${scope} memory file found.`,\n };\n }\n },\n};\n\nexport const memorySaveTool: ToolHandler = {\n definition: {\n name: \"memory_save\",\n description:\n \"Save or replace long-term memory. Use scope 'global' for user preferences (e.g. coding style, preferred tools) that apply across all projects, or 'project' (default) for project-specific context (e.g. architecture decisions, tech stack).\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n content: {\n type: \"string\",\n description:\n \"The full content to write to memory.md (markdown format). This replaces the entire file.\",\n },\n scope: {\n type: \"string\",\n enum: [\"project\", \"global\"],\n description:\n \"Which memory to save: 'project' for this workspace, 'global' for cross-project preferences.\",\n },\n },\n required: [\"content\"],\n },\n },\n async execute(\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<ToolResult> {\n const content = args.content as string;\n if (!content) {\n return {\n toolCallId: \"\",\n content: \"Error: content is required\",\n isError: true,\n };\n }\n\n const scope = (args.scope as string) || \"project\";\n const memoryPath = getMemoryPath(scope, context);\n await fs.mkdir(path.dirname(memoryPath), { recursive: true });\n await fs.writeFile(memoryPath, content, \"utf-8\");\n return {\n toolCallId: \"\",\n content: `${scope === \"global\" ? \"Global\" : \"Project\"} memory saved (${content.length} chars)`,\n };\n },\n};\n\nexport const memoryAppendTool: ToolHandler = {\n definition: {\n name: \"memory_append\",\n description:\n \"Append a note to long-term memory. Use scope 'global' for user preferences that apply across all projects, or 'project' (default) for project-specific context.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n note: {\n type: \"string\",\n description: \"The note to append to memory.md\",\n },\n scope: {\n type: \"string\",\n enum: [\"project\", \"global\"],\n description:\n \"Which memory to append to: 'project' for this workspace, 'global' for cross-project preferences.\",\n },\n },\n required: [\"note\"],\n },\n },\n async execute(\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<ToolResult> {\n const note = args.note as string;\n if (!note) {\n return {\n toolCallId: \"\",\n content: \"Error: note is required\",\n isError: true,\n };\n }\n\n const scope = (args.scope as string) || \"project\";\n const memoryPath = getMemoryPath(scope, context);\n await fs.mkdir(path.dirname(memoryPath), { recursive: true });\n\n let existing = \"\";\n try {\n existing = await fs.readFile(memoryPath, \"utf-8\");\n } catch {\n existing = scope === \"global\"\n ? \"# Global Memory\\n\\nUser preferences and context that apply across all projects.\\n\"\n : \"# Project Memory\\n\\nThis file is used by Cortask to remember important context about this project.\\n\";\n }\n\n const updated = existing.trimEnd() + \"\\n\\n\" + note + \"\\n\";\n await fs.writeFile(memoryPath, updated, \"utf-8\");\n return {\n toolCallId: \"\",\n content: `Note appended to ${scope} memory.`,\n };\n },\n};\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolHandler } from \"../types.js\";\n\nexport const showFileTool: ToolHandler = {\n definition: {\n name: \"show_file\",\n description:\n \"Present a file to the user as a downloadable card in the chat. Use this after creating or processing a file that the user would want to download (e.g. generated documents, images, exports). Path is relative to workspace root.\",\n inputSchema: {\n type: \"object\",\n properties: {\n path: {\n type: \"string\",\n description: \"File path relative to workspace root\",\n },\n label: {\n type: \"string\",\n description: \"Optional display label for the file card\",\n },\n },\n required: [\"path\"],\n },\n },\n async execute(args, context) {\n const filePath = path.resolve(context.workspacePath, args.path as string);\n\n if (!filePath.startsWith(context.workspacePath)) {\n return {\n toolCallId: \"\",\n content: \"Error: Cannot access files outside the workspace\",\n isError: true,\n };\n }\n\n try {\n const stat = await fs.stat(filePath);\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n __fileRef: true,\n path: args.path as string,\n size: stat.size,\n label: (args.label as string) || undefined,\n }),\n };\n } catch {\n return {\n toolCallId: \"\",\n content: `Error: File not found — ${args.path}`,\n isError: true,\n };\n }\n },\n};\n","import path from \"node:path\";\nimport fs from \"node:fs\";\nimport Database from \"better-sqlite3\";\nimport type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport {\n parseDataFile,\n detectColumnTypes,\n type TabularData,\n} from \"../../data/parser.js\";\n\nconst MAX_QUERY_ROWS = 100;\n\nexport const dataFileTool: ToolHandler = {\n definition: {\n name: \"data_file\",\n description:\n \"Inspect and query data files (CSV, TSV, JSON, XLSX) without loading them into the conversation. \" +\n \"Use 'inspect' to see column names, types, row count, and sample rows. \" +\n \"Use 'query' to run SQL queries (table is named 'data') for aggregations, filtering, and analysis. \" +\n \"For showing files to the user, use the show_file tool instead.\",\n inputSchema: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n enum: [\"inspect\", \"query\"],\n description: \"The action to perform\",\n },\n path: {\n type: \"string\",\n description:\n \"Path to the data file (relative to workspace or absolute)\",\n },\n sql: {\n type: \"string\",\n description:\n 'SQL query to run against the data (action=query only). The table is named \"data\". Example: SELECT column, COUNT(*) FROM data GROUP BY column',\n },\n },\n required: [\"action\", \"path\"],\n },\n },\n\n async execute(\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<ToolResult> {\n const action = args.action as string;\n const rawPath = args.path as string;\n\n if (!action || !rawPath) {\n return {\n toolCallId: \"\",\n content: \"action and path are required\",\n isError: true,\n };\n }\n\n // Resolve path relative to workspace\n const filePath = path.isAbsolute(rawPath)\n ? rawPath\n : path.resolve(context.workspacePath, rawPath);\n\n // Security: validate path is within workspace\n if (!filePath.startsWith(context.workspacePath)) {\n return {\n toolCallId: \"\",\n content: \"Error: Cannot access files outside the workspace\",\n isError: true,\n };\n }\n\n if (!fs.existsSync(filePath)) {\n return {\n toolCallId: \"\",\n content: `File not found: ${rawPath}`,\n isError: true,\n };\n }\n\n try {\n switch (action) {\n case \"inspect\":\n return await handleInspect(filePath);\n case \"query\":\n return await handleQuery(filePath, args.sql as string);\n default:\n return {\n toolCallId: \"\",\n content: `Unknown action: ${action}. Use \"inspect\" or \"query\".`,\n isError: true,\n };\n }\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n};\n\n// ---------------------------------------------------------------------------\n// inspect\n// ---------------------------------------------------------------------------\n\nasync function handleInspect(filePath: string): Promise<ToolResult> {\n const data = await parseDataFile(filePath);\n const types = detectColumnTypes(data);\n const fileName = path.basename(filePath);\n const ext = path.extname(filePath).toLowerCase().slice(1);\n\n const lines: string[] = [];\n lines.push(`File: ${fileName} (${ext.toUpperCase()})`);\n lines.push(`Rows: ${data.rows.length}`);\n lines.push(`Columns: ${data.headers.length}`);\n lines.push(\"\");\n\n // Column info — show quoted SQL names so the agent knows exactly how to reference them\n lines.push(\"Columns (use these quoted names in SQL):\");\n for (let i = 0; i < data.headers.length; i++) {\n lines.push(` \"${data.headers[i]}\" (${types[i]})`);\n }\n\n // Sample rows\n if (data.rows.length > 0) {\n lines.push(\"\");\n lines.push(\"Sample rows (first 3):\");\n const sampleRows = data.rows.slice(0, 3);\n for (const row of sampleRows) {\n const pairs = data.headers\n .map((h, i) => {\n const val = row[i] ?? \"\";\n return `${h}: ${val.length > 80 ? val.slice(0, 80) + \"…\" : val}`;\n })\n .join(\" | \");\n lines.push(` ${pairs}`);\n }\n }\n\n return { toolCallId: \"\", content: lines.join(\"\\n\") };\n}\n\n// ---------------------------------------------------------------------------\n// query\n// ---------------------------------------------------------------------------\n\nasync function handleQuery(\n filePath: string,\n sql: string | undefined,\n): Promise<ToolResult> {\n if (!sql) {\n return {\n toolCallId: \"\",\n content:\n 'The \"sql\" parameter is required for query action. Example: SELECT COUNT(*) FROM data',\n isError: true,\n };\n }\n\n const data = await parseDataFile(filePath);\n\n if (data.headers.length === 0) {\n return { toolCallId: \"\", content: \"File has no columns.\", isError: true };\n }\n\n const db = new Database(\":memory:\");\n\n try {\n createTable(db, data);\n insertRows(db, data);\n\n const stmt = db.prepare(sql);\n\n // Detect if query returns rows (SELECT) or is a command\n if (stmt.reader) {\n const rows = stmt.all() as Record<string, unknown>[];\n return {\n toolCallId: \"\",\n content: formatQueryResults(rows),\n };\n } else {\n const info = stmt.run();\n return {\n toolCallId: \"\",\n content: `Statement executed. Changes: ${info.changes}`,\n };\n }\n } finally {\n db.close();\n }\n}\n\nfunction escapeIdent(name: string): string {\n // Escape double quotes inside the name, then wrap in double quotes\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\nfunction createTable(db: Database.Database, data: TabularData): void {\n const types = detectColumnTypes(data);\n const columns = data.headers\n .map((h, i) => `${escapeIdent(h)} ${types[i]}`)\n .join(\", \");\n\n db.exec(`CREATE TABLE data (${columns})`);\n}\n\nfunction insertRows(db: Database.Database, data: TabularData): void {\n const types = detectColumnTypes(data);\n const placeholders = data.headers.map(() => \"?\").join(\", \");\n const insert = db.prepare(`INSERT INTO data VALUES (${placeholders})`);\n\n const insertMany = db.transaction((rows: string[][]) => {\n for (const row of rows) {\n const values = row.map((val, i) => {\n if (val === \"\") return null;\n if (types[i] === \"INTEGER\") {\n const n = parseInt(val, 10);\n return isNaN(n) ? val : n;\n }\n if (types[i] === \"REAL\") {\n const n = parseFloat(val.replace(\",\", \".\"));\n return isNaN(n) ? val : n;\n }\n return val;\n });\n insert.run(...values);\n }\n });\n\n insertMany(data.rows);\n}\n\nfunction formatQueryResults(rows: Record<string, unknown>[]): string {\n if (rows.length === 0) return \"No results.\";\n\n const limited = rows.slice(0, MAX_QUERY_ROWS);\n const keys = Object.keys(limited[0]);\n\n // Format as aligned text table\n const colWidths = keys.map((k) => {\n const maxVal = limited.reduce((max, row) => {\n const val = String(row[k] ?? \"\");\n return Math.max(max, val.length);\n }, k.length);\n return Math.min(maxVal, 40); // Cap column width\n });\n\n const header = keys\n .map((k, i) => k.padEnd(colWidths[i]))\n .join(\" | \");\n const separator = colWidths.map((w) => \"-\".repeat(w)).join(\"-+-\");\n const body = limited.map((row) =>\n keys\n .map((k, i) => {\n const val = String(row[k] ?? \"\");\n return (val.length > 40 ? val.slice(0, 37) + \"…\" : val).padEnd(\n colWidths[i],\n );\n })\n .join(\" | \"),\n );\n\n const lines = [header, separator, ...body];\n\n if (rows.length > MAX_QUERY_ROWS) {\n lines.push(`\\n... (${rows.length - MAX_QUERY_ROWS} more rows not shown)`);\n }\n\n lines.push(`\\n${rows.length} row(s)`);\n\n return lines.join(\"\\n\");\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nexport interface TabularData {\n headers: string[];\n rows: string[][];\n}\n\nconst MAX_RAW_SIZE = 500_000; // 500KB for CSV/JSON\nconst MAX_ROWS = 50_000;\n\n/**\n * Parse a data file into tabular form.\n * Supports CSV, JSON (array of objects), and XLSX.\n */\nexport async function parseDataFile(filePath: string): Promise<TabularData> {\n const ext = path.extname(filePath).toLowerCase();\n\n switch (ext) {\n case \".csv\":\n case \".tsv\":\n return parseCsv(filePath, ext === \".tsv\" ? \"\\t\" : undefined);\n case \".json\":\n return parseJson(filePath);\n case \".xlsx\":\n return parseXlsx(filePath);\n default:\n throw new Error(\n `Unsupported file type: ${ext}. Supported: .csv, .tsv, .json, .xlsx`,\n );\n }\n}\n\n/**\n * Detect column types by sampling the first 100 non-empty values per column.\n */\nexport function detectColumnTypes(\n data: TabularData,\n): Array<\"INTEGER\" | \"REAL\" | \"TEXT\"> {\n return data.headers.map((_, colIdx) => {\n const sample = data.rows\n .slice(0, 100)\n .map((r) => r[colIdx] ?? \"\")\n .filter((v) => v !== \"\");\n\n if (sample.length === 0) return \"TEXT\";\n if (sample.every((v) => /^-?\\d+$/.test(v))) return \"INTEGER\";\n if (sample.every((v) => /^-?\\d+[.,]?\\d*$/.test(v.replace(\",\", \".\"))))\n return \"REAL\";\n return \"TEXT\";\n });\n}\n\n// ---------------------------------------------------------------------------\n// CSV parser\n// ---------------------------------------------------------------------------\n\nfunction parseCsv(filePath: string, forceDelimiter?: string): TabularData {\n let raw = fs.readFileSync(filePath, \"utf-8\");\n if (raw.length > MAX_RAW_SIZE) {\n raw = raw.slice(0, MAX_RAW_SIZE);\n // Trim to last complete line\n const lastNewline = raw.lastIndexOf(\"\\n\");\n if (lastNewline > 0) raw = raw.slice(0, lastNewline);\n }\n\n // Strip BOM\n if (raw.startsWith(\"\\ufeff\")) raw = raw.slice(1);\n raw = raw.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n\n // Auto-detect delimiter from first line\n const firstLine = raw.split(\"\\n\")[0] ?? \"\";\n let delimiter = forceDelimiter ?? \",\";\n if (!forceDelimiter) {\n const tabs = (firstLine.match(/\\t/g) ?? []).length;\n const semicolons = (firstLine.match(/;/g) ?? []).length;\n const commas = (firstLine.match(/,/g) ?? []).length;\n if (tabs > commas && tabs > semicolons) delimiter = \"\\t\";\n else if (semicolons > commas) delimiter = \";\";\n }\n\n const lines = splitCsvLines(raw, delimiter);\n if (lines.length === 0) return { headers: [], rows: [] };\n\n const headers = lines[0];\n const rows = lines.slice(1, MAX_ROWS + 1);\n return { headers, rows };\n}\n\nfunction splitCsvLines(text: string, delimiter: string): string[][] {\n const result: string[][] = [];\n let current: string[] = [];\n let field = \"\";\n let inQuotes = false;\n\n for (let i = 0; i < text.length; i++) {\n const ch = text[i];\n if (inQuotes) {\n if (ch === '\"') {\n if (text[i + 1] === '\"') {\n field += '\"';\n i++;\n } else {\n inQuotes = false;\n }\n } else {\n field += ch;\n }\n } else {\n if (ch === '\"') {\n inQuotes = true;\n } else if (ch === delimiter) {\n current.push(field.trim());\n field = \"\";\n } else if (ch === \"\\n\") {\n current.push(field.trim());\n if (current.length > 1 || current[0] !== \"\") {\n result.push(current);\n }\n current = [];\n field = \"\";\n } else {\n field += ch;\n }\n }\n }\n\n // Last field\n current.push(field.trim());\n if (current.length > 1 || current[0] !== \"\") {\n result.push(current);\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// JSON parser\n// ---------------------------------------------------------------------------\n\nfunction parseJson(filePath: string): TabularData {\n let raw = fs.readFileSync(filePath, \"utf-8\");\n if (raw.length > MAX_RAW_SIZE) {\n throw new Error(\n `JSON file too large (${(raw.length / 1024).toFixed(0)}KB, max ${MAX_RAW_SIZE / 1024}KB). ` +\n \"Consider converting to CSV first.\",\n );\n }\n\n const parsed = JSON.parse(raw);\n\n if (!Array.isArray(parsed)) {\n throw new Error(\n \"JSON file must contain an array of objects at the top level.\",\n );\n }\n\n if (parsed.length === 0) return { headers: [], rows: [] };\n\n // Collect all keys from all objects for headers\n const keySet = new Set<string>();\n for (const obj of parsed.slice(0, 1000)) {\n if (obj && typeof obj === \"object\" && !Array.isArray(obj)) {\n for (const key of Object.keys(obj)) keySet.add(key);\n }\n }\n const headers = Array.from(keySet);\n\n const rows: string[][] = [];\n for (const obj of parsed.slice(0, MAX_ROWS)) {\n if (obj && typeof obj === \"object\" && !Array.isArray(obj)) {\n rows.push(\n headers.map((h) => {\n const val = obj[h];\n if (val === null || val === undefined) return \"\";\n if (typeof val === \"object\") return JSON.stringify(val);\n return String(val);\n }),\n );\n }\n }\n\n return { headers, rows };\n}\n\n// ---------------------------------------------------------------------------\n// XLSX parser\n// ---------------------------------------------------------------------------\n\nasync function parseXlsx(filePath: string): Promise<TabularData> {\n const ExcelJS = await import(\"exceljs\");\n const workbook = new ExcelJS.default.Workbook();\n await workbook.xlsx.readFile(filePath);\n\n const worksheet = workbook.worksheets[0];\n if (!worksheet || worksheet.rowCount === 0) {\n return { headers: [], rows: [] };\n }\n\n const headers: string[] = [];\n const firstRow = worksheet.getRow(1);\n firstRow.eachCell({ includeEmpty: true }, (cell, colNumber) => {\n while (headers.length < colNumber - 1) headers.push(\"\");\n headers.push(String(cell.value ?? \"\"));\n });\n\n const rows: string[][] = [];\n const maxRow = Math.min(worksheet.rowCount, MAX_ROWS + 1);\n\n for (let rowNum = 2; rowNum <= maxRow; rowNum++) {\n const row = worksheet.getRow(rowNum);\n const values: string[] = [];\n let hasValue = false;\n\n for (let colIdx = 0; colIdx < headers.length; colIdx++) {\n const cell = row.getCell(colIdx + 1);\n const val = cell.value;\n if (val !== null && val !== undefined) hasValue = true;\n\n if (val === null || val === undefined) {\n values.push(\"\");\n } else if (val instanceof Date) {\n values.push(val.toISOString());\n } else if (typeof val === \"object\") {\n // Handle rich text, formula results, etc.\n const result = (val as { result?: unknown }).result;\n const text = (val as { text?: unknown }).text;\n values.push(String(result ?? text ?? JSON.stringify(val)));\n } else {\n values.push(String(val));\n }\n }\n\n if (hasValue) rows.push(values);\n }\n\n return { headers, rows };\n}\n","import { Cron } from \"croner\";\nimport type { CronSchedule } from \"./types.js\";\n\n/**\n * Compute the next run time in milliseconds for a given schedule.\n * Returns null if the schedule has no future run (e.g. one-shot in the past).\n */\nexport function computeNextRunAtMs(\n schedule: CronSchedule,\n now: number = Date.now(),\n): number | null {\n switch (schedule.type) {\n case \"at\": {\n const target = new Date(schedule.datetime).getTime();\n return target > now ? target : null;\n }\n case \"every\": {\n // Next interval tick from now\n const interval = schedule.intervalMs;\n if (interval <= 0) return null;\n return now + interval;\n }\n case \"cron\": {\n try {\n const job = new Cron(schedule.expression, {\n timezone: schedule.timezone,\n });\n const next = job.nextRun();\n return next ? next.getTime() : null;\n } catch {\n return null;\n }\n }\n default:\n return null;\n }\n}\n\n/**\n * Validate a cron expression. Returns null if valid, error message if not.\n */\nexport function validateCronExpr(expression: string): string | null {\n try {\n new Cron(expression);\n return null;\n } catch (err) {\n return err instanceof Error ? err.message : \"Invalid cron expression\";\n }\n}\n","import type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport type { CronService } from \"../../cron/service.js\";\nimport type { CronSchedule, CronDelivery } from \"../../cron/types.js\";\nimport { validateCronExpr } from \"../../cron/schedule.js\";\n\n/**\n * Creates a cron tool handler bound to a CronService instance.\n * This is a factory because the cron service is initialized at runtime.\n */\nexport function createCronTool(cronService: CronService): ToolHandler {\n return {\n definition: {\n name: \"cortask_cron\",\n description:\n 'Manage scheduled jobs. To create: set action=\"create\", name, schedule_type, schedule_value, and prompt. To list all jobs: set action=\"list\". To remove: set action=\"remove\" and job_id.',\n inputSchema: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n description: \"The action to perform\",\n enum: [\"list\", \"create\", \"update\", \"remove\", \"run_now\"],\n },\n name: {\n type: \"string\",\n description: \"Job name (for create/update)\",\n },\n schedule_type: {\n type: \"string\",\n description: 'Schedule type: \"at\" for one-time (ISO datetime), \"every\" for interval (milliseconds), \"cron\" for recurring (cron expression)',\n enum: [\"at\", \"every\", \"cron\"],\n },\n schedule_value: {\n type: \"string\",\n description:\n 'The schedule value. Examples: \"2026-03-10T10:00:00\" for at, \"60000\" for every, \"0 9 * * 1\" for cron',\n },\n timezone: {\n type: \"string\",\n description: \"Timezone (e.g. Europe/Berlin)\",\n },\n prompt: {\n type: \"string\",\n description: \"The prompt/task to execute when the job runs\",\n },\n enabled: {\n type: \"boolean\",\n description: \"Whether the job is enabled\",\n },\n delivery_channel: {\n type: \"string\",\n description:\n 'Channel to deliver results to (e.g. \"telegram\", \"discord\", \"whatsapp\")',\n },\n delivery_target: {\n type: \"string\",\n description: \"Target chat/user ID for delivery\",\n },\n job_id: {\n type: \"string\",\n description: \"Job ID (for update, remove, run_now)\",\n },\n },\n required: [\"action\"],\n },\n },\n\n execute: async (\n args: Record<string, unknown>,\n _context: ToolExecutionContext,\n ): Promise<ToolResult> => {\n const action = args.action as string;\n\n try {\n switch (action) {\n case \"list\": {\n const jobs = cronService.list();\n if (jobs.length === 0) {\n return { toolCallId: \"\", content: \"No cron jobs found.\" };\n }\n const lines = jobs.map((j) => {\n const state = cronService.getState(j.id);\n const nextRun = state?.nextRunAtMs\n ? new Date(state.nextRunAtMs).toISOString()\n : \"none\";\n const status = j.enabled ? \"enabled\" : \"disabled\";\n return `- **${j.name}** (${j.id})\\n Status: ${status} | Next: ${nextRun} | Schedule: ${JSON.stringify(j.schedule)}\\n Prompt: ${j.prompt.slice(0, 100)}`;\n });\n return { toolCallId: \"\", content: lines.join(\"\\n\\n\") };\n }\n\n case \"create\": {\n const name = args.name as string;\n const prompt = args.prompt as string;\n if (!name || !prompt) {\n return {\n toolCallId: \"\",\n content: \"name and prompt are required for create\",\n isError: true,\n };\n }\n\n const schedule = buildSchedule(args);\n if (typeof schedule === \"string\") {\n return { toolCallId: \"\", content: schedule, isError: true };\n }\n\n const delivery = buildDelivery(args);\n const job = cronService.add({\n name,\n schedule,\n prompt,\n enabled: (args.enabled as boolean) ?? true,\n delivery,\n });\n\n return {\n toolCallId: \"\",\n content: `Cron job created: \"${job.name}\" (${job.id})\\nSchedule: ${JSON.stringify(job.schedule)}`,\n };\n }\n\n case \"update\": {\n const jobId = args.job_id as string;\n if (!jobId) {\n return {\n toolCallId: \"\",\n content: \"job_id is required for update\",\n isError: true,\n };\n }\n\n const updates: Record<string, unknown> = {};\n if (args.name) updates.name = args.name;\n if (args.prompt) updates.prompt = args.prompt;\n if (args.enabled !== undefined) updates.enabled = args.enabled;\n if (args.delivery_channel || args.delivery_target) {\n updates.delivery = buildDelivery(args);\n }\n if (args.schedule_type) {\n const schedule = buildSchedule(args);\n if (typeof schedule === \"string\") {\n return { toolCallId: \"\", content: schedule, isError: true };\n }\n updates.schedule = schedule;\n }\n\n const updated = cronService.update(jobId, updates);\n if (!updated) {\n return {\n toolCallId: \"\",\n content: `Job ${jobId} not found`,\n isError: true,\n };\n }\n\n return {\n toolCallId: \"\",\n content: `Job \"${updated.name}\" updated.`,\n };\n }\n\n case \"remove\": {\n const jobId = args.job_id as string;\n if (!jobId) {\n return {\n toolCallId: \"\",\n content: \"job_id is required for remove\",\n isError: true,\n };\n }\n const removed = cronService.remove(jobId);\n return {\n toolCallId: \"\",\n content: removed\n ? `Job ${jobId} removed.`\n : `Job ${jobId} not found.`,\n };\n }\n\n case \"run_now\": {\n const jobId = args.job_id as string;\n if (!jobId) {\n return {\n toolCallId: \"\",\n content: \"job_id is required for run_now\",\n isError: true,\n };\n }\n await cronService.runNow(jobId);\n return { toolCallId: \"\", content: `Job ${jobId} executed.` };\n }\n\n default:\n return {\n toolCallId: \"\",\n content: `Unknown action: ${action}`,\n isError: true,\n };\n }\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Cron error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n };\n}\n\nfunction buildDelivery(args: Record<string, unknown>): CronDelivery {\n return {\n channel: (args.delivery_channel as string) || undefined,\n target: (args.delivery_target as string) || undefined,\n };\n}\n\nfunction buildSchedule(\n args: Record<string, unknown>,\n): CronSchedule | string {\n const type = args.schedule_type as string;\n const value = args.schedule_value as string;\n\n if (!type || !value) {\n return \"schedule_type and schedule_value are required\";\n }\n\n switch (type) {\n case \"at\":\n return { type: \"at\", datetime: value };\n case \"every\": {\n const ms = parseInt(value, 10);\n if (isNaN(ms) || ms <= 0) return \"schedule_value must be a positive number of milliseconds\";\n return { type: \"every\", intervalMs: ms };\n }\n case \"cron\": {\n const err = validateCronExpr(value);\n if (err) return `Invalid cron expression: ${err}`;\n return {\n type: \"cron\",\n expression: value,\n timezone: (args.timezone as string) || undefined,\n };\n }\n default:\n return `Unknown schedule type: ${type}`;\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport type { ArtifactStore, Artifact } from \"../../artifacts/store.js\";\n\n/**\n * Creates an artifact tool handler bound to an ArtifactStore instance.\n */\nexport function createArtifactTool(artifactStore: ArtifactStore): ToolHandler {\n return {\n definition: {\n name: \"artifact\",\n description:\n \"Create rich artifacts (HTML, CSV, SVG, JSON) that will be rendered inline in the chat. Use this for tables, charts, interactive content, and structured data. You can either provide the content directly OR reference a file path to read from disk (preferred when the file already exists).\",\n inputSchema: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n description: \"The artifact type\",\n enum: [\"html\", \"csv\", \"json\", \"svg\", \"text\"],\n },\n title: {\n type: \"string\",\n description: \"A short title for the artifact\",\n },\n content: {\n type: \"string\",\n description:\n \"The artifact content (HTML, CSV, JSON, SVG, or plain text). Not needed if path is provided.\",\n },\n path: {\n type: \"string\",\n description:\n \"File path relative to workspace root. When provided, content is read from the file instead of the content parameter. Preferred when showing an existing file inline.\",\n },\n },\n required: [\"type\", \"title\"],\n },\n },\n\n execute: async (\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<ToolResult> => {\n const type = args.type as Artifact[\"type\"];\n const title = args.title as string;\n const filePath = args.path as string | undefined;\n let content = args.content as string | undefined;\n\n if (!type || !title) {\n return {\n toolCallId: \"\",\n content: \"type and title are required\",\n isError: true,\n };\n }\n\n // Read content from file if path is provided\n if (filePath) {\n const resolved = path.resolve(context.workspacePath, filePath);\n if (!resolved.startsWith(context.workspacePath)) {\n return {\n toolCallId: \"\",\n content: \"Error: Cannot access files outside the workspace\",\n isError: true,\n };\n }\n try {\n content = await fs.readFile(resolved, \"utf-8\");\n } catch {\n return {\n toolCallId: \"\",\n content: `Error: File not found — ${filePath}`,\n isError: true,\n };\n }\n }\n\n if (!content) {\n return {\n toolCallId: \"\",\n content: \"Either content or path must be provided\",\n isError: true,\n };\n }\n\n try {\n const artifact = artifactStore.create(type, title, content);\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n artifactId: artifact.id,\n type: artifact.type,\n title: artifact.title,\n mimeType: artifact.mimeType,\n }),\n };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Artifact error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n };\n}\n","// agent-browser CLI manager\n// Uses the agent-browser daemon for browser automation.\n// The daemon persists between commands so the browser stays open.\n\nimport { execFile } from \"node:child_process\";\nimport { existsSync, mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { createRequire } from \"node:module\";\n\nconst DEFAULT_TIMEOUT = 30_000;\n\nfunction getNativeBinName(): string | null {\n const platform = process.platform;\n const arch = process.arch;\n if (platform === \"win32\" && arch === \"x64\") return \"agent-browser-win32-x64.exe\";\n if (platform === \"darwin\" && arch === \"arm64\") return \"agent-browser-darwin-arm64\";\n if (platform === \"darwin\" && arch === \"x64\") return \"agent-browser-darwin-x64\";\n if (platform === \"linux\" && arch === \"arm64\") return \"agent-browser-linux-arm64\";\n if (platform === \"linux\" && arch === \"x64\") return \"agent-browser-linux-x64\";\n return null;\n}\n\nfunction resolveCmd(): string {\n const nativeBin = getNativeBinName();\n\n // Check Electron extraResources (packaged desktop app)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const resourcesPath = (process as any).resourcesPath as string | undefined;\n if (resourcesPath && nativeBin) {\n const candidate = join(resourcesPath, \"agent-browser\", nativeBin);\n if (existsSync(candidate)) return candidate;\n }\n\n try {\n const require = createRequire(import.meta.url);\n if (nativeBin) {\n try {\n return require.resolve(`agent-browser/bin/${nativeBin}`);\n } catch {\n // fall through to .js wrapper\n }\n }\n return require.resolve(\"agent-browser/bin/agent-browser.js\");\n } catch {\n return \"agent-browser\";\n }\n}\n\nconst CMD = resolveCmd();\n\nexport interface BrowserInstance {\n run(args: string[]): Promise<string>;\n navigate(url: string): Promise<{ title: string; url: string; content: string }>;\n snapshot(interactive?: boolean): Promise<string>;\n screenshot(): Promise<Buffer>;\n click(selector: string): Promise<void>;\n fill(selector: string, text: string): Promise<void>;\n type(selector: string, text: string): Promise<void>;\n evaluate(script: string): Promise<string>;\n getContent(): Promise<{ title: string; url: string; content: string }>;\n select(selector: string, value: string): Promise<void>;\n press(key: string): Promise<void>;\n wait(target: string): Promise<void>;\n close(): Promise<void>;\n}\n\nlet instance: BrowserInstance | null = null;\n\nfunction ensureAgentBrowserHome(): string {\n if (!process.env.AGENT_BROWSER_HOME) {\n const dir = join(homedir(), \".agent-browser\");\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n // Set globally so daemon subprocesses inherit it\n process.env.AGENT_BROWSER_HOME = dir;\n }\n return process.env.AGENT_BROWSER_HOME;\n}\n\n// Set AGENT_BROWSER_HOME early so it's in process.env for all child processes\nensureAgentBrowserHome();\n\nfunction exec(args: string[], timeout = DEFAULT_TIMEOUT): Promise<string> {\n return new Promise((resolve, reject) => {\n const isScript = CMD.endsWith(\".js\");\n const cmd = isScript ? (process.env.NODE_PATH_BIN || process.execPath) : CMD;\n const finalArgs = isScript ? [CMD, ...args] : args;\n // Explicitly pass env and cwd to ensure agent-browser finds its home\n const env = { ...process.env };\n delete env.ELECTRON_RUN_AS_NODE;\n const cwd = ensureAgentBrowserHome();\n execFile(cmd, finalArgs, { timeout, maxBuffer: 5 * 1024 * 1024, env, cwd }, (err, stdout, stderr) => {\n if (err) {\n const msg = stderr?.trim() || stdout?.trim() || err.message;\n reject(new Error(msg));\n } else {\n resolve(stdout);\n }\n });\n });\n}\n\nexport async function isAgentBrowserAvailable(): Promise<boolean> {\n try {\n await exec([\"--version\"], 5000);\n return true;\n } catch {\n return false;\n }\n}\n\nlet _installed = false;\n\nexport async function ensureInstalled(): Promise<void> {\n if (_installed) return;\n try {\n await exec([\"--version\"], 5000);\n } catch {\n throw new Error(\"agent-browser is not installed. Run: npm install -g agent-browser\");\n }\n // Download a browser if none is available (system Chrome is used as fallback).\n // Run in background so it doesn't block startup.\n exec([\"install\"], 120_000)\n .then(() => exec([\"close\"], 5000).catch(() => {}))\n .catch(() => {});\n _installed = true;\n}\n\nexport async function ensureBrowser(): Promise<BrowserInstance> {\n if (instance) return instance;\n await ensureInstalled();\n\n const inst: BrowserInstance = {\n async run(args: string[]) {\n return exec(args);\n },\n\n async navigate(url: string) {\n await exec([\"open\", url, \"--headed\"]);\n await exec([\"wait\", \"--load\", \"domcontentloaded\"]);\n const titleOut = await exec([\"get\", \"title\"]);\n const urlOut = await exec([\"get\", \"url\"]);\n const content = await exec([\"snapshot\", \"-i\", \"-c\"]);\n return {\n title: titleOut.trim(),\n url: urlOut.trim(),\n content,\n };\n },\n\n async snapshot(interactive = true) {\n const args = [\"snapshot\"];\n if (interactive) args.push(\"-i\");\n args.push(\"-c\");\n return exec(args);\n },\n\n async screenshot() {\n const tmpPath = `${process.env.TEMP || \"/tmp\"}/ab-screenshot-${Date.now()}.png`;\n await exec([\"screenshot\", tmpPath]);\n const fs = await import(\"node:fs/promises\");\n const buf = await fs.readFile(tmpPath);\n await fs.unlink(tmpPath).catch(() => {});\n return buf;\n },\n\n async click(selector: string) {\n await exec([\"click\", selector]);\n },\n\n async fill(selector: string, text: string) {\n await exec([\"fill\", selector, text]);\n },\n\n async type(selector: string, text: string) {\n await exec([\"type\", selector, text]);\n },\n\n async evaluate(script: string) {\n return exec([\"eval\", script]);\n },\n\n async getContent() {\n const titleOut = await exec([\"get\", \"title\"]);\n const urlOut = await exec([\"get\", \"url\"]);\n const content = await exec([\"snapshot\", \"-i\", \"-c\"]);\n return {\n title: titleOut.trim(),\n url: urlOut.trim(),\n content,\n };\n },\n\n async select(selector: string, value: string) {\n await exec([\"select\", selector, value]);\n },\n\n async press(key: string) {\n await exec([\"press\", key]);\n },\n\n async wait(target: string) {\n if (target.startsWith(\"http\")) {\n await exec([\"wait\", \"--url\", target]);\n } else {\n await exec([\"wait\", target]);\n }\n },\n\n async close() {\n await exec([\"close\"]).catch(() => {});\n instance = null;\n },\n };\n\n instance = inst;\n return inst;\n}\n\nexport async function closeBrowser(): Promise<void> {\n if (instance) {\n await instance.close();\n }\n}\n","import type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport type { ArtifactStore } from \"../../artifacts/store.js\";\nimport { ensureBrowser, closeBrowser } from \"./browser-manager.js\";\n\nconst MAX_CONTENT = 50_000;\n\nfunction truncate(text: string, max: number): string {\n return text.length > max ? text.slice(0, max) + \"\\n...(truncated)\" : text;\n}\n\nexport function createBrowserTool(artifactStore: ArtifactStore): ToolHandler {\n return {\n definition: {\n name: \"browser\",\n description:\n \"Control a visible browser window using agent-browser. \" +\n \"Use 'navigate' to open a URL, then 'snapshot' to see interactive elements with refs (@e1, @e2...). \" +\n \"Use those refs with click, fill, type, select actions for reliable interaction. \" +\n \"The browser is visible to the user. Prefer web_fetch for simple content retrieval.\",\n inputSchema: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n enum: [\n \"navigate\",\n \"snapshot\",\n \"screenshot\",\n \"click\",\n \"fill\",\n \"type\",\n \"select\",\n \"press\",\n \"evaluate\",\n \"get_text\",\n \"get_content\",\n \"wait\",\n \"back\",\n \"forward\",\n \"reload\",\n \"close\",\n ],\n description:\n \"navigate: go to URL. snapshot: get accessibility tree with element refs (@e1, @e2...). \" +\n \"screenshot: capture page. click: click element (use @eN ref or selector). \" +\n \"fill: clear and fill input. type: type into focused/selected element. \" +\n \"select: select dropdown option. press: press a key (Enter, Tab, etc). \" +\n \"evaluate: run JS. get_text: get text of element. get_content: get page title, URL and snapshot. \" +\n \"wait: wait for selector, text, or milliseconds. back/forward/reload: navigate history. close: close browser.\",\n },\n url: {\n type: \"string\",\n description: \"URL to navigate to (for navigate action)\",\n },\n selector: {\n type: \"string\",\n description:\n \"Element ref from snapshot (@e1, @e2...) or CSS selector (for click, fill, type, select, get_text actions)\",\n },\n text: {\n type: \"string\",\n description: \"Text to type/fill (for fill and type actions)\",\n },\n value: {\n type: \"string\",\n description: \"Value for select action\",\n },\n key: {\n type: \"string\",\n description: \"Key to press (for press action, e.g. Enter, Tab, Escape)\",\n },\n script: {\n type: \"string\",\n description: \"JavaScript to evaluate (for evaluate action)\",\n },\n target: {\n type: \"string\",\n description:\n \"Wait target: CSS selector, milliseconds, or URL pattern (for wait action)\",\n },\n },\n required: [\"action\"],\n },\n },\n\n async execute(\n args: Record<string, unknown>,\n _context: ToolExecutionContext,\n ): Promise<ToolResult> {\n const action = args.action as string;\n\n if (action === \"close\") {\n await closeBrowser();\n return { toolCallId: \"\", content: \"Browser closed.\" };\n }\n\n try {\n const browser = await ensureBrowser();\n\n switch (action) {\n case \"navigate\": {\n const url = args.url as string;\n if (!url) {\n return {\n toolCallId: \"\",\n content: \"url is required for navigate action\",\n isError: true,\n };\n }\n const result = await browser.navigate(url);\n return {\n toolCallId: \"\",\n content: truncate(\n `Navigated to: ${result.url}\\nTitle: ${result.title}\\n\\nInteractive elements:\\n${result.content}`,\n MAX_CONTENT,\n ),\n };\n }\n\n case \"snapshot\": {\n const snapshot = await browser.snapshot(true);\n return {\n toolCallId: \"\",\n content: truncate(snapshot, MAX_CONTENT),\n };\n }\n\n case \"screenshot\": {\n const buffer = await browser.screenshot();\n const base64 = buffer.toString(\"base64\");\n const artifact = artifactStore.create(\n \"image\",\n \"Browser Screenshot\",\n base64,\n );\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n artifactId: artifact.id,\n type: artifact.type,\n title: artifact.title,\n mimeType: artifact.mimeType,\n }),\n };\n }\n\n case \"click\": {\n const selector = args.selector as string;\n if (!selector) {\n return {\n toolCallId: \"\",\n content: \"selector is required for click action (use @eN ref or CSS selector)\",\n isError: true,\n };\n }\n await browser.click(selector);\n return { toolCallId: \"\", content: `Clicked: ${selector}` };\n }\n\n case \"fill\": {\n const selector = args.selector as string;\n const text = args.text as string;\n if (!selector || text == null) {\n return {\n toolCallId: \"\",\n content: \"selector and text are required for fill action\",\n isError: true,\n };\n }\n await browser.fill(selector, text);\n return {\n toolCallId: \"\",\n content: `Filled ${selector} with: ${text}`,\n };\n }\n\n case \"type\": {\n const selector = args.selector as string;\n const text = args.text as string;\n if (!selector || !text) {\n return {\n toolCallId: \"\",\n content: \"selector and text are required for type action\",\n isError: true,\n };\n }\n await browser.type(selector, text);\n return {\n toolCallId: \"\",\n content: `Typed into ${selector}: ${text}`,\n };\n }\n\n case \"select\": {\n const selector = args.selector as string;\n const value = args.value as string;\n if (!selector || !value) {\n return {\n toolCallId: \"\",\n content: \"selector and value are required for select action\",\n isError: true,\n };\n }\n await browser.select(selector, value);\n return {\n toolCallId: \"\",\n content: `Selected \"${value}\" in ${selector}`,\n };\n }\n\n case \"press\": {\n const key = args.key as string;\n if (!key) {\n return {\n toolCallId: \"\",\n content: \"key is required for press action\",\n isError: true,\n };\n }\n await browser.press(key);\n return { toolCallId: \"\", content: `Pressed: ${key}` };\n }\n\n case \"evaluate\": {\n const script = args.script as string;\n if (!script) {\n return {\n toolCallId: \"\",\n content: \"script is required for evaluate action\",\n isError: true,\n };\n }\n const result = await browser.evaluate(script);\n return {\n toolCallId: \"\",\n content: truncate(result, MAX_CONTENT),\n };\n }\n\n case \"get_text\": {\n const selector = args.selector as string;\n if (!selector) {\n return {\n toolCallId: \"\",\n content: \"selector is required for get_text action\",\n isError: true,\n };\n }\n const result = await browser.run([\"get\", \"text\", selector]);\n return {\n toolCallId: \"\",\n content: truncate(result, MAX_CONTENT),\n };\n }\n\n case \"get_content\": {\n const result = await browser.getContent();\n return {\n toolCallId: \"\",\n content: truncate(\n `URL: ${result.url}\\nTitle: ${result.title}\\n\\nInteractive elements:\\n${result.content}`,\n MAX_CONTENT,\n ),\n };\n }\n\n case \"wait\": {\n const target = (args.target as string) || \"2000\";\n await browser.wait(target);\n return { toolCallId: \"\", content: `Waited for: ${target}` };\n }\n\n case \"back\": {\n await browser.run([\"back\"]);\n return { toolCallId: \"\", content: \"Navigated back\" };\n }\n\n case \"forward\": {\n await browser.run([\"forward\"]);\n return { toolCallId: \"\", content: \"Navigated forward\" };\n }\n\n case \"reload\": {\n await browser.run([\"reload\"]);\n return { toolCallId: \"\", content: \"Page reloaded\" };\n }\n\n default:\n return {\n toolCallId: \"\",\n content: `Unknown action: ${action}`,\n isError: true,\n };\n }\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Browser error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n };\n}\n","import crypto from \"node:crypto\";\nimport type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport type { AgentRunner } from \"../runner.js\";\nimport {\n registerSubagentRun,\n completeSubagentRun,\n countActiveChildren,\n getDepthForSession,\n getSubagentRun,\n cancelSubagentRun,\n SUBAGENT_DEFAULTS,\n type SubagentRunRecord,\n} from \"../subagent/index.js\";\nimport { logger } from \"../../logging/logger.js\";\n\n// Lazy reference to AgentRunner to avoid circular dependency\nlet runnerRef: AgentRunner | null = null;\n\n/**\n * Set the AgentRunner reference for subagent spawning.\n * Must be called after AgentRunner instantiation.\n */\nexport function setSubagentRunner(runner: AgentRunner): void {\n runnerRef = runner;\n}\n\n/**\n * Create the subagent tool handler.\n * Factory pattern to allow runtime injection of dependencies.\n */\nexport function createSubagentTool(): ToolHandler {\n return {\n definition: {\n name: \"subagent\",\n description:\n \"Spawn a sub-agent to handle an independent subtask. The sub-agent runs in isolation and returns its result directly. Use for delegating research, analysis, or parallel tasks to save context. The tool waits for the subagent to complete and returns the result. Simply provide the task description.\",\n inputSchema: {\n type: \"object\",\n properties: {\n task: {\n type: \"string\",\n description:\n \"Clear description of the task for the sub-agent\",\n },\n },\n required: [\"task\"],\n },\n },\n\n execute: async (\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n ): Promise<ToolResult> => {\n return executeSpawn(args, context);\n },\n };\n}\n\n/**\n * Execute the spawn action - create and run a subagent.\n */\nasync function executeSpawn(\n args: Record<string, unknown>,\n context: ToolExecutionContext,\n): Promise<ToolResult> {\n const task = args.task as string;\n if (!task?.trim()) {\n return {\n toolCallId: \"\",\n content: \"Error: task is required for spawn action\",\n isError: true,\n };\n }\n\n if (!runnerRef) {\n return {\n toolCallId: \"\",\n content:\n \"Error: Subagent spawning not available - runner not initialized. This is a system error.\",\n isError: true,\n };\n }\n\n // Check depth limit\n const currentDepth = getDepthForSession(context.sessionId);\n if (currentDepth >= SUBAGENT_DEFAULTS.maxDepth) {\n return {\n toolCallId: \"\",\n content: `Error: Maximum subagent depth reached (${currentDepth}/${SUBAGENT_DEFAULTS.maxDepth}). Cannot spawn deeper subagents. Consider completing this task directly or restructuring your approach.`,\n isError: true,\n };\n }\n\n // Check concurrency limit\n const activeChildren = countActiveChildren(context.sessionId);\n if (activeChildren >= SUBAGENT_DEFAULTS.maxChildrenPerAgent) {\n return {\n toolCallId: \"\",\n content: `Error: Maximum concurrent subagents reached (${activeChildren}/${SUBAGENT_DEFAULTS.maxChildrenPerAgent}). Wait for existing subagents to complete before spawning more.`,\n isError: true,\n };\n }\n\n const childRunId = crypto.randomUUID();\n const childSessionId = `subagent:${childRunId}`;\n\n // Create AbortController for cancellation support\n const abortController = new AbortController();\n\n // Register the subagent run\n const record: SubagentRunRecord = {\n runId: childRunId,\n childSessionId,\n parentSessionId: context.sessionId,\n parentRunId: context.runId,\n task,\n depth: currentDepth + 1,\n status: \"running\",\n createdAt: Date.now(),\n abortController,\n };\n registerSubagentRun(record);\n\n logger.info(\n `Subagent spawned: ${childRunId} (depth ${record.depth}) for parent ${context.sessionId}`,\n \"agent\",\n );\n\n // Capture runner reference for async function\n const runner = runnerRef;\n\n // Async execution function\n const runSubagent = async () => {\n try {\n // Create timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(\n () => reject(new Error(\"Subagent timeout after 2 minutes\")),\n SUBAGENT_DEFAULTS.timeoutMs,\n );\n });\n\n // Run subagent with race against timeout\n const result = await Promise.race([\n runner.run({\n prompt: `[Subagent Task] You are a subagent helping with a specific subtask. Complete this task concisely and provide a clear result.\\n\\nTask: ${task}`,\n sessionId: childSessionId,\n signal: abortController.signal,\n }),\n timeoutPromise,\n ]);\n\n // Mark as complete\n completeSubagentRun(childRunId, \"done\", result.response);\n\n logger.info(`Subagent completed: ${childRunId}`, \"agent\");\n\n return { success: true, result: result.response, usage: result.usage };\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n const isTimeout = errorMsg.includes(\"timeout\");\n const isCancelled = abortController.signal.aborted;\n\n completeSubagentRun(\n childRunId,\n isCancelled ? \"cancelled\" : isTimeout ? \"timeout\" : \"error\",\n undefined,\n errorMsg,\n );\n\n logger.error(`Subagent failed: ${childRunId} - ${errorMsg}`, \"agent\");\n\n return { success: false, error: errorMsg, isTimeout, isCancelled };\n }\n };\n\n // Wait for completion and return result directly\n const outcome = await runSubagent();\n\n if (!outcome.success) {\n return {\n toolCallId: \"\",\n content: `Subagent failed: ${outcome.error}`,\n isError: true,\n };\n }\n\n // Return the subagent's result directly to the parent agent\n return {\n toolCallId: \"\",\n content: outcome.result || \"Subagent completed with no output.\",\n };\n}\n\n/**\n * Execute the status action - check subagent status.\n */\nfunction executeStatus(args: Record<string, unknown>): ToolResult {\n const runId = args.runId as string;\n if (!runId?.trim()) {\n return {\n toolCallId: \"\",\n content: JSON.stringify({ error: \"runId is required for status action\" }),\n isError: true,\n };\n }\n\n const record = getSubagentRun(runId);\n if (!record) {\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n error: `Subagent run \"${runId}\" not found. It may have completed and been cleaned up.`,\n }),\n isError: true,\n };\n }\n\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n runId: record.runId,\n task: record.task,\n status: record.status,\n depth: record.depth,\n result: record.result,\n error: record.error,\n createdAt: new Date(record.createdAt).toISOString(),\n endedAt: record.endedAt\n ? new Date(record.endedAt).toISOString()\n : undefined,\n }),\n };\n}\n\n/**\n * Execute the cancel action - cancel a running subagent.\n */\nfunction executeCancel(args: Record<string, unknown>): ToolResult {\n const runId = args.runId as string;\n if (!runId?.trim()) {\n return {\n toolCallId: \"\",\n content: JSON.stringify({ error: \"runId is required for cancel action\" }),\n isError: true,\n };\n }\n\n const record = getSubagentRun(runId);\n if (!record) {\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n error: `Subagent run \"${runId}\" not found. It may have already completed.`,\n }),\n isError: true,\n };\n }\n\n if (record.status !== \"running\") {\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n error: `Subagent \"${runId}\" is not running (status: ${record.status}). Cannot cancel.`,\n }),\n isError: true,\n };\n }\n\n const cancelled = cancelSubagentRun(runId);\n\n if (cancelled) {\n logger.info(`Subagent cancelled: ${runId}`, \"agent\");\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n success: true,\n runId,\n message: \"Subagent cancelled successfully.\",\n }),\n };\n } else {\n return {\n toolCallId: \"\",\n content: JSON.stringify({\n error: `Failed to cancel subagent \"${runId}\".`,\n }),\n isError: true,\n };\n }\n}\n","export interface SubagentRunRecord {\n runId: string;\n childSessionId: string; // Format: \"subagent:{runId}\"\n parentSessionId: string;\n parentRunId: string;\n task: string;\n depth: number; // 0=root, 1=child\n status: \"running\" | \"done\" | \"error\" | \"timeout\" | \"cancelled\";\n result?: string;\n error?: string;\n createdAt: number;\n endedAt?: number;\n abortController?: AbortController; // For cancellation\n}\n\nexport const SUBAGENT_DEFAULTS = {\n maxDepth: 1,\n maxChildrenPerAgent: 5,\n timeoutMs: 120_000, // 2 minutes\n} as const;\n","import type { SubagentRunRecord } from \"./types.js\";\n\nconst activeRuns = new Map<string, SubagentRunRecord>();\n\n/**\n * Register a new subagent run in the registry.\n */\nexport function registerSubagentRun(record: SubagentRunRecord): void {\n activeRuns.set(record.runId, record);\n}\n\n/**\n * Retrieve a subagent run by its ID.\n */\nexport function getSubagentRun(runId: string): SubagentRunRecord | undefined {\n return activeRuns.get(runId);\n}\n\n/**\n * Mark a subagent run as complete with result or error.\n */\nexport function completeSubagentRun(\n runId: string,\n status: \"done\" | \"error\" | \"timeout\" | \"cancelled\",\n result?: string,\n error?: string,\n): void {\n const record = activeRuns.get(runId);\n if (record) {\n record.status = status;\n record.result = result;\n record.error = error;\n record.endedAt = Date.now();\n // Clean up abort controller\n delete record.abortController;\n }\n}\n\n/**\n * Cancel a subagent run and all its children.\n */\nexport function cancelSubagentRun(runId: string): boolean {\n const record = activeRuns.get(runId);\n if (!record) return false;\n\n // Abort the controller if it exists\n if (record.abortController && !record.abortController.signal.aborted) {\n record.abortController.abort();\n }\n\n // Mark as cancelled\n completeSubagentRun(runId, \"cancelled\", undefined, \"Cancelled by user or parent\");\n\n // Recursively cancel children\n for (const [childRunId, childRecord] of activeRuns) {\n if (childRecord.parentSessionId === record.childSessionId && childRecord.status === \"running\") {\n cancelSubagentRun(childRunId);\n }\n }\n\n return true;\n}\n\n/**\n * Cancel all children of a parent session.\n */\nexport function cancelChildrenOfSession(parentSessionId: string): number {\n let count = 0;\n for (const [runId, record] of activeRuns) {\n if (record.parentSessionId === parentSessionId && record.status === \"running\") {\n if (cancelSubagentRun(runId)) {\n count++;\n }\n }\n }\n return count;\n}\n\n/**\n * Count how many active (running) children belong to a parent session.\n */\nexport function countActiveChildren(parentSessionId: string): number {\n let count = 0;\n for (const r of activeRuns.values()) {\n if (r.parentSessionId === parentSessionId && r.status === \"running\") {\n count++;\n }\n }\n return count;\n}\n\n/**\n * Get the depth of a session (0 for root, 1+ for subagents).\n */\nexport function getDepthForSession(sessionId: string): number {\n for (const r of activeRuns.values()) {\n if (r.childSessionId === sessionId) {\n return r.depth;\n }\n }\n return 0;\n}\n\n/**\n * Cleanup old completed subagent records.\n * @param maxAgeMs Maximum age in milliseconds (default: 30 minutes)\n */\nexport function cleanupSubagentRecords(maxAgeMs = 30 * 60 * 1000): void {\n const now = Date.now();\n for (const [runId, record] of activeRuns) {\n if (\n record.status !== \"running\" &&\n record.endedAt &&\n now - record.endedAt > maxAgeMs\n ) {\n activeRuns.delete(runId);\n }\n }\n}\n","import type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport type { WorkspaceManager } from \"../../workspace/manager.js\";\n\n/**\n * Creates a switch_workspace tool for channel-based runners.\n * Allows the user to list workspaces or switch to a different one.\n * Switching updates the workspace mapping so the next message uses the new workspace.\n */\nexport function createSwitchWorkspaceTool(\n workspaceManager: WorkspaceManager,\n chatKey: string,\n): ToolHandler {\n return {\n definition: {\n name: \"switch_workspace\",\n description:\n \"Switch the active workspace/project for this chat. Use 'list' to show available workspaces, or 'switch' with a workspace name to change. After switching, a fresh conversation starts in the new workspace context.\",\n inputSchema: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n description: \"The action to perform\",\n enum: [\"list\", \"switch\"],\n },\n workspace_name: {\n type: \"string\",\n description: \"The name of the workspace to switch to (case-insensitive partial match).\",\n },\n },\n required: [\"action\"],\n },\n },\n\n execute: async (\n args: Record<string, unknown>,\n _context: ToolExecutionContext,\n ): Promise<ToolResult> => {\n const action = args.action as string;\n\n try {\n const workspaces = await workspaceManager.list();\n\n if (action === \"list\") {\n if (workspaces.length === 0) {\n return { toolCallId: \"\", content: \"No workspaces configured.\" };\n }\n const currentWsId = workspaceManager.getChannelWorkspace(chatKey);\n const lines = workspaces.map((ws) => {\n const active = ws.id === currentWsId ? \" (active)\" : \"\";\n return `- **${ws.name}**${active}`;\n });\n return { toolCallId: \"\", content: `Available workspaces:\\n${lines.join(\"\\n\")}` };\n }\n\n if (action === \"switch\") {\n const name = args.workspace_name as string;\n if (!name) {\n return { toolCallId: \"\", content: \"workspace_name is required for switch.\", isError: true };\n }\n\n const query = name.toLowerCase();\n const match =\n workspaces.find((ws) => ws.name.toLowerCase() === query) ??\n workspaces.find((ws) => ws.name.toLowerCase().includes(query));\n\n if (!match) {\n const available = workspaces.map((ws) => ws.name).join(\", \");\n return { toolCallId: \"\", content: `No workspace matching \"${name}\". Available: ${available}`, isError: true };\n }\n\n workspaceManager.setChannelWorkspace(chatKey, match.id);\n return { toolCallId: \"\", content: `Switched to workspace **${match.name}**. The next message will start a fresh conversation in this workspace.` };\n }\n\n return { toolCallId: \"\", content: `Unknown action: ${action}. Use \"list\" or \"switch\".`, isError: true };\n } catch (err) {\n return { toolCallId: \"\", content: `Error: ${err instanceof Error ? err.message : String(err)}`, isError: true };\n }\n },\n };\n}\n","import fs from \"node:fs/promises\";\nimport type { ToolHandler, ToolExecutionContext } from \"../types.js\";\nimport type { ToolResult } from \"../../providers/types.js\";\nimport { createSkill, updateSkill, readSkillFile, validateSkillName } from \"../../skills/writer.js\";\nimport { removeSkill } from \"../../skills/installer.js\";\n\n/**\n * Creates a skill management tool bound to the user skills directory.\n */\nexport function createSkillTool(\n userSkillsDir: string,\n bundledSkillNames: string[],\n): ToolHandler {\n const bundledNames = new Set(bundledSkillNames);\n\n return {\n definition: {\n name: \"cortask_skill\",\n description:\n 'Manage custom skills. To create: set action=\"create\", name, and content (full SKILL.md with YAML frontmatter + markdown). To update: action=\"update\" with name and content. To list: action=\"list\". To remove: action=\"remove\" and name.',\n inputSchema: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n description: \"The action to perform\",\n enum: [\"create\", \"update\", \"list\", \"remove\"],\n },\n name: {\n type: \"string\",\n description: \"Skill name in kebab-case (for create/update/remove)\",\n },\n content: {\n type: \"string\",\n description:\n \"Full SKILL.md content including YAML frontmatter and markdown body (for create/update)\",\n },\n },\n required: [\"action\"],\n },\n },\n\n execute: async (\n args: Record<string, unknown>,\n _context: ToolExecutionContext,\n ): Promise<ToolResult> => {\n const action = args.action as string;\n\n try {\n switch (action) {\n case \"create\": {\n const name = args.name as string;\n const content = args.content as string;\n if (!name || !content) {\n return {\n toolCallId: \"\",\n content: \"name and content are required for create\",\n isError: true,\n };\n }\n\n const nameErr = validateSkillName(name);\n if (nameErr) {\n return { toolCallId: \"\", content: nameErr, isError: true };\n }\n\n if (bundledNames.has(name)) {\n return {\n toolCallId: \"\",\n content: `Cannot create skill \"${name}\" — a built-in skill with that name already exists. Choose a different name.`,\n isError: true,\n };\n }\n\n const result = await createSkill(userSkillsDir, name, content);\n return {\n toolCallId: \"\",\n content: `Custom skill \"${result.name}\" created at ${result.path}. It will be available in the next conversation.`,\n };\n }\n\n case \"update\": {\n const name = args.name as string;\n const content = args.content as string;\n if (!name || !content) {\n return {\n toolCallId: \"\",\n content: \"name and content are required for update\",\n isError: true,\n };\n }\n\n await updateSkill(userSkillsDir, name, content);\n return {\n toolCallId: \"\",\n content: `Custom skill \"${name}\" updated. Changes will take effect in the next conversation.`,\n };\n }\n\n case \"list\": {\n try {\n const entries = await fs.readdir(userSkillsDir, {\n withFileTypes: true,\n });\n const dirs = entries\n .filter((e) => e.isDirectory())\n .map((e) => e.name);\n\n if (dirs.length === 0) {\n return {\n toolCallId: \"\",\n content: \"No custom skills found.\",\n };\n }\n\n return {\n toolCallId: \"\",\n content: `Custom skills:\\n${dirs.map((d) => `- ${d}`).join(\"\\n\")}`,\n };\n } catch {\n return {\n toolCallId: \"\",\n content: \"No custom skills found.\",\n };\n }\n }\n\n case \"remove\": {\n const name = args.name as string;\n if (!name) {\n return {\n toolCallId: \"\",\n content: \"name is required for remove\",\n isError: true,\n };\n }\n\n await removeSkill(name, userSkillsDir);\n return {\n toolCallId: \"\",\n content: `Custom skill \"${name}\" removed.`,\n };\n }\n\n default:\n return {\n toolCallId: \"\",\n content: `Unknown action: ${action}`,\n isError: true,\n };\n }\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Skill error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n };\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { clearSkillCache } from \"./loader.js\";\n\nconst SKILL_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n/**\n * Validate a skill name (kebab-case, 2-50 chars).\n */\nexport function validateSkillName(name: string): string | null {\n if (!name || name.length < 2 || name.length > 50) {\n return \"Skill name must be 2-50 characters\";\n }\n if (!SKILL_NAME_RE.test(name)) {\n return \"Skill name must be kebab-case (lowercase letters, numbers, hyphens)\";\n }\n return null;\n}\n\n/**\n * Create a new custom skill by writing a SKILL.md file.\n */\nexport async function createSkill(\n skillsDir: string,\n name: string,\n rawContent: string,\n): Promise<{ name: string; path: string }> {\n const nameErr = validateSkillName(name);\n if (nameErr) throw new Error(nameErr);\n\n const skillDir = path.join(skillsDir, name);\n\n // Check if directory already exists\n try {\n await fs.access(skillDir);\n throw new Error(`Skill \"${name}\" already exists`);\n } catch (err) {\n if ((err as Error).message.includes(\"already exists\")) throw err;\n // Directory doesn't exist — good\n }\n\n await fs.mkdir(skillDir, { recursive: true });\n await fs.writeFile(path.join(skillDir, \"SKILL.md\"), rawContent, \"utf-8\");\n\n clearSkillCache();\n return { name, path: skillDir };\n}\n\n/**\n * Update an existing custom skill's SKILL.md file.\n */\nexport async function updateSkill(\n skillsDir: string,\n name: string,\n rawContent: string,\n): Promise<void> {\n const skillDir = path.join(skillsDir, name);\n const skillMdPath = path.join(skillDir, \"SKILL.md\");\n\n try {\n await fs.access(skillMdPath);\n } catch {\n throw new Error(`Skill \"${name}\" not found`);\n }\n\n await fs.writeFile(skillMdPath, rawContent, \"utf-8\");\n clearSkillCache();\n}\n\n/**\n * Read the raw SKILL.md content for editing.\n */\nexport async function readSkillFile(\n skillsDir: string,\n name: string,\n): Promise<string> {\n const skillMdPath = path.join(skillsDir, name, \"SKILL.md\");\n\n try {\n return await fs.readFile(skillMdPath, \"utf-8\");\n } catch {\n throw new Error(`Skill \"${name}\" not found`);\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport matter from \"gray-matter\";\nimport type {\n SkillManifest,\n SkillEntry,\n SkillSource,\n SkillInstallOption,\n CredentialSchema,\n} from \"./types.js\";\nimport { loadCredentialSchema, getCredentialStorageKey, getOAuth2StorageKeys, getInstanceRegistryKey, getInstanceStorageKey } from \"./credential-schema.js\";\nimport type { CredentialStore } from \"../credentials/store.js\";\nimport { logger } from \"../logging/logger.js\";\n\n// In-memory cache\nlet skillCache: SkillEntry[] | null = null;\n\nexport function clearSkillCache(): void {\n skillCache = null;\n}\n\n/**\n * Load all skills from bundled, user, and config directories.\n */\nexport async function loadSkills(\n bundledDir: string | null,\n userDir: string | null,\n configDirs: string[],\n credentialStore: CredentialStore | null,\n): Promise<SkillEntry[]> {\n if (skillCache) return skillCache;\n\n const skills: SkillEntry[] = [];\n\n // Load from bundled skills directory\n if (bundledDir) {\n const entries = await scanSkillDir(bundledDir, \"bundled\");\n skills.push(...entries);\n }\n\n // Load from user data directory\n if (userDir) {\n const entries = await scanSkillDir(userDir, \"user\");\n skills.push(...entries);\n }\n\n // Load from config-specified directories\n for (const dir of configDirs) {\n const entries = await scanSkillDir(dir, \"config-dir\");\n skills.push(...entries);\n }\n\n // Check eligibility and credential status for all skills\n for (const skill of skills) {\n // Load credential schema\n skill.credentialSchema = await loadCredentialSchema(skill.path);\n\n // Check eligibility\n const result = await checkEligibility(skill, credentialStore);\n skill.eligible = result.eligible;\n skill.ineligibleReason = result.reason;\n skill.credentialStatus = result.credentialStatus;\n\n // Filter install options by platform\n if (skill.manifest.install) {\n skill.installOptions = skill.manifest.install\n .filter((spec) => {\n if (!spec.os) return true;\n return spec.os.includes(process.platform);\n })\n .map((spec, i) => ({\n id: spec.id ?? `install-${i}`,\n kind: spec.kind,\n label: spec.label ?? `Install via ${spec.kind}`,\n }));\n }\n }\n\n skillCache = skills;\n return skills;\n}\n\n/**\n * Get only eligible skills.\n */\nexport function getEligibleSkills(skills: SkillEntry[]): SkillEntry[] {\n return skills.filter((s) => s.eligible);\n}\n\n/**\n * Scan a directory for skill subdirectories containing SKILL.md.\n */\nasync function scanSkillDir(\n dir: string,\n source: SkillSource,\n): Promise<SkillEntry[]> {\n const skills: SkillEntry[] = [];\n\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const skillDir = path.join(dir, entry.name);\n const skillMdPath = path.join(skillDir, \"SKILL.md\");\n\n try {\n const raw = await fs.readFile(skillMdPath, \"utf-8\");\n const parsed = matter(raw);\n const manifest = parsed.data as SkillManifest;\n\n if (!manifest.name) {\n manifest.name = entry.name;\n }\n if (!manifest.description) {\n manifest.description = \"\";\n }\n\n // Detect git-installed skills\n let skillSource = source;\n try {\n await fs.access(path.join(skillDir, \".origin\"));\n skillSource = \"git\";\n } catch {\n // Not a git skill\n }\n\n // Detect code tools (index.js)\n let hasCodeTools = false;\n try {\n await fs.access(path.join(skillDir, \"index.js\"));\n hasCodeTools = true;\n } catch {\n // No code tools\n }\n\n skills.push({\n manifest,\n content: parsed.content.trim(),\n path: skillDir,\n eligible: false, // Will be set by checkEligibility\n source: skillSource,\n editable: skillSource !== \"bundled\",\n hasCodeTools,\n });\n } catch {\n // No SKILL.md or parse error — skip\n }\n }\n } catch {\n // Directory doesn't exist — skip\n }\n\n return skills;\n}\n\ninterface EligibilityResult {\n eligible: boolean;\n reason?: string;\n credentialStatus?: Record<string, boolean>;\n}\n\n/**\n * Check if a skill is eligible to run on this system.\n */\nasync function checkEligibility(\n skill: SkillEntry,\n credentialStore: CredentialStore | null,\n): Promise<EligibilityResult> {\n const { manifest } = skill;\n\n // `always: true` bypasses all checks\n if (manifest.always) {\n return { eligible: true };\n }\n\n // OS check\n const requiredOs = manifest.compatibility?.os;\n if (requiredOs && !requiredOs.includes(process.platform)) {\n return {\n eligible: false,\n reason: `Requires OS: ${requiredOs.join(\", \")} (current: ${process.platform})`,\n };\n }\n\n // Environment variable check\n if (manifest.requires?.env) {\n for (const envVar of manifest.requires.env) {\n if (!process.env[envVar]) {\n return {\n eligible: false,\n reason: `Missing environment variable: ${envVar}`,\n };\n }\n }\n }\n\n // Binary availability check\n if (manifest.requires?.bins) {\n for (const bin of manifest.requires.bins) {\n if (!(await isBinaryAvailable(bin))) {\n return {\n eligible: false,\n reason: `Missing binary: ${bin}`,\n };\n }\n }\n }\n\n // Credential check\n if (skill.credentialSchema && credentialStore) {\n const credentialStatus: Record<string, boolean> = {};\n let allFulfilled = true;\n\n for (const cred of skill.credentialSchema.credentials) {\n if (cred.type === \"oauth2\") {\n const keys = getOAuth2StorageKeys(manifest.name, cred.id);\n const hasToken = await credentialStore.has(keys.accessToken);\n credentialStatus[cred.id] = hasToken;\n if (!hasToken) allFulfilled = false;\n } else if (cred.multiple && cred.fields) {\n // Multi-instance: eligible if at least one instance has all required fields\n const registryKey = getInstanceRegistryKey(manifest.name, cred.id, cred.storeAs);\n const raw = await credentialStore.get(registryKey);\n const instances = raw ? JSON.parse(raw) as Array<{ id: string }> : [];\n let anyInstanceFulfilled = false;\n\n for (const instance of instances) {\n let instanceOk = true;\n for (const field of cred.fields) {\n if (field.required === false) continue;\n const key = getInstanceStorageKey(\n manifest.name,\n cred.id,\n instance.id,\n field.key,\n cred.storeAs,\n );\n if (!(await credentialStore.has(key))) {\n instanceOk = false;\n break;\n }\n }\n if (instanceOk) {\n anyInstanceFulfilled = true;\n break;\n }\n }\n\n credentialStatus[cred.id] = anyInstanceFulfilled;\n if (!anyInstanceFulfilled) allFulfilled = false;\n } else if (cred.fields) {\n let fieldsFulfilled = true;\n for (const field of cred.fields) {\n if (field.required === false) continue;\n const key = getCredentialStorageKey(\n manifest.name,\n cred.id,\n field.key,\n cred.storeAs,\n );\n const exists = await credentialStore.has(key);\n if (!exists) {\n fieldsFulfilled = false;\n break;\n }\n }\n credentialStatus[cred.id] = fieldsFulfilled;\n if (!fieldsFulfilled) allFulfilled = false;\n }\n }\n\n if (!allFulfilled) {\n return {\n eligible: false,\n reason: \"Missing required credentials\",\n credentialStatus,\n };\n }\n\n return { eligible: true, credentialStatus };\n }\n\n return { eligible: true };\n}\n\n/**\n * Check if a binary is available on PATH.\n */\nasync function isBinaryAvailable(name: string): Promise<boolean> {\n const { exec } = await import(\"node:child_process\");\n const cmd = process.platform === \"win32\" ? `where ${name}` : `which ${name}`;\n\n return new Promise((resolve) => {\n exec(cmd, (error) => {\n resolve(!error);\n });\n });\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { CredentialSchema, CredentialInstance } from \"./types.js\";\n\n/**\n * Load credential schema from a skill's credentials.json file.\n */\nexport async function loadCredentialSchema(\n skillDir: string,\n): Promise<CredentialSchema | undefined> {\n const schemaPath = path.join(skillDir, \"credentials.json\");\n try {\n const raw = await fs.readFile(schemaPath, \"utf-8\");\n const parsed = JSON.parse(raw) as CredentialSchema;\n\n if (\n !parsed.credentials ||\n !Array.isArray(parsed.credentials)\n ) {\n return undefined;\n }\n\n return parsed;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Get the credential store key for a skill credential field.\n * Format: skill.{skillName}.{credentialId}.{fieldKey}\n */\nexport function getCredentialStorageKey(\n skillName: string,\n credentialId: string,\n fieldKey: string,\n storeAs?: string,\n): string {\n if (storeAs) {\n return `${storeAs}.${fieldKey}`;\n }\n return `skill.${skillName}.${credentialId}.${fieldKey}`;\n}\n\n/**\n * Get the credential store key for a multi-instance credential field.\n * Format: skill.{skillName}.{credentialId}.{instanceId}.{fieldKey}\n */\nexport function getInstanceStorageKey(\n skillName: string,\n credentialId: string,\n instanceId: string,\n fieldKey: string,\n storeAs?: string,\n): string {\n if (storeAs) {\n return `${storeAs}.${instanceId}.${fieldKey}`;\n }\n return `skill.${skillName}.${credentialId}.${instanceId}.${fieldKey}`;\n}\n\n/**\n * Get the registry key that stores the list of instances for a multi-instance credential.\n * Value is a JSON array of CredentialInstance objects.\n */\nexport function getInstanceRegistryKey(\n skillName: string,\n credentialId: string,\n storeAs?: string,\n): string {\n if (storeAs) {\n return `${storeAs}._instances`;\n }\n return `skill.${skillName}.${credentialId}._instances`;\n}\n\n/**\n * Slugify a label into a valid instance ID.\n */\nexport function slugifyInstanceLabel(label: string): string {\n return label\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\n/**\n * Get OAuth2 storage keys for a skill credential.\n */\nexport function getOAuth2StorageKeys(\n skillName: string,\n credentialId: string,\n): {\n accessToken: string;\n refreshToken: string;\n expiresAt: string;\n} {\n const prefix = `skill.${skillName}.${credentialId}.oauth2`;\n return {\n accessToken: `${prefix}.accessToken`,\n refreshToken: `${prefix}.refreshToken`,\n expiresAt: `${prefix}.expiresAt`,\n };\n}\n","import { execFile } from \"node:child_process\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { clearSkillCache } from \"./loader.js\";\nimport { logger } from \"../logging/logger.js\";\n\n/**\n * Install a skill from a git URL into the user skills directory.\n */\nexport async function installSkillFromGit(\n gitUrl: string,\n skillsDir: string,\n): Promise<{ name: string; path: string }> {\n await fs.mkdir(skillsDir, { recursive: true });\n\n // Extract repo name from URL\n const repoName = gitUrl\n .split(\"/\")\n .pop()\n ?.replace(/\\.git$/, \"\");\n\n if (!repoName) {\n throw new Error(`Invalid git URL: ${gitUrl}`);\n }\n\n // Validate URL format to prevent malicious input\n if (!/^(https?:\\/\\/|git@[\\w.-]+:|ssh:\\/\\/)/.test(gitUrl)) {\n throw new Error(`Invalid git URL format: ${gitUrl}`);\n }\n\n const targetDir = path.join(skillsDir, repoName);\n\n // Check if already installed\n try {\n await fs.access(targetDir);\n throw new Error(`Skill \"${repoName}\" is already installed`);\n } catch (err) {\n if ((err as Error).message.includes(\"already installed\")) throw err;\n // Directory doesn't exist — good\n }\n\n // Clone the repo (using execFile to prevent shell injection)\n await execFileAsync(\"git\", [\"clone\", \"--depth\", \"1\", gitUrl, targetDir]);\n\n // Verify SKILL.md exists\n try {\n await fs.access(path.join(targetDir, \"SKILL.md\"));\n } catch {\n // Clean up\n await fs.rm(targetDir, { recursive: true, force: true });\n throw new Error(\n `Invalid skill: no SKILL.md found in ${repoName}`,\n );\n }\n\n // Write .origin marker\n await fs.writeFile(\n path.join(targetDir, \".origin\"),\n gitUrl,\n \"utf-8\",\n );\n\n // Remove .git directory to save space\n try {\n await fs.rm(path.join(targetDir, \".git\"), {\n recursive: true,\n force: true,\n });\n } catch {\n // Non-critical\n }\n\n clearSkillCache();\n logger.info(`Installed skill \"${repoName}\" from ${gitUrl}`, \"skills\");\n\n return { name: repoName, path: targetDir };\n}\n\n/**\n * Remove an installed skill.\n */\nexport async function removeSkill(\n skillName: string,\n skillsDir: string,\n): Promise<void> {\n const targetDir = path.join(skillsDir, skillName);\n\n try {\n await fs.access(targetDir);\n } catch {\n throw new Error(`Skill \"${skillName}\" not found`);\n }\n\n await fs.rm(targetDir, { recursive: true, force: true });\n clearSkillCache();\n logger.info(`Removed skill \"${skillName}\"`, \"skills\");\n}\n\nfunction execFileAsync(cmd: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(cmd, args, { timeout: 60_000 }, (error, stdout, stderr) => {\n if (error) {\n reject(new Error(stderr || error.message));\n return;\n }\n resolve(stdout);\n });\n });\n}\n","import type { ToolHandler } from \"../types.js\";\nimport { readFileTool } from \"./read-file.js\";\nimport { writeFileTool } from \"./write-file.js\";\nimport { listFilesTool } from \"./list-files.js\";\nimport { bashTool } from \"./bash.js\";\nimport { webFetchTool } from \"./web-fetch.js\";\nimport { webSearchTool } from \"./web-search.js\";\nimport { questionnaireTool } from \"./questionnaire.js\";\nimport { memoryReadTool, memorySaveTool, memoryAppendTool } from \"./memory.js\";\nimport { showFileTool } from \"./show-file.js\";\nimport { dataFileTool } from \"./data-file.js\";\n\nexport const builtinTools: ToolHandler[] = [\n readFileTool,\n writeFileTool,\n listFilesTool,\n bashTool,\n webFetchTool,\n webSearchTool,\n\n questionnaireTool,\n memoryReadTool,\n memorySaveTool,\n memoryAppendTool,\n showFileTool,\n dataFileTool,\n];\n\nexport {\n readFileTool,\n writeFileTool,\n listFilesTool,\n bashTool,\n webFetchTool,\n webSearchTool,\n\n questionnaireTool,\n memoryReadTool,\n memorySaveTool,\n memoryAppendTool,\n showFileTool,\n dataFileTool,\n};\n\nexport { createCronTool } from \"./cron.js\";\nexport { createArtifactTool } from \"./artifact.js\";\nexport { createBrowserTool } from \"./browser.js\";\nexport { ensureInstalled as ensureBrowserInstalled } from \"./browser-manager.js\";\nexport { createSubagentTool, setSubagentRunner } from \"./subagent.js\";\nexport { createSwitchWorkspaceTool } from \"./switch-workspace.js\";\nexport { createSkillTool } from \"./skill.js\";\n","import crypto from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport interface CredentialStore {\n get(key: string): Promise<string | null>;\n set(key: string, value: string): Promise<void>;\n delete(key: string): Promise<void>;\n has(key: string): Promise<boolean>;\n list(): Promise<string[]>;\n}\n\ninterface EncryptedData {\n iv: string;\n data: string;\n tag: string;\n salt: string;\n}\n\ninterface StoreFile {\n version: 1;\n entries: Record<string, EncryptedData>;\n}\n\nfunction deriveKey(secret: string, salt: Buffer): Buffer {\n return crypto.scryptSync(secret, salt, 32);\n}\n\nfunction encrypt(text: string, secret: string): EncryptedData {\n const salt = crypto.randomBytes(16);\n const key = deriveKey(secret, salt);\n const iv = crypto.randomBytes(12);\n const cipher = crypto.createCipheriv(\"aes-256-gcm\", key, iv);\n const encrypted = Buffer.concat([\n cipher.update(text, \"utf-8\"),\n cipher.final(),\n ]);\n const tag = cipher.getAuthTag();\n return {\n iv: iv.toString(\"hex\"),\n data: encrypted.toString(\"hex\"),\n tag: tag.toString(\"hex\"),\n salt: salt.toString(\"hex\"),\n };\n}\n\nfunction decrypt(enc: EncryptedData, secret: string): string {\n const salt = Buffer.from(enc.salt, \"hex\");\n const key = deriveKey(secret, salt);\n const iv = Buffer.from(enc.iv, \"hex\");\n const tag = Buffer.from(enc.tag, \"hex\");\n const decipher = crypto.createDecipheriv(\"aes-256-gcm\", key, iv);\n decipher.setAuthTag(tag);\n const decrypted = Buffer.concat([\n decipher.update(Buffer.from(enc.data, \"hex\")),\n decipher.final(),\n ]);\n return decrypted.toString(\"utf-8\");\n}\n\nexport class EncryptedCredentialStore implements CredentialStore {\n private filePath: string;\n private secret: string;\n private store: StoreFile | null = null;\n\n constructor(filePath: string, secret: string) {\n this.filePath = filePath;\n this.secret = secret;\n }\n\n private async load(): Promise<StoreFile> {\n if (this.store) return this.store;\n try {\n const raw = await fs.readFile(this.filePath, \"utf-8\");\n this.store = JSON.parse(raw) as StoreFile;\n } catch {\n this.store = { version: 1, entries: {} };\n }\n return this.store;\n }\n\n private async save(): Promise<void> {\n if (!this.store) return;\n await fs.mkdir(path.dirname(this.filePath), { recursive: true });\n const tmp = `${this.filePath}.${process.pid}.tmp`;\n await fs.writeFile(tmp, JSON.stringify(this.store, null, 2), {\n encoding: \"utf-8\",\n mode: 0o600,\n });\n await fs.rename(tmp, this.filePath);\n }\n\n async get(key: string): Promise<string | null> {\n const store = await this.load();\n const entry = store.entries[key];\n if (!entry) return null;\n try {\n return decrypt(entry, this.secret);\n } catch {\n return null;\n }\n }\n\n async set(key: string, value: string): Promise<void> {\n const store = await this.load();\n store.entries[key] = encrypt(value, this.secret);\n await this.save();\n }\n\n async delete(key: string): Promise<void> {\n const store = await this.load();\n delete store.entries[key];\n await this.save();\n }\n\n async has(key: string): Promise<boolean> {\n const store = await this.load();\n return key in store.entries;\n }\n\n async list(): Promise<string[]> {\n const store = await this.load();\n return Object.keys(store.entries);\n }\n}\n\nexport async function getOrCreateSecret(dataDir: string): Promise<string> {\n const secretFromEnv = process.env.CORTASK_SECRET;\n if (secretFromEnv) return secretFromEnv;\n\n const keyPath = path.join(dataDir, \"master.key\");\n try {\n return await fs.readFile(keyPath, \"utf-8\");\n } catch {\n const key = crypto.randomBytes(32).toString(\"hex\");\n await fs.mkdir(path.dirname(keyPath), { recursive: true });\n await fs.writeFile(keyPath, key, { mode: 0o600 });\n return key;\n }\n}\n\nexport function credentialKey(\n category: string,\n ...parts: string[]\n): string {\n return [category, ...parts].join(\".\");\n}\n","import { z } from \"zod\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\n\nconst providerConfigSchema = z.object({\n model: z.string().optional(),\n});\n\nconst agentConfigSchema = z.object({\n maxTurns: z.number().int().min(1).max(200).default(25),\n temperature: z.number().min(0).max(2).default(0.7),\n maxTokens: z.number().int().positive().optional(),\n});\n\nconst telegramChannelSchema = z.object({\n enabled: z.boolean().default(false),\n allowedUsers: z.array(z.string()).default([]),\n});\n\nconst channelsConfigSchema = z.object({\n telegram: telegramChannelSchema.default({}),\n});\n\nconst skillsConfigSchema = z.object({\n dirs: z.array(z.string()).default([]),\n});\n\nconst spendingLimitSchema = z.object({\n enabled: z.boolean().default(false),\n maxTokens: z.number().int().nonnegative().optional(),\n maxCostUsd: z.number().nonnegative().optional(),\n period: z.enum([\"daily\", \"weekly\", \"monthly\"]).default(\"monthly\"),\n});\n\nconst serverConfigSchema = z.object({\n port: z.number().int().min(1).max(65535).default(3777),\n host: z.string().default(\"127.0.0.1\"),\n});\n\nexport const cortaskConfigSchema = z.object({\n onboarded: z.boolean().default(false),\n workspace: z\n .object({\n defaultDir: z.string().optional(),\n })\n .default({}),\n providers: z\n .object({\n default: z.string().default(\"anthropic\"),\n anthropic: providerConfigSchema.default({}),\n openai: providerConfigSchema.default({}),\n google: providerConfigSchema.default({}),\n moonshot: providerConfigSchema.default({}),\n grok: providerConfigSchema.default({}),\n openrouter: providerConfigSchema.default({}),\n minimax: providerConfigSchema.default({}),\n ollama: providerConfigSchema.default({}),\n })\n .default({}),\n agent: agentConfigSchema.default({}),\n spending: spendingLimitSchema.default({}),\n channels: channelsConfigSchema.default({}),\n skills: skillsConfigSchema.default({}),\n server: serverConfigSchema.default({}),\n});\n\nexport type CortaskConfig = z.infer<typeof cortaskConfigSchema>;\n\nexport async function loadConfig(configPath: string): Promise<CortaskConfig> {\n try {\n const raw = await fs.readFile(configPath, \"utf-8\");\n // Simple env var substitution: ${ENV_VAR}\n const resolved = raw.replace(/\\$\\{(\\w+)\\}/g, (_, name) => {\n return process.env[name] ?? \"\";\n });\n\n // Dynamic import of yaml parser — use JSON as fallback\n let parsed: unknown;\n if (configPath.endsWith(\".yaml\") || configPath.endsWith(\".yml\")) {\n // Use a simple YAML subset parser or require yaml package\n const { parse } = await import(\"yaml\" as string).catch(() => ({\n parse: (s: string) => JSON.parse(s),\n }));\n parsed = parse(resolved);\n } else {\n parsed = JSON.parse(resolved);\n }\n\n return cortaskConfigSchema.parse(parsed);\n } catch {\n // Return defaults if no config file exists\n return cortaskConfigSchema.parse({});\n }\n}\n\nexport async function saveConfig(\n configPath: string,\n config: CortaskConfig,\n): Promise<void> {\n const dir = path.dirname(configPath);\n await fs.mkdir(dir, { recursive: true });\n\n if (configPath.endsWith(\".yaml\") || configPath.endsWith(\".yml\")) {\n const { stringify } = await import(\"yaml\" as string).catch(() => ({\n stringify: (obj: unknown) => JSON.stringify(obj, null, 2),\n }));\n await fs.writeFile(configPath, stringify(config), \"utf-8\");\n } else {\n await fs.writeFile(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n }\n}\n\nexport function getDataDir(): string {\n if (process.env.CORTASK_DATA_DIR) {\n return process.env.CORTASK_DATA_DIR;\n }\n const home =\n process.env.HOME || process.env.USERPROFILE || process.cwd();\n return path.join(home, \".cortask\");\n}\n","import { createProvider, type ProviderId } from \"../providers/index.js\";\nimport type { ProviderValidationResult } from \"./types.js\";\n\nexport async function validateProvider(\n type: ProviderId,\n apiKey: string,\n): Promise<ProviderValidationResult> {\n try {\n const provider = createProvider(type, apiKey);\n\n // Test with a simple prompt\n const result = await provider.generateText({\n model: getDefaultModel(type),\n messages: [{ role: \"user\", content: \"Hi\" }],\n maxTokens: 10,\n });\n\n return {\n valid: true,\n model: getDefaultModel(type),\n };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : \"Invalid API key\",\n };\n }\n}\n\nfunction getDefaultModel(type: ProviderId): string {\n switch (type) {\n case \"anthropic\":\n return \"claude-sonnet-4-5-20250929\";\n case \"openai\":\n return \"gpt-4o\";\n case \"google\":\n return \"gemini-2.0-flash-exp\";\n case \"moonshot\":\n return \"moonshot-v1-8k\";\n case \"grok\":\n return \"grok-3-latest\";\n case \"openrouter\":\n return \"openai/gpt-4o\";\n case \"minimax\":\n return \"MiniMax-Text-01\";\n default:\n throw new Error(`Unknown provider: ${type}`);\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport Database from \"better-sqlite3\";\n\nexport interface Workspace {\n id: string;\n name: string;\n rootPath: string;\n lastAccessedAt: string;\n provider?: string;\n model?: string;\n skills?: string[];\n}\n\nconst CORTASK_DIR = \".cortask\";\n\nexport class WorkspaceManager {\n private db: Database.Database;\n private dataDir: string;\n private activeWorkspaceId: string | null = null;\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.dataDir = path.dirname(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.db.pragma(\"foreign_keys = ON\");\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS workspaces (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n root_path TEXT NOT NULL UNIQUE,\n last_accessed_at TEXT NOT NULL,\n provider TEXT,\n model TEXT,\n skills TEXT,\n sort_order INTEGER NOT NULL DEFAULT 0\n );\n CREATE TABLE IF NOT EXISTS channel_workspace_map (\n chat_key TEXT PRIMARY KEY,\n workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE\n )\n `);\n // Migration: add sort_order if missing\n const cols = this.db.pragma(\"table_info(workspaces)\") as Array<{ name: string }>;\n if (!cols.some((c) => c.name === \"sort_order\")) {\n this.db.exec(\"ALTER TABLE workspaces ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0\");\n }\n }\n\n async list(): Promise<Workspace[]> {\n const rows = this.db\n .prepare(\n \"SELECT * FROM workspaces ORDER BY sort_order ASC, last_accessed_at DESC LIMIT 20\",\n )\n .all() as Array<{\n id: string;\n name: string;\n root_path: string;\n last_accessed_at: string;\n provider: string | null;\n model: string | null;\n skills: string | null;\n sort_order: number;\n }>;\n\n return rows.map((r) => ({\n id: r.id,\n name: r.name,\n rootPath: r.root_path,\n lastAccessedAt: r.last_accessed_at,\n provider: r.provider ?? undefined,\n model: r.model ?? undefined,\n skills: r.skills ? JSON.parse(r.skills) : undefined,\n }));\n }\n\n async get(id: string): Promise<Workspace | null> {\n const row = this.db\n .prepare(\"SELECT * FROM workspaces WHERE id = ?\")\n .get(id) as {\n id: string;\n name: string;\n root_path: string;\n last_accessed_at: string;\n provider: string | null;\n model: string | null;\n skills: string | null;\n } | undefined;\n\n if (!row) return null;\n\n return {\n id: row.id,\n name: row.name,\n rootPath: row.root_path,\n lastAccessedAt: row.last_accessed_at,\n provider: row.provider ?? undefined,\n model: row.model ?? undefined,\n skills: row.skills ? JSON.parse(row.skills) : undefined,\n };\n }\n\n async create(name: string, rootPath?: string): Promise<Workspace> {\n const id = crypto.randomUUID();\n const now = new Date().toISOString();\n const absPath = rootPath\n ? path.resolve(rootPath)\n : path.join(this.dataDir, \"projects\", id);\n\n // Ensure .cortask directory exists in the workspace\n const cortaskDir = path.join(absPath, CORTASK_DIR);\n await fs.mkdir(cortaskDir, { recursive: true });\n\n // Create default memory.md\n const memoryPath = path.join(cortaskDir, \"memory.md\");\n try {\n await fs.access(memoryPath);\n } catch {\n await fs.writeFile(\n memoryPath,\n \"# Project Memory\\n\\nThis file is used by Cortask to remember important context about this project.\\n\",\n \"utf-8\",\n );\n }\n\n this.db\n .prepare(\n \"INSERT INTO workspaces (id, name, root_path, last_accessed_at) VALUES (?, ?, ?, ?)\",\n )\n .run(id, name, absPath, now);\n\n return { id, name, rootPath: absPath, lastAccessedAt: now };\n }\n\n async update(\n id: string,\n updates: Partial<Pick<Workspace, \"name\" | \"provider\" | \"model\" | \"skills\">>,\n ): Promise<void> {\n const sets: string[] = [];\n const values: unknown[] = [];\n\n if (updates.name !== undefined) {\n sets.push(\"name = ?\");\n values.push(updates.name);\n }\n if (updates.provider !== undefined) {\n sets.push(\"provider = ?\");\n values.push(updates.provider);\n }\n if (updates.model !== undefined) {\n sets.push(\"model = ?\");\n values.push(updates.model);\n }\n if (updates.skills !== undefined) {\n sets.push(\"skills = ?\");\n values.push(JSON.stringify(updates.skills));\n }\n\n if (sets.length === 0) return;\n\n values.push(id);\n this.db\n .prepare(`UPDATE workspaces SET ${sets.join(\", \")} WHERE id = ?`)\n .run(...values);\n }\n\n async reorder(orderedIds: string[]): Promise<void> {\n const update = this.db.prepare(\n \"UPDATE workspaces SET sort_order = ? WHERE id = ?\",\n );\n const transaction = this.db.transaction(() => {\n for (let i = 0; i < orderedIds.length; i++) {\n update.run(i, orderedIds[i]);\n }\n });\n transaction();\n }\n\n async delete(id: string): Promise<void> {\n this.db.prepare(\"DELETE FROM workspaces WHERE id = ?\").run(id);\n }\n\n async open(id: string): Promise<Workspace | null> {\n const workspace = await this.get(id);\n if (!workspace) return null;\n\n this.db\n .prepare(\"UPDATE workspaces SET last_accessed_at = ? WHERE id = ?\")\n .run(new Date().toISOString(), id);\n\n this.activeWorkspaceId = id;\n return workspace;\n }\n\n getActiveWorkspaceId(): string | null {\n return this.activeWorkspaceId;\n }\n\n async getActiveWorkspace(): Promise<Workspace | null> {\n if (!this.activeWorkspaceId) return null;\n return this.get(this.activeWorkspaceId);\n }\n\n async readMemory(workspacePath: string): Promise<string | undefined> {\n const memoryPath = path.join(workspacePath, CORTASK_DIR, \"memory.md\");\n try {\n return await fs.readFile(memoryPath, \"utf-8\");\n } catch {\n return undefined;\n }\n }\n\n async writeMemory(workspacePath: string, content: string): Promise<void> {\n const memoryPath = path.join(workspacePath, CORTASK_DIR, \"memory.md\");\n await fs.mkdir(path.dirname(memoryPath), { recursive: true });\n await fs.writeFile(memoryPath, content, \"utf-8\");\n }\n\n async readGlobalMemory(dataDir: string): Promise<string | undefined> {\n const memoryPath = path.join(dataDir, \"memory.md\");\n try {\n return await fs.readFile(memoryPath, \"utf-8\");\n } catch {\n return undefined;\n }\n }\n\n async writeGlobalMemory(dataDir: string, content: string): Promise<void> {\n await fs.mkdir(dataDir, { recursive: true });\n await fs.writeFile(path.join(dataDir, \"memory.md\"), content, \"utf-8\");\n }\n\n getSessionDbPath(workspacePath: string): string {\n return path.join(workspacePath, CORTASK_DIR, \"sessions.db\");\n }\n\n getChannelWorkspace(chatKey: string): string | null {\n const row = this.db\n .prepare(\"SELECT workspace_id FROM channel_workspace_map WHERE chat_key = ?\")\n .get(chatKey) as { workspace_id: string } | undefined;\n return row?.workspace_id ?? null;\n }\n\n setChannelWorkspace(chatKey: string, workspaceId: string): void {\n this.db\n .prepare(\"INSERT OR REPLACE INTO channel_workspace_map (chat_key, workspace_id) VALUES (?, ?)\")\n .run(chatKey, workspaceId);\n }\n\n close(): void {\n this.db.close();\n }\n}\n","import Database from \"better-sqlite3\";\nimport type { Message } from \"../providers/types.js\";\n\nexport type ChannelType = \"whatsapp\" | \"telegram\" | \"discord\";\n\nexport interface Session {\n id: string;\n title: string;\n createdAt: string;\n updatedAt: string;\n parentSessionId?: string;\n depth?: number;\n channel?: ChannelType;\n}\n\nexport interface SessionWithMessages extends Session {\n messages: Message[];\n}\n\nexport class SessionStore {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n title TEXT NOT NULL DEFAULT 'New Chat',\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n parent_session_id TEXT,\n depth INTEGER DEFAULT 0,\n channel TEXT\n );\n CREATE TABLE IF NOT EXISTS messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n created_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);\n CREATE INDEX IF NOT EXISTS idx_sessions_parent ON sessions(parent_session_id);\n `);\n\n // Note: Migrations are run at server startup via migrateSessionDatabase()\n // See packages/core/src/session/migrate.ts\n }\n\n listSessions(): Session[] {\n return this.db\n .prepare(\n \"SELECT id, title, created_at as createdAt, updated_at as updatedAt, parent_session_id as parentSessionId, depth, channel FROM sessions ORDER BY updated_at DESC\",\n )\n .all() as Session[];\n }\n\n getSession(id: string): SessionWithMessages | null {\n const session = this.db\n .prepare(\n \"SELECT id, title, created_at as createdAt, updated_at as updatedAt, parent_session_id as parentSessionId, depth, channel FROM sessions WHERE id = ?\",\n )\n .get(id) as Session | undefined;\n\n if (!session) return null;\n\n const rows = this.db\n .prepare(\n \"SELECT role, content FROM messages WHERE session_id = ? ORDER BY id ASC\",\n )\n .all(id) as Array<{ role: string; content: string }>;\n\n const messages: Message[] = rows.map((r) => ({\n role: r.role as Message[\"role\"],\n content: JSON.parse(r.content),\n }));\n\n return { ...session, messages };\n }\n\n createSession(id: string, title?: string, parentSessionId?: string, depth?: number, channel?: ChannelType): Session {\n const now = new Date().toISOString();\n this.db\n .prepare(\n \"INSERT INTO sessions (id, title, created_at, updated_at, parent_session_id, depth, channel) VALUES (?, ?, ?, ?, ?, ?, ?)\",\n )\n .run(id, title ?? \"New Chat\", now, now, parentSessionId ?? null, depth ?? 0, channel ?? null);\n\n return { id, title: title ?? \"New Chat\", createdAt: now, updatedAt: now, parentSessionId, depth, channel };\n }\n\n saveMessages(sessionId: string, messages: Message[], channel?: ChannelType): void {\n // Ensure session exists\n const exists = this.db\n .prepare(\"SELECT 1 FROM sessions WHERE id = ?\")\n .get(sessionId);\n\n if (!exists) {\n this.createSession(sessionId, undefined, undefined, undefined, channel);\n }\n\n // Clear existing messages and re-insert all\n const transaction = this.db.transaction(() => {\n this.db\n .prepare(\"DELETE FROM messages WHERE session_id = ?\")\n .run(sessionId);\n\n const insert = this.db.prepare(\n \"INSERT INTO messages (session_id, role, content, created_at) VALUES (?, ?, ?, ?)\",\n );\n\n const now = new Date().toISOString();\n for (const msg of messages) {\n insert.run(\n sessionId,\n msg.role,\n JSON.stringify(msg.content),\n now,\n );\n }\n\n this.db\n .prepare(\"UPDATE sessions SET updated_at = ? WHERE id = ?\")\n .run(now, sessionId);\n });\n\n transaction();\n }\n\n getMessages(sessionId: string): Message[] {\n const rows = this.db\n .prepare(\n \"SELECT role, content FROM messages WHERE session_id = ? ORDER BY id ASC\",\n )\n .all(sessionId) as Array<{ role: string; content: string }>;\n\n return rows.map((r) => ({\n role: r.role as Message[\"role\"],\n content: JSON.parse(r.content),\n }));\n }\n\n deleteSession(id: string): void {\n this.db.prepare(\"DELETE FROM sessions WHERE id = ?\").run(id);\n }\n\n updateTitle(id: string, title: string): void {\n this.db\n .prepare(\"UPDATE sessions SET title = ? WHERE id = ?\")\n .run(title, id);\n }\n\n close(): void {\n this.db.close();\n }\n}\n","import Database from \"better-sqlite3\";\nimport fs from \"node:fs\";\nimport { logger } from \"../logging/logger.js\";\n\n/**\n * Run database migrations on a session database.\n * This is separate from SessionStore to allow running migrations at startup\n * before any SessionStore instances are cached.\n */\nexport function migrateSessionDatabase(dbPath: string): void {\n // Check if database file exists\n if (!fs.existsSync(dbPath)) {\n logger.debug(`Session database does not exist yet: ${dbPath}`, \"migration\");\n return;\n }\n\n const db = new Database(dbPath);\n\n try {\n // Get current schema\n const columns = db\n .prepare(\"PRAGMA table_info(sessions)\")\n .all() as Array<{ name: string }>;\n\n if (columns.length === 0) {\n logger.debug(`Sessions table does not exist yet in: ${dbPath}`, \"migration\");\n db.close();\n return;\n }\n\n const hasParentSessionId = columns.some((c) => c.name === \"parent_session_id\");\n const hasDepth = columns.some((c) => c.name === \"depth\");\n const hasChannel = columns.some((c) => c.name === \"channel\");\n\n let changesMade = false;\n\n // Add parent_session_id column\n if (!hasParentSessionId) {\n logger.info(`Migrating database: adding parent_session_id to ${dbPath}`, \"migration\");\n db.exec(\"ALTER TABLE sessions ADD COLUMN parent_session_id TEXT\");\n changesMade = true;\n logger.info(\"✓ Added parent_session_id column\", \"migration\");\n }\n\n // Add depth column\n if (!hasDepth) {\n logger.info(`Migrating database: adding depth to ${dbPath}`, \"migration\");\n db.exec(\"ALTER TABLE sessions ADD COLUMN depth INTEGER DEFAULT 0\");\n changesMade = true;\n logger.info(\"✓ Added depth column\", \"migration\");\n }\n\n // Add channel column\n if (!hasChannel) {\n logger.info(`Migrating database: adding channel to ${dbPath}`, \"migration\");\n db.exec(\"ALTER TABLE sessions ADD COLUMN channel TEXT\");\n changesMade = true;\n logger.info(\"✓ Added channel column\", \"migration\");\n }\n\n // Create index if we added parent_session_id\n if (!hasParentSessionId) {\n db.exec(\n \"CREATE INDEX IF NOT EXISTS idx_sessions_parent ON sessions(parent_session_id)\",\n );\n logger.info(\"✓ Created parent session index\", \"migration\");\n }\n\n if (changesMade) {\n logger.info(`Migration complete for: ${dbPath}`, \"migration\");\n } else {\n logger.debug(`No migration needed for: ${dbPath}`, \"migration\");\n }\n } catch (err) {\n logger.error(\n `Migration failed for ${dbPath}: ${err instanceof Error ? err.message : String(err)}`,\n \"migration\",\n );\n throw err;\n } finally {\n db.close();\n }\n}\n\n/**\n * Migrate all workspace session databases.\n * @param workspaces Array of workspace objects with rootPath property\n */\nexport function migrateAllWorkspaces(workspaces: Array<{ rootPath: string }>): void {\n logger.info(`Running migrations for ${workspaces.length} workspace(s)`, \"migration\");\n\n let successCount = 0;\n let errorCount = 0;\n\n for (const workspace of workspaces) {\n const dbPath = `${workspace.rootPath}/.cortask/sessions.db`;\n try {\n migrateSessionDatabase(dbPath);\n successCount++;\n } catch (err) {\n errorCount++;\n logger.error(\n `Failed to migrate workspace ${workspace.rootPath}: ${err instanceof Error ? err.message : String(err)}`,\n \"migration\",\n );\n }\n }\n\n logger.info(\n `Migration summary: ${successCount} successful, ${errorCount} failed`,\n \"migration\",\n );\n\n if (errorCount > 0) {\n throw new Error(`Migration failed for ${errorCount} workspace(s)`);\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ToolDefinition, ToolResult } from \"../providers/types.js\";\nimport type {\n SkillEntry,\n SkillToolTemplate,\n SkillCodeTool,\n} from \"./types.js\";\nimport {\n getCredentialStorageKey,\n getOAuth2StorageKeys,\n getInstanceRegistryKey,\n getInstanceStorageKey,\n} from \"./credential-schema.js\";\nimport type { CredentialStore } from \"../credentials/store.js\";\nimport { logger } from \"../logging/logger.js\";\n\ninterface SkillToolRegistry {\n toolDefs: ToolDefinition[];\n toolNames: Set<string>;\n handlers: Map<\n string,\n (args: Record<string, unknown>, workspacePath: string) => Promise<ToolResult>\n >;\n}\n\n/**\n * Build tool definitions and handlers from eligible skills.\n */\nexport async function buildSkillTools(\n skills: SkillEntry[],\n credentialStore: CredentialStore | null,\n): Promise<SkillToolRegistry> {\n const toolDefs: ToolDefinition[] = [];\n const toolNames = new Set<string>();\n const handlers = new Map<\n string,\n (args: Record<string, unknown>, workspacePath: string) => Promise<ToolResult>\n >();\n\n for (const skill of skills) {\n // HTTP template tools\n if (skill.manifest.tools) {\n for (const template of skill.manifest.tools) {\n const def = buildHttpToolDefinition(template);\n toolDefs.push(def);\n toolNames.add(def.name);\n\n handlers.set(def.name, async (args, workspacePath) => {\n return executeHttpTool(\n template,\n args,\n skill,\n credentialStore,\n workspacePath,\n );\n });\n }\n }\n\n // Code tools (index.js)\n if (skill.hasCodeTools) {\n try {\n const indexPath = `file://${skill.path}/index.js`;\n const mod = await import(indexPath);\n const codeTools = (mod.tools ?? []) as SkillCodeTool[];\n\n for (const ct of codeTools) {\n toolDefs.push({\n name: ct.name,\n description: ct.description,\n inputSchema: ct.inputSchema,\n });\n toolNames.add(ct.name);\n\n handlers.set(ct.name, async (args, _workspacePath) => {\n try {\n const result = await ct.execute(args, {\n credentialStore,\n skillName: skill.manifest.name,\n });\n return {\n toolCallId: \"\",\n content: result.content,\n isError: result.isError,\n };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `Code tool error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n });\n }\n } catch (err) {\n logger.error(\n `Failed to load code tools for skill ${skill.manifest.name}: ${err}`,\n \"skills\",\n );\n }\n }\n }\n\n return { toolDefs, toolNames, handlers };\n}\n\n/**\n * Build a ToolDefinition from an HTTP template.\n */\nfunction buildHttpToolDefinition(\n template: SkillToolTemplate,\n): ToolDefinition {\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n\n for (const [key, input] of Object.entries(template.input)) {\n properties[key] = {\n type: input.type,\n description: input.description,\n };\n if (input.enum) {\n (properties[key] as Record<string, unknown>).enum = input.enum;\n }\n if (input.required !== false) {\n required.push(key);\n }\n }\n\n return {\n name: template.name,\n description: template.description,\n inputSchema: {\n type: \"object\",\n properties,\n required,\n },\n };\n}\n\n/**\n * Execute an HTTP template tool call.\n *\n * Supports three placeholder types in URL, headers, body:\n * - {{argName}} → from tool call arguments\n * - {{credential:fieldKey}} → from credential store\n * - {{oauth2:accessToken}} → from OAuth2 tokens\n */\nasync function executeHttpTool(\n template: SkillToolTemplate,\n args: Record<string, unknown>,\n skill: SkillEntry,\n credentialStore: CredentialStore | null,\n workspacePath: string,\n): Promise<ToolResult> {\n try {\n // Build credential values map\n const credValues = await resolveCredentials(skill, credentialStore);\n\n // Resolve URL\n const url = resolvePlaceholders(\n template.request.url,\n args,\n credValues,\n );\n\n // Resolve method\n const method = template.request.method\n ? resolvePlaceholders(template.request.method, args, credValues)\n : \"GET\";\n\n // Resolve headers\n const headers: Record<string, string> = {};\n if (template.request.headers) {\n for (const [key, value] of Object.entries(template.request.headers)) {\n headers[key] = resolvePlaceholders(value, args, credValues);\n }\n }\n if (!headers[\"Content-Type\"] && method !== \"GET\") {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n // Resolve body\n let body: string | undefined;\n if (template.request.body) {\n body = resolvePlaceholders(template.request.body, args, credValues);\n }\n\n logger.debug(\n `Skill HTTP: ${method} ${url.slice(0, 100)}`,\n \"skills\",\n );\n\n // Make the request\n const response = await fetch(url, {\n method,\n headers,\n body: method !== \"GET\" ? body : undefined,\n signal: AbortSignal.timeout(60_000),\n });\n\n const content = await response.text();\n\n if (!response.ok) {\n return {\n toolCallId: \"\",\n content: `HTTP ${response.status} ${response.statusText}: ${content.slice(0, 2000)}`,\n isError: true,\n };\n }\n\n // Save response to _temp/ and return metadata so the agent can\n // use data_file to query, artifact to display, or write_file to transform\n const tempDir = path.join(workspacePath, \"_temp\");\n await fs.mkdir(tempDir, { recursive: true });\n\n const isJson = looksLikeJson(content);\n const ext = isJson ? \"json\" : \"txt\";\n const filename = `${template.name}_${Date.now()}.${ext}`;\n const filePath = path.join(tempDir, filename);\n await fs.writeFile(filePath, content, \"utf-8\");\n\n const summary = buildResponseSummary(content, isJson);\n\n return {\n toolCallId: \"\",\n content: [\n `Data saved to: _temp/${filename}`,\n `Size: ${formatBytes(content.length)}`,\n summary,\n \"\",\n \"Use data_file to inspect or query this data, or artifact to display it.\",\n ].join(\"\\n\"),\n };\n } catch (err) {\n return {\n toolCallId: \"\",\n content: `HTTP tool error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n}\n\nfunction looksLikeJson(content: string): boolean {\n const trimmed = content.trimStart();\n return trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\");\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction buildResponseSummary(content: string, isJson: boolean): string {\n if (!isJson) {\n const lines = content.split(\"\\n\");\n return `Lines: ${lines.length}\\nPreview:\\n${lines.slice(0, 5).join(\"\\n\")}`;\n }\n\n try {\n const parsed = JSON.parse(content);\n\n // Array of objects — most common API response\n if (Array.isArray(parsed)) {\n const count = parsed.length;\n const sample = parsed[0];\n const columns = sample && typeof sample === \"object\"\n ? Object.keys(sample)\n : [];\n return [\n `Format: JSON array (${count} items)`,\n columns.length > 0 ? `Columns: ${columns.join(\", \")}` : \"\",\n count > 0 ? `Sample: ${JSON.stringify(parsed[0]).slice(0, 300)}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n }\n\n // Object with a data/results array inside\n if (typeof parsed === \"object\" && parsed !== null) {\n const keys = Object.keys(parsed);\n // Find the first array property (likely the data payload)\n const arrayKey = keys.find((k) => Array.isArray(parsed[k]));\n if (arrayKey) {\n const arr = parsed[arrayKey] as unknown[];\n const sample = arr[0];\n const columns = sample && typeof sample === \"object\" && sample !== null\n ? Object.keys(sample)\n : [];\n return [\n `Format: JSON object with ${keys.length} keys: ${keys.join(\", \")}`,\n `Data in \"${arrayKey}\": ${arr.length} items`,\n columns.length > 0 ? `Columns: ${columns.join(\", \")}` : \"\",\n arr.length > 0 ? `Sample: ${JSON.stringify(arr[0]).slice(0, 300)}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n }\n\n return `Format: JSON object with ${keys.length} keys: ${keys.join(\", \")}`;\n }\n\n return `Format: JSON (${typeof parsed})`;\n } catch {\n return \"Format: text (invalid JSON)\";\n }\n}\n\n/**\n * Resolve all credential values for a skill into a flat map.\n */\nasync function resolveCredentials(\n skill: SkillEntry,\n credentialStore: CredentialStore | null,\n): Promise<Map<string, string>> {\n const values = new Map<string, string>();\n\n if (!skill.credentialSchema || !credentialStore) return values;\n\n for (const cred of skill.credentialSchema.credentials) {\n if (cred.type === \"oauth2\") {\n const keys = getOAuth2StorageKeys(skill.manifest.name, cred.id);\n const accessToken = await credentialStore.get(keys.accessToken);\n if (accessToken) {\n values.set(\"oauth2:accessToken\", accessToken);\n }\n const refreshToken = await credentialStore.get(keys.refreshToken);\n if (refreshToken) {\n values.set(\"oauth2:refreshToken\", refreshToken);\n }\n } else if (cred.multiple && cred.fields) {\n // Multi-instance: resolve from first available instance\n const registryKey = getInstanceRegistryKey(skill.manifest.name, cred.id, cred.storeAs);\n const raw = await credentialStore.get(registryKey);\n const instances = raw ? JSON.parse(raw) as Array<{ id: string }> : [];\n if (instances.length > 0) {\n for (const field of cred.fields) {\n const key = getInstanceStorageKey(\n skill.manifest.name,\n cred.id,\n instances[0].id,\n field.key,\n cred.storeAs,\n );\n const value = await credentialStore.get(key);\n if (value) {\n values.set(`credential:${field.key}`, value);\n }\n }\n }\n } else if (cred.fields) {\n for (const field of cred.fields) {\n const key = getCredentialStorageKey(\n skill.manifest.name,\n cred.id,\n field.key,\n cred.storeAs,\n );\n const value = await credentialStore.get(key);\n if (value) {\n values.set(`credential:${field.key}`, value);\n }\n }\n }\n }\n\n return values;\n}\n\n/**\n * Replace {{placeholder}} patterns in a string.\n *\n * Priority:\n * 1. {{credential:fieldKey}} → from credential map\n * 2. {{oauth2:tokenField}} → from credential map\n * 3. {{argName}} → from tool call arguments\n */\nfunction resolvePlaceholders(\n template: string,\n args: Record<string, unknown>,\n credValues: Map<string, string>,\n): string {\n return template.replace(/\\{\\{([^}]+)\\}\\}/g, (match, key: string) => {\n // Credential placeholder\n if (key.startsWith(\"credential:\") || key.startsWith(\"oauth2:\")) {\n const value = credValues.get(key);\n if (value) return value;\n return match; // Leave unresolved\n }\n\n // Argument placeholder\n const argValue = args[key];\n if (argValue !== undefined) {\n return typeof argValue === \"string\"\n ? argValue\n : JSON.stringify(argValue);\n }\n\n return match;\n });\n}\n","import type { OAuth2Config } from \"./types.js\";\nimport type { EncryptedCredentialStore } from \"../credentials/store.js\";\nimport { getOAuth2StorageKeys, getCredentialStorageKey } from \"./credential-schema.js\";\n\n/**\n * Build the OAuth2 authorization URL for a skill.\n */\nexport function buildSkillOAuth2AuthUrl(\n skillName: string,\n oauth: OAuth2Config,\n clientId: string,\n redirectUri: string,\n state: string,\n): string {\n const params = new URLSearchParams({\n client_id: clientId,\n redirect_uri: redirectUri,\n response_type: \"code\",\n state,\n access_type: oauth.refreshable ? \"offline\" : \"online\",\n prompt: \"consent\",\n });\n\n if (oauth.scopes?.length) {\n params.set(\"scope\", oauth.scopes.join(\" \"));\n }\n\n return `${oauth.authorizationUrl}?${params.toString()}`;\n}\n\n/**\n * Exchange an OAuth2 authorization code for tokens and store them.\n */\nexport async function exchangeSkillOAuth2Code(\n skillName: string,\n credentialId: string,\n oauth: OAuth2Config,\n clientId: string,\n clientSecret: string,\n code: string,\n redirectUri: string,\n credentialStore: EncryptedCredentialStore,\n): Promise<void> {\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n redirect_uri: redirectUri,\n client_id: clientId,\n client_secret: clientSecret,\n });\n\n const res = await fetch(oauth.tokenUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: body.toString(),\n });\n\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Token exchange failed (${res.status}): ${text}`);\n }\n\n const data = (await res.json()) as {\n access_token: string;\n refresh_token?: string;\n expires_in?: number;\n token_type?: string;\n };\n\n const keys = getOAuth2StorageKeys(skillName, credentialId);\n await credentialStore.set(keys.accessToken, data.access_token);\n\n if (data.refresh_token) {\n await credentialStore.set(keys.refreshToken, data.refresh_token);\n }\n\n if (data.expires_in) {\n const expiresAt = Date.now() + data.expires_in * 1000;\n await credentialStore.set(keys.expiresAt, String(expiresAt));\n }\n}\n\n/**\n * Revoke OAuth2 tokens for a skill by removing them from the credential store.\n */\nexport async function revokeSkillOAuth2(\n skillName: string,\n credentialId: string,\n credentialStore: EncryptedCredentialStore,\n): Promise<void> {\n const keys = getOAuth2StorageKeys(skillName, credentialId);\n await credentialStore.delete(keys.accessToken);\n await credentialStore.delete(keys.refreshToken);\n await credentialStore.delete(keys.expiresAt);\n}\n","import crypto from \"node:crypto\";\nimport Database from \"better-sqlite3\";\nimport { computeNextRunAtMs } from \"./schedule.js\";\nimport { logger } from \"../logging/logger.js\";\nimport type {\n CronJob,\n CronJobCreate,\n CronJobState,\n CronSchedule,\n CronEvent,\n} from \"./types.js\";\n\nconst MAX_TIMER_DELAY_MS = 60_000;\nconst MIN_REFIRE_GAP_MS = 2_000;\nconst ERROR_BACKOFF_MS = [30_000, 60_000, 300_000, 900_000, 3_600_000];\n\ntype EventHandler = (event: CronEvent) => void;\ntype JobExecutor = (job: CronJob) => Promise<string>;\n\nexport class CronService {\n private db: Database.Database;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private running = false;\n private executor: JobExecutor | null = null;\n private eventHandlers: EventHandler[] = [];\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS cron_jobs (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n enabled INTEGER NOT NULL DEFAULT 1,\n schedule TEXT NOT NULL,\n prompt TEXT NOT NULL,\n delivery TEXT NOT NULL DEFAULT '{}',\n workspace_id TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS cron_job_states (\n job_id TEXT PRIMARY KEY REFERENCES cron_jobs(id) ON DELETE CASCADE,\n next_run_at_ms INTEGER,\n last_run_at_ms INTEGER,\n last_status TEXT,\n last_error TEXT,\n consecutive_errors INTEGER NOT NULL DEFAULT 0\n );\n `);\n }\n\n setExecutor(executor: JobExecutor): void {\n this.executor = executor;\n }\n\n onEvent(handler: EventHandler): void {\n this.eventHandlers.push(handler);\n }\n\n private emit(event: CronEvent): void {\n for (const handler of this.eventHandlers) {\n try {\n handler(event);\n } catch {\n // Ignore handler errors\n }\n }\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n logger.info(\"Cron service started\", \"cron\");\n\n // Compute initial next-run for all enabled jobs missing a next_run_at_ms\n const jobs = this.list();\n for (const job of jobs) {\n if (!job.enabled) continue;\n const state = this.getState(job.id);\n if (!state || state.nextRunAtMs === null) {\n const nextMs = computeNextRunAtMs(job.schedule);\n this.upsertState(job.id, { nextRunAtMs: nextMs });\n }\n }\n\n this.scheduleNext();\n }\n\n stop(): void {\n this.running = false;\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n logger.info(\"Cron service stopped\", \"cron\");\n }\n\n private scheduleNext(): void {\n if (!this.running) return;\n\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n\n // Find the soonest job\n const row = this.db\n .prepare(\n `SELECT s.job_id, s.next_run_at_ms\n FROM cron_job_states s\n JOIN cron_jobs j ON j.id = s.job_id\n WHERE j.enabled = 1 AND s.next_run_at_ms IS NOT NULL\n ORDER BY s.next_run_at_ms ASC\n LIMIT 1`,\n )\n .get() as { job_id: string; next_run_at_ms: number } | undefined;\n\n if (!row) return;\n\n const delayMs = Math.max(0, row.next_run_at_ms - Date.now());\n const clampedDelay = Math.min(delayMs, MAX_TIMER_DELAY_MS);\n\n this.timer = setTimeout(() => {\n this.tick();\n }, clampedDelay);\n }\n\n private async tick(): Promise<void> {\n if (!this.running) return;\n\n const now = Date.now();\n\n // Get all jobs due to run\n const dueRows = this.db\n .prepare(\n `SELECT s.job_id\n FROM cron_job_states s\n JOIN cron_jobs j ON j.id = s.job_id\n WHERE j.enabled = 1\n AND s.next_run_at_ms IS NOT NULL\n AND s.next_run_at_ms <= ?`,\n )\n .all(now) as Array<{ job_id: string }>;\n\n for (const { job_id } of dueRows) {\n await this.executeJob(job_id);\n }\n\n this.scheduleNext();\n }\n\n private async executeJob(jobId: string): Promise<void> {\n const job = this.getJob(jobId);\n if (!job || !this.executor) return;\n\n const state = this.getState(jobId);\n if (state?.lastRunAtMs && Date.now() - state.lastRunAtMs < MIN_REFIRE_GAP_MS) {\n return;\n }\n\n this.emit({\n type: \"started\",\n jobId: job.id,\n jobName: job.name,\n });\n\n try {\n const result = await this.executor(job);\n\n this.upsertState(jobId, {\n lastRunAtMs: Date.now(),\n lastStatus: \"success\",\n lastError: null,\n consecutiveErrors: 0,\n nextRunAtMs: computeNextRunAtMs(job.schedule),\n });\n\n this.emit({\n type: \"finished\",\n jobId: job.id,\n jobName: job.name,\n result,\n });\n\n logger.info(`Cron job \"${job.name}\" completed`, \"cron\");\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n const currentErrors = (state?.consecutiveErrors ?? 0) + 1;\n const backoffIdx = Math.min(currentErrors - 1, ERROR_BACKOFF_MS.length - 1);\n const backoffMs = ERROR_BACKOFF_MS[backoffIdx];\n\n this.upsertState(jobId, {\n lastRunAtMs: Date.now(),\n lastStatus: \"error\",\n lastError: errorMsg,\n consecutiveErrors: currentErrors,\n nextRunAtMs: Date.now() + backoffMs,\n });\n\n this.emit({\n type: \"error\",\n jobId: job.id,\n jobName: job.name,\n error: errorMsg,\n });\n\n logger.error(\n `Cron job \"${job.name}\" failed (${currentErrors} errors): ${errorMsg}`,\n \"cron\",\n );\n }\n }\n\n // CRUD\n\n add(input: CronJobCreate): CronJob {\n const id = crypto.randomUUID();\n const now = new Date().toISOString();\n\n const job: CronJob = {\n id,\n name: input.name,\n enabled: input.enabled ?? true,\n schedule: input.schedule,\n prompt: input.prompt,\n delivery: input.delivery ?? {},\n workspaceId: input.workspaceId,\n createdAt: now,\n updatedAt: now,\n };\n\n this.db\n .prepare(\n `INSERT INTO cron_jobs (id, name, enabled, schedule, prompt, delivery, workspace_id, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n job.id,\n job.name,\n job.enabled ? 1 : 0,\n JSON.stringify(job.schedule),\n job.prompt,\n JSON.stringify(job.delivery),\n job.workspaceId ?? null,\n job.createdAt,\n job.updatedAt,\n );\n\n // Set initial state\n const nextMs = job.enabled ? computeNextRunAtMs(job.schedule) : null;\n this.upsertState(id, { nextRunAtMs: nextMs });\n\n this.emit({ type: \"added\", jobId: id, jobName: job.name });\n\n if (this.running) this.scheduleNext();\n\n return job;\n }\n\n update(\n id: string,\n updates: Partial<Pick<CronJob, \"name\" | \"enabled\" | \"schedule\" | \"prompt\" | \"delivery\">>,\n ): CronJob | null {\n const existing = this.getJob(id);\n if (!existing) return null;\n\n const sets: string[] = [\"updated_at = ?\"];\n const values: unknown[] = [new Date().toISOString()];\n\n if (updates.name !== undefined) {\n sets.push(\"name = ?\");\n values.push(updates.name);\n }\n if (updates.enabled !== undefined) {\n sets.push(\"enabled = ?\");\n values.push(updates.enabled ? 1 : 0);\n }\n if (updates.schedule !== undefined) {\n sets.push(\"schedule = ?\");\n values.push(JSON.stringify(updates.schedule));\n }\n if (updates.prompt !== undefined) {\n sets.push(\"prompt = ?\");\n values.push(updates.prompt);\n }\n if (updates.delivery !== undefined) {\n sets.push(\"delivery = ?\");\n values.push(JSON.stringify(updates.delivery));\n }\n\n values.push(id);\n this.db\n .prepare(`UPDATE cron_jobs SET ${sets.join(\", \")} WHERE id = ?`)\n .run(...values);\n\n // Recompute next run if schedule or enabled changed\n if (updates.schedule !== undefined || updates.enabled !== undefined) {\n const updated = this.getJob(id)!;\n const nextMs = updated.enabled ? computeNextRunAtMs(updated.schedule) : null;\n this.upsertState(id, { nextRunAtMs: nextMs, consecutiveErrors: 0 });\n }\n\n if (this.running) this.scheduleNext();\n\n return this.getJob(id);\n }\n\n remove(id: string): boolean {\n const job = this.getJob(id);\n if (!job) return false;\n\n this.db.prepare(\"DELETE FROM cron_jobs WHERE id = ?\").run(id);\n this.emit({ type: \"removed\", jobId: id, jobName: job.name });\n\n if (this.running) this.scheduleNext();\n return true;\n }\n\n getJob(id: string): CronJob | null {\n const row = this.db\n .prepare(\"SELECT * FROM cron_jobs WHERE id = ?\")\n .get(id) as CronJobRow | undefined;\n\n return row ? rowToJob(row) : null;\n }\n\n list(workspaceId?: string): CronJob[] {\n let rows: CronJobRow[];\n if (workspaceId) {\n rows = this.db\n .prepare(\n \"SELECT * FROM cron_jobs WHERE workspace_id = ? ORDER BY created_at DESC\",\n )\n .all(workspaceId) as CronJobRow[];\n } else {\n rows = this.db\n .prepare(\"SELECT * FROM cron_jobs ORDER BY created_at DESC\")\n .all() as CronJobRow[];\n }\n return rows.map(rowToJob);\n }\n\n getState(jobId: string): CronJobState | null {\n const row = this.db\n .prepare(\"SELECT * FROM cron_job_states WHERE job_id = ?\")\n .get(jobId) as {\n job_id: string;\n next_run_at_ms: number | null;\n last_run_at_ms: number | null;\n last_status: string | null;\n last_error: string | null;\n consecutive_errors: number;\n } | undefined;\n\n if (!row) return null;\n\n return {\n jobId: row.job_id,\n nextRunAtMs: row.next_run_at_ms,\n lastRunAtMs: row.last_run_at_ms,\n lastStatus: row.last_status as \"success\" | \"error\" | null,\n lastError: row.last_error,\n consecutiveErrors: row.consecutive_errors,\n };\n }\n\n async runNow(id: string): Promise<void> {\n await this.executeJob(id);\n if (this.running) this.scheduleNext();\n }\n\n private upsertState(\n jobId: string,\n partial: Partial<Omit<CronJobState, \"jobId\">>,\n ): void {\n const existing = this.getState(jobId);\n\n if (existing) {\n const sets: string[] = [];\n const values: unknown[] = [];\n\n if (partial.nextRunAtMs !== undefined) {\n sets.push(\"next_run_at_ms = ?\");\n values.push(partial.nextRunAtMs);\n }\n if (partial.lastRunAtMs !== undefined) {\n sets.push(\"last_run_at_ms = ?\");\n values.push(partial.lastRunAtMs);\n }\n if (partial.lastStatus !== undefined) {\n sets.push(\"last_status = ?\");\n values.push(partial.lastStatus);\n }\n if (partial.lastError !== undefined) {\n sets.push(\"last_error = ?\");\n values.push(partial.lastError);\n }\n if (partial.consecutiveErrors !== undefined) {\n sets.push(\"consecutive_errors = ?\");\n values.push(partial.consecutiveErrors);\n }\n\n if (sets.length > 0) {\n values.push(jobId);\n this.db\n .prepare(\n `UPDATE cron_job_states SET ${sets.join(\", \")} WHERE job_id = ?`,\n )\n .run(...values);\n }\n } else {\n this.db\n .prepare(\n `INSERT INTO cron_job_states (job_id, next_run_at_ms, last_run_at_ms, last_status, last_error, consecutive_errors)\n VALUES (?, ?, ?, ?, ?, ?)`,\n )\n .run(\n jobId,\n partial.nextRunAtMs ?? null,\n partial.lastRunAtMs ?? null,\n partial.lastStatus ?? null,\n partial.lastError ?? null,\n partial.consecutiveErrors ?? 0,\n );\n }\n }\n\n close(): void {\n this.stop();\n this.db.close();\n }\n}\n\n// Internal helpers\n\ninterface CronJobRow {\n id: string;\n name: string;\n enabled: number;\n schedule: string;\n prompt: string;\n delivery: string;\n workspace_id: string | null;\n created_at: string;\n updated_at: string;\n}\n\nfunction rowToJob(row: CronJobRow): CronJob {\n return {\n id: row.id,\n name: row.name,\n enabled: row.enabled === 1,\n schedule: JSON.parse(row.schedule) as CronSchedule,\n prompt: row.prompt,\n delivery: JSON.parse(row.delivery),\n workspaceId: row.workspace_id ?? undefined,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n","import crypto from \"node:crypto\";\n\nexport interface Artifact {\n id: string;\n type: \"html\" | \"csv\" | \"image\" | \"json\" | \"text\" | \"svg\";\n title: string;\n content: string;\n mimeType: string;\n createdAt: number;\n}\n\nconst TTL_MS = 24 * 60 * 60 * 1000; // 24 hours\n\nexport class ArtifactStore {\n private store = new Map<string, Artifact>();\n\n create(\n type: Artifact[\"type\"],\n title: string,\n content: string,\n ): Artifact {\n this.pruneExpired();\n\n const id = crypto.randomUUID();\n const mimeType = getMimeType(type);\n const artifact: Artifact = {\n id,\n type,\n title,\n content,\n mimeType,\n createdAt: Date.now(),\n };\n this.store.set(id, artifact);\n return artifact;\n }\n\n get(id: string): Artifact | undefined {\n const artifact = this.store.get(id);\n if (artifact && Date.now() - artifact.createdAt > TTL_MS) {\n this.store.delete(id);\n return undefined;\n }\n return artifact;\n }\n\n list(): Artifact[] {\n this.pruneExpired();\n return Array.from(this.store.values()).sort(\n (a, b) => b.createdAt - a.createdAt,\n );\n }\n\n delete(id: string): boolean {\n return this.store.delete(id);\n }\n\n private pruneExpired(): void {\n const now = Date.now();\n for (const [id, artifact] of this.store) {\n if (now - artifact.createdAt > TTL_MS) {\n this.store.delete(id);\n }\n }\n }\n}\n\nfunction getMimeType(type: Artifact[\"type\"]): string {\n switch (type) {\n case \"html\":\n return \"text/html\";\n case \"csv\":\n return \"text/csv\";\n case \"image\":\n return \"image/png\";\n case \"json\":\n return \"application/json\";\n case \"svg\":\n return \"image/svg+xml\";\n case \"text\":\n default:\n return \"text/plain\";\n }\n}\n","import Database from \"better-sqlite3\";\nimport type { ModelStore } from \"../models/store.js\";\nimport { MODEL_DEFINITIONS } from \"../models/definitions.js\";\n\nexport interface UsageRecord {\n id: number;\n provider: string;\n model: string;\n inputTokens: number;\n outputTokens: number;\n costUsd: number;\n createdAt: string;\n}\n\nexport interface UsageSummary {\n totalInputTokens: number;\n totalOutputTokens: number;\n totalTokens: number;\n totalCostUsd: number;\n recordCount: number;\n}\n\nexport function estimateCost(\n inputTokens: number,\n outputTokens: number,\n pricing: { input: number; output: number },\n): number {\n const inputCost = (inputTokens / 1_000_000) * pricing.input;\n const outputCost = (outputTokens / 1_000_000) * pricing.output;\n return Math.round((inputCost + outputCost) * 1_000_000) / 1_000_000;\n}\n\nexport class UsageStore {\n private db: Database.Database;\n private modelStore: ModelStore;\n\n constructor(dbPath: string, modelStore: ModelStore) {\n this.db = new Database(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.modelStore = modelStore;\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS usage_records (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n provider TEXT NOT NULL,\n model TEXT NOT NULL,\n input_tokens INTEGER NOT NULL DEFAULT 0,\n output_tokens INTEGER NOT NULL DEFAULT 0,\n cost_usd REAL NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `);\n }\n\n record(\n provider: string,\n model: string,\n inputTokens: number,\n outputTokens: number,\n ): void {\n let pricing = this.modelStore.getPricing(provider, model);\n if (!pricing) {\n // Fall back to hardcoded model definitions when model isn't in enabled_models\n const def = MODEL_DEFINITIONS[provider]?.find((m) => m.id === model);\n if (def?.inputPricePer1m != null && def?.outputPricePer1m != null) {\n pricing = { input: def.inputPricePer1m, output: def.outputPricePer1m };\n }\n }\n const costUsd = pricing\n ? estimateCost(inputTokens, outputTokens, pricing)\n : 0;\n this.db\n .prepare(\n `INSERT INTO usage_records (provider, model, input_tokens, output_tokens, cost_usd)\n VALUES (?, ?, ?, ?, ?)`,\n )\n .run(provider, model, inputTokens, outputTokens, costUsd);\n }\n\n getSummary(period: \"daily\" | \"weekly\" | \"monthly\"): UsageSummary {\n const since = this.periodStart(period);\n const row = this.db\n .prepare(\n `SELECT\n COALESCE(SUM(input_tokens), 0) as totalInputTokens,\n COALESCE(SUM(output_tokens), 0) as totalOutputTokens,\n COALESCE(SUM(input_tokens + output_tokens), 0) as totalTokens,\n COALESCE(SUM(cost_usd), 0) as totalCostUsd,\n COUNT(*) as recordCount\n FROM usage_records\n WHERE created_at >= ?`,\n )\n .get(since) as UsageSummary;\n return row;\n }\n\n getHistory(days: number = 30): Array<{ date: string; tokens: number; costUsd: number }> {\n const since = new Date();\n since.setDate(since.getDate() - days);\n const rows = this.db\n .prepare(\n `SELECT\n date(created_at) as date,\n SUM(input_tokens + output_tokens) as tokens,\n SUM(cost_usd) as costUsd\n FROM usage_records\n WHERE created_at >= ?\n GROUP BY date(created_at)\n ORDER BY date(created_at)`,\n )\n .all(since.toISOString()) as Array<{ date: string; tokens: number; costUsd: number }>;\n return rows;\n }\n\n private periodStart(period: \"daily\" | \"weekly\" | \"monthly\"): string {\n const now = new Date();\n switch (period) {\n case \"daily\":\n now.setHours(0, 0, 0, 0);\n break;\n case \"weekly\": {\n const day = now.getDay();\n now.setDate(now.getDate() - day);\n now.setHours(0, 0, 0, 0);\n break;\n }\n case \"monthly\":\n now.setDate(1);\n now.setHours(0, 0, 0, 0);\n break;\n }\n return now.toISOString();\n }\n}\n","import Database from \"better-sqlite3\";\n\nexport interface EnabledModel {\n id: string;\n provider: string;\n modelId: string;\n label: string;\n inputPricePer1m: number;\n outputPricePer1m: number;\n enabledAt: string;\n}\n\nexport class ModelStore {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS enabled_models (\n id TEXT PRIMARY KEY,\n provider TEXT NOT NULL,\n model_id TEXT NOT NULL,\n label TEXT NOT NULL,\n input_price_per_1m REAL NOT NULL DEFAULT 0,\n output_price_per_1m REAL NOT NULL DEFAULT 0,\n enabled_at TEXT NOT NULL DEFAULT (datetime('now')),\n UNIQUE(provider, model_id)\n )\n `);\n }\n\n list(provider?: string): EnabledModel[] {\n const query = provider\n ? \"SELECT * FROM enabled_models WHERE provider = ? ORDER BY label\"\n : \"SELECT * FROM enabled_models ORDER BY provider, label\";\n const rows = (provider\n ? this.db.prepare(query).all(provider)\n : this.db.prepare(query).all()) as Array<{\n id: string;\n provider: string;\n model_id: string;\n label: string;\n input_price_per_1m: number;\n output_price_per_1m: number;\n enabled_at: string;\n }>;\n return rows.map((r) => ({\n id: r.id,\n provider: r.provider,\n modelId: r.model_id,\n label: r.label,\n inputPricePer1m: r.input_price_per_1m,\n outputPricePer1m: r.output_price_per_1m,\n enabledAt: r.enabled_at,\n }));\n }\n\n enable(\n provider: string,\n modelId: string,\n label: string,\n inputPricePer1m: number,\n outputPricePer1m: number,\n ): EnabledModel {\n const id = crypto.randomUUID();\n const now = new Date().toISOString();\n this.db\n .prepare(\n `INSERT OR REPLACE INTO enabled_models (id, provider, model_id, label, input_price_per_1m, output_price_per_1m, enabled_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(id, provider, modelId, label, inputPricePer1m, outputPricePer1m, now);\n return { id, provider, modelId, label, inputPricePer1m, outputPricePer1m, enabledAt: now };\n }\n\n disable(provider: string, modelId: string): void {\n this.db\n .prepare(\"DELETE FROM enabled_models WHERE provider = ? AND model_id = ?\")\n .run(provider, modelId);\n }\n\n updatePricing(\n provider: string,\n modelId: string,\n inputPricePer1m: number,\n outputPricePer1m: number,\n ): void {\n this.db\n .prepare(\n \"UPDATE enabled_models SET input_price_per_1m = ?, output_price_per_1m = ? WHERE provider = ? AND model_id = ?\",\n )\n .run(inputPricePer1m, outputPricePer1m, provider, modelId);\n }\n\n getPricing(provider: string, modelId: string): { input: number; output: number } | null {\n const row = this.db\n .prepare(\"SELECT input_price_per_1m, output_price_per_1m FROM enabled_models WHERE provider = ? AND model_id = ?\")\n .get(provider, modelId) as { input_price_per_1m: number; output_price_per_1m: number } | undefined;\n if (!row) return null;\n return { input: row.input_price_per_1m, output: row.output_price_per_1m };\n }\n}\n","import Database from \"better-sqlite3\";\n\nexport interface PromptTemplate {\n id: string;\n name: string;\n content: string;\n category: string;\n createdAt: string;\n updatedAt: string;\n}\n\nconst DEFAULT_TEMPLATES: Array<{ name: string; content: string; category: string }> = [\n { name: \"Summarize\", content: \"Summarize the following:\\n\\n\", category: \"General\" },\n { name: \"Explain code\", content: \"Explain this code in detail:\\n\\n\", category: \"Development\" },\n { name: \"Write email\", content: \"Write a professional email about:\\n\\n\", category: \"Writing\" },\n { name: \"Fix bug\", content: \"Help me fix this bug:\\n\\n\", category: \"Development\" },\n { name: \"Brainstorm\", content: \"Brainstorm ideas for:\\n\\n\", category: \"General\" },\n];\n\nexport class TemplateStore {\n private db: Database.Database;\n\n constructor(dbPath: string) {\n this.db = new Database(dbPath);\n this.db.pragma(\"journal_mode = WAL\");\n this.initSchema();\n }\n\n private initSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS prompt_templates (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n content TEXT NOT NULL,\n category TEXT NOT NULL DEFAULT 'General',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now'))\n )\n `);\n\n // Seed defaults if table is empty\n const count = this.db\n .prepare(\"SELECT COUNT(*) as cnt FROM prompt_templates\")\n .get() as { cnt: number };\n\n if (count.cnt === 0) {\n const insert = this.db.prepare(\n \"INSERT INTO prompt_templates (id, name, content, category, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)\",\n );\n const now = new Date().toISOString();\n for (const t of DEFAULT_TEMPLATES) {\n insert.run(crypto.randomUUID(), t.name, t.content, t.category, now, now);\n }\n }\n }\n\n list(): PromptTemplate[] {\n const rows = this.db\n .prepare(\n \"SELECT id, name, content, category, created_at, updated_at FROM prompt_templates ORDER BY category, name\",\n )\n .all() as Array<{\n id: string;\n name: string;\n content: string;\n category: string;\n created_at: string;\n updated_at: string;\n }>;\n\n return rows.map((r) => ({\n id: r.id,\n name: r.name,\n content: r.content,\n category: r.category,\n createdAt: r.created_at,\n updatedAt: r.updated_at,\n }));\n }\n\n get(id: string): PromptTemplate | null {\n const row = this.db\n .prepare(\n \"SELECT id, name, content, category, created_at, updated_at FROM prompt_templates WHERE id = ?\",\n )\n .get(id) as {\n id: string;\n name: string;\n content: string;\n category: string;\n created_at: string;\n updated_at: string;\n } | undefined;\n\n if (!row) return null;\n\n return {\n id: row.id,\n name: row.name,\n content: row.content,\n category: row.category,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n }\n\n create(name: string, content: string, category?: string): PromptTemplate {\n const id = crypto.randomUUID();\n const now = new Date().toISOString();\n this.db\n .prepare(\n \"INSERT INTO prompt_templates (id, name, content, category, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)\",\n )\n .run(id, name, content, category ?? \"General\", now, now);\n\n return { id, name, content, category: category ?? \"General\", createdAt: now, updatedAt: now };\n }\n\n update(id: string, data: Partial<Pick<PromptTemplate, \"name\" | \"content\" | \"category\">>): PromptTemplate | null {\n const existing = this.get(id);\n if (!existing) return null;\n\n const now = new Date().toISOString();\n const name = data.name ?? existing.name;\n const content = data.content ?? existing.content;\n const category = data.category ?? existing.category;\n\n this.db\n .prepare(\n \"UPDATE prompt_templates SET name = ?, content = ?, category = ?, updated_at = ? WHERE id = ?\",\n )\n .run(name, content, category, now, id);\n\n return { id, name, content, category, createdAt: existing.createdAt, updatedAt: now };\n }\n\n delete(id: string): void {\n this.db.prepare(\"DELETE FROM prompt_templates WHERE id = ?\").run(id);\n }\n}\n"],"mappings":"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","names":["crypto","crypto","fs","path","fs","path","fs","path","fs","path","fs","path","path","fs","fs","path","path","fs","fs","path","require","exec","exec","fs","MAX_CONTENT","crypto","crypto","fs","fs","path","fs","path","fs","path","fs","path","instance","exec","path","fs","execFile","fs","path","fs","path","execFile","fs","crypto","fs","path","fs","path","fs","path","Database","CORTASK_DIR","Database","Database","fs","fs","Database","fs","path","path","fs","crypto","Database","Database","crypto","crypto","Database","Database","Database","Database"]}