pulse-coder-engine 0.0.1-alpha.3 → 0.0.1-alpha.4

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.
@@ -70,7 +70,7 @@ function createHTTPTransport(config) {
70
70
  };
71
71
  }
72
72
  var builtInMCPPlugin = {
73
- name: "@pulse-coder/engine/built-in-mcp",
73
+ name: "pulse-coder-engine/built-in-mcp",
74
74
  version: "1.0.0",
75
75
  async initialize(context) {
76
76
  const config = await loadMCPConfig(process.cwd());
@@ -257,7 +257,7 @@ function generateSkillTool(skills) {
257
257
  };
258
258
  }
259
259
  var builtInSkillsPlugin = {
260
- name: "@pulse-coder/engine/built-in-skills",
260
+ name: "pulse-coder-engine/built-in-skills",
261
261
  version: "1.0.0",
262
262
  async initialize(context) {
263
263
  const registry = new BuiltInSkillRegistry();
@@ -293,7 +293,7 @@ var CoderAI = process.env.USE_ANTHROPIC ? (0, import_anthropic.createAnthropic)(
293
293
  }) : (0, import_openai.createOpenAI)({
294
294
  apiKey: process.env.OPENAI_API_KEY || "",
295
295
  baseURL: process.env.OPENAI_API_URL || "https://api.openai.com/v1"
296
- }).chat;
296
+ }).responses;
297
297
  var DEFAULT_MODEL = process.env.ANTHROPIC_MODEL || process.env.OPENAI_MODEL || "novita/deepseek/deepseek_v3";
298
298
  var MAX_ERROR_COUNT = 3;
299
299
  var MAX_STEPS = 100;
@@ -434,7 +434,16 @@ Here is some useful information about the environment you are running in:
434
434
  };
435
435
 
436
436
  // src/ai/index.ts
