agentix-cli 0.22.0 → 0.25.0
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/LICENSE +21 -0
- package/README.md +102 -103
- package/agentx.example.json +9 -3
- package/dist/App-6Y7B3YQH.js +8 -0
- package/dist/App-6Y7B3YQH.js.map +1 -0
- package/dist/ChatApp-KIEUJ2DS.js +7 -0
- package/dist/ChatApp-KIEUJ2DS.js.map +1 -0
- package/dist/{agent-Y4U4R3ZZ.js → agent-QGZIAZMY.js} +2 -2
- package/dist/architect-SEPWMWS4.js +2 -0
- package/dist/{board-dashboard-2CPBWFOB.js → board-dashboard-CQ5F4GPD.js} +3756 -1010
- package/dist/board-dashboard-CQ5F4GPD.js.map +1 -0
- package/dist/builtin-FRKAQMFS.js +2 -0
- package/dist/chunk-2WVX3LEC.js +2 -0
- package/dist/chunk-2WVX3LEC.js.map +1 -0
- package/dist/chunk-3WQFCIB6.js +24 -0
- package/dist/chunk-3WQFCIB6.js.map +1 -0
- package/dist/chunk-53GCFZPR.js +116 -0
- package/dist/chunk-53GCFZPR.js.map +1 -0
- package/dist/{chunk-IKBHHTIT.js → chunk-5U35WAZF.js} +2 -2
- package/dist/chunk-67Q4DCPS.js +54 -0
- package/dist/chunk-67Q4DCPS.js.map +1 -0
- package/dist/chunk-76Z4VHDX.js +8 -0
- package/dist/chunk-76Z4VHDX.js.map +1 -0
- package/dist/{chunk-7P5QRX5W.js → chunk-BFXONUUN.js} +2 -2
- package/dist/{chunk-P3TJHGO5.js → chunk-FDMWOPEL.js} +2 -2
- package/dist/chunk-FDWOECJY.js +54 -0
- package/dist/chunk-FDWOECJY.js.map +1 -0
- package/dist/chunk-G57RZCXM.js +5 -0
- package/dist/chunk-G57RZCXM.js.map +1 -0
- package/dist/{chunk-NOF4HSGK.js → chunk-H5D7ATXS.js} +2 -2
- package/dist/chunk-HA3XI7Z2.js +155 -0
- package/dist/chunk-HA3XI7Z2.js.map +1 -0
- package/dist/chunk-HR4JSRZS.js +3 -0
- package/dist/{chunk-A6BKSZQA.js.map → chunk-HR4JSRZS.js.map} +1 -1
- package/dist/chunk-I3SIXTJO.js +44 -0
- package/dist/chunk-I3SIXTJO.js.map +1 -0
- package/dist/chunk-ISEBLHWX.js +118 -0
- package/dist/chunk-ISEBLHWX.js.map +1 -0
- package/dist/{chunk-4ITQP3XL.js → chunk-JP5IEXR7.js} +2 -2
- package/dist/chunk-JXWAGMI2.js +13 -0
- package/dist/chunk-JXWAGMI2.js.map +1 -0
- package/dist/chunk-KUCCW2VG.js +431 -0
- package/dist/chunk-KUCCW2VG.js.map +1 -0
- package/dist/chunk-LDHPMJ7M.js +257 -0
- package/dist/chunk-LDHPMJ7M.js.map +1 -0
- package/dist/{chunk-WHP4I44J.js → chunk-LNXCJWOU.js} +29 -30
- package/dist/chunk-LNXCJWOU.js.map +1 -0
- package/dist/chunk-M4AMWP3H.js +178 -0
- package/dist/chunk-M4AMWP3H.js.map +1 -0
- package/dist/chunk-NGSIRE4X.js +126 -0
- package/dist/chunk-NGSIRE4X.js.map +1 -0
- package/dist/{chunk-CNNLREHD.js → chunk-P4VWIVKN.js} +268 -410
- package/dist/chunk-P4VWIVKN.js.map +1 -0
- package/dist/chunk-Q6YO7LYE.js +47 -0
- package/dist/chunk-Q6YO7LYE.js.map +1 -0
- package/dist/chunk-TMKLHTCG.js +971 -0
- package/dist/chunk-TMKLHTCG.js.map +1 -0
- package/dist/chunk-TRJTTBE2.js +7 -0
- package/dist/chunk-TRJTTBE2.js.map +1 -0
- package/dist/chunk-U2CKL755.js +4 -0
- package/dist/chunk-U2CKL755.js.map +1 -0
- package/dist/chunk-UCQ2N3KO.js +9 -0
- package/dist/chunk-UCQ2N3KO.js.map +1 -0
- package/dist/chunk-W4YR2RO2.js +2 -0
- package/dist/chunk-W4YR2RO2.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/client-GGVVLOOF.js +2 -0
- package/dist/{compaction-BTUJJ3LJ.js → compaction-NWEMOSHA.js} +3 -3
- package/dist/config-7FSZFRTQ.js +2 -0
- package/dist/config-mutator-POCOYYJ4.js +2 -0
- package/dist/{context-planner-I7ID7XF3.js → context-planner-45GEWKGL.js} +2 -2
- package/dist/doctor-DHLBEKA4.js +2 -0
- package/dist/heal-HZ3EQD52.js +2 -0
- package/dist/index.d.ts +1244 -225
- package/dist/index.js +12 -12
- package/dist/index.js.map +1 -1
- package/dist/memory-extract-AENFVVO5.js +2 -0
- package/dist/processes-UIC4XXA6.js +2 -0
- package/dist/program-WVAVJFND.js +2 -0
- package/dist/projects-api-KRME2YKZ.js +2 -0
- package/dist/projects-api-KRME2YKZ.js.map +1 -0
- package/dist/projects-mutate-3NHVG437.js +7 -0
- package/dist/projects-mutate-3NHVG437.js.map +1 -0
- package/dist/providers-L27BJ5A6.js +2 -0
- package/dist/registry-T36ZIAWV.js +2 -0
- package/dist/rotation-memo-B3EXXSEH.js +13 -0
- package/dist/rotation-memo-B3EXXSEH.js.map +1 -0
- package/dist/scheduler-GH7TIKYS.js +2 -0
- package/dist/surface-usage-PRL6Z4U3.js +2 -0
- package/dist/wiki-M6YNRFC4.js +2 -0
- package/dist/workflows/templates/branching.yaml +75 -0
- package/dist/workflows/templates/extract.yaml +59 -0
- package/dist/workflows/templates/linear.yaml +37 -0
- package/dist/workflows/templates/retry.yaml +61 -0
- package/dist/workspace-setup-TBQAHYHJ.js +2 -0
- package/package.json +11 -3
- package/dist/board-dashboard-2CPBWFOB.js.map +0 -1
- package/dist/chunk-2HXSJYAJ.js +0 -15
- package/dist/chunk-2HXSJYAJ.js.map +0 -1
- package/dist/chunk-5F3J55LG.js +0 -2
- package/dist/chunk-5F3J55LG.js.map +0 -1
- package/dist/chunk-A6BKSZQA.js +0 -3
- package/dist/chunk-ABVZHJUO.js +0 -7
- package/dist/chunk-ABVZHJUO.js.map +0 -1
- package/dist/chunk-BHSPAP4U.js +0 -44
- package/dist/chunk-BHSPAP4U.js.map +0 -1
- package/dist/chunk-CDNWCYF7.js +0 -2
- package/dist/chunk-CDNWCYF7.js.map +0 -1
- package/dist/chunk-CNNLREHD.js.map +0 -1
- package/dist/chunk-CO4YCIIA.js +0 -13
- package/dist/chunk-CO4YCIIA.js.map +0 -1
- package/dist/chunk-EW27SCCC.js +0 -2
- package/dist/chunk-EW27SCCC.js.map +0 -1
- package/dist/chunk-GOLZ6NEL.js +0 -111
- package/dist/chunk-GOLZ6NEL.js.map +0 -1
- package/dist/chunk-JGXE2YNV.js +0 -46
- package/dist/chunk-JGXE2YNV.js.map +0 -1
- package/dist/chunk-KX626FN4.js +0 -6
- package/dist/chunk-KX626FN4.js.map +0 -1
- package/dist/chunk-MTRWXRFF.js +0 -380
- package/dist/chunk-MTRWXRFF.js.map +0 -1
- package/dist/chunk-N67JZAXU.js +0 -2
- package/dist/chunk-N67JZAXU.js.map +0 -1
- package/dist/chunk-OPKQNLGX.js +0 -450
- package/dist/chunk-OPKQNLGX.js.map +0 -1
- package/dist/chunk-OZOQKPJV.js +0 -102
- package/dist/chunk-OZOQKPJV.js.map +0 -1
- package/dist/chunk-VYLZ7UYM.js +0 -118
- package/dist/chunk-VYLZ7UYM.js.map +0 -1
- package/dist/chunk-WHP4I44J.js.map +0 -1
- package/dist/chunk-WJXU5F4Z.js +0 -53
- package/dist/chunk-WJXU5F4Z.js.map +0 -1
- package/dist/chunk-X5D5AV5N.js +0 -833
- package/dist/chunk-X5D5AV5N.js.map +0 -1
- package/dist/config-BLOKGMER.js +0 -2
- package/dist/config-mutator-RG7QY2EL.js +0 -2
- package/dist/doctor-ZTECTUHX.js +0 -2
- package/dist/editor-chat-RVLCKKB7.js +0 -137
- package/dist/editor-chat-RVLCKKB7.js.map +0 -1
- package/dist/heal-YEQYWX2L.js +0 -2
- package/dist/inbox-BIN2S5XN.js +0 -2
- package/dist/memory-extract-KRCHD3OP.js +0 -2
- package/dist/processes-RJ6RDP32.js +0 -2
- package/dist/program-GZOJIWTB.js +0 -2
- package/dist/providers-WVCMIW67.js +0 -2
- package/dist/registry-QZIUSQ5J.js +0 -2
- package/dist/rotation-memo-GMTZPMNE.js +0 -13
- package/dist/rotation-memo-GMTZPMNE.js.map +0 -1
- package/dist/scheduler-B2BQPV4M.js +0 -2
- package/dist/slack-6P7ZJ32Y.js +0 -3
- package/dist/slack-6P7ZJ32Y.js.map +0 -1
- package/dist/store-BAPDZHXE.js +0 -2
- package/dist/task-store-RHISEU6V.js +0 -2
- package/dist/telegram-PIYDRM46.js +0 -3
- package/dist/telegram-PIYDRM46.js.map +0 -1
- package/dist/types-ZRLHHCGB.js +0 -2
- package/dist/web/workflow-editor.global.js +0 -1452
- package/dist/web/workflow-editor.global.js.map +0 -1
- package/dist/whatsapp-PFRDMUMT.js +0 -3
- package/dist/whatsapp-PFRDMUMT.js.map +0 -1
- package/dist/wiki-53W5NLZV.js +0 -2
- package/dist/workspace-setup-DQCZX2NE.js +0 -2
- /package/dist/{agent-Y4U4R3ZZ.js.map → agent-QGZIAZMY.js.map} +0 -0
- /package/dist/{config-BLOKGMER.js.map → architect-SEPWMWS4.js.map} +0 -0
- /package/dist/{config-mutator-RG7QY2EL.js.map → builtin-FRKAQMFS.js.map} +0 -0
- /package/dist/{chunk-IKBHHTIT.js.map → chunk-5U35WAZF.js.map} +0 -0
- /package/dist/{chunk-7P5QRX5W.js.map → chunk-BFXONUUN.js.map} +0 -0
- /package/dist/{chunk-P3TJHGO5.js.map → chunk-FDMWOPEL.js.map} +0 -0
- /package/dist/{chunk-NOF4HSGK.js.map → chunk-H5D7ATXS.js.map} +0 -0
- /package/dist/{chunk-4ITQP3XL.js.map → chunk-JP5IEXR7.js.map} +0 -0
- /package/dist/{doctor-ZTECTUHX.js.map → client-GGVVLOOF.js.map} +0 -0
- /package/dist/{compaction-BTUJJ3LJ.js.map → compaction-NWEMOSHA.js.map} +0 -0
- /package/dist/{heal-YEQYWX2L.js.map → config-7FSZFRTQ.js.map} +0 -0
- /package/dist/{inbox-BIN2S5XN.js.map → config-mutator-POCOYYJ4.js.map} +0 -0
- /package/dist/{context-planner-I7ID7XF3.js.map → context-planner-45GEWKGL.js.map} +0 -0
- /package/dist/{memory-extract-KRCHD3OP.js.map → doctor-DHLBEKA4.js.map} +0 -0
- /package/dist/{processes-RJ6RDP32.js.map → heal-HZ3EQD52.js.map} +0 -0
- /package/dist/{program-GZOJIWTB.js.map → memory-extract-AENFVVO5.js.map} +0 -0
- /package/dist/{providers-WVCMIW67.js.map → processes-UIC4XXA6.js.map} +0 -0
- /package/dist/{registry-QZIUSQ5J.js.map → program-WVAVJFND.js.map} +0 -0
- /package/dist/{scheduler-B2BQPV4M.js.map → providers-L27BJ5A6.js.map} +0 -0
- /package/dist/{store-BAPDZHXE.js.map → registry-T36ZIAWV.js.map} +0 -0
- /package/dist/{task-store-RHISEU6V.js.map → scheduler-GH7TIKYS.js.map} +0 -0
- /package/dist/{types-ZRLHHCGB.js.map → surface-usage-PRL6Z4U3.js.map} +0 -0
- /package/dist/{wiki-53W5NLZV.js.map → wiki-M6YNRFC4.js.map} +0 -0
- /package/dist/{workspace-setup-DQCZX2NE.js.map → workspace-setup-TBQAHYHJ.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agent/providers/types.ts","../src/agent/context/schema.ts","../src/agent/context/context7.ts","../src/agent/outputs/types.ts","../src/agent/outputs/handlers.ts","../src/hooks/registry.ts","../src/hooks/types.ts","../src/observability/tracker.ts","../src/observability/export.ts","../src/hooks/loader.ts","../src/hooks/index.ts","../src/permissions/manager.ts","../src/permissions/types.ts","../src/memory/hierarchy.ts","../src/memory/context-builder.ts","../src/agent/tools/executor.ts","../src/agent/tools/noqta.ts","../src/agent/orchestrator.ts","../src/agent/mcp-client.ts","../src/utils/async-queue.ts","../src/agent/index.ts"],"sourcesContent":["import { z } from \"zod\"\n\n// --- Provider abstraction ---\n\nexport interface GenerationMessage {\n role: \"user\" | \"assistant\" | \"system\"\n content: string\n}\n\nexport interface GenerationResult {\n content: string\n files: GeneratedFile[]\n followUp?: string // Agent may ask for more info\n tokensUsed?: number\n}\n\nexport interface GeneratedFile {\n path: string\n content: string\n language?: string\n description?: string\n}\n\nexport interface ProviderOptions {\n model?: string\n maxTokens?: number\n temperature?: number\n apiKey?: string\n /** Operator-cancel signal — passed straight to fetch() so the in-\n * flight HTTP request to the provider can be closed when the\n * task is cancelled. Without this, /api/tasks/:id/cancel only\n * marks the task aborted in the registry; the underlying request\n * can hang for hours waiting for the model to finish thinking. */\n abortSignal?: AbortSignal\n}\n\nexport type StreamEvent =\n | { type: \"text_delta\"; text: string }\n | { type: \"tool_use_start\"; name: string; id: string }\n | { type: \"tool_use_delta\"; json: string }\n | { type: \"tool_use_end\"; name: string }\n // Internal reasoning chunk from a thinking-mode model (DeepSeek V4\n // `reasoning_content`, OpenAI o-series, …). Consumers can render\n // these inline as the agent thinks; runtime.ts forwards them with\n // a `💭 ` marker so the live dashboard modal's existing thought-\n // event renderer picks them up automatically.\n | { type: \"thinking_delta\"; text: string }\n | { type: \"done\"; result: GenerationResult }\n | { type: \"error\"; error: string }\n\n// --- Raw (agentic) API types ---\n\nexport interface AnthropicMessage {\n role: \"user\" | \"assistant\"\n content: string | ContentBlock[]\n}\n\nexport type ContentBlock =\n | { type: \"text\"; text: string }\n | { type: \"tool_use\"; id: string; name: string; input: Record<string, unknown> }\n | { type: \"tool_result\"; tool_use_id: string; content: string; is_error?: boolean }\n // Internal-thinking output from \"reasoning\" models (DeepSeek V4\n // `reasoning_content`, OpenAI o-series, etc.). Not surfaced to end\n // users; the agentic loop keeps it on the assistant turn so the\n // round-trip to the next iteration carries it back — required by\n // DeepSeek V4 which otherwise errors \"reasoning_content in the\n // thinking mode must be passed back to the API\". Non-reasoning\n // providers ignore this block type.\n | { type: \"reasoning\"; text: string }\n\nexport interface RawGenerationResult {\n content: ContentBlock[]\n stop_reason: \"end_turn\" | \"tool_use\" | \"max_tokens\" | \"stop_sequence\"\n usage: { input_tokens: number; output_tokens: number }\n}\n\nexport interface AgentProvider {\n name: string\n generate(\n messages: GenerationMessage[],\n options?: ProviderOptions\n ): Promise<GenerationResult>\n stream?(\n messages: GenerationMessage[],\n options?: ProviderOptions\n ): AsyncIterable<StreamEvent>\n /** Low-level method returning raw content blocks for the agentic tool_result loop */\n generateRaw?(\n messages: AnthropicMessage[],\n systemPrompt: string,\n tools: Array<{ name: string; description: string; input_schema: Record<string, unknown> }>,\n options?: ProviderOptions\n ): Promise<RawGenerationResult>\n /**\n * Streaming variant of generateRaw — emits text_delta events as the\n * model generates so callers can pipe per-token to UIs (voice TTS,\n * SSE, etc.) AND still get the full RawGenerationResult at the end\n * with the tool_use blocks intact, so the agentic loop's tool\n * dispatch keeps working unchanged. Optional — runAgenticLoop falls\n * back to generateRaw() when this isn't implemented.\n */\n generateRawStream?(\n messages: AnthropicMessage[],\n systemPrompt: string,\n tools: Array<{ name: string; description: string; input_schema: Record<string, unknown> }>,\n options?: ProviderOptions\n ): AsyncIterable<RawStreamEvent>\n}\n\n/**\n * Event stream from generateRawStream. text_delta arrives per chunk so\n * the caller can stream to a UI; tool_use blocks accumulate silently and\n * are surfaced in the terminal raw_result event so the agentic loop's\n * tool dispatch logic stays unchanged.\n */\nexport type RawStreamEvent =\n | { type: \"text_delta\"; text: string }\n // Reasoning chunk from a thinking-mode model. Emitted alongside\n // text_delta events as the model thinks; the final raw_result also\n // carries a `reasoning` content block so the agentic loop's\n // round-trip continues to satisfy DeepSeek's \"must echo back\" rule.\n | { type: \"thinking_delta\"; text: string }\n | { type: \"raw_result\"; result: RawGenerationResult }\n | { type: \"error\"; error: string }\n\n// --- Agent configuration ---\n\nexport const agentConfigSchema = z.object({\n provider: z.enum([\"claude-code\", \"claude\", \"openai\", \"deepseek\", \"ollama\", \"demo\", \"custom\"]).default(\"claude-code\"),\n model: z.string().optional(),\n apiKey: z.string().optional(),\n skills: z.array(z.string()).default([]),\n output: z\n .object({\n dir: z.string().default(\"./generated\"),\n })\n .default({}),\n context7: z\n .object({\n enabled: z.boolean().default(true),\n apiKey: z.string().optional(),\n })\n .default({}),\n agentic: z\n .object({\n maxIterations: z.number().default(20),\n enabledTools: z.array(z.string()).default([\n \"create_files\", \"ask_user\", \"read_file\",\n \"search_files\", \"list_directory\", \"run_command\", \"edit_file\",\n ]),\n disabledTools: z.array(z.string()).default([]),\n })\n .default({}),\n})\n\nexport type AgentConfig = z.infer<typeof agentConfigSchema>\n\n// --- Output types ---\n\nexport const OUTPUT_TYPES = [\n \"component\",\n \"page\",\n \"api\",\n \"website\",\n \"document\",\n \"script\",\n \"config\",\n \"skill\",\n \"media\",\n \"report\",\n \"test\",\n \"workflow\",\n \"schema\",\n \"email\",\n \"diagram\",\n \"auto\",\n] as const\n\nexport type OutputType = (typeof OUTPUT_TYPES)[number]\n\nexport const outputTypeDescriptions: Record<OutputType, string> = {\n component: \"UI component (any framework)\",\n page: \"Full page or screen\",\n api: \"API endpoint, route handler, or service\",\n website: \"Multi-page website or app\",\n document: \"Markdown, documentation, or specification\",\n script: \"Standalone script or utility\",\n config: \"Configuration file or setup\",\n skill: \"Agent skill (SKILL.md format for skills.sh)\",\n media: \"Media generation prompt (image/audio/video description)\",\n report: \"Analysis report or audit\",\n test: \"Test suite, test fixtures, or test data\",\n workflow: \"CI/CD pipeline, GitHub Actions, or automation\",\n schema: \"Database schema, Zod validators, or GraphQL types\",\n email: \"Email template (React Email, MJML, HTML)\",\n diagram: \"Mermaid, D2, or PlantUML diagram\",\n auto: \"Auto-detect the best output type\",\n}\n","import { existsSync, promises as fs } from \"fs\"\nimport path from \"path\"\nimport fg from \"fast-glob\"\n\n// --- Schema awareness: detect DB schemas, API specs, env vars, configs ---\n\nexport interface ProjectSchemas {\n database?: DatabaseSchema\n api?: ApiSchema\n env?: EnvSchema\n models?: ModelFile[]\n}\n\nexport interface DatabaseSchema {\n type: string // prisma, drizzle, typeorm, etc.\n content: string\n tables?: string[]\n}\n\nexport interface ApiSchema {\n type: string // openapi, graphql, trpc, etc.\n content: string\n endpoints?: string[]\n}\n\nexport interface EnvSchema {\n variables: { key: string; description?: string; required: boolean }[]\n}\n\nexport interface ModelFile {\n path: string\n content: string\n type: string\n}\n\nconst SCHEMA_FILES: Record<string, { type: string; category: \"database\" | \"api\" | \"model\" }> = {\n \"prisma/schema.prisma\": { type: \"prisma\", category: \"database\" },\n \"drizzle/schema.ts\": { type: \"drizzle\", category: \"database\" },\n \"schema.graphql\": { type: \"graphql\", category: \"api\" },\n \"schema.gql\": { type: \"graphql\", category: \"api\" },\n \"openapi.yaml\": { type: \"openapi\", category: \"api\" },\n \"openapi.json\": { type: \"openapi\", category: \"api\" },\n \"swagger.yaml\": { type: \"openapi\", category: \"api\" },\n \"swagger.json\": { type: \"openapi\", category: \"api\" },\n}\n\nexport async function detectSchemas(cwd: string): Promise<ProjectSchemas> {\n const schemas: ProjectSchemas = {}\n\n // Find schema files\n const files = await fg.glob(\"**/*\", {\n cwd,\n deep: 4,\n ignore: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/.next/**\",\n \"**/target/**\",\n \"**/__pycache__/**\",\n \"**/vendor/**\",\n \"**/.git/**\",\n ],\n onlyFiles: true,\n })\n\n // Detect database schemas\n for (const [schemaFile, info] of Object.entries(SCHEMA_FILES)) {\n const match = files.find((f) => f.endsWith(schemaFile) || f === schemaFile)\n if (match && info.category === \"database\") {\n const content = await safeReadFile(path.resolve(cwd, match))\n if (content) {\n schemas.database = {\n type: info.type,\n content: truncate(content, 3000),\n tables: extractTableNames(content, info.type),\n }\n break\n }\n }\n }\n\n // Detect API schemas\n for (const [schemaFile, info] of Object.entries(SCHEMA_FILES)) {\n const match = files.find((f) => f.endsWith(schemaFile) || f === schemaFile)\n if (match && info.category === \"api\") {\n const content = await safeReadFile(path.resolve(cwd, match))\n if (content) {\n schemas.api = {\n type: info.type,\n content: truncate(content, 3000),\n }\n break\n }\n }\n }\n\n // Detect tRPC router\n if (!schemas.api) {\n const trpcRouter = files.find(\n (f) => f.includes(\"trpc\") && (f.endsWith(\"router.ts\") || f.endsWith(\"router.js\"))\n )\n if (trpcRouter) {\n const content = await safeReadFile(path.resolve(cwd, trpcRouter))\n if (content) {\n schemas.api = {\n type: \"trpc\",\n content: truncate(content, 3000),\n }\n }\n }\n }\n\n // Detect env variables\n const envExample = files.find(\n (f) => f === \".env.example\" || f === \".env.local.example\" || f === \".env.template\"\n )\n if (envExample) {\n const content = await safeReadFile(path.resolve(cwd, envExample))\n if (content) {\n schemas.env = parseEnvFile(content)\n }\n }\n\n // Detect model/type files\n const modelFiles = files.filter(\n (f) =>\n (f.includes(\"models\") || f.includes(\"types\") || f.includes(\"schemas\")) &&\n (f.endsWith(\".ts\") || f.endsWith(\".py\") || f.endsWith(\".rs\") || f.endsWith(\".go\"))\n )\n\n if (modelFiles.length) {\n schemas.models = []\n for (const mf of modelFiles.slice(0, 5)) {\n const content = await safeReadFile(path.resolve(cwd, mf))\n if (content) {\n schemas.models.push({\n path: mf,\n content: truncate(content, 2000),\n type: path.extname(mf).slice(1),\n })\n }\n }\n }\n\n return schemas\n}\n\nfunction extractTableNames(content: string, type: string): string[] {\n if (type === \"prisma\") {\n const matches = content.match(/model\\s+(\\w+)\\s*\\{/g)\n return matches ? matches.map((m) => m.replace(/model\\s+/, \"\").replace(/\\s*\\{/, \"\")) : []\n }\n return []\n}\n\nfunction parseEnvFile(content: string): EnvSchema {\n const lines = content.split(\"\\n\").filter((l) => l.trim() && !l.trim().startsWith(\"#\"))\n const variables = lines.map((line) => {\n const [keyPart] = line.split(\"=\")\n const key = keyPart.trim()\n const hasValue = line.includes(\"=\") && line.split(\"=\")[1]?.trim().length > 0\n return {\n key,\n required: !hasValue,\n }\n })\n return { variables }\n}\n\nasync function safeReadFile(filePath: string): Promise<string | null> {\n try {\n if (!existsSync(filePath)) return null\n return await fs.readFile(filePath, \"utf8\")\n } catch {\n return null\n }\n}\n\nfunction truncate(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str\n return str.slice(0, maxLen) + \"\\n... (truncated)\"\n}\n\nexport function formatSchemas(schemas: ProjectSchemas): string {\n const sections: string[] = []\n\n if (schemas.database) {\n sections.push(\n `## Database Schema (${schemas.database.type})\\n` +\n (schemas.database.tables?.length\n ? `Tables: ${schemas.database.tables.join(\", \")}\\n`\n : \"\") +\n \"```\\n\" +\n schemas.database.content +\n \"\\n```\"\n )\n }\n\n if (schemas.api) {\n sections.push(\n `## API Schema (${schemas.api.type})\\n` + \"```\\n\" + schemas.api.content + \"\\n```\"\n )\n }\n\n if (schemas.env) {\n sections.push(\n `## Environment Variables\\n` +\n schemas.env.variables.map((v) => `- ${v.key}${v.required ? \" (required)\" : \"\"}`).join(\"\\n\")\n )\n }\n\n if (schemas.models?.length) {\n for (const model of schemas.models) {\n sections.push(\n `## Model: ${model.path}\\n` + \"```\" + model.type + \"\\n\" + model.content + \"\\n```\"\n )\n }\n }\n\n return sections.join(\"\\n\\n\")\n}\n","import fetch from \"node-fetch\"\nimport { logger } from \"@/utils/logger\"\nimport type { TechStack } from \"./tech-stack\"\n\n// --- Context7 integration: fetch up-to-date library documentation ---\n\nconst CONTEXT7_API = \"https://api.context7.com/v1\"\n\ninterface Context7Library {\n id: string\n name: string\n description?: string\n}\n\ninterface Context7Docs {\n libraryId: string\n content: string\n tokens: number\n}\n\nexport async function resolveLibraryId(\n libraryName: string,\n apiKey?: string\n): Promise<Context7Library | null> {\n try {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n }\n if (apiKey) headers[\"Authorization\"] = `Bearer ${apiKey}`\n\n const response = await fetch(`${CONTEXT7_API}/libraries/resolve`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ name: libraryName }),\n })\n\n if (!response.ok) return null\n\n const data = (await response.json()) as any\n if (data?.libraries?.length) {\n return data.libraries[0]\n }\n return null\n } catch {\n return null\n }\n}\n\nexport async function getLibraryDocs(\n libraryId: string,\n topic?: string,\n maxTokens: number = 5000,\n apiKey?: string\n): Promise<string | null> {\n try {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n }\n if (apiKey) headers[\"Authorization\"] = `Bearer ${apiKey}`\n\n const response = await fetch(`${CONTEXT7_API}/libraries/${encodeURIComponent(libraryId)}/docs`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ topic, maxTokens }),\n })\n\n if (!response.ok) return null\n\n const data = (await response.json()) as any\n return data?.content || null\n } catch {\n return null\n }\n}\n\nexport async function gatherContext7Docs(\n stack: TechStack,\n topic: string,\n apiKey?: string\n): Promise<string> {\n const relevantLibraries: string[] = []\n\n // Gather the most important frameworks and libraries\n for (const fw of stack.frameworks.slice(0, 3)) {\n relevantLibraries.push(fw.name)\n }\n\n // Add key dependencies\n const priorityDeps = [\n \"react\",\n \"vue\",\n \"svelte\",\n \"angular\",\n \"next\",\n \"nuxt\",\n \"express\",\n \"fastify\",\n \"hono\",\n \"prisma\",\n \"drizzle-orm\",\n \"tailwindcss\",\n \"shadcn\",\n \"@tanstack/react-query\",\n \"zod\",\n \"trpc\",\n ]\n\n for (const dep of priorityDeps) {\n if (stack.dependencies[dep] || stack.devDependencies[dep]) {\n if (!relevantLibraries.includes(dep)) {\n relevantLibraries.push(dep)\n }\n }\n }\n\n const docs: string[] = []\n\n for (const lib of relevantLibraries.slice(0, 5)) {\n const library = await resolveLibraryId(lib, apiKey)\n if (library) {\n const content = await getLibraryDocs(library.id, topic, 3000, apiKey)\n if (content) {\n docs.push(`## ${library.name} Documentation\\n${content}`)\n }\n }\n }\n\n if (!docs.length) {\n return \"\"\n }\n\n return `# Relevant Library Documentation (via Context7)\\n\\n${docs.join(\"\\n\\n---\\n\\n\")}`\n}\n","import type { OutputType } from \"../providers/types\"\n\n// --- Output type resolution and file path mapping ---\n\nexport interface OutputConfig {\n type: OutputType\n baseDir: string\n filePatterns: string[]\n description: string\n}\n\nexport const OUTPUT_CONFIGS: Record<string, OutputConfig> = {\n component: {\n type: \"component\",\n baseDir: \"src/components\",\n filePatterns: [\"*.tsx\", \"*.vue\", \"*.svelte\", \"*.jsx\", \"*.ts\"],\n description: \"UI component\",\n },\n page: {\n type: \"page\",\n baseDir: \"src/app\",\n filePatterns: [\"*.tsx\", \"*.vue\", \"*.svelte\", \"*.jsx\", \"*.astro\"],\n description: \"Page or screen\",\n },\n api: {\n type: \"api\",\n baseDir: \"src/api\",\n filePatterns: [\"*.ts\", \"*.js\", \"*.py\", \"*.go\", \"*.rs\"],\n description: \"API route or endpoint\",\n },\n website: {\n type: \"website\",\n baseDir: \".\",\n filePatterns: [\"*\"],\n description: \"Multi-file website\",\n },\n document: {\n type: \"document\",\n baseDir: \"docs\",\n filePatterns: [\"*.md\", \"*.mdx\", \"*.txt\", \"*.rst\"],\n description: \"Documentation\",\n },\n script: {\n type: \"script\",\n baseDir: \"scripts\",\n filePatterns: [\"*.ts\", \"*.js\", \"*.py\", \"*.sh\", \"*.go\"],\n description: \"Standalone script\",\n },\n config: {\n type: \"config\",\n baseDir: \".\",\n filePatterns: [\"*.json\", \"*.yaml\", \"*.yml\", \"*.toml\", \"*.env\"],\n description: \"Configuration file\",\n },\n skill: {\n type: \"skill\",\n baseDir: \".skills\",\n filePatterns: [\"SKILL.md\"],\n description: \"Agent skill (SKILL.md)\",\n },\n media: {\n type: \"media\",\n baseDir: \"media\",\n filePatterns: [\"*.md\", \"*.json\", \"*.txt\"],\n description: \"Media generation prompt/description\",\n },\n report: {\n type: \"report\",\n baseDir: \"reports\",\n filePatterns: [\"*.md\", \"*.html\", \"*.json\"],\n description: \"Analysis report\",\n },\n test: {\n type: \"test\",\n baseDir: \"src\",\n filePatterns: [\"*.test.ts\", \"*.test.tsx\", \"*.spec.ts\", \"*.test.js\", \"*.test.py\", \"*.test.go\"],\n description: \"Test suite or fixture\",\n },\n workflow: {\n type: \"workflow\",\n baseDir: \".github/workflows\",\n filePatterns: [\"*.yml\", \"*.yaml\"],\n description: \"CI/CD pipeline or automation\",\n },\n schema: {\n type: \"schema\",\n baseDir: \"src\",\n filePatterns: [\"*.ts\", \"*.prisma\", \"*.graphql\", \"*.gql\", \"*.py\"],\n description: \"Database schema, validators, or types\",\n },\n email: {\n type: \"email\",\n baseDir: \"src/emails\",\n filePatterns: [\"*.tsx\", \"*.jsx\", \"*.html\", \"*.mjml\"],\n description: \"Email template\",\n },\n diagram: {\n type: \"diagram\",\n baseDir: \"docs\",\n filePatterns: [\"*.md\", \"*.mmd\", \"*.d2\", \"*.puml\"],\n description: \"Architecture or data diagram\",\n },\n}\n\nexport function resolveOutputType(\n userHint: string | undefined,\n taskDescription: string\n): OutputType {\n if (userHint && userHint !== \"auto\") {\n return userHint as OutputType\n }\n\n const lower = taskDescription.toLowerCase()\n\n // Pattern matching for output type detection\n const patterns: [RegExp, OutputType][] = [\n [/\\b(component|button|card|modal|dialog|form|input|dropdown|nav|sidebar|header|footer|widget|ui)\\b/i, \"component\"],\n [/\\b(page|screen|view|route|layout|dashboard|landing)\\b/i, \"page\"],\n [/\\b(api|endpoint|route handler|rest|graphql|webhook|middleware|server)\\b/i, \"api\"],\n [/\\b(website|site|web app|landing page|portfolio|blog)\\b/i, \"website\"],\n [/\\b(document|doc|readme|guide|tutorial|specification|spec|changelog)\\b/i, \"document\"],\n [/\\b(script|cli|command|tool|utility|migration|seed|cron)\\b/i, \"script\"],\n [/\\b(config|configuration|setup|env|settings)\\b/i, \"config\"],\n [/\\b(skill|agent skill|skill\\.md)\\b/i, \"skill\"],\n [/\\b(video|audio|image|media|animation|thumbnail|podcast)\\b/i, \"media\"],\n [/\\b(report|audit|analysis|review|assessment|benchmark)\\b/i, \"report\"],\n [/\\b(test|spec|unit test|integration test|e2e|coverage|fixture|mock)\\b/i, \"test\"],\n [/\\b(workflow|ci|cd|pipeline|github action|deploy|automation|ci\\/cd)\\b/i, \"workflow\"],\n [/\\b(schema|model|migration|prisma|drizzle|zod|validator|graphql type)\\b/i, \"schema\"],\n [/\\b(email|newsletter|transactional|invite|welcome email|notification email)\\b/i, \"email\"],\n [/\\b(diagram|erd|flowchart|architecture diagram|sequence diagram|mermaid|plantuml|d2)\\b/i, \"diagram\"],\n ]\n\n for (const [pattern, type] of patterns) {\n if (pattern.test(lower)) {\n return type\n }\n }\n\n return \"component\" // Default fallback\n}\n","import { existsSync, promises as fs } from \"fs\"\nimport path from \"path\"\nimport type { GeneratedFile } from \"../providers/types\"\nimport type { TechStack } from \"../context/tech-stack\"\nimport { OUTPUT_CONFIGS } from \"./types\"\nimport { logger } from \"@/utils/logger\"\nimport { globalHooks } from \"@/hooks\"\nimport { globalPermissions } from \"@/permissions\"\n\n// --- Write generated files to disk ---\n\nexport interface WriteOptions {\n cwd: string\n overwrite: boolean\n dryRun: boolean\n outputDir?: string\n}\n\nexport interface WriteResult {\n written: string[]\n skipped: string[]\n errors: string[]\n}\n\nexport async function writeGeneratedFiles(\n files: GeneratedFile[],\n options: WriteOptions\n): Promise<WriteResult> {\n const result: WriteResult = { written: [], skipped: [], errors: [] }\n\n for (const file of files) {\n const filePath = path.isAbsolute(file.path)\n ? file.path\n : path.resolve(options.cwd, options.outputDir || \"\", file.path)\n\n try {\n // pre:file-write hook — can block or modify file content\n let fileContent = file.content\n if (globalHooks.has(\"pre:file-write\")) {\n const hookResult = await globalHooks.execute(\"pre:file-write\", {\n event: \"pre:file-write\",\n file: filePath,\n fileContent,\n cwd: options.cwd,\n })\n if (hookResult.blocked) {\n result.skipped.push(filePath)\n continue\n }\n if (hookResult.modified?.fileContent) {\n fileContent = String(hookResult.modified.fileContent)\n }\n }\n\n // Permissions check — can allow, deny, or skip (plan mode)\n const relativePath = path.relative(options.cwd, filePath)\n const permission = await globalPermissions.checkFileWrite(relativePath)\n if (permission === \"deny\") {\n result.skipped.push(filePath)\n continue\n }\n if (permission === \"skip\") {\n // Plan mode: record what would be written but don't write\n result.written.push(filePath)\n continue\n }\n\n if (existsSync(filePath) && !options.overwrite) {\n result.skipped.push(filePath)\n continue\n }\n\n if (options.dryRun) {\n result.written.push(filePath)\n continue\n }\n\n // Create directory structure\n const dir = path.dirname(filePath)\n await fs.mkdir(dir, { recursive: true })\n\n // Write file\n await fs.writeFile(filePath, fileContent, \"utf8\")\n result.written.push(filePath)\n\n // post:file-write hook — post-processing (format, git add, etc.)\n if (globalHooks.has(\"post:file-write\")) {\n await globalHooks.execute(\"post:file-write\", {\n event: \"post:file-write\",\n file: filePath,\n fileContent,\n cwd: options.cwd,\n })\n }\n } catch (error: any) {\n result.errors.push(`${filePath}: ${error.message}`)\n }\n }\n\n return result\n}\n\nexport function resolveOutputDir(\n outputType: string,\n stack: TechStack,\n customDir?: string\n): string {\n if (customDir) return customDir\n\n const config = OUTPUT_CONFIGS[outputType]\n if (!config) return \"generated\"\n\n // Adjust base dir based on project structure\n let baseDir = config.baseDir\n\n if (outputType === \"component\") {\n // Detect existing component directory\n if (stack.srcDir) {\n baseDir = `${stack.srcDir}/components`\n } else {\n baseDir = \"components\"\n }\n }\n\n if (outputType === \"page\") {\n // Detect app dir structure\n const hasAppDir =\n stack.frameworks.find((f) => f.name === \"nextjs\") && stack.srcDir\n if (hasAppDir) {\n baseDir = `${stack.srcDir}/app`\n }\n }\n\n if (outputType === \"api\") {\n const isNextJs = stack.frameworks.find((f) => f.name === \"nextjs\")\n if (isNextJs) {\n baseDir = stack.srcDir ? `${stack.srcDir}/app/api` : \"app/api\"\n }\n }\n\n if (outputType === \"test\") {\n if (stack.testing.includes(\"vitest\") || stack.testing.includes(\"jest\")) {\n baseDir = stack.srcDir || \"src\"\n }\n }\n\n if (outputType === \"workflow\") {\n baseDir = \".github/workflows\"\n }\n\n if (outputType === \"schema\") {\n if (stack.databases.includes(\"prisma\")) {\n baseDir = \"prisma\"\n } else if (stack.srcDir) {\n baseDir = `${stack.srcDir}/schemas`\n }\n }\n\n if (outputType === \"email\") {\n baseDir = stack.srcDir ? `${stack.srcDir}/emails` : \"emails\"\n }\n\n return baseDir\n}\n","import { execa } from \"execa\"\nimport type { HookEvent, HookDefinition, HookContext, HookResult, HookHandler } from \"./types\"\nimport { BLOCKING_EVENTS } from \"./types\"\nimport { logger } from \"@/utils/logger\"\nimport { debug } from \"@/observability\"\nimport { loadAuthConfig, resolveToken } from \"@/utils/auth-store\"\n\n// --- Hook Registry: registration, priority ordering, execution ---\n\ninterface RegisteredHook {\n event: HookEvent\n definition: HookDefinition\n handler: HookHandler\n}\n\nexport class HookRegistry {\n private hooks: Map<HookEvent, RegisteredHook[]> = new Map()\n\n /**\n * Register a hook for an event.\n */\n register(event: HookEvent, definition: HookDefinition): void {\n if (!definition.enabled) return\n\n const handler = this.createHandler(definition)\n const entry: RegisteredHook = { event, definition, handler }\n\n const existing = this.hooks.get(event) || []\n existing.push(entry)\n // Sort by priority (lower number = runs first)\n existing.sort((a, b) => a.definition.priority - b.definition.priority)\n this.hooks.set(event, existing)\n }\n\n /**\n * Execute all hooks for an event. Returns combined result.\n * For blocking events, stops at the first hook that returns { blocked: true }.\n */\n async execute(event: HookEvent, context: HookContext): Promise<HookResult> {\n const registered = this.hooks.get(event)\n if (!registered?.length) {\n return {}\n }\n\n const canBlock = BLOCKING_EVENTS.includes(event)\n let combinedModified: Record<string, unknown> = {}\n\n for (const hook of registered) {\n const start = Date.now()\n try {\n const result = await hook.handler({ ...context, ...combinedModified })\n const duration = Date.now() - start\n\n if (result.modified) {\n combinedModified = { ...combinedModified, ...result.modified }\n }\n\n if (canBlock && result.blocked) {\n debug.hook(hook.definition.name, duration, \"blocked\")\n return {\n blocked: true,\n message: result.message || `Blocked by hook: ${hook.definition.name}`,\n modified: combinedModified,\n }\n }\n\n debug.hook(hook.definition.name, duration, \"ok\")\n } catch (error: any) {\n const duration = Date.now() - start\n debug.hook(hook.definition.name, duration, `error: ${error.message}`)\n logger.warn(`Hook \"${hook.definition.name}\" failed: ${error.message}`)\n // Non-blocking hooks swallow errors; blocking hooks propagate\n if (canBlock) {\n return {\n blocked: true,\n message: `Hook \"${hook.definition.name}\" errored: ${error.message}`,\n }\n }\n }\n }\n\n return { modified: Object.keys(combinedModified).length ? combinedModified : undefined }\n }\n\n /**\n * Register an in-process handler for an event. Used by modules that ship\n * their hook behavior as plain JS functions rather than as command/script/\n * prompt definitions loaded from disk (e.g. the workflow engine's\n * subscribers to on:gitlab-issue / on:gitlab-pipeline / post:response).\n * Priority follows the same rule as register(): lower runs first.\n */\n registerHandler(event: HookEvent, name: string, handler: HookHandler, priority: number = 100): void {\n const definition: HookDefinition = { name, type: \"script\", priority, enabled: true }\n const entry: RegisteredHook = { event, definition, handler }\n const existing = this.hooks.get(event) || []\n existing.push(entry)\n existing.sort((a, b) => a.definition.priority - b.definition.priority)\n this.hooks.set(event, existing)\n }\n\n /**\n * Check if any hooks are registered for an event.\n */\n has(event: HookEvent): boolean {\n const registered = this.hooks.get(event)\n return !!registered?.length\n }\n\n /**\n * Clear all hooks (useful for testing).\n */\n clear(): void {\n this.hooks.clear()\n }\n\n /** Total number of registered hook entries across all events. Used by the\n * daemon reload path to surface hook-count deltas in the reload summary. */\n size(): number {\n let n = 0\n for (const list of this.hooks.values()) n += list.length\n return n\n }\n\n /**\n * Create a HookHandler from a HookDefinition.\n */\n private createHandler(definition: HookDefinition): HookHandler {\n switch (definition.type) {\n case \"command\":\n return this.createCommandHandler(definition)\n case \"script\":\n return this.createScriptHandler(definition)\n case \"prompt\":\n return this.createPromptHandler(definition)\n default:\n throw new Error(`Unknown hook type: ${definition.type}`)\n }\n }\n\n /**\n * Command hook: runs a shell command with {{variable}} interpolation.\n * Exit code 0 = success, non-zero = blocked (for blocking events).\n */\n private createCommandHandler(definition: HookDefinition): HookHandler {\n return async (context: HookContext): Promise<HookResult> => {\n if (!definition.command) {\n return {}\n }\n\n // Interpolate {{variable}} placeholders\n let cmd = definition.command\n cmd = cmd.replace(/\\{\\{(\\w+)\\}\\}/g, (_match, key) => {\n return String(context[key] ?? \"\")\n })\n\n const result = await execa(\"sh\", [\"-c\", cmd], {\n cwd: context.cwd || process.cwd(),\n reject: false,\n timeout: 60_000,\n env: process.env,\n })\n\n if (result.exitCode !== 0) {\n return {\n blocked: true,\n message: result.stderr || result.stdout || `Command hook \"${definition.name}\" failed`,\n }\n }\n\n return {}\n }\n }\n\n /**\n * Script hook: imports and runs a JS/TS module that exports a handler function.\n */\n private createScriptHandler(definition: HookDefinition): HookHandler {\n return async (context: HookContext): Promise<HookResult> => {\n if (!definition.script) {\n return {}\n }\n\n const scriptPath = definition.script.startsWith(\"/\")\n ? definition.script\n : `${context.cwd || process.cwd()}/${definition.script}`\n\n const mod = await import(scriptPath)\n const handler = mod.default || mod.handler || mod\n\n if (typeof handler === \"function\") {\n return await handler(context)\n }\n\n return {}\n }\n }\n\n /**\n * Prompt hook: single-turn LLM call that can block or modify the operation.\n * The prompt template supports {{variable}} interpolation from hook context.\n * The LLM must respond with JSON: { \"action\": \"allow\"|\"block\", \"message\": \"...\", \"modified\": {...} }\n */\n private createPromptHandler(definition: HookDefinition): HookHandler {\n return async (context: HookContext): Promise<HookResult> => {\n if (!definition.prompt) {\n return {}\n }\n\n // Check credentials are available (don't prompt interactively)\n const providerName = definition.provider || loadAuthConfig()?.provider || \"claude-code\"\n const resolved = resolveToken()\n if (!resolved && providerName !== \"claude-code\") {\n logger.warn(\n `Prompt hook \"${definition.name}\" skipped: no credentials available for provider \"${providerName}\"`\n )\n return {}\n }\n\n try {\n // Lazy import to avoid circular deps\n const { createProvider } = await import(\"@/agent/providers\")\n const provider = createProvider(providerName as any, resolved?.token)\n\n // Interpolate {{variable}} placeholders in the prompt template\n let prompt = definition.prompt\n prompt = prompt.replace(/\\{\\{(\\w+)\\}\\}/g, (_match, key) => {\n return String(context[key] ?? \"\")\n })\n\n const systemPrompt = `You are a hook validator for agentx. Analyze the following context and respond with ONLY a JSON object (no markdown, no code fences).\n\nResponse format:\n{\"action\": \"allow\", \"message\": \"optional explanation\"}\nOR\n{\"action\": \"block\", \"message\": \"reason for blocking\"}\nOR\n{\"action\": \"allow\", \"message\": \"optional\", \"modified\": {\"key\": \"new value\"}}\n\nThe \"modified\" field is optional and can contain updated values to pass forward.`\n\n const result = await provider.generate(\n [\n { role: \"system\", content: systemPrompt },\n { role: \"user\", content: prompt },\n ],\n {\n model: definition.model,\n maxTokens: 1024,\n }\n )\n\n // Parse the LLM response as JSON\n const content = result.content.trim()\n // Try to extract JSON from the response (handle markdown fences)\n const jsonMatch = content.match(/\\{[\\s\\S]*\\}/)\n if (!jsonMatch) {\n logger.warn(`Prompt hook \"${definition.name}\": LLM response was not valid JSON, allowing`)\n return {}\n }\n\n const parsed = JSON.parse(jsonMatch[0])\n\n if (parsed.action === \"block\") {\n return {\n blocked: true,\n message: parsed.message || `Blocked by prompt hook: ${definition.name}`,\n }\n }\n\n if (parsed.modified) {\n return { modified: parsed.modified }\n }\n\n return {}\n } catch (error: any) {\n // Don't block on hook failures — log and continue\n logger.warn(`Prompt hook \"${definition.name}\" failed: ${error.message}`)\n return {}\n }\n }\n }\n}\n","import { z } from \"zod\"\n\n// --- Hook system types ---\n\nexport const HOOK_EVENTS = [\n \"pre:generate\",\n \"post:generate\",\n \"pre:file-write\",\n \"post:file-write\",\n \"pre:prompt\",\n \"post:response\",\n \"pre:command\",\n \"on:error\",\n \"pre:tool-call\",\n \"post:tool-call\",\n // Daemon events\n \"pre:channel-message\",\n \"post:channel-message\",\n \"pre:a2a-task\",\n \"pre:cron-run\",\n \"post:cron-run\",\n // GitLab-specific events (fired without agent routing — side-effect hooks\n // OR routing-modifying hooks that return `modified.dispatch` to pick the\n // agent(s) to run for this event).\n \"on:gitlab-pipeline\",\n \"on:gitlab-issue\",\n \"on:gitlab-mr\",\n \"on:gitlab-note\",\n // GitHub events — fired by the generic webhook handler after signature\n // verification. Workflow `trigger.hook` subscribers can subscribe.\n \"on:github-issue\",\n \"on:github-pr\",\n \"on:github-push\",\n // External-service events — fired by the generic webhook handler after\n // signature verification. Workflows subscribe via trigger.hook.\n \"on:stripe-event\",\n \"on:sentry-issue\",\n \"on:vercel-deployment\",\n \"on:odoo-event\",\n \"on:hubspot-event\",\n] as const\n\nexport type HookEvent = (typeof HOOK_EVENTS)[number]\n\n// Which hooks can block (return { blocked: true } to cancel the operation)\nexport const BLOCKING_EVENTS: HookEvent[] = [\n \"pre:generate\",\n \"pre:file-write\",\n \"pre:prompt\",\n \"post:response\",\n \"pre:command\",\n \"pre:tool-call\",\n // Daemon blocking events\n \"pre:channel-message\",\n \"post:channel-message\",\n \"pre:a2a-task\",\n \"pre:cron-run\",\n]\n\nexport type HookType = \"command\" | \"prompt\" | \"script\"\n\nexport const hookDefinitionSchema = z.object({\n name: z.string(),\n type: z.enum([\"command\", \"prompt\", \"script\"]),\n // For \"command\" type: shell command with {{variable}} interpolation\n command: z.string().optional(),\n // For \"prompt\" type: LLM prompt template\n prompt: z.string().optional(),\n // For \"prompt\" type: override provider/model for this hook\n provider: z.enum([\"claude-code\", \"claude\", \"openai\", \"deepseek\", \"ollama\", \"custom\"]).optional(),\n model: z.string().optional(),\n // For \"script\" type: path to JS/TS file exporting a handler\n script: z.string().optional(),\n // Hook priority (lower runs first, default 100)\n priority: z.number().default(100),\n // Whether this hook is enabled\n enabled: z.boolean().default(true),\n})\n\nexport type HookDefinition = z.infer<typeof hookDefinitionSchema>\n\nexport interface HookContext {\n event: HookEvent\n // Data varies by event\n task?: string\n file?: string\n fileContent?: string\n content?: string\n command?: string\n error?: Error\n cwd?: string\n [key: string]: unknown\n}\n\nexport interface HookResult {\n // If true, the operation is blocked/cancelled\n blocked?: boolean\n // Optional message explaining why it was blocked\n message?: string\n // Modified data to pass forward (e.g., modified file content)\n modified?: Record<string, unknown>\n}\n\nexport type HookHandler = (context: HookContext) => Promise<HookResult>\n","// --- Usage tracking: tokens, cost, per-step and per-model breakdown ---\n\nexport interface StepUsage {\n step: number\n model: string\n inputTokens: number\n outputTokens: number\n cost: number\n timestamp: number\n}\n\nexport interface ModelUsage {\n inputTokens: number\n outputTokens: number\n cost: number\n steps: number\n}\n\nexport interface UsageSummary {\n totalInputTokens: number\n totalOutputTokens: number\n totalTokens: number\n totalCost: number\n steps: StepUsage[]\n models: Record<string, ModelUsage>\n}\n\n// Cost per million tokens (input / output)\nconst MODEL_PRICING: Record<string, { input: number; output: number }> = {\n \"claude-sonnet\": { input: 3, output: 15 },\n \"claude-opus\": { input: 15, output: 75 },\n \"claude-haiku\": { input: 0.25, output: 1.25 },\n}\n\nfunction getModelFamily(model: string): string {\n const lower = model.toLowerCase()\n if (lower.includes(\"opus\")) return \"claude-opus\"\n if (lower.includes(\"haiku\")) return \"claude-haiku\"\n return \"claude-sonnet\" // default\n}\n\nexport class UsageTracker {\n private steps: StepUsage[] = []\n private models: Map<string, ModelUsage> = new Map()\n\n recordStep(\n step: number,\n model: string,\n inputTokens: number,\n outputTokens: number\n ): void {\n const family = getModelFamily(model)\n const pricing = MODEL_PRICING[family] || MODEL_PRICING[\"claude-sonnet\"]\n const cost =\n (inputTokens / 1_000_000) * pricing.input +\n (outputTokens / 1_000_000) * pricing.output\n\n this.steps.push({\n step,\n model,\n inputTokens,\n outputTokens,\n cost,\n timestamp: Date.now(),\n })\n\n const existing = this.models.get(model) || {\n inputTokens: 0,\n outputTokens: 0,\n cost: 0,\n steps: 0,\n }\n existing.inputTokens += inputTokens\n existing.outputTokens += outputTokens\n existing.cost += cost\n existing.steps++\n this.models.set(model, existing)\n }\n\n getSummary(): UsageSummary {\n let totalInputTokens = 0\n let totalOutputTokens = 0\n let totalCost = 0\n\n for (const step of this.steps) {\n totalInputTokens += step.inputTokens\n totalOutputTokens += step.outputTokens\n totalCost += step.cost\n }\n\n const models: Record<string, ModelUsage> = {}\n for (const [name, usage] of this.models) {\n models[name] = { ...usage }\n }\n\n return {\n totalInputTokens,\n totalOutputTokens,\n totalTokens: totalInputTokens + totalOutputTokens,\n totalCost,\n steps: [...this.steps],\n models,\n }\n }\n\n reset(): void {\n this.steps = []\n this.models.clear()\n }\n}\n\nexport const globalTracker = new UsageTracker()\n","// --- Session export: convert a session to readable markdown ---\n\nimport type { Session } from \"@/repl/session\"\nimport type { UsageSummary } from \"./tracker\"\n\nexport function exportSession(session: Session, usage?: UsageSummary): string {\n const lines: string[] = []\n\n // Header\n lines.push(`# Session: ${session.id}`)\n lines.push(\"\")\n lines.push(`- **Created**: ${session.createdAt}`)\n lines.push(`- **Updated**: ${session.updatedAt}`)\n lines.push(`- **CWD**: ${session.cwd}`)\n lines.push(`- **Messages**: ${session.messages.length}`)\n lines.push(`- **Tokens**: ${session.tokensUsed.toLocaleString()}`)\n lines.push(\"\")\n\n // Files generated\n if (session.filesGenerated.length) {\n lines.push(\"## Files Generated\")\n lines.push(\"\")\n for (const file of session.filesGenerated) {\n lines.push(`- \\`${file}\\``)\n }\n lines.push(\"\")\n }\n\n // Conversation\n if (session.messages.length) {\n lines.push(\"## Conversation\")\n lines.push(\"\")\n for (const msg of session.messages) {\n if (msg.role === \"system\") continue\n const label = msg.role === \"user\" ? \"**User**\" : \"**Assistant**\"\n lines.push(`### ${label}`)\n lines.push(\"\")\n if (msg.role === \"assistant\") {\n lines.push(msg.content)\n } else {\n lines.push(msg.content)\n }\n lines.push(\"\")\n }\n }\n\n // Cost summary\n if (usage) {\n lines.push(\"## Cost Summary\")\n lines.push(\"\")\n lines.push(`- **Total tokens**: ${usage.totalTokens.toLocaleString()}`)\n lines.push(` - Input: ${usage.totalInputTokens.toLocaleString()}`)\n lines.push(` - Output: ${usage.totalOutputTokens.toLocaleString()}`)\n lines.push(`- **Total cost**: $${usage.totalCost.toFixed(4)}`)\n lines.push(\"\")\n\n if (Object.keys(usage.models).length) {\n lines.push(\"### Per Model\")\n lines.push(\"\")\n lines.push(\"| Model | Input | Output | Cost | Steps |\")\n lines.push(\"|-------|-------|--------|------|-------|\")\n for (const [model, mu] of Object.entries(usage.models)) {\n lines.push(\n `| ${model} | ${mu.inputTokens.toLocaleString()} | ${mu.outputTokens.toLocaleString()} | $${mu.cost.toFixed(4)} | ${mu.steps} |`\n )\n }\n lines.push(\"\")\n }\n\n if (usage.steps.length) {\n lines.push(\"### Per Step\")\n lines.push(\"\")\n lines.push(\"| Step | Model | Input | Output | Cost |\")\n lines.push(\"|------|-------|-------|--------|------|\")\n for (const step of usage.steps) {\n lines.push(\n `| ${step.step} | ${step.model} | ${step.inputTokens.toLocaleString()} | ${step.outputTokens.toLocaleString()} | $${step.cost.toFixed(4)} |`\n )\n }\n lines.push(\"\")\n }\n }\n\n return lines.join(\"\\n\")\n}\n","import { existsSync, readFileSync, readdirSync } from \"fs\"\nimport path from \"path\"\nimport type { HookEvent, HookDefinition } from \"./types\"\nimport { HOOK_EVENTS, hookDefinitionSchema } from \"./types\"\nimport { HookRegistry } from \"./registry\"\nimport { logger } from \"@/utils/logger\"\n\n// --- Hook Loader: load hooks from config and .agentx/hooks/ ---\n\ninterface HooksConfig {\n hooks?: Partial<Record<HookEvent, HookDefinition[]>>\n}\n\n/**\n * Load hooks from agentx.config.json and .agentx/hooks/ directory.\n */\nexport function loadHooks(cwd: string, registry: HookRegistry): void {\n loadHooksFromConfig(cwd, registry)\n loadHooksFromDirectory(cwd, registry)\n}\n\n/**\n * Load hook definitions from agentx.config.json.\n */\nfunction loadHooksFromConfig(cwd: string, registry: HookRegistry): void {\n const configPath = path.join(cwd, \"agentx.config.json\")\n if (!existsSync(configPath)) return\n\n try {\n const raw = JSON.parse(readFileSync(configPath, \"utf8\")) as HooksConfig\n if (!raw.hooks) return\n\n for (const [eventName, definitions] of Object.entries(raw.hooks)) {\n if (!HOOK_EVENTS.includes(eventName as HookEvent)) {\n logger.warn(`Unknown hook event in config: ${eventName}`)\n continue\n }\n\n const event = eventName as HookEvent\n if (!Array.isArray(definitions)) continue\n\n for (const def of definitions) {\n try {\n const parsed = hookDefinitionSchema.parse(def)\n registry.register(event, parsed)\n } catch (error: any) {\n logger.warn(`Invalid hook definition for ${event}: ${error.message}`)\n }\n }\n }\n } catch (error: any) {\n logger.warn(`Failed to load hooks from config: ${error.message}`)\n }\n}\n\n/**\n * Load hook scripts from .agentx/hooks/ directory.\n * Files are named <event>.<name>.ts (e.g., pre-file-write.format.ts).\n */\nfunction loadHooksFromDirectory(cwd: string, registry: HookRegistry): void {\n const hooksDir = path.join(cwd, \".agentx\", \"hooks\")\n if (!existsSync(hooksDir)) return\n\n try {\n const files = readdirSync(hooksDir).filter(\n (f) => f.endsWith(\".ts\") || f.endsWith(\".js\") || f.endsWith(\".mjs\")\n )\n\n for (const file of files) {\n // Parse filename: <event>.<name>.<ext>\n // Event uses dashes in filename: pre-file-write → pre:file-write\n const parts = file.replace(/\\.(ts|js|mjs)$/, \"\").split(\".\")\n if (parts.length < 2) {\n logger.warn(`Hook file \"${file}\" should be named <event>.<name>.<ext>`)\n continue\n }\n\n const eventSlug = parts[0]\n const name = parts.slice(1).join(\".\")\n\n // Convert slug to event name: pre-file-write → pre:file-write\n const eventName = eventSlug.replace(/-/g, \":\") as HookEvent\n if (!HOOK_EVENTS.includes(eventName)) {\n // Try replacing first dash only: pre-generate → pre:generate\n const altEvent = eventSlug.replace(\"-\", \":\") as HookEvent\n if (!HOOK_EVENTS.includes(altEvent)) {\n logger.warn(`Unknown hook event in filename: ${file}`)\n continue\n }\n registry.register(altEvent, {\n name,\n type: \"script\",\n script: path.join(hooksDir, file),\n priority: 100,\n enabled: true,\n })\n continue\n }\n\n registry.register(eventName, {\n name,\n type: \"script\",\n script: path.join(hooksDir, file),\n priority: 100,\n enabled: true,\n })\n }\n } catch (error: any) {\n logger.warn(`Failed to load hooks from directory: ${error.message}`)\n }\n}\n","export { HookRegistry } from \"./registry\"\nexport { loadHooks } from \"./loader\"\nexport type { HookEvent, HookDefinition, HookContext, HookResult, HookHandler } from \"./types\"\nexport { HOOK_EVENTS, BLOCKING_EVENTS } from \"./types\"\n\nimport { HookRegistry } from \"./registry\"\n\n// Singleton hook registry for the CLI process\nexport const globalHooks = new HookRegistry()\n","// --- Permission Manager: checking and inline prompts for file writes ---\n\nimport prompts from \"prompts\"\nimport chalk from \"chalk\"\nimport type { PermissionMode, PermissionConfig } from \"./types\"\nimport { permissionConfigSchema } from \"./types\"\nimport { debug } from \"@/observability\"\n\nexport type PermissionAction = \"allow\" | \"deny\" | \"skip\"\n\n/**\n * Simple glob matching: supports *, **, and ? wildcards.\n */\nfunction matchGlob(filePath: string, pattern: string): boolean {\n // Convert glob pattern to regex\n let regex = pattern\n .replace(/\\./g, \"\\\\.\")\n .replace(/\\*\\*/g, \"{{GLOBSTAR}}\")\n .replace(/\\*/g, \"[^/]*\")\n .replace(/\\{\\{GLOBSTAR\\}\\}/g, \".*\")\n .replace(/\\?/g, \"[^/]\")\n return new RegExp(`^${regex}$`).test(filePath)\n}\n\nexport class PermissionManager {\n private mode: PermissionMode\n private allowPatterns: string[]\n private denyPatterns: string[]\n private confirmPatterns: string[]\n private autoAllowAll = false // set when user picks \"all\" in interactive prompt\n\n constructor(config?: Partial<PermissionConfig>) {\n const parsed = permissionConfigSchema.parse(config || {})\n this.mode = parsed.mode\n this.allowPatterns = parsed.allow\n this.denyPatterns = parsed.deny\n this.confirmPatterns = parsed.confirm\n }\n\n getMode(): PermissionMode {\n return this.mode\n }\n\n setMode(mode: PermissionMode): void {\n this.mode = mode\n this.autoAllowAll = false // reset on mode change\n debug.context(\"permissions\", `mode set to ${mode}`)\n }\n\n /**\n * Check whether a file write should proceed.\n */\n async checkFileWrite(filePath: string): Promise<PermissionAction> {\n debug.context(\"permissions\", `checking write: ${filePath} (mode: ${this.mode})`)\n\n // Always deny files matching deny patterns\n if (this.matchesAny(filePath, this.denyPatterns)) {\n debug.context(\"permissions\", `denied by pattern: ${filePath}`)\n return \"deny\"\n }\n\n switch (this.mode) {\n case \"yolo\":\n return \"allow\"\n\n case \"plan\":\n return \"skip\"\n\n case \"acceptEdits\":\n return \"allow\"\n\n case \"default\":\n // If user already chose \"all\", auto-allow\n if (this.autoAllowAll) return \"allow\"\n\n // Auto-allow if matches allow patterns\n if (this.matchesAny(filePath, this.allowPatterns)) {\n return \"allow\"\n }\n\n // Must confirm if matches confirm patterns or no patterns match\n return this.promptUser(filePath)\n\n default:\n return \"allow\"\n }\n }\n\n /**\n * Check whether a command should proceed (for pre:command hook).\n */\n async checkCommand(command: string): Promise<\"allow\" | \"deny\"> {\n if (this.mode === \"yolo\") return \"allow\"\n if (this.mode === \"plan\") return \"deny\"\n // For default and acceptEdits, commands are allowed\n return \"allow\"\n }\n\n private matchesAny(filePath: string, patterns: string[]): boolean {\n return patterns.some((p) => matchGlob(filePath, p))\n }\n\n private async promptUser(filePath: string): Promise<PermissionAction> {\n const { action } = await prompts({\n type: \"select\",\n name: \"action\",\n message: `Write file ${chalk.cyan(filePath)}?`,\n choices: [\n { title: \"Yes\", value: \"allow\" },\n { title: \"No\", value: \"deny\" },\n { title: \"All (allow remaining)\", value: \"all\" },\n { title: \"Skip\", value: \"skip\" },\n ],\n initial: 0,\n })\n\n if (action === \"all\") {\n this.autoAllowAll = true\n return \"allow\"\n }\n\n return action || \"deny\"\n }\n}\n\nexport const globalPermissions = new PermissionManager()\n","// --- Permission mode definitions and config schema ---\n\nimport { z } from \"zod\"\n\nexport const PERMISSION_MODES = [\"default\", \"acceptEdits\", \"plan\", \"yolo\"] as const\nexport type PermissionMode = (typeof PERMISSION_MODES)[number]\n\nexport const permissionModeSchema = z.enum(PERMISSION_MODES)\n\nexport interface PermissionRule {\n pattern: string\n action: \"allow\" | \"deny\" | \"confirm\"\n}\n\nexport const permissionConfigSchema = z.object({\n mode: permissionModeSchema.default(\"default\"),\n allow: z.array(z.string()).default([]),\n deny: z.array(z.string()).default([]),\n confirm: z.array(z.string()).default([]),\n})\n\nexport type PermissionConfig = z.infer<typeof permissionConfigSchema>\n","// --- Memory Hierarchy: user-level + project-level layered memory ---\n\nimport os from \"os\"\nimport { Memory, type UserPreference, type MemoryEntry, type LearnedPattern, type MemoryStore } from \"@/runtime/memory\"\n\nconst USER_MEMORY_DIR = os.homedir()\n\nexport class MemoryHierarchy {\n private userMemory: Memory\n private projectMemory: Memory\n\n constructor(private cwd: string) {\n // User-level memory at ~/.agentx/memory.json\n this.userMemory = new Memory(USER_MEMORY_DIR)\n // Project-level memory at <cwd>/.agentx/memory.json\n this.projectMemory = new Memory(cwd)\n }\n\n async load(): Promise<void> {\n await Promise.all([this.userMemory.load(), this.projectMemory.load()])\n }\n\n async save(): Promise<void> {\n await Promise.all([this.userMemory.save(), this.projectMemory.save()])\n }\n\n /**\n * Build merged memory context for the agent. Project overrides user.\n */\n buildMemoryContext(task: string): string {\n const userCtx = this.userMemory.buildMemoryContext(task)\n const projectCtx = this.projectMemory.buildMemoryContext(task)\n\n if (!userCtx && !projectCtx) return \"\"\n\n const sections: string[] = []\n if (projectCtx) {\n sections.push(projectCtx)\n }\n if (userCtx) {\n // Prefix user-level context to distinguish it\n sections.push(\n userCtx.replace(\n \"# Memory (learned from past interactions)\",\n \"# Global Memory (cross-project patterns)\"\n )\n )\n }\n\n return sections.join(\"\\n\\n\")\n }\n\n /**\n * Learn a preference at user level (global).\n */\n async learnPreference(key: string, value: string, source: string): Promise<void> {\n await this.userMemory.learnPreference(key, value, source)\n }\n\n /**\n * Record a generation at project level (task-specific).\n */\n async recordGeneration(\n entry: Omit<MemoryEntry, \"id\" | \"timestamp\" | \"type\"> & { type?: MemoryEntry[\"type\"] }\n ): Promise<string> {\n return this.projectMemory.recordGeneration(entry)\n }\n\n /**\n * Get combined preferences (project overrides user for same keys).\n */\n getPreferences(): UserPreference[] {\n const userPrefs = this.userMemory.getPreferences()\n const projectPrefs = this.projectMemory.getPreferences()\n\n const merged = new Map<string, UserPreference>()\n for (const p of userPrefs) {\n merged.set(p.key, p)\n }\n for (const p of projectPrefs) {\n merged.set(p.key, p) // project overrides\n }\n return Array.from(merged.values())\n }\n\n /**\n * Get combined patterns from both levels.\n */\n getPatterns(): LearnedPattern[] {\n const userPatterns = this.userMemory.getPatterns()\n const projectPatterns = this.projectMemory.getPatterns()\n return [...projectPatterns, ...userPatterns]\n }\n\n /**\n * Get stats from both levels.\n */\n getStats(): { user: MemoryStore[\"stats\"]; project: MemoryStore[\"stats\"] } {\n return {\n user: this.userMemory.getStats(),\n project: this.projectMemory.getStats(),\n }\n }\n\n /**\n * Get recent generations from project level.\n */\n getRecentGenerations(limit = 10): MemoryEntry[] {\n return this.projectMemory.getRecentGenerations(limit)\n }\n}\n","// --- Context Builder: smart assembly with @-import resolution and relevance trimming ---\n\nimport { existsSync, readFileSync } from \"fs\"\nimport path from \"path\"\nimport { buildIndex, scoreAll } from \"./bm25\"\n\ninterface ContextSection {\n label: string\n content: string\n priority: number // higher = more important\n}\n\n/**\n * Resolve @-imports in content: replace @path/to/file with file contents.\n */\nexport function resolveAtImports(content: string, basedir: string): string {\n return content.replace(/@([\\w./-]+)/g, (match, filePath: string) => {\n const resolved = path.resolve(basedir, filePath)\n if (existsSync(resolved)) {\n try {\n return readFileSync(resolved, \"utf8\")\n } catch {\n return match // keep original if read fails\n }\n }\n return match // keep original if file doesn't exist\n })\n}\n\n/**\n * Load project instructions from SHADXN.md or CLAUDE.md.\n */\nexport function loadProjectInstructions(cwd: string): string {\n const candidates = [\"SHADXN.md\", \"CLAUDE.md\"]\n for (const name of candidates) {\n const filePath = path.join(cwd, name)\n if (existsSync(filePath)) {\n try {\n let content = readFileSync(filePath, \"utf8\")\n content = resolveAtImports(content, cwd)\n return content\n } catch {\n // skip if unreadable\n }\n }\n }\n return \"\"\n}\n\n/**\n * Estimate token count from content (rough chars-to-tokens).\n */\nfunction estimateTokens(content: string): number {\n return Math.ceil(content.length / 4)\n}\n\nexport class ContextBuilder {\n private sections: ContextSection[] = []\n\n addSection(label: string, content: string, priority = 50): void {\n if (!content.trim()) return\n this.sections.push({ label, content, priority })\n }\n\n /**\n * Build final context, trimming lowest-relevance sections if over budget.\n */\n buildContext(task: string, maxTokens = 12000): string {\n if (this.sections.length === 0) return \"\"\n\n // Score each section via BM25\n const docs = this.sections.map((s) => s.content)\n const index = buildIndex(docs)\n const bm25Results = scoreAll(task, index)\n const scoreMap = new Map(bm25Results.map((r) => [r.docIndex, r.score]))\n\n const scored = this.sections.map((s, i) => ({\n ...s,\n relevance: scoreMap.get(i) ?? 0,\n tokens: estimateTokens(s.content),\n }))\n\n // Sort by combined score (priority weight + relevance)\n scored.sort(\n (a, b) => b.priority + b.relevance * 100 - (a.priority + a.relevance * 100)\n )\n\n // Include sections until budget is exceeded\n const included: typeof scored = []\n let totalTokens = 0\n\n for (const section of scored) {\n if (totalTokens + section.tokens > maxTokens && included.length > 0) {\n // Skip this section — over budget\n continue\n }\n included.push(section)\n totalTokens += section.tokens\n }\n\n return included.map((s) => s.content).join(\"\\n\\n\")\n }\n}\n","// --- Tool Executor: runs tool calls with permission and hook integration ---\n\nimport { promises as fs } from \"fs\"\nimport path from \"path\"\nimport { execa } from \"execa\"\nimport fg from \"fast-glob\"\nimport { globalPermissions } from \"@/permissions\"\nimport { globalHooks } from \"@/hooks\"\nimport { debug } from \"@/observability\"\nimport type { GeneratedFile } from \"../providers/types\"\nimport { executeNoqtaTool, isNoqtaTool, type NoqtaToolContext } from \"./noqta\"\n\nexport interface ToolCallInput {\n name: string\n id: string\n input: Record<string, unknown>\n}\n\nexport interface ToolResult {\n tool_use_id: string\n content: string\n is_error?: boolean\n /** Files collected from create_files calls */\n files?: GeneratedFile[]\n /** Question from ask_user calls */\n followUp?: string\n}\n\nexport interface ToolExecutorOptions {\n interactive?: boolean\n overwrite?: boolean\n dryRun?: boolean\n /** When set, noqta-tools (list_projects, create_task, etc.) become\n * available — the executor dispatches them by POSTing to\n * /api/agent/tools with the server-held bearer. The bearer NEVER\n * enters the model's prompt context. Omit to leave noqta-tools off\n * (the agent will see \"Unknown tool\" if it calls one anyway). */\n noqtaContext?: NoqtaToolContext\n /** Operator-cancel signal. When fired we short-circuit `execute()`\n * before dispatch and forward to execa as `cancelSignal` so a\n * hung shell command can't outlive the abort. */\n abortSignal?: AbortSignal\n}\n\nexport class ToolExecutor {\n private cwd: string\n private options: ToolExecutorOptions\n\n constructor(cwd: string, options: ToolExecutorOptions = {}) {\n this.cwd = cwd\n this.options = options\n }\n\n async execute(call: ToolCallInput): Promise<ToolResult> {\n debug.context(\"tool-executor\", `executing: ${call.name}`)\n\n if (this.options.abortSignal?.aborted) {\n return {\n tool_use_id: call.id,\n content: \"Task cancelled before tool dispatch.\",\n is_error: true,\n }\n }\n\n // pre:tool-call hook\n if (globalHooks.has(\"pre:tool-call\")) {\n const hookResult = await globalHooks.execute(\"pre:tool-call\", {\n event: \"pre:tool-call\" as any,\n toolName: call.name,\n toolInput: call.input,\n cwd: this.cwd,\n })\n if (hookResult.blocked) {\n return {\n tool_use_id: call.id,\n content: hookResult.message || `Tool ${call.name} blocked by pre:tool-call hook`,\n is_error: true,\n }\n }\n }\n\n let result: ToolResult\n\n try {\n // noqta-tools dispatch first — if the call name belongs to the\n // noqta catalog AND a noqtaContext is configured, run it via the\n // server-side HTTP dispatcher. Without context we fall through to\n // the \"unknown tool\" branch so the agent gets a clear error.\n if (this.options.noqtaContext && isNoqtaTool(call.name)) {\n const res = await executeNoqtaTool(call.name, call.input, this.options.noqtaContext)\n result = {\n tool_use_id: call.id,\n content: res.content,\n is_error: res.is_error,\n }\n } else {\n switch (call.name) {\n case \"read_file\":\n result = await this.readFile(call)\n break\n case \"search_files\":\n result = await this.searchFiles(call)\n break\n case \"list_directory\":\n result = await this.listDirectory(call)\n break\n case \"run_command\":\n result = await this.runCommand(call)\n break\n case \"edit_file\":\n result = await this.editFile(call)\n break\n case \"create_files\":\n result = await this.createFiles(call)\n break\n case \"ask_user\":\n result = await this.askUser(call)\n break\n case \"spawn_agent\":\n result = await this.spawnAgent(call)\n break\n default:\n result = {\n tool_use_id: call.id,\n content: `Unknown tool: ${call.name}`,\n is_error: true,\n }\n }\n }\n } catch (error: any) {\n result = {\n tool_use_id: call.id,\n content: `Error executing ${call.name}: ${error.message}`,\n is_error: true,\n }\n }\n\n // post:tool-call hook\n if (globalHooks.has(\"post:tool-call\")) {\n await globalHooks.execute(\"post:tool-call\", {\n event: \"post:tool-call\" as any,\n toolName: call.name,\n toolInput: call.input,\n toolResult: result.content,\n cwd: this.cwd,\n })\n }\n\n return result\n }\n\n private async readFile(call: ToolCallInput): Promise<ToolResult> {\n const filePath = String(call.input.path || \"\")\n const maxLines = Number(call.input.max_lines) || 500\n const absPath = path.resolve(this.cwd, filePath)\n\n const content = await fs.readFile(absPath, \"utf8\")\n const lines = content.split(\"\\n\")\n const truncated = lines.length > maxLines\n const output = truncated\n ? lines.slice(0, maxLines).join(\"\\n\") + `\\n\\n... (truncated, ${lines.length - maxLines} more lines)`\n : content\n\n return {\n tool_use_id: call.id,\n content: output,\n }\n }\n\n private async searchFiles(call: ToolCallInput): Promise<ToolResult> {\n const pattern = String(call.input.pattern || \"**/*\")\n const contentRegex = call.input.content_regex ? String(call.input.content_regex) : undefined\n const maxResults = Number(call.input.max_results) || 50\n\n const files = await fg(pattern, {\n cwd: this.cwd,\n ignore: [\"node_modules/**\", \".git/**\", \"dist/**\", \".next/**\"],\n dot: false,\n })\n\n if (!contentRegex) {\n const limited = files.slice(0, maxResults)\n return {\n tool_use_id: call.id,\n content: limited.length\n ? limited.join(\"\\n\") + (files.length > maxResults ? `\\n\\n... (${files.length - maxResults} more files)` : \"\")\n : \"No files matched the pattern.\",\n }\n }\n\n // Search content within matched files\n const regex = new RegExp(contentRegex, \"gm\")\n const results: string[] = []\n\n for (const file of files) {\n if (results.length >= maxResults) break\n try {\n const content = await fs.readFile(path.resolve(this.cwd, file), \"utf8\")\n const lines = content.split(\"\\n\")\n for (let i = 0; i < lines.length; i++) {\n if (results.length >= maxResults) break\n if (regex.test(lines[i])) {\n results.push(`${file}:${i + 1}: ${lines[i]}`)\n }\n regex.lastIndex = 0\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n return {\n tool_use_id: call.id,\n content: results.length\n ? results.join(\"\\n\")\n : \"No matches found.\",\n }\n }\n\n private async listDirectory(call: ToolCallInput): Promise<ToolResult> {\n const dirPath = String(call.input.path || \".\")\n const recursive = Boolean(call.input.recursive)\n const maxDepth = Number(call.input.max_depth) || 3\n const absPath = path.resolve(this.cwd, dirPath)\n\n if (recursive) {\n const pattern = \"**/*\"\n const entries = await fg(pattern, {\n cwd: absPath,\n onlyFiles: false,\n markDirectories: true,\n deep: maxDepth,\n ignore: [\"node_modules/**\", \".git/**\", \"dist/**\", \".next/**\"],\n })\n return {\n tool_use_id: call.id,\n content: entries.length ? entries.join(\"\\n\") : \"Empty directory.\",\n }\n }\n\n const entries = await fs.readdir(absPath, { withFileTypes: true })\n const formatted = entries.map((e) =>\n e.isDirectory() ? `${e.name}/` : e.name\n )\n\n return {\n tool_use_id: call.id,\n content: formatted.length ? formatted.join(\"\\n\") : \"Empty directory.\",\n }\n }\n\n private async runCommand(call: ToolCallInput): Promise<ToolResult> {\n const command = String(call.input.command || \"\")\n const timeout = Number(call.input.timeout) || 30_000\n\n // Check permissions\n const permission = await globalPermissions.checkCommand(command)\n if (permission === \"deny\") {\n return {\n tool_use_id: call.id,\n content: `Command blocked by permissions (mode: ${globalPermissions.getMode()}): ${command}`,\n is_error: true,\n }\n }\n\n // pre:command hook\n if (globalHooks.has(\"pre:command\")) {\n const hookResult = await globalHooks.execute(\"pre:command\", {\n event: \"pre:command\",\n command,\n cwd: this.cwd,\n })\n if (hookResult.blocked) {\n return {\n tool_use_id: call.id,\n content: hookResult.message || `Command blocked by pre:command hook: ${command}`,\n is_error: true,\n }\n }\n }\n\n const result = await execa(\"sh\", [\"-c\", command], {\n cwd: this.cwd,\n timeout,\n reject: false,\n stdin: \"ignore\",\n signal: this.options.abortSignal,\n })\n\n const output = [result.stdout, result.stderr].filter(Boolean).join(\"\\n\")\n const truncated = output.length > 10_000\n ? output.slice(0, 10_000) + \"\\n\\n... (output truncated)\"\n : output\n\n if (result.exitCode !== 0) {\n return {\n tool_use_id: call.id,\n content: `Command exited with code ${result.exitCode}:\\n${truncated}`,\n is_error: true,\n }\n }\n\n return {\n tool_use_id: call.id,\n content: truncated || \"(no output)\",\n }\n }\n\n private async editFile(call: ToolCallInput): Promise<ToolResult> {\n const filePath = String(call.input.path || \"\")\n const edits = call.input.edits as Array<{ old_text: string; new_text: string }> | undefined\n const absPath = path.resolve(this.cwd, filePath)\n\n if (!edits || edits.length === 0) {\n return {\n tool_use_id: call.id,\n content: \"No edits provided.\",\n is_error: true,\n }\n }\n\n // Check write permission\n const permission = await globalPermissions.checkFileWrite(filePath)\n if (permission === \"deny\") {\n return {\n tool_use_id: call.id,\n content: `File write blocked by permissions: ${filePath}`,\n is_error: true,\n }\n }\n if (permission === \"skip\") {\n return {\n tool_use_id: call.id,\n content: `File write skipped (plan mode): ${filePath}`,\n }\n }\n\n // pre:file-write hook\n if (globalHooks.has(\"pre:file-write\")) {\n const hookResult = await globalHooks.execute(\"pre:file-write\", {\n event: \"pre:file-write\",\n file: absPath,\n cwd: this.cwd,\n })\n if (hookResult.blocked) {\n return {\n tool_use_id: call.id,\n content: hookResult.message || `File edit blocked by pre:file-write hook: ${filePath}`,\n is_error: true,\n }\n }\n }\n\n let content = await fs.readFile(absPath, \"utf8\")\n const applied: string[] = []\n\n for (const edit of edits) {\n if (content.includes(edit.old_text)) {\n content = content.replace(edit.old_text, edit.new_text)\n applied.push(`Replaced: \"${edit.old_text.slice(0, 40)}...\"`)\n } else {\n applied.push(`Not found: \"${edit.old_text.slice(0, 40)}...\"`)\n }\n }\n\n if (!this.options.dryRun) {\n await fs.writeFile(absPath, content, \"utf8\")\n }\n\n // post:file-write hook\n if (globalHooks.has(\"post:file-write\")) {\n await globalHooks.execute(\"post:file-write\", {\n event: \"post:file-write\",\n file: absPath,\n fileContent: content,\n cwd: this.cwd,\n })\n }\n\n return {\n tool_use_id: call.id,\n content: `Edited ${filePath}:\\n${applied.join(\"\\n\")}`,\n }\n }\n\n private async createFiles(call: ToolCallInput): Promise<ToolResult> {\n const input = call.input as {\n files?: GeneratedFile[]\n summary?: string\n }\n\n const files = input.files || []\n\n return {\n tool_use_id: call.id,\n content: input.summary || `Queued ${files.length} file(s) for creation.`,\n files,\n }\n }\n\n private async spawnAgent(call: ToolCallInput): Promise<ToolResult> {\n const agentId = String(call.input.agent_id || \"\")\n const prompt = String(call.input.prompt || \"\")\n const timeoutSeconds = Number(call.input.timeout_seconds) || 300\n\n if (!agentId || !prompt) {\n return {\n tool_use_id: call.id,\n content: \"agent_id and prompt are required.\",\n is_error: true,\n }\n }\n\n try {\n // Dynamically import to avoid circular dependency\n const { SubAgentManager } = await import(\"@/agents/subagent\")\n\n // Get the global registry from the daemon (if running)\n const { getGlobalRegistry } = await import(\"@/agents/registry\")\n const registry = getGlobalRegistry()\n\n if (!registry) {\n return {\n tool_use_id: call.id,\n content: \"Sub-agent spawning requires the daemon to be running.\",\n is_error: true,\n }\n }\n\n const manager = new SubAgentManager(registry)\n const result = await manager.spawn({\n targetAgentId: agentId,\n prompt,\n parentAgentId: \"orchestrator\",\n timeout: timeoutSeconds * 1000,\n })\n\n if (result.success) {\n return {\n tool_use_id: call.id,\n content: `Sub-agent \"${agentId}\" completed (${Math.round(result.duration / 1000)}s):\\n\\n${result.content}`,\n }\n } else {\n return {\n tool_use_id: call.id,\n content: `Sub-agent \"${agentId}\" failed: ${result.error}`,\n is_error: true,\n }\n }\n } catch (error: any) {\n return {\n tool_use_id: call.id,\n content: `Failed to spawn sub-agent: ${error.message}`,\n is_error: true,\n }\n }\n }\n\n private async askUser(call: ToolCallInput): Promise<ToolResult> {\n const question = String(call.input.question || \"\")\n const options = call.input.options as string[] | undefined\n\n let followUp = question\n if (options?.length) {\n followUp += `\\nOptions: ${options.join(\", \")}`\n }\n\n return {\n tool_use_id: call.id,\n content: \"Question sent to user.\",\n followUp,\n }\n }\n}\n","// --- noqta.tn workspace tools (registered with the agentic loop) ---\n//\n// When an agent runs on behalf of a noqta.tn user (e.g. the noqta-public\n// agent serving the on-site chat / voice path), we expose 7 server-side\n// primitives as native Anthropic tools the model can call. The agentic\n// loop dispatches them by POSTing to {NOQTA_API_URL}/api/agent/tools\n// with the server-held AGENTX_TOOLS_SECRET — the bearer NEVER enters\n// the model's prompt context.\n//\n// The catalog mirrors the noqta.tn-side dispatcher in\n// app/api/agent/tools/route.ts. Schemas must match — the agent will be\n// confused if a field exists here but not there (or vice-versa).\n\nimport type { ToolDefinition } from \"./definitions\"\n\nexport const NOQTA_TOOL_NAMES = [\n \"list_projects\",\n \"get_project\",\n \"create_task\",\n \"update_task\",\n \"add_deliverable\",\n \"list_attachments\",\n \"get_credit_balance\",\n] as const\n\nexport type NoqtaToolName = typeof NOQTA_TOOL_NAMES[number]\n\nexport const NOQTA_TOOLS: ToolDefinition[] = [\n {\n name: \"list_projects\",\n description:\n \"List the noqta.tn user's active projects with per-project task counts. Use when the user asks 'what am I working on' or wants a project overview.\",\n input_schema: { type: \"object\", properties: {}, additionalProperties: false },\n permission: \"none\",\n },\n {\n name: \"get_project\",\n description:\n \"Get a single project with its tasks and recent conversations. Use after list_projects when the user picks one.\",\n input_schema: {\n type: \"object\",\n properties: {\n project_id: { type: \"string\", description: \"Project UUID from list_projects.\" },\n },\n required: [\"project_id\"],\n additionalProperties: false,\n },\n permission: \"none\",\n },\n {\n name: \"create_task\",\n description:\n \"Queue a new task for the user. Use when they ask you to build, fix, or work on something. CONFIRM the summary verbally first.\",\n input_schema: {\n type: \"object\",\n properties: {\n summary: { type: \"string\", description: \"Short task description (one sentence).\" },\n project_id: { type: \"string\", description: \"Optional — bind to a project.\" },\n conversation_id: {\n type: \"string\",\n description: \"Optional — bind to the on-site conversation id (from [Context]).\",\n },\n },\n required: [\"summary\"],\n additionalProperties: false,\n },\n permission: \"none\",\n },\n {\n name: \"update_task\",\n description:\n \"Update a task's state (mark completed, cancel, record hours, write a result_summary). Status: queued|active|completed|cancelled.\",\n input_schema: {\n type: \"object\",\n properties: {\n task_id: { type: \"string\" },\n status: {\n type: \"string\",\n enum: [\"queued\", \"active\", \"completed\", \"cancelled\"],\n },\n summary: { type: \"string\" },\n result_summary: { type: \"string\" },\n hours_spent: { type: \"number\" },\n },\n required: [\"task_id\"],\n additionalProperties: false,\n },\n permission: \"none\",\n },\n {\n name: \"add_deliverable\",\n description:\n \"Record a shipped artefact against a task (repo URL, preview URL, design file, document, etc.). type: repo|preview|design|artifact|document|screenshot|figma|spreadsheet|presentation|video|audio|image|other.\",\n input_schema: {\n type: \"object\",\n properties: {\n task_id: { type: \"string\" },\n type: {\n type: \"string\",\n enum: [\n \"repo\", \"preview\", \"design\", \"artifact\", \"document\", \"screenshot\",\n \"figma\", \"spreadsheet\", \"presentation\", \"video\", \"audio\", \"image\", \"other\",\n ],\n },\n label: { type: \"string\", description: \"Human label, e.g. 'Staging — workspace v2'.\" },\n url: { type: \"string\", description: \"Public URL of the artefact.\" },\n file_size: { type: \"number\" },\n },\n required: [\"task_id\", \"type\", \"label\", \"url\"],\n additionalProperties: false,\n },\n permission: \"none\",\n },\n {\n name: \"list_attachments\",\n description:\n \"List files the user has uploaded to the workspace. Filter by project_id and/or task_id.\",\n input_schema: {\n type: \"object\",\n properties: {\n project_id: { type: \"string\" },\n task_id: { type: \"string\" },\n },\n additionalProperties: false,\n },\n permission: \"none\",\n },\n {\n name: \"get_credit_balance\",\n description:\n \"Get the user's live credit balance and 7-day burn rate. Use when the user asks 'how much do I have left' or before starting a big task.\",\n input_schema: { type: \"object\", properties: {}, additionalProperties: false },\n permission: \"none\",\n },\n]\n\nexport interface NoqtaToolContext {\n /** The noqta.tn user UUID this tool call impersonates. */\n userId: string\n /** Logical agent id (for the audit table's X-Agent-Id column). */\n agentId?: string\n /** Override the noqta.tn base URL — defaults to NOQTA_API_URL env or https://noqta.tn. */\n apiUrl?: string\n}\n\n/**\n * Execute a noqta-tool by POSTing to /api/agent/tools with the server-\n * held bearer. The bearer is read from env at call time (not embedded\n * in prompts). Returns the raw response body as a string for the\n * agentic loop's tool_result block.\n */\nexport async function executeNoqtaTool(\n toolName: NoqtaToolName | string,\n input: Record<string, unknown>,\n ctx: NoqtaToolContext,\n): Promise<{ content: string; is_error: boolean }> {\n const bearer =\n process.env.NOQTA_AGENT_TOOLS_SECRET ||\n process.env.AGENTX_TOOLS_SECRET ||\n process.env.TELEGRAM_BOT_API_SECRET\n if (!bearer) {\n return {\n content: JSON.stringify({ ok: false, error: \"NOQTA_AGENT_TOOLS_SECRET not set on this host\" }),\n is_error: true,\n }\n }\n const baseUrl = ctx.apiUrl || process.env.NOQTA_API_URL || \"https://noqta.tn\"\n const url = `${baseUrl.replace(/\\/$/, \"\")}/api/agent/tools`\n\n const body = { tool: toolName, user_id: ctx.userId, ...(input || {}) }\n\n // Hard timeout on the HTTP call. Without this, a slow or hung\n // /api/agent/tools response stalls the agentic loop indefinitely\n // (observed in prod: two voice turns stuck for 71+ min on the same\n // conversation before a manual daemon restart). 30s is generous for\n // a DB-backed RPC; the tool itself is supposed to be sub-second.\n // Tunable via NOQTA_TOOL_TIMEOUT_MS env.\n const timeoutMs = Number(process.env.NOQTA_TOOL_TIMEOUT_MS || 30_000)\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), timeoutMs)\n\n try {\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${bearer}`,\n \"X-Agent-Id\": ctx.agentId || \"noqta-public\",\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n })\n const text = await res.text()\n const MAX = 4 * 1024\n const trimmed = text.length > MAX ? text.slice(0, MAX) + \"…(truncated)\" : text\n if (!res.ok) {\n return { content: trimmed, is_error: true }\n }\n return { content: trimmed, is_error: false }\n } catch (err: any) {\n const aborted = err?.name === \"AbortError\"\n return {\n content: JSON.stringify({\n ok: false,\n error: aborted ? `noqta tool RPC timed out after ${timeoutMs}ms` : \"noqta tool RPC failed\",\n detail: err?.message || \"unknown\",\n }),\n is_error: true,\n }\n } finally {\n clearTimeout(timer)\n }\n}\n\nexport function isNoqtaTool(name: string): name is NoqtaToolName {\n return (NOQTA_TOOL_NAMES as readonly string[]).includes(name)\n}\n","// --- Agentic Orchestrator: tool_result feedback loop ---\n\nimport type {\n AgentProvider,\n GenerationMessage,\n GeneratedFile,\n ProviderOptions,\n AnthropicMessage,\n ContentBlock,\n RawGenerationResult,\n} from \"./providers/types\"\nimport { ToolExecutor, type ToolResult } from \"./tools\"\nimport { getAnthropicTools, formatToolsForSystemPrompt } from \"./tools\"\nimport { NOQTA_TOOLS, type NoqtaToolContext } from \"./tools/noqta\"\nimport type { McpTool, McpCallResult } from \"./mcp-client\"\nimport { debug } from \"@/observability\"\n\nexport interface AgenticLoopOptions {\n provider: AgentProvider\n systemPrompt: string\n messages: GenerationMessage[]\n providerOptions: ProviderOptions\n cwd: string\n maxIterations?: number\n enabledTools?: string[]\n interactive?: boolean\n overwrite?: boolean\n dryRun?: boolean\n onProgress?: (event: AgenticProgressEvent) => void\n /** When set, the noqta workspace tool catalog (list_projects,\n * create_task, …) becomes part of the agent's tool set and the\n * executor dispatches calls via /api/agent/tools using the server-\n * held bearer. The bearer NEVER enters the model's prompt context. */\n noqtaContext?: NoqtaToolContext\n /** Tools supplied by external MCP servers booted upstream\n * (see src/agent/mcp-client.ts). The loop merges these into the\n * catalog passed to provider.generateRaw and routes matching\n * tool_use blocks through `mcpDispatch` instead of the local\n * executor. */\n mcpTools?: McpTool[]\n mcpDispatch?: (name: string, input: Record<string, unknown>) => Promise<McpCallResult>\n /** Cancel signal. Forwarded into ProviderOptions so the provider's\n * fetch() actually closes when the operator hits Stop. */\n abortSignal?: AbortSignal\n}\n\nexport type AgenticProgressEvent =\n | { type: \"iteration_start\"; iteration: number }\n | { type: \"tool_call\"; name: string; id: string; input: Record<string, unknown> }\n | { type: \"tool_result\"; name: string; id: string; content: string; is_error?: boolean }\n | { type: \"text_delta\"; text: string }\n // Thinking-mode chunk (DeepSeek V4 `reasoning_content` / OpenAI o-series).\n // Distinct from text_delta so consumers can render with a different style\n // and so the final response content stays clean.\n | { type: \"thinking_delta\"; text: string }\n | { type: \"files_created\"; files: GeneratedFile[] }\n | { type: \"complete\"; iterations: number; totalTokens: number }\n\nexport interface AgenticResult {\n files: GeneratedFile[]\n content: string\n followUp?: string\n tokensUsed: number\n /** Split input/output token counts when the provider supplies them.\n * Kept separate from `tokensUsed` so callers that bill by direction\n * (input vs output have very different per-1M costs) don't have to\n * guess a 30/70 split. Undefined when the provider only reports a\n * combined total (CLI tier, legacy loop). */\n inputTokens?: number\n outputTokens?: number\n iterations: number\n}\n\n/**\n * Run the agentic tool_result loop.\n * The LLM decides what tools to call (read files, search, edit, etc.)\n * and we feed results back until it signals completion.\n */\nexport async function runAgenticLoop(options: AgenticLoopOptions): Promise<AgenticResult> {\n const {\n provider,\n systemPrompt,\n messages: inputMessages,\n providerOptions: providerOptionsRaw,\n cwd,\n maxIterations = 20,\n enabledTools,\n interactive = true,\n overwrite = false,\n dryRun = false,\n onProgress,\n abortSignal,\n } = options\n // Fold the abort signal into ProviderOptions so each iteration's\n // provider call (fetch under the hood) gets it. Without this, an\n // operator Stop only flags the task in the registry — the in-flight\n // HTTP request to DeepSeek/OpenAI keeps running until the model\n // decides to finish, which has produced multi-hour hangs.\n const providerOptions: ProviderOptions = abortSignal\n ? { ...providerOptionsRaw, abortSignal }\n : providerOptionsRaw\n\n // Check if provider supports generateRaw\n if (!provider.generateRaw) {\n return runLegacyLoop(options)\n }\n\n const executor = new ToolExecutor(cwd, {\n interactive,\n overwrite,\n dryRun,\n noqtaContext: options.noqtaContext,\n abortSignal,\n })\n const tools = getAnthropicTools(enabledTools)\n // Append noqta workspace tools only when we have a noqta user context\n // to dispatch them against. Adding them otherwise would confuse the\n // model (it'd see tools it can't successfully invoke).\n if (options.noqtaContext) {\n for (const t of NOQTA_TOOLS) {\n tools.push({ name: t.name, description: t.description, input_schema: t.input_schema })\n }\n }\n // MCP tools — booted by the caller (executeOrchestrator) so the loop\n // doesn't need to know about agent definitions or .mcp.json. Routed\n // via options.mcpDispatch in the tool_use branch below.\n const mcpToolNames = new Set<string>()\n if (options.mcpTools?.length) {\n for (const t of options.mcpTools) {\n tools.push({ name: t.name, description: t.description, input_schema: t.input_schema })\n mcpToolNames.add(t.name)\n }\n }\n\n // Convert GenerationMessage[] to AnthropicMessage[] (strip system messages)\n const anthropicMessages: AnthropicMessage[] = inputMessages\n .filter((m) => m.role !== \"system\")\n .map((m) => ({\n role: m.role as \"user\" | \"assistant\",\n content: m.content,\n }))\n\n const allFiles: GeneratedFile[] = []\n let totalTokens = 0\n let totalInputTokens = 0\n let totalOutputTokens = 0\n let textContent = \"\"\n let followUp: string | undefined\n let iteration = 0\n\n while (iteration < maxIterations) {\n iteration++\n // Operator-cancel check between iterations — bails before we\n // pay for another provider round-trip.\n if (abortSignal?.aborted) {\n throw new Error(\"cancelled\")\n }\n onProgress?.({ type: \"iteration_start\", iteration })\n debug.step(iteration, `Agentic loop iteration (${tools.length} tools available)`)\n\n // Streaming path: when the provider supports generateRawStream AND a\n // caller is listening for progress events, pipe text deltas through\n // as they arrive (so voice/SSE clients see per-token output) and\n // still assemble the same RawGenerationResult the non-streaming\n // path produces. Tool detection then runs unchanged on result.content.\n //\n // The fallback (generateRaw, single-shot) is preserved for:\n // - providers without generateRawStream (CLI, anything pre-stream)\n // - non-streaming callers (no onProgress) — extra streaming\n // ceremony would add latency and per-chunk parsing overhead\n // for callers that don't need it (telegram, crons, mesh).\n let result: RawGenerationResult\n const useRawStream = !!provider.generateRawStream && !!onProgress\n try {\n if (useRawStream) {\n // We accumulate text per-block as it streams. The raw_result\n // event at the end carries the same blocks (with tool_use\n // inputs fully parsed) so the existing tool-dispatch branch\n // below operates on identical data to the non-streaming case.\n let streamedResult: RawGenerationResult | null = null\n let streamError: string | null = null\n let streamedTextThisIteration = \"\"\n for await (const ev of provider.generateRawStream!(\n anthropicMessages,\n systemPrompt,\n tools,\n providerOptions,\n )) {\n if (ev.type === \"text_delta\") {\n streamedTextThisIteration += ev.text\n // Emit per-chunk so the caller (daemon /chat handler ->\n // SSE writer) can push to the client right away. We do NOT\n // emit a duplicate text_delta from the result-block loop\n // below for streamed text (handled via the `streamedText`\n // guard on each text block).\n onProgress?.({ type: \"text_delta\", text: ev.text })\n } else if (ev.type === \"thinking_delta\") {\n // Forward the thinking chunk. It's not folded into\n // streamedTextThisIteration (or `content`) — the agent's\n // visible answer should stay clean — but the raw_result's\n // `reasoning` content block carries the full text for the\n // agentic round-trip.\n onProgress?.({ type: \"thinking_delta\", text: ev.text })\n } else if (ev.type === \"raw_result\") {\n streamedResult = ev.result\n } else if (ev.type === \"error\") {\n streamError = ev.error\n }\n }\n if (streamError && !streamedResult) {\n throw new Error(streamError)\n }\n if (!streamedResult) {\n throw new Error(\"generateRawStream returned no raw_result event\")\n }\n result = streamedResult\n // Track the text we already streamed so the block-loop below\n // doesn't re-emit it as a duplicate text_delta event.\n ;(result as any)._streamedText = streamedTextThisIteration\n } else {\n result = await provider.generateRaw!(\n anthropicMessages,\n systemPrompt,\n tools,\n providerOptions,\n )\n }\n } catch (error: any) {\n // If generateRaw fails (e.g., OAuth mode), fall back to legacy\n if (error.message?.includes(\"not available\")) {\n return runLegacyLoop(options)\n }\n throw error\n }\n\n totalTokens += result.usage.input_tokens + result.usage.output_tokens\n totalInputTokens += result.usage.input_tokens\n totalOutputTokens += result.usage.output_tokens\n\n // Collect text from response. In the streaming path we already\n // emitted per-chunk deltas above — only re-emit text from blocks\n // that came in AFTER our streamed accumulation (defensive: should\n // be zero, but a divergence wouldn't silently lose tokens).\n const streamedText: string | undefined = (result as any)._streamedText\n for (const block of result.content) {\n if (block.type === \"text\") {\n textContent += block.text\n if (streamedText === undefined) {\n // Non-streaming path — fire one text_delta per block as before.\n onProgress?.({ type: \"text_delta\", text: block.text })\n }\n }\n }\n if (streamedText !== undefined) delete (result as any)._streamedText\n\n // If stop_reason is end_turn or max_tokens, we're done\n if (result.stop_reason === \"end_turn\" || result.stop_reason === \"max_tokens\") {\n break\n }\n\n // If stop_reason is tool_use, execute the tools\n if (result.stop_reason === \"tool_use\") {\n const toolUseBlocks = result.content.filter(\n (b): b is Extract<ContentBlock, { type: \"tool_use\" }> => b.type === \"tool_use\"\n )\n\n if (toolUseBlocks.length === 0) break\n\n // Append assistant message with the tool_use blocks\n anthropicMessages.push({\n role: \"assistant\",\n content: result.content,\n })\n\n // Execute each tool and collect results\n const toolResults: ContentBlock[] = []\n\n for (const toolBlock of toolUseBlocks) {\n onProgress?.({\n type: \"tool_call\",\n name: toolBlock.name,\n id: toolBlock.id,\n input: toolBlock.input,\n })\n\n debug.step(iteration, `Tool call: ${toolBlock.name}`)\n\n let toolResult: ToolResult\n if (mcpToolNames.has(toolBlock.name) && options.mcpDispatch) {\n const r = await options.mcpDispatch(toolBlock.name, toolBlock.input)\n toolResult = {\n tool_use_id: toolBlock.id,\n content: r.content,\n is_error: r.isError,\n }\n } else {\n toolResult = await executor.execute({\n name: toolBlock.name,\n id: toolBlock.id,\n input: toolBlock.input,\n })\n }\n\n onProgress?.({\n type: \"tool_result\",\n name: toolBlock.name,\n id: toolBlock.id,\n content: toolResult.content.slice(0, 200),\n is_error: toolResult.is_error,\n })\n\n // Collect files from create_files calls\n if (toolResult.files?.length) {\n allFiles.push(...toolResult.files)\n onProgress?.({ type: \"files_created\", files: toolResult.files })\n }\n\n // Handle ask_user — surface the question to caller\n if (toolResult.followUp) {\n followUp = toolResult.followUp\n }\n\n toolResults.push({\n type: \"tool_result\",\n tool_use_id: toolResult.tool_use_id,\n content: toolResult.content,\n is_error: toolResult.is_error,\n })\n }\n\n // Append user message with tool_result blocks\n anthropicMessages.push({\n role: \"user\",\n content: toolResults,\n })\n\n // If we got a follow-up question, break the loop to surface it\n if (followUp) break\n\n continue\n }\n\n // Unknown stop_reason — break\n break\n }\n\n onProgress?.({ type: \"complete\", iterations: iteration, totalTokens })\n\n return {\n files: allFiles,\n content: textContent,\n followUp,\n tokensUsed: totalTokens,\n inputTokens: totalInputTokens || undefined,\n outputTokens: totalOutputTokens || undefined,\n iterations: iteration,\n }\n}\n\n/**\n * Fallback to the legacy [CONTINUE]-based multi-step loop.\n * Used when provider doesn't support generateRaw() (CLI/OAuth mode).\n * For CLI mode, we include tool descriptions in the system prompt so the\n * `claude` binary uses its own built-in tools (read, write, bash, etc.).\n */\nasync function runLegacyLoop(options: AgenticLoopOptions): Promise<AgenticResult> {\n const {\n provider,\n systemPrompt,\n messages: inputMessages,\n providerOptions,\n maxIterations = 5,\n } = options\n\n // Enhance system prompt with tool descriptions for CLI mode\n const enhancedSystemPrompt = systemPrompt + \"\\n\\n\" + formatToolsForSystemPrompt()\n\n const messages: GenerationMessage[] = [\n { role: \"system\", content: enhancedSystemPrompt },\n ...inputMessages.filter((m) => m.role !== \"system\"),\n ]\n\n const allFiles: GeneratedFile[] = []\n let totalTokens = 0\n let content = \"\"\n let followUp: string | undefined\n let step = 0\n\n while (step < maxIterations) {\n step++\n debug.step(step, `Legacy loop step (model: ${providerOptions.model || \"default\"})`)\n\n const result = await provider.generate(messages, providerOptions)\n\n totalTokens += result.tokensUsed || 0\n content = result.content\n\n if (result.files.length) {\n allFiles.push(...result.files)\n }\n\n if (result.followUp) {\n followUp = result.followUp\n break\n }\n\n if (result.files.length === 0 && step > 1) break\n\n const wantsContinuation =\n result.content.includes(\"[CONTINUE]\") ||\n result.content.includes(\"Next, I'll\") ||\n result.content.includes(\"Now let me\") ||\n result.content.includes(\"I'll also generate\")\n\n if (!wantsContinuation) break\n\n const filesSummary = result.files\n .map((f) => `Created: ${f.path}${f.description ? ` — ${f.description}` : \"\"}`)\n .join(\"\\n\")\n\n messages.push({\n role: \"assistant\",\n content: result.content + (filesSummary ? `\\n\\nFiles created:\\n${filesSummary}` : \"\"),\n })\n\n messages.push({\n role: \"user\",\n content:\n \"Continue generating the remaining files. Build on what you've already created. When finished, do not include [CONTINUE] in your response.\",\n })\n }\n\n return {\n files: allFiles,\n content,\n followUp,\n tokensUsed: totalTokens,\n iterations: step,\n }\n}\n\n/**\n * Check if a provider supports the agentic loop (has generateRaw).\n */\nexport function supportsAgenticLoop(provider: AgentProvider): boolean {\n return typeof provider.generateRaw === \"function\"\n}\n","// --- MCP client + pool for the orchestrator tier ---\n//\n// CLI-backed tiers (claude-code, codex-cli) read <workspace>/.mcp.json\n// natively, so the daemon's agent-mcp.ts sync is enough for them. The\n// orchestrator tier runs agentx's own agentic loop against a provider\n// (Claude / OpenAI / DeepSeek / Ollama / custom), and that loop has its\n// own hand-rolled tool catalog (read_file, run_command, …) — MCP servers\n// declared in agentx.json were dead weight for those agents until now.\n//\n// This module connects to each declared MCP server (stdio child or\n// HTTP+SSE endpoint), lists its tools, namespaces them as\n// `mcp__<server>__<tool>`, and exposes a dispatcher. The orchestrator\n// merges the tool list into the catalog passed to provider.generateRaw()\n// and routes matching tool_use blocks back through dispatch().\n\nimport { spawn, type ChildProcess } from \"child_process\"\nimport { debug } from \"@/observability\"\n\n/** stdio MCP server — spawned as a child process, JSON-RPC over NDJSON\n * on stdin/stdout. The `type` field is optional for backward compat\n * with the original config shape (`{ command, args, env }`). */\nexport interface McpStdioSpec {\n type?: \"stdio\"\n command: string\n args?: string[]\n env?: Record<string, string>\n}\n\n/** HTTP MCP server (Streamable HTTP transport) — POST JSON-RPC bodies to\n * `url`, server may answer as `application/json` or stream as\n * `text/event-stream` (`data: <json>` lines). Optional `headers` get\n * merged into every request (auth tokens, tenancy hints, etc.). */\nexport interface McpHttpSpec {\n type: \"http\"\n url: string\n headers?: Record<string, string>\n}\n\nexport type McpServerSpec = McpStdioSpec | McpHttpSpec\n\nexport type McpServerMap = Record<string, McpServerSpec>\n\nexport interface McpTool {\n name: string\n description: string\n input_schema: Record<string, unknown>\n}\n\nexport interface McpCallResult {\n content: string\n isError?: boolean\n}\n\nconst PROTOCOL_VERSION = \"2024-11-05\"\nconst INIT_TIMEOUT_MS = 15_000\nconst CALL_TIMEOUT_MS = 120_000\nconst TOOL_PREFIX = \"mcp__\"\n\nfunction isHttpSpec(spec: McpServerSpec): spec is McpHttpSpec {\n return (spec as McpHttpSpec).type === \"http\"\n}\n\ninterface Transport {\n /** Issue a JSON-RPC request and resolve with the `result` payload. */\n request(method: string, params: Record<string, unknown>, timeoutMs: number): Promise<unknown>\n /** Fire a JSON-RPC notification (no id, no response expected). */\n notify(method: string, params?: Record<string, unknown>): void\n /** Release transport resources. Safe to call multiple times. */\n close(): void\n}\n\nclass StdioTransport implements Transport {\n private proc: ChildProcess\n private buffer = \"\"\n private nextId = 1\n private pending = new Map<\n number,\n { resolve: (v: unknown) => void; reject: (e: Error) => void; timer: NodeJS.Timeout }\n >()\n private closed = false\n\n constructor(private readonly name: string, spec: McpStdioSpec) {\n this.proc = spawn(spec.command, spec.args ?? [], {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: { ...process.env, ...(spec.env ?? {}) },\n })\n this.proc.stdout!.setEncoding(\"utf-8\")\n this.proc.stdout!.on(\"data\", (chunk: string) => this.onData(chunk))\n this.proc.stderr!.setEncoding(\"utf-8\")\n this.proc.stderr!.on(\"data\", (chunk: string) =>\n debug.context(\"mcp\", `${name} stderr: ${chunk.trimEnd()}`),\n )\n this.proc.on(\"exit\", (code) => {\n this.closed = true\n debug.context(\"mcp\", `${name}: exited (code=${code})`)\n for (const [, p] of this.pending) {\n clearTimeout(p.timer)\n p.reject(new Error(`mcp server \"${name}\" exited`))\n }\n this.pending.clear()\n })\n this.proc.on(\"error\", (e: Error) => {\n debug.context(\"mcp\", `${name}: spawn error: ${e.message}`)\n })\n }\n\n request(method: string, params: Record<string, unknown>, timeoutMs: number): Promise<unknown> {\n if (this.closed) return Promise.reject(new Error(`mcp server \"${this.name}\" is closed`))\n const id = this.nextId++\n const payload = JSON.stringify({ jsonrpc: \"2.0\", id, method, params }) + \"\\n\"\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(id)\n reject(new Error(`mcp \"${this.name}\" ${method} timeout after ${timeoutMs}ms`))\n }, timeoutMs)\n this.pending.set(id, { resolve, reject, timer })\n try {\n this.proc.stdin!.write(payload)\n } catch (e: any) {\n clearTimeout(timer)\n this.pending.delete(id)\n reject(new Error(`mcp \"${this.name}\" write failed: ${e.message}`))\n }\n })\n }\n\n notify(method: string, params?: Record<string, unknown>): void {\n if (this.closed) return\n const payload = JSON.stringify({ jsonrpc: \"2.0\", method, params: params ?? {} }) + \"\\n\"\n try {\n this.proc.stdin!.write(payload)\n } catch {\n /* */\n }\n }\n\n close(): void {\n if (this.closed) return\n this.closed = true\n try {\n this.proc.kill(\"SIGTERM\")\n } catch {\n /* */\n }\n }\n\n private onData(chunk: string): void {\n this.buffer += chunk\n while (true) {\n const nl = this.buffer.indexOf(\"\\n\")\n if (nl < 0) break\n const line = this.buffer.slice(0, nl).trim()\n this.buffer = this.buffer.slice(nl + 1)\n if (!line) continue\n let msg: any\n try {\n msg = JSON.parse(line)\n } catch (e: any) {\n debug.context(\"mcp\", `${this.name}: parse error: ${e.message} (line: ${line.slice(0, 200)})`)\n continue\n }\n if (typeof msg.id === \"number\" && this.pending.has(msg.id)) {\n const p = this.pending.get(msg.id)!\n this.pending.delete(msg.id)\n clearTimeout(p.timer)\n if (msg.error) p.reject(new Error(`${msg.error.code}: ${msg.error.message}`))\n else p.resolve(msg.result)\n }\n // server-initiated notifications/requests (logging, sampling) are\n // ignored — the orchestrator doesn't expose capabilities for them.\n }\n }\n}\n\nclass HttpTransport implements Transport {\n private nextId = 1\n private sessionId: string | null = null\n private closed = false\n\n constructor(private readonly name: string, private readonly spec: McpHttpSpec) {}\n\n async request(method: string, params: Record<string, unknown>, timeoutMs: number): Promise<unknown> {\n if (this.closed) throw new Error(`mcp server \"${this.name}\" is closed`)\n const id = this.nextId++\n const body = JSON.stringify({ jsonrpc: \"2.0\", id, method, params })\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n // The Streamable HTTP MCP spec lets servers answer either inline\n // JSON or via SSE; advertising both keeps us compatible with both\n // flavours (JORT-wiki uses SSE; some hosted MCPs return raw JSON).\n Accept: \"application/json, text/event-stream\",\n ...(this.spec.headers ?? {}),\n }\n // The MCP session-id handshake: server may return `mcp-session-id`\n // on the initialize response; we echo it back on every subsequent\n // call so the server can attach state (auth scope, conversation\n // history, etc.).\n if (this.sessionId) headers[\"Mcp-Session-Id\"] = this.sessionId\n\n const ctl = new AbortController()\n const timer = setTimeout(() => ctl.abort(new Error(`timeout after ${timeoutMs}ms`)), timeoutMs)\n ;(timer as any).unref?.()\n\n let res: Response\n try {\n res = await fetch(this.spec.url, {\n method: \"POST\",\n headers,\n body,\n signal: ctl.signal,\n })\n } catch (e: any) {\n clearTimeout(timer)\n if (e?.name === \"AbortError\") {\n throw new Error(`mcp \"${this.name}\" ${method} timeout after ${timeoutMs}ms`)\n }\n throw new Error(`mcp \"${this.name}\" ${method} fetch failed: ${e?.message ?? e}`)\n }\n\n // Capture the session id from initialize (and any later response\n // that re-issues it). Header lookup is case-insensitive.\n const newSession = res.headers.get(\"mcp-session-id\")\n if (newSession) this.sessionId = newSession\n\n if (!res.ok) {\n clearTimeout(timer)\n const errText = await res.text().catch(() => \"\")\n throw new Error(`mcp \"${this.name}\" HTTP ${res.status}: ${errText.slice(0, 300)}`)\n }\n\n const contentType = (res.headers.get(\"content-type\") || \"\").toLowerCase()\n let parsed: any\n try {\n if (contentType.includes(\"text/event-stream\")) {\n parsed = await parseSseEnvelope(res, id)\n } else {\n parsed = await res.json()\n }\n } catch (e: any) {\n clearTimeout(timer)\n throw new Error(`mcp \"${this.name}\" ${method} response parse failed: ${e?.message ?? e}`)\n } finally {\n clearTimeout(timer)\n }\n\n if (!parsed || typeof parsed !== \"object\") {\n throw new Error(`mcp \"${this.name}\" ${method} returned non-object body`)\n }\n if (parsed.error) {\n throw new Error(`${parsed.error.code}: ${parsed.error.message}`)\n }\n return parsed.result\n }\n\n notify(method: string, params?: Record<string, unknown>): void {\n if (this.closed) return\n // Notifications have no id and expect no response body. Server may\n // still 200 / 202; we don't care about the result. Fire-and-forget\n // so the caller (initialize → notifications/initialized) isn't\n // blocked on a round-trip the protocol doesn't require.\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json, text/event-stream\",\n ...(this.spec.headers ?? {}),\n }\n if (this.sessionId) headers[\"Mcp-Session-Id\"] = this.sessionId\n fetch(this.spec.url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ jsonrpc: \"2.0\", method, params: params ?? {} }),\n }).catch((e: any) => {\n debug.context(\"mcp\", `${this.name}: notify ${method} failed: ${e?.message ?? e}`)\n })\n }\n\n close(): void {\n if (this.closed) return\n this.closed = true\n // The Streamable HTTP MCP spec defines DELETE on the URL with the\n // session id to terminate. Fire-and-forget; the server may also\n // expire sessions on its own.\n if (this.sessionId) {\n const headers: Record<string, string> = {\n \"Mcp-Session-Id\": this.sessionId,\n ...(this.spec.headers ?? {}),\n }\n fetch(this.spec.url, { method: \"DELETE\", headers }).catch(() => { /* */ })\n }\n }\n}\n\n/** Read the SSE body, find the `data:` line whose JSON payload matches\n * `id`, and return that JSON-RPC envelope. Discards any other events\n * (server-initiated notifications, keep-alives, comment lines). */\nasync function parseSseEnvelope(res: Response, id: number): Promise<any> {\n const reader = res.body?.getReader()\n if (!reader) throw new Error(\"SSE response had no body\")\n const decoder = new TextDecoder()\n let buffer = \"\"\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n buffer += decoder.decode(value, { stream: true })\n // SSE messages are separated by blank lines. Within a message,\n // `data:` may appear multiple times — concatenate them.\n let sepIdx: number\n while ((sepIdx = buffer.indexOf(\"\\n\\n\")) >= 0) {\n const raw = buffer.slice(0, sepIdx)\n buffer = buffer.slice(sepIdx + 2)\n const dataLines: string[] = []\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.replace(/\\r$/, \"\")\n if (trimmed.startsWith(\"data:\")) dataLines.push(trimmed.slice(5).trim())\n }\n if (!dataLines.length) continue\n const dataStr = dataLines.join(\"\\n\")\n if (!dataStr || dataStr === \"[DONE]\") continue\n let payload: any\n try { payload = JSON.parse(dataStr) } catch { continue }\n // Match by request id; ignore unrelated notifications.\n if (payload && payload.id === id) return payload\n }\n }\n } finally {\n try { reader.cancel().catch(() => { /* */ }) } catch { /* */ }\n }\n throw new Error(`SSE stream ended without a response for id=${id}`)\n}\n\nexport class McpClient {\n private transport: Transport\n\n constructor(public readonly name: string, spec: McpServerSpec) {\n this.transport = isHttpSpec(spec)\n ? new HttpTransport(name, spec)\n : new StdioTransport(name, spec)\n }\n\n async initialize(): Promise<void> {\n await this.transport.request(\n \"initialize\",\n {\n protocolVersion: PROTOCOL_VERSION,\n capabilities: {},\n clientInfo: { name: \"agentx-orchestrator\", version: \"0.1.0\" },\n },\n INIT_TIMEOUT_MS,\n )\n this.transport.notify(\"notifications/initialized\")\n }\n\n async listTools(): Promise<McpTool[]> {\n const result = (await this.transport.request(\"tools/list\", {}, INIT_TIMEOUT_MS)) as {\n tools?: Array<{ name: string; description?: string; inputSchema?: Record<string, unknown> }>\n }\n return (result.tools ?? []).map((t) => ({\n name: t.name,\n description: t.description ?? \"\",\n input_schema: t.inputSchema ?? { type: \"object\", properties: {} },\n }))\n }\n\n async callTool(name: string, args: Record<string, unknown>): Promise<McpCallResult> {\n const result = (await this.transport.request(\n \"tools/call\",\n { name, arguments: args ?? {} },\n CALL_TIMEOUT_MS,\n )) as { content?: Array<{ type: string; text?: string }>; isError?: boolean }\n // MCP tool results are a content array; flatten text blocks and JSON\n // any non-text blocks so the model sees something meaningful.\n const parts: string[] = []\n for (const block of result.content ?? []) {\n if (block?.type === \"text\" && typeof block.text === \"string\") parts.push(block.text)\n else parts.push(JSON.stringify(block))\n }\n return { content: parts.join(\"\\n\") || \"(no output)\", isError: result.isError }\n }\n\n close(): void {\n this.transport.close()\n }\n}\n\nexport interface McpPool {\n /** Namespaced tools (`mcp__<server>__<tool>`) ready to merge into the\n * agentic catalog passed to provider.generateRaw(). */\n tools: McpTool[]\n /** Resolve a namespaced tool name back to the right client and remote\n * tool name. Returns an error envelope when the name is unknown. */\n dispatch(name: string, input: Record<string, unknown>): Promise<McpCallResult>\n close(): void\n}\n\n/** Boot each declared server, list its tools, and return a pool that\n * the orchestrator can drop into runAgenticLoop. A server that fails\n * to initialize is dropped from the catalog (with a debug log) so one\n * broken entry can't disable the whole tier. */\nexport async function startMcpPool(servers: McpServerMap): Promise<McpPool> {\n const clients = new Map<string, McpClient>()\n const tools: McpTool[] = []\n const router = new Map<string, { client: McpClient; remote: string }>()\n\n for (const [serverName, spec] of Object.entries(servers)) {\n const client = new McpClient(serverName, spec)\n try {\n await client.initialize()\n const remoteTools = await client.listTools()\n for (const t of remoteTools) {\n const namespaced = `${TOOL_PREFIX}${serverName}__${t.name}`\n tools.push({\n name: namespaced,\n description: t.description || `${serverName}.${t.name}`,\n input_schema: t.input_schema,\n })\n router.set(namespaced, { client, remote: t.name })\n }\n clients.set(serverName, client)\n } catch (e: any) {\n debug.context(\"mcp\", `${serverName}: skipped — ${e.message}`)\n client.close()\n }\n }\n\n return {\n tools,\n async dispatch(name, input) {\n const route = router.get(name)\n if (!route) return { content: `Unknown MCP tool: ${name}`, isError: true }\n try {\n return await route.client.callTool(route.remote, input)\n } catch (e: any) {\n return { content: `MCP call failed: ${e.message}`, isError: true }\n }\n },\n close() {\n for (const c of clients.values()) c.close()\n },\n }\n}\n\nexport function isMcpToolName(name: string): boolean {\n return name.startsWith(TOOL_PREFIX)\n}\n","export class AsyncQueue<T> {\n private queue: T[] = []\n private resolvers: Array<(value: IteratorResult<T>) => void> = []\n private closed = false\n\n push(item: T): void {\n if (this.closed) return\n\n const resolver = this.resolvers.shift()\n if (resolver) {\n resolver({ value: item, done: false })\n return\n }\n this.queue.push(item)\n }\n\n close(): void {\n if (this.closed) return\n this.closed = true\n for (const resolve of this.resolvers.splice(0)) {\n resolve({ value: undefined as any, done: true })\n }\n }\n\n async next(): Promise<IteratorResult<T>> {\n if (this.queue.length) {\n return { value: this.queue.shift() as T, done: false }\n }\n if (this.closed) {\n return { value: undefined as any, done: true }\n }\n return new Promise<IteratorResult<T>>((resolve) => {\n this.resolvers.push(resolve)\n })\n }\n\n async *[Symbol.asyncIterator](): AsyncGenerator<T> {\n while (true) {\n const { value, done } = await this.next()\n if (done) return\n yield value\n }\n }\n}\n\n","import type { AgentProvider, GenerationMessage, GenerationResult, OutputType, StreamEvent } from \"./providers/types\"\nimport { agentConfigSchema, type AgentConfig } from \"./providers/types\"\nimport { createProvider, type ProviderName } from \"./providers\"\nimport { loadAuthConfig } from \"@/utils/auth-store\"\nimport { ensureCredentials } from \"@/utils/auth-store\"\nimport { detectTechStack, formatTechStack, type TechStack } from \"./context/tech-stack\"\nimport { detectSchemas, formatSchemas, type ProjectSchemas } from \"./context/schema\"\nimport { gatherContext7Docs } from \"./context/context7\"\nimport { loadLocalSkills, matchSkillsToTask } from \"./skills/loader\"\nimport { resolveOutputType } from \"./outputs/types\"\nimport { writeGeneratedFiles, resolveOutputDir, type WriteOptions, type WriteResult } from \"./outputs/handlers\"\nimport { logger } from \"@/utils/logger\"\nimport { globalHooks } from \"@/hooks\"\nimport { globalTracker } from \"@/observability\"\nimport { debug } from \"@/observability\"\nimport { MemoryHierarchy, ContextBuilder, loadProjectInstructions } from \"@/memory\"\nimport type { Skill } from \"./skills/types\"\nimport { runAgenticLoop, supportsAgenticLoop, type AgenticProgressEvent } from \"./orchestrator\"\nimport { startMcpPool, type McpPool, type McpServerMap } from \"./mcp-client\"\nimport { AsyncQueue } from \"@/utils/async-queue\"\n\n// --- Agent Orchestrator: the brain that coordinates everything ---\n\nexport interface AgentContext {\n techStack: TechStack\n schemas: ProjectSchemas\n skills: Skill[]\n docs: string\n config: AgentConfig\n memoryContext: string\n projectInstructions: string\n}\n\nexport interface GenerateOptions {\n task: string\n outputType?: OutputType\n outputDir?: string\n overwrite?: boolean\n dryRun?: boolean\n provider?: ProviderName\n model?: string\n apiKey?: string\n cwd: string\n context7?: boolean\n interactive?: boolean\n skills?: string[] // Additional skill packages to load\n maxSteps?: number // Max agentic loop iterations (default 20 for agentic, 5 for legacy)\n sessionMessages?: GenerationMessage[] // Multi-turn context from REPL sessions\n heal?: boolean // undefined = auto (heal if files written), false = skip\n healConfig?: {\n testCommand?: string\n buildCommand?: string\n lintCommand?: string\n maxAttempts?: number\n }\n /** Enables the noqta workspace tool catalog (list_projects, create_task,\n * …) in the agentic loop and threads the user_id through to the\n * executor. Without this set, the noqta-tools are absent from the\n * agent's tool list — keeps non-noqta agents clean. The bearer is\n * read from env at dispatch time and NEVER enters the prompt. */\n noqtaContext?: import(\"./tools/noqta\").NoqtaToolContext\n /** Provider-level options forwarded to `createProvider`. Today only\n * `thinking` (for DeepSeek thinking-mode). Wired from\n * `providers.<name>.thinking` in agentx.json by the daemon's\n * orchestrator-tier dispatch path. */\n providerOpts?: { thinking?: boolean }\n /** Operator-cancel signal. When the daemon's task-cancel API fires\n * the AbortController, runAgenticLoop forwards this into the\n * provider's fetch() so the in-flight HTTP call is actually\n * closed. Without this, /api/tasks/:id/cancel for orchestrator-\n * tier agents only marks the task `cancelled` in the registry\n * while the underlying DeepSeek request keeps running (seen in\n * production: 100+ minute hangs). */\n abortSignal?: AbortSignal\n /** External MCP servers to boot for this generation. Each entry is\n * spawned as a stdio child, its tools listed via tools/list, and\n * exposed to the agentic loop as `mcp__<server>__<tool>`. Wired\n * from `effectiveMcpConfig(agent)` by the orchestrator tier in\n * src/agents/runtime.ts — CLI-backed tiers (claude-code, codex-cli)\n * load their own `.mcp.json` natively and ignore this. */\n mcpServers?: McpServerMap\n}\n\nexport interface GenerateResult {\n files: WriteResult\n content: string\n outputType: OutputType\n followUp?: string\n tokensUsed?: number\n /** Split tokens when the provider supplies them (Claude raw mode does;\n * CLI mode and legacy fallbacks may not). Callers that bill by\n * direction should prefer these over a 30/70 estimate of tokensUsed. */\n inputTokens?: number\n outputTokens?: number\n healResult?: import(\"@/runtime/heal\").HealResult\n}\n\nexport async function createAgentContext(\n cwd: string,\n task: string,\n config?: Partial<AgentConfig>\n): Promise<AgentContext> {\n const agentConfig = agentConfigSchema.parse(config || {})\n\n // Load memory hierarchy\n const memory = new MemoryHierarchy(cwd)\n await memory.load()\n\n // Gather all context in parallel\n const [techStack, schemas, skills] = await Promise.all([\n detectTechStack(cwd),\n detectSchemas(cwd),\n loadLocalSkills(cwd),\n ])\n\n // Context7 docs (optional, can fail gracefully)\n let docs = \"\"\n if (agentConfig.context7.enabled) {\n try {\n docs = await gatherContext7Docs(techStack, task, agentConfig.context7.apiKey)\n } catch {\n // Context7 is optional, don't fail the whole flow\n }\n }\n\n // Build memory context from both user and project levels\n const memoryContext = memory.buildMemoryContext(task)\n\n // Load project instructions (SHADXN.md or CLAUDE.md) with @-import resolution\n const projectInstructions = loadProjectInstructions(cwd)\n\n debug.context(\"memory\", memoryContext ? \"loaded\" : \"empty\")\n debug.context(\"instructions\", projectInstructions ? \"loaded from project\" : \"none\")\n\n return {\n techStack,\n schemas,\n skills,\n docs,\n config: agentConfig,\n memoryContext,\n projectInstructions,\n }\n}\n\nexport async function generate(options: GenerateOptions): Promise<GenerateResult> {\n const {\n task,\n cwd,\n overwrite = false,\n dryRun = false,\n provider: providerName = \"claude-code\",\n model,\n apiKey,\n context7 = true,\n interactive = true,\n } = options\n\n // 0. pre:prompt hook — can modify or block the task prompt\n let effectiveTask = task\n if (globalHooks.has(\"pre:prompt\")) {\n const promptResult = await globalHooks.execute(\"pre:prompt\", {\n event: \"pre:prompt\",\n task,\n cwd,\n })\n if (promptResult.blocked) {\n throw new Error(promptResult.message || \"Blocked by pre:prompt hook\")\n }\n if (promptResult.modified?.task) {\n effectiveTask = String(promptResult.modified.task)\n }\n }\n\n // 0b. pre:generate hook — can block the entire generation\n if (globalHooks.has(\"pre:generate\")) {\n const genResult = await globalHooks.execute(\"pre:generate\", {\n event: \"pre:generate\",\n task: effectiveTask,\n cwd,\n })\n if (genResult.blocked) {\n throw new Error(genResult.message || \"Blocked by pre:generate hook\")\n }\n }\n\n // 1. Gather context\n logger.info(\"Analyzing project...\")\n const context = await createAgentContext(cwd, effectiveTask, {\n provider: providerName,\n context7: { enabled: context7, apiKey },\n })\n\n // 2. Resolve output type\n const outputType = resolveOutputType(options.outputType, effectiveTask)\n logger.info(`Output type: ${outputType}`)\n\n // 3. Match relevant skills\n const matchedSkills = matchSkillsToTask(context.skills, effectiveTask, outputType)\n if (matchedSkills.length) {\n logger.info(\n `Loaded ${matchedSkills.length} relevant skill(s): ${matchedSkills.map((m) => m.skill.frontmatter.name).join(\", \")}`\n )\n }\n\n // 4. Build system prompt\n const systemPrompt = buildSystemPrompt(context, outputType, matchedSkills.map((m) => m.skill))\n\n // 5. Ensure credentials exist (auto-prompt if missing)\n const hasCredentials = await ensureCredentials(apiKey)\n if (!hasCredentials) {\n throw new Error(\"No credentials configured. Run `agentx model` to set up.\")\n }\n\n // 6. Create provider\n const provider = createProvider(providerName, apiKey, options.providerOpts || {})\n const resolvedModel = model || loadAuthConfig()?.model\n\n // Build initial messages (without system — orchestrator handles it)\n const sessionMessages: GenerationMessage[] = [\n ...(options.sessionMessages || []),\n { role: \"user\", content: effectiveTask },\n ]\n\n logger.info(\"Generating...\")\n\n // Determine if we should use the agentic loop\n const useAgentic = supportsAgenticLoop(provider)\n const maxSteps = options.maxSteps ?? (useAgentic ? 20 : 5)\n\n // Boot MCP servers (orchestrator tier only — CLI tiers don't reach\n // this codepath). Always closed in `finally` so a crash inside the\n // loop can't leak child processes.\n const mcpPool = options.mcpServers && Object.keys(options.mcpServers).length > 0\n ? await startMcpPool(options.mcpServers)\n : undefined\n\n let agenticResult: Awaited<ReturnType<typeof runAgenticLoop>>\n try {\n // 7. Run orchestrator (agentic or legacy)\n agenticResult = await runAgenticLoop({\n provider,\n systemPrompt,\n messages: [\n { role: \"system\", content: systemPrompt },\n ...sessionMessages,\n ],\n providerOptions: { model: resolvedModel, maxTokens: 8192 },\n cwd,\n maxIterations: maxSteps,\n enabledTools: context.config.agentic.enabledTools.filter(\n (t) => !context.config.agentic.disabledTools.includes(t)\n ),\n interactive,\n overwrite,\n dryRun,\n noqtaContext: options.noqtaContext,\n // Forward operator-Stop / wall-clock timeout into the loop. Without\n // this, generate() ignored the signal and the orchestrator kept\n // iterating after combined.abort() fired in executeOrchestrator —\n // production saw 3-hour hangs on noqta-public (A2A /task path).\n abortSignal: options.abortSignal,\n mcpTools: mcpPool?.tools,\n mcpDispatch: mcpPool ? mcpPool.dispatch.bind(mcpPool) : undefined,\n onProgress: (event) => {\n if (event.type === \"iteration_start\" && event.iteration > 1) {\n logger.info(`Step ${event.iteration}/${maxSteps}...`)\n }\n if (event.type === \"tool_call\") {\n debug.step(0, `Tool: ${event.name}`)\n }\n },\n })\n } finally {\n mcpPool?.close()\n }\n\n // Track token usage\n if (agenticResult.tokensUsed) {\n const stepModel = resolvedModel || \"claude-sonnet-4-20250514\"\n const estInput = Math.round(agenticResult.tokensUsed * 0.3)\n const estOutput = agenticResult.tokensUsed - estInput\n globalTracker.recordStep(1, stepModel, estInput, estOutput)\n }\n\n let { content } = agenticResult\n const { followUp, tokensUsed: totalTokens, inputTokens: agInput, outputTokens: agOutput } = agenticResult\n\n if (agenticResult.iterations > 1) {\n logger.info(`Completed in ${agenticResult.iterations} step(s)`)\n }\n\n // post:response hook — can modify or block the AI response\n if (globalHooks.has(\"post:response\")) {\n const responseResult = await globalHooks.execute(\"post:response\", {\n event: \"post:response\",\n content,\n task: effectiveTask,\n cwd,\n })\n if (responseResult.blocked) {\n throw new Error(responseResult.message || \"Blocked by post:response hook\")\n }\n if (responseResult.modified?.content) {\n content = String(responseResult.modified.content)\n }\n }\n\n // Handle follow-up questions (interactive mode)\n if (followUp && interactive) {\n return {\n files: { written: [], skipped: [], errors: [] },\n content,\n outputType,\n followUp,\n tokensUsed: totalTokens,\n inputTokens: agInput,\n outputTokens: agOutput,\n }\n }\n\n // Deduplicate files (later versions override earlier ones)\n const deduped = new Map<string, import(\"./providers/types\").GeneratedFile>()\n for (const file of agenticResult.files) {\n deduped.set(file.path, file)\n }\n\n // Write files\n const outputDir = resolveOutputDir(outputType, context.techStack, options.outputDir)\n\n const writeResult = await writeGeneratedFiles(Array.from(deduped.values()), {\n cwd,\n overwrite,\n dryRun,\n outputDir,\n })\n\n // Heal loop — verify generated code and auto-fix if needed\n let healResult: import(\"@/runtime/heal\").HealResult | undefined\n if (options.heal !== false && !dryRun && writeResult.written.length > 0) {\n const { HealEngine } = await import(\"@/runtime/heal\")\n const healEngine = new HealEngine(cwd, {\n enabled: true,\n testCommand: options.healConfig?.testCommand,\n buildCommand: options.healConfig?.buildCommand,\n lintCommand: options.healConfig?.lintCommand,\n maxAttempts: options.healConfig?.maxAttempts ?? 3,\n provider: providerName,\n model: resolvedModel,\n apiKey,\n })\n healResult = await healEngine.detectAndHeal(writeResult.written, effectiveTask)\n\n if (!healResult.healed && healResult.error) {\n await globalHooks.execute(\"on:error\", {\n event: \"on:error\",\n error: new Error(healResult.error),\n task: effectiveTask,\n cwd,\n })\n }\n }\n\n // post:generate hook — post-processing (format, lint, etc.)\n if (globalHooks.has(\"post:generate\")) {\n await globalHooks.execute(\"post:generate\", {\n event: \"post:generate\",\n task: effectiveTask,\n content,\n cwd,\n })\n }\n\n return {\n files: writeResult,\n content,\n outputType,\n tokensUsed: totalTokens,\n inputTokens: agInput,\n outputTokens: agOutput,\n healResult,\n }\n}\n\n// --- Streaming generation ---\n\nexport type GenerateStreamEvent =\n | StreamEvent\n | { type: \"context_ready\"; outputType: OutputType }\n | { type: \"step_complete\"; step: number; filesCount: number }\n | { type: \"tool_call\"; name: string; id: string }\n | { type: \"tool_result\"; name: string; id: string; is_error?: boolean }\n | { type: \"iteration\"; iteration: number }\n | { type: \"generate_result\"; result: GenerateResult }\n\nexport async function* generateStream(\n options: GenerateOptions\n): AsyncGenerator<GenerateStreamEvent> {\n const {\n task,\n cwd,\n overwrite = false,\n dryRun = false,\n provider: providerName = \"claude-code\",\n model,\n apiKey,\n context7 = true,\n interactive = true,\n } = options\n\n // 0. pre:prompt hook\n let effectiveTask = task\n if (globalHooks.has(\"pre:prompt\")) {\n const promptResult = await globalHooks.execute(\"pre:prompt\", {\n event: \"pre:prompt\",\n task,\n cwd,\n })\n if (promptResult.blocked) {\n yield { type: \"error\", error: promptResult.message || \"Blocked by pre:prompt hook\" }\n return\n }\n if (promptResult.modified?.task) {\n effectiveTask = String(promptResult.modified.task)\n }\n }\n\n // 0b. pre:generate hook\n if (globalHooks.has(\"pre:generate\")) {\n const genResult = await globalHooks.execute(\"pre:generate\", {\n event: \"pre:generate\",\n task: effectiveTask,\n cwd,\n })\n if (genResult.blocked) {\n yield { type: \"error\", error: genResult.message || \"Blocked by pre:generate hook\" }\n return\n }\n }\n\n // 1. Gather context\n const context = await createAgentContext(cwd, effectiveTask, {\n provider: providerName,\n context7: { enabled: context7, apiKey },\n })\n\n // 2. Resolve output type\n const outputType = resolveOutputType(options.outputType, effectiveTask)\n\n // Signal context ready so UI can stop spinner\n yield { type: \"context_ready\", outputType }\n\n // 3. Match relevant skills\n const matchedSkills = matchSkillsToTask(context.skills, effectiveTask, outputType)\n\n // 4. Build system prompt\n const systemPrompt = buildSystemPrompt(context, outputType, matchedSkills.map((m) => m.skill))\n\n // 5. Ensure credentials\n const hasCredentials = await ensureCredentials(apiKey)\n if (!hasCredentials) {\n yield { type: \"error\", error: \"No credentials configured. Run `agentx model` to set up.\" }\n return\n }\n\n // 6. Create provider\n const provider = createProvider(providerName, apiKey, options.providerOpts || {})\n const resolvedModel = model || loadAuthConfig()?.model\n const useAgentic = supportsAgenticLoop(provider)\n const maxSteps = options.maxSteps ?? (useAgentic ? 20 : 5)\n\n const sessionMessages: GenerationMessage[] = [\n ...(options.sessionMessages || []),\n { role: \"user\", content: effectiveTask },\n ]\n\n // For agentic mode, use the orchestrator with progress events\n if (useAgentic) {\n const q = new AsyncQueue<GenerateStreamEvent>()\n let agenticResult: Awaited<ReturnType<typeof runAgenticLoop>> | undefined\n let agenticError: unknown\n\n // Boot MCP servers (orchestrator tier only). Pool is closed in the\n // agenticPromise's finally so child processes are reaped on both\n // success and error paths.\n let mcpPool: McpPool | undefined\n if (options.mcpServers && Object.keys(options.mcpServers).length > 0) {\n try {\n mcpPool = await startMcpPool(options.mcpServers)\n } catch (e: any) {\n yield { type: \"error\", error: `MCP pool startup failed: ${e.message}` }\n return\n }\n }\n\n const agenticPromise = (async () => {\n try {\n agenticResult = await runAgenticLoop({\n provider,\n systemPrompt,\n messages: [\n { role: \"system\", content: systemPrompt },\n ...sessionMessages,\n ],\n providerOptions: { model: resolvedModel, maxTokens: 8192 },\n cwd,\n maxIterations: maxSteps,\n abortSignal: options.abortSignal,\n enabledTools: context.config.agentic.enabledTools.filter(\n (t) => !context.config.agentic.disabledTools.includes(t)\n ),\n interactive,\n overwrite,\n dryRun,\n noqtaContext: options.noqtaContext,\n mcpTools: mcpPool?.tools,\n mcpDispatch: mcpPool ? mcpPool.dispatch.bind(mcpPool) : undefined,\n onProgress: (event) => {\n if (event.type === \"text_delta\") {\n q.push({ type: \"text_delta\", text: event.text })\n }\n if (event.type === \"thinking_delta\") {\n q.push({ type: \"thinking_delta\", text: event.text })\n }\n if (event.type === \"iteration_start\") {\n q.push({ type: \"iteration\", iteration: event.iteration })\n }\n if (event.type === \"tool_call\") {\n q.push({ type: \"tool_call\", name: event.name, id: event.id })\n }\n if (event.type === \"tool_result\") {\n q.push({ type: \"tool_result\", name: event.name, id: event.id, is_error: event.is_error })\n }\n if (event.type === \"files_created\") {\n q.push({ type: \"step_complete\", step: 0, filesCount: event.files.length })\n }\n },\n })\n } catch (err) {\n agenticError = err\n } finally {\n mcpPool?.close()\n q.close()\n }\n })()\n\n for await (const evt of q) {\n yield evt\n }\n\n await agenticPromise\n if (agenticError) {\n const msg = agenticError instanceof Error ? agenticError.message : String(agenticError)\n yield { type: \"error\", error: msg }\n return\n }\n if (!agenticResult) {\n yield { type: \"error\", error: \"Agentic loop failed without a result\" }\n return\n }\n\n yield {\n type: \"done\",\n result: {\n content: agenticResult.content,\n files: agenticResult.files,\n tokensUsed: agenticResult.tokensUsed,\n followUp: agenticResult.followUp,\n },\n }\n\n // Write files and heal\n let { content } = agenticResult\n\n // post:response hook\n if (globalHooks.has(\"post:response\")) {\n const responseResult = await globalHooks.execute(\"post:response\", {\n event: \"post:response\",\n content,\n task: effectiveTask,\n cwd,\n })\n if (responseResult.blocked) {\n yield { type: \"error\", error: responseResult.message || \"Blocked by post:response hook\" }\n return\n }\n if (responseResult.modified?.content) {\n content = String(responseResult.modified.content)\n }\n }\n\n if (agenticResult.followUp && interactive) {\n yield {\n type: \"generate_result\",\n result: {\n files: { written: [], skipped: [], errors: [] },\n content,\n outputType,\n followUp: agenticResult.followUp,\n tokensUsed: agenticResult.tokensUsed,\n inputTokens: agenticResult.inputTokens,\n outputTokens: agenticResult.outputTokens,\n },\n }\n return\n }\n\n const deduped = new Map<string, import(\"./providers/types\").GeneratedFile>()\n for (const file of agenticResult.files) {\n deduped.set(file.path, file)\n }\n\n const outputDir = resolveOutputDir(outputType, context.techStack, options.outputDir)\n const writeResult = await writeGeneratedFiles(Array.from(deduped.values()), {\n cwd,\n overwrite,\n dryRun,\n outputDir,\n })\n\n let healResult: import(\"@/runtime/heal\").HealResult | undefined\n if (options.heal !== false && !dryRun && writeResult.written.length > 0) {\n const { HealEngine } = await import(\"@/runtime/heal\")\n const healEngine = new HealEngine(cwd, {\n enabled: true,\n testCommand: options.healConfig?.testCommand,\n buildCommand: options.healConfig?.buildCommand,\n lintCommand: options.healConfig?.lintCommand,\n maxAttempts: options.healConfig?.maxAttempts ?? 3,\n provider: providerName,\n model: resolvedModel,\n apiKey,\n })\n healResult = await healEngine.detectAndHeal(writeResult.written, effectiveTask)\n }\n\n if (globalHooks.has(\"post:generate\")) {\n await globalHooks.execute(\"post:generate\", {\n event: \"post:generate\",\n task: effectiveTask,\n content,\n cwd,\n })\n }\n\n yield {\n type: \"generate_result\",\n result: {\n files: writeResult,\n content,\n outputType,\n tokensUsed: agenticResult.tokensUsed,\n inputTokens: agenticResult.inputTokens,\n outputTokens: agenticResult.outputTokens,\n healResult,\n },\n }\n return\n }\n\n // --- Legacy streaming path (no generateRaw) ---\n\n const messages: GenerationMessage[] = [\n { role: \"system\", content: systemPrompt },\n ...sessionMessages,\n ]\n\n const allFiles: import(\"./providers/types\").GeneratedFile[] = []\n let totalTokens = 0\n let content = \"\"\n let followUp: string | undefined\n let step = 0\n\n // --- Step 1: streamed ---\n step++\n debug.step(step, `Starting generation (model: ${resolvedModel || \"default\"})`)\n\n let step1Result: GenerationResult\n\n if (provider.stream) {\n let accumulated = \"\"\n let streamResult: GenerationResult | undefined\n\n for await (const event of provider.stream(messages, {\n model: resolvedModel,\n maxTokens: 8192,\n })) {\n yield event\n\n if (event.type === \"text_delta\") {\n accumulated += event.text\n }\n if (event.type === \"done\") {\n streamResult = event.result\n }\n }\n\n step1Result = streamResult || {\n content: accumulated,\n files: [],\n tokensUsed: 0,\n }\n } else {\n const result = await provider.generate(messages, {\n model: resolvedModel,\n maxTokens: 8192,\n })\n\n if (result.content) {\n yield { type: \"text_delta\", text: result.content }\n }\n yield { type: \"done\", result }\n step1Result = result\n }\n\n totalTokens += step1Result.tokensUsed || 0\n content = step1Result.content\n\n const step1Tokens = step1Result.tokensUsed || 0\n const step1Model = resolvedModel || \"claude-sonnet-4-20250514\"\n const estInput1 = Math.round(step1Tokens * 0.3)\n const estOutput1 = step1Tokens - estInput1\n globalTracker.recordStep(step, step1Model, estInput1, estOutput1)\n debug.api(\"generate\", step1Model, step1Tokens)\n debug.step(step, `Generated ${step1Result.files.length} file(s), ${step1Tokens} tokens`)\n\n if (step1Result.files.length) {\n allFiles.push(...step1Result.files)\n }\n\n if (step1Result.followUp) {\n followUp = step1Result.followUp\n }\n\n yield { type: \"step_complete\", step, filesCount: step1Result.files.length }\n\n // --- Steps 2-N: non-streaming continuation loop ---\n if (!followUp) {\n const wantsContinuation1 =\n content.includes(\"[CONTINUE]\") ||\n content.includes(\"Next, I'll\") ||\n content.includes(\"Now let me\") ||\n content.includes(\"I'll also generate\")\n\n if (wantsContinuation1 && step1Result.files.length > 0) {\n const filesSummary = step1Result.files\n .map((f) => `Created: ${f.path}${f.description ? ` — ${f.description}` : \"\"}`)\n .join(\"\\n\")\n messages.push({\n role: \"assistant\",\n content: content + (filesSummary ? `\\n\\nFiles created:\\n${filesSummary}` : \"\"),\n })\n messages.push({\n role: \"user\",\n content:\n \"Continue generating the remaining files. Build on what you've already created. When finished, do not include [CONTINUE] in your response.\",\n })\n\n while (step < maxSteps) {\n step++\n debug.step(step, `Starting generation (model: ${resolvedModel || \"default\"})`)\n\n const result = await provider.generate(messages, {\n model: resolvedModel,\n maxTokens: 8192,\n })\n\n totalTokens += result.tokensUsed || 0\n content = result.content\n\n const stepTokens = result.tokensUsed || 0\n const stepModel = resolvedModel || \"claude-sonnet-4-20250514\"\n const estInput = Math.round(stepTokens * 0.3)\n const estOutput = stepTokens - estInput\n globalTracker.recordStep(step, stepModel, estInput, estOutput)\n debug.api(\"generate\", stepModel, stepTokens)\n debug.step(step, `Generated ${result.files.length} file(s), ${stepTokens} tokens`)\n\n if (result.files.length) {\n allFiles.push(...result.files)\n }\n\n yield { type: \"step_complete\", step, filesCount: result.files.length }\n\n if (result.followUp) {\n followUp = result.followUp\n break\n }\n if (result.files.length === 0 && step > 1) break\n\n const wantsContinuation =\n result.content.includes(\"[CONTINUE]\") ||\n result.content.includes(\"Next, I'll\") ||\n result.content.includes(\"Now let me\") ||\n result.content.includes(\"I'll also generate\")\n\n if (!wantsContinuation) break\n\n const filesSummary2 = result.files\n .map((f) => `Created: ${f.path}${f.description ? ` — ${f.description}` : \"\"}`)\n .join(\"\\n\")\n messages.push({\n role: \"assistant\",\n content: result.content + (filesSummary2 ? `\\n\\nFiles created:\\n${filesSummary2}` : \"\"),\n })\n messages.push({\n role: \"user\",\n content:\n \"Continue generating the remaining files. Build on what you've already created. When finished, do not include [CONTINUE] in your response.\",\n })\n }\n }\n }\n\n // post:response hook\n if (globalHooks.has(\"post:response\")) {\n const responseResult = await globalHooks.execute(\"post:response\", {\n event: \"post:response\",\n content,\n task: effectiveTask,\n cwd,\n })\n if (responseResult.blocked) {\n yield { type: \"error\", error: responseResult.message || \"Blocked by post:response hook\" }\n return\n }\n if (responseResult.modified?.content) {\n content = String(responseResult.modified.content)\n }\n }\n\n if (followUp && interactive) {\n yield {\n type: \"generate_result\",\n result: {\n files: { written: [], skipped: [], errors: [] },\n content,\n outputType,\n followUp,\n tokensUsed: totalTokens,\n },\n }\n return\n }\n\n const deduped = new Map<import(\"./providers/types\").GeneratedFile[\"path\"], import(\"./providers/types\").GeneratedFile>()\n for (const file of allFiles) {\n deduped.set(file.path, file)\n }\n\n const outputDir = resolveOutputDir(outputType, context.techStack, options.outputDir)\n const writeResult = await writeGeneratedFiles(Array.from(deduped.values()), {\n cwd,\n overwrite,\n dryRun,\n outputDir,\n })\n\n let healResult: import(\"@/runtime/heal\").HealResult | undefined\n if (options.heal !== false && !dryRun && writeResult.written.length > 0) {\n const { HealEngine } = await import(\"@/runtime/heal\")\n const healEngine = new HealEngine(cwd, {\n enabled: true,\n testCommand: options.healConfig?.testCommand,\n buildCommand: options.healConfig?.buildCommand,\n lintCommand: options.healConfig?.lintCommand,\n maxAttempts: options.healConfig?.maxAttempts ?? 3,\n provider: providerName,\n model: resolvedModel,\n apiKey,\n })\n healResult = await healEngine.detectAndHeal(writeResult.written, effectiveTask)\n\n if (!healResult.healed && healResult.error) {\n await globalHooks.execute(\"on:error\", {\n event: \"on:error\",\n error: new Error(healResult.error),\n task: effectiveTask,\n cwd,\n })\n }\n }\n\n if (globalHooks.has(\"post:generate\")) {\n await globalHooks.execute(\"post:generate\", {\n event: \"post:generate\",\n task: effectiveTask,\n content,\n cwd,\n })\n }\n\n yield {\n type: \"generate_result\",\n result: {\n files: writeResult,\n content,\n outputType,\n tokensUsed: totalTokens,\n healResult,\n },\n }\n}\n\nfunction buildSystemPrompt(\n context: AgentContext,\n outputType: string,\n skills: Skill[]\n): string {\n const sections: string[] = []\n\n // Identity — updated for agentic capabilities\n sections.push(`You are agentx, an agentic code generation tool. You generate high-quality, production-ready output for any tech stack.\n\nYour primary tool is \\`create_files\\` — use it to output all generated code, documents, and configs as files.\nIf the request is ambiguous or you need critical information to proceed correctly, use \\`ask_user\\` to ask a clarifying question.\n\nYou also have tools to inspect the codebase before generating code:\n- \\`read_file\\` — read existing files to understand patterns, styles, and implementations\n- \\`search_files\\` — search for files by glob pattern, optionally grep content with regex\n- \\`list_directory\\` — explore the project structure\n- \\`run_command\\` — run shell commands (build, test, lint, etc.)\n- \\`edit_file\\` — apply targeted search/replace edits to existing files\n\nAGENTIC WORKFLOW:\n- Before generating code, use \\`read_file\\` and \\`search_files\\` to understand the existing codebase\n- Match the project's existing patterns, naming conventions, and code style\n- After creating files, consider running tests or build commands to verify correctness\n- Use \\`edit_file\\` for small, targeted changes instead of rewriting entire files\n\nIMPORTANT RULES:\n- Generate complete, working code — not stubs or placeholders\n- Follow the project's existing patterns and conventions\n- Use the detected tech stack to choose the right language, framework, and patterns\n- File paths should be relative to the project root\n- Include all necessary imports\n- Do NOT add unnecessary dependencies\n\nMULTI-STEP GENERATION:\nFor complex tasks that require multiple related files (e.g., schema + API + UI + tests), you can chain steps:\n- Generate the foundational files first (schemas, types, configs)\n- Include \"[CONTINUE]\" in your response text when there are more files to generate\n- In subsequent steps, you'll see what was already created — build on it\n- When all files are generated, do NOT include \"[CONTINUE]\"\n- This enables you to generate a schema first, then an API that references it, then a UI that calls the API`)\n\n // Tech stack context\n sections.push(`# Project Tech Stack\\n${formatTechStack(context.techStack)}`)\n\n // Key dependencies\n const deps = Object.keys(context.techStack.dependencies).slice(0, 30)\n if (deps.length) {\n sections.push(`# Key Dependencies\\n${deps.join(\", \")}`)\n }\n\n // Schema context\n const schemaStr = formatSchemas(context.schemas)\n if (schemaStr) {\n sections.push(`# Project Schemas\\n${schemaStr}`)\n }\n\n // Skills context\n if (skills.length) {\n sections.push(\n `# Active Skills\\nFollow these skill instructions when applicable:\\n\\n` +\n skills\n .map(\n (s) =>\n `## Skill: ${s.frontmatter.name}\\n${s.frontmatter.description}\\n\\n${s.instructions}`\n )\n .join(\"\\n\\n---\\n\\n\")\n )\n }\n\n // Context7 docs\n if (context.docs) {\n sections.push(context.docs)\n }\n\n // Project instructions (SHADXN.md / CLAUDE.md)\n if (context.projectInstructions) {\n sections.push(`# Project Instructions\\n${context.projectInstructions}`)\n }\n\n // Memory context (past generations, patterns, preferences)\n if (context.memoryContext) {\n sections.push(context.memoryContext)\n }\n\n // Output type guidance\n sections.push(`# Output Type: ${outputType}\\nGenerate output appropriate for: ${outputType}. Use the \\`create_files\\` tool to output all files.`)\n\n return sections.join(\"\\n\\n\")\n}\n\n// Re-export key types\nexport type { TechStack } from \"./context/tech-stack\"\nexport type { ProjectSchemas } from \"./context/schema\"\nexport type { Skill } from \"./skills/types\"\nexport type { AgentConfig, OutputType, GeneratedFile, StreamEvent } from \"./providers/types\"\n"],"mappings":"2TAAA,OAAS,KAAAA,MAAS,MA+HX,IAAMC,GAAoBD,EAAE,OAAO,CACxC,SAAUA,EAAE,KAAK,CAAC,cAAe,SAAU,SAAU,WAAY,SAAU,OAAQ,QAAQ,CAAC,EAAE,QAAQ,aAAa,EACnH,MAAOA,EAAE,OAAO,EAAE,SAAS,EAC3B,OAAQA,EAAE,OAAO,EAAE,SAAS,EAC5B,OAAQA,EAAE,MAAMA,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC,EACtC,OAAQA,EACL,OAAO,CACN,IAAKA,EAAE,OAAO,EAAE,QAAQ,aAAa,CACvC,CAAC,EACA,QAAQ,CAAC,CAAC,EACb,SAAUA,EACP,OAAO,CACN,QAASA,EAAE,QAAQ,EAAE,QAAQ,EAAI,EACjC,OAAQA,EAAE,OAAO,EAAE,SAAS,CAC9B,CAAC,EACA,QAAQ,CAAC,CAAC,EACb,QAASA,EACN,OAAO,CACN,cAAeA,EAAE,OAAO,EAAE,QAAQ,EAAE,EACpC,aAAcA,EAAE,MAAMA,EAAE,OAAO,CAAC,EAAE,QAAQ,CACxC,eAAgB,WAAY,YAC5B,eAAgB,iBAAkB,cAAe,WACnD,CAAC,EACD,cAAeA,EAAE,MAAMA,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC,CAC/C,CAAC,EACA,QAAQ,CAAC,CAAC,CACf,CAAC,EAMYE,GAAe,CAC1B,YACA,OACA,MACA,UACA,WACA,SACA,SACA,QACA,QACA,SACA,OACA,WACA,SACA,QACA,UACA,MACF,EAIaC,GAAqD,CAChE,UAAW,+BACX,KAAM,sBACN,IAAK,0CACL,QAAS,4BACT,SAAU,4CACV,OAAQ,+BACR,OAAQ,8BACR,MAAO,8CACP,MAAO,0DACP,OAAQ,2BACR,KAAM,0CACN,SAAU,gDACV,OAAQ,oDACR,MAAO,2CACP,QAAS,mCACT,KAAM,kCACR,ECrMA,OAAS,cAAAC,GAAY,YAAYC,OAAU,KAC3C,OAAOC,MAAU,OACjB,OAAOC,OAAQ,YAiCf,IAAMC,GAAyF,CAC7F,uBAAwB,CAAE,KAAM,SAAU,SAAU,UAAW,EAC/D,oBAAqB,CAAE,KAAM,UAAW,SAAU,UAAW,EAC7D,iBAAkB,CAAE,KAAM,UAAW,SAAU,KAAM,EACrD,aAAc,CAAE,KAAM,UAAW,SAAU,KAAM,EACjD,eAAgB,CAAE,KAAM,UAAW,SAAU,KAAM,EACnD,eAAgB,CAAE,KAAM,UAAW,SAAU,KAAM,EACnD,eAAgB,CAAE,KAAM,UAAW,SAAU,KAAM,EACnD,eAAgB,CAAE,KAAM,UAAW,SAAU,KAAM,CACrD,EAEA,eAAsBC,GAAcC,EAAsC,CACxE,IAAMC,EAA0B,CAAC,EAG3BC,EAAQ,MAAML,GAAG,KAAK,OAAQ,CAClC,IAAAG,EACA,KAAM,EACN,OAAQ,CACN,qBACA,aACA,cACA,cACA,eACA,oBACA,eACA,YACF,EACA,UAAW,EACb,CAAC,EAGD,OAAW,CAACG,EAAYC,CAAI,IAAK,OAAO,QAAQN,EAAY,EAAG,CAC7D,IAAMO,EAAQH,EAAM,KAAMI,GAAMA,EAAE,SAASH,CAAU,GAAKG,IAAMH,CAAU,EAC1E,GAAIE,GAASD,EAAK,WAAa,WAAY,CACzC,IAAMG,EAAU,MAAMC,EAAaZ,EAAK,QAAQI,EAAKK,CAAK,CAAC,EAC3D,GAAIE,EAAS,CACXN,EAAQ,SAAW,CACjB,KAAMG,EAAK,KACX,QAASK,GAASF,EAAS,GAAI,EAC/B,OAAQG,GAAkBH,EAASH,EAAK,IAAI,CAC9C,EACA,QAMN,OAAW,CAACD,EAAYC,CAAI,IAAK,OAAO,QAAQN,EAAY,EAAG,CAC7D,IAAMO,EAAQH,EAAM,KAAMI,GAAMA,EAAE,SAASH,CAAU,GAAKG,IAAMH,CAAU,EAC1E,GAAIE,GAASD,EAAK,WAAa,MAAO,CACpC,IAAMG,EAAU,MAAMC,EAAaZ,EAAK,QAAQI,EAAKK,CAAK,CAAC,EAC3D,GAAIE,EAAS,CACXN,EAAQ,IAAM,CACZ,KAAMG,EAAK,KACX,QAASK,GAASF,EAAS,GAAI,CACjC,EACA,QAMN,GAAI,CAACN,EAAQ,IAAK,CAChB,IAAMU,EAAaT,EAAM,KACtBI,GAAMA,EAAE,SAAS,MAAM,IAAMA,EAAE,SAAS,WAAW,GAAKA,EAAE,SAAS,WAAW,EACjF,EACA,GAAIK,EAAY,CACd,IAAMJ,EAAU,MAAMC,EAAaZ,EAAK,QAAQI,EAAKW,CAAU,CAAC,EAC5DJ,IACFN,EAAQ,IAAM,CACZ,KAAM,OACN,QAASQ,GAASF,EAAS,GAAI,CACjC,IAMN,IAAMK,EAAaV,EAAM,KACtBI,GAAMA,IAAM,gBAAkBA,IAAM,sBAAwBA,IAAM,eACrE,EACA,GAAIM,EAAY,CACd,IAAML,EAAU,MAAMC,EAAaZ,EAAK,QAAQI,EAAKY,CAAU,CAAC,EAC5DL,IACFN,EAAQ,IAAMY,GAAaN,CAAO,GAKtC,IAAMO,EAAaZ,EAAM,OACtBI,IACEA,EAAE,SAAS,QAAQ,GAAKA,EAAE,SAAS,OAAO,GAAKA,EAAE,SAAS,SAAS,KACnEA,EAAE,SAAS,KAAK,GAAKA,EAAE,SAAS,KAAK,GAAKA,EAAE,SAAS,KAAK,GAAKA,EAAE,SAAS,KAAK,EACpF,EAEA,GAAIQ,EAAW,OAAQ,CACrBb,EAAQ,OAAS,CAAC,EAClB,QAAWc,KAAMD,EAAW,MAAM,EAAG,CAAC,EAAG,CACvC,IAAMP,EAAU,MAAMC,EAAaZ,EAAK,QAAQI,EAAKe,CAAE,CAAC,EACpDR,GACFN,EAAQ,OAAO,KAAK,CAClB,KAAMc,EACN,QAASN,GAASF,EAAS,GAAI,EAC/B,KAAMX,EAAK,QAAQmB,CAAE,EAAE,MAAM,CAAC,CAChC,CAAC,GAKP,OAAOd,CACT,CAEA,SAASS,GAAkBH,EAAiBS,EAAwB,CAClE,GAAIA,IAAS,SAAU,CACrB,IAAMC,EAAUV,EAAQ,MAAM,qBAAqB,EACnD,OAAOU,EAAUA,EAAQ,IAAKC,GAAMA,EAAE,QAAQ,WAAY,EAAE,EAAE,QAAQ,QAAS,EAAE,CAAC,EAAI,CAAC,EAEzF,MAAO,CAAC,CACV,CAEA,SAASL,GAAaN,EAA4B,CAWhD,MAAO,CAAE,UAVKA,EAAQ,MAAM;AAAA,CAAI,EAAE,OAAQY,GAAMA,EAAE,KAAK,GAAK,CAACA,EAAE,KAAK,EAAE,WAAW,GAAG,CAAC,EAC7D,IAAKC,GAAS,CACpC,GAAM,CAACC,CAAO,EAAID,EAAK,MAAM,GAAG,EAC1BE,EAAMD,EAAQ,KAAK,EACnBE,EAAWH,EAAK,SAAS,GAAG,GAAKA,EAAK,MAAM,GAAG,EAAE,CAAC,GAAG,KAAK,EAAE,OAAS,EAC3E,MAAO,CACL,IAAAE,EACA,SAAU,CAACC,CACb,CACF,CAAC,CACkB,CACrB,CAEA,eAAef,EAAagB,EAA0C,CACpE,GAAI,CACF,OAAK9B,GAAW8B,CAAQ,EACjB,MAAM7B,GAAG,SAAS6B,EAAU,MAAM,EADP,IAEpC,MAAE,CACA,OAAO,IACT,CACF,CAEA,SAASf,GAASgB,EAAaC,EAAwB,CACrD,OAAID,EAAI,QAAUC,EAAeD,EAC1BA,EAAI,MAAM,EAAGC,CAAM,EAAI;AAAA,gBAChC,CAEO,SAASC,GAAc1B,EAAiC,CAC7D,IAAM2B,EAAqB,CAAC,EA2B5B,GAzBI3B,EAAQ,UACV2B,EAAS,KACP,uBAAuB3B,EAAQ,SAAS;AAAA,GACrCA,EAAQ,SAAS,QAAQ,OACtB,WAAWA,EAAQ,SAAS,OAAO,KAAK,IAAI;AAAA,EAC5C,IACJ,QACAA,EAAQ,SAAS,QACjB,OACJ,EAGEA,EAAQ,KACV2B,EAAS,KACP,kBAAkB3B,EAAQ,IAAI;AAAA;AAAA,EAAsBA,EAAQ,IAAI,QAAU,OAC5E,EAGEA,EAAQ,KACV2B,EAAS,KACP;AAAA,EACE3B,EAAQ,IAAI,UAAU,IAAK4B,GAAM,KAAKA,EAAE,MAAMA,EAAE,SAAW,cAAgB,IAAI,EAAE,KAAK;AAAA,CAAI,CAC9F,EAGE5B,EAAQ,QAAQ,OAClB,QAAW6B,KAAS7B,EAAQ,OAC1B2B,EAAS,KACP,aAAaE,EAAM;AAAA,QAAmBA,EAAM,KAAO;AAAA,EAAOA,EAAM,QAAU,OAC5E,EAIJ,OAAOF,EAAS,KAAK;AAAA;AAAA,CAAM,CAC7B,CC7NA,OAAOG,OAAW,aAMlB,IAAMC,GAAe,8BAcrB,eAAsBC,GACpBC,EACAC,EACiC,CACjC,GAAI,CACF,IAAMC,EAAkC,CACtC,eAAgB,kBAClB,EACID,IAAQC,EAAQ,cAAmB,UAAUD,KAEjD,IAAME,EAAW,MAAMN,GAAM,GAAGC,uBAAkC,CAChE,OAAQ,OACR,QAAAI,EACA,KAAM,KAAK,UAAU,CAAE,KAAMF,CAAY,CAAC,CAC5C,CAAC,EAED,GAAI,CAACG,EAAS,GAAI,OAAO,KAEzB,IAAMC,EAAQ,MAAMD,EAAS,KAAK,EAClC,OAAIC,GAAM,WAAW,OACZA,EAAK,UAAU,CAAC,EAElB,IACT,MAAE,CACA,OAAO,IACT,CACF,CAEA,eAAsBC,GACpBC,EACAC,EACAC,EAAoB,IACpBP,EACwB,CACxB,GAAI,CACF,IAAMC,EAAkC,CACtC,eAAgB,kBAClB,EACID,IAAQC,EAAQ,cAAmB,UAAUD,KAEjD,IAAME,EAAW,MAAMN,GAAM,GAAGC,gBAA0B,mBAAmBQ,CAAS,SAAU,CAC9F,OAAQ,OACR,QAAAJ,EACA,KAAM,KAAK,UAAU,CAAE,MAAAK,EAAO,UAAAC,CAAU,CAAC,CAC3C,CAAC,EAED,OAAKL,EAAS,KAEA,MAAMA,EAAS,KAAK,IACrB,SAAW,IAC1B,MAAE,CACA,OAAO,IACT,CACF,CAEA,eAAsBM,GACpBC,EACAH,EACAN,EACiB,CACjB,IAAMU,EAA8B,CAAC,EAGrC,QAAWC,KAAMF,EAAM,WAAW,MAAM,EAAG,CAAC,EAC1CC,EAAkB,KAAKC,EAAG,IAAI,EAIhC,IAAMC,EAAe,CACnB,QACA,MACA,SACA,UACA,OACA,OACA,UACA,UACA,OACA,SACA,cACA,cACA,SACA,wBACA,MACA,MACF,EAEA,QAAWC,KAAOD,GACZH,EAAM,aAAaI,CAAG,GAAKJ,EAAM,gBAAgBI,CAAG,KACjDH,EAAkB,SAASG,CAAG,GACjCH,EAAkB,KAAKG,CAAG,GAKhC,IAAMC,EAAiB,CAAC,EAExB,QAAWC,KAAOL,EAAkB,MAAM,EAAG,CAAC,EAAG,CAC/C,IAAMM,EAAU,MAAMlB,GAAiBiB,EAAKf,CAAM,EAClD,GAAIgB,EAAS,CACX,IAAMC,EAAU,MAAMb,GAAeY,EAAQ,GAAIV,EAAO,IAAMN,CAAM,EAChEiB,GACFH,EAAK,KAAK,MAAME,EAAQ;AAAA,EAAuBC,GAAS,GAK9D,OAAKH,EAAK,OAIH;AAAA;AAAA,EAAsDA,EAAK,KAAK;AAAA;AAAA;AAAA;AAAA,CAAa,IAH3E,EAIX,CCzHO,IAAMI,GAA+C,CAC1D,UAAW,CACT,KAAM,YACN,QAAS,iBACT,aAAc,CAAC,QAAS,QAAS,WAAY,QAAS,MAAM,EAC5D,YAAa,cACf,EACA,KAAM,CACJ,KAAM,OACN,QAAS,UACT,aAAc,CAAC,QAAS,QAAS,WAAY,QAAS,SAAS,EAC/D,YAAa,gBACf,EACA,IAAK,CACH,KAAM,MACN,QAAS,UACT,aAAc,CAAC,OAAQ,OAAQ,OAAQ,OAAQ,MAAM,EACrD,YAAa,uBACf,EACA,QAAS,CACP,KAAM,UACN,QAAS,IACT,aAAc,CAAC,GAAG,EAClB,YAAa,oBACf,EACA,SAAU,CACR,KAAM,WACN,QAAS,OACT,aAAc,CAAC,OAAQ,QAAS,QAAS,OAAO,EAChD,YAAa,eACf,EACA,OAAQ,CACN,KAAM,SACN,QAAS,UACT,aAAc,CAAC,OAAQ,OAAQ,OAAQ,OAAQ,MAAM,EACrD,YAAa,mBACf,EACA,OAAQ,CACN,KAAM,SACN,QAAS,IACT,aAAc,CAAC,SAAU,SAAU,QAAS,SAAU,OAAO,EAC7D,YAAa,oBACf,EACA,MAAO,CACL,KAAM,QACN,QAAS,UACT,aAAc,CAAC,UAAU,EACzB,YAAa,wBACf,EACA,MAAO,CACL,KAAM,QACN,QAAS,QACT,aAAc,CAAC,OAAQ,SAAU,OAAO,EACxC,YAAa,qCACf,EACA,OAAQ,CACN,KAAM,SACN,QAAS,UACT,aAAc,CAAC,OAAQ,SAAU,QAAQ,EACzC,YAAa,iBACf,EACA,KAAM,CACJ,KAAM,OACN,QAAS,MACT,aAAc,CAAC,YAAa,aAAc,YAAa,YAAa,YAAa,WAAW,EAC5F,YAAa,uBACf,EACA,SAAU,CACR,KAAM,WACN,QAAS,oBACT,aAAc,CAAC,QAAS,QAAQ,EAChC,YAAa,8BACf,EACA,OAAQ,CACN,KAAM,SACN,QAAS,MACT,aAAc,CAAC,OAAQ,WAAY,YAAa,QAAS,MAAM,EAC/D,YAAa,uCACf,EACA,MAAO,CACL,KAAM,QACN,QAAS,aACT,aAAc,CAAC,QAAS,QAAS,SAAU,QAAQ,EACnD,YAAa,gBACf,EACA,QAAS,CACP,KAAM,UACN,QAAS,OACT,aAAc,CAAC,OAAQ,QAAS,OAAQ,QAAQ,EAChD,YAAa,8BACf,CACF,EAEO,SAASC,GACdC,EACAC,EACY,CACZ,GAAID,GAAYA,IAAa,OAC3B,OAAOA,EAGT,IAAME,EAAQD,EAAgB,YAAY,EAGpCE,EAAmC,CACvC,CAAC,oGAAqG,WAAW,EACjH,CAAC,yDAA0D,MAAM,EACjE,CAAC,2EAA4E,KAAK,EAClF,CAAC,0DAA2D,SAAS,EACrE,CAAC,yEAA0E,UAAU,EACrF,CAAC,6DAA8D,QAAQ,EACvE,CAAC,iDAAkD,QAAQ,EAC3D,CAAC,qCAAsC,OAAO,EAC9C,CAAC,6DAA8D,OAAO,EACtE,CAAC,2DAA4D,QAAQ,EACrE,CAAC,wEAAyE,MAAM,EAChF,CAAC,wEAAyE,UAAU,EACpF,CAAC,0EAA2E,QAAQ,EACpF,CAAC,gFAAiF,OAAO,EACzF,CAAC,yFAA0F,SAAS,CACtG,EAEA,OAAW,CAACC,EAASC,CAAI,IAAKF,EAC5B,GAAIC,EAAQ,KAAKF,CAAK,EACpB,OAAOG,EAIX,MAAO,WACT,CC5IA,OAAS,cAAAC,GAAY,YAAYC,OAAU,KAC3C,OAAOC,OAAU,OCDjB,OAAS,SAAAC,OAAa,QCAtB,OAAS,KAAAC,MAAS,MAIX,IAAMC,GAAc,CACzB,eACA,gBACA,iBACA,kBACA,aACA,gBACA,cACA,WACA,gBACA,iBAEA,sBACA,uBACA,eACA,eACA,gBAIA,qBACA,kBACA,eACA,iBAGA,kBACA,eACA,iBAGA,kBACA,kBACA,uBACA,gBACA,kBACF,EAKaC,GAA+B,CAC1C,eACA,iBACA,aACA,gBACA,cACA,gBAEA,sBACA,uBACA,eACA,cACF,EAIaC,GAAuBH,EAAE,OAAO,CAC3C,KAAMA,EAAE,OAAO,EACf,KAAMA,EAAE,KAAK,CAAC,UAAW,SAAU,QAAQ,CAAC,EAE5C,QAASA,EAAE,OAAO,EAAE,SAAS,EAE7B,OAAQA,EAAE,OAAO,EAAE,SAAS,EAE5B,SAAUA,EAAE,KAAK,CAAC,cAAe,SAAU,SAAU,WAAY,SAAU,QAAQ,CAAC,EAAE,SAAS,EAC/F,MAAOA,EAAE,OAAO,EAAE,SAAS,EAE3B,OAAQA,EAAE,OAAO,EAAE,SAAS,EAE5B,SAAUA,EAAE,OAAO,EAAE,QAAQ,GAAG,EAEhC,QAASA,EAAE,QAAQ,EAAE,QAAQ,EAAI,CACnC,CAAC,ECjDD,IAAMI,GAAmE,CACvE,gBAAiB,CAAE,MAAO,EAAG,OAAQ,EAAG,EACxC,cAAe,CAAE,MAAO,GAAI,OAAQ,EAAG,EACvC,eAAgB,CAAE,MAAO,IAAM,OAAQ,IAAK,CAC9C,EAEA,SAASC,GAAeC,EAAuB,CAC7C,IAAMC,EAAQD,EAAM,YAAY,EAChC,OAAIC,EAAM,SAAS,MAAM,EAAU,cAC/BA,EAAM,SAAS,OAAO,EAAU,eAC7B,eACT,CAEO,IAAMC,GAAN,KAAmB,CAChB,MAAqB,CAAC,EACtB,OAAkC,IAAI,IAE9C,WACEC,EACAH,EACAI,EACAC,EACM,CACN,IAAMC,EAASP,GAAeC,CAAK,EAC7BO,EAAUT,GAAcQ,CAAM,GAAKR,GAAc,eAAe,EAChEU,EACHJ,EAAc,IAAaG,EAAQ,MACnCF,EAAe,IAAaE,EAAQ,OAEvC,KAAK,MAAM,KAAK,CACd,KAAAJ,EACA,MAAAH,EACA,YAAAI,EACA,aAAAC,EACA,KAAAG,EACA,UAAW,KAAK,IAAI,CACtB,CAAC,EAED,IAAMC,EAAW,KAAK,OAAO,IAAIT,CAAK,GAAK,CACzC,YAAa,EACb,aAAc,EACd,KAAM,EACN,MAAO,CACT,EACAS,EAAS,aAAeL,EACxBK,EAAS,cAAgBJ,EACzBI,EAAS,MAAQD,EACjBC,EAAS,QACT,KAAK,OAAO,IAAIT,EAAOS,CAAQ,CACjC,CAEA,YAA2B,CACzB,IAAIC,EAAmB,EACnBC,EAAoB,EACpBC,EAAY,EAEhB,QAAWT,KAAQ,KAAK,MACtBO,GAAoBP,EAAK,YACzBQ,GAAqBR,EAAK,aAC1BS,GAAaT,EAAK,KAGpB,IAAMU,EAAqC,CAAC,EAC5C,OAAW,CAACC,EAAMC,CAAK,IAAK,KAAK,OAC/BF,EAAOC,CAAI,EAAI,CAAE,GAAGC,CAAM,EAG5B,MAAO,CACL,iBAAAL,EACA,kBAAAC,EACA,YAAaD,EAAmBC,EAChC,UAAAC,EACA,MAAO,CAAC,GAAG,KAAK,KAAK,EACrB,OAAAC,CACF,CACF,CAEA,OAAc,CACZ,KAAK,MAAQ,CAAC,EACd,KAAK,OAAO,MAAM,CACpB,CACF,EAEaG,GAAgB,IAAId,GC1G1B,SAASe,GAAcC,EAAkBC,EAA8B,CAC5E,IAAMC,EAAkB,CAAC,EAazB,GAVAA,EAAM,KAAK,cAAcF,EAAQ,IAAI,EACrCE,EAAM,KAAK,EAAE,EACbA,EAAM,KAAK,kBAAkBF,EAAQ,WAAW,EAChDE,EAAM,KAAK,kBAAkBF,EAAQ,WAAW,EAChDE,EAAM,KAAK,cAAcF,EAAQ,KAAK,EACtCE,EAAM,KAAK,mBAAmBF,EAAQ,SAAS,QAAQ,EACvDE,EAAM,KAAK,iBAAiBF,EAAQ,WAAW,eAAe,GAAG,EACjEE,EAAM,KAAK,EAAE,EAGTF,EAAQ,eAAe,OAAQ,CACjCE,EAAM,KAAK,oBAAoB,EAC/BA,EAAM,KAAK,EAAE,EACb,QAAWC,KAAQH,EAAQ,eACzBE,EAAM,KAAK,OAAOC,KAAQ,EAE5BD,EAAM,KAAK,EAAE,EAIf,GAAIF,EAAQ,SAAS,OAAQ,CAC3BE,EAAM,KAAK,iBAAiB,EAC5BA,EAAM,KAAK,EAAE,EACb,QAAWE,KAAOJ,EAAQ,SAAU,CAClC,GAAII,EAAI,OAAS,SAAU,SAC3B,IAAMC,EAAQD,EAAI,OAAS,OAAS,WAAa,gBACjDF,EAAM,KAAK,OAAOG,GAAO,EACzBH,EAAM,KAAK,EAAE,EACTE,EAAI,KACNF,EAAM,KAAKE,EAAI,OAAO,EAIxBF,EAAM,KAAK,EAAE,GAKjB,GAAID,EAAO,CAST,GARAC,EAAM,KAAK,iBAAiB,EAC5BA,EAAM,KAAK,EAAE,EACbA,EAAM,KAAK,uBAAuBD,EAAM,YAAY,eAAe,GAAG,EACtEC,EAAM,KAAK,cAAcD,EAAM,iBAAiB,eAAe,GAAG,EAClEC,EAAM,KAAK,eAAeD,EAAM,kBAAkB,eAAe,GAAG,EACpEC,EAAM,KAAK,sBAAsBD,EAAM,UAAU,QAAQ,CAAC,GAAG,EAC7DC,EAAM,KAAK,EAAE,EAET,OAAO,KAAKD,EAAM,MAAM,EAAE,OAAQ,CACpCC,EAAM,KAAK,eAAe,EAC1BA,EAAM,KAAK,EAAE,EACbA,EAAM,KAAK,2CAA2C,EACtDA,EAAM,KAAK,2CAA2C,EACtD,OAAW,CAACI,EAAOC,CAAE,IAAK,OAAO,QAAQN,EAAM,MAAM,EACnDC,EAAM,KACJ,KAAKI,OAAWC,EAAG,YAAY,eAAe,OAAOA,EAAG,aAAa,eAAe,QAAQA,EAAG,KAAK,QAAQ,CAAC,OAAOA,EAAG,SACzH,EAEFL,EAAM,KAAK,EAAE,EAGf,GAAID,EAAM,MAAM,OAAQ,CACtBC,EAAM,KAAK,cAAc,EACzBA,EAAM,KAAK,EAAE,EACbA,EAAM,KAAK,0CAA0C,EACrDA,EAAM,KAAK,0CAA0C,EACrD,QAAWM,KAAQP,EAAM,MACvBC,EAAM,KACJ,KAAKM,EAAK,UAAUA,EAAK,WAAWA,EAAK,YAAY,eAAe,OAAOA,EAAK,aAAa,eAAe,QAAQA,EAAK,KAAK,QAAQ,CAAC,KACzI,EAEFN,EAAM,KAAK,EAAE,GAIjB,OAAOA,EAAM,KAAK;AAAA,CAAI,CACxB,CHrEO,IAAMO,GAAN,KAAmB,CAChB,MAA0C,IAAI,IAKtD,SAASC,EAAkBC,EAAkC,CAC3D,GAAI,CAACA,EAAW,QAAS,OAEzB,IAAMC,EAAU,KAAK,cAAcD,CAAU,EACvCE,EAAwB,CAAE,MAAAH,EAAO,WAAAC,EAAY,QAAAC,CAAQ,EAErDE,EAAW,KAAK,MAAM,IAAIJ,CAAK,GAAK,CAAC,EAC3CI,EAAS,KAAKD,CAAK,EAEnBC,EAAS,KAAK,CAACC,EAAGC,IAAMD,EAAE,WAAW,SAAWC,EAAE,WAAW,QAAQ,EACrE,KAAK,MAAM,IAAIN,EAAOI,CAAQ,CAChC,CAMA,MAAM,QAAQJ,EAAkBO,EAA2C,CACzE,IAAMC,EAAa,KAAK,MAAM,IAAIR,CAAK,EACvC,GAAI,CAACQ,GAAY,OACf,MAAO,CAAC,EAGV,IAAMC,EAAWC,GAAgB,SAASV,CAAK,EAC3CW,EAA4C,CAAC,EAEjD,QAAWC,KAAQJ,EAAY,CAC7B,IAAMK,EAAQ,KAAK,IAAI,EACvB,GAAI,CACF,IAAMC,EAAS,MAAMF,EAAK,QAAQ,CAAE,GAAGL,EAAS,GAAGI,CAAiB,CAAC,EAC/DI,EAAW,KAAK,IAAI,EAAIF,EAM9B,GAJIC,EAAO,WACTH,EAAmB,CAAE,GAAGA,EAAkB,GAAGG,EAAO,QAAS,GAG3DL,GAAYK,EAAO,QACrB,OAAAE,EAAM,KAAKJ,EAAK,WAAW,KAAMG,EAAU,SAAS,EAC7C,CACL,QAAS,GACT,QAASD,EAAO,SAAW,oBAAoBF,EAAK,WAAW,OAC/D,SAAUD,CACZ,EAGFK,EAAM,KAAKJ,EAAK,WAAW,KAAMG,EAAU,IAAI,CACjD,OAASE,EAAP,CACA,IAAMF,EAAW,KAAK,IAAI,EAAIF,EAI9B,GAHAG,EAAM,KAAKJ,EAAK,WAAW,KAAMG,EAAU,UAAUE,EAAM,SAAS,EACpEC,EAAO,KAAK,SAASN,EAAK,WAAW,iBAAiBK,EAAM,SAAS,EAEjER,EACF,MAAO,CACL,QAAS,GACT,QAAS,SAASG,EAAK,WAAW,kBAAkBK,EAAM,SAC5D,CAEJ,EAGF,MAAO,CAAE,SAAU,OAAO,KAAKN,CAAgB,EAAE,OAASA,EAAmB,MAAU,CACzF,CASA,gBAAgBX,EAAkBmB,EAAcjB,EAAsBkB,EAAmB,IAAW,CAElG,IAAMjB,EAAwB,CAAE,MAAAH,EAAO,WADJ,CAAE,KAAAmB,EAAM,KAAM,SAAU,SAAAC,EAAU,QAAS,EAAK,EAChC,QAAAlB,CAAQ,EACrDE,EAAW,KAAK,MAAM,IAAIJ,CAAK,GAAK,CAAC,EAC3CI,EAAS,KAAKD,CAAK,EACnBC,EAAS,KAAK,CAAC,EAAGE,IAAM,EAAE,WAAW,SAAWA,EAAE,WAAW,QAAQ,EACrE,KAAK,MAAM,IAAIN,EAAOI,CAAQ,CAChC,CAKA,IAAIJ,EAA2B,CAE7B,MAAO,CAAC,CADW,KAAK,MAAM,IAAIA,CAAK,GAClB,MACvB,CAKA,OAAc,CACZ,KAAK,MAAM,MAAM,CACnB,CAIA,MAAe,CACb,IAAIqB,EAAI,EACR,QAAWC,KAAQ,KAAK,MAAM,OAAO,EAAGD,GAAKC,EAAK,OAClD,OAAOD,CACT,CAKQ,cAAcpB,EAAyC,CAC7D,OAAQA,EAAW,KAAM,CACvB,IAAK,UACH,OAAO,KAAK,qBAAqBA,CAAU,EAC7C,IAAK,SACH,OAAO,KAAK,oBAAoBA,CAAU,EAC5C,IAAK,SACH,OAAO,KAAK,oBAAoBA,CAAU,EAC5C,QACE,MAAM,IAAI,MAAM,sBAAsBA,EAAW,MAAM,CAC3D,CACF,CAMQ,qBAAqBA,EAAyC,CACpE,MAAO,OAAOM,GAA8C,CAC1D,GAAI,CAACN,EAAW,QACd,MAAO,CAAC,EAIV,IAAIsB,EAAMtB,EAAW,QACrBsB,EAAMA,EAAI,QAAQ,iBAAkB,CAACC,EAAQC,IACpC,OAAOlB,EAAQkB,CAAG,GAAK,EAAE,CACjC,EAED,IAAMX,EAAS,MAAMY,GAAM,KAAM,CAAC,KAAMH,CAAG,EAAG,CAC5C,IAAKhB,EAAQ,KAAO,QAAQ,IAAI,EAChC,OAAQ,GACR,QAAS,IACT,IAAK,QAAQ,GACf,CAAC,EAED,OAAIO,EAAO,WAAa,EACf,CACL,QAAS,GACT,QAASA,EAAO,QAAUA,EAAO,QAAU,iBAAiBb,EAAW,cACzE,EAGK,CAAC,CACV,CACF,CAKQ,oBAAoBA,EAAyC,CACnE,MAAO,OAAOM,GAA8C,CAC1D,GAAI,CAACN,EAAW,OACd,MAAO,CAAC,EAOV,IAAM0B,EAAM,MAAM,OAJC1B,EAAW,OAAO,WAAW,GAAG,EAC/CA,EAAW,OACX,GAAGM,EAAQ,KAAO,QAAQ,IAAI,KAAKN,EAAW,UAG5CC,EAAUyB,EAAI,SAAWA,EAAI,SAAWA,EAE9C,OAAI,OAAOzB,GAAY,WACd,MAAMA,EAAQK,CAAO,EAGvB,CAAC,CACV,CACF,CAOQ,oBAAoBN,EAAyC,CACnE,MAAO,OAAOM,GAA8C,CAC1D,GAAI,CAACN,EAAW,OACd,MAAO,CAAC,EAIV,IAAM2B,EAAe3B,EAAW,UAAY4B,EAAe,GAAG,UAAY,cACpEC,EAAWC,GAAa,EAC9B,GAAI,CAACD,GAAYF,IAAiB,cAChC,OAAAV,EAAO,KACL,gBAAgBjB,EAAW,yDAAyD2B,IACtF,EACO,CAAC,EAGV,GAAI,CAEF,GAAM,CAAE,eAAAI,CAAe,EAAI,KAAM,QAAO,yBAAmB,EACrDC,EAAWD,EAAeJ,EAAqBE,GAAU,KAAK,EAGhEI,EAASjC,EAAW,OACxBiC,EAASA,EAAO,QAAQ,iBAAkB,CAACV,EAAQC,IAC1C,OAAOlB,EAAQkB,CAAG,GAAK,EAAE,CACjC,EAED,IAAMU,EAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kFAyBfC,GAdS,MAAMH,EAAS,SAC5B,CACE,CAAE,KAAM,SAAU,QAASE,CAAa,EACxC,CAAE,KAAM,OAAQ,QAASD,CAAO,CAClC,EACA,CACE,MAAOjC,EAAW,MAClB,UAAW,IACb,CACF,GAGuB,QAAQ,KAAK,EAEV,MAAM,aAAa,EAC7C,GAAI,CAACmC,EACH,OAAAlB,EAAO,KAAK,gBAAgBjB,EAAW,kDAAkD,EAClF,CAAC,EAGV,IAAMoC,EAAS,KAAK,MAAMD,EAAU,CAAC,CAAC,EAEtC,OAAIC,EAAO,SAAW,QACb,CACL,QAAS,GACT,QAASA,EAAO,SAAW,2BAA2BpC,EAAW,MACnE,EAGEoC,EAAO,SACF,CAAE,SAAUA,EAAO,QAAS,EAG9B,CAAC,CACV,OAASpB,EAAP,CAEA,OAAAC,EAAO,KAAK,gBAAgBjB,EAAW,iBAAiBgB,EAAM,SAAS,EAChE,CAAC,CACV,CACF,CACF,CACF,EIzRA,OAAS,cAAAqB,GAAY,gBAAAC,GAAc,eAAAC,OAAmB,KACtD,OAAOC,OAAU,OAeV,SAASC,GAAUC,EAAaC,EAA8B,CACnEC,GAAoBF,EAAKC,CAAQ,EACjCE,GAAuBH,EAAKC,CAAQ,CACtC,CAKA,SAASC,GAAoBF,EAAaC,EAA8B,CACtE,IAAMG,EAAaC,GAAK,KAAKL,EAAK,oBAAoB,EACtD,GAAKM,GAAWF,CAAU,EAE1B,GAAI,CACF,IAAMG,EAAM,KAAK,MAAMC,GAAaJ,EAAY,MAAM,CAAC,EACvD,GAAI,CAACG,EAAI,MAAO,OAEhB,OAAW,CAACE,EAAWC,CAAW,IAAK,OAAO,QAAQH,EAAI,KAAK,EAAG,CAChE,GAAI,CAACI,GAAY,SAASF,CAAsB,EAAG,CACjDG,EAAO,KAAK,iCAAiCH,GAAW,EACxD,SAGF,IAAMI,EAAQJ,EACd,GAAK,MAAM,QAAQC,CAAW,EAE9B,QAAWI,KAAOJ,EAChB,GAAI,CACF,IAAMK,EAASC,GAAqB,MAAMF,CAAG,EAC7Cb,EAAS,SAASY,EAAOE,CAAM,CACjC,OAASE,EAAP,CACAL,EAAO,KAAK,+BAA+BC,MAAUI,EAAM,SAAS,CACtE,EAGN,OAASA,EAAP,CACAL,EAAO,KAAK,qCAAqCK,EAAM,SAAS,CAClE,CACF,CAMA,SAASd,GAAuBH,EAAaC,EAA8B,CACzE,IAAMiB,EAAWb,GAAK,KAAKL,EAAK,UAAW,OAAO,EAClD,GAAKM,GAAWY,CAAQ,EAExB,GAAI,CACF,IAAMC,EAAQC,GAAYF,CAAQ,EAAE,OACjCG,GAAMA,EAAE,SAAS,KAAK,GAAKA,EAAE,SAAS,KAAK,GAAKA,EAAE,SAAS,MAAM,CACpE,EAEA,QAAWC,KAAQH,EAAO,CAGxB,IAAMI,EAAQD,EAAK,QAAQ,iBAAkB,EAAE,EAAE,MAAM,GAAG,EAC1D,GAAIC,EAAM,OAAS,EAAG,CACpBX,EAAO,KAAK,cAAcU,yCAA4C,EACtE,SAGF,IAAME,EAAYD,EAAM,CAAC,EACnBE,EAAOF,EAAM,MAAM,CAAC,EAAE,KAAK,GAAG,EAG9Bd,EAAYe,EAAU,QAAQ,KAAM,GAAG,EAC7C,GAAI,CAACb,GAAY,SAASF,CAAS,EAAG,CAEpC,IAAMiB,EAAWF,EAAU,QAAQ,IAAK,GAAG,EAC3C,GAAI,CAACb,GAAY,SAASe,CAAQ,EAAG,CACnCd,EAAO,KAAK,mCAAmCU,GAAM,EACrD,SAEFrB,EAAS,SAASyB,EAAU,CAC1B,KAAAD,EACA,KAAM,SACN,OAAQpB,GAAK,KAAKa,EAAUI,CAAI,EAChC,SAAU,IACV,QAAS,EACX,CAAC,EACD,SAGFrB,EAAS,SAASQ,EAAW,CAC3B,KAAAgB,EACA,KAAM,SACN,OAAQpB,GAAK,KAAKa,EAAUI,CAAI,EAChC,SAAU,IACV,QAAS,EACX,CAAC,EAEL,OAASL,EAAP,CACAL,EAAO,KAAK,wCAAwCK,EAAM,SAAS,CACrE,CACF,CCtGO,IAAMU,EAAc,IAAIC,GCN/B,OAAOC,OAAa,UACpB,OAAOC,OAAW,QCDlB,OAAS,KAAAC,MAAS,MAEX,IAAMC,GAAmB,CAAC,UAAW,cAAe,OAAQ,MAAM,EAG5DC,GAAuBF,EAAE,KAAKC,EAAgB,EAO9CE,GAAyBH,EAAE,OAAO,CAC7C,KAAME,GAAqB,QAAQ,SAAS,EAC5C,MAAOF,EAAE,MAAMA,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC,EACrC,KAAMA,EAAE,MAAMA,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC,EACpC,QAASA,EAAE,MAAMA,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC,CACzC,CAAC,EDND,SAASI,GAAUC,EAAkBC,EAA0B,CAE7D,IAAIC,EAAQD,EACT,QAAQ,MAAO,KAAK,EACpB,QAAQ,QAAS,cAAc,EAC/B,QAAQ,MAAO,OAAO,EACtB,QAAQ,oBAAqB,IAAI,EACjC,QAAQ,MAAO,MAAM,EACxB,OAAO,IAAI,OAAO,IAAIC,IAAQ,EAAE,KAAKF,CAAQ,CAC/C,CAEO,IAAMG,GAAN,KAAwB,CACrB,KACA,cACA,aACA,gBACA,aAAe,GAEvB,YAAYC,EAAoC,CAC9C,IAAMC,EAASC,GAAuB,MAAMF,GAAU,CAAC,CAAC,EACxD,KAAK,KAAOC,EAAO,KACnB,KAAK,cAAgBA,EAAO,MAC5B,KAAK,aAAeA,EAAO,KAC3B,KAAK,gBAAkBA,EAAO,OAChC,CAEA,SAA0B,CACxB,OAAO,KAAK,IACd,CAEA,QAAQE,EAA4B,CAClC,KAAK,KAAOA,EACZ,KAAK,aAAe,GACpBC,EAAM,QAAQ,cAAe,eAAeD,GAAM,CACpD,CAKA,MAAM,eAAeP,EAA6C,CAIhE,GAHAQ,EAAM,QAAQ,cAAe,mBAAmBR,YAAmB,KAAK,OAAO,EAG3E,KAAK,WAAWA,EAAU,KAAK,YAAY,EAC7C,OAAAQ,EAAM,QAAQ,cAAe,sBAAsBR,GAAU,EACtD,OAGT,OAAQ,KAAK,KAAM,CACjB,IAAK,OACH,MAAO,QAET,IAAK,OACH,MAAO,OAET,IAAK,cACH,MAAO,QAET,IAAK,UAKH,OAHI,KAAK,cAGL,KAAK,WAAWA,EAAU,KAAK,aAAa,EACvC,QAIF,KAAK,WAAWA,CAAQ,EAEjC,QACE,MAAO,OACX,CACF,CAKA,MAAM,aAAaS,EAA4C,CAC7D,OAAI,KAAK,OAAS,OAAe,QAC7B,KAAK,OAAS,OAAe,OAE1B,OACT,CAEQ,WAAWT,EAAkBU,EAA6B,CAChE,OAAOA,EAAS,KAAMC,GAAMZ,GAAUC,EAAUW,CAAC,CAAC,CACpD,CAEA,MAAc,WAAWX,EAA6C,CACpE,GAAM,CAAE,OAAAY,CAAO,EAAI,MAAMC,GAAQ,CAC/B,KAAM,SACN,KAAM,SACN,QAAS,cAAcC,GAAM,KAAKd,CAAQ,KAC1C,QAAS,CACP,CAAE,MAAO,MAAO,MAAO,OAAQ,EAC/B,CAAE,MAAO,KAAM,MAAO,MAAO,EAC7B,CAAE,MAAO,wBAAyB,MAAO,KAAM,EAC/C,CAAE,MAAO,OAAQ,MAAO,MAAO,CACjC,EACA,QAAS,CACX,CAAC,EAED,OAAIY,IAAW,OACb,KAAK,aAAe,GACb,SAGFA,GAAU,MACnB,CACF,EAEaG,EAAoB,IAAIZ,GPrGrC,eAAsBa,GACpBC,EACAC,EACsB,CACtB,IAAMC,EAAsB,CAAE,QAAS,CAAC,EAAG,QAAS,CAAC,EAAG,OAAQ,CAAC,CAAE,EAEnE,QAAWC,KAAQH,EAAO,CACxB,IAAMI,EAAWC,GAAK,WAAWF,EAAK,IAAI,EACtCA,EAAK,KACLE,GAAK,QAAQJ,EAAQ,IAAKA,EAAQ,WAAa,GAAIE,EAAK,IAAI,EAEhE,GAAI,CAEF,IAAIG,EAAcH,EAAK,QACvB,GAAII,EAAY,IAAI,gBAAgB,EAAG,CACrC,IAAMC,EAAa,MAAMD,EAAY,QAAQ,iBAAkB,CAC7D,MAAO,iBACP,KAAMH,EACN,YAAAE,EACA,IAAKL,EAAQ,GACf,CAAC,EACD,GAAIO,EAAW,QAAS,CACtBN,EAAO,QAAQ,KAAKE,CAAQ,EAC5B,SAEEI,EAAW,UAAU,cACvBF,EAAc,OAAOE,EAAW,SAAS,WAAW,GAKxD,IAAMC,EAAeJ,GAAK,SAASJ,EAAQ,IAAKG,CAAQ,EAClDM,EAAa,MAAMC,EAAkB,eAAeF,CAAY,EACtE,GAAIC,IAAe,OAAQ,CACzBR,EAAO,QAAQ,KAAKE,CAAQ,EAC5B,SAEF,GAAIM,IAAe,OAAQ,CAEzBR,EAAO,QAAQ,KAAKE,CAAQ,EAC5B,SAGF,GAAIQ,GAAWR,CAAQ,GAAK,CAACH,EAAQ,UAAW,CAC9CC,EAAO,QAAQ,KAAKE,CAAQ,EAC5B,SAGF,GAAIH,EAAQ,OAAQ,CAClBC,EAAO,QAAQ,KAAKE,CAAQ,EAC5B,SAIF,IAAMS,EAAMR,GAAK,QAAQD,CAAQ,EACjC,MAAMU,GAAG,MAAMD,EAAK,CAAE,UAAW,EAAK,CAAC,EAGvC,MAAMC,GAAG,UAAUV,EAAUE,EAAa,MAAM,EAChDJ,EAAO,QAAQ,KAAKE,CAAQ,EAGxBG,EAAY,IAAI,iBAAiB,GACnC,MAAMA,EAAY,QAAQ,kBAAmB,CAC3C,MAAO,kBACP,KAAMH,EACN,YAAAE,EACA,IAAKL,EAAQ,GACf,CAAC,CAEL,OAASc,EAAP,CACAb,EAAO,OAAO,KAAK,GAAGE,MAAaW,EAAM,SAAS,CACpD,EAGF,OAAOb,CACT,CAEO,SAASc,GACdC,EACAC,EACAC,EACQ,CACR,GAAIA,EAAW,OAAOA,EAEtB,IAAMC,EAASC,GAAeJ,CAAU,EACxC,GAAI,CAACG,EAAQ,MAAO,YAGpB,IAAIE,EAAUF,EAAO,QAErB,OAAIH,IAAe,cAEbC,EAAM,OACRI,EAAU,GAAGJ,EAAM,oBAEnBI,EAAU,cAIVL,IAAe,QAGfC,EAAM,WAAW,KAAMK,GAAMA,EAAE,OAAS,QAAQ,GAAKL,EAAM,SAE3DI,EAAU,GAAGJ,EAAM,cAInBD,IAAe,OACAC,EAAM,WAAW,KAAMK,GAAMA,EAAE,OAAS,QAAQ,IAE/DD,EAAUJ,EAAM,OAAS,GAAGA,EAAM,iBAAmB,WAIrDD,IAAe,SACbC,EAAM,QAAQ,SAAS,QAAQ,GAAKA,EAAM,QAAQ,SAAS,MAAM,KACnEI,EAAUJ,EAAM,QAAU,OAI1BD,IAAe,aACjBK,EAAU,qBAGRL,IAAe,WACbC,EAAM,UAAU,SAAS,QAAQ,EACnCI,EAAU,SACDJ,EAAM,SACfI,EAAU,GAAGJ,EAAM,mBAInBD,IAAe,UACjBK,EAAUJ,EAAM,OAAS,GAAGA,EAAM,gBAAkB,UAG/CI,CACT,CSjKA,OAAOE,OAAQ,KAGf,IAAMC,GAAkBC,GAAG,QAAQ,EAEtBC,GAAN,KAAsB,CAI3B,YAAoBC,EAAa,CAAb,SAAAA,EAElB,KAAK,WAAa,IAAIC,GAAOJ,EAAe,EAE5C,KAAK,cAAgB,IAAII,GAAOD,CAAG,CACrC,CARQ,WACA,cASR,MAAM,MAAsB,CAC1B,MAAM,QAAQ,IAAI,CAAC,KAAK,WAAW,KAAK,EAAG,KAAK,cAAc,KAAK,CAAC,CAAC,CACvE,CAEA,MAAM,MAAsB,CAC1B,MAAM,QAAQ,IAAI,CAAC,KAAK,WAAW,KAAK,EAAG,KAAK,cAAc,KAAK,CAAC,CAAC,CACvE,CAKA,mBAAmBE,EAAsB,CACvC,IAAMC,EAAU,KAAK,WAAW,mBAAmBD,CAAI,EACjDE,EAAa,KAAK,cAAc,mBAAmBF,CAAI,EAE7D,GAAI,CAACC,GAAW,CAACC,EAAY,MAAO,GAEpC,IAAMC,EAAqB,CAAC,EAC5B,OAAID,GACFC,EAAS,KAAKD,CAAU,EAEtBD,GAEFE,EAAS,KACPF,EAAQ,QACN,4CACA,0CACF,CACF,EAGKE,EAAS,KAAK;AAAA;AAAA,CAAM,CAC7B,CAKA,MAAM,gBAAgBC,EAAaC,EAAeC,EAA+B,CAC/E,MAAM,KAAK,WAAW,gBAAgBF,EAAKC,EAAOC,CAAM,CAC1D,CAKA,MAAM,iBACJC,EACiB,CACjB,OAAO,KAAK,cAAc,iBAAiBA,CAAK,CAClD,CAKA,gBAAmC,CACjC,IAAMC,EAAY,KAAK,WAAW,eAAe,EAC3CC,EAAe,KAAK,cAAc,eAAe,EAEjDC,EAAS,IAAI,IACnB,QAAWC,KAAKH,EACdE,EAAO,IAAIC,EAAE,IAAKA,CAAC,EAErB,QAAWA,KAAKF,EACdC,EAAO,IAAIC,EAAE,IAAKA,CAAC,EAErB,OAAO,MAAM,KAAKD,EAAO,OAAO,CAAC,CACnC,CAKA,aAAgC,CAC9B,IAAME,EAAe,KAAK,WAAW,YAAY,EAEjD,MAAO,CAAC,GADgB,KAAK,cAAc,YAAY,EAC3B,GAAGA,CAAY,CAC7C,CAKA,UAA0E,CACxE,MAAO,CACL,KAAM,KAAK,WAAW,SAAS,EAC/B,QAAS,KAAK,cAAc,SAAS,CACvC,CACF,CAKA,qBAAqBC,EAAQ,GAAmB,CAC9C,OAAO,KAAK,cAAc,qBAAqBA,CAAK,CACtD,CACF,EC5GA,OAAS,cAAAC,GAAY,gBAAAC,OAAoB,KACzC,OAAOC,OAAU,OAYV,SAASC,GAAiBC,EAAiBC,EAAyB,CACzE,OAAOD,EAAQ,QAAQ,eAAgB,CAACE,EAAOC,IAAqB,CAClE,IAAMC,EAAWC,GAAK,QAAQJ,EAASE,CAAQ,EAC/C,GAAIG,GAAWF,CAAQ,EACrB,GAAI,CACF,OAAOG,GAAaH,EAAU,MAAM,CACtC,MAAE,CACA,OAAOF,CACT,CAEF,OAAOA,CACT,CAAC,CACH,CAKO,SAASM,GAAwBC,EAAqB,CAC3D,IAAMC,EAAa,CAAC,YAAa,WAAW,EAC5C,QAAWC,KAAQD,EAAY,CAC7B,IAAMP,EAAWE,GAAK,KAAKI,EAAKE,CAAI,EACpC,GAAIL,GAAWH,CAAQ,EACrB,GAAI,CACF,IAAIH,EAAUO,GAAaJ,EAAU,MAAM,EAC3C,OAAAH,EAAUD,GAAiBC,EAASS,CAAG,EAChCT,CACT,MAAE,CAEF,EAGJ,MAAO,EACT,CAKA,SAASY,GAAeZ,EAAyB,CAC/C,OAAO,KAAK,KAAKA,EAAQ,OAAS,CAAC,CACrC,CAEO,IAAMa,GAAN,KAAqB,CAClB,SAA6B,CAAC,EAEtC,WAAWC,EAAed,EAAiBe,EAAW,GAAU,CACzDf,EAAQ,KAAK,GAClB,KAAK,SAAS,KAAK,CAAE,MAAAc,EAAO,QAAAd,EAAS,SAAAe,CAAS,CAAC,CACjD,CAKA,aAAaC,EAAcC,EAAY,KAAe,CACpD,GAAI,KAAK,SAAS,SAAW,EAAG,MAAO,GAGvC,IAAMC,EAAO,KAAK,SAAS,IAAKC,GAAMA,EAAE,OAAO,EACzCC,EAAQC,GAAWH,CAAI,EACvBI,EAAcC,GAASP,EAAMI,CAAK,EAClCI,EAAW,IAAI,IAAIF,EAAY,IAAKG,GAAM,CAACA,EAAE,SAAUA,EAAE,KAAK,CAAC,CAAC,EAEhEC,EAAS,KAAK,SAAS,IAAI,CAACP,EAAGQ,KAAO,CAC1C,GAAGR,EACH,UAAWK,EAAS,IAAIG,CAAC,GAAK,EAC9B,OAAQf,GAAeO,EAAE,OAAO,CAClC,EAAE,EAGFO,EAAO,KACL,CAACE,EAAGC,IAAMA,EAAE,SAAWA,EAAE,UAAY,KAAOD,EAAE,SAAWA,EAAE,UAAY,IACzE,EAGA,IAAME,EAA0B,CAAC,EAC7BC,EAAc,EAElB,QAAWC,KAAWN,EAChBK,EAAcC,EAAQ,OAASf,GAAaa,EAAS,OAAS,IAIlEA,EAAS,KAAKE,CAAO,EACrBD,GAAeC,EAAQ,QAGzB,OAAOF,EAAS,IAAKX,GAAMA,EAAE,OAAO,EAAE,KAAK;AAAA;AAAA,CAAM,CACnD,CACF,ECpGA,OAAS,YAAYc,OAAU,KAC/B,OAAOC,OAAU,OACjB,OAAS,SAAAC,OAAa,QACtB,OAAOC,OAAQ,YCUR,IAAMC,GAAmB,CAC9B,gBACA,cACA,cACA,cACA,kBACA,mBACA,oBACF,EAIaC,GAAgC,CAC3C,CACE,KAAM,gBACN,YACE,oJACF,aAAc,CAAE,KAAM,SAAU,WAAY,CAAC,EAAG,qBAAsB,EAAM,EAC5E,WAAY,MACd,EACA,CACE,KAAM,cACN,YACE,iHACF,aAAc,CACZ,KAAM,SACN,WAAY,CACV,WAAY,CAAE,KAAM,SAAU,YAAa,kCAAmC,CAChF,EACA,SAAU,CAAC,YAAY,EACvB,qBAAsB,EACxB,EACA,WAAY,MACd,EACA,CACE,KAAM,cACN,YACE,gIACF,aAAc,CACZ,KAAM,SACN,WAAY,CACV,QAAS,CAAE,KAAM,SAAU,YAAa,wCAAyC,EACjF,WAAY,CAAE,KAAM,SAAU,YAAa,oCAAgC,EAC3E,gBAAiB,CACf,KAAM,SACN,YAAa,uEACf,CACF,EACA,SAAU,CAAC,SAAS,EACpB,qBAAsB,EACxB,EACA,WAAY,MACd,EACA,CACE,KAAM,cACN,YACE,mIACF,aAAc,CACZ,KAAM,SACN,WAAY,CACV,QAAS,CAAE,KAAM,QAAS,EAC1B,OAAQ,CACN,KAAM,SACN,KAAM,CAAC,SAAU,SAAU,YAAa,WAAW,CACrD,EACA,QAAS,CAAE,KAAM,QAAS,EAC1B,eAAgB,CAAE,KAAM,QAAS,EACjC,YAAa,CAAE,KAAM,QAAS,CAChC,EACA,SAAU,CAAC,SAAS,EACpB,qBAAsB,EACxB,EACA,WAAY,MACd,EACA,CACE,KAAM,kBACN,YACE,gNACF,aAAc,CACZ,KAAM,SACN,WAAY,CACV,QAAS,CAAE,KAAM,QAAS,EAC1B,KAAM,CACJ,KAAM,SACN,KAAM,CACJ,OAAQ,UAAW,SAAU,WAAY,WAAY,aACrD,QAAS,cAAe,eAAgB,QAAS,QAAS,QAAS,OACrE,CACF,EACA,MAAO,CAAE,KAAM,SAAU,YAAa,kDAA8C,EACpF,IAAK,CAAE,KAAM,SAAU,YAAa,6BAA8B,EAClE,UAAW,CAAE,KAAM,QAAS,CAC9B,EACA,SAAU,CAAC,UAAW,OAAQ,QAAS,KAAK,EAC5C,qBAAsB,EACxB,EACA,WAAY,MACd,EACA,CACE,KAAM,mBACN,YACE,0FACF,aAAc,CACZ,KAAM,SACN,WAAY,CACV,WAAY,CAAE,KAAM,QAAS,EAC7B,QAAS,CAAE,KAAM,QAAS,CAC5B,EACA,qBAAsB,EACxB,EACA,WAAY,MACd,EACA,CACE,KAAM,qBACN,YACE,0IACF,aAAc,CAAE,KAAM,SAAU,WAAY,CAAC,EAAG,qBAAsB,EAAM,EAC5E,WAAY,MACd,CACF,EAiBA,eAAsBC,GACpBC,EACAC,EACAC,EACiD,CACjD,IAAMC,EACJ,QAAQ,IAAI,0BACZ,QAAQ,IAAI,qBACZ,QAAQ,IAAI,wBACd,GAAI,CAACA,EACH,MAAO,CACL,QAAS,KAAK,UAAU,CAAE,GAAI,GAAO,MAAO,+CAAgD,CAAC,EAC7F,SAAU,EACZ,EAGF,IAAMC,EAAM,IADIF,EAAI,QAAU,QAAQ,IAAI,eAAiB,oBACpC,QAAQ,MAAO,EAAE,oBAElCG,EAAO,CAAE,KAAML,EAAU,QAASE,EAAI,OAAQ,GAAID,GAAS,CAAC,CAAG,EAQ/DK,EAAY,OAAO,QAAQ,IAAI,uBAAyB,GAAM,EAC9DC,EAAa,IAAI,gBACjBC,EAAQ,WAAW,IAAMD,EAAW,MAAM,EAAGD,CAAS,EAE5D,GAAI,CACF,IAAMG,EAAM,MAAM,MAAML,EAAK,CAC3B,OAAQ,OACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAUD,IACzB,aAAcD,EAAI,SAAW,cAC/B,EACA,KAAM,KAAK,UAAUG,CAAI,EACzB,OAAQE,EAAW,MACrB,CAAC,EACKG,EAAO,MAAMD,EAAI,KAAK,EACtBE,EAAM,EAAI,KACVC,EAAUF,EAAK,OAASC,EAAMD,EAAK,MAAM,EAAGC,CAAG,EAAI,oBAAiBD,EAC1E,OAAKD,EAAI,GAGF,CAAE,QAASG,EAAS,SAAU,EAAM,EAFlC,CAAE,QAASA,EAAS,SAAU,EAAK,CAG9C,OAASC,EAAP,CACA,IAAMC,EAAUD,GAAK,OAAS,aAC9B,MAAO,CACL,QAAS,KAAK,UAAU,CACtB,GAAI,GACJ,MAAOC,EAAU,kCAAkCR,MAAgB,wBACnE,OAAQO,GAAK,SAAW,SAC1B,CAAC,EACD,SAAU,EACZ,CACF,QAAE,CACA,aAAaL,CAAK,CACpB,CACF,CAEO,SAASO,GAAYC,EAAqC,CAC/D,OAAQnB,GAAuC,SAASmB,CAAI,CAC9D,CD5KO,IAAMC,GAAN,KAAmB,CAChB,IACA,QAER,YAAYC,EAAaC,EAA+B,CAAC,EAAG,CAC1D,KAAK,IAAMD,EACX,KAAK,QAAUC,CACjB,CAEA,MAAM,QAAQC,EAA0C,CAGtD,GAFAC,EAAM,QAAQ,gBAAiB,cAAcD,EAAK,MAAM,EAEpD,KAAK,QAAQ,aAAa,QAC5B,MAAO,CACL,YAAaA,EAAK,GAClB,QAAS,uCACT,SAAU,EACZ,EAIF,GAAIE,EAAY,IAAI,eAAe,EAAG,CACpC,IAAMC,EAAa,MAAMD,EAAY,QAAQ,gBAAiB,CAC5D,MAAO,gBACP,SAAUF,EAAK,KACf,UAAWA,EAAK,MAChB,IAAK,KAAK,GACZ,CAAC,EACD,GAAIG,EAAW,QACb,MAAO,CACL,YAAaH,EAAK,GAClB,QAASG,EAAW,SAAW,QAAQH,EAAK,qCAC5C,SAAU,EACZ,EAIJ,IAAII,EAEJ,GAAI,CAKF,GAAI,KAAK,QAAQ,cAAgBC,GAAYL,EAAK,IAAI,EAAG,CACvD,IAAMM,EAAM,MAAMC,GAAiBP,EAAK,KAAMA,EAAK,MAAO,KAAK,QAAQ,YAAY,EACnFI,EAAS,CACP,YAAaJ,EAAK,GAClB,QAASM,EAAI,QACb,SAAUA,EAAI,QAChB,MAEA,QAAQN,EAAK,KAAM,CACjB,IAAK,YACHI,EAAS,MAAM,KAAK,SAASJ,CAAI,EACjC,MACF,IAAK,eACHI,EAAS,MAAM,KAAK,YAAYJ,CAAI,EACpC,MACF,IAAK,iBACHI,EAAS,MAAM,KAAK,cAAcJ,CAAI,EACtC,MACF,IAAK,cACHI,EAAS,MAAM,KAAK,WAAWJ,CAAI,EACnC,MACF,IAAK,YACHI,EAAS,MAAM,KAAK,SAASJ,CAAI,EACjC,MACF,IAAK,eACHI,EAAS,MAAM,KAAK,YAAYJ,CAAI,EACpC,MACF,IAAK,WACHI,EAAS,MAAM,KAAK,QAAQJ,CAAI,EAChC,MACF,IAAK,cACHI,EAAS,MAAM,KAAK,WAAWJ,CAAI,EACnC,MACF,QACEI,EAAS,CACP,YAAaJ,EAAK,GAClB,QAAS,iBAAiBA,EAAK,OAC/B,SAAU,EACZ,CACJ,CAEJ,OAASQ,EAAP,CACAJ,EAAS,CACP,YAAaJ,EAAK,GAClB,QAAS,mBAAmBA,EAAK,SAASQ,EAAM,UAChD,SAAU,EACZ,CACF,CAGA,OAAIN,EAAY,IAAI,gBAAgB,GAClC,MAAMA,EAAY,QAAQ,iBAAkB,CAC1C,MAAO,iBACP,SAAUF,EAAK,KACf,UAAWA,EAAK,MAChB,WAAYI,EAAO,QACnB,IAAK,KAAK,GACZ,CAAC,EAGIA,CACT,CAEA,MAAc,SAASJ,EAA0C,CAC/D,IAAMS,EAAW,OAAOT,EAAK,MAAM,MAAQ,EAAE,EACvCU,EAAW,OAAOV,EAAK,MAAM,SAAS,GAAK,IAC3CW,EAAUC,GAAK,QAAQ,KAAK,IAAKH,CAAQ,EAEzCI,EAAU,MAAMC,GAAG,SAASH,EAAS,MAAM,EAC3CI,EAAQF,EAAQ,MAAM;AAAA,CAAI,EAE1BG,EADYD,EAAM,OAASL,EAE7BK,EAAM,MAAM,EAAGL,CAAQ,EAAE,KAAK;AAAA,CAAI,EAAI;AAAA;AAAA,kBAAuBK,EAAM,OAASL,gBAC5EG,EAEJ,MAAO,CACL,YAAab,EAAK,GAClB,QAASgB,CACX,CACF,CAEA,MAAc,YAAYhB,EAA0C,CAClE,IAAMiB,EAAU,OAAOjB,EAAK,MAAM,SAAW,MAAM,EAC7CkB,EAAelB,EAAK,MAAM,cAAgB,OAAOA,EAAK,MAAM,aAAa,EAAI,OAC7EmB,EAAa,OAAOnB,EAAK,MAAM,WAAW,GAAK,GAE/CoB,EAAQ,MAAMC,GAAGJ,EAAS,CAC9B,IAAK,KAAK,IACV,OAAQ,CAAC,kBAAmB,UAAW,UAAW,UAAU,EAC5D,IAAK,EACP,CAAC,EAED,GAAI,CAACC,EAAc,CACjB,IAAMI,EAAUF,EAAM,MAAM,EAAGD,CAAU,EACzC,MAAO,CACL,YAAanB,EAAK,GAClB,QAASsB,EAAQ,OACbA,EAAQ,KAAK;AAAA,CAAI,GAAKF,EAAM,OAASD,EAAa;AAAA;AAAA,OAAYC,EAAM,OAASD,gBAA2B,IACxG,+BACN,EAIF,IAAMI,EAAQ,IAAI,OAAOL,EAAc,IAAI,EACrCM,EAAoB,CAAC,EAE3B,QAAWC,KAAQL,EAAO,CACxB,GAAII,EAAQ,QAAUL,EAAY,MAClC,GAAI,CAEF,IAAMJ,GADU,MAAMD,GAAG,SAASF,GAAK,QAAQ,KAAK,IAAKa,CAAI,EAAG,MAAM,GAChD,MAAM;AAAA,CAAI,EAChC,QAASC,EAAI,EAAGA,EAAIX,EAAM,QACpB,EAAAS,EAAQ,QAAUL,GADUO,IAE5BH,EAAM,KAAKR,EAAMW,CAAC,CAAC,GACrBF,EAAQ,KAAK,GAAGC,KAAQC,EAAI,MAAMX,EAAMW,CAAC,GAAG,EAE9CH,EAAM,UAAY,CAEtB,MAAE,CAEF,EAGF,MAAO,CACL,YAAavB,EAAK,GAClB,QAASwB,EAAQ,OACbA,EAAQ,KAAK;AAAA,CAAI,EACjB,mBACN,CACF,CAEA,MAAc,cAAcxB,EAA0C,CACpE,IAAM2B,EAAU,OAAO3B,EAAK,MAAM,MAAQ,GAAG,EACvC4B,EAAY,EAAQ5B,EAAK,MAAM,UAC/B6B,EAAW,OAAO7B,EAAK,MAAM,SAAS,GAAK,EAC3CW,EAAUC,GAAK,QAAQ,KAAK,IAAKe,CAAO,EAE9C,GAAIC,EAAW,CAEb,IAAME,EAAU,MAAMT,GADN,OACkB,CAChC,IAAKV,EACL,UAAW,GACX,gBAAiB,GACjB,KAAMkB,EACN,OAAQ,CAAC,kBAAmB,UAAW,UAAW,UAAU,CAC9D,CAAC,EACD,MAAO,CACL,YAAa7B,EAAK,GAClB,QAAS8B,EAAQ,OAASA,EAAQ,KAAK;AAAA,CAAI,EAAI,kBACjD,EAIF,IAAMC,GADU,MAAMjB,GAAG,QAAQH,EAAS,CAAE,cAAe,EAAK,CAAC,GACvC,IAAKqB,GAC7BA,EAAE,YAAY,EAAI,GAAGA,EAAE,QAAUA,EAAE,IACrC,EAEA,MAAO,CACL,YAAahC,EAAK,GAClB,QAAS+B,EAAU,OAASA,EAAU,KAAK;AAAA,CAAI,EAAI,kBACrD,CACF,CAEA,MAAc,WAAW/B,EAA0C,CACjE,IAAMiC,EAAU,OAAOjC,EAAK,MAAM,SAAW,EAAE,EACzCkC,EAAU,OAAOlC,EAAK,MAAM,OAAO,GAAK,IAI9C,GADmB,MAAMmC,EAAkB,aAAaF,CAAO,IAC5C,OACjB,MAAO,CACL,YAAajC,EAAK,GAClB,QAAS,yCAAyCmC,EAAkB,QAAQ,OAAOF,IACnF,SAAU,EACZ,EAIF,GAAI/B,EAAY,IAAI,aAAa,EAAG,CAClC,IAAMC,EAAa,MAAMD,EAAY,QAAQ,cAAe,CAC1D,MAAO,cACP,QAAA+B,EACA,IAAK,KAAK,GACZ,CAAC,EACD,GAAI9B,EAAW,QACb,MAAO,CACL,YAAaH,EAAK,GAClB,QAASG,EAAW,SAAW,wCAAwC8B,IACvE,SAAU,EACZ,EAIJ,IAAM7B,EAAS,MAAMgC,GAAM,KAAM,CAAC,KAAMH,CAAO,EAAG,CAChD,IAAK,KAAK,IACV,QAAAC,EACA,OAAQ,GACR,MAAO,SACP,OAAQ,KAAK,QAAQ,WACvB,CAAC,EAEKlB,EAAS,CAACZ,EAAO,OAAQA,EAAO,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK;AAAA,CAAI,EACjEiC,EAAYrB,EAAO,OAAS,IAC9BA,EAAO,MAAM,EAAG,GAAM,EAAI;AAAA;AAAA,wBAC1BA,EAEJ,OAAIZ,EAAO,WAAa,EACf,CACL,YAAaJ,EAAK,GAClB,QAAS,4BAA4BI,EAAO;AAAA,EAAciC,IAC1D,SAAU,EACZ,EAGK,CACL,YAAarC,EAAK,GAClB,QAASqC,GAAa,aACxB,CACF,CAEA,MAAc,SAASrC,EAA0C,CAC/D,IAAMS,EAAW,OAAOT,EAAK,MAAM,MAAQ,EAAE,EACvCsC,EAAQtC,EAAK,MAAM,MACnBW,EAAUC,GAAK,QAAQ,KAAK,IAAKH,CAAQ,EAE/C,GAAI,CAAC6B,GAASA,EAAM,SAAW,EAC7B,MAAO,CACL,YAAatC,EAAK,GAClB,QAAS,qBACT,SAAU,EACZ,EAIF,IAAMuC,EAAa,MAAMJ,EAAkB,eAAe1B,CAAQ,EAClE,GAAI8B,IAAe,OACjB,MAAO,CACL,YAAavC,EAAK,GAClB,QAAS,sCAAsCS,IAC/C,SAAU,EACZ,EAEF,GAAI8B,IAAe,OACjB,MAAO,CACL,YAAavC,EAAK,GAClB,QAAS,mCAAmCS,GAC9C,EAIF,GAAIP,EAAY,IAAI,gBAAgB,EAAG,CACrC,IAAMC,EAAa,MAAMD,EAAY,QAAQ,iBAAkB,CAC7D,MAAO,iBACP,KAAMS,EACN,IAAK,KAAK,GACZ,CAAC,EACD,GAAIR,EAAW,QACb,MAAO,CACL,YAAaH,EAAK,GAClB,QAASG,EAAW,SAAW,6CAA6CM,IAC5E,SAAU,EACZ,EAIJ,IAAII,EAAU,MAAMC,GAAG,SAASH,EAAS,MAAM,EACzC6B,EAAoB,CAAC,EAE3B,QAAWC,KAAQH,EACbzB,EAAQ,SAAS4B,EAAK,QAAQ,GAChC5B,EAAUA,EAAQ,QAAQ4B,EAAK,SAAUA,EAAK,QAAQ,EACtDD,EAAQ,KAAK,cAAcC,EAAK,SAAS,MAAM,EAAG,EAAE,OAAO,GAE3DD,EAAQ,KAAK,eAAeC,EAAK,SAAS,MAAM,EAAG,EAAE,OAAO,EAIhE,OAAK,KAAK,QAAQ,QAChB,MAAM3B,GAAG,UAAUH,EAASE,EAAS,MAAM,EAIzCX,EAAY,IAAI,iBAAiB,GACnC,MAAMA,EAAY,QAAQ,kBAAmB,CAC3C,MAAO,kBACP,KAAMS,EACN,YAAaE,EACb,IAAK,KAAK,GACZ,CAAC,EAGI,CACL,YAAab,EAAK,GAClB,QAAS,UAAUS;AAAA,EAAc+B,EAAQ,KAAK;AAAA,CAAI,GACpD,CACF,CAEA,MAAc,YAAYxC,EAA0C,CAClE,IAAM0C,EAAQ1C,EAAK,MAKboB,EAAQsB,EAAM,OAAS,CAAC,EAE9B,MAAO,CACL,YAAa1C,EAAK,GAClB,QAAS0C,EAAM,SAAW,UAAUtB,EAAM,+BAC1C,MAAAA,CACF,CACF,CAEA,MAAc,WAAWpB,EAA0C,CACjE,IAAM2C,EAAU,OAAO3C,EAAK,MAAM,UAAY,EAAE,EAC1C4C,EAAS,OAAO5C,EAAK,MAAM,QAAU,EAAE,EACvC6C,EAAiB,OAAO7C,EAAK,MAAM,eAAe,GAAK,IAE7D,GAAI,CAAC2C,GAAW,CAACC,EACf,MAAO,CACL,YAAa5C,EAAK,GAClB,QAAS,oCACT,SAAU,EACZ,EAGF,GAAI,CAEF,GAAM,CAAE,gBAAA8C,CAAgB,EAAI,KAAM,QAAO,wBAAmB,EAGtD,CAAE,kBAAAC,CAAkB,EAAI,KAAM,QAAO,wBAAmB,EACxDC,EAAWD,EAAkB,EAEnC,GAAI,CAACC,EACH,MAAO,CACL,YAAahD,EAAK,GAClB,QAAS,wDACT,SAAU,EACZ,EAIF,IAAMI,EAAS,MADC,IAAI0C,EAAgBE,CAAQ,EACf,MAAM,CACjC,cAAeL,EACf,OAAAC,EACA,cAAe,eACf,QAASC,EAAiB,GAC5B,CAAC,EAED,OAAIzC,EAAO,QACF,CACL,YAAaJ,EAAK,GAClB,QAAS,cAAc2C,iBAAuB,KAAK,MAAMvC,EAAO,SAAW,GAAI;AAAA;AAAA,EAAWA,EAAO,SACnG,EAEO,CACL,YAAaJ,EAAK,GAClB,QAAS,cAAc2C,cAAoBvC,EAAO,QAClD,SAAU,EACZ,CAEJ,OAASI,EAAP,CACA,MAAO,CACL,YAAaR,EAAK,GAClB,QAAS,8BAA8BQ,EAAM,UAC7C,SAAU,EACZ,CACF,CACF,CAEA,MAAc,QAAQR,EAA0C,CAC9D,IAAMiD,EAAW,OAAOjD,EAAK,MAAM,UAAY,EAAE,EAC3CD,EAAUC,EAAK,MAAM,QAEvBkD,EAAWD,EACf,OAAIlD,GAAS,SACXmD,GAAY;AAAA,WAAcnD,EAAQ,KAAK,IAAI,KAGtC,CACL,YAAaC,EAAK,GAClB,QAAS,yBACT,SAAAkD,CACF,CACF,CACF,EE3YA,eAAsBC,GAAeC,EAAqD,CACxF,GAAM,CACJ,SAAAC,EACA,aAAAC,EACA,SAAUC,EACV,gBAAiBC,EACjB,IAAAC,EACA,cAAAC,EAAgB,GAChB,aAAAC,EACA,YAAAC,EAAc,GACd,UAAAC,EAAY,GACZ,OAAAC,EAAS,GACT,WAAAC,EACA,YAAAC,CACF,EAAIZ,EAMEa,EAAmCD,EACrC,CAAE,GAAGR,EAAoB,YAAAQ,CAAY,EACrCR,EAGJ,GAAI,CAACH,EAAS,YACZ,OAAOa,GAAcd,CAAO,EAG9B,IAAMe,EAAW,IAAIC,GAAaX,EAAK,CACrC,YAAAG,EACA,UAAAC,EACA,OAAAC,EACA,aAAcV,EAAQ,aACtB,YAAAY,CACF,CAAC,EACKK,EAAQC,GAAkBX,CAAY,EAI5C,GAAIP,EAAQ,aACV,QAAWmB,KAAKC,GACdH,EAAM,KAAK,CAAE,KAAME,EAAE,KAAM,YAAaA,EAAE,YAAa,aAAcA,EAAE,YAAa,CAAC,EAMzF,IAAME,EAAe,IAAI,IACzB,GAAIrB,EAAQ,UAAU,OACpB,QAAWmB,KAAKnB,EAAQ,SACtBiB,EAAM,KAAK,CAAE,KAAME,EAAE,KAAM,YAAaA,EAAE,YAAa,aAAcA,EAAE,YAAa,CAAC,EACrFE,EAAa,IAAIF,EAAE,IAAI,EAK3B,IAAMG,EAAwCnB,EAC3C,OAAQoB,GAAMA,EAAE,OAAS,QAAQ,EACjC,IAAKA,IAAO,CACX,KAAMA,EAAE,KACR,QAASA,EAAE,OACb,EAAE,EAEEC,EAA4B,CAAC,EAC/BC,EAAc,EACdC,EAAmB,EACnBC,EAAoB,EACpBC,EAAc,GACdC,EACAC,EAAY,EAEhB,KAAOA,EAAYxB,GAAe,CAIhC,GAHAwB,IAGIlB,GAAa,QACf,MAAM,IAAI,MAAM,WAAW,EAE7BD,IAAa,CAAE,KAAM,kBAAmB,UAAAmB,CAAU,CAAC,EACnDC,EAAM,KAAKD,EAAW,2BAA2Bb,EAAM,yBAAyB,EAahF,IAAIe,EACEC,EAAe,CAAC,CAAChC,EAAS,mBAAqB,CAAC,CAACU,EACvD,GAAI,CACF,GAAIsB,EAAc,CAKhB,IAAIC,EAA6C,KAC7CC,EAA6B,KAC7BC,EAA4B,GAChC,cAAiBC,KAAMpC,EAAS,kBAC9BqB,EACApB,EACAe,EACAJ,CACF,EACMwB,EAAG,OAAS,cACdD,GAA6BC,EAAG,KAMhC1B,IAAa,CAAE,KAAM,aAAc,KAAM0B,EAAG,IAAK,CAAC,GACzCA,EAAG,OAAS,iBAMrB1B,IAAa,CAAE,KAAM,iBAAkB,KAAM0B,EAAG,IAAK,CAAC,EAC7CA,EAAG,OAAS,aACrBH,EAAiBG,EAAG,OACXA,EAAG,OAAS,UACrBF,EAAcE,EAAG,OAGrB,GAAIF,GAAe,CAACD,EAClB,MAAM,IAAI,MAAMC,CAAW,EAE7B,GAAI,CAACD,EACH,MAAM,IAAI,MAAM,gDAAgD,EAElEF,EAASE,EAGPF,EAAe,cAAgBI,OAEjCJ,EAAS,MAAM/B,EAAS,YACtBqB,EACApB,EACAe,EACAJ,CACF,CAEJ,OAASyB,EAAP,CAEA,GAAIA,EAAM,SAAS,SAAS,eAAe,EACzC,OAAOxB,GAAcd,CAAO,EAE9B,MAAMsC,CACR,CAEAb,GAAeO,EAAO,MAAM,aAAeA,EAAO,MAAM,cACxDN,GAAoBM,EAAO,MAAM,aACjCL,GAAqBK,EAAO,MAAM,cAMlC,IAAMO,EAAoCP,EAAe,cACzD,QAAWQ,KAASR,EAAO,QACrBQ,EAAM,OAAS,SACjBZ,GAAeY,EAAM,KACjBD,IAAiB,QAEnB5B,IAAa,CAAE,KAAM,aAAc,KAAM6B,EAAM,IAAK,CAAC,GAO3D,GAHID,IAAiB,QAAW,OAAQP,EAAe,cAGnDA,EAAO,cAAgB,YAAcA,EAAO,cAAgB,aAC9D,MAIF,GAAIA,EAAO,cAAgB,WAAY,CACrC,IAAMS,EAAgBT,EAAO,QAAQ,OAClCU,GAAwDA,EAAE,OAAS,UACtE,EAEA,GAAID,EAAc,SAAW,EAAG,MAGhCnB,EAAkB,KAAK,CACrB,KAAM,YACN,QAASU,EAAO,OAClB,CAAC,EAGD,IAAMW,EAA8B,CAAC,EAErC,QAAWC,KAAaH,EAAe,CACrC9B,IAAa,CACX,KAAM,YACN,KAAMiC,EAAU,KAChB,GAAIA,EAAU,GACd,MAAOA,EAAU,KACnB,CAAC,EAEDb,EAAM,KAAKD,EAAW,cAAcc,EAAU,MAAM,EAEpD,IAAIC,EACJ,GAAIxB,EAAa,IAAIuB,EAAU,IAAI,GAAK5C,EAAQ,YAAa,CAC3D,IAAM8C,EAAI,MAAM9C,EAAQ,YAAY4C,EAAU,KAAMA,EAAU,KAAK,EACnEC,EAAa,CACX,YAAaD,EAAU,GACvB,QAASE,EAAE,QACX,SAAUA,EAAE,OACd,OAEAD,EAAa,MAAM9B,EAAS,QAAQ,CAClC,KAAM6B,EAAU,KAChB,GAAIA,EAAU,GACd,MAAOA,EAAU,KACnB,CAAC,EAGHjC,IAAa,CACX,KAAM,cACN,KAAMiC,EAAU,KAChB,GAAIA,EAAU,GACd,QAASC,EAAW,QAAQ,MAAM,EAAG,GAAG,EACxC,SAAUA,EAAW,QACvB,CAAC,EAGGA,EAAW,OAAO,SACpBrB,EAAS,KAAK,GAAGqB,EAAW,KAAK,EACjClC,IAAa,CAAE,KAAM,gBAAiB,MAAOkC,EAAW,KAAM,CAAC,GAI7DA,EAAW,WACbhB,EAAWgB,EAAW,UAGxBF,EAAY,KAAK,CACf,KAAM,cACN,YAAaE,EAAW,YACxB,QAASA,EAAW,QACpB,SAAUA,EAAW,QACvB,CAAC,EAUH,GANAvB,EAAkB,KAAK,CACrB,KAAM,OACN,QAASqB,CACX,CAAC,EAGGd,EAAU,MAEd,SAIF,MAGF,OAAAlB,IAAa,CAAE,KAAM,WAAY,WAAYmB,EAAW,YAAAL,CAAY,CAAC,EAE9D,CACL,MAAOD,EACP,QAASI,EACT,SAAAC,EACA,WAAYJ,EACZ,YAAaC,GAAoB,OACjC,aAAcC,GAAqB,OACnC,WAAYG,CACd,CACF,CAQA,eAAehB,GAAcd,EAAqD,CAChF,GAAM,CACJ,SAAAC,EACA,aAAAC,EACA,SAAUC,EACV,gBAAAU,EACA,cAAAP,EAAgB,CAClB,EAAIN,EAKE+C,EAAgC,CACpC,CAAE,KAAM,SAAU,QAHS7C,EAAe;AAAA;AAAA,EAAS8C,GAA2B,CAG9B,EAChD,GAAG7C,EAAc,OAAQ,GAAM,EAAE,OAAS,QAAQ,CACpD,EAEMqB,EAA4B,CAAC,EAC/BC,EAAc,EACdwB,EAAU,GACVpB,EACAqB,EAAO,EAEX,KAAOA,EAAO5C,GAAe,CAC3B4C,IACAnB,EAAM,KAAKmB,EAAM,4BAA4BrC,EAAgB,OAAS,YAAY,EAElF,IAAMmB,EAAS,MAAM/B,EAAS,SAAS8C,EAAUlC,CAAe,EAShE,GAPAY,GAAeO,EAAO,YAAc,EACpCiB,EAAUjB,EAAO,QAEbA,EAAO,MAAM,QACfR,EAAS,KAAK,GAAGQ,EAAO,KAAK,EAG3BA,EAAO,SAAU,CACnBH,EAAWG,EAAO,SAClB,MAWF,GARIA,EAAO,MAAM,SAAW,GAAKkB,EAAO,GAQpC,EALFlB,EAAO,QAAQ,SAAS,YAAY,GACpCA,EAAO,QAAQ,SAAS,YAAY,GACpCA,EAAO,QAAQ,SAAS,YAAY,GACpCA,EAAO,QAAQ,SAAS,oBAAoB,GAEtB,MAExB,IAAMmB,EAAenB,EAAO,MACzB,IAAKoB,GAAM,YAAYA,EAAE,OAAOA,EAAE,YAAc,WAAMA,EAAE,cAAgB,IAAI,EAC5E,KAAK;AAAA,CAAI,EAEZL,EAAS,KAAK,CACZ,KAAM,YACN,QAASf,EAAO,SAAWmB,EAAe;AAAA;AAAA;AAAA,EAAuBA,IAAiB,GACpF,CAAC,EAEDJ,EAAS,KAAK,CACZ,KAAM,OACN,QACE,2IACJ,CAAC,EAGH,MAAO,CACL,MAAOvB,EACP,QAAAyB,EACA,SAAApB,EACA,WAAYJ,EACZ,WAAYyB,CACd,CACF,CAKO,SAASG,GAAoBpD,EAAkC,CACpE,OAAO,OAAOA,EAAS,aAAgB,UACzC,CC/aA,OAAS,SAAAqD,OAAgC,gBAsCzC,IAAMC,GAAmB,aACnBC,GAAkB,KAClBC,GAAkB,KAClBC,GAAc,QAEpB,SAASC,GAAWC,EAA0C,CAC5D,OAAQA,EAAqB,OAAS,MACxC,CAWA,IAAMC,GAAN,KAA0C,CAUxC,YAA6BC,EAAcF,EAAoB,CAAlC,UAAAE,EAC3B,KAAK,KAAOC,GAAMH,EAAK,QAASA,EAAK,MAAQ,CAAC,EAAG,CAC/C,MAAO,CAAC,OAAQ,OAAQ,MAAM,EAC9B,IAAK,CAAE,GAAG,QAAQ,IAAK,GAAIA,EAAK,KAAO,CAAC,CAAG,CAC7C,CAAC,EACD,KAAK,KAAK,OAAQ,YAAY,OAAO,EACrC,KAAK,KAAK,OAAQ,GAAG,OAASI,GAAkB,KAAK,OAAOA,CAAK,CAAC,EAClE,KAAK,KAAK,OAAQ,YAAY,OAAO,EACrC,KAAK,KAAK,OAAQ,GAAG,OAASA,GAC5BC,EAAM,QAAQ,MAAO,GAAGH,aAAgBE,EAAM,QAAQ,GAAG,CAC3D,EACA,KAAK,KAAK,GAAG,OAASE,GAAS,CAC7B,KAAK,OAAS,GACdD,EAAM,QAAQ,MAAO,GAAGH,mBAAsBI,IAAO,EACrD,OAAW,CAAC,CAAEC,CAAC,IAAK,KAAK,QACvB,aAAaA,EAAE,KAAK,EACpBA,EAAE,OAAO,IAAI,MAAM,eAAeL,WAAc,CAAC,EAEnD,KAAK,QAAQ,MAAM,CACrB,CAAC,EACD,KAAK,KAAK,GAAG,QAAUM,GAAa,CAClCH,EAAM,QAAQ,MAAO,GAAGH,mBAAsBM,EAAE,SAAS,CAC3D,CAAC,CACH,CAhCQ,KACA,OAAS,GACT,OAAS,EACT,QAAU,IAAI,IAId,OAAS,GA2BjB,QAAQC,EAAgBC,EAAiCC,EAAqC,CAC5F,GAAI,KAAK,OAAQ,OAAO,QAAQ,OAAO,IAAI,MAAM,eAAe,KAAK,iBAAiB,CAAC,EACvF,IAAMC,EAAK,KAAK,SACVC,EAAU,KAAK,UAAU,CAAE,QAAS,MAAO,GAAAD,EAAI,OAAAH,EAAQ,OAAAC,CAAO,CAAC,EAAI;AAAA,EACzE,OAAO,IAAI,QAAQ,CAACI,EAASC,IAAW,CACtC,IAAMC,EAAQ,WAAW,IAAM,CAC7B,KAAK,QAAQ,OAAOJ,CAAE,EACtBG,EAAO,IAAI,MAAM,QAAQ,KAAK,SAASN,mBAAwBE,KAAa,CAAC,CAC/E,EAAGA,CAAS,EACZ,KAAK,QAAQ,IAAIC,EAAI,CAAE,QAAAE,EAAS,OAAAC,EAAQ,MAAAC,CAAM,CAAC,EAC/C,GAAI,CACF,KAAK,KAAK,MAAO,MAAMH,CAAO,CAChC,OAASL,EAAP,CACA,aAAaQ,CAAK,EAClB,KAAK,QAAQ,OAAOJ,CAAE,EACtBG,EAAO,IAAI,MAAM,QAAQ,KAAK,uBAAuBP,EAAE,SAAS,CAAC,CACnE,CACF,CAAC,CACH,CAEA,OAAOC,EAAgBC,EAAwC,CAC7D,GAAI,KAAK,OAAQ,OACjB,IAAMG,EAAU,KAAK,UAAU,CAAE,QAAS,MAAO,OAAAJ,EAAQ,OAAQC,GAAU,CAAC,CAAE,CAAC,EAAI;AAAA,EACnF,GAAI,CACF,KAAK,KAAK,MAAO,MAAMG,CAAO,CAChC,MAAE,CAEF,CACF,CAEA,OAAc,CACZ,GAAI,MAAK,OACT,MAAK,OAAS,GACd,GAAI,CACF,KAAK,KAAK,KAAK,SAAS,CAC1B,MAAE,CAEF,EACF,CAEQ,OAAOT,EAAqB,CAElC,IADA,KAAK,QAAUA,IACF,CACX,IAAMa,EAAK,KAAK,OAAO,QAAQ;AAAA,CAAI,EACnC,GAAIA,EAAK,EAAG,MACZ,IAAMC,EAAO,KAAK,OAAO,MAAM,EAAGD,CAAE,EAAE,KAAK,EAE3C,GADA,KAAK,OAAS,KAAK,OAAO,MAAMA,EAAK,CAAC,EAClC,CAACC,EAAM,SACX,IAAIC,EACJ,GAAI,CACFA,EAAM,KAAK,MAAMD,CAAI,CACvB,OAASV,EAAP,CACAH,EAAM,QAAQ,MAAO,GAAG,KAAK,sBAAsBG,EAAE,kBAAkBU,EAAK,MAAM,EAAG,GAAG,IAAI,EAC5F,QACF,CACA,GAAI,OAAOC,EAAI,IAAO,UAAY,KAAK,QAAQ,IAAIA,EAAI,EAAE,EAAG,CAC1D,IAAMZ,EAAI,KAAK,QAAQ,IAAIY,EAAI,EAAE,EACjC,KAAK,QAAQ,OAAOA,EAAI,EAAE,EAC1B,aAAaZ,EAAE,KAAK,EAChBY,EAAI,MAAOZ,EAAE,OAAO,IAAI,MAAM,GAAGY,EAAI,MAAM,SAASA,EAAI,MAAM,SAAS,CAAC,EACvEZ,EAAE,QAAQY,EAAI,MAAM,GAK/B,CACF,EAEMC,GAAN,KAAyC,CAKvC,YAA6BlB,EAA+BF,EAAmB,CAAlD,UAAAE,EAA+B,UAAAF,CAAoB,CAJxE,OAAS,EACT,UAA2B,KAC3B,OAAS,GAIjB,MAAM,QAAQS,EAAgBC,EAAiCC,EAAqC,CAClG,GAAI,KAAK,OAAQ,MAAM,IAAI,MAAM,eAAe,KAAK,iBAAiB,EACtE,IAAMC,EAAK,KAAK,SACVS,EAAO,KAAK,UAAU,CAAE,QAAS,MAAO,GAAAT,EAAI,OAAAH,EAAQ,OAAAC,CAAO,CAAC,EAC5DY,EAAkC,CACtC,eAAgB,mBAIhB,OAAQ,sCACR,GAAI,KAAK,KAAK,SAAW,CAAC,CAC5B,EAKI,KAAK,YAAWA,EAAQ,gBAAgB,EAAI,KAAK,WAErD,IAAMC,EAAM,IAAI,gBACVP,EAAQ,WAAW,IAAMO,EAAI,MAAM,IAAI,MAAM,iBAAiBZ,KAAa,CAAC,EAAGA,CAAS,EAC5FK,EAAc,QAAQ,EAExB,IAAIQ,EACJ,GAAI,CACFA,EAAM,MAAM,MAAM,KAAK,KAAK,IAAK,CAC/B,OAAQ,OACR,QAAAF,EACA,KAAAD,EACA,OAAQE,EAAI,MACd,CAAC,CACH,OAASf,EAAP,CAEA,MADA,aAAaQ,CAAK,EACdR,GAAG,OAAS,aACR,IAAI,MAAM,QAAQ,KAAK,SAASC,mBAAwBE,KAAa,EAEvE,IAAI,MAAM,QAAQ,KAAK,SAASF,mBAAwBD,GAAG,SAAWA,GAAG,CACjF,CAIA,IAAMiB,EAAaD,EAAI,QAAQ,IAAI,gBAAgB,EAGnD,GAFIC,IAAY,KAAK,UAAYA,GAE7B,CAACD,EAAI,GAAI,CACX,aAAaR,CAAK,EAClB,IAAMU,EAAU,MAAMF,EAAI,KAAK,EAAE,MAAM,IAAM,EAAE,EAC/C,MAAM,IAAI,MAAM,QAAQ,KAAK,cAAcA,EAAI,WAAWE,EAAQ,MAAM,EAAG,GAAG,GAAG,EAGnF,IAAMC,GAAeH,EAAI,QAAQ,IAAI,cAAc,GAAK,IAAI,YAAY,EACpEI,EACJ,GAAI,CACED,EAAY,SAAS,mBAAmB,EAC1CC,EAAS,MAAMC,GAAiBL,EAAKZ,CAAE,EAEvCgB,EAAS,MAAMJ,EAAI,KAAK,CAE5B,OAAShB,EAAP,CACA,mBAAaQ,CAAK,EACZ,IAAI,MAAM,QAAQ,KAAK,SAASP,4BAAiCD,GAAG,SAAWA,GAAG,CAC1F,QAAE,CACA,aAAaQ,CAAK,CACpB,CAEA,GAAI,CAACY,GAAU,OAAOA,GAAW,SAC/B,MAAM,IAAI,MAAM,QAAQ,KAAK,SAASnB,4BAAiC,EAEzE,GAAImB,EAAO,MACT,MAAM,IAAI,MAAM,GAAGA,EAAO,MAAM,SAASA,EAAO,MAAM,SAAS,EAEjE,OAAOA,EAAO,MAChB,CAEA,OAAOnB,EAAgBC,EAAwC,CAC7D,GAAI,KAAK,OAAQ,OAKjB,IAAMY,EAAkC,CACtC,eAAgB,mBAChB,OAAQ,sCACR,GAAI,KAAK,KAAK,SAAW,CAAC,CAC5B,EACI,KAAK,YAAWA,EAAQ,gBAAgB,EAAI,KAAK,WACrD,MAAM,KAAK,KAAK,IAAK,CACnB,OAAQ,OACR,QAAAA,EACA,KAAM,KAAK,UAAU,CAAE,QAAS,MAAO,OAAAb,EAAQ,OAAQC,GAAU,CAAC,CAAE,CAAC,CACvE,CAAC,EAAE,MAAOF,GAAW,CACnBH,EAAM,QAAQ,MAAO,GAAG,KAAK,gBAAgBI,aAAkBD,GAAG,SAAWA,GAAG,CAClF,CAAC,CACH,CAEA,OAAc,CACZ,GAAI,MAAK,SACT,KAAK,OAAS,GAIV,KAAK,WAAW,CAClB,IAAMc,EAAkC,CACtC,iBAAkB,KAAK,UACvB,GAAI,KAAK,KAAK,SAAW,CAAC,CAC5B,EACA,MAAM,KAAK,KAAK,IAAK,CAAE,OAAQ,SAAU,QAAAA,CAAQ,CAAC,EAAE,MAAM,IAAM,CAAQ,CAAC,EAE7E,CACF,EAKA,eAAeO,GAAiBL,EAAeZ,EAA0B,CACvE,IAAMkB,EAASN,EAAI,MAAM,UAAU,EACnC,GAAI,CAACM,EAAQ,MAAM,IAAI,MAAM,0BAA0B,EACvD,IAAMC,EAAU,IAAI,YAChBC,EAAS,GACb,GAAI,CACF,OAAa,CACX,GAAM,CAAE,KAAAC,EAAM,MAAAC,CAAM,EAAI,MAAMJ,EAAO,KAAK,EAC1C,GAAIG,EAAM,MACVD,GAAUD,EAAQ,OAAOG,EAAO,CAAE,OAAQ,EAAK,CAAC,EAGhD,IAAIC,EACJ,MAAQA,EAASH,EAAO,QAAQ;AAAA;AAAA,CAAM,IAAM,GAAG,CAC7C,IAAMI,EAAMJ,EAAO,MAAM,EAAGG,CAAM,EAClCH,EAASA,EAAO,MAAMG,EAAS,CAAC,EAChC,IAAME,EAAsB,CAAC,EAC7B,QAAWnB,KAAQkB,EAAI,MAAM;AAAA,CAAI,EAAG,CAClC,IAAME,EAAUpB,EAAK,QAAQ,MAAO,EAAE,EAClCoB,EAAQ,WAAW,OAAO,GAAGD,EAAU,KAAKC,EAAQ,MAAM,CAAC,EAAE,KAAK,CAAC,EAEzE,GAAI,CAACD,EAAU,OAAQ,SACvB,IAAME,EAAUF,EAAU,KAAK;AAAA,CAAI,EACnC,GAAI,CAACE,GAAWA,IAAY,SAAU,SACtC,IAAI1B,EACJ,GAAI,CAAEA,EAAU,KAAK,MAAM0B,CAAO,CAAE,MAAE,CAAQ,QAAS,CAEvD,GAAI1B,GAAWA,EAAQ,KAAOD,EAAI,OAAOC,GAG/C,QAAE,CACA,GAAI,CAAEiB,EAAO,OAAO,EAAE,MAAM,IAAM,CAAQ,CAAC,CAAE,MAAE,CAAc,CAC/D,CACA,MAAM,IAAI,MAAM,8CAA8ClB,GAAI,CACpE,CAEO,IAAM4B,GAAN,KAAgB,CAGrB,YAA4BtC,EAAcF,EAAqB,CAAnC,UAAAE,EAC1B,KAAK,UAAYH,GAAWC,CAAI,EAC5B,IAAIoB,GAAclB,EAAMF,CAAI,EAC5B,IAAIC,GAAeC,EAAMF,CAAI,CACnC,CANQ,UAQR,MAAM,YAA4B,CAChC,MAAM,KAAK,UAAU,QACnB,aACA,CACE,gBAAiBL,GACjB,aAAc,CAAC,EACf,WAAY,CAAE,KAAM,sBAAuB,QAAS,OAAQ,CAC9D,EACAC,EACF,EACA,KAAK,UAAU,OAAO,2BAA2B,CACnD,CAEA,MAAM,WAAgC,CAIpC,QAHgB,MAAM,KAAK,UAAU,QAAQ,aAAc,CAAC,EAAGA,EAAe,GAG/D,OAAS,CAAC,GAAG,IAAK,IAAO,CACtC,KAAM,EAAE,KACR,YAAa,EAAE,aAAe,GAC9B,aAAc,EAAE,aAAe,CAAE,KAAM,SAAU,WAAY,CAAC,CAAE,CAClE,EAAE,CACJ,CAEA,MAAM,SAASM,EAAcuC,EAAuD,CAClF,IAAMC,EAAU,MAAM,KAAK,UAAU,QACnC,aACA,CAAE,KAAAxC,EAAM,UAAWuC,GAAQ,CAAC,CAAE,EAC9B5C,EACF,EAGM8C,EAAkB,CAAC,EACzB,QAAWC,KAASF,EAAO,SAAW,CAAC,EACjCE,GAAO,OAAS,QAAU,OAAOA,EAAM,MAAS,SAAUD,EAAM,KAAKC,EAAM,IAAI,EAC9ED,EAAM,KAAK,KAAK,UAAUC,CAAK,CAAC,EAEvC,MAAO,CAAE,QAASD,EAAM,KAAK;AAAA,CAAI,GAAK,cAAe,QAASD,EAAO,OAAQ,CAC/E,CAEA,OAAc,CACZ,KAAK,UAAU,MAAM,CACvB,CACF,EAgBA,eAAsBG,GAAaC,EAAyC,CAC1E,IAAMC,EAAU,IAAI,IACdC,EAAmB,CAAC,EACpBC,EAAS,IAAI,IAEnB,OAAW,CAACC,EAAYlD,CAAI,IAAK,OAAO,QAAQ8C,CAAO,EAAG,CACxD,IAAMK,EAAS,IAAIX,GAAUU,EAAYlD,CAAI,EAC7C,GAAI,CACF,MAAMmD,EAAO,WAAW,EACxB,IAAMC,EAAc,MAAMD,EAAO,UAAU,EAC3C,QAAWE,KAAKD,EAAa,CAC3B,IAAME,EAAa,GAAGxD,KAAcoD,MAAeG,EAAE,OACrDL,EAAM,KAAK,CACT,KAAMM,EACN,YAAaD,EAAE,aAAe,GAAGH,KAAcG,EAAE,OACjD,aAAcA,EAAE,YAClB,CAAC,EACDJ,EAAO,IAAIK,EAAY,CAAE,OAAAH,EAAQ,OAAQE,EAAE,IAAK,CAAC,EAEnDN,EAAQ,IAAIG,EAAYC,CAAM,CAChC,OAAS3C,EAAP,CACAH,EAAM,QAAQ,MAAO,GAAG6C,qBAAyB1C,EAAE,SAAS,EAC5D2C,EAAO,MAAM,CACf,EAGF,MAAO,CACL,MAAAH,EACA,MAAM,SAAS9C,EAAMqD,EAAO,CAC1B,IAAMC,EAAQP,EAAO,IAAI/C,CAAI,EAC7B,GAAI,CAACsD,EAAO,MAAO,CAAE,QAAS,qBAAqBtD,IAAQ,QAAS,EAAK,EACzE,GAAI,CACF,OAAO,MAAMsD,EAAM,OAAO,SAASA,EAAM,OAAQD,CAAK,CACxD,OAAS/C,EAAP,CACA,MAAO,CAAE,QAAS,oBAAoBA,EAAE,UAAW,QAAS,EAAK,CACnE,CACF,EACA,OAAQ,CACN,QAAWiD,KAAKV,EAAQ,OAAO,EAAGU,EAAE,MAAM,CAC5C,CACF,CACF,CCvbO,IAAMC,GAAN,KAAoB,CACjB,MAAa,CAAC,EACd,UAAuD,CAAC,EACxD,OAAS,GAEjB,KAAKC,EAAe,CAClB,GAAI,KAAK,OAAQ,OAEjB,IAAMC,EAAW,KAAK,UAAU,MAAM,EACtC,GAAIA,EAAU,CACZA,EAAS,CAAE,MAAOD,EAAM,KAAM,EAAM,CAAC,EACrC,OAEF,KAAK,MAAM,KAAKA,CAAI,CACtB,CAEA,OAAc,CACZ,GAAI,MAAK,OACT,MAAK,OAAS,GACd,QAAWE,KAAW,KAAK,UAAU,OAAO,CAAC,EAC3CA,EAAQ,CAAE,MAAO,OAAkB,KAAM,EAAK,CAAC,EAEnD,CAEA,MAAM,MAAmC,CACvC,OAAI,KAAK,MAAM,OACN,CAAE,MAAO,KAAK,MAAM,MAAM,EAAQ,KAAM,EAAM,EAEnD,KAAK,OACA,CAAE,MAAO,OAAkB,KAAM,EAAK,EAExC,IAAI,QAA4BA,GAAY,CACjD,KAAK,UAAU,KAAKA,CAAO,CAC7B,CAAC,CACH,CAEA,OAAQ,OAAO,aAAa,GAAuB,CACjD,OAAa,CACX,GAAM,CAAE,MAAAC,EAAO,KAAAC,CAAK,EAAI,MAAM,KAAK,KAAK,EACxC,GAAIA,EAAM,OACV,MAAMD,EAEV,CACF,ECsDA,eAAsBE,GACpBC,EACAC,EACAC,EACuB,CACvB,IAAMC,EAAcC,GAAkB,MAAMF,GAAU,CAAC,CAAC,EAGlDG,EAAS,IAAIC,GAAgBN,CAAG,EACtC,MAAMK,EAAO,KAAK,EAGlB,GAAM,CAACE,EAAWC,EAASC,CAAM,EAAI,MAAM,QAAQ,IAAI,CACrDC,GAAgBV,CAAG,EACnBW,GAAcX,CAAG,EACjBY,GAAgBZ,CAAG,CACrB,CAAC,EAGGa,EAAO,GACX,GAAIV,EAAY,SAAS,QACvB,GAAI,CACFU,EAAO,MAAMC,GAAmBP,EAAWN,EAAME,EAAY,SAAS,MAAM,CAC9E,MAAE,CAEF,CAIF,IAAMY,EAAgBV,EAAO,mBAAmBJ,CAAI,EAG9Ce,EAAsBC,GAAwBjB,CAAG,EAEvD,OAAAkB,EAAM,QAAQ,SAAUH,EAAgB,SAAW,OAAO,EAC1DG,EAAM,QAAQ,eAAgBF,EAAsB,sBAAwB,MAAM,EAE3E,CACL,UAAAT,EACA,QAAAC,EACA,OAAAC,EACA,KAAAI,EACA,OAAQV,EACR,cAAAY,EACA,oBAAAC,CACF,CACF,CAEA,eAAsBG,GAASC,EAAmD,CAChF,GAAM,CACJ,KAAAnB,EACA,IAAAD,EACA,UAAAqB,EAAY,GACZ,OAAAC,EAAS,GACT,SAAUC,EAAe,cACzB,MAAAC,EACA,OAAAC,EACA,SAAAC,EAAW,GACX,YAAAC,EAAc,EAChB,EAAIP,EAGAQ,EAAgB3B,EACpB,GAAI4B,EAAY,IAAI,YAAY,EAAG,CACjC,IAAMC,EAAe,MAAMD,EAAY,QAAQ,aAAc,CAC3D,MAAO,aACP,KAAA5B,EACA,IAAAD,CACF,CAAC,EACD,GAAI8B,EAAa,QACf,MAAM,IAAI,MAAMA,EAAa,SAAW,4BAA4B,EAElEA,EAAa,UAAU,OACzBF,EAAgB,OAAOE,EAAa,SAAS,IAAI,GAKrD,GAAID,EAAY,IAAI,cAAc,EAAG,CACnC,IAAME,EAAY,MAAMF,EAAY,QAAQ,eAAgB,CAC1D,MAAO,eACP,KAAMD,EACN,IAAA5B,CACF,CAAC,EACD,GAAI+B,EAAU,QACZ,MAAM,IAAI,MAAMA,EAAU,SAAW,8BAA8B,EAKvEC,EAAO,KAAK,sBAAsB,EAClC,IAAMC,EAAU,MAAMlC,GAAmBC,EAAK4B,EAAe,CAC3D,SAAUL,EACV,SAAU,CAAE,QAASG,EAAU,OAAAD,CAAO,CACxC,CAAC,EAGKS,EAAaC,GAAkBf,EAAQ,WAAYQ,CAAa,EACtEI,EAAO,KAAK,gBAAgBE,GAAY,EAGxC,IAAME,EAAgBC,GAAkBJ,EAAQ,OAAQL,EAAeM,CAAU,EAC7EE,EAAc,QAChBJ,EAAO,KACL,UAAUI,EAAc,6BAA6BA,EAAc,IAAKE,GAAMA,EAAE,MAAM,YAAY,IAAI,EAAE,KAAK,IAAI,GACnH,EAIF,IAAMC,EAAeC,GAAkBP,EAASC,EAAYE,EAAc,IAAKE,GAAMA,EAAE,KAAK,CAAC,EAI7F,GAAI,CADmB,MAAMG,GAAkBhB,CAAM,EAEnD,MAAM,IAAI,MAAM,0DAA0D,EAI5E,IAAMiB,EAAWC,GAAepB,EAAcE,EAAQL,EAAQ,cAAgB,CAAC,CAAC,EAC1EwB,EAAgBpB,GAASqB,EAAe,GAAG,MAG3CC,EAAuC,CAC3C,GAAI1B,EAAQ,iBAAmB,CAAC,EAChC,CAAE,KAAM,OAAQ,QAASQ,CAAc,CACzC,EAEAI,EAAO,KAAK,eAAe,EAG3B,IAAMe,EAAaC,GAAoBN,CAAQ,EACzCO,EAAW7B,EAAQ,WAAa2B,EAAa,GAAK,GAKlDG,EAAU9B,EAAQ,YAAc,OAAO,KAAKA,EAAQ,UAAU,EAAE,OAAS,EAC3E,MAAM+B,GAAa/B,EAAQ,UAAU,EACrC,OAEAgC,EACJ,GAAI,CAEFA,EAAgB,MAAMC,GAAe,CACnC,SAAAX,EACA,aAAAH,EACA,SAAU,CACR,CAAE,KAAM,SAAU,QAASA,CAAa,EACxC,GAAGO,CACL,EACA,gBAAiB,CAAE,MAAOF,EAAe,UAAW,IAAK,EACzD,IAAA5C,EACA,cAAeiD,EACf,aAAchB,EAAQ,OAAO,QAAQ,aAAa,OAC/CqB,GAAM,CAACrB,EAAQ,OAAO,QAAQ,cAAc,SAASqB,CAAC,CACzD,EACA,YAAA3B,EACA,UAAAN,EACA,OAAAC,EACA,aAAcF,EAAQ,aAKtB,YAAaA,EAAQ,YACrB,SAAU8B,GAAS,MACnB,YAAaA,EAAUA,EAAQ,SAAS,KAAKA,CAAO,EAAI,OACxD,WAAaK,GAAU,CACjBA,EAAM,OAAS,mBAAqBA,EAAM,UAAY,GACxDvB,EAAO,KAAK,QAAQuB,EAAM,aAAaN,MAAa,EAElDM,EAAM,OAAS,aACjBrC,EAAM,KAAK,EAAG,SAASqC,EAAM,MAAM,CAEvC,CACF,CAAC,CACH,QAAE,CACAL,GAAS,MAAM,CACjB,CAGA,GAAIE,EAAc,WAAY,CAC5B,IAAMI,EAAYZ,GAAiB,2BAC7Ba,EAAW,KAAK,MAAML,EAAc,WAAa,EAAG,EACpDM,EAAYN,EAAc,WAAaK,EAC7CE,GAAc,WAAW,EAAGH,EAAWC,EAAUC,CAAS,EAG5D,GAAI,CAAE,QAAAE,CAAQ,EAAIR,EACZ,CAAE,SAAAS,EAAU,WAAYC,EAAa,YAAaC,EAAS,aAAcC,CAAS,EAAIZ,EAO5F,GALIA,EAAc,WAAa,GAC7BpB,EAAO,KAAK,gBAAgBoB,EAAc,oBAAoB,EAI5DvB,EAAY,IAAI,eAAe,EAAG,CACpC,IAAMoC,EAAiB,MAAMpC,EAAY,QAAQ,gBAAiB,CAChE,MAAO,gBACP,QAAA+B,EACA,KAAMhC,EACN,IAAA5B,CACF,CAAC,EACD,GAAIiE,EAAe,QACjB,MAAM,IAAI,MAAMA,EAAe,SAAW,+BAA+B,EAEvEA,EAAe,UAAU,UAC3BL,EAAU,OAAOK,EAAe,SAAS,OAAO,GAKpD,GAAIJ,GAAYlC,EACd,MAAO,CACL,MAAO,CAAE,QAAS,CAAC,EAAG,QAAS,CAAC,EAAG,OAAQ,CAAC,CAAE,EAC9C,QAAAiC,EACA,WAAA1B,EACA,SAAA2B,EACA,WAAYC,EACZ,YAAaC,EACb,aAAcC,CAChB,EAIF,IAAME,EAAU,IAAI,IACpB,QAAWC,KAAQf,EAAc,MAC/Bc,EAAQ,IAAIC,EAAK,KAAMA,CAAI,EAI7B,IAAMC,EAAYC,GAAiBnC,EAAYD,EAAQ,UAAWb,EAAQ,SAAS,EAE7EkD,EAAc,MAAMC,GAAoB,MAAM,KAAKL,EAAQ,OAAO,CAAC,EAAG,CAC1E,IAAAlE,EACA,UAAAqB,EACA,OAAAC,EACA,UAAA8C,CACF,CAAC,EAGGI,EACJ,GAAIpD,EAAQ,OAAS,IAAS,CAACE,GAAUgD,EAAY,QAAQ,OAAS,EAAG,CACvE,GAAM,CAAE,WAAAG,CAAW,EAAI,KAAM,QAAO,oBAAgB,EAWpDD,EAAa,MAVM,IAAIC,EAAWzE,EAAK,CACrC,QAAS,GACT,YAAaoB,EAAQ,YAAY,YACjC,aAAcA,EAAQ,YAAY,aAClC,YAAaA,EAAQ,YAAY,YACjC,YAAaA,EAAQ,YAAY,aAAe,EAChD,SAAUG,EACV,MAAOqB,EACP,OAAAnB,CACF,CAAC,EAC6B,cAAc6C,EAAY,QAAS1C,CAAa,EAE1E,CAAC4C,EAAW,QAAUA,EAAW,OACnC,MAAM3C,EAAY,QAAQ,WAAY,CACpC,MAAO,WACP,MAAO,IAAI,MAAM2C,EAAW,KAAK,EACjC,KAAM5C,EACN,IAAA5B,CACF,CAAC,EAKL,OAAI6B,EAAY,IAAI,eAAe,GACjC,MAAMA,EAAY,QAAQ,gBAAiB,CACzC,MAAO,gBACP,KAAMD,EACN,QAAAgC,EACA,IAAA5D,CACF,CAAC,EAGI,CACL,MAAOsE,EACP,QAAAV,EACA,WAAA1B,EACA,WAAY4B,EACZ,YAAaC,EACb,aAAcC,EACd,WAAAQ,CACF,CACF,CAaA,eAAuBE,GACrBtD,EACqC,CACrC,GAAM,CACJ,KAAAnB,EACA,IAAAD,EACA,UAAAqB,EAAY,GACZ,OAAAC,EAAS,GACT,SAAUC,EAAe,cACzB,MAAAC,EACA,OAAAC,EACA,SAAAC,EAAW,GACX,YAAAC,EAAc,EAChB,EAAIP,EAGAQ,EAAgB3B,EACpB,GAAI4B,EAAY,IAAI,YAAY,EAAG,CACjC,IAAMC,EAAe,MAAMD,EAAY,QAAQ,aAAc,CAC3D,MAAO,aACP,KAAA5B,EACA,IAAAD,CACF,CAAC,EACD,GAAI8B,EAAa,QAAS,CACxB,KAAM,CAAE,KAAM,QAAS,MAAOA,EAAa,SAAW,4BAA6B,EACnF,OAEEA,EAAa,UAAU,OACzBF,EAAgB,OAAOE,EAAa,SAAS,IAAI,GAKrD,GAAID,EAAY,IAAI,cAAc,EAAG,CACnC,IAAME,EAAY,MAAMF,EAAY,QAAQ,eAAgB,CAC1D,MAAO,eACP,KAAMD,EACN,IAAA5B,CACF,CAAC,EACD,GAAI+B,EAAU,QAAS,CACrB,KAAM,CAAE,KAAM,QAAS,MAAOA,EAAU,SAAW,8BAA+B,EAClF,QAKJ,IAAME,EAAU,MAAMlC,GAAmBC,EAAK4B,EAAe,CAC3D,SAAUL,EACV,SAAU,CAAE,QAASG,EAAU,OAAAD,CAAO,CACxC,CAAC,EAGKS,EAAaC,GAAkBf,EAAQ,WAAYQ,CAAa,EAGtE,KAAM,CAAE,KAAM,gBAAiB,WAAAM,CAAW,EAG1C,IAAME,EAAgBC,GAAkBJ,EAAQ,OAAQL,EAAeM,CAAU,EAG3EK,EAAeC,GAAkBP,EAASC,EAAYE,EAAc,IAAKE,GAAMA,EAAE,KAAK,CAAC,EAI7F,GAAI,CADmB,MAAMG,GAAkBhB,CAAM,EAChC,CACnB,KAAM,CAAE,KAAM,QAAS,MAAO,0DAA2D,EACzF,OAIF,IAAMiB,EAAWC,GAAepB,EAAcE,EAAQL,EAAQ,cAAgB,CAAC,CAAC,EAC1EwB,EAAgBpB,GAASqB,EAAe,GAAG,MAC3CE,EAAaC,GAAoBN,CAAQ,EACzCO,EAAW7B,EAAQ,WAAa2B,EAAa,GAAK,GAElDD,EAAuC,CAC3C,GAAI1B,EAAQ,iBAAmB,CAAC,EAChC,CAAE,KAAM,OAAQ,QAASQ,CAAc,CACzC,EAGA,GAAImB,EAAY,CACd,IAAM4B,EAAI,IAAIC,GACVxB,EACAyB,EAKA3B,EACJ,GAAI9B,EAAQ,YAAc,OAAO,KAAKA,EAAQ,UAAU,EAAE,OAAS,EACjE,GAAI,CACF8B,EAAU,MAAMC,GAAa/B,EAAQ,UAAU,CACjD,OAAS0D,EAAP,CACA,KAAM,CAAE,KAAM,QAAS,MAAO,4BAA4BA,EAAE,SAAU,EACtE,MACF,CAGF,IAAMC,IAAkB,SAAY,CAClC,GAAI,CACF3B,EAAgB,MAAMC,GAAe,CACnC,SAAAX,EACA,aAAAH,EACA,SAAU,CACR,CAAE,KAAM,SAAU,QAASA,CAAa,EACxC,GAAGO,CACL,EACA,gBAAiB,CAAE,MAAOF,EAAe,UAAW,IAAK,EACzD,IAAA5C,EACA,cAAeiD,EACf,YAAa7B,EAAQ,YACrB,aAAca,EAAQ,OAAO,QAAQ,aAAa,OAC/CqB,GAAM,CAACrB,EAAQ,OAAO,QAAQ,cAAc,SAASqB,CAAC,CACzD,EACA,YAAA3B,EACA,UAAAN,EACA,OAAAC,EACA,aAAcF,EAAQ,aACtB,SAAU8B,GAAS,MACnB,YAAaA,EAAUA,EAAQ,SAAS,KAAKA,CAAO,EAAI,OACxD,WAAaK,GAAU,CACjBA,EAAM,OAAS,cACjBoB,EAAE,KAAK,CAAE,KAAM,aAAc,KAAMpB,EAAM,IAAK,CAAC,EAE7CA,EAAM,OAAS,kBACjBoB,EAAE,KAAK,CAAE,KAAM,iBAAkB,KAAMpB,EAAM,IAAK,CAAC,EAEjDA,EAAM,OAAS,mBACjBoB,EAAE,KAAK,CAAE,KAAM,YAAa,UAAWpB,EAAM,SAAU,CAAC,EAEtDA,EAAM,OAAS,aACjBoB,EAAE,KAAK,CAAE,KAAM,YAAa,KAAMpB,EAAM,KAAM,GAAIA,EAAM,EAAG,CAAC,EAE1DA,EAAM,OAAS,eACjBoB,EAAE,KAAK,CAAE,KAAM,cAAe,KAAMpB,EAAM,KAAM,GAAIA,EAAM,GAAI,SAAUA,EAAM,QAAS,CAAC,EAEtFA,EAAM,OAAS,iBACjBoB,EAAE,KAAK,CAAE,KAAM,gBAAiB,KAAM,EAAG,WAAYpB,EAAM,MAAM,MAAO,CAAC,CAE7E,CACF,CAAC,CACH,OAASyB,EAAP,CACAH,EAAeG,CACjB,QAAE,CACA9B,GAAS,MAAM,EACfyB,EAAE,MAAM,CACV,CACF,GAAG,EAEH,cAAiBM,KAAON,EACtB,MAAMM,EAIR,GADA,MAAMF,GACFF,EAAc,CAEhB,KAAM,CAAE,KAAM,QAAS,MADXA,aAAwB,MAAQA,EAAa,QAAU,OAAOA,CAAY,CACpD,EAClC,OAEF,GAAI,CAACzB,EAAe,CAClB,KAAM,CAAE,KAAM,QAAS,MAAO,sCAAuC,EACrE,OAGF,KAAM,CACJ,KAAM,OACN,OAAQ,CACN,QAASA,EAAc,QACvB,MAAOA,EAAc,MACrB,WAAYA,EAAc,WAC1B,SAAUA,EAAc,QAC1B,CACF,EAGA,GAAI,CAAE,QAAAQ,CAAQ,EAAIR,EAGlB,GAAIvB,EAAY,IAAI,eAAe,EAAG,CACpC,IAAMoC,EAAiB,MAAMpC,EAAY,QAAQ,gBAAiB,CAChE,MAAO,gBACP,QAAA+B,EACA,KAAMhC,EACN,IAAA5B,CACF,CAAC,EACD,GAAIiE,EAAe,QAAS,CAC1B,KAAM,CAAE,KAAM,QAAS,MAAOA,EAAe,SAAW,+BAAgC,EACxF,OAEEA,EAAe,UAAU,UAC3BL,EAAU,OAAOK,EAAe,SAAS,OAAO,GAIpD,GAAIb,EAAc,UAAYzB,EAAa,CACzC,KAAM,CACJ,KAAM,kBACN,OAAQ,CACN,MAAO,CAAE,QAAS,CAAC,EAAG,QAAS,CAAC,EAAG,OAAQ,CAAC,CAAE,EAC9C,QAAAiC,EACA,WAAA1B,EACA,SAAUkB,EAAc,SACxB,WAAYA,EAAc,WAC1B,YAAaA,EAAc,YAC3B,aAAcA,EAAc,YAC9B,CACF,EACA,OAGF,IAAMc,GAAU,IAAI,IACpB,QAAWC,KAAQf,EAAc,MAC/Bc,GAAQ,IAAIC,EAAK,KAAMA,CAAI,EAG7B,IAAMC,GAAYC,GAAiBnC,EAAYD,EAAQ,UAAWb,EAAQ,SAAS,EAC7EkD,EAAc,MAAMC,GAAoB,MAAM,KAAKL,GAAQ,OAAO,CAAC,EAAG,CAC1E,IAAAlE,EACA,UAAAqB,EACA,OAAAC,EACA,UAAA8C,EACF,CAAC,EAEGI,EACJ,GAAIpD,EAAQ,OAAS,IAAS,CAACE,GAAUgD,EAAY,QAAQ,OAAS,EAAG,CACvE,GAAM,CAAE,WAAAG,CAAW,EAAI,KAAM,QAAO,oBAAgB,EAWpDD,EAAa,MAVM,IAAIC,EAAWzE,EAAK,CACrC,QAAS,GACT,YAAaoB,EAAQ,YAAY,YACjC,aAAcA,EAAQ,YAAY,aAClC,YAAaA,EAAQ,YAAY,YACjC,YAAaA,EAAQ,YAAY,aAAe,EAChD,SAAUG,EACV,MAAOqB,EACP,OAAAnB,CACF,CAAC,EAC6B,cAAc6C,EAAY,QAAS1C,CAAa,EAG5EC,EAAY,IAAI,eAAe,GACjC,MAAMA,EAAY,QAAQ,gBAAiB,CACzC,MAAO,gBACP,KAAMD,EACN,QAAAgC,EACA,IAAA5D,CACF,CAAC,EAGH,KAAM,CACJ,KAAM,kBACN,OAAQ,CACN,MAAOsE,EACP,QAAAV,EACA,WAAA1B,EACA,WAAYkB,EAAc,WAC1B,YAAaA,EAAc,YAC3B,aAAcA,EAAc,aAC5B,WAAAoB,CACF,CACF,EACA,OAKF,IAAMU,EAAgC,CACpC,CAAE,KAAM,SAAU,QAAS3C,CAAa,EACxC,GAAGO,CACL,EAEMqC,EAAwD,CAAC,EAC3DrB,EAAc,EACdF,EAAU,GACVC,EACAuB,EAAO,EAGXA,IACAlE,EAAM,KAAKkE,EAAM,+BAA+BxC,GAAiB,YAAY,EAE7E,IAAIyC,EAEJ,GAAI3C,EAAS,OAAQ,CACnB,IAAI4C,EAAc,GACdC,EAEJ,cAAiBhC,KAASb,EAAS,OAAOwC,EAAU,CAClD,MAAOtC,EACP,UAAW,IACb,CAAC,EACC,MAAMW,EAEFA,EAAM,OAAS,eACjB+B,GAAe/B,EAAM,MAEnBA,EAAM,OAAS,SACjBgC,EAAehC,EAAM,QAIzB8B,EAAcE,GAAgB,CAC5B,QAASD,EACT,MAAO,CAAC,EACR,WAAY,CACd,MACK,CACL,IAAME,EAAS,MAAM9C,EAAS,SAASwC,EAAU,CAC/C,MAAOtC,EACP,UAAW,IACb,CAAC,EAEG4C,EAAO,UACT,KAAM,CAAE,KAAM,aAAc,KAAMA,EAAO,OAAQ,GAEnD,KAAM,CAAE,KAAM,OAAQ,OAAAA,CAAO,EAC7BH,EAAcG,EAGhB1B,GAAeuB,EAAY,YAAc,EACzCzB,EAAUyB,EAAY,QAEtB,IAAMI,EAAcJ,EAAY,YAAc,EACxCK,EAAa9C,GAAiB,2BAC9B+C,EAAY,KAAK,MAAMF,EAAc,EAAG,EACxCG,EAAaH,EAAcE,EAgBjC,GAfAhC,GAAc,WAAWyB,EAAMM,EAAYC,EAAWC,CAAU,EAChE1E,EAAM,IAAI,WAAYwE,EAAYD,CAAW,EAC7CvE,EAAM,KAAKkE,EAAM,aAAaC,EAAY,MAAM,mBAAmBI,UAAoB,EAEnFJ,EAAY,MAAM,QACpBF,EAAS,KAAK,GAAGE,EAAY,KAAK,EAGhCA,EAAY,WACdxB,EAAWwB,EAAY,UAGzB,KAAM,CAAE,KAAM,gBAAiB,KAAAD,EAAM,WAAYC,EAAY,MAAM,MAAO,EAGtE,CAACxB,IAEDD,EAAQ,SAAS,YAAY,GAC7BA,EAAQ,SAAS,YAAY,GAC7BA,EAAQ,SAAS,YAAY,GAC7BA,EAAQ,SAAS,oBAAoB,IAEbyB,EAAY,MAAM,OAAS,EAAG,CACtD,IAAMQ,EAAeR,EAAY,MAC9B,IAAKS,GAAM,YAAYA,EAAE,OAAOA,EAAE,YAAc,WAAMA,EAAE,cAAgB,IAAI,EAC5E,KAAK;AAAA,CAAI,EAWZ,IAVAZ,EAAS,KAAK,CACZ,KAAM,YACN,QAAStB,GAAWiC,EAAe;AAAA;AAAA;AAAA,EAAuBA,IAAiB,GAC7E,CAAC,EACDX,EAAS,KAAK,CACZ,KAAM,OACN,QACE,2IACJ,CAAC,EAEME,EAAOnC,GAAU,CACtBmC,IACAlE,EAAM,KAAKkE,EAAM,+BAA+BxC,GAAiB,YAAY,EAE7E,IAAM4C,EAAS,MAAM9C,EAAS,SAASwC,EAAU,CAC/C,MAAOtC,EACP,UAAW,IACb,CAAC,EAEDkB,GAAe0B,EAAO,YAAc,EACpC5B,EAAU4B,EAAO,QAEjB,IAAMO,EAAaP,EAAO,YAAc,EAClChC,GAAYZ,GAAiB,2BAC7Ba,EAAW,KAAK,MAAMsC,EAAa,EAAG,EACtCrC,GAAYqC,EAAatC,EAW/B,GAVAE,GAAc,WAAWyB,EAAM5B,GAAWC,EAAUC,EAAS,EAC7DxC,EAAM,IAAI,WAAYsC,GAAWuC,CAAU,EAC3C7E,EAAM,KAAKkE,EAAM,aAAaI,EAAO,MAAM,mBAAmBO,UAAmB,EAE7EP,EAAO,MAAM,QACfL,EAAS,KAAK,GAAGK,EAAO,KAAK,EAG/B,KAAM,CAAE,KAAM,gBAAiB,KAAAJ,EAAM,WAAYI,EAAO,MAAM,MAAO,EAEjEA,EAAO,SAAU,CACnB3B,EAAW2B,EAAO,SAClB,MAUF,GARIA,EAAO,MAAM,SAAW,GAAKJ,EAAO,GAQpC,EALFI,EAAO,QAAQ,SAAS,YAAY,GACpCA,EAAO,QAAQ,SAAS,YAAY,GACpCA,EAAO,QAAQ,SAAS,YAAY,GACpCA,EAAO,QAAQ,SAAS,oBAAoB,GAEtB,MAExB,IAAMQ,EAAgBR,EAAO,MAC1B,IAAKM,GAAM,YAAYA,EAAE,OAAOA,EAAE,YAAc,WAAMA,EAAE,cAAgB,IAAI,EAC5E,KAAK;AAAA,CAAI,EACZZ,EAAS,KAAK,CACZ,KAAM,YACN,QAASM,EAAO,SAAWQ,EAAgB;AAAA;AAAA;AAAA,EAAuBA,IAAkB,GACtF,CAAC,EACDd,EAAS,KAAK,CACZ,KAAM,OACN,QACE,2IACJ,CAAC,GAMP,GAAIrD,EAAY,IAAI,eAAe,EAAG,CACpC,IAAMoC,EAAiB,MAAMpC,EAAY,QAAQ,gBAAiB,CAChE,MAAO,gBACP,QAAA+B,EACA,KAAMhC,EACN,IAAA5B,CACF,CAAC,EACD,GAAIiE,EAAe,QAAS,CAC1B,KAAM,CAAE,KAAM,QAAS,MAAOA,EAAe,SAAW,+BAAgC,EACxF,OAEEA,EAAe,UAAU,UAC3BL,EAAU,OAAOK,EAAe,SAAS,OAAO,GAIpD,GAAIJ,GAAYlC,EAAa,CAC3B,KAAM,CACJ,KAAM,kBACN,OAAQ,CACN,MAAO,CAAE,QAAS,CAAC,EAAG,QAAS,CAAC,EAAG,OAAQ,CAAC,CAAE,EAC9C,QAAAiC,EACA,WAAA1B,EACA,SAAA2B,EACA,WAAYC,CACd,CACF,EACA,OAGF,IAAMI,EAAU,IAAI,IACpB,QAAWC,KAAQgB,EACjBjB,EAAQ,IAAIC,EAAK,KAAMA,CAAI,EAG7B,IAAMC,EAAYC,GAAiBnC,EAAYD,EAAQ,UAAWb,EAAQ,SAAS,EAC7EkD,EAAc,MAAMC,GAAoB,MAAM,KAAKL,EAAQ,OAAO,CAAC,EAAG,CAC1E,IAAAlE,EACA,UAAAqB,EACA,OAAAC,EACA,UAAA8C,CACF,CAAC,EAEGI,EACJ,GAAIpD,EAAQ,OAAS,IAAS,CAACE,GAAUgD,EAAY,QAAQ,OAAS,EAAG,CACvE,GAAM,CAAE,WAAAG,CAAW,EAAI,KAAM,QAAO,oBAAgB,EAWpDD,EAAa,MAVM,IAAIC,EAAWzE,EAAK,CACrC,QAAS,GACT,YAAaoB,EAAQ,YAAY,YACjC,aAAcA,EAAQ,YAAY,aAClC,YAAaA,EAAQ,YAAY,YACjC,YAAaA,EAAQ,YAAY,aAAe,EAChD,SAAUG,EACV,MAAOqB,EACP,OAAAnB,CACF,CAAC,EAC6B,cAAc6C,EAAY,QAAS1C,CAAa,EAE1E,CAAC4C,EAAW,QAAUA,EAAW,OACnC,MAAM3C,EAAY,QAAQ,WAAY,CACpC,MAAO,WACP,MAAO,IAAI,MAAM2C,EAAW,KAAK,EACjC,KAAM5C,EACN,IAAA5B,CACF,CAAC,EAID6B,EAAY,IAAI,eAAe,GACjC,MAAMA,EAAY,QAAQ,gBAAiB,CACzC,MAAO,gBACP,KAAMD,EACN,QAAAgC,EACA,IAAA5D,CACF,CAAC,EAGH,KAAM,CACJ,KAAM,kBACN,OAAQ,CACN,MAAOsE,EACP,QAAAV,EACA,WAAA1B,EACA,WAAY4B,EACZ,WAAAU,CACF,CACF,CACF,CAEA,SAAShC,GACPP,EACAC,EACAzB,EACQ,CACR,IAAMwF,EAAqB,CAAC,EAG5BA,EAAS,KAAK;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;AAAA;AAAA;AAAA;AAAA,4GAgC4F,EAG1GA,EAAS,KAAK;AAAA,EAAyBC,GAAgBjE,EAAQ,SAAS,GAAG,EAG3E,IAAMkE,EAAO,OAAO,KAAKlE,EAAQ,UAAU,YAAY,EAAE,MAAM,EAAG,EAAE,EAChEkE,EAAK,QACPF,EAAS,KAAK;AAAA,EAAuBE,EAAK,KAAK,IAAI,GAAG,EAIxD,IAAMC,EAAYC,GAAcpE,EAAQ,OAAO,EAC/C,OAAImE,GACFH,EAAS,KAAK;AAAA,EAAsBG,GAAW,EAI7C3F,EAAO,QACTwF,EAAS,KACP;AAAA;AAAA;AAAA,EACExF,EACG,IACE6F,GACC,aAAaA,EAAE,YAAY;AAAA,EAASA,EAAE,YAAY;AAAA;AAAA,EAAkBA,EAAE,cAC1E,EACC,KAAK;AAAA;AAAA;AAAA;AAAA,CAAa,CACzB,EAIErE,EAAQ,MACVgE,EAAS,KAAKhE,EAAQ,IAAI,EAIxBA,EAAQ,qBACVgE,EAAS,KAAK;AAAA,EAA2BhE,EAAQ,qBAAqB,EAIpEA,EAAQ,eACVgE,EAAS,KAAKhE,EAAQ,aAAa,EAIrCgE,EAAS,KAAK,kBAAkB/D;AAAA,mCAAgDA,uDAAgE,EAEzI+D,EAAS,KAAK;AAAA;AAAA,CAAM,CAC7B","names":["z","agentConfigSchema","OUTPUT_TYPES","outputTypeDescriptions","existsSync","fs","path","fg","SCHEMA_FILES","detectSchemas","cwd","schemas","files","schemaFile","info","match","f","content","safeReadFile","truncate","extractTableNames","trpcRouter","envExample","parseEnvFile","modelFiles","mf","type","matches","m","l","line","keyPart","key","hasValue","filePath","str","maxLen","formatSchemas","sections","v","model","fetch","CONTEXT7_API","resolveLibraryId","libraryName","apiKey","headers","response","data","getLibraryDocs","libraryId","topic","maxTokens","gatherContext7Docs","stack","relevantLibraries","fw","priorityDeps","dep","docs","lib","library","content","OUTPUT_CONFIGS","resolveOutputType","userHint","taskDescription","lower","patterns","pattern","type","existsSync","fs","path","execa","z","HOOK_EVENTS","BLOCKING_EVENTS","hookDefinitionSchema","MODEL_PRICING","getModelFamily","model","lower","UsageTracker","step","inputTokens","outputTokens","family","pricing","cost","existing","totalInputTokens","totalOutputTokens","totalCost","models","name","usage","globalTracker","exportSession","session","usage","lines","file","msg","label","model","mu","step","HookRegistry","event","definition","handler","entry","existing","a","b","context","registered","canBlock","BLOCKING_EVENTS","combinedModified","hook","start","result","duration","debug","error","logger","name","priority","n","list","cmd","_match","key","execa","mod","providerName","loadAuthConfig","resolved","resolveToken","createProvider","provider","prompt","systemPrompt","jsonMatch","parsed","existsSync","readFileSync","readdirSync","path","loadHooks","cwd","registry","loadHooksFromConfig","loadHooksFromDirectory","configPath","path","existsSync","raw","readFileSync","eventName","definitions","HOOK_EVENTS","logger","event","def","parsed","hookDefinitionSchema","error","hooksDir","files","readdirSync","f","file","parts","eventSlug","name","altEvent","globalHooks","HookRegistry","prompts","chalk","z","PERMISSION_MODES","permissionModeSchema","permissionConfigSchema","matchGlob","filePath","pattern","regex","PermissionManager","config","parsed","permissionConfigSchema","mode","debug","command","patterns","p","action","prompts","chalk","globalPermissions","writeGeneratedFiles","files","options","result","file","filePath","path","fileContent","globalHooks","hookResult","relativePath","permission","globalPermissions","existsSync","dir","fs","error","resolveOutputDir","outputType","stack","customDir","config","OUTPUT_CONFIGS","baseDir","f","os","USER_MEMORY_DIR","os","MemoryHierarchy","cwd","Memory","task","userCtx","projectCtx","sections","key","value","source","entry","userPrefs","projectPrefs","merged","p","userPatterns","limit","existsSync","readFileSync","path","resolveAtImports","content","basedir","match","filePath","resolved","path","existsSync","readFileSync","loadProjectInstructions","cwd","candidates","name","estimateTokens","ContextBuilder","label","priority","task","maxTokens","docs","s","index","buildIndex","bm25Results","scoreAll","scoreMap","r","scored","i","a","b","included","totalTokens","section","fs","path","execa","fg","NOQTA_TOOL_NAMES","NOQTA_TOOLS","executeNoqtaTool","toolName","input","ctx","bearer","url","body","timeoutMs","controller","timer","res","text","MAX","trimmed","err","aborted","isNoqtaTool","name","ToolExecutor","cwd","options","call","debug","globalHooks","hookResult","result","isNoqtaTool","res","executeNoqtaTool","error","filePath","maxLines","absPath","path","content","fs","lines","output","pattern","contentRegex","maxResults","files","fg","limited","regex","results","file","i","dirPath","recursive","maxDepth","entries","formatted","e","command","timeout","globalPermissions","execa","truncated","edits","permission","applied","edit","input","agentId","prompt","timeoutSeconds","SubAgentManager","getGlobalRegistry","registry","question","followUp","runAgenticLoop","options","provider","systemPrompt","inputMessages","providerOptionsRaw","cwd","maxIterations","enabledTools","interactive","overwrite","dryRun","onProgress","abortSignal","providerOptions","runLegacyLoop","executor","ToolExecutor","tools","getAnthropicTools","t","NOQTA_TOOLS","mcpToolNames","anthropicMessages","m","allFiles","totalTokens","totalInputTokens","totalOutputTokens","textContent","followUp","iteration","debug","result","useRawStream","streamedResult","streamError","streamedTextThisIteration","ev","error","streamedText","block","toolUseBlocks","b","toolResults","toolBlock","toolResult","r","messages","formatToolsForSystemPrompt","content","step","filesSummary","f","supportsAgenticLoop","spawn","PROTOCOL_VERSION","INIT_TIMEOUT_MS","CALL_TIMEOUT_MS","TOOL_PREFIX","isHttpSpec","spec","StdioTransport","name","spawn","chunk","debug","code","p","e","method","params","timeoutMs","id","payload","resolve","reject","timer","nl","line","msg","HttpTransport","body","headers","ctl","res","newSession","errText","contentType","parsed","parseSseEnvelope","reader","decoder","buffer","done","value","sepIdx","raw","dataLines","trimmed","dataStr","McpClient","args","result","parts","block","startMcpPool","servers","clients","tools","router","serverName","client","remoteTools","t","namespaced","input","route","c","AsyncQueue","item","resolver","resolve","value","done","createAgentContext","cwd","task","config","agentConfig","agentConfigSchema","memory","MemoryHierarchy","techStack","schemas","skills","detectTechStack","detectSchemas","loadLocalSkills","docs","gatherContext7Docs","memoryContext","projectInstructions","loadProjectInstructions","debug","generate","options","overwrite","dryRun","providerName","model","apiKey","context7","interactive","effectiveTask","globalHooks","promptResult","genResult","logger","context","outputType","resolveOutputType","matchedSkills","matchSkillsToTask","m","systemPrompt","buildSystemPrompt","ensureCredentials","provider","createProvider","resolvedModel","loadAuthConfig","sessionMessages","useAgentic","supportsAgenticLoop","maxSteps","mcpPool","startMcpPool","agenticResult","runAgenticLoop","t","event","stepModel","estInput","estOutput","globalTracker","content","followUp","totalTokens","agInput","agOutput","responseResult","deduped","file","outputDir","resolveOutputDir","writeResult","writeGeneratedFiles","healResult","HealEngine","generateStream","q","AsyncQueue","agenticError","e","agenticPromise","err","evt","messages","allFiles","step","step1Result","accumulated","streamResult","result","step1Tokens","step1Model","estInput1","estOutput1","filesSummary","f","stepTokens","filesSummary2","sections","formatTechStack","deps","schemaStr","formatSchemas","s"]}
|