oricore 1.5.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-DO76AL42.js → chunk-D5X6YFSK.js} +2 -1
- package/dist/{chunk-4QYFQSAC.js → chunk-MZNH54NB.js} +128 -75
- package/dist/chunk-MZNH54NB.js.map +1 -0
- package/dist/{chunk-OYWDQD3F.js → chunk-XBRIUBK5.js} +2 -2
- package/dist/history-FS6CASR6.js +8 -0
- package/dist/index.cjs +416 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +240 -4
- package/dist/index.d.ts +240 -4
- package/dist/index.js +282 -10
- package/dist/index.js.map +1 -1
- package/dist/{session-QMS6OYG2.js → session-W73HJB5Q.js} +4 -4
- package/dist/undici-NSB7IUB7.js +5 -0
- package/package.json +2 -1
- package/src/index.ts +12 -0
- package/src/skill/bundled.ts +225 -0
- package/src/skill/skill.ts +260 -4
- package/src/tools/tool.ts +14 -4
- package/src/tools/tools/skill.ts +86 -8
- package/dist/chunk-4QYFQSAC.js.map +0 -1
- package/dist/history-AGNMX5YW.js +0 -8
- package/dist/undici-326ZBRKH.js +0 -5
- /package/dist/{chunk-DO76AL42.js.map → chunk-D5X6YFSK.js.map} +0 -0
- /package/dist/{chunk-OYWDQD3F.js.map → chunk-XBRIUBK5.js.map} +0 -0
- /package/dist/{history-AGNMX5YW.js.map → history-FS6CASR6.js.map} +0 -0
- /package/dist/{session-QMS6OYG2.js.map → session-W73HJB5Q.js.map} +0 -0
- /package/dist/{undici-326ZBRKH.js.map → undici-NSB7IUB7.js.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/context.ts","../src/agent/agent/agentManager.ts","../src/utils/safeFrontMatter.ts","../src/core/jsonl.ts","../src/core/llmsContext.ts","../src/core/rules.ts","../src/utils/execFileNoThrow.ts","../src/utils/git.ts","../src/utils/project.ts","../src/core/outputFormat.ts","../src/core/outputStyle.ts","../src/core/output-style/builtin/default.ts","../src/core/output-style/builtin/explanatory.ts","../src/core/output-style/builtin/miao.ts","../src/core/output-style/builtin/minimal.ts","../src/core/output-style/builtin/index.ts","../src/utils/string.ts","../src/core/planSystemPrompt.ts","../src/core/systemPrompt.ts","../src/core/project.ts","../src/agent/agent/executor.ts","../src/core/backgroundTaskManager.ts","../src/core/globalData.ts","../src/mcp/mcp.ts","../src/core/paths.ts","../src/skill/skill.ts","../src/communication/messageBus.ts","../src/platform/node.ts","../src/jsonl.ts","../src/modes/registry.ts","../src/modes/builtin.ts","../src/api/engine.ts","../src/index.ts"],"sourcesContent":["import fs from 'fs';\nimport { createJiti } from 'jiti';\nimport path from 'pathe';\nimport resolve from 'resolve';\nimport { AgentManager } from '../agent/agent/agentManager';\nimport { BackgroundTaskManager } from './backgroundTaskManager';\nimport { type Config, ConfigManager } from '../core/config';\nimport { GlobalData } from './globalData';\nimport { MCPManager } from '../mcp/mcp';\nimport type { MessageBus } from '../communication/messageBus';\nimport { Paths } from './paths';\nimport {\n type Plugin,\n type PluginApplyOpts,\n PluginHookType,\n PluginManager,\n} from '../core/plugin';\n// notificationSoundPlugin is CLI-specific, not needed in engine\n// import { notificationSoundPlugin } from '../plugins/notification';\nimport { SkillManager } from '../skill/skill';\n\ntype ContextOpts = {\n cwd: string;\n productName: string;\n productASCIIArt?: string;\n version: string;\n config: Config;\n pluginManager: PluginManager;\n paths: Paths;\n argvConfig: Record<string, any>;\n mcpManager: MCPManager;\n backgroundTaskManager: BackgroundTaskManager;\n skillManager?: SkillManager;\n messageBus?: MessageBus;\n agentManager?: AgentManager;\n plugins: (string | Plugin)[];\n fetch?: typeof globalThis.fetch;\n globalData: GlobalData;\n};\n\nexport type ContextCreateOpts = {\n cwd: string;\n productName: string;\n productASCIIArt?: string;\n version: string;\n argvConfig: Record<string, any>;\n plugins: (string | Plugin)[];\n messageBus?: MessageBus;\n fetch?: typeof globalThis.fetch;\n};\n\nexport class Context {\n cwd: string;\n productName: string;\n productASCIIArt?: string;\n version: string;\n config: Config;\n paths: Paths;\n #pluginManager: PluginManager;\n argvConfig: Record<string, any>;\n mcpManager: MCPManager;\n backgroundTaskManager: BackgroundTaskManager;\n skillManager?: SkillManager;\n messageBus?: MessageBus;\n agentManager?: AgentManager;\n plugins: (string | Plugin)[];\n fetch?: typeof globalThis.fetch;\n globalData: GlobalData;\n constructor(opts: ContextOpts) {\n this.cwd = opts.cwd;\n this.productName = opts.productName;\n this.productASCIIArt = opts.productASCIIArt;\n this.version = opts.version;\n this.config = opts.config;\n this.paths = opts.paths;\n this.mcpManager = opts.mcpManager;\n this.#pluginManager = opts.pluginManager;\n this.argvConfig = opts.argvConfig;\n this.backgroundTaskManager = opts.backgroundTaskManager;\n this.skillManager = opts.skillManager;\n this.messageBus = opts.messageBus;\n this.agentManager = opts.agentManager;\n this.plugins = opts.plugins;\n this.fetch = opts.fetch;\n this.globalData = opts.globalData;\n }\n\n async apply(applyOpts: Omit<PluginApplyOpts, 'pluginContext'>) {\n return this.#pluginManager.apply({\n ...applyOpts,\n pluginContext: this,\n });\n }\n\n async destroy() {\n await this.mcpManager.destroy();\n await this.apply({\n hook: 'destroy',\n args: [],\n type: PluginHookType.Parallel,\n });\n }\n\n static async create(opts: ContextCreateOpts) {\n const { cwd, version, productASCIIArt } = opts;\n const productName = opts.productName.toLowerCase();\n const paths = new Paths({\n productName,\n cwd,\n });\n const configManager = new ConfigManager(\n cwd,\n productName,\n opts.argvConfig || {},\n );\n const initialConfig = configManager.config;\n // notificationSoundPlugin is CLI-specific, not needed in engine\n const buildInPlugins: Plugin[] = []; // [notificationSoundPlugin];\n const globalPlugins = scanPlugins(\n path.join(paths.globalConfigDir, 'plugins'),\n );\n const projectPlugins = scanPlugins(\n path.join(paths.projectConfigDir, 'plugins'),\n );\n const pluginsConfigs: (string | Plugin)[] = [\n ...buildInPlugins,\n ...globalPlugins,\n ...projectPlugins,\n ...(initialConfig.plugins || []),\n ...(opts.plugins || []),\n ];\n const plugins = await normalizePlugins(opts.cwd, pluginsConfigs);\n const pluginManager = new PluginManager(plugins);\n const apply = async (hookOpts: any) => {\n return pluginManager.apply({ ...hookOpts, pluginContext: tempContext });\n };\n const tempContext = {\n ...opts,\n config: initialConfig,\n apply,\n pluginManager,\n };\n const resolvedConfig = await apply({\n hook: 'config',\n args: [{ config: initialConfig, argvConfig: opts.argvConfig }],\n memo: initialConfig,\n type: PluginHookType.SeriesMerge,\n });\n tempContext.config = resolvedConfig;\n const mcpServers = {\n ...(resolvedConfig.mcpServers || {}),\n ...opts.argvConfig.mcpServers,\n };\n const mcpManager = MCPManager.create(mcpServers);\n const backgroundTaskManager = new BackgroundTaskManager();\n const globalData = new GlobalData({ globalDataPath: paths.getGlobalDataPath() });\n\n const context = new Context({\n cwd,\n productName,\n productASCIIArt,\n version,\n pluginManager,\n argvConfig: opts.argvConfig,\n config: resolvedConfig,\n paths,\n mcpManager,\n backgroundTaskManager,\n messageBus: opts.messageBus,\n plugins: pluginsConfigs,\n fetch: opts.fetch,\n globalData,\n });\n\n // Create and attach SkillManager\n const skillManager = new SkillManager({ context });\n await skillManager.loadSkills();\n context.skillManager = skillManager;\n\n // Create and attach AgentManager\n const agentManager = new AgentManager({ context });\n // Load agents from files\n await agentManager.loadAgents();\n context.agentManager = agentManager;\n\n return context;\n }\n}\n\nfunction normalizePlugins(cwd: string, plugins: (string | Plugin)[]) {\n let jiti: any = null;\n return Promise.all(\n plugins.map(async (plugin) => {\n if (typeof plugin === 'string') {\n const pluginPath = resolve.sync(plugin, { basedir: cwd });\n if (!jiti) {\n // Use cwd as base for jiti instead of import.meta.url for CJS compatibility\n jiti = createJiti(cwd);\n }\n return (await jiti.import(pluginPath, {\n default: true,\n })) as Plugin;\n }\n return plugin;\n }),\n );\n}\n\nfunction scanPlugins(pluginDir: string): string[] {\n try {\n if (!fs.existsSync(pluginDir)) {\n return [];\n }\n const files = fs.readdirSync(pluginDir);\n return files\n .filter((file) => file.endsWith('.js') || file.endsWith('.ts'))\n .map((file) => path.join(pluginDir, file));\n } catch (_error) {\n return [];\n }\n}\n","import fs from 'fs';\nimport path from 'pathe';\nimport { TOOL_NAMES } from '../../core/constants';\nimport type { Context } from '../../core/context';\nimport type { NormalizedMessage } from '../../core/message';\nimport { PluginHookType } from '../../core/plugin';\nimport type {\n ApprovalCategory,\n Tool,\n ToolApprovalResult,\n ToolUse,\n} from '../../tools/tool';\nimport { safeFrontMatter } from '../../utils/safeFrontMatter';\n// builtin agents excluded from engine for now\n// import { getBuiltinAgents } from './builtin';\nimport { executeAgent } from './executor';\nimport type {\n AgentDefinition,\n AgentExecuteOptions,\n AgentExecutionResult,\n AgentLoadError,\n TaskToolInput,\n} from './types';\nimport { AgentSource } from './types';\n\nconst MAX_NAME_LENGTH = 64;\nconst MAX_DESCRIPTION_LENGTH = 1024;\n\nexport class AgentManager {\n private agents: Map<string, AgentDefinition> = new Map();\n private context: Context;\n private errors: AgentLoadError[] = [];\n\n constructor(opts: { context: Context }) {\n this.context = opts.context;\n this.registerBuiltinAgents();\n }\n\n private registerBuiltinAgents(): void {\n // builtin agents excluded from engine for now\n // const builtinAgents = getBuiltinAgents({ context: this.context });\n // for (const agent of builtinAgents) {\n // this.agents.set(agent.agentType, agent);\n // }\n }\n\n registerAgent(definition: AgentDefinition): void {\n if (!definition.agentType) {\n throw new Error('Agent definition must have agentType');\n }\n if (!definition.systemPrompt) {\n throw new Error('Agent definition must have systemPrompt');\n }\n\n this.agents.set(definition.agentType, definition);\n }\n\n isAgentEnabled(agent: AgentDefinition): boolean {\n if (agent.isEnabled === undefined) {\n return true;\n }\n if (typeof agent.isEnabled === 'boolean') {\n return agent.isEnabled;\n }\n if (typeof agent.isEnabled === 'function') {\n return agent.isEnabled(this.context);\n }\n return true;\n }\n\n getAgent(agentType: string): AgentDefinition | undefined {\n const agent = this.agents.get(agentType);\n if (agent && this.isAgentEnabled(agent)) {\n return agent;\n }\n return undefined;\n }\n\n getAllAgents(): AgentDefinition[] {\n return Array.from(this.agents.values()).filter((agent) =>\n this.isAgentEnabled(agent),\n );\n }\n\n getAgentTypes(): string[] {\n return this.getAllAgents().map((agent) => agent.agentType);\n }\n\n async executeTask(\n input: TaskToolInput,\n context: {\n tools: Tool[];\n cwd: string;\n signal?: AbortSignal;\n parentSessionId?: string;\n forkContextMessages?: NormalizedMessage[];\n onMessage?: (\n message: NormalizedMessage,\n agentId: string,\n model: string,\n ) => void | Promise<void>;\n onToolApprove?: (opts: {\n toolUse: ToolUse;\n category?: ApprovalCategory;\n }) => Promise<boolean | ToolApprovalResult>;\n },\n ): Promise<AgentExecutionResult> {\n const definition = this.getAgent(input.subagent_type);\n if (!definition) {\n const availableTypes = this.getAgentTypes().join(', ');\n throw new Error(\n `Agent type '${input.subagent_type}' not found. Available agents: ${availableTypes}`,\n );\n }\n\n const executeOptions: AgentExecuteOptions = {\n definition,\n prompt: input.prompt,\n tools: context.tools,\n context: this.context,\n model: input.model,\n resume: input.resume,\n parentSessionId: context.parentSessionId,\n forkContextMessages: definition.forkContext\n ? context.forkContextMessages\n : undefined,\n cwd: context.cwd,\n signal: context.signal,\n onMessage: context.onMessage,\n onToolApprove: context.onToolApprove,\n };\n\n return executeAgent(executeOptions);\n }\n\n getAgentDescriptions(): string {\n const descriptions = this.getAllAgents()\n .map((agent) => {\n return `- ${agent.agentType}: ${agent.whenToUse ?? 'This subagent should only be called manually by the user.'}`;\n })\n .join('\\n');\n\n return `${descriptions}`;\n }\n\n async loadAgents(): Promise<void> {\n this.errors = [];\n\n // Plugins\n await this.loadAgentsFromPlugins();\n\n // GlobalClaude\n const globalClaudeDir = path.join(\n path.dirname(this.context.paths.globalConfigDir),\n '.claude',\n 'agents',\n );\n\n this.loadAgentsFromDirectory(globalClaudeDir, AgentSource.GlobalClaude);\n\n // Global\n const globalDir = path.join(this.context.paths.globalConfigDir, 'agents');\n this.loadAgentsFromDirectory(globalDir, AgentSource.Global);\n\n // ProjectClaude\n const projectClaudeDir = path.join(\n path.dirname(this.context.paths.projectConfigDir),\n '.claude',\n 'agents',\n );\n this.loadAgentsFromDirectory(projectClaudeDir, AgentSource.ProjectClaude);\n\n // Project\n const projectDir = path.join(this.context.paths.projectConfigDir, 'agents');\n this.loadAgentsFromDirectory(projectDir, AgentSource.Project);\n }\n\n private async loadAgentsFromPlugins(): Promise<void> {\n const pluginAgents = await this.context.apply({\n hook: 'agent',\n args: [],\n memo: [],\n type: PluginHookType.SeriesMerge,\n });\n\n for (const agent of pluginAgents) {\n this.agents.set(agent.agentType, {\n ...agent,\n model: agent.model || 'inherit',\n source: AgentSource.Plugin,\n });\n }\n }\n\n getErrors(): AgentLoadError[] {\n return this.errors;\n }\n\n private loadAgentsFromDirectory(\n agentsDir: string,\n source: AgentSource,\n ): void {\n if (!fs.existsSync(agentsDir)) {\n return;\n }\n\n try {\n const entries = fs.readdirSync(agentsDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith('.md')) {\n const agentPath = path.join(agentsDir, entry.name);\n this.loadAgentFile(agentPath, source);\n }\n }\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : 'Unknown error scanning directory';\n this.errors.push({\n path: agentsDir,\n message: `Failed to scan agents directory: ${message}`,\n });\n }\n }\n\n private loadAgentFile(filePath: string, source: AgentSource): void {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = this.parseAgentFile(content, filePath);\n\n if (parsed) {\n if (\n source === AgentSource.GlobalClaude ||\n source === AgentSource.ProjectClaude\n ) {\n parsed.tools = this.convertToolNames(parsed.tools || [], filePath);\n parsed.disallowedTools = this.convertToolNames(\n parsed.disallowedTools || [],\n filePath,\n );\n }\n this.agents.set(parsed.agentType, {\n ...parsed,\n source,\n path: filePath,\n });\n }\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'Unknown error loading agent';\n this.errors.push({\n path: filePath,\n message,\n });\n }\n }\n\n private convertToolNames(toolNames: string[], filePath: string): string[] {\n // Return tool names as-is, no conversion needed\n return toolNames;\n }\n\n private parseAgentFile(\n content: string,\n filePath: string,\n ): Omit<AgentDefinition, 'source' | 'path'> | null {\n try {\n const { attributes, body } = safeFrontMatter<{\n name?: string;\n description?: string;\n tools?: string;\n disallowedTools?: string;\n model?: string;\n forkContext?: boolean;\n color?: string;\n }>(content, filePath);\n\n if (!attributes.name) {\n this.errors.push({\n path: filePath,\n message: 'Missing required field: name',\n });\n return null;\n }\n\n if (!attributes.description) {\n this.errors.push({\n path: filePath,\n message: 'Missing required field: description',\n });\n return null;\n }\n\n if (attributes.name.length > MAX_NAME_LENGTH) {\n this.errors.push({\n path: filePath,\n message: `Name exceeds maximum length of ${MAX_NAME_LENGTH} characters`,\n });\n return null;\n }\n\n if (attributes.name.includes('\\n')) {\n this.errors.push({\n path: filePath,\n message: 'Name must be a single line',\n });\n return null;\n }\n\n if (attributes.description.length > MAX_DESCRIPTION_LENGTH) {\n this.errors.push({\n path: filePath,\n message: `Description exceeds maximum length of ${MAX_DESCRIPTION_LENGTH} characters`,\n });\n return null;\n }\n\n if (attributes.description.includes('\\n')) {\n this.errors.push({\n path: filePath,\n message: 'Description must be a single line',\n });\n return null;\n }\n\n const systemPrompt = body.trim();\n if (!systemPrompt) {\n this.errors.push({\n path: filePath,\n message: 'Missing system prompt (file body is empty)',\n });\n return null;\n }\n\n const tools = attributes.tools\n ? attributes.tools\n .split(',')\n .map((t) => t.trim())\n .filter((t) => t.length > 0)\n : undefined;\n\n const disallowedTools = attributes.disallowedTools\n ? attributes.disallowedTools\n .split(',')\n .map((t) => t.trim())\n .filter((t) => t.length > 0)\n : undefined;\n\n return {\n agentType: attributes.name,\n whenToUse: attributes.description,\n systemPrompt,\n model: attributes.model || 'inherit',\n tools,\n disallowedTools,\n forkContext: attributes.forkContext,\n color: attributes.color,\n };\n } catch (error) {\n this.errors.push({\n path: filePath,\n message:\n error instanceof Error\n ? error.message\n : 'Failed to parse frontmatter',\n });\n return null;\n }\n }\n}\n","import fm from 'front-matter';\n\nconst SIMPLE_VALUE_PATTERN = /^[a-zA-Z0-9_.\\-\\s]+$/;\n\nfunction isSimpleValue(value: string): boolean {\n if (!value) return true;\n const trimmed = value.trim();\n if (!trimmed) return true;\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n return true;\n }\n return SIMPLE_VALUE_PATTERN.test(trimmed);\n}\n\nfunction fixFrontmatterValues(frontmatter: string): string {\n return frontmatter.replace(\n /^(\\s*[a-zA-Z0-9_-]+\\s*:\\s*)(.+)$/gm,\n (match, keyPart, valuePart) => {\n if (isSimpleValue(valuePart)) {\n return match;\n }\n const trimmed = valuePart.trim();\n return `${keyPart}\"${trimmed.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\n },\n );\n}\n\n/**\n * Safely parse frontmatter from markdown content with automatic error recovery\n * Handles common YAML issues like unquoted colons in values\n * @param content - The markdown content with frontmatter\n * @param filePath - Optional file path for better error messages\n * @returns Parsed frontmatter attributes and body\n */\nexport function safeFrontMatter<T = Record<string, string>>(\n content: string,\n filePath?: string,\n): { attributes: T; body: string } {\n try {\n const { attributes, body } = fm<T>(content);\n return { attributes, body };\n } catch (error) {\n try {\n const frontmatterMatch = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\n if (frontmatterMatch) {\n const originalFm = frontmatterMatch[1];\n const fixedFm = fixFrontmatterValues(originalFm);\n\n if (fixedFm !== originalFm) {\n const fixedContent = content.replace(originalFm, fixedFm);\n const { attributes, body } = fm<T>(fixedContent);\n return { attributes, body };\n }\n }\n } catch {\n // Ignore retry errors\n }\n\n if (error instanceof Error) {\n const fileInfo = filePath ? ` ${filePath}` : '';\n error.message = `Failed to parse frontmatter${fileInfo}: ${error.message}`;\n }\n throw error;\n }\n}\n","import fs from 'fs';\nimport path from 'pathe';\nimport type { NormalizedMessage } from './message';\nimport { createUserMessage } from './message';\nimport type { StreamResult } from './loop';\n\nexport class JsonlLogger {\n filePath: string;\n lastUuid: string | null = null;\n constructor(opts: { filePath: string }) {\n this.filePath = opts.filePath;\n this.lastUuid = this.getLatestUuid();\n }\n\n getLatestUuid() {\n if (!fs.existsSync(this.filePath)) {\n return null;\n }\n const file = fs.readFileSync(this.filePath, 'utf8');\n const lines = file.split('\\n').filter(Boolean);\n const lastLine = lines[lines.length - 1];\n if (!lastLine) {\n return null;\n }\n const message = JSON.parse(lastLine);\n return message.uuid || null;\n }\n\n addMessage(opts: { message: NormalizedMessage & { sessionId: string } }) {\n const dir = path.dirname(this.filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n const message = opts.message;\n fs.appendFileSync(this.filePath, JSON.stringify(message) + '\\n');\n this.lastUuid = message.uuid;\n return message;\n }\n\n addUserMessage(content: string, sessionId: string) {\n const message = {\n ...createUserMessage(content, this.lastUuid),\n sessionId,\n };\n return this.addMessage({\n message,\n });\n }\n}\n\nexport class RequestLogger {\n globalProjectDir: string;\n\n constructor(opts: { globalProjectDir: string }) {\n this.globalProjectDir = opts.globalProjectDir;\n }\n\n private getFilePath(requestId: string): string {\n const requestsDir = path.join(this.globalProjectDir, 'requests');\n if (!fs.existsSync(requestsDir)) {\n fs.mkdirSync(requestsDir, { recursive: true });\n }\n return path.join(requestsDir, `${requestId}.jsonl`);\n }\n\n logMetadata(opts: {\n requestId: string;\n prompt: StreamResult['prompt'];\n model: StreamResult['model'];\n tools: StreamResult['tools'];\n request?: StreamResult['request'];\n response?: StreamResult['response'];\n error?: StreamResult['error'];\n }) {\n const filePath = this.getFilePath(opts.requestId);\n const entry = {\n type: 'metadata',\n requestId: opts.requestId,\n timestamp: new Date().toISOString(),\n prompt: opts.prompt,\n model: opts.model,\n tools: opts.tools,\n request: opts.request,\n response: opts.response,\n error: opts.error,\n };\n fs.appendFileSync(filePath, JSON.stringify(entry) + '\\n');\n }\n\n logChunk(requestId: string, chunk: any) {\n const filePath = this.getFilePath(requestId);\n const entry = {\n type: 'chunk',\n requestId,\n timestamp: new Date().toISOString(),\n chunk,\n };\n fs.appendFileSync(filePath, JSON.stringify(entry) + '\\n');\n }\n}\n","import fs from 'fs';\nimport path from 'pathe';\nimport { platform } from 'process';\nimport type { Context } from './context';\nimport { PluginHookType } from './plugin';\nimport { getLlmsRules } from './rules';\nimport { createLSTool } from '../tools/tools/ls';\nimport { getGitStatus, getLlmGitStatus } from '../utils/git';\nimport { isProjectDirectory } from '../utils/project';\n\nexport type LlmsContextCreateOpts = {\n context: Context;\n sessionId: string;\n userPrompt: string | null;\n additionalDirectories?: string[];\n};\n\nexport class LlmsContext {\n messages: string[];\n constructor(opts: { messages: string[] }) {\n this.messages = opts.messages;\n }\n\n static async create(opts: LlmsContextCreateOpts) {\n const gitStatus = await getGitStatus({ cwd: opts.context.cwd });\n\n let llmsContext: Record<string, string> = {};\n // 1. git status\n const llmsGitStatus = await getLlmGitStatus(gitStatus);\n if (llmsGitStatus) {\n llmsContext.gitStatus = llmsGitStatus;\n }\n // 2. directory structure\n const isProject = isProjectDirectory(opts.context.cwd);\n if (isProject) {\n const LSTool = createLSTool({\n cwd: opts.context.cwd,\n });\n const result = await LSTool.execute({ dir_path: '.' });\n if (result) {\n llmsContext.directoryStructure = `\n${result.returnDisplay}\n<directory_structure>\n${result.llmContent}\n</directory_structure>\n `.trim();\n }\n }\n // 3. rules\n const rules = getLlmsRules({\n cwd: opts.context.cwd,\n productName: opts.context.productName,\n globalConfigDir: opts.context.paths.globalConfigDir,\n });\n if (rules) {\n llmsContext.rules = rules.llmsDescription;\n }\n // 4. readme\n const readmePath = path.join(opts.context.cwd, 'README.md');\n if (fs.existsSync(readmePath)) {\n llmsContext.readme = fs.readFileSync(readmePath, 'utf-8');\n }\n\n llmsContext = await opts.context.apply({\n hook: 'context',\n args: [\n {\n sessionId: opts.sessionId,\n userPrompt: opts.userPrompt,\n },\n ],\n memo: llmsContext,\n type: PluginHookType.SeriesMerge,\n });\n const llmsContextStr = `\n# Context\nAs you answer the user's questions, you can use the following context:\n${Object.entries(llmsContext)\n // Support disabling default context\n .filter(([_, value]) => value)\n .map(([key, value]) => `<context name=\"${key}\">${value}</context>`)\n .join('\\n')}\n `.trim();\n\n let llmsEnv = {\n 'Working directory': opts.context.cwd,\n ...(opts.additionalDirectories &&\n opts.additionalDirectories.length > 0 && {\n 'Additional working directories':\n opts.additionalDirectories.join(', '),\n }),\n 'Is directory a git repo': gitStatus ? 'YES' : 'NO',\n Platform: platform,\n \"Today's date\": new Date().toLocaleDateString(),\n };\n llmsEnv = await opts.context.apply({\n hook: 'env',\n args: [\n {\n sessionId: opts.sessionId,\n userPrompt: opts.userPrompt,\n },\n ],\n memo: llmsEnv,\n type: PluginHookType.SeriesMerge,\n });\n const llmsEnvStr = `\n# Environment\nHere is useful information about the environment you are running in.\n${Object.entries(llmsEnv)\n .map(([key, value]) => `<env name=\"${key}\">${value}</env>`)\n .join('\\n')}\n `.trim();\n\n return new LlmsContext({ messages: [llmsContextStr, llmsEnvStr] });\n }\n}\n","import fs from 'fs';\nimport path from 'pathe';\n\nexport function getLlmsRules(opts: {\n cwd: string;\n productName: string;\n globalConfigDir: string;\n}) {\n const rules: string[] = [];\n const productName = opts.productName;\n\n const globalRuleNames = ['AGENTS.md', `${productName.toUpperCase()}.md`];\n const projectRuleNames = [\n 'AGENTS.md',\n 'CLAUDE.md',\n `${productName.toUpperCase()}.md`,\n ];\n\n // 1. project rules\n let currentDir = opts.cwd;\n while (currentDir !== path.parse(currentDir).root) {\n for (const ruleName of projectRuleNames) {\n const stylePath = path.join(currentDir, ruleName);\n if (fs.existsSync(stylePath)) {\n rules.push(fs.readFileSync(stylePath, 'utf-8'));\n }\n }\n currentDir = path.dirname(currentDir);\n }\n // 2. global rules\n for (const ruleName of globalRuleNames) {\n const globalStylePath = path.join(opts.globalConfigDir, ruleName);\n if (fs.existsSync(globalStylePath)) {\n rules.push(fs.readFileSync(globalStylePath, 'utf-8'));\n }\n }\n const globalClaudeRulePath = path.join(\n opts.globalConfigDir,\n '../.claude/CLAUDE.md',\n );\n if (fs.existsSync(globalClaudeRulePath)) {\n rules.push(fs.readFileSync(globalClaudeRulePath, 'utf-8'));\n }\n\n if (rules.length === 0) {\n return null;\n }\n const reversedRules = rules.reverse();\n return {\n rules: reversedRules.join('\\n\\n'),\n llmsDescription: `\n Codebase and user instructions are shown below. Be sure to adhere to these instructions. IMPORTANT: These instructions OVERRIDE any default behavior and you MUST follow them exactly as written\n\n ${reversedRules.join('\\n\\n')}`,\n };\n}\n","import { execFile } from 'child_process';\n\nconst MS_IN_SECOND = 1000;\nconst SECONDS_IN_MINUTE = 60;\n\n/**\n * execFile, but always resolves (never throws)\n */\nexport function execFileNoThrow(\n cwd: string,\n file: string,\n args: string[],\n abortSignal?: AbortSignal,\n timeout = 10 * SECONDS_IN_MINUTE * MS_IN_SECOND,\n preserveOutputOnError = true,\n): Promise<{ stdout: string; stderr: string; code: number }> {\n return new Promise((resolve) => {\n try {\n execFile(\n file,\n args,\n {\n maxBuffer: 1_000_000,\n signal: abortSignal,\n timeout,\n cwd,\n },\n (error, stdout, stderr) => {\n if (error) {\n if (preserveOutputOnError) {\n const errorCode = typeof error.code === 'number' ? error.code : 1;\n resolve({\n stdout: stdout || '',\n stderr: stderr || '',\n code: errorCode,\n });\n } else {\n resolve({ stdout: '', stderr: '', code: 1 });\n }\n } else {\n resolve({ stdout, stderr, code: 0 });\n }\n },\n );\n } catch (error) {\n resolve({ stdout: '', stderr: '', code: 1 });\n }\n });\n}\n","import { execFileNoThrow } from './execFileNoThrow';\n\n// ============================================================================\n// Internal Helpers (DRY)\n// ============================================================================\n\nasync function gitExec(\n cwd: string,\n args: string[],\n): Promise<{ code: number; stdout: string; stderr: string }> {\n return execFileNoThrow(cwd, 'git', args, undefined, undefined, false);\n}\n\nasync function gitCheck(cwd: string, args: string[]): Promise<boolean> {\n const { code } = await gitExec(cwd, args);\n return code === 0;\n}\n\nasync function gitOutput(cwd: string, args: string[]): Promise<string> {\n const { stdout } = await gitExec(cwd, args);\n return stdout.trim();\n}\n\n// ============================================================================\n// Validation Functions\n// ============================================================================\n\n/**\n * Check if git is installed and available in PATH\n */\nexport async function isGitInstalled(): Promise<boolean> {\n try {\n const { code } = await execFileNoThrow(\n process.cwd(),\n 'git',\n ['--version'],\n undefined,\n undefined,\n false,\n );\n return code === 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if the given directory is inside a git repository\n */\nexport async function isGitRepository(cwd: string): Promise<boolean> {\n return gitCheck(cwd, ['rev-parse', '--is-inside-work-tree']);\n}\n\n/**\n * Check if git user name and email are configured\n */\nexport async function isGitUserConfigured(\n cwd: string,\n): Promise<{ name: boolean; email: boolean }> {\n const [nameResult, emailResult] = await Promise.all([\n gitCheck(cwd, ['config', 'user.name']),\n gitCheck(cwd, ['config', 'user.email']),\n ]);\n return { name: nameResult, email: emailResult };\n}\n\n// ============================================================================\n// Query Functions\n// ============================================================================\n\n/**\n * Check if there are uncommitted changes (staged or unstaged)\n */\nexport async function hasUncommittedChanges(cwd: string): Promise<boolean> {\n const output = await gitOutput(cwd, ['status', '--porcelain']);\n return output.length > 0;\n}\n\n/**\n * Get list of unstaged files with their status\n * Returns files that have changes not yet staged (working tree changes)\n */\nexport async function getUnstagedFiles(\n cwd: string,\n): Promise<Array<{ status: string; file: string }>> {\n const { stdout } = await gitExec(cwd, ['status', '--porcelain']);\n const output = stdout.trimEnd();\n if (!output) return [];\n\n const files: Array<{ status: string; file: string }> = [];\n for (const line of output.split('\\n')) {\n if (!line) continue;\n const indexStatus = line[0];\n const workTreeStatus = line[1];\n const file = line.substring(3);\n if (indexStatus === '?' && workTreeStatus === '?') {\n files.push({ status: '?', file });\n } else if (workTreeStatus !== ' ' && workTreeStatus !== undefined) {\n files.push({ status: workTreeStatus, file });\n }\n }\n return files;\n}\n\n/**\n * Check if any remote is configured\n */\nexport async function hasRemote(cwd: string): Promise<boolean> {\n const output = await gitOutput(cwd, ['remote']);\n return output.length > 0;\n}\n\n/**\n * Check if origin remote is configured\n */\nexport async function hasOriginRemote(cwd: string): Promise<boolean> {\n return gitCheck(cwd, ['remote', 'get-url', 'origin']);\n}\n\n/**\n * Check if a branch exists\n */\nexport async function branchExists(\n cwd: string,\n branchName: string,\n): Promise<boolean> {\n return gitCheck(cwd, ['rev-parse', '--verify', branchName]);\n}\n\n/**\n * Get recent commit messages\n */\nexport async function getRecentCommitMessages(\n cwd: string,\n count = 10,\n): Promise<string> {\n return gitOutput(cwd, ['log', '-n', String(count), '--pretty=format:%s']);\n}\n\n// ============================================================================\n// Action Functions\n// ============================================================================\n\n/**\n * Stage all changes\n */\nexport async function stageAll(cwd: string): Promise<void> {\n const { code, stderr } = await gitExec(cwd, ['add', '.']);\n if (code !== 0) {\n const errorMessage = stderr || 'Unknown error';\n if (errorMessage.includes('fatal: pathspec')) {\n throw new Error('Failed to stage files: Invalid file path or pattern');\n }\n throw new Error(`Failed to stage files: ${errorMessage}`);\n }\n}\n\n/**\n * Commit staged changes with a message\n * @param cwd - Working directory\n * @param message - Commit message\n * @param skipHooks - Skip pre-commit hooks\n * @param onOutput - Optional callback for streaming output\n */\nexport async function gitCommit(\n cwd: string,\n message: string,\n skipHooks = false,\n onOutput?: (line: string, stream: 'stdout' | 'stderr') => void,\n): Promise<void> {\n const args = ['commit', '-m', message];\n if (skipHooks) {\n args.push('--no-verify');\n }\n\n // If no output callback, use the simple exec approach\n if (!onOutput) {\n const { code, stderr } = await gitExec(cwd, args);\n if (code !== 0) {\n throw new Error(stderr || 'Commit failed');\n }\n return;\n }\n\n // Use spawn for streaming output\n const { spawn } = await import('child_process');\n\n return new Promise((resolve, reject) => {\n const gitProcess = spawn('git', args, { cwd });\n let stderr = '';\n\n const processOutput = (\n data: Buffer,\n stream: 'stdout' | 'stderr',\n buffer: string,\n ): string => {\n const text = buffer + data.toString();\n const lines = text.split('\\n');\n // Keep the last incomplete line in buffer\n const incomplete = lines.pop() || '';\n for (const line of lines) {\n if (line.trim()) {\n onOutput(line, stream);\n }\n }\n return incomplete;\n };\n\n let stdoutBuffer = '';\n let stderrBuffer = '';\n\n gitProcess.stdout?.on('data', (data: Buffer) => {\n stdoutBuffer = processOutput(data, 'stdout', stdoutBuffer);\n });\n\n gitProcess.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n stderrBuffer = processOutput(data, 'stderr', stderrBuffer);\n });\n\n gitProcess.on('error', (error) => {\n reject(error);\n });\n\n gitProcess.on('close', (code) => {\n // Flush any remaining buffered content\n if (stdoutBuffer.trim()) {\n onOutput(stdoutBuffer, 'stdout');\n }\n if (stderrBuffer.trim()) {\n onOutput(stderrBuffer, 'stderr');\n }\n\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(stderr || 'Commit failed'));\n }\n });\n });\n}\n\n/**\n * Push changes to remote\n * @param cwd - Working directory\n * @param onOutput - Optional callback for streaming output\n */\nexport async function gitPush(\n cwd: string,\n onOutput?: (line: string, stream: 'stdout' | 'stderr') => void,\n): Promise<void> {\n // If no output callback, use the simple exec approach\n if (!onOutput) {\n const { code, stderr } = await gitExec(cwd, [\n 'push',\n '-u',\n 'origin',\n 'HEAD',\n ]);\n if (code !== 0) {\n throw new Error(stderr || 'Push failed');\n }\n return;\n }\n\n // Use spawn for streaming output with progress\n const { spawn } = await import('child_process');\n\n return new Promise((resolve, reject) => {\n // Use --progress to ensure git outputs progress info\n // Use -u origin HEAD to auto-set upstream for new branches\n const gitProcess = spawn(\n 'git',\n ['push', '-u', 'origin', 'HEAD', '--progress'],\n { cwd },\n );\n let stderr = '';\n\n // Process output, handling \\r (carriage return) for in-place progress updates\n // Only output complete lines (ending with \\n), taking the last \\r segment\n const processOutput = (\n data: Buffer,\n stream: 'stdout' | 'stderr',\n buffer: string,\n ): string => {\n const text = buffer + data.toString();\n // Split by newlines only\n const lines = text.split('\\n');\n // Keep the last incomplete line in buffer\n const incomplete = lines.pop() || '';\n for (const line of lines) {\n // For lines with \\r, take only the last segment (final progress state)\n const segments = line.split('\\r');\n const finalSegment = segments[segments.length - 1];\n if (finalSegment.trim()) {\n onOutput(finalSegment, stream);\n }\n }\n return incomplete;\n };\n\n let stdoutBuffer = '';\n let stderrBuffer = '';\n\n gitProcess.stdout?.on('data', (data: Buffer) => {\n stdoutBuffer = processOutput(data, 'stdout', stdoutBuffer);\n });\n\n gitProcess.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n stderrBuffer = processOutput(data, 'stderr', stderrBuffer);\n });\n\n gitProcess.on('error', (error) => {\n reject(error);\n });\n\n gitProcess.on('close', (code) => {\n // Flush any remaining buffered content, handling \\r for progress updates\n if (stdoutBuffer.trim()) {\n const segments = stdoutBuffer.split('\\r');\n const finalSegment = segments[segments.length - 1];\n if (finalSegment.trim()) {\n onOutput(finalSegment, 'stdout');\n }\n }\n if (stderrBuffer.trim()) {\n const segments = stderrBuffer.split('\\r');\n const finalSegment = segments[segments.length - 1];\n if (finalSegment.trim()) {\n onOutput(finalSegment, 'stderr');\n }\n }\n\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(stderr || 'Push failed'));\n }\n });\n });\n}\n\n/**\n * Create and checkout a new branch\n */\nexport async function createAndCheckoutBranch(\n cwd: string,\n branchName: string,\n): Promise<void> {\n const { code, stderr } = await gitExec(cwd, ['checkout', '-b', branchName]);\n if (code !== 0) {\n throw new Error(stderr || 'Failed to create branch');\n }\n}\n\n// ============================================================================\n// Composite Functions\n// ============================================================================\n\nexport async function getGitStatus(opts: { cwd: string }) {\n const { cwd } = opts;\n if (!(await isGitRepository(cwd))) {\n return null;\n }\n\n const [branch, mainBranch, status, log, author] = await Promise.all([\n gitOutput(cwd, ['branch', '--show-current']),\n gitOutput(cwd, ['rev-parse', '--abbrev-ref', 'origin/HEAD']).then((s) =>\n s.replace('origin/', ''),\n ),\n gitOutput(cwd, ['status', '--short']),\n gitOutput(cwd, ['log', '--oneline', '-n', '5']),\n gitOutput(cwd, ['config', 'user.email']),\n ]);\n\n const authorLog = await gitOutput(cwd, [\n 'log',\n '--author',\n author,\n '--oneline',\n '-n',\n '5',\n ]);\n\n return {\n branch,\n mainBranch,\n status,\n log,\n author,\n authorLog,\n };\n}\n\nexport async function getLlmGitStatus(\n status: Awaited<ReturnType<typeof getGitStatus>>,\n) {\n if (!status) {\n return null;\n }\n return `\nThis is the git status at the start of the conversation. Note that this status is a snapshot in time, and will not update during the conversation.\nCurrent branch: ${status.branch}\n\nMain branch (you will usually use this for PRs): ${status.mainBranch}\n\nStatus:\n${status.status || '(clean)'}\n\nRecent commits:\n${status.log}\n\nYour recent commits:\n${status.authorLog || '(no recent commits)'}\n `.trim();\n}\n\n/**\n * Get remote origin URL\n */\nexport async function getGitRemoteUrl(cwd: string): Promise<string | null> {\n try {\n const { stdout } = await execFileNoThrow(\n cwd,\n 'git',\n ['config', '--get', 'remote.origin.url'],\n undefined,\n undefined,\n false,\n );\n return stdout.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get default branch from remote\n */\nexport async function getDefaultBranch(cwd: string): Promise<string | null> {\n try {\n const { stdout } = await execFileNoThrow(\n cwd,\n 'git',\n ['rev-parse', '--abbrev-ref', 'origin/HEAD'],\n undefined,\n undefined,\n false,\n );\n return stdout.replace('origin/', '').trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check sync status with remote\n */\nexport async function getGitSyncStatus(\n cwd: string,\n): Promise<'synced' | 'ahead' | 'behind' | 'diverged' | 'unknown'> {\n try {\n // Fetch remote to get latest info\n await execFileNoThrow(\n cwd,\n 'git',\n ['fetch', 'origin', '--quiet'],\n undefined,\n undefined,\n false,\n );\n\n // Get current branch\n const { stdout: branch } = await execFileNoThrow(\n cwd,\n 'git',\n ['rev-parse', '--abbrev-ref', 'HEAD'],\n undefined,\n undefined,\n false,\n );\n const currentBranch = branch.trim();\n\n // Check if remote tracking branch exists\n const { code: trackingExists } = await execFileNoThrow(\n cwd,\n 'git',\n ['rev-parse', '--verify', `origin/${currentBranch}`],\n undefined,\n undefined,\n false,\n );\n\n if (trackingExists !== 0) {\n return 'unknown';\n }\n\n // Get ahead/behind counts\n const { stdout: counts } = await execFileNoThrow(\n cwd,\n 'git',\n ['rev-list', '--left-right', '--count', `origin/${currentBranch}...HEAD`],\n undefined,\n undefined,\n false,\n );\n\n const [behind, ahead] = counts.trim().split('\\t').map(Number);\n\n if (ahead === 0 && behind === 0) {\n return 'synced';\n }\n if (ahead > 0 && behind === 0) {\n return 'ahead';\n }\n if (ahead === 0 && behind > 0) {\n return 'behind';\n }\n return 'diverged';\n } catch {\n return 'unknown';\n }\n}\n\n/**\n * Get current commit hash\n */\nexport async function getCurrentCommit(cwd: string): Promise<string> {\n try {\n const { stdout } = await execFileNoThrow(\n cwd,\n 'git',\n ['rev-parse', 'HEAD'],\n undefined,\n undefined,\n false,\n );\n return stdout.trim();\n } catch {\n return '';\n }\n}\n\n/**\n * Get list of pending changes\n */\nexport async function getPendingChanges(cwd: string): Promise<string[]> {\n try {\n const { stdout } = await execFileNoThrow(\n cwd,\n 'git',\n ['status', '--porcelain'],\n undefined,\n undefined,\n false,\n );\n if (!stdout.trim()) {\n return [];\n }\n return stdout\n .trim()\n .split('\\n')\n .map((line) => line.substring(3).trim());\n } catch {\n return [];\n }\n}\n\n/**\n * Get staged file list with status\n */\nexport async function getStagedFileList(cwd: string): Promise<string> {\n return gitOutput(cwd, ['diff', '--cached', '--name-status']);\n}\n\n/**\n * Git URL validation patterns\n */\nconst GIT_HTTPS_PATTERN =\n /^https?:\\/\\/(?:[a-zA-Z0-9_.~-]+@)?[a-zA-Z0-9_.~-]+(?:\\.[a-zA-Z0-9_.~-]+)*(?::\\d+)?\\/[a-zA-Z0-9_.~/-]+(\\.git)?$/;\nconst GIT_SSH_PATTERN =\n /^git@[a-zA-Z0-9_.~-]+(?:\\.[a-zA-Z0-9_.~-]+)*:[a-zA-Z0-9_.~/-]+(\\.git)?$/;\n\n/**\n * Validate git repository URL format\n */\nexport function validateGitUrl(url: string): boolean {\n return GIT_HTTPS_PATTERN.test(url) || GIT_SSH_PATTERN.test(url);\n}\n\n/**\n * Sanitize git URL to prevent command injection\n */\nexport function sanitizeGitUrl(url: string): string {\n return url\n .split(/[;&|`$()]/)[0] // Remove shell special characters\n .trim();\n}\n\n/**\n * Validate destination path security\n */\nexport function validateDestinationPath(destination: string): {\n valid: boolean;\n error?: string;\n} {\n const { resolve } = require('pathe');\n const normalizedDest = resolve(destination);\n const dangerousPaths = [\n '/etc',\n '/usr',\n '/bin',\n '/sbin',\n '/var',\n '/System',\n 'C:\\\\Windows',\n 'C:\\\\Program Files',\n ];\n\n if (dangerousPaths.some((p) => normalizedDest.startsWith(p))) {\n return {\n valid: false,\n error: 'Cannot clone to system directories',\n };\n }\n\n return { valid: true };\n}\n\n/**\n * Extract repository name from git URL\n */\nexport function extractRepoName(url: string): string {\n const repoNameMatch = url.match(/\\/([^/]+?)(\\.git)?$/);\n return repoNameMatch ? repoNameMatch[1] : `repo-${Date.now()}`;\n}\n\n/**\n * Parse git clone progress output\n */\nexport interface GitCloneProgress {\n percent: number;\n message: string;\n}\n\nexport class GitCloneProgressParser {\n private currentStage = '';\n private stageProgress = { receiving: 0, resolving: 0, checking: 0 };\n private lastOverallPercent = 0;\n\n parse(output: string): GitCloneProgress | null {\n // Support both English and Chinese Git output\n const progressMatch = output.match(/(\\d+)%/);\n if (!progressMatch) {\n return null;\n }\n\n const percent = Number.parseInt(progressMatch[1], 10);\n\n // Detect current stage and update stage progress\n if (output.includes('Receiving objects') || output.includes('接收对象中')) {\n this.currentStage = 'receiving';\n this.stageProgress.receiving = percent;\n } else if (\n output.includes('Resolving deltas') ||\n output.includes('处理 delta 中')\n ) {\n // Mark receiving as complete when resolving starts\n if (this.stageProgress.receiving === 0) {\n this.stageProgress.receiving = 100;\n }\n\n // Reset lastOverallPercent when transitioning to new stage\n if (this.currentStage !== 'resolving') {\n this.lastOverallPercent = 0;\n }\n\n this.currentStage = 'resolving';\n this.stageProgress.resolving = percent;\n } else if (\n output.includes('Checking out files') ||\n output.includes('检出文件中')\n ) {\n // Mark previous stages as complete\n if (this.stageProgress.receiving === 0) {\n this.stageProgress.receiving = 100;\n }\n if (this.stageProgress.resolving === 0) {\n this.stageProgress.resolving = 100;\n }\n\n // Reset lastOverallPercent when transitioning to new stage\n if (this.currentStage !== 'checking') {\n this.lastOverallPercent = 0;\n }\n\n this.currentStage = 'checking';\n this.stageProgress.checking = percent;\n } else {\n // Unknown stage with percentage - skip to avoid noise\n return null;\n }\n\n // Calculate overall progress (0-100%)\n let overallPercent = 0;\n\n // Determine active stages\n const hasResolving =\n this.stageProgress.resolving > 0 || this.currentStage === 'resolving';\n const hasChecking =\n this.stageProgress.checking > 0 || this.currentStage === 'checking';\n\n if (hasResolving && hasChecking) {\n // All three stages: Receiving(0-70%), Resolving(70-90%), Checking(90-100%)\n overallPercent =\n Math.floor((this.stageProgress.receiving * 70) / 100) +\n Math.floor((this.stageProgress.resolving * 20) / 100) +\n Math.floor((this.stageProgress.checking * 10) / 100);\n } else if (hasResolving) {\n // Two stages: Receiving(0-80%), Resolving(80-100%)\n overallPercent =\n Math.floor((this.stageProgress.receiving * 80) / 100) +\n Math.floor((this.stageProgress.resolving * 20) / 100);\n } else {\n // Single stage (small repos): Receiving(0-100%)\n overallPercent = this.stageProgress.receiving;\n }\n\n // Ensure progress only increases (monotonic progress)\n overallPercent = Math.max(overallPercent, this.lastOverallPercent);\n this.lastOverallPercent = overallPercent;\n\n return {\n percent: overallPercent,\n message: output.trim(),\n };\n }\n}\n\n/**\n * Clone repository options\n */\nexport interface CloneRepositoryOptions {\n url: string;\n destination: string;\n onProgress?: (progress: GitCloneProgress) => void;\n signal?: AbortSignal;\n timeoutMinutes?: number;\n}\n\n/**\n * Clone repository result\n */\nexport interface CloneRepositoryResult {\n success: boolean;\n clonePath?: string;\n repoName?: string;\n error?: string;\n errorCode?:\n | 'CANCELLED'\n | 'SSH_AUTH_FAILED'\n | 'AUTH_REQUIRED'\n | 'NETWORK_ERROR'\n | 'REPO_NOT_FOUND'\n | 'TIMEOUT'\n | 'GIT_NOT_INSTALLED'\n | 'INVALID_URL'\n | 'DIR_EXISTS'\n | 'UNKNOWN';\n needsCredentials?: boolean;\n}\n\n/**\n * Clone a git repository\n */\nexport async function cloneRepository(\n options: CloneRepositoryOptions,\n): Promise<CloneRepositoryResult> {\n const { promisify } = await import('util');\n const { spawn, execFile } = await import('child_process');\n const { existsSync, mkdirSync, rmSync } = await import('fs');\n const { join, resolve } = await import('pathe');\n\n let clonePath = '';\n\n try {\n // Validate inputs\n if (!options.url || !options.destination) {\n return {\n success: false,\n error: 'Git URL and destination are required',\n };\n }\n\n // Sanitize Git URL\n const sanitizedUrl = sanitizeGitUrl(options.url);\n\n // Check if Git is available\n try {\n const execFilePromise = promisify(execFile);\n await execFilePromise('git', ['--version']);\n } catch (_gitError) {\n return {\n success: false,\n error:\n 'Git is not installed or not available in PATH. Please install Git and try again.',\n errorCode: 'GIT_NOT_INSTALLED',\n };\n }\n\n // Validate URL format\n if (!validateGitUrl(sanitizedUrl)) {\n return {\n success: false,\n error:\n 'Invalid Git repository URL format. Please use HTTPS or SSH format.',\n errorCode: 'INVALID_URL',\n };\n }\n\n // Ensure destination directory exists\n if (!existsSync(options.destination)) {\n mkdirSync(options.destination, { recursive: true });\n }\n\n // Validate destination path security\n const destValidation = validateDestinationPath(options.destination);\n if (!destValidation.valid) {\n return {\n success: false,\n error: destValidation.error,\n };\n }\n\n // Extract repo name and build clone path\n const repoName = extractRepoName(sanitizedUrl);\n clonePath = join(options.destination, repoName);\n\n // Check if directory already exists\n if (existsSync(clonePath)) {\n return {\n success: false,\n error: `Directory '${repoName}' already exists at destination`,\n errorCode: 'DIR_EXISTS',\n };\n }\n\n // Clone the repository\n let gitProcess: ReturnType<typeof spawn> | null = null;\n let isCancelled = false;\n const progressParser = new GitCloneProgressParser();\n\n const clonePromise = new Promise<void>((resolvePromise, reject) => {\n const env: Record<string, string> = {\n ...process.env,\n GIT_SSH_COMMAND: 'ssh -o StrictHostKeyChecking=accept-new',\n };\n\n gitProcess = spawn(\n 'git',\n ['clone', '--progress', sanitizedUrl, clonePath],\n { env },\n );\n let stderr = '';\n\n // Set up abort handling\n if (options.signal) {\n const abortHandler = async () => {\n isCancelled = true;\n if (gitProcess && !gitProcess.killed) {\n // Clean up event listeners first\n gitProcess.stdout?.removeAllListeners();\n gitProcess.stderr?.removeAllListeners();\n gitProcess.removeAllListeners();\n\n // Try graceful shutdown first (SIGTERM)\n gitProcess.kill('SIGTERM');\n\n // Wait for process to exit, force kill if timeout\n await new Promise<void>((resolve) => {\n const forceKillTimeout = setTimeout(() => {\n if (gitProcess && !gitProcess.killed) {\n gitProcess.kill('SIGKILL');\n }\n resolve();\n }, 1000);\n\n // Clear timeout if process exits gracefully\n if (gitProcess) {\n gitProcess.once('exit', () => {\n clearTimeout(forceKillTimeout);\n resolve();\n });\n } else {\n clearTimeout(forceKillTimeout);\n resolve();\n }\n });\n }\n reject(new Error('Clone operation cancelled by user'));\n };\n\n options.signal.addEventListener('abort', abortHandler);\n }\n\n // Parse progress from stderr\n gitProcess.stderr?.on('data', (data: Buffer) => {\n const output = data.toString();\n stderr += output;\n\n if (options.onProgress) {\n const progress = progressParser.parse(output);\n if (progress) {\n options.onProgress(progress);\n }\n }\n });\n\n gitProcess.on('error', (error) => {\n reject(error);\n });\n\n gitProcess.on('close', (code) => {\n // Don't reject again if already cancelled\n if (isCancelled) {\n return;\n }\n\n if (code === 0) {\n // Send 100% progress on completion\n if (options.onProgress) {\n options.onProgress({\n percent: 100,\n message: 'Clone completed',\n });\n }\n resolvePromise();\n } else {\n reject(new Error(stderr || `Git clone exited with code ${code}`));\n }\n });\n });\n\n // Add timeout\n const timeoutMinutes = options.timeoutMinutes || 30;\n const CLONE_TIMEOUT = timeoutMinutes * 60 * 1000;\n let timeoutId: NodeJS.Timeout | null = null;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(async () => {\n if (gitProcess) {\n // Clean up event listeners first\n gitProcess.stdout?.removeAllListeners();\n gitProcess.stderr?.removeAllListeners();\n gitProcess.removeAllListeners();\n\n // Try graceful shutdown first (SIGTERM)\n gitProcess.kill('SIGTERM');\n\n // Wait for process to exit, force kill if timeout\n await new Promise<void>((resolve) => {\n const forceKillTimeout = setTimeout(() => {\n if (gitProcess && !gitProcess.killed) {\n gitProcess.kill('SIGKILL');\n }\n resolve();\n }, 1000);\n\n // Clear timeout if process exits gracefully\n if (gitProcess) {\n gitProcess.once('exit', () => {\n clearTimeout(forceKillTimeout);\n resolve();\n });\n } else {\n clearTimeout(forceKillTimeout);\n resolve();\n }\n });\n }\n reject(\n new Error(\n 'Clone operation timed out. The repository might be too large or the connection is slow.',\n ),\n );\n }, CLONE_TIMEOUT);\n });\n\n try {\n await Promise.race([clonePromise, timeoutPromise]);\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n\n return {\n success: true,\n clonePath,\n repoName,\n };\n } catch (error: any) {\n // Clean up incomplete clone directory\n if (clonePath && existsSync(clonePath)) {\n try {\n rmSync(clonePath, { recursive: true, force: true });\n } catch (_cleanupError) {\n // Ignore cleanup errors\n }\n }\n\n // Handle common git clone errors\n const errorMessage = error.message || 'Unknown error';\n\n // SSH-related errors\n if (\n errorMessage.includes('Host key verification failed') ||\n errorMessage.includes('Permission denied (publickey)')\n ) {\n return {\n success: false,\n error:\n 'SSH authentication failed. Please ensure your SSH keys are properly configured.',\n errorCode: 'SSH_AUTH_FAILED',\n };\n }\n\n // HTTPS authentication errors\n if (\n errorMessage.includes('Authentication failed') ||\n errorMessage.includes('could not read Username') ||\n errorMessage.includes('could not read Password')\n ) {\n return {\n success: false,\n error: 'Authentication required. Please provide username and password.',\n errorCode: 'AUTH_REQUIRED',\n needsCredentials: true,\n };\n }\n\n if (errorMessage.includes('Could not resolve hostname')) {\n return {\n success: false,\n error:\n 'Could not resolve hostname. Please check your internet connection and the repository URL.',\n errorCode: 'NETWORK_ERROR',\n };\n }\n\n if (errorMessage.includes('not found') || errorMessage.includes('404')) {\n return {\n success: false,\n error: 'Repository not found or access denied',\n errorCode: 'REPO_NOT_FOUND',\n };\n }\n\n // Timeout errors\n if (errorMessage.includes('timed out')) {\n return {\n success: false,\n error:\n 'Clone operation timed out. The repository might be too large or the connection is slow.',\n errorCode: 'TIMEOUT',\n };\n }\n\n // User cancelled\n if (errorMessage.includes('cancelled by user')) {\n return {\n success: false,\n error: 'Clone operation cancelled by user',\n errorCode: 'CANCELLED',\n };\n }\n\n return {\n success: false,\n error: 'Failed to clone repository. Please check the URL and try again.',\n errorCode: 'UNKNOWN',\n };\n }\n}\n\n/**\n * Get the staged diff while handling large files\n * - Excludes common lockfiles and large file types\n * - Limits diff size to prevent context overflow\n */\nexport async function getStagedDiff(cwd: string): Promise<string> {\n // Exclude lockfiles and common large file types\n const excludePatterns = [\n ':!pnpm-lock.yaml',\n ':!package-lock.json',\n ':!yarn.lock',\n ':!*.min.js',\n ':!*.bundle.js',\n ':!dist/**',\n ':!build/**',\n ':!*.gz',\n ':!*.zip',\n ':!*.tar',\n ':!*.tgz',\n ':!*.woff',\n ':!*.woff2',\n ':!*.ttf',\n ':!*.png',\n ':!*.jpg',\n ':!*.jpeg',\n ':!*.gif',\n ':!*.ico',\n ':!*.svg',\n ':!*.pdf',\n ];\n\n const args = ['diff', '--cached', '--', ...excludePatterns];\n\n const { code, stdout: diff, stderr } = await gitExec(cwd, args);\n\n if (code !== 0) {\n const errorMessage = stderr || 'Unknown error';\n\n if (errorMessage.includes('bad revision')) {\n throw new Error(\n 'Failed to get staged diff: Invalid Git revision or corrupt repository',\n );\n }\n\n if (errorMessage.includes('fatal: not a git repository')) {\n throw new Error('Not a Git repository');\n }\n\n throw new Error(`Failed to get staged diff: ${errorMessage}`);\n }\n\n // Limit diff size - 100KB is a reasonable limit for most LLM contexts\n const MAX_DIFF_SIZE = 100 * 1024; // 100KB\n\n if (diff.length > MAX_DIFF_SIZE) {\n // If diff is too large, truncate and add a note\n const truncatedDiff = diff.substring(0, MAX_DIFF_SIZE);\n return (\n truncatedDiff +\n '\\n\\n[Diff truncated due to size. Total diff size: ' +\n (diff.length / 1024).toFixed(2) +\n 'KB]'\n );\n }\n return diff;\n}\n","import fs from 'fs';\nimport { homedir } from 'os';\nimport path from 'pathe';\n\nconst PROJECT_MARKERS = [\n 'package.json',\n 'Cargo.toml',\n 'pyproject.toml',\n 'go.mod',\n 'composer.json',\n 'pom.xml',\n 'build.gradle',\n 'requirements.txt',\n 'Gemfile',\n 'mix.exs',\n 'deno.json',\n 'deno.jsonc',\n];\n\nexport function isProjectDirectory(cwd: string): boolean {\n const normalizedCwd = path.resolve(cwd);\n const homeDir = path.resolve(homedir());\n\n if (normalizedCwd === homeDir) {\n return false;\n }\n\n return PROJECT_MARKERS.some((marker) => {\n const markerPath = path.join(normalizedCwd, marker);\n return fs.existsSync(markerPath);\n });\n}\n","import type { LoopResult } from '../core/loop';\nimport type { SDKResultMessage, SDKSystemMessage } from '../core/message';\nimport type { ModelInfo } from '../core/model';\nimport type { Tool } from '../tools/tool';\n\ntype Format = 'text' | 'stream-json' | 'json';\n\ntype OutputFormatOpts = {\n format: Format;\n quiet: boolean;\n};\n\nexport class OutputFormat {\n format: Format;\n quiet: boolean;\n dataArr: any[];\n constructor(opts: OutputFormatOpts) {\n this.format = opts.format;\n this.quiet = opts.quiet;\n this.dataArr = [];\n }\n onInit(opts: {\n text: string;\n sessionId: string;\n cwd: string;\n tools: Tool[];\n model: ModelInfo;\n }) {\n if (!this.quiet) {\n return;\n }\n const model = `${opts.model.provider.id}/${opts.model.model.id}`;\n const data: SDKSystemMessage = {\n type: 'system',\n subtype: 'init',\n sessionId: opts.sessionId,\n model,\n cwd: opts.cwd,\n tools: opts.tools.map((tool) => tool.name),\n };\n if (this.format === 'stream-json') {\n console.log(JSON.stringify(data));\n } else if (this.format === 'json') {\n this.dataArr.push(data);\n }\n }\n onMessage(opts: { message: any }) {\n if (!this.quiet) {\n return;\n }\n const data = { ...opts.message };\n if (this.format === 'stream-json') {\n console.log(JSON.stringify(data));\n } else if (this.format === 'json') {\n this.dataArr.push(data);\n }\n }\n onEnd(opts: { result: LoopResult; sessionId: string }) {\n if (!this.quiet) {\n return;\n }\n const isError = !opts.result.success;\n const subtype = isError ? 'error' : 'success';\n const data: SDKResultMessage = {\n type: 'result',\n subtype,\n isError,\n content: opts.result.success\n ? opts.result.data.text\n : opts.result.error.message,\n sessionId: opts.sessionId,\n ...(isError ? { __result: opts.result } : {}),\n };\n if (opts.result.success) {\n data.usage = {\n input_tokens: opts.result.data.usage.promptTokens,\n output_tokens: opts.result.data.usage.completionTokens,\n };\n }\n if (this.format === 'stream-json') {\n console.log(JSON.stringify(data));\n } else if (this.format === 'json') {\n this.dataArr.push(data);\n console.log(JSON.stringify(this.dataArr));\n } else if (this.format === 'text') {\n console.log(\n opts.result.success\n ? opts.result.data?.text || ''\n : opts.result.error.message,\n );\n }\n }\n}\n","import assert from 'assert';\nimport fs from 'fs';\nimport { glob } from 'glob';\nimport path from 'pathe';\nimport type { Context } from '../core/context';\nimport {\n defaultOutputStyle,\n getBuiltinOutputStyles,\n} from './output-style/builtin';\nimport type { Paths } from './paths';\nimport { PluginHookType } from '../core/plugin';\nimport { safeFrontMatter } from '../utils/safeFrontMatter';\nimport { kebabToTitleCase } from '../utils/string';\n\nexport type OutputStyleOpts = {\n name: string;\n description: string;\n isCodingRelated: boolean;\n prompt: string;\n};\n\nexport class OutputStyle {\n name: string;\n description: string;\n isCodingRelated: boolean;\n prompt: string;\n\n constructor(opts: OutputStyleOpts) {\n this.name = opts.name;\n this.description = opts.description;\n this.isCodingRelated = opts.isCodingRelated;\n this.prompt = opts.prompt;\n }\n\n isDefault(): boolean {\n return this.name === 'Default';\n }\n}\n\nexport type OutputStyleManagerOpts = {\n paths: Paths;\n outputStyles: OutputStyle[];\n};\n\nexport class OutputStyleManager {\n outputStyles: OutputStyle[] = [];\n constructor(opts: OutputStyleManagerOpts) {\n this.outputStyles = [...this.load(opts.paths), ...opts.outputStyles];\n }\n\n static async create(context: Context) {\n const outputStyles = await context.apply({\n hook: 'outputStyle',\n args: [],\n memo: [],\n type: PluginHookType.SeriesMerge,\n });\n return new OutputStyleManager({\n paths: context.paths,\n outputStyles,\n });\n }\n\n load(paths: Paths): OutputStyle[] {\n const builtin = getBuiltinOutputStyles().map((item) => {\n return new OutputStyle({\n name: item.name,\n description: item.description,\n isCodingRelated: item.isCodingRelated,\n prompt: item.prompt,\n });\n });\n const global = this.loadGlobal(\n path.join(paths.globalConfigDir, 'output-styles'),\n );\n const project = this.loadProject(\n path.join(paths.projectConfigDir, 'output-styles'),\n );\n return [...builtin, ...global, ...project];\n }\n\n loadGlobal(globalConfigDir: string): OutputStyle[] {\n return loadPolishedMarkdownFiles(globalConfigDir).map((file) => {\n return new OutputStyle({\n name: file.name,\n description: `${file.description} (user)`,\n isCodingRelated: !!file.attributes.isCodingRelated,\n prompt: file.body,\n });\n });\n }\n\n loadProject(projectConfigDir: string): OutputStyle[] {\n return loadPolishedMarkdownFiles(projectConfigDir).map((file) => {\n return new OutputStyle({\n name: file.name,\n description: `${file.description} (project)`,\n isCodingRelated: !!file.attributes.isCodingRelated,\n prompt: file.body,\n });\n });\n }\n\n // name support\n // 1) name of builtin and plugin extended output styles\n // 2) path to a file which defines an output style with markdown with frontmatter\n // 3) url to a file which defines an output style with markdown with frontmatter (TODO: support)\n getOutputStyle(name: string | undefined, cwd: string): OutputStyle {\n const defaultOutputStyle = this.getDefaultOutputStyle();\n if (!name) {\n return defaultOutputStyle;\n }\n // Check if name is a file path\n if (path.isAbsolute(name) || name.startsWith('.')) {\n if (!name.endsWith('.md')) {\n throw new Error('Output style file must be a .md file');\n }\n let filePath = name;\n if (!path.isAbsolute(name)) {\n filePath = path.resolve(cwd, name);\n // Validate against path traversal attacks\n if (!filePath.startsWith(path.resolve(cwd))) {\n throw new Error('Path traversal not allowed');\n }\n }\n const file = loadPolishedMarkdownFile(filePath);\n return new OutputStyle({\n name: file.name,\n description: file.description,\n isCodingRelated: !!file.attributes.isCodingRelated,\n prompt: file.body,\n });\n } else if (name.startsWith('{') && name.endsWith('}')) {\n let json = null;\n try {\n json = JSON.parse(name);\n } catch (error) {\n throw new Error(\n `Invalid JSON output style: ${error instanceof Error ? error.message : String(error)}, original: ${name}`,\n );\n }\n assert(json.prompt, 'prompt is required');\n return new OutputStyle({\n name: json.name || 'Custom',\n description: json.description || 'Custom',\n isCodingRelated: json.isCodingRelated,\n prompt: json.prompt,\n });\n } else if (name) {\n const outputStyle = this.outputStyles.find(\n (style) => style.name === name,\n );\n assert(outputStyle, `Output style ${name} not found`);\n return outputStyle;\n } else {\n return defaultOutputStyle;\n }\n }\n\n getDefaultOutputStyle(): OutputStyle {\n return new OutputStyle({\n name: defaultOutputStyle.name,\n description: defaultOutputStyle.description,\n isCodingRelated: defaultOutputStyle.isCodingRelated,\n prompt: defaultOutputStyle.prompt,\n });\n }\n}\n\ntype MarkdownFile = {\n path: string;\n attributes: Record<string, string>;\n body: string;\n};\n\nexport type NormalizedMarkdownFile = MarkdownFile & {\n description: string;\n name: string;\n relativePath: string;\n};\n\nexport function loadPolishedMarkdownFiles(\n dir: string,\n): NormalizedMarkdownFile[] {\n if (!fs.existsSync(dir)) {\n return [];\n }\n const files = glob.sync('**/*.md', {\n cwd: dir,\n follow: true,\n });\n return files.map((relativePath) => {\n const absPath = path.join(dir, relativePath);\n return loadPolishedMarkdownFile(absPath, dir);\n });\n}\n\nexport function loadMarkdownFile(filePath: string): MarkdownFile {\n const content = fs.readFileSync(filePath, 'utf-8');\n const { attributes, body } = safeFrontMatter<Record<string, string>>(\n content,\n filePath,\n );\n return {\n path: filePath,\n attributes,\n body,\n };\n}\n\nfunction loadPolishedMarkdownFile(\n filePath: string,\n dir?: string,\n): NormalizedMarkdownFile {\n if (!fs.existsSync(filePath)) {\n throw new Error(`Output style file not found: ${filePath}`);\n }\n\n let name = path.basename(filePath, '.md');\n const file = loadMarkdownFile(filePath);\n if (dir) {\n const relativePath = path.relative(dir, filePath);\n // Extract command name from relative path (remove .md extension and convert / to :)\n name = relativePath.replace(/\\.md$/, '').replace(/[/\\\\]/g, ':');\n }\n let description = file.attributes.description?.trim();\n if (!description) {\n const lines = (file.body || '').split('\\n');\n const firstLine = lines.find((line) => line.trim())?.trim();\n if (firstLine) {\n // Handle title lines starting with # (supports multiple #)\n if (firstLine.startsWith('#')) {\n // Remove all # symbols and clean up\n description = firstLine.replace(/^#+\\s*/, '').trim();\n } else {\n // Use directly for any other starting character (including ```, ##, *, -, etc.)\n description = firstLine;\n }\n\n // Limit length to 50 characters, truncate and add ellipsis if exceeds\n if (description.length > 50) {\n description = `${description.substring(0, 50)}...`;\n }\n }\n }\n if (!description) {\n description = kebabToTitleCase(name);\n }\n return {\n ...file,\n relativePath: filePath,\n name,\n description,\n };\n}\n","import { DEFAULT_OUTPUT_STYLE_NAME } from '../../constants';\nimport type { OutputStyle } from '../types';\n\nexport const defaultOutputStyle: OutputStyle = {\n name: DEFAULT_OUTPUT_STYLE_NAME,\n description: 'Default output style',\n isCodingRelated: true,\n prompt: '',\n};\n","import type { OutputStyle } from '../types';\n\nexport const explanatoryOutputStyle: OutputStyle = {\n name: 'Explanatory',\n description: 'Explains its implementation choices and codebase patterns',\n isCodingRelated: true,\n prompt: `\nYou are an interactive CLI tool that helps users with software engineering tasks. In addition to software engineering tasks, you should provide educational insights about the codebase along the way.\n\nYou should be clear and educational, providing helpful explanations while remaining focused on the task. Balance educational content with task completion. When providing insights, you may exceed typical length constraints, but remain focused and relevant.\n\n# Explanatory Style Active\n\n## Insights\nIn order to encourage learning, before and after writing code, always provide brief educational explanations about implementation choices using (with backticks):\n\"\\`★ Insight ─────────────────────────────────────\\`\n[2-3 key educational points]\n\\`─────────────────────────────────────────────────\\`\"\n\nThese insights should be included in the conversation, not in the codebase. You should generally focus on interesting insights that are specific to the codebase or the code you just wrote, rather than general programming concepts.\n `.trim(),\n};\n","import type { OutputStyle } from '../types';\n\nexport const miaoOutputStyle: OutputStyle = {\n name: 'Miao',\n description:\n 'Limited time - Adds \"miao~~~\" after every sentence for a cute cat-like style',\n isCodingRelated: true,\n prompt: `\nYou are an interactive CLI tool that helps users with software engineering tasks, but with a cute cat-like personality.\n\n# Miao Style Active\n\nYou should add \"miao~~~\" after every sentence. A sentence is typically defined as text ending with a period (.), exclamation mark (!), or question mark (?). Apply this consistently throughout your responses.\n\nExamples:\n- \"I'll help you with that miao~~~\"\n- \"Let me check the file first miao~~~\"\n- \"The function works correctly miao~~~\"\n\nKeep your technical accuracy and helpfulness while adding this cute touch to make interactions more fun and engaging.\n `.trim(),\n};\n","import type { OutputStyle } from '../types';\n\nexport const minimalOutputStyle: OutputStyle = {\n name: 'Minimal',\n description: 'Simple and concise for non-coding tasks',\n isCodingRelated: false,\n prompt: `You are a helpful assistant. Be concise and direct. Answer questions clearly without unnecessary elaboration.`,\n};\n","import type { OutputStyle } from '../types';\nimport { defaultOutputStyle } from './default';\nimport { explanatoryOutputStyle } from './explanatory';\nimport { miaoOutputStyle } from './miao';\nimport { minimalOutputStyle } from './minimal';\n\nexport * from './default';\nexport * from './explanatory';\nexport * from './miao';\nexport * from './minimal';\n\nexport function getBuiltinOutputStyles(): OutputStyle[] {\n return [\n defaultOutputStyle,\n explanatoryOutputStyle,\n miaoOutputStyle,\n minimalOutputStyle,\n ];\n}\n","/**\n * Converts a kebab-case string to Title Case.\n * Examples:\n * - \"foo-bar\" → \"Foo Bar\"\n * - \"review\" → \"Review\"\n * - \"multi-word-command\" → \"Multi Word Command\"\n */\nexport function kebabToTitleCase(kebabString: string): string {\n return kebabString\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n}\n","export function generatePlanSystemPrompt(opts: {\n todo: boolean;\n productName: string;\n language?: string;\n}) {\n return `\nYou are an interactive CLI tool that helps users with software engineering tasks. Plan mode is active, which means you should analyze the user's request and create a detailed execution plan before taking any actions.\n\nIMPORTANT: RETURN THE PLAN ONLY.\n\n# Plan Mode Guidelines\n\nYou MUST NOT execute any system-modifying actions. This includes:\n- Making file edits (edit, write, multiedit tools)\n- Running bash commands or scripts\n- Changing configurations or making commits\n- Any tool that modifies system state\n\nYou MAY use read-only tools for research:\n- read, glob, grep, ls tools for codebase analysis\n- Understanding existing patterns and conventions\n- Gathering information needed for planning\n\n# Planning Methodology\n\n1. **Analyze the Request**: Break down what the user wants to accomplish\n2. **Research Context**: Use read-only tools to understand the current codebase\n3. **Design Approach**: Consider existing patterns, dependencies, and best practices\n4. **Create Structured Plan**: Provide clear, actionable steps with specific details\n\n# Plan Quality Standards\n\nYour plan should be:\n- **Specific**: Include exact file paths, function names, and implementation details\n- **Actionable**: Each step should be clear and executable\n- **Complete**: Cover all aspects from implementation to testing\n- **Informed**: Based on actual codebase analysis, not assumptions\n- **Ordered**: Steps should follow logical dependencies\n\n# Communication Style\n\nBe concise and direct. Focus on the technical plan rather than explanations. Use the same professional tone as other agents in this codebase.\n\n${opts.language === 'English' ? '' : `IMPORTANT: Answer in ${opts.language}.`}\n`.trim();\n}\n","import { AGENT_TYPE, TOOL_NAMES } from './constants';\nimport type { OutputStyle } from './outputStyle';\n\nfunction getTasksPrompt(opts: { todo: boolean; productName: string }) {\n if (!opts.todo) {\n return '';\n }\n const productName = opts.productName;\n return `\n# Task Management\nYou have access to the ${TOOL_NAMES.TODO_WRITE} tool to help you manage and plan tasks. Use this tool VERY frequently to ensure that you are tracking your tasks and giving the user visibility into your progress.\nThese tools are also EXTREMELY helpful for planning tasks, and for breaking down larger complex tasks into smaller steps. If you do not use this tool when planning, you may forget to do important tasks - and that is unacceptable.\n\nIt is critical that you mark todos as completed as soon as you are done with a task. Do not batch up multiple tasks before marking them as completed.\n\nExamples:\n\n<example>\nuser: Run the build and fix any type errors\nassistant: I'm going to use the ${TOOL_NAMES.TODO_WRITE} tool to write the following items to the todo list:\n- Run the build\n- Fix any type errors\n\nI'm now going to run the build using ${TOOL_NAMES.BASH}.\n\nLooks like I found 10 type errors. I'm going to use the ${TOOL_NAMES.TODO_WRITE} tool to write 10 items to the todo list.\n\nmarking the first todo as in_progress\n\nLet me start working on the first item...\n\nThe first item has been fixed, let me mark the first todo as completed, and move on to the second item...\n\n</example>\nIn the above example, the assistant completes all the tasks, including the 10 error fixes and running the build and fixing all errors.\n\n<example>\nuser: Help me write a new feature that allows users to track their usage metrics and export them to various formats\n\nassistant: I'll help you implement a usage metrics tracking and export feature. Let me first use the ${TOOL_NAMES.TODO_WRITE} tool to plan this task.\nAdding the following todos to the todo list:\n1. Research existing metrics tracking in the codebase\n2. Design the metrics collection system\n3. Implement core metrics tracking functionality\n4. Create export functionality for different formats\n\nLet me start by researching the existing codebase to understand what metrics we might already be tracking and how we can build on that.\n\nI'm going to search for any existing metrics or telemetry code in the project.\n\nI've found some existing telemetry code. Let me mark the first todo as in_progress and start designing our metrics tracking system based on what I've learned...\n\n[Assistant continues implementing the feature step by step, marking todos as in_progress and completed as they go]\n</example>\n\n# Doing tasks\nThe user will primarily request you perform software engineering tasks. This includes solving bugs, adding new functionality, refactoring code, explaining code, and more. For these tasks the following steps are recommended:\n- Use the ${TOOL_NAMES.TODO_WRITE} tool to plan the task if required\n- Use the available search tools to understand the codebase and the user's query. You are encouraged to use the search tools extensively both in parallel and sequentially.\n- Implement the solution using all tools available to you\n- Verify the solution if possible with tests. NEVER assume specific test framework or test script. Check the README or search codebase to determine the testing approach.\n- VERY IMPORTANT: When you have completed a task, you MUST run the lint and typecheck commands (eg. npm run lint, npm run typecheck, ruff, etc.) with ${TOOL_NAMES.BASH} if they were provided to you to ensure your code is correct. If you are unable to find the correct command, ask the user for the command to run and if they supply it, proactively suggest writing it to ${productName}.md so that you will know to run it next time.\nNEVER commit changes unless the user explicitly asks you to. It is VERY IMPORTANT to only commit when explicitly asked, otherwise the user will feel that you are being too proactive.\n\nIMPORTANT: Always use the ${TOOL_NAMES.TODO_WRITE} tool to plan and track tasks throughout the conversation.\n `;\n}\n\nfunction getToolUsagePolicyPrompt(task: boolean) {\n const taskPolicy = task\n ? `\n- When doing file search, prefer to use the ${TOOL_NAMES.TASK} tool in order to reduce context usage.\n- You should proactively use the ${TOOL_NAMES.TASK} tool with specialized agents when the task at hand matches the agent's description.\n- If the user specifies that they want you to run tools \"in parallel\", you MUST send a single message with multiple tool use content blocks. For example, if you need to launch multiple agents in parallel, send a single message with multiple ${TOOL_NAMES.TASK} tool calls.\n- VERY IMPORTANT: When exploring the codebase to gather context or to answer a question that is not a needle query for a specific file/class/function, it is CRITICAL that you use the ${TOOL_NAMES.TASK} tool with subagent_type=${AGENT_TYPE.EXPLORE} instead of running search commands directly.\n<example>\nuser: Where are errors from the client handled?\nassistant: [Uses the ${TOOL_NAMES.TASK} tool with subagent_type=${AGENT_TYPE.EXPLORE} to find the files that handle client errors instead of using ${TOOL_NAMES.GLOB} or ${TOOL_NAMES.GREP} directly]\n</example>\n<example>\nuser: What is the codebase structure?\nassistant: [Uses the ${TOOL_NAMES.TASK} tool with subagent_type=${AGENT_TYPE.EXPLORE}]\n</example>`\n : '';\n\n return `\n# Tool usage policy${taskPolicy}\n- When fetch returns a message about a redirect to a different host, you should immediately make a new fetch request with the redirect URL provided in the response.\n- You can call multiple tools in a single response. If you intend to call multiple tools and there are no dependencies between them, make all independent tool calls in parallel. Maximize use of parallel tool calls where possible to increase efficiency. However, if some tool calls depend on previous calls to inform dependent values, do NOT call these tools in parallel and instead call them sequentially. For instance, if one operation must complete before another starts, run these operations sequentially instead. Never use placeholders or guess missing parameters in tool calls.\n- Use specialized tools instead of bash commands when possible, as this provides a better user experience. For file operations, use dedicated tools: ${TOOL_NAMES.READ} for reading files instead of cat/head/tail, ${TOOL_NAMES.EDIT} for editing instead of sed/awk, and ${TOOL_NAMES.WRITE} for creating files instead of cat with heredoc or echo redirection. Reserve bash tools exclusively for actual system commands and terminal operations that require shell execution. NEVER use bash echo or other command-line tools to communicate thoughts, explanations, or instructions to the user. Output all communication directly in your response text instead.\n `;\n}\n\nexport function generateSystemPrompt(opts: {\n todo: boolean;\n productName: string;\n language?: string;\n appendSystemPrompt?: string;\n outputStyle: OutputStyle;\n task?: boolean;\n}) {\n const { outputStyle } = opts;\n const isDefaultOutputStyle = outputStyle.isDefault();\n return `\nYou are an interactive CLI tool that helps users ${isDefaultOutputStyle ? 'with software engineering tasks.' : `according to your \"Output Style\" below, which describes how you should respond to user queries.`} Use the instructions below and the tools available to you to assist the user.\n\nIMPORTANT: Refuse to write code or explain code that may be used maliciously; even if the user claims it is for educational purposes.\n${\n opts.language === 'English'\n ? ''\n : `IMPORTANT: Answer in ${opts.language}.\n`\n}\n\n${\n !isDefaultOutputStyle\n ? `\n# Output style: ${outputStyle.name}\n${outputStyle.prompt}\n `\n : `\n# Tone and style\nYou should be concise, direct, and to the point. When you run a non-trivial bash command, you should explain what the command does and why you are running it.\nOutput text to communicate with the user; all text you output outside of tool use is displayed to the user. Only use tools to complete tasks. Never use tools like \\`bash\\` to communicate with the user during the session.\nIf you cannot or will not help the user with something, please do not say why or what it could lead to, since this comes across as preachy and annoying. Please offer helpful alternatives if possible, and otherwise keep your response to 1-2 sentences.\nOnly use emojis if the user explicitly requests it. Avoid using emojis in all communication unless asked.\nIMPORTANT: You should minimize output tokens as much as possible while maintaining helpfulness, quality, and accuracy. Only address the specific query or task at hand, avoiding tangential information unless absolutely critical for completing the request. If you can answer in 1-3 sentences or a short paragraph, please do.\nIMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to.\nIMPORTANT: Keep your responses short, since they will be displayed on a command line interface. You MUST answer concisely with fewer than 4 lines (not including tool use or code generation), unless user asks for detail. Answer the user's question directly, without elaboration, explanation, or details. One word answers are best. Avoid introductions, conclusions, and explanations. You MUST avoid text before/after your response, such as \"The answer is <answer>.\", \"Here is the content of the file...\" or \"Based on the information provided, the answer is...\" or \"Here is what I will do next...\". Here are some examples to demonstrate appropriate verbosity:\n<example>\nuser: 2 + 2\nassistant: 4\n</example>\n<example>\nuser: is 11 a prime number?\nassistant: Yes\n</example>\n<example>\nuser: what command should I run to list files in the current directory?\nassistant: ls\n</example>\n<example>\nuser: what files are in the directory src/?\nassistant: [runs ls and sees foo.c, bar.c, baz.c]\nuser: which file contains the implementation of foo?\nassistant: src/foo.c\n</example>\n<example>\nuser: write tests for new feature\nassistant: [uses grep and glob tools to find where similar tests are defined, uses concurrent read file tool use blocks in one tool call to read relevant files at the same time, uses edit file tool to write new tests]\n</example>\n `\n}\n\n# Following conventions\nWhen making changes to files, first understand the file's code conventions. Mimic code style, use existing libraries and utilities, and follow existing patterns.\n- NEVER assume that a given library is available, even if it is well known. Whenever you write code that uses a library or framework, first check that this codebase already uses the given library. For example, you might look at neighboring files, or check the package.json (or cargo.toml, and so on depending on the language).\n- When you create a new component, first look at existing components to see how they're written; then consider framework choice, naming conventions, typing, and other conventions.\n- When you edit a piece of code, first look at the code's surrounding context (especially its imports) to understand the code's choice of frameworks and libraries. Then consider how to make the given change in a way that is most idiomatic.\n- Always follow security best practices. Never introduce code that exposes or logs secrets and keys. Never commit secrets or keys to the repository.\n\n${\n outputStyle.isCodingRelated\n ? `\n# Code style\n- IMPORTANT: DO NOT ADD ***ANY*** COMMENTS unless asked\n\n${getTasksPrompt(opts)}`\n : ''\n}\n\n${getToolUsagePolicyPrompt(opts.task ?? false)}\n\n${opts.appendSystemPrompt ? opts.appendSystemPrompt : ''}\n`.trim();\n}\n","import { TOOL_NAMES } from './constants';\nimport type { Context } from './context';\nimport { JsonlLogger, RequestLogger } from './jsonl';\nimport { LlmsContext } from './llmsContext';\nimport { runLoop, type StreamResult, type ThinkingConfig } from './loop';\nimport type { ImagePart, NormalizedMessage, UserContent } from './message';\nimport { resolveModelWithContext } from './model';\nimport { OutputFormat } from './outputFormat';\nimport { OutputStyleManager } from './outputStyle';\nimport { generatePlanSystemPrompt } from './planSystemPrompt';\nimport { PluginHookType } from './plugin';\nimport { Session, SessionConfigManager, type SessionId } from '../session/session';\nimport { generateSystemPrompt } from './systemPrompt';\nimport type {\n ApprovalCategory,\n Tool,\n ToolApprovalResult,\n ToolUse,\n} from '../tools/tool';\nimport { resolveTools, Tools } from '../tools/tool';\nimport { Usage } from './usage';\nimport { randomUUID } from '../utils/randomUUID';\n\nexport class Project {\n session: Session;\n context: Context;\n // For subagent to inherit parent session config\n parentSessionId?: string;\n constructor(opts: {\n sessionId?: SessionId;\n parentSessionId?: string;\n context: Context;\n }) {\n this.session = opts.sessionId\n ? Session.resume({\n id: opts.sessionId,\n logPath: opts.context.paths.getSessionLogPath(opts.sessionId),\n })\n : Session.create();\n this.context = opts.context;\n this.parentSessionId = opts.parentSessionId;\n }\n\n async send(\n message: string | null,\n opts: {\n model?: string;\n onMessage?: (opts: { message: NormalizedMessage }) => Promise<void>;\n onToolApprove?: (opts: {\n toolUse: ToolUse;\n }) => Promise<boolean | ToolApprovalResult>;\n onTextDelta?: (text: string) => Promise<void>;\n onChunk?: (chunk: any, requestId: string) => Promise<void>;\n onStreamResult?: (result: StreamResult) => Promise<void>;\n signal?: AbortSignal;\n attachments?: ImagePart[];\n parentUuid?: string;\n thinking?: ThinkingConfig;\n } = {},\n ) {\n let tools = await resolveTools({\n context: this.context,\n sessionId: this.session.id,\n write: true,\n todo: true,\n askUserQuestion: !this.context.config.quiet,\n signal: opts.signal,\n task: true,\n });\n tools = await this.context.apply({\n hook: 'tool',\n args: [{ sessionId: this.session.id }],\n memo: tools,\n type: PluginHookType.SeriesMerge,\n });\n const outputStyleManager = await OutputStyleManager.create(this.context);\n const outputStyle = outputStyleManager.getOutputStyle(\n this.context.config.outputStyle,\n this.context.cwd,\n );\n const hasTaskTool = tools.some((t) => t.name === TOOL_NAMES.TASK);\n let systemPrompt = generateSystemPrompt({\n todo: this.context.config.todo!,\n productName: this.context.productName,\n language: this.context.config.language,\n outputStyle,\n task: hasTaskTool,\n });\n systemPrompt = await this.context.apply({\n hook: 'systemPrompt',\n args: [{ sessionId: this.session.id }],\n memo: systemPrompt,\n type: PluginHookType.SeriesLast,\n });\n return this.sendWithSystemPromptAndTools(message, {\n ...opts,\n tools,\n systemPrompt,\n });\n }\n\n async plan(\n message: string | null,\n opts: {\n model?: string;\n onMessage?: (opts: { message: NormalizedMessage }) => Promise<void>;\n onTextDelta?: (text: string) => Promise<void>;\n onChunk?: (chunk: any, requestId: string) => Promise<void>;\n onStreamResult?: (result: StreamResult) => Promise<void>;\n signal?: AbortSignal;\n attachments?: ImagePart[];\n parentUuid?: string;\n thinking?: ThinkingConfig;\n } = {},\n ) {\n let tools = await resolveTools({\n context: this.context,\n sessionId: this.session.id,\n write: false,\n todo: false,\n askUserQuestion: !this.context.config.quiet,\n signal: opts.signal,\n task: false,\n });\n tools = await this.context.apply({\n hook: 'tool',\n args: [{ isPlan: true, sessionId: this.session.id }],\n memo: tools,\n type: PluginHookType.SeriesMerge,\n });\n let systemPrompt = generatePlanSystemPrompt({\n todo: this.context.config.todo!,\n productName: this.context.productName,\n language: this.context.config.language,\n });\n systemPrompt = await this.context.apply({\n hook: 'systemPrompt',\n args: [{ isPlan: true, sessionId: this.session.id }],\n memo: systemPrompt,\n type: PluginHookType.SeriesLast,\n });\n return this.sendWithSystemPromptAndTools(message, {\n ...opts,\n model: opts.model || this.context.config.planModel,\n tools,\n systemPrompt,\n onToolApprove: () => Promise.resolve(true),\n });\n }\n\n async sendWithSystemPromptAndTools(\n message: string | null,\n opts: {\n model?: string;\n onMessage?: (opts: { message: NormalizedMessage }) => Promise<void>;\n onToolApprove?: (opts: {\n toolUse: ToolUse;\n category?: ApprovalCategory;\n }) => Promise<boolean | ToolApprovalResult>;\n onTextDelta?: (text: string) => Promise<void>;\n onChunk?: (chunk: any, requestId: string) => Promise<void>;\n onStreamResult?: (result: StreamResult) => Promise<void>;\n signal?: AbortSignal;\n tools?: Tool[];\n systemPrompt?: string;\n attachments?: ImagePart[];\n parentUuid?: string;\n thinking?: ThinkingConfig;\n skipStopHook?: boolean;\n } = {},\n ) {\n const startTime = new Date();\n const tools = opts.tools || [];\n const outputFormat = new OutputFormat({\n format: this.context.config.outputFormat!,\n quiet: this.context.config.quiet,\n });\n\n const jsonlLogger = new JsonlLogger({\n filePath: this.context.paths.getSessionLogPath(this.session.id),\n });\n const requestLogger = new RequestLogger({\n globalProjectDir: this.context.paths.globalProjectDir,\n });\n if (message !== null) {\n message = await this.context.apply({\n hook: 'userPrompt',\n memo: message,\n args: [\n {\n sessionId: this.session.id,\n },\n ],\n type: PluginHookType.SeriesLast,\n });\n }\n const sessionConfigManager = new SessionConfigManager({\n logPath: this.context.paths.getSessionLogPath(this.session.id),\n });\n const additionalDirectories =\n sessionConfigManager.config.additionalDirectories || [];\n\n const llmsContext = await LlmsContext.create({\n context: this.context,\n sessionId: this.session.id,\n userPrompt: message,\n additionalDirectories,\n });\n let userMessage: NormalizedMessage | null = null;\n if (message !== null) {\n const lastMessageUuid =\n opts.parentUuid ||\n this.session.history.messages[this.session.history.messages.length - 1]\n ?.uuid;\n\n let content: UserContent = message;\n if (opts.attachments?.length) {\n content = [\n {\n type: 'text' as const,\n text: message,\n },\n ...opts.attachments,\n ];\n }\n\n userMessage = {\n parentUuid: lastMessageUuid || null,\n uuid: randomUUID(),\n role: 'user',\n content,\n type: 'message',\n timestamp: new Date().toISOString(),\n };\n const userMessageWithSessionId = {\n ...userMessage,\n sessionId: this.session.id,\n };\n jsonlLogger.addMessage({\n message: userMessageWithSessionId,\n });\n await opts.onMessage?.({\n message: userMessage,\n });\n }\n const historyMessages = opts.parentUuid\n ? this.session.history.getMessagesToUuid(opts.parentUuid)\n : this.session.history.messages;\n const input =\n historyMessages.length > 0\n ? [...historyMessages, userMessage]\n : [userMessage];\n const filteredInput = input.filter((message) => message !== null);\n\n // Check if conversation history contains any images\n const hasImagesInHistory = filteredInput.some((msg) => {\n if (msg.role === 'user' && Array.isArray(msg.content)) {\n return msg.content.some((part: any) => part.type === 'image');\n }\n return false;\n });\n\n // Model selection priority (high to low):\n // 1. opts.model - explicitly specified for this call\n // 2. visionModel - if images present and visionModel is configured\n // 3. default model - resolved from context\n let modelToUse = opts.model;\n\n // Auto-select visionModel when:\n // - Conversation contains images\n // - visionModel is configured and different from the base model\n if (hasImagesInHistory) {\n const visionModel = this.context.config.visionModel;\n const baseModel = this.context.config.model;\n\n // Check if visionModel was explicitly configured (not just a fallback)\n // by comparing against what the base model would be\n if (visionModel && visionModel !== baseModel) {\n modelToUse = visionModel;\n }\n }\n\n // Resolve the final model (only once)\n const resolvedModel = (\n await resolveModelWithContext(modelToUse || null, this.context)\n ).model!;\n\n // Output model info for initial message\n if (message !== null) {\n outputFormat.onInit({\n text: message,\n sessionId: this.session.id,\n tools,\n model: resolvedModel,\n cwd: this.context.cwd,\n });\n }\n\n const toolsManager = new Tools(tools);\n const result = await runLoop({\n input: filteredInput,\n model: resolvedModel,\n tools: toolsManager,\n cwd: this.context.cwd,\n systemPrompt: opts.systemPrompt,\n llmsContexts: llmsContext.messages,\n signal: opts.signal,\n autoCompact: this.context.config.autoCompact,\n language: this.context.config.language,\n thinking: opts.thinking,\n temperature: this.context.config.temperature,\n onMessage: async (message) => {\n const normalizedMessage = {\n ...message,\n sessionId: this.session.id,\n };\n outputFormat.onMessage({\n message: normalizedMessage,\n });\n jsonlLogger.addMessage({\n message: normalizedMessage,\n });\n await opts.onMessage?.({\n message: normalizedMessage,\n });\n },\n onTextDelta: async (text) => {\n await opts.onTextDelta?.(text);\n },\n onStreamResult: async (result) => {\n requestLogger.logMetadata({\n requestId: result.requestId,\n prompt: result.prompt,\n model: result.model,\n tools: result.tools,\n request: result.request,\n response: result.response,\n error: result.error,\n });\n await opts.onStreamResult?.(result);\n },\n onChunk: async (chunk, requestId) => {\n requestLogger.logChunk(requestId, chunk);\n await opts.onChunk?.(chunk, requestId);\n },\n onText: async (text) => {},\n onReasoning: async (text) => {},\n onToolUse: async (toolUse) => {\n return await this.context.apply({\n hook: 'toolUse',\n args: [\n {\n sessionId: this.session.id,\n },\n ],\n memo: toolUse,\n type: PluginHookType.SeriesLast,\n });\n },\n onToolResult: async (toolUse, toolResult, approved) => {\n return await this.context.apply({\n hook: 'toolResult',\n args: [\n {\n toolUse,\n approved,\n sessionId: this.session.id,\n },\n ],\n memo: toolResult,\n type: PluginHookType.SeriesLast,\n });\n },\n onTurn: async (turn: {\n usage: Usage;\n startTime: Date;\n endTime: Date;\n }) => {\n await this.context.apply({\n hook: 'query',\n args: [\n {\n startTime: turn.startTime,\n endTime: turn.endTime,\n usage: turn.usage,\n sessionId: this.session.id,\n },\n ],\n type: PluginHookType.Series,\n });\n },\n onToolApprove: async (toolUse) => {\n const tool = toolsManager.get(toolUse.name);\n if (!tool) {\n // Let the tool invoke handle the `tool not found` error\n return true;\n }\n\n // TODO: if quiet return true\n // 1. if yolo return true\n const approvalMode = this.context.config.approvalMode;\n // Tools that require clarifying user input must always prompt the user, even in yolo mode\n if (approvalMode === 'yolo' && tool.approval?.category !== 'ask') {\n return true;\n }\n\n // 2. if category is read return true\n if (tool.approval?.category === 'read') {\n return true;\n }\n // 3. run tool should approve if true return true\n const needsApproval = tool.approval?.needsApproval;\n if (needsApproval) {\n const needsApprovalResult = await needsApproval({\n toolName: toolUse.name,\n params: toolUse.params,\n approvalMode: this.context.config.approvalMode,\n context: this.context,\n });\n if (!needsApprovalResult) {\n return true;\n }\n }\n // 4. if category is edit check autoEdit config (including session config)\n // Read parent session config first, so subagent can inherit parent agent's approval settings\n // If there is no parent (independent agent), use its own session\n const sessionIdToCheck = this.parentSessionId || this.session.id;\n const sessionConfigManager = new SessionConfigManager({\n logPath: this.context.paths.getSessionLogPath(sessionIdToCheck),\n });\n if (tool.approval?.category === 'write') {\n if (\n sessionConfigManager.config.approvalMode === 'autoEdit' ||\n approvalMode === 'autoEdit'\n ) {\n return true;\n }\n }\n // 5. check session config's approvalTools config\n if (sessionConfigManager.config.approvalTools.includes(toolUse.name)) {\n return true;\n }\n // 6. request user approval\n return (\n (await opts.onToolApprove?.({\n toolUse,\n category: tool.approval?.category,\n })) ?? false\n );\n },\n });\n const endTime = new Date();\n await this.context.apply({\n hook: 'conversation',\n args: [\n {\n userPrompt: message,\n result,\n startTime,\n endTime,\n sessionId: this.session.id,\n },\n ],\n type: PluginHookType.Series,\n });\n if (!opts.skipStopHook) {\n await this.context.apply({\n hook: 'stop',\n args: [\n {\n sessionId: this.session.id,\n result,\n usage: result.success ? result.data.usage : Usage.empty(),\n turnsCount: result.success ? result.metadata.turnsCount : 0,\n toolCallsCount: result.success ? result.metadata.toolCallsCount : 0,\n duration: result.success ? result.metadata.duration : 0,\n model: `${resolvedModel.provider.id}/${resolvedModel.model.id}`,\n },\n ],\n type: PluginHookType.Series,\n });\n }\n outputFormat.onEnd({\n result,\n sessionId: this.session.id,\n });\n if (result.success && result.data.history) {\n this.session.updateHistory(result.data.history);\n }\n\n return result;\n }\n}\n","import type { Context } from '../../core/context';\nimport type { NormalizedMessage } from '../../core/message';\nimport { PluginHookType } from '../../core/plugin';\nimport { Project } from '../../core/project';\nimport { Session } from '../../session/session';\nimport type { Tool } from '../../tools/tool';\nimport type {\n AgentDefinition,\n AgentExecuteOptions,\n AgentExecutionResult,\n} from './types';\n\nenum AgentStatus {\n Completed = 'completed',\n Failed = 'failed',\n}\n\n// Resolve model\nconst MODEL_INHERIT = 'inherit';\n\n/**\n * Resolve the model for an agent with the following priority:\n * 1. Model explicitly passed in options\n * 2. Model configured in config.agent.{agentType}.model\n * 3. Model defined in agent definition\n * 4. Global model from context.config.model (fallback)\n */\nfunction resolveAgentModel(\n agentType: string,\n options: AgentExecuteOptions,\n definition: AgentDefinition,\n context: Context,\n): string {\n // Priority 1: Explicit model from options\n if (options.model && options.model !== MODEL_INHERIT) {\n return options.model;\n }\n\n // Priority 2: Config agent-specific model\n const configModel = context.config.agent?.[agentType]?.model;\n if (configModel && configModel !== MODEL_INHERIT) {\n return configModel;\n }\n\n // Priority 3: Agent definition model\n if (definition.model && definition.model !== MODEL_INHERIT) {\n return definition.model;\n }\n\n // Priority 4: Global fallback\n return context.config.model;\n}\n\nexport async function executeAgent(\n options: AgentExecuteOptions,\n): Promise<AgentExecutionResult> {\n const {\n definition,\n prompt,\n tools,\n context,\n signal,\n onMessage,\n onToolApprove,\n resume,\n } = options;\n\n const startTime = Date.now();\n\n const agentId = (() => {\n if (resume) {\n return resume;\n }\n return Session.createSessionId();\n })();\n\n try {\n // Validate Agent definition\n if (!definition.agentType) {\n throw new Error('Agent definition must have agentType');\n }\n if (!definition.systemPrompt) {\n throw new Error(`Agent '${definition.agentType}' must have systemPrompt`);\n }\n\n // Filter tools\n const filteredToolList = filterTools(tools, definition);\n\n if (filteredToolList.length === 0) {\n throw new Error(\n `Agent '${definition.agentType}' has no available tools after filtering.`,\n );\n }\n\n // Resolve model using priority-based resolution\n const modelName = resolveAgentModel(\n definition.agentType,\n options,\n definition,\n context,\n );\n\n if (!modelName) {\n throw new Error(`No model specified for agent '${definition.agentType}'`);\n }\n\n // Create Project instance with agent log path\n const project = new Project({\n sessionId: `agent-${agentId}`,\n parentSessionId: options.parentSessionId,\n context,\n });\n\n // Execute using Project.send\n const result = await project.sendWithSystemPromptAndTools(prompt, {\n model: modelName,\n systemPrompt: definition.systemPrompt,\n tools: filteredToolList,\n signal,\n skipStopHook: true,\n onMessage: async ({ message }) => {\n // Add agent metadata\n const enhancedMessage: NormalizedMessage = {\n ...message,\n metadata: {\n ...(message.metadata || {}),\n agentId,\n agentType: definition.agentType,\n },\n };\n\n if (onMessage) {\n try {\n await onMessage(enhancedMessage, agentId, modelName);\n } catch (error) {\n console.error('[executeAgent] Failed to send message:', error);\n }\n }\n },\n onToolApprove,\n });\n\n // Handle result\n let executionResult: AgentExecutionResult;\n if (result.success) {\n executionResult = {\n status: AgentStatus.Completed,\n agentId,\n content: extractFinalContent(result.data),\n totalToolCalls: result.metadata?.toolCallsCount || 0,\n totalDuration: Date.now() - startTime,\n model: modelName,\n usage: {\n inputTokens: result.data.usage?.promptTokens || 0,\n outputTokens: result.data.usage?.completionTokens || 0,\n },\n };\n } else {\n executionResult = {\n status: AgentStatus.Failed,\n agentId,\n content: `Agent execution failed: ${result.error.message}`,\n totalToolCalls: 0,\n totalDuration: Date.now() - startTime,\n model: modelName,\n usage: { inputTokens: 0, outputTokens: 0 },\n };\n }\n\n await context.apply({\n hook: 'subagentStop',\n args: [\n {\n parentSessionId: options.parentSessionId || '',\n agentId,\n agentType: definition.agentType,\n result: executionResult,\n usage: executionResult.usage,\n totalToolCalls: executionResult.totalToolCalls,\n totalDuration: executionResult.totalDuration,\n model: modelName,\n },\n ],\n type: PluginHookType.Series,\n });\n\n return executionResult;\n } catch (error) {\n return {\n status: AgentStatus.Failed,\n agentId,\n content: `Agent execution error: ${error instanceof Error ? error.message : String(error)}`,\n totalToolCalls: 0,\n totalDuration: Date.now() - startTime,\n usage: { inputTokens: 0, outputTokens: 0 },\n };\n }\n}\n\nfunction extractFinalContent(data: Record<string, unknown>): string {\n if (data.text && typeof data.text === 'string') {\n return data.text;\n }\n if (data.content && typeof data.content === 'string') {\n return data.content;\n }\n return 'Agent completed successfully';\n}\n\nfunction filterTools(allTools: Tool[], agentDef: AgentDefinition): Tool[] {\n const { tools, disallowedTools } = agentDef;\n const disallowedSet = new Set(disallowedTools || []);\n const hasWildcard =\n tools === undefined || (tools.length === 1 && tools[0] === '*');\n\n if (hasWildcard) {\n return allTools.filter((tool) => !disallowedSet.has(tool.name));\n }\n\n const allowedSet = new Set(tools);\n return allTools.filter(\n (tool) => allowedSet.has(tool.name) && !disallowedSet.has(tool.name),\n );\n}\n","import { spawn } from 'child_process';\nimport crypto from 'crypto';\nimport os from 'os';\n\nconst MAX_OUTPUT_SIZE = 100 * 1024 * 1024; // 100MB\n\nexport interface BackgroundTask {\n id: string;\n command: string;\n pid: number;\n pgid?: number;\n status: 'running' | 'completed' | 'killed' | 'failed';\n createdAt: number;\n output: string;\n exitCode: number | null;\n}\n\ninterface CreateTaskInput {\n command: string;\n pid: number;\n pgid?: number;\n}\n\nexport class BackgroundTaskManager {\n private tasks: Map<string, BackgroundTask> = new Map();\n\n createTask(input: CreateTaskInput): string {\n const id = `task_${crypto.randomBytes(6).toString('hex')}`;\n const task: BackgroundTask = {\n id,\n command: input.command,\n pid: input.pid,\n pgid: input.pgid,\n status: 'running',\n createdAt: Date.now(),\n output: '',\n exitCode: null,\n };\n this.tasks.set(id, task);\n return id;\n }\n\n getTask(id: string): BackgroundTask | null {\n return this.tasks.get(id) || null;\n }\n\n getAllTasks(): BackgroundTask[] {\n return Array.from(this.tasks.values());\n }\n\n appendOutput(id: string, output: string): void {\n const task = this.tasks.get(id);\n if (task) {\n const newOutput = task.output + output;\n if (newOutput.length > MAX_OUTPUT_SIZE) {\n const truncateAmount = Math.floor(MAX_OUTPUT_SIZE * 0.3);\n task.output =\n '... [output truncated] ...\\n' +\n newOutput.slice(newOutput.length - MAX_OUTPUT_SIZE + truncateAmount);\n } else {\n task.output = newOutput;\n }\n }\n }\n\n updateTaskStatus(\n id: string,\n status: BackgroundTask['status'],\n exitCode: number | null = null,\n ): void {\n const task = this.tasks.get(id);\n if (task) {\n task.status = status;\n if (exitCode !== null) {\n task.exitCode = exitCode;\n }\n }\n }\n\n deleteTask(id: string): void {\n this.tasks.delete(id);\n }\n\n private isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n }\n\n async killTask(id: string): Promise<boolean> {\n const task = this.tasks.get(id);\n if (!task || task.status !== 'running') {\n return false;\n }\n\n const isWindows = os.platform() === 'win32';\n\n try {\n if (isWindows) {\n spawn('taskkill', ['/pid', task.pid.toString(), '/f', '/t']);\n } else {\n const targetPid = task.pgid || task.pid;\n try {\n process.kill(-targetPid, 'SIGTERM');\n await new Promise((resolve) => setTimeout(resolve, 200));\n if (this.isProcessAlive(targetPid)) {\n process.kill(-targetPid, 'SIGKILL');\n }\n } catch {\n try {\n process.kill(task.pid, 'SIGKILL');\n } catch {\n // Process may not exist, still mark as killed\n }\n }\n }\n\n this.updateTaskStatus(id, 'killed');\n return true;\n } catch (error) {\n // Even if kill fails, mark as killed since we attempted\n this.updateTaskStatus(id, 'failed');\n return false;\n }\n }\n}\n","import fs from 'fs';\nimport path from 'pathe';\n\ninterface GlobalDataSchema {\n projects: Record<\n string,\n {\n history: string[];\n lastAccessed?: number;\n }\n >;\n recentModels?: string[];\n}\n\nexport class GlobalData {\n private globalDataPath: string;\n\n constructor({ globalDataPath }: { globalDataPath: string }) {\n this.globalDataPath = globalDataPath;\n }\n\n private readData(): GlobalDataSchema {\n if (!fs.existsSync(this.globalDataPath)) {\n return { projects: {} };\n }\n try {\n const content = fs.readFileSync(this.globalDataPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n return { projects: {} };\n }\n }\n\n private writeData(data: GlobalDataSchema): void {\n const dir = path.dirname(this.globalDataPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n fs.writeFileSync(\n this.globalDataPath,\n JSON.stringify(data, null, 2),\n 'utf-8',\n );\n }\n\n getProjectHistory({ cwd }: { cwd: string }): string[] {\n const data = this.readData();\n return data.projects[cwd]?.history || [];\n }\n\n addProjectHistory({ cwd, history }: { cwd: string; history: string }): void {\n const data = this.readData();\n\n if (!data.projects[cwd]) {\n data.projects[cwd] = { history: [] };\n }\n\n data.projects[cwd].history.push(history);\n this.writeData(data);\n }\n\n getProjectLastAccessed({ cwd }: { cwd: string }): number | null {\n const data = this.readData();\n return data.projects[cwd]?.lastAccessed || null;\n }\n\n updateProjectLastAccessed({ cwd }: { cwd: string }): void {\n const data = this.readData();\n\n if (!data.projects[cwd]) {\n data.projects[cwd] = { history: [] };\n }\n\n data.projects[cwd].lastAccessed = Date.now();\n this.writeData(data);\n }\n\n getRecentModels(): string[] {\n const data = this.readData();\n return data.recentModels || [];\n }\n\n addRecentModel(model: string): void {\n const data = this.readData();\n const recentModels = data.recentModels || [];\n const filtered = recentModels.filter((m) => m !== model);\n filtered.unshift(model);\n data.recentModels = filtered.slice(0, 5);\n this.writeData(data);\n }\n}\n","import { experimental_createMCPClient } from '@ai-sdk/mcp';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport createDebug from 'debug';\nimport { existsSync, readFileSync } from 'fs';\nimport { resolve } from 'pathe';\nimport type { ImagePart, TextPart } from '../core/message';\nimport type { Tool } from '../tools/tool';\nimport { safeStringify } from '../utils/safeStringify';\n\nexport interface MCPConfig {\n type?: 'stdio' | 'sse' | 'http';\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n disable?: boolean;\n /**\n * The timeout for tool calls in milliseconds.\n */\n timeout?: number;\n headers?: Record<string, string>;\n}\n\nconst debug = createDebug('oricore:mcp');\n\ntype MCPServerStatus =\n | 'pending'\n | 'connecting'\n | 'connected'\n | 'failed'\n | 'disconnected';\n\ninterface ServerState {\n config: MCPConfig;\n status: MCPServerStatus;\n error?: string;\n tools?: Record<string, any>;\n client?: any; // Store client for cleanup\n retryCount: number;\n isTemporaryError?: boolean;\n}\n\nexport class MCPManager {\n private servers: Map<string, ServerState> = new Map();\n private configs: Record<string, MCPConfig> = {};\n private isInitialized: boolean = false;\n private initPromise?: Promise<void>;\n private initLock: boolean = false;\n\n static create(mcpServers: Record<string, MCPConfig>): MCPManager {\n debug('create MCPManager', mcpServers);\n const manager = new MCPManager();\n manager.configs = mcpServers || {};\n\n // Initialize servers state without connecting\n for (const [key, config] of Object.entries(mcpServers || {})) {\n if (config.disable) {\n debug(`Skipping disabled MCP server: ${key}`);\n continue;\n }\n manager.servers.set(key, {\n config,\n status: 'pending',\n retryCount: 0,\n });\n }\n\n return manager;\n }\n\n async initAsync(): Promise<void> {\n // Return existing promise if initialization is already in progress\n if (this.initPromise) {\n return this.initPromise;\n }\n // Double-check locking pattern for thread safety\n if (this.initLock) {\n // Wait for lock to be released and check if initialization completed\n while (this.initLock) {\n await new Promise((resolve) => setTimeout(resolve, 10));\n }\n if (this.isInitialized) {\n return;\n }\n }\n // Acquire lock\n this.initLock = true;\n try {\n // Check again in case another thread completed initialization\n if (this.isInitialized) {\n return;\n }\n this.initPromise = this._performInit();\n await this.initPromise;\n } finally {\n // Release lock\n this.initLock = false;\n }\n }\n\n private async _performInit(): Promise<void> {\n debug('Starting async MCP initialization');\n const connectionPromises: Promise<void>[] = [];\n\n for (const [key, config] of Object.entries(this.configs)) {\n if (config.disable) {\n continue;\n }\n\n const connectionPromise = this._connectServer(key, config);\n connectionPromises.push(connectionPromise);\n }\n\n // Wait for all connections to complete (success or failure)\n await Promise.allSettled(connectionPromises);\n this.isInitialized = true;\n debug('MCP initialization completed');\n }\n\n private async _connectServer(key: string, config: MCPConfig): Promise<void> {\n const serverState = this.servers.get(key);\n if (!serverState) return;\n\n try {\n debug(`Connecting MCP server: ${key}`);\n serverState.status = 'connecting';\n\n // Test connection and fetch tools\n const { client, tools } = await this._testConnectionAndFetchTools(config);\n\n serverState.status = 'connected';\n serverState.client = client;\n serverState.tools = tools;\n serverState.error = undefined;\n\n debug(\n `MCP server connected successfully: ${key}, tools: ${Object.keys(tools).length}`,\n );\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n debug(`Failed to connect MCP server ${key}: ${errorMessage}`);\n\n // Classify error types for better handling\n const isTemporaryError = this._isTemporaryError(error);\n\n serverState.status = 'failed';\n serverState.error = errorMessage;\n serverState.retryCount += 1;\n serverState.isTemporaryError = isTemporaryError;\n\n // Ensure no client reference is left on failure\n serverState.client = undefined;\n serverState.tools = undefined;\n }\n }\n\n async getAllTools(): Promise<Tool[]> {\n const allTools: Tool[] = [];\n const toolNames = new Set<string>();\n\n for (const [serverName, serverState] of this.servers.entries()) {\n if (serverState.status !== 'connected' || !serverState.tools) {\n continue;\n }\n\n for (const [toolName, toolDef] of Object.entries(serverState.tools)) {\n const fullToolName = `mcp__${serverName}__${toolName}`;\n\n if (toolNames.has(fullToolName)) {\n throw new Error(`Duplicate tool name found: ${fullToolName}`);\n }\n\n toolNames.add(fullToolName);\n allTools.push(\n this.#convertAiSdkToolToLocal(\n toolName,\n toolDef,\n serverName,\n serverState.config,\n ),\n );\n }\n }\n\n return allTools;\n }\n\n async getTools(keys: string[]): Promise<Tool[]> {\n const allTools: Tool[] = [];\n const toolNames = new Set<string>();\n\n for (const key of keys) {\n const serverState = this.servers.get(key);\n if (\n !serverState ||\n serverState.status !== 'connected' ||\n !serverState.tools\n ) {\n continue;\n }\n\n for (const [toolName, toolDef] of Object.entries(serverState.tools)) {\n const fullToolName = `mcp__${key}__${toolName}`;\n\n if (toolNames.has(fullToolName)) {\n throw new Error(`Duplicate tool name found: ${fullToolName}`);\n }\n\n toolNames.add(fullToolName);\n allTools.push(\n this.#convertAiSdkToolToLocal(\n toolName,\n toolDef,\n key,\n serverState.config,\n ),\n );\n }\n }\n\n return allTools;\n }\n\n async destroy() {\n // Close all client connections\n const closePromises = Array.from(this.servers.values())\n .filter((state) => state.client)\n .map((state) =>\n state.client.close().catch((err: Error) => {\n debug('Error closing client during destroy:', err);\n }),\n );\n\n await Promise.allSettled(closePromises);\n this.servers.clear();\n this.isInitialized = false;\n this.initPromise = undefined;\n }\n\n getServerNames(): string[] {\n return Array.from(this.servers.keys());\n }\n\n hasServer(name: string): boolean {\n return this.servers.has(name);\n }\n\n getServerStatus(name: string): MCPServerStatus | undefined {\n return this.servers.get(name)?.status;\n }\n\n getServerError(name: string): string | undefined {\n return this.servers.get(name)?.error;\n }\n\n async getAllServerStatus(): Promise<\n Record<\n string,\n { status: MCPServerStatus; error?: string; toolCount: number }\n >\n > {\n await this.initAsync();\n\n const result: Record<\n string,\n { status: MCPServerStatus; error?: string; toolCount: number }\n > = {};\n for (const [name, state] of this.servers.entries()) {\n result[name] = {\n status: state.status,\n error: state.error,\n toolCount: state.tools ? Object.keys(state.tools).length : 0,\n };\n }\n return result;\n }\n\n isReady(): boolean {\n return this.isInitialized;\n }\n\n isLoading(): boolean {\n return !!this.initPromise && !this.isInitialized;\n }\n\n async retryConnection(serverName: string): Promise<void> {\n const config = this.configs[serverName];\n if (!config) {\n throw new Error(`Server ${serverName} not found in configuration`);\n }\n\n const serverState = this.servers.get(serverName);\n if (!serverState) {\n throw new Error(`Server ${serverName} state not found`);\n }\n\n // Log reconnection attempt\n debug(`Attempting to reconnect MCP server: ${serverName}`);\n\n // Close existing client if any\n if (serverState.client) {\n try {\n await serverState.client.close();\n } catch (error) {\n debug(`Error closing existing client for ${serverName}:`, error);\n }\n }\n\n // Reset state and retry\n serverState.client = undefined;\n serverState.tools = undefined;\n serverState.error = undefined;\n serverState.status = 'connecting';\n\n await this._connectServer(serverName, config);\n\n // Verify reconnection result\n const newState = this.servers.get(serverName);\n if (newState?.status !== 'connected') {\n throw new Error(newState?.error || 'Reconnection failed');\n }\n\n debug(`Successfully reconnected MCP server: ${serverName}`);\n }\n\n private async _createClient(config: MCPConfig) {\n if (config.command) {\n // Stdio transport (for local servers only)\n const env = config.env\n ? { ...config.env, PATH: process.env.PATH || '' }\n : undefined;\n\n const { Experimental_StdioMCPTransport } = await import(\n '@ai-sdk/mcp/mcp-stdio'\n );\n\n // Windows: if command is npx/npm/yarn/pnpm/bun/bunx, use cmd.exe to execute, fix: spawn npx ENOENT error\n const windowsShellCommands = [\n 'npx',\n 'npm',\n 'yarn',\n 'pnpm',\n 'bun',\n 'bunx',\n ];\n let command = config.command;\n let args = config.args;\n const isWin = process.platform === 'win32';\n if (isWin && windowsShellCommands.includes(command.toLowerCase())) {\n args = ['/c', command, ...(args || [])];\n command = 'cmd.exe';\n }\n\n return experimental_createMCPClient({\n transport: new Experimental_StdioMCPTransport({\n command,\n args,\n stderr: 'ignore',\n env,\n }),\n });\n } else if (config.url) {\n // HTTP or SSE transport\n const transportType = config.type || 'http'; // Default to HTTP\n if (transportType === 'sse') {\n // SSE transport\n return experimental_createMCPClient({\n transport: {\n type: 'sse',\n url: config.url,\n headers: config.headers,\n },\n });\n } else {\n // HTTP transport\n return experimental_createMCPClient({\n transport: new StreamableHTTPClientTransport(new URL(config.url), {\n requestInit: {\n headers: config.headers,\n },\n }),\n });\n }\n } else {\n throw new Error('MCP config must have either command or url configured');\n }\n }\n\n private async _testConnectionAndFetchTools(\n config: MCPConfig,\n ): Promise<{ client: any; tools: Record<string, any> }> {\n const client = await this._createClient(config);\n try {\n const tools = await client.tools();\n return { client, tools };\n } catch (error) {\n // Close client on error\n await client.close().catch((err) => {\n debug('Error closing client after connection failure:', err);\n });\n throw error;\n }\n }\n\n private _isTemporaryError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n const message = error.message.toLowerCase();\n\n // Network-related temporary errors\n const temporaryErrors = [\n 'timeout',\n 'connection refused',\n 'network error',\n 'temporary',\n 'try again',\n 'rate limit',\n 'too many requests',\n 'service unavailable',\n 'socket hang up',\n 'econnreset',\n 'enotfound',\n 'econnrefused',\n 'etimedout',\n ];\n\n // Configuration or permanent errors\n const permanentErrors = [\n 'command not found',\n 'no such file',\n 'permission denied',\n 'invalid configuration',\n 'malformed',\n 'syntax error',\n 'authentication failed',\n 'unauthorized',\n ];\n\n // Check for permanent errors first (higher priority)\n if (permanentErrors.some((permanent) => message.includes(permanent))) {\n return false;\n }\n\n // Check for temporary errors\n if (temporaryErrors.some((temporary) => message.includes(temporary))) {\n return true;\n }\n\n // Default to temporary for unknown errors (safer for retries)\n return true;\n }\n\n #convertAiSdkToolToLocal(\n toolName: string,\n toolDef: any,\n serverName: string,\n config: MCPConfig,\n ): Tool {\n const safeServerName = serverName.replace(/[^a-zA-Z0-9_-]/g, '');\n const safeToolName = toolName.replace(/[^a-zA-Z0-9_-]/g, '_');\n\n return {\n name: `mcp__${safeServerName}__${safeToolName}`,\n description: toolDef.description,\n getDescription: ({ params }) => {\n return formatParamsDescription(params as Record<string, any>);\n },\n // Why? Some models do not support null values, so null values need to be removed.\n parameters: removeNullValues(toolDef.inputSchema.jsonSchema),\n execute: async (params) => {\n try {\n // toolDef is already a Tool from AI SDK with an execute method\n const result = await toolDef.execute(params || {});\n\n const returnDisplay = `Tool ${toolName} executed successfully${params ? `, parameters: ${JSON.stringify(params)}` : ''}`;\n const llmContent = convertMcpResultToLlmContent(result);\n\n return {\n llmContent,\n returnDisplay,\n };\n } catch (error) {\n return {\n isError: true,\n llmContent: error instanceof Error ? error.message : String(error),\n };\n }\n },\n approval: {\n category: 'network',\n },\n };\n }\n}\n\nexport function parseMcpConfig(\n mcpConfigArgs: string[],\n cwd: string,\n): Record<string, MCPConfig> {\n const mcpServers: Record<string, MCPConfig> = {};\n for (const configItem of mcpConfigArgs) {\n let configData: unknown;\n try {\n // Try to parse as JSON string first\n configData = JSON.parse(configItem);\n } catch (e) {\n // If JSON parsing fails, treat as file path\n const configPath = resolve(cwd, configItem);\n if (!existsSync(configPath)) {\n throw new Error(`MCP config file not found: ${configPath}`);\n }\n try {\n const fileContent = readFileSync(configPath, 'utf-8');\n configData = JSON.parse(fileContent);\n } catch (error) {\n throw new Error(\n `Failed to parse MCP config file ${configPath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n // Extract mcpServer object from the config data\n if (!configData || typeof configData !== 'object') {\n throw new Error('MCP config must be a valid JSON object');\n }\n const configObj = configData as Record<string, unknown>;\n if (!configObj.mcpServers || typeof configObj.mcpServers !== 'object') {\n throw new Error('MCP config must contain an \"mcpServers\" object');\n }\n Object.assign(\n mcpServers,\n configObj.mcpServers as Record<string, MCPConfig>,\n );\n }\n\n return mcpServers;\n}\n\nfunction removeNullValues(obj: unknown): any {\n if (obj === null || obj === undefined) {\n return undefined;\n }\n if (Array.isArray(obj)) {\n return obj.map(removeNullValues).filter((v) => v !== undefined);\n }\n if (typeof obj === 'object') {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj as Record<string, unknown>)) {\n const cleaned = removeNullValues(v);\n if (cleaned !== undefined) {\n result[k] = cleaned;\n }\n }\n return result;\n }\n return obj;\n}\n\nfunction formatParamsDescription(params: Record<string, any>): string {\n if (!params || typeof params !== 'object') {\n return '';\n }\n const entries = Object.entries(params);\n if (entries.length === 0) {\n return '';\n }\n return entries\n .filter(([key, value]) => value !== null && value !== undefined)\n .map(([key, value]) => {\n return `${key}: ${safeStringify(value)}`;\n })\n .join(', ');\n}\n\nexport function convertMcpResultToLlmContent(\n result: any,\n): string | (TextPart | ImagePart)[] {\n // Support mcp spec data types\n // ref: https://modelcontextprotocol.io/specification/2025-06-18/server/tools#data-types\n\n // Step 1: Unpack MCP result format\n let actualContent: any;\n\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n // why? https://github.com/vercel/ai/blob/main/packages/mcp/src/tool/types.ts#L201\n if ('content' in result && Array.isArray(result.content)) {\n // Format 1: { content: [...], isError?: boolean }\n actualContent = result.content;\n } else if ('toolResult' in result) {\n // Format 2: { toolResult: unknown }\n return safeStringify(result.toolResult);\n } else {\n // Fallback: treat as regular object\n actualContent = result;\n }\n } else {\n actualContent = result;\n }\n\n // Step 2: Type detection functions\n const isTextPart = (part: object) => {\n return 'type' in part && part.type === 'text' && 'text' in part;\n };\n const isImagePart = (part: object) => {\n return (\n 'type' in part &&\n part.type === 'image' &&\n 'data' in part &&\n 'mimeType' in part\n );\n };\n const isResourcePart = (part: object) => {\n return 'type' in part && part.type === 'resource' && 'resource' in part;\n };\n const isPart = (part: object) => {\n return isTextPart(part) || isImagePart(part) || isResourcePart(part);\n };\n\n // Step 3: Process actualContent based on type\n let llmContent: any = actualContent;\n\n if (typeof llmContent === 'object' && !Array.isArray(llmContent)) {\n // Single object: wrap in array if it's a part, otherwise stringify\n if (isPart(llmContent as object)) {\n llmContent = [llmContent];\n } else {\n llmContent = safeStringify(llmContent);\n }\n } else if (Array.isArray(llmContent)) {\n // Array: check if it contains parts\n const hasPart = llmContent.some(\n (item) => typeof item === 'object' && item !== null && isPart(item),\n );\n if (hasPart) {\n // Mixed array: convert non-part elements to text parts\n llmContent = llmContent.map((part) => {\n if (typeof part === 'object' && part !== null && isPart(part)) {\n return part;\n } else {\n return { type: 'text', text: safeStringify(part) };\n }\n });\n } else {\n // Pure data array: stringify\n llmContent = safeStringify(llmContent);\n }\n } else if (typeof llmContent === 'string') {\n // Keep llmContent as string\n } else {\n // Other types: convert to string\n llmContent = String(llmContent);\n }\n\n return llmContent;\n}\n","import fs from 'fs';\nimport os from 'os';\nimport path from 'pathe';\n// TODO: SessionConfig will be imported when session module is ready\n// import type { SessionConfig } from '../session';\n\ninterface ConfigLogEntry {\n type: 'config';\n config: any; // SessionConfig\n}\n\ninterface MessageLogEntry {\n type: 'message';\n role: string;\n content: string | any[];\n [key: string]: any;\n}\n\ntype LogEntry = ConfigLogEntry | MessageLogEntry;\n\nexport function getGlobalDataPath(globalDir: string): string {\n return path.join(globalDir, 'data.json');\n}\n\nexport class Paths {\n globalConfigDir: string;\n globalProjectDir: string;\n projectConfigDir: string;\n\n constructor(opts: { productName: string; cwd: string }) {\n const productName = opts.productName.toLowerCase();\n this.globalConfigDir = path.join(os.homedir(), `.${productName}`);\n this.globalProjectDir = path.join(\n this.globalConfigDir,\n 'projects',\n formatPath(opts.cwd),\n );\n this.projectConfigDir = path.join(opts.cwd, `.${productName}`);\n }\n\n getSessionLogPath(sessionId: string) {\n if (path.isAbsolute(sessionId)) {\n return sessionId;\n } else if (sessionId.startsWith('.') || sessionId.endsWith('.jsonl')) {\n return path.join(process.cwd(), sessionId);\n } else {\n return path.join(this.globalProjectDir, `${sessionId}.jsonl`);\n }\n }\n\n getLatestSessionId() {\n if (!fs.existsSync(this.globalProjectDir)) {\n return undefined;\n }\n const jsonlFileTimeStamps = fs\n .readdirSync(this.globalProjectDir)\n .filter((file) => file.endsWith('.jsonl'))\n .map((file) => {\n const stats = fs.statSync(path.join(this.globalProjectDir, file));\n return {\n timestamp: stats.mtime.getTime(),\n sessionId: path.basename(file, '.jsonl'),\n };\n });\n const latestSession = jsonlFileTimeStamps.sort(\n (a, b) => b.timestamp - a.timestamp,\n )[0];\n return latestSession.sessionId;\n }\n\n getAllSessions() {\n if (!fs.existsSync(this.globalProjectDir)) {\n return [];\n }\n const jsonlFiles = fs\n .readdirSync(this.globalProjectDir)\n .filter((file) => file.endsWith('.jsonl'))\n .map((file) => {\n const filePath = path.join(this.globalProjectDir, file);\n const stats = fs.statSync(filePath);\n const sessionId = path.basename(file, '.jsonl');\n\n // Read message count and summary\n let messageCount = 0;\n let summary = '';\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const lines = content.split('\\n').filter(Boolean);\n messageCount = lines.length;\n\n // Extract summary: prioritize config.summary, fallback to first user message\n if (lines.length > 0) {\n try {\n const firstEntry: LogEntry = JSON.parse(lines[0]);\n if (firstEntry.type === 'config' && firstEntry.config.summary) {\n summary = firstEntry.config.summary;\n } else {\n summary = extractFirstUserMessageSummary(lines);\n }\n } catch (e) {\n summary = extractFirstUserMessageSummary(lines);\n }\n }\n } catch (e) {\n // ignore read error, message count is 0\n }\n\n return {\n sessionId,\n modified: stats.mtime,\n created: stats.birthtime,\n messageCount,\n summary: normalizeSummary(summary),\n };\n })\n .sort((a, b) => b.modified.getTime() - a.modified.getTime())\n .slice(0, 50);\n\n return jsonlFiles;\n }\n\n getGlobalDataPath() {\n return path.join(this.globalConfigDir, 'data.json');\n }\n}\n\nfunction normalizeSummary(summary: string): string {\n if (!summary) return '';\n return summary\n .replace(/\\r\\n|\\r|\\n/g, ' ') // Replace all line breaks with spaces\n .replace(/\\s+/g, ' ') // Merge consecutive whitespace characters into single space\n .trim(); // Remove leading and trailing whitespace\n}\n\nfunction extractFirstUserMessageSummary(lines: string[]): string {\n for (const line of lines) {\n try {\n const entry: LogEntry = JSON.parse(line);\n if (\n entry.type === 'message' &&\n 'role' in entry &&\n entry.role === 'user' &&\n typeof entry.content === 'string'\n ) {\n return entry.content.length > 50\n ? entry.content.slice(0, 50) + '...'\n : entry.content;\n }\n } catch (e) {}\n }\n return '';\n}\n\nfunction formatPath(from: string) {\n return from\n .replace(/^\\/+|\\/+$/g, '') // Remove leading/trailing slashes\n .replace(/[^a-zA-Z0-9]/g, '-')\n .replace(/-+/g, '-') // Collapse multiple dashes\n .replace(/^-+|-+$/g, '') // Remove leading/trailing dashes\n .toLowerCase(); // Ensure consistency across filesystems\n}\n","import degit from 'degit';\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'pathe';\nimport type { Context } from '../core/context';\nimport type { Paths } from '../core/paths';\nimport { PluginHookType } from '../core/plugin';\nimport { safeFrontMatter } from '../utils/safeFrontMatter';\n\n/**\n * Check if a directory entry is a directory or a symlink pointing to a directory.\n */\nfunction isDirOrSymlinkToDir(parentDir: string, entry: fs.Dirent): boolean {\n if (entry.isDirectory()) return true;\n if (entry.isSymbolicLink()) {\n try {\n return fs.statSync(path.join(parentDir, entry.name)).isDirectory();\n } catch {\n // broken symlink, skip\n }\n }\n return false;\n}\n\nexport enum SkillSource {\n Plugin = 'plugin',\n GlobalClaude = 'global-claude',\n Global = 'global',\n ProjectClaude = 'project-claude',\n Project = 'project',\n}\n\nexport interface SkillMetadata {\n name: string;\n description: string;\n path: string;\n source: SkillSource;\n}\n\nexport interface SkillError {\n path: string;\n message: string;\n}\n\nexport interface SkillLoadOutcome {\n skills: SkillMetadata[];\n errors: SkillError[];\n}\n\nexport interface AddSkillOptions {\n global?: boolean;\n claude?: boolean;\n overwrite?: boolean;\n name?: string;\n targetDir?: string;\n}\n\nexport interface SkillPreview {\n name: string;\n description: string;\n skillPath: string;\n skillDir: string;\n}\n\nexport interface PreviewSkillsResult {\n tempDir: string;\n skills: SkillPreview[];\n errors: SkillError[];\n}\n\nexport interface AddSkillResult {\n installed: SkillMetadata[];\n skipped: { name: string; reason: string }[];\n errors: SkillError[];\n}\n\nconst MAX_NAME_LENGTH = 64;\nconst MAX_DESCRIPTION_LENGTH = 2048;\n\nexport interface SkillManagerOpts {\n context: Context;\n}\n\nexport class SkillManager {\n private skillsMap: Map<string, SkillMetadata> = new Map();\n private errors: SkillError[] = [];\n private paths: Paths;\n private context: Context;\n\n constructor(opts: SkillManagerOpts) {\n this.context = opts.context;\n this.paths = opts.context.paths;\n }\n\n getSkills(): SkillMetadata[] {\n return Array.from(this.skillsMap.values());\n }\n\n getSkill(name: string): SkillMetadata | undefined {\n return this.skillsMap.get(name);\n }\n\n getErrors(): SkillError[] {\n return this.errors;\n }\n\n async readSkillBody(skill: SkillMetadata): Promise<string> {\n try {\n const content = fs.readFileSync(skill.path, 'utf-8');\n const { body } = safeFrontMatter(content, skill.path);\n return body;\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'Unknown error reading skill';\n throw new Error(`Failed to read skill ${skill.name}: ${message}`);\n }\n }\n\n async loadSkills(): Promise<void> {\n this.skillsMap.clear();\n this.errors = [];\n\n const pluginSkills = await this.context.apply({\n hook: 'skill',\n args: [],\n memo: [],\n type: PluginHookType.SeriesMerge,\n });\n\n if (Array.isArray(pluginSkills)) {\n for (const skillPath of pluginSkills) {\n if (typeof skillPath !== 'string') {\n this.errors.push({\n path: String(skillPath),\n message: 'Invalid skill path type: expected string',\n });\n continue;\n }\n if (!fs.existsSync(skillPath)) {\n this.errors.push({\n path: skillPath,\n message: 'Skill file not found',\n });\n continue;\n }\n this.loadSkillFile(skillPath, SkillSource.Plugin);\n }\n }\n\n const globalClaudeDir = path.join(\n path.dirname(this.paths.globalConfigDir),\n '.claude',\n 'skills',\n );\n this.loadSkillsFromDirectory(globalClaudeDir, SkillSource.GlobalClaude);\n\n const globalDir = path.join(this.paths.globalConfigDir, 'skills');\n this.loadSkillsFromDirectory(globalDir, SkillSource.Global);\n\n const projectClaudeDir = path.join(\n path.dirname(this.paths.projectConfigDir),\n '.claude',\n 'skills',\n );\n this.loadSkillsFromDirectory(projectClaudeDir, SkillSource.ProjectClaude);\n\n const projectDir = path.join(this.paths.projectConfigDir, 'skills');\n this.loadSkillsFromDirectory(projectDir, SkillSource.Project);\n }\n\n private loadSkillsFromDirectory(\n skillsDir: string,\n source: SkillSource,\n ): void {\n if (!fs.existsSync(skillsDir)) {\n return;\n }\n\n try {\n const entries = fs.readdirSync(skillsDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (isDirOrSymlinkToDir(skillsDir, entry)) {\n const skillPath = path.join(skillsDir, entry.name, 'SKILL.md');\n if (fs.existsSync(skillPath)) {\n this.loadSkillFile(skillPath, source);\n }\n }\n }\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : 'Unknown error scanning directory';\n this.errors.push({\n path: skillsDir,\n message: `Failed to scan skills directory: ${message}`,\n });\n }\n }\n\n private loadSkillFile(skillPath: string, source: SkillSource): void {\n try {\n const content = fs.readFileSync(skillPath, 'utf-8');\n const parsed = this.parseSkillFile(content, skillPath);\n\n if (parsed) {\n this.skillsMap.set(parsed.name, { ...parsed, source });\n }\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'Unknown error loading skill';\n this.errors.push({\n path: skillPath,\n message,\n });\n }\n }\n\n private parseSkillFile(\n content: string,\n skillPath: string,\n ): Omit<SkillMetadata, 'source'> | null {\n try {\n const { attributes } = safeFrontMatter<{\n name?: string;\n description?: string;\n }>(content, skillPath);\n\n if (!attributes.name) {\n this.errors.push({\n path: skillPath,\n message: 'Missing required field: name',\n });\n return null;\n }\n\n if (!attributes.description) {\n this.errors.push({\n path: skillPath,\n message: 'Missing required field: description',\n });\n return null;\n }\n\n if (attributes.name.length > MAX_NAME_LENGTH) {\n this.errors.push({\n path: skillPath,\n message: `Name exceeds maximum length of ${MAX_NAME_LENGTH} characters`,\n });\n return null;\n }\n\n if (attributes.name.includes('\\n')) {\n this.errors.push({\n path: skillPath,\n message: 'Name must be a single line',\n });\n return null;\n }\n\n if (attributes.description.length > MAX_DESCRIPTION_LENGTH) {\n this.errors.push({\n path: skillPath,\n message: `Description exceeds maximum length of ${MAX_DESCRIPTION_LENGTH} characters`,\n });\n return null;\n }\n\n return {\n name: attributes.name,\n description: attributes.description,\n path: skillPath,\n };\n } catch (error) {\n this.errors.push({\n path: skillPath,\n message:\n error instanceof Error\n ? error.message\n : 'Failed to parse frontmatter',\n });\n return null;\n }\n }\n\n async addSkill(\n source: string,\n options: AddSkillOptions = {},\n ): Promise<AddSkillResult> {\n const {\n global: isGlobal = false,\n claude: isClaude = false,\n overwrite = false,\n name,\n targetDir,\n } = options;\n const result: AddSkillResult = {\n installed: [],\n skipped: [],\n errors: [],\n };\n\n const tempDir = path.join(os.tmpdir(), `oricore-skill-${Date.now()}`);\n\n try {\n const normalizedSource = this.normalizeSource(source);\n const emitter = degit(normalizedSource, { force: true });\n await emitter.clone(tempDir);\n\n const skillPaths = this.scanForSkills(tempDir);\n\n if (skillPaths.length === 0) {\n result.errors.push({\n path: source,\n message: 'No skills found (no SKILL.md files)',\n });\n return result;\n }\n\n if (name && skillPaths.length > 1) {\n throw new Error(\n 'Cannot use --name when source contains multiple skills',\n );\n }\n\n const targetBaseDir = targetDir\n ? targetDir\n : isClaude && isGlobal\n ? path.join(\n path.dirname(this.paths.globalConfigDir),\n '.claude',\n 'skills',\n )\n : isClaude\n ? path.join(\n path.dirname(this.paths.projectConfigDir),\n '.claude',\n 'skills',\n )\n : isGlobal\n ? path.join(this.paths.globalConfigDir, 'skills')\n : path.join(this.paths.projectConfigDir, 'skills');\n\n fs.mkdirSync(targetBaseDir, { recursive: true });\n\n for (const skillPath of skillPaths) {\n const skillDir = path.dirname(skillPath);\n const isRootSkill = skillDir === tempDir;\n const folderName =\n name ||\n (isRootSkill\n ? this.extractFolderName(source)\n : path.basename(skillDir));\n const targetDir = path.join(targetBaseDir, folderName);\n\n const content = fs.readFileSync(skillPath, 'utf-8');\n const parsed = this.parseSkillFileForAdd(content, skillPath);\n\n if (!parsed) {\n result.errors.push({\n path: skillPath,\n message: 'Invalid skill file',\n });\n continue;\n }\n\n if (fs.existsSync(targetDir)) {\n if (!overwrite) {\n result.skipped.push({\n name: parsed.name,\n reason: 'already exists',\n });\n continue;\n }\n fs.rmSync(targetDir, { recursive: true });\n }\n\n this.copyDirectory(skillDir, targetDir);\n\n result.installed.push({\n name: parsed.name,\n description: parsed.description,\n path: path.join(targetDir, 'SKILL.md'),\n source:\n isClaude && isGlobal\n ? SkillSource.GlobalClaude\n : isClaude\n ? SkillSource.ProjectClaude\n : isGlobal\n ? SkillSource.Global\n : SkillSource.Project,\n });\n }\n\n await this.loadSkills();\n } finally {\n if (fs.existsSync(tempDir)) {\n fs.rmSync(tempDir, { recursive: true });\n }\n }\n\n return result;\n }\n\n private normalizeSource(source: string): string {\n let normalized = source;\n\n if (\n normalized.startsWith('https://github.com/') ||\n normalized.startsWith('http://github.com/')\n ) {\n normalized = normalized.replace(/^https?:\\/\\/github\\.com\\//, '');\n const treeMatch = normalized.match(\n /^([^/]+\\/[^/]+)\\/tree\\/([^/]+)(?:\\/(.+))?$/,\n );\n if (treeMatch) {\n const [, repo, branch, subpath] = treeMatch;\n normalized = subpath\n ? `${repo}/${subpath}#${branch}`\n : `${repo}#${branch}`;\n }\n return `github:${normalized}`;\n }\n\n if (\n !normalized.startsWith('github:') &&\n !normalized.startsWith('gitlab:') &&\n !normalized.startsWith('bitbucket:')\n ) {\n return `github:${normalized}`;\n }\n return normalized;\n }\n\n private extractFolderName(source: string): string {\n let normalized = source\n .replace(/^https?:\\/\\/github\\.com\\//, '')\n .replace(/^github:/, '')\n .replace(/^gitlab:/, '')\n .replace(/^bitbucket:/, '');\n\n const treeMatchWithPath = normalized.match(\n /^[^/]+\\/[^/]+\\/tree\\/[^/]+\\/(.+)$/,\n );\n if (treeMatchWithPath) {\n normalized = treeMatchWithPath[1];\n } else {\n const treeMatchBranchOnly = normalized.match(\n /^([^/]+)\\/([^/]+)\\/tree\\/[^/]+$/,\n );\n if (treeMatchBranchOnly) {\n normalized = treeMatchBranchOnly[2];\n }\n }\n\n normalized = normalized.replace(/#.*$/, '');\n const lastSegment = normalized.split('/').filter(Boolean).pop();\n return lastSegment || 'skill';\n }\n\n private scanForSkills(dir: string): string[] {\n const skills: string[] = [];\n\n const rootSkill = path.join(dir, 'SKILL.md');\n if (fs.existsSync(rootSkill)) {\n skills.push(rootSkill);\n return skills;\n }\n\n const skillsDir = path.join(dir, 'skills');\n if (fs.existsSync(skillsDir) && fs.statSync(skillsDir).isDirectory()) {\n const entries = fs.readdirSync(skillsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (isDirOrSymlinkToDir(skillsDir, entry)) {\n const skillPath = path.join(skillsDir, entry.name, 'SKILL.md');\n if (fs.existsSync(skillPath)) {\n skills.push(skillPath);\n }\n }\n }\n if (skills.length > 0) {\n return skills;\n }\n }\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (isDirOrSymlinkToDir(dir, entry)) {\n const skillPath = path.join(dir, entry.name, 'SKILL.md');\n if (fs.existsSync(skillPath)) {\n skills.push(skillPath);\n }\n }\n }\n\n return skills;\n }\n\n private copyDirectory(src: string, dest: string): void {\n fs.mkdirSync(dest, { recursive: true });\n const entries = fs.readdirSync(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const destPath = path.join(dest, entry.name);\n\n if (entry.isDirectory()) {\n this.copyDirectory(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n }\n\n private parseSkillFileForAdd(\n content: string,\n skillPath: string,\n ): { name: string; description: string } | null {\n try {\n const { attributes } = safeFrontMatter<{\n name?: string;\n description?: string;\n }>(content, skillPath);\n\n if (!attributes.name || !attributes.description) {\n return null;\n }\n\n if (\n attributes.name.length > MAX_NAME_LENGTH ||\n attributes.name.includes('\\n')\n ) {\n return null;\n }\n\n if (attributes.description.length > MAX_DESCRIPTION_LENGTH) {\n return null;\n }\n\n return {\n name: attributes.name,\n description: attributes.description,\n };\n } catch {\n return null;\n }\n }\n\n async previewSkills(source: string): Promise<PreviewSkillsResult> {\n const tempDir = path.join(os.tmpdir(), `oricore-skill-${Date.now()}`);\n const result: PreviewSkillsResult = {\n tempDir,\n skills: [],\n errors: [],\n };\n\n const normalizedSource = this.normalizeSource(source);\n const emitter = degit(normalizedSource, { force: true });\n await emitter.clone(tempDir);\n\n const skillPaths = this.scanForSkills(tempDir);\n\n if (skillPaths.length === 0) {\n result.errors.push({\n path: source,\n message: 'No skills found (no SKILL.md files)',\n });\n return result;\n }\n\n for (const skillPath of skillPaths) {\n const content = fs.readFileSync(skillPath, 'utf-8');\n const parsed = this.parseSkillFileForAdd(content, skillPath);\n\n if (!parsed) {\n result.errors.push({\n path: skillPath,\n message: 'Invalid skill file',\n });\n continue;\n }\n\n result.skills.push({\n name: parsed.name,\n description: parsed.description,\n skillPath,\n skillDir: path.dirname(skillPath),\n });\n }\n\n return result;\n }\n\n async installFromPreview(\n preview: PreviewSkillsResult,\n selectedSkills: SkillPreview[],\n source: string,\n options: AddSkillOptions = {},\n ): Promise<AddSkillResult> {\n const {\n global: isGlobal = false,\n claude: isClaude = false,\n overwrite = false,\n name,\n targetDir,\n } = options;\n const result: AddSkillResult = {\n installed: [],\n skipped: [],\n errors: [],\n };\n\n if (name && selectedSkills.length > 1) {\n throw new Error('Cannot use --name when installing multiple skills');\n }\n\n const targetBaseDir = targetDir\n ? targetDir\n : isClaude && isGlobal\n ? path.join(\n path.dirname(this.paths.globalConfigDir),\n '.claude',\n 'skills',\n )\n : isClaude\n ? path.join(\n path.dirname(this.paths.projectConfigDir),\n '.claude',\n 'skills',\n )\n : isGlobal\n ? path.join(this.paths.globalConfigDir, 'skills')\n : path.join(this.paths.projectConfigDir, 'skills');\n\n fs.mkdirSync(targetBaseDir, { recursive: true });\n\n for (const skill of selectedSkills) {\n const isRootSkill = skill.skillDir === preview.tempDir;\n const folderName =\n name ||\n (isRootSkill\n ? this.extractFolderName(source)\n : path.basename(skill.skillDir));\n const skillTargetDir = path.join(targetBaseDir, folderName);\n\n if (fs.existsSync(skillTargetDir)) {\n if (!overwrite) {\n result.skipped.push({\n name: skill.name,\n reason: 'already exists',\n });\n continue;\n }\n fs.rmSync(skillTargetDir, { recursive: true });\n }\n\n this.copyDirectory(skill.skillDir, skillTargetDir);\n\n result.installed.push({\n name: skill.name,\n description: skill.description,\n path: path.join(skillTargetDir, 'SKILL.md'),\n source:\n isClaude && isGlobal\n ? SkillSource.GlobalClaude\n : isClaude\n ? SkillSource.ProjectClaude\n : isGlobal\n ? SkillSource.Global\n : SkillSource.Project,\n });\n }\n\n await this.loadSkills();\n return result;\n }\n\n cleanupPreview(preview: PreviewSkillsResult): void {\n if (fs.existsSync(preview.tempDir)) {\n fs.rmSync(preview.tempDir, { recursive: true });\n }\n }\n\n async removeSkill(\n name: string,\n targetDir?: string,\n ): Promise<{ success: boolean; error?: string }> {\n const skillsDir =\n targetDir || path.join(this.paths.projectConfigDir, 'skills');\n const skillDir = path.join(skillsDir, name);\n\n if (!fs.existsSync(skillDir)) {\n return { success: false, error: 'Skill not found' };\n }\n\n const skillPath = path.join(skillDir, 'SKILL.md');\n if (!fs.existsSync(skillPath)) {\n return { success: false, error: 'Invalid skill directory (no SKILL.md)' };\n }\n\n fs.rmSync(skillDir, { recursive: true });\n await this.loadSkills();\n return { success: true };\n }\n}\n","import EventEmitter from 'events';\nimport { randomUUID } from '../utils/randomUUID';\n\nexport type MessageId = string;\nexport type BaseMessage = {\n id: MessageId;\n timestamp: number;\n};\nexport type RequestMessage = BaseMessage & {\n type: 'request';\n method: string;\n params: any;\n};\nexport type ResponseMessage = BaseMessage & {\n type: 'response';\n result?: any;\n error?: any;\n};\nexport type EventMessage = BaseMessage & {\n type: 'event';\n event: string;\n data: any;\n};\nexport type Message = RequestMessage | ResponseMessage | EventMessage;\nexport type ConnectionState =\n | 'disconnected'\n | 'connecting'\n | 'connected'\n | 'reconnecting'\n | 'error'\n | 'closed';\nexport interface MessageTransport {\n send: (message: Message) => Promise<void>;\n onMessage: (handler: (message: Message) => void) => void;\n onError: (handler: (error: Error) => void) => void;\n onClose: (handler: () => void) => void;\n close: () => Promise<void>;\n isConnected: () => boolean;\n}\n\nfunction createRequest(\n id: MessageId,\n method: string,\n params: any,\n): RequestMessage {\n return {\n type: 'request',\n id,\n method,\n params,\n timestamp: Date.now(),\n };\n}\n\nfunction createResponse(\n id: MessageId,\n result: any,\n error?: any,\n): ResponseMessage {\n return {\n type: 'response',\n id,\n result,\n error,\n timestamp: Date.now(),\n };\n}\nfunction createErrorResponse(id: MessageId, error: any): ResponseMessage {\n return {\n type: 'response',\n id,\n error,\n timestamp: Date.now(),\n };\n}\nfunction createEvent(id: MessageId, event: string, data: any): EventMessage {\n return {\n type: 'event',\n id,\n event,\n data,\n timestamp: Date.now(),\n };\n}\n\nconst MAX_BUFFER_SIZE = 1000;\n\nexport class DirectTransport extends EventEmitter implements MessageTransport {\n private peer?: DirectTransport;\n private state: ConnectionState = 'connected';\n private messageBuffer: Message[] = [];\n constructor() {\n super();\n }\n static createPair(): [DirectTransport, DirectTransport] {\n const transport1 = new DirectTransport();\n const transport2 = new DirectTransport();\n transport1.setPeer(transport2);\n transport2.setPeer(transport1);\n return [transport1, transport2];\n }\n setPeer(peer: DirectTransport) {\n this.peer = peer;\n this.flushBuffer();\n }\n isConnected() {\n return this.state === 'connected';\n }\n onMessage(handler: (message: Message) => void): void {\n this.on('message', handler);\n }\n onError(handler: (error: Error) => void): void {\n this.on('error', handler);\n }\n onClose(handler: () => void): void {\n this.on('close', handler);\n }\n async send(message: Message) {\n try {\n if (this.peer && this.peer.isConnected()) {\n setImmediate(() => {\n this.peer!.receive(message);\n });\n } else {\n this.messageBuffer.push(message);\n }\n } catch (error) {\n this.emit('error', error);\n throw error;\n }\n }\n async close() {\n this.state = 'closed';\n }\n private flushBuffer() {\n if (\n !this.peer ||\n !this.peer.isConnected() ||\n this.messageBuffer.length === 0\n ) {\n return;\n }\n if (this.messageBuffer.length > MAX_BUFFER_SIZE) {\n this.emit('error', new Error('Message buffer overflow'));\n return;\n }\n const messages = [...this.messageBuffer];\n this.messageBuffer.length = 0;\n for (const message of messages) {\n setImmediate(() => {\n this.peer!.receive(message);\n });\n }\n }\n private receive(message: Message) {\n if (this.state !== 'connected') {\n return;\n }\n try {\n this.emit('message', message);\n } catch (error) {\n this.emit('error', error);\n }\n }\n}\n\ntype PendingRequest = {\n id: MessageId;\n method: string;\n timestamp: number;\n timeout?: NodeJS.Timeout;\n resolve: (result: any) => void;\n reject: (error: Error) => void;\n};\nexport type MessageHandler = (data: any) => Promise<any>;\nexport type EventHandler = (data: any) => void;\n\nexport class MessageBus extends EventEmitter {\n public messageHandlers = new Map<string, MessageHandler>();\n private transport?: MessageTransport;\n private pendingRequests = new Map<MessageId, PendingRequest>();\n private eventHandlers = new Map<string, Set<EventHandler>>();\n constructor() {\n super();\n }\n setTransport(transport: MessageTransport) {\n this.transport = transport;\n transport.onMessage((message) => {\n this.handleIncomingMessage(message);\n });\n transport.onError((error) => {\n this.emit('error', error);\n });\n transport.onClose(() => {\n this.emit('close');\n });\n this.emit('transportReady');\n }\n isConnected() {\n return this.transport?.isConnected() ?? false;\n }\n\n // Request method - generic version for engine package\n /**\n * Send a request to the message bus and wait for a response.\n *\n * @param method - The method name to call (e.g., 'toolApproval')\n * @param params - The parameters to pass to the method handler\n * @param options.timeout - Optional timeout in milliseconds (0 = no timeout)\n * @returns Promise that resolves with the handler's return value\n *\n * @example\n * // Tool approval with session context\n * const result = await messageBus.request('toolApproval', {\n * toolUse: { name: 'bash', params: { command: 'ls' }, callId: '123' },\n * category: 'command',\n * sessionId: 'session-abc' // Used for session identification\n * });\n *\n * @example\n * // Register a handler for the request\n * messageBus.registerHandler('toolApproval', async ({ toolUse, category, sessionId }) => {\n * // sessionId can be used for:\n * // - Logging which session requested approval\n * // - UI routing to the correct session window\n * // - Multi-session management\n * return { approved: true, params: undefined, denyReason: undefined };\n * });\n */\n async request(\n method: string,\n params: any,\n options: { timeout?: number } = {},\n ): Promise<any> {\n if (!this.transport) {\n throw new Error('No transport available');\n }\n if (!this.transport.isConnected()) {\n throw new Error('Transport is not connected');\n }\n const id = randomUUID();\n const timeout = options.timeout ?? 0;\n const requestMessage = createRequest(id, method, params);\n const promise = new Promise<any>((resolve, reject) => {\n const pendingRequest: PendingRequest = {\n id,\n method,\n timestamp: Date.now(),\n resolve,\n reject,\n };\n if (timeout > 0) {\n pendingRequest.timeout = setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(new Error(`Request timeout after ${timeout}ms: ${method}`));\n }, timeout);\n }\n this.pendingRequests.set(id, pendingRequest);\n });\n try {\n await this.transport.send(requestMessage);\n return await promise;\n } catch (error) {\n // Clean up pending request if send fails or promise rejects\n const pending = this.pendingRequests.get(id);\n if (pending) {\n if (pending.timeout) {\n clearTimeout(pending.timeout);\n }\n this.pendingRequests.delete(id);\n }\n throw error;\n }\n }\n // Register handler - generic version for engine package\n /**\n * Register a handler for a specific request method.\n *\n * @param method - The method name to handle (e.g., 'toolApproval')\n * @param handler - Async function that receives params and returns a result\n *\n * @example\n * // Tool approval handler with session support\n * messageBus.registerHandler('toolApproval', async (params) => {\n * const { toolUse, category, sessionId } = params;\n *\n * // sessionId enables:\n * // 1. Session-specific logging and monitoring\n * // 2. UI routing to the correct session window\n * // 3. Multi-session approval tracking\n * // 4. Session-level permissions and policies\n *\n * console.log(`[${sessionId}] Tool approval request: ${toolUse.name}`);\n *\n * // Return approval result\n * return {\n * approved: true,\n * params: toolUse.params, // optionally modify params\n * denyReason: undefined // or provide reason if denied\n * };\n * });\n *\n * // Backward compatibility: handlers can ignore sessionId\n * messageBus.registerHandler('toolApproval', async ({ toolUse, category }) => {\n * // Old code that doesn't use sessionId still works\n * return { approved: true };\n * });\n */\n registerHandler(method: string, handler: MessageHandler) {\n this.messageHandlers.set(method, handler);\n }\n unregisterHandler(method: string) {\n if (this.messageHandlers.has(method)) {\n this.messageHandlers.delete(method);\n }\n }\n async emitEvent(event: string, data: any) {\n if (!this.transport) {\n return;\n }\n if (!this.transport.isConnected()) {\n return;\n }\n const id = randomUUID();\n const message = createEvent(id, event, data);\n try {\n await this.transport.send(message);\n } catch (error) {\n throw error;\n }\n }\n onEvent(event: string, handler: EventHandler) {\n if (!this.eventHandlers.has(event)) {\n this.eventHandlers.set(event, new Set());\n }\n this.eventHandlers.get(event)!.add(handler);\n }\n offEvent(event: string, handler: EventHandler) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n if (handlers.size === 0) {\n this.eventHandlers.delete(event);\n }\n }\n }\n private async handleIncomingMessage(message: Message) {\n try {\n if (!message.id || !message.timestamp || !message.type) {\n throw new Error('Invalid message format');\n }\n switch (message.type) {\n case 'request':\n await this.handleRequest(message as RequestMessage);\n break;\n case 'response':\n this.handleResponse(message as ResponseMessage);\n break;\n case 'event':\n this.handleEvent(message as EventMessage);\n break;\n default:\n break;\n }\n } catch (error) {\n this.emit('messageError', error, message);\n }\n }\n private async handleRequest(message: RequestMessage) {\n const { id, method, params } = message;\n const handler = this.messageHandlers.get(method);\n if (!handler) {\n await this.sendResponse(\n createErrorResponse(id, {\n message: `No handler registered for method: ${method}`,\n code: 'METHOD_NOT_FOUND',\n }),\n );\n return;\n }\n try {\n const result = await handler(params);\n const response = createResponse(id, result);\n await this.sendResponse(response);\n } catch (error) {\n await this.sendResponse(\n createErrorResponse(id, {\n message: error instanceof Error ? error.message : String(error),\n code: 'HANDLER_ERROR',\n details: error instanceof Error ? { stack: error.stack } : undefined,\n }),\n );\n }\n }\n private async handleResponse(message: ResponseMessage) {\n const { id, result, error } = message;\n const pending = this.pendingRequests.get(id);\n if (!pending) {\n return;\n }\n if (pending.timeout) {\n clearTimeout(pending.timeout);\n }\n this.pendingRequests.delete(id);\n if (error) {\n // Create a more informative error\n const errorMessage =\n typeof error === 'object' && error.message\n ? error.message\n : typeof error === 'string'\n ? error\n : 'Request failed';\n\n const err = new Error(errorMessage);\n // Attach the full error details\n (err as any).details = error.details\n ? Array.isArray(error.details)\n ? error.details.join('\\n')\n : JSON.stringify(error.details)\n : error;\n (err as any).method = pending.method;\n\n pending.reject(err);\n } else {\n pending.resolve(result);\n }\n }\n private async handleEvent(message: EventMessage) {\n const { event, data } = message;\n const handlers = this.eventHandlers.get(event);\n if (!handlers || handlers.size === 0) {\n return;\n }\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n this.emit('eventHandlerError', error, event, data);\n }\n }\n }\n private async sendResponse(response: ResponseMessage) {\n if (!this.transport) {\n return;\n }\n try {\n await this.transport.send(response);\n } catch (error) {\n throw error;\n }\n }\n}\n","/**\n * Node.js platform implementation\n * Provides Node.js-specific implementations for the PlatformAdapter interface\n */\n\nimport fs from 'node:fs';\nimport path from 'pathe';\nimport { execSync } from 'node:child_process';\nimport os from 'node:os';\nimport type { PlatformAdapter, ExecOptions, ExecResult, Stats } from './types';\n\nexport class NodePlatform implements PlatformAdapter {\n // File system - async\n readFile = (path: string): Promise<string> =>\n fs.promises.readFile(path, 'utf-8');\n\n writeFile = (path: string, content: string): Promise<void> =>\n fs.promises.writeFile(path, content, 'utf-8');\n\n // File system - sync\n readFileSync = (path: string): string =>\n fs.readFileSync(path, 'utf-8');\n\n writeFileSync = (path: string, content: string): void =>\n fs.writeFileSync(path, content, 'utf-8');\n\n existsSync = (path: string): boolean =>\n fs.existsSync(path);\n\n mkdirSync = (path: string, options?: { recursive: boolean }): void => {\n fs.mkdirSync(path, options);\n };\n\n readdirSync = (path: string): string[] =>\n fs.readdirSync(path);\n\n statSync = (path: string): Stats => {\n const stats = fs.statSync(path);\n return {\n size: stats.size,\n mtime: stats.mtimeMs,\n birthtime: stats.birthtimeMs,\n };\n };\n\n // Process\n cwd = (): string => process.cwd();\n\n env = process.env;\n\n platform = process.platform;\n\n // Exec\n exec = async (command: string, options?: ExecOptions): Promise<ExecResult> => {\n try {\n const stdout = execSync(command, {\n cwd: options?.cwd,\n env: { ...process.env, ...options?.env },\n timeout: options?.timeout,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n return {\n stdout: stdout.toString(),\n stderr: '',\n exitCode: 0,\n };\n } catch (error: any) {\n return {\n stdout: error.stdout?.toString() || '',\n stderr: error.stderr?.toString() || error.message || '',\n exitCode: error.status || 1,\n };\n }\n };\n\n // Paths\n join = (...paths: string[]): string => path.join(...paths);\n\n dirname = (filePath: string): string => path.dirname(filePath);\n\n basename = (filePath: string): string => path.basename(filePath);\n\n resolve = (...paths: string[]): string => path.resolve(...paths);\n\n // Configuration directories\n getConfigDir = (): string => {\n const base = process.platform === 'darwin'\n ? path.join(os.homedir(), 'Library', 'Application Support')\n : process.platform === 'win32'\n ? process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming')\n : path.join(os.homedir(), '.config');\n return base;\n };\n\n getDataDir = (): string => {\n const base = process.platform === 'darwin'\n ? path.join(os.homedir(), 'Library', 'Application Support')\n : process.platform === 'win32'\n ? process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming')\n : path.join(os.homedir(), '.local', 'share');\n return base;\n };\n}\n\n// Export a singleton instance for convenience\nexport const nodePlatform = new NodePlatform();\n","import fs from 'fs';\nimport path from 'pathe';\nimport type { NormalizedMessage } from './core/message';\nimport { createUserMessage } from './core/message';\n\n/**\n * JsonlLogger - Handles persistent logging of messages to JSONL files\n *\n * Each message is appended as a JSON line, enabling:\n * - Session persistence across restarts\n * - Message history recovery\n * - Debugging and auditing\n */\nexport class JsonlLogger {\n filePath: string;\n lastUuid: string | null = null;\n\n constructor(opts: { filePath: string }) {\n this.filePath = opts.filePath;\n this.lastUuid = this.getLatestUuid();\n }\n\n /**\n * Get the UUID of the last message in the log file\n * Used for chaining new messages to the conversation\n */\n getLatestUuid(): string | null {\n if (!fs.existsSync(this.filePath)) {\n return null;\n }\n try {\n const file = fs.readFileSync(this.filePath, 'utf8');\n const lines = file.split('\\n').filter(Boolean);\n if (lines.length === 0) {\n return null;\n }\n const lastLine = lines[lines.length - 1];\n const message = JSON.parse(lastLine);\n return message.uuid || null;\n } catch {\n return null;\n }\n }\n\n /**\n * Add a message to the log file\n * Also updates the lastUuid for chaining\n */\n addMessage(opts: { message: NormalizedMessage & { sessionId: string } }): NormalizedMessage & { sessionId: string } {\n const dir = path.dirname(this.filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n const message = opts.message;\n fs.appendFileSync(this.filePath, JSON.stringify(message) + '\\n');\n this.lastUuid = message.uuid;\n return message;\n }\n\n /**\n * Add a user message to the log file\n * Convenience method that creates a user message with proper chaining\n */\n addUserMessage(content: string, sessionId: string): NormalizedMessage & { sessionId: string } {\n const message = {\n ...createUserMessage(content, this.lastUuid),\n sessionId,\n };\n return this.addMessage({\n message,\n });\n }\n}\n","/**\n * Mode Registry\n *\n * Manages AI interaction modes\n */\n\nimport type { Mode, ModeRegistry, ModeType } from './types';\n\nexport class ModeRegistryImpl implements ModeRegistry {\n private modes = new Map<ModeType, Mode>();\n\n register(mode: Mode): void {\n if (this.modes.has(mode.id)) {\n throw new Error(`Mode ${mode.id} is already registered`);\n }\n this.modes.set(mode.id, mode);\n }\n\n unregister(id: ModeType): void {\n this.modes.delete(id);\n }\n\n get(id: ModeType): Mode | undefined {\n return this.modes.get(id);\n }\n\n getAll(): Mode[] {\n return Array.from(this.modes.values());\n }\n\n has(id: ModeType): boolean {\n return this.modes.has(id);\n }\n}\n\n/**\n * Global mode registry instance\n */\nexport const modeRegistry = new ModeRegistryImpl();\n","/**\n * Built-in Modes\n *\n * Pre-defined AI interaction modes\n */\n\nimport type { Mode } from './types';\n\n/**\n * Default mode - general purpose AI assistant\n */\nexport const defaultMode: Mode = {\n id: 'default',\n name: 'Default',\n description: 'General purpose AI coding assistant',\n config: {\n systemPrompt: `You are Claude Code, an AI programming assistant.\n\n## Core Principles\n- Be concise and direct\n- Show code when helpful\n- Use tools to complete tasks\n- Ask for clarification when needed\n- Verify your work when possible\n\n## Tool Usage\n- Use read tools to understand code\n- Use write/edit tools to make changes\n- Use bash to run commands and tests\n- Use todo to track progress\n\n## Communication Style\n- Be helpful but concise\n- Focus on what matters\n- Explain trade-offs when relevant`,\n write: true,\n todo: true,\n askUserQuestion: false,\n task: true,\n maxTurns: 50,\n autoCompact: true,\n },\n};\n\n/**\n * Brainstorm mode - interactive design and ideation\n */\nexport const brainstormMode: Mode = {\n id: 'brainstorm',\n name: 'Brainstorm',\n description: 'Interactive design and ideation mode - asks questions to refine ideas',\n config: {\n systemPrompt: `# Brainstorming Ideas Into Designs\n\n## Overview\nTransform rough ideas into fully-formed designs through structured questioning and alternative exploration.\n\n**Core principle:** Ask questions to understand, explore alternatives, present design incrementally for validation.\n\n**Announce at start:** \"I'm refining your idea into a design.\"\n\n## Critical Constraints\n- **DO NOT WRITE CODE** (except small snippets for illustration)\n- **DO NOT EDIT FILES**\n- This is a **DESIGN** phase, not an implementation phase\n- Even if the input looks like a coding task, you must TREAT IT AS A TOPIC FOR DESIGN DISCUSSION first\n\n## The Process\n\n### Phase 1: Understanding\n- Check current project state in working directory\n- Ask ONE question at a time to refine the idea\n- **IMPORTANT: Use the askUserQuestion tool when asking clarification questions**\n- Prefer multiple choice when possible\n- Gather: Purpose, constraints, success criteria\n\n### Phase 2: Exploration\n- Propose 2-3 different approaches\n- For each: Core architecture, trade-offs, complexity assessment\n- Ask which approach resonates\n\n### Phase 3: Design Presentation\n- Present in 200-300 word sections\n- Cover: Architecture, components, data flow, error handling, testing\n- Ask after each section: \"Does this look right so far?\"\n\n## When to Revisit Earlier Phases\nYou can and should go backward when:\n- Partner reveals new constraint during Phase 2 or 3 → Return to Phase 1\n- Validation shows fundamental gap in requirements → Return to Phase 1\n- Partner questions approach during Phase 3 → Return to Phase 2\n- Something doesn't make sense → Go back and clarify\n\nDon't force forward linearly when going backward would give better results.\n\n## Remember\n- One question per message during Phase 1\n- Apply YAGNI ruthlessly\n- Explore 2-3 alternatives before settling\n- Present incrementally, validate as you go\n- Go backward when needed - flexibility > rigid progression\n- Don't edit or write code during brainstorming`,\n write: false,\n todo: false,\n askUserQuestion: true, // Critical for interactive brainstorming\n task: false,\n maxTurns: 50,\n autoCompact: false, // Keep full conversation for context\n },\n};\n\n/**\n * Plan mode - create implementation plans\n */\nexport const planMode: Mode = {\n id: 'plan',\n name: 'Plan',\n description: 'Create detailed implementation plans',\n config: {\n systemPrompt: `# Writing Plans\n\n## Overview\nWrite comprehensive implementation plans assuming the engineer has zero context for our codebase and questionable taste. Document everything they need to know: which files to touch for each task, code, testing, docs they might need to check, how to test it. Give them the whole plan as bite-sized tasks. DRY. YAGNI.\n\nAssume they are a skilled developer, but know almost nothing about our toolset or problem domain. Assume they don't know good test design very well.\n\n**Announce at start:** \"I'm creating the implementation plan.\"\n\n**Save plans to:** \\`docs/plans/YYYY-MM-DD-<feature-name>.md\\`\n\n## Bite-Sized Task Granularity\n\nEach step is one action (2-5 minutes):\n- \"Write the failing test\" - step\n- \"Run it to make sure it fails\" - step\n- \"Implement the minimal code to make the test pass\" - step\n- \"Run the tests and make sure they pass\" - step\n- \"Commit\" - step\n\n## Plan Document Header\n\nEvery plan MUST start with this header:\n\n\\`\\`\\`markdown\n# [Feature Name] Implementation Plan\n\n**Goal:** [One sentence describing what this builds]\n\n**Architecture:** [2-3 sentences about approach]\n\n**Tech Stack:** [Key technologies/libraries]\n\n---\n\\`\\`\\`\n\n## Task Structure\n\n\\`\\`\\`markdown\n### Task N: [Component Name]\n\n**Files:**\n- Create: \\`exact/path/to/file.py\\`\n- Modify: \\`exact/path/to/existing.py:123-145\\`\n- Test: \\`tests/exact/path/to/test.py\\`\n\n**Step 1: Write the failing test**\n[code here]\n\n**Step 2: Run test to verify it fails**\nRun: \\`pytest tests/path/test.py::test_name -v\\`\nExpected: FAIL\n\n**Step 3: Write minimal implementation**\n[code here]\n\n**Step 4: Run test to verify it passes**\nRun: \\`pytest tests/path/test.py::test_name -v\\`\nExpected: PASS\n\\`\\`\\`\n\n## Remember\n- Exact file paths always\n- Complete code in plan (not \"add validation\")\n- Exact commands with expected output\n- DRY, YAGNI`,\n write: true,\n todo: true,\n askUserQuestion: true,\n task: false,\n maxTurns: 50,\n autoCompact: true,\n },\n};\n\n/**\n * Review mode - code review and analysis\n */\nexport const reviewMode: Mode = {\n id: 'review',\n name: 'Review',\n description: 'Code review and analysis mode',\n config: {\n systemPrompt: `# Code Review Mode\n\nYou are an expert code reviewer. Your role is to:\n\n1. **Understand the context**\n - Read the files mentioned in the diff or description\n - Understand what change is being made\n - Consider the broader codebase architecture\n\n2. **Review systematically**\n - Correctness: Does the code work as intended?\n - Design: Is it well-structured and maintainable?\n - Performance: Are there obvious performance issues?\n - Security: Are there security vulnerabilities?\n - Testing: Is there adequate test coverage?\n\n3. **Provide constructive feedback**\n - Be specific about issues\n - Explain why something is problematic\n - Suggest improvements\n - Acknowledge good practices\n\n4. **Prioritize issues**\n - Critical: Must fix (bugs, security)\n - Important: Should fix (design, performance)\n - Nice to have: Could improve (style, minor optimizations)\n\nFormat your review clearly with:\n- Summary\n- Issues (by priority)\n- Positive observations\n- Suggestions`,\n write: false,\n todo: false,\n askUserQuestion: false,\n task: false,\n maxTurns: 10,\n autoCompact: false,\n },\n};\n\n/**\n * Debug mode - troubleshooting and debugging\n */\nexport const debugMode: Mode = {\n id: 'debug',\n name: 'Debug',\n description: 'Troubleshooting and debugging mode',\n config: {\n systemPrompt: `# Debug Mode\n\nYou are an expert debugger. Your approach:\n\n1. **Understand the problem**\n - Ask what error or behavior they're seeing\n - Get the relevant code\n - Understand expected vs actual behavior\n\n2. **Form hypotheses**\n - Based on the symptoms, what could cause this?\n - Prioritize most likely causes\n\n3. **Test hypotheses**\n - Use read tools to examine code\n - Use bash to run tests or checks\n - Use logs if available\n\n4. **Propose fixes**\n - Start with minimal changes\n - Explain why the fix works\n - Suggest how to prevent similar issues\n\nBe methodical and systematic. Don't guess - verify.`,\n write: true,\n todo: true,\n askUserQuestion: true,\n task: false,\n maxTurns: 50,\n autoCompact: true,\n },\n};\n\n/**\n * All built-in modes\n */\nexport const builtinModes: Mode[] = [\n defaultMode,\n brainstormMode,\n planMode,\n reviewMode,\n debugMode,\n];\n\n/**\n * Register all built-in modes\n */\nexport function registerBuiltinModes(registry: import('./registry').ModeRegistryImpl): void {\n for (const mode of builtinModes) {\n if (!registry.has(mode.id)) {\n registry.register(mode);\n }\n }\n}\n","/**\n * Engine API\n *\n * Main entry point for the OriCore package.\n * Provides a high-level API for AI-powered coding assistance.\n */\n\nimport type { Context } from '../core/context';\nimport { Context as createContext } from '../core/context';\nimport type { Config, ProviderConfig } from '../core/config';\nimport type { MessageBus as IMessageBus } from '../communication/messageBus';\nimport { MessageBus } from '../communication/messageBus';\nimport type { PlatformAdapter } from '../platform';\nimport { NodePlatform } from '../platform/node';\nimport type { Session } from '../session/session';\nimport { Session as createSession } from '../session/session';\nimport { JsonlLogger } from '../jsonl';\nimport { resolveModelWithContext } from '../core/model';\nimport { runLoop, type LoopResult } from '../core/loop';\nimport { resolveTools, Tools } from '../tools/tool';\nimport type { NormalizedMessage } from '../core/message';\nimport type { ToolUse, ToolResult, ToolApprovalResult } from '../tools/tool';\nimport { modeRegistry, registerBuiltinModes, type Mode, type ModeType } from '../modes';\n\n/**\n * Engine initialization options\n */\nexport interface EngineOptions {\n /** Product name (e.g., \"AI Engine\") */\n productName: string;\n /** ASCII art banner for display */\n productASCIIArt?: string;\n /** Version string */\n version: string;\n /** Current working directory */\n cwd?: string;\n /** Fetch implementation (optional, uses globalThis.fetch by default) */\n fetch?: typeof globalThis.fetch;\n /** Platform implementation (defaults to Node.js) */\n platform?: PlatformAdapter;\n /** Message bus for event communication */\n messageBus?: MessageBus;\n}\n\n/**\n * Engine configuration\n */\nexport interface EngineConfig {\n /** Model to use for AI responses */\n model?: string;\n /** Model for planning mode */\n planModel?: string;\n /** Approval mode for tool usage */\n approvalMode?: 'default' | 'autoEdit' | 'yolo';\n /** System prompt override */\n systemPrompt?: string;\n /** Additional system prompt */\n appendSystemPrompt?: string;\n /** Language for responses */\n language?: string;\n /** MCP servers configuration */\n mcpServers?: Record<string, any>;\n /** Tools configuration */\n tools?: Record<string, boolean>;\n /** Plugins to load */\n plugins?: (string | any)[];\n /** Provider configuration (custom API endpoints, keys, etc.) */\n provider?: Record<string, ProviderConfig>;\n}\n\n/**\n * Session creation options\n */\nexport interface SessionOptions {\n /** Session ID (auto-generated if not provided) */\n sessionId?: string;\n /** Resume from existing session */\n resume?: string;\n /** Continue from latest session */\n continue?: boolean;\n}\n\n/**\n * Message sending options\n */\nexport interface SendMessageOptions {\n /** Message content (string or message array) */\n message: string | NormalizedMessage[];\n /** Session ID for persistent conversations */\n sessionId?: string;\n /** Enable write tools (default: true) */\n write?: boolean;\n /** Enable todo tools (default: true) */\n todo?: boolean;\n /** Enable ask user question tool (default: false) */\n askUserQuestion?: boolean;\n /** Enable task/agent tool (default: false) */\n task?: boolean;\n /** Override model for this message */\n model?: string;\n /** Maximum turns (default: 50) */\n maxTurns?: number;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Callback for text delta (streaming) */\n onTextDelta?: (text: string) => Promise<void>;\n /** Callback for complete text */\n onText?: (text: string) => Promise<void>;\n /** Callback for reasoning */\n onReasoning?: (text: string) => Promise<void>;\n /** Callback for tool use */\n onToolUse?: (toolUse: ToolUse) => Promise<ToolUse>;\n /** Callback for tool result */\n onToolResult?: (toolUse: ToolUse, toolResult: ToolResult, approved: boolean) => Promise<ToolResult>;\n /** Callback for tool approval (return false to deny) */\n onToolApprove?: (toolUse: ToolUse) => Promise<ToolApprovalResult>;\n /** Callback for turn completion */\n onTurn?: (turn: any) => Promise<void>;\n}\n\n/**\n * Main Engine class\n *\n * The Engine is the primary interface for interacting with the AI coding assistant.\n * It manages initialization, configuration, and provides access to context.\n */\nexport class Engine {\n private context: Context | null = null;\n private platform: PlatformAdapter;\n private messageBus: MessageBus;\n private options: EngineOptions;\n private initialized = false;\n private currentMode: ModeType = 'default';\n private jsonlLoggers: Map<string, JsonlLogger> = new Map();\n\n constructor(options: EngineOptions) {\n this.options = options;\n this.platform = options.platform || new NodePlatform();\n this.messageBus = options.messageBus || new MessageBus();\n\n // Register built-in modes\n registerBuiltinModes(modeRegistry);\n }\n\n /**\n * Initialize the engine with configuration\n */\n async initialize(config: EngineConfig = {}): Promise<void> {\n const cwd = this.options.cwd || this.platform.cwd();\n\n this.context = await createContext.create({\n cwd,\n productName: this.options.productName,\n productASCIIArt: this.options.productASCIIArt,\n version: this.options.version,\n argvConfig: config,\n plugins: config.plugins || [],\n messageBus: this.messageBus,\n fetch: this.options.fetch,\n });\n\n await this.context.apply({\n hook: 'initialized',\n args: [{ cwd, quiet: false }],\n type: 'series' as any,\n });\n\n this.initialized = true;\n }\n\n /**\n * Create or resume a session\n */\n async createSession(options: SessionOptions = {}): Promise<Session> {\n if (!this.initialized) {\n throw new Error('Engine not initialized. Call initialize() first.');\n }\n\n if (!this.context) {\n throw new Error('Context not available');\n }\n\n const paths = this.context.paths;\n const sessionId = options.sessionId || (() => {\n if (options.resume) {\n return options.resume;\n }\n if (options.continue) {\n return paths.getLatestSessionId() || this.generateSessionId();\n }\n return this.generateSessionId();\n })();\n\n if (options.resume || options.continue) {\n const logPath = paths.getSessionLogPath(sessionId);\n return createSession.resume({ id: sessionId, logPath });\n }\n\n return createSession.create();\n }\n\n /**\n * Get the MessageBus for event communication\n */\n getMessageBus(): MessageBus {\n return this.messageBus;\n }\n\n /**\n * Get the current context\n */\n getContext(): Context {\n if (!this.context) {\n throw new Error('Engine not initialized');\n }\n return this.context;\n }\n\n /**\n * Shutdown the engine and cleanup resources\n */\n async shutdown(): Promise<void> {\n if (this.context) {\n await this.context.destroy();\n this.context = null;\n }\n this.jsonlLoggers.clear();\n this.initialized = false;\n }\n\n /**\n * Get or create a JsonlLogger for a session\n */\n private getLogger(sessionId: string): JsonlLogger {\n if (!this.jsonlLoggers.has(sessionId)) {\n if (!this.context) {\n throw new Error('Context not available');\n }\n const logPath = this.context.paths.getSessionLogPath(sessionId);\n this.jsonlLoggers.set(sessionId, new JsonlLogger({ filePath: logPath }));\n }\n return this.jsonlLoggers.get(sessionId)!;\n }\n\n /**\n * Get list of all sessions\n */\n getSessions() {\n if (!this.context) {\n throw new Error('Context not available');\n }\n return this.context.paths.getAllSessions();\n }\n\n /**\n * Send a message to the AI and get a response\n *\n * This is the main method for interacting with the AI engine.\n * It handles the full conversation loop including tool execution.\n *\n * @param options - Message sending options\n * @returns Promise<LoopResult> - The result of the conversation loop\n */\n async sendMessage(options: SendMessageOptions): Promise<LoopResult> {\n if (!this.initialized || !this.context) {\n throw new Error('Engine not initialized. Call initialize() first.');\n }\n\n const context = this.context;\n const modelId = options.model || context.config.model;\n const resolvedModel = await resolveModelWithContext(modelId, context);\n\n if (!resolvedModel.model) {\n throw new Error(`Failed to resolve model: ${modelId}`);\n }\n\n // Get or create session ID\n const sessionId = options.sessionId || this.generateSessionId();\n\n // Get logger for this session\n const logger = this.getLogger(sessionId);\n\n // Resolve available tools\n const toolsList = await resolveTools({\n context,\n sessionId,\n write: options.write !== false,\n todo: options.todo !== false,\n askUserQuestion: options.askUserQuestion || false,\n task: options.task || false,\n signal: options.signal,\n });\n\n // Get system prompt from config\n const systemPrompt = context.config.systemPrompt || '';\n\n // Load existing session history if session exists\n let sessionHistory: import('../core/history').History | undefined = undefined;\n if (options.sessionId) {\n const { loadSessionMessages } = await import('../session/session');\n const logPath = context.paths.getSessionLogPath(sessionId);\n try {\n const existingMessages = loadSessionMessages({ logPath });\n if (existingMessages.length > 0) {\n const { History } = await import('../core/history');\n sessionHistory = new History({\n messages: existingMessages,\n });\n }\n } catch {\n // Session doesn't exist yet, will be created\n }\n }\n\n // Create the persistence callback that will be used by history.addMessage\n const onMessageCallback = async (message: import('../core/message').NormalizedMessage) => {\n // Persist all messages (user, assistant, tool) to session log\n // We add sessionId here for tracking\n logger.addMessage({ message: { ...message, sessionId } });\n };\n\n // If we have session history, set its onMessage callback\n if (sessionHistory && !sessionHistory.onMessage) {\n sessionHistory.onMessage = onMessageCallback;\n }\n\n // Run the conversation loop\n // The history's onMessage callback will handle persistence\n const result = await runLoop({\n input: options.message,\n history: sessionHistory,\n model: resolvedModel.model,\n tools: new Tools(toolsList),\n cwd: context.cwd,\n systemPrompt,\n maxTurns: options.maxTurns,\n signal: options.signal,\n onTextDelta: options.onTextDelta,\n onText: options.onText,\n onReasoning: options.onReasoning,\n onToolUse: options.onToolUse,\n onToolResult: options.onToolResult,\n onToolApprove: options.onToolApprove,\n onTurn: options.onTurn,\n onMessage: sessionHistory?.onMessage || onMessageCallback,\n });\n\n // Record the model usage if successful\n if (result.success && modelId) {\n context.globalData.addRecentModel(modelId);\n }\n\n return result;\n }\n\n /**\n * Create a simple request-response interaction (single turn)\n *\n * This is a simplified version of sendMessage that returns just the text response.\n * Tools are disabled by default for simple requests.\n *\n * @param message - The message to send\n * @param options - Optional configuration\n * @returns Promise<string> - The AI's text response\n */\n async ask(\n message: string,\n options?: {\n model?: string;\n systemPrompt?: string;\n },\n ): Promise<string> {\n const result = await this.sendMessage({\n message,\n model: options?.model,\n write: false,\n todo: false,\n askUserQuestion: false,\n task: false,\n maxTurns: 1,\n });\n\n if (result.success) {\n return result.data.text || '';\n }\n\n throw new Error(result.error.message);\n }\n\n /**\n * Set the current interaction mode\n *\n * @param mode - The mode to set (e.g., 'brainstorm', 'plan', 'review')\n */\n setMode(mode: ModeType): void {\n if (!modeRegistry.has(mode)) {\n throw new Error(`Unknown mode: ${mode}. Available modes: ${modeRegistry.getAll().map(m => m.id).join(', ')}`);\n }\n this.currentMode = mode;\n }\n\n /**\n * Get the current mode\n */\n getMode(): ModeType {\n return this.currentMode;\n }\n\n /**\n * Get all available modes\n */\n getAvailableModes(): Mode[] {\n return modeRegistry.getAll();\n }\n\n /**\n * Register a custom mode\n *\n * @param mode - The mode to register\n */\n registerMode(mode: Mode): void {\n modeRegistry.register(mode);\n }\n\n /**\n * Send a message using the current mode\n *\n * This is a convenience method that applies the current mode's configuration\n *\n * @param message - The message to send\n * @param options - Optional overrides for this specific message\n * @returns Promise<LoopResult> - The result of the conversation loop\n */\n async sendMessageWithMode(\n message: string | NormalizedMessage[],\n options?: Partial<Omit<SendMessageOptions, 'message' | 'systemPrompt'>> & {\n systemPrompt?: string;\n },\n ): Promise<LoopResult> {\n const mode = modeRegistry.get(this.currentMode);\n if (!mode) {\n throw new Error(`Current mode ${this.currentMode} not found`);\n }\n\n const modeConfig = mode.config;\n\n // Build options with mode config as defaults\n const sendOptions: Omit<SendMessageOptions, 'message'> = {\n write: options?.write ?? modeConfig.write,\n todo: options?.todo ?? modeConfig.todo,\n askUserQuestion: options?.askUserQuestion ?? modeConfig.askUserQuestion,\n task: options?.task ?? modeConfig.task,\n maxTurns: options?.maxTurns ?? modeConfig.maxTurns,\n model: options?.model ?? modeConfig.model,\n onTextDelta: options?.onTextDelta,\n onText: options?.onText,\n onReasoning: options?.onReasoning,\n onToolUse: options?.onToolUse,\n onToolResult: options?.onToolResult,\n onToolApprove: options?.onToolApprove,\n onTurn: options?.onTurn,\n signal: options?.signal,\n };\n\n // Special handling for system prompt\n const finalSystemPrompt = options?.systemPrompt ?? modeConfig.systemPrompt;\n\n return this._sendMessageWithSystemPrompt(message, sendOptions, finalSystemPrompt);\n }\n\n /**\n * Internal method to send message with custom system prompt\n */\n private async _sendMessageWithSystemPrompt(\n message: string | NormalizedMessage[],\n options: Omit<SendMessageOptions, 'message'>,\n systemPrompt: string,\n ): Promise<LoopResult> {\n if (!this.initialized || !this.context) {\n throw new Error('Engine not initialized. Call initialize() first.');\n }\n\n const context = this.context;\n const modelId = options.model || context.config.model;\n const resolvedModel = await resolveModelWithContext(modelId, context);\n\n if (!resolvedModel.model) {\n throw new Error(`Failed to resolve model: ${modelId}`);\n }\n\n // Resolve available tools\n const toolsList = await resolveTools({\n context,\n sessionId: this.generateSessionId(),\n write: options.write !== false,\n todo: options.todo !== false,\n askUserQuestion: options.askUserQuestion || false,\n task: options.task || false,\n signal: options.signal,\n });\n\n // Run the conversation loop with custom system prompt\n const result = await runLoop({\n input: message,\n model: resolvedModel.model,\n tools: new Tools(toolsList),\n cwd: context.cwd,\n systemPrompt,\n maxTurns: options.maxTurns,\n signal: options.signal,\n onTextDelta: options.onTextDelta,\n onText: options.onText,\n onReasoning: options.onReasoning,\n onToolUse: options.onToolUse,\n onToolResult: options.onToolResult,\n onToolApprove: options.onToolApprove,\n onTurn: options.onTurn,\n });\n\n // Record the model usage if successful\n if (result.success && modelId) {\n context.globalData.addRecentModel(modelId);\n }\n\n return result;\n }\n\n /**\n * Generate a unique session ID\n */\n private generateSessionId(): string {\n return Date.now().toString(36) + Math.random().toString(36).substring(2);\n }\n}\n\n/**\n * Create a new Engine instance\n */\nexport function createEngine(options: EngineOptions): Engine {\n return new Engine(options);\n}\n\n// Re-export commonly used types\nexport type { Config, ApprovalMode } from '../core/config';\nexport type { Session, SessionId } from '../session/session';\nexport type { Tool, ToolUse, ToolResult } from '../tools/tool';\nexport type { Message, NormalizedMessage, UserMessage, AssistantMessage } from '../core/message';\nexport type { Plugin, PluginHookType } from '../core/plugin';\n","/**\n * OriCore\n *\n * Core AI engine for AI-powered coding assistance.\n * This package provides the core functionality for AI-powered coding assistance.\n *\n * @version 1.0.0\n */\n\n// Main Engine API\nexport {\n Engine,\n createEngine,\n type EngineOptions,\n type EngineConfig,\n type SessionOptions,\n type SendMessageOptions,\n} from './api/engine';\n\n// Mode system\nexport * from './modes';\n\n// Platform abstraction\nexport * from './platform';\n\n// Communication layer\nexport * from './communication';\n\n// Session management\nexport { Session, type SessionId, type SessionConfig, SessionConfigManager, loadSessionMessages } from './session/session';\nexport { JsonlLogger } from './jsonl';\nexport { History } from './core/history';\nexport { Usage } from './core/usage';\n\n// Compression\nexport { Compression, isOverflow } from './compression';\nexport type { CompressionConfig, PruneResult } from './compression';\n\n// Core utilities\nexport { randomUUID } from './utils/randomUUID';\n\n// Paths\nexport { Paths, getGlobalDataPath } from './core/paths';\n\n// GlobalData\nexport { GlobalData } from './core/globalData';\n\n// Skill system\nexport { SkillManager } from './skill/skill';\nexport type {\n SkillManagerOpts,\n SkillMetadata,\n SkillError,\n SkillLoadOutcome,\n AddSkillOptions,\n SkillPreview,\n PreviewSkillsResult,\n AddSkillResult,\n} from './skill/skill';\nexport { SkillSource } from './skill/skill';\n\n// Loop result type (for sendMessage return value)\nexport type { LoopResult } from './core/loop';\n\n// Version\nexport const ENGINE_VERSION = '1.0.0';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAOA,UAAQ;AACf,SAAS,kBAAkB;AAC3B,OAAOC,YAAU;AACjB,OAAOC,cAAa;;;ACHpB,OAAOC,SAAQ;AACf,OAAOC,WAAU;;;ACDjB,OAAO,QAAQ;AAEf,IAAM,uBAAuB;AAE7B,SAAS,cAAc,OAAwB;AAC7C,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,CAAC,QAAS,QAAO;AACrB,MACG,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,KAC/C,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GAChD;AACA,WAAO;AAAA,EACT;AACA,SAAO,qBAAqB,KAAK,OAAO;AAC1C;AAEA,SAAS,qBAAqB,aAA6B;AACzD,SAAO,YAAY;AAAA,IACjB;AAAA,IACA,CAAC,OAAO,SAAS,cAAc;AAC7B,UAAI,cAAc,SAAS,GAAG;AAC5B,eAAO;AAAA,MACT;AACA,YAAM,UAAU,UAAU,KAAK;AAC/B,aAAO,GAAG,OAAO,IAAI,QAAQ,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK,CAAC;AAAA,IAC1E;AAAA,EACF;AACF;AASO,SAAS,gBACd,SACA,UACiC;AACjC,MAAI;AACF,UAAM,EAAE,YAAY,KAAK,IAAI,GAAM,OAAO;AAC1C,WAAO,EAAE,YAAY,KAAK;AAAA,EAC5B,SAAS,OAAO;AACd,QAAI;AACF,YAAM,mBAAmB,QAAQ,MAAM,6BAA6B;AACpE,UAAI,kBAAkB;AACpB,cAAM,aAAa,iBAAiB,CAAC;AACrC,cAAM,UAAU,qBAAqB,UAAU;AAE/C,YAAI,YAAY,YAAY;AAC1B,gBAAM,eAAe,QAAQ,QAAQ,YAAY,OAAO;AACxD,gBAAM,EAAE,YAAY,KAAK,IAAI,GAAM,YAAY;AAC/C,iBAAO,EAAE,YAAY,KAAK;AAAA,QAC5B;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAEA,QAAI,iBAAiB,OAAO;AAC1B,YAAM,WAAW,WAAW,IAAI,QAAQ,KAAK;AAC7C,YAAM,UAAU,8BAA8B,QAAQ,KAAK,MAAM,OAAO;AAAA,IAC1E;AACA,UAAM;AAAA,EACR;AACF;;;ACnEA,OAAO,QAAQ;AACf,OAAO,UAAU;AAKV,IAAM,cAAN,MAAkB;AAAA,EACvB;AAAA,EACA,WAA0B;AAAA,EAC1B,YAAY,MAA4B;AACtC,SAAK,WAAW,KAAK;AACrB,SAAK,WAAW,KAAK,cAAc;AAAA,EACrC;AAAA,EAEA,gBAAgB;AACd,QAAI,CAAC,GAAG,WAAW,KAAK,QAAQ,GAAG;AACjC,aAAO;AAAA,IACT;AACA,UAAM,OAAO,GAAG,aAAa,KAAK,UAAU,MAAM;AAClD,UAAM,QAAQ,KAAK,MAAM,IAAI,EAAE,OAAO,OAAO;AAC7C,UAAM,WAAW,MAAM,MAAM,SAAS,CAAC;AACvC,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,IACT;AACA,UAAM,UAAU,KAAK,MAAM,QAAQ;AACnC,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EAEA,WAAW,MAA8D;AACvE,UAAM,MAAM,KAAK,QAAQ,KAAK,QAAQ;AACtC,QAAI,CAAC,GAAG,WAAW,GAAG,GAAG;AACvB,SAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,IACvC;AACA,UAAM,UAAU,KAAK;AACrB,OAAG,eAAe,KAAK,UAAU,KAAK,UAAU,OAAO,IAAI,IAAI;AAC/D,SAAK,WAAW,QAAQ;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,SAAiB,WAAmB;AACjD,UAAM,UAAU;AAAA,MACd,GAAG,kBAAkB,SAAS,KAAK,QAAQ;AAAA,MAC3C;AAAA,IACF;AACA,WAAO,KAAK,WAAW;AAAA,MACrB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,IAAM,gBAAN,MAAoB;AAAA,EACzB;AAAA,EAEA,YAAY,MAAoC;AAC9C,SAAK,mBAAmB,KAAK;AAAA,EAC/B;AAAA,EAEQ,YAAY,WAA2B;AAC7C,UAAM,cAAc,KAAK,KAAK,KAAK,kBAAkB,UAAU;AAC/D,QAAI,CAAC,GAAG,WAAW,WAAW,GAAG;AAC/B,SAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAAA,IAC/C;AACA,WAAO,KAAK,KAAK,aAAa,GAAG,SAAS,QAAQ;AAAA,EACpD;AAAA,EAEA,YAAY,MAQT;AACD,UAAM,WAAW,KAAK,YAAY,KAAK,SAAS;AAChD,UAAM,QAAQ;AAAA,MACZ,MAAM;AAAA,MACN,WAAW,KAAK;AAAA,MAChB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,IACd;AACA,OAAG,eAAe,UAAU,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,EAC1D;AAAA,EAEA,SAAS,WAAmB,OAAY;AACtC,UAAM,WAAW,KAAK,YAAY,SAAS;AAC3C,UAAM,QAAQ;AAAA,MACZ,MAAM;AAAA,MACN;AAAA,MACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAAA,IACF;AACA,OAAG,eAAe,UAAU,KAAK,UAAU,KAAK,IAAI,IAAI;AAAA,EAC1D;AACF;;;ACnGA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,gBAAgB;;;ACFzB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAEV,SAAS,aAAa,MAI1B;AACD,QAAM,QAAkB,CAAC;AACzB,QAAM,cAAc,KAAK;AAEzB,QAAM,kBAAkB,CAAC,aAAa,GAAG,YAAY,YAAY,CAAC,KAAK;AACvE,QAAM,mBAAmB;AAAA,IACvB;AAAA,IACA;AAAA,IACA,GAAG,YAAY,YAAY,CAAC;AAAA,EAC9B;AAGA,MAAI,aAAa,KAAK;AACtB,SAAO,eAAeA,MAAK,MAAM,UAAU,EAAE,MAAM;AACjD,eAAW,YAAY,kBAAkB;AACvC,YAAM,YAAYA,MAAK,KAAK,YAAY,QAAQ;AAChD,UAAID,IAAG,WAAW,SAAS,GAAG;AAC5B,cAAM,KAAKA,IAAG,aAAa,WAAW,OAAO,CAAC;AAAA,MAChD;AAAA,IACF;AACA,iBAAaC,MAAK,QAAQ,UAAU;AAAA,EACtC;AAEA,aAAW,YAAY,iBAAiB;AACtC,UAAM,kBAAkBA,MAAK,KAAK,KAAK,iBAAiB,QAAQ;AAChE,QAAID,IAAG,WAAW,eAAe,GAAG;AAClC,YAAM,KAAKA,IAAG,aAAa,iBAAiB,OAAO,CAAC;AAAA,IACtD;AAAA,EACF;AACA,QAAM,uBAAuBC,MAAK;AAAA,IAChC,KAAK;AAAA,IACL;AAAA,EACF;AACA,MAAID,IAAG,WAAW,oBAAoB,GAAG;AACvC,UAAM,KAAKA,IAAG,aAAa,sBAAsB,OAAO,CAAC;AAAA,EAC3D;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AACA,QAAM,gBAAgB,MAAM,QAAQ;AACpC,SAAO;AAAA,IACL,OAAO,cAAc,KAAK,MAAM;AAAA,IAChC,iBAAiB;AAAA;AAAA;AAAA,MAGf,cAAc,KAAK,MAAM,CAAC;AAAA,EAC9B;AACF;;;ACvDA,SAAS,gBAAgB;AAEzB,IAAM,eAAe;AACrB,IAAM,oBAAoB;AAKnB,SAAS,gBACd,KACA,MACA,MACA,aACA,UAAU,KAAK,oBAAoB,cACnC,wBAAwB,MACmC;AAC3D,SAAO,IAAI,QAAQ,CAACE,aAAY;AAC9B,QAAI;AACF;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,UACE,WAAW;AAAA,UACX,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,QACF;AAAA,QACA,CAAC,OAAO,QAAQ,WAAW;AACzB,cAAI,OAAO;AACT,gBAAI,uBAAuB;AACzB,oBAAM,YAAY,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAChE,cAAAA,SAAQ;AAAA,gBACN,QAAQ,UAAU;AAAA,gBAClB,QAAQ,UAAU;AAAA,gBAClB,MAAM;AAAA,cACR,CAAC;AAAA,YACH,OAAO;AACL,cAAAA,SAAQ,EAAE,QAAQ,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;AAAA,YAC7C;AAAA,UACF,OAAO;AACL,YAAAA,SAAQ,EAAE,QAAQ,QAAQ,MAAM,EAAE,CAAC;AAAA,UACrC;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,MAAAA,SAAQ,EAAE,QAAQ,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;AAAA,IAC7C;AAAA,EACF,CAAC;AACH;;;AC1CA,eAAe,QACb,KACA,MAC2D;AAC3D,SAAO,gBAAgB,KAAK,OAAO,MAAM,QAAW,QAAW,KAAK;AACtE;AAEA,eAAe,SAAS,KAAa,MAAkC;AACrE,QAAM,EAAE,KAAK,IAAI,MAAM,QAAQ,KAAK,IAAI;AACxC,SAAO,SAAS;AAClB;AAEA,eAAe,UAAU,KAAa,MAAiC;AACrE,QAAM,EAAE,OAAO,IAAI,MAAM,QAAQ,KAAK,IAAI;AAC1C,SAAO,OAAO,KAAK;AACrB;AA4BA,eAAsB,gBAAgB,KAA+B;AACnE,SAAO,SAAS,KAAK,CAAC,aAAa,uBAAuB,CAAC;AAC7D;AAqTA,eAAsB,aAAa,MAAuB;AACxD,QAAM,EAAE,IAAI,IAAI;AAChB,MAAI,CAAE,MAAM,gBAAgB,GAAG,GAAI;AACjC,WAAO;AAAA,EACT;AAEA,QAAM,CAAC,QAAQ,YAAY,QAAQ,KAAK,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,IAClE,UAAU,KAAK,CAAC,UAAU,gBAAgB,CAAC;AAAA,IAC3C,UAAU,KAAK,CAAC,aAAa,gBAAgB,aAAa,CAAC,EAAE;AAAA,MAAK,CAAC,MACjE,EAAE,QAAQ,WAAW,EAAE;AAAA,IACzB;AAAA,IACA,UAAU,KAAK,CAAC,UAAU,SAAS,CAAC;AAAA,IACpC,UAAU,KAAK,CAAC,OAAO,aAAa,MAAM,GAAG,CAAC;AAAA,IAC9C,UAAU,KAAK,CAAC,UAAU,YAAY,CAAC;AAAA,EACzC,CAAC;AAED,QAAM,YAAY,MAAM,UAAU,KAAK;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,gBACpB,QACA;AACA,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,SAAO;AAAA;AAAA,kBAES,OAAO,MAAM;AAAA;AAAA,mDAEoB,OAAO,UAAU;AAAA;AAAA;AAAA,EAGlE,OAAO,UAAU,SAAS;AAAA;AAAA;AAAA,EAG1B,OAAO,GAAG;AAAA;AAAA;AAAA,EAGV,OAAO,aAAa,qBAAqB;AAAA,IACvC,KAAK;AACT;;;AChaA,OAAOC,SAAQ;AACf,SAAS,eAAe;AACxB,OAAOC,WAAU;AAEjB,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,mBAAmB,KAAsB;AACvD,QAAM,gBAAgBA,MAAK,QAAQ,GAAG;AACtC,QAAM,UAAUA,MAAK,QAAQ,QAAQ,CAAC;AAEtC,MAAI,kBAAkB,SAAS;AAC7B,WAAO;AAAA,EACT;AAEA,SAAO,gBAAgB,KAAK,CAAC,WAAW;AACtC,UAAM,aAAaA,MAAK,KAAK,eAAe,MAAM;AAClD,WAAOD,IAAG,WAAW,UAAU;AAAA,EACjC,CAAC;AACH;;;AJdO,IAAM,cAAN,MAAM,aAAY;AAAA,EACvB;AAAA,EACA,YAAY,MAA8B;AACxC,SAAK,WAAW,KAAK;AAAA,EACvB;AAAA,EAEA,aAAa,OAAO,MAA6B;AAC/C,UAAM,YAAY,MAAM,aAAa,EAAE,KAAK,KAAK,QAAQ,IAAI,CAAC;AAE9D,QAAI,cAAsC,CAAC;AAE3C,UAAM,gBAAgB,MAAM,gBAAgB,SAAS;AACrD,QAAI,eAAe;AACjB,kBAAY,YAAY;AAAA,IAC1B;AAEA,UAAM,YAAY,mBAAmB,KAAK,QAAQ,GAAG;AACrD,QAAI,WAAW;AACb,YAAM,SAAS,aAAa;AAAA,QAC1B,KAAK,KAAK,QAAQ;AAAA,MACpB,CAAC;AACD,YAAM,SAAS,MAAM,OAAO,QAAQ,EAAE,UAAU,IAAI,CAAC;AACrD,UAAI,QAAQ;AACV,oBAAY,qBAAqB;AAAA,EACvC,OAAO,aAAa;AAAA;AAAA,EAEpB,OAAO,UAAU;AAAA;AAAA,UAET,KAAK;AAAA,MACT;AAAA,IACF;AAEA,UAAM,QAAQ,aAAa;AAAA,MACzB,KAAK,KAAK,QAAQ;AAAA,MAClB,aAAa,KAAK,QAAQ;AAAA,MAC1B,iBAAiB,KAAK,QAAQ,MAAM;AAAA,IACtC,CAAC;AACD,QAAI,OAAO;AACT,kBAAY,QAAQ,MAAM;AAAA,IAC5B;AAEA,UAAM,aAAaE,MAAK,KAAK,KAAK,QAAQ,KAAK,WAAW;AAC1D,QAAIC,IAAG,WAAW,UAAU,GAAG;AAC7B,kBAAY,SAASA,IAAG,aAAa,YAAY,OAAO;AAAA,IAC1D;AAEA,kBAAc,MAAM,KAAK,QAAQ,MAAM;AAAA,MACrC,MAAM;AAAA,MACN,MAAM;AAAA,QACJ;AAAA,UACE,WAAW,KAAK;AAAA,UAChB,YAAY,KAAK;AAAA,QACnB;AAAA,MACF;AAAA,MACA,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AACD,UAAM,iBAAiB;AAAA;AAAA;AAAA,EAGzB,OAAO,QAAQ,WAAW,EAEzB,OAAO,CAAC,CAAC,GAAG,KAAK,MAAM,KAAK,EAC5B,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,kBAAkB,GAAG,KAAK,KAAK,YAAY,EACjE,KAAK,IAAI,CAAC;AAAA,MACP,KAAK;AAEP,QAAI,UAAU;AAAA,MACZ,qBAAqB,KAAK,QAAQ;AAAA,MAClC,GAAI,KAAK,yBACP,KAAK,sBAAsB,SAAS,KAAK;AAAA,QACvC,kCACE,KAAK,sBAAsB,KAAK,IAAI;AAAA,MACxC;AAAA,MACF,2BAA2B,YAAY,QAAQ;AAAA,MAC/C,UAAU;AAAA,MACV,iBAAgB,oBAAI,KAAK,GAAE,mBAAmB;AAAA,IAChD;AACA,cAAU,MAAM,KAAK,QAAQ,MAAM;AAAA,MACjC,MAAM;AAAA,MACN,MAAM;AAAA,QACJ;AAAA,UACE,WAAW,KAAK;AAAA,UAChB,YAAY,KAAK;AAAA,QACnB;AAAA,MACF;AAAA,MACA,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AACD,UAAM,aAAa;AAAA;AAAA;AAAA,EAGrB,OAAO,QAAQ,OAAO,EACrB,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,cAAc,GAAG,KAAK,KAAK,QAAQ,EACzD,KAAK,IAAI,CAAC;AAAA,MACP,KAAK;AAEP,WAAO,IAAI,aAAY,EAAE,UAAU,CAAC,gBAAgB,UAAU,EAAE,CAAC;AAAA,EACnE;AACF;;;AKxGO,IAAM,eAAN,MAAmB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,MAAwB;AAClC,SAAK,SAAS,KAAK;AACnB,SAAK,QAAQ,KAAK;AAClB,SAAK,UAAU,CAAC;AAAA,EAClB;AAAA,EACA,OAAO,MAMJ;AACD,QAAI,CAAC,KAAK,OAAO;AACf;AAAA,IACF;AACA,UAAM,QAAQ,GAAG,KAAK,MAAM,SAAS,EAAE,IAAI,KAAK,MAAM,MAAM,EAAE;AAC9D,UAAM,OAAyB;AAAA,MAC7B,MAAM;AAAA,MACN,SAAS;AAAA,MACT,WAAW,KAAK;AAAA,MAChB;AAAA,MACA,KAAK,KAAK;AAAA,MACV,OAAO,KAAK,MAAM,IAAI,CAAC,SAAS,KAAK,IAAI;AAAA,IAC3C;AACA,QAAI,KAAK,WAAW,eAAe;AACjC,cAAQ,IAAI,KAAK,UAAU,IAAI,CAAC;AAAA,IAClC,WAAW,KAAK,WAAW,QAAQ;AACjC,WAAK,QAAQ,KAAK,IAAI;AAAA,IACxB;AAAA,EACF;AAAA,EACA,UAAU,MAAwB;AAChC,QAAI,CAAC,KAAK,OAAO;AACf;AAAA,IACF;AACA,UAAM,OAAO,EAAE,GAAG,KAAK,QAAQ;AAC/B,QAAI,KAAK,WAAW,eAAe;AACjC,cAAQ,IAAI,KAAK,UAAU,IAAI,CAAC;AAAA,IAClC,WAAW,KAAK,WAAW,QAAQ;AACjC,WAAK,QAAQ,KAAK,IAAI;AAAA,IACxB;AAAA,EACF;AAAA,EACA,MAAM,MAAiD;AACrD,QAAI,CAAC,KAAK,OAAO;AACf;AAAA,IACF;AACA,UAAM,UAAU,CAAC,KAAK,OAAO;AAC7B,UAAM,UAAU,UAAU,UAAU;AACpC,UAAM,OAAyB;AAAA,MAC7B,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,SAAS,KAAK,OAAO,UACjB,KAAK,OAAO,KAAK,OACjB,KAAK,OAAO,MAAM;AAAA,MACtB,WAAW,KAAK;AAAA,MAChB,GAAI,UAAU,EAAE,UAAU,KAAK,OAAO,IAAI,CAAC;AAAA,IAC7C;AACA,QAAI,KAAK,OAAO,SAAS;AACvB,WAAK,QAAQ;AAAA,QACX,cAAc,KAAK,OAAO,KAAK,MAAM;AAAA,QACrC,eAAe,KAAK,OAAO,KAAK,MAAM;AAAA,MACxC;AAAA,IACF;AACA,QAAI,KAAK,WAAW,eAAe;AACjC,cAAQ,IAAI,KAAK,UAAU,IAAI,CAAC;AAAA,IAClC,WAAW,KAAK,WAAW,QAAQ;AACjC,WAAK,QAAQ,KAAK,IAAI;AACtB,cAAQ,IAAI,KAAK,UAAU,KAAK,OAAO,CAAC;AAAA,IAC1C,WAAW,KAAK,WAAW,QAAQ;AACjC,cAAQ;AAAA,QACN,KAAK,OAAO,UACR,KAAK,OAAO,MAAM,QAAQ,KAC1B,KAAK,OAAO,MAAM;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACF;;;AC5FA,OAAO,YAAY;AACnB,OAAOC,SAAQ;AACf,SAAS,YAAY;AACrB,OAAOC,WAAU;;;ACAV,IAAM,qBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,QAAQ;AACV;;;ACNO,IAAM,yBAAsC;AAAA,EACjD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcN,KAAK;AACT;;;ACnBO,IAAM,kBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,aACE;AAAA,EACF,iBAAiB;AAAA,EACjB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaN,KAAK;AACT;;;ACnBO,IAAM,qBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,QAAQ;AACV;;;ACIO,SAAS,yBAAwC;AACtD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACXO,SAAS,iBAAiB,aAA6B;AAC5D,SAAO,YACJ,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACxE,KAAK,GAAG;AACb;;;ANSO,IAAM,cAAN,MAAkB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,MAAuB;AACjC,SAAK,OAAO,KAAK;AACjB,SAAK,cAAc,KAAK;AACxB,SAAK,kBAAkB,KAAK;AAC5B,SAAK,SAAS,KAAK;AAAA,EACrB;AAAA,EAEA,YAAqB;AACnB,WAAO,KAAK,SAAS;AAAA,EACvB;AACF;AAOO,IAAM,qBAAN,MAAM,oBAAmB;AAAA,EAC9B,eAA8B,CAAC;AAAA,EAC/B,YAAY,MAA8B;AACxC,SAAK,eAAe,CAAC,GAAG,KAAK,KAAK,KAAK,KAAK,GAAG,GAAG,KAAK,YAAY;AAAA,EACrE;AAAA,EAEA,aAAa,OAAO,SAAkB;AACpC,UAAM,eAAe,MAAM,QAAQ,MAAM;AAAA,MACvC,MAAM;AAAA,MACN,MAAM,CAAC;AAAA,MACP,MAAM,CAAC;AAAA,MACP;AAAA,IACF,CAAC;AACD,WAAO,IAAI,oBAAmB;AAAA,MAC5B,OAAO,QAAQ;AAAA,MACf;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,KAAK,OAA6B;AAChC,UAAM,UAAU,uBAAuB,EAAE,IAAI,CAAC,SAAS;AACrD,aAAO,IAAI,YAAY;AAAA,QACrB,MAAM,KAAK;AAAA,QACX,aAAa,KAAK;AAAA,QAClB,iBAAiB,KAAK;AAAA,QACtB,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AACD,UAAM,SAAS,KAAK;AAAA,MAClBC,MAAK,KAAK,MAAM,iBAAiB,eAAe;AAAA,IAClD;AACA,UAAM,UAAU,KAAK;AAAA,MACnBA,MAAK,KAAK,MAAM,kBAAkB,eAAe;AAAA,IACnD;AACA,WAAO,CAAC,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO;AAAA,EAC3C;AAAA,EAEA,WAAW,iBAAwC;AACjD,WAAO,0BAA0B,eAAe,EAAE,IAAI,CAAC,SAAS;AAC9D,aAAO,IAAI,YAAY;AAAA,QACrB,MAAM,KAAK;AAAA,QACX,aAAa,GAAG,KAAK,WAAW;AAAA,QAChC,iBAAiB,CAAC,CAAC,KAAK,WAAW;AAAA,QACnC,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,YAAY,kBAAyC;AACnD,WAAO,0BAA0B,gBAAgB,EAAE,IAAI,CAAC,SAAS;AAC/D,aAAO,IAAI,YAAY;AAAA,QACrB,MAAM,KAAK;AAAA,QACX,aAAa,GAAG,KAAK,WAAW;AAAA,QAChC,iBAAiB,CAAC,CAAC,KAAK,WAAW;AAAA,QACnC,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe,MAA0B,KAA0B;AACjE,UAAMC,sBAAqB,KAAK,sBAAsB;AACtD,QAAI,CAAC,MAAM;AACT,aAAOA;AAAA,IACT;AAEA,QAAID,MAAK,WAAW,IAAI,KAAK,KAAK,WAAW,GAAG,GAAG;AACjD,UAAI,CAAC,KAAK,SAAS,KAAK,GAAG;AACzB,cAAM,IAAI,MAAM,sCAAsC;AAAA,MACxD;AACA,UAAI,WAAW;AACf,UAAI,CAACA,MAAK,WAAW,IAAI,GAAG;AAC1B,mBAAWA,MAAK,QAAQ,KAAK,IAAI;AAEjC,YAAI,CAAC,SAAS,WAAWA,MAAK,QAAQ,GAAG,CAAC,GAAG;AAC3C,gBAAM,IAAI,MAAM,4BAA4B;AAAA,QAC9C;AAAA,MACF;AACA,YAAM,OAAO,yBAAyB,QAAQ;AAC9C,aAAO,IAAI,YAAY;AAAA,QACrB,MAAM,KAAK;AAAA,QACX,aAAa,KAAK;AAAA,QAClB,iBAAiB,CAAC,CAAC,KAAK,WAAW;AAAA,QACnC,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,IACH,WAAW,KAAK,WAAW,GAAG,KAAK,KAAK,SAAS,GAAG,GAAG;AACrD,UAAI,OAAO;AACX,UAAI;AACF,eAAO,KAAK,MAAM,IAAI;AAAA,MACxB,SAAS,OAAO;AACd,cAAM,IAAI;AAAA,UACR,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,eAAe,IAAI;AAAA,QACzG;AAAA,MACF;AACA,aAAO,KAAK,QAAQ,oBAAoB;AACxC,aAAO,IAAI,YAAY;AAAA,QACrB,MAAM,KAAK,QAAQ;AAAA,QACnB,aAAa,KAAK,eAAe;AAAA,QACjC,iBAAiB,KAAK;AAAA,QACtB,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,IACH,WAAW,MAAM;AACf,YAAM,cAAc,KAAK,aAAa;AAAA,QACpC,CAAC,UAAU,MAAM,SAAS;AAAA,MAC5B;AACA,aAAO,aAAa,gBAAgB,IAAI,YAAY;AACpD,aAAO;AAAA,IACT,OAAO;AACL,aAAOC;AAAA,IACT;AAAA,EACF;AAAA,EAEA,wBAAqC;AACnC,WAAO,IAAI,YAAY;AAAA,MACrB,MAAM,mBAAmB;AAAA,MACzB,aAAa,mBAAmB;AAAA,MAChC,iBAAiB,mBAAmB;AAAA,MACpC,QAAQ,mBAAmB;AAAA,IAC7B,CAAC;AAAA,EACH;AACF;AAcO,SAAS,0BACd,KAC0B;AAC1B,MAAI,CAACC,IAAG,WAAW,GAAG,GAAG;AACvB,WAAO,CAAC;AAAA,EACV;AACA,QAAM,QAAQ,KAAK,KAAK,WAAW;AAAA,IACjC,KAAK;AAAA,IACL,QAAQ;AAAA,EACV,CAAC;AACD,SAAO,MAAM,IAAI,CAAC,iBAAiB;AACjC,UAAM,UAAUF,MAAK,KAAK,KAAK,YAAY;AAC3C,WAAO,yBAAyB,SAAS,GAAG;AAAA,EAC9C,CAAC;AACH;AAEO,SAAS,iBAAiB,UAAgC;AAC/D,QAAM,UAAUE,IAAG,aAAa,UAAU,OAAO;AACjD,QAAM,EAAE,YAAY,KAAK,IAAI;AAAA,IAC3B;AAAA,IACA;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,yBACP,UACA,KACwB;AACxB,MAAI,CAACA,IAAG,WAAW,QAAQ,GAAG;AAC5B,UAAM,IAAI,MAAM,gCAAgC,QAAQ,EAAE;AAAA,EAC5D;AAEA,MAAI,OAAOF,MAAK,SAAS,UAAU,KAAK;AACxC,QAAM,OAAO,iBAAiB,QAAQ;AACtC,MAAI,KAAK;AACP,UAAM,eAAeA,MAAK,SAAS,KAAK,QAAQ;AAEhD,WAAO,aAAa,QAAQ,SAAS,EAAE,EAAE,QAAQ,UAAU,GAAG;AAAA,EAChE;AACA,MAAI,cAAc,KAAK,WAAW,aAAa,KAAK;AACpD,MAAI,CAAC,aAAa;AAChB,UAAM,SAAS,KAAK,QAAQ,IAAI,MAAM,IAAI;AAC1C,UAAM,YAAY,MAAM,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,GAAG,KAAK;AAC1D,QAAI,WAAW;AAEb,UAAI,UAAU,WAAW,GAAG,GAAG;AAE7B,sBAAc,UAAU,QAAQ,UAAU,EAAE,EAAE,KAAK;AAAA,MACrD,OAAO;AAEL,sBAAc;AAAA,MAChB;AAGA,UAAI,YAAY,SAAS,IAAI;AAC3B,sBAAc,GAAG,YAAY,UAAU,GAAG,EAAE,CAAC;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AACA,MAAI,CAAC,aAAa;AAChB,kBAAc,iBAAiB,IAAI;AAAA,EACrC;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF;AACF;;;AO9PO,SAAS,yBAAyB,MAItC;AACD,SAAO;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,EAsCP,KAAK,aAAa,YAAY,KAAK,wBAAwB,KAAK,QAAQ,GAAG;AAAA,EAC3E,KAAK;AACP;;;AC1CA,SAAS,eAAe,MAA8C;AACpE,MAAI,CAAC,KAAK,MAAM;AACd,WAAO;AAAA,EACT;AACA,QAAM,cAAc,KAAK;AACzB,SAAO;AAAA;AAAA,qDAEqC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8DASS;AAAA;AAAA;AAAA;AAAA,wDAID;AAAA;AAAA,sFAEyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mIAc6C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wCAkB3F;AAAA;AAAA;AAAA;AAAA,yKAIsI,6MAA6M,WAAW;AAAA;AAAA;AAAA,wDAG9U;AAAA;AAEjD;AAEA,SAAS,yBAAyB,MAAe;AAC/C,QAAM,aAAa,OACf;AAAA,+DACuD;AAAA,oDACX;AAAA,oQACgN;AAAA,0MAC1D,mDAA8C;AAAA;AAAA;AAAA,wCAGhN,mDAA8C,kFAAgF,wBAAsB;AAAA;AAAA;AAAA;AAAA,wCAIpJ,mDAA8C;AAAA,cAE9E;AAEJ,SAAO;AAAA,qBACY,UAAU;AAAA;AAAA;AAAA,wKAGuI,iEAA+D,2DAAwD;AAAA;AAE7R;AAEO,SAAS,qBAAqB,MAOlC;AACD,QAAM,EAAE,YAAY,IAAI;AACxB,QAAM,uBAAuB,YAAY,UAAU;AACnD,SAAO;AAAA,mDAC0C,uBAAuB,qCAAqC,iGAAiG;AAAA;AAAA;AAAA,EAI9M,KAAK,aAAa,YACd,KACA,wBAAwB,KAAK,QAAQ;AAAA,CAE3C;AAAA;AAAA,EAGE,CAAC,uBACG;AAAA,kBACY,YAAY,IAAI;AAAA,EAChC,YAAY,MAAM;AAAA,MAEd;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,GAgCN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUE,YAAY,kBACR;AAAA;AAAA;AAAA;AAAA,EAIJ,eAAe,IAAI,CAAC,KAChB,EACN;AAAA;AAAA,EAEE,yBAAyB,KAAK,QAAQ,KAAK,CAAC;AAAA;AAAA,EAE5C,KAAK,qBAAqB,KAAK,qBAAqB,EAAE;AAAA,EACtD,KAAK;AACP;;;ACxJO,IAAM,UAAN,MAAc;AAAA,EACnB;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA,YAAY,MAIT;AACD,SAAK,UAAU,KAAK,YAChB,QAAQ,OAAO;AAAA,MACb,IAAI,KAAK;AAAA,MACT,SAAS,KAAK,QAAQ,MAAM,kBAAkB,KAAK,SAAS;AAAA,IAC9D,CAAC,IACD,QAAQ,OAAO;AACnB,SAAK,UAAU,KAAK;AACpB,SAAK,kBAAkB,KAAK;AAAA,EAC9B;AAAA,EAEA,MAAM,KACJ,SACA,OAaI,CAAC,GACL;AACA,QAAI,QAAQ,MAAM,aAAa;AAAA,MAC7B,SAAS,KAAK;AAAA,MACd,WAAW,KAAK,QAAQ;AAAA,MACxB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,iBAAiB,CAAC,KAAK,QAAQ,OAAO;AAAA,MACtC,QAAQ,KAAK;AAAA,MACb,MAAM;AAAA,IACR,CAAC;AACD,YAAQ,MAAM,KAAK,QAAQ,MAAM;AAAA,MAC/B,MAAM;AAAA,MACN,MAAM,CAAC,EAAE,WAAW,KAAK,QAAQ,GAAG,CAAC;AAAA,MACrC,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AACD,UAAM,qBAAqB,MAAM,mBAAmB,OAAO,KAAK,OAAO;AACvE,UAAM,cAAc,mBAAmB;AAAA,MACrC,KAAK,QAAQ,OAAO;AAAA,MACpB,KAAK,QAAQ;AAAA,IACf;AACA,UAAM,cAAc,MAAM,KAAK,CAAC,MAAM,EAAE,0BAAwB;AAChE,QAAI,eAAe,qBAAqB;AAAA,MACtC,MAAM,KAAK,QAAQ,OAAO;AAAA,MAC1B,aAAa,KAAK,QAAQ;AAAA,MAC1B,UAAU,KAAK,QAAQ,OAAO;AAAA,MAC9B;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AACD,mBAAe,MAAM,KAAK,QAAQ,MAAM;AAAA,MACtC,MAAM;AAAA,MACN,MAAM,CAAC,EAAE,WAAW,KAAK,QAAQ,GAAG,CAAC;AAAA,MACrC,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AACD,WAAO,KAAK,6BAA6B,SAAS;AAAA,MAChD,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,KACJ,SACA,OAUI,CAAC,GACL;AACA,QAAI,QAAQ,MAAM,aAAa;AAAA,MAC7B,SAAS,KAAK;AAAA,MACd,WAAW,KAAK,QAAQ;AAAA,MACxB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,iBAAiB,CAAC,KAAK,QAAQ,OAAO;AAAA,MACtC,QAAQ,KAAK;AAAA,MACb,MAAM;AAAA,IACR,CAAC;AACD,YAAQ,MAAM,KAAK,QAAQ,MAAM;AAAA,MAC/B,MAAM;AAAA,MACN,MAAM,CAAC,EAAE,QAAQ,MAAM,WAAW,KAAK,QAAQ,GAAG,CAAC;AAAA,MACnD,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AACD,QAAI,eAAe,yBAAyB;AAAA,MAC1C,MAAM,KAAK,QAAQ,OAAO;AAAA,MAC1B,aAAa,KAAK,QAAQ;AAAA,MAC1B,UAAU,KAAK,QAAQ,OAAO;AAAA,IAChC,CAAC;AACD,mBAAe,MAAM,KAAK,QAAQ,MAAM;AAAA,MACtC,MAAM;AAAA,MACN,MAAM,CAAC,EAAE,QAAQ,MAAM,WAAW,KAAK,QAAQ,GAAG,CAAC;AAAA,MACnD,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AACD,WAAO,KAAK,6BAA6B,SAAS;AAAA,MAChD,GAAG;AAAA,MACH,OAAO,KAAK,SAAS,KAAK,QAAQ,OAAO;AAAA,MACzC;AAAA,MACA;AAAA,MACA,eAAe,MAAM,QAAQ,QAAQ,IAAI;AAAA,IAC3C,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,6BACJ,SACA,OAiBI,CAAC,GACL;AACA,UAAM,YAAY,oBAAI,KAAK;AAC3B,UAAM,QAAQ,KAAK,SAAS,CAAC;AAC7B,UAAM,eAAe,IAAI,aAAa;AAAA,MACpC,QAAQ,KAAK,QAAQ,OAAO;AAAA,MAC5B,OAAO,KAAK,QAAQ,OAAO;AAAA,IAC7B,CAAC;AAED,UAAM,cAAc,IAAI,YAAY;AAAA,MAClC,UAAU,KAAK,QAAQ,MAAM,kBAAkB,KAAK,QAAQ,EAAE;AAAA,IAChE,CAAC;AACD,UAAM,gBAAgB,IAAI,cAAc;AAAA,MACtC,kBAAkB,KAAK,QAAQ,MAAM;AAAA,IACvC,CAAC;AACD,QAAI,YAAY,MAAM;AACpB,gBAAU,MAAM,KAAK,QAAQ,MAAM;AAAA,QACjC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,UACJ;AAAA,YACE,WAAW,KAAK,QAAQ;AAAA,UAC1B;AAAA,QACF;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AACA,UAAM,uBAAuB,IAAI,qBAAqB;AAAA,MACpD,SAAS,KAAK,QAAQ,MAAM,kBAAkB,KAAK,QAAQ,EAAE;AAAA,IAC/D,CAAC;AACD,UAAM,wBACJ,qBAAqB,OAAO,yBAAyB,CAAC;AAExD,UAAM,cAAc,MAAM,YAAY,OAAO;AAAA,MAC3C,SAAS,KAAK;AAAA,MACd,WAAW,KAAK,QAAQ;AAAA,MACxB,YAAY;AAAA,MACZ;AAAA,IACF,CAAC;AACD,QAAI,cAAwC;AAC5C,QAAI,YAAY,MAAM;AACpB,YAAM,kBACJ,KAAK,cACL,KAAK,QAAQ,QAAQ,SAAS,KAAK,QAAQ,QAAQ,SAAS,SAAS,CAAC,GAClE;AAEN,UAAI,UAAuB;AAC3B,UAAI,KAAK,aAAa,QAAQ;AAC5B,kBAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,UACR;AAAA,UACA,GAAG,KAAK;AAAA,QACV;AAAA,MACF;AAEA,oBAAc;AAAA,QACZ,YAAY,mBAAmB;AAAA,QAC/B,MAAM,WAAW;AAAA,QACjB,MAAM;AAAA,QACN;AAAA,QACA,MAAM;AAAA,QACN,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC;AACA,YAAM,2BAA2B;AAAA,QAC/B,GAAG;AAAA,QACH,WAAW,KAAK,QAAQ;AAAA,MAC1B;AACA,kBAAY,WAAW;AAAA,QACrB,SAAS;AAAA,MACX,CAAC;AACD,YAAM,KAAK,YAAY;AAAA,QACrB,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AACA,UAAM,kBAAkB,KAAK,aACzB,KAAK,QAAQ,QAAQ,kBAAkB,KAAK,UAAU,IACtD,KAAK,QAAQ,QAAQ;AACzB,UAAM,QACJ,gBAAgB,SAAS,IACrB,CAAC,GAAG,iBAAiB,WAAW,IAChC,CAAC,WAAW;AAClB,UAAM,gBAAgB,MAAM,OAAO,CAACG,aAAYA,aAAY,IAAI;AAGhE,UAAM,qBAAqB,cAAc,KAAK,CAAC,QAAQ;AACrD,UAAI,IAAI,SAAS,UAAU,MAAM,QAAQ,IAAI,OAAO,GAAG;AACrD,eAAO,IAAI,QAAQ,KAAK,CAAC,SAAc,KAAK,SAAS,OAAO;AAAA,MAC9D;AACA,aAAO;AAAA,IACT,CAAC;AAMD,QAAI,aAAa,KAAK;AAKtB,QAAI,oBAAoB;AACtB,YAAM,cAAc,KAAK,QAAQ,OAAO;AACxC,YAAM,YAAY,KAAK,QAAQ,OAAO;AAItC,UAAI,eAAe,gBAAgB,WAAW;AAC5C,qBAAa;AAAA,MACf;AAAA,IACF;AAGA,UAAM,iBACJ,MAAM,wBAAwB,cAAc,MAAM,KAAK,OAAO,GAC9D;AAGF,QAAI,YAAY,MAAM;AACpB,mBAAa,OAAO;AAAA,QAClB,MAAM;AAAA,QACN,WAAW,KAAK,QAAQ;AAAA,QACxB;AAAA,QACA,OAAO;AAAA,QACP,KAAK,KAAK,QAAQ;AAAA,MACpB,CAAC;AAAA,IACH;AAEA,UAAM,eAAe,IAAI,MAAM,KAAK;AACpC,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,KAAK,KAAK,QAAQ;AAAA,MAClB,cAAc,KAAK;AAAA,MACnB,cAAc,YAAY;AAAA,MAC1B,QAAQ,KAAK;AAAA,MACb,aAAa,KAAK,QAAQ,OAAO;AAAA,MACjC,UAAU,KAAK,QAAQ,OAAO;AAAA,MAC9B,UAAU,KAAK;AAAA,MACf,aAAa,KAAK,QAAQ,OAAO;AAAA,MACjC,WAAW,OAAOA,aAAY;AAC5B,cAAM,oBAAoB;AAAA,UACxB,GAAGA;AAAA,UACH,WAAW,KAAK,QAAQ;AAAA,QAC1B;AACA,qBAAa,UAAU;AAAA,UACrB,SAAS;AAAA,QACX,CAAC;AACD,oBAAY,WAAW;AAAA,UACrB,SAAS;AAAA,QACX,CAAC;AACD,cAAM,KAAK,YAAY;AAAA,UACrB,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,MACA,aAAa,OAAO,SAAS;AAC3B,cAAM,KAAK,cAAc,IAAI;AAAA,MAC/B;AAAA,MACA,gBAAgB,OAAOC,YAAW;AAChC,sBAAc,YAAY;AAAA,UACxB,WAAWA,QAAO;AAAA,UAClB,QAAQA,QAAO;AAAA,UACf,OAAOA,QAAO;AAAA,UACd,OAAOA,QAAO;AAAA,UACd,SAASA,QAAO;AAAA,UAChB,UAAUA,QAAO;AAAA,UACjB,OAAOA,QAAO;AAAA,QAChB,CAAC;AACD,cAAM,KAAK,iBAAiBA,OAAM;AAAA,MACpC;AAAA,MACA,SAAS,OAAO,OAAO,cAAc;AACnC,sBAAc,SAAS,WAAW,KAAK;AACvC,cAAM,KAAK,UAAU,OAAO,SAAS;AAAA,MACvC;AAAA,MACA,QAAQ,OAAO,SAAS;AAAA,MAAC;AAAA,MACzB,aAAa,OAAO,SAAS;AAAA,MAAC;AAAA,MAC9B,WAAW,OAAO,YAAY;AAC5B,eAAO,MAAM,KAAK,QAAQ,MAAM;AAAA,UAC9B,MAAM;AAAA,UACN,MAAM;AAAA,YACJ;AAAA,cACE,WAAW,KAAK,QAAQ;AAAA,YAC1B;AAAA,UACF;AAAA,UACA,MAAM;AAAA,UACN;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MACA,cAAc,OAAO,SAAS,YAAY,aAAa;AACrD,eAAO,MAAM,KAAK,QAAQ,MAAM;AAAA,UAC9B,MAAM;AAAA,UACN,MAAM;AAAA,YACJ;AAAA,cACE;AAAA,cACA;AAAA,cACA,WAAW,KAAK,QAAQ;AAAA,YAC1B;AAAA,UACF;AAAA,UACA,MAAM;AAAA,UACN;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MACA,QAAQ,OAAO,SAIT;AACJ,cAAM,KAAK,QAAQ,MAAM;AAAA,UACvB,MAAM;AAAA,UACN,MAAM;AAAA,YACJ;AAAA,cACE,WAAW,KAAK;AAAA,cAChB,SAAS,KAAK;AAAA,cACd,OAAO,KAAK;AAAA,cACZ,WAAW,KAAK,QAAQ;AAAA,YAC1B;AAAA,UACF;AAAA,UACA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MACA,eAAe,OAAO,YAAY;AAChC,cAAM,OAAO,aAAa,IAAI,QAAQ,IAAI;AAC1C,YAAI,CAAC,MAAM;AAET,iBAAO;AAAA,QACT;AAIA,cAAM,eAAe,KAAK,QAAQ,OAAO;AAEzC,YAAI,iBAAiB,UAAU,KAAK,UAAU,aAAa,OAAO;AAChE,iBAAO;AAAA,QACT;AAGA,YAAI,KAAK,UAAU,aAAa,QAAQ;AACtC,iBAAO;AAAA,QACT;AAEA,cAAM,gBAAgB,KAAK,UAAU;AACrC,YAAI,eAAe;AACjB,gBAAM,sBAAsB,MAAM,cAAc;AAAA,YAC9C,UAAU,QAAQ;AAAA,YAClB,QAAQ,QAAQ;AAAA,YAChB,cAAc,KAAK,QAAQ,OAAO;AAAA,YAClC,SAAS,KAAK;AAAA,UAChB,CAAC;AACD,cAAI,CAAC,qBAAqB;AACxB,mBAAO;AAAA,UACT;AAAA,QACF;AAIA,cAAM,mBAAmB,KAAK,mBAAmB,KAAK,QAAQ;AAC9D,cAAMC,wBAAuB,IAAI,qBAAqB;AAAA,UACpD,SAAS,KAAK,QAAQ,MAAM,kBAAkB,gBAAgB;AAAA,QAChE,CAAC;AACD,YAAI,KAAK,UAAU,aAAa,SAAS;AACvC,cACEA,sBAAqB,OAAO,iBAAiB,cAC7C,iBAAiB,YACjB;AACA,mBAAO;AAAA,UACT;AAAA,QACF;AAEA,YAAIA,sBAAqB,OAAO,cAAc,SAAS,QAAQ,IAAI,GAAG;AACpE,iBAAO;AAAA,QACT;AAEA,eACG,MAAM,KAAK,gBAAgB;AAAA,UAC1B;AAAA,UACA,UAAU,KAAK,UAAU;AAAA,QAC3B,CAAC,KAAM;AAAA,MAEX;AAAA,IACF,CAAC;AACD,UAAM,UAAU,oBAAI,KAAK;AACzB,UAAM,KAAK,QAAQ,MAAM;AAAA,MACvB,MAAM;AAAA,MACN,MAAM;AAAA,QACJ;AAAA,UACE,YAAY;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,UACA,WAAW,KAAK,QAAQ;AAAA,QAC1B;AAAA,MACF;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,CAAC,KAAK,cAAc;AACtB,YAAM,KAAK,QAAQ,MAAM;AAAA,QACvB,MAAM;AAAA,QACN,MAAM;AAAA,UACJ;AAAA,YACE,WAAW,KAAK,QAAQ;AAAA,YACxB;AAAA,YACA,OAAO,OAAO,UAAU,OAAO,KAAK,QAAQ,MAAM,MAAM;AAAA,YACxD,YAAY,OAAO,UAAU,OAAO,SAAS,aAAa;AAAA,YAC1D,gBAAgB,OAAO,UAAU,OAAO,SAAS,iBAAiB;AAAA,YAClE,UAAU,OAAO,UAAU,OAAO,SAAS,WAAW;AAAA,YACtD,OAAO,GAAG,cAAc,SAAS,EAAE,IAAI,cAAc,MAAM,EAAE;AAAA,UAC/D;AAAA,QACF;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AACA,iBAAa,MAAM;AAAA,MACjB;AAAA,MACA,WAAW,KAAK,QAAQ;AAAA,IAC1B,CAAC;AACD,QAAI,OAAO,WAAW,OAAO,KAAK,SAAS;AACzC,WAAK,QAAQ,cAAc,OAAO,KAAK,OAAO;AAAA,IAChD;AAEA,WAAO;AAAA,EACT;AACF;;;AC1dA,IAAM,gBAAgB;AAStB,SAAS,kBACP,WACA,SACA,YACA,SACQ;AAER,MAAI,QAAQ,SAAS,QAAQ,UAAU,eAAe;AACpD,WAAO,QAAQ;AAAA,EACjB;AAGA,QAAM,cAAc,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACvD,MAAI,eAAe,gBAAgB,eAAe;AAChD,WAAO;AAAA,EACT;AAGA,MAAI,WAAW,SAAS,WAAW,UAAU,eAAe;AAC1D,WAAO,WAAW;AAAA,EACpB;AAGA,SAAO,QAAQ,OAAO;AACxB;AAEA,eAAsB,aACpB,SAC+B;AAC/B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,YAAY,KAAK,IAAI;AAE3B,QAAM,WAAW,MAAM;AACrB,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AACA,WAAO,QAAQ,gBAAgB;AAAA,EACjC,GAAG;AAEH,MAAI;AAEF,QAAI,CAAC,WAAW,WAAW;AACzB,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,QAAI,CAAC,WAAW,cAAc;AAC5B,YAAM,IAAI,MAAM,UAAU,WAAW,SAAS,0BAA0B;AAAA,IAC1E;AAGA,UAAM,mBAAmB,YAAY,OAAO,UAAU;AAEtD,QAAI,iBAAiB,WAAW,GAAG;AACjC,YAAM,IAAI;AAAA,QACR,UAAU,WAAW,SAAS;AAAA,MAChC;AAAA,IACF;AAGA,UAAM,YAAY;AAAA,MAChB,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,iCAAiC,WAAW,SAAS,GAAG;AAAA,IAC1E;AAGA,UAAM,UAAU,IAAI,QAAQ;AAAA,MAC1B,WAAW,SAAS,OAAO;AAAA,MAC3B,iBAAiB,QAAQ;AAAA,MACzB;AAAA,IACF,CAAC;AAGD,UAAM,SAAS,MAAM,QAAQ,6BAA6B,QAAQ;AAAA,MAChE,OAAO;AAAA,MACP,cAAc,WAAW;AAAA,MACzB,OAAO;AAAA,MACP;AAAA,MACA,cAAc;AAAA,MACd,WAAW,OAAO,EAAE,QAAQ,MAAM;AAEhC,cAAM,kBAAqC;AAAA,UACzC,GAAG;AAAA,UACH,UAAU;AAAA,YACR,GAAI,QAAQ,YAAY,CAAC;AAAA,YACzB;AAAA,YACA,WAAW,WAAW;AAAA,UACxB;AAAA,QACF;AAEA,YAAI,WAAW;AACb,cAAI;AACF,kBAAM,UAAU,iBAAiB,SAAS,SAAS;AAAA,UACrD,SAAS,OAAO;AACd,oBAAQ,MAAM,0CAA0C,KAAK;AAAA,UAC/D;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,IACF,CAAC;AAGD,QAAI;AACJ,QAAI,OAAO,SAAS;AAClB,wBAAkB;AAAA,QAChB,QAAQ;AAAA,QACR;AAAA,QACA,SAAS,oBAAoB,OAAO,IAAI;AAAA,QACxC,gBAAgB,OAAO,UAAU,kBAAkB;AAAA,QACnD,eAAe,KAAK,IAAI,IAAI;AAAA,QAC5B,OAAO;AAAA,QACP,OAAO;AAAA,UACL,aAAa,OAAO,KAAK,OAAO,gBAAgB;AAAA,UAChD,cAAc,OAAO,KAAK,OAAO,oBAAoB;AAAA,QACvD;AAAA,MACF;AAAA,IACF,OAAO;AACL,wBAAkB;AAAA,QAChB,QAAQ;AAAA,QACR;AAAA,QACA,SAAS,2BAA2B,OAAO,MAAM,OAAO;AAAA,QACxD,gBAAgB;AAAA,QAChB,eAAe,KAAK,IAAI,IAAI;AAAA,QAC5B,OAAO;AAAA,QACP,OAAO,EAAE,aAAa,GAAG,cAAc,EAAE;AAAA,MAC3C;AAAA,IACF;AAEA,UAAM,QAAQ,MAAM;AAAA,MAClB,MAAM;AAAA,MACN,MAAM;AAAA,QACJ;AAAA,UACE,iBAAiB,QAAQ,mBAAmB;AAAA,UAC5C;AAAA,UACA,WAAW,WAAW;AAAA,UACtB,QAAQ;AAAA,UACR,OAAO,gBAAgB;AAAA,UACvB,gBAAgB,gBAAgB;AAAA,UAChC,eAAe,gBAAgB;AAAA,UAC/B,OAAO;AAAA,QACT;AAAA,MACF;AAAA,MACA;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA,SAAS,0BAA0B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACzF,gBAAgB;AAAA,MAChB,eAAe,KAAK,IAAI,IAAI;AAAA,MAC5B,OAAO,EAAE,aAAa,GAAG,cAAc,EAAE;AAAA,IAC3C;AAAA,EACF;AACF;AAEA,SAAS,oBAAoB,MAAuC;AAClE,MAAI,KAAK,QAAQ,OAAO,KAAK,SAAS,UAAU;AAC9C,WAAO,KAAK;AAAA,EACd;AACA,MAAI,KAAK,WAAW,OAAO,KAAK,YAAY,UAAU;AACpD,WAAO,KAAK;AAAA,EACd;AACA,SAAO;AACT;AAEA,SAAS,YAAY,UAAkB,UAAmC;AACxE,QAAM,EAAE,OAAO,gBAAgB,IAAI;AACnC,QAAM,gBAAgB,IAAI,IAAI,mBAAmB,CAAC,CAAC;AACnD,QAAM,cACJ,UAAU,UAAc,MAAM,WAAW,KAAK,MAAM,CAAC,MAAM;AAE7D,MAAI,aAAa;AACf,WAAO,SAAS,OAAO,CAAC,SAAS,CAAC,cAAc,IAAI,KAAK,IAAI,CAAC;AAAA,EAChE;AAEA,QAAM,aAAa,IAAI,IAAI,KAAK;AAChC,SAAO,SAAS;AAAA,IACd,CAAC,SAAS,WAAW,IAAI,KAAK,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,IAAI;AAAA,EACrE;AACF;;;AnBtMA,IAAM,kBAAkB;AACxB,IAAM,yBAAyB;AAExB,IAAM,eAAN,MAAmB;AAAA,EAChB,SAAuC,oBAAI,IAAI;AAAA,EAC/C;AAAA,EACA,SAA2B,CAAC;AAAA,EAEpC,YAAY,MAA4B;AACtC,SAAK,UAAU,KAAK;AACpB,SAAK,sBAAsB;AAAA,EAC7B;AAAA,EAEQ,wBAA8B;AAAA,EAMtC;AAAA,EAEA,cAAc,YAAmC;AAC/C,QAAI,CAAC,WAAW,WAAW;AACzB,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,QAAI,CAAC,WAAW,cAAc;AAC5B,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAEA,SAAK,OAAO,IAAI,WAAW,WAAW,UAAU;AAAA,EAClD;AAAA,EAEA,eAAe,OAAiC;AAC9C,QAAI,MAAM,cAAc,QAAW;AACjC,aAAO;AAAA,IACT;AACA,QAAI,OAAO,MAAM,cAAc,WAAW;AACxC,aAAO,MAAM;AAAA,IACf;AACA,QAAI,OAAO,MAAM,cAAc,YAAY;AACzC,aAAO,MAAM,UAAU,KAAK,OAAO;AAAA,IACrC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,WAAgD;AACvD,UAAM,QAAQ,KAAK,OAAO,IAAI,SAAS;AACvC,QAAI,SAAS,KAAK,eAAe,KAAK,GAAG;AACvC,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,eAAkC;AAChC,WAAO,MAAM,KAAK,KAAK,OAAO,OAAO,CAAC,EAAE;AAAA,MAAO,CAAC,UAC9C,KAAK,eAAe,KAAK;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,gBAA0B;AACxB,WAAO,KAAK,aAAa,EAAE,IAAI,CAAC,UAAU,MAAM,SAAS;AAAA,EAC3D;AAAA,EAEA,MAAM,YACJ,OACA,SAgB+B;AAC/B,UAAM,aAAa,KAAK,SAAS,MAAM,aAAa;AACpD,QAAI,CAAC,YAAY;AACf,YAAM,iBAAiB,KAAK,cAAc,EAAE,KAAK,IAAI;AACrD,YAAM,IAAI;AAAA,QACR,eAAe,MAAM,aAAa,kCAAkC,cAAc;AAAA,MACpF;AAAA,IACF;AAEA,UAAM,iBAAsC;AAAA,MAC1C;AAAA,MACA,QAAQ,MAAM;AAAA,MACd,OAAO,QAAQ;AAAA,MACf,SAAS,KAAK;AAAA,MACd,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,MACd,iBAAiB,QAAQ;AAAA,MACzB,qBAAqB,WAAW,cAC5B,QAAQ,sBACR;AAAA,MACJ,KAAK,QAAQ;AAAA,MACb,QAAQ,QAAQ;AAAA,MAChB,WAAW,QAAQ;AAAA,MACnB,eAAe,QAAQ;AAAA,IACzB;AAEA,WAAO,aAAa,cAAc;AAAA,EACpC;AAAA,EAEA,uBAA+B;AAC7B,UAAM,eAAe,KAAK,aAAa,EACpC,IAAI,CAAC,UAAU;AACd,aAAO,KAAK,MAAM,SAAS,KAAK,MAAM,aAAa,2DAA2D;AAAA,IAChH,CAAC,EACA,KAAK,IAAI;AAEZ,WAAO,GAAG,YAAY;AAAA,EACxB;AAAA,EAEA,MAAM,aAA4B;AAChC,SAAK,SAAS,CAAC;AAGf,UAAM,KAAK,sBAAsB;AAGjC,UAAM,kBAAkBC,MAAK;AAAA,MAC3BA,MAAK,QAAQ,KAAK,QAAQ,MAAM,eAAe;AAAA,MAC/C;AAAA,MACA;AAAA,IACF;AAEA,SAAK,wBAAwB,mDAAyC;AAGtE,UAAM,YAAYA,MAAK,KAAK,KAAK,QAAQ,MAAM,iBAAiB,QAAQ;AACxE,SAAK,wBAAwB,gCAA6B;AAG1D,UAAM,mBAAmBA,MAAK;AAAA,MAC5BA,MAAK,QAAQ,KAAK,QAAQ,MAAM,gBAAgB;AAAA,MAChD;AAAA,MACA;AAAA,IACF;AACA,SAAK,wBAAwB,sDAA2C;AAGxE,UAAM,aAAaA,MAAK,KAAK,KAAK,QAAQ,MAAM,kBAAkB,QAAQ;AAC1E,SAAK,wBAAwB,mCAA+B;AAAA,EAC9D;AAAA,EAEA,MAAc,wBAAuC;AACnD,UAAM,eAAe,MAAM,KAAK,QAAQ,MAAM;AAAA,MAC5C,MAAM;AAAA,MACN,MAAM,CAAC;AAAA,MACP,MAAM,CAAC;AAAA,MACP;AAAA,IACF,CAAC;AAED,eAAW,SAAS,cAAc;AAChC,WAAK,OAAO,IAAI,MAAM,WAAW;AAAA,QAC/B,GAAG;AAAA,QACH,OAAO,MAAM,SAAS;AAAA,QACtB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,YAA8B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,wBACN,WACA,QACM;AACN,QAAI,CAACC,IAAG,WAAW,SAAS,GAAG;AAC7B;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAUA,IAAG,YAAY,WAAW,EAAE,eAAe,KAAK,CAAC;AAEjE,iBAAW,SAAS,SAAS;AAC3B,YAAI,MAAM,OAAO,KAAK,MAAM,KAAK,SAAS,KAAK,GAAG;AAChD,gBAAM,YAAYD,MAAK,KAAK,WAAW,MAAM,IAAI;AACjD,eAAK,cAAc,WAAW,MAAM;AAAA,QACtC;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,UACJ,iBAAiB,QACb,MAAM,UACN;AACN,WAAK,OAAO,KAAK;AAAA,QACf,MAAM;AAAA,QACN,SAAS,oCAAoC,OAAO;AAAA,MACtD,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,cAAc,UAAkB,QAA2B;AACjE,QAAI;AACF,YAAM,UAAUC,IAAG,aAAa,UAAU,OAAO;AACjD,YAAM,SAAS,KAAK,eAAe,SAAS,QAAQ;AAEpD,UAAI,QAAQ;AACV,YACE,iDACA,iDACA;AACA,iBAAO,QAAQ,KAAK,iBAAiB,OAAO,SAAS,CAAC,GAAG,QAAQ;AACjE,iBAAO,kBAAkB,KAAK;AAAA,YAC5B,OAAO,mBAAmB,CAAC;AAAA,YAC3B;AAAA,UACF;AAAA,QACF;AACA,aAAK,OAAO,IAAI,OAAO,WAAW;AAAA,UAChC,GAAG;AAAA,UACH;AAAA,UACA,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,YAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,WAAK,OAAO,KAAK;AAAA,QACf,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,iBAAiB,WAAqB,UAA4B;AAExE,WAAO;AAAA,EACT;AAAA,EAEQ,eACN,SACA,UACiD;AACjD,QAAI;AACF,YAAM,EAAE,YAAY,KAAK,IAAI,gBAQ1B,SAAS,QAAQ;AAEpB,UAAI,CAAC,WAAW,MAAM;AACpB,aAAK,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD,eAAO;AAAA,MACT;AAEA,UAAI,CAAC,WAAW,aAAa;AAC3B,aAAK,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD,eAAO;AAAA,MACT;AAEA,UAAI,WAAW,KAAK,SAAS,iBAAiB;AAC5C,aAAK,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS,kCAAkC,eAAe;AAAA,QAC5D,CAAC;AACD,eAAO;AAAA,MACT;AAEA,UAAI,WAAW,KAAK,SAAS,IAAI,GAAG;AAClC,aAAK,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD,eAAO;AAAA,MACT;AAEA,UAAI,WAAW,YAAY,SAAS,wBAAwB;AAC1D,aAAK,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS,yCAAyC,sBAAsB;AAAA,QAC1E,CAAC;AACD,eAAO;AAAA,MACT;AAEA,UAAI,WAAW,YAAY,SAAS,IAAI,GAAG;AACzC,aAAK,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD,eAAO;AAAA,MACT;AAEA,YAAM,eAAe,KAAK,KAAK;AAC/B,UAAI,CAAC,cAAc;AACjB,aAAK,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD,eAAO;AAAA,MACT;AAEA,YAAM,QAAQ,WAAW,QACrB,WAAW,MACR,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,IAC7B;AAEJ,YAAM,kBAAkB,WAAW,kBAC/B,WAAW,gBACR,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,IAC7B;AAEJ,aAAO;AAAA,QACL,WAAW,WAAW;AAAA,QACtB,WAAW,WAAW;AAAA,QACtB;AAAA,QACA,OAAO,WAAW,SAAS;AAAA,QAC3B;AAAA,QACA;AAAA,QACA,aAAa,WAAW;AAAA,QACxB,OAAO,WAAW;AAAA,MACpB;AAAA,IACF,SAAS,OAAO;AACd,WAAK,OAAO,KAAK;AAAA,QACf,MAAM;AAAA,QACN,SACE,iBAAiB,QACb,MAAM,UACN;AAAA,MACR,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AoBnXA,SAAS,aAAa;AACtB,OAAO,YAAY;AACnB,OAAO,QAAQ;AAEf,IAAM,kBAAkB,MAAM,OAAO;AAmB9B,IAAM,wBAAN,MAA4B;AAAA,EACzB,QAAqC,oBAAI,IAAI;AAAA,EAErD,WAAW,OAAgC;AACzC,UAAM,KAAK,QAAQ,OAAO,YAAY,CAAC,EAAE,SAAS,KAAK,CAAC;AACxD,UAAM,OAAuB;AAAA,MAC3B;AAAA,MACA,SAAS,MAAM;AAAA,MACf,KAAK,MAAM;AAAA,MACX,MAAM,MAAM;AAAA,MACZ,QAAQ;AAAA,MACR,WAAW,KAAK,IAAI;AAAA,MACpB,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AACA,SAAK,MAAM,IAAI,IAAI,IAAI;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,IAAmC;AACzC,WAAO,KAAK,MAAM,IAAI,EAAE,KAAK;AAAA,EAC/B;AAAA,EAEA,cAAgC;AAC9B,WAAO,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC;AAAA,EACvC;AAAA,EAEA,aAAa,IAAY,QAAsB;AAC7C,UAAM,OAAO,KAAK,MAAM,IAAI,EAAE;AAC9B,QAAI,MAAM;AACR,YAAM,YAAY,KAAK,SAAS;AAChC,UAAI,UAAU,SAAS,iBAAiB;AACtC,cAAM,iBAAiB,KAAK,MAAM,kBAAkB,GAAG;AACvD,aAAK,SACH,iCACA,UAAU,MAAM,UAAU,SAAS,kBAAkB,cAAc;AAAA,MACvE,OAAO;AACL,aAAK,SAAS;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,iBACE,IACA,QACA,WAA0B,MACpB;AACN,UAAM,OAAO,KAAK,MAAM,IAAI,EAAE;AAC9B,QAAI,MAAM;AACR,WAAK,SAAS;AACd,UAAI,aAAa,MAAM;AACrB,aAAK,WAAW;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAAW,IAAkB;AAC3B,SAAK,MAAM,OAAO,EAAE;AAAA,EACtB;AAAA,EAEQ,eAAe,KAAsB;AAC3C,QAAI;AACF,cAAQ,KAAK,KAAK,CAAC;AACnB,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,IAA8B;AAC3C,UAAM,OAAO,KAAK,MAAM,IAAI,EAAE;AAC9B,QAAI,CAAC,QAAQ,KAAK,WAAW,WAAW;AACtC,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,GAAG,SAAS,MAAM;AAEpC,QAAI;AACF,UAAI,WAAW;AACb,cAAM,YAAY,CAAC,QAAQ,KAAK,IAAI,SAAS,GAAG,MAAM,IAAI,CAAC;AAAA,MAC7D,OAAO;AACL,cAAM,YAAY,KAAK,QAAQ,KAAK;AACpC,YAAI;AACF,kBAAQ,KAAK,CAAC,WAAW,SAAS;AAClC,gBAAM,IAAI,QAAQ,CAACC,aAAY,WAAWA,UAAS,GAAG,CAAC;AACvD,cAAI,KAAK,eAAe,SAAS,GAAG;AAClC,oBAAQ,KAAK,CAAC,WAAW,SAAS;AAAA,UACpC;AAAA,QACF,QAAQ;AACN,cAAI;AACF,oBAAQ,KAAK,KAAK,KAAK,SAAS;AAAA,UAClC,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AAEA,WAAK,iBAAiB,IAAI,QAAQ;AAClC,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,WAAK,iBAAiB,IAAI,QAAQ;AAClC,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AChIA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAaV,IAAM,aAAN,MAAiB;AAAA,EACd;AAAA,EAER,YAAY,EAAE,eAAe,GAA+B;AAC1D,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEQ,WAA6B;AACnC,QAAI,CAACD,IAAG,WAAW,KAAK,cAAc,GAAG;AACvC,aAAO,EAAE,UAAU,CAAC,EAAE;AAAA,IACxB;AACA,QAAI;AACF,YAAM,UAAUA,IAAG,aAAa,KAAK,gBAAgB,OAAO;AAC5D,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B,SAAS,OAAO;AACd,aAAO,EAAE,UAAU,CAAC,EAAE;AAAA,IACxB;AAAA,EACF;AAAA,EAEQ,UAAU,MAA8B;AAC9C,UAAM,MAAMC,MAAK,QAAQ,KAAK,cAAc;AAC5C,QAAI,CAACD,IAAG,WAAW,GAAG,GAAG;AACvB,MAAAA,IAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,IACvC;AAEA,IAAAA,IAAG;AAAA,MACD,KAAK;AAAA,MACL,KAAK,UAAU,MAAM,MAAM,CAAC;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,kBAAkB,EAAE,IAAI,GAA8B;AACpD,UAAM,OAAO,KAAK,SAAS;AAC3B,WAAO,KAAK,SAAS,GAAG,GAAG,WAAW,CAAC;AAAA,EACzC;AAAA,EAEA,kBAAkB,EAAE,KAAK,QAAQ,GAA2C;AAC1E,UAAM,OAAO,KAAK,SAAS;AAE3B,QAAI,CAAC,KAAK,SAAS,GAAG,GAAG;AACvB,WAAK,SAAS,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE;AAAA,IACrC;AAEA,SAAK,SAAS,GAAG,EAAE,QAAQ,KAAK,OAAO;AACvC,SAAK,UAAU,IAAI;AAAA,EACrB;AAAA,EAEA,uBAAuB,EAAE,IAAI,GAAmC;AAC9D,UAAM,OAAO,KAAK,SAAS;AAC3B,WAAO,KAAK,SAAS,GAAG,GAAG,gBAAgB;AAAA,EAC7C;AAAA,EAEA,0BAA0B,EAAE,IAAI,GAA0B;AACxD,UAAM,OAAO,KAAK,SAAS;AAE3B,QAAI,CAAC,KAAK,SAAS,GAAG,GAAG;AACvB,WAAK,SAAS,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE;AAAA,IACrC;AAEA,SAAK,SAAS,GAAG,EAAE,eAAe,KAAK,IAAI;AAC3C,SAAK,UAAU,IAAI;AAAA,EACrB;AAAA,EAEA,kBAA4B;AAC1B,UAAM,OAAO,KAAK,SAAS;AAC3B,WAAO,KAAK,gBAAgB,CAAC;AAAA,EAC/B;AAAA,EAEA,eAAe,OAAqB;AAClC,UAAM,OAAO,KAAK,SAAS;AAC3B,UAAM,eAAe,KAAK,gBAAgB,CAAC;AAC3C,UAAM,WAAW,aAAa,OAAO,CAAC,MAAM,MAAM,KAAK;AACvD,aAAS,QAAQ,KAAK;AACtB,SAAK,eAAe,SAAS,MAAM,GAAG,CAAC;AACvC,SAAK,UAAU,IAAI;AAAA,EACrB;AACF;;;AC3FA,SAAS,oCAAoC;AAC7C,SAAS,qCAAqC;AAC9C,OAAO,iBAAiB;AAExB,SAAS,eAAe;AAmBxB,IAAM,QAAQ,YAAY,aAAa;AAmBhC,IAAM,aAAN,MAAM,YAAW;AAAA,EACd,UAAoC,oBAAI,IAAI;AAAA,EAC5C,UAAqC,CAAC;AAAA,EACtC,gBAAyB;AAAA,EACzB;AAAA,EACA,WAAoB;AAAA,EAE5B,OAAO,OAAO,YAAmD;AAC/D,UAAM,qBAAqB,UAAU;AACrC,UAAM,UAAU,IAAI,YAAW;AAC/B,YAAQ,UAAU,cAAc,CAAC;AAGjC,eAAW,CAAC,KAAK,MAAM,KAAK,OAAO,QAAQ,cAAc,CAAC,CAAC,GAAG;AAC5D,UAAI,OAAO,SAAS;AAClB,cAAM,iCAAiC,GAAG,EAAE;AAC5C;AAAA,MACF;AACA,cAAQ,QAAQ,IAAI,KAAK;AAAA,QACvB;AAAA,QACA,QAAQ;AAAA,QACR,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAA2B;AAE/B,QAAI,KAAK,aAAa;AACpB,aAAO,KAAK;AAAA,IACd;AAEA,QAAI,KAAK,UAAU;AAEjB,aAAO,KAAK,UAAU;AACpB,cAAM,IAAI,QAAQ,CAACE,aAAY,WAAWA,UAAS,EAAE,CAAC;AAAA,MACxD;AACA,UAAI,KAAK,eAAe;AACtB;AAAA,MACF;AAAA,IACF;AAEA,SAAK,WAAW;AAChB,QAAI;AAEF,UAAI,KAAK,eAAe;AACtB;AAAA,MACF;AACA,WAAK,cAAc,KAAK,aAAa;AACrC,YAAM,KAAK;AAAA,IACb,UAAE;AAEA,WAAK,WAAW;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,MAAc,eAA8B;AAC1C,UAAM,mCAAmC;AACzC,UAAM,qBAAsC,CAAC;AAE7C,eAAW,CAAC,KAAK,MAAM,KAAK,OAAO,QAAQ,KAAK,OAAO,GAAG;AACxD,UAAI,OAAO,SAAS;AAClB;AAAA,MACF;AAEA,YAAM,oBAAoB,KAAK,eAAe,KAAK,MAAM;AACzD,yBAAmB,KAAK,iBAAiB;AAAA,IAC3C;AAGA,UAAM,QAAQ,WAAW,kBAAkB;AAC3C,SAAK,gBAAgB;AACrB,UAAM,8BAA8B;AAAA,EACtC;AAAA,EAEA,MAAc,eAAe,KAAa,QAAkC;AAC1E,UAAM,cAAc,KAAK,QAAQ,IAAI,GAAG;AACxC,QAAI,CAAC,YAAa;AAElB,QAAI;AACF,YAAM,0BAA0B,GAAG,EAAE;AACrC,kBAAY,SAAS;AAGrB,YAAM,EAAE,QAAQ,MAAM,IAAI,MAAM,KAAK,6BAA6B,MAAM;AAExE,kBAAY,SAAS;AACrB,kBAAY,SAAS;AACrB,kBAAY,QAAQ;AACpB,kBAAY,QAAQ;AAEpB;AAAA,QACE,sCAAsC,GAAG,YAAY,OAAO,KAAK,KAAK,EAAE,MAAM;AAAA,MAChF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eACJ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACvD,YAAM,gCAAgC,GAAG,KAAK,YAAY,EAAE;AAG5D,YAAM,mBAAmB,KAAK,kBAAkB,KAAK;AAErD,kBAAY,SAAS;AACrB,kBAAY,QAAQ;AACpB,kBAAY,cAAc;AAC1B,kBAAY,mBAAmB;AAG/B,kBAAY,SAAS;AACrB,kBAAY,QAAQ;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,cAA+B;AACnC,UAAM,WAAmB,CAAC;AAC1B,UAAM,YAAY,oBAAI,IAAY;AAElC,eAAW,CAAC,YAAY,WAAW,KAAK,KAAK,QAAQ,QAAQ,GAAG;AAC9D,UAAI,YAAY,WAAW,eAAe,CAAC,YAAY,OAAO;AAC5D;AAAA,MACF;AAEA,iBAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,YAAY,KAAK,GAAG;AACnE,cAAM,eAAe,QAAQ,UAAU,KAAK,QAAQ;AAEpD,YAAI,UAAU,IAAI,YAAY,GAAG;AAC/B,gBAAM,IAAI,MAAM,8BAA8B,YAAY,EAAE;AAAA,QAC9D;AAEA,kBAAU,IAAI,YAAY;AAC1B,iBAAS;AAAA,UACP,KAAK;AAAA,YACH;AAAA,YACA;AAAA,YACA;AAAA,YACA,YAAY;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,MAAiC;AAC9C,UAAM,WAAmB,CAAC;AAC1B,UAAM,YAAY,oBAAI,IAAY;AAElC,eAAW,OAAO,MAAM;AACtB,YAAM,cAAc,KAAK,QAAQ,IAAI,GAAG;AACxC,UACE,CAAC,eACD,YAAY,WAAW,eACvB,CAAC,YAAY,OACb;AACA;AAAA,MACF;AAEA,iBAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,YAAY,KAAK,GAAG;AACnE,cAAM,eAAe,QAAQ,GAAG,KAAK,QAAQ;AAE7C,YAAI,UAAU,IAAI,YAAY,GAAG;AAC/B,gBAAM,IAAI,MAAM,8BAA8B,YAAY,EAAE;AAAA,QAC9D;AAEA,kBAAU,IAAI,YAAY;AAC1B,iBAAS;AAAA,UACP,KAAK;AAAA,YACH;AAAA,YACA;AAAA,YACA;AAAA,YACA,YAAY;AAAA,UACd;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU;AAEd,UAAM,gBAAgB,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC,EACnD,OAAO,CAAC,UAAU,MAAM,MAAM,EAC9B;AAAA,MAAI,CAAC,UACJ,MAAM,OAAO,MAAM,EAAE,MAAM,CAAC,QAAe;AACzC,cAAM,wCAAwC,GAAG;AAAA,MACnD,CAAC;AAAA,IACH;AAEF,UAAM,QAAQ,WAAW,aAAa;AACtC,SAAK,QAAQ,MAAM;AACnB,SAAK,gBAAgB;AACrB,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,iBAA2B;AACzB,WAAO,MAAM,KAAK,KAAK,QAAQ,KAAK,CAAC;AAAA,EACvC;AAAA,EAEA,UAAU,MAAuB;AAC/B,WAAO,KAAK,QAAQ,IAAI,IAAI;AAAA,EAC9B;AAAA,EAEA,gBAAgB,MAA2C;AACzD,WAAO,KAAK,QAAQ,IAAI,IAAI,GAAG;AAAA,EACjC;AAAA,EAEA,eAAe,MAAkC;AAC/C,WAAO,KAAK,QAAQ,IAAI,IAAI,GAAG;AAAA,EACjC;AAAA,EAEA,MAAM,qBAKJ;AACA,UAAM,KAAK,UAAU;AAErB,UAAM,SAGF,CAAC;AACL,eAAW,CAAC,MAAM,KAAK,KAAK,KAAK,QAAQ,QAAQ,GAAG;AAClD,aAAO,IAAI,IAAI;AAAA,QACb,QAAQ,MAAM;AAAA,QACd,OAAO,MAAM;AAAA,QACb,WAAW,MAAM,QAAQ,OAAO,KAAK,MAAM,KAAK,EAAE,SAAS;AAAA,MAC7D;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAqB;AACnB,WAAO,CAAC,CAAC,KAAK,eAAe,CAAC,KAAK;AAAA,EACrC;AAAA,EAEA,MAAM,gBAAgB,YAAmC;AACvD,UAAM,SAAS,KAAK,QAAQ,UAAU;AACtC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,UAAU,UAAU,6BAA6B;AAAA,IACnE;AAEA,UAAM,cAAc,KAAK,QAAQ,IAAI,UAAU;AAC/C,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,MAAM,UAAU,UAAU,kBAAkB;AAAA,IACxD;AAGA,UAAM,uCAAuC,UAAU,EAAE;AAGzD,QAAI,YAAY,QAAQ;AACtB,UAAI;AACF,cAAM,YAAY,OAAO,MAAM;AAAA,MACjC,SAAS,OAAO;AACd,cAAM,qCAAqC,UAAU,KAAK,KAAK;AAAA,MACjE;AAAA,IACF;AAGA,gBAAY,SAAS;AACrB,gBAAY,QAAQ;AACpB,gBAAY,QAAQ;AACpB,gBAAY,SAAS;AAErB,UAAM,KAAK,eAAe,YAAY,MAAM;AAG5C,UAAM,WAAW,KAAK,QAAQ,IAAI,UAAU;AAC5C,QAAI,UAAU,WAAW,aAAa;AACpC,YAAM,IAAI,MAAM,UAAU,SAAS,qBAAqB;AAAA,IAC1D;AAEA,UAAM,wCAAwC,UAAU,EAAE;AAAA,EAC5D;AAAA,EAEA,MAAc,cAAc,QAAmB;AAC7C,QAAI,OAAO,SAAS;AAElB,YAAM,MAAM,OAAO,MACf,EAAE,GAAG,OAAO,KAAK,MAAM,QAAQ,IAAI,QAAQ,GAAG,IAC9C;AAEJ,YAAM,EAAE,+BAA+B,IAAI,MAAM,OAC/C,uBACF;AAGA,YAAM,uBAAuB;AAAA,QAC3B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,UAAI,UAAU,OAAO;AACrB,UAAI,OAAO,OAAO;AAClB,YAAM,QAAQ,QAAQ,aAAa;AACnC,UAAI,SAAS,qBAAqB,SAAS,QAAQ,YAAY,CAAC,GAAG;AACjE,eAAO,CAAC,MAAM,SAAS,GAAI,QAAQ,CAAC,CAAE;AACtC,kBAAU;AAAA,MACZ;AAEA,aAAO,6BAA6B;AAAA,QAClC,WAAW,IAAI,+BAA+B;AAAA,UAC5C;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH,WAAW,OAAO,KAAK;AAErB,YAAM,gBAAgB,OAAO,QAAQ;AACrC,UAAI,kBAAkB,OAAO;AAE3B,eAAO,6BAA6B;AAAA,UAClC,WAAW;AAAA,YACT,MAAM;AAAA,YACN,KAAK,OAAO;AAAA,YACZ,SAAS,OAAO;AAAA,UAClB;AAAA,QACF,CAAC;AAAA,MACH,OAAO;AAEL,eAAO,6BAA6B;AAAA,UAClC,WAAW,IAAI,8BAA8B,IAAI,IAAI,OAAO,GAAG,GAAG;AAAA,YAChE,aAAa;AAAA,cACX,SAAS,OAAO;AAAA,YAClB;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AAAA,EACF;AAAA,EAEA,MAAc,6BACZ,QACsD;AACtD,UAAM,SAAS,MAAM,KAAK,cAAc,MAAM;AAC9C,QAAI;AACF,YAAM,QAAQ,MAAM,OAAO,MAAM;AACjC,aAAO,EAAE,QAAQ,MAAM;AAAA,IACzB,SAAS,OAAO;AAEd,YAAM,OAAO,MAAM,EAAE,MAAM,CAAC,QAAQ;AAClC,cAAM,kDAAkD,GAAG;AAAA,MAC7D,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,kBAAkB,OAAyB;AACjD,QAAI,EAAE,iBAAiB,QAAQ;AAC7B,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,MAAM,QAAQ,YAAY;AAG1C,UAAM,kBAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,kBAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,QAAI,gBAAgB,KAAK,CAAC,cAAc,QAAQ,SAAS,SAAS,CAAC,GAAG;AACpE,aAAO;AAAA,IACT;AAGA,QAAI,gBAAgB,KAAK,CAAC,cAAc,QAAQ,SAAS,SAAS,CAAC,GAAG;AACpE,aAAO;AAAA,IACT;AAGA,WAAO;AAAA,EACT;AAAA,EAEA,yBACE,UACA,SACA,YACA,QACM;AACN,UAAM,iBAAiB,WAAW,QAAQ,mBAAmB,EAAE;AAC/D,UAAM,eAAe,SAAS,QAAQ,mBAAmB,GAAG;AAE5D,WAAO;AAAA,MACL,MAAM,QAAQ,cAAc,KAAK,YAAY;AAAA,MAC7C,aAAa,QAAQ;AAAA,MACrB,gBAAgB,CAAC,EAAE,OAAO,MAAM;AAC9B,eAAO,wBAAwB,MAA6B;AAAA,MAC9D;AAAA;AAAA,MAEA,YAAY,iBAAiB,QAAQ,YAAY,UAAU;AAAA,MAC3D,SAAS,OAAO,WAAW;AACzB,YAAI;AAEF,gBAAM,SAAS,MAAM,QAAQ,QAAQ,UAAU,CAAC,CAAC;AAEjD,gBAAM,gBAAgB,QAAQ,QAAQ,yBAAyB,SAAS,iBAAiB,KAAK,UAAU,MAAM,CAAC,KAAK,EAAE;AACtH,gBAAM,aAAa,6BAA6B,MAAM;AAEtD,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,YAAY,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UACnE;AAAA,QACF;AAAA,MACF;AAAA,MACA,UAAU;AAAA,QACR,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AACF;AA4CA,SAAS,iBAAiB,KAAmB;AAC3C,MAAI,QAAQ,QAAQ,QAAQ,QAAW;AACrC,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAO,IAAI,IAAI,gBAAgB,EAAE,OAAO,CAAC,MAAM,MAAM,MAAS;AAAA,EAChE;AACA,MAAI,OAAO,QAAQ,UAAU;AAC3B,UAAM,SAAkC,CAAC;AACzC,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,GAA8B,GAAG;AACnE,YAAM,UAAU,iBAAiB,CAAC;AAClC,UAAI,YAAY,QAAW;AACzB,eAAO,CAAC,IAAI;AAAA,MACd;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB,QAAqC;AACpE,MAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,WAAO;AAAA,EACT;AACA,QAAM,UAAU,OAAO,QAAQ,MAAM;AACrC,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,EACT;AACA,SAAO,QACJ,OAAO,CAAC,CAAC,KAAK,KAAK,MAAM,UAAU,QAAQ,UAAU,MAAS,EAC9D,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AACrB,WAAO,GAAG,GAAG,KAAK,cAAc,KAAK,CAAC;AAAA,EACxC,CAAC,EACA,KAAK,IAAI;AACd;AAEO,SAAS,6BACd,QACmC;AAKnC,MAAI;AAEJ,MAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,GAAG;AAElE,QAAI,aAAa,UAAU,MAAM,QAAQ,OAAO,OAAO,GAAG;AAExD,sBAAgB,OAAO;AAAA,IACzB,WAAW,gBAAgB,QAAQ;AAEjC,aAAO,cAAc,OAAO,UAAU;AAAA,IACxC,OAAO;AAEL,sBAAgB;AAAA,IAClB;AAAA,EACF,OAAO;AACL,oBAAgB;AAAA,EAClB;AAGA,QAAM,aAAa,CAAC,SAAiB;AACnC,WAAO,UAAU,QAAQ,KAAK,SAAS,UAAU,UAAU;AAAA,EAC7D;AACA,QAAM,cAAc,CAAC,SAAiB;AACpC,WACE,UAAU,QACV,KAAK,SAAS,WACd,UAAU,QACV,cAAc;AAAA,EAElB;AACA,QAAM,iBAAiB,CAAC,SAAiB;AACvC,WAAO,UAAU,QAAQ,KAAK,SAAS,cAAc,cAAc;AAAA,EACrE;AACA,QAAM,SAAS,CAAC,SAAiB;AAC/B,WAAO,WAAW,IAAI,KAAK,YAAY,IAAI,KAAK,eAAe,IAAI;AAAA,EACrE;AAGA,MAAI,aAAkB;AAEtB,MAAI,OAAO,eAAe,YAAY,CAAC,MAAM,QAAQ,UAAU,GAAG;AAEhE,QAAI,OAAO,UAAoB,GAAG;AAChC,mBAAa,CAAC,UAAU;AAAA,IAC1B,OAAO;AACL,mBAAa,cAAc,UAAU;AAAA,IACvC;AAAA,EACF,WAAW,MAAM,QAAQ,UAAU,GAAG;AAEpC,UAAM,UAAU,WAAW;AAAA,MACzB,CAAC,SAAS,OAAO,SAAS,YAAY,SAAS,QAAQ,OAAO,IAAI;AAAA,IACpE;AACA,QAAI,SAAS;AAEX,mBAAa,WAAW,IAAI,CAAC,SAAS;AACpC,YAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,OAAO,IAAI,GAAG;AAC7D,iBAAO;AAAA,QACT,OAAO;AACL,iBAAO,EAAE,MAAM,QAAQ,MAAM,cAAc,IAAI,EAAE;AAAA,QACnD;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AAEL,mBAAa,cAAc,UAAU;AAAA,IACvC;AAAA,EACF,WAAW,OAAO,eAAe,UAAU;AAAA,EAE3C,OAAO;AAEL,iBAAa,OAAO,UAAU;AAAA,EAChC;AAEA,SAAO;AACT;;;AChpBA,OAAOC,SAAQ;AACf,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAkBV,SAAS,kBAAkB,WAA2B;AAC3D,SAAOA,MAAK,KAAK,WAAW,WAAW;AACzC;AAEO,IAAM,QAAN,MAAY;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,MAA4C;AACtD,UAAM,cAAc,KAAK,YAAY,YAAY;AACjD,SAAK,kBAAkBA,MAAK,KAAKD,IAAG,QAAQ,GAAG,IAAI,WAAW,EAAE;AAChE,SAAK,mBAAmBC,MAAK;AAAA,MAC3B,KAAK;AAAA,MACL;AAAA,MACA,WAAW,KAAK,GAAG;AAAA,IACrB;AACA,SAAK,mBAAmBA,MAAK,KAAK,KAAK,KAAK,IAAI,WAAW,EAAE;AAAA,EAC/D;AAAA,EAEA,kBAAkB,WAAmB;AACnC,QAAIA,MAAK,WAAW,SAAS,GAAG;AAC9B,aAAO;AAAA,IACT,WAAW,UAAU,WAAW,GAAG,KAAK,UAAU,SAAS,QAAQ,GAAG;AACpE,aAAOA,MAAK,KAAK,QAAQ,IAAI,GAAG,SAAS;AAAA,IAC3C,OAAO;AACL,aAAOA,MAAK,KAAK,KAAK,kBAAkB,GAAG,SAAS,QAAQ;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,qBAAqB;AACnB,QAAI,CAACF,IAAG,WAAW,KAAK,gBAAgB,GAAG;AACzC,aAAO;AAAA,IACT;AACA,UAAM,sBAAsBA,IACzB,YAAY,KAAK,gBAAgB,EACjC,OAAO,CAAC,SAAS,KAAK,SAAS,QAAQ,CAAC,EACxC,IAAI,CAAC,SAAS;AACb,YAAM,QAAQA,IAAG,SAASE,MAAK,KAAK,KAAK,kBAAkB,IAAI,CAAC;AAChE,aAAO;AAAA,QACL,WAAW,MAAM,MAAM,QAAQ;AAAA,QAC/B,WAAWA,MAAK,SAAS,MAAM,QAAQ;AAAA,MACzC;AAAA,IACF,CAAC;AACH,UAAM,gBAAgB,oBAAoB;AAAA,MACxC,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE;AAAA,IAC5B,EAAE,CAAC;AACH,WAAO,cAAc;AAAA,EACvB;AAAA,EAEA,iBAAiB;AACf,QAAI,CAACF,IAAG,WAAW,KAAK,gBAAgB,GAAG;AACzC,aAAO,CAAC;AAAA,IACV;AACA,UAAM,aAAaA,IAChB,YAAY,KAAK,gBAAgB,EACjC,OAAO,CAAC,SAAS,KAAK,SAAS,QAAQ,CAAC,EACxC,IAAI,CAAC,SAAS;AACb,YAAM,WAAWE,MAAK,KAAK,KAAK,kBAAkB,IAAI;AACtD,YAAM,QAAQF,IAAG,SAAS,QAAQ;AAClC,YAAM,YAAYE,MAAK,SAAS,MAAM,QAAQ;AAG9C,UAAI,eAAe;AACnB,UAAI,UAAU;AACd,UAAI;AACF,cAAM,UAAUF,IAAG,aAAa,UAAU,OAAO;AACjD,cAAM,QAAQ,QAAQ,MAAM,IAAI,EAAE,OAAO,OAAO;AAChD,uBAAe,MAAM;AAGrB,YAAI,MAAM,SAAS,GAAG;AACpB,cAAI;AACF,kBAAM,aAAuB,KAAK,MAAM,MAAM,CAAC,CAAC;AAChD,gBAAI,WAAW,SAAS,YAAY,WAAW,OAAO,SAAS;AAC7D,wBAAU,WAAW,OAAO;AAAA,YAC9B,OAAO;AACL,wBAAU,+BAA+B,KAAK;AAAA,YAChD;AAAA,UACF,SAAS,GAAG;AACV,sBAAU,+BAA+B,KAAK;AAAA,UAChD;AAAA,QACF;AAAA,MACF,SAAS,GAAG;AAAA,MAEZ;AAEA,aAAO;AAAA,QACL;AAAA,QACA,UAAU,MAAM;AAAA,QAChB,SAAS,MAAM;AAAA,QACf;AAAA,QACA,SAAS,iBAAiB,OAAO;AAAA,MACnC;AAAA,IACF,CAAC,EACA,KAAK,CAAC,GAAG,MAAM,EAAE,SAAS,QAAQ,IAAI,EAAE,SAAS,QAAQ,CAAC,EAC1D,MAAM,GAAG,EAAE;AAEd,WAAO;AAAA,EACT;AAAA,EAEA,oBAAoB;AAClB,WAAOE,MAAK,KAAK,KAAK,iBAAiB,WAAW;AAAA,EACpD;AACF;AAEA,SAAS,iBAAiB,SAAyB;AACjD,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,QACJ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,QAAQ,GAAG,EACnB,KAAK;AACV;AAEA,SAAS,+BAA+B,OAAyB;AAC/D,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,YAAM,QAAkB,KAAK,MAAM,IAAI;AACvC,UACE,MAAM,SAAS,aACf,UAAU,SACV,MAAM,SAAS,UACf,OAAO,MAAM,YAAY,UACzB;AACA,eAAO,MAAM,QAAQ,SAAS,KAC1B,MAAM,QAAQ,MAAM,GAAG,EAAE,IAAI,QAC7B,MAAM;AAAA,MACZ;AAAA,IACF,SAAS,GAAG;AAAA,IAAC;AAAA,EACf;AACA,SAAO;AACT;AAEA,SAAS,WAAW,MAAc;AAChC,SAAO,KACJ,QAAQ,cAAc,EAAE,EACxB,QAAQ,iBAAiB,GAAG,EAC5B,QAAQ,OAAO,GAAG,EAClB,QAAQ,YAAY,EAAE,EACtB,YAAY;AACjB;;;AChKA,OAAO,WAAW;AAClB,OAAOC,SAAQ;AACf,OAAOC,SAAQ;AACf,OAAOC,WAAU;AASjB,SAAS,oBAAoB,WAAmB,OAA2B;AACzE,MAAI,MAAM,YAAY,EAAG,QAAO;AAChC,MAAI,MAAM,eAAe,GAAG;AAC1B,QAAI;AACF,aAAOC,IAAG,SAASC,MAAK,KAAK,WAAW,MAAM,IAAI,CAAC,EAAE,YAAY;AAAA,IACnE,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAEO,IAAK,cAAL,kBAAKC,iBAAL;AACL,EAAAA,aAAA,YAAS;AACT,EAAAA,aAAA,kBAAe;AACf,EAAAA,aAAA,YAAS;AACT,EAAAA,aAAA,mBAAgB;AAChB,EAAAA,aAAA,aAAU;AALA,SAAAA;AAAA,GAAA;AAoDZ,IAAMC,mBAAkB;AACxB,IAAMC,0BAAyB;AAMxB,IAAM,eAAN,MAAmB;AAAA,EAChB,YAAwC,oBAAI,IAAI;AAAA,EAChD,SAAuB,CAAC;AAAA,EACxB;AAAA,EACA;AAAA,EAER,YAAY,MAAwB;AAClC,SAAK,UAAU,KAAK;AACpB,SAAK,QAAQ,KAAK,QAAQ;AAAA,EAC5B;AAAA,EAEA,YAA6B;AAC3B,WAAO,MAAM,KAAK,KAAK,UAAU,OAAO,CAAC;AAAA,EAC3C;AAAA,EAEA,SAAS,MAAyC;AAChD,WAAO,KAAK,UAAU,IAAI,IAAI;AAAA,EAChC;AAAA,EAEA,YAA0B;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,cAAc,OAAuC;AACzD,QAAI;AACF,YAAM,UAAUJ,IAAG,aAAa,MAAM,MAAM,OAAO;AACnD,YAAM,EAAE,KAAK,IAAI,gBAAgB,SAAS,MAAM,IAAI;AACpD,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,YAAM,IAAI,MAAM,wBAAwB,MAAM,IAAI,KAAK,OAAO,EAAE;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,MAAM,aAA4B;AAChC,SAAK,UAAU,MAAM;AACrB,SAAK,SAAS,CAAC;AAEf,UAAM,eAAe,MAAM,KAAK,QAAQ,MAAM;AAAA,MAC5C,MAAM;AAAA,MACN,MAAM,CAAC;AAAA,MACP,MAAM,CAAC;AAAA,MACP;AAAA,IACF,CAAC;AAED,QAAI,MAAM,QAAQ,YAAY,GAAG;AAC/B,iBAAW,aAAa,cAAc;AACpC,YAAI,OAAO,cAAc,UAAU;AACjC,eAAK,OAAO,KAAK;AAAA,YACf,MAAM,OAAO,SAAS;AAAA,YACtB,SAAS;AAAA,UACX,CAAC;AACD;AAAA,QACF;AACA,YAAI,CAACA,IAAG,WAAW,SAAS,GAAG;AAC7B,eAAK,OAAO,KAAK;AAAA,YACf,MAAM;AAAA,YACN,SAAS;AAAA,UACX,CAAC;AACD;AAAA,QACF;AACA,aAAK,cAAc,WAAW,qBAAkB;AAAA,MAClD;AAAA,IACF;AAEA,UAAM,kBAAkBC,MAAK;AAAA,MAC3BA,MAAK,QAAQ,KAAK,MAAM,eAAe;AAAA,MACvC;AAAA,MACA;AAAA,IACF;AACA,SAAK,wBAAwB,iBAAiB,kCAAwB;AAEtE,UAAM,YAAYA,MAAK,KAAK,KAAK,MAAM,iBAAiB,QAAQ;AAChE,SAAK,wBAAwB,WAAW,qBAAkB;AAE1D,UAAM,mBAAmBA,MAAK;AAAA,MAC5BA,MAAK,QAAQ,KAAK,MAAM,gBAAgB;AAAA,MACxC;AAAA,MACA;AAAA,IACF;AACA,SAAK,wBAAwB,kBAAkB,oCAAyB;AAExE,UAAM,aAAaA,MAAK,KAAK,KAAK,MAAM,kBAAkB,QAAQ;AAClE,SAAK,wBAAwB,YAAY,uBAAmB;AAAA,EAC9D;AAAA,EAEQ,wBACN,WACA,QACM;AACN,QAAI,CAACD,IAAG,WAAW,SAAS,GAAG;AAC7B;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAUA,IAAG,YAAY,WAAW,EAAE,eAAe,KAAK,CAAC;AAEjE,iBAAW,SAAS,SAAS;AAC3B,YAAI,oBAAoB,WAAW,KAAK,GAAG;AACzC,gBAAM,YAAYC,MAAK,KAAK,WAAW,MAAM,MAAM,UAAU;AAC7D,cAAID,IAAG,WAAW,SAAS,GAAG;AAC5B,iBAAK,cAAc,WAAW,MAAM;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,UACJ,iBAAiB,QACb,MAAM,UACN;AACN,WAAK,OAAO,KAAK;AAAA,QACf,MAAM;AAAA,QACN,SAAS,oCAAoC,OAAO;AAAA,MACtD,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,cAAc,WAAmB,QAA2B;AAClE,QAAI;AACF,YAAM,UAAUA,IAAG,aAAa,WAAW,OAAO;AAClD,YAAM,SAAS,KAAK,eAAe,SAAS,SAAS;AAErD,UAAI,QAAQ;AACV,aAAK,UAAU,IAAI,OAAO,MAAM,EAAE,GAAG,QAAQ,OAAO,CAAC;AAAA,MACvD;AAAA,IACF,SAAS,OAAO;AACd,YAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,WAAK,OAAO,KAAK;AAAA,QACf,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,eACN,SACA,WACsC;AACtC,QAAI;AACF,YAAM,EAAE,WAAW,IAAI,gBAGpB,SAAS,SAAS;AAErB,UAAI,CAAC,WAAW,MAAM;AACpB,aAAK,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD,eAAO;AAAA,MACT;AAEA,UAAI,CAAC,WAAW,aAAa;AAC3B,aAAK,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD,eAAO;AAAA,MACT;AAEA,UAAI,WAAW,KAAK,SAASG,kBAAiB;AAC5C,aAAK,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS,kCAAkCA,gBAAe;AAAA,QAC5D,CAAC;AACD,eAAO;AAAA,MACT;AAEA,UAAI,WAAW,KAAK,SAAS,IAAI,GAAG;AAClC,aAAK,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD,eAAO;AAAA,MACT;AAEA,UAAI,WAAW,YAAY,SAASC,yBAAwB;AAC1D,aAAK,OAAO,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS,yCAAyCA,uBAAsB;AAAA,QAC1E,CAAC;AACD,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,QACL,MAAM,WAAW;AAAA,QACjB,aAAa,WAAW;AAAA,QACxB,MAAM;AAAA,MACR;AAAA,IACF,SAAS,OAAO;AACd,WAAK,OAAO,KAAK;AAAA,QACf,MAAM;AAAA,QACN,SACE,iBAAiB,QACb,MAAM,UACN;AAAA,MACR,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,SACJ,QACA,UAA2B,CAAC,GACH;AACzB,UAAM;AAAA,MACJ,QAAQ,WAAW;AAAA,MACnB,QAAQ,WAAW;AAAA,MACnB,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,IACF,IAAI;AACJ,UAAM,SAAyB;AAAA,MAC7B,WAAW,CAAC;AAAA,MACZ,SAAS,CAAC;AAAA,MACV,QAAQ,CAAC;AAAA,IACX;AAEA,UAAM,UAAUH,MAAK,KAAKI,IAAG,OAAO,GAAG,iBAAiB,KAAK,IAAI,CAAC,EAAE;AAEpE,QAAI;AACF,YAAM,mBAAmB,KAAK,gBAAgB,MAAM;AACpD,YAAM,UAAU,MAAM,kBAAkB,EAAE,OAAO,KAAK,CAAC;AACvD,YAAM,QAAQ,MAAM,OAAO;AAE3B,YAAM,aAAa,KAAK,cAAc,OAAO;AAE7C,UAAI,WAAW,WAAW,GAAG;AAC3B,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD,eAAO;AAAA,MACT;AAEA,UAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,YAAM,gBAAgB,YAClB,YACA,YAAY,WACVJ,MAAK;AAAA,QACHA,MAAK,QAAQ,KAAK,MAAM,eAAe;AAAA,QACvC;AAAA,QACA;AAAA,MACF,IACA,WACEA,MAAK;AAAA,QACHA,MAAK,QAAQ,KAAK,MAAM,gBAAgB;AAAA,QACxC;AAAA,QACA;AAAA,MACF,IACA,WACEA,MAAK,KAAK,KAAK,MAAM,iBAAiB,QAAQ,IAC9CA,MAAK,KAAK,KAAK,MAAM,kBAAkB,QAAQ;AAEzD,MAAAD,IAAG,UAAU,eAAe,EAAE,WAAW,KAAK,CAAC;AAE/C,iBAAW,aAAa,YAAY;AAClC,cAAM,WAAWC,MAAK,QAAQ,SAAS;AACvC,cAAM,cAAc,aAAa;AACjC,cAAM,aACJ,SACC,cACG,KAAK,kBAAkB,MAAM,IAC7BA,MAAK,SAAS,QAAQ;AAC5B,cAAMK,aAAYL,MAAK,KAAK,eAAe,UAAU;AAErD,cAAM,UAAUD,IAAG,aAAa,WAAW,OAAO;AAClD,cAAM,SAAS,KAAK,qBAAqB,SAAS,SAAS;AAE3D,YAAI,CAAC,QAAQ;AACX,iBAAO,OAAO,KAAK;AAAA,YACjB,MAAM;AAAA,YACN,SAAS;AAAA,UACX,CAAC;AACD;AAAA,QACF;AAEA,YAAIA,IAAG,WAAWM,UAAS,GAAG;AAC5B,cAAI,CAAC,WAAW;AACd,mBAAO,QAAQ,KAAK;AAAA,cAClB,MAAM,OAAO;AAAA,cACb,QAAQ;AAAA,YACV,CAAC;AACD;AAAA,UACF;AACA,UAAAN,IAAG,OAAOM,YAAW,EAAE,WAAW,KAAK,CAAC;AAAA,QAC1C;AAEA,aAAK,cAAc,UAAUA,UAAS;AAEtC,eAAO,UAAU,KAAK;AAAA,UACpB,MAAM,OAAO;AAAA,UACb,aAAa,OAAO;AAAA,UACpB,MAAML,MAAK,KAAKK,YAAW,UAAU;AAAA,UACrC,QACE,YAAY,WACR,qCACA,WACE,uCACA,WACE,wBACA;AAAA,QACZ,CAAC;AAAA,MACH;AAEA,YAAM,KAAK,WAAW;AAAA,IACxB,UAAE;AACA,UAAIN,IAAG,WAAW,OAAO,GAAG;AAC1B,QAAAA,IAAG,OAAO,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,MACxC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,gBAAgB,QAAwB;AAC9C,QAAI,aAAa;AAEjB,QACE,WAAW,WAAW,qBAAqB,KAC3C,WAAW,WAAW,oBAAoB,GAC1C;AACA,mBAAa,WAAW,QAAQ,6BAA6B,EAAE;AAC/D,YAAM,YAAY,WAAW;AAAA,QAC3B;AAAA,MACF;AACA,UAAI,WAAW;AACb,cAAM,CAAC,EAAE,MAAM,QAAQ,OAAO,IAAI;AAClC,qBAAa,UACT,GAAG,IAAI,IAAI,OAAO,IAAI,MAAM,KAC5B,GAAG,IAAI,IAAI,MAAM;AAAA,MACvB;AACA,aAAO,UAAU,UAAU;AAAA,IAC7B;AAEA,QACE,CAAC,WAAW,WAAW,SAAS,KAChC,CAAC,WAAW,WAAW,SAAS,KAChC,CAAC,WAAW,WAAW,YAAY,GACnC;AACA,aAAO,UAAU,UAAU;AAAA,IAC7B;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB,QAAwB;AAChD,QAAI,aAAa,OACd,QAAQ,6BAA6B,EAAE,EACvC,QAAQ,YAAY,EAAE,EACtB,QAAQ,YAAY,EAAE,EACtB,QAAQ,eAAe,EAAE;AAE5B,UAAM,oBAAoB,WAAW;AAAA,MACnC;AAAA,IACF;AACA,QAAI,mBAAmB;AACrB,mBAAa,kBAAkB,CAAC;AAAA,IAClC,OAAO;AACL,YAAM,sBAAsB,WAAW;AAAA,QACrC;AAAA,MACF;AACA,UAAI,qBAAqB;AACvB,qBAAa,oBAAoB,CAAC;AAAA,MACpC;AAAA,IACF;AAEA,iBAAa,WAAW,QAAQ,QAAQ,EAAE;AAC1C,UAAM,cAAc,WAAW,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,IAAI;AAC9D,WAAO,eAAe;AAAA,EACxB;AAAA,EAEQ,cAAc,KAAuB;AAC3C,UAAM,SAAmB,CAAC;AAE1B,UAAM,YAAYC,MAAK,KAAK,KAAK,UAAU;AAC3C,QAAID,IAAG,WAAW,SAAS,GAAG;AAC5B,aAAO,KAAK,SAAS;AACrB,aAAO;AAAA,IACT;AAEA,UAAM,YAAYC,MAAK,KAAK,KAAK,QAAQ;AACzC,QAAID,IAAG,WAAW,SAAS,KAAKA,IAAG,SAAS,SAAS,EAAE,YAAY,GAAG;AACpE,YAAMO,WAAUP,IAAG,YAAY,WAAW,EAAE,eAAe,KAAK,CAAC;AACjE,iBAAW,SAASO,UAAS;AAC3B,YAAI,oBAAoB,WAAW,KAAK,GAAG;AACzC,gBAAM,YAAYN,MAAK,KAAK,WAAW,MAAM,MAAM,UAAU;AAC7D,cAAID,IAAG,WAAW,SAAS,GAAG;AAC5B,mBAAO,KAAK,SAAS;AAAA,UACvB;AAAA,QACF;AAAA,MACF;AACA,UAAI,OAAO,SAAS,GAAG;AACrB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,UAAUA,IAAG,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAC3D,eAAW,SAAS,SAAS;AAC3B,UAAI,oBAAoB,KAAK,KAAK,GAAG;AACnC,cAAM,YAAYC,MAAK,KAAK,KAAK,MAAM,MAAM,UAAU;AACvD,YAAID,IAAG,WAAW,SAAS,GAAG;AAC5B,iBAAO,KAAK,SAAS;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,cAAc,KAAa,MAAoB;AACrD,IAAAA,IAAG,UAAU,MAAM,EAAE,WAAW,KAAK,CAAC;AACtC,UAAM,UAAUA,IAAG,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAE3D,eAAW,SAAS,SAAS;AAC3B,YAAM,UAAUC,MAAK,KAAK,KAAK,MAAM,IAAI;AACzC,YAAM,WAAWA,MAAK,KAAK,MAAM,MAAM,IAAI;AAE3C,UAAI,MAAM,YAAY,GAAG;AACvB,aAAK,cAAc,SAAS,QAAQ;AAAA,MACtC,OAAO;AACL,QAAAD,IAAG,aAAa,SAAS,QAAQ;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,qBACN,SACA,WAC8C;AAC9C,QAAI;AACF,YAAM,EAAE,WAAW,IAAI,gBAGpB,SAAS,SAAS;AAErB,UAAI,CAAC,WAAW,QAAQ,CAAC,WAAW,aAAa;AAC/C,eAAO;AAAA,MACT;AAEA,UACE,WAAW,KAAK,SAASG,oBACzB,WAAW,KAAK,SAAS,IAAI,GAC7B;AACA,eAAO;AAAA,MACT;AAEA,UAAI,WAAW,YAAY,SAASC,yBAAwB;AAC1D,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,QACL,MAAM,WAAW;AAAA,QACjB,aAAa,WAAW;AAAA,MAC1B;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,QAA8C;AAChE,UAAM,UAAUH,MAAK,KAAKI,IAAG,OAAO,GAAG,iBAAiB,KAAK,IAAI,CAAC,EAAE;AACpE,UAAM,SAA8B;AAAA,MAClC;AAAA,MACA,QAAQ,CAAC;AAAA,MACT,QAAQ,CAAC;AAAA,IACX;AAEA,UAAM,mBAAmB,KAAK,gBAAgB,MAAM;AACpD,UAAM,UAAU,MAAM,kBAAkB,EAAE,OAAO,KAAK,CAAC;AACvD,UAAM,QAAQ,MAAM,OAAO;AAE3B,UAAM,aAAa,KAAK,cAAc,OAAO;AAE7C,QAAI,WAAW,WAAW,GAAG;AAC3B,aAAO,OAAO,KAAK;AAAA,QACjB,MAAM;AAAA,QACN,SAAS;AAAA,MACX,CAAC;AACD,aAAO;AAAA,IACT;AAEA,eAAW,aAAa,YAAY;AAClC,YAAM,UAAUL,IAAG,aAAa,WAAW,OAAO;AAClD,YAAM,SAAS,KAAK,qBAAqB,SAAS,SAAS;AAE3D,UAAI,CAAC,QAAQ;AACX,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AACD;AAAA,MACF;AAEA,aAAO,OAAO,KAAK;AAAA,QACjB,MAAM,OAAO;AAAA,QACb,aAAa,OAAO;AAAA,QACpB;AAAA,QACA,UAAUC,MAAK,QAAQ,SAAS;AAAA,MAClC,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,mBACJ,SACA,gBACA,QACA,UAA2B,CAAC,GACH;AACzB,UAAM;AAAA,MACJ,QAAQ,WAAW;AAAA,MACnB,QAAQ,WAAW;AAAA,MACnB,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,IACF,IAAI;AACJ,UAAM,SAAyB;AAAA,MAC7B,WAAW,CAAC;AAAA,MACZ,SAAS,CAAC;AAAA,MACV,QAAQ,CAAC;AAAA,IACX;AAEA,QAAI,QAAQ,eAAe,SAAS,GAAG;AACrC,YAAM,IAAI,MAAM,mDAAmD;AAAA,IACrE;AAEA,UAAM,gBAAgB,YAClB,YACA,YAAY,WACVA,MAAK;AAAA,MACHA,MAAK,QAAQ,KAAK,MAAM,eAAe;AAAA,MACvC;AAAA,MACA;AAAA,IACF,IACA,WACEA,MAAK;AAAA,MACHA,MAAK,QAAQ,KAAK,MAAM,gBAAgB;AAAA,MACxC;AAAA,MACA;AAAA,IACF,IACA,WACEA,MAAK,KAAK,KAAK,MAAM,iBAAiB,QAAQ,IAC9CA,MAAK,KAAK,KAAK,MAAM,kBAAkB,QAAQ;AAEzD,IAAAD,IAAG,UAAU,eAAe,EAAE,WAAW,KAAK,CAAC;AAE/C,eAAW,SAAS,gBAAgB;AAClC,YAAM,cAAc,MAAM,aAAa,QAAQ;AAC/C,YAAM,aACJ,SACC,cACG,KAAK,kBAAkB,MAAM,IAC7BC,MAAK,SAAS,MAAM,QAAQ;AAClC,YAAM,iBAAiBA,MAAK,KAAK,eAAe,UAAU;AAE1D,UAAID,IAAG,WAAW,cAAc,GAAG;AACjC,YAAI,CAAC,WAAW;AACd,iBAAO,QAAQ,KAAK;AAAA,YAClB,MAAM,MAAM;AAAA,YACZ,QAAQ;AAAA,UACV,CAAC;AACD;AAAA,QACF;AACA,QAAAA,IAAG,OAAO,gBAAgB,EAAE,WAAW,KAAK,CAAC;AAAA,MAC/C;AAEA,WAAK,cAAc,MAAM,UAAU,cAAc;AAEjD,aAAO,UAAU,KAAK;AAAA,QACpB,MAAM,MAAM;AAAA,QACZ,aAAa,MAAM;AAAA,QACnB,MAAMC,MAAK,KAAK,gBAAgB,UAAU;AAAA,QAC1C,QACE,YAAY,WACR,qCACA,WACE,uCACA,WACE,wBACA;AAAA,MACZ,CAAC;AAAA,IACH;AAEA,UAAM,KAAK,WAAW;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,SAAoC;AACjD,QAAID,IAAG,WAAW,QAAQ,OAAO,GAAG;AAClC,MAAAA,IAAG,OAAO,QAAQ,SAAS,EAAE,WAAW,KAAK,CAAC;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,MAAM,YACJ,MACA,WAC+C;AAC/C,UAAM,YACJ,aAAaC,MAAK,KAAK,KAAK,MAAM,kBAAkB,QAAQ;AAC9D,UAAM,WAAWA,MAAK,KAAK,WAAW,IAAI;AAE1C,QAAI,CAACD,IAAG,WAAW,QAAQ,GAAG;AAC5B,aAAO,EAAE,SAAS,OAAO,OAAO,kBAAkB;AAAA,IACpD;AAEA,UAAM,YAAYC,MAAK,KAAK,UAAU,UAAU;AAChD,QAAI,CAACD,IAAG,WAAW,SAAS,GAAG;AAC7B,aAAO,EAAE,SAAS,OAAO,OAAO,wCAAwC;AAAA,IAC1E;AAEA,IAAAA,IAAG,OAAO,UAAU,EAAE,WAAW,KAAK,CAAC;AACvC,UAAM,KAAK,WAAW;AACtB,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AACF;;;AzB9oBO,IAAM,UAAN,MAAM,SAAQ;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,MAAmB;AAC7B,SAAK,MAAM,KAAK;AAChB,SAAK,cAAc,KAAK;AACxB,SAAK,kBAAkB,KAAK;AAC5B,SAAK,UAAU,KAAK;AACpB,SAAK,SAAS,KAAK;AACnB,SAAK,QAAQ,KAAK;AAClB,SAAK,aAAa,KAAK;AACvB,SAAK,iBAAiB,KAAK;AAC3B,SAAK,aAAa,KAAK;AACvB,SAAK,wBAAwB,KAAK;AAClC,SAAK,eAAe,KAAK;AACzB,SAAK,aAAa,KAAK;AACvB,SAAK,eAAe,KAAK;AACzB,SAAK,UAAU,KAAK;AACpB,SAAK,QAAQ,KAAK;AAClB,SAAK,aAAa,KAAK;AAAA,EACzB;AAAA,EAEA,MAAM,MAAM,WAAmD;AAC7D,WAAO,KAAK,eAAe,MAAM;AAAA,MAC/B,GAAG;AAAA,MACH,eAAe;AAAA,IACjB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,UAAU;AACd,UAAM,KAAK,WAAW,QAAQ;AAC9B,UAAM,KAAK,MAAM;AAAA,MACf,MAAM;AAAA,MACN,MAAM,CAAC;AAAA,MACP;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,OAAO,MAAyB;AAC3C,UAAM,EAAE,KAAK,SAAS,gBAAgB,IAAI;AAC1C,UAAM,cAAc,KAAK,YAAY,YAAY;AACjD,UAAM,QAAQ,IAAI,MAAM;AAAA,MACtB;AAAA,MACA;AAAA,IACF,CAAC;AACD,UAAM,gBAAgB,IAAI;AAAA,MACxB;AAAA,MACA;AAAA,MACA,KAAK,cAAc,CAAC;AAAA,IACtB;AACA,UAAM,gBAAgB,cAAc;AAEpC,UAAM,iBAA2B,CAAC;AAClC,UAAM,gBAAgB;AAAA,MACpBQ,OAAK,KAAK,MAAM,iBAAiB,SAAS;AAAA,IAC5C;AACA,UAAM,iBAAiB;AAAA,MACrBA,OAAK,KAAK,MAAM,kBAAkB,SAAS;AAAA,IAC7C;AACA,UAAM,iBAAsC;AAAA,MAC1C,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAI,cAAc,WAAW,CAAC;AAAA,MAC9B,GAAI,KAAK,WAAW,CAAC;AAAA,IACvB;AACA,UAAM,UAAU,MAAM,iBAAiB,KAAK,KAAK,cAAc;AAC/D,UAAM,gBAAgB,IAAI,cAAc,OAAO;AAC/C,UAAM,QAAQ,OAAO,aAAkB;AACrC,aAAO,cAAc,MAAM,EAAE,GAAG,UAAU,eAAe,YAAY,CAAC;AAAA,IACxE;AACA,UAAM,cAAc;AAAA,MAClB,GAAG;AAAA,MACH,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF;AACA,UAAM,iBAAiB,MAAM,MAAM;AAAA,MACjC,MAAM;AAAA,MACN,MAAM,CAAC,EAAE,QAAQ,eAAe,YAAY,KAAK,WAAW,CAAC;AAAA,MAC7D,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AACD,gBAAY,SAAS;AACrB,UAAM,aAAa;AAAA,MACjB,GAAI,eAAe,cAAc,CAAC;AAAA,MAClC,GAAG,KAAK,WAAW;AAAA,IACrB;AACA,UAAM,aAAa,WAAW,OAAO,UAAU;AAC/C,UAAM,wBAAwB,IAAI,sBAAsB;AACxD,UAAM,aAAa,IAAI,WAAW,EAAE,gBAAgB,MAAM,kBAAkB,EAAE,CAAC;AAE/E,UAAM,UAAU,IAAI,SAAQ;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,KAAK;AAAA,MACjB,SAAS;AAAA,MACT,OAAO,KAAK;AAAA,MACZ;AAAA,IACF,CAAC;AAGD,UAAM,eAAe,IAAI,aAAa,EAAE,QAAQ,CAAC;AACjD,UAAM,aAAa,WAAW;AAC9B,YAAQ,eAAe;AAGvB,UAAM,eAAe,IAAI,aAAa,EAAE,QAAQ,CAAC;AAEjD,UAAM,aAAa,WAAW;AAC9B,YAAQ,eAAe;AAEvB,WAAO;AAAA,EACT;AACF;AAEA,SAAS,iBAAiB,KAAa,SAA8B;AACnE,MAAI,OAAY;AAChB,SAAO,QAAQ;AAAA,IACb,QAAQ,IAAI,OAAO,WAAW;AAC5B,UAAI,OAAO,WAAW,UAAU;AAC9B,cAAM,aAAaC,SAAQ,KAAK,QAAQ,EAAE,SAAS,IAAI,CAAC;AACxD,YAAI,CAAC,MAAM;AAET,iBAAO,WAAW,GAAG;AAAA,QACvB;AACA,eAAQ,MAAM,KAAK,OAAO,YAAY;AAAA,UACpC,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AAEA,SAAS,YAAY,WAA6B;AAChD,MAAI;AACF,QAAI,CAACC,KAAG,WAAW,SAAS,GAAG;AAC7B,aAAO,CAAC;AAAA,IACV;AACA,UAAM,QAAQA,KAAG,YAAY,SAAS;AACtC,WAAO,MACJ,OAAO,CAAC,SAAS,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,KAAK,CAAC,EAC7D,IAAI,CAAC,SAASF,OAAK,KAAK,WAAW,IAAI,CAAC;AAAA,EAC7C,SAAS,QAAQ;AACf,WAAO,CAAC;AAAA,EACV;AACF;;;A0B5NA,OAAO,kBAAkB;AAwCzB,SAAS,cACP,IACA,QACA,QACgB;AAChB,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,KAAK,IAAI;AAAA,EACtB;AACF;AAEA,SAAS,eACP,IACA,QACA,OACiB;AACjB,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,KAAK,IAAI;AAAA,EACtB;AACF;AACA,SAAS,oBAAoB,IAAe,OAA6B;AACvE,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,WAAW,KAAK,IAAI;AAAA,EACtB;AACF;AACA,SAAS,YAAY,IAAe,OAAe,MAAyB;AAC1E,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,KAAK,IAAI;AAAA,EACtB;AACF;AAEA,IAAM,kBAAkB;AAEjB,IAAM,kBAAN,MAAM,yBAAwB,aAAyC;AAAA,EACpE;AAAA,EACA,QAAyB;AAAA,EACzB,gBAA2B,CAAC;AAAA,EACpC,cAAc;AACZ,UAAM;AAAA,EACR;AAAA,EACA,OAAO,aAAiD;AACtD,UAAM,aAAa,IAAI,iBAAgB;AACvC,UAAM,aAAa,IAAI,iBAAgB;AACvC,eAAW,QAAQ,UAAU;AAC7B,eAAW,QAAQ,UAAU;AAC7B,WAAO,CAAC,YAAY,UAAU;AAAA,EAChC;AAAA,EACA,QAAQ,MAAuB;AAC7B,SAAK,OAAO;AACZ,SAAK,YAAY;AAAA,EACnB;AAAA,EACA,cAAc;AACZ,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA,EACA,UAAU,SAA2C;AACnD,SAAK,GAAG,WAAW,OAAO;AAAA,EAC5B;AAAA,EACA,QAAQ,SAAuC;AAC7C,SAAK,GAAG,SAAS,OAAO;AAAA,EAC1B;AAAA,EACA,QAAQ,SAA2B;AACjC,SAAK,GAAG,SAAS,OAAO;AAAA,EAC1B;AAAA,EACA,MAAM,KAAK,SAAkB;AAC3B,QAAI;AACF,UAAI,KAAK,QAAQ,KAAK,KAAK,YAAY,GAAG;AACxC,qBAAa,MAAM;AACjB,eAAK,KAAM,QAAQ,OAAO;AAAA,QAC5B,CAAC;AAAA,MACH,OAAO;AACL,aAAK,cAAc,KAAK,OAAO;AAAA,MACjC;AAAA,IACF,SAAS,OAAO;AACd,WAAK,KAAK,SAAS,KAAK;AACxB,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,MAAM,QAAQ;AACZ,SAAK,QAAQ;AAAA,EACf;AAAA,EACQ,cAAc;AACpB,QACE,CAAC,KAAK,QACN,CAAC,KAAK,KAAK,YAAY,KACvB,KAAK,cAAc,WAAW,GAC9B;AACA;AAAA,IACF;AACA,QAAI,KAAK,cAAc,SAAS,iBAAiB;AAC/C,WAAK,KAAK,SAAS,IAAI,MAAM,yBAAyB,CAAC;AACvD;AAAA,IACF;AACA,UAAM,WAAW,CAAC,GAAG,KAAK,aAAa;AACvC,SAAK,cAAc,SAAS;AAC5B,eAAW,WAAW,UAAU;AAC9B,mBAAa,MAAM;AACjB,aAAK,KAAM,QAAQ,OAAO;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EACQ,QAAQ,SAAkB;AAChC,QAAI,KAAK,UAAU,aAAa;AAC9B;AAAA,IACF;AACA,QAAI;AACF,WAAK,KAAK,WAAW,OAAO;AAAA,IAC9B,SAAS,OAAO;AACd,WAAK,KAAK,SAAS,KAAK;AAAA,IAC1B;AAAA,EACF;AACF;AAaO,IAAM,aAAN,cAAyB,aAAa;AAAA,EACpC,kBAAkB,oBAAI,IAA4B;AAAA,EACjD;AAAA,EACA,kBAAkB,oBAAI,IAA+B;AAAA,EACrD,gBAAgB,oBAAI,IAA+B;AAAA,EAC3D,cAAc;AACZ,UAAM;AAAA,EACR;AAAA,EACA,aAAa,WAA6B;AACxC,SAAK,YAAY;AACjB,cAAU,UAAU,CAAC,YAAY;AAC/B,WAAK,sBAAsB,OAAO;AAAA,IACpC,CAAC;AACD,cAAU,QAAQ,CAAC,UAAU;AAC3B,WAAK,KAAK,SAAS,KAAK;AAAA,IAC1B,CAAC;AACD,cAAU,QAAQ,MAAM;AACtB,WAAK,KAAK,OAAO;AAAA,IACnB,CAAC;AACD,SAAK,KAAK,gBAAgB;AAAA,EAC5B;AAAA,EACA,cAAc;AACZ,WAAO,KAAK,WAAW,YAAY,KAAK;AAAA,EAC1C;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,EA6BA,MAAM,QACJ,QACA,QACA,UAAgC,CAAC,GACnB;AACd,QAAI,CAAC,KAAK,WAAW;AACnB,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AACA,QAAI,CAAC,KAAK,UAAU,YAAY,GAAG;AACjC,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AACA,UAAM,KAAK,WAAW;AACtB,UAAM,UAAU,QAAQ,WAAW;AACnC,UAAM,iBAAiB,cAAc,IAAI,QAAQ,MAAM;AACvD,UAAM,UAAU,IAAI,QAAa,CAACG,UAAS,WAAW;AACpD,YAAM,iBAAiC;AAAA,QACrC;AAAA,QACA;AAAA,QACA,WAAW,KAAK,IAAI;AAAA,QACpB,SAAAA;AAAA,QACA;AAAA,MACF;AACA,UAAI,UAAU,GAAG;AACf,uBAAe,UAAU,WAAW,MAAM;AACxC,eAAK,gBAAgB,OAAO,EAAE;AAC9B,iBAAO,IAAI,MAAM,yBAAyB,OAAO,OAAO,MAAM,EAAE,CAAC;AAAA,QACnE,GAAG,OAAO;AAAA,MACZ;AACA,WAAK,gBAAgB,IAAI,IAAI,cAAc;AAAA,IAC7C,CAAC;AACD,QAAI;AACF,YAAM,KAAK,UAAU,KAAK,cAAc;AACxC,aAAO,MAAM;AAAA,IACf,SAAS,OAAO;AAEd,YAAM,UAAU,KAAK,gBAAgB,IAAI,EAAE;AAC3C,UAAI,SAAS;AACX,YAAI,QAAQ,SAAS;AACnB,uBAAa,QAAQ,OAAO;AAAA,QAC9B;AACA,aAAK,gBAAgB,OAAO,EAAE;AAAA,MAChC;AACA,YAAM;AAAA,IACR;AAAA,EACF;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,EAmCA,gBAAgB,QAAgB,SAAyB;AACvD,SAAK,gBAAgB,IAAI,QAAQ,OAAO;AAAA,EAC1C;AAAA,EACA,kBAAkB,QAAgB;AAChC,QAAI,KAAK,gBAAgB,IAAI,MAAM,GAAG;AACpC,WAAK,gBAAgB,OAAO,MAAM;AAAA,IACpC;AAAA,EACF;AAAA,EACA,MAAM,UAAU,OAAe,MAAW;AACxC,QAAI,CAAC,KAAK,WAAW;AACnB;AAAA,IACF;AACA,QAAI,CAAC,KAAK,UAAU,YAAY,GAAG;AACjC;AAAA,IACF;AACA,UAAM,KAAK,WAAW;AACtB,UAAM,UAAU,YAAY,IAAI,OAAO,IAAI;AAC3C,QAAI;AACF,YAAM,KAAK,UAAU,KAAK,OAAO;AAAA,IACnC,SAAS,OAAO;AACd,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,QAAQ,OAAe,SAAuB;AAC5C,QAAI,CAAC,KAAK,cAAc,IAAI,KAAK,GAAG;AAClC,WAAK,cAAc,IAAI,OAAO,oBAAI,IAAI,CAAC;AAAA,IACzC;AACA,SAAK,cAAc,IAAI,KAAK,EAAG,IAAI,OAAO;AAAA,EAC5C;AAAA,EACA,SAAS,OAAe,SAAuB;AAC7C,UAAM,WAAW,KAAK,cAAc,IAAI,KAAK;AAC7C,QAAI,UAAU;AACZ,eAAS,OAAO,OAAO;AACvB,UAAI,SAAS,SAAS,GAAG;AACvB,aAAK,cAAc,OAAO,KAAK;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAc,sBAAsB,SAAkB;AACpD,QAAI;AACF,UAAI,CAAC,QAAQ,MAAM,CAAC,QAAQ,aAAa,CAAC,QAAQ,MAAM;AACtD,cAAM,IAAI,MAAM,wBAAwB;AAAA,MAC1C;AACA,cAAQ,QAAQ,MAAM;AAAA,QACpB,KAAK;AACH,gBAAM,KAAK,cAAc,OAAyB;AAClD;AAAA,QACF,KAAK;AACH,eAAK,eAAe,OAA0B;AAC9C;AAAA,QACF,KAAK;AACH,eAAK,YAAY,OAAuB;AACxC;AAAA,QACF;AACE;AAAA,MACJ;AAAA,IACF,SAAS,OAAO;AACd,WAAK,KAAK,gBAAgB,OAAO,OAAO;AAAA,IAC1C;AAAA,EACF;AAAA,EACA,MAAc,cAAc,SAAyB;AACnD,UAAM,EAAE,IAAI,QAAQ,OAAO,IAAI;AAC/B,UAAM,UAAU,KAAK,gBAAgB,IAAI,MAAM;AAC/C,QAAI,CAAC,SAAS;AACZ,YAAM,KAAK;AAAA,QACT,oBAAoB,IAAI;AAAA,UACtB,SAAS,qCAAqC,MAAM;AAAA,UACpD,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AACA;AAAA,IACF;AACA,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ,MAAM;AACnC,YAAM,WAAW,eAAe,IAAI,MAAM;AAC1C,YAAM,KAAK,aAAa,QAAQ;AAAA,IAClC,SAAS,OAAO;AACd,YAAM,KAAK;AAAA,QACT,oBAAoB,IAAI;AAAA,UACtB,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UAC9D,MAAM;AAAA,UACN,SAAS,iBAAiB,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI;AAAA,QAC7D,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAc,eAAe,SAA0B;AACrD,UAAM,EAAE,IAAI,QAAQ,MAAM,IAAI;AAC9B,UAAM,UAAU,KAAK,gBAAgB,IAAI,EAAE;AAC3C,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AACA,QAAI,QAAQ,SAAS;AACnB,mBAAa,QAAQ,OAAO;AAAA,IAC9B;AACA,SAAK,gBAAgB,OAAO,EAAE;AAC9B,QAAI,OAAO;AAET,YAAM,eACJ,OAAO,UAAU,YAAY,MAAM,UAC/B,MAAM,UACN,OAAO,UAAU,WACf,QACA;AAER,YAAM,MAAM,IAAI,MAAM,YAAY;AAElC,MAAC,IAAY,UAAU,MAAM,UACzB,MAAM,QAAQ,MAAM,OAAO,IACzB,MAAM,QAAQ,KAAK,IAAI,IACvB,KAAK,UAAU,MAAM,OAAO,IAC9B;AACJ,MAAC,IAAY,SAAS,QAAQ;AAE9B,cAAQ,OAAO,GAAG;AAAA,IACpB,OAAO;AACL,cAAQ,QAAQ,MAAM;AAAA,IACxB;AAAA,EACF;AAAA,EACA,MAAc,YAAY,SAAuB;AAC/C,UAAM,EAAE,OAAO,KAAK,IAAI;AACxB,UAAM,WAAW,KAAK,cAAc,IAAI,KAAK;AAC7C,QAAI,CAAC,YAAY,SAAS,SAAS,GAAG;AACpC;AAAA,IACF;AACA,eAAW,WAAW,UAAU;AAC9B,UAAI;AACF,gBAAQ,IAAI;AAAA,MACd,SAAS,OAAO;AACd,aAAK,KAAK,qBAAqB,OAAO,OAAO,IAAI;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAc,aAAa,UAA2B;AACpD,QAAI,CAAC,KAAK,WAAW;AACnB;AAAA,IACF;AACA,QAAI;AACF,YAAM,KAAK,UAAU,KAAK,QAAQ;AAAA,IACpC,SAAS,OAAO;AACd,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;AC9bA,OAAOC,UAAQ;AACf,OAAOC,YAAU;AACjB,SAAS,gBAAgB;AACzB,OAAOC,SAAQ;AAGR,IAAM,eAAN,MAA8C;AAAA;AAAA,EAEnD,WAAW,CAACD,WACVD,KAAG,SAAS,SAASC,QAAM,OAAO;AAAA,EAEpC,YAAY,CAACA,QAAc,YACzBD,KAAG,SAAS,UAAUC,QAAM,SAAS,OAAO;AAAA;AAAA,EAG9C,eAAe,CAACA,WACdD,KAAG,aAAaC,QAAM,OAAO;AAAA,EAE/B,gBAAgB,CAACA,QAAc,YAC7BD,KAAG,cAAcC,QAAM,SAAS,OAAO;AAAA,EAEzC,aAAa,CAACA,WACZD,KAAG,WAAWC,MAAI;AAAA,EAEpB,YAAY,CAACA,QAAc,YAA2C;AACpE,IAAAD,KAAG,UAAUC,QAAM,OAAO;AAAA,EAC5B;AAAA,EAEA,cAAc,CAACA,WACbD,KAAG,YAAYC,MAAI;AAAA,EAErB,WAAW,CAACA,WAAwB;AAClC,UAAM,QAAQD,KAAG,SAASC,MAAI;AAC9B,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,OAAO,MAAM;AAAA,MACb,WAAW,MAAM;AAAA,IACnB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,MAAc,QAAQ,IAAI;AAAA,EAEhC,MAAM,QAAQ;AAAA,EAEd,WAAW,QAAQ;AAAA;AAAA,EAGnB,OAAO,OAAO,SAAiB,YAA+C;AAC5E,QAAI;AACF,YAAM,SAAS,SAAS,SAAS;AAAA,QAC/B,KAAK,SAAS;AAAA,QACd,KAAK,EAAE,GAAG,QAAQ,KAAK,GAAG,SAAS,IAAI;AAAA,QACvC,SAAS,SAAS;AAAA,QAClB,UAAU;AAAA,QACV,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,MAClC,CAAC;AAED,aAAO;AAAA,QACL,QAAQ,OAAO,SAAS;AAAA,QACxB,QAAQ;AAAA,QACR,UAAU;AAAA,MACZ;AAAA,IACF,SAAS,OAAY;AACnB,aAAO;AAAA,QACL,QAAQ,MAAM,QAAQ,SAAS,KAAK;AAAA,QACpC,QAAQ,MAAM,QAAQ,SAAS,KAAK,MAAM,WAAW;AAAA,QACrD,UAAU,MAAM,UAAU;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,OAAO,IAAI,UAA4BA,OAAK,KAAK,GAAG,KAAK;AAAA,EAEzD,UAAU,CAAC,aAA6BA,OAAK,QAAQ,QAAQ;AAAA,EAE7D,WAAW,CAAC,aAA6BA,OAAK,SAAS,QAAQ;AAAA,EAE/D,UAAU,IAAI,UAA4BA,OAAK,QAAQ,GAAG,KAAK;AAAA;AAAA,EAG/D,eAAe,MAAc;AAC3B,UAAM,OAAO,QAAQ,aAAa,WAC9BA,OAAK,KAAKC,IAAG,QAAQ,GAAG,WAAW,qBAAqB,IACxD,QAAQ,aAAa,UACnB,QAAQ,IAAI,WAAWD,OAAK,KAAKC,IAAG,QAAQ,GAAG,WAAW,SAAS,IACnED,OAAK,KAAKC,IAAG,QAAQ,GAAG,SAAS;AACvC,WAAO;AAAA,EACT;AAAA,EAEA,aAAa,MAAc;AACzB,UAAM,OAAO,QAAQ,aAAa,WAC9BD,OAAK,KAAKC,IAAG,QAAQ,GAAG,WAAW,qBAAqB,IACxD,QAAQ,aAAa,UACnB,QAAQ,IAAI,WAAWD,OAAK,KAAKC,IAAG,QAAQ,GAAG,WAAW,SAAS,IACnED,OAAK,KAAKC,IAAG,QAAQ,GAAG,UAAU,OAAO;AAC/C,WAAO;AAAA,EACT;AACF;AAGO,IAAM,eAAe,IAAI,aAAa;;;AC3G7C,OAAOC,UAAQ;AACf,OAAOC,YAAU;AAYV,IAAMC,eAAN,MAAkB;AAAA,EACvB;AAAA,EACA,WAA0B;AAAA,EAE1B,YAAY,MAA4B;AACtC,SAAK,WAAW,KAAK;AACrB,SAAK,WAAW,KAAK,cAAc;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAA+B;AAC7B,QAAI,CAACC,KAAG,WAAW,KAAK,QAAQ,GAAG;AACjC,aAAO;AAAA,IACT;AACA,QAAI;AACF,YAAM,OAAOA,KAAG,aAAa,KAAK,UAAU,MAAM;AAClD,YAAM,QAAQ,KAAK,MAAM,IAAI,EAAE,OAAO,OAAO;AAC7C,UAAI,MAAM,WAAW,GAAG;AACtB,eAAO;AAAA,MACT;AACA,YAAM,WAAW,MAAM,MAAM,SAAS,CAAC;AACvC,YAAM,UAAU,KAAK,MAAM,QAAQ;AACnC,aAAO,QAAQ,QAAQ;AAAA,IACzB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,MAAyG;AAClH,UAAM,MAAMC,OAAK,QAAQ,KAAK,QAAQ;AACtC,QAAI,CAACD,KAAG,WAAW,GAAG,GAAG;AACvB,MAAAA,KAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,IACvC;AACA,UAAM,UAAU,KAAK;AACrB,IAAAA,KAAG,eAAe,KAAK,UAAU,KAAK,UAAU,OAAO,IAAI,IAAI;AAC/D,SAAK,WAAW,QAAQ;AACxB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe,SAAiB,WAA8D;AAC5F,UAAM,UAAU;AAAA,MACd,GAAG,kBAAkB,SAAS,KAAK,QAAQ;AAAA,MAC3C;AAAA,IACF;AACA,WAAO,KAAK,WAAW;AAAA,MACrB;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AChEO,IAAM,mBAAN,MAA+C;AAAA,EAC5C,QAAQ,oBAAI,IAAoB;AAAA,EAExC,SAAS,MAAkB;AACzB,QAAI,KAAK,MAAM,IAAI,KAAK,EAAE,GAAG;AAC3B,YAAM,IAAI,MAAM,QAAQ,KAAK,EAAE,wBAAwB;AAAA,IACzD;AACA,SAAK,MAAM,IAAI,KAAK,IAAI,IAAI;AAAA,EAC9B;AAAA,EAEA,WAAW,IAAoB;AAC7B,SAAK,MAAM,OAAO,EAAE;AAAA,EACtB;AAAA,EAEA,IAAI,IAAgC;AAClC,WAAO,KAAK,MAAM,IAAI,EAAE;AAAA,EAC1B;AAAA,EAEA,SAAiB;AACf,WAAO,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC;AAAA,EACvC;AAAA,EAEA,IAAI,IAAuB;AACzB,WAAO,KAAK,MAAM,IAAI,EAAE;AAAA,EAC1B;AACF;AAKO,IAAM,eAAe,IAAI,iBAAiB;;;AC3B1C,IAAM,cAAoB;AAAA,EAC/B,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ;AAAA,IACN,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAmBd,OAAO;AAAA,IACP,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,MAAM;AAAA,IACN,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AACF;AAKO,IAAM,iBAAuB;AAAA,EAClC,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ;AAAA,IACN,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAkDd,OAAO;AAAA,IACP,MAAM;AAAA,IACN,iBAAiB;AAAA;AAAA,IACjB,MAAM;AAAA,IACN,UAAU;AAAA,IACV,aAAa;AAAA;AAAA,EACf;AACF;AAKO,IAAM,WAAiB;AAAA,EAC5B,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ;AAAA,IACN,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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,IAkEd,OAAO;AAAA,IACP,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,MAAM;AAAA,IACN,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AACF;AAKO,IAAM,aAAmB;AAAA,EAC9B,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ;AAAA,IACN,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgCd,OAAO;AAAA,IACP,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,MAAM;AAAA,IACN,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AACF;AAKO,IAAM,YAAkB;AAAA,EAC7B,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ;AAAA,IACN,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAwBd,OAAO;AAAA,IACP,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,MAAM;AAAA,IACN,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AACF;AAKO,IAAM,eAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,SAAS,qBAAqB,UAAuD;AAC1F,aAAW,QAAQ,cAAc;AAC/B,QAAI,CAAC,SAAS,IAAI,KAAK,EAAE,GAAG;AAC1B,eAAS,SAAS,IAAI;AAAA,IACxB;AAAA,EACF;AACF;;;AClLO,IAAM,SAAN,MAAa;AAAA,EACV,UAA0B;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,cAAwB;AAAA,EACxB,eAAyC,oBAAI,IAAI;AAAA,EAEzD,YAAY,SAAwB;AAClC,SAAK,UAAU;AACf,SAAK,WAAW,QAAQ,YAAY,IAAI,aAAa;AACrD,SAAK,aAAa,QAAQ,cAAc,IAAI,WAAW;AAGvD,yBAAqB,YAAY;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAAW,SAAuB,CAAC,GAAkB;AACzD,UAAM,MAAM,KAAK,QAAQ,OAAO,KAAK,SAAS,IAAI;AAElD,SAAK,UAAU,MAAM,QAAc,OAAO;AAAA,MACxC;AAAA,MACA,aAAa,KAAK,QAAQ;AAAA,MAC1B,iBAAiB,KAAK,QAAQ;AAAA,MAC9B,SAAS,KAAK,QAAQ;AAAA,MACtB,YAAY;AAAA,MACZ,SAAS,OAAO,WAAW,CAAC;AAAA,MAC5B,YAAY,KAAK;AAAA,MACjB,OAAO,KAAK,QAAQ;AAAA,IACtB,CAAC;AAED,UAAM,KAAK,QAAQ,MAAM;AAAA,MACvB,MAAM;AAAA,MACN,MAAM,CAAC,EAAE,KAAK,OAAO,MAAM,CAAC;AAAA,MAC5B,MAAM;AAAA,IACR,CAAC;AAED,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,UAA0B,CAAC,GAAqB;AAClE,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,IAAI,MAAM,kDAAkD;AAAA,IACpE;AAEA,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AAEA,UAAM,QAAQ,KAAK,QAAQ;AAC3B,UAAM,YAAY,QAAQ,cAAc,MAAM;AAC5C,UAAI,QAAQ,QAAQ;AAClB,eAAO,QAAQ;AAAA,MACjB;AACA,UAAI,QAAQ,UAAU;AACpB,eAAO,MAAM,mBAAmB,KAAK,KAAK,kBAAkB;AAAA,MAC9D;AACA,aAAO,KAAK,kBAAkB;AAAA,IAChC,GAAG;AAEH,QAAI,QAAQ,UAAU,QAAQ,UAAU;AACtC,YAAM,UAAU,MAAM,kBAAkB,SAAS;AACjD,aAAO,QAAc,OAAO,EAAE,IAAI,WAAW,QAAQ,CAAC;AAAA,IACxD;AAEA,WAAO,QAAc,OAAO;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,gBAA4B;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,aAAsB;AACpB,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC1C;AACA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAA0B;AAC9B,QAAI,KAAK,SAAS;AAChB,YAAM,KAAK,QAAQ,QAAQ;AAC3B,WAAK,UAAU;AAAA,IACjB;AACA,SAAK,aAAa,MAAM;AACxB,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKQ,UAAU,WAAgC;AAChD,QAAI,CAAC,KAAK,aAAa,IAAI,SAAS,GAAG;AACrC,UAAI,CAAC,KAAK,SAAS;AACjB,cAAM,IAAI,MAAM,uBAAuB;AAAA,MACzC;AACA,YAAM,UAAU,KAAK,QAAQ,MAAM,kBAAkB,SAAS;AAC9D,WAAK,aAAa,IAAI,WAAW,IAAIE,aAAY,EAAE,UAAU,QAAQ,CAAC,CAAC;AAAA,IACzE;AACA,WAAO,KAAK,aAAa,IAAI,SAAS;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc;AACZ,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AACA,WAAO,KAAK,QAAQ,MAAM,eAAe;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,YAAY,SAAkD;AAClE,QAAI,CAAC,KAAK,eAAe,CAAC,KAAK,SAAS;AACtC,YAAM,IAAI,MAAM,kDAAkD;AAAA,IACpE;AAEA,UAAM,UAAU,KAAK;AACrB,UAAM,UAAU,QAAQ,SAAS,QAAQ,OAAO;AAChD,UAAM,gBAAgB,MAAM,wBAAwB,SAAS,OAAO;AAEpE,QAAI,CAAC,cAAc,OAAO;AACxB,YAAM,IAAI,MAAM,4BAA4B,OAAO,EAAE;AAAA,IACvD;AAGA,UAAM,YAAY,QAAQ,aAAa,KAAK,kBAAkB;AAG9D,UAAM,SAAS,KAAK,UAAU,SAAS;AAGvC,UAAM,YAAY,MAAM,aAAa;AAAA,MACnC;AAAA,MACA;AAAA,MACA,OAAO,QAAQ,UAAU;AAAA,MACzB,MAAM,QAAQ,SAAS;AAAA,MACvB,iBAAiB,QAAQ,mBAAmB;AAAA,MAC5C,MAAM,QAAQ,QAAQ;AAAA,MACtB,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAGD,UAAM,eAAe,QAAQ,OAAO,gBAAgB;AAGpD,QAAI,iBAAgE;AACpE,QAAI,QAAQ,WAAW;AACrB,YAAM,EAAE,qBAAAC,qBAAoB,IAAI,MAAM,OAAO,uBAAoB;AACjE,YAAM,UAAU,QAAQ,MAAM,kBAAkB,SAAS;AACzD,UAAI;AACF,cAAM,mBAAmBA,qBAAoB,EAAE,QAAQ,CAAC;AACxD,YAAI,iBAAiB,SAAS,GAAG;AAC/B,gBAAM,EAAE,SAAAC,SAAQ,IAAI,MAAM,OAAO,uBAAiB;AAClD,2BAAiB,IAAIA,SAAQ;AAAA,YAC3B,UAAU;AAAA,UACZ,CAAC;AAAA,QACH;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAGA,UAAM,oBAAoB,OAAO,YAAyD;AAGxF,aAAO,WAAW,EAAE,SAAS,EAAE,GAAG,SAAS,UAAU,EAAE,CAAC;AAAA,IAC1D;AAGA,QAAI,kBAAkB,CAAC,eAAe,WAAW;AAC/C,qBAAe,YAAY;AAAA,IAC7B;AAIA,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,OAAO,QAAQ;AAAA,MACf,SAAS;AAAA,MACT,OAAO,cAAc;AAAA,MACrB,OAAO,IAAI,MAAM,SAAS;AAAA,MAC1B,KAAK,QAAQ;AAAA,MACb;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB,QAAQ,QAAQ;AAAA,MAChB,aAAa,QAAQ;AAAA,MACrB,QAAQ,QAAQ;AAAA,MAChB,aAAa,QAAQ;AAAA,MACrB,WAAW,QAAQ;AAAA,MACnB,cAAc,QAAQ;AAAA,MACtB,eAAe,QAAQ;AAAA,MACvB,QAAQ,QAAQ;AAAA,MAChB,WAAW,gBAAgB,aAAa;AAAA,IAC1C,CAAC;AAGD,QAAI,OAAO,WAAW,SAAS;AAC7B,cAAQ,WAAW,eAAe,OAAO;AAAA,IAC3C;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,IACJ,SACA,SAIiB;AACjB,UAAM,SAAS,MAAM,KAAK,YAAY;AAAA,MACpC;AAAA,MACA,OAAO,SAAS;AAAA,MAChB,OAAO;AAAA,MACP,MAAM;AAAA,MACN,iBAAiB;AAAA,MACjB,MAAM;AAAA,MACN,UAAU;AAAA,IACZ,CAAC;AAED,QAAI,OAAO,SAAS;AAClB,aAAO,OAAO,KAAK,QAAQ;AAAA,IAC7B;AAEA,UAAM,IAAI,MAAM,OAAO,MAAM,OAAO;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,MAAsB;AAC5B,QAAI,CAAC,aAAa,IAAI,IAAI,GAAG;AAC3B,YAAM,IAAI,MAAM,iBAAiB,IAAI,sBAAsB,aAAa,OAAO,EAAE,IAAI,OAAK,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,IAC9G;AACA,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,UAAoB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,oBAA4B;AAC1B,WAAO,aAAa,OAAO;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,MAAkB;AAC7B,iBAAa,SAAS,IAAI;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,oBACJ,SACA,SAGqB;AACrB,UAAM,OAAO,aAAa,IAAI,KAAK,WAAW;AAC9C,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,gBAAgB,KAAK,WAAW,YAAY;AAAA,IAC9D;AAEA,UAAM,aAAa,KAAK;AAGxB,UAAM,cAAmD;AAAA,MACvD,OAAO,SAAS,SAAS,WAAW;AAAA,MACpC,MAAM,SAAS,QAAQ,WAAW;AAAA,MAClC,iBAAiB,SAAS,mBAAmB,WAAW;AAAA,MACxD,MAAM,SAAS,QAAQ,WAAW;AAAA,MAClC,UAAU,SAAS,YAAY,WAAW;AAAA,MAC1C,OAAO,SAAS,SAAS,WAAW;AAAA,MACpC,aAAa,SAAS;AAAA,MACtB,QAAQ,SAAS;AAAA,MACjB,aAAa,SAAS;AAAA,MACtB,WAAW,SAAS;AAAA,MACpB,cAAc,SAAS;AAAA,MACvB,eAAe,SAAS;AAAA,MACxB,QAAQ,SAAS;AAAA,MACjB,QAAQ,SAAS;AAAA,IACnB;AAGA,UAAM,oBAAoB,SAAS,gBAAgB,WAAW;AAE9D,WAAO,KAAK,6BAA6B,SAAS,aAAa,iBAAiB;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,6BACZ,SACA,SACA,cACqB;AACrB,QAAI,CAAC,KAAK,eAAe,CAAC,KAAK,SAAS;AACtC,YAAM,IAAI,MAAM,kDAAkD;AAAA,IACpE;AAEA,UAAM,UAAU,KAAK;AACrB,UAAM,UAAU,QAAQ,SAAS,QAAQ,OAAO;AAChD,UAAM,gBAAgB,MAAM,wBAAwB,SAAS,OAAO;AAEpE,QAAI,CAAC,cAAc,OAAO;AACxB,YAAM,IAAI,MAAM,4BAA4B,OAAO,EAAE;AAAA,IACvD;AAGA,UAAM,YAAY,MAAM,aAAa;AAAA,MACnC;AAAA,MACA,WAAW,KAAK,kBAAkB;AAAA,MAClC,OAAO,QAAQ,UAAU;AAAA,MACzB,MAAM,QAAQ,SAAS;AAAA,MACvB,iBAAiB,QAAQ,mBAAmB;AAAA,MAC5C,MAAM,QAAQ,QAAQ;AAAA,MACtB,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAGD,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,OAAO;AAAA,MACP,OAAO,cAAc;AAAA,MACrB,OAAO,IAAI,MAAM,SAAS;AAAA,MAC1B,KAAK,QAAQ;AAAA,MACb;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB,QAAQ,QAAQ;AAAA,MAChB,aAAa,QAAQ;AAAA,MACrB,QAAQ,QAAQ;AAAA,MAChB,aAAa,QAAQ;AAAA,MACrB,WAAW,QAAQ;AAAA,MACnB,cAAc,QAAQ;AAAA,MACtB,eAAe,QAAQ;AAAA,MACvB,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAGD,QAAI,OAAO,WAAW,SAAS;AAC7B,cAAQ,WAAW,eAAe,OAAO;AAAA,IAC3C;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAA4B;AAClC,WAAO,KAAK,IAAI,EAAE,SAAS,EAAE,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,CAAC;AAAA,EACzE;AACF;AAKO,SAAS,aAAa,SAAgC;AAC3D,SAAO,IAAI,OAAO,OAAO;AAC3B;;;AC3dO,IAAM,iBAAiB;","names":["fs","path","resolve","fs","path","fs","path","fs","path","resolve","fs","path","path","fs","fs","path","path","defaultOutputStyle","fs","message","result","sessionConfigManager","path","fs","resolve","fs","path","resolve","fs","os","path","fs","os","path","fs","path","SkillSource","MAX_NAME_LENGTH","MAX_DESCRIPTION_LENGTH","os","targetDir","entries","path","resolve","fs","resolve","fs","path","os","fs","path","JsonlLogger","fs","path","JsonlLogger","loadSessionMessages","History"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/context.ts","../src/agent/agent/agentManager.ts","../src/utils/safeFrontMatter.ts","../src/core/jsonl.ts","../src/core/llmsContext.ts","../src/core/rules.ts","../src/utils/execFileNoThrow.ts","../src/utils/git.ts","../src/utils/project.ts","../src/core/outputFormat.ts","../src/core/outputStyle.ts","../src/core/output-style/builtin/default.ts","../src/core/output-style/builtin/explanatory.ts","../src/core/output-style/builtin/miao.ts","../src/core/output-style/builtin/minimal.ts","../src/core/output-style/builtin/index.ts","../src/utils/string.ts","../src/core/planSystemPrompt.ts","../src/core/systemPrompt.ts","../src/core/project.ts","../src/agent/agent/executor.ts","../src/core/backgroundTaskManager.ts","../src/core/globalData.ts","../src/mcp/mcp.ts","../src/core/paths.ts","../src/skill/skill.ts","../src/skill/bundled.ts","../src/communication/messageBus.ts","../src/platform/node.ts","../src/jsonl.ts","../src/modes/registry.ts","../src/modes/builtin.ts","../src/api/engine.ts","../src/index.ts"],"sourcesContent":["import fs from 'fs';\nimport { createJiti } from 'jiti';\nimport path from 'pathe';\nimport resolve from 'resolve';\nimport { AgentManager } from '../agent/agent/agentManager';\nimport { BackgroundTaskManager } from './backgroundTaskManager';\nimport { type Config, ConfigManager } from '../core/config';\nimport { GlobalData } from './globalData';\nimport { MCPManager } from '../mcp/mcp';\nimport type { MessageBus } from '../communication/messageBus';\nimport { Paths } from './paths';\nimport {\n type Plugin,\n type PluginApplyOpts,\n PluginHookType,\n PluginManager,\n} from '../core/plugin';\n// notificationSoundPlugin is CLI-specific, not needed in engine\n// import { notificationSoundPlugin } from '../plugins/notification';\nimport { SkillManager } from '../skill/skill';\n\ntype ContextOpts = {\n cwd: string;\n productName: string;\n productASCIIArt?: string;\n version: string;\n config: Config;\n pluginManager: PluginManager;\n paths: Paths;\n argvConfig: Record<string, any>;\n mcpManager: MCPManager;\n backgroundTaskManager: BackgroundTaskManager;\n skillManager?: SkillManager;\n messageBus?: MessageBus;\n agentManager?: AgentManager;\n plugins: (string | Plugin)[];\n fetch?: typeof globalThis.fetch;\n globalData: GlobalData;\n};\n\nexport type ContextCreateOpts = {\n cwd: string;\n productName: string;\n productASCIIArt?: string;\n version: string;\n argvConfig: Record<string, any>;\n plugins: (string | Plugin)[];\n messageBus?: MessageBus;\n fetch?: typeof globalThis.fetch;\n};\n\nexport class Context {\n cwd: string;\n productName: string;\n productASCIIArt?: string;\n version: string;\n config: Config;\n paths: Paths;\n #pluginManager: PluginManager;\n argvConfig: Record<string, any>;\n mcpManager: MCPManager;\n backgroundTaskManager: BackgroundTaskManager;\n skillManager?: SkillManager;\n messageBus?: MessageBus;\n agentManager?: AgentManager;\n plugins: (string | Plugin)[];\n fetch?: typeof globalThis.fetch;\n globalData: GlobalData;\n constructor(opts: ContextOpts) {\n this.cwd = opts.cwd;\n this.productName = opts.productName;\n this.productASCIIArt = opts.productASCIIArt;\n this.version = opts.version;\n this.config = opts.config;\n this.paths = opts.paths;\n this.mcpManager = opts.mcpManager;\n this.#pluginManager = opts.pluginManager;\n this.argvConfig = opts.argvConfig;\n this.backgroundTaskManager = opts.backgroundTaskManager;\n this.skillManager = opts.skillManager;\n this.messageBus = opts.messageBus;\n this.agentManager = opts.agentManager;\n this.plugins = opts.plugins;\n this.fetch = opts.fetch;\n this.globalData = opts.globalData;\n }\n\n async apply(applyOpts: Omit<PluginApplyOpts, 'pluginContext'>) {\n return this.#pluginManager.apply({\n ...applyOpts,\n pluginContext: this,\n });\n }\n\n async destroy() {\n await this.mcpManager.destroy();\n await this.apply({\n hook: 'destroy',\n args: [],\n type: PluginHookType.Parallel,\n });\n }\n\n static async create(opts: ContextCreateOpts) {\n const { cwd, version, productASCIIArt } = opts;\n const productName = opts.productName.toLowerCase();\n const paths = new Paths({\n productName,\n cwd,\n });\n const configManager = new ConfigManager(\n cwd,\n productName,\n opts.argvConfig || {},\n );\n const initialConfig = configManager.config;\n // notificationSoundPlugin is CLI-specific, not needed in engine\n const buildInPlugins: Plugin[] = []; // [notificationSoundPlugin];\n const globalPlugins = scanPlugins(\n path.join(paths.globalConfigDir, 'plugins'),\n );\n const projectPlugins = scanPlugins(\n path.join(paths.projectConfigDir, 'plugins'),\n );\n const pluginsConfigs: (string | Plugin)[] = [\n ...buildInPlugins,\n ...globalPlugins,\n ...projectPlugins,\n ...(initialConfig.plugins || []),\n ...(opts.plugins || []),\n ];\n const plugins = await normalizePlugins(opts.cwd, pluginsConfigs);\n const pluginManager = new PluginManager(plugins);\n const apply = async (hookOpts: any) => {\n return pluginManager.apply({ ...hookOpts, pluginContext: tempContext });\n };\n const tempContext = {\n ...opts,\n config: initialConfig,\n apply,\n pluginManager,\n };\n const resolvedConfig = await apply({\n hook: 'config',\n args: [{ config: initialConfig, argvConfig: opts.argvConfig }],\n memo: initialConfig,\n type: PluginHookType.SeriesMerge,\n });\n tempContext.config = resolvedConfig;\n const mcpServers = {\n ...(resolvedConfig.mcpServers || {}),\n ...opts.argvConfig.mcpServers,\n };\n const mcpManager = MCPManager.create(mcpServers);\n const backgroundTaskManager = new BackgroundTaskManager();\n const globalData = new GlobalData({ globalDataPath: paths.getGlobalDataPath() });\n\n const context = new Context({\n cwd,\n productName,\n productASCIIArt,\n version,\n pluginManager,\n argvConfig: opts.argvConfig,\n config: resolvedConfig,\n paths,\n mcpManager,\n backgroundTaskManager,\n messageBus: opts.messageBus,\n plugins: pluginsConfigs,\n fetch: opts.fetch,\n globalData,\n });\n\n // Create and attach SkillManager\n const skillManager = new SkillManager({ context });\n await skillManager.loadSkills();\n context.skillManager = skillManager;\n\n // Create and attach AgentManager\n const agentManager = new AgentManager({ context });\n // Load agents from files\n await agentManager.loadAgents();\n context.agentManager = agentManager;\n\n return context;\n }\n}\n\nfunction normalizePlugins(cwd: string, plugins: (string | Plugin)[]) {\n let jiti: any = null;\n return Promise.all(\n plugins.map(async (plugin) => {\n if (typeof plugin === 'string') {\n const pluginPath = resolve.sync(plugin, { basedir: cwd });\n if (!jiti) {\n // Use cwd as base for jiti instead of import.meta.url for CJS compatibility\n jiti = createJiti(cwd);\n }\n return (await jiti.import(pluginPath, {\n default: true,\n })) as Plugin;\n }\n return plugin;\n }),\n );\n}\n\nfunction scanPlugins(pluginDir: string): string[] {\n try {\n if (!fs.existsSync(pluginDir)) {\n return [];\n }\n const files = fs.readdirSync(pluginDir);\n return files\n .filter((file) => file.endsWith('.js') || file.endsWith('.ts'))\n .map((file) => path.join(pluginDir, file));\n } catch (_error) {\n return [];\n }\n}\n","import fs from 'fs';\nimport path from 'pathe';\nimport { TOOL_NAMES } from '../../core/constants';\nimport type { Context } from '../../core/context';\nimport type { NormalizedMessage } from '../../core/message';\nimport { PluginHookType } from '../../core/plugin';\nimport type {\n ApprovalCategory,\n Tool,\n ToolApprovalResult,\n ToolUse,\n} from '../../tools/tool';\nimport { safeFrontMatter } from '../../utils/safeFrontMatter';\n// builtin agents excluded from engine for now\n// import { getBuiltinAgents } from './builtin';\nimport { executeAgent } from './executor';\nimport type {\n AgentDefinition,\n AgentExecuteOptions,\n AgentExecutionResult,\n AgentLoadError,\n TaskToolInput,\n} from './types';\nimport { AgentSource } from './types';\n\nconst MAX_NAME_LENGTH = 64;\nconst MAX_DESCRIPTION_LENGTH = 1024;\n\nexport class AgentManager {\n private agents: Map<string, AgentDefinition> = new Map();\n private context: Context;\n private errors: AgentLoadError[] = [];\n\n constructor(opts: { context: Context }) {\n this.context = opts.context;\n this.registerBuiltinAgents();\n }\n\n private registerBuiltinAgents(): void {\n // builtin agents excluded from engine for now\n // const builtinAgents = getBuiltinAgents({ context: this.context });\n // for (const agent of builtinAgents) {\n // this.agents.set(agent.agentType, agent);\n // }\n }\n\n registerAgent(definition: AgentDefinition): void {\n if (!definition.agentType) {\n throw new Error('Agent definition must have agentType');\n }\n if (!definition.systemPrompt) {\n throw new Error('Agent definition must have systemPrompt');\n }\n\n this.agents.set(definition.agentType, definition);\n }\n\n isAgentEnabled(agent: AgentDefinition): boolean {\n if (agent.isEnabled === undefined) {\n return true;\n }\n if (typeof agent.isEnabled === 'boolean') {\n return agent.isEnabled;\n }\n if (typeof agent.isEnabled === 'function') {\n return agent.isEnabled(this.context);\n }\n return true;\n }\n\n getAgent(agentType: string): AgentDefinition | undefined {\n const agent = this.agents.get(agentType);\n if (agent && this.isAgentEnabled(agent)) {\n return agent;\n }\n return undefined;\n }\n\n getAllAgents(): AgentDefinition[] {\n return Array.from(this.agents.values()).filter((agent) =>\n this.isAgentEnabled(agent),\n );\n }\n\n getAgentTypes(): string[] {\n return this.getAllAgents().map((agent) => agent.agentType);\n }\n\n async executeTask(\n input: TaskToolInput,\n context: {\n tools: Tool[];\n cwd: string;\n signal?: AbortSignal;\n parentSessionId?: string;\n forkContextMessages?: NormalizedMessage[];\n onMessage?: (\n message: NormalizedMessage,\n agentId: string,\n model: string,\n ) => void | Promise<void>;\n onToolApprove?: (opts: {\n toolUse: ToolUse;\n category?: ApprovalCategory;\n }) => Promise<boolean | ToolApprovalResult>;\n },\n ): Promise<AgentExecutionResult> {\n const definition = this.getAgent(input.subagent_type);\n if (!definition) {\n const availableTypes = this.getAgentTypes().join(', ');\n throw new Error(\n `Agent type '${input.subagent_type}' not found. Available agents: ${availableTypes}`,\n );\n }\n\n const executeOptions: AgentExecuteOptions = {\n definition,\n prompt: input.prompt,\n tools: context.tools,\n context: this.context,\n model: input.model,\n resume: input.resume,\n parentSessionId: context.parentSessionId,\n forkContextMessages: definition.forkContext\n ? context.forkContextMessages\n : undefined,\n cwd: context.cwd,\n signal: context.signal,\n onMessage: context.onMessage,\n onToolApprove: context.onToolApprove,\n };\n\n return executeAgent(executeOptions);\n }\n\n getAgentDescriptions(): string {\n const descriptions = this.getAllAgents()\n .map((agent) => {\n return `- ${agent.agentType}: ${agent.whenToUse ?? 'This subagent should only be called manually by the user.'}`;\n })\n .join('\\n');\n\n return `${descriptions}`;\n }\n\n async loadAgents(): Promise<void> {\n this.errors = [];\n\n // Plugins\n await this.loadAgentsFromPlugins();\n\n // GlobalClaude\n const globalClaudeDir = path.join(\n path.dirname(this.context.paths.globalConfigDir),\n '.claude',\n 'agents',\n );\n\n this.loadAgentsFromDirectory(globalClaudeDir, AgentSource.GlobalClaude);\n\n // Global\n const globalDir = path.join(this.context.paths.globalConfigDir, 'agents');\n this.loadAgentsFromDirectory(globalDir, AgentSource.Global);\n\n // ProjectClaude\n const projectClaudeDir = path.join(\n path.dirname(this.context.paths.projectConfigDir),\n '.claude',\n 'agents',\n );\n this.loadAgentsFromDirectory(projectClaudeDir, AgentSource.ProjectClaude);\n\n // Project\n const projectDir = path.join(this.context.paths.projectConfigDir, 'agents');\n this.loadAgentsFromDirectory(projectDir, AgentSource.Project);\n }\n\n private async loadAgentsFromPlugins(): Promise<void> {\n const pluginAgents = await this.context.apply({\n hook: 'agent',\n args: [],\n memo: [],\n type: PluginHookType.SeriesMerge,\n });\n\n for (const agent of pluginAgents) {\n this.agents.set(agent.agentType, {\n ...agent,\n model: agent.model || 'inherit',\n source: AgentSource.Plugin,\n });\n }\n }\n\n getErrors(): AgentLoadError[] {\n return this.errors;\n }\n\n private loadAgentsFromDirectory(\n agentsDir: string,\n source: AgentSource,\n ): void {\n if (!fs.existsSync(agentsDir)) {\n return;\n }\n\n try {\n const entries = fs.readdirSync(agentsDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith('.md')) {\n const agentPath = path.join(agentsDir, entry.name);\n this.loadAgentFile(agentPath, source);\n }\n }\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : 'Unknown error scanning directory';\n this.errors.push({\n path: agentsDir,\n message: `Failed to scan agents directory: ${message}`,\n });\n }\n }\n\n private loadAgentFile(filePath: string, source: AgentSource): void {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = this.parseAgentFile(content, filePath);\n\n if (parsed) {\n if (\n source === AgentSource.GlobalClaude ||\n source === AgentSource.ProjectClaude\n ) {\n parsed.tools = this.convertToolNames(parsed.tools || [], filePath);\n parsed.disallowedTools = this.convertToolNames(\n parsed.disallowedTools || [],\n filePath,\n );\n }\n this.agents.set(parsed.agentType, {\n ...parsed,\n source,\n path: filePath,\n });\n }\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'Unknown error loading agent';\n this.errors.push({\n path: filePath,\n message,\n });\n }\n }\n\n private convertToolNames(toolNames: string[], filePath: string): string[] {\n // Return tool names as-is, no conversion needed\n return toolNames;\n }\n\n private parseAgentFile(\n content: string,\n filePath: string,\n ): Omit<AgentDefinition, 'source' | 'path'> | null {\n try {\n const { attributes, body } = safeFrontMatter<{\n name?: string;\n description?: string;\n tools?: string;\n disallowedTools?: string;\n model?: string;\n forkContext?: boolean;\n color?: string;\n }>(content, filePath);\n\n if (!attributes.name) {\n this.errors.push({\n path: filePath,\n message: 'Missing required field: name',\n });\n return null;\n }\n\n if (!attributes.description) {\n this.errors.push({\n path: filePath,\n message: 'Missing required field: description',\n });\n return null;\n }\n\n if (attributes.name.length > MAX_NAME_LENGTH) {\n this.errors.push({\n path: filePath,\n message: `Name exceeds maximum length of ${MAX_NAME_LENGTH} characters`,\n });\n return null;\n }\n\n if (attributes.name.includes('\\n')) {\n this.errors.push({\n path: filePath,\n message: 'Name must be a single line',\n });\n return null;\n }\n\n if (attributes.description.length > MAX_DESCRIPTION_LENGTH) {\n this.errors.push({\n path: filePath,\n message: `Description exceeds maximum length of ${MAX_DESCRIPTION_LENGTH} characters`,\n });\n return null;\n }\n\n if (attributes.description.includes('\\n')) {\n this.errors.push({\n path: filePath,\n message: 'Description must be a single line',\n });\n return null;\n }\n\n const systemPrompt = body.trim();\n if (!systemPrompt) {\n this.errors.push({\n path: filePath,\n message: 'Missing system prompt (file body is empty)',\n });\n return null;\n }\n\n const tools = attributes.tools\n ? attributes.tools\n .split(',')\n .map((t) => t.trim())\n .filter((t) => t.length > 0)\n : undefined;\n\n const disallowedTools = attributes.disallowedTools\n ? attributes.disallowedTools\n .split(',')\n .map((t) => t.trim())\n .filter((t) => t.length > 0)\n : undefined;\n\n return {\n agentType: attributes.name,\n whenToUse: attributes.description,\n systemPrompt,\n model: attributes.model || 'inherit',\n tools,\n disallowedTools,\n forkContext: attributes.forkContext,\n color: attributes.color,\n };\n } catch (error) {\n this.errors.push({\n path: filePath,\n message:\n error instanceof Error\n ? error.message\n : 'Failed to parse frontmatter',\n });\n return null;\n }\n }\n}\n","import fm from 'front-matter';\n\nconst SIMPLE_VALUE_PATTERN = /^[a-zA-Z0-9_.\\-\\s]+$/;\n\nfunction isSimpleValue(value: string): boolean {\n if (!value) return true;\n const trimmed = value.trim();\n if (!trimmed) return true;\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n return true;\n }\n return SIMPLE_VALUE_PATTERN.test(trimmed);\n}\n\nfunction fixFrontmatterValues(frontmatter: string): string {\n return frontmatter.replace(\n /^(\\s*[a-zA-Z0-9_-]+\\s*:\\s*)(.+)$/gm,\n (match, keyPart, valuePart) => {\n if (isSimpleValue(valuePart)) {\n return match;\n }\n const trimmed = valuePart.trim();\n return `${keyPart}\"${trimmed.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\n },\n );\n}\n\n/**\n * Safely parse frontmatter from markdown content with automatic error recovery\n * Handles common YAML issues like unquoted colons in values\n * @param content - The markdown content with frontmatter\n * @param filePath - Optional file path for better error messages\n * @returns Parsed frontmatter attributes and body\n */\nexport function safeFrontMatter<T = Record<string, string>>(\n content: string,\n filePath?: string,\n): { attributes: T; body: string } {\n try {\n const { attributes, body } = fm<T>(content);\n return { attributes, body };\n } catch (error) {\n try {\n const frontmatterMatch = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/);\n if (frontmatterMatch) {\n const originalFm = frontmatterMatch[1];\n const fixedFm = fixFrontmatterValues(originalFm);\n\n if (fixedFm !== originalFm) {\n const fixedContent = content.replace(originalFm, fixedFm);\n const { attributes, body } = fm<T>(fixedContent);\n return { attributes, body };\n }\n }\n } catch {\n // Ignore retry errors\n }\n\n if (error instanceof Error) {\n const fileInfo = filePath ? ` ${filePath}` : '';\n error.message = `Failed to parse frontmatter${fileInfo}: ${error.message}`;\n }\n throw error;\n }\n}\n","import fs from 'fs';\nimport path from 'pathe';\nimport type { NormalizedMessage } from './message';\nimport { createUserMessage } from './message';\nimport type { StreamResult } from './loop';\n\nexport class JsonlLogger {\n filePath: string;\n lastUuid: string | null = null;\n constructor(opts: { filePath: string }) {\n this.filePath = opts.filePath;\n this.lastUuid = this.getLatestUuid();\n }\n\n getLatestUuid() {\n if (!fs.existsSync(this.filePath)) {\n return null;\n }\n const file = fs.readFileSync(this.filePath, 'utf8');\n const lines = file.split('\\n').filter(Boolean);\n const lastLine = lines[lines.length - 1];\n if (!lastLine) {\n return null;\n }\n const message = JSON.parse(lastLine);\n return message.uuid || null;\n }\n\n addMessage(opts: { message: NormalizedMessage & { sessionId: string } }) {\n const dir = path.dirname(this.filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n const message = opts.message;\n fs.appendFileSync(this.filePath, JSON.stringify(message) + '\\n');\n this.lastUuid = message.uuid;\n return message;\n }\n\n addUserMessage(content: string, sessionId: string) {\n const message = {\n ...createUserMessage(content, this.lastUuid),\n sessionId,\n };\n return this.addMessage({\n message,\n });\n }\n}\n\nexport class RequestLogger {\n globalProjectDir: string;\n\n constructor(opts: { globalProjectDir: string }) {\n this.globalProjectDir = opts.globalProjectDir;\n }\n\n private getFilePath(requestId: string): string {\n const requestsDir = path.join(this.globalProjectDir, 'requests');\n if (!fs.existsSync(requestsDir)) {\n fs.mkdirSync(requestsDir, { recursive: true });\n }\n return path.join(requestsDir, `${requestId}.jsonl`);\n }\n\n logMetadata(opts: {\n requestId: string;\n prompt: StreamResult['prompt'];\n model: StreamResult['model'];\n tools: StreamResult['tools'];\n request?: StreamResult['request'];\n response?: StreamResult['response'];\n error?: StreamResult['error'];\n }) {\n const filePath = this.getFilePath(opts.requestId);\n const entry = {\n type: 'metadata',\n requestId: opts.requestId,\n timestamp: new Date().toISOString(),\n prompt: opts.prompt,\n model: opts.model,\n tools: opts.tools,\n request: opts.request,\n response: opts.response,\n error: opts.error,\n };\n fs.appendFileSync(filePath, JSON.stringify(entry) + '\\n');\n }\n\n logChunk(requestId: string, chunk: any) {\n const filePath = this.getFilePath(requestId);\n const entry = {\n type: 'chunk',\n requestId,\n timestamp: new Date().toISOString(),\n chunk,\n };\n fs.appendFileSync(filePath, JSON.stringify(entry) + '\\n');\n }\n}\n","import fs from 'fs';\nimport path from 'pathe';\nimport { platform } from 'process';\nimport type { Context } from './context';\nimport { PluginHookType } from './plugin';\nimport { getLlmsRules } from './rules';\nimport { createLSTool } from '../tools/tools/ls';\nimport { getGitStatus, getLlmGitStatus } from '../utils/git';\nimport { isProjectDirectory } from '../utils/project';\n\nexport type LlmsContextCreateOpts = {\n context: Context;\n sessionId: string;\n userPrompt: string | null;\n additionalDirectories?: string[];\n};\n\nexport class LlmsContext {\n messages: string[];\n constructor(opts: { messages: string[] }) {\n this.messages = opts.messages;\n }\n\n static async create(opts: LlmsContextCreateOpts) {\n const gitStatus = await getGitStatus({ cwd: opts.context.cwd });\n\n let llmsContext: Record<string, string> = {};\n // 1. git status\n const llmsGitStatus = await getLlmGitStatus(gitStatus);\n if (llmsGitStatus) {\n llmsContext.gitStatus = llmsGitStatus;\n }\n // 2. directory structure\n const isProject = isProjectDirectory(opts.context.cwd);\n if (isProject) {\n const LSTool = createLSTool({\n cwd: opts.context.cwd,\n });\n const result = await LSTool.execute({ dir_path: '.' });\n if (result) {\n llmsContext.directoryStructure = `\n${result.returnDisplay}\n<directory_structure>\n${result.llmContent}\n</directory_structure>\n `.trim();\n }\n }\n // 3. rules\n const rules = getLlmsRules({\n cwd: opts.context.cwd,\n productName: opts.context.productName,\n globalConfigDir: opts.context.paths.globalConfigDir,\n });\n if (rules) {\n llmsContext.rules = rules.llmsDescription;\n }\n // 4. readme\n const readmePath = path.join(opts.context.cwd, 'README.md');\n if (fs.existsSync(readmePath)) {\n llmsContext.readme = fs.readFileSync(readmePath, 'utf-8');\n }\n\n llmsContext = await opts.context.apply({\n hook: 'context',\n args: [\n {\n sessionId: opts.sessionId,\n userPrompt: opts.userPrompt,\n },\n ],\n memo: llmsContext,\n type: PluginHookType.SeriesMerge,\n });\n const llmsContextStr = `\n# Context\nAs you answer the user's questions, you can use the following context:\n${Object.entries(llmsContext)\n // Support disabling default context\n .filter(([_, value]) => value)\n .map(([key, value]) => `<context name=\"${key}\">${value}</context>`)\n .join('\\n')}\n `.trim();\n\n let llmsEnv = {\n 'Working directory': opts.context.cwd,\n ...(opts.additionalDirectories &&\n opts.additionalDirectories.length > 0 && {\n 'Additional working directories':\n opts.additionalDirectories.join(', '),\n }),\n 'Is directory a git repo': gitStatus ? 'YES' : 'NO',\n Platform: platform,\n \"Today's date\": new Date().toLocaleDateString(),\n };\n llmsEnv = await opts.context.apply({\n hook: 'env',\n args: [\n {\n sessionId: opts.sessionId,\n userPrompt: opts.userPrompt,\n },\n ],\n memo: llmsEnv,\n type: PluginHookType.SeriesMerge,\n });\n const llmsEnvStr = `\n# Environment\nHere is useful information about the environment you are running in.\n${Object.entries(llmsEnv)\n .map(([key, value]) => `<env name=\"${key}\">${value}</env>`)\n .join('\\n')}\n `.trim();\n\n return new LlmsContext({ messages: [llmsContextStr, llmsEnvStr] });\n }\n}\n","import fs from 'fs';\nimport path from 'pathe';\n\nexport function getLlmsRules(opts: {\n cwd: string;\n productName: string;\n globalConfigDir: string;\n}) {\n const rules: string[] = [];\n const productName = opts.productName;\n\n const globalRuleNames = ['AGENTS.md', `${productName.toUpperCase()}.md`];\n const projectRuleNames = [\n 'AGENTS.md',\n 'CLAUDE.md',\n `${productName.toUpperCase()}.md`,\n ];\n\n // 1. project rules\n let currentDir = opts.cwd;\n while (currentDir !== path.parse(currentDir).root) {\n for (const ruleName of projectRuleNames) {\n const stylePath = path.join(currentDir, ruleName);\n if (fs.existsSync(stylePath)) {\n rules.push(fs.readFileSync(stylePath, 'utf-8'));\n }\n }\n currentDir = path.dirname(currentDir);\n }\n // 2. global rules\n for (const ruleName of globalRuleNames) {\n const globalStylePath = path.join(opts.globalConfigDir, ruleName);\n if (fs.existsSync(globalStylePath)) {\n rules.push(fs.readFileSync(globalStylePath, 'utf-8'));\n }\n }\n const globalClaudeRulePath = path.join(\n opts.globalConfigDir,\n '../.claude/CLAUDE.md',\n );\n if (fs.existsSync(globalClaudeRulePath)) {\n rules.push(fs.readFileSync(globalClaudeRulePath, 'utf-8'));\n }\n\n if (rules.length === 0) {\n return null;\n }\n const reversedRules = rules.reverse();\n return {\n rules: reversedRules.join('\\n\\n'),\n llmsDescription: `\n Codebase and user instructions are shown below. Be sure to adhere to these instructions. IMPORTANT: These instructions OVERRIDE any default behavior and you MUST follow them exactly as written\n\n ${reversedRules.join('\\n\\n')}`,\n };\n}\n","import { execFile } from 'child_process';\n\nconst MS_IN_SECOND = 1000;\nconst SECONDS_IN_MINUTE = 60;\n\n/**\n * execFile, but always resolves (never throws)\n */\nexport function execFileNoThrow(\n cwd: string,\n file: string,\n args: string[],\n abortSignal?: AbortSignal,\n timeout = 10 * SECONDS_IN_MINUTE * MS_IN_SECOND,\n preserveOutputOnError = true,\n): Promise<{ stdout: string; stderr: string; code: number }> {\n return new Promise((resolve) => {\n try {\n execFile(\n file,\n args,\n {\n maxBuffer: 1_000_000,\n signal: abortSignal,\n timeout,\n cwd,\n },\n (error, stdout, stderr) => {\n if (error) {\n if (preserveOutputOnError) {\n const errorCode = typeof error.code === 'number' ? error.code : 1;\n resolve({\n stdout: stdout || '',\n stderr: stderr || '',\n code: errorCode,\n });\n } else {\n resolve({ stdout: '', stderr: '', code: 1 });\n }\n } else {\n resolve({ stdout, stderr, code: 0 });\n }\n },\n );\n } catch (error) {\n resolve({ stdout: '', stderr: '', code: 1 });\n }\n });\n}\n","import { execFileNoThrow } from './execFileNoThrow';\n\n// ============================================================================\n// Internal Helpers (DRY)\n// ============================================================================\n\nasync function gitExec(\n cwd: string,\n args: string[],\n): Promise<{ code: number; stdout: string; stderr: string }> {\n return execFileNoThrow(cwd, 'git', args, undefined, undefined, false);\n}\n\nasync function gitCheck(cwd: string, args: string[]): Promise<boolean> {\n const { code } = await gitExec(cwd, args);\n return code === 0;\n}\n\nasync function gitOutput(cwd: string, args: string[]): Promise<string> {\n const { stdout } = await gitExec(cwd, args);\n return stdout.trim();\n}\n\n// ============================================================================\n// Validation Functions\n// ============================================================================\n\n/**\n * Check if git is installed and available in PATH\n */\nexport async function isGitInstalled(): Promise<boolean> {\n try {\n const { code } = await execFileNoThrow(\n process.cwd(),\n 'git',\n ['--version'],\n undefined,\n undefined,\n false,\n );\n return code === 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if the given directory is inside a git repository\n */\nexport async function isGitRepository(cwd: string): Promise<boolean> {\n return gitCheck(cwd, ['rev-parse', '--is-inside-work-tree']);\n}\n\n/**\n * Check if git user name and email are configured\n */\nexport async function isGitUserConfigured(\n cwd: string,\n): Promise<{ name: boolean; email: boolean }> {\n const [nameResult, emailResult] = await Promise.all([\n gitCheck(cwd, ['config', 'user.name']),\n gitCheck(cwd, ['config', 'user.email']),\n ]);\n return { name: nameResult, email: emailResult };\n}\n\n// ============================================================================\n// Query Functions\n// ============================================================================\n\n/**\n * Check if there are uncommitted changes (staged or unstaged)\n */\nexport async function hasUncommittedChanges(cwd: string): Promise<boolean> {\n const output = await gitOutput(cwd, ['status', '--porcelain']);\n return output.length > 0;\n}\n\n/**\n * Get list of unstaged files with their status\n * Returns files that have changes not yet staged (working tree changes)\n */\nexport async function getUnstagedFiles(\n cwd: string,\n): Promise<Array<{ status: string; file: string }>> {\n const { stdout } = await gitExec(cwd, ['status', '--porcelain']);\n const output = stdout.trimEnd();\n if (!output) return [];\n\n const files: Array<{ status: string; file: string }> = [];\n for (const line of output.split('\\n')) {\n if (!line) continue;\n const indexStatus = line[0];\n const workTreeStatus = line[1];\n const file = line.substring(3);\n if (indexStatus === '?' && workTreeStatus === '?') {\n files.push({ status: '?', file });\n } else if (workTreeStatus !== ' ' && workTreeStatus !== undefined) {\n files.push({ status: workTreeStatus, file });\n }\n }\n return files;\n}\n\n/**\n * Check if any remote is configured\n */\nexport async function hasRemote(cwd: string): Promise<boolean> {\n const output = await gitOutput(cwd, ['remote']);\n return output.length > 0;\n}\n\n/**\n * Check if origin remote is configured\n */\nexport async function hasOriginRemote(cwd: string): Promise<boolean> {\n return gitCheck(cwd, ['remote', 'get-url', 'origin']);\n}\n\n/**\n * Check if a branch exists\n */\nexport async function branchExists(\n cwd: string,\n branchName: string,\n): Promise<boolean> {\n return gitCheck(cwd, ['rev-parse', '--verify', branchName]);\n}\n\n/**\n * Get recent commit messages\n */\nexport async function getRecentCommitMessages(\n cwd: string,\n count = 10,\n): Promise<string> {\n return gitOutput(cwd, ['log', '-n', String(count), '--pretty=format:%s']);\n}\n\n// ============================================================================\n// Action Functions\n// ============================================================================\n\n/**\n * Stage all changes\n */\nexport async function stageAll(cwd: string): Promise<void> {\n const { code, stderr } = await gitExec(cwd, ['add', '.']);\n if (code !== 0) {\n const errorMessage = stderr || 'Unknown error';\n if (errorMessage.includes('fatal: pathspec')) {\n throw new Error('Failed to stage files: Invalid file path or pattern');\n }\n throw new Error(`Failed to stage files: ${errorMessage}`);\n }\n}\n\n/**\n * Commit staged changes with a message\n * @param cwd - Working directory\n * @param message - Commit message\n * @param skipHooks - Skip pre-commit hooks\n * @param onOutput - Optional callback for streaming output\n */\nexport async function gitCommit(\n cwd: string,\n message: string,\n skipHooks = false,\n onOutput?: (line: string, stream: 'stdout' | 'stderr') => void,\n): Promise<void> {\n const args = ['commit', '-m', message];\n if (skipHooks) {\n args.push('--no-verify');\n }\n\n // If no output callback, use the simple exec approach\n if (!onOutput) {\n const { code, stderr } = await gitExec(cwd, args);\n if (code !== 0) {\n throw new Error(stderr || 'Commit failed');\n }\n return;\n }\n\n // Use spawn for streaming output\n const { spawn } = await import('child_process');\n\n return new Promise((resolve, reject) => {\n const gitProcess = spawn('git', args, { cwd });\n let stderr = '';\n\n const processOutput = (\n data: Buffer,\n stream: 'stdout' | 'stderr',\n buffer: string,\n ): string => {\n const text = buffer + data.toString();\n const lines = text.split('\\n');\n // Keep the last incomplete line in buffer\n const incomplete = lines.pop() || '';\n for (const line of lines) {\n if (line.trim()) {\n onOutput(line, stream);\n }\n }\n return incomplete;\n };\n\n let stdoutBuffer = '';\n let stderrBuffer = '';\n\n gitProcess.stdout?.on('data', (data: Buffer) => {\n stdoutBuffer = processOutput(data, 'stdout', stdoutBuffer);\n });\n\n gitProcess.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n stderrBuffer = processOutput(data, 'stderr', stderrBuffer);\n });\n\n gitProcess.on('error', (error) => {\n reject(error);\n });\n\n gitProcess.on('close', (code) => {\n // Flush any remaining buffered content\n if (stdoutBuffer.trim()) {\n onOutput(stdoutBuffer, 'stdout');\n }\n if (stderrBuffer.trim()) {\n onOutput(stderrBuffer, 'stderr');\n }\n\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(stderr || 'Commit failed'));\n }\n });\n });\n}\n\n/**\n * Push changes to remote\n * @param cwd - Working directory\n * @param onOutput - Optional callback for streaming output\n */\nexport async function gitPush(\n cwd: string,\n onOutput?: (line: string, stream: 'stdout' | 'stderr') => void,\n): Promise<void> {\n // If no output callback, use the simple exec approach\n if (!onOutput) {\n const { code, stderr } = await gitExec(cwd, [\n 'push',\n '-u',\n 'origin',\n 'HEAD',\n ]);\n if (code !== 0) {\n throw new Error(stderr || 'Push failed');\n }\n return;\n }\n\n // Use spawn for streaming output with progress\n const { spawn } = await import('child_process');\n\n return new Promise((resolve, reject) => {\n // Use --progress to ensure git outputs progress info\n // Use -u origin HEAD to auto-set upstream for new branches\n const gitProcess = spawn(\n 'git',\n ['push', '-u', 'origin', 'HEAD', '--progress'],\n { cwd },\n );\n let stderr = '';\n\n // Process output, handling \\r (carriage return) for in-place progress updates\n // Only output complete lines (ending with \\n), taking the last \\r segment\n const processOutput = (\n data: Buffer,\n stream: 'stdout' | 'stderr',\n buffer: string,\n ): string => {\n const text = buffer + data.toString();\n // Split by newlines only\n const lines = text.split('\\n');\n // Keep the last incomplete line in buffer\n const incomplete = lines.pop() || '';\n for (const line of lines) {\n // For lines with \\r, take only the last segment (final progress state)\n const segments = line.split('\\r');\n const finalSegment = segments[segments.length - 1];\n if (finalSegment.trim()) {\n onOutput(finalSegment, stream);\n }\n }\n return incomplete;\n };\n\n let stdoutBuffer = '';\n let stderrBuffer = '';\n\n gitProcess.stdout?.on('data', (data: Buffer) => {\n stdoutBuffer = processOutput(data, 'stdout', stdoutBuffer);\n });\n\n gitProcess.stderr?.on('data', (data: Buffer) => {\n stderr += data.toString();\n stderrBuffer = processOutput(data, 'stderr', stderrBuffer);\n });\n\n gitProcess.on('error', (error) => {\n reject(error);\n });\n\n gitProcess.on('close', (code) => {\n // Flush any remaining buffered content, handling \\r for progress updates\n if (stdoutBuffer.trim()) {\n const segments = stdoutBuffer.split('\\r');\n const finalSegment = segments[segments.length - 1];\n if (finalSegment.trim()) {\n onOutput(finalSegment, 'stdout');\n }\n }\n if (stderrBuffer.trim()) {\n const segments = stderrBuffer.split('\\r');\n const finalSegment = segments[segments.length - 1];\n if (finalSegment.trim()) {\n onOutput(finalSegment, 'stderr');\n }\n }\n\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(stderr || 'Push failed'));\n }\n });\n });\n}\n\n/**\n * Create and checkout a new branch\n */\nexport async function createAndCheckoutBranch(\n cwd: string,\n branchName: string,\n): Promise<void> {\n const { code, stderr } = await gitExec(cwd, ['checkout', '-b', branchName]);\n if (code !== 0) {\n throw new Error(stderr || 'Failed to create branch');\n }\n}\n\n// ============================================================================\n// Composite Functions\n// ============================================================================\n\nexport async function getGitStatus(opts: { cwd: string }) {\n const { cwd } = opts;\n if (!(await isGitRepository(cwd))) {\n return null;\n }\n\n const [branch, mainBranch, status, log, author] = await Promise.all([\n gitOutput(cwd, ['branch', '--show-current']),\n gitOutput(cwd, ['rev-parse', '--abbrev-ref', 'origin/HEAD']).then((s) =>\n s.replace('origin/', ''),\n ),\n gitOutput(cwd, ['status', '--short']),\n gitOutput(cwd, ['log', '--oneline', '-n', '5']),\n gitOutput(cwd, ['config', 'user.email']),\n ]);\n\n const authorLog = await gitOutput(cwd, [\n 'log',\n '--author',\n author,\n '--oneline',\n '-n',\n '5',\n ]);\n\n return {\n branch,\n mainBranch,\n status,\n log,\n author,\n authorLog,\n };\n}\n\nexport async function getLlmGitStatus(\n status: Awaited<ReturnType<typeof getGitStatus>>,\n) {\n if (!status) {\n return null;\n }\n return `\nThis is the git status at the start of the conversation. Note that this status is a snapshot in time, and will not update during the conversation.\nCurrent branch: ${status.branch}\n\nMain branch (you will usually use this for PRs): ${status.mainBranch}\n\nStatus:\n${status.status || '(clean)'}\n\nRecent commits:\n${status.log}\n\nYour recent commits:\n${status.authorLog || '(no recent commits)'}\n `.trim();\n}\n\n/**\n * Get remote origin URL\n */\nexport async function getGitRemoteUrl(cwd: string): Promise<string | null> {\n try {\n const { stdout } = await execFileNoThrow(\n cwd,\n 'git',\n ['config', '--get', 'remote.origin.url'],\n undefined,\n undefined,\n false,\n );\n return stdout.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get default branch from remote\n */\nexport async function getDefaultBranch(cwd: string): Promise<string | null> {\n try {\n const { stdout } = await execFileNoThrow(\n cwd,\n 'git',\n ['rev-parse', '--abbrev-ref', 'origin/HEAD'],\n undefined,\n undefined,\n false,\n );\n return stdout.replace('origin/', '').trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check sync status with remote\n */\nexport async function getGitSyncStatus(\n cwd: string,\n): Promise<'synced' | 'ahead' | 'behind' | 'diverged' | 'unknown'> {\n try {\n // Fetch remote to get latest info\n await execFileNoThrow(\n cwd,\n 'git',\n ['fetch', 'origin', '--quiet'],\n undefined,\n undefined,\n false,\n );\n\n // Get current branch\n const { stdout: branch } = await execFileNoThrow(\n cwd,\n 'git',\n ['rev-parse', '--abbrev-ref', 'HEAD'],\n undefined,\n undefined,\n false,\n );\n const currentBranch = branch.trim();\n\n // Check if remote tracking branch exists\n const { code: trackingExists } = await execFileNoThrow(\n cwd,\n 'git',\n ['rev-parse', '--verify', `origin/${currentBranch}`],\n undefined,\n undefined,\n false,\n );\n\n if (trackingExists !== 0) {\n return 'unknown';\n }\n\n // Get ahead/behind counts\n const { stdout: counts } = await execFileNoThrow(\n cwd,\n 'git',\n ['rev-list', '--left-right', '--count', `origin/${currentBranch}...HEAD`],\n undefined,\n undefined,\n false,\n );\n\n const [behind, ahead] = counts.trim().split('\\t').map(Number);\n\n if (ahead === 0 && behind === 0) {\n return 'synced';\n }\n if (ahead > 0 && behind === 0) {\n return 'ahead';\n }\n if (ahead === 0 && behind > 0) {\n return 'behind';\n }\n return 'diverged';\n } catch {\n return 'unknown';\n }\n}\n\n/**\n * Get current commit hash\n */\nexport async function getCurrentCommit(cwd: string): Promise<string> {\n try {\n const { stdout } = await execFileNoThrow(\n cwd,\n 'git',\n ['rev-parse', 'HEAD'],\n undefined,\n undefined,\n false,\n );\n return stdout.trim();\n } catch {\n return '';\n }\n}\n\n/**\n * Get list of pending changes\n */\nexport async function getPendingChanges(cwd: string): Promise<string[]> {\n try {\n const { stdout } = await execFileNoThrow(\n cwd,\n 'git',\n ['status', '--porcelain'],\n undefined,\n undefined,\n false,\n );\n if (!stdout.trim()) {\n return [];\n }\n return stdout\n .trim()\n .split('\\n')\n .map((line) => line.substring(3).trim());\n } catch {\n return [];\n }\n}\n\n/**\n * Get staged file list with status\n */\nexport async function getStagedFileList(cwd: string): Promise<string> {\n return gitOutput(cwd, ['diff', '--cached', '--name-status']);\n}\n\n/**\n * Git URL validation patterns\n */\nconst GIT_HTTPS_PATTERN =\n /^https?:\\/\\/(?:[a-zA-Z0-9_.~-]+@)?[a-zA-Z0-9_.~-]+(?:\\.[a-zA-Z0-9_.~-]+)*(?::\\d+)?\\/[a-zA-Z0-9_.~/-]+(\\.git)?$/;\nconst GIT_SSH_PATTERN =\n /^git@[a-zA-Z0-9_.~-]+(?:\\.[a-zA-Z0-9_.~-]+)*:[a-zA-Z0-9_.~/-]+(\\.git)?$/;\n\n/**\n * Validate git repository URL format\n */\nexport function validateGitUrl(url: string): boolean {\n return GIT_HTTPS_PATTERN.test(url) || GIT_SSH_PATTERN.test(url);\n}\n\n/**\n * Sanitize git URL to prevent command injection\n */\nexport function sanitizeGitUrl(url: string): string {\n return url\n .split(/[;&|`$()]/)[0] // Remove shell special characters\n .trim();\n}\n\n/**\n * Validate destination path security\n */\nexport function validateDestinationPath(destination: string): {\n valid: boolean;\n error?: string;\n} {\n const { resolve } = require('pathe');\n const normalizedDest = resolve(destination);\n const dangerousPaths = [\n '/etc',\n '/usr',\n '/bin',\n '/sbin',\n '/var',\n '/System',\n 'C:\\\\Windows',\n 'C:\\\\Program Files',\n ];\n\n if (dangerousPaths.some((p) => normalizedDest.startsWith(p))) {\n return {\n valid: false,\n error: 'Cannot clone to system directories',\n };\n }\n\n return { valid: true };\n}\n\n/**\n * Extract repository name from git URL\n */\nexport function extractRepoName(url: string): string {\n const repoNameMatch = url.match(/\\/([^/]+?)(\\.git)?$/);\n return repoNameMatch ? repoNameMatch[1] : `repo-${Date.now()}`;\n}\n\n/**\n * Parse git clone progress output\n */\nexport interface GitCloneProgress {\n percent: number;\n message: string;\n}\n\nexport class GitCloneProgressParser {\n private currentStage = '';\n private stageProgress = { receiving: 0, resolving: 0, checking: 0 };\n private lastOverallPercent = 0;\n\n parse(output: string): GitCloneProgress | null {\n // Support both English and Chinese Git output\n const progressMatch = output.match(/(\\d+)%/);\n if (!progressMatch) {\n return null;\n }\n\n const percent = Number.parseInt(progressMatch[1], 10);\n\n // Detect current stage and update stage progress\n if (output.includes('Receiving objects') || output.includes('接收对象中')) {\n this.currentStage = 'receiving';\n this.stageProgress.receiving = percent;\n } else if (\n output.includes('Resolving deltas') ||\n output.includes('处理 delta 中')\n ) {\n // Mark receiving as complete when resolving starts\n if (this.stageProgress.receiving === 0) {\n this.stageProgress.receiving = 100;\n }\n\n // Reset lastOverallPercent when transitioning to new stage\n if (this.currentStage !== 'resolving') {\n this.lastOverallPercent = 0;\n }\n\n this.currentStage = 'resolving';\n this.stageProgress.resolving = percent;\n } else if (\n output.includes('Checking out files') ||\n output.includes('检出文件中')\n ) {\n // Mark previous stages as complete\n if (this.stageProgress.receiving === 0) {\n this.stageProgress.receiving = 100;\n }\n if (this.stageProgress.resolving === 0) {\n this.stageProgress.resolving = 100;\n }\n\n // Reset lastOverallPercent when transitioning to new stage\n if (this.currentStage !== 'checking') {\n this.lastOverallPercent = 0;\n }\n\n this.currentStage = 'checking';\n this.stageProgress.checking = percent;\n } else {\n // Unknown stage with percentage - skip to avoid noise\n return null;\n }\n\n // Calculate overall progress (0-100%)\n let overallPercent = 0;\n\n // Determine active stages\n const hasResolving =\n this.stageProgress.resolving > 0 || this.currentStage === 'resolving';\n const hasChecking =\n this.stageProgress.checking > 0 || this.currentStage === 'checking';\n\n if (hasResolving && hasChecking) {\n // All three stages: Receiving(0-70%), Resolving(70-90%), Checking(90-100%)\n overallPercent =\n Math.floor((this.stageProgress.receiving * 70) / 100) +\n Math.floor((this.stageProgress.resolving * 20) / 100) +\n Math.floor((this.stageProgress.checking * 10) / 100);\n } else if (hasResolving) {\n // Two stages: Receiving(0-80%), Resolving(80-100%)\n overallPercent =\n Math.floor((this.stageProgress.receiving * 80) / 100) +\n Math.floor((this.stageProgress.resolving * 20) / 100);\n } else {\n // Single stage (small repos): Receiving(0-100%)\n overallPercent = this.stageProgress.receiving;\n }\n\n // Ensure progress only increases (monotonic progress)\n overallPercent = Math.max(overallPercent, this.lastOverallPercent);\n this.lastOverallPercent = overallPercent;\n\n return {\n percent: overallPercent,\n message: output.trim(),\n };\n }\n}\n\n/**\n * Clone repository options\n */\nexport interface CloneRepositoryOptions {\n url: string;\n destination: string;\n onProgress?: (progress: GitCloneProgress) => void;\n signal?: AbortSignal;\n timeoutMinutes?: number;\n}\n\n/**\n * Clone repository result\n */\nexport interface CloneRepositoryResult {\n success: boolean;\n clonePath?: string;\n repoName?: string;\n error?: string;\n errorCode?:\n | 'CANCELLED'\n | 'SSH_AUTH_FAILED'\n | 'AUTH_REQUIRED'\n | 'NETWORK_ERROR'\n | 'REPO_NOT_FOUND'\n | 'TIMEOUT'\n | 'GIT_NOT_INSTALLED'\n | 'INVALID_URL'\n | 'DIR_EXISTS'\n | 'UNKNOWN';\n needsCredentials?: boolean;\n}\n\n/**\n * Clone a git repository\n */\nexport async function cloneRepository(\n options: CloneRepositoryOptions,\n): Promise<CloneRepositoryResult> {\n const { promisify } = await import('util');\n const { spawn, execFile } = await import('child_process');\n const { existsSync, mkdirSync, rmSync } = await import('fs');\n const { join, resolve } = await import('pathe');\n\n let clonePath = '';\n\n try {\n // Validate inputs\n if (!options.url || !options.destination) {\n return {\n success: false,\n error: 'Git URL and destination are required',\n };\n }\n\n // Sanitize Git URL\n const sanitizedUrl = sanitizeGitUrl(options.url);\n\n // Check if Git is available\n try {\n const execFilePromise = promisify(execFile);\n await execFilePromise('git', ['--version']);\n } catch (_gitError) {\n return {\n success: false,\n error:\n 'Git is not installed or not available in PATH. Please install Git and try again.',\n errorCode: 'GIT_NOT_INSTALLED',\n };\n }\n\n // Validate URL format\n if (!validateGitUrl(sanitizedUrl)) {\n return {\n success: false,\n error:\n 'Invalid Git repository URL format. Please use HTTPS or SSH format.',\n errorCode: 'INVALID_URL',\n };\n }\n\n // Ensure destination directory exists\n if (!existsSync(options.destination)) {\n mkdirSync(options.destination, { recursive: true });\n }\n\n // Validate destination path security\n const destValidation = validateDestinationPath(options.destination);\n if (!destValidation.valid) {\n return {\n success: false,\n error: destValidation.error,\n };\n }\n\n // Extract repo name and build clone path\n const repoName = extractRepoName(sanitizedUrl);\n clonePath = join(options.destination, repoName);\n\n // Check if directory already exists\n if (existsSync(clonePath)) {\n return {\n success: false,\n error: `Directory '${repoName}' already exists at destination`,\n errorCode: 'DIR_EXISTS',\n };\n }\n\n // Clone the repository\n let gitProcess: ReturnType<typeof spawn> | null = null;\n let isCancelled = false;\n const progressParser = new GitCloneProgressParser();\n\n const clonePromise = new Promise<void>((resolvePromise, reject) => {\n const env: Record<string, string> = {\n ...process.env,\n GIT_SSH_COMMAND: 'ssh -o StrictHostKeyChecking=accept-new',\n };\n\n gitProcess = spawn(\n 'git',\n ['clone', '--progress', sanitizedUrl, clonePath],\n { env },\n );\n let stderr = '';\n\n // Set up abort handling\n if (options.signal) {\n const abortHandler = async () => {\n isCancelled = true;\n if (gitProcess && !gitProcess.killed) {\n // Clean up event listeners first\n gitProcess.stdout?.removeAllListeners();\n gitProcess.stderr?.removeAllListeners();\n gitProcess.removeAllListeners();\n\n // Try graceful shutdown first (SIGTERM)\n gitProcess.kill('SIGTERM');\n\n // Wait for process to exit, force kill if timeout\n await new Promise<void>((resolve) => {\n const forceKillTimeout = setTimeout(() => {\n if (gitProcess && !gitProcess.killed) {\n gitProcess.kill('SIGKILL');\n }\n resolve();\n }, 1000);\n\n // Clear timeout if process exits gracefully\n if (gitProcess) {\n gitProcess.once('exit', () => {\n clearTimeout(forceKillTimeout);\n resolve();\n });\n } else {\n clearTimeout(forceKillTimeout);\n resolve();\n }\n });\n }\n reject(new Error('Clone operation cancelled by user'));\n };\n\n options.signal.addEventListener('abort', abortHandler);\n }\n\n // Parse progress from stderr\n gitProcess.stderr?.on('data', (data: Buffer) => {\n const output = data.toString();\n stderr += output;\n\n if (options.onProgress) {\n const progress = progressParser.parse(output);\n if (progress) {\n options.onProgress(progress);\n }\n }\n });\n\n gitProcess.on('error', (error) => {\n reject(error);\n });\n\n gitProcess.on('close', (code) => {\n // Don't reject again if already cancelled\n if (isCancelled) {\n return;\n }\n\n if (code === 0) {\n // Send 100% progress on completion\n if (options.onProgress) {\n options.onProgress({\n percent: 100,\n message: 'Clone completed',\n });\n }\n resolvePromise();\n } else {\n reject(new Error(stderr || `Git clone exited with code ${code}`));\n }\n });\n });\n\n // Add timeout\n const timeoutMinutes = options.timeoutMinutes || 30;\n const CLONE_TIMEOUT = timeoutMinutes * 60 * 1000;\n let timeoutId: NodeJS.Timeout | null = null;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(async () => {\n if (gitProcess) {\n // Clean up event listeners first\n gitProcess.stdout?.removeAllListeners();\n gitProcess.stderr?.removeAllListeners();\n gitProcess.removeAllListeners();\n\n // Try graceful shutdown first (SIGTERM)\n gitProcess.kill('SIGTERM');\n\n // Wait for process to exit, force kill if timeout\n await new Promise<void>((resolve) => {\n const forceKillTimeout = setTimeout(() => {\n if (gitProcess && !gitProcess.killed) {\n gitProcess.kill('SIGKILL');\n }\n resolve();\n }, 1000);\n\n // Clear timeout if process exits gracefully\n if (gitProcess) {\n gitProcess.once('exit', () => {\n clearTimeout(forceKillTimeout);\n resolve();\n });\n } else {\n clearTimeout(forceKillTimeout);\n resolve();\n }\n });\n }\n reject(\n new Error(\n 'Clone operation timed out. The repository might be too large or the connection is slow.',\n ),\n );\n }, CLONE_TIMEOUT);\n });\n\n try {\n await Promise.race([clonePromise, timeoutPromise]);\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n\n return {\n success: true,\n clonePath,\n repoName,\n };\n } catch (error: any) {\n // Clean up incomplete clone directory\n if (clonePath && existsSync(clonePath)) {\n try {\n rmSync(clonePath, { recursive: true, force: true });\n } catch (_cleanupError) {\n // Ignore cleanup errors\n }\n }\n\n // Handle common git clone errors\n const errorMessage = error.message || 'Unknown error';\n\n // SSH-related errors\n if (\n errorMessage.includes('Host key verification failed') ||\n errorMessage.includes('Permission denied (publickey)')\n ) {\n return {\n success: false,\n error:\n 'SSH authentication failed. Please ensure your SSH keys are properly configured.',\n errorCode: 'SSH_AUTH_FAILED',\n };\n }\n\n // HTTPS authentication errors\n if (\n errorMessage.includes('Authentication failed') ||\n errorMessage.includes('could not read Username') ||\n errorMessage.includes('could not read Password')\n ) {\n return {\n success: false,\n error: 'Authentication required. Please provide username and password.',\n errorCode: 'AUTH_REQUIRED',\n needsCredentials: true,\n };\n }\n\n if (errorMessage.includes('Could not resolve hostname')) {\n return {\n success: false,\n error:\n 'Could not resolve hostname. Please check your internet connection and the repository URL.',\n errorCode: 'NETWORK_ERROR',\n };\n }\n\n if (errorMessage.includes('not found') || errorMessage.includes('404')) {\n return {\n success: false,\n error: 'Repository not found or access denied',\n errorCode: 'REPO_NOT_FOUND',\n };\n }\n\n // Timeout errors\n if (errorMessage.includes('timed out')) {\n return {\n success: false,\n error:\n 'Clone operation timed out. The repository might be too large or the connection is slow.',\n errorCode: 'TIMEOUT',\n };\n }\n\n // User cancelled\n if (errorMessage.includes('cancelled by user')) {\n return {\n success: false,\n error: 'Clone operation cancelled by user',\n errorCode: 'CANCELLED',\n };\n }\n\n return {\n success: false,\n error: 'Failed to clone repository. Please check the URL and try again.',\n errorCode: 'UNKNOWN',\n };\n }\n}\n\n/**\n * Get the staged diff while handling large files\n * - Excludes common lockfiles and large file types\n * - Limits diff size to prevent context overflow\n */\nexport async function getStagedDiff(cwd: string): Promise<string> {\n // Exclude lockfiles and common large file types\n const excludePatterns = [\n ':!pnpm-lock.yaml',\n ':!package-lock.json',\n ':!yarn.lock',\n ':!*.min.js',\n ':!*.bundle.js',\n ':!dist/**',\n ':!build/**',\n ':!*.gz',\n ':!*.zip',\n ':!*.tar',\n ':!*.tgz',\n ':!*.woff',\n ':!*.woff2',\n ':!*.ttf',\n ':!*.png',\n ':!*.jpg',\n ':!*.jpeg',\n ':!*.gif',\n ':!*.ico',\n ':!*.svg',\n ':!*.pdf',\n ];\n\n const args = ['diff', '--cached', '--', ...excludePatterns];\n\n const { code, stdout: diff, stderr } = await gitExec(cwd, args);\n\n if (code !== 0) {\n const errorMessage = stderr || 'Unknown error';\n\n if (errorMessage.includes('bad revision')) {\n throw new Error(\n 'Failed to get staged diff: Invalid Git revision or corrupt repository',\n );\n }\n\n if (errorMessage.includes('fatal: not a git repository')) {\n throw new Error('Not a Git repository');\n }\n\n throw new Error(`Failed to get staged diff: ${errorMessage}`);\n }\n\n // Limit diff size - 100KB is a reasonable limit for most LLM contexts\n const MAX_DIFF_SIZE = 100 * 1024; // 100KB\n\n if (diff.length > MAX_DIFF_SIZE) {\n // If diff is too large, truncate and add a note\n const truncatedDiff = diff.substring(0, MAX_DIFF_SIZE);\n return (\n truncatedDiff +\n '\\n\\n[Diff truncated due to size. Total diff size: ' +\n (diff.length / 1024).toFixed(2) +\n 'KB]'\n );\n }\n return diff;\n}\n","import fs from 'fs';\nimport { homedir } from 'os';\nimport path from 'pathe';\n\nconst PROJECT_MARKERS = [\n 'package.json',\n 'Cargo.toml',\n 'pyproject.toml',\n 'go.mod',\n 'composer.json',\n 'pom.xml',\n 'build.gradle',\n 'requirements.txt',\n 'Gemfile',\n 'mix.exs',\n 'deno.json',\n 'deno.jsonc',\n];\n\nexport function isProjectDirectory(cwd: string): boolean {\n const normalizedCwd = path.resolve(cwd);\n const homeDir = path.resolve(homedir());\n\n if (normalizedCwd === homeDir) {\n return false;\n }\n\n return PROJECT_MARKERS.some((marker) => {\n const markerPath = path.join(normalizedCwd, marker);\n return fs.existsSync(markerPath);\n });\n}\n","import type { LoopResult } from '../core/loop';\nimport type { SDKResultMessage, SDKSystemMessage } from '../core/message';\nimport type { ModelInfo } from '../core/model';\nimport type { Tool } from '../tools/tool';\n\ntype Format = 'text' | 'stream-json' | 'json';\n\ntype OutputFormatOpts = {\n format: Format;\n quiet: boolean;\n};\n\nexport class OutputFormat {\n format: Format;\n quiet: boolean;\n dataArr: any[];\n constructor(opts: OutputFormatOpts) {\n this.format = opts.format;\n this.quiet = opts.quiet;\n this.dataArr = [];\n }\n onInit(opts: {\n text: string;\n sessionId: string;\n cwd: string;\n tools: Tool[];\n model: ModelInfo;\n }) {\n if (!this.quiet) {\n return;\n }\n const model = `${opts.model.provider.id}/${opts.model.model.id}`;\n const data: SDKSystemMessage = {\n type: 'system',\n subtype: 'init',\n sessionId: opts.sessionId,\n model,\n cwd: opts.cwd,\n tools: opts.tools.map((tool) => tool.name),\n };\n if (this.format === 'stream-json') {\n console.log(JSON.stringify(data));\n } else if (this.format === 'json') {\n this.dataArr.push(data);\n }\n }\n onMessage(opts: { message: any }) {\n if (!this.quiet) {\n return;\n }\n const data = { ...opts.message };\n if (this.format === 'stream-json') {\n console.log(JSON.stringify(data));\n } else if (this.format === 'json') {\n this.dataArr.push(data);\n }\n }\n onEnd(opts: { result: LoopResult; sessionId: string }) {\n if (!this.quiet) {\n return;\n }\n const isError = !opts.result.success;\n const subtype = isError ? 'error' : 'success';\n const data: SDKResultMessage = {\n type: 'result',\n subtype,\n isError,\n content: opts.result.success\n ? opts.result.data.text\n : opts.result.error.message,\n sessionId: opts.sessionId,\n ...(isError ? { __result: opts.result } : {}),\n };\n if (opts.result.success) {\n data.usage = {\n input_tokens: opts.result.data.usage.promptTokens,\n output_tokens: opts.result.data.usage.completionTokens,\n };\n }\n if (this.format === 'stream-json') {\n console.log(JSON.stringify(data));\n } else if (this.format === 'json') {\n this.dataArr.push(data);\n console.log(JSON.stringify(this.dataArr));\n } else if (this.format === 'text') {\n console.log(\n opts.result.success\n ? opts.result.data?.text || ''\n : opts.result.error.message,\n );\n }\n }\n}\n","import assert from 'assert';\nimport fs from 'fs';\nimport { glob } from 'glob';\nimport path from 'pathe';\nimport type { Context } from '../core/context';\nimport {\n defaultOutputStyle,\n getBuiltinOutputStyles,\n} from './output-style/builtin';\nimport type { Paths } from './paths';\nimport { PluginHookType } from '../core/plugin';\nimport { safeFrontMatter } from '../utils/safeFrontMatter';\nimport { kebabToTitleCase } from '../utils/string';\n\nexport type OutputStyleOpts = {\n name: string;\n description: string;\n isCodingRelated: boolean;\n prompt: string;\n};\n\nexport class OutputStyle {\n name: string;\n description: string;\n isCodingRelated: boolean;\n prompt: string;\n\n constructor(opts: OutputStyleOpts) {\n this.name = opts.name;\n this.description = opts.description;\n this.isCodingRelated = opts.isCodingRelated;\n this.prompt = opts.prompt;\n }\n\n isDefault(): boolean {\n return this.name === 'Default';\n }\n}\n\nexport type OutputStyleManagerOpts = {\n paths: Paths;\n outputStyles: OutputStyle[];\n};\n\nexport class OutputStyleManager {\n outputStyles: OutputStyle[] = [];\n constructor(opts: OutputStyleManagerOpts) {\n this.outputStyles = [...this.load(opts.paths), ...opts.outputStyles];\n }\n\n static async create(context: Context) {\n const outputStyles = await context.apply({\n hook: 'outputStyle',\n args: [],\n memo: [],\n type: PluginHookType.SeriesMerge,\n });\n return new OutputStyleManager({\n paths: context.paths,\n outputStyles,\n });\n }\n\n load(paths: Paths): OutputStyle[] {\n const builtin = getBuiltinOutputStyles().map((item) => {\n return new OutputStyle({\n name: item.name,\n description: item.description,\n isCodingRelated: item.isCodingRelated,\n prompt: item.prompt,\n });\n });\n const global = this.loadGlobal(\n path.join(paths.globalConfigDir, 'output-styles'),\n );\n const project = this.loadProject(\n path.join(paths.projectConfigDir, 'output-styles'),\n );\n return [...builtin, ...global, ...project];\n }\n\n loadGlobal(globalConfigDir: string): OutputStyle[] {\n return loadPolishedMarkdownFiles(globalConfigDir).map((file) => {\n return new OutputStyle({\n name: file.name,\n description: `${file.description} (user)`,\n isCodingRelated: !!file.attributes.isCodingRelated,\n prompt: file.body,\n });\n });\n }\n\n loadProject(projectConfigDir: string): OutputStyle[] {\n return loadPolishedMarkdownFiles(projectConfigDir).map((file) => {\n return new OutputStyle({\n name: file.name,\n description: `${file.description} (project)`,\n isCodingRelated: !!file.attributes.isCodingRelated,\n prompt: file.body,\n });\n });\n }\n\n // name support\n // 1) name of builtin and plugin extended output styles\n // 2) path to a file which defines an output style with markdown with frontmatter\n // 3) url to a file which defines an output style with markdown with frontmatter (TODO: support)\n getOutputStyle(name: string | undefined, cwd: string): OutputStyle {\n const defaultOutputStyle = this.getDefaultOutputStyle();\n if (!name) {\n return defaultOutputStyle;\n }\n // Check if name is a file path\n if (path.isAbsolute(name) || name.startsWith('.')) {\n if (!name.endsWith('.md')) {\n throw new Error('Output style file must be a .md file');\n }\n let filePath = name;\n if (!path.isAbsolute(name)) {\n filePath = path.resolve(cwd, name);\n // Validate against path traversal attacks\n if (!filePath.startsWith(path.resolve(cwd))) {\n throw new Error('Path traversal not allowed');\n }\n }\n const file = loadPolishedMarkdownFile(filePath);\n return new OutputStyle({\n name: file.name,\n description: file.description,\n isCodingRelated: !!file.attributes.isCodingRelated,\n prompt: file.body,\n });\n } else if (name.startsWith('{') && name.endsWith('}')) {\n let json = null;\n try {\n json = JSON.parse(name);\n } catch (error) {\n throw new Error(\n `Invalid JSON output style: ${error instanceof Error ? error.message : String(error)}, original: ${name}`,\n );\n }\n assert(json.prompt, 'prompt is required');\n return new OutputStyle({\n name: json.name || 'Custom',\n description: json.description || 'Custom',\n isCodingRelated: json.isCodingRelated,\n prompt: json.prompt,\n });\n } else if (name) {\n const outputStyle = this.outputStyles.find(\n (style) => style.name === name,\n );\n assert(outputStyle, `Output style ${name} not found`);\n return outputStyle;\n } else {\n return defaultOutputStyle;\n }\n }\n\n getDefaultOutputStyle(): OutputStyle {\n return new OutputStyle({\n name: defaultOutputStyle.name,\n description: defaultOutputStyle.description,\n isCodingRelated: defaultOutputStyle.isCodingRelated,\n prompt: defaultOutputStyle.prompt,\n });\n }\n}\n\ntype MarkdownFile = {\n path: string;\n attributes: Record<string, string>;\n body: string;\n};\n\nexport type NormalizedMarkdownFile = MarkdownFile & {\n description: string;\n name: string;\n relativePath: string;\n};\n\nexport function loadPolishedMarkdownFiles(\n dir: string,\n): NormalizedMarkdownFile[] {\n if (!fs.existsSync(dir)) {\n return [];\n }\n const files = glob.sync('**/*.md', {\n cwd: dir,\n follow: true,\n });\n return files.map((relativePath) => {\n const absPath = path.join(dir, relativePath);\n return loadPolishedMarkdownFile(absPath, dir);\n });\n}\n\nexport function loadMarkdownFile(filePath: string): MarkdownFile {\n const content = fs.readFileSync(filePath, 'utf-8');\n const { attributes, body } = safeFrontMatter<Record<string, string>>(\n content,\n filePath,\n );\n return {\n path: filePath,\n attributes,\n body,\n };\n}\n\nfunction loadPolishedMarkdownFile(\n filePath: string,\n dir?: string,\n): NormalizedMarkdownFile {\n if (!fs.existsSync(filePath)) {\n throw new Error(`Output style file not found: ${filePath}`);\n }\n\n let name = path.basename(filePath, '.md');\n const file = loadMarkdownFile(filePath);\n if (dir) {\n const relativePath = path.relative(dir, filePath);\n // Extract command name from relative path (remove .md extension and convert / to :)\n name = relativePath.replace(/\\.md$/, '').replace(/[/\\\\]/g, ':');\n }\n let description = file.attributes.description?.trim();\n if (!description) {\n const lines = (file.body || '').split('\\n');\n const firstLine = lines.find((line) => line.trim())?.trim();\n if (firstLine) {\n // Handle title lines starting with # (supports multiple #)\n if (firstLine.startsWith('#')) {\n // Remove all # symbols and clean up\n description = firstLine.replace(/^#+\\s*/, '').trim();\n } else {\n // Use directly for any other starting character (including ```, ##, *, -, etc.)\n description = firstLine;\n }\n\n // Limit length to 50 characters, truncate and add ellipsis if exceeds\n if (description.length > 50) {\n description = `${description.substring(0, 50)}...`;\n }\n }\n }\n if (!description) {\n description = kebabToTitleCase(name);\n }\n return {\n ...file,\n relativePath: filePath,\n name,\n description,\n };\n}\n","import { DEFAULT_OUTPUT_STYLE_NAME } from '../../constants';\nimport type { OutputStyle } from '../types';\n\nexport const defaultOutputStyle: OutputStyle = {\n name: DEFAULT_OUTPUT_STYLE_NAME,\n description: 'Default output style',\n isCodingRelated: true,\n prompt: '',\n};\n","import type { OutputStyle } from '../types';\n\nexport const explanatoryOutputStyle: OutputStyle = {\n name: 'Explanatory',\n description: 'Explains its implementation choices and codebase patterns',\n isCodingRelated: true,\n prompt: `\nYou are an interactive CLI tool that helps users with software engineering tasks. In addition to software engineering tasks, you should provide educational insights about the codebase along the way.\n\nYou should be clear and educational, providing helpful explanations while remaining focused on the task. Balance educational content with task completion. When providing insights, you may exceed typical length constraints, but remain focused and relevant.\n\n# Explanatory Style Active\n\n## Insights\nIn order to encourage learning, before and after writing code, always provide brief educational explanations about implementation choices using (with backticks):\n\"\\`★ Insight ─────────────────────────────────────\\`\n[2-3 key educational points]\n\\`─────────────────────────────────────────────────\\`\"\n\nThese insights should be included in the conversation, not in the codebase. You should generally focus on interesting insights that are specific to the codebase or the code you just wrote, rather than general programming concepts.\n `.trim(),\n};\n","import type { OutputStyle } from '../types';\n\nexport const miaoOutputStyle: OutputStyle = {\n name: 'Miao',\n description:\n 'Limited time - Adds \"miao~~~\" after every sentence for a cute cat-like style',\n isCodingRelated: true,\n prompt: `\nYou are an interactive CLI tool that helps users with software engineering tasks, but with a cute cat-like personality.\n\n# Miao Style Active\n\nYou should add \"miao~~~\" after every sentence. A sentence is typically defined as text ending with a period (.), exclamation mark (!), or question mark (?). Apply this consistently throughout your responses.\n\nExamples:\n- \"I'll help you with that miao~~~\"\n- \"Let me check the file first miao~~~\"\n- \"The function works correctly miao~~~\"\n\nKeep your technical accuracy and helpfulness while adding this cute touch to make interactions more fun and engaging.\n `.trim(),\n};\n","import type { OutputStyle } from '../types';\n\nexport const minimalOutputStyle: OutputStyle = {\n name: 'Minimal',\n description: 'Simple and concise for non-coding tasks',\n isCodingRelated: false,\n prompt: `You are a helpful assistant. Be concise and direct. Answer questions clearly without unnecessary elaboration.`,\n};\n","import type { OutputStyle } from '../types';\nimport { defaultOutputStyle } from './default';\nimport { explanatoryOutputStyle } from './explanatory';\nimport { miaoOutputStyle } from './miao';\nimport { minimalOutputStyle } from './minimal';\n\nexport * from './default';\nexport * from './explanatory';\nexport * from './miao';\nexport * from './minimal';\n\nexport function getBuiltinOutputStyles(): OutputStyle[] {\n return [\n defaultOutputStyle,\n explanatoryOutputStyle,\n miaoOutputStyle,\n minimalOutputStyle,\n ];\n}\n","/**\n * Converts a kebab-case string to Title Case.\n * Examples:\n * - \"foo-bar\" → \"Foo Bar\"\n * - \"review\" → \"Review\"\n * - \"multi-word-command\" → \"Multi Word Command\"\n */\nexport function kebabToTitleCase(kebabString: string): string {\n return kebabString\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n}\n","export function generatePlanSystemPrompt(opts: {\n todo: boolean;\n productName: string;\n language?: string;\n}) {\n return `\nYou are an interactive CLI tool that helps users with software engineering tasks. Plan mode is active, which means you should analyze the user's request and create a detailed execution plan before taking any actions.\n\nIMPORTANT: RETURN THE PLAN ONLY.\n\n# Plan Mode Guidelines\n\nYou MUST NOT execute any system-modifying actions. This includes:\n- Making file edits (edit, write, multiedit tools)\n- Running bash commands or scripts\n- Changing configurations or making commits\n- Any tool that modifies system state\n\nYou MAY use read-only tools for research:\n- read, glob, grep, ls tools for codebase analysis\n- Understanding existing patterns and conventions\n- Gathering information needed for planning\n\n# Planning Methodology\n\n1. **Analyze the Request**: Break down what the user wants to accomplish\n2. **Research Context**: Use read-only tools to understand the current codebase\n3. **Design Approach**: Consider existing patterns, dependencies, and best practices\n4. **Create Structured Plan**: Provide clear, actionable steps with specific details\n\n# Plan Quality Standards\n\nYour plan should be:\n- **Specific**: Include exact file paths, function names, and implementation details\n- **Actionable**: Each step should be clear and executable\n- **Complete**: Cover all aspects from implementation to testing\n- **Informed**: Based on actual codebase analysis, not assumptions\n- **Ordered**: Steps should follow logical dependencies\n\n# Communication Style\n\nBe concise and direct. Focus on the technical plan rather than explanations. Use the same professional tone as other agents in this codebase.\n\n${opts.language === 'English' ? '' : `IMPORTANT: Answer in ${opts.language}.`}\n`.trim();\n}\n","import { AGENT_TYPE, TOOL_NAMES } from './constants';\nimport type { OutputStyle } from './outputStyle';\n\nfunction getTasksPrompt(opts: { todo: boolean; productName: string }) {\n if (!opts.todo) {\n return '';\n }\n const productName = opts.productName;\n return `\n# Task Management\nYou have access to the ${TOOL_NAMES.TODO_WRITE} tool to help you manage and plan tasks. Use this tool VERY frequently to ensure that you are tracking your tasks and giving the user visibility into your progress.\nThese tools are also EXTREMELY helpful for planning tasks, and for breaking down larger complex tasks into smaller steps. If you do not use this tool when planning, you may forget to do important tasks - and that is unacceptable.\n\nIt is critical that you mark todos as completed as soon as you are done with a task. Do not batch up multiple tasks before marking them as completed.\n\nExamples:\n\n<example>\nuser: Run the build and fix any type errors\nassistant: I'm going to use the ${TOOL_NAMES.TODO_WRITE} tool to write the following items to the todo list:\n- Run the build\n- Fix any type errors\n\nI'm now going to run the build using ${TOOL_NAMES.BASH}.\n\nLooks like I found 10 type errors. I'm going to use the ${TOOL_NAMES.TODO_WRITE} tool to write 10 items to the todo list.\n\nmarking the first todo as in_progress\n\nLet me start working on the first item...\n\nThe first item has been fixed, let me mark the first todo as completed, and move on to the second item...\n\n</example>\nIn the above example, the assistant completes all the tasks, including the 10 error fixes and running the build and fixing all errors.\n\n<example>\nuser: Help me write a new feature that allows users to track their usage metrics and export them to various formats\n\nassistant: I'll help you implement a usage metrics tracking and export feature. Let me first use the ${TOOL_NAMES.TODO_WRITE} tool to plan this task.\nAdding the following todos to the todo list:\n1. Research existing metrics tracking in the codebase\n2. Design the metrics collection system\n3. Implement core metrics tracking functionality\n4. Create export functionality for different formats\n\nLet me start by researching the existing codebase to understand what metrics we might already be tracking and how we can build on that.\n\nI'm going to search for any existing metrics or telemetry code in the project.\n\nI've found some existing telemetry code. Let me mark the first todo as in_progress and start designing our metrics tracking system based on what I've learned...\n\n[Assistant continues implementing the feature step by step, marking todos as in_progress and completed as they go]\n</example>\n\n# Doing tasks\nThe user will primarily request you perform software engineering tasks. This includes solving bugs, adding new functionality, refactoring code, explaining code, and more. For these tasks the following steps are recommended:\n- Use the ${TOOL_NAMES.TODO_WRITE} tool to plan the task if required\n- Use the available search tools to understand the codebase and the user's query. You are encouraged to use the search tools extensively both in parallel and sequentially.\n- Implement the solution using all tools available to you\n- Verify the solution if possible with tests. NEVER assume specific test framework or test script. Check the README or search codebase to determine the testing approach.\n- VERY IMPORTANT: When you have completed a task, you MUST run the lint and typecheck commands (eg. npm run lint, npm run typecheck, ruff, etc.) with ${TOOL_NAMES.BASH} if they were provided to you to ensure your code is correct. If you are unable to find the correct command, ask the user for the command to run and if they supply it, proactively suggest writing it to ${productName}.md so that you will know to run it next time.\nNEVER commit changes unless the user explicitly asks you to. It is VERY IMPORTANT to only commit when explicitly asked, otherwise the user will feel that you are being too proactive.\n\nIMPORTANT: Always use the ${TOOL_NAMES.TODO_WRITE} tool to plan and track tasks throughout the conversation.\n `;\n}\n\nfunction getToolUsagePolicyPrompt(task: boolean) {\n const taskPolicy = task\n ? `\n- When doing file search, prefer to use the ${TOOL_NAMES.TASK} tool in order to reduce context usage.\n- You should proactively use the ${TOOL_NAMES.TASK} tool with specialized agents when the task at hand matches the agent's description.\n- If the user specifies that they want you to run tools \"in parallel\", you MUST send a single message with multiple tool use content blocks. For example, if you need to launch multiple agents in parallel, send a single message with multiple ${TOOL_NAMES.TASK} tool calls.\n- VERY IMPORTANT: When exploring the codebase to gather context or to answer a question that is not a needle query for a specific file/class/function, it is CRITICAL that you use the ${TOOL_NAMES.TASK} tool with subagent_type=${AGENT_TYPE.EXPLORE} instead of running search commands directly.\n<example>\nuser: Where are errors from the client handled?\nassistant: [Uses the ${TOOL_NAMES.TASK} tool with subagent_type=${AGENT_TYPE.EXPLORE} to find the files that handle client errors instead of using ${TOOL_NAMES.GLOB} or ${TOOL_NAMES.GREP} directly]\n</example>\n<example>\nuser: What is the codebase structure?\nassistant: [Uses the ${TOOL_NAMES.TASK} tool with subagent_type=${AGENT_TYPE.EXPLORE}]\n</example>`\n : '';\n\n return `\n# Tool usage policy${taskPolicy}\n- When fetch returns a message about a redirect to a different host, you should immediately make a new fetch request with the redirect URL provided in the response.\n- You can call multiple tools in a single response. If you intend to call multiple tools and there are no dependencies between them, make all independent tool calls in parallel. Maximize use of parallel tool calls where possible to increase efficiency. However, if some tool calls depend on previous calls to inform dependent values, do NOT call these tools in parallel and instead call them sequentially. For instance, if one operation must complete before another starts, run these operations sequentially instead. Never use placeholders or guess missing parameters in tool calls.\n- Use specialized tools instead of bash commands when possible, as this provides a better user experience. For file operations, use dedicated tools: ${TOOL_NAMES.READ} for reading files instead of cat/head/tail, ${TOOL_NAMES.EDIT} for editing instead of sed/awk, and ${TOOL_NAMES.WRITE} for creating files instead of cat with heredoc or echo redirection. Reserve bash tools exclusively for actual system commands and terminal operations that require shell execution. NEVER use bash echo or other command-line tools to communicate thoughts, explanations, or instructions to the user. Output all communication directly in your response text instead.\n `;\n}\n\nexport function generateSystemPrompt(opts: {\n todo: boolean;\n productName: string;\n language?: string;\n appendSystemPrompt?: string;\n outputStyle: OutputStyle;\n task?: boolean;\n}) {\n const { outputStyle } = opts;\n const isDefaultOutputStyle = outputStyle.isDefault();\n return `\nYou are an interactive CLI tool that helps users ${isDefaultOutputStyle ? 'with software engineering tasks.' : `according to your \"Output Style\" below, which describes how you should respond to user queries.`} Use the instructions below and the tools available to you to assist the user.\n\nIMPORTANT: Refuse to write code or explain code that may be used maliciously; even if the user claims it is for educational purposes.\n${\n opts.language === 'English'\n ? ''\n : `IMPORTANT: Answer in ${opts.language}.\n`\n}\n\n${\n !isDefaultOutputStyle\n ? `\n# Output style: ${outputStyle.name}\n${outputStyle.prompt}\n `\n : `\n# Tone and style\nYou should be concise, direct, and to the point. When you run a non-trivial bash command, you should explain what the command does and why you are running it.\nOutput text to communicate with the user; all text you output outside of tool use is displayed to the user. Only use tools to complete tasks. Never use tools like \\`bash\\` to communicate with the user during the session.\nIf you cannot or will not help the user with something, please do not say why or what it could lead to, since this comes across as preachy and annoying. Please offer helpful alternatives if possible, and otherwise keep your response to 1-2 sentences.\nOnly use emojis if the user explicitly requests it. Avoid using emojis in all communication unless asked.\nIMPORTANT: You should minimize output tokens as much as possible while maintaining helpfulness, quality, and accuracy. Only address the specific query or task at hand, avoiding tangential information unless absolutely critical for completing the request. If you can answer in 1-3 sentences or a short paragraph, please do.\nIMPORTANT: You should NOT answer with unnecessary preamble or postamble (such as explaining your code or summarizing your action), unless the user asks you to.\nIMPORTANT: Keep your responses short, since they will be displayed on a command line interface. You MUST answer concisely with fewer than 4 lines (not including tool use or code generation), unless user asks for detail. Answer the user's question directly, without elaboration, explanation, or details. One word answers are best. Avoid introductions, conclusions, and explanations. You MUST avoid text before/after your response, such as \"The answer is <answer>.\", \"Here is the content of the file...\" or \"Based on the information provided, the answer is...\" or \"Here is what I will do next...\". Here are some examples to demonstrate appropriate verbosity:\n<example>\nuser: 2 + 2\nassistant: 4\n</example>\n<example>\nuser: is 11 a prime number?\nassistant: Yes\n</example>\n<example>\nuser: what command should I run to list files in the current directory?\nassistant: ls\n</example>\n<example>\nuser: what files are in the directory src/?\nassistant: [runs ls and sees foo.c, bar.c, baz.c]\nuser: which file contains the implementation of foo?\nassistant: src/foo.c\n</example>\n<example>\nuser: write tests for new feature\nassistant: [uses grep and glob tools to find where similar tests are defined, uses concurrent read file tool use blocks in one tool call to read relevant files at the same time, uses edit file tool to write new tests]\n</example>\n `\n}\n\n# Following conventions\nWhen making changes to files, first understand the file's code conventions. Mimic code style, use existing libraries and utilities, and follow existing patterns.\n- NEVER assume that a given library is available, even if it is well known. Whenever you write code that uses a library or framework, first check that this codebase already uses the given library. For example, you might look at neighboring files, or check the package.json (or cargo.toml, and so on depending on the language).\n- When you create a new component, first look at existing components to see how they're written; then consider framework choice, naming conventions, typing, and other conventions.\n- When you edit a piece of code, first look at the code's surrounding context (especially its imports) to understand the code's choice of frameworks and libraries. Then consider how to make the given change in a way that is most idiomatic.\n- Always follow security best practices. Never introduce code that exposes or logs secrets and keys. Never commit secrets or keys to the repository.\n\n${\n outputStyle.isCodingRelated\n ? `\n# Code style\n- IMPORTANT: DO NOT ADD ***ANY*** COMMENTS unless asked\n\n${getTasksPrompt(opts)}`\n : ''\n}\n\n${getToolUsagePolicyPrompt(opts.task ?? false)}\n\n${opts.appendSystemPrompt ? opts.appendSystemPrompt : ''}\n`.trim();\n}\n","import { TOOL_NAMES } from './constants';\nimport type { Context } from './context';\nimport { JsonlLogger, RequestLogger } from './jsonl';\nimport { LlmsContext } from './llmsContext';\nimport { runLoop, type StreamResult, type ThinkingConfig } from './loop';\nimport type { ImagePart, NormalizedMessage, UserContent } from './message';\nimport { resolveModelWithContext } from './model';\nimport { OutputFormat } from './outputFormat';\nimport { OutputStyleManager } from './outputStyle';\nimport { generatePlanSystemPrompt } from './planSystemPrompt';\nimport { PluginHookType } from './plugin';\nimport { Session, SessionConfigManager, type SessionId } from '../session/session';\nimport { generateSystemPrompt } from './systemPrompt';\nimport type {\n ApprovalCategory,\n Tool,\n ToolApprovalResult,\n ToolUse,\n} from '../tools/tool';\nimport { resolveTools, Tools } from '../tools/tool';\nimport { Usage } from './usage';\nimport { randomUUID } from '../utils/randomUUID';\n\nexport class Project {\n session: Session;\n context: Context;\n // For subagent to inherit parent session config\n parentSessionId?: string;\n constructor(opts: {\n sessionId?: SessionId;\n parentSessionId?: string;\n context: Context;\n }) {\n this.session = opts.sessionId\n ? Session.resume({\n id: opts.sessionId,\n logPath: opts.context.paths.getSessionLogPath(opts.sessionId),\n })\n : Session.create();\n this.context = opts.context;\n this.parentSessionId = opts.parentSessionId;\n }\n\n async send(\n message: string | null,\n opts: {\n model?: string;\n onMessage?: (opts: { message: NormalizedMessage }) => Promise<void>;\n onToolApprove?: (opts: {\n toolUse: ToolUse;\n }) => Promise<boolean | ToolApprovalResult>;\n onTextDelta?: (text: string) => Promise<void>;\n onChunk?: (chunk: any, requestId: string) => Promise<void>;\n onStreamResult?: (result: StreamResult) => Promise<void>;\n signal?: AbortSignal;\n attachments?: ImagePart[];\n parentUuid?: string;\n thinking?: ThinkingConfig;\n } = {},\n ) {\n let tools = await resolveTools({\n context: this.context,\n sessionId: this.session.id,\n write: true,\n todo: true,\n askUserQuestion: !this.context.config.quiet,\n signal: opts.signal,\n task: true,\n });\n tools = await this.context.apply({\n hook: 'tool',\n args: [{ sessionId: this.session.id }],\n memo: tools,\n type: PluginHookType.SeriesMerge,\n });\n const outputStyleManager = await OutputStyleManager.create(this.context);\n const outputStyle = outputStyleManager.getOutputStyle(\n this.context.config.outputStyle,\n this.context.cwd,\n );\n const hasTaskTool = tools.some((t) => t.name === TOOL_NAMES.TASK);\n let systemPrompt = generateSystemPrompt({\n todo: this.context.config.todo!,\n productName: this.context.productName,\n language: this.context.config.language,\n outputStyle,\n task: hasTaskTool,\n });\n systemPrompt = await this.context.apply({\n hook: 'systemPrompt',\n args: [{ sessionId: this.session.id }],\n memo: systemPrompt,\n type: PluginHookType.SeriesLast,\n });\n return this.sendWithSystemPromptAndTools(message, {\n ...opts,\n tools,\n systemPrompt,\n });\n }\n\n async plan(\n message: string | null,\n opts: {\n model?: string;\n onMessage?: (opts: { message: NormalizedMessage }) => Promise<void>;\n onTextDelta?: (text: string) => Promise<void>;\n onChunk?: (chunk: any, requestId: string) => Promise<void>;\n onStreamResult?: (result: StreamResult) => Promise<void>;\n signal?: AbortSignal;\n attachments?: ImagePart[];\n parentUuid?: string;\n thinking?: ThinkingConfig;\n } = {},\n ) {\n let tools = await resolveTools({\n context: this.context,\n sessionId: this.session.id,\n write: false,\n todo: false,\n askUserQuestion: !this.context.config.quiet,\n signal: opts.signal,\n task: false,\n });\n tools = await this.context.apply({\n hook: 'tool',\n args: [{ isPlan: true, sessionId: this.session.id }],\n memo: tools,\n type: PluginHookType.SeriesMerge,\n });\n let systemPrompt = generatePlanSystemPrompt({\n todo: this.context.config.todo!,\n productName: this.context.productName,\n language: this.context.config.language,\n });\n systemPrompt = await this.context.apply({\n hook: 'systemPrompt',\n args: [{ isPlan: true, sessionId: this.session.id }],\n memo: systemPrompt,\n type: PluginHookType.SeriesLast,\n });\n return this.sendWithSystemPromptAndTools(message, {\n ...opts,\n model: opts.model || this.context.config.planModel,\n tools,\n systemPrompt,\n onToolApprove: () => Promise.resolve(true),\n });\n }\n\n async sendWithSystemPromptAndTools(\n message: string | null,\n opts: {\n model?: string;\n onMessage?: (opts: { message: NormalizedMessage }) => Promise<void>;\n onToolApprove?: (opts: {\n toolUse: ToolUse;\n category?: ApprovalCategory;\n }) => Promise<boolean | ToolApprovalResult>;\n onTextDelta?: (text: string) => Promise<void>;\n onChunk?: (chunk: any, requestId: string) => Promise<void>;\n onStreamResult?: (result: StreamResult) => Promise<void>;\n signal?: AbortSignal;\n tools?: Tool[];\n systemPrompt?: string;\n attachments?: ImagePart[];\n parentUuid?: string;\n thinking?: ThinkingConfig;\n skipStopHook?: boolean;\n } = {},\n ) {\n const startTime = new Date();\n const tools = opts.tools || [];\n const outputFormat = new OutputFormat({\n format: this.context.config.outputFormat!,\n quiet: this.context.config.quiet,\n });\n\n const jsonlLogger = new JsonlLogger({\n filePath: this.context.paths.getSessionLogPath(this.session.id),\n });\n const requestLogger = new RequestLogger({\n globalProjectDir: this.context.paths.globalProjectDir,\n });\n if (message !== null) {\n message = await this.context.apply({\n hook: 'userPrompt',\n memo: message,\n args: [\n {\n sessionId: this.session.id,\n },\n ],\n type: PluginHookType.SeriesLast,\n });\n }\n const sessionConfigManager = new SessionConfigManager({\n logPath: this.context.paths.getSessionLogPath(this.session.id),\n });\n const additionalDirectories =\n sessionConfigManager.config.additionalDirectories || [];\n\n const llmsContext = await LlmsContext.create({\n context: this.context,\n sessionId: this.session.id,\n userPrompt: message,\n additionalDirectories,\n });\n let userMessage: NormalizedMessage | null = null;\n if (message !== null) {\n const lastMessageUuid =\n opts.parentUuid ||\n this.session.history.messages[this.session.history.messages.length - 1]\n ?.uuid;\n\n let content: UserContent = message;\n if (opts.attachments?.length) {\n content = [\n {\n type: 'text' as const,\n text: message,\n },\n ...opts.attachments,\n ];\n }\n\n userMessage = {\n parentUuid: lastMessageUuid || null,\n uuid: randomUUID(),\n role: 'user',\n content,\n type: 'message',\n timestamp: new Date().toISOString(),\n };\n const userMessageWithSessionId = {\n ...userMessage,\n sessionId: this.session.id,\n };\n jsonlLogger.addMessage({\n message: userMessageWithSessionId,\n });\n await opts.onMessage?.({\n message: userMessage,\n });\n }\n const historyMessages = opts.parentUuid\n ? this.session.history.getMessagesToUuid(opts.parentUuid)\n : this.session.history.messages;\n const input =\n historyMessages.length > 0\n ? [...historyMessages, userMessage]\n : [userMessage];\n const filteredInput = input.filter((message) => message !== null);\n\n // Check if conversation history contains any images\n const hasImagesInHistory = filteredInput.some((msg) => {\n if (msg.role === 'user' && Array.isArray(msg.content)) {\n return msg.content.some((part: any) => part.type === 'image');\n }\n return false;\n });\n\n // Model selection priority (high to low):\n // 1. opts.model - explicitly specified for this call\n // 2. visionModel - if images present and visionModel is configured\n // 3. default model - resolved from context\n let modelToUse = opts.model;\n\n // Auto-select visionModel when:\n // - Conversation contains images\n // - visionModel is configured and different from the base model\n if (hasImagesInHistory) {\n const visionModel = this.context.config.visionModel;\n const baseModel = this.context.config.model;\n\n // Check if visionModel was explicitly configured (not just a fallback)\n // by comparing against what the base model would be\n if (visionModel && visionModel !== baseModel) {\n modelToUse = visionModel;\n }\n }\n\n // Resolve the final model (only once)\n const resolvedModel = (\n await resolveModelWithContext(modelToUse || null, this.context)\n ).model!;\n\n // Output model info for initial message\n if (message !== null) {\n outputFormat.onInit({\n text: message,\n sessionId: this.session.id,\n tools,\n model: resolvedModel,\n cwd: this.context.cwd,\n });\n }\n\n const toolsManager = new Tools(tools);\n const result = await runLoop({\n input: filteredInput,\n model: resolvedModel,\n tools: toolsManager,\n cwd: this.context.cwd,\n systemPrompt: opts.systemPrompt,\n llmsContexts: llmsContext.messages,\n signal: opts.signal,\n autoCompact: this.context.config.autoCompact,\n language: this.context.config.language,\n thinking: opts.thinking,\n temperature: this.context.config.temperature,\n onMessage: async (message) => {\n const normalizedMessage = {\n ...message,\n sessionId: this.session.id,\n };\n outputFormat.onMessage({\n message: normalizedMessage,\n });\n jsonlLogger.addMessage({\n message: normalizedMessage,\n });\n await opts.onMessage?.({\n message: normalizedMessage,\n });\n },\n onTextDelta: async (text) => {\n await opts.onTextDelta?.(text);\n },\n onStreamResult: async (result) => {\n requestLogger.logMetadata({\n requestId: result.requestId,\n prompt: result.prompt,\n model: result.model,\n tools: result.tools,\n request: result.request,\n response: result.response,\n error: result.error,\n });\n await opts.onStreamResult?.(result);\n },\n onChunk: async (chunk, requestId) => {\n requestLogger.logChunk(requestId, chunk);\n await opts.onChunk?.(chunk, requestId);\n },\n onText: async (text) => {},\n onReasoning: async (text) => {},\n onToolUse: async (toolUse) => {\n return await this.context.apply({\n hook: 'toolUse',\n args: [\n {\n sessionId: this.session.id,\n },\n ],\n memo: toolUse,\n type: PluginHookType.SeriesLast,\n });\n },\n onToolResult: async (toolUse, toolResult, approved) => {\n return await this.context.apply({\n hook: 'toolResult',\n args: [\n {\n toolUse,\n approved,\n sessionId: this.session.id,\n },\n ],\n memo: toolResult,\n type: PluginHookType.SeriesLast,\n });\n },\n onTurn: async (turn: {\n usage: Usage;\n startTime: Date;\n endTime: Date;\n }) => {\n await this.context.apply({\n hook: 'query',\n args: [\n {\n startTime: turn.startTime,\n endTime: turn.endTime,\n usage: turn.usage,\n sessionId: this.session.id,\n },\n ],\n type: PluginHookType.Series,\n });\n },\n onToolApprove: async (toolUse) => {\n const tool = toolsManager.get(toolUse.name);\n if (!tool) {\n // Let the tool invoke handle the `tool not found` error\n return true;\n }\n\n // TODO: if quiet return true\n // 1. if yolo return true\n const approvalMode = this.context.config.approvalMode;\n // Tools that require clarifying user input must always prompt the user, even in yolo mode\n if (approvalMode === 'yolo' && tool.approval?.category !== 'ask') {\n return true;\n }\n\n // 2. if category is read return true\n if (tool.approval?.category === 'read') {\n return true;\n }\n // 3. run tool should approve if true return true\n const needsApproval = tool.approval?.needsApproval;\n if (needsApproval) {\n const needsApprovalResult = await needsApproval({\n toolName: toolUse.name,\n params: toolUse.params,\n approvalMode: this.context.config.approvalMode,\n context: this.context,\n });\n if (!needsApprovalResult) {\n return true;\n }\n }\n // 4. if category is edit check autoEdit config (including session config)\n // Read parent session config first, so subagent can inherit parent agent's approval settings\n // If there is no parent (independent agent), use its own session\n const sessionIdToCheck = this.parentSessionId || this.session.id;\n const sessionConfigManager = new SessionConfigManager({\n logPath: this.context.paths.getSessionLogPath(sessionIdToCheck),\n });\n if (tool.approval?.category === 'write') {\n if (\n sessionConfigManager.config.approvalMode === 'autoEdit' ||\n approvalMode === 'autoEdit'\n ) {\n return true;\n }\n }\n // 5. check session config's approvalTools config\n if (sessionConfigManager.config.approvalTools.includes(toolUse.name)) {\n return true;\n }\n // 6. request user approval\n return (\n (await opts.onToolApprove?.({\n toolUse,\n category: tool.approval?.category,\n })) ?? false\n );\n },\n });\n const endTime = new Date();\n await this.context.apply({\n hook: 'conversation',\n args: [\n {\n userPrompt: message,\n result,\n startTime,\n endTime,\n sessionId: this.session.id,\n },\n ],\n type: PluginHookType.Series,\n });\n if (!opts.skipStopHook) {\n await this.context.apply({\n hook: 'stop',\n args: [\n {\n sessionId: this.session.id,\n result,\n usage: result.success ? result.data.usage : Usage.empty(),\n turnsCount: result.success ? result.metadata.turnsCount : 0,\n toolCallsCount: result.success ? result.metadata.toolCallsCount : 0,\n duration: result.success ? result.metadata.duration : 0,\n model: `${resolvedModel.provider.id}/${resolvedModel.model.id}`,\n },\n ],\n type: PluginHookType.Series,\n });\n }\n outputFormat.onEnd({\n result,\n sessionId: this.session.id,\n });\n if (result.success && result.data.history) {\n this.session.updateHistory(result.data.history);\n }\n\n return result;\n }\n}\n","import type { Context } from '../../core/context';\nimport type { NormalizedMessage } from '../../core/message';\nimport { PluginHookType } from '../../core/plugin';\nimport { Project } from '../../core/project';\nimport { Session } from '../../session/session';\nimport type { Tool } from '../../tools/tool';\nimport type {\n AgentDefinition,\n AgentExecuteOptions,\n AgentExecutionResult,\n} from './types';\n\nenum AgentStatus {\n Completed = 'completed',\n Failed = 'failed',\n}\n\n// Resolve model\nconst MODEL_INHERIT = 'inherit';\n\n/**\n * Resolve the model for an agent with the following priority:\n * 1. Model explicitly passed in options\n * 2. Model configured in config.agent.{agentType}.model\n * 3. Model defined in agent definition\n * 4. Global model from context.config.model (fallback)\n */\nfunction resolveAgentModel(\n agentType: string,\n options: AgentExecuteOptions,\n definition: AgentDefinition,\n context: Context,\n): string {\n // Priority 1: Explicit model from options\n if (options.model && options.model !== MODEL_INHERIT) {\n return options.model;\n }\n\n // Priority 2: Config agent-specific model\n const configModel = context.config.agent?.[agentType]?.model;\n if (configModel && configModel !== MODEL_INHERIT) {\n return configModel;\n }\n\n // Priority 3: Agent definition model\n if (definition.model && definition.model !== MODEL_INHERIT) {\n return definition.model;\n }\n\n // Priority 4: Global fallback\n return context.config.model;\n}\n\nexport async function executeAgent(\n options: AgentExecuteOptions,\n): Promise<AgentExecutionResult> {\n const {\n definition,\n prompt,\n tools,\n context,\n signal,\n onMessage,\n onToolApprove,\n resume,\n } = options;\n\n const startTime = Date.now();\n\n const agentId = (() => {\n if (resume) {\n return resume;\n }\n return Session.createSessionId();\n })();\n\n try {\n // Validate Agent definition\n if (!definition.agentType) {\n throw new Error('Agent definition must have agentType');\n }\n if (!definition.systemPrompt) {\n throw new Error(`Agent '${definition.agentType}' must have systemPrompt`);\n }\n\n // Filter tools\n const filteredToolList = filterTools(tools, definition);\n\n if (filteredToolList.length === 0) {\n throw new Error(\n `Agent '${definition.agentType}' has no available tools after filtering.`,\n );\n }\n\n // Resolve model using priority-based resolution\n const modelName = resolveAgentModel(\n definition.agentType,\n options,\n definition,\n context,\n );\n\n if (!modelName) {\n throw new Error(`No model specified for agent '${definition.agentType}'`);\n }\n\n // Create Project instance with agent log path\n const project = new Project({\n sessionId: `agent-${agentId}`,\n parentSessionId: options.parentSessionId,\n context,\n });\n\n // Execute using Project.send\n const result = await project.sendWithSystemPromptAndTools(prompt, {\n model: modelName,\n systemPrompt: definition.systemPrompt,\n tools: filteredToolList,\n signal,\n skipStopHook: true,\n onMessage: async ({ message }) => {\n // Add agent metadata\n const enhancedMessage: NormalizedMessage = {\n ...message,\n metadata: {\n ...(message.metadata || {}),\n agentId,\n agentType: definition.agentType,\n },\n };\n\n if (onMessage) {\n try {\n await onMessage(enhancedMessage, agentId, modelName);\n } catch (error) {\n console.error('[executeAgent] Failed to send message:', error);\n }\n }\n },\n onToolApprove,\n });\n\n // Handle result\n let executionResult: AgentExecutionResult;\n if (result.success) {\n executionResult = {\n status: AgentStatus.Completed,\n agentId,\n content: extractFinalContent(result.data),\n totalToolCalls: result.metadata?.toolCallsCount || 0,\n totalDuration: Date.now() - startTime,\n model: modelName,\n usage: {\n inputTokens: result.data.usage?.promptTokens || 0,\n outputTokens: result.data.usage?.completionTokens || 0,\n },\n };\n } else {\n executionResult = {\n status: AgentStatus.Failed,\n agentId,\n content: `Agent execution failed: ${result.error.message}`,\n totalToolCalls: 0,\n totalDuration: Date.now() - startTime,\n model: modelName,\n usage: { inputTokens: 0, outputTokens: 0 },\n };\n }\n\n await context.apply({\n hook: 'subagentStop',\n args: [\n {\n parentSessionId: options.parentSessionId || '',\n agentId,\n agentType: definition.agentType,\n result: executionResult,\n usage: executionResult.usage,\n totalToolCalls: executionResult.totalToolCalls,\n totalDuration: executionResult.totalDuration,\n model: modelName,\n },\n ],\n type: PluginHookType.Series,\n });\n\n return executionResult;\n } catch (error) {\n return {\n status: AgentStatus.Failed,\n agentId,\n content: `Agent execution error: ${error instanceof Error ? error.message : String(error)}`,\n totalToolCalls: 0,\n totalDuration: Date.now() - startTime,\n usage: { inputTokens: 0, outputTokens: 0 },\n };\n }\n}\n\nfunction extractFinalContent(data: Record<string, unknown>): string {\n if (data.text && typeof data.text === 'string') {\n return data.text;\n }\n if (data.content && typeof data.content === 'string') {\n return data.content;\n }\n return 'Agent completed successfully';\n}\n\nfunction filterTools(allTools: Tool[], agentDef: AgentDefinition): Tool[] {\n const { tools, disallowedTools } = agentDef;\n const disallowedSet = new Set(disallowedTools || []);\n const hasWildcard =\n tools === undefined || (tools.length === 1 && tools[0] === '*');\n\n if (hasWildcard) {\n return allTools.filter((tool) => !disallowedSet.has(tool.name));\n }\n\n const allowedSet = new Set(tools);\n return allTools.filter(\n (tool) => allowedSet.has(tool.name) && !disallowedSet.has(tool.name),\n );\n}\n","import { spawn } from 'child_process';\nimport crypto from 'crypto';\nimport os from 'os';\n\nconst MAX_OUTPUT_SIZE = 100 * 1024 * 1024; // 100MB\n\nexport interface BackgroundTask {\n id: string;\n command: string;\n pid: number;\n pgid?: number;\n status: 'running' | 'completed' | 'killed' | 'failed';\n createdAt: number;\n output: string;\n exitCode: number | null;\n}\n\ninterface CreateTaskInput {\n command: string;\n pid: number;\n pgid?: number;\n}\n\nexport class BackgroundTaskManager {\n private tasks: Map<string, BackgroundTask> = new Map();\n\n createTask(input: CreateTaskInput): string {\n const id = `task_${crypto.randomBytes(6).toString('hex')}`;\n const task: BackgroundTask = {\n id,\n command: input.command,\n pid: input.pid,\n pgid: input.pgid,\n status: 'running',\n createdAt: Date.now(),\n output: '',\n exitCode: null,\n };\n this.tasks.set(id, task);\n return id;\n }\n\n getTask(id: string): BackgroundTask | null {\n return this.tasks.get(id) || null;\n }\n\n getAllTasks(): BackgroundTask[] {\n return Array.from(this.tasks.values());\n }\n\n appendOutput(id: string, output: string): void {\n const task = this.tasks.get(id);\n if (task) {\n const newOutput = task.output + output;\n if (newOutput.length > MAX_OUTPUT_SIZE) {\n const truncateAmount = Math.floor(MAX_OUTPUT_SIZE * 0.3);\n task.output =\n '... [output truncated] ...\\n' +\n newOutput.slice(newOutput.length - MAX_OUTPUT_SIZE + truncateAmount);\n } else {\n task.output = newOutput;\n }\n }\n }\n\n updateTaskStatus(\n id: string,\n status: BackgroundTask['status'],\n exitCode: number | null = null,\n ): void {\n const task = this.tasks.get(id);\n if (task) {\n task.status = status;\n if (exitCode !== null) {\n task.exitCode = exitCode;\n }\n }\n }\n\n deleteTask(id: string): void {\n this.tasks.delete(id);\n }\n\n private isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n }\n\n async killTask(id: string): Promise<boolean> {\n const task = this.tasks.get(id);\n if (!task || task.status !== 'running') {\n return false;\n }\n\n const isWindows = os.platform() === 'win32';\n\n try {\n if (isWindows) {\n spawn('taskkill', ['/pid', task.pid.toString(), '/f', '/t']);\n } else {\n const targetPid = task.pgid || task.pid;\n try {\n process.kill(-targetPid, 'SIGTERM');\n await new Promise((resolve) => setTimeout(resolve, 200));\n if (this.isProcessAlive(targetPid)) {\n process.kill(-targetPid, 'SIGKILL');\n }\n } catch {\n try {\n process.kill(task.pid, 'SIGKILL');\n } catch {\n // Process may not exist, still mark as killed\n }\n }\n }\n\n this.updateTaskStatus(id, 'killed');\n return true;\n } catch (error) {\n // Even if kill fails, mark as killed since we attempted\n this.updateTaskStatus(id, 'failed');\n return false;\n }\n }\n}\n","import fs from 'fs';\nimport path from 'pathe';\n\ninterface GlobalDataSchema {\n projects: Record<\n string,\n {\n history: string[];\n lastAccessed?: number;\n }\n >;\n recentModels?: string[];\n}\n\nexport class GlobalData {\n private globalDataPath: string;\n\n constructor({ globalDataPath }: { globalDataPath: string }) {\n this.globalDataPath = globalDataPath;\n }\n\n private readData(): GlobalDataSchema {\n if (!fs.existsSync(this.globalDataPath)) {\n return { projects: {} };\n }\n try {\n const content = fs.readFileSync(this.globalDataPath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n return { projects: {} };\n }\n }\n\n private writeData(data: GlobalDataSchema): void {\n const dir = path.dirname(this.globalDataPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n fs.writeFileSync(\n this.globalDataPath,\n JSON.stringify(data, null, 2),\n 'utf-8',\n );\n }\n\n getProjectHistory({ cwd }: { cwd: string }): string[] {\n const data = this.readData();\n return data.projects[cwd]?.history || [];\n }\n\n addProjectHistory({ cwd, history }: { cwd: string; history: string }): void {\n const data = this.readData();\n\n if (!data.projects[cwd]) {\n data.projects[cwd] = { history: [] };\n }\n\n data.projects[cwd].history.push(history);\n this.writeData(data);\n }\n\n getProjectLastAccessed({ cwd }: { cwd: string }): number | null {\n const data = this.readData();\n return data.projects[cwd]?.lastAccessed || null;\n }\n\n updateProjectLastAccessed({ cwd }: { cwd: string }): void {\n const data = this.readData();\n\n if (!data.projects[cwd]) {\n data.projects[cwd] = { history: [] };\n }\n\n data.projects[cwd].lastAccessed = Date.now();\n this.writeData(data);\n }\n\n getRecentModels(): string[] {\n const data = this.readData();\n return data.recentModels || [];\n }\n\n addRecentModel(model: string): void {\n const data = this.readData();\n const recentModels = data.recentModels || [];\n const filtered = recentModels.filter((m) => m !== model);\n filtered.unshift(model);\n data.recentModels = filtered.slice(0, 5);\n this.writeData(data);\n }\n}\n","import { experimental_createMCPClient } from '@ai-sdk/mcp';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport createDebug from 'debug';\nimport { existsSync, readFileSync } from 'fs';\nimport { resolve } from 'pathe';\nimport type { ImagePart, TextPart } from '../core/message';\nimport type { Tool } from '../tools/tool';\nimport { safeStringify } from '../utils/safeStringify';\n\nexport interface MCPConfig {\n type?: 'stdio' | 'sse' | 'http';\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n disable?: boolean;\n /**\n * The timeout for tool calls in milliseconds.\n */\n timeout?: number;\n headers?: Record<string, string>;\n}\n\nconst debug = createDebug('oricore:mcp');\n\ntype MCPServerStatus =\n | 'pending'\n | 'connecting'\n | 'connected'\n | 'failed'\n | 'disconnected';\n\ninterface ServerState {\n config: MCPConfig;\n status: MCPServerStatus;\n error?: string;\n tools?: Record<string, any>;\n client?: any; // Store client for cleanup\n retryCount: number;\n isTemporaryError?: boolean;\n}\n\nexport class MCPManager {\n private servers: Map<string, ServerState> = new Map();\n private configs: Record<string, MCPConfig> = {};\n private isInitialized: boolean = false;\n private initPromise?: Promise<void>;\n private initLock: boolean = false;\n\n static create(mcpServers: Record<string, MCPConfig>): MCPManager {\n debug('create MCPManager', mcpServers);\n const manager = new MCPManager();\n manager.configs = mcpServers || {};\n\n // Initialize servers state without connecting\n for (const [key, config] of Object.entries(mcpServers || {})) {\n if (config.disable) {\n debug(`Skipping disabled MCP server: ${key}`);\n continue;\n }\n manager.servers.set(key, {\n config,\n status: 'pending',\n retryCount: 0,\n });\n }\n\n return manager;\n }\n\n async initAsync(): Promise<void> {\n // Return existing promise if initialization is already in progress\n if (this.initPromise) {\n return this.initPromise;\n }\n // Double-check locking pattern for thread safety\n if (this.initLock) {\n // Wait for lock to be released and check if initialization completed\n while (this.initLock) {\n await new Promise((resolve) => setTimeout(resolve, 10));\n }\n if (this.isInitialized) {\n return;\n }\n }\n // Acquire lock\n this.initLock = true;\n try {\n // Check again in case another thread completed initialization\n if (this.isInitialized) {\n return;\n }\n this.initPromise = this._performInit();\n await this.initPromise;\n } finally {\n // Release lock\n this.initLock = false;\n }\n }\n\n private async _performInit(): Promise<void> {\n debug('Starting async MCP initialization');\n const connectionPromises: Promise<void>[] = [];\n\n for (const [key, config] of Object.entries(this.configs)) {\n if (config.disable) {\n continue;\n }\n\n const connectionPromise = this._connectServer(key, config);\n connectionPromises.push(connectionPromise);\n }\n\n // Wait for all connections to complete (success or failure)\n await Promise.allSettled(connectionPromises);\n this.isInitialized = true;\n debug('MCP initialization completed');\n }\n\n private async _connectServer(key: string, config: MCPConfig): Promise<void> {\n const serverState = this.servers.get(key);\n if (!serverState) return;\n\n try {\n debug(`Connecting MCP server: ${key}`);\n serverState.status = 'connecting';\n\n // Test connection and fetch tools\n const { client, tools } = await this._testConnectionAndFetchTools(config);\n\n serverState.status = 'connected';\n serverState.client = client;\n serverState.tools = tools;\n serverState.error = undefined;\n\n debug(\n `MCP server connected successfully: ${key}, tools: ${Object.keys(tools).length}`,\n );\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n debug(`Failed to connect MCP server ${key}: ${errorMessage}`);\n\n // Classify error types for better handling\n const isTemporaryError = this._isTemporaryError(error);\n\n serverState.status = 'failed';\n serverState.error = errorMessage;\n serverState.retryCount += 1;\n serverState.isTemporaryError = isTemporaryError;\n\n // Ensure no client reference is left on failure\n serverState.client = undefined;\n serverState.tools = undefined;\n }\n }\n\n async getAllTools(): Promise<Tool[]> {\n const allTools: Tool[] = [];\n const toolNames = new Set<string>();\n\n for (const [serverName, serverState] of this.servers.entries()) {\n if (serverState.status !== 'connected' || !serverState.tools) {\n continue;\n }\n\n for (const [toolName, toolDef] of Object.entries(serverState.tools)) {\n const fullToolName = `mcp__${serverName}__${toolName}`;\n\n if (toolNames.has(fullToolName)) {\n throw new Error(`Duplicate tool name found: ${fullToolName}`);\n }\n\n toolNames.add(fullToolName);\n allTools.push(\n this.#convertAiSdkToolToLocal(\n toolName,\n toolDef,\n serverName,\n serverState.config,\n ),\n );\n }\n }\n\n return allTools;\n }\n\n async getTools(keys: string[]): Promise<Tool[]> {\n const allTools: Tool[] = [];\n const toolNames = new Set<string>();\n\n for (const key of keys) {\n const serverState = this.servers.get(key);\n if (\n !serverState ||\n serverState.status !== 'connected' ||\n !serverState.tools\n ) {\n continue;\n }\n\n for (const [toolName, toolDef] of Object.entries(serverState.tools)) {\n const fullToolName = `mcp__${key}__${toolName}`;\n\n if (toolNames.has(fullToolName)) {\n throw new Error(`Duplicate tool name found: ${fullToolName}`);\n }\n\n toolNames.add(fullToolName);\n allTools.push(\n this.#convertAiSdkToolToLocal(\n toolName,\n toolDef,\n key,\n serverState.config,\n ),\n );\n }\n }\n\n return allTools;\n }\n\n async destroy() {\n // Close all client connections\n const closePromises = Array.from(this.servers.values())\n .filter((state) => state.client)\n .map((state) =>\n state.client.close().catch((err: Error) => {\n debug('Error closing client during destroy:', err);\n }),\n );\n\n await Promise.allSettled(closePromises);\n this.servers.clear();\n this.isInitialized = false;\n this.initPromise = undefined;\n }\n\n getServerNames(): string[] {\n return Array.from(this.servers.keys());\n }\n\n hasServer(name: string): boolean {\n return this.servers.has(name);\n }\n\n getServerStatus(name: string): MCPServerStatus | undefined {\n return this.servers.get(name)?.status;\n }\n\n getServerError(name: string): string | undefined {\n return this.servers.get(name)?.error;\n }\n\n async getAllServerStatus(): Promise<\n Record<\n string,\n { status: MCPServerStatus; error?: string; toolCount: number }\n >\n > {\n await this.initAsync();\n\n const result: Record<\n string,\n { status: MCPServerStatus; error?: string; toolCount: number }\n > = {};\n for (const [name, state] of this.servers.entries()) {\n result[name] = {\n status: state.status,\n error: state.error,\n toolCount: state.tools ? Object.keys(state.tools).length : 0,\n };\n }\n return result;\n }\n\n isReady(): boolean {\n return this.isInitialized;\n }\n\n isLoading(): boolean {\n return !!this.initPromise && !this.isInitialized;\n }\n\n async retryConnection(serverName: string): Promise<void> {\n const config = this.configs[serverName];\n if (!config) {\n throw new Error(`Server ${serverName} not found in configuration`);\n }\n\n const serverState = this.servers.get(serverName);\n if (!serverState) {\n throw new Error(`Server ${serverName} state not found`);\n }\n\n // Log reconnection attempt\n debug(`Attempting to reconnect MCP server: ${serverName}`);\n\n // Close existing client if any\n if (serverState.client) {\n try {\n await serverState.client.close();\n } catch (error) {\n debug(`Error closing existing client for ${serverName}:`, error);\n }\n }\n\n // Reset state and retry\n serverState.client = undefined;\n serverState.tools = undefined;\n serverState.error = undefined;\n serverState.status = 'connecting';\n\n await this._connectServer(serverName, config);\n\n // Verify reconnection result\n const newState = this.servers.get(serverName);\n if (newState?.status !== 'connected') {\n throw new Error(newState?.error || 'Reconnection failed');\n }\n\n debug(`Successfully reconnected MCP server: ${serverName}`);\n }\n\n private async _createClient(config: MCPConfig) {\n if (config.command) {\n // Stdio transport (for local servers only)\n const env = config.env\n ? { ...config.env, PATH: process.env.PATH || '' }\n : undefined;\n\n const { Experimental_StdioMCPTransport } = await import(\n '@ai-sdk/mcp/mcp-stdio'\n );\n\n // Windows: if command is npx/npm/yarn/pnpm/bun/bunx, use cmd.exe to execute, fix: spawn npx ENOENT error\n const windowsShellCommands = [\n 'npx',\n 'npm',\n 'yarn',\n 'pnpm',\n 'bun',\n 'bunx',\n ];\n let command = config.command;\n let args = config.args;\n const isWin = process.platform === 'win32';\n if (isWin && windowsShellCommands.includes(command.toLowerCase())) {\n args = ['/c', command, ...(args || [])];\n command = 'cmd.exe';\n }\n\n return experimental_createMCPClient({\n transport: new Experimental_StdioMCPTransport({\n command,\n args,\n stderr: 'ignore',\n env,\n }),\n });\n } else if (config.url) {\n // HTTP or SSE transport\n const transportType = config.type || 'http'; // Default to HTTP\n if (transportType === 'sse') {\n // SSE transport\n return experimental_createMCPClient({\n transport: {\n type: 'sse',\n url: config.url,\n headers: config.headers,\n },\n });\n } else {\n // HTTP transport\n return experimental_createMCPClient({\n transport: new StreamableHTTPClientTransport(new URL(config.url), {\n requestInit: {\n headers: config.headers,\n },\n }),\n });\n }\n } else {\n throw new Error('MCP config must have either command or url configured');\n }\n }\n\n private async _testConnectionAndFetchTools(\n config: MCPConfig,\n ): Promise<{ client: any; tools: Record<string, any> }> {\n const client = await this._createClient(config);\n try {\n const tools = await client.tools();\n return { client, tools };\n } catch (error) {\n // Close client on error\n await client.close().catch((err) => {\n debug('Error closing client after connection failure:', err);\n });\n throw error;\n }\n }\n\n private _isTemporaryError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n\n const message = error.message.toLowerCase();\n\n // Network-related temporary errors\n const temporaryErrors = [\n 'timeout',\n 'connection refused',\n 'network error',\n 'temporary',\n 'try again',\n 'rate limit',\n 'too many requests',\n 'service unavailable',\n 'socket hang up',\n 'econnreset',\n 'enotfound',\n 'econnrefused',\n 'etimedout',\n ];\n\n // Configuration or permanent errors\n const permanentErrors = [\n 'command not found',\n 'no such file',\n 'permission denied',\n 'invalid configuration',\n 'malformed',\n 'syntax error',\n 'authentication failed',\n 'unauthorized',\n ];\n\n // Check for permanent errors first (higher priority)\n if (permanentErrors.some((permanent) => message.includes(permanent))) {\n return false;\n }\n\n // Check for temporary errors\n if (temporaryErrors.some((temporary) => message.includes(temporary))) {\n return true;\n }\n\n // Default to temporary for unknown errors (safer for retries)\n return true;\n }\n\n #convertAiSdkToolToLocal(\n toolName: string,\n toolDef: any,\n serverName: string,\n config: MCPConfig,\n ): Tool {\n const safeServerName = serverName.replace(/[^a-zA-Z0-9_-]/g, '');\n const safeToolName = toolName.replace(/[^a-zA-Z0-9_-]/g, '_');\n\n return {\n name: `mcp__${safeServerName}__${safeToolName}`,\n description: toolDef.description,\n getDescription: ({ params }) => {\n return formatParamsDescription(params as Record<string, any>);\n },\n // Why? Some models do not support null values, so null values need to be removed.\n parameters: removeNullValues(toolDef.inputSchema.jsonSchema),\n execute: async (params) => {\n try {\n // toolDef is already a Tool from AI SDK with an execute method\n const result = await toolDef.execute(params || {});\n\n const returnDisplay = `Tool ${toolName} executed successfully${params ? `, parameters: ${JSON.stringify(params)}` : ''}`;\n const llmContent = convertMcpResultToLlmContent(result);\n\n return {\n llmContent,\n returnDisplay,\n };\n } catch (error) {\n return {\n isError: true,\n llmContent: error instanceof Error ? error.message : String(error),\n };\n }\n },\n approval: {\n category: 'network',\n },\n };\n }\n}\n\nexport function parseMcpConfig(\n mcpConfigArgs: string[],\n cwd: string,\n): Record<string, MCPConfig> {\n const mcpServers: Record<string, MCPConfig> = {};\n for (const configItem of mcpConfigArgs) {\n let configData: unknown;\n try {\n // Try to parse as JSON string first\n configData = JSON.parse(configItem);\n } catch (e) {\n // If JSON parsing fails, treat as file path\n const configPath = resolve(cwd, configItem);\n if (!existsSync(configPath)) {\n throw new Error(`MCP config file not found: ${configPath}`);\n }\n try {\n const fileContent = readFileSync(configPath, 'utf-8');\n configData = JSON.parse(fileContent);\n } catch (error) {\n throw new Error(\n `Failed to parse MCP config file ${configPath}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n // Extract mcpServer object from the config data\n if (!configData || typeof configData !== 'object') {\n throw new Error('MCP config must be a valid JSON object');\n }\n const configObj = configData as Record<string, unknown>;\n if (!configObj.mcpServers || typeof configObj.mcpServers !== 'object') {\n throw new Error('MCP config must contain an \"mcpServers\" object');\n }\n Object.assign(\n mcpServers,\n configObj.mcpServers as Record<string, MCPConfig>,\n );\n }\n\n return mcpServers;\n}\n\nfunction removeNullValues(obj: unknown): any {\n if (obj === null || obj === undefined) {\n return undefined;\n }\n if (Array.isArray(obj)) {\n return obj.map(removeNullValues).filter((v) => v !== undefined);\n }\n if (typeof obj === 'object') {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj as Record<string, unknown>)) {\n const cleaned = removeNullValues(v);\n if (cleaned !== undefined) {\n result[k] = cleaned;\n }\n }\n return result;\n }\n return obj;\n}\n\nfunction formatParamsDescription(params: Record<string, any>): string {\n if (!params || typeof params !== 'object') {\n return '';\n }\n const entries = Object.entries(params);\n if (entries.length === 0) {\n return '';\n }\n return entries\n .filter(([key, value]) => value !== null && value !== undefined)\n .map(([key, value]) => {\n return `${key}: ${safeStringify(value)}`;\n })\n .join(', ');\n}\n\nexport function convertMcpResultToLlmContent(\n result: any,\n): string | (TextPart | ImagePart)[] {\n // Support mcp spec data types\n // ref: https://modelcontextprotocol.io/specification/2025-06-18/server/tools#data-types\n\n // Step 1: Unpack MCP result format\n let actualContent: any;\n\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n // why? https://github.com/vercel/ai/blob/main/packages/mcp/src/tool/types.ts#L201\n if ('content' in result && Array.isArray(result.content)) {\n // Format 1: { content: [...], isError?: boolean }\n actualContent = result.content;\n } else if ('toolResult' in result) {\n // Format 2: { toolResult: unknown }\n return safeStringify(result.toolResult);\n } else {\n // Fallback: treat as regular object\n actualContent = result;\n }\n } else {\n actualContent = result;\n }\n\n // Step 2: Type detection functions\n const isTextPart = (part: object) => {\n return 'type' in part && part.type === 'text' && 'text' in part;\n };\n const isImagePart = (part: object) => {\n return (\n 'type' in part &&\n part.type === 'image' &&\n 'data' in part &&\n 'mimeType' in part\n );\n };\n const isResourcePart = (part: object) => {\n return 'type' in part && part.type === 'resource' && 'resource' in part;\n };\n const isPart = (part: object) => {\n return isTextPart(part) || isImagePart(part) || isResourcePart(part);\n };\n\n // Step 3: Process actualContent based on type\n let llmContent: any = actualContent;\n\n if (typeof llmContent === 'object' && !Array.isArray(llmContent)) {\n // Single object: wrap in array if it's a part, otherwise stringify\n if (isPart(llmContent as object)) {\n llmContent = [llmContent];\n } else {\n llmContent = safeStringify(llmContent);\n }\n } else if (Array.isArray(llmContent)) {\n // Array: check if it contains parts\n const hasPart = llmContent.some(\n (item) => typeof item === 'object' && item !== null && isPart(item),\n );\n if (hasPart) {\n // Mixed array: convert non-part elements to text parts\n llmContent = llmContent.map((part) => {\n if (typeof part === 'object' && part !== null && isPart(part)) {\n return part;\n } else {\n return { type: 'text', text: safeStringify(part) };\n }\n });\n } else {\n // Pure data array: stringify\n llmContent = safeStringify(llmContent);\n }\n } else if (typeof llmContent === 'string') {\n // Keep llmContent as string\n } else {\n // Other types: convert to string\n llmContent = String(llmContent);\n }\n\n return llmContent;\n}\n","import fs from 'fs';\nimport os from 'os';\nimport path from 'pathe';\n// TODO: SessionConfig will be imported when session module is ready\n// import type { SessionConfig } from '../session';\n\ninterface ConfigLogEntry {\n type: 'config';\n config: any; // SessionConfig\n}\n\ninterface MessageLogEntry {\n type: 'message';\n role: string;\n content: string | any[];\n [key: string]: any;\n}\n\ntype LogEntry = ConfigLogEntry | MessageLogEntry;\n\nexport function getGlobalDataPath(globalDir: string): string {\n return path.join(globalDir, 'data.json');\n}\n\nexport class Paths {\n globalConfigDir: string;\n globalProjectDir: string;\n projectConfigDir: string;\n\n constructor(opts: { productName: string; cwd: string }) {\n const productName = opts.productName.toLowerCase();\n this.globalConfigDir = path.join(os.homedir(), `.${productName}`);\n this.globalProjectDir = path.join(\n this.globalConfigDir,\n 'projects',\n formatPath(opts.cwd),\n );\n this.projectConfigDir = path.join(opts.cwd, `.${productName}`);\n }\n\n getSessionLogPath(sessionId: string) {\n if (path.isAbsolute(sessionId)) {\n return sessionId;\n } else if (sessionId.startsWith('.') || sessionId.endsWith('.jsonl')) {\n return path.join(process.cwd(), sessionId);\n } else {\n return path.join(this.globalProjectDir, `${sessionId}.jsonl`);\n }\n }\n\n getLatestSessionId() {\n if (!fs.existsSync(this.globalProjectDir)) {\n return undefined;\n }\n const jsonlFileTimeStamps = fs\n .readdirSync(this.globalProjectDir)\n .filter((file) => file.endsWith('.jsonl'))\n .map((file) => {\n const stats = fs.statSync(path.join(this.globalProjectDir, file));\n return {\n timestamp: stats.mtime.getTime(),\n sessionId: path.basename(file, '.jsonl'),\n };\n });\n const latestSession = jsonlFileTimeStamps.sort(\n (a, b) => b.timestamp - a.timestamp,\n )[0];\n return latestSession.sessionId;\n }\n\n getAllSessions() {\n if (!fs.existsSync(this.globalProjectDir)) {\n return [];\n }\n const jsonlFiles = fs\n .readdirSync(this.globalProjectDir)\n .filter((file) => file.endsWith('.jsonl'))\n .map((file) => {\n const filePath = path.join(this.globalProjectDir, file);\n const stats = fs.statSync(filePath);\n const sessionId = path.basename(file, '.jsonl');\n\n // Read message count and summary\n let messageCount = 0;\n let summary = '';\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const lines = content.split('\\n').filter(Boolean);\n messageCount = lines.length;\n\n // Extract summary: prioritize config.summary, fallback to first user message\n if (lines.length > 0) {\n try {\n const firstEntry: LogEntry = JSON.parse(lines[0]);\n if (firstEntry.type === 'config' && firstEntry.config.summary) {\n summary = firstEntry.config.summary;\n } else {\n summary = extractFirstUserMessageSummary(lines);\n }\n } catch (e) {\n summary = extractFirstUserMessageSummary(lines);\n }\n }\n } catch (e) {\n // ignore read error, message count is 0\n }\n\n return {\n sessionId,\n modified: stats.mtime,\n created: stats.birthtime,\n messageCount,\n summary: normalizeSummary(summary),\n };\n })\n .sort((a, b) => b.modified.getTime() - a.modified.getTime())\n .slice(0, 50);\n\n return jsonlFiles;\n }\n\n getGlobalDataPath() {\n return path.join(this.globalConfigDir, 'data.json');\n }\n}\n\nfunction normalizeSummary(summary: string): string {\n if (!summary) return '';\n return summary\n .replace(/\\r\\n|\\r|\\n/g, ' ') // Replace all line breaks with spaces\n .replace(/\\s+/g, ' ') // Merge consecutive whitespace characters into single space\n .trim(); // Remove leading and trailing whitespace\n}\n\nfunction extractFirstUserMessageSummary(lines: string[]): string {\n for (const line of lines) {\n try {\n const entry: LogEntry = JSON.parse(line);\n if (\n entry.type === 'message' &&\n 'role' in entry &&\n entry.role === 'user' &&\n typeof entry.content === 'string'\n ) {\n return entry.content.length > 50\n ? entry.content.slice(0, 50) + '...'\n : entry.content;\n }\n } catch (e) {}\n }\n return '';\n}\n\nfunction formatPath(from: string) {\n return from\n .replace(/^\\/+|\\/+$/g, '') // Remove leading/trailing slashes\n .replace(/[^a-zA-Z0-9]/g, '-')\n .replace(/-+/g, '-') // Collapse multiple dashes\n .replace(/^-+|-+$/g, '') // Remove leading/trailing dashes\n .toLowerCase(); // Ensure consistency across filesystems\n}\n","import degit from 'degit';\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'pathe';\nimport type { Context } from '../core/context';\nimport type { Paths } from '../core/paths';\nimport { PluginHookType } from '../core/plugin';\nimport { safeFrontMatter } from '../utils/safeFrontMatter';\nimport {\n bundledSkillRegistry,\n bundledSkillToMetadata,\n type BundledSkillDefinition,\n} from './bundled';\n\n/**\n * Check if a directory entry is a directory or a symlink pointing to a directory.\n */\nfunction isDirOrSymlinkToDir(parentDir: string, entry: fs.Dirent): boolean {\n if (entry.isDirectory()) return true;\n if (entry.isSymbolicLink()) {\n try {\n return fs.statSync(path.join(parentDir, entry.name)).isDirectory();\n } catch {\n // broken symlink, skip\n }\n }\n return false;\n}\n\nexport enum SkillSource {\n Plugin = 'plugin',\n GlobalClaude = 'global-claude',\n Global = 'global',\n ProjectClaude = 'project-claude',\n Project = 'project',\n Builtin = 'builtin',\n}\n\nexport type SkillContext = 'inline' | 'fork';\n\nexport interface SkillMetadata {\n name: string;\n description: string;\n path: string;\n source: SkillSource;\n /**\n * Tools that this skill is allowed to use.\n * If specified, only these tools will be available when the skill executes.\n * Example: ['Read', 'Grep', 'Bash']\n */\n allowedTools?: string[];\n /**\n * Execution context for the skill.\n * - 'inline': Skill content is injected into current conversation (default)\n * - 'fork': Skill runs in an isolated sub-agent\n */\n context?: SkillContext;\n /**\n * Agent type to use when context is 'fork'.\n * If not specified, defaults to a general-purpose agent.\n */\n agent?: string;\n /**\n * File path patterns that trigger this skill's availability.\n * Example: ['src/asterisk/asterisk.ts', '*.test.js']\n */\n paths?: string[];\n /**\n * Whether this skill can be invoked by users via slash commands.\n * @default true\n */\n userInvocable?: boolean;\n /**\n * Whether this skill can be invoked by the model via SkillTool.\n * @default true\n */\n modelInvocable?: boolean;\n}\n\nexport interface SkillError {\n path: string;\n message: string;\n}\n\nexport interface SkillLoadOutcome {\n skills: SkillMetadata[];\n errors: SkillError[];\n}\n\nexport interface AddSkillOptions {\n global?: boolean;\n claude?: boolean;\n overwrite?: boolean;\n name?: string;\n targetDir?: string;\n}\n\nexport interface SkillPreview {\n name: string;\n description: string;\n skillPath: string;\n skillDir: string;\n}\n\nexport interface PreviewSkillsResult {\n tempDir: string;\n skills: SkillPreview[];\n errors: SkillError[];\n}\n\nexport interface AddSkillResult {\n installed: SkillMetadata[];\n skipped: { name: string; reason: string }[];\n errors: SkillError[];\n}\n\nconst MAX_NAME_LENGTH = 64;\nconst MAX_DESCRIPTION_LENGTH = 2048;\n\nexport interface SkillManagerOpts {\n context: Context;\n}\n\nexport class SkillManager {\n private skillsMap: Map<string, SkillMetadata> = new Map();\n private errors: SkillError[] = [];\n private paths: Paths;\n private context: Context;\n /**\n * Tracks which skills are currently \"active\" based on file operations.\n * Skills with `paths` frontmatter are activated when matching files are accessed.\n */\n private activeSkillNames: Set<string> = new Set();\n /**\n * Maps alias names to original skill names for bundled skills.\n */\n private aliasMap: Map<string, string> = new Map();\n\n constructor(opts: SkillManagerOpts) {\n this.context = opts.context;\n this.paths = opts.context.paths;\n }\n\n /**\n * Get all loaded skills.\n * @param options Filter options\n * @returns Array of skill metadata\n */\n getSkills(options?: {\n /** Only return skills that are user-invocable */\n userInvocable?: boolean;\n /** Only return skills that are model-invocable */\n modelInvocable?: boolean;\n /** Only return active skills (those with matching paths) */\n activeOnly?: boolean;\n }): SkillMetadata[] {\n let skills = Array.from(this.skillsMap.values());\n\n if (options?.userInvocable !== undefined) {\n skills = skills.filter(\n (s) => (s.userInvocable ?? true) === options.userInvocable,\n );\n }\n\n if (options?.modelInvocable !== undefined) {\n skills = skills.filter(\n (s) => (s.modelInvocable ?? true) === options.modelInvocable,\n );\n }\n\n if (options?.activeOnly) {\n skills = skills.filter((s) => this.activeSkillNames.has(s.name));\n }\n\n return skills;\n }\n\n /**\n * Get a specific skill by name.\n * Automatically resolves aliases to the original skill.\n * @param name Skill name or alias\n * @returns Skill metadata or undefined if not found\n */\n getSkill(name: string): SkillMetadata | undefined {\n // Check direct name first\n const skill = this.skillsMap.get(name);\n if (skill) return skill;\n\n // Check if it's an alias\n const originalName = this.aliasMap.get(name);\n if (originalName) {\n return this.skillsMap.get(originalName);\n }\n\n return undefined;\n }\n\n /**\n * Check if a skill is active (has matching paths for current context).\n * @param name Skill name\n */\n isSkillActive(name: string): boolean {\n return this.activeSkillNames.has(name);\n }\n\n /**\n * Activate skills based on file paths.\n * Skills with `paths` frontmatter that match the given paths will be activated.\n * @param filePaths Array of file paths to check\n * @returns Array of newly activated skill names\n */\n activateSkillsForPaths(filePaths: string[]): string[] {\n const newlyActivated: string[] = [];\n const minimatch = require('minimatch');\n\n for (const [name, skill] of this.skillsMap) {\n if (skill.paths && skill.paths.length > 0) {\n const isMatch = skill.paths.some((pattern) =>\n filePaths.some((filePath) => minimatch(filePath, pattern)),\n );\n\n if (isMatch && !this.activeSkillNames.has(name)) {\n this.activeSkillNames.add(name);\n newlyActivated.push(name);\n }\n }\n }\n\n return newlyActivated;\n }\n\n /**\n * Clear all active skill activations.\n * Useful when switching contexts or projects.\n */\n clearActiveSkills(): void {\n this.activeSkillNames.clear();\n }\n\n /**\n * Get all skills that have path-based conditional activation.\n * @returns Array of skills with paths defined\n */\n getConditionalSkills(): SkillMetadata[] {\n return Array.from(this.skillsMap.values()).filter(\n (s) => s.paths && s.paths.length > 0,\n );\n }\n\n getErrors(): SkillError[] {\n return this.errors;\n }\n\n /**\n * Read the body content of a skill.\n * For file-based skills, reads from disk.\n * For bundled skills, generates content via getPrompt.\n */\n async readSkillBody(skill: SkillMetadata, args: string = ''): Promise<string> {\n try {\n // Handle bundled skills\n if (skill.path.startsWith('bundled://')) {\n const bundledName = skill.path.replace('bundled://', '');\n const bundledSkill = bundledSkillRegistry.get(bundledName);\n if (!bundledSkill) {\n throw new Error(`Bundled skill \"${bundledName}\" not found in registry`);\n }\n return await bundledSkill.getPrompt(args, this.context);\n }\n\n // Handle file-based skills\n const content = fs.readFileSync(skill.path, 'utf-8');\n const { body } = safeFrontMatter(content, skill.path);\n return body;\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'Unknown error reading skill';\n throw new Error(`Failed to read skill ${skill.name}: ${message}`);\n }\n }\n\n /**\n * Get a bundled skill definition by name.\n * @param name Bundled skill name\n * @returns Bundled skill definition or undefined if not found\n */\n getBundledSkill(name: string): BundledSkillDefinition | undefined {\n return bundledSkillRegistry.get(name);\n }\n\n /**\n * Register a bundled skill programmatically.\n * @param definition Bundled skill definition\n */\n registerBundledSkill(definition: BundledSkillDefinition): void {\n bundledSkillRegistry.register(definition);\n // Reload to include the new skill\n this.loadBuiltinSkills();\n }\n\n async loadSkills(): Promise<void> {\n this.skillsMap.clear();\n this.errors = [];\n\n // Load builtin/bundled skills first\n this.loadBuiltinSkills();\n\n const pluginSkills = await this.context.apply({\n hook: 'skill',\n args: [],\n memo: [],\n type: PluginHookType.SeriesMerge,\n });\n\n if (Array.isArray(pluginSkills)) {\n for (const skillPath of pluginSkills) {\n if (typeof skillPath !== 'string') {\n this.errors.push({\n path: String(skillPath),\n message: 'Invalid skill path type: expected string',\n });\n continue;\n }\n if (!fs.existsSync(skillPath)) {\n this.errors.push({\n path: skillPath,\n message: 'Skill file not found',\n });\n continue;\n }\n this.loadSkillFile(skillPath, SkillSource.Plugin);\n }\n }\n\n const globalClaudeDir = path.join(\n path.dirname(this.paths.globalConfigDir),\n '.claude',\n 'skills',\n );\n this.loadSkillsFromDirectory(globalClaudeDir, SkillSource.GlobalClaude);\n\n const globalDir = path.join(this.paths.globalConfigDir, 'skills');\n this.loadSkillsFromDirectory(globalDir, SkillSource.Global);\n\n const projectClaudeDir = path.join(\n path.dirname(this.paths.projectConfigDir),\n '.claude',\n 'skills',\n );\n this.loadSkillsFromDirectory(projectClaudeDir, SkillSource.ProjectClaude);\n\n const projectDir = path.join(this.paths.projectConfigDir, 'skills');\n this.loadSkillsFromDirectory(projectDir, SkillSource.Project);\n }\n\n /**\n * Load builtin/bundled skills from the registry.\n */\n private loadBuiltinSkills(): void {\n // Clear alias map when reloading\n this.aliasMap.clear();\n\n const bundledSkills = bundledSkillRegistry.getAll(this.context);\n for (const skill of bundledSkills) {\n const metadata = bundledSkillToMetadata(skill, SkillSource.Builtin);\n this.skillsMap.set(skill.name, metadata);\n\n // Register aliases in the alias map\n if (skill.aliases) {\n for (const alias of skill.aliases) {\n this.aliasMap.set(alias, skill.name);\n }\n }\n }\n }\n\n private loadSkillsFromDirectory(\n skillsDir: string,\n source: SkillSource,\n ): void {\n if (!fs.existsSync(skillsDir)) {\n return;\n }\n\n try {\n const entries = fs.readdirSync(skillsDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (isDirOrSymlinkToDir(skillsDir, entry)) {\n const skillPath = path.join(skillsDir, entry.name, 'SKILL.md');\n if (fs.existsSync(skillPath)) {\n this.loadSkillFile(skillPath, source);\n }\n }\n }\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : 'Unknown error scanning directory';\n this.errors.push({\n path: skillsDir,\n message: `Failed to scan skills directory: ${message}`,\n });\n }\n }\n\n private loadSkillFile(skillPath: string, source: SkillSource): void {\n try {\n const content = fs.readFileSync(skillPath, 'utf-8');\n const parsed = this.parseSkillFile(content, skillPath);\n\n if (parsed) {\n this.skillsMap.set(parsed.name, { ...parsed, source });\n }\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'Unknown error loading skill';\n this.errors.push({\n path: skillPath,\n message,\n });\n }\n }\n\n private parseSkillFile(\n content: string,\n skillPath: string,\n ): Omit<SkillMetadata, 'source'> | null {\n try {\n const { attributes } = safeFrontMatter<{\n name?: string;\n description?: string;\n allowedTools?: string | string[];\n context?: string;\n agent?: string;\n paths?: string | string[];\n userInvocable?: boolean;\n modelInvocable?: boolean;\n }>(content, skillPath);\n\n if (!attributes.name) {\n this.errors.push({\n path: skillPath,\n message: 'Missing required field: name',\n });\n return null;\n }\n\n if (!attributes.description) {\n this.errors.push({\n path: skillPath,\n message: 'Missing required field: description',\n });\n return null;\n }\n\n if (attributes.name.length > MAX_NAME_LENGTH) {\n this.errors.push({\n path: skillPath,\n message: `Name exceeds maximum length of ${MAX_NAME_LENGTH} characters`,\n });\n return null;\n }\n\n if (attributes.name.includes('\\n')) {\n this.errors.push({\n path: skillPath,\n message: 'Name must be a single line',\n });\n return null;\n }\n\n if (attributes.description.length > MAX_DESCRIPTION_LENGTH) {\n this.errors.push({\n path: skillPath,\n message: `Description exceeds maximum length of ${MAX_DESCRIPTION_LENGTH} characters`,\n });\n return null;\n }\n\n // Parse allowedTools - supports both string and array formats\n const allowedTools = this.parseStringArrayField(attributes.allowedTools);\n\n // Parse context (inline or fork)\n const context: SkillContext | undefined =\n attributes.context === 'inline' || attributes.context === 'fork'\n ? attributes.context\n : undefined;\n\n // Parse paths - supports both string and array formats\n const paths = this.parseStringArrayField(attributes.paths);\n\n return {\n name: attributes.name,\n description: attributes.description,\n path: skillPath,\n allowedTools,\n context,\n agent: attributes.agent,\n paths,\n userInvocable: attributes.userInvocable ?? true,\n modelInvocable: attributes.modelInvocable ?? true,\n };\n } catch (error) {\n this.errors.push({\n path: skillPath,\n message:\n error instanceof Error\n ? error.message\n : 'Failed to parse frontmatter',\n });\n return null;\n }\n }\n\n /**\n * Parse a field that can be either a comma-separated string or an array of strings.\n * @param value The value to parse\n * @returns Array of strings or undefined if empty\n */\n private parseStringArrayField(\n value: string | string[] | undefined,\n ): string[] | undefined {\n if (!value) return undefined;\n\n if (Array.isArray(value)) {\n return value\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n }\n\n if (typeof value === 'string') {\n return value\n .split(',')\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n }\n\n return undefined;\n }\n\n async addSkill(\n source: string,\n options: AddSkillOptions = {},\n ): Promise<AddSkillResult> {\n const {\n global: isGlobal = false,\n claude: isClaude = false,\n overwrite = false,\n name,\n targetDir,\n } = options;\n const result: AddSkillResult = {\n installed: [],\n skipped: [],\n errors: [],\n };\n\n const tempDir = path.join(os.tmpdir(), `oricore-skill-${Date.now()}`);\n\n try {\n const normalizedSource = this.normalizeSource(source);\n const emitter = degit(normalizedSource, { force: true });\n await emitter.clone(tempDir);\n\n const skillPaths = this.scanForSkills(tempDir);\n\n if (skillPaths.length === 0) {\n result.errors.push({\n path: source,\n message: 'No skills found (no SKILL.md files)',\n });\n return result;\n }\n\n if (name && skillPaths.length > 1) {\n throw new Error(\n 'Cannot use --name when source contains multiple skills',\n );\n }\n\n const targetBaseDir = targetDir\n ? targetDir\n : isClaude && isGlobal\n ? path.join(\n path.dirname(this.paths.globalConfigDir),\n '.claude',\n 'skills',\n )\n : isClaude\n ? path.join(\n path.dirname(this.paths.projectConfigDir),\n '.claude',\n 'skills',\n )\n : isGlobal\n ? path.join(this.paths.globalConfigDir, 'skills')\n : path.join(this.paths.projectConfigDir, 'skills');\n\n fs.mkdirSync(targetBaseDir, { recursive: true });\n\n for (const skillPath of skillPaths) {\n const skillDir = path.dirname(skillPath);\n const isRootSkill = skillDir === tempDir;\n const folderName =\n name ||\n (isRootSkill\n ? this.extractFolderName(source)\n : path.basename(skillDir));\n const targetDir = path.join(targetBaseDir, folderName);\n\n const content = fs.readFileSync(skillPath, 'utf-8');\n const parsed = this.parseSkillFileForAdd(content, skillPath);\n\n if (!parsed) {\n result.errors.push({\n path: skillPath,\n message: 'Invalid skill file',\n });\n continue;\n }\n\n if (fs.existsSync(targetDir)) {\n if (!overwrite) {\n result.skipped.push({\n name: parsed.name,\n reason: 'already exists',\n });\n continue;\n }\n fs.rmSync(targetDir, { recursive: true });\n }\n\n this.copyDirectory(skillDir, targetDir);\n\n result.installed.push({\n name: parsed.name,\n description: parsed.description,\n path: path.join(targetDir, 'SKILL.md'),\n source:\n isClaude && isGlobal\n ? SkillSource.GlobalClaude\n : isClaude\n ? SkillSource.ProjectClaude\n : isGlobal\n ? SkillSource.Global\n : SkillSource.Project,\n });\n }\n\n await this.loadSkills();\n } finally {\n if (fs.existsSync(tempDir)) {\n fs.rmSync(tempDir, { recursive: true });\n }\n }\n\n return result;\n }\n\n private normalizeSource(source: string): string {\n let normalized = source;\n\n if (\n normalized.startsWith('https://github.com/') ||\n normalized.startsWith('http://github.com/')\n ) {\n normalized = normalized.replace(/^https?:\\/\\/github\\.com\\//, '');\n const treeMatch = normalized.match(\n /^([^/]+\\/[^/]+)\\/tree\\/([^/]+)(?:\\/(.+))?$/,\n );\n if (treeMatch) {\n const [, repo, branch, subpath] = treeMatch;\n normalized = subpath\n ? `${repo}/${subpath}#${branch}`\n : `${repo}#${branch}`;\n }\n return `github:${normalized}`;\n }\n\n if (\n !normalized.startsWith('github:') &&\n !normalized.startsWith('gitlab:') &&\n !normalized.startsWith('bitbucket:')\n ) {\n return `github:${normalized}`;\n }\n return normalized;\n }\n\n private extractFolderName(source: string): string {\n let normalized = source\n .replace(/^https?:\\/\\/github\\.com\\//, '')\n .replace(/^github:/, '')\n .replace(/^gitlab:/, '')\n .replace(/^bitbucket:/, '');\n\n const treeMatchWithPath = normalized.match(\n /^[^/]+\\/[^/]+\\/tree\\/[^/]+\\/(.+)$/,\n );\n if (treeMatchWithPath) {\n normalized = treeMatchWithPath[1];\n } else {\n const treeMatchBranchOnly = normalized.match(\n /^([^/]+)\\/([^/]+)\\/tree\\/[^/]+$/,\n );\n if (treeMatchBranchOnly) {\n normalized = treeMatchBranchOnly[2];\n }\n }\n\n normalized = normalized.replace(/#.*$/, '');\n const lastSegment = normalized.split('/').filter(Boolean).pop();\n return lastSegment || 'skill';\n }\n\n private scanForSkills(dir: string): string[] {\n const skills: string[] = [];\n\n const rootSkill = path.join(dir, 'SKILL.md');\n if (fs.existsSync(rootSkill)) {\n skills.push(rootSkill);\n return skills;\n }\n\n const skillsDir = path.join(dir, 'skills');\n if (fs.existsSync(skillsDir) && fs.statSync(skillsDir).isDirectory()) {\n const entries = fs.readdirSync(skillsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (isDirOrSymlinkToDir(skillsDir, entry)) {\n const skillPath = path.join(skillsDir, entry.name, 'SKILL.md');\n if (fs.existsSync(skillPath)) {\n skills.push(skillPath);\n }\n }\n }\n if (skills.length > 0) {\n return skills;\n }\n }\n\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (isDirOrSymlinkToDir(dir, entry)) {\n const skillPath = path.join(dir, entry.name, 'SKILL.md');\n if (fs.existsSync(skillPath)) {\n skills.push(skillPath);\n }\n }\n }\n\n return skills;\n }\n\n private copyDirectory(src: string, dest: string): void {\n fs.mkdirSync(dest, { recursive: true });\n const entries = fs.readdirSync(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const destPath = path.join(dest, entry.name);\n\n if (entry.isDirectory()) {\n this.copyDirectory(srcPath, destPath);\n } else {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n }\n\n private parseSkillFileForAdd(\n content: string,\n skillPath: string,\n ): { name: string; description: string } | null {\n try {\n const { attributes } = safeFrontMatter<{\n name?: string;\n description?: string;\n }>(content, skillPath);\n\n if (!attributes.name || !attributes.description) {\n return null;\n }\n\n if (\n attributes.name.length > MAX_NAME_LENGTH ||\n attributes.name.includes('\\n')\n ) {\n return null;\n }\n\n if (attributes.description.length > MAX_DESCRIPTION_LENGTH) {\n return null;\n }\n\n return {\n name: attributes.name,\n description: attributes.description,\n };\n } catch {\n return null;\n }\n }\n\n async previewSkills(source: string): Promise<PreviewSkillsResult> {\n const tempDir = path.join(os.tmpdir(), `oricore-skill-${Date.now()}`);\n const result: PreviewSkillsResult = {\n tempDir,\n skills: [],\n errors: [],\n };\n\n const normalizedSource = this.normalizeSource(source);\n const emitter = degit(normalizedSource, { force: true });\n await emitter.clone(tempDir);\n\n const skillPaths = this.scanForSkills(tempDir);\n\n if (skillPaths.length === 0) {\n result.errors.push({\n path: source,\n message: 'No skills found (no SKILL.md files)',\n });\n return result;\n }\n\n for (const skillPath of skillPaths) {\n const content = fs.readFileSync(skillPath, 'utf-8');\n const parsed = this.parseSkillFileForAdd(content, skillPath);\n\n if (!parsed) {\n result.errors.push({\n path: skillPath,\n message: 'Invalid skill file',\n });\n continue;\n }\n\n result.skills.push({\n name: parsed.name,\n description: parsed.description,\n skillPath,\n skillDir: path.dirname(skillPath),\n });\n }\n\n return result;\n }\n\n async installFromPreview(\n preview: PreviewSkillsResult,\n selectedSkills: SkillPreview[],\n source: string,\n options: AddSkillOptions = {},\n ): Promise<AddSkillResult> {\n const {\n global: isGlobal = false,\n claude: isClaude = false,\n overwrite = false,\n name,\n targetDir,\n } = options;\n const result: AddSkillResult = {\n installed: [],\n skipped: [],\n errors: [],\n };\n\n if (name && selectedSkills.length > 1) {\n throw new Error('Cannot use --name when installing multiple skills');\n }\n\n const targetBaseDir = targetDir\n ? targetDir\n : isClaude && isGlobal\n ? path.join(\n path.dirname(this.paths.globalConfigDir),\n '.claude',\n 'skills',\n )\n : isClaude\n ? path.join(\n path.dirname(this.paths.projectConfigDir),\n '.claude',\n 'skills',\n )\n : isGlobal\n ? path.join(this.paths.globalConfigDir, 'skills')\n : path.join(this.paths.projectConfigDir, 'skills');\n\n fs.mkdirSync(targetBaseDir, { recursive: true });\n\n for (const skill of selectedSkills) {\n const isRootSkill = skill.skillDir === preview.tempDir;\n const folderName =\n name ||\n (isRootSkill\n ? this.extractFolderName(source)\n : path.basename(skill.skillDir));\n const skillTargetDir = path.join(targetBaseDir, folderName);\n\n if (fs.existsSync(skillTargetDir)) {\n if (!overwrite) {\n result.skipped.push({\n name: skill.name,\n reason: 'already exists',\n });\n continue;\n }\n fs.rmSync(skillTargetDir, { recursive: true });\n }\n\n this.copyDirectory(skill.skillDir, skillTargetDir);\n\n result.installed.push({\n name: skill.name,\n description: skill.description,\n path: path.join(skillTargetDir, 'SKILL.md'),\n source:\n isClaude && isGlobal\n ? SkillSource.GlobalClaude\n : isClaude\n ? SkillSource.ProjectClaude\n : isGlobal\n ? SkillSource.Global\n : SkillSource.Project,\n });\n }\n\n await this.loadSkills();\n return result;\n }\n\n cleanupPreview(preview: PreviewSkillsResult): void {\n if (fs.existsSync(preview.tempDir)) {\n fs.rmSync(preview.tempDir, { recursive: true });\n }\n }\n\n async removeSkill(\n name: string,\n targetDir?: string,\n ): Promise<{ success: boolean; error?: string }> {\n const skillsDir =\n targetDir || path.join(this.paths.projectConfigDir, 'skills');\n const skillDir = path.join(skillsDir, name);\n\n if (!fs.existsSync(skillDir)) {\n return { success: false, error: 'Skill not found' };\n }\n\n const skillPath = path.join(skillDir, 'SKILL.md');\n if (!fs.existsSync(skillPath)) {\n return { success: false, error: 'Invalid skill directory (no SKILL.md)' };\n }\n\n fs.rmSync(skillDir, { recursive: true });\n await this.loadSkills();\n return { success: true };\n }\n}\n","import type { Context } from '../core/context';\nimport type { SkillMetadata, SkillSource } from './skill';\n\n/**\n * Bundled skill definition for TypeScript-encoded skills.\n * This allows skills to be defined programmatically with dynamic behavior.\n */\nexport interface BundledSkillDefinition {\n /** Unique skill name */\n name: string;\n /** Skill description */\n description: string;\n /**\n * Tools that this skill is allowed to use.\n * If specified, only these tools will be available when the skill executes.\n */\n allowedTools?: string[];\n /**\n * Execution context for the skill.\n * - 'inline': Skill content is injected into current conversation (default)\n * - 'fork': Skill runs in an isolated sub-agent\n */\n context?: 'inline' | 'fork';\n /**\n * Agent type to use when context is 'fork'.\n * If not specified, defaults to 'general-purpose'.\n */\n agent?: string;\n /**\n * Whether this skill can be invoked by users via slash commands.\n * @default true\n */\n userInvocable?: boolean;\n /**\n * Whether this skill can be invoked by the model via SkillTool.\n * @default true\n */\n modelInvocable?: boolean;\n /**\n * Aliases for the skill name.\n * Allows the skill to be invoked by alternative names.\n */\n aliases?: string[];\n /**\n * When to use this skill.\n * Provides guidance to the model about when to invoke this skill.\n */\n whenToUse?: string;\n /**\n * Hint for arguments that can be passed to the skill.\n * Example: '[file_path] [issue_description]'\n */\n argumentHint?: string;\n /**\n * Function to determine if this skill is enabled in the current context.\n * Can be a boolean or a function that receives the context.\n */\n isEnabled?: boolean | ((context: Context) => boolean);\n /**\n * Embedded reference files that will be extracted when the skill runs.\n * Key is the filename, value is the file content.\n */\n files?: Record<string, string>;\n /**\n * Generate the skill prompt content.\n * This function is called when the skill is invoked.\n * @param args Arguments passed to the skill\n * @param context The execution context\n * @returns Promise resolving to the skill prompt content\n */\n getPrompt: (args: string, context: Context) => Promise<string> | string;\n}\n\n/**\n * Registry for bundled skills.\n * Skills registered here are built into the engine binary.\n */\nclass BundledSkillRegistry {\n private skills: Map<string, BundledSkillDefinition> = new Map();\n private aliases: Map<string, string> = new Map();\n\n /**\n * Register a bundled skill.\n * @param definition The skill definition\n */\n register(definition: BundledSkillDefinition): void {\n if (!definition.name) {\n throw new Error('Bundled skill must have a name');\n }\n if (!definition.description) {\n throw new Error('Bundled skill must have a description');\n }\n if (!definition.getPrompt) {\n throw new Error('Bundled skill must have a getPrompt function');\n }\n\n this.skills.set(definition.name, definition);\n\n // Register aliases\n if (definition.aliases) {\n for (const alias of definition.aliases) {\n this.aliases.set(alias, definition.name);\n }\n }\n }\n\n /**\n * Get a bundled skill by name or alias.\n * @param name Skill name or alias\n * @returns The skill definition or undefined if not found\n */\n get(name: string): BundledSkillDefinition | undefined {\n // Check direct name first\n const skill = this.skills.get(name);\n if (skill) return skill;\n\n // Check aliases\n const aliasedName = this.aliases.get(name);\n if (aliasedName) {\n return this.skills.get(aliasedName);\n }\n\n return undefined;\n }\n\n /**\n * Get all registered bundled skills.\n * @param context Optional context to filter by isEnabled\n * @returns Array of skill definitions\n */\n getAll(context?: Context): BundledSkillDefinition[] {\n return Array.from(this.skills.values()).filter((skill) => {\n if (skill.isEnabled === undefined) return true;\n if (typeof skill.isEnabled === 'boolean') return skill.isEnabled;\n if (typeof skill.isEnabled === 'function' && context) {\n return skill.isEnabled(context);\n }\n return true;\n });\n }\n\n /**\n * Check if a skill is registered.\n * @param name Skill name or alias\n */\n has(name: string): boolean {\n return this.skills.has(name) || this.aliases.has(name);\n }\n\n /**\n * Unregister a skill.\n * @param name Skill name\n */\n unregister(name: string): void {\n const skill = this.skills.get(name);\n if (skill && skill.aliases) {\n for (const alias of skill.aliases) {\n this.aliases.delete(alias);\n }\n }\n this.skills.delete(name);\n }\n\n /**\n * Clear all registered skills.\n */\n clear(): void {\n this.skills.clear();\n this.aliases.clear();\n }\n}\n\n// Global registry instance\nexport const bundledSkillRegistry = new BundledSkillRegistry();\n\n/**\n * Convert a bundled skill definition to SkillMetadata format.\n * This is used internally when loading bundled skills into the SkillManager.\n */\nexport function bundledSkillToMetadata(\n definition: BundledSkillDefinition,\n source: SkillSource = 'builtin' as SkillSource,\n): SkillMetadata {\n return {\n name: definition.name,\n description: definition.description,\n path: `bundled://${definition.name}`,\n source,\n allowedTools: definition.allowedTools,\n context: definition.context,\n agent: definition.agent,\n userInvocable: definition.userInvocable ?? true,\n modelInvocable: definition.modelInvocable ?? true,\n // Note: bundled skills don't support 'paths' conditional activation\n };\n}\n\n/**\n * Helper function to create a simple bundled skill.\n */\nexport function createBundledSkill(\n config: Omit<BundledSkillDefinition, 'getPrompt'> & {\n prompt: string | ((args: string, context: Context) => Promise<string> | string);\n },\n): BundledSkillDefinition {\n return {\n ...config,\n getPrompt:\n typeof config.prompt === 'string'\n ? () => config.prompt as string\n : config.prompt,\n };\n}\n\n/**\n * Register a bundled skill using a simplified configuration.\n */\nexport function registerBundledSkill(\n config: Omit<BundledSkillDefinition, 'getPrompt'> & {\n prompt: string | ((args: string, context: Context) => Promise<string> | string);\n },\n): void {\n const skill = createBundledSkill(config);\n bundledSkillRegistry.register(skill);\n}\n","import EventEmitter from 'events';\nimport { randomUUID } from '../utils/randomUUID';\n\nexport type MessageId = string;\nexport type BaseMessage = {\n id: MessageId;\n timestamp: number;\n};\nexport type RequestMessage = BaseMessage & {\n type: 'request';\n method: string;\n params: any;\n};\nexport type ResponseMessage = BaseMessage & {\n type: 'response';\n result?: any;\n error?: any;\n};\nexport type EventMessage = BaseMessage & {\n type: 'event';\n event: string;\n data: any;\n};\nexport type Message = RequestMessage | ResponseMessage | EventMessage;\nexport type ConnectionState =\n | 'disconnected'\n | 'connecting'\n | 'connected'\n | 'reconnecting'\n | 'error'\n | 'closed';\nexport interface MessageTransport {\n send: (message: Message) => Promise<void>;\n onMessage: (handler: (message: Message) => void) => void;\n onError: (handler: (error: Error) => void) => void;\n onClose: (handler: () => void) => void;\n close: () => Promise<void>;\n isConnected: () => boolean;\n}\n\nfunction createRequest(\n id: MessageId,\n method: string,\n params: any,\n): RequestMessage {\n return {\n type: 'request',\n id,\n method,\n params,\n timestamp: Date.now(),\n };\n}\n\nfunction createResponse(\n id: MessageId,\n result: any,\n error?: any,\n): ResponseMessage {\n return {\n type: 'response',\n id,\n result,\n error,\n timestamp: Date.now(),\n };\n}\nfunction createErrorResponse(id: MessageId, error: any): ResponseMessage {\n return {\n type: 'response',\n id,\n error,\n timestamp: Date.now(),\n };\n}\nfunction createEvent(id: MessageId, event: string, data: any): EventMessage {\n return {\n type: 'event',\n id,\n event,\n data,\n timestamp: Date.now(),\n };\n}\n\nconst MAX_BUFFER_SIZE = 1000;\n\nexport class DirectTransport extends EventEmitter implements MessageTransport {\n private peer?: DirectTransport;\n private state: ConnectionState = 'connected';\n private messageBuffer: Message[] = [];\n constructor() {\n super();\n }\n static createPair(): [DirectTransport, DirectTransport] {\n const transport1 = new DirectTransport();\n const transport2 = new DirectTransport();\n transport1.setPeer(transport2);\n transport2.setPeer(transport1);\n return [transport1, transport2];\n }\n setPeer(peer: DirectTransport) {\n this.peer = peer;\n this.flushBuffer();\n }\n isConnected() {\n return this.state === 'connected';\n }\n onMessage(handler: (message: Message) => void): void {\n this.on('message', handler);\n }\n onError(handler: (error: Error) => void): void {\n this.on('error', handler);\n }\n onClose(handler: () => void): void {\n this.on('close', handler);\n }\n async send(message: Message) {\n try {\n if (this.peer && this.peer.isConnected()) {\n setImmediate(() => {\n this.peer!.receive(message);\n });\n } else {\n this.messageBuffer.push(message);\n }\n } catch (error) {\n this.emit('error', error);\n throw error;\n }\n }\n async close() {\n this.state = 'closed';\n }\n private flushBuffer() {\n if (\n !this.peer ||\n !this.peer.isConnected() ||\n this.messageBuffer.length === 0\n ) {\n return;\n }\n if (this.messageBuffer.length > MAX_BUFFER_SIZE) {\n this.emit('error', new Error('Message buffer overflow'));\n return;\n }\n const messages = [...this.messageBuffer];\n this.messageBuffer.length = 0;\n for (const message of messages) {\n setImmediate(() => {\n this.peer!.receive(message);\n });\n }\n }\n private receive(message: Message) {\n if (this.state !== 'connected') {\n return;\n }\n try {\n this.emit('message', message);\n } catch (error) {\n this.emit('error', error);\n }\n }\n}\n\ntype PendingRequest = {\n id: MessageId;\n method: string;\n timestamp: number;\n timeout?: NodeJS.Timeout;\n resolve: (result: any) => void;\n reject: (error: Error) => void;\n};\nexport type MessageHandler = (data: any) => Promise<any>;\nexport type EventHandler = (data: any) => void;\n\nexport class MessageBus extends EventEmitter {\n public messageHandlers = new Map<string, MessageHandler>();\n private transport?: MessageTransport;\n private pendingRequests = new Map<MessageId, PendingRequest>();\n private eventHandlers = new Map<string, Set<EventHandler>>();\n constructor() {\n super();\n }\n setTransport(transport: MessageTransport) {\n this.transport = transport;\n transport.onMessage((message) => {\n this.handleIncomingMessage(message);\n });\n transport.onError((error) => {\n this.emit('error', error);\n });\n transport.onClose(() => {\n this.emit('close');\n });\n this.emit('transportReady');\n }\n isConnected() {\n return this.transport?.isConnected() ?? false;\n }\n\n // Request method - generic version for engine package\n /**\n * Send a request to the message bus and wait for a response.\n *\n * @param method - The method name to call (e.g., 'toolApproval')\n * @param params - The parameters to pass to the method handler\n * @param options.timeout - Optional timeout in milliseconds (0 = no timeout)\n * @returns Promise that resolves with the handler's return value\n *\n * @example\n * // Tool approval with session context\n * const result = await messageBus.request('toolApproval', {\n * toolUse: { name: 'bash', params: { command: 'ls' }, callId: '123' },\n * category: 'command',\n * sessionId: 'session-abc' // Used for session identification\n * });\n *\n * @example\n * // Register a handler for the request\n * messageBus.registerHandler('toolApproval', async ({ toolUse, category, sessionId }) => {\n * // sessionId can be used for:\n * // - Logging which session requested approval\n * // - UI routing to the correct session window\n * // - Multi-session management\n * return { approved: true, params: undefined, denyReason: undefined };\n * });\n */\n async request(\n method: string,\n params: any,\n options: { timeout?: number } = {},\n ): Promise<any> {\n if (!this.transport) {\n throw new Error('No transport available');\n }\n if (!this.transport.isConnected()) {\n throw new Error('Transport is not connected');\n }\n const id = randomUUID();\n const timeout = options.timeout ?? 0;\n const requestMessage = createRequest(id, method, params);\n const promise = new Promise<any>((resolve, reject) => {\n const pendingRequest: PendingRequest = {\n id,\n method,\n timestamp: Date.now(),\n resolve,\n reject,\n };\n if (timeout > 0) {\n pendingRequest.timeout = setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(new Error(`Request timeout after ${timeout}ms: ${method}`));\n }, timeout);\n }\n this.pendingRequests.set(id, pendingRequest);\n });\n try {\n await this.transport.send(requestMessage);\n return await promise;\n } catch (error) {\n // Clean up pending request if send fails or promise rejects\n const pending = this.pendingRequests.get(id);\n if (pending) {\n if (pending.timeout) {\n clearTimeout(pending.timeout);\n }\n this.pendingRequests.delete(id);\n }\n throw error;\n }\n }\n // Register handler - generic version for engine package\n /**\n * Register a handler for a specific request method.\n *\n * @param method - The method name to handle (e.g., 'toolApproval')\n * @param handler - Async function that receives params and returns a result\n *\n * @example\n * // Tool approval handler with session support\n * messageBus.registerHandler('toolApproval', async (params) => {\n * const { toolUse, category, sessionId } = params;\n *\n * // sessionId enables:\n * // 1. Session-specific logging and monitoring\n * // 2. UI routing to the correct session window\n * // 3. Multi-session approval tracking\n * // 4. Session-level permissions and policies\n *\n * console.log(`[${sessionId}] Tool approval request: ${toolUse.name}`);\n *\n * // Return approval result\n * return {\n * approved: true,\n * params: toolUse.params, // optionally modify params\n * denyReason: undefined // or provide reason if denied\n * };\n * });\n *\n * // Backward compatibility: handlers can ignore sessionId\n * messageBus.registerHandler('toolApproval', async ({ toolUse, category }) => {\n * // Old code that doesn't use sessionId still works\n * return { approved: true };\n * });\n */\n registerHandler(method: string, handler: MessageHandler) {\n this.messageHandlers.set(method, handler);\n }\n unregisterHandler(method: string) {\n if (this.messageHandlers.has(method)) {\n this.messageHandlers.delete(method);\n }\n }\n async emitEvent(event: string, data: any) {\n if (!this.transport) {\n return;\n }\n if (!this.transport.isConnected()) {\n return;\n }\n const id = randomUUID();\n const message = createEvent(id, event, data);\n try {\n await this.transport.send(message);\n } catch (error) {\n throw error;\n }\n }\n onEvent(event: string, handler: EventHandler) {\n if (!this.eventHandlers.has(event)) {\n this.eventHandlers.set(event, new Set());\n }\n this.eventHandlers.get(event)!.add(handler);\n }\n offEvent(event: string, handler: EventHandler) {\n const handlers = this.eventHandlers.get(event);\n if (handlers) {\n handlers.delete(handler);\n if (handlers.size === 0) {\n this.eventHandlers.delete(event);\n }\n }\n }\n private async handleIncomingMessage(message: Message) {\n try {\n if (!message.id || !message.timestamp || !message.type) {\n throw new Error('Invalid message format');\n }\n switch (message.type) {\n case 'request':\n await this.handleRequest(message as RequestMessage);\n break;\n case 'response':\n this.handleResponse(message as ResponseMessage);\n break;\n case 'event':\n this.handleEvent(message as EventMessage);\n break;\n default:\n break;\n }\n } catch (error) {\n this.emit('messageError', error, message);\n }\n }\n private async handleRequest(message: RequestMessage) {\n const { id, method, params } = message;\n const handler = this.messageHandlers.get(method);\n if (!handler) {\n await this.sendResponse(\n createErrorResponse(id, {\n message: `No handler registered for method: ${method}`,\n code: 'METHOD_NOT_FOUND',\n }),\n );\n return;\n }\n try {\n const result = await handler(params);\n const response = createResponse(id, result);\n await this.sendResponse(response);\n } catch (error) {\n await this.sendResponse(\n createErrorResponse(id, {\n message: error instanceof Error ? error.message : String(error),\n code: 'HANDLER_ERROR',\n details: error instanceof Error ? { stack: error.stack } : undefined,\n }),\n );\n }\n }\n private async handleResponse(message: ResponseMessage) {\n const { id, result, error } = message;\n const pending = this.pendingRequests.get(id);\n if (!pending) {\n return;\n }\n if (pending.timeout) {\n clearTimeout(pending.timeout);\n }\n this.pendingRequests.delete(id);\n if (error) {\n // Create a more informative error\n const errorMessage =\n typeof error === 'object' && error.message\n ? error.message\n : typeof error === 'string'\n ? error\n : 'Request failed';\n\n const err = new Error(errorMessage);\n // Attach the full error details\n (err as any).details = error.details\n ? Array.isArray(error.details)\n ? error.details.join('\\n')\n : JSON.stringify(error.details)\n : error;\n (err as any).method = pending.method;\n\n pending.reject(err);\n } else {\n pending.resolve(result);\n }\n }\n private async handleEvent(message: EventMessage) {\n const { event, data } = message;\n const handlers = this.eventHandlers.get(event);\n if (!handlers || handlers.size === 0) {\n return;\n }\n for (const handler of handlers) {\n try {\n handler(data);\n } catch (error) {\n this.emit('eventHandlerError', error, event, data);\n }\n }\n }\n private async sendResponse(response: ResponseMessage) {\n if (!this.transport) {\n return;\n }\n try {\n await this.transport.send(response);\n } catch (error) {\n throw error;\n }\n }\n}\n","/**\n * Node.js platform implementation\n * Provides Node.js-specific implementations for the PlatformAdapter interface\n */\n\nimport fs from 'node:fs';\nimport path from 'pathe';\nimport { execSync } from 'node:child_process';\nimport os from 'node:os';\nimport type { PlatformAdapter, ExecOptions, ExecResult, Stats } from './types';\n\nexport class NodePlatform implements PlatformAdapter {\n // File system - async\n readFile = (path: string): Promise<string> =>\n fs.promises.readFile(path, 'utf-8');\n\n writeFile = (path: string, content: string): Promise<void> =>\n fs.promises.writeFile(path, content, 'utf-8');\n\n // File system - sync\n readFileSync = (path: string): string =>\n fs.readFileSync(path, 'utf-8');\n\n writeFileSync = (path: string, content: string): void =>\n fs.writeFileSync(path, content, 'utf-8');\n\n existsSync = (path: string): boolean =>\n fs.existsSync(path);\n\n mkdirSync = (path: string, options?: { recursive: boolean }): void => {\n fs.mkdirSync(path, options);\n };\n\n readdirSync = (path: string): string[] =>\n fs.readdirSync(path);\n\n statSync = (path: string): Stats => {\n const stats = fs.statSync(path);\n return {\n size: stats.size,\n mtime: stats.mtimeMs,\n birthtime: stats.birthtimeMs,\n };\n };\n\n // Process\n cwd = (): string => process.cwd();\n\n env = process.env;\n\n platform = process.platform;\n\n // Exec\n exec = async (command: string, options?: ExecOptions): Promise<ExecResult> => {\n try {\n const stdout = execSync(command, {\n cwd: options?.cwd,\n env: { ...process.env, ...options?.env },\n timeout: options?.timeout,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n return {\n stdout: stdout.toString(),\n stderr: '',\n exitCode: 0,\n };\n } catch (error: any) {\n return {\n stdout: error.stdout?.toString() || '',\n stderr: error.stderr?.toString() || error.message || '',\n exitCode: error.status || 1,\n };\n }\n };\n\n // Paths\n join = (...paths: string[]): string => path.join(...paths);\n\n dirname = (filePath: string): string => path.dirname(filePath);\n\n basename = (filePath: string): string => path.basename(filePath);\n\n resolve = (...paths: string[]): string => path.resolve(...paths);\n\n // Configuration directories\n getConfigDir = (): string => {\n const base = process.platform === 'darwin'\n ? path.join(os.homedir(), 'Library', 'Application Support')\n : process.platform === 'win32'\n ? process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming')\n : path.join(os.homedir(), '.config');\n return base;\n };\n\n getDataDir = (): string => {\n const base = process.platform === 'darwin'\n ? path.join(os.homedir(), 'Library', 'Application Support')\n : process.platform === 'win32'\n ? process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming')\n : path.join(os.homedir(), '.local', 'share');\n return base;\n };\n}\n\n// Export a singleton instance for convenience\nexport const nodePlatform = new NodePlatform();\n","import fs from 'fs';\nimport path from 'pathe';\nimport type { NormalizedMessage } from './core/message';\nimport { createUserMessage } from './core/message';\n\n/**\n * JsonlLogger - Handles persistent logging of messages to JSONL files\n *\n * Each message is appended as a JSON line, enabling:\n * - Session persistence across restarts\n * - Message history recovery\n * - Debugging and auditing\n */\nexport class JsonlLogger {\n filePath: string;\n lastUuid: string | null = null;\n\n constructor(opts: { filePath: string }) {\n this.filePath = opts.filePath;\n this.lastUuid = this.getLatestUuid();\n }\n\n /**\n * Get the UUID of the last message in the log file\n * Used for chaining new messages to the conversation\n */\n getLatestUuid(): string | null {\n if (!fs.existsSync(this.filePath)) {\n return null;\n }\n try {\n const file = fs.readFileSync(this.filePath, 'utf8');\n const lines = file.split('\\n').filter(Boolean);\n if (lines.length === 0) {\n return null;\n }\n const lastLine = lines[lines.length - 1];\n const message = JSON.parse(lastLine);\n return message.uuid || null;\n } catch {\n return null;\n }\n }\n\n /**\n * Add a message to the log file\n * Also updates the lastUuid for chaining\n */\n addMessage(opts: { message: NormalizedMessage & { sessionId: string } }): NormalizedMessage & { sessionId: string } {\n const dir = path.dirname(this.filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n const message = opts.message;\n fs.appendFileSync(this.filePath, JSON.stringify(message) + '\\n');\n this.lastUuid = message.uuid;\n return message;\n }\n\n /**\n * Add a user message to the log file\n * Convenience method that creates a user message with proper chaining\n */\n addUserMessage(content: string, sessionId: string): NormalizedMessage & { sessionId: string } {\n const message = {\n ...createUserMessage(content, this.lastUuid),\n sessionId,\n };\n return this.addMessage({\n message,\n });\n }\n}\n","/**\n * Mode Registry\n *\n * Manages AI interaction modes\n */\n\nimport type { Mode, ModeRegistry, ModeType } from './types';\n\nexport class ModeRegistryImpl implements ModeRegistry {\n private modes = new Map<ModeType, Mode>();\n\n register(mode: Mode): void {\n if (this.modes.has(mode.id)) {\n throw new Error(`Mode ${mode.id} is already registered`);\n }\n this.modes.set(mode.id, mode);\n }\n\n unregister(id: ModeType): void {\n this.modes.delete(id);\n }\n\n get(id: ModeType): Mode | undefined {\n return this.modes.get(id);\n }\n\n getAll(): Mode[] {\n return Array.from(this.modes.values());\n }\n\n has(id: ModeType): boolean {\n return this.modes.has(id);\n }\n}\n\n/**\n * Global mode registry instance\n */\nexport const modeRegistry = new ModeRegistryImpl();\n","/**\n * Built-in Modes\n *\n * Pre-defined AI interaction modes\n */\n\nimport type { Mode } from './types';\n\n/**\n * Default mode - general purpose AI assistant\n */\nexport const defaultMode: Mode = {\n id: 'default',\n name: 'Default',\n description: 'General purpose AI coding assistant',\n config: {\n systemPrompt: `You are Claude Code, an AI programming assistant.\n\n## Core Principles\n- Be concise and direct\n- Show code when helpful\n- Use tools to complete tasks\n- Ask for clarification when needed\n- Verify your work when possible\n\n## Tool Usage\n- Use read tools to understand code\n- Use write/edit tools to make changes\n- Use bash to run commands and tests\n- Use todo to track progress\n\n## Communication Style\n- Be helpful but concise\n- Focus on what matters\n- Explain trade-offs when relevant`,\n write: true,\n todo: true,\n askUserQuestion: false,\n task: true,\n maxTurns: 50,\n autoCompact: true,\n },\n};\n\n/**\n * Brainstorm mode - interactive design and ideation\n */\nexport const brainstormMode: Mode = {\n id: 'brainstorm',\n name: 'Brainstorm',\n description: 'Interactive design and ideation mode - asks questions to refine ideas',\n config: {\n systemPrompt: `# Brainstorming Ideas Into Designs\n\n## Overview\nTransform rough ideas into fully-formed designs through structured questioning and alternative exploration.\n\n**Core principle:** Ask questions to understand, explore alternatives, present design incrementally for validation.\n\n**Announce at start:** \"I'm refining your idea into a design.\"\n\n## Critical Constraints\n- **DO NOT WRITE CODE** (except small snippets for illustration)\n- **DO NOT EDIT FILES**\n- This is a **DESIGN** phase, not an implementation phase\n- Even if the input looks like a coding task, you must TREAT IT AS A TOPIC FOR DESIGN DISCUSSION first\n\n## The Process\n\n### Phase 1: Understanding\n- Check current project state in working directory\n- Ask ONE question at a time to refine the idea\n- **IMPORTANT: Use the askUserQuestion tool when asking clarification questions**\n- Prefer multiple choice when possible\n- Gather: Purpose, constraints, success criteria\n\n### Phase 2: Exploration\n- Propose 2-3 different approaches\n- For each: Core architecture, trade-offs, complexity assessment\n- Ask which approach resonates\n\n### Phase 3: Design Presentation\n- Present in 200-300 word sections\n- Cover: Architecture, components, data flow, error handling, testing\n- Ask after each section: \"Does this look right so far?\"\n\n## When to Revisit Earlier Phases\nYou can and should go backward when:\n- Partner reveals new constraint during Phase 2 or 3 → Return to Phase 1\n- Validation shows fundamental gap in requirements → Return to Phase 1\n- Partner questions approach during Phase 3 → Return to Phase 2\n- Something doesn't make sense → Go back and clarify\n\nDon't force forward linearly when going backward would give better results.\n\n## Remember\n- One question per message during Phase 1\n- Apply YAGNI ruthlessly\n- Explore 2-3 alternatives before settling\n- Present incrementally, validate as you go\n- Go backward when needed - flexibility > rigid progression\n- Don't edit or write code during brainstorming`,\n write: false,\n todo: false,\n askUserQuestion: true, // Critical for interactive brainstorming\n task: false,\n maxTurns: 50,\n autoCompact: false, // Keep full conversation for context\n },\n};\n\n/**\n * Plan mode - create implementation plans\n */\nexport const planMode: Mode = {\n id: 'plan',\n name: 'Plan',\n description: 'Create detailed implementation plans',\n config: {\n systemPrompt: `# Writing Plans\n\n## Overview\nWrite comprehensive implementation plans assuming the engineer has zero context for our codebase and questionable taste. Document everything they need to know: which files to touch for each task, code, testing, docs they might need to check, how to test it. Give them the whole plan as bite-sized tasks. DRY. YAGNI.\n\nAssume they are a skilled developer, but know almost nothing about our toolset or problem domain. Assume they don't know good test design very well.\n\n**Announce at start:** \"I'm creating the implementation plan.\"\n\n**Save plans to:** \\`docs/plans/YYYY-MM-DD-<feature-name>.md\\`\n\n## Bite-Sized Task Granularity\n\nEach step is one action (2-5 minutes):\n- \"Write the failing test\" - step\n- \"Run it to make sure it fails\" - step\n- \"Implement the minimal code to make the test pass\" - step\n- \"Run the tests and make sure they pass\" - step\n- \"Commit\" - step\n\n## Plan Document Header\n\nEvery plan MUST start with this header:\n\n\\`\\`\\`markdown\n# [Feature Name] Implementation Plan\n\n**Goal:** [One sentence describing what this builds]\n\n**Architecture:** [2-3 sentences about approach]\n\n**Tech Stack:** [Key technologies/libraries]\n\n---\n\\`\\`\\`\n\n## Task Structure\n\n\\`\\`\\`markdown\n### Task N: [Component Name]\n\n**Files:**\n- Create: \\`exact/path/to/file.py\\`\n- Modify: \\`exact/path/to/existing.py:123-145\\`\n- Test: \\`tests/exact/path/to/test.py\\`\n\n**Step 1: Write the failing test**\n[code here]\n\n**Step 2: Run test to verify it fails**\nRun: \\`pytest tests/path/test.py::test_name -v\\`\nExpected: FAIL\n\n**Step 3: Write minimal implementation**\n[code here]\n\n**Step 4: Run test to verify it passes**\nRun: \\`pytest tests/path/test.py::test_name -v\\`\nExpected: PASS\n\\`\\`\\`\n\n## Remember\n- Exact file paths always\n- Complete code in plan (not \"add validation\")\n- Exact commands with expected output\n- DRY, YAGNI`,\n write: true,\n todo: true,\n askUserQuestion: true,\n task: false,\n maxTurns: 50,\n autoCompact: true,\n },\n};\n\n/**\n * Review mode - code review and analysis\n */\nexport const reviewMode: Mode = {\n id: 'review',\n name: 'Review',\n description: 'Code review and analysis mode',\n config: {\n systemPrompt: `# Code Review Mode\n\nYou are an expert code reviewer. Your role is to:\n\n1. **Understand the context**\n - Read the files mentioned in the diff or description\n - Understand what change is being made\n - Consider the broader codebase architecture\n\n2. **Review systematically**\n - Correctness: Does the code work as intended?\n - Design: Is it well-structured and maintainable?\n - Performance: Are there obvious performance issues?\n - Security: Are there security vulnerabilities?\n - Testing: Is there adequate test coverage?\n\n3. **Provide constructive feedback**\n - Be specific about issues\n - Explain why something is problematic\n - Suggest improvements\n - Acknowledge good practices\n\n4. **Prioritize issues**\n - Critical: Must fix (bugs, security)\n - Important: Should fix (design, performance)\n - Nice to have: Could improve (style, minor optimizations)\n\nFormat your review clearly with:\n- Summary\n- Issues (by priority)\n- Positive observations\n- Suggestions`,\n write: false,\n todo: false,\n askUserQuestion: false,\n task: false,\n maxTurns: 10,\n autoCompact: false,\n },\n};\n\n/**\n * Debug mode - troubleshooting and debugging\n */\nexport const debugMode: Mode = {\n id: 'debug',\n name: 'Debug',\n description: 'Troubleshooting and debugging mode',\n config: {\n systemPrompt: `# Debug Mode\n\nYou are an expert debugger. Your approach:\n\n1. **Understand the problem**\n - Ask what error or behavior they're seeing\n - Get the relevant code\n - Understand expected vs actual behavior\n\n2. **Form hypotheses**\n - Based on the symptoms, what could cause this?\n - Prioritize most likely causes\n\n3. **Test hypotheses**\n - Use read tools to examine code\n - Use bash to run tests or checks\n - Use logs if available\n\n4. **Propose fixes**\n - Start with minimal changes\n - Explain why the fix works\n - Suggest how to prevent similar issues\n\nBe methodical and systematic. Don't guess - verify.`,\n write: true,\n todo: true,\n askUserQuestion: true,\n task: false,\n maxTurns: 50,\n autoCompact: true,\n },\n};\n\n/**\n * All built-in modes\n */\nexport const builtinModes: Mode[] = [\n defaultMode,\n brainstormMode,\n planMode,\n reviewMode,\n debugMode,\n];\n\n/**\n * Register all built-in modes\n */\nexport function registerBuiltinModes(registry: import('./registry').ModeRegistryImpl): void {\n for (const mode of builtinModes) {\n if (!registry.has(mode.id)) {\n registry.register(mode);\n }\n }\n}\n","/**\n * Engine API\n *\n * Main entry point for the OriCore package.\n * Provides a high-level API for AI-powered coding assistance.\n */\n\nimport type { Context } from '../core/context';\nimport { Context as createContext } from '../core/context';\nimport type { Config, ProviderConfig } from '../core/config';\nimport type { MessageBus as IMessageBus } from '../communication/messageBus';\nimport { MessageBus } from '../communication/messageBus';\nimport type { PlatformAdapter } from '../platform';\nimport { NodePlatform } from '../platform/node';\nimport type { Session } from '../session/session';\nimport { Session as createSession } from '../session/session';\nimport { JsonlLogger } from '../jsonl';\nimport { resolveModelWithContext } from '../core/model';\nimport { runLoop, type LoopResult } from '../core/loop';\nimport { resolveTools, Tools } from '../tools/tool';\nimport type { NormalizedMessage } from '../core/message';\nimport type { ToolUse, ToolResult, ToolApprovalResult } from '../tools/tool';\nimport { modeRegistry, registerBuiltinModes, type Mode, type ModeType } from '../modes';\n\n/**\n * Engine initialization options\n */\nexport interface EngineOptions {\n /** Product name (e.g., \"AI Engine\") */\n productName: string;\n /** ASCII art banner for display */\n productASCIIArt?: string;\n /** Version string */\n version: string;\n /** Current working directory */\n cwd?: string;\n /** Fetch implementation (optional, uses globalThis.fetch by default) */\n fetch?: typeof globalThis.fetch;\n /** Platform implementation (defaults to Node.js) */\n platform?: PlatformAdapter;\n /** Message bus for event communication */\n messageBus?: MessageBus;\n}\n\n/**\n * Engine configuration\n */\nexport interface EngineConfig {\n /** Model to use for AI responses */\n model?: string;\n /** Model for planning mode */\n planModel?: string;\n /** Approval mode for tool usage */\n approvalMode?: 'default' | 'autoEdit' | 'yolo';\n /** System prompt override */\n systemPrompt?: string;\n /** Additional system prompt */\n appendSystemPrompt?: string;\n /** Language for responses */\n language?: string;\n /** MCP servers configuration */\n mcpServers?: Record<string, any>;\n /** Tools configuration */\n tools?: Record<string, boolean>;\n /** Plugins to load */\n plugins?: (string | any)[];\n /** Provider configuration (custom API endpoints, keys, etc.) */\n provider?: Record<string, ProviderConfig>;\n}\n\n/**\n * Session creation options\n */\nexport interface SessionOptions {\n /** Session ID (auto-generated if not provided) */\n sessionId?: string;\n /** Resume from existing session */\n resume?: string;\n /** Continue from latest session */\n continue?: boolean;\n}\n\n/**\n * Message sending options\n */\nexport interface SendMessageOptions {\n /** Message content (string or message array) */\n message: string | NormalizedMessage[];\n /** Session ID for persistent conversations */\n sessionId?: string;\n /** Enable write tools (default: true) */\n write?: boolean;\n /** Enable todo tools (default: true) */\n todo?: boolean;\n /** Enable ask user question tool (default: false) */\n askUserQuestion?: boolean;\n /** Enable task/agent tool (default: false) */\n task?: boolean;\n /** Override model for this message */\n model?: string;\n /** Maximum turns (default: 50) */\n maxTurns?: number;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Callback for text delta (streaming) */\n onTextDelta?: (text: string) => Promise<void>;\n /** Callback for complete text */\n onText?: (text: string) => Promise<void>;\n /** Callback for reasoning */\n onReasoning?: (text: string) => Promise<void>;\n /** Callback for tool use */\n onToolUse?: (toolUse: ToolUse) => Promise<ToolUse>;\n /** Callback for tool result */\n onToolResult?: (toolUse: ToolUse, toolResult: ToolResult, approved: boolean) => Promise<ToolResult>;\n /** Callback for tool approval (return false to deny) */\n onToolApprove?: (toolUse: ToolUse) => Promise<ToolApprovalResult>;\n /** Callback for turn completion */\n onTurn?: (turn: any) => Promise<void>;\n}\n\n/**\n * Main Engine class\n *\n * The Engine is the primary interface for interacting with the AI coding assistant.\n * It manages initialization, configuration, and provides access to context.\n */\nexport class Engine {\n private context: Context | null = null;\n private platform: PlatformAdapter;\n private messageBus: MessageBus;\n private options: EngineOptions;\n private initialized = false;\n private currentMode: ModeType = 'default';\n private jsonlLoggers: Map<string, JsonlLogger> = new Map();\n\n constructor(options: EngineOptions) {\n this.options = options;\n this.platform = options.platform || new NodePlatform();\n this.messageBus = options.messageBus || new MessageBus();\n\n // Register built-in modes\n registerBuiltinModes(modeRegistry);\n }\n\n /**\n * Initialize the engine with configuration\n */\n async initialize(config: EngineConfig = {}): Promise<void> {\n const cwd = this.options.cwd || this.platform.cwd();\n\n this.context = await createContext.create({\n cwd,\n productName: this.options.productName,\n productASCIIArt: this.options.productASCIIArt,\n version: this.options.version,\n argvConfig: config,\n plugins: config.plugins || [],\n messageBus: this.messageBus,\n fetch: this.options.fetch,\n });\n\n await this.context.apply({\n hook: 'initialized',\n args: [{ cwd, quiet: false }],\n type: 'series' as any,\n });\n\n this.initialized = true;\n }\n\n /**\n * Create or resume a session\n */\n async createSession(options: SessionOptions = {}): Promise<Session> {\n if (!this.initialized) {\n throw new Error('Engine not initialized. Call initialize() first.');\n }\n\n if (!this.context) {\n throw new Error('Context not available');\n }\n\n const paths = this.context.paths;\n const sessionId = options.sessionId || (() => {\n if (options.resume) {\n return options.resume;\n }\n if (options.continue) {\n return paths.getLatestSessionId() || this.generateSessionId();\n }\n return this.generateSessionId();\n })();\n\n if (options.resume || options.continue) {\n const logPath = paths.getSessionLogPath(sessionId);\n return createSession.resume({ id: sessionId, logPath });\n }\n\n return createSession.create();\n }\n\n /**\n * Get the MessageBus for event communication\n */\n getMessageBus(): MessageBus {\n return this.messageBus;\n }\n\n /**\n * Get the current context\n */\n getContext(): Context {\n if (!this.context) {\n throw new Error('Engine not initialized');\n }\n return this.context;\n }\n\n /**\n * Shutdown the engine and cleanup resources\n */\n async shutdown(): Promise<void> {\n if (this.context) {\n await this.context.destroy();\n this.context = null;\n }\n this.jsonlLoggers.clear();\n this.initialized = false;\n }\n\n /**\n * Get or create a JsonlLogger for a session\n */\n private getLogger(sessionId: string): JsonlLogger {\n if (!this.jsonlLoggers.has(sessionId)) {\n if (!this.context) {\n throw new Error('Context not available');\n }\n const logPath = this.context.paths.getSessionLogPath(sessionId);\n this.jsonlLoggers.set(sessionId, new JsonlLogger({ filePath: logPath }));\n }\n return this.jsonlLoggers.get(sessionId)!;\n }\n\n /**\n * Get list of all sessions\n */\n getSessions() {\n if (!this.context) {\n throw new Error('Context not available');\n }\n return this.context.paths.getAllSessions();\n }\n\n /**\n * Send a message to the AI and get a response\n *\n * This is the main method for interacting with the AI engine.\n * It handles the full conversation loop including tool execution.\n *\n * @param options - Message sending options\n * @returns Promise<LoopResult> - The result of the conversation loop\n */\n async sendMessage(options: SendMessageOptions): Promise<LoopResult> {\n if (!this.initialized || !this.context) {\n throw new Error('Engine not initialized. Call initialize() first.');\n }\n\n const context = this.context;\n const modelId = options.model || context.config.model;\n const resolvedModel = await resolveModelWithContext(modelId, context);\n\n if (!resolvedModel.model) {\n throw new Error(`Failed to resolve model: ${modelId}`);\n }\n\n // Get or create session ID\n const sessionId = options.sessionId || this.generateSessionId();\n\n // Get logger for this session\n const logger = this.getLogger(sessionId);\n\n // Resolve available tools\n const toolsList = await resolveTools({\n context,\n sessionId,\n write: options.write !== false,\n todo: options.todo !== false,\n askUserQuestion: options.askUserQuestion || false,\n task: options.task || false,\n signal: options.signal,\n });\n\n // Get system prompt from config\n const systemPrompt = context.config.systemPrompt || '';\n\n // Load existing session history if session exists\n let sessionHistory: import('../core/history').History | undefined = undefined;\n if (options.sessionId) {\n const { loadSessionMessages } = await import('../session/session');\n const logPath = context.paths.getSessionLogPath(sessionId);\n try {\n const existingMessages = loadSessionMessages({ logPath });\n if (existingMessages.length > 0) {\n const { History } = await import('../core/history');\n sessionHistory = new History({\n messages: existingMessages,\n });\n }\n } catch {\n // Session doesn't exist yet, will be created\n }\n }\n\n // Create the persistence callback that will be used by history.addMessage\n const onMessageCallback = async (message: import('../core/message').NormalizedMessage) => {\n // Persist all messages (user, assistant, tool) to session log\n // We add sessionId here for tracking\n logger.addMessage({ message: { ...message, sessionId } });\n };\n\n // If we have session history, set its onMessage callback\n if (sessionHistory && !sessionHistory.onMessage) {\n sessionHistory.onMessage = onMessageCallback;\n }\n\n // Run the conversation loop\n // The history's onMessage callback will handle persistence\n const result = await runLoop({\n input: options.message,\n history: sessionHistory,\n model: resolvedModel.model,\n tools: new Tools(toolsList),\n cwd: context.cwd,\n systemPrompt,\n maxTurns: options.maxTurns,\n signal: options.signal,\n onTextDelta: options.onTextDelta,\n onText: options.onText,\n onReasoning: options.onReasoning,\n onToolUse: options.onToolUse,\n onToolResult: options.onToolResult,\n onToolApprove: options.onToolApprove,\n onTurn: options.onTurn,\n onMessage: sessionHistory?.onMessage || onMessageCallback,\n });\n\n // Record the model usage if successful\n if (result.success && modelId) {\n context.globalData.addRecentModel(modelId);\n }\n\n return result;\n }\n\n /**\n * Create a simple request-response interaction (single turn)\n *\n * This is a simplified version of sendMessage that returns just the text response.\n * Tools are disabled by default for simple requests.\n *\n * @param message - The message to send\n * @param options - Optional configuration\n * @returns Promise<string> - The AI's text response\n */\n async ask(\n message: string,\n options?: {\n model?: string;\n systemPrompt?: string;\n },\n ): Promise<string> {\n const result = await this.sendMessage({\n message,\n model: options?.model,\n write: false,\n todo: false,\n askUserQuestion: false,\n task: false,\n maxTurns: 1,\n });\n\n if (result.success) {\n return result.data.text || '';\n }\n\n throw new Error(result.error.message);\n }\n\n /**\n * Set the current interaction mode\n *\n * @param mode - The mode to set (e.g., 'brainstorm', 'plan', 'review')\n */\n setMode(mode: ModeType): void {\n if (!modeRegistry.has(mode)) {\n throw new Error(`Unknown mode: ${mode}. Available modes: ${modeRegistry.getAll().map(m => m.id).join(', ')}`);\n }\n this.currentMode = mode;\n }\n\n /**\n * Get the current mode\n */\n getMode(): ModeType {\n return this.currentMode;\n }\n\n /**\n * Get all available modes\n */\n getAvailableModes(): Mode[] {\n return modeRegistry.getAll();\n }\n\n /**\n * Register a custom mode\n *\n * @param mode - The mode to register\n */\n registerMode(mode: Mode): void {\n modeRegistry.register(mode);\n }\n\n /**\n * Send a message using the current mode\n *\n * This is a convenience method that applies the current mode's configuration\n *\n * @param message - The message to send\n * @param options - Optional overrides for this specific message\n * @returns Promise<LoopResult> - The result of the conversation loop\n */\n async sendMessageWithMode(\n message: string | NormalizedMessage[],\n options?: Partial<Omit<SendMessageOptions, 'message' | 'systemPrompt'>> & {\n systemPrompt?: string;\n },\n ): Promise<LoopResult> {\n const mode = modeRegistry.get(this.currentMode);\n if (!mode) {\n throw new Error(`Current mode ${this.currentMode} not found`);\n }\n\n const modeConfig = mode.config;\n\n // Build options with mode config as defaults\n const sendOptions: Omit<SendMessageOptions, 'message'> = {\n write: options?.write ?? modeConfig.write,\n todo: options?.todo ?? modeConfig.todo,\n askUserQuestion: options?.askUserQuestion ?? modeConfig.askUserQuestion,\n task: options?.task ?? modeConfig.task,\n maxTurns: options?.maxTurns ?? modeConfig.maxTurns,\n model: options?.model ?? modeConfig.model,\n onTextDelta: options?.onTextDelta,\n onText: options?.onText,\n onReasoning: options?.onReasoning,\n onToolUse: options?.onToolUse,\n onToolResult: options?.onToolResult,\n onToolApprove: options?.onToolApprove,\n onTurn: options?.onTurn,\n signal: options?.signal,\n };\n\n // Special handling for system prompt\n const finalSystemPrompt = options?.systemPrompt ?? modeConfig.systemPrompt;\n\n return this._sendMessageWithSystemPrompt(message, sendOptions, finalSystemPrompt);\n }\n\n /**\n * Internal method to send message with custom system prompt\n */\n private async _sendMessageWithSystemPrompt(\n message: string | NormalizedMessage[],\n options: Omit<SendMessageOptions, 'message'>,\n systemPrompt: string,\n ): Promise<LoopResult> {\n if (!this.initialized || !this.context) {\n throw new Error('Engine not initialized. Call initialize() first.');\n }\n\n const context = this.context;\n const modelId = options.model || context.config.model;\n const resolvedModel = await resolveModelWithContext(modelId, context);\n\n if (!resolvedModel.model) {\n throw new Error(`Failed to resolve model: ${modelId}`);\n }\n\n // Resolve available tools\n const toolsList = await resolveTools({\n context,\n sessionId: this.generateSessionId(),\n write: options.write !== false,\n todo: options.todo !== false,\n askUserQuestion: options.askUserQuestion || false,\n task: options.task || false,\n signal: options.signal,\n });\n\n // Run the conversation loop with custom system prompt\n const result = await runLoop({\n input: message,\n model: resolvedModel.model,\n tools: new Tools(toolsList),\n cwd: context.cwd,\n systemPrompt,\n maxTurns: options.maxTurns,\n signal: options.signal,\n onTextDelta: options.onTextDelta,\n onText: options.onText,\n onReasoning: options.onReasoning,\n onToolUse: options.onToolUse,\n onToolResult: options.onToolResult,\n onToolApprove: options.onToolApprove,\n onTurn: options.onTurn,\n });\n\n // Record the model usage if successful\n if (result.success && modelId) {\n context.globalData.addRecentModel(modelId);\n }\n\n return result;\n }\n\n /**\n * Generate a unique session ID\n */\n private generateSessionId(): string {\n return Date.now().toString(36) + Math.random().toString(36).substring(2);\n }\n}\n\n/**\n * Create a new Engine instance\n */\nexport function createEngine(options: EngineOptions): Engine {\n return new Engine(options);\n}\n\n// Re-export commonly used types\nexport type { Config, ApprovalMode } from '../core/config';\nexport type { Session, SessionId } from '../session/session';\nexport type { Tool, ToolUse, ToolResult } from '../tools/tool';\nexport type { Message, NormalizedMessage, UserMessage, AssistantMessage } from '../core/message';\nexport type { Plugin, PluginHookType } from '../core/plugin';\n","/**\n * OriCore\n *\n * Core AI engine for AI-powered coding assistance.\n * This package provides the core functionality for AI-powered coding assistance.\n *\n * @version 1.0.0\n */\n\n// Main Engine API\nexport {\n Engine,\n createEngine,\n type EngineOptions,\n type EngineConfig,\n type SessionOptions,\n type SendMessageOptions,\n} from './api/engine';\n\n// Mode system\nexport * from './modes';\n\n// Platform abstraction\nexport * from './platform';\n\n// Communication layer\nexport * from './communication';\n\n// Session management\nexport { Session, type SessionId, type SessionConfig, SessionConfigManager, loadSessionMessages } from './session/session';\nexport { JsonlLogger } from './jsonl';\nexport { History } from './core/history';\nexport { Usage } from './core/usage';\n\n// Compression\nexport { Compression, isOverflow } from './compression';\nexport type { CompressionConfig, PruneResult } from './compression';\n\n// Core utilities\nexport { randomUUID } from './utils/randomUUID';\n\n// Paths\nexport { Paths, getGlobalDataPath } from './core/paths';\n\n// GlobalData\nexport { GlobalData } from './core/globalData';\n\n// Skill system\nexport { SkillManager } from './skill/skill';\nexport type {\n SkillManagerOpts,\n SkillMetadata,\n SkillError,\n SkillLoadOutcome,\n AddSkillOptions,\n SkillPreview,\n PreviewSkillsResult,\n AddSkillResult,\n SkillContext,\n} from './skill/skill';\nexport { SkillSource } from './skill/skill';\n\n// Bundled skills\nexport {\n bundledSkillRegistry,\n registerBundledSkill,\n createBundledSkill,\n bundledSkillToMetadata,\n} from './skill/bundled';\nexport type {\n BundledSkillDefinition,\n} from './skill/bundled';\n\n// Loop result type (for sendMessage return value)\nexport type { LoopResult } from './core/loop';\n\n// Version\nexport const ENGINE_VERSION = '1.0.0';\n"],"mappings":"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","names":["fs","path","resolve","fs","path","fs","path","fs","path","resolve","fs","path","path","fs","fs","path","path","defaultOutputStyle","fs","message","result","sessionConfigManager","path","fs","resolve","fs","path","resolve","fs","os","path","fs","os","path","fs","path","SkillSource","MAX_NAME_LENGTH","MAX_DESCRIPTION_LENGTH","os","targetDir","entries","path","resolve","fs","resolve","fs","path","os","fs","path","JsonlLogger","fs","path","JsonlLogger","loadSessionMessages","History"]}
|