437
- var providerOptions = OPENAI_REASONING_EFFORT ? { openai: { reasoningEffort: OPENAI_REASONING_EFFORT } } : void 0;
437
+ var providerOptions = { openai: { store: false, reasoningEffort: OPENAI_REASONING_EFFORT } };
438
+ var resolveSystemPrompt = (option) => {
439
+ const base = generateSystemPrompt();
440
+ if (!option) return base;
441
+ if (typeof option === "string") return option;
442
+ if (typeof option === "function") return option();
443
+ return `${base}
444
+
445
+ ${option.append}`;
446
+ };
438
447
  var wrapToolsWithContext = (tools, context) => {
439
448
  const wrappedTools = {};
440
449
  for (const [name, tool2] of Object.entries(tools)) {
@@ -448,17 +457,13 @@ var wrapToolsWithContext = (tools, context) => {
448
457
  return wrappedTools;
449
458
  };
450
459
  var streamTextAI = (messages, tools, options) => {
451
- const finalMessages = [
452
- {
453
- role: "system",
454
- content: generateSystemPrompt()
455
- },
456
- ...messages
457
- ];
460
+ const provider = options?.provider ?? CoderAI;
461
+ const model = options?.model ?? DEFAULT_MODEL;
458
462
  const wrappedTools = options?.toolExecutionContext ? wrapToolsWithContext(tools, options.toolExecutionContext) : tools;
459
463
  return (0, import_ai.streamText)({
460
- model: CoderAI(DEFAULT_MODEL),
461
- messages: finalMessages,
464
+ model: provider(model),
465
+ system: resolveSystemPrompt(options?.systemPrompt),
466
+ messages,
462
467
  tools: wrappedTools,
463
468
  providerOptions,
464
469
  abortSignal: options?.abortSignal,
@@ -467,6 +472,8 @@ var streamTextAI = (messages, tools, options) => {
467
472
  });
468
473
  };
469
474
  var summarizeMessages = async (messages, options) => {
475
+ const provider = options?.provider ?? CoderAI;
476
+ const model = options?.model ?? DEFAULT_MODEL;
470
477
  const SUMMARY_SYSTEM_PROMPT = "\u4F60\u662F\u8D1F\u8D23\u538B\u7F29\u5BF9\u8BDD\u4E0A\u4E0B\u6587\u7684\u52A9\u624B\u3002\u8BF7\u57FA\u4E8E\u7ED9\u5B9A\u5386\u53F2\u6D88\u606F\uFF0C\u63D0\u70BC\u5173\u952E\u4E8B\u5B9E\u4E0E\u51B3\u7B56\uFF0C\u907F\u514D\u81C6\u6D4B\u6216\u6269\u5C55\u3002";
471
478
  const SUMMARY_USER_PROMPT = [
472
479
  "\u8BF7\u5C06\u4EE5\u4E0A\u5BF9\u8BDD\u538B\u7F29\u4E3A\u4EE5\u4E0B\u683C\u5F0F\uFF0C\u4F7F\u7528\u4E2D\u6587\uFF1A",
@@ -481,9 +488,9 @@ var summarizeMessages = async (messages, options) => {
481
488
  "\u8981\u6C42\uFF1A\u5185\u5BB9\u7B80\u6D01\u51C6\u786E\uFF0C\u4E0D\u8981\u7F16\u9020\u3002"
482
489
  ].join("\n");
483
490
  const result = await (0, import_ai.generateText)({
484
- model: CoderAI(DEFAULT_MODEL),
491
+ model: provider(model),
492
+ system: SUMMARY_SYSTEM_PROMPT,
485
493
  messages: [
486
- { role: "system", content: SUMMARY_SYSTEM_PROMPT },
487
494
  ...messages,
488
495
  { role: "user", content: SUMMARY_USER_PROMPT }
489
496
  ],
@@ -571,7 +578,10 @@ var maybeCompactContext = async (context, options) => {
571
578
  return { didCompact: false };
572
579
  }
573
580
  try {
574
- const summary = await summarizeMessages(oldMessages);
581
+ const summary = await summarizeMessages(oldMessages, {
582
+ provider: options?.provider,
583
+ model: options?.model
584
+ });
575
585
  const summaryText = ensureSummaryPrefix(summary);
576
586
  if (!summaryText) {
577
587
  throw new Error("Empty summary result");
@@ -598,6 +608,20 @@ var maybeCompactContext = async (context, options) => {
598
608
  };
599
609
 
600
610
  // src/core/loop.ts
611
+ function applyToolHooks(tools, hooks) {
612
+ const wrapped = {};
613
+ for (const [name, t] of Object.entries(tools)) {
614
+ wrapped[name] = {
615
+ ...t,
616
+ execute: async (input, ctx) => {
617
+ const finalInput = hooks.onBeforeToolCall ? await hooks.onBeforeToolCall(name, input) ?? input : input;
618
+ const output = await t.execute(finalInput, ctx);
619
+ return hooks.onAfterToolCall ? await hooks.onAfterToolCall(name, finalInput, output) ?? output : output;
620
+ }
621
+ };
622
+ }
623
+ return wrapped;
624
+ }
601
625
  async function loop(context, options) {
602
626
  let errorCount = 0;
603
627
  let totalSteps = 0;
@@ -605,7 +629,10 @@ async function loop(context, options) {
605
629
  while (true) {
606
630
  try {
607
631
  if (compactionAttempts < MAX_COMPACTION_ATTEMPTS) {
608
- const { didCompact, newMessages } = await maybeCompactContext(context);
632
+ const { didCompact, newMessages } = await maybeCompactContext(context, {
633
+ provider: options?.provider,
634
+ model: options?.model
635
+ });
609
636
  if (didCompact) {
610
637
  compactionAttempts++;
611
638
  if (newMessages) {
@@ -614,7 +641,10 @@ async function loop(context, options) {
614
641
  continue;
615
642
  }
616
643
  }
617
- const tools = options?.tools || {};
644
+ let tools = options?.tools || {};
645
+ if (options?.hooks) {
646
+ tools = applyToolHooks(tools, options.hooks);
647
+ }
618
648
  const toolExecutionContext = {
619
649
  onClarificationRequest: options?.onClarificationRequest,
620
650
  abortSignal: options?.abortSignal
@@ -622,6 +652,9 @@ async function loop(context, options) {
622
652
  const result = streamTextAI(context.messages, tools, {
623
653
  abortSignal: options?.abortSignal,
624
654
  toolExecutionContext,
655
+ provider: options?.provider,
656
+ model: options?.model,
657
+ systemPrompt: options?.systemPrompt,
625
658
  onStepFinish: (step) => {
626
659
  options?.onStepFinish?.(step);
627
660
  },
@@ -654,7 +687,11 @@ async function loop(context, options) {
654
687
  }
655
688
  if (finishReason === "length") {
656
689
  if (compactionAttempts < MAX_COMPACTION_ATTEMPTS) {
657
- const { didCompact, newMessages } = await maybeCompactContext(context, { force: true });
690
+ const { didCompact, newMessages } = await maybeCompactContext(context, {
691
+ force: true,
692
+ provider: options?.provider,
693
+ model: options?.model
694
+ });
658
695
  if (didCompact) {
659
696
  compactionAttempts++;
660
697
  if (newMessages) {
@@ -1211,7 +1248,6 @@ var AgentRunner = class {
1211
1248
  async runAgent(config, task, context, tools) {
1212
1249
  const subContext = {
1213
1250
  messages: [
1214
- { role: "system", content: config.systemPrompt },
1215
1251
  { role: "user", content: task }
1216
1252
  ]
1217
1253
  };
@@ -1222,7 +1258,7 @@ var AgentRunner = class {
1222
1258
  ${JSON.stringify(context, null, 2)}`
1223
1259
  });
1224
1260
  }
1225
- return await loop(subContext, { tools });
1261
+ return await loop(subContext, { tools, systemPrompt: config.systemPrompt });
1226
1262
  }
1227
1263
  };
1228
1264
  var SubAgentPlugin = class {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/built-in/index.ts","../../src/built-in/mcp-plugin/index.ts","../../src/built-in/skills-plugin/index.ts","../../src/built-in/sub-agent-plugin/index.ts","../../src/ai/index.ts","../../src/config/index.ts","../../src/prompt/system.ts","../../src/context/index.ts","../../src/core/loop.ts","../../src/tools/read.ts","../../src/tools/utils.ts","../../src/tools/write.ts","../../src/tools/edit.ts","../../src/tools/grep.ts","../../src/tools/ls.ts","../../src/tools/bash.ts","../../src/tools/tavily.ts","../../src/tools/clarify.ts","../../src/tools/index.ts"],"sourcesContent":["/**\n * Built-in plugins for Pulse Coder Engine\n * 引擎内置插件集合\n */\n\nimport { builtInMCPPlugin } from './mcp-plugin';\nimport { builtInSkillsPlugin } from './skills-plugin';\nimport { SubAgentPlugin } from './sub-agent-plugin';\n\n/**\n * 默认内置插件列表\n * 这些插件会在引擎启动时自动加载\n */\nexport const builtInPlugins = [\n builtInMCPPlugin,\n builtInSkillsPlugin,\n new SubAgentPlugin()\n];\n\n/**\n * 单独导出各个内置插件,便于外部使用\n */\nexport { builtInMCPPlugin } from './mcp-plugin';\nexport { builtInSkillsPlugin, BuiltInSkillRegistry } from './skills-plugin';\nexport { SubAgentPlugin } from './sub-agent-plugin';\n\nexport default builtInPlugins;","/**\n * Built-in MCP Plugin for Pulse Coder Engine\n * 将 MCP 功能作为引擎内置插件\n */\n\nimport { EnginePlugin, EnginePluginContext } from '../../plugin/EnginePlugin';\nimport { createMCPClient } from '@ai-sdk/mcp';\nimport { existsSync, readFileSync } from 'fs';\nimport * as path from 'path';\n\nexport interface MCPPluginConfig {\n servers: Record<string, { url: string }>;\n}\n\nexport async function loadMCPConfig(cwd: string): Promise<MCPPluginConfig> {\n // 优先读取 .pulse-coder/mcp.json,兼容旧版 .coder/mcp.json\n const newConfigPath = path.join(cwd, '.pulse-coder', 'mcp.json');\n const legacyConfigPath = path.join(cwd, '.coder', 'mcp.json');\n const configPath = existsSync(newConfigPath) ? newConfigPath : legacyConfigPath;\n\n if (!existsSync(configPath)) {\n return { servers: {} };\n }\n\n try {\n const content = readFileSync(configPath, 'utf-8');\n const parsed = JSON.parse(content);\n \n if (!parsed.servers || typeof parsed.servers !== 'object') {\n console.warn('[MCP] Invalid config: missing \"servers\" object');\n return { servers: {} };\n }\n\n return { servers: parsed.servers };\n } catch (error) {\n console.warn(`[MCP] Failed to load config: ${error instanceof Error ? error.message : 'Unknown error'}`);\n return { servers: {} };\n }\n}\n\nfunction createHTTPTransport(config: { url: string }) {\n return {\n type: 'http' as const,\n url: config.url\n };\n}\n\nexport const builtInMCPPlugin: EnginePlugin = {\n name: '@pulse-coder/engine/built-in-mcp',\n version: '1.0.0',\n\n async initialize(context: EnginePluginContext) {\n const config = await loadMCPConfig(process.cwd());\n\n const serverCount = Object.keys(config.servers).length;\n if (serverCount === 0) {\n console.log('[MCP] No MCP servers configured');\n return;\n }\n\n let loadedCount = 0;\n\n for (const [serverName, serverConfig] of Object.entries(config.servers)) {\n try {\n if (!serverConfig.url) {\n console.warn(`[MCP] Server \"${serverName}\" missing URL, skipping`);\n continue;\n }\n\n const transport = createHTTPTransport(serverConfig);\n const client = await createMCPClient({ transport });\n\n const tools = await client.tools();\n\n // 注册工具到引擎,使用命名空间前缀\n const namespacedTools = Object.fromEntries(\n Object.entries(tools).map(([toolName, tool]) => [\n `mcp_${serverName}_${toolName}`,\n tool as any\n ])\n );\n\n context.registerTools(namespacedTools);\n\n loadedCount++;\n console.log(`[MCP] Server \"${serverName}\" loaded (${Object.keys(tools).length} tools)`);\n\n // 注册服务供其他插件使用\n context.registerService(`mcp:${serverName}`, client);\n\n } catch (error) {\n console.warn(`[MCP] Failed to load server \"${serverName}\": ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n if (loadedCount > 0) {\n console.log(`[MCP] Successfully loaded ${loadedCount}/${serverCount} MCP servers`);\n } else {\n console.warn('[MCP] No MCP servers were loaded successfully');\n }\n }\n};\n\nexport default builtInMCPPlugin;","/**\n * Built-in Skills Plugin for Pulse Coder Engine\n * 将技能系统作为引擎内置插件\n */\n\nimport { EnginePlugin, EnginePluginContext } from '../../plugin/EnginePlugin';\nimport { Tool } from '../../shared/types';\nimport { existsSync, readFileSync } from 'fs';\nimport { globSync } from 'glob';\nimport matter from 'gray-matter';\nimport { homedir } from 'os';\nimport * as path from 'path';\nimport { z } from 'zod';\n\n/**\n * 技能信息接口\n */\nexport interface SkillInfo {\n name: string;\n description: string;\n location: string;\n content: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * 技能注册表\n */\nexport class BuiltInSkillRegistry {\n private skills: Map<string, SkillInfo> = new Map();\n private initialized = false;\n\n /**\n * 初始化注册表,扫描并加载所有技能\n */\n async initialize(cwd: string): Promise<void> {\n if (this.initialized) {\n console.warn('SkillRegistry already initialized');\n return;\n }\n\n console.log('Scanning built-in skills...');\n const skillList = await this.scanSkills(cwd);\n\n this.skills.clear();\n for (const skill of skillList) {\n this.skills.set(skill.name, skill);\n }\n\n this.initialized = true;\n console.log(`Loaded ${this.skills.size} built-in skill(s)`);\n }\n\n /**\n * 扫描技能文件\n */\n private async scanSkills(cwd: string): Promise<SkillInfo[]> {\n const skills: SkillInfo[] = [];\n \n const scanPaths = [\n // 项目级技能(优先 .pulse-coder,兼容旧版 .coder 和 .claude)\n { base: cwd, pattern: '.pulse-coder/skills/**/SKILL.md' },\n { base: cwd, pattern: '.coder/skills/**/SKILL.md' },\n { base: cwd, pattern: '.claude/skills/**/SKILL.md' },\n // 用户级技能(优先 .pulse-coder,兼容旧版 .coder)\n { base: homedir(), pattern: '.pulse-coder/skills/**/SKILL.md' },\n { base: homedir(), pattern: '.coder/skills/**/SKILL.md' }\n ];\n\n for (const { base, pattern } of scanPaths) {\n try {\n const files = globSync(pattern, { cwd: base, absolute: true });\n \n for (const filePath of files) {\n try {\n const skillInfo = this.parseSkillFile(filePath);\n if (skillInfo) {\n skills.push(skillInfo);\n }\n } catch (error) {\n console.warn(`Failed to parse skill file ${filePath}:`, error);\n }\n }\n } catch (error) {\n console.debug(`Skip scanning ${pattern} in ${base}:`, error);\n }\n }\n\n return skills;\n }\n\n /**\n * 解析技能文件\n */\n private parseSkillFile(filePath: string): SkillInfo | null {\n try {\n const content = readFileSync(filePath, 'utf-8');\n const { data, content: markdownContent } = matter(content);\n\n if (!data.name || !data.description) {\n console.warn(`Skill file ${filePath} missing required fields (name or description)`);\n return null;\n }\n\n return {\n name: data.name,\n description: data.description,\n location: filePath,\n content: markdownContent,\n metadata: data\n };\n } catch (error) {\n console.warn(`Failed to read skill file ${filePath}:`, error);\n return null;\n }\n }\n\n /**\n * 获取所有技能\n */\n getAll(): SkillInfo[] {\n return Array.from(this.skills.values());\n }\n\n /**\n * 根据名称获取技能\n */\n get(name: string): SkillInfo | undefined {\n return this.skills.get(name);\n }\n\n /**\n * 检查技能是否存在\n */\n has(name: string): boolean {\n return this.skills.has(name);\n }\n\n /**\n * 搜索技能(模糊匹配)\n */\n search(keyword: string): SkillInfo[] {\n const lowerKeyword = keyword.toLowerCase();\n return this.getAll().filter(\n (skill) =>\n skill.name.toLowerCase().includes(lowerKeyword) ||\n skill.description.toLowerCase().includes(lowerKeyword)\n );\n }\n}\n\n/**\n * 技能工具参数 schema\n */\nconst skillToolSchema = z.object({\n name: z.string().describe('The name of the skill to execute')\n});\n\ntype SkillToolInput = z.infer<typeof skillToolSchema>;\n\n/**\n * 生成技能工具\n */\nfunction generateSkillTool(skills: SkillInfo[]): Tool<SkillToolInput, SkillInfo> {\n const getSkillsPrompt = (availableSkills: SkillInfo[]) => {\n return [\n \"If query matches an available skill's description or instruction [use skill], use the skill tool to get detailed instructions.\",\n \"Load a skill to get detailed instructions for a specific task.\",\n \"Skills provide specialized knowledge and step-by-step guidance.\",\n \"Use this when a task matches an available skill's description.\",\n \"Only the skills listed here are available:\",\n \"[!important] You should follow the skill's step-by-step guidance. If the skill is not complete, ask the user for more information.\",\n \"<available_skills>\",\n ...availableSkills.flatMap((skill) => [\n ` <skill>`,\n ` <name>${skill.name}</name>`,\n ` <description>${skill.description}</description>`,\n ` </skill>`\n ]),\n \"</available_skills>\"\n ].join(\" \");\n };\n\n return {\n name: \"skill\",\n description: getSkillsPrompt(skills),\n inputSchema: skillToolSchema,\n execute: async ({ name }) => {\n const skill = skills.find((skill) => skill.name === name);\n if (!skill) {\n throw new Error(`Skill ${name} not found`);\n }\n return skill;\n }\n };\n}\n\n/**\n * 内置技能插件\n */\nexport const builtInSkillsPlugin: EnginePlugin = {\n name: '@pulse-coder/engine/built-in-skills',\n version: '1.0.0',\n\n async initialize(context: EnginePluginContext) {\n const registry = new BuiltInSkillRegistry();\n await registry.initialize(process.cwd());\n\n const skills = registry.getAll();\n if (skills.length === 0) {\n console.log('[Skills] No skills found');\n return;\n }\n\n const skillTool = generateSkillTool(skills);\n context.registerTool('skill', skillTool);\n context.registerService('skillRegistry', registry);\n\n console.log(`[Skills] Registered ${skills.length} skill(s)`);\n }\n};\n\nexport default builtInSkillsPlugin;","import { z } from 'zod';\nimport { promises as fs } from 'fs';\nimport path from 'path';\nimport type { EnginePlugin, EnginePluginContext } from '../../plugin/EnginePlugin';\nimport type { Context } from '../../shared/types.js';\nimport { loop } from '../../core/loop';\nimport { BuiltinToolsMap } from '../../tools';\nimport { Tool } from 'ai';\n\ninterface AgentConfig {\n name: string;\n description: string;\n systemPrompt: string;\n filePath: string;\n}\n\nclass ConfigLoader {\n\n async getAgentFilesInfo(configDirs: string[]) {\n const fileInfos: Array<{ files: string[], configDir: string }> = [];\n for (let configDir of configDirs) {\n try {\n await fs.access(configDir);\n\n const files = await fs.readdir(configDir);\n fileInfos.push({ files, configDir });\n } catch {\n continue;\n }\n }\n\n return fileInfos;\n }\n\n async loadAgentConfigs(configDir: string | string[] = ['.pulse-coder/agents', '.coder/agents']): Promise<AgentConfig[]> {\n const configs: AgentConfig[] = [];\n\n const configDirs = Array.isArray(configDir) ? configDir : [configDir];\n\n try {\n const filesInfo = await this.getAgentFilesInfo(configDirs);\n\n for (const fileInfo of filesInfo) {\n const files = fileInfo.files;\n for (const file of files) {\n if (file.endsWith('.md')) {\n const config = await this.parseConfig(path.join(fileInfo.configDir, file));\n if (config) configs.push(config);\n }\n }\n }\n } catch (error) {\n console.warn(`Failed to scan agent configs: ${error}`);\n }\n\n return configs;\n }\n\n private async parseConfig(filePath: string): Promise<AgentConfig | null> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.split('\\n');\n\n let name = '';\n let description = '';\n let systemPrompt = '';\n let inFrontmatter = false;\n let frontmatterEnd = false;\n\n for (const line of lines) {\n if (line.trim() === '---') {\n if (!inFrontmatter) {\n inFrontmatter = true;\n continue;\n } else {\n frontmatterEnd = true;\n continue;\n }\n }\n\n if (inFrontmatter && !frontmatterEnd) {\n const match = line.match(/^\\s*(\\w+)\\s*:\\s*(.+)$/);\n if (match) {\n const [, key, value] = match;\n if (key === 'name') name = value.trim();\n if (key === 'description') description = value.trim();\n }\n } else if (frontmatterEnd) {\n systemPrompt += line + '\\n';\n }\n }\n\n if (!name) {\n name = path.basename(filePath, '.md');\n }\n\n return {\n name: name.trim(),\n description: description.trim(),\n systemPrompt: systemPrompt.trim(),\n filePath\n };\n } catch (error) {\n console.warn(`Failed to parse agent config ${filePath}: ${error}`);\n return null;\n }\n }\n}\n\nclass AgentRunner {\n async runAgent(\n config: AgentConfig,\n task: string,\n context?: Record<string, any>,\n tools?: Record<string, any>\n ): Promise<string> {\n const subContext: Context = {\n messages: [\n { role: 'system', content: config.systemPrompt },\n { role: 'user', content: task }\n ]\n };\n\n if (context && Object.keys(context).length > 0) {\n subContext.messages.push({\n role: 'user',\n content: `上下文信息:\\n${JSON.stringify(context, null, 2)}`\n });\n }\n\n return await loop(subContext, { tools });\n }\n}\n\nexport class SubAgentPlugin implements EnginePlugin {\n name = 'sub-agent';\n version = '1.0.0';\n\n private configLoader = new ConfigLoader();\n private agentRunner = new AgentRunner();\n\n async initialize(context: EnginePluginContext): Promise<void> {\n try {\n const configs = await this.configLoader.loadAgentConfigs();\n\n // 获取插件管理器提供的所有工具\n const tools = this.getAvailableTools(context);\n\n for (const config of configs) {\n this.registerAgentTool(context, config, tools);\n }\n\n context.logger.info(`SubAgentPlugin loaded ${configs.length} agents.`);\n } catch (error) {\n context.logger.error('Failed to initialize SubAgentPlugin', error as Error);\n }\n }\n\n private getAvailableTools(context: EnginePluginContext): Record<string, any> {\n // 从插件上下文中获取所有注册的工具\n // 在初始化阶段,所有工具已经通过插件系统注册\n const allTools: Record<string, any> = {};\n\n // 这里我们假设工具通过某种方式可用\n // 实际使用时,引擎会提供所有可用的工具\n return BuiltinToolsMap;\n }\n\n private registerAgentTool(\n context: EnginePluginContext,\n config: AgentConfig,\n tools: Record<string, any>\n ): void {\n const toolName = `${config.name}_agent`;\n\n const tool: Tool = {\n description: config.description,\n inputSchema: z.object({\n task: z.string().describe('要执行的任务描述'),\n context: z.any().optional().describe('任务上下文信息')\n }),\n execute: async ({ task, context: taskContext }: { task: string; context?: Record<string, any> }) => {\n try {\n context.logger.info(`Running agent ${config.name}: ${task}`);\n const result = await this.agentRunner.runAgent(config, task, taskContext, tools);\n context.logger.info(`Agent ${config.name} completed successfully`);\n return result;\n } catch (error) {\n context.logger.error(`Agent ${config.name} failed`, error as Error);\n throw new Error(`Agent ${config.name} failed: ${error}`);\n }\n }\n };\n\n context.registerTool(toolName, tool);\n }\n\n async destroy(context: EnginePluginContext): Promise<void> {\n context.logger.info('SubAgentPlugin destroyed');\n }\n}\n\nexport default SubAgentPlugin;","import { generateText, streamText, tool, type ModelMessage, type StepResult, type Tool } from 'ai';\nimport { CoderAI, DEFAULT_MODEL, COMPACT_SUMMARY_MAX_TOKENS, OPENAI_REASONING_EFFORT } from '../config';\nimport z from 'zod';\nimport { generateSystemPrompt } from '../prompt';\nimport type { Tool as CoderTool, ToolExecutionContext } from '../shared/types';\n\n\nconst providerOptions = OPENAI_REASONING_EFFORT\n ? { openai: { reasoningEffort: OPENAI_REASONING_EFFORT } }\n : undefined;\n\nexport const generateTextAI = (messages: ModelMessage[], tools: Record<string, Tool>) => {\n const finalMessages = [\n {\n role: 'system',\n content: generateSystemPrompt(),\n },\n ...messages,\n ] as ModelMessage[];\n\n return generateText({\n model: CoderAI(DEFAULT_MODEL),\n messages: finalMessages,\n tools,\n providerOptions,\n }) as unknown as ReturnType<typeof generateText> & { steps: StepResult<any>[]; finishReason: string };\n}\n\nexport interface StreamOptions {\n abortSignal?: AbortSignal;\n onStepFinish?: (event: StepResult<any>) => void;\n onChunk?: (event: { chunk: any }) => void;\n toolExecutionContext?: ToolExecutionContext;\n}\n\n/**\n * Wraps tools to inject ToolExecutionContext before execution\n */\nexport const wrapToolsWithContext = (\n tools: Record<string, CoderTool>,\n context?: ToolExecutionContext\n): Record<string, Tool> => {\n const wrappedTools: Record<string, Tool> = {};\n\n for (const [name, tool] of Object.entries(tools)) {\n wrappedTools[name] = {\n ...tool,\n execute: async (input: any) => {\n // Call the original execute with context\n return await tool.execute(input, context);\n }\n } as Tool;\n }\n\n return wrappedTools;\n};\n\nexport const streamTextAI = (messages: ModelMessage[], tools: Record<string, CoderTool>, options?: StreamOptions) => {\n\n const finalMessages = [\n {\n role: 'system',\n content: generateSystemPrompt(),\n },\n ...messages,\n ] as ModelMessage[];\n\n // Wrap tools with execution context if provided\n const wrappedTools = options?.toolExecutionContext\n ? wrapToolsWithContext(tools, options.toolExecutionContext)\n : tools;\n\n return streamText({\n model: CoderAI(DEFAULT_MODEL),\n messages: finalMessages,\n tools: wrappedTools as Record<string, Tool>,\n providerOptions,\n abortSignal: options?.abortSignal,\n onStepFinish: options?.onStepFinish,\n onChunk: options?.onChunk,\n }) as unknown as ReturnType<typeof streamText> & { steps: StepResult<any>[]; finishReason: string };\n}\n\nexport const summarizeMessages = async (\n messages: ModelMessage[],\n options?: { maxOutputTokens?: number }\n): Promise<string> => {\n const SUMMARY_SYSTEM_PROMPT =\n '你是负责压缩对话上下文的助手。请基于给定历史消息,提炼关键事实与决策,避免臆测或扩展。';\n\n const SUMMARY_USER_PROMPT = [\n '请将以上对话压缩为以下格式,使用中文:',\n '[COMPACTED_CONTEXT]',\n '- 目标: ...',\n '- 进展: ...',\n '- 关键结果: ...',\n '- 文件与变更: ...',\n '- 关键片段: \"...\" / `...` / \"...\"',\n '- 待确认: ...',\n '',\n '要求:内容简洁准确,不要编造。',\n ].join('\\n');\n\n const result = await generateText({\n model: CoderAI(DEFAULT_MODEL),\n messages: [\n { role: 'system', content: SUMMARY_SYSTEM_PROMPT },\n ...messages,\n { role: 'user', content: SUMMARY_USER_PROMPT },\n ],\n maxOutputTokens: options?.maxOutputTokens ?? COMPACT_SUMMARY_MAX_TOKENS,\n providerOptions,\n });\n\n return result.text ?? '';\n}","import dotenv from \"dotenv\";\nimport { createOpenAI } from '@ai-sdk/openai';\nimport { createAnthropic } from \"@ai-sdk/anthropic\";\nimport { LanguageModel } from \"ai\";\n\ndotenv.config();\n\nexport const CoderAI = (process.env.USE_ANTHROPIC\n ? createAnthropic({\n apiKey: process.env.ANTHROPIC_API_KEY || '',\n baseURL: process.env.ANTHROPIC_API_URL || 'https://api.anthropic.com/v1'\n })\n : createOpenAI({\n apiKey: process.env.OPENAI_API_KEY || '',\n baseURL: process.env.OPENAI_API_URL || 'https://api.openai.com/v1'\n }).chat) as (model: string) => LanguageModel;\n\nexport const DEFAULT_MODEL = process.env.ANTHROPIC_MODEL || process.env.OPENAI_MODEL || 'novita/deepseek/deepseek_v3';\n\nexport const MAX_TURNS = 100;\nexport const MAX_ERROR_COUNT = 3;\nexport const MAX_STEPS = 100;\nexport const MAX_TOOL_OUTPUT_LENGTH = 30_000;\n\nexport const CONTEXT_WINDOW_TOKENS = Number(process.env.CONTEXT_WINDOW_TOKENS ?? 64_000);\nexport const COMPACT_TRIGGER = Number(process.env.COMPACT_TRIGGER ?? Math.floor(CONTEXT_WINDOW_TOKENS * 0.75));\nexport const COMPACT_TARGET = Number(process.env.COMPACT_TARGET ?? Math.floor(CONTEXT_WINDOW_TOKENS * 0.5));\nexport const KEEP_LAST_TURNS = Number(process.env.KEEP_LAST_TURNS ?? 6);\nexport const COMPACT_SUMMARY_MAX_TOKENS = Number(process.env.COMPACT_SUMMARY_MAX_TOKENS ?? 1200);\nexport const MAX_COMPACTION_ATTEMPTS = Number(process.env.MAX_COMPACTION_ATTEMPTS ?? 2);\nexport const OPENAI_REASONING_EFFORT = process.env.OPENAI_REASONING_EFFORT;\n\n// Clarification settings\nexport const CLARIFICATION_TIMEOUT = Number(process.env.CLARIFICATION_TIMEOUT ?? 300_000); // 5 minutes\nexport const CLARIFICATION_ENABLED = process.env.CLARIFICATION_ENABLED !== 'false';","export const generateSystemPrompt = () => {\n const basePrompt = `\nYou are Pulse Coder, the best coding agent on the planet.\n\nYou are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.\n\n## Editing constraints\n- Default to ASCII when editing or creating files. Only introduce non-ASCII or other Unicode characters when there is a clear justification and the file already uses them.\n- Only add comments if they are necessary to make a non-obvious block easier to understand.\n- Try to use apply_patch for single file edits, but it is fine to explore other options to make the edit if it does not work well. Do not use apply_patch for changes that are auto-generated (i.e. generating package.json or running a lint or format command like gofmt) or when scripting is more efficient (such as search and replacing a string across a codebase).\n\n## Skills\n- If query matches an available skill's description or instruction [use skill], use the skill tool to get detailed instructions.\n- You should Load a skill to get detailed instructions for a specific task. It always is a complex task that requires multiple steps.\n- You should check the skill is complete and follow the step-by-step guidance. If the skill is not complete, you should ask the user for more information.\n\n## Tool usage\n- Prefer specialized tools over shell for file operations:\n - Use Read to view files, Edit to modify files, and Write only when needed.\n - Use Glob to find files by name and Grep to search file contents.\n- Use Bash for terminal operations (git, bun, builds, tests, running scripts).\n- Run tool calls in parallel when neither call needs the other’s output; otherwise run sequentially.\n\n## Git and workspace hygiene\n- You may be in a dirty git worktree.\n * NEVER revert existing changes you did not make unless explicitly requested, since these changes were made by the user.\n * If asked to make a commit or code edits and there are unrelated changes to your work or changes that you didn't make in those files, don't revert those changes.\n * If the changes are in files you've touched recently, you should read carefully and understand how you can work with the changes rather than reverting them.\n * If the changes are in unrelated files, just ignore them and don't revert them.\n- Do not amend commits unless explicitly requested.\n- **NEVER** use destructive commands like \\`git reset --hard\\` or \\`git checkout--\\` unless specifically requested or approved by the user.\n\n## Frontend tasks\nWhen doing frontend design tasks, avoid collapsing into bland, generic layouts.\nAim for interfaces that feel intentional and deliberate.\n- Typography: Use expressive, purposeful fonts and avoid default stacks (Inter, Roboto, Arial, system).\n- Color & Look: Choose a clear visual direction; define CSS variables; avoid purple-on-white defaults. No purple bias or dark mode bias.\n- Motion: Use a few meaningful animations (page-load, staggered reveals) instead of generic micro-motions.\n- Background: Don't rely on flat, single-color backgrounds; use gradients, shapes, or subtle patterns to build atmosphere.\n- Overall: Avoid boilerplate layouts and interchangeable UI patterns. Vary themes, type families, and visual languages across outputs.\n- Ensure the page loads properly on both desktop and mobile.\n\nException: If working within an existing website or design system, preserve the established patterns, structure, and visual language.\n\n## Presenting your work and final message\n\nYou are producing plain text that will later be styled by the CLI. Follow these rules exactly. Formatting should make results easy to scan, but not feel mechanical. Use judgment to decide how much structure adds value.\n\n- Default: be very concise; friendly coding teammate tone.\n- Default: do the work without asking questions. Treat short tasks as sufficient direction; infer missing details by reading the codebase and following existing conventions.\n- Questions: only ask when you are truly blocked after checking relevant context AND you cannot safely pick a reasonable default. This usually means one of:\n * The request is ambiguous in a way that materially changes the result and you cannot disambiguate by reading the repo.\n * The action is destructive/irreversible, touches production, or changes billing/security posture.\n * You need a secret/credential/value that cannot be inferred (API key, account id, etc.).\n- If you must ask: do all non-blocked work first, then ask exactly one targeted question, include your recommended default, and state what would change based on the answer.\n- Never ask permission questions like \"Should I proceed?\" or \"Do you want me to run tests?\"; proceed with the most reasonable option and mention what you did.\n\n## Clarification Tool\n\nUse the 'clarify' tool when you genuinely need information from the user to proceed. This tool pauses execution and waits for user input.\n\n**When to use clarify:**\n- The request is ambiguous in a way that materially affects the implementation and cannot be resolved by reading the codebase\n- You cannot safely infer the answer from existing code, conventions, or context\n- You need confirmation before destructive or irreversible actions (e.g., deleting resources, modifying production data)\n- You need specific values that cannot be guessed (API keys, account IDs, specific user choices between valid alternatives)\n\n**When NOT to use clarify:**\n- For trivial decisions you can make based on codebase conventions or common practices\n- For permission questions like \"Should I proceed?\" (just proceed with the best option)\n- For information that's likely in the codebase, configuration files, or documentation (read those first)\n- Multiple times in a row - complete all non-blocked work first, then ask one clear question\n- For choices where a reasonable default exists (use the default and mention what you chose)\n\n**How to use clarify:**\n- Ask ONE clear, specific question per clarification\n- Provide context if needed to help the user understand the choice\n- Include a recommended default answer when applicable\n- Explain briefly what would change based on the answer\n\nExample usage: Call clarify with a question, optional context, and optional default answer. The tool will pause and wait for the user's response.\n- For substantial work, summarize clearly; follow final‑answer formatting.\n- Skip heavy formatting for simple confirmations.\n- Don't dump large files you've written; reference paths only.\n- No \"save/copy this file\" - User is on the same machine.\n- Offer logical next steps (tests, commits, build) briefly; add verify steps if you couldn't do something.\n- For code changes:\n * Lead with a quick explanation of the change, and then give more details on the context covering where and why a change was made. Do not start this explanation with \"summary\", just jump right in.\n * If there are natural next steps the user may want to take, suggest them at the end of your response. Do not make suggestions if there are no natural next steps.\n * When suggesting multiple options, use numeric lists for the suggestions so the user can quickly respond with a single number.\n- The user does not command execution outputs. When asked to show the output of a command (e.g. \\`git show\\`), relay the important details in your answer or summarize the key lines so the user understands the result.\n\n## Final answer structure and style guidelines\n\n- Plain text; CLI handles styling. Use structure only when it helps scanability.\n- Headers: optional; short Title Case (1-3 words) wrapped in **…**; no blank line before the first bullet; add only if they truly help.\n- Bullets: use - ; merge related points; keep to one line when possible; 4–6 per list ordered by importance; keep phrasing consistent.\n- Monospace: backticks for commands/paths/env vars/code ids and inline examples; use for literal keyword bullets; never combine with **.\n- Code samples or multi-line snippets should be wrapped in fenced code blocks; include an info string as often as possible.\n- Structure: group related bullets; order sections general → specific → supporting; for subsections, start with a bolded keyword bullet, then items; match complexity to the task.\n- Tone: collaborative, concise, factual; present tense, active voice; self‑contained; no \"above/below\"; parallel wording.\n- Don'ts: no nested bullets/hierarchies; no ANSI codes; don't cram unrelated keywords; keep keyword lists short—wrap/reformat if long; avoid naming formatting styles in answers.\n- Adaptation: code explanations → precise, structured with code refs; simple tasks → lead with outcome; big changes → logical walkthrough + rationale + next actions; casual one-offs → plain sentences, no headers/bullets.\n- File References: When referencing files in your response follow the below rules:\n * Use inline code to make file paths clickable.\n * Each reference should have a stand alone path. Even if it's the same file.\n * Accepted: absolute, workspace‑relative, a/ or b/ diff prefixes, or bare filename/suffix.\n * Optionally include line/column (1‑based): :line[:column] or #Lline[Ccolumn] (column defaults to 1).\n * Do not use URIs like file://, vscode://, or https://.\n * Do not provide range of lines\n * Examples: src/app.ts, src/app.ts:42, b/server/index.js#L10, C:\\repo\\project\\main.rs:12:5\n\nHere is some useful information about the environment you are running in:\n<env>\n Working directory: ${process.cwd()}\n Platform: darwin\n Today's date: ${new Date().toLocaleDateString()}\n</env>\n<files>\n\n</files>`;\n\n return basePrompt;\n};\n\nexport default generateSystemPrompt;","import { pruneMessages, type ModelMessage } from \"ai\";\nimport { summarizeMessages } from \"../ai\";\nimport {\n COMPACT_TRIGGER,\n COMPACT_TARGET,\n KEEP_LAST_TURNS,\n} from \"../config/index\";\nimport type { Context } from \"../shared/types\";\n\ntype CompactResult = {\n didCompact: boolean;\n reason?: string;\n newMessages?: ModelMessage[];\n};\n\nconst ensureSummaryPrefix = (summary: string): string => {\n const trimmed = summary.trim();\n if (trimmed.length === 0) {\n return '';\n }\n if (trimmed.startsWith('[COMPACTED_CONTEXT]')) {\n return trimmed;\n }\n return `[COMPACTED_CONTEXT]\\n${trimmed}`;\n};\n\nconst safeStringify = (value: unknown): string => {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n};\n\nconst estimateTokens = (messages: ModelMessage[]): number => {\n let totalChars = 0;\n for (const message of messages) {\n totalChars += message.role.length;\n if (typeof message.content === 'string') {\n totalChars += message.content.length;\n } else {\n totalChars += safeStringify(message.content).length;\n }\n }\n return Math.ceil(totalChars / 4);\n};\n\nconst splitByTurns = (messages: ModelMessage[], keepLastTurns: number) => {\n const userIndices: number[] = [];\n messages.forEach((message, index) => {\n if (message.role === 'user') {\n userIndices.push(index);\n }\n });\n\n if (userIndices.length <= keepLastTurns) {\n return { oldMessages: [], recentMessages: messages };\n }\n\n const cutIndex = userIndices[userIndices.length - keepLastTurns];\n return {\n oldMessages: messages.slice(0, cutIndex),\n recentMessages: messages.slice(cutIndex),\n };\n};\n\nconst takeLastTurns = (messages: ModelMessage[], keepLastTurns: number): ModelMessage[] => {\n const userIndices: number[] = [];\n messages.forEach((message, index) => {\n if (message.role === 'user') {\n userIndices.push(index);\n }\n });\n\n if (userIndices.length === 0) {\n return messages;\n }\n\n if (userIndices.length <= keepLastTurns) {\n return messages;\n }\n\n const startIndex = userIndices[userIndices.length - keepLastTurns];\n return messages.slice(startIndex);\n};\n\nexport const maybeCompactContext = async (\n context: Context,\n options?: { force?: boolean }\n): Promise<CompactResult> => {\n const { messages } = context;\n if (messages.length === 0) {\n return { didCompact: false };\n }\n\n const estimatedTokens = estimateTokens(messages);\n if (!options?.force && estimatedTokens < COMPACT_TRIGGER) {\n return { didCompact: false };\n }\n\n const { oldMessages, recentMessages } = splitByTurns(messages, KEEP_LAST_TURNS);\n if (oldMessages.length === 0) {\n return { didCompact: false };\n }\n\n try {\n const summary = await summarizeMessages(oldMessages);\n const summaryText = ensureSummaryPrefix(summary);\n if (!summaryText) {\n throw new Error('Empty summary result');\n }\n\n const nextMessages: ModelMessage[] = [\n { role: 'assistant', content: summaryText },\n ...recentMessages,\n ];\n\n if (estimateTokens(nextMessages) > COMPACT_TARGET) {\n const newMessages = takeLastTurns(messages, KEEP_LAST_TURNS);\n return { didCompact: true, reason: 'summary-too-large', newMessages };\n }\n\n return { didCompact: true, newMessages: nextMessages };\n } catch (error) {\n const pruned = pruneMessages({\n messages,\n reasoning: 'all',\n toolCalls: 'all',\n emptyMessages: 'remove',\n });\n const newMessages = takeLastTurns(pruned, KEEP_LAST_TURNS);\n return { didCompact: true, reason: 'fallback', newMessages };\n }\n};","import { ToolSet, type StepResult, type ModelMessage } from \"ai\";\nimport type { Context, ClarificationRequest, Tool } from \"../shared/types\";\nimport { streamTextAI } from \"../ai\";\nimport { maybeCompactContext } from \"../context\";\nimport {\n MAX_COMPACTION_ATTEMPTS,\n MAX_ERROR_COUNT,\n MAX_STEPS\n} from \"../config/index.js\";\n\nexport interface LoopOptions {\n onText?: (delta: string) => void;\n onToolCall?: (toolCall: any) => void;\n onToolResult?: (toolResult: any) => void;\n onStepFinish?: (step: StepResult<any>) => void;\n onClarificationRequest?: (request: ClarificationRequest) => Promise<string>;\n onCompacted?: (newMessages: ModelMessage[]) => void;\n onResponse?: (messages: StepResult<ToolSet>['response']['messages']) => void;\n abortSignal?: AbortSignal;\n\n tools?: Record<string, Tool>; // 允许传入工具覆盖默认工具\n}\n\nexport async function loop(context: Context, options?: LoopOptions): Promise<string> {\n let errorCount = 0;\n let totalSteps = 0;\n let compactionAttempts = 0;\n\n while (true) {\n try {\n if (compactionAttempts < MAX_COMPACTION_ATTEMPTS) {\n const { didCompact, newMessages } = await maybeCompactContext(context);\n if (didCompact) {\n compactionAttempts++;\n\n if (newMessages) {\n options?.onCompacted?.(newMessages)\n }\n continue;\n }\n }\n\n const tools = options?.tools || {}; // 允许传入工具覆盖默认工具\n\n // Prepare tool execution context\n const toolExecutionContext = {\n onClarificationRequest: options?.onClarificationRequest,\n abortSignal: options?.abortSignal\n };\n\n const result = streamTextAI(context.messages, tools, {\n abortSignal: options?.abortSignal,\n toolExecutionContext,\n onStepFinish: (step) => {\n options?.onStepFinish?.(step);\n },\n onChunk: ({ chunk }) => {\n if (chunk.type === 'text-delta') {\n options?.onText?.(chunk.text);\n }\n if (chunk.type === 'tool-call') {\n options?.onToolCall?.(chunk);\n }\n if (chunk.type === 'tool-result') {\n options?.onToolResult?.(chunk);\n }\n },\n });\n\n const [text, steps, finishReason] = await Promise.all([\n result.text,\n result.steps,\n result.finishReason,\n ]);\n\n totalSteps += steps.length;\n\n for (const step of steps) {\n if (step.response?.messages?.length) {\n const messages = [...step.response.messages];\n options?.onResponse?.(messages);\n }\n }\n\n if (finishReason === 'stop') {\n return text || 'Task completed.';\n }\n\n if (finishReason === 'length') {\n if (compactionAttempts < MAX_COMPACTION_ATTEMPTS) {\n const { didCompact, newMessages } = await maybeCompactContext(context, { force: true });\n if (didCompact) {\n compactionAttempts++;\n if (newMessages) {\n options?.onCompacted?.(newMessages)\n }\n continue;\n }\n }\n return text || 'Context limit reached.';\n }\n\n if (finishReason === 'content-filter') {\n return text || 'Content filtered.';\n }\n\n if (finishReason === 'error') {\n return text || 'Task failed.';\n }\n\n if (finishReason === 'tool-calls') {\n if (totalSteps >= MAX_STEPS) {\n return text || 'Max steps reached, task may be incomplete.';\n }\n continue;\n }\n\n return text || 'Task completed.';\n } catch (error: any) {\n if (options?.abortSignal?.aborted || error?.name === 'AbortError') {\n return 'Request aborted.';\n }\n\n errorCount++;\n if (errorCount >= MAX_ERROR_COUNT) {\n return `Failed after ${errorCount} errors: ${error?.message ?? String(error)}`;\n }\n\n if (isRetryableError(error)) {\n const delay = Math.min(2000 * Math.pow(2, errorCount - 1), 30000);\n await sleep(delay);\n continue;\n }\n\n return `Error: ${error?.message ?? String(error)}`;\n }\n }\n}\n\nfunction isRetryableError(error: any): boolean {\n const status = error?.status ?? error?.statusCode;\n return status === 429 || status === 500 || status === 502 || status === 503;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}","import z from \"zod\";\nimport { readFileSync, existsSync, statSync } from \"fs\";\nimport type { Tool } from \"../shared/types\";\nimport { truncateOutput } from \"./utils\";\n\nexport const ReadTool: Tool<\n { filePath: string; offset?: number; limit?: number },\n { content: string; totalLines?: number }\n> = {\n name: 'read',\n description: 'Read the contents of a file. Supports reading specific line ranges with offset and limit.',\n inputSchema: z.object({\n filePath: z.string().describe('The absolute path to the file to read'),\n offset: z.number().optional().describe('The line number to start reading from (0-based). Only provide if the file is too large to read at once.'),\n limit: z.number().optional().describe('The number of lines to read. Only provide if the file is too large to read at once.'),\n }),\n execute: async ({ filePath, offset, limit }) => {\n // Check if file exists\n if (!existsSync(filePath)) {\n throw new Error(`File does not exist: ${filePath}`);\n }\n\n // Check if it's a directory\n const stats = statSync(filePath);\n if (stats.isDirectory()) {\n throw new Error(`Cannot read directory: ${filePath}. Use 'ls' tool to list directory contents.`);\n }\n\n // Read the entire file\n const content = readFileSync(filePath, 'utf-8');\n const lines = content.split('\\n');\n const totalLines = lines.length;\n\n // If no offset/limit specified, return the entire file\n if (offset === undefined && limit === undefined) {\n return {\n content: truncateOutput(content),\n totalLines,\n };\n }\n\n // Apply offset and limit\n const startLine = offset || 0;\n const endLine = limit ? startLine + limit : lines.length;\n\n // Validate range\n if (startLine < 0 || startLine >= totalLines) {\n throw new Error(`Invalid offset: ${startLine}. File has ${totalLines} lines.`);\n }\n\n // Extract the requested lines\n const selectedLines = lines.slice(startLine, endLine);\n\n // Format with line numbers (1-based for display)\n const numberedContent = selectedLines\n .map((line, idx) => {\n const lineNum = startLine + idx + 1;\n return `${String(lineNum).padStart(6, ' ')}→${line}`;\n })\n .join('\\n');\n\n return {\n content: truncateOutput(numberedContent),\n totalLines,\n };\n },\n};\n\nexport default ReadTool;\n","import { MAX_TOOL_OUTPUT_LENGTH } from \"../config\";\n\nexport const truncateOutput = (output: string): string => {\n if (output.length <= MAX_TOOL_OUTPUT_LENGTH) {\n return output;\n }\n\n const half = Math.floor(MAX_TOOL_OUTPUT_LENGTH / 2);\n const removed = output.length - MAX_TOOL_OUTPUT_LENGTH;\n\n return (\n output.slice(0, half) +\n `\\n\\n... [truncated ${removed} characters] ...\\n\\n` +\n output.slice(-half)\n );\n};\n","import z from \"zod\";\nimport { writeFileSync, mkdirSync, existsSync } from \"fs\";\nimport { dirname } from \"path\";\nimport type { Tool } from \"../shared/types\";\n\nexport const WriteTool: Tool<\n { filePath: string; content: string },\n { success: boolean; created: boolean; bytes: number }\n> = {\n name: 'write',\n description: 'Write contents to a file. Automatically creates parent directories if they do not exist. Will overwrite existing files.',\n inputSchema: z.object({\n filePath: z.string().describe('The absolute path to the file to write (must be absolute, not relative)'),\n content: z.string().describe('The content to write to the file'),\n }),\n execute: async ({ filePath, content }) => {\n // Check if file already exists\n const fileExists = existsSync(filePath);\n\n // Get the directory path\n const dir = dirname(filePath);\n\n // Create parent directories if they don't exist\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Write the file\n writeFileSync(filePath, content, 'utf-8');\n\n // Calculate bytes written\n const bytes = Buffer.byteLength(content, 'utf-8');\n\n return {\n success: true,\n created: !fileExists,\n bytes,\n };\n },\n};\n\nexport default WriteTool;\n","import z from \"zod\";\nimport { readFileSync, writeFileSync } from \"fs\";\nimport type { Tool } from \"../shared/types\";\nimport { truncateOutput } from \"./utils\";\n\nexport const EditTool: Tool<\n { filePath: string; oldString: string; newString: string; replaceAll?: boolean },\n { success: boolean; replacements: number; preview?: string }\n> = {\n name: 'edit',\n description: 'Performs exact string replacements in files. Use this to edit existing files by replacing old_string with new_string.',\n inputSchema: z.object({\n filePath: z.string().describe('The absolute path to the file to modify'),\n oldString: z.string().describe('The exact text to replace (must match exactly)'),\n newString: z.string().describe('The text to replace it with (must be different from old_string)'),\n replaceAll: z.boolean().optional().default(false).describe('Replace all occurrences of old_string (default false)'),\n }),\n execute: async ({ filePath, oldString, newString, replaceAll = false }) => {\n // Validate that old and new strings are different\n if (oldString === newString) {\n throw new Error('old_string and new_string must be different');\n }\n\n // Read the file\n const content = readFileSync(filePath, 'utf-8');\n\n // Check if oldString exists in the file\n if (!content.includes(oldString)) {\n throw new Error(`old_string not found in file: ${filePath}`);\n }\n\n let newContent: string;\n let replacements = 0;\n\n if (replaceAll) {\n // Replace all occurrences\n const parts = content.split(oldString);\n replacements = parts.length - 1;\n newContent = parts.join(newString);\n } else {\n // Replace only the first occurrence\n const index = content.indexOf(oldString);\n if (index === -1) {\n throw new Error(`old_string not found in file: ${filePath}`);\n }\n\n // Check if the string is unique (appears only once)\n const secondIndex = content.indexOf(oldString, index + oldString.length);\n if (secondIndex !== -1) {\n throw new Error(\n 'old_string is not unique in the file. Either provide a larger string with more surrounding context to make it unique or use replace_all to change every instance.'\n );\n }\n\n newContent = content.slice(0, index) + newString + content.slice(index + oldString.length);\n replacements = 1;\n }\n\n // Write the modified content back\n writeFileSync(filePath, newContent, 'utf-8');\n\n // Generate a preview of the changes (show the changed section with context)\n const changedIndex = newContent.indexOf(newString);\n const contextLength = 200;\n const start = Math.max(0, changedIndex - contextLength);\n const end = Math.min(newContent.length, changedIndex + newString.length + contextLength);\n const preview = truncateOutput(\n `...${newContent.slice(start, end)}...`\n );\n\n return {\n success: true,\n replacements,\n preview,\n };\n },\n};\n\nexport default EditTool;\n","import z from \"zod\";\nimport { execSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport type { Tool } from \"../shared/types\";\nimport { truncateOutput } from \"./utils\";\n\nexport const GrepTool: Tool<\n {\n pattern: string;\n path?: string;\n glob?: string;\n type?: string;\n outputMode?: 'content' | 'files_with_matches' | 'count';\n context?: number;\n caseInsensitive?: boolean;\n headLimit?: number;\n offset?: number;\n multiline?: boolean;\n },\n { output: string; matches?: number }\n> = {\n name: 'grep',\n description: 'A powerful search tool built on ripgrep. Supports regex patterns, file filtering, and multiple output modes.',\n inputSchema: z.object({\n pattern: z.string().describe('The regular expression pattern to search for in file contents'),\n path: z.string().optional().describe('File or directory to search in. Defaults to current working directory.'),\n glob: z.string().optional().describe('Glob pattern to filter files (e.g. \"*.js\", \"*.{ts,tsx}\")'),\n type: z.string().optional().describe('File type to search (e.g., js, py, rust, go, java, ts, tsx, json, md)'),\n outputMode: z.enum(['content', 'files_with_matches', 'count']).optional().default('files_with_matches')\n .describe('Output mode: \"content\" shows matching lines, \"files_with_matches\" shows file paths, \"count\" shows match counts'),\n context: z.number().optional().describe('Number of lines to show before and after each match (only with output_mode: \"content\")'),\n caseInsensitive: z.boolean().optional().default(false).describe('Case insensitive search'),\n headLimit: z.number().optional().default(0).describe('Limit output to first N lines/entries. 0 means unlimited.'),\n offset: z.number().optional().default(0).describe('Skip first N lines/entries before applying head_limit'),\n multiline: z.boolean().optional().default(false).describe('Enable multiline mode where patterns can span lines'),\n }),\n execute: async ({\n pattern,\n path = '.',\n glob,\n type,\n outputMode = 'files_with_matches',\n context,\n caseInsensitive = false,\n headLimit = 0,\n offset = 0,\n multiline = false,\n }) => {\n // Build ripgrep command\n const args: string[] = ['rg'];\n\n // Pattern\n args.push(pattern);\n\n // Case sensitivity\n if (caseInsensitive) {\n args.push('-i');\n }\n\n // Output mode\n if (outputMode === 'files_with_matches') {\n args.push('-l'); // --files-with-matches\n } else if (outputMode === 'count') {\n args.push('-c'); // --count\n } else if (outputMode === 'content') {\n args.push('-n'); // Show line numbers\n if (context !== undefined) {\n args.push(`-C${context}`);\n }\n }\n\n // Multiline mode\n if (multiline) {\n args.push('-U'); // --multiline\n args.push('--multiline-dotall');\n }\n\n // File filtering\n if (glob) {\n args.push('--glob', glob);\n }\n if (type) {\n args.push('--type', type);\n }\n\n // Path\n if (path && path !== '.') {\n // Verify path exists\n if (!existsSync(path)) {\n throw new Error(`Path does not exist: ${path}`);\n }\n args.push(path);\n }\n\n // Build the command string\n let command = args.map(arg => {\n // Quote arguments that contain spaces or special characters\n if (arg.includes(' ') || arg.includes('$') || arg.includes('*')) {\n return `'${arg.replace(/'/g, \"'\\\\''\")}'`;\n }\n return arg;\n }).join(' ');\n\n // Add tail/head for offset/limit\n if (offset > 0) {\n command += ` | tail -n +${offset + 1}`;\n }\n if (headLimit > 0) {\n command += ` | head -n ${headLimit}`;\n }\n\n try {\n const output = execSync(command, {\n encoding: 'utf-8',\n maxBuffer: 1024 * 1024 * 10, // 10MB\n shell: '/bin/bash',\n });\n\n // Count matches for count mode\n let matches: number | undefined;\n if (outputMode === 'count') {\n matches = output.split('\\n').filter(line => line.trim()).length;\n } else if (outputMode === 'files_with_matches') {\n matches = output.split('\\n').filter(line => line.trim()).length;\n }\n\n return {\n output: truncateOutput(output || '(no matches found)'),\n matches,\n };\n } catch (error: any) {\n // Exit code 1 means no matches found (not an error)\n if (error.status === 1) {\n return {\n output: '(no matches found)',\n matches: 0,\n };\n }\n\n // Other errors\n throw new Error(\n `grep failed: ${error.stderr || error.message}\\nCommand: ${command}`\n );\n }\n },\n};\n\nexport default GrepTool;\n","import z from \"zod\";\nimport { readdirSync } from \"fs\";\nimport type { Tool } from \"../shared/types\";\n\nexport const LsTool: Tool<\n { path?: string },\n { files: string[] }\n> = {\n name: 'ls',\n description: 'List files and directories in a given path',\n inputSchema: z.object({\n path: z.string().optional().describe('The path to list files from (defaults to current directory)'),\n }),\n execute: async ({ path = '.' }) => {\n const files = readdirSync(path);\n return { files };\n },\n};\n\nexport default LsTool;\n","import z from \"zod\";\nimport { execSync } from \"child_process\";\nimport type { Tool } from \"../shared/types\";\nimport { truncateOutput } from \"./utils\";\n\nexport const BashTool: Tool<\n { command: string; timeout?: number; cwd?: string; description?: string },\n { output: string; error?: string; exitCode?: number }\n> = {\n name: 'bash',\n description: 'Execute a bash command and return the output. Supports timeout and working directory configuration.',\n inputSchema: z.object({\n command: z.string().describe('The bash command to execute'),\n timeout: z.number().optional().describe('Optional timeout in milliseconds (max 600000ms / 10 minutes). Defaults to 120000ms (2 minutes).'),\n cwd: z.string().optional().describe('Optional working directory for command execution. Defaults to current directory.'),\n description: z.string().optional().describe('Optional description of what this command does (for logging/debugging)'),\n }),\n execute: async ({ command, timeout = 120000, cwd, description }) => {\n // Validate timeout\n if (timeout && (timeout < 0 || timeout > 600000)) {\n throw new Error('Timeout must be between 0 and 600000ms (10 minutes)');\n }\n\n try {\n const output = execSync(command, {\n encoding: 'utf-8',\n maxBuffer: 1024 * 1024 * 10, // 10MB\n timeout: timeout || 120000,\n cwd: cwd || process.cwd(),\n shell: '/bin/bash',\n });\n return {\n output: truncateOutput(output || '(command completed with no output)'),\n exitCode: 0,\n };\n } catch (error: any) {\n const exitCode = error.status || error.code || 1;\n const stdout = String(error.stdout || '');\n const stderr = String(error.stderr || error.message || '');\n\n // Check if it's a timeout error\n if (error.killed && error.signal === 'SIGTERM') {\n return {\n output: truncateOutput(stdout),\n error: truncateOutput(`Command timed out after ${timeout}ms\\n${stderr}`),\n exitCode,\n };\n }\n\n return {\n output: truncateOutput(stdout),\n error: truncateOutput(stderr),\n exitCode,\n };\n }\n },\n};\n\nexport default BashTool;\n","import z from \"zod\";\nimport type { Tool } from \"../shared/types\";\nimport { truncateOutput } from \"./utils\";\n\nexport const TavilyTool: Tool<\n { query: string; maxResults?: number },\n { results: Array<{ title: string; url: string; content: string; score?: number }> }\n> = {\n name: 'tavily',\n description: 'Search the web using Tavily API',\n inputSchema: z.object({\n query: z.string().describe('The search query'),\n maxResults: z.number().optional().default(5).describe('Maximum number of results to return'),\n }),\n execute: async ({ query, maxResults = 5 }) => {\n const apiKey = process.env.TAVILY_API_KEY;\n\n if (!apiKey) {\n throw new Error('TAVILY_API_KEY environment variable is not set');\n }\n\n const response = await fetch('https://api.tavily.com/search', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n api_key: apiKey,\n query,\n max_results: maxResults,\n search_depth: 'basic',\n include_answer: false,\n include_raw_content: false,\n include_images: false,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Tavily API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n\n return {\n results: data.results?.map((result: any) => ({\n title: result.title || '',\n url: result.url || '',\n content: truncateOutput(result.content || ''),\n score: result.score || 0,\n })) || [],\n };\n },\n};\n\nexport default TavilyTool;\n","import z from \"zod\";\nimport type { Tool, ToolExecutionContext } from \"../shared/types\";\nimport { CLARIFICATION_TIMEOUT } from \"../config/index.js\";\nimport { randomUUID } from \"crypto\";\n\nexport interface ClarifyInput {\n question: string;\n context?: string;\n defaultAnswer?: string;\n timeout?: number;\n}\n\nexport interface ClarifyOutput {\n answer: string;\n timedOut: boolean;\n}\n\nexport const ClarifyTool: Tool<ClarifyInput, ClarifyOutput> = {\n name: 'clarify',\n description: 'Ask the user a clarifying question and wait for their response. Use this when you need information from the user to proceed with the task.',\n inputSchema: z.object({\n question: z.string().describe('The question to ask the user'),\n context: z.string().optional().describe('Additional context to help the user answer'),\n defaultAnswer: z.string().optional().describe('Default answer if user does not respond within timeout'),\n timeout: z.number().optional().describe('Timeout in milliseconds (default: 5 minutes)')\n }),\n execute: async (input, toolContext) => {\n if (!toolContext?.onClarificationRequest) {\n throw new Error('Clarification is not supported in this context. The clarify tool requires a CLI interface with user interaction.');\n }\n\n const timeout = input.timeout ?? CLARIFICATION_TIMEOUT;\n const requestId = randomUUID();\n\n try {\n // Create a promise that rejects on timeout\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Clarification request timed out after ${timeout}ms`));\n }, timeout);\n });\n\n // Race between user response and timeout\n const answer = await Promise.race([\n toolContext.onClarificationRequest({\n id: requestId,\n question: input.question,\n context: input.context,\n defaultAnswer: input.defaultAnswer,\n timeout\n }),\n timeoutPromise\n ]);\n\n return {\n answer,\n timedOut: false\n };\n } catch (error: any) {\n // If timeout occurred and we have a default answer, use it\n if (error?.message?.includes('timed out') && input.defaultAnswer) {\n return {\n answer: input.defaultAnswer,\n timedOut: true\n };\n }\n\n // Otherwise, re-throw the error\n throw error;\n }\n },\n};\n\nexport default ClarifyTool;\n","import { ReadTool } from './read';\nimport { WriteTool } from './write';\nimport { EditTool } from './edit';\nimport { GrepTool } from './grep';\nimport { LsTool } from './ls';\nimport { BashTool } from './bash';\nimport { TavilyTool } from './tavily';\nimport { ClarifyTool } from './clarify';\nimport { Tool } from 'ai';\n// import { SkillTool } from './skill;\n\nexport const BuiltinTools = [\n ReadTool,\n WriteTool,\n EditTool,\n GrepTool,\n LsTool,\n BashTool,\n TavilyTool,\n ClarifyTool,\n] as const;\n\nexport const BuiltinToolsMap = BuiltinTools.reduce((acc, toolInstance) => {\n acc[toolInstance.name] = toolInstance;\n return acc;\n}, {} as Record<string, any>);\n\nexport const getFinalToolsMap = (customTools?: Record<string, Tool>) => {\n if (!customTools) {\n return BuiltinToolsMap;\n }\n return { ...BuiltinToolsMap, ...customTools };\n};\n\nexport {\n ReadTool,\n WriteTool,\n EditTool,\n GrepTool,\n LsTool,\n BashTool,\n TavilyTool,\n ClarifyTool,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACMA,iBAAgC;AAChC,gBAAyC;AACzC,WAAsB;AAMtB,eAAsB,cAAc,KAAuC;AAEzE,QAAM,gBAAqB,UAAK,KAAK,gBAAgB,UAAU;AAC/D,QAAM,mBAAwB,UAAK,KAAK,UAAU,UAAU;AAC5D,QAAM,iBAAa,sBAAW,aAAa,IAAI,gBAAgB;AAE/D,MAAI,KAAC,sBAAW,UAAU,GAAG;AAC3B,WAAO,EAAE,SAAS,CAAC,EAAE;AAAA,EACvB;AAEA,MAAI;AACF,UAAM,cAAU,wBAAa,YAAY,OAAO;AAChD,UAAM,SAAS,KAAK,MAAM,OAAO;AAEjC,QAAI,CAAC,OAAO,WAAW,OAAO,OAAO,YAAY,UAAU;AACzD,cAAQ,KAAK,gDAAgD;AAC7D,aAAO,EAAE,SAAS,CAAC,EAAE;AAAA,IACvB;AAEA,WAAO,EAAE,SAAS,OAAO,QAAQ;AAAA,EACnC,SAAS,OAAO;AACd,YAAQ,KAAK,gCAAgC,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AACvG,WAAO,EAAE,SAAS,CAAC,EAAE;AAAA,EACvB;AACF;AAEA,SAAS,oBAAoB,QAAyB;AACpD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,KAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,mBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,SAAS;AAAA,EAET,MAAM,WAAW,SAA8B;AAC7C,UAAM,SAAS,MAAM,cAAc,QAAQ,IAAI,CAAC;AAEhD,UAAM,cAAc,OAAO,KAAK,OAAO,OAAO,EAAE;AAChD,QAAI,gBAAgB,GAAG;AACrB,cAAQ,IAAI,iCAAiC;AAC7C;AAAA,IACF;AAEA,QAAI,cAAc;AAElB,eAAW,CAAC,YAAY,YAAY,KAAK,OAAO,QAAQ,OAAO,OAAO,GAAG;AACvE,UAAI;AACF,YAAI,CAAC,aAAa,KAAK;AACrB,kBAAQ,KAAK,iBAAiB,UAAU,yBAAyB;AACjE;AAAA,QACF;AAEA,cAAM,YAAY,oBAAoB,YAAY;AAClD,cAAM,SAAS,UAAM,4BAAgB,EAAE,UAAU,CAAC;AAElD,cAAM,QAAQ,MAAM,OAAO,MAAM;AAGjC,cAAM,kBAAkB,OAAO;AAAA,UAC7B,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,UAAUA,KAAI,MAAM;AAAA,YAC9C,OAAO,UAAU,IAAI,QAAQ;AAAA,YAC7BA;AAAA,UACF,CAAC;AAAA,QACH;AAEA,gBAAQ,cAAc,eAAe;AAErC;AACA,gBAAQ,IAAI,iBAAiB,UAAU,aAAa,OAAO,KAAK,KAAK,EAAE,MAAM,SAAS;AAGtF,gBAAQ,gBAAgB,OAAO,UAAU,IAAI,MAAM;AAAA,MAErD,SAAS,OAAO;AACd,gBAAQ,KAAK,gCAAgC,UAAU,MAAM,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,MACzH;AAAA,IACF;AAEA,QAAI,cAAc,GAAG;AACnB,cAAQ,IAAI,6BAA6B,WAAW,IAAI,WAAW,cAAc;AAAA,IACnF,OAAO;AACL,cAAQ,KAAK,+CAA+C;AAAA,IAC9D;AAAA,EACF;AACF;;;AC9FA,IAAAC,aAAyC;AACzC,kBAAyB;AACzB,yBAAmB;AACnB,gBAAwB;AAExB,iBAAkB;AAgBX,IAAM,uBAAN,MAA2B;AAAA,EACxB,SAAiC,oBAAI,IAAI;AAAA,EACzC,cAAc;AAAA;AAAA;AAAA;AAAA,EAKtB,MAAM,WAAW,KAA4B;AAC3C,QAAI,KAAK,aAAa;AACpB,cAAQ,KAAK,mCAAmC;AAChD;AAAA,IACF;AAEA,YAAQ,IAAI,6BAA6B;AACzC,UAAM,YAAY,MAAM,KAAK,WAAW,GAAG;AAE3C,SAAK,OAAO,MAAM;AAClB,eAAW,SAAS,WAAW;AAC7B,WAAK,OAAO,IAAI,MAAM,MAAM,KAAK;AAAA,IACnC;AAEA,SAAK,cAAc;AACnB,YAAQ,IAAI,UAAU,KAAK,OAAO,IAAI,oBAAoB;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,WAAW,KAAmC;AAC1D,UAAM,SAAsB,CAAC;AAE7B,UAAM,YAAY;AAAA;AAAA,MAEhB,EAAE,MAAM,KAAK,SAAS,kCAAkC;AAAA,MACxD,EAAE,MAAM,KAAK,SAAS,4BAA4B;AAAA,MAClD,EAAE,MAAM,KAAK,SAAS,6BAA6B;AAAA;AAAA,MAEnD,EAAE,UAAM,mBAAQ,GAAG,SAAS,kCAAkC;AAAA,MAC9D,EAAE,UAAM,mBAAQ,GAAG,SAAS,4BAA4B;AAAA,IAC1D;AAEA,eAAW,EAAE,MAAM,QAAQ,KAAK,WAAW;AACzC,UAAI;AACF,cAAM,YAAQ,sBAAS,SAAS,EAAE,KAAK,MAAM,UAAU,KAAK,CAAC;AAE7D,mBAAW,YAAY,OAAO;AAC5B,cAAI;AACF,kBAAM,YAAY,KAAK,eAAe,QAAQ;AAC9C,gBAAI,WAAW;AACb,qBAAO,KAAK,SAAS;AAAA,YACvB;AAAA,UACF,SAAS,OAAO;AACd,oBAAQ,KAAK,8BAA8B,QAAQ,KAAK,KAAK;AAAA,UAC/D;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,iBAAiB,OAAO,OAAO,IAAI,KAAK,KAAK;AAAA,MAC7D;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,UAAoC;AACzD,QAAI;AACF,YAAM,cAAU,yBAAa,UAAU,OAAO;AAC9C,YAAM,EAAE,MAAM,SAAS,gBAAgB,QAAI,mBAAAC,SAAO,OAAO;AAEzD,UAAI,CAAC,KAAK,QAAQ,CAAC,KAAK,aAAa;AACnC,gBAAQ,KAAK,cAAc,QAAQ,gDAAgD;AACnF,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,QACL,MAAM,KAAK;AAAA,QACX,aAAa,KAAK;AAAA,QAClB,UAAU;AAAA,QACV,SAAS;AAAA,QACT,UAAU;AAAA,MACZ;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,KAAK,6BAA6B,QAAQ,KAAK,KAAK;AAC5D,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAAsB;AACpB,WAAO,MAAM,KAAK,KAAK,OAAO,OAAO,CAAC;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,MAAqC;AACvC,WAAO,KAAK,OAAO,IAAI,IAAI;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,MAAuB;AACzB,WAAO,KAAK,OAAO,IAAI,IAAI;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,SAA8B;AACnC,UAAM,eAAe,QAAQ,YAAY;AACzC,WAAO,KAAK,OAAO,EAAE;AAAA,MACnB,CAAC,UACC,MAAM,KAAK,YAAY,EAAE,SAAS,YAAY,KAC9C,MAAM,YAAY,YAAY,EAAE,SAAS,YAAY;AAAA,IACzD;AAAA,EACF;AACF;AAKA,IAAM,kBAAkB,aAAE,OAAO;AAAA,EAC/B,MAAM,aAAE,OAAO,EAAE,SAAS,kCAAkC;AAC9D,CAAC;AAOD,SAAS,kBAAkB,QAAsD;AAC/E,QAAM,kBAAkB,CAAC,oBAAiC;AACxD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,gBAAgB,QAAQ,CAAC,UAAU;AAAA,QACpC;AAAA,QACA,aAAa,MAAM,IAAI;AAAA,QACvB,oBAAoB,MAAM,WAAW;AAAA,QACrC;AAAA,MACF,CAAC;AAAA,MACD;AAAA,IACF,EAAE,KAAK,GAAG;AAAA,EACZ;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa,gBAAgB,MAAM;AAAA,IACnC,aAAa;AAAA,IACb,SAAS,OAAO,EAAE,KAAK,MAAM;AAC3B,YAAM,QAAQ,OAAO,KAAK,CAACC,WAAUA,OAAM,SAAS,IAAI;AACxD,UAAI,CAAC,OAAO;AACV,cAAM,IAAI,MAAM,SAAS,IAAI,YAAY;AAAA,MAC3C;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAKO,IAAM,sBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,SAAS;AAAA,EAET,MAAM,WAAW,SAA8B;AAC7C,UAAM,WAAW,IAAI,qBAAqB;AAC1C,UAAM,SAAS,WAAW,QAAQ,IAAI,CAAC;AAEvC,UAAM,SAAS,SAAS,OAAO;AAC/B,QAAI,OAAO,WAAW,GAAG;AACvB,cAAQ,IAAI,0BAA0B;AACtC;AAAA,IACF;AAEA,UAAM,YAAY,kBAAkB,MAAM;AAC1C,YAAQ,aAAa,SAAS,SAAS;AACvC,YAAQ,gBAAgB,iBAAiB,QAAQ;AAEjD,YAAQ,IAAI,uBAAuB,OAAO,MAAM,WAAW;AAAA,EAC7D;AACF;;;AC5NA,IAAAC,eAAkB;AAClB,IAAAC,aAA+B;AAC/B,IAAAC,eAAiB;;;ACFjB,gBAA8F;;;ACA9F,oBAAmB;AACnB,oBAA6B;AAC7B,uBAAgC;AAGhC,cAAAC,QAAO,OAAO;AAEP,IAAM,UAAW,QAAQ,IAAI,oBAChC,kCAAgB;AAAA,EAChB,QAAQ,QAAQ,IAAI,qBAAqB;AAAA,EACzC,SAAS,QAAQ,IAAI,qBAAqB;AAC5C,CAAC,QACC,4BAAa;AAAA,EACb,QAAQ,QAAQ,IAAI,kBAAkB;AAAA,EACtC,SAAS,QAAQ,IAAI,kBAAkB;AACzC,CAAC,EAAE;AAEE,IAAM,gBAAgB,QAAQ,IAAI,mBAAmB,QAAQ,IAAI,gBAAgB;AAGjF,IAAM,kBAAkB;AACxB,IAAM,YAAY;AAClB,IAAM,yBAAyB;AAE/B,IAAM,wBAAwB,OAAO,QAAQ,IAAI,yBAAyB,IAAM;AAChF,IAAM,kBAAkB,OAAO,QAAQ,IAAI,mBAAmB,KAAK,MAAM,wBAAwB,IAAI,CAAC;AACtG,IAAM,iBAAiB,OAAO,QAAQ,IAAI,kBAAkB,KAAK,MAAM,wBAAwB,GAAG,CAAC;AACnG,IAAM,kBAAkB,OAAO,QAAQ,IAAI,mBAAmB,CAAC;AAC/D,IAAM,6BAA6B,OAAO,QAAQ,IAAI,8BAA8B,IAAI;AACxF,IAAM,0BAA0B,OAAO,QAAQ,IAAI,2BAA2B,CAAC;AAC/E,IAAM,0BAA0B,QAAQ,IAAI;AAG5C,IAAM,wBAAwB,OAAO,QAAQ,IAAI,yBAAyB,GAAO;AACjF,IAAM,wBAAwB,QAAQ,IAAI,0BAA0B;;;AClCpE,IAAM,uBAAuB,MAAM;AACxC,QAAM,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;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;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAiHE,QAAQ,IAAI,CAAC;AAAA;AAAA,mBAElB,oBAAI,KAAK,GAAE,mBAAmB,CAAC;AAAA;AAAA;AAAA;AAAA;AAM/C,SAAO;AACT;;;AFpHA,IAAM,kBAAkB,0BACpB,EAAE,QAAQ,EAAE,iBAAiB,wBAAwB,EAAE,IACvD;AA6BG,IAAM,uBAAuB,CAClC,OACA,YACyB;AACzB,QAAM,eAAqC,CAAC;AAE5C,aAAW,CAAC,MAAMC,KAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,iBAAa,IAAI,IAAI;AAAA,MACnB,GAAGA;AAAA,MACH,SAAS,OAAO,UAAe;AAE7B,eAAO,MAAMA,MAAK,QAAQ,OAAO,OAAO;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,eAAe,CAAC,UAA0B,OAAkC,YAA4B;AAEnH,QAAM,gBAAgB;AAAA,IACpB;AAAA,MACE,MAAM;AAAA,MACN,SAAS,qBAAqB;AAAA,IAChC;AAAA,IACA,GAAG;AAAA,EACL;AAGA,QAAM,eAAe,SAAS,uBAC1B,qBAAqB,OAAO,QAAQ,oBAAoB,IACxD;AAEJ,aAAO,sBAAW;AAAA,IAChB,OAAO,QAAQ,aAAa;AAAA,IAC5B,UAAU;AAAA,IACV,OAAO;AAAA,IACP;AAAA,IACA,aAAa,SAAS;AAAA,IACtB,cAAc,SAAS;AAAA,IACvB,SAAS,SAAS;AAAA,EACpB,CAAC;AACH;AAEO,IAAM,oBAAoB,OAC/B,UACA,YACoB;AACpB,QAAM,wBACJ;AAEF,QAAM,sBAAsB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,QAAM,SAAS,UAAM,wBAAa;AAAA,IAChC,OAAO,QAAQ,aAAa;AAAA,IAC5B,UAAU;AAAA,MACR,EAAE,MAAM,UAAU,SAAS,sBAAsB;AAAA,MACjD,GAAG;AAAA,MACH,EAAE,MAAM,QAAQ,SAAS,oBAAoB;AAAA,IAC/C;AAAA,IACA,iBAAiB,SAAS,mBAAmB;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,SAAO,OAAO,QAAQ;AACxB;;;AGnHA,IAAAC,aAAiD;AAejD,IAAM,sBAAsB,CAAC,YAA4B;AACvD,QAAM,UAAU,QAAQ,KAAK;AAC7B,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,WAAW,qBAAqB,GAAG;AAC7C,WAAO;AAAA,EACT;AACA,SAAO;AAAA,EAAwB,OAAO;AACxC;AAEA,IAAM,gBAAgB,CAAC,UAA2B;AAChD,MAAI;AACF,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO,OAAO,KAAK;AAAA,EACrB;AACF;AAEA,IAAM,iBAAiB,CAAC,aAAqC;AAC3D,MAAI,aAAa;AACjB,aAAW,WAAW,UAAU;AAC9B,kBAAc,QAAQ,KAAK;AAC3B,QAAI,OAAO,QAAQ,YAAY,UAAU;AACvC,oBAAc,QAAQ,QAAQ;AAAA,IAChC,OAAO;AACL,oBAAc,cAAc,QAAQ,OAAO,EAAE;AAAA,IAC/C;AAAA,EACF;AACA,SAAO,KAAK,KAAK,aAAa,CAAC;AACjC;AAEA,IAAM,eAAe,CAAC,UAA0B,kBAA0B;AACxE,QAAM,cAAwB,CAAC;AAC/B,WAAS,QAAQ,CAAC,SAAS,UAAU;AACnC,QAAI,QAAQ,SAAS,QAAQ;AAC3B,kBAAY,KAAK,KAAK;AAAA,IACxB;AAAA,EACF,CAAC;AAED,MAAI,YAAY,UAAU,eAAe;AACvC,WAAO,EAAE,aAAa,CAAC,GAAG,gBAAgB,SAAS;AAAA,EACrD;AAEA,QAAM,WAAW,YAAY,YAAY,SAAS,aAAa;AAC/D,SAAO;AAAA,IACL,aAAa,SAAS,MAAM,GAAG,QAAQ;AAAA,IACvC,gBAAgB,SAAS,MAAM,QAAQ;AAAA,EACzC;AACF;AAEA,IAAM,gBAAgB,CAAC,UAA0B,kBAA0C;AACzF,QAAM,cAAwB,CAAC;AAC/B,WAAS,QAAQ,CAAC,SAAS,UAAU;AACnC,QAAI,QAAQ,SAAS,QAAQ;AAC3B,kBAAY,KAAK,KAAK;AAAA,IACxB;AAAA,EACF,CAAC;AAED,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,MAAI,YAAY,UAAU,eAAe;AACvC,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,YAAY,YAAY,SAAS,aAAa;AACjE,SAAO,SAAS,MAAM,UAAU;AAClC;AAEO,IAAM,sBAAsB,OACjC,SACA,YAC2B;AAC3B,QAAM,EAAE,SAAS,IAAI;AACrB,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,EAAE,YAAY,MAAM;AAAA,EAC7B;AAEA,QAAM,kBAAkB,eAAe,QAAQ;AAC/C,MAAI,CAAC,SAAS,SAAS,kBAAkB,iBAAiB;AACxD,WAAO,EAAE,YAAY,MAAM;AAAA,EAC7B;AAEA,QAAM,EAAE,aAAa,eAAe,IAAI,aAAa,UAAU,eAAe;AAC9E,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO,EAAE,YAAY,MAAM;AAAA,EAC7B;AAEA,MAAI;AACF,UAAM,UAAU,MAAM,kBAAkB,WAAW;AACnD,UAAM,cAAc,oBAAoB,OAAO;AAC/C,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACxC;AAEA,UAAM,eAA+B;AAAA,MACnC,EAAE,MAAM,aAAa,SAAS,YAAY;AAAA,MAC1C,GAAG;AAAA,IACL;AAEA,QAAI,eAAe,YAAY,IAAI,gBAAgB;AACjD,YAAM,cAAc,cAAc,UAAU,eAAe;AAC3D,aAAO,EAAE,YAAY,MAAM,QAAQ,qBAAqB,YAAY;AAAA,IACtE;AAEA,WAAO,EAAE,YAAY,MAAM,aAAa,aAAa;AAAA,EACvD,SAAS,OAAO;AACd,UAAM,aAAS,0BAAc;AAAA,MAC3B;AAAA,MACA,WAAW;AAAA,MACX,WAAW;AAAA,MACX,eAAe;AAAA,IACjB,CAAC;AACD,UAAM,cAAc,cAAc,QAAQ,eAAe;AACzD,WAAO,EAAE,YAAY,MAAM,QAAQ,YAAY,YAAY;AAAA,EAC7D;AACF;;;AC9GA,eAAsB,KAAK,SAAkB,SAAwC;AACnF,MAAI,aAAa;AACjB,MAAI,aAAa;AACjB,MAAI,qBAAqB;AAEzB,SAAO,MAAM;AACX,QAAI;AACF,UAAI,qBAAqB,yBAAyB;AAChD,cAAM,EAAE,YAAY,YAAY,IAAI,MAAM,oBAAoB,OAAO;AACrE,YAAI,YAAY;AACd;AAEA,cAAI,aAAa;AACf,qBAAS,cAAc,WAAW;AAAA,UACpC;AACA;AAAA,QACF;AAAA,MACF;AAEA,YAAM,QAAQ,SAAS,SAAS,CAAC;AAGjC,YAAM,uBAAuB;AAAA,QAC3B,wBAAwB,SAAS;AAAA,QACjC,aAAa,SAAS;AAAA,MACxB;AAEA,YAAM,SAAS,aAAa,QAAQ,UAAU,OAAO;AAAA,QACnD,aAAa,SAAS;AAAA,QACtB;AAAA,QACA,cAAc,CAAC,SAAS;AACtB,mBAAS,eAAe,IAAI;AAAA,QAC9B;AAAA,QACA,SAAS,CAAC,EAAE,MAAM,MAAM;AACtB,cAAI,MAAM,SAAS,cAAc;AAC/B,qBAAS,SAAS,MAAM,IAAI;AAAA,UAC9B;AACA,cAAI,MAAM,SAAS,aAAa;AAC9B,qBAAS,aAAa,KAAK;AAAA,UAC7B;AACA,cAAI,MAAM,SAAS,eAAe;AAChC,qBAAS,eAAe,KAAK;AAAA,UAC/B;AAAA,QACF;AAAA,MACF,CAAC;AAED,YAAM,CAAC,MAAM,OAAO,YAAY,IAAI,MAAM,QAAQ,IAAI;AAAA,QACpD,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT,CAAC;AAED,oBAAc,MAAM;AAEpB,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,UAAU,UAAU,QAAQ;AACnC,gBAAM,WAAW,CAAC,GAAG,KAAK,SAAS,QAAQ;AAC3C,mBAAS,aAAa,QAAQ;AAAA,QAChC;AAAA,MACF;AAEA,UAAI,iBAAiB,QAAQ;AAC3B,eAAO,QAAQ;AAAA,MACjB;AAEA,UAAI,iBAAiB,UAAU;AAC7B,YAAI,qBAAqB,yBAAyB;AAChD,gBAAM,EAAE,YAAY,YAAY,IAAI,MAAM,oBAAoB,SAAS,EAAE,OAAO,KAAK,CAAC;AACtF,cAAI,YAAY;AACd;AACA,gBAAI,aAAa;AACf,uBAAS,cAAc,WAAW;AAAA,YACpC;AACA;AAAA,UACF;AAAA,QACF;AACA,eAAO,QAAQ;AAAA,MACjB;AAEA,UAAI,iBAAiB,kBAAkB;AACrC,eAAO,QAAQ;AAAA,MACjB;AAEA,UAAI,iBAAiB,SAAS;AAC5B,eAAO,QAAQ;AAAA,MACjB;AAEA,UAAI,iBAAiB,cAAc;AACjC,YAAI,cAAc,WAAW;AAC3B,iBAAO,QAAQ;AAAA,QACjB;AACA;AAAA,MACF;AAEA,aAAO,QAAQ;AAAA,IACjB,SAAS,OAAY;AACnB,UAAI,SAAS,aAAa,WAAW,OAAO,SAAS,cAAc;AACjE,eAAO;AAAA,MACT;AAEA;AACA,UAAI,cAAc,iBAAiB;AACjC,eAAO,gBAAgB,UAAU,YAAY,OAAO,WAAW,OAAO,KAAK,CAAC;AAAA,MAC9E;AAEA,UAAI,iBAAiB,KAAK,GAAG;AAC3B,cAAM,QAAQ,KAAK,IAAI,MAAO,KAAK,IAAI,GAAG,aAAa,CAAC,GAAG,GAAK;AAChE,cAAM,MAAM,KAAK;AACjB;AAAA,MACF;AAEA,aAAO,UAAU,OAAO,WAAW,OAAO,KAAK,CAAC;AAAA,IAClD;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,OAAqB;AAC7C,QAAM,SAAS,OAAO,UAAU,OAAO;AACvC,SAAO,WAAW,OAAO,WAAW,OAAO,WAAW,OAAO,WAAW;AAC1E;AAEA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;;;AClJA,IAAAC,cAAc;AACd,IAAAC,aAAmD;;;ACC5C,IAAM,iBAAiB,CAAC,WAA2B;AACxD,MAAI,OAAO,UAAU,wBAAwB;AAC3C,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,KAAK,MAAM,yBAAyB,CAAC;AAClD,QAAM,UAAU,OAAO,SAAS;AAEhC,SACE,OAAO,MAAM,GAAG,IAAI,IACpB;AAAA;AAAA,iBAAsB,OAAO;AAAA;AAAA,IAC7B,OAAO,MAAM,CAAC,IAAI;AAEtB;;;ADVO,IAAM,WAGT;AAAA,EACF,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa,YAAAC,QAAE,OAAO;AAAA,IACpB,UAAU,YAAAA,QAAE,OAAO,EAAE,SAAS,uCAAuC;AAAA,IACrE,QAAQ,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yGAAyG;AAAA,IAChJ,OAAO,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qFAAqF;AAAA,EAC7H,CAAC;AAAA,EACD,SAAS,OAAO,EAAE,UAAU,QAAQ,MAAM,MAAM;AAE9C,QAAI,KAAC,uBAAW,QAAQ,GAAG;AACzB,YAAM,IAAI,MAAM,wBAAwB,QAAQ,EAAE;AAAA,IACpD;AAGA,UAAM,YAAQ,qBAAS,QAAQ;AAC/B,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,IAAI,MAAM,0BAA0B,QAAQ,6CAA6C;AAAA,IACjG;AAGA,UAAM,cAAU,yBAAa,UAAU,OAAO;AAC9C,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,UAAM,aAAa,MAAM;AAGzB,QAAI,WAAW,UAAa,UAAU,QAAW;AAC/C,aAAO;AAAA,QACL,SAAS,eAAe,OAAO;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY,UAAU;AAC5B,UAAM,UAAU,QAAQ,YAAY,QAAQ,MAAM;AAGlD,QAAI,YAAY,KAAK,aAAa,YAAY;AAC5C,YAAM,IAAI,MAAM,mBAAmB,SAAS,cAAc,UAAU,SAAS;AAAA,IAC/E;AAGA,UAAM,gBAAgB,MAAM,MAAM,WAAW,OAAO;AAGpD,UAAM,kBAAkB,cACrB,IAAI,CAAC,MAAM,QAAQ;AAClB,YAAM,UAAU,YAAY,MAAM;AAClC,aAAO,GAAG,OAAO,OAAO,EAAE,SAAS,GAAG,GAAG,CAAC,SAAI,IAAI;AAAA,IACpD,CAAC,EACA,KAAK,IAAI;AAEZ,WAAO;AAAA,MACL,SAAS,eAAe,eAAe;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AACF;;;AElEA,IAAAC,cAAc;AACd,IAAAC,aAAqD;AACrD,kBAAwB;AAGjB,IAAM,YAGT;AAAA,EACF,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa,YAAAC,QAAE,OAAO;AAAA,IACpB,UAAU,YAAAA,QAAE,OAAO,EAAE,SAAS,yEAAyE;AAAA,IACvG,SAAS,YAAAA,QAAE,OAAO,EAAE,SAAS,kCAAkC;AAAA,EACjE,CAAC;AAAA,EACD,SAAS,OAAO,EAAE,UAAU,QAAQ,MAAM;AAExC,UAAM,iBAAa,uBAAW,QAAQ;AAGtC,UAAM,UAAM,qBAAQ,QAAQ;AAG5B,QAAI,KAAC,uBAAW,GAAG,GAAG;AACpB,gCAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,IACpC;AAGA,kCAAc,UAAU,SAAS,OAAO;AAGxC,UAAM,QAAQ,OAAO,WAAW,SAAS,OAAO;AAEhD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,CAAC;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;;;ACvCA,IAAAC,cAAc;AACd,IAAAC,aAA4C;AAIrC,IAAM,WAGT;AAAA,EACF,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa,YAAAC,QAAE,OAAO;AAAA,IACpB,UAAU,YAAAA,QAAE,OAAO,EAAE,SAAS,yCAAyC;AAAA,IACvE,WAAW,YAAAA,QAAE,OAAO,EAAE,SAAS,gDAAgD;AAAA,IAC/E,WAAW,YAAAA,QAAE,OAAO,EAAE,SAAS,iEAAiE;AAAA,IAChG,YAAY,YAAAA,QAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK,EAAE,SAAS,uDAAuD;AAAA,EACpH,CAAC;AAAA,EACD,SAAS,OAAO,EAAE,UAAU,WAAW,WAAW,aAAa,MAAM,MAAM;AAEzE,QAAI,cAAc,WAAW;AAC3B,YAAM,IAAI,MAAM,6CAA6C;AAAA,IAC/D;AAGA,UAAM,cAAU,yBAAa,UAAU,OAAO;AAG9C,QAAI,CAAC,QAAQ,SAAS,SAAS,GAAG;AAChC,YAAM,IAAI,MAAM,iCAAiC,QAAQ,EAAE;AAAA,IAC7D;AAEA,QAAI;AACJ,QAAI,eAAe;AAEnB,QAAI,YAAY;AAEd,YAAM,QAAQ,QAAQ,MAAM,SAAS;AACrC,qBAAe,MAAM,SAAS;AAC9B,mBAAa,MAAM,KAAK,SAAS;AAAA,IACnC,OAAO;AAEL,YAAM,QAAQ,QAAQ,QAAQ,SAAS;AACvC,UAAI,UAAU,IAAI;AAChB,cAAM,IAAI,MAAM,iCAAiC,QAAQ,EAAE;AAAA,MAC7D;AAGA,YAAM,cAAc,QAAQ,QAAQ,WAAW,QAAQ,UAAU,MAAM;AACvE,UAAI,gBAAgB,IAAI;AACtB,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,mBAAa,QAAQ,MAAM,GAAG,KAAK,IAAI,YAAY,QAAQ,MAAM,QAAQ,UAAU,MAAM;AACzF,qBAAe;AAAA,IACjB;AAGA,kCAAc,UAAU,YAAY,OAAO;AAG3C,UAAM,eAAe,WAAW,QAAQ,SAAS;AACjD,UAAM,gBAAgB;AACtB,UAAM,QAAQ,KAAK,IAAI,GAAG,eAAe,aAAa;AACtD,UAAM,MAAM,KAAK,IAAI,WAAW,QAAQ,eAAe,UAAU,SAAS,aAAa;AACvF,UAAM,UAAU;AAAA,MACd,MAAM,WAAW,MAAM,OAAO,GAAG,CAAC;AAAA,IACpC;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;AC5EA,IAAAC,cAAc;AACd,2BAAyB;AACzB,IAAAC,aAA2B;AAIpB,IAAM,WAcT;AAAA,EACF,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa,YAAAC,QAAE,OAAO;AAAA,IACpB,SAAS,YAAAA,QAAE,OAAO,EAAE,SAAS,+DAA+D;AAAA,IAC5F,MAAM,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wEAAwE;AAAA,IAC7G,MAAM,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0DAA0D;AAAA,IAC/F,MAAM,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uEAAuE;AAAA,IAC5G,YAAY,YAAAA,QAAE,KAAK,CAAC,WAAW,sBAAsB,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,oBAAoB,EACnG,SAAS,gHAAgH;AAAA,IAC5H,SAAS,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wFAAwF;AAAA,IAChI,iBAAiB,YAAAA,QAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK,EAAE,SAAS,yBAAyB;AAAA,IACzF,WAAW,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,SAAS,2DAA2D;AAAA,IAChH,QAAQ,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,SAAS,uDAAuD;AAAA,IACzG,WAAW,YAAAA,QAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK,EAAE,SAAS,qDAAqD;AAAA,EACjH,CAAC;AAAA,EACD,SAAS,OAAO;AAAA,IACd;AAAA,IACA,MAAAC,QAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,YAAY;AAAA,EACd,MAAM;AAEJ,UAAM,OAAiB,CAAC,IAAI;AAG5B,SAAK,KAAK,OAAO;AAGjB,QAAI,iBAAiB;AACnB,WAAK,KAAK,IAAI;AAAA,IAChB;AAGA,QAAI,eAAe,sBAAsB;AACvC,WAAK,KAAK,IAAI;AAAA,IAChB,WAAW,eAAe,SAAS;AACjC,WAAK,KAAK,IAAI;AAAA,IAChB,WAAW,eAAe,WAAW;AACnC,WAAK,KAAK,IAAI;AACd,UAAI,YAAY,QAAW;AACzB,aAAK,KAAK,KAAK,OAAO,EAAE;AAAA,MAC1B;AAAA,IACF;AAGA,QAAI,WAAW;AACb,WAAK,KAAK,IAAI;AACd,WAAK,KAAK,oBAAoB;AAAA,IAChC;AAGA,QAAI,MAAM;AACR,WAAK,KAAK,UAAU,IAAI;AAAA,IAC1B;AACA,QAAI,MAAM;AACR,WAAK,KAAK,UAAU,IAAI;AAAA,IAC1B;AAGA,QAAIA,SAAQA,UAAS,KAAK;AAExB,UAAI,KAAC,uBAAWA,KAAI,GAAG;AACrB,cAAM,IAAI,MAAM,wBAAwBA,KAAI,EAAE;AAAA,MAChD;AACA,WAAK,KAAKA,KAAI;AAAA,IAChB;AAGA,QAAI,UAAU,KAAK,IAAI,SAAO;AAE5B,UAAI,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,GAAG;AAC/D,eAAO,IAAI,IAAI,QAAQ,MAAM,OAAO,CAAC;AAAA,MACvC;AACA,aAAO;AAAA,IACT,CAAC,EAAE,KAAK,GAAG;AAGX,QAAI,SAAS,GAAG;AACd,iBAAW,eAAe,SAAS,CAAC;AAAA,IACtC;AACA,QAAI,YAAY,GAAG;AACjB,iBAAW,cAAc,SAAS;AAAA,IACpC;AAEA,QAAI;AACF,YAAM,aAAS,+BAAS,SAAS;AAAA,QAC/B,UAAU;AAAA,QACV,WAAW,OAAO,OAAO;AAAA;AAAA,QACzB,OAAO;AAAA,MACT,CAAC;AAGD,UAAI;AACJ,UAAI,eAAe,SAAS;AAC1B,kBAAU,OAAO,MAAM,IAAI,EAAE,OAAO,UAAQ,KAAK,KAAK,CAAC,EAAE;AAAA,MAC3D,WAAW,eAAe,sBAAsB;AAC9C,kBAAU,OAAO,MAAM,IAAI,EAAE,OAAO,UAAQ,KAAK,KAAK,CAAC,EAAE;AAAA,MAC3D;AAEA,aAAO;AAAA,QACL,QAAQ,eAAe,UAAU,oBAAoB;AAAA,QACrD;AAAA,MACF;AAAA,IACF,SAAS,OAAY;AAEnB,UAAI,MAAM,WAAW,GAAG;AACtB,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS;AAAA,QACX;AAAA,MACF;AAGA,YAAM,IAAI;AAAA,QACR,gBAAgB,MAAM,UAAU,MAAM,OAAO;AAAA,WAAc,OAAO;AAAA,MACpE;AAAA,IACF;AAAA,EACF;AACF;;;ACjJA,IAAAC,cAAc;AACd,IAAAC,aAA4B;AAGrB,IAAM,SAGT;AAAA,EACF,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa,YAAAC,QAAE,OAAO;AAAA,IACpB,MAAM,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6DAA6D;AAAA,EACpG,CAAC;AAAA,EACD,SAAS,OAAO,EAAE,MAAAC,QAAO,IAAI,MAAM;AACjC,UAAM,YAAQ,wBAAYA,KAAI;AAC9B,WAAO,EAAE,MAAM;AAAA,EACjB;AACF;;;ACjBA,IAAAC,cAAc;AACd,IAAAC,wBAAyB;AAIlB,IAAM,WAGT;AAAA,EACF,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa,YAAAC,QAAE,OAAO;AAAA,IACpB,SAAS,YAAAA,QAAE,OAAO,EAAE,SAAS,6BAA6B;AAAA,IAC1D,SAAS,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iGAAiG;AAAA,IACzI,KAAK,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kFAAkF;AAAA,IACtH,aAAa,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wEAAwE;AAAA,EACtH,CAAC;AAAA,EACD,SAAS,OAAO,EAAE,SAAS,UAAU,MAAQ,KAAK,YAAY,MAAM;AAElE,QAAI,YAAY,UAAU,KAAK,UAAU,MAAS;AAChD,YAAM,IAAI,MAAM,qDAAqD;AAAA,IACvE;AAEA,QAAI;AACF,YAAM,aAAS,gCAAS,SAAS;AAAA,QAC/B,UAAU;AAAA,QACV,WAAW,OAAO,OAAO;AAAA;AAAA,QACzB,SAAS,WAAW;AAAA,QACpB,KAAK,OAAO,QAAQ,IAAI;AAAA,QACxB,OAAO;AAAA,MACT,CAAC;AACD,aAAO;AAAA,QACL,QAAQ,eAAe,UAAU,oCAAoC;AAAA,QACrE,UAAU;AAAA,MACZ;AAAA,IACF,SAAS,OAAY;AACnB,YAAM,WAAW,MAAM,UAAU,MAAM,QAAQ;AAC/C,YAAM,SAAS,OAAO,MAAM,UAAU,EAAE;AACxC,YAAM,SAAS,OAAO,MAAM,UAAU,MAAM,WAAW,EAAE;AAGzD,UAAI,MAAM,UAAU,MAAM,WAAW,WAAW;AAC9C,eAAO;AAAA,UACL,QAAQ,eAAe,MAAM;AAAA,UAC7B,OAAO,eAAe,2BAA2B,OAAO;AAAA,EAAO,MAAM,EAAE;AAAA,UACvE;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,QACL,QAAQ,eAAe,MAAM;AAAA,QAC7B,OAAO,eAAe,MAAM;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACxDA,IAAAC,cAAc;AAIP,IAAM,aAGT;AAAA,EACF,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa,YAAAC,QAAE,OAAO;AAAA,IACpB,OAAO,YAAAA,QAAE,OAAO,EAAE,SAAS,kBAAkB;AAAA,IAC7C,YAAY,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,SAAS,qCAAqC;AAAA,EAC7F,CAAC;AAAA,EACD,SAAS,OAAO,EAAE,OAAO,aAAa,EAAE,MAAM;AAC5C,UAAM,SAAS,QAAQ,IAAI;AAE3B,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AAEA,UAAM,WAAW,MAAM,MAAM,iCAAiC;AAAA,MAC5D,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACnB,SAAS;AAAA,QACT;AAAA,QACA,aAAa;AAAA,QACb,cAAc;AAAA,QACd,gBAAgB;AAAA,QAChB,qBAAqB;AAAA,QACrB,gBAAgB;AAAA,MAClB,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,qBAAqB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,IAC/E;AAEA,UAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,WAAO;AAAA,MACL,SAAS,KAAK,SAAS,IAAI,CAAC,YAAiB;AAAA,QAC3C,OAAO,OAAO,SAAS;AAAA,QACvB,KAAK,OAAO,OAAO;AAAA,QACnB,SAAS,eAAe,OAAO,WAAW,EAAE;AAAA,QAC5C,OAAO,OAAO,SAAS;AAAA,MACzB,EAAE,KAAK,CAAC;AAAA,IACV;AAAA,EACF;AACF;;;ACpDA,IAAAC,cAAc;AAGd,oBAA2B;AAcpB,IAAM,cAAiD;AAAA,EAC5D,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa,YAAAC,QAAE,OAAO;AAAA,IACpB,UAAU,YAAAA,QAAE,OAAO,EAAE,SAAS,8BAA8B;AAAA,IAC5D,SAAS,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,IACpF,eAAe,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wDAAwD;AAAA,IACtG,SAAS,YAAAA,QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,EACxF,CAAC;AAAA,EACD,SAAS,OAAO,OAAO,gBAAgB;AACrC,QAAI,CAAC,aAAa,wBAAwB;AACxC,YAAM,IAAI,MAAM,kHAAkH;AAAA,IACpI;AAEA,UAAM,UAAU,MAAM,WAAW;AACjC,UAAM,gBAAY,0BAAW;AAE7B,QAAI;AAEF,YAAM,iBAAiB,IAAI,QAAe,CAAC,GAAG,WAAW;AACvD,mBAAW,MAAM;AACf,iBAAO,IAAI,MAAM,yCAAyC,OAAO,IAAI,CAAC;AAAA,QACxE,GAAG,OAAO;AAAA,MACZ,CAAC;AAGD,YAAM,SAAS,MAAM,QAAQ,KAAK;AAAA,QAChC,YAAY,uBAAuB;AAAA,UACjC,IAAI;AAAA,UACJ,UAAU,MAAM;AAAA,UAChB,SAAS,MAAM;AAAA,UACf,eAAe,MAAM;AAAA,UACrB;AAAA,QACF,CAAC;AAAA,QACD;AAAA,MACF,CAAC;AAED,aAAO;AAAA,QACL;AAAA,QACA,UAAU;AAAA,MACZ;AAAA,IACF,SAAS,OAAY;AAEnB,UAAI,OAAO,SAAS,SAAS,WAAW,KAAK,MAAM,eAAe;AAChE,eAAO;AAAA,UACL,QAAQ,MAAM;AAAA,UACd,UAAU;AAAA,QACZ;AAAA,MACF;AAGA,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;AC5DO,IAAM,eAAe;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,kBAAkB,aAAa,OAAO,CAAC,KAAK,iBAAiB;AACxE,MAAI,aAAa,IAAI,IAAI;AACzB,SAAO;AACT,GAAG,CAAC,CAAwB;;;AfT5B,IAAM,eAAN,MAAmB;AAAA,EAEjB,MAAM,kBAAkB,YAAsB;AAC5C,UAAM,YAA2D,CAAC;AAClE,aAAS,aAAa,YAAY;AAChC,UAAI;AACF,cAAM,WAAAC,SAAG,OAAO,SAAS;AAEzB,cAAM,QAAQ,MAAM,WAAAA,SAAG,QAAQ,SAAS;AACxC,kBAAU,KAAK,EAAE,OAAO,UAAU,CAAC;AAAA,MACrC,QAAQ;AACN;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,YAA+B,CAAC,uBAAuB,eAAe,GAA2B;AACtH,UAAM,UAAyB,CAAC;AAEhC,UAAM,aAAa,MAAM,QAAQ,SAAS,IAAI,YAAY,CAAC,SAAS;AAEpE,QAAI;AACF,YAAM,YAAY,MAAM,KAAK,kBAAkB,UAAU;AAEzD,iBAAW,YAAY,WAAW;AAChC,cAAM,QAAQ,SAAS;AACvB,mBAAW,QAAQ,OAAO;AACxB,cAAI,KAAK,SAAS,KAAK,GAAG;AACxB,kBAAM,SAAS,MAAM,KAAK,YAAY,aAAAC,QAAK,KAAK,SAAS,WAAW,IAAI,CAAC;AACzE,gBAAI,OAAQ,SAAQ,KAAK,MAAM;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,KAAK,iCAAiC,KAAK,EAAE;AAAA,IACvD;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,YAAY,UAA+C;AACvE,QAAI;AACF,YAAM,UAAU,MAAM,WAAAD,SAAG,SAAS,UAAU,OAAO;AACnD,YAAM,QAAQ,QAAQ,MAAM,IAAI;AAEhC,UAAI,OAAO;AACX,UAAI,cAAc;AAClB,UAAI,eAAe;AACnB,UAAI,gBAAgB;AACpB,UAAI,iBAAiB;AAErB,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,KAAK,MAAM,OAAO;AACzB,cAAI,CAAC,eAAe;AAClB,4BAAgB;AAChB;AAAA,UACF,OAAO;AACL,6BAAiB;AACjB;AAAA,UACF;AAAA,QACF;AAEA,YAAI,iBAAiB,CAAC,gBAAgB;AACpC,gBAAM,QAAQ,KAAK,MAAM,uBAAuB;AAChD,cAAI,OAAO;AACT,kBAAM,CAAC,EAAE,KAAK,KAAK,IAAI;AACvB,gBAAI,QAAQ,OAAQ,QAAO,MAAM,KAAK;AACtC,gBAAI,QAAQ,cAAe,eAAc,MAAM,KAAK;AAAA,UACtD;AAAA,QACF,WAAW,gBAAgB;AACzB,0BAAgB,OAAO;AAAA,QACzB;AAAA,MACF;AAEA,UAAI,CAAC,MAAM;AACT,eAAO,aAAAC,QAAK,SAAS,UAAU,KAAK;AAAA,MACtC;AAEA,aAAO;AAAA,QACL,MAAM,KAAK,KAAK;AAAA,QAChB,aAAa,YAAY,KAAK;AAAA,QAC9B,cAAc,aAAa,KAAK;AAAA,QAChC;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,KAAK,gCAAgC,QAAQ,KAAK,KAAK,EAAE;AACjE,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,IAAM,cAAN,MAAkB;AAAA,EAChB,MAAM,SACJ,QACA,MACA,SACA,OACiB;AACjB,UAAM,aAAsB;AAAA,MAC1B,UAAU;AAAA,QACR,EAAE,MAAM,UAAU,SAAS,OAAO,aAAa;AAAA,QAC/C,EAAE,MAAM,QAAQ,SAAS,KAAK;AAAA,MAChC;AAAA,IACF;AAEA,QAAI,WAAW,OAAO,KAAK,OAAO,EAAE,SAAS,GAAG;AAC9C,iBAAW,SAAS,KAAK;AAAA,QACvB,MAAM;AAAA,QACN,SAAS;AAAA,EAAW,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,MACtD,CAAC;AAAA,IACH;AAEA,WAAO,MAAM,KAAK,YAAY,EAAE,MAAM,CAAC;AAAA,EACzC;AACF;AAEO,IAAM,iBAAN,MAA6C;AAAA,EAClD,OAAO;AAAA,EACP,UAAU;AAAA,EAEF,eAAe,IAAI,aAAa;AAAA,EAChC,cAAc,IAAI,YAAY;AAAA,EAEtC,MAAM,WAAW,SAA6C;AAC5D,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,aAAa,iBAAiB;AAGzD,YAAM,QAAQ,KAAK,kBAAkB,OAAO;AAE5C,iBAAW,UAAU,SAAS;AAC5B,aAAK,kBAAkB,SAAS,QAAQ,KAAK;AAAA,MAC/C;AAEA,cAAQ,OAAO,KAAK,yBAAyB,QAAQ,MAAM,UAAU;AAAA,IACvE,SAAS,OAAO;AACd,cAAQ,OAAO,MAAM,uCAAuC,KAAc;AAAA,IAC5E;AAAA,EACF;AAAA,EAEQ,kBAAkB,SAAmD;AAG3E,UAAM,WAAgC,CAAC;AAIvC,WAAO;AAAA,EACT;AAAA,EAEQ,kBACN,SACA,QACA,OACM;AACN,UAAM,WAAW,GAAG,OAAO,IAAI;AAE/B,UAAMC,QAAa;AAAA,MACjB,aAAa,OAAO;AAAA,MACpB,aAAa,eAAE,OAAO;AAAA,QACpB,MAAM,eAAE,OAAO,EAAE,SAAS,kDAAU;AAAA,QACpC,SAAS,eAAE,IAAI,EAAE,SAAS,EAAE,SAAS,4CAAS;AAAA,MAChD,CAAC;AAAA,MACD,SAAS,OAAO,EAAE,MAAM,SAAS,YAAY,MAAuD;AAClG,YAAI;AACF,kBAAQ,OAAO,KAAK,iBAAiB,OAAO,IAAI,KAAK,IAAI,EAAE;AAC3D,gBAAM,SAAS,MAAM,KAAK,YAAY,SAAS,QAAQ,MAAM,aAAa,KAAK;AAC/E,kBAAQ,OAAO,KAAK,SAAS,OAAO,IAAI,yBAAyB;AACjE,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,kBAAQ,OAAO,MAAM,SAAS,OAAO,IAAI,WAAW,KAAc;AAClE,gBAAM,IAAI,MAAM,SAAS,OAAO,IAAI,YAAY,KAAK,EAAE;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAEA,YAAQ,aAAa,UAAUA,KAAI;AAAA,EACrC;AAAA,EAEA,MAAM,QAAQ,SAA6C;AACzD,YAAQ,OAAO,KAAK,0BAA0B;AAAA,EAChD;AACF;;;AH3LO,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,IAAI,eAAe;AACrB;AASA,IAAO,mBAAQ;","names":["tool","import_fs","matter","skill","import_zod","import_fs","import_path","dotenv","tool","import_ai","import_zod","import_fs","z","import_zod","import_fs","z","import_zod","import_fs","z","import_zod","import_fs","z","path","import_zod","import_fs","z","path","import_zod","import_child_process","z","import_zod","z","import_zod","z","fs","path","tool"]}
1
+ {"version":3,"sources":["../../src/built-in/index.ts","../../src/built-in/mcp-plugin/index.ts","../../src/built-in/skills-plugin/index.ts","../../src/built-in/sub-agent-plugin/index.ts","../../src/ai/index.ts","../../src/config/index.ts","../../src/prompt/system.ts","../../src/context/index.ts","../../src/core/loop.ts","../../src/tools/read.ts","../../src/tools/utils.ts","../../src/tools/write.ts","../../src/tools/edit.ts","../../src/tools/grep.ts","../../src/tools/ls.ts","../../src/tools/bash.ts","../../src/tools/tavily.ts","../../src/tools/clarify.ts","../../src/tools/index.ts"],"sourcesContent":["/**\n * Built-in plugins for Pulse Coder Engine\n * 引擎内置插件集合\n */\n\nimport { builtInMCPPlugin } from './mcp-plugin';\nimport { builtInSkillsPlugin } from './skills-plugin';\nimport { SubAgentPlugin } from './sub-agent-plugin';\n\n/**\n * 默认内置插件列表\n * 这些插件会在引擎启动时自动加载\n */\nexport const builtInPlugins = [\n builtInMCPPlugin,\n builtInSkillsPlugin,\n new SubAgentPlugin()\n];\n\n/**\n * 单独导出各个内置插件,便于外部使用\n */\nexport { builtInMCPPlugin } from './mcp-plugin';\nexport { builtInSkillsPlugin, BuiltInSkillRegistry } from './skills-plugin';\nexport { SubAgentPlugin } from './sub-agent-plugin';\n\nexport default builtInPlugins;","/**\n * Built-in MCP Plugin for Pulse Coder Engine\n * 将 MCP 功能作为引擎内置插件\n */\n\nimport { EnginePlugin, EnginePluginContext } from '../../plugin/EnginePlugin';\nimport { createMCPClient } from '@ai-sdk/mcp';\nimport { existsSync, readFileSync } from 'fs';\nimport * as path from 'path';\n\nexport interface MCPPluginConfig {\n servers: Record<string, { url: string }>;\n}\n\nexport async function loadMCPConfig(cwd: string): Promise<MCPPluginConfig> {\n // 优先读取 .pulse-coder/mcp.json,兼容旧版 .coder/mcp.json\n const newConfigPath = path.join(cwd, '.pulse-coder', 'mcp.json');\n const legacyConfigPath = path.join(cwd, '.coder', 'mcp.json');\n const configPath = existsSync(newConfigPath) ? newConfigPath : legacyConfigPath;\n\n if (!existsSync(configPath)) {\n return { servers: {} };\n }\n\n try {\n const content = readFileSync(configPath, 'utf-8');\n const parsed = JSON.parse(content);\n\n if (!parsed.servers || typeof parsed.servers !== 'object') {\n console.warn('[MCP] Invalid config: missing \"servers\" object');\n return { servers: {} };\n }\n\n return { servers: parsed.servers };\n } catch (error) {\n console.warn(`[MCP] Failed to load config: ${error instanceof Error ? error.message : 'Unknown error'}`);\n return { servers: {} };\n }\n}\n\nfunction createHTTPTransport(config: { url: string }) {\n return {\n type: 'http' as const,\n url: config.url\n };\n}\n\nexport const builtInMCPPlugin: EnginePlugin = {\n name: 'pulse-coder-engine/built-in-mcp',\n version: '1.0.0',\n\n async initialize(context: EnginePluginContext) {\n const config = await loadMCPConfig(process.cwd());\n\n const serverCount = Object.keys(config.servers).length;\n if (serverCount === 0) {\n console.log('[MCP] No MCP servers configured');\n return;\n }\n\n let loadedCount = 0;\n\n for (const [serverName, serverConfig] of Object.entries(config.servers)) {\n try {\n if (!serverConfig.url) {\n console.warn(`[MCP] Server \"${serverName}\" missing URL, skipping`);\n continue;\n }\n\n const transport = createHTTPTransport(serverConfig);\n const client = await createMCPClient({ transport });\n\n const tools = await client.tools();\n\n // 注册工具到引擎,使用命名空间前缀\n const namespacedTools = Object.fromEntries(\n Object.entries(tools).map(([toolName, tool]) => [\n `mcp_${serverName}_${toolName}`,\n tool as any\n ])\n );\n\n context.registerTools(namespacedTools);\n\n loadedCount++;\n console.log(`[MCP] Server \"${serverName}\" loaded (${Object.keys(tools).length} tools)`);\n\n // 注册服务供其他插件使用\n context.registerService(`mcp:${serverName}`, client);\n\n } catch (error) {\n console.warn(`[MCP] Failed to load server \"${serverName}\": ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n if (loadedCount > 0) {\n console.log(`[MCP] Successfully loaded ${loadedCount}/${serverCount} MCP servers`);\n } else {\n console.warn('[MCP] No MCP servers were loaded successfully');\n }\n }\n};\n\nexport default builtInMCPPlugin;","/**\n * Built-in Skills Plugin for Pulse Coder Engine\n * 将技能系统作为引擎内置插件\n */\n\nimport { EnginePlugin, EnginePluginContext } from '../../plugin/EnginePlugin';\nimport { Tool } from '../../shared/types';\nimport { existsSync, readFileSync } from 'fs';\nimport { globSync } from 'glob';\nimport matter from 'gray-matter';\nimport { homedir } from 'os';\nimport * as path from 'path';\nimport { z } from 'zod';\n\n/**\n * 技能信息接口\n */\nexport interface SkillInfo {\n name: string;\n description: string;\n location: string;\n content: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * 技能注册表\n */\nexport class BuiltInSkillRegistry {\n private skills: Map<string, SkillInfo> = new Map();\n private initialized = false;\n\n /**\n * 初始化注册表,扫描并加载所有技能\n */\n async initialize(cwd: string): Promise<void> {\n if (this.initialized) {\n console.warn('SkillRegistry already initialized');\n return;\n }\n\n console.log('Scanning built-in skills...');\n const skillList = await this.scanSkills(cwd);\n\n this.skills.clear();\n for (const skill of skillList) {\n this.skills.set(skill.name, skill);\n }\n\n this.initialized = true;\n console.log(`Loaded ${this.skills.size} built-in skill(s)`);\n }\n\n /**\n * 扫描技能文件\n */\n private async scanSkills(cwd: string): Promise<SkillInfo[]> {\n const skills: SkillInfo[] = [];\n\n const scanPaths = [\n // 项目级技能(优先 .pulse-coder,兼容旧版 .coder 和 .claude)\n { base: cwd, pattern: '.pulse-coder/skills/**/SKILL.md' },\n { base: cwd, pattern: '.coder/skills/**/SKILL.md' },\n { base: cwd, pattern: '.claude/skills/**/SKILL.md' },\n // 用户级技能(优先 .pulse-coder,兼容旧版 .coder)\n { base: homedir(), pattern: '.pulse-coder/skills/**/SKILL.md' },\n { base: homedir(), pattern: '.coder/skills/**/SKILL.md' }\n ];\n\n for (const { base, pattern } of scanPaths) {\n try {\n const files = globSync(pattern, { cwd: base, absolute: true });\n\n for (const filePath of files) {\n try {\n const skillInfo = this.parseSkillFile(filePath);\n if (skillInfo) {\n skills.push(skillInfo);\n }\n } catch (error) {\n console.warn(`Failed to parse skill file ${filePath}:`, error);\n }\n }\n } catch (error) {\n console.debug(`Skip scanning ${pattern} in ${base}:`, error);\n }\n }\n\n return skills;\n }\n\n /**\n * 解析技能文件\n */\n private parseSkillFile(filePath: string): SkillInfo | null {\n try {\n const content = readFileSync(filePath, 'utf-8');\n const { data, content: markdownContent } = matter(content);\n\n if (!data.name || !data.description) {\n console.warn(`Skill file ${filePath} missing required fields (name or description)`);\n return null;\n }\n\n return {\n name: data.name,\n description: data.description,\n location: filePath,\n content: markdownContent,\n metadata: data\n };\n } catch (error) {\n console.warn(`Failed to read skill file ${filePath}:`, error);\n return null;\n }\n }\n\n /**\n * 获取所有技能\n */\n getAll(): SkillInfo[] {\n return Array.from(this.skills.values());\n }\n\n /**\n * 根据名称获取技能\n */\n get(name: string): SkillInfo | undefined {\n return this.skills.get(name);\n }\n\n /**\n * 检查技能是否存在\n */\n has(name: string): boolean {\n return this.skills.has(name);\n }\n\n /**\n * 搜索技能(模糊匹配)\n */\n search(keyword: string): SkillInfo[] {\n const lowerKeyword = keyword.toLowerCase();\n return this.getAll().filter(\n (skill) =>\n skill.name.toLowerCase().includes(lowerKeyword) ||\n skill.description.toLowerCase().includes(lowerKeyword)\n );\n }\n}\n\n/**\n * 技能工具参数 schema\n */\nconst skillToolSchema = z.object({\n name: z.string().describe('The name of the skill to execute')\n});\n\ntype SkillToolInput = z.infer<typeof skillToolSchema>;\n\n/**\n * 生成技能工具\n */\nfunction generateSkillTool(skills: SkillInfo[]): Tool<SkillToolInput, SkillInfo> {\n const getSkillsPrompt = (availableSkills: SkillInfo[]) => {\n return [\n \"If query matches an available skill's description or instruction [use skill], use the skill tool to get detailed instructions.\",\n \"Load a skill to get detailed instructions for a specific task.\",\n \"Skills provide specialized knowledge and step-by-step guidance.\",\n \"Use this when a task matches an available skill's description.\",\n \"Only the skills listed here are available:\",\n \"[!important] You should follow the skill's step-by-step guidance. If the skill is not complete, ask the user for more information.\",\n \"<available_skills>\",\n ...availableSkills.flatMap((skill) => [\n ` <skill>`,\n ` <name>${skill.name}</name>`,\n ` <description>${skill.description}</description>`,\n ` </skill>`\n ]),\n \"</available_skills>\"\n ].join(\" \");\n };\n\n return {\n name: \"skill\",\n description: getSkillsPrompt(skills),\n inputSchema: skillToolSchema,\n execute: async ({ name }) => {\n const skill = skills.find((skill) => skill.name === name);\n if (!skill) {\n throw new Error(`Skill ${name} not found`);\n }\n return skill;\n }\n };\n}\n\n/**\n * 内置技能插件\n */\nexport const builtInSkillsPlugin: EnginePlugin = {\n name: 'pulse-coder-engine/built-in-skills',\n version: '1.0.0',\n\n async initialize(context: EnginePluginContext) {\n const registry = new BuiltInSkillRegistry();\n await registry.initialize(process.cwd());\n\n const skills = registry.getAll();\n if (skills.length === 0) {\n console.log('[Skills] No skills found');\n return;\n }\n\n const skillTool = generateSkillTool(skills);\n context.registerTool('skill', skillTool);\n context.registerService('skillRegistry', registry);\n\n console.log(`[Skills] Registered ${skills.length} skill(s)`);\n }\n};\n\nexport default builtInSkillsPlugin;","import { z } from 'zod';\nimport { promises as fs } from 'fs';\nimport path from 'path';\nimport type { EnginePlugin, EnginePluginContext } from '../../plugin/EnginePlugin';\nimport type { Context } from '../../shared/types.js';\nimport { loop } from '../../core/loop';\nimport { BuiltinToolsMap } from '../../tools';\nimport { Tool } from 'ai';\n\ninterface AgentConfig {\n name: string;\n description: string;\n systemPrompt: string;\n filePath: string;\n}\n\nclass ConfigLoader {\n\n async getAgentFilesInfo(configDirs: string[]) {\n const fileInfos: Array<{ files: string[], configDir: string }> = [];\n for (let configDir of configDirs) {\n try {\n await fs.access(configDir);\n\n const files = await fs.readdir(configDir);\n fileInfos.push({ files, configDir });\n } catch {\n continue;\n }\n }\n\n return fileInfos;\n }\n\n async loadAgentConfigs(configDir: string | string[] = ['.pulse-coder/agents', '.coder/agents']): Promise<AgentConfig[]> {\n const configs: AgentConfig[] = [];\n\n const configDirs = Array.isArray(configDir) ? configDir : [configDir];\n\n try {\n const filesInfo = await this.getAgentFilesInfo(configDirs);\n\n for (const fileInfo of filesInfo) {\n const files = fileInfo.files;\n for (const file of files) {\n if (file.endsWith('.md')) {\n const config = await this.parseConfig(path.join(fileInfo.configDir, file));\n if (config) configs.push(config);\n }\n }\n }\n } catch (error) {\n console.warn(`Failed to scan agent configs: ${error}`);\n }\n\n return configs;\n }\n\n private async parseConfig(filePath: string): Promise<AgentConfig | null> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.split('\\n');\n\n let name = '';\n let description = '';\n let systemPrompt = '';\n let inFrontmatter = false;\n let frontmatterEnd = false;\n\n for (const line of lines) {\n if (line.trim() === '---') {\n if (!inFrontmatter) {\n inFrontmatter = true;\n continue;\n } else {\n frontmatterEnd = true;\n continue;\n }\n }\n\n if (inFrontmatter && !frontmatterEnd) {\n const match = line.match(/^\\s*(\\w+)\\s*:\\s*(.+)$/);\n if (match) {\n const [, key, value] = match;\n if (key === 'name') name = value.trim();\n if (key === 'description') description = value.trim();\n }\n } else if (frontmatterEnd) {\n systemPrompt += line + '\\n';\n }\n }\n\n if (!name) {\n name = path.basename(filePath, '.md');\n }\n\n return {\n name: name.trim(),\n description: description.trim(),\n systemPrompt: systemPrompt.trim(),\n filePath\n };\n } catch (error) {\n console.warn(`Failed to parse agent config ${filePath}: ${error}`);\n return null;\n }\n }\n}\n\nclass AgentRunner {\n async runAgent(\n config: AgentConfig,\n task: string,\n context?: Record<string, any>,\n tools?: Record<string, any>\n ): Promise<string> {\n const subContext: Context = {\n messages: [\n { role: 'user', content: task }\n ]\n };\n\n if (context && Object.keys(context).length > 0) {\n subContext.messages.push({\n role: 'user',\n content: `上下文信息:\\n${JSON.stringify(context, null, 2)}`\n });\n }\n\n return await loop(subContext, { tools, systemPrompt: config.systemPrompt });\n }\n}\n\nexport class SubAgentPlugin implements EnginePlugin {\n name = 'sub-agent';\n version = '1.0.0';\n\n private configLoader = new ConfigLoader();\n private agentRunner = new AgentRunner();\n\n async initialize(context: EnginePluginContext): Promise<void> {\n try {\n const configs = await this.configLoader.loadAgentConfigs();\n\n // 获取插件管理器提供的所有工具\n const tools = this.getAvailableTools(context);\n\n for (const config of configs) {\n this.registerAgentTool(context, config, tools);\n }\n\n context.logger.info(`SubAgentPlugin loaded ${configs.length} agents.`);\n } catch (error) {\n context.logger.error('Failed to initialize SubAgentPlugin', error as Error);\n }\n }\n\n private getAvailableTools(context: EnginePluginContext): Record<string, any> {\n // 从插件上下文中获取所有注册的工具\n // 在初始化阶段,所有工具已经通过插件系统注册\n const allTools: Record<string, any> = {};\n\n // 这里我们假设工具通过某种方式可用\n // 实际使用时,引擎会提供所有可用的工具\n return BuiltinToolsMap;\n }\n\n private registerAgentTool(\n context: EnginePluginContext,\n config: AgentConfig,\n tools: Record<string, any>\n ): void {\n const toolName = `${config.name}_agent`;\n\n const tool: Tool = {\n description: config.description,\n inputSchema: z.object({\n task: z.string().describe('要执行的任务描述'),\n context: z.any().optional().describe('任务上下文信息')\n }),\n execute: async ({ task, context: taskContext }: { task: string; context?: Record<string, any> }) => {\n try {\n context.logger.info(`Running agent ${config.name}: ${task}`);\n const result = await this.agentRunner.runAgent(config, task, taskContext, tools);\n context.logger.info(`Agent ${config.name} completed successfully`);\n return result;\n } catch (error) {\n context.logger.error(`Agent ${config.name} failed`, error as Error);\n throw new Error(`Agent ${config.name} failed: ${error}`);\n }\n }\n };\n\n context.registerTool(toolName, tool);\n }\n\n async destroy(context: EnginePluginContext): Promise<void> {\n context.logger.info('SubAgentPlugin destroyed');\n }\n}\n\nexport default SubAgentPlugin;","import { generateText, streamText, tool, type ModelMessage, type StepResult, type Tool } from 'ai';\nimport { CoderAI, DEFAULT_MODEL, COMPACT_SUMMARY_MAX_TOKENS, OPENAI_REASONING_EFFORT } from '../config';\nimport z from 'zod';\nimport { generateSystemPrompt } from '../prompt';\nimport type { Tool as CoderTool, ToolExecutionContext, LLMProviderFactory, SystemPromptOption } from '../shared/types';\n\n\nconst providerOptions = { openai: { store: false, reasoningEffort: OPENAI_REASONING_EFFORT } }\n\n/** Resolve a SystemPromptOption into a final string. */\nconst resolveSystemPrompt = (option: SystemPromptOption | undefined): string => {\n const base = generateSystemPrompt();\n if (!option) return base;\n if (typeof option === 'string') return option;\n if (typeof option === 'function') return option();\n return `${base}\\n\\n${option.append}`;\n};\n\nexport const generateTextAI = (\n messages: ModelMessage[],\n tools: Record<string, Tool>,\n options?: { provider?: LLMProviderFactory; model?: string; systemPrompt?: SystemPromptOption }\n) => {\n const provider = options?.provider ?? CoderAI;\n const model = options?.model ?? DEFAULT_MODEL;\n\n return generateText({\n model: provider(model),\n system: resolveSystemPrompt(options?.systemPrompt),\n messages,\n tools,\n providerOptions,\n }) as unknown as ReturnType<typeof generateText> & { steps: StepResult<any>[]; finishReason: string };\n}\n\nexport interface StreamOptions {\n abortSignal?: AbortSignal;\n onStepFinish?: (event: StepResult<any>) => void;\n onChunk?: (event: { chunk: any }) => void;\n toolExecutionContext?: ToolExecutionContext;\n /** Custom LLM provider. Falls back to the default CoderAI provider when not set. */\n provider?: LLMProviderFactory;\n /** Model name to pass to the provider. Falls back to DEFAULT_MODEL when not set. */\n model?: string;\n /** Custom system prompt. See SystemPromptOption for the three supported forms. */\n systemPrompt?: SystemPromptOption;\n}\n\n/**\n * Wraps tools to inject ToolExecutionContext before execution\n */\nexport const wrapToolsWithContext = (\n tools: Record<string, CoderTool>,\n context?: ToolExecutionContext\n): Record<string, Tool> => {\n const wrappedTools: Record<string, Tool> = {};\n\n for (const [name, tool] of Object.entries(tools)) {\n wrappedTools[name] = {\n ...tool,\n execute: async (input: any) => {\n // Call the original execute with context\n return await tool.execute(input, context);\n }\n } as Tool;\n }\n\n return wrappedTools;\n};\n\nexport const streamTextAI = (messages: ModelMessage[], tools: Record<string, CoderTool>, options?: StreamOptions) => {\n const provider = options?.provider ?? CoderAI;\n const model = options?.model ?? DEFAULT_MODEL;\n\n // Wrap tools with execution context if provided\n const wrappedTools = options?.toolExecutionContext\n ? wrapToolsWithContext(tools, options.toolExecutionContext)\n : tools;\n\n return streamText({\n model: provider(model),\n system: resolveSystemPrompt(options?.systemPrompt),\n messages,\n tools: wrappedTools as Record<string, Tool>,\n providerOptions,\n abortSignal: options?.abortSignal,\n onStepFinish: options?.onStepFinish,\n onChunk: options?.onChunk,\n }) as unknown as ReturnType<typeof streamText> & { steps: StepResult<any>[]; finishReason: string };\n}\n\nexport const summarizeMessages = async (\n messages: ModelMessage[],\n options?: { maxOutputTokens?: number; provider?: LLMProviderFactory; model?: string }\n): Promise<string> => {\n const provider = options?.provider ?? CoderAI;\n const model = options?.model ?? DEFAULT_MODEL;\n const SUMMARY_SYSTEM_PROMPT =\n '你是负责压缩对话上下文的助手。请基于给定历史消息,提炼关键事实与决策,避免臆测或扩展。';\n\n const SUMMARY_USER_PROMPT = [\n '请将以上对话压缩为以下格式,使用中文:',\n '[COMPACTED_CONTEXT]',\n '- 目标: ...',\n '- 进展: ...',\n '- 关键结果: ...',\n '- 文件与变更: ...',\n '- 关键片段: \"...\" / `...` / \"...\"',\n '- 待确认: ...',\n '',\n '要求:内容简洁准确,不要编造。',\n ].join('\\n');\n\n const result = await generateText({\n model: provider(model),\n system: SUMMARY_SYSTEM_PROMPT,\n messages: [\n ...messages,\n { role: 'user', content: SUMMARY_USER_PROMPT },\n ],\n maxOutputTokens: options?.maxOutputTokens ?? COMPACT_SUMMARY_MAX_TOKENS,\n providerOptions,\n });\n\n return result.text ?? '';\n}","import dotenv from \"dotenv\";\nimport { createOpenAI } from '@ai-sdk/openai';\nimport { createAnthropic } from \"@ai-sdk/anthropic\";\nimport { LanguageModel } from \"ai\";\n\ndotenv.config();\n\nexport const CoderAI = (process.env.USE_ANTHROPIC\n ? createAnthropic({\n apiKey: process.env.ANTHROPIC_API_KEY || '',\n baseURL: process.env.ANTHROPIC_API_URL || 'https://api.anthropic.com/v1'\n })\n : createOpenAI({\n apiKey: process.env.OPENAI_API_KEY || '',\n baseURL: process.env.OPENAI_API_URL || 'https://api.openai.com/v1'\n }).responses) as (model: string) => LanguageModel;\n\nexport const DEFAULT_MODEL = process.env.ANTHROPIC_MODEL || process.env.OPENAI_MODEL || 'novita/deepseek/deepseek_v3';\n\nexport const MAX_TURNS = 100;\nexport const MAX_ERROR_COUNT = 3;\nexport const MAX_STEPS = 100;\nexport const MAX_TOOL_OUTPUT_LENGTH = 30_000;\n\nexport const CONTEXT_WINDOW_TOKENS = Number(process.env.CONTEXT_WINDOW_TOKENS ?? 64_000);\nexport const COMPACT_TRIGGER = Number(process.env.COMPACT_TRIGGER ?? Math.floor(CONTEXT_WINDOW_TOKENS * 0.75));\nexport const COMPACT_TARGET = Number(process.env.COMPACT_TARGET ?? Math.floor(CONTEXT_WINDOW_TOKENS * 0.5));\nexport const KEEP_LAST_TURNS = Number(process.env.KEEP_LAST_TURNS ?? 6);\nexport const COMPACT_SUMMARY_MAX_TOKENS = Number(process.env.COMPACT_SUMMARY_MAX_TOKENS ?? 1200);\nexport const MAX_COMPACTION_ATTEMPTS = Number(process.env.MAX_COMPACTION_ATTEMPTS ?? 2);\nexport const OPENAI_REASONING_EFFORT = process.env.OPENAI_REASONING_EFFORT;\n\n// Clarification settings\nexport const CLARIFICATION_TIMEOUT = Number(process.env.CLARIFICATION_TIMEOUT ?? 300_000); // 5 minutes\nexport const CLARIFICATION_ENABLED = process.env.CLARIFICATION_ENABLED !== 'false';","export const generateSystemPrompt = () => {\n const basePrompt = `\nYou are Pulse Coder, the best coding agent on the planet.\n\nYou are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.\n\n## Editing constraints\n- Default to ASCII when editing or creating files. Only introduce non-ASCII or other Unicode characters when there is a clear justification and the file already uses them.\n- Only add comments if they are necessary to make a non-obvious block easier to understand.\n- Try to use apply_patch for single file edits, but it is fine to explore other options to make the edit if it does not work well. Do not use apply_patch for changes that are auto-generated (i.e. generating package.json or running a lint or format command like gofmt) or when scripting is more efficient (such as search and replacing a string across a codebase).\n\n## Skills\n- If query matches an available skill's description or instruction [use skill], use the skill tool to get detailed instructions.\n- You should Load a skill to get detailed instructions for a specific task. It always is a complex task that requires multiple steps.\n- You should check the skill is complete and follow the step-by-step guidance. If the skill is not complete, you should ask the user for more information.\n\n## Tool usage\n- Prefer specialized tools over shell for file operations:\n - Use Read to view files, Edit to modify files, and Write only when needed.\n - Use Glob to find files by name and Grep to search file contents.\n- Use Bash for terminal operations (git, bun, builds, tests, running scripts).\n- Run tool calls in parallel when neither call needs the other’s output; otherwise run sequentially.\n\n## Git and workspace hygiene\n- You may be in a dirty git worktree.\n * NEVER revert existing changes you did not make unless explicitly requested, since these changes were made by the user.\n * If asked to make a commit or code edits and there are unrelated changes to your work or changes that you didn't make in those files, don't revert those changes.\n * If the changes are in files you've touched recently, you should read carefully and understand how you can work with the changes rather than reverting them.\n * If the changes are in unrelated files, just ignore them and don't revert them.\n- Do not amend commits unless explicitly requested.\n- **NEVER** use destructive commands like \\`git reset --hard\\` or \\`git checkout--\\` unless specifically requested or approved by the user.\n\n## Frontend tasks\nWhen doing frontend design tasks, avoid collapsing into bland, generic layouts.\nAim for interfaces that feel intentional and deliberate.\n- Typography: Use expressive, purposeful fonts and avoid default stacks (Inter, Roboto, Arial, system).\n- Color & Look: Choose a clear visual direction; define CSS variables; avoid purple-on-white defaults. No purple bias or dark mode bias.\n- Motion: Use a few meaningful animations (page-load, staggered reveals) instead of generic micro-motions.\n- Background: Don't rely on flat, single-color backgrounds; use gradients, shapes, or subtle patterns to build atmosphere.\n- Overall: Avoid boilerplate layouts and interchangeable UI patterns. Vary themes, type families, and visual languages across outputs.\n- Ensure the page loads properly on both desktop and mobile.\n\nException: If working within an existing website or design system, preserve the established patterns, structure, and visual language.\n\n## Presenting your work and final message\n\nYou are producing plain text that will later be styled by the CLI. Follow these rules exactly. Formatting should make results easy to scan, but not feel mechanical. Use judgment to decide how much structure adds value.\n\n- Default: be very concise; friendly coding teammate tone.\n- Default: do the work without asking questions. Treat short tasks as sufficient direction; infer missing details by reading the codebase and following existing conventions.\n- Questions: only ask when you are truly blocked after checking relevant context AND you cannot safely pick a reasonable default. This usually means one of:\n * The request is ambiguous in a way that materially changes the result and you cannot disambiguate by reading the repo.\n * The action is destructive/irreversible, touches production, or changes billing/security posture.\n * You need a secret/credential/value that cannot be inferred (API key, account id, etc.).\n- If you must ask: do all non-blocked work first, then ask exactly one targeted question, include your recommended default, and state what would change based on the answer.\n- Never ask permission questions like \"Should I proceed?\" or \"Do you want me to run tests?\"; proceed with the most reasonable option and mention what you did.\n\n## Clarification Tool\n\nUse the 'clarify' tool when you genuinely need information from the user to proceed. This tool pauses execution and waits for user input.\n\n**When to use clarify:**\n- The request is ambiguous in a way that materially affects the implementation and cannot be resolved by reading the codebase\n- You cannot safely infer the answer from existing code, conventions, or context\n- You need confirmation before destructive or irreversible actions (e.g., deleting resources, modifying production data)\n- You need specific values that cannot be guessed (API keys, account IDs, specific user choices between valid alternatives)\n\n**When NOT to use clarify:**\n- For trivial decisions you can make based on codebase conventions or common practices\n- For permission questions like \"Should I proceed?\" (just proceed with the best option)\n- For information that's likely in the codebase, configuration files, or documentation (read those first)\n- Multiple times in a row - complete all non-blocked work first, then ask one clear question\n- For choices where a reasonable default exists (use the default and mention what you chose)\n\n**How to use clarify:**\n- Ask ONE clear, specific question per clarification\n- Provide context if needed to help the user understand the choice\n- Include a recommended default answer when applicable\n- Explain briefly what would change based on the answer\n\nExample usage: Call clarify with a question, optional context, and optional default answer. The tool will pause and wait for the user's response.\n- For substantial work, summarize clearly; follow final‑answer formatting.\n- Skip heavy formatting for simple confirmations.\n- Don't dump large files you've written; reference paths only.\n- No \"save/copy this file\" - User is on the same machine.\n- Offer logical next steps (tests, commits, build) briefly; add verify steps if you couldn't do something.\n- For code changes:\n * Lead with a quick explanation of the change, and then give more details on the context covering where and why a change was made. Do not start this explanation with \"summary\", just jump right in.\n * If there are natural next steps the user may want to take, suggest them at the end of your response. Do not make suggestions if there are no natural next steps.\n * When suggesting multiple options, use numeric lists for the suggestions so the user can quickly respond with a single number.\n- The user does not command execution outputs. When asked to show the output of a command (e.g. \\`git show\\`), relay the important details in your answer or summarize the key lines so the user understands the result.\n\n## Final answer structure and style guidelines\n\n- Plain text; CLI handles styling. Use structure only when it helps scanability.\n- Headers: optional; short Title Case (1-3 words) wrapped in **…**; no blank line before the first bullet; add only if they truly help.\n- Bullets: use - ; merge related points; keep to one line when possible; 4–6 per list ordered by importance; keep phrasing consistent.\n- Monospace: backticks for commands/paths/env vars/code ids and inline examples; use for literal keyword bullets; never combine with **.\n- Code samples or multi-line snippets should be wrapped in fenced code blocks; include an info string as often as possible.\n- Structure: group related bullets; order sections general → specific → supporting; for subsections, start with a bolded keyword bullet, then items; match complexity to the task.\n- Tone: collaborative, concise, factual; present tense, active voice; self‑contained; no \"above/below\"; parallel wording.\n- Don'ts: no nested bullets/hierarchies; no ANSI codes; don't cram unrelated keywords; keep keyword lists short—wrap/reformat if long; avoid naming formatting styles in answers.\n- Adaptation: code explanations → precise, structured with code refs; simple tasks → lead with outcome; big changes → logical walkthrough + rationale + next actions; casual one-offs → plain sentences, no headers/bullets.\n- File References: When referencing files in your response follow the below rules:\n * Use inline code to make file paths clickable.\n * Each reference should have a stand alone path. Even if it's the same file.\n * Accepted: absolute, workspace‑relative, a/ or b/ diff prefixes, or bare filename/suffix.\n * Optionally include line/column (1‑based): :line[:column] or #Lline[Ccolumn] (column defaults to 1).\n * Do not use URIs like file://, vscode://, or https://.\n * Do not provide range of lines\n * Examples: src/app.ts, src/app.ts:42, b/server/index.js#L10, C:\\repo\\project\\main.rs:12:5\n\nHere is some useful information about the environment you are running in:\n<env>\n Working directory: ${process.cwd()}\n Platform: darwin\n Today's date: ${new Date().toLocaleDateString()}\n</env>\n<files>\n\n</files>`;\n\n return basePrompt;\n};\n\nexport default generateSystemPrompt;","import { pruneMessages, type ModelMessage } from \"ai\";\nimport { summarizeMessages } from \"../ai\";\nimport {\n COMPACT_TRIGGER,\n COMPACT_TARGET,\n KEEP_LAST_TURNS,\n} from \"../config/index\";\nimport type { Context, LLMProviderFactory } from \"../shared/types\";\n\ntype CompactResult = {\n didCompact: boolean;\n reason?: string;\n newMessages?: ModelMessage[];\n};\n\nconst ensureSummaryPrefix = (summary: string): string => {\n const trimmed = summary.trim();\n if (trimmed.length === 0) {\n return '';\n }\n if (trimmed.startsWith('[COMPACTED_CONTEXT]')) {\n return trimmed;\n }\n return `[COMPACTED_CONTEXT]\\n${trimmed}`;\n};\n\nconst safeStringify = (value: unknown): string => {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n};\n\nconst estimateTokens = (messages: ModelMessage[]): number => {\n let totalChars = 0;\n for (const message of messages) {\n totalChars += message.role.length;\n if (typeof message.content === 'string') {\n totalChars += message.content.length;\n } else {\n totalChars += safeStringify(message.content).length;\n }\n }\n return Math.ceil(totalChars / 4);\n};\n\nconst splitByTurns = (messages: ModelMessage[], keepLastTurns: number) => {\n const userIndices: number[] = [];\n messages.forEach((message, index) => {\n if (message.role === 'user') {\n userIndices.push(index);\n }\n });\n\n if (userIndices.length <= keepLastTurns) {\n return { oldMessages: [], recentMessages: messages };\n }\n\n const cutIndex = userIndices[userIndices.length - keepLastTurns];\n return {\n oldMessages: messages.slice(0, cutIndex),\n recentMessages: messages.slice(cutIndex),\n };\n};\n\nconst takeLastTurns = (messages: ModelMessage[], keepLastTurns: number): ModelMessage[] => {\n const userIndices: number[] = [];\n messages.forEach((message, index) => {\n if (message.role === 'user') {\n userIndices.push(index);\n }\n });\n\n if (userIndices.length === 0) {\n return messages;\n }\n\n if (userIndices.length <= keepLastTurns) {\n return messages;\n }\n\n const startIndex = userIndices[userIndices.length - keepLastTurns];\n return messages.slice(startIndex);\n};\n\nexport const maybeCompactContext = async (\n context: Context,\n options?: { force?: boolean; provider?: LLMProviderFactory; model?: string }\n): Promise<CompactResult> => {\n const { messages } = context;\n if (messages.length === 0) {\n return { didCompact: false };\n }\n\n const estimatedTokens = estimateTokens(messages);\n if (!options?.force && estimatedTokens < COMPACT_TRIGGER) {\n return { didCompact: false };\n }\n\n const { oldMessages, recentMessages } = splitByTurns(messages, KEEP_LAST_TURNS);\n if (oldMessages.length === 0) {\n return { didCompact: false };\n }\n\n try {\n const summary = await summarizeMessages(oldMessages, {\n provider: options?.provider,\n model: options?.model,\n });\n const summaryText = ensureSummaryPrefix(summary);\n if (!summaryText) {\n throw new Error('Empty summary result');\n }\n\n const nextMessages: ModelMessage[] = [\n { role: 'assistant', content: summaryText },\n ...recentMessages,\n ];\n\n if (estimateTokens(nextMessages) > COMPACT_TARGET) {\n const newMessages = takeLastTurns(messages, KEEP_LAST_TURNS);\n return { didCompact: true, reason: 'summary-too-large', newMessages };\n }\n\n return { didCompact: true, newMessages: nextMessages };\n } catch (error) {\n const pruned = pruneMessages({\n messages,\n reasoning: 'all',\n toolCalls: 'all',\n emptyMessages: 'remove',\n });\n const newMessages = takeLastTurns(pruned, KEEP_LAST_TURNS);\n return { didCompact: true, reason: 'fallback', newMessages };\n }\n};","import { ToolSet, type StepResult, type ModelMessage } from \"ai\";\nimport type { Context, ClarificationRequest, Tool, LLMProviderFactory, SystemPromptOption, ToolHooks } from \"../shared/types\";\nimport { streamTextAI } from \"../ai\";\nimport { maybeCompactContext } from \"../context\";\nimport {\n MAX_COMPACTION_ATTEMPTS,\n MAX_ERROR_COUNT,\n MAX_STEPS\n} from \"../config/index.js\";\n\nexport interface LoopOptions {\n onText?: (delta: string) => void;\n onToolCall?: (toolCall: any) => void;\n onToolResult?: (toolResult: any) => void;\n onStepFinish?: (step: StepResult<any>) => void;\n onClarificationRequest?: (request: ClarificationRequest) => Promise<string>;\n onCompacted?: (newMessages: ModelMessage[]) => void;\n onResponse?: (messages: StepResult<ToolSet>['response']['messages']) => void;\n abortSignal?: AbortSignal;\n\n tools?: Record<string, Tool>; // 允许传入工具覆盖默认工具\n\n /** Custom LLM provider factory. Overrides the default provider when set. */\n provider?: LLMProviderFactory;\n /** Model name passed to the provider. Overrides DEFAULT_MODEL when set. */\n model?: string;\n /** Custom system prompt. See SystemPromptOption for the three supported forms. */\n systemPrompt?: SystemPromptOption;\n /** Hooks fired around every tool execution (before/after). */\n hooks?: ToolHooks;\n}\n\n/** Wraps tools with ToolHooks so each call passes through before/after handlers. */\nfunction applyToolHooks(tools: Record<string, Tool>, hooks: ToolHooks): Record<string, Tool> {\n const wrapped: Record<string, Tool> = {};\n for (const [name, t] of Object.entries(tools)) {\n wrapped[name] = {\n ...t,\n execute: async (input: any, ctx: any) => {\n const finalInput = hooks.onBeforeToolCall\n ? (await hooks.onBeforeToolCall(name, input)) ?? input\n : input;\n const output = await t.execute(finalInput, ctx);\n return hooks.onAfterToolCall\n ? (await hooks.onAfterToolCall(name, finalInput, output)) ?? output\n : output;\n },\n };\n }\n return wrapped;\n}\n\nexport async function loop(context: Context, options?: LoopOptions): Promise<string> {\n let errorCount = 0;\n let totalSteps = 0;\n let compactionAttempts = 0;\n\n while (true) {\n try {\n if (compactionAttempts < MAX_COMPACTION_ATTEMPTS) {\n const { didCompact, newMessages } = await maybeCompactContext(context, {\n provider: options?.provider,\n model: options?.model,\n });\n if (didCompact) {\n compactionAttempts++;\n\n if (newMessages) {\n options?.onCompacted?.(newMessages)\n }\n continue;\n }\n }\n\n let tools = options?.tools || {}; // 允许传入工具覆盖默认工具\n\n // Apply tool hooks if provided\n if (options?.hooks) {\n tools = applyToolHooks(tools, options.hooks);\n }\n\n // Prepare tool execution context\n const toolExecutionContext = {\n onClarificationRequest: options?.onClarificationRequest,\n abortSignal: options?.abortSignal\n };\n\n const result = streamTextAI(context.messages, tools, {\n abortSignal: options?.abortSignal,\n toolExecutionContext,\n provider: options?.provider,\n model: options?.model,\n systemPrompt: options?.systemPrompt,\n onStepFinish: (step) => {\n options?.onStepFinish?.(step);\n },\n onChunk: ({ chunk }) => {\n if (chunk.type === 'text-delta') {\n options?.onText?.(chunk.text);\n }\n if (chunk.type === 'tool-call') {\n options?.onToolCall?.(chunk);\n }\n if (chunk.type === 'tool-result') {\n options?.onToolResult?.(chunk);\n }\n },\n });\n\n const [text, steps, finishReason] = await Promise.all([\n result.text,\n result.steps,\n result.finishReason,\n ]);\n\n totalSteps += steps.length;\n\n for (const step of steps) {\n if (step.response?.messages?.length) {\n const messages = [...step.response.messages];\n options?.onResponse?.(messages);\n }\n }\n\n if (finishReason === 'stop') {\n return text || 'Task completed.';\n }\n\n if (finishReason === 'length') {\n if (compactionAttempts < MAX_COMPACTION_ATTEMPTS) {\n const { didCompact, newMessages } = await maybeCompactContext(context, {\n force: true,\n provider: options?.provider,\n model: options?.model,\n });\n if (didCompact) {\n compactionAttempts++;\n if (newMessages) {\n options?.onCompacted?.(newMessages)\n }\n continue;\n }\n }\n return text || 'Context limit reached.';\n }\n\n if (finishReason === 'content-filter') {\n return text || 'Content filtered.';\n }\n\n if (finishReason === 'error') {\n return text || 'Task failed.';\n }\n\n if (finishReason === 'tool-calls') {\n if (totalSteps >= MAX_STEPS) {\n return text || 'Max steps reached, task may be incomplete.';\n }\n continue;\n }\n\n return text || 'Task completed.';\n } catch (error: any) {\n if (options?.abortSignal?.aborted || error?.name === 'AbortError') {\n return 'Request aborted.';\n }\n\n errorCount++;\n if (errorCount >= MAX_ERROR_COUNT) {\n return `Failed after ${errorCount} errors: ${error?.message ?? String(error)}`;\n }\n\n if (isRetryableError(error)) {\n const delay = Math.min(2000 * Math.pow(2, errorCount - 1), 30000);\n await sleep(delay);\n continue;\n }\n\n return `Error: ${error?.message ?? String(error)}`;\n }\n }\n}\n\nfunction isRetryableError(error: any): boolean {\n const status = error?.status ?? error?.statusCode;\n return status === 429 || status === 500 || status === 502 || status === 503;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}","import z from \"zod\";\nimport { readFileSync, existsSync, statSync } from \"fs\";\nimport type { Tool } from \"../shared/types\";\nimport { truncateOutput } from \"./utils\";\n\nexport const ReadTool: Tool<\n { filePath: string; offset?: number; limit?: number },\n { content: string; totalLines?: number }\n> = {\n name: 'read',\n description: 'Read the contents of a file. Supports reading specific line ranges with offset and limit.',\n inputSchema: z.object({\n filePath: z.string().describe('The absolute path to the file to read'),\n offset: z.number().optional().describe('The line number to start reading from (0-based). Only provide if the file is too large to read at once.'),\n limit: z.number().optional().describe('The number of lines to read. Only provide if the file is too large to read at once.'),\n }),\n execute: async ({ filePath, offset, limit }) => {\n // Check if file exists\n if (!existsSync(filePath)) {\n throw new Error(`File does not exist: ${filePath}`);\n }\n\n // Check if it's a directory\n const stats = statSync(filePath);\n if (stats.isDirectory()) {\n throw new Error(`Cannot read directory: ${filePath}. Use 'ls' tool to list directory contents.`);\n }\n\n // Read the entire file\n const content = readFileSync(filePath, 'utf-8');\n const lines = content.split('\\n');\n const totalLines = lines.length;\n\n // If no offset/limit specified, return the entire file\n if (offset === undefined && limit === undefined) {\n return {\n content: truncateOutput(content),\n totalLines,\n };\n }\n\n // Apply offset and limit\n const startLine = offset || 0;\n const endLine = limit ? startLine + limit : lines.length;\n\n // Validate range\n if (startLine < 0 || startLine >= totalLines) {\n throw new Error(`Invalid offset: ${startLine}. File has ${totalLines} lines.`);\n }\n\n // Extract the requested lines\n const selectedLines = lines.slice(startLine, endLine);\n\n // Format with line numbers (1-based for display)\n const numberedContent = selectedLines\n .map((line, idx) => {\n const lineNum = startLine + idx + 1;\n return `${String(lineNum).padStart(6, ' ')}→${line}`;\n })\n .join('\\n');\n\n return {\n content: truncateOutput(numberedContent),\n totalLines,\n };\n },\n};\n\nexport default ReadTool;\n","import { MAX_TOOL_OUTPUT_LENGTH } from \"../config\";\n\nexport const truncateOutput = (output: string): string => {\n if (output.length <= MAX_TOOL_OUTPUT_LENGTH) {\n return output;\n }\n\n const half = Math.floor(MAX_TOOL_OUTPUT_LENGTH / 2);\n const removed = output.length - MAX_TOOL_OUTPUT_LENGTH;\n\n return (\n output.slice(0, half) +\n `\\n\\n... [truncated ${removed} characters] ...\\n\\n` +\n output.slice(-half)\n );\n};\n","import z from \"zod\";\nimport { writeFileSync, mkdirSync, existsSync } from \"fs\";\nimport { dirname } from \"path\";\nimport type { Tool } from \"../shared/types\";\n\nexport const WriteTool: Tool<\n { filePath: string; content: string },\n { success: boolean; created: boolean; bytes: number }\n> = {\n name: 'write',\n description: 'Write contents to a file. Automatically creates parent directories if they do not exist. Will overwrite existing files.',\n inputSchema: z.object({\n filePath: z.string().describe('The absolute path to the file to write (must be absolute, not relative)'),\n content: z.string().describe('The content to write to the file'),\n }),\n execute: async ({ filePath, content }) => {\n // Check if file already exists\n const fileExists = existsSync(filePath);\n\n // Get the directory path\n const dir = dirname(filePath);\n\n // Create parent directories if they don't exist\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n\n // Write the file\n writeFileSync(filePath, content, 'utf-8');\n\n // Calculate bytes written\n const bytes = Buffer.byteLength(content, 'utf-8');\n\n return {\n success: true,\n created: !fileExists,\n bytes,\n };\n },\n};\n\nexport default WriteTool;\n","import z from \"zod\";\nimport { readFileSync, writeFileSync } from \"fs\";\nimport type { Tool } from \"../shared/types\";\nimport { truncateOutput } from \"./utils\";\n\nexport const EditTool: Tool<\n { filePath: string; oldString: string; newString: string; replaceAll?: boolean },\n { success: boolean; replacements: number; preview?: string }\n> = {\n name: 'edit',\n description: 'Performs exact string replacements in files. Use this to edit existing files by replacing old_string with new_string.',\n inputSchema: z.object({\n filePath: z.string().describe('The absolute path to the file to modify'),\n oldString: z.string().describe('The exact text to replace (must match exactly)'),\n newString: z.string().describe('The text to replace it with (must be different from old_string)'),\n replaceAll: z.boolean().optional().default(false).describe('Replace all occurrences of old_string (default false)'),\n }),\n execute: async ({ filePath, oldString, newString, replaceAll = false }) => {\n // Validate that old and new strings are different\n if (oldString === newString) {\n throw new Error('old_string and new_string must be different');\n }\n\n // Read the file\n const content = readFileSync(filePath, 'utf-8');\n\n // Check if oldString exists in the file\n if (!content.includes(oldString)) {\n throw new Error(`old_string not found in file: ${filePath}`);\n }\n\n let newContent: string;\n let replacements = 0;\n\n if (replaceAll) {\n // Replace all occurrences\n const parts = content.split(oldString);\n replacements = parts.length - 1;\n newContent = parts.join(newString);\n } else {\n // Replace only the first occurrence\n const index = content.indexOf(oldString);\n if (index === -1) {\n throw new Error(`old_string not found in file: ${filePath}`);\n }\n\n // Check if the string is unique (appears only once)\n const secondIndex = content.indexOf(oldString, index + oldString.length);\n if (secondIndex !== -1) {\n throw new Error(\n 'old_string is not unique in the file. Either provide a larger string with more surrounding context to make it unique or use replace_all to change every instance.'\n );\n }\n\n newContent = content.slice(0, index) + newString + content.slice(index + oldString.length);\n replacements = 1;\n }\n\n // Write the modified content back\n writeFileSync(filePath, newContent, 'utf-8');\n\n // Generate a preview of the changes (show the changed section with context)\n const changedIndex = newContent.indexOf(newString);\n const contextLength = 200;\n const start = Math.max(0, changedIndex - contextLength);\n const end = Math.min(newContent.length, changedIndex + newString.length + contextLength);\n const preview = truncateOutput(\n `...${newContent.slice(start, end)}...`\n );\n\n return {\n success: true,\n replacements,\n preview,\n };\n },\n};\n\nexport default EditTool;\n","import z from \"zod\";\nimport { execSync } from \"child_process\";\nimport { existsSync } from \"fs\";\nimport type { Tool } from \"../shared/types\";\nimport { truncateOutput } from \"./utils\";\n\nexport const GrepTool: Tool<\n {\n pattern: string;\n path?: string;\n glob?: string;\n type?: string;\n outputMode?: 'content' | 'files_with_matches' | 'count';\n context?: number;\n caseInsensitive?: boolean;\n headLimit?: number;\n offset?: number;\n multiline?: boolean;\n },\n { output: string; matches?: number }\n> = {\n name: 'grep',\n description: 'A powerful search tool built on ripgrep. Supports regex patterns, file filtering, and multiple output modes.',\n inputSchema: z.object({\n pattern: z.string().describe('The regular expression pattern to search for in file contents'),\n path: z.string().optional().describe('File or directory to search in. Defaults to current working directory.'),\n glob: z.string().optional().describe('Glob pattern to filter files (e.g. \"*.js\", \"*.{ts,tsx}\")'),\n type: z.string().optional().describe('File type to search (e.g., js, py, rust, go, java, ts, tsx, json, md)'),\n outputMode: z.enum(['content', 'files_with_matches', 'count']).optional().default('files_with_matches')\n .describe('Output mode: \"content\" shows matching lines, \"files_with_matches\" shows file paths, \"count\" shows match counts'),\n context: z.number().optional().describe('Number of lines to show before and after each match (only with output_mode: \"content\")'),\n caseInsensitive: z.boolean().optional().default(false).describe('Case insensitive search'),\n headLimit: z.number().optional().default(0).describe('Limit output to first N lines/entries. 0 means unlimited.'),\n offset: z.number().optional().default(0).describe('Skip first N lines/entries before applying head_limit'),\n multiline: z.boolean().optional().default(false).describe('Enable multiline mode where patterns can span lines'),\n }),\n execute: async ({\n pattern,\n path = '.',\n glob,\n type,\n outputMode = 'files_with_matches',\n context,\n caseInsensitive = false,\n headLimit = 0,\n offset = 0,\n multiline = false,\n }) => {\n // Build ripgrep command\n const args: string[] = ['rg'];\n\n // Pattern\n args.push(pattern);\n\n // Case sensitivity\n if (caseInsensitive) {\n args.push('-i');\n }\n\n // Output mode\n if (outputMode === 'files_with_matches') {\n args.push('-l'); // --files-with-matches\n } else if (outputMode === 'count') {\n args.push('-c'); // --count\n } else if (outputMode === 'content') {\n args.push('-n'); // Show line numbers\n if (context !== undefined) {\n args.push(`-C${context}`);\n }\n }\n\n // Multiline mode\n if (multiline) {\n args.push('-U'); // --multiline\n args.push('--multiline-dotall');\n }\n\n // File filtering\n if (glob) {\n args.push('--glob', glob);\n }\n if (type) {\n args.push('--type', type);\n }\n\n // Path\n if (path && path !== '.') {\n // Verify path exists\n if (!existsSync(path)) {\n throw new Error(`Path does not exist: ${path}`);\n }\n args.push(path);\n }\n\n // Build the command string\n let command = args.map(arg => {\n // Quote arguments that contain spaces or special characters\n if (arg.includes(' ') || arg.includes('$') || arg.includes('*')) {\n return `'${arg.replace(/'/g, \"'\\\\''\")}'`;\n }\n return arg;\n }).join(' ');\n\n // Add tail/head for offset/limit\n if (offset > 0) {\n command += ` | tail -n +${offset + 1}`;\n }\n if (headLimit > 0) {\n command += ` | head -n ${headLimit}`;\n }\n\n try {\n const output = execSync(command, {\n encoding: 'utf-8',\n maxBuffer: 1024 * 1024 * 10, // 10MB\n shell: '/bin/bash',\n });\n\n // Count matches for count mode\n let matches: number | undefined;\n if (outputMode === 'count') {\n matches = output.split('\\n').filter(line => line.trim()).length;\n } else if (outputMode === 'files_with_matches') {\n matches = output.split('\\n').filter(line => line.trim()).length;\n }\n\n return {\n output: truncateOutput(output || '(no matches found)'),\n matches,\n };\n } catch (error: any) {\n // Exit code 1 means no matches found (not an error)\n if (error.status === 1) {\n return {\n output: '(no matches found)',\n matches: 0,\n };\n }\n\n // Other errors\n throw new Error(\n `grep failed: ${error.stderr || error.message}\\nCommand: ${command}`\n );\n }\n },\n};\n\nexport default GrepTool;\n","import z from \"zod\";\nimport { readdirSync } from \"fs\";\nimport type { Tool } from \"../shared/types\";\n\nexport const LsTool: Tool<\n { path?: string },\n { files: string[] }\n> = {\n name: 'ls',\n description: 'List files and directories in a given path',\n inputSchema: z.object({\n path: z.string().optional().describe('The path to list files from (defaults to current directory)'),\n }),\n execute: async ({ path = '.' }) => {\n const files = readdirSync(path);\n return { files };\n },\n};\n\nexport default LsTool;\n","import z from \"zod\";\nimport { execSync } from \"child_process\";\nimport type { Tool } from \"../shared/types\";\nimport { truncateOutput } from \"./utils\";\n\nexport const BashTool: Tool<\n { command: string; timeout?: number; cwd?: string; description?: string },\n { output: string; error?: string; exitCode?: number }\n> = {\n name: 'bash',\n description: 'Execute a bash command and return the output. Supports timeout and working directory configuration.',\n inputSchema: z.object({\n command: z.string().describe('The bash command to execute'),\n timeout: z.number().optional().describe('Optional timeout in milliseconds (max 600000ms / 10 minutes). Defaults to 120000ms (2 minutes).'),\n cwd: z.string().optional().describe('Optional working directory for command execution. Defaults to current directory.'),\n description: z.string().optional().describe('Optional description of what this command does (for logging/debugging)'),\n }),\n execute: async ({ command, timeout = 120000, cwd, description }) => {\n // Validate timeout\n if (timeout && (timeout < 0 || timeout > 600000)) {\n throw new Error('Timeout must be between 0 and 600000ms (10 minutes)');\n }\n\n try {\n const output = execSync(command, {\n encoding: 'utf-8',\n maxBuffer: 1024 * 1024 * 10, // 10MB\n timeout: timeout || 120000,\n cwd: cwd || process.cwd(),\n shell: '/bin/bash',\n });\n return {\n output: truncateOutput(output || '(command completed with no output)'),\n exitCode: 0,\n };\n } catch (error: any) {\n const exitCode = error.status || error.code || 1;\n const stdout = String(error.stdout || '');\n const stderr = String(error.stderr || error.message || '');\n\n // Check if it's a timeout error\n if (error.killed && error.signal === 'SIGTERM') {\n return {\n output: truncateOutput(stdout),\n error: truncateOutput(`Command timed out after ${timeout}ms\\n${stderr}`),\n exitCode,\n };\n }\n\n return {\n output: truncateOutput(stdout),\n error: truncateOutput(stderr),\n exitCode,\n };\n }\n },\n};\n\nexport default BashTool;\n","import z from \"zod\";\nimport type { Tool } from \"../shared/types\";\nimport { truncateOutput } from \"./utils\";\n\nexport const TavilyTool: Tool<\n { query: string; maxResults?: number },\n { results: Array<{ title: string; url: string; content: string; score?: number }> }\n> = {\n name: 'tavily',\n description: 'Search the web using Tavily API',\n inputSchema: z.object({\n query: z.string().describe('The search query'),\n maxResults: z.number().optional().default(5).describe('Maximum number of results to return'),\n }),\n execute: async ({ query, maxResults = 5 }) => {\n const apiKey = process.env.TAVILY_API_KEY;\n\n if (!apiKey) {\n throw new Error('TAVILY_API_KEY environment variable is not set');\n }\n\n const response = await fetch('https://api.tavily.com/search', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n api_key: apiKey,\n query,\n max_results: maxResults,\n search_depth: 'basic',\n include_answer: false,\n include_raw_content: false,\n include_images: false,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Tavily API error: ${response.status} ${response.statusText}`);\n }\n\n const data = await response.json();\n\n return {\n results: data.results?.map((result: any) => ({\n title: result.title || '',\n url: result.url || '',\n content: truncateOutput(result.content || ''),\n score: result.score || 0,\n })) || [],\n };\n },\n};\n\nexport default TavilyTool;\n","import z from \"zod\";\nimport type { Tool, ToolExecutionContext } from \"../shared/types\";\nimport { CLARIFICATION_TIMEOUT } from \"../config/index.js\";\nimport { randomUUID } from \"crypto\";\n\nexport interface ClarifyInput {\n question: string;\n context?: string;\n defaultAnswer?: string;\n timeout?: number;\n}\n\nexport interface ClarifyOutput {\n answer: string;\n timedOut: boolean;\n}\n\nexport const ClarifyTool: Tool<ClarifyInput, ClarifyOutput> = {\n name: 'clarify',\n description: 'Ask the user a clarifying question and wait for their response. Use this when you need information from the user to proceed with the task.',\n inputSchema: z.object({\n question: z.string().describe('The question to ask the user'),\n context: z.string().optional().describe('Additional context to help the user answer'),\n defaultAnswer: z.string().optional().describe('Default answer if user does not respond within timeout'),\n timeout: z.number().optional().describe('Timeout in milliseconds (default: 5 minutes)')\n }),\n execute: async (input, toolContext) => {\n if (!toolContext?.onClarificationRequest) {\n throw new Error('Clarification is not supported in this context. The clarify tool requires a CLI interface with user interaction.');\n }\n\n const timeout = input.timeout ?? CLARIFICATION_TIMEOUT;\n const requestId = randomUUID();\n\n try {\n // Create a promise that rejects on timeout\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Clarification request timed out after ${timeout}ms`));\n }, timeout);\n });\n\n // Race between user response and timeout\n const answer = await Promise.race([\n toolContext.onClarificationRequest({\n id: requestId,\n question: input.question,\n context: input.context,\n defaultAnswer: input.defaultAnswer,\n timeout\n }),\n timeoutPromise\n ]);\n\n return {\n answer,\n timedOut: false\n };\n } catch (error: any) {\n // If timeout occurred and we have a default answer, use it\n if (error?.message?.includes('timed out') && input.defaultAnswer) {\n return {\n answer: input.defaultAnswer,\n timedOut: true\n };\n }\n\n // Otherwise, re-throw the error\n throw error;\n }\n },\n};\n\nexport default ClarifyTool;\n","import { ReadTool } from './read';\nimport { WriteTool } from './write';\nimport { EditTool } from './edit';\nimport { GrepTool } from './grep';\nimport { LsTool } from './ls';\nimport { BashTool } from './bash';\nimport { TavilyTool } from './tavily';\nimport { ClarifyTool } from './clarify';\nimport { Tool } from 'ai';\n// import { SkillTool } from './skill;\n\nexport const BuiltinTools = [\n ReadTool,\n WriteTool,\n EditTool,\n GrepTool,\n LsTool,\n BashTool,\n TavilyTool,\n ClarifyTool,\n] as const;\n\nexport const BuiltinToolsMap = BuiltinTools.reduce((acc, toolInstance) => {\n acc[toolInstance.name] = toolInstance;\n return acc;\n}, {} as Record<string, any>);\n\nexport const getFinalToolsMap = (customTools?: Record<string, Tool>) => {\n if (!customTools) {\n return BuiltinToolsMap;\n }\n return { ...BuiltinToolsMap, ...customTools };\n};\n\nexport {\n ReadTool,\n WriteTool,\n EditTool,\n GrepTool,\n LsTool,\n BashTool,\n TavilyTool,\n ClarifyTool,\n};\n"],"mappings":"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","names":["tool","import_fs","matter","skill","import_zod","import_fs","import_path","dotenv","tool","import_ai","import_zod","import_fs","z","import_zod","import_fs","z","import_zod","import_fs","z","import_zod","import_fs","z","path","import_zod","import_fs","z","path","import_zod","import_child_process","z","import_zod","z","import_zod","z","fs","path","tool"]}