@tractorscorch/clank 1.3.0 → 1.3.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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/engine/context-engine.ts","../src/providers/types.ts","../src/providers/ollama.ts","../src/providers/prompt-fallback.ts","../src/engine/agent.ts","../src/engine/system-prompt.ts","../src/engine/index.ts","../src/tools/types.ts","../src/tools/registry.ts","../src/tools/path-guard.ts","../src/tools/read-file.ts","../src/tools/write-file.ts","../src/tools/edit-file.ts","../src/tools/list-directory.ts","../src/tools/search-files.ts","../src/tools/glob-files.ts","../src/tools/bash.ts","../src/tools/git.ts","../src/config/config.ts","../src/config/watcher.ts","../src/config/index.ts","../src/tools/web-search.ts","../src/tools/web-fetch.ts","../src/config/redact.ts","../src/tools/self-config/config-tool.ts","../src/tools/self-config/channel-tool.ts","../src/tools/self-config/agent-tool.ts","../src/providers/anthropic.ts","../src/providers/openai.ts","../src/providers/google.ts","../src/providers/router.ts","../src/providers/index.ts","../src/tools/self-config/model-tool.ts","../src/sessions/store.ts","../src/sessions/index.ts","../src/tools/self-config/session-tool.ts","../src/cron/scheduler.ts","../src/cron/index.ts","../src/tools/self-config/cron-tool.ts","../src/gateway/protocol.ts","../src/tools/self-config/gateway-tool.ts","../src/tools/self-config/message-tool.ts","../src/voice/tts.ts","../src/voice/index.ts","../src/tools/self-config/voice-tool.ts","../src/tools/self-config/index.ts","../src/tools/index.ts","../src/cli/chat.ts","../src/memory/memory.ts","../src/memory/index.ts","../src/routing/resolve-route.ts","../src/routing/index.ts","../src/adapters/base.ts","../src/adapters/telegram.ts","../src/adapters/discord.ts","../src/adapters/web.ts","../src/plugins/loader.ts","../src/plugins/index.ts","../src/gateway/server.ts","../src/gateway/index.ts","../src/cli/gateway-cmd.ts","../src/daemon/install.ts","../src/daemon/index.ts","../src/cli/setup.ts","../src/cli/fix.ts","../src/cli/models.ts","../src/cli/agents.ts","../src/cli/tui.ts","../src/cli/update.ts","../src/cli/uninstall.ts","../src/cli/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * Context engine — two-tier compaction for local model optimization.\n *\n * Local models typically have 8K-32K context windows vs 128K-200K for cloud.\n * Smart compaction is what makes the difference between a usable local\n * agent and one that constantly errors out.\n *\n * Tier 1 (fast, every turn):\n * - System prompt token budgeting\n * - Tool result deduplication (same file read twice → keep latest)\n * - Tool result summarization (>500 chars → first 3 + last 2 lines)\n * - Long assistant message truncation (>3000 chars → first 1000)\n * - Oldest message dropping as last resort\n *\n * Tier 2 (LLM-summarized, when tier 1 isn't enough):\n * - Uses the model to generate a conversation summary\n * - Replaces oldest N messages with a single recap message\n * - Preserves meaning instead of just chopping text\n * - Adds latency but keeps the agent coherent over long sessions\n */\n\nimport type { Message } from \"../providers/types.js\";\nimport type { BaseProvider } from \"../providers/types.js\";\n\nexport interface CompactionResult {\n ok: boolean;\n tier: 1 | 2;\n messagesBefore: number;\n messagesAfter: number;\n estimatedTokensBefore: number;\n estimatedTokensAfter: number;\n}\n\n/** Budget allocation for system prompt vs conversation */\ninterface TokenBudget {\n systemPrompt: number;\n conversation: number;\n responseReserve: number;\n}\n\nexport class ContextEngine {\n private messages: Message[] = [];\n private contextWindowSize: number;\n private isLocal: boolean;\n private systemPromptTokens: number = 0;\n /** Provider for tier 2 LLM-summarized compaction */\n private provider: BaseProvider | null = null;\n private modelId: string = \"\";\n /** Cache of tool results by file path to detect duplicates */\n private toolResultHashes = new Map<string, number>();\n\n constructor(opts: { contextWindow: number; isLocal: boolean }) {\n this.contextWindowSize = opts.contextWindow;\n this.isLocal = opts.isLocal;\n }\n\n /** Set the provider for tier 2 compaction */\n setProvider(provider: BaseProvider, modelId: string): void {\n this.provider = provider;\n this.modelId = modelId;\n }\n\n /** Set the system prompt size for token budgeting */\n setSystemPromptSize(tokens: number): void {\n this.systemPromptTokens = tokens;\n }\n\n /** Get all messages */\n getMessages(): Message[] {\n return this.messages;\n }\n\n /** Set messages (e.g., when loading a session) */\n setMessages(messages: Message[]): void {\n this.messages = [...messages];\n }\n\n /** Add a message to the context */\n ingest(message: Message): void {\n this.messages.push(message);\n }\n\n /** Add multiple messages */\n ingestBatch(messages: Message[]): void {\n this.messages.push(...messages);\n }\n\n /**\n * Estimate total tokens in the current context.\n * Uses ~4 chars per token as a rough estimate.\n */\n estimateTokens(): number {\n let chars = 0;\n for (const msg of this.messages) {\n if (typeof msg.content === \"string\") {\n chars += msg.content.length;\n } else {\n chars += JSON.stringify(msg.content).length;\n }\n }\n return Math.ceil(chars / 4);\n }\n\n /** Calculate token budgets */\n private getBudget(): TokenBudget {\n // Reserve 25% of context for the model's response\n const responseReserve = Math.floor(this.contextWindowSize * 0.25);\n const available = this.contextWindowSize - responseReserve;\n // System prompt gets what it needs, conversation gets the rest\n const systemPrompt = Math.min(this.systemPromptTokens, Math.floor(available * 0.3));\n const conversation = available - systemPrompt;\n return { systemPrompt, conversation, responseReserve };\n }\n\n /** Get context utilization as a percentage of the conversation budget */\n utilizationPercent(): number {\n const budget = this.getBudget();\n return (this.estimateTokens() / budget.conversation) * 100;\n }\n\n /**\n * Check if compaction is needed.\n * Local models trigger earlier (60%) to leave room for the response.\n * Cloud models can wait longer (80%).\n */\n needsCompaction(): boolean {\n const threshold = this.isLocal ? 60 : 80;\n return this.utilizationPercent() >= threshold;\n }\n\n /**\n * Run compaction — tier 1 first, tier 2 if still over budget.\n * Returns the result with which tier was used.\n */\n async compactSmart(): Promise<CompactionResult> {\n const before = this.messages.length;\n const tokensBefore = this.estimateTokens();\n\n // Tier 1: mechanical compaction\n this.compactTier1();\n\n // Check if tier 1 was enough\n if (this.utilizationPercent() < 70) {\n return {\n ok: true,\n tier: 1,\n messagesBefore: before,\n messagesAfter: this.messages.length,\n estimatedTokensBefore: tokensBefore,\n estimatedTokensAfter: this.estimateTokens(),\n };\n }\n\n // Tier 2: LLM-summarized compaction\n if (this.provider) {\n await this.compactTier2();\n } else {\n // No provider — aggressive tier 1 fallback (drop more messages)\n this.compactTier1Aggressive();\n }\n\n return {\n ok: true,\n tier: this.provider ? 2 : 1,\n messagesBefore: before,\n messagesAfter: this.messages.length,\n estimatedTokensBefore: tokensBefore,\n estimatedTokensAfter: this.estimateTokens(),\n };\n }\n\n /** Synchronous compact (backward compat — uses tier 1 only) */\n compact(): CompactionResult {\n const before = this.messages.length;\n const tokensBefore = this.estimateTokens();\n\n this.compactTier1();\n\n if (this.utilizationPercent() >= 70) {\n this.compactTier1Aggressive();\n }\n\n return {\n ok: true,\n tier: 1,\n messagesBefore: before,\n messagesAfter: this.messages.length,\n estimatedTokensBefore: tokensBefore,\n estimatedTokensAfter: this.estimateTokens(),\n };\n }\n\n /**\n * Tier 1: Fast mechanical compaction (no LLM calls).\n */\n private compactTier1(): void {\n const protectedCount = 6;\n if (this.messages.length <= protectedCount) return;\n\n const protectedZone = this.messages.slice(-protectedCount);\n const compactable = this.messages.slice(0, -protectedCount);\n const compacted: Message[] = [];\n\n // Pass 1: Deduplicate tool results (same tool+path → keep latest only)\n const seenToolResults = new Map<string, number>();\n for (let i = compactable.length - 1; i >= 0; i--) {\n const msg = compactable[i];\n if (msg.role === \"tool\" && msg.tool_call_id) {\n const content = typeof msg.content === \"string\" ? msg.content : \"\";\n // Extract a dedup key from the tool call (e.g., read_file:/path)\n const key = msg.tool_call_id;\n if (!seenToolResults.has(key)) {\n seenToolResults.set(key, i);\n }\n }\n }\n\n // Pass 2: Compact messages\n for (let i = 0; i < compactable.length; i++) {\n const msg = compactable[i];\n\n if (msg._compacted) {\n compacted.push(msg);\n continue;\n }\n\n const content = typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content);\n\n if (msg.role === \"tool\") {\n // Summarize long tool results\n if (content.length > 500) {\n const lines = content.split(\"\\n\");\n const summary = [\n ...lines.slice(0, 3),\n `... (${lines.length - 5} lines omitted)`,\n ...lines.slice(-2),\n ].join(\"\\n\");\n compacted.push({ ...msg, content: summary, _compacted: true });\n } else {\n compacted.push(msg);\n }\n } else if (msg.role === \"assistant\") {\n // Truncate long assistant messages\n if (content.length > 3000) {\n compacted.push({\n ...msg,\n content: content.slice(0, 1000) + \"\\n... (truncated)\",\n _compacted: true,\n });\n } else {\n compacted.push(msg);\n }\n } else if (msg.role === \"user\") {\n // Truncate very long user messages\n if (content.length > 2000) {\n compacted.push({\n ...msg,\n content: content.slice(0, 800) + \"\\n... (truncated)\",\n _compacted: true,\n });\n } else {\n compacted.push(msg);\n }\n } else {\n compacted.push(msg);\n }\n }\n\n this.messages = [...compacted, ...protectedZone];\n }\n\n /**\n * Tier 1 aggressive: drop oldest messages when regular compaction isn't enough.\n */\n private compactTier1Aggressive(): void {\n const protectedCount = 6;\n const budget = this.getBudget();\n\n while (this.estimateTokens() > budget.conversation * 0.7 && this.messages.length > protectedCount + 2) {\n // Find the first non-system message to drop\n const dropIdx = this.messages.findIndex((m) => m.role !== \"system\");\n if (dropIdx === -1 || dropIdx >= this.messages.length - protectedCount) break;\n this.messages.splice(dropIdx, 1);\n }\n }\n\n /**\n * Tier 2: LLM-summarized compaction.\n *\n * Takes the oldest messages (outside protected zone), sends them to\n * the model with a summarization prompt, and replaces them with a\n * single \"conversation recap\" message. This preserves meaning that\n * mechanical truncation loses.\n */\n private async compactTier2(): Promise<void> {\n if (!this.provider) return;\n\n const protectedCount = 6;\n if (this.messages.length <= protectedCount + 2) return;\n\n // Take the older half of the conversation for summarization\n const cutoff = Math.max(2, this.messages.length - protectedCount - 2);\n const toSummarize = this.messages.slice(0, cutoff);\n const toKeep = this.messages.slice(cutoff);\n\n // Build the summarization prompt\n const conversationText = toSummarize\n .map((m) => {\n const content = typeof m.content === \"string\" ? m.content : JSON.stringify(m.content);\n const truncated = content.length > 500 ? content.slice(0, 500) + \"...\" : content;\n return `${m.role}: ${truncated}`;\n })\n .join(\"\\n\\n\");\n\n const summaryPrompt = [\n \"Summarize this conversation concisely. Capture:\",\n \"- Key decisions made\",\n \"- Files modified and why\",\n \"- Current task status\",\n \"- Important context the assistant needs going forward\",\n \"\",\n \"Be brief (under 300 words). Use bullet points.\",\n \"\",\n \"Conversation:\",\n conversationText,\n ].join(\"\\n\");\n\n try {\n // Use the model to generate a summary\n let summary = \"\";\n for await (const event of this.provider.stream(\n [{ role: \"user\", content: summaryPrompt }],\n \"You are a conversation summarizer. Output only the summary, nothing else.\",\n [], // no tools\n )) {\n if (event.type === \"text\") {\n summary += event.content;\n }\n }\n\n if (summary.trim()) {\n // Replace old messages with the summary\n const recapMessage: Message = {\n role: \"user\",\n content: `[Conversation recap — earlier messages were compacted]\\n\\n${summary.trim()}`,\n _compacted: true,\n };\n\n this.messages = [recapMessage, ...toKeep];\n }\n } catch {\n // LLM summary failed — fall back to aggressive tier 1\n this.compactTier1Aggressive();\n }\n }\n\n /** Clear all messages */\n clear(): void {\n this.messages = [];\n this.toolResultHashes.clear();\n }\n\n /** Update the context window size */\n setContextWindow(size: number): void {\n this.contextWindowSize = size;\n }\n}\n","/**\n * Provider type definitions.\n *\n * All providers return the same stream event format regardless of the\n * underlying API. This abstraction lets the agent engine treat Ollama,\n * Anthropic, OpenAI, and Google identically.\n */\n\n/** Events yielded by provider.stream() */\nexport type StreamEvent =\n | { type: \"text\"; content: string }\n | { type: \"thinking\"; content: string }\n | { type: \"tool_call\"; id: string; name: string; arguments: Record<string, unknown> }\n | { type: \"usage\"; promptTokens: number; outputTokens: number; evalDurationNs?: number }\n | { type: \"done\" };\n\n/** Tool definition in the format passed to providers */\nexport interface ToolDefinition {\n name: string;\n description: string;\n parameters: {\n type: \"object\";\n properties: Record<string, unknown>;\n required?: string[];\n };\n}\n\n/** Message in conversation history */\nexport interface Message {\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string | ContentBlock[];\n /** For tool result messages */\n tool_call_id?: string;\n /** For assistant messages with tool calls */\n tool_calls?: ToolCallMessage[];\n /** Marks messages that have been compacted */\n _compacted?: boolean;\n}\n\nexport interface ContentBlock {\n type: \"text\" | \"image\" | \"tool_use\" | \"tool_result\";\n text?: string;\n id?: string;\n name?: string;\n input?: Record<string, unknown>;\n content?: string;\n is_error?: boolean;\n}\n\nexport interface ToolCallMessage {\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/**\n * Per-model compatibility config.\n *\n * Different models (especially local ones) have quirks — some don't support\n * tools natively, some need different thinking formats, some have weird\n * max_tokens field names. This config lets us handle all of that.\n */\nexport interface ModelCompatConfig {\n supportsTools?: boolean;\n supportsStreaming?: boolean;\n supportsImages?: boolean;\n /** How thinking/reasoning blocks are formatted */\n thinkingFormat?: \"anthropic\" | \"openai\" | \"qwen\" | \"none\";\n /** Field name for max output tokens */\n maxTokensField?: \"max_tokens\" | \"max_completion_tokens\";\n /** Some models need tool result messages to include the tool name */\n requiresToolResultName?: boolean;\n /** Some models need an assistant message after tool results */\n requiresAssistantAfterToolResult?: boolean;\n /** Max output tokens override */\n maxOutputTokens?: number;\n}\n\n/** Provider resolution result from the router */\nexport interface ResolvedProvider {\n provider: BaseProvider;\n providerName: string;\n modelId: string;\n isLocal: boolean;\n}\n\n/** Model entry in config */\nexport interface ModelConfig {\n primary: string;\n fallbacks?: string[];\n temperature?: number;\n maxResponseTokens?: number;\n}\n\n/**\n * Base provider interface.\n *\n * Every LLM provider (Ollama, Anthropic, OpenAI, Google) implements this.\n * The stream() method is an async generator that yields StreamEvents,\n * giving the agent engine a unified interface regardless of backend.\n */\nexport abstract class BaseProvider {\n abstract readonly name: string;\n\n /** Convert tool definitions to the provider's native format */\n abstract formatTools(tools: ToolDefinition[]): unknown[];\n\n /**\n * Stream a completion from the model.\n * Yields StreamEvents in a normalized format.\n */\n abstract stream(\n messages: Message[],\n systemPrompt: string,\n tools: ToolDefinition[],\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent>;\n\n /** Rough token estimate (~4 chars per token) */\n estimateTokens(messages: Message[]): number {\n const text = messages\n .map((m) => (typeof m.content === \"string\" ? m.content : JSON.stringify(m.content)))\n .join(\"\");\n return Math.ceil(text.length / 4);\n }\n\n /** Max context window size in tokens */\n abstract contextWindow(): number;\n\n /** Format an assistant tool use for message history */\n abstract formatAssistantToolUse(\n toolCallId: string,\n name: string,\n args: Record<string, unknown>,\n ): Message;\n\n /** Format a tool result for message history */\n abstract formatToolResult(\n toolCallId: string,\n name: string,\n result: string,\n isError?: boolean,\n ): Message;\n}\n","/**\n * Ollama provider — the primary provider for Clank.\n *\n * Uses the OpenAI-compatible API that Ollama exposes at /v1/.\n * Key local-model optimizations:\n * - Dynamic context window detection via /api/show\n * - Tool support checking against known model patterns\n * - Response token capping for smaller models\n */\n\nimport {\n BaseProvider,\n type Message,\n type StreamEvent,\n type ToolDefinition,\n} from \"./types.js\";\n\n/** Models known to support native tool calling */\nconst TOOL_CAPABLE_PATTERNS = [\n /^llama3\\.[1-9]/i,\n /^llama-3\\.[1-9]/i,\n /^qwen[23]/i,\n /^mistral-nemo/i,\n /^mistral-large/i,\n /^command-r/i,\n /^firefunction/i,\n /^hermes-[23]/i,\n /^nemotron/i,\n];\n\n/** Cache for context window sizes per model */\nconst contextWindowCache = new Map<string, number>();\n\nexport class OllamaProvider extends BaseProvider {\n readonly name = \"ollama\";\n private baseUrl: string;\n private model: string;\n private maxResponseTokens?: number;\n\n constructor(opts: {\n baseUrl?: string;\n model: string;\n maxResponseTokens?: number;\n }) {\n super();\n this.baseUrl = (opts.baseUrl || \"http://127.0.0.1:11434\").replace(/\\/$/, \"\");\n this.model = opts.model;\n this.maxResponseTokens = opts.maxResponseTokens;\n }\n\n /**\n * Auto-detect Ollama by probing /api/tags.\n * Returns the list of available models, or null if Ollama isn't running.\n */\n static async detect(baseUrl = \"http://127.0.0.1:11434\"): Promise<string[] | null> {\n try {\n const res = await fetch(`${baseUrl}/api/tags`, { signal: AbortSignal.timeout(3000) });\n if (!res.ok) return null;\n const data = (await res.json()) as { models?: Array<{ name: string }> };\n return data.models?.map((m) => m.name) ?? [];\n } catch {\n return null;\n }\n }\n\n /**\n * Detect the context window for a model via /api/show.\n * Caches the result since this doesn't change at runtime.\n */\n async detectContextWindow(): Promise<number> {\n const cached = contextWindowCache.get(this.model);\n if (cached) return cached;\n\n try {\n const res = await fetch(`${this.baseUrl}/api/show`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ name: this.model }),\n signal: AbortSignal.timeout(5000),\n });\n if (!res.ok) return 32768;\n\n const data = (await res.json()) as {\n model_info?: Record<string, unknown>;\n parameters?: string;\n };\n\n // Check model_info for context length keys\n if (data.model_info) {\n for (const [key, value] of Object.entries(data.model_info)) {\n if (\n key.includes(\"context_length\") ||\n key.includes(\"context_window\") ||\n key.includes(\"num_ctx\")\n ) {\n const ctx = Number(value);\n if (ctx > 0) {\n contextWindowCache.set(this.model, ctx);\n return ctx;\n }\n }\n }\n }\n\n // Check parameters string for num_ctx\n if (data.parameters) {\n const match = data.parameters.match(/num_ctx\\s+(\\d+)/);\n if (match) {\n const ctx = parseInt(match[1], 10);\n contextWindowCache.set(this.model, ctx);\n return ctx;\n }\n }\n } catch {\n // Fall through to default\n }\n\n const defaultCtx = 32768;\n contextWindowCache.set(this.model, defaultCtx);\n return defaultCtx;\n }\n\n /** Check if a model supports native tool calling */\n static supportsTools(model: string): boolean {\n const baseName = model.split(\":\")[0];\n return TOOL_CAPABLE_PATTERNS.some((p) => p.test(baseName));\n }\n\n contextWindow(): number {\n return contextWindowCache.get(this.model) ?? 32768;\n }\n\n formatTools(tools: ToolDefinition[]): unknown[] {\n return tools.map((t) => ({\n type: \"function\",\n function: {\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n },\n }));\n }\n\n async *stream(\n messages: Message[],\n systemPrompt: string,\n tools: ToolDefinition[],\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n // Build OpenAI-compatible messages array\n const apiMessages: Array<Record<string, unknown>> = [];\n\n if (systemPrompt) {\n apiMessages.push({ role: \"system\", content: systemPrompt });\n }\n\n for (const msg of messages) {\n if (msg.role === \"tool\") {\n apiMessages.push({\n role: \"tool\",\n tool_call_id: msg.tool_call_id,\n content: typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content),\n });\n } else if (msg.role === \"assistant\" && msg.tool_calls) {\n apiMessages.push({\n role: \"assistant\",\n content: typeof msg.content === \"string\" ? msg.content : null,\n tool_calls: msg.tool_calls,\n });\n } else {\n apiMessages.push({\n role: msg.role,\n content: typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content),\n });\n }\n }\n\n const body: Record<string, unknown> = {\n model: this.model,\n messages: apiMessages,\n stream: true,\n };\n\n if (tools.length > 0 && OllamaProvider.supportsTools(this.model)) {\n body.tools = this.formatTools(tools);\n }\n\n if (this.maxResponseTokens) {\n body.max_tokens = this.maxResponseTokens;\n }\n\n const res = await fetch(`${this.baseUrl}/v1/chat/completions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"Unknown error\");\n throw new Error(`Ollama API error ${res.status}: ${text}`);\n }\n\n if (!res.body) {\n throw new Error(\"No response body from Ollama\");\n }\n\n // Parse SSE stream\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n const toolCalls = new Map<number, { id: string; name: string; arguments: string }>();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || !trimmed.startsWith(\"data: \")) continue;\n\n const data = trimmed.slice(6);\n if (data === \"[DONE]\") {\n // Emit any accumulated tool calls\n for (const tc of toolCalls.values()) {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(tc.arguments) as Record<string, unknown>;\n } catch {\n parsedArgs = {};\n }\n yield { type: \"tool_call\", id: tc.id, name: tc.name, arguments: parsedArgs };\n }\n yield { type: \"done\" };\n return;\n }\n\n try {\n const chunk = JSON.parse(data) as {\n choices?: Array<{\n delta?: {\n content?: string | null;\n tool_calls?: Array<{\n index: number;\n id?: string;\n function?: { name?: string; arguments?: string };\n }>;\n };\n finish_reason?: string | null;\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n };\n\n const choice = chunk.choices?.[0];\n if (!choice) continue;\n\n // Text content\n if (choice.delta?.content) {\n yield { type: \"text\", content: choice.delta.content };\n }\n\n // Tool calls (accumulated across chunks)\n if (choice.delta?.tool_calls) {\n for (const tc of choice.delta.tool_calls) {\n const existing = toolCalls.get(tc.index);\n if (existing) {\n if (tc.function?.arguments) {\n existing.arguments += tc.function.arguments;\n }\n } else {\n toolCalls.set(tc.index, {\n id: tc.id || `call_${tc.index}`,\n name: tc.function?.name || \"\",\n arguments: tc.function?.arguments || \"\",\n });\n }\n }\n }\n\n // Usage info\n if (chunk.usage) {\n yield {\n type: \"usage\",\n promptTokens: chunk.usage.prompt_tokens ?? 0,\n outputTokens: chunk.usage.completion_tokens ?? 0,\n };\n }\n } catch {\n // Skip malformed JSON chunks\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n // If we exit without [DONE], still emit pending tool calls and done\n for (const tc of toolCalls.values()) {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(tc.arguments) as Record<string, unknown>;\n } catch {\n parsedArgs = {};\n }\n yield { type: \"tool_call\", id: tc.id, name: tc.name, arguments: parsedArgs };\n }\n yield { type: \"done\" };\n }\n\n formatAssistantToolUse(\n toolCallId: string,\n name: string,\n args: Record<string, unknown>,\n ): Message {\n return {\n role: \"assistant\",\n content: \"\",\n tool_calls: [\n {\n id: toolCallId,\n type: \"function\",\n function: { name, arguments: JSON.stringify(args) },\n },\n ],\n };\n }\n\n formatToolResult(\n toolCallId: string,\n _name: string,\n result: string,\n _isError?: boolean,\n ): Message {\n return {\n role: \"tool\",\n content: result,\n tool_call_id: toolCallId,\n };\n }\n}\n","/**\n * Prompt fallback provider.\n *\n * Wraps any provider to add tool support for models that don't have\n * native function calling. Instead of passing tools via the API, it:\n *\n * 1. Injects tool definitions into the system prompt as JSON specs\n * 2. Asks the model to respond with a specific format when using tools\n * 3. Parses the model's text output to extract tool calls via regex\n *\n * This is how smaller local models (llama3.2 3B, phi-3, etc.) can\n * still use tools — they just need to follow a text format instead\n * of producing structured function calls.\n */\n\nimport {\n BaseProvider,\n type Message,\n type StreamEvent,\n type ToolDefinition,\n} from \"./types.js\";\n\nconst TOOL_PROMPT_TEMPLATE = `\nYou have access to the following tools. To use a tool, respond with a JSON block in this exact format:\n\n\\`\\`\\`tool_call\n{\"name\": \"tool_name\", \"arguments\": {\"arg1\": \"value1\"}}\n\\`\\`\\`\n\nAvailable tools:\n`;\n\n/** Regex to extract tool calls from model text output */\nconst TOOL_CALL_REGEX = /```tool_call\\s*\\n?\\s*(\\{[\\s\\S]*?\\})\\s*\\n?\\s*```/g;\n\nexport class PromptFallbackProvider extends BaseProvider {\n readonly name: string;\n private wrapped: BaseProvider;\n\n constructor(wrapped: BaseProvider) {\n super();\n this.wrapped = wrapped;\n this.name = `${wrapped.name}+prompt-fallback`;\n }\n\n contextWindow(): number {\n return this.wrapped.contextWindow();\n }\n\n formatTools(_tools: ToolDefinition[]): unknown[] {\n // Tools are injected into the prompt, not passed to the API\n return [];\n }\n\n /**\n * Build the tool injection block for the system prompt.\n */\n private buildToolPrompt(tools: ToolDefinition[]): string {\n if (tools.length === 0) return \"\";\n\n let prompt = TOOL_PROMPT_TEMPLATE;\n for (const tool of tools) {\n prompt += `\\n### ${tool.name}\\n`;\n prompt += `${tool.description}\\n`;\n prompt += `Parameters: ${JSON.stringify(tool.parameters, null, 2)}\\n`;\n }\n prompt += \"\\nYou can use multiple tools in one response. After each tool call, wait for the result before proceeding.\\n\";\n prompt += \"If you don't need a tool, just respond normally with text.\\n\";\n return prompt;\n }\n\n async *stream(\n messages: Message[],\n systemPrompt: string,\n tools: ToolDefinition[],\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n // Inject tools into system prompt\n const augmentedPrompt = tools.length > 0\n ? systemPrompt + \"\\n\\n\" + this.buildToolPrompt(tools)\n : systemPrompt;\n\n // Collect the full response to parse for tool calls\n let fullText = \"\";\n\n for await (const event of this.wrapped.stream(messages, augmentedPrompt, [], signal)) {\n if (event.type === \"text\") {\n fullText += event.content;\n yield event;\n } else if (event.type === \"done\") {\n // Parse tool calls from the accumulated text\n const toolCalls = this.parseToolCalls(fullText);\n for (const tc of toolCalls) {\n yield tc;\n }\n yield event;\n } else {\n yield event;\n }\n }\n }\n\n /**\n * Parse tool calls from model text output.\n */\n private parseToolCalls(text: string): StreamEvent[] {\n const calls: StreamEvent[] = [];\n let match: RegExpExecArray | null;\n let callIndex = 0;\n\n // Reset regex state\n TOOL_CALL_REGEX.lastIndex = 0;\n\n while ((match = TOOL_CALL_REGEX.exec(text)) !== null) {\n try {\n const parsed = JSON.parse(match[1]) as {\n name?: string;\n arguments?: Record<string, unknown>;\n };\n\n if (parsed.name) {\n calls.push({\n type: \"tool_call\",\n id: `prompt_call_${callIndex++}`,\n name: parsed.name,\n arguments: parsed.arguments ?? {},\n });\n }\n } catch {\n // Malformed JSON in tool call block — skip\n }\n }\n\n return calls;\n }\n\n formatAssistantToolUse(\n toolCallId: string,\n name: string,\n args: Record<string, unknown>,\n ): Message {\n // For prompt-based tools, represent the tool call as text in the\n // assistant message so the model sees its own format\n return {\n role: \"assistant\",\n content: `\\`\\`\\`tool_call\\n${JSON.stringify({ name, arguments: args })}\\n\\`\\`\\``,\n };\n }\n\n formatToolResult(\n _toolCallId: string,\n name: string,\n result: string,\n isError?: boolean,\n ): Message {\n const prefix = isError ? `Error from ${name}` : `Result from ${name}`;\n return {\n role: \"user\",\n content: `${prefix}:\\n${result}`,\n };\n }\n}\n","/**\n * AgentEngine — the core of Clank.\n *\n * This is the ReAct loop: Reason → Act → Observe → Repeat.\n * The engine streams from an LLM provider, detects tool calls,\n * executes them (with user confirmation for risky ones), feeds\n * results back, and loops until the model responds with plain text.\n *\n * Events are emitted at every stage so frontends (CLI, Web, Telegram)\n * can display progress in real-time without knowing the internals.\n */\n\nimport { EventEmitter } from \"node:events\";\nimport { ContextEngine } from \"./context-engine.js\";\nimport { ToolRegistry, type ToolContext, type Tool, type ToolTier } from \"../tools/index.js\";\nimport {\n type BaseProvider,\n type Message,\n type StreamEvent,\n type ToolDefinition,\n type ResolvedProvider,\n} from \"../providers/types.js\";\nimport { OllamaProvider } from \"../providers/ollama.js\";\nimport { PromptFallbackProvider } from \"../providers/prompt-fallback.js\";\nimport { SessionStore, type SessionEntry } from \"../sessions/index.js\";\n\n/** Agent identity — who is this agent? */\nexport interface AgentIdentity {\n id: string;\n name: string;\n model: { primary: string; fallbacks?: string[] };\n workspace: string;\n toolTier: ToolTier;\n temperature?: number;\n maxResponseTokens?: number;\n tools?: { allow?: string[]; deny?: string[] };\n}\n\n/** Events the engine emits */\nexport interface AgentEvents {\n \"thinking-start\": () => void;\n \"thinking-stop\": () => void;\n \"response-start\": () => void;\n \"token\": (data: { content: string }) => void;\n \"response-end\": (data: { text: string }) => void;\n \"tool-start\": (data: { id: string; name: string; arguments: Record<string, unknown> }) => void;\n \"tool-result\": (data: { id: string; name: string; success: boolean; summary: string }) => void;\n \"confirm-needed\": (data: { actions: ConfirmAction[]; resolve: (approved: boolean | \"always\") => void }) => void;\n \"context-compacting\": () => void;\n \"usage\": (data: { promptTokens: number; outputTokens: number; iterationCount: number; contextPercent: number }) => void;\n \"error\": (data: { message: string; recoverable: boolean }) => void;\n \"turn-complete\": () => void;\n}\n\nexport interface ConfirmAction {\n toolName: string;\n description: string;\n safetyLevel: string;\n}\n\nconst MAX_ITERATIONS = 50;\n\nexport class AgentEngine extends EventEmitter {\n readonly identity: AgentIdentity;\n private contextEngine: ContextEngine;\n private toolRegistry: ToolRegistry;\n private resolvedProvider: ResolvedProvider | null = null;\n private sessionStore: SessionStore;\n private currentSession: SessionEntry | null = null;\n private abortController: AbortController | null = null;\n private systemPrompt: string = \"\";\n private autoApprove = { low: true, medium: false, high: false };\n /** Tools the user has approved \"always\" for this session */\n private alwaysApproved = new Set<string>();\n\n constructor(opts: {\n identity: AgentIdentity;\n toolRegistry: ToolRegistry;\n sessionStore: SessionStore;\n provider: ResolvedProvider;\n autoApprove?: { low: boolean; medium: boolean; high: boolean };\n systemPrompt?: string;\n }) {\n super();\n this.identity = opts.identity;\n this.toolRegistry = opts.toolRegistry;\n this.sessionStore = opts.sessionStore;\n this.resolvedProvider = opts.provider;\n if (opts.autoApprove) this.autoApprove = opts.autoApprove;\n if (opts.systemPrompt) this.systemPrompt = opts.systemPrompt;\n\n this.contextEngine = new ContextEngine({\n contextWindow: opts.provider.provider.contextWindow(),\n isLocal: opts.provider.isLocal,\n });\n\n // Wire provider into context engine for tier 2 LLM-summarized compaction\n this.contextEngine.setProvider(opts.provider.provider, opts.identity.model.primary);\n }\n\n /** Set the system prompt */\n setSystemPrompt(prompt: string): void {\n this.systemPrompt = prompt;\n // Update token budget in context engine\n this.contextEngine.setSystemPromptSize(Math.ceil(prompt.length / 4));\n }\n\n /** Load or create a session */\n async loadSession(normalizedKey: string, channel: string): Promise<void> {\n this.currentSession = await this.sessionStore.resolve(normalizedKey, {\n agentId: this.identity.id,\n channel,\n });\n\n const messages = await this.sessionStore.loadMessages(this.currentSession.id);\n this.contextEngine.setMessages(messages);\n\n // Detect context window for Ollama models\n if (this.resolvedProvider?.provider instanceof OllamaProvider) {\n const ctxSize = await (this.resolvedProvider.provider as OllamaProvider).detectContextWindow();\n this.contextEngine.setContextWindow(ctxSize);\n }\n }\n\n /** Cancel the current request */\n cancel(): void {\n this.abortController?.abort();\n this.emit(\"cancelled\");\n }\n\n /**\n * Send a message and get a response.\n * This is THE agent loop — the heart of Clank.\n */\n async sendMessage(text: string): Promise<string> {\n if (!this.resolvedProvider) {\n throw new Error(\"No provider configured\");\n }\n\n this.abortController = new AbortController();\n const signal = this.abortController.signal;\n\n // Add user message to context\n this.contextEngine.ingest({ role: \"user\", content: text });\n\n // Auto-title session from first message\n if (this.currentSession && !this.currentSession.label) {\n const label = text.length > 60 ? text.slice(0, 57) + \"...\" : text;\n await this.sessionStore.setLabel(this.currentSession.normalizedKey, label);\n }\n\n const provider = this.resolvedProvider.provider;\n const isLocal = this.resolvedProvider.isLocal;\n\n // Wrap provider with prompt fallback if model doesn't support tools\n let activeProvider: BaseProvider = provider;\n if (isLocal && provider instanceof OllamaProvider) {\n const modelName = this.identity.model.primary.split(\"/\").pop() || \"\";\n if (!OllamaProvider.supportsTools(modelName)) {\n activeProvider = new PromptFallbackProvider(provider);\n }\n }\n\n let fullResponse = \"\";\n let iterationCount = 0;\n\n try {\n // === THE REACT LOOP ===\n while (iterationCount < MAX_ITERATIONS) {\n iterationCount++;\n\n // Check if compaction is needed\n if (this.contextEngine.needsCompaction()) {\n this.emit(\"context-compacting\");\n // Use smart (async) compaction with LLM summary if available\n const compactResult = await this.contextEngine.compactSmart();\n if (compactResult.tier === 2) {\n this.emit(\"usage\", {\n promptTokens: 0, outputTokens: 0, iterationCount,\n contextPercent: Math.round(this.contextEngine.utilizationPercent()),\n });\n }\n }\n\n // Get tool definitions for this iteration\n const toolDefs = this.toolRegistry.getDefinitions({\n tier: this.identity.toolTier,\n userMessage: text,\n allowlist: this.identity.tools?.allow,\n denylist: this.identity.tools?.deny,\n });\n\n // Stream from the provider\n let iterationText = \"\";\n const toolCalls: Array<{ id: string; name: string; arguments: Record<string, unknown> }> = [];\n let promptTokens = 0;\n let outputTokens = 0;\n\n this.emit(\"response-start\");\n\n for await (const event of activeProvider.stream(\n this.contextEngine.getMessages(),\n this.systemPrompt,\n toolDefs,\n signal,\n )) {\n switch (event.type) {\n case \"text\":\n iterationText += event.content;\n this.emit(\"token\", { content: event.content });\n break;\n\n case \"thinking\":\n this.emit(\"thinking-start\");\n // Thinking content not added to visible response\n break;\n\n case \"tool_call\":\n toolCalls.push({\n id: event.id,\n name: event.name,\n arguments: event.arguments,\n });\n break;\n\n case \"usage\":\n promptTokens = event.promptTokens;\n outputTokens = event.outputTokens;\n break;\n\n case \"done\":\n break;\n }\n }\n\n // Emit usage stats\n this.emit(\"usage\", {\n promptTokens,\n outputTokens,\n iterationCount,\n contextPercent: Math.round(this.contextEngine.utilizationPercent()),\n });\n\n // If no tool calls, we're done — this is the final response\n if (toolCalls.length === 0) {\n fullResponse = iterationText;\n this.contextEngine.ingest({ role: \"assistant\", content: iterationText });\n this.emit(\"response-end\", { text: iterationText });\n break;\n }\n\n // Add assistant message with tool calls to context\n const assistantMsg = activeProvider.formatAssistantToolUse(\n toolCalls[0].id,\n toolCalls[0].name,\n toolCalls[0].arguments,\n );\n // If there's text before tool calls, prepend it\n if (iterationText) {\n assistantMsg.content = iterationText;\n }\n // For multiple tool calls, add them all\n if (toolCalls.length > 1 && assistantMsg.tool_calls) {\n assistantMsg.tool_calls = toolCalls.map((tc) => ({\n id: tc.id,\n type: \"function\" as const,\n function: { name: tc.name, arguments: JSON.stringify(tc.arguments) },\n }));\n }\n this.contextEngine.ingest(assistantMsg);\n\n this.emit(\"response-end\", { text: iterationText });\n\n // Execute tool calls sequentially\n for (const tc of toolCalls) {\n const tool = this.toolRegistry.get(tc.name);\n if (!tool) {\n const errorResult = activeProvider.formatToolResult(tc.id, tc.name, `Error: Unknown tool \"${tc.name}\"`, true);\n this.contextEngine.ingest(errorResult);\n continue;\n }\n\n this.emit(\"tool-start\", { id: tc.id, name: tc.name, arguments: tc.arguments });\n\n // Validate\n const toolCtx: ToolContext = {\n projectRoot: this.identity.workspace,\n autoApprove: this.autoApprove,\n agentId: this.identity.id,\n signal,\n };\n\n const validation = tool.validate(tc.arguments, toolCtx);\n if (!validation.ok) {\n const result = activeProvider.formatToolResult(tc.id, tc.name, `Validation error: ${validation.error}`, true);\n this.contextEngine.ingest(result);\n this.emit(\"tool-result\", { id: tc.id, name: tc.name, success: false, summary: validation.error || \"Validation failed\" });\n continue;\n }\n\n // Check if confirmation is needed\n const level = typeof tool.safetyLevel === \"function\" ? tool.safetyLevel(tc.arguments) : tool.safetyLevel;\n const needsConfirm = !this.autoApprove[level] && !this.alwaysApproved.has(tc.name);\n\n if (needsConfirm) {\n const approved = await this.requestConfirmation(tool, tc);\n if (!approved) {\n const result = activeProvider.formatToolResult(tc.id, tc.name, \"Tool execution denied by user\", true);\n this.contextEngine.ingest(result);\n this.emit(\"tool-result\", { id: tc.id, name: tc.name, success: false, summary: \"Denied by user\" });\n continue;\n }\n }\n\n // Execute\n try {\n const output = await tool.execute(tc.arguments, toolCtx);\n const result = activeProvider.formatToolResult(tc.id, tc.name, output);\n this.contextEngine.ingest(result);\n this.emit(\"tool-result\", {\n id: tc.id,\n name: tc.name,\n success: true,\n summary: output.length > 100 ? output.slice(0, 97) + \"...\" : output,\n });\n } catch (err: unknown) {\n const errMsg = err instanceof Error ? err.message : String(err);\n const result = activeProvider.formatToolResult(tc.id, tc.name, `Error: ${errMsg}`, true);\n this.contextEngine.ingest(result);\n this.emit(\"tool-result\", { id: tc.id, name: tc.name, success: false, summary: errMsg });\n }\n }\n\n // Loop continues — the model will see tool results and decide next action\n }\n\n if (iterationCount >= MAX_ITERATIONS) {\n this.emit(\"error\", { message: \"Max iterations reached\", recoverable: true });\n }\n } catch (err: unknown) {\n if (signal.aborted) {\n return \"\";\n }\n const errMsg = err instanceof Error ? err.message : String(err);\n this.emit(\"error\", { message: errMsg, recoverable: false });\n throw err;\n } finally {\n // Save session\n if (this.currentSession) {\n await this.sessionStore.saveMessages(this.currentSession.id, this.contextEngine.getMessages());\n }\n this.emit(\"turn-complete\");\n this.abortController = null;\n }\n\n return fullResponse;\n }\n\n /**\n * Request user confirmation for a tool execution.\n * Returns a promise that resolves when the user responds.\n */\n private requestConfirmation(\n tool: Tool,\n tc: { id: string; name: string; arguments: Record<string, unknown> },\n ): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const description = tool.formatConfirmation\n ? tool.formatConfirmation(tc.arguments)\n : `Execute ${tc.name}`;\n\n const level = typeof tool.safetyLevel === \"function\" ? tool.safetyLevel(tc.arguments) : tool.safetyLevel;\n\n this.emit(\"confirm-needed\", {\n actions: [{ toolName: tc.name, description, safetyLevel: level }],\n resolve: (approved: boolean | \"always\") => {\n if (approved === \"always\") {\n this.alwaysApproved.add(tc.name);\n resolve(true);\n } else {\n resolve(approved);\n }\n },\n });\n });\n }\n\n /** Get the context engine (for direct access if needed) */\n getContextEngine(): ContextEngine {\n return this.contextEngine;\n }\n\n /** Destroy the engine and clean up */\n destroy(): void {\n this.cancel();\n this.removeAllListeners();\n }\n}\n","/**\n * System prompt builder.\n *\n * Assembles the system prompt from workspace files (SOUL.md, USER.md, etc.),\n * agent identity, runtime info, and tool descriptions. This is what gives\n * the agent its personality and context.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { platform, hostname } from \"node:os\";\nimport type { AgentIdentity } from \"./agent.js\";\n\n/** Workspace files to load into the system prompt */\nconst WORKSPACE_FILES = [\n \"SOUL.md\",\n \"USER.md\",\n \"IDENTITY.md\",\n \"AGENTS.md\",\n \"TOOLS.md\",\n \"MEMORY.md\",\n];\n\n/**\n * Build the complete system prompt for an agent.\n */\nexport async function buildSystemPrompt(opts: {\n identity: AgentIdentity;\n workspaceDir: string;\n channel?: string;\n}): Promise<string> {\n const parts: string[] = [];\n\n // Load workspace files\n const workspaceContent = await loadWorkspaceFiles(opts.workspaceDir);\n if (workspaceContent) {\n parts.push(workspaceContent);\n parts.push(\"---\");\n }\n\n // Runtime info\n parts.push(\"## Runtime\");\n parts.push(`Agent: ${opts.identity.name} (${opts.identity.id})`);\n parts.push(`Model: ${opts.identity.model.primary}`);\n parts.push(`Workspace: ${opts.identity.workspace}`);\n parts.push(`Platform: ${platform()} (${hostname()})`);\n parts.push(`Channel: ${opts.channel || \"cli\"}`);\n parts.push(`Tool tier: ${opts.identity.toolTier}`);\n parts.push(\"\");\n\n // Core instructions\n parts.push(\"## Instructions\");\n parts.push(\"You are a helpful AI assistant with access to tools for reading/writing files, running commands, and more.\");\n parts.push(\"Be concise and direct. Use tools proactively to accomplish tasks.\");\n parts.push(\"When you need to make changes, read the relevant files first to understand the context.\");\n parts.push(\"You can configure yourself — use the config, channel, agent, and model management tools to modify your own setup.\");\n parts.push(\"\");\n\n // Project context — check for .clank.md in workspace\n const projectMemory = await loadProjectMemory(opts.identity.workspace);\n if (projectMemory) {\n parts.push(\"## Project Context\");\n parts.push(projectMemory);\n parts.push(\"\");\n }\n\n return parts.join(\"\\n\");\n}\n\n/** Load workspace bootstrap files into a combined string */\nasync function loadWorkspaceFiles(workspaceDir: string): Promise<string | null> {\n const sections: string[] = [];\n\n for (const filename of WORKSPACE_FILES) {\n const filePath = join(workspaceDir, filename);\n if (existsSync(filePath)) {\n try {\n const content = await readFile(filePath, \"utf-8\");\n if (content.trim()) {\n sections.push(content.trim());\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return sections.length > 0 ? sections.join(\"\\n\\n---\\n\\n\") : null;\n}\n\n/** Load project-specific memory (.clank.md) */\nasync function loadProjectMemory(projectRoot: string): Promise<string | null> {\n const candidates = [\".clank.md\", \".clankbuild.md\", \".llamabuild.md\"];\n\n for (const filename of candidates) {\n const filePath = join(projectRoot, filename);\n if (existsSync(filePath)) {\n try {\n const content = await readFile(filePath, \"utf-8\");\n return content.trim() || null;\n } catch {\n continue;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Ensure workspace directory has all template files.\n * Creates missing files from templates.\n */\nexport async function ensureWorkspaceFiles(workspaceDir: string, templateDir: string): Promise<void> {\n const { mkdir, copyFile } = await import(\"node:fs/promises\");\n await mkdir(workspaceDir, { recursive: true });\n\n for (const filename of [...WORKSPACE_FILES, \"BOOTSTRAP.md\", \"HEARTBEAT.md\"]) {\n const target = join(workspaceDir, filename);\n const source = join(templateDir, filename);\n if (!existsSync(target) && existsSync(source)) {\n await copyFile(source, target);\n }\n }\n}\n","export { AgentEngine, type AgentIdentity, type AgentEvents, type ConfirmAction } from \"./agent.js\";\nexport { ContextEngine, type CompactionResult } from \"./context-engine.js\";\nexport { buildSystemPrompt, ensureWorkspaceFiles } from \"./system-prompt.js\";\n","/**\n * Tool system type definitions.\n *\n * Tools are the agent's hands — they let it read files, write code,\n * run commands, search the web, etc. Each tool has a safety level\n * that controls whether it needs user confirmation before executing.\n */\n\n/** Safety classification for tools */\nexport type SafetyLevel = \"low\" | \"medium\" | \"high\";\n\n/** Context passed to tool execute/validate */\nexport interface ToolContext {\n /** Working directory for file operations */\n projectRoot: string;\n /** Whether external paths are allowed */\n allowExternal?: boolean;\n /** Auto-approve settings per safety level */\n autoApprove: { low: boolean; medium: boolean; high: boolean };\n /** Agent ID (for scoping) */\n agentId?: string;\n /** Abort signal */\n signal?: AbortSignal;\n}\n\n/** Validation result from tool.validate() */\nexport interface ValidationResult {\n ok: boolean;\n error?: string;\n}\n\n/** The interface every tool must implement */\nexport interface Tool {\n /** Tool definition sent to the LLM */\n definition: {\n name: string;\n description: string;\n parameters: {\n type: \"object\";\n properties: Record<string, unknown>;\n required?: string[];\n };\n };\n\n /** Safety classification — determines if user confirmation is needed */\n safetyLevel: SafetyLevel | ((args: Record<string, unknown>) => SafetyLevel);\n\n /** Whether this tool only reads data (safe in plan mode) */\n readOnly: boolean;\n\n /** Validate arguments before execution */\n validate(args: Record<string, unknown>, context: ToolContext): ValidationResult;\n\n /** Execute the tool and return a string result */\n execute(args: Record<string, unknown>, context: ToolContext): Promise<string>;\n\n /** Human-readable confirmation message for the action */\n formatConfirmation?(args: Record<string, unknown>): string;\n}\n\n/** Tool tier for local model optimization */\nexport type ToolTier = \"full\" | \"core\" | \"auto\";\n\n/** Keywords that trigger dynamic tool injection in \"auto\" tier */\nexport const AUTO_TIER_TRIGGERS: Record<string, string[]> = {\n web_fetch: [\"web\", \"fetch\", \"url\", \"http\", \"download\", \"website\"],\n web_search: [\"search\", \"google\", \"find online\", \"look up\", \"browse\"],\n npm_install: [\"install\", \"npm\", \"package\", \"dependency\"],\n pip_install: [\"pip\", \"python package\", \"pip install\"],\n install_tool: [\"install\", \"winget\", \"choco\", \"brew\", \"apt\"],\n generate_file: [\"generate\", \"pdf\", \"create file\", \"export\"],\n};\n\n/** Core tools available at all tiers */\nexport const CORE_TOOL_NAMES = [\n \"read_file\",\n \"write_file\",\n \"edit_file\",\n \"list_directory\",\n \"search_files\",\n \"glob_files\",\n \"bash\",\n \"git\",\n];\n","/**\n * Tool registry — manages available tools and handles tiering.\n *\n * The registry holds all registered tools and can filter them based on\n * the tool tier setting. This is critical for local model optimization:\n *\n * - \"full\": All tools available (best for capable models like Claude, GPT-4o)\n * - \"core\": Only 8 essential tools (best for smaller local models)\n * - \"auto\": Start with core, dynamically add tools when user message\n * contains relevant keywords (smart middle ground)\n *\n * Why tiering matters: Smaller models get confused when given too many\n * tools. Reducing the tool count improves their tool selection accuracy.\n */\n\nimport type { Tool, ToolTier } from \"./types.js\";\nimport { CORE_TOOL_NAMES, AUTO_TIER_TRIGGERS } from \"./types.js\";\nimport type { ToolDefinition } from \"../providers/types.js\";\n\nexport class ToolRegistry {\n private tools = new Map<string, Tool>();\n\n /** Register a tool */\n register(tool: Tool): void {\n this.tools.set(tool.definition.name, tool);\n }\n\n /** Get a tool by name */\n get(name: string): Tool | undefined {\n return this.tools.get(name);\n }\n\n /** Get all registered tools */\n getAll(): Tool[] {\n return Array.from(this.tools.values());\n }\n\n /** Get tool names */\n list(): string[] {\n return Array.from(this.tools.keys());\n }\n\n /**\n * Get tool definitions for the LLM, filtered by tier.\n *\n * @param tier - Which tool tier to use\n * @param userMessage - Current user message (for \"auto\" tier keyword matching)\n * @param allowlist - Optional allowlist of tool names (for per-agent filtering)\n * @param denylist - Optional denylist of tool names\n */\n getDefinitions(opts?: {\n tier?: ToolTier;\n userMessage?: string;\n allowlist?: string[];\n denylist?: string[];\n }): ToolDefinition[] {\n const tier = opts?.tier ?? \"full\";\n const userMessage = opts?.userMessage?.toLowerCase() ?? \"\";\n\n let toolNames: string[];\n\n switch (tier) {\n case \"core\":\n toolNames = CORE_TOOL_NAMES.filter((n) => this.tools.has(n));\n break;\n\n case \"auto\": {\n // Start with core tools\n const names = new Set(CORE_TOOL_NAMES.filter((n) => this.tools.has(n)));\n\n // Dynamically add tools based on keywords in the user message\n for (const [toolName, keywords] of Object.entries(AUTO_TIER_TRIGGERS)) {\n if (this.tools.has(toolName) && keywords.some((k) => userMessage.includes(k))) {\n names.add(toolName);\n }\n }\n\n toolNames = Array.from(names);\n break;\n }\n\n case \"full\":\n default:\n toolNames = this.list();\n break;\n }\n\n // Apply allowlist/denylist\n if (opts?.allowlist) {\n const allowed = new Set(opts.allowlist);\n toolNames = toolNames.filter((n) => allowed.has(n));\n }\n if (opts?.denylist) {\n const denied = new Set(opts.denylist);\n toolNames = toolNames.filter((n) => !denied.has(n));\n }\n\n return toolNames\n .map((name) => this.tools.get(name)!)\n .map((tool) => tool.definition as ToolDefinition);\n }\n\n /**\n * Register a tool from a plugin manifest.\n * Used by the plugin system for runtime tool loading.\n */\n registerFromManifest(manifest: {\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n safetyLevel: string;\n entrypoint: string;\n }): void {\n // Plugin tool loading will be implemented in the plugin sprint\n // For now, just validate the manifest shape\n if (!manifest.name || !manifest.description) {\n throw new Error(\"Plugin tool manifest must have name and description\");\n }\n }\n}\n","/**\n * Path containment guard.\n *\n * Prevents file tools from accessing paths outside the workspace.\n * All resolved paths must be within the projectRoot or explicitly\n * allowed external paths (with user confirmation).\n */\n\nimport { resolve, isAbsolute, normalize, relative } from \"node:path\";\n\n/**\n * Resolve a path and verify it's within the allowed root.\n * Returns the resolved path, or an error string if blocked.\n */\nexport function guardPath(\n inputPath: string,\n projectRoot: string,\n opts?: { allowExternal?: boolean },\n): { ok: true; path: string } | { ok: false; error: string } {\n // Resolve the full path\n const resolved = isAbsolute(inputPath)\n ? normalize(inputPath)\n : normalize(resolve(projectRoot, inputPath));\n\n // Check containment — resolved path must start with projectRoot\n const rel = relative(projectRoot, resolved);\n const isOutside = rel.startsWith(\"..\") || isAbsolute(rel);\n\n if (isOutside && !opts?.allowExternal) {\n return {\n ok: false,\n error: `Path \"${inputPath}\" resolves outside workspace. Resolved to: ${resolved}`,\n };\n }\n\n return { ok: true, path: resolved };\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\nimport { guardPath } from \"./path-guard.js\";\n\nexport const readFileTool: Tool = {\n definition: {\n name: \"read_file\",\n description:\n \"Read the contents of a file. Returns the file content with line numbers. \" +\n \"Supports text files, detects binary files. Use offset and limit for large files.\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"File path (absolute or relative to workspace)\" },\n offset: { type: \"number\", description: \"Start reading from this line number (1-based)\" },\n limit: { type: \"number\", description: \"Maximum number of lines to read\" },\n },\n required: [\"path\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.path || typeof args.path !== \"string\") {\n return { ok: false, error: \"path is required and must be a string\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const guard = guardPath(args.path as string, ctx.projectRoot, { allowExternal: ctx.allowExternal });\n if (!guard.ok) return guard.error;\n const filePath = guard.path;\n\n try {\n const fileStats = await stat(filePath);\n if (fileStats.isDirectory()) {\n return `Error: ${filePath} is a directory, not a file. Use list_directory instead.`;\n }\n\n // Binary detection: check first 8KB for null bytes\n const probe = Buffer.alloc(8192);\n const { createReadStream } = await import(\"node:fs\");\n const stream = createReadStream(filePath, { start: 0, end: 8191 });\n let probeLen = 0;\n for await (const chunk of stream) {\n (chunk as Buffer).copy(probe, probeLen);\n probeLen += (chunk as Buffer).length;\n }\n if (probe.subarray(0, probeLen).includes(0)) {\n return `Binary file detected: ${filePath} (${fileStats.size} bytes)`;\n }\n\n const content = await readFile(filePath, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n const offset = Math.max(1, Number(args.offset) || 1);\n const limit = Number(args.limit) || lines.length;\n\n const sliced = lines.slice(offset - 1, offset - 1 + limit);\n const numbered = sliced.map((line, i) => `${offset + i}\\t${line}`).join(\"\\n\");\n\n return numbered || \"(empty file)\";\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return `Error reading file: ${msg}`;\n }\n },\n};\n","import { writeFile, mkdir } from \"node:fs/promises\";\nimport { dirname, isAbsolute } from \"node:path\";\nimport { guardPath } from \"./path-guard.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\nexport const writeFileTool: Tool = {\n definition: {\n name: \"write_file\",\n description:\n \"Write content to a file. Creates the file if it doesn't exist, \" +\n \"overwrites if it does. Automatically creates parent directories.\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"File path (absolute or relative to workspace)\" },\n content: { type: \"string\", description: \"Content to write to the file\" },\n },\n required: [\"path\", \"content\"],\n },\n },\n\n safetyLevel(args: Record<string, unknown>) {\n const p = String(args.path || \"\");\n // External paths or overwriting existing files are higher risk\n if (isAbsolute(p) && !p.startsWith(process.cwd())) return \"high\";\n return \"medium\";\n },\n\n readOnly: false,\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.path || typeof args.path !== \"string\") {\n return { ok: false, error: \"path is required\" };\n }\n if (typeof args.content !== \"string\") {\n return { ok: false, error: \"content is required\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const guard = guardPath(args.path as string, ctx.projectRoot, { allowExternal: ctx.allowExternal });\n if (!guard.ok) return guard.error;\n const filePath = guard.path;\n\n try {\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, args.content as string, \"utf-8\");\n\n const lines = (args.content as string).split(\"\\n\").length;\n return `Wrote ${lines} lines to ${filePath}`;\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return `Error writing file: ${msg}`;\n }\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `Write to ${args.path}`;\n },\n};\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { isAbsolute } from \"node:path\";\nimport { guardPath } from \"./path-guard.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\nexport const editFileTool: Tool = {\n definition: {\n name: \"edit_file\",\n description:\n \"Edit a file by replacing an exact string match with new content. \" +\n \"The old_string must match exactly (including whitespace). \" +\n \"Use replace_all to replace every occurrence.\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"File path\" },\n old_string: { type: \"string\", description: \"Exact string to find and replace\" },\n new_string: { type: \"string\", description: \"Replacement string\" },\n replace_all: { type: \"boolean\", description: \"Replace all occurrences (default: false)\" },\n },\n required: [\"path\", \"old_string\", \"new_string\"],\n },\n },\n\n safetyLevel(args: Record<string, unknown>) {\n const p = String(args.path || \"\");\n if (isAbsolute(p) && !p.startsWith(process.cwd())) return \"high\";\n return \"medium\";\n },\n\n readOnly: false,\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.path || typeof args.path !== \"string\") return { ok: false, error: \"path is required\" };\n if (typeof args.old_string !== \"string\") return { ok: false, error: \"old_string is required\" };\n if (typeof args.new_string !== \"string\") return { ok: false, error: \"new_string is required\" };\n if (args.old_string === args.new_string) return { ok: false, error: \"old_string and new_string are the same\" };\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const guard = guardPath(args.path as string, ctx.projectRoot, { allowExternal: ctx.allowExternal });\n if (!guard.ok) return guard.error;\n const filePath = guard.path;\n\n try {\n const content = await readFile(filePath, \"utf-8\");\n const oldStr = args.old_string as string;\n const newStr = args.new_string as string;\n const replaceAll = Boolean(args.replace_all);\n\n if (!content.includes(oldStr)) {\n return `Error: old_string not found in ${filePath}. Make sure it matches exactly including whitespace.`;\n }\n\n if (!replaceAll) {\n // Check uniqueness — if old_string appears more than once, reject\n const count = content.split(oldStr).length - 1;\n if (count > 1) {\n return `Error: old_string appears ${count} times in ${filePath}. Use replace_all: true or provide more context to make it unique.`;\n }\n }\n\n const updated = replaceAll\n ? content.split(oldStr).join(newStr)\n : content.replace(oldStr, newStr);\n\n await writeFile(filePath, updated, \"utf-8\");\n\n const replacements = replaceAll ? content.split(oldStr).length - 1 : 1;\n return `Edited ${filePath} (${replacements} replacement${replacements > 1 ? \"s\" : \"\"})`;\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return `Error editing file: ${msg}`;\n }\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `Edit ${args.path}`;\n },\n};\n","import { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { guardPath } from \"./path-guard.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\nexport const listDirectoryTool: Tool = {\n definition: {\n name: \"list_directory\",\n description: \"List files and directories in a path. Shows names, sizes, and types.\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"Directory path (default: workspace root)\" },\n },\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(_args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n let dirPath = ctx.projectRoot;\n if (args.path) {\n const guard = guardPath(args.path as string, ctx.projectRoot, { allowExternal: ctx.allowExternal });\n if (!guard.ok) return guard.error;\n dirPath = guard.path;\n }\n\n try {\n const entries = await readdir(dirPath);\n if (entries.length === 0) return `(empty directory: ${dirPath})`;\n\n const lines: string[] = [];\n for (const entry of entries.slice(0, 100)) {\n try {\n const full = join(dirPath, entry);\n const s = await stat(full);\n const type = s.isDirectory() ? \"dir\" : \"file\";\n const size = s.isDirectory() ? \"\" : ` (${formatSize(s.size)})`;\n lines.push(`${type}\\t${entry}${size}`);\n } catch {\n lines.push(`?\\t${entry}`);\n }\n }\n\n if (entries.length > 100) {\n lines.push(`... and ${entries.length - 100} more entries`);\n }\n\n return lines.join(\"\\n\");\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return `Error listing directory: ${msg}`;\n }\n },\n};\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes}B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n","import { readdir, readFile, stat } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\nimport { guardPath } from \"./path-guard.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\n/** Directories to skip during search */\nconst IGNORE_DIRS = new Set([\n \"node_modules\", \".git\", \"dist\", \"build\", \".next\", \"__pycache__\",\n \".cache\", \"coverage\", \".venv\", \"venv\", \"target\",\n]);\n\nexport const searchFilesTool: Tool = {\n definition: {\n name: \"search_files\",\n description:\n \"Search for a regex pattern across files in the workspace. \" +\n \"Returns matching lines with file paths and line numbers. \" +\n \"Ignores node_modules, .git, dist, etc.\",\n parameters: {\n type: \"object\",\n properties: {\n pattern: { type: \"string\", description: \"Regex pattern to search for\" },\n path: { type: \"string\", description: \"Directory to search in (default: workspace root)\" },\n glob: { type: \"string\", description: \"File glob filter, e.g. '*.ts' or '*.py'\" },\n max_results: { type: \"number\", description: \"Maximum results to return (default: 50)\" },\n },\n required: [\"pattern\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.pattern || typeof args.pattern !== \"string\") {\n return { ok: false, error: \"pattern is required\" };\n }\n // Validate regex\n try {\n new RegExp(args.pattern as string);\n } catch {\n return { ok: false, error: \"Invalid regex pattern\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n let searchPath = ctx.projectRoot;\n if (args.path) {\n const guard = guardPath(args.path as string, ctx.projectRoot, { allowExternal: ctx.allowExternal });\n if (!guard.ok) return guard.error;\n searchPath = guard.path;\n }\n\n const maxResults = Number(args.max_results) || 50;\n const globFilter = args.glob as string | undefined;\n let regex: RegExp;\n try {\n regex = new RegExp(args.pattern as string, \"gi\");\n } catch {\n return `Error: Invalid regex pattern`;\n }\n\n const results: string[] = [];\n\n async function searchDir(dir: string): Promise<void> {\n if (results.length >= maxResults) return;\n\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (results.length >= maxResults) return;\n if (IGNORE_DIRS.has(entry)) continue;\n\n const full = join(dir, entry);\n let s;\n try {\n s = await stat(full);\n } catch {\n continue;\n }\n\n if (s.isDirectory()) {\n await searchDir(full);\n } else if (s.isFile() && s.size < 1024 * 1024) {\n // Skip files >1MB\n if (globFilter) {\n const ext = globFilter.replace(\"*\", \"\");\n if (!entry.endsWith(ext)) continue;\n }\n\n try {\n const content = await readFile(full, \"utf-8\");\n const lines = content.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n regex.lastIndex = 0;\n if (regex.test(lines[i])) {\n const rel = relative(ctx.projectRoot, full);\n results.push(`${rel}:${i + 1}\\t${lines[i].trim()}`);\n if (results.length >= maxResults) return;\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n }\n\n await searchDir(searchPath);\n\n if (results.length === 0) return `No matches found for pattern: ${args.pattern}`;\n return results.join(\"\\n\");\n },\n};\n","import { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { guardPath } from \"./path-guard.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\nconst IGNORE_DIRS = new Set([\n \"node_modules\", \".git\", \"dist\", \"build\", \".next\", \"__pycache__\",\n \".cache\", \"coverage\", \".venv\", \"venv\", \"target\",\n]);\n\nexport const globFilesTool: Tool = {\n definition: {\n name: \"glob_files\",\n description:\n \"Find files matching a glob pattern. Supports **, *, and ? wildcards. \" +\n \"Returns matching file paths sorted by modification time (newest first). Max 200 results.\",\n parameters: {\n type: \"object\",\n properties: {\n pattern: { type: \"string\", description: \"Glob pattern, e.g. '**/*.ts' or 'src/**/*.js'\" },\n path: { type: \"string\", description: \"Base directory (default: workspace root)\" },\n },\n required: [\"pattern\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.pattern || typeof args.pattern !== \"string\") {\n return { ok: false, error: \"pattern is required\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n let basePath = ctx.projectRoot;\n if (args.path) {\n const guard = guardPath(args.path as string, ctx.projectRoot, { allowExternal: ctx.allowExternal });\n if (!guard.ok) return guard.error;\n basePath = guard.path;\n }\n\n const pattern = args.pattern as string;\n const regex = globToRegex(pattern);\n const matches: Array<{ path: string; mtime: number }> = [];\n\n async function scanDir(dir: string, relDir: string): Promise<void> {\n if (matches.length >= 200) return;\n\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (matches.length >= 200) return;\n if (IGNORE_DIRS.has(entry)) continue;\n\n const full = join(dir, entry);\n const rel = relDir ? `${relDir}/${entry}` : entry;\n\n let s;\n try {\n s = await stat(full);\n } catch {\n continue;\n }\n\n if (s.isDirectory()) {\n await scanDir(full, rel);\n } else if (s.isFile() && regex.test(rel)) {\n matches.push({ path: rel, mtime: s.mtimeMs });\n }\n }\n }\n\n await scanDir(basePath, \"\");\n\n if (matches.length === 0) return `No files matching: ${pattern}`;\n\n // Sort by mtime descending (newest first)\n matches.sort((a, b) => b.mtime - a.mtime);\n\n return matches.map((m) => m.path).join(\"\\n\");\n },\n};\n\n/** Convert a simple glob pattern to a regex */\nfunction globToRegex(pattern: string): RegExp {\n let regex = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\") // Escape special regex chars\n .replace(/\\*\\*/g, \"{{GLOBSTAR}}\") // Temp placeholder\n .replace(/\\*/g, \"[^/]*\") // * matches within directory\n .replace(/\\?/g, \"[^/]\") // ? matches single char\n .replace(/\\{\\{GLOBSTAR\\}\\}/g, \".*\"); // ** matches across directories\n\n return new RegExp(`^${regex}$`, \"i\");\n}\n","import { execFile } from \"node:child_process\";\nimport { resolve, isAbsolute } from \"node:path\";\nimport { platform } from \"node:os\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\n/** Commands that are blocked for safety — defense in depth */\nconst BLOCKED_PATTERNS = [\n // Recursive deletion of root/system dirs\n /rm\\s+.*-[a-z]*r[a-z]*f[a-z]*\\s+\\//i,\n /rm\\s+.*-[a-z]*f[a-z]*r[a-z]*\\s+\\//i,\n /rm\\s+.*--recursive.*\\//i,\n /rm\\s+.*--force.*\\//i,\n /Remove-Item.*-Recurse/i,\n /del\\s+\\/[sS].*[\\\\\\/]/i,\n /rd\\s+\\/[sS].*[\\\\\\/]/i,\n // Disk formatting\n /\\bformat\\s+[a-z]:/i,\n /\\bmkfs\\b/i,\n /\\bdd\\s+.*of=\\/dev/i,\n /diskpart/i,\n // Force push to main branches\n /git\\s+push\\s+.*(-f|--force).*\\b(main|master)\\b/i,\n /git\\s+push\\s+.*\\b(main|master)\\b.*(-f|--force)/i,\n // Shell-in-shell execution (limits encoded payloads)\n /\\|\\s*(bash|sh|cmd|powershell|pwsh)\\b/i,\n /base64\\s+(-d|--decode).*\\|\\s*(bash|sh)/i,\n // Direct system damage\n /\\bchmod\\s+.*777\\s+\\//i,\n /\\bchown\\s+.*\\//i,\n /\\bshutdown\\b/i,\n /\\breboot\\b/i,\n // Windows-specific\n /powershell\\s+.*-[eE]ncodedCommand/i,\n /reg\\s+(delete|add).*\\\\\\\\HKLM/i,\n];\n\nconst MAX_OUTPUT = 30 * 1024; // 30KB output cap\nconst TIMEOUT_MS = 120_000; // 2 minute timeout\n\nexport const bashTool: Tool = {\n definition: {\n name: \"bash\",\n description:\n \"Execute a shell command. Use for system operations, builds, installs, etc. \" +\n \"Output is capped at 30KB. Times out after 2 minutes. \" +\n \"Dangerous commands (rm -rf /, format, etc.) are blocked.\",\n parameters: {\n type: \"object\",\n properties: {\n command: { type: \"string\", description: \"The shell command to execute\" },\n cwd: { type: \"string\", description: \"Working directory (default: workspace root)\" },\n timeout: { type: \"number\", description: \"Timeout in milliseconds (default: 120000)\" },\n },\n required: [\"command\"],\n },\n },\n\n safetyLevel: \"high\",\n readOnly: false,\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.command || typeof args.command !== \"string\") {\n return { ok: false, error: \"command is required\" };\n }\n\n const cmd = args.command as string;\n for (const pattern of BLOCKED_PATTERNS) {\n if (pattern.test(cmd)) {\n return { ok: false, error: `Blocked: dangerous command pattern detected` };\n }\n }\n\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const command = args.command as string;\n const cwd = args.cwd\n ? isAbsolute(args.cwd as string)\n ? (args.cwd as string)\n : resolve(ctx.projectRoot, args.cwd as string)\n : ctx.projectRoot;\n const timeout = Number(args.timeout) || TIMEOUT_MS;\n\n const shell = platform() === \"win32\" ? \"cmd.exe\" : \"/bin/bash\";\n const shellArgs = platform() === \"win32\" ? [\"/c\", command] : [\"-c\", command];\n\n return new Promise<string>((resolvePromise) => {\n const proc = execFile(\n shell,\n shellArgs,\n {\n cwd,\n timeout,\n maxBuffer: MAX_OUTPUT * 2,\n signal: ctx.signal,\n },\n (error, stdout, stderr) => {\n let output = \"\";\n\n if (stdout) output += stdout;\n if (stderr) output += (output ? \"\\n\" : \"\") + stderr;\n\n // Cap output\n if (output.length > MAX_OUTPUT) {\n output = output.slice(0, MAX_OUTPUT) + \"\\n... (output truncated)\";\n }\n\n if (error && !output) {\n output = `Error: ${error.message}`;\n }\n\n if (error && \"code\" in error) {\n output += `\\n(exit code: ${(error as NodeJS.ErrnoException & { code?: number }).code})`;\n }\n\n resolvePromise(output || \"(no output)\");\n },\n );\n });\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `Run: ${args.command}`;\n },\n};\n","import { execFile } from \"node:child_process\";\nimport { resolve, isAbsolute } from \"node:path\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\n/** Git subcommands classified by risk level */\nconst SAFE_SUBCOMMANDS = new Set([\n \"status\", \"log\", \"diff\", \"show\", \"branch\", \"tag\", \"remote\",\n \"stash\", \"blame\", \"shortlog\", \"describe\", \"rev-parse\",\n \"ls-files\", \"ls-tree\", \"cat-file\",\n]);\n\nconst DANGEROUS_SUBCOMMANDS = new Set([\n \"push\", \"reset\", \"rebase\", \"merge\", \"cherry-pick\",\n \"clean\", \"checkout\", \"restore\",\n]);\n\nexport const gitTool: Tool = {\n definition: {\n name: \"git\",\n description:\n \"Run a git command. Safe commands (status, log, diff, etc.) are low risk. \" +\n \"Mutating commands (push, reset, rebase) are high risk and need confirmation.\",\n parameters: {\n type: \"object\",\n properties: {\n args: { type: \"string\", description: \"Git arguments, e.g. 'status' or 'log --oneline -10'\" },\n cwd: { type: \"string\", description: \"Repository directory (default: workspace root)\" },\n },\n required: [\"args\"],\n },\n },\n\n safetyLevel(args: Record<string, unknown>) {\n const gitArgs = String(args.args || \"\");\n const subcommand = gitArgs.trim().split(/\\s+/)[0];\n if (SAFE_SUBCOMMANDS.has(subcommand)) return \"low\";\n if (DANGEROUS_SUBCOMMANDS.has(subcommand)) return \"high\";\n return \"medium\";\n },\n\n readOnly: false, // depends on subcommand, but conservatively false\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.args || typeof args.args !== \"string\") {\n return { ok: false, error: \"args is required\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const gitArgs = (args.args as string).trim().split(/\\s+/);\n const cwd = args.cwd\n ? isAbsolute(args.cwd as string)\n ? (args.cwd as string)\n : resolve(ctx.projectRoot, args.cwd as string)\n : ctx.projectRoot;\n\n return new Promise<string>((resolvePromise) => {\n execFile(\n \"git\",\n gitArgs,\n { cwd, timeout: 30_000, maxBuffer: 1024 * 1024 },\n (error, stdout, stderr) => {\n let output = \"\";\n if (stdout) output += stdout;\n if (stderr) output += (output ? \"\\n\" : \"\") + stderr;\n if (error && !output) output = `Error: ${error.message}`;\n\n // Cap output\n if (output.length > 30 * 1024) {\n output = output.slice(0, 30 * 1024) + \"\\n... (output truncated)\";\n }\n\n resolvePromise(output || \"(no output)\");\n },\n );\n });\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `Run: git ${args.args}`;\n },\n};\n","/**\n * Configuration system for Clank.\n *\n * Config lives at ~/.clank/config.json5 (or %APPDATA%/Clank/config.json5 on Windows).\n * Uses JSON5 for human-friendly comments and trailing commas.\n * Supports ${ENV_VAR} substitution for secrets.\n */\n\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir, platform } from \"node:os\";\nimport JSON5 from \"json5\";\nimport type { ProviderConfig } from \"../providers/router.js\";\nimport type { ToolTier } from \"../tools/types.js\";\nimport type { ModelConfig } from \"../providers/types.js\";\n\n/** Full Clank configuration schema */\nexport interface ClankConfig {\n /** Gateway settings */\n gateway: {\n port: number;\n bind: \"loopback\" | \"lan\" | string;\n auth: {\n mode: \"token\" | \"pin\" | \"none\";\n token?: string;\n };\n };\n\n /** Agent definitions */\n agents: {\n defaults: {\n model: ModelConfig;\n workspace: string;\n toolTier: ToolTier;\n temperature?: number;\n maxResponseTokens?: number;\n };\n list: Array<{\n id: string;\n name?: string;\n model?: ModelConfig;\n workspace?: string;\n toolTier?: ToolTier;\n tools?: { allow?: string[]; deny?: string[] };\n }>;\n };\n\n /** Model provider configs */\n models: {\n providers: ProviderConfig;\n };\n\n /** Channel configs */\n channels: {\n telegram?: {\n enabled: boolean;\n botToken?: string;\n allowFrom?: Array<string | number>;\n groups?: Record<string, { requireMention?: boolean }>;\n };\n discord?: {\n enabled: boolean;\n botToken?: string;\n };\n web?: {\n enabled: boolean;\n };\n };\n\n /** Session settings */\n session: {\n dmScope: \"main\" | \"per-peer\" | \"per-channel-peer\";\n maxSessions: number;\n resetMode?: \"idle\" | \"daily\";\n resetAfterMinutes?: number;\n };\n\n /** Tool settings */\n tools: {\n autoApprove: { low: boolean; medium: boolean; high: boolean };\n webSearch?: { enabled: boolean; provider?: string; apiKey?: string };\n };\n\n /** Safety settings */\n safety: {\n confirmExternal: boolean;\n };\n\n /** Third-party API integrations */\n integrations: {\n elevenlabs?: {\n enabled: boolean;\n apiKey: string;\n voiceId?: string;\n model?: string; // e.g., \"eleven_multilingual_v2\"\n };\n whisper?: {\n enabled: boolean;\n provider: \"local\" | \"openai\"; // local = whisper.cpp, openai = Whisper API\n apiKey?: string; // only for openai provider\n model?: string;\n };\n imageGen?: {\n enabled: boolean;\n provider: \"openai\" | \"fal\";\n apiKey?: string;\n };\n /** Generic integrations — extensible for future services */\n [key: string]: { enabled: boolean; apiKey?: string; [k: string]: unknown } | undefined;\n };\n}\n\n/** Get the config directory path */\nexport function getConfigDir(): string {\n if (platform() === \"win32\") {\n return join(process.env.APPDATA || join(homedir(), \"AppData\", \"Roaming\"), \"Clank\");\n }\n return join(homedir(), \".clank\");\n}\n\n/** Get the config file path */\nexport function getConfigPath(): string {\n return join(getConfigDir(), \"config.json5\");\n}\n\n/** Default configuration */\nexport function defaultConfig(): ClankConfig {\n return {\n gateway: {\n port: 18790,\n bind: \"loopback\",\n auth: { mode: \"token\" },\n },\n agents: {\n defaults: {\n model: { primary: \"ollama/qwen3.5\" },\n workspace: join(getConfigDir(), \"workspace\"),\n toolTier: \"auto\",\n temperature: 0.7,\n },\n list: [],\n },\n models: {\n providers: {\n ollama: { baseUrl: \"http://127.0.0.1:11434\" },\n },\n },\n channels: {\n web: { enabled: true },\n },\n session: {\n dmScope: \"main\",\n maxSessions: 50,\n },\n tools: {\n autoApprove: { low: true, medium: false, high: false },\n },\n safety: {\n confirmExternal: true,\n },\n integrations: {},\n };\n}\n\n/**\n * Substitute ${ENV_VAR} references in string values.\n * This lets users reference secrets from environment variables\n * instead of storing them in the config file.\n */\nfunction substituteEnvVars(obj: unknown): unknown {\n if (typeof obj === \"string\") {\n return obj.replace(/\\$\\{(\\w+)\\}/g, (_, varName) => {\n return process.env[varName] || \"\";\n });\n }\n if (Array.isArray(obj)) {\n return obj.map(substituteEnvVars);\n }\n if (obj && typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = substituteEnvVars(value);\n }\n return result;\n }\n return obj;\n}\n\n/** Deep merge two objects (source overrides target) */\nfunction deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n const result = { ...target };\n for (const [key, value] of Object.entries(source)) {\n if (value && typeof value === \"object\" && !Array.isArray(value) && target[key] && typeof target[key] === \"object\") {\n result[key] = deepMerge(target[key] as Record<string, unknown>, value as Record<string, unknown>);\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\n/** Load configuration from disk, merging with defaults */\nexport async function loadConfig(): Promise<ClankConfig> {\n const configPath = getConfigPath();\n const defaults = defaultConfig();\n\n if (!existsSync(configPath)) {\n return defaults;\n }\n\n try {\n const raw = await readFile(configPath, \"utf-8\");\n const parsed = JSON5.parse(raw) as Record<string, unknown>;\n const substituted = substituteEnvVars(parsed) as Record<string, unknown>;\n return deepMerge(defaults as unknown as Record<string, unknown>, substituted) as unknown as ClankConfig;\n } catch (err) {\n console.error(`Warning: Failed to parse config at ${configPath}, using defaults`);\n return defaults;\n }\n}\n\n/** Save configuration to disk */\nexport async function saveConfig(config: ClankConfig): Promise<void> {\n const configPath = getConfigPath();\n await mkdir(getConfigDir(), { recursive: true });\n\n // JSON5 stringify with nice formatting\n const content = JSON5.stringify(config, null, 2);\n await writeFile(configPath, content, \"utf-8\");\n}\n\n/** Ensure the config directory and workspace exist */\nexport async function ensureConfigDir(): Promise<void> {\n const configDir = getConfigDir();\n await mkdir(configDir, { recursive: true });\n await mkdir(join(configDir, \"workspace\"), { recursive: true });\n await mkdir(join(configDir, \"conversations\"), { recursive: true });\n await mkdir(join(configDir, \"memory\"), { recursive: true });\n await mkdir(join(configDir, \"logs\"), { recursive: true });\n}\n","/**\n * Config hot-reload — watches config.json5 for changes.\n *\n * When the config file changes, it reloads and emits an event\n * so the gateway can apply changes without restarting.\n */\n\nimport { watch, type FSWatcher } from \"node:fs\";\nimport { EventEmitter } from \"node:events\";\nimport { loadConfig, getConfigPath, type ClankConfig } from \"./config.js\";\n\nexport class ConfigWatcher extends EventEmitter {\n private watcher: FSWatcher | null = null;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private currentConfig: ClankConfig | null = null;\n\n /** Start watching the config file */\n async start(): Promise<ClankConfig> {\n this.currentConfig = await loadConfig();\n const configPath = getConfigPath();\n\n try {\n this.watcher = watch(configPath, { persistent: false }, () => {\n // Debounce — config editors may write multiple times\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => this.reload(), 500);\n });\n } catch {\n // Config file might not exist yet — that's fine\n }\n\n return this.currentConfig;\n }\n\n /** Stop watching */\n stop(): void {\n if (this.watcher) {\n this.watcher.close();\n this.watcher = null;\n }\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n }\n\n /** Reload config and emit change event */\n private async reload(): Promise<void> {\n try {\n const newConfig = await loadConfig();\n const oldConfig = this.currentConfig;\n this.currentConfig = newConfig;\n this.emit(\"change\", { oldConfig, newConfig });\n } catch (err) {\n this.emit(\"error\", err);\n }\n }\n\n /** Get the current config */\n getConfig(): ClankConfig | null {\n return this.currentConfig;\n }\n}\n","export {\n loadConfig,\n saveConfig,\n defaultConfig,\n getConfigDir,\n getConfigPath,\n ensureConfigDir,\n type ClankConfig,\n} from \"./config.js\";\n\nexport { ConfigWatcher } from \"./watcher.js\";\n","/**\n * Web search tool — uses Brave Search API.\n *\n * Brave Search has a free tier which makes it the default choice\n * for a local-first tool. API key configured during onboarding.\n */\n\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\nexport const webSearchTool: Tool = {\n definition: {\n name: \"web_search\",\n description:\n \"Search the web using Brave Search. Returns relevant results with titles, URLs, and snippets. \" +\n \"Requires a Brave Search API key configured in settings.\",\n parameters: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Search query\" },\n count: { type: \"number\", description: \"Number of results (default: 5, max: 20)\" },\n },\n required: [\"query\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>): ValidationResult {\n if (!args.query || typeof args.query !== \"string\") {\n return { ok: false, error: \"query is required\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const query = args.query as string;\n const count = Math.min(Number(args.count) || 5, 20);\n\n // Load API key from config\n const { loadConfig } = await import(\"../config/index.js\");\n const config = await loadConfig();\n const apiKey = config.tools.webSearch?.apiKey;\n\n if (!apiKey) {\n return \"Error: Brave Search API key not configured. Run `clank setup --section search` or tell me to set it up.\";\n }\n\n try {\n const url = `https://api.search.brave.com/res/v1/web/search?q=${encodeURIComponent(query)}&count=${count}`;\n const res = await fetch(url, {\n headers: {\n \"Accept\": \"application/json\",\n \"Accept-Encoding\": \"gzip\",\n \"X-Subscription-Token\": apiKey,\n },\n signal: ctx.signal,\n });\n\n if (!res.ok) {\n return `Search error: ${res.status} ${res.statusText}`;\n }\n\n const data = await res.json() as {\n web?: { results?: Array<{ title: string; url: string; description: string }> };\n };\n\n const results = data.web?.results || [];\n if (results.length === 0) return `No results found for: ${query}`;\n\n return results.map((r, i) =>\n `${i + 1}. ${r.title}\\n ${r.url}\\n ${r.description}`\n ).join(\"\\n\\n\");\n } catch (err) {\n return `Search error: ${err instanceof Error ? err.message : err}`;\n }\n },\n};\n","/**\n * Web fetch tool — fetch content from a URL.\n */\n\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\nconst MAX_BODY = 500 * 1024; // 500KB cap\n\nexport const webFetchTool: Tool = {\n definition: {\n name: \"web_fetch\",\n description: \"Fetch content from a URL. Returns the response body as text. Max 500KB.\",\n parameters: {\n type: \"object\",\n properties: {\n url: { type: \"string\", description: \"URL to fetch\" },\n },\n required: [\"url\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>): ValidationResult {\n if (!args.url || typeof args.url !== \"string\") {\n return { ok: false, error: \"url is required\" };\n }\n try {\n const parsed = new URL(args.url as string);\n // Block SSRF targets\n if (parsed.protocol === \"file:\") return { ok: false, error: \"file:// URLs are not allowed\" };\n const host = parsed.hostname.toLowerCase();\n if (host === \"localhost\" || host === \"127.0.0.1\" || host === \"[::1]\" || host === \"0.0.0.0\") {\n return { ok: false, error: \"localhost URLs are blocked (SSRF protection)\" };\n }\n if (host === \"169.254.169.254\" || host === \"metadata.google.internal\") {\n return { ok: false, error: \"Cloud metadata endpoints are blocked\" };\n }\n if (host.endsWith(\".internal\") || host.endsWith(\".local\")) {\n return { ok: false, error: \"Internal network hostnames are blocked\" };\n }\n } catch {\n return { ok: false, error: \"Invalid URL\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const url = args.url as string;\n\n try {\n const res = await fetch(url, {\n headers: { \"User-Agent\": \"Clank/0.1.0\" },\n signal: ctx.signal || AbortSignal.timeout(30_000),\n });\n\n if (!res.ok) {\n return `HTTP ${res.status}: ${res.statusText}`;\n }\n\n const contentType = res.headers.get(\"content-type\") || \"\";\n if (contentType.includes(\"application/json\")) {\n const json = await res.json();\n const text = JSON.stringify(json, null, 2);\n return text.length > MAX_BODY ? text.slice(0, MAX_BODY) + \"\\n... (truncated)\" : text;\n }\n\n const text = await res.text();\n return text.length > MAX_BODY ? text.slice(0, MAX_BODY) + \"\\n... (truncated)\" : text;\n } catch (err) {\n return `Fetch error: ${err instanceof Error ? err.message : err}`;\n }\n },\n};\n","/**\n * Redact sensitive fields from config before exposing to LLMs or clients.\n *\n * API keys, bot tokens, and auth tokens are replaced with \"[REDACTED]\"\n * to prevent accidental leakage to cloud LLM providers or WebSocket clients.\n */\n\nconst SENSITIVE_KEYS = new Set([\n \"apikey\", \"api_key\", \"apiKey\",\n \"token\", \"bottoken\", \"botToken\",\n \"secret\", \"password\", \"pin\",\n]);\n\nexport function redactConfig(obj: unknown): unknown {\n if (typeof obj === \"string\") return obj;\n if (Array.isArray(obj)) return obj.map(redactConfig);\n if (obj && typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n if (SENSITIVE_KEYS.has(key) && typeof value === \"string\" && value.length > 0) {\n result[key] = \"[REDACTED]\";\n } else if (typeof value === \"object\" && value !== null) {\n result[key] = redactConfig(value);\n } else {\n result[key] = value;\n }\n }\n return result;\n }\n return obj;\n}\n","/**\n * Config tool — lets the agent read and modify gateway config.\n *\n * This is the foundation of self-configuration. Instead of manually\n * editing config.json5, users just tell their agent what they want\n * and the agent uses this tool to make it happen.\n */\n\nimport { loadConfig, saveConfig, getConfigPath } from \"../../config/index.js\";\nimport { redactConfig } from \"../../config/redact.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"../types.js\";\n\nexport const configTool: Tool = {\n definition: {\n name: \"config\",\n description:\n \"Read or modify the Clank gateway configuration. Use 'read' to see current config, \" +\n \"'set' to change a value, or 'get' to read a specific key. \" +\n \"Keys use dot notation: 'gateway.port', 'agents.defaults.model.primary', etc.\",\n parameters: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n description: \"'read' (full config), 'get' (specific key), or 'set' (change a value)\",\n },\n key: { type: \"string\", description: \"Config key in dot notation (for get/set)\" },\n value: { type: \"string\", description: \"New value to set (for set action). JSON parsed if possible.\" },\n },\n required: [\"action\"],\n },\n },\n\n safetyLevel: (args) => (args.action === \"read\" || args.action === \"get\") ? \"low\" : \"medium\",\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n const action = args.action as string;\n if (![\"read\", \"get\", \"set\"].includes(action)) {\n return { ok: false, error: \"action must be 'read', 'get', or 'set'\" };\n }\n if ((action === \"get\" || action === \"set\") && !args.key) {\n return { ok: false, error: \"key is required for get/set\" };\n }\n if (action === \"set\" && args.value === undefined) {\n return { ok: false, error: \"value is required for set\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const action = args.action as string;\n const config = await loadConfig();\n\n if (action === \"read\") {\n return JSON.stringify(redactConfig(config), null, 2);\n }\n\n const key = args.key as string;\n const keys = key.split(\".\");\n\n if (action === \"get\") {\n let current: unknown = config;\n for (const k of keys) {\n if (current && typeof current === \"object\") {\n current = (current as Record<string, unknown>)[k];\n } else {\n return `Key not found: ${key}`;\n }\n }\n return typeof current === \"object\" ? JSON.stringify(current, null, 2) : String(current);\n }\n\n if (action === \"set\") {\n let parsed: unknown = args.value;\n try {\n parsed = JSON.parse(args.value as string);\n } catch {\n // Keep as string\n }\n\n // Navigate to parent and set the value\n let current: Record<string, unknown> = config as unknown as Record<string, unknown>;\n for (let i = 0; i < keys.length - 1; i++) {\n if (!current[keys[i]] || typeof current[keys[i]] !== \"object\") {\n current[keys[i]] = {};\n }\n current = current[keys[i]] as Record<string, unknown>;\n }\n current[keys[keys.length - 1]] = parsed;\n\n await saveConfig(config);\n return `Set ${key} = ${JSON.stringify(parsed)}`;\n }\n\n return \"Unknown action\";\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n if (args.action === \"set\") return `Set config: ${args.key} = ${args.value}`;\n return `Read config`;\n },\n};\n","/**\n * Channel tool — add, remove, and configure channels through conversation.\n *\n * \"Hey, connect my Telegram bot\" → agent uses this tool to add\n * the Telegram config, enable the adapter, and restart it.\n */\n\nimport { loadConfig, saveConfig } from \"../../config/index.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"../types.js\";\n\nexport const channelTool: Tool = {\n definition: {\n name: \"manage_channel\",\n description:\n \"Add, remove, or configure a messaging channel (Telegram, Discord, Slack, etc.). \" +\n \"Use 'list' to see configured channels, 'add' to set one up, 'remove' to disable, \" +\n \"'configure' to change settings.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"'list', 'add', 'remove', or 'configure'\" },\n channel: { type: \"string\", description: \"Channel name: 'telegram', 'discord', 'slack', 'web'\" },\n settings: { type: \"string\", description: \"JSON settings to apply (for add/configure)\" },\n },\n required: [\"action\"],\n },\n },\n\n safetyLevel: (args) => args.action === \"list\" ? \"low\" : \"medium\",\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n const action = args.action as string;\n if (![\"list\", \"add\", \"remove\", \"configure\"].includes(action)) {\n return { ok: false, error: \"action must be 'list', 'add', 'remove', or 'configure'\" };\n }\n if (action !== \"list\" && !args.channel) {\n return { ok: false, error: \"channel is required for add/remove/configure\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const config = await loadConfig();\n const action = args.action as string;\n\n if (action === \"list\") {\n const channels = config.channels || {};\n const entries = Object.entries(channels).map(([name, cfg]) => {\n const c = cfg as Record<string, unknown>;\n return `${name}: ${c.enabled ? \"enabled\" : \"disabled\"}`;\n });\n return entries.length > 0 ? entries.join(\"\\n\") : \"No channels configured\";\n }\n\n const channel = args.channel as string;\n\n if (action === \"add\" || action === \"configure\") {\n let settings: Record<string, unknown> = {};\n if (args.settings) {\n try {\n settings = JSON.parse(args.settings as string) as Record<string, unknown>;\n } catch {\n return \"Error: settings must be valid JSON\";\n }\n }\n\n if (!config.channels) config.channels = {};\n const existing = (config.channels as Record<string, unknown>)[channel] as Record<string, unknown> || {};\n (config.channels as Record<string, unknown>)[channel] = { ...existing, ...settings, enabled: true };\n\n await saveConfig(config);\n return `Channel ${channel} ${action === \"add\" ? \"added\" : \"updated\"} and enabled`;\n }\n\n if (action === \"remove\") {\n if (config.channels && (config.channels as Record<string, unknown>)[channel]) {\n ((config.channels as Record<string, unknown>)[channel] as Record<string, unknown>).enabled = false;\n await saveConfig(config);\n return `Channel ${channel} disabled`;\n }\n return `Channel ${channel} not found`;\n }\n\n return \"Unknown action\";\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `${args.action} channel: ${args.channel || \"all\"}`;\n },\n};\n","/**\n * Agent tool — add, configure, and manage agents through conversation.\n *\n * \"Create a new agent called Ratchet that uses Qwen 3.5 for coding\"\n * → agent uses this tool to add the definition and routing.\n */\n\nimport { loadConfig, saveConfig } from \"../../config/index.js\";\nimport type { Tool, ValidationResult } from \"../types.js\";\n\nexport const agentTool: Tool = {\n definition: {\n name: \"manage_agent\",\n description:\n \"Add, remove, list, or configure agents. Agents are named AI instances \" +\n \"with their own model, workspace, and tool access. \" +\n \"Use 'list' to see agents, 'add' to create one, 'remove' to delete, 'configure' to update.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"'list', 'add', 'remove', or 'configure'\" },\n id: { type: \"string\", description: \"Agent ID (lowercase, no spaces)\" },\n name: { type: \"string\", description: \"Display name for the agent\" },\n model: { type: \"string\", description: \"Model ID (e.g., 'ollama/qwen3.5')\" },\n workspace: { type: \"string\", description: \"Workspace directory path\" },\n toolTier: { type: \"string\", description: \"'full', 'core', or 'auto'\" },\n },\n required: [\"action\"],\n },\n },\n\n safetyLevel: (args) => args.action === \"list\" ? \"low\" : \"medium\",\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n const action = args.action as string;\n if (![\"list\", \"add\", \"remove\", \"configure\"].includes(action)) {\n return { ok: false, error: \"action must be 'list', 'add', 'remove', or 'configure'\" };\n }\n if (action !== \"list\" && !args.id) {\n return { ok: false, error: \"id is required\" };\n }\n if (action === \"add\" && !args.model) {\n return { ok: false, error: \"model is required when adding an agent\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const config = await loadConfig();\n const action = args.action as string;\n\n if (action === \"list\") {\n const agents = config.agents.list || [];\n if (agents.length === 0) return \"No agents configured (using default agent)\";\n return agents.map((a) =>\n `${a.id}: ${a.name || a.id} | model: ${a.model?.primary || \"default\"} | workspace: ${a.workspace || \"default\"}`\n ).join(\"\\n\");\n }\n\n const id = args.id as string;\n\n if (action === \"add\") {\n const existing = config.agents.list.find((a) => a.id === id);\n if (existing) return `Agent ${id} already exists. Use 'configure' to update.`;\n\n config.agents.list.push({\n id,\n name: (args.name as string) || id,\n model: { primary: args.model as string },\n workspace: args.workspace as string | undefined,\n toolTier: (args.toolTier as \"full\" | \"core\" | \"auto\") || undefined,\n });\n\n await saveConfig(config);\n return `Agent ${id} created with model ${args.model}`;\n }\n\n if (action === \"remove\") {\n const idx = config.agents.list.findIndex((a) => a.id === id);\n if (idx === -1) return `Agent ${id} not found`;\n config.agents.list.splice(idx, 1);\n await saveConfig(config);\n return `Agent ${id} removed`;\n }\n\n if (action === \"configure\") {\n const agent = config.agents.list.find((a) => a.id === id);\n if (!agent) return `Agent ${id} not found`;\n if (args.name) agent.name = args.name as string;\n if (args.model) agent.model = { primary: args.model as string };\n if (args.workspace) agent.workspace = args.workspace as string;\n if (args.toolTier) agent.toolTier = args.toolTier as \"full\" | \"core\" | \"auto\";\n await saveConfig(config);\n return `Agent ${id} updated`;\n }\n\n return \"Unknown action\";\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `${args.action} agent: ${args.id || \"all\"}`;\n },\n};\n","/**\n * Anthropic Claude provider.\n *\n * Uses the Messages API with SSE streaming. Cloud-only — used as a\n * fallback when local models can't handle a task, or when the user\n * explicitly configures a Claude model.\n */\n\nimport {\n BaseProvider,\n type Message,\n type StreamEvent,\n type ToolDefinition,\n type ContentBlock,\n} from \"./types.js\";\n\nconst CONTEXT_WINDOWS: Record<string, number> = {\n \"claude-opus-4-6\": 200000,\n \"claude-sonnet-4-6\": 200000,\n \"claude-haiku-4-5\": 200000,\n \"claude-sonnet-4-5\": 200000,\n};\n\nexport class AnthropicProvider extends BaseProvider {\n readonly name = \"anthropic\";\n private apiKey: string;\n private model: string;\n private baseUrl: string;\n\n constructor(opts: { apiKey: string; model: string; baseUrl?: string }) {\n super();\n this.apiKey = opts.apiKey;\n this.model = opts.model;\n this.baseUrl = opts.baseUrl || \"https://api.anthropic.com\";\n }\n\n contextWindow(): number {\n return CONTEXT_WINDOWS[this.model] ?? 200000;\n }\n\n formatTools(tools: ToolDefinition[]): unknown[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.parameters,\n }));\n }\n\n /**\n * Merge consecutive same-role messages.\n * Anthropic's API requires alternating user/assistant roles.\n */\n private prepareMessages(messages: Message[]): Array<Record<string, unknown>> {\n const result: Array<Record<string, unknown>> = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue; // System goes in separate param\n\n if (msg.role === \"tool\") {\n // Tool results become user messages with tool_result content blocks\n const block = {\n type: \"tool_result\",\n tool_use_id: msg.tool_call_id,\n content: typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content),\n };\n\n const last = result[result.length - 1];\n if (last && last.role === \"user\") {\n (last.content as unknown[]).push(block);\n } else {\n result.push({ role: \"user\", content: [block] });\n }\n continue;\n }\n\n if (msg.role === \"assistant\" && msg.tool_calls) {\n // Assistant with tool calls → tool_use content blocks\n const content: unknown[] = [];\n if (typeof msg.content === \"string\" && msg.content) {\n content.push({ type: \"text\", text: msg.content });\n }\n for (const tc of msg.tool_calls) {\n content.push({\n type: \"tool_use\",\n id: tc.id,\n name: tc.function.name,\n input: JSON.parse(tc.function.arguments),\n });\n }\n result.push({ role: \"assistant\", content });\n continue;\n }\n\n // Regular text message — merge with previous if same role\n const textContent = typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content);\n const last = result[result.length - 1];\n if (last && last.role === msg.role) {\n if (typeof last.content === \"string\") {\n last.content = last.content + \"\\n\" + textContent;\n } else {\n (last.content as unknown[]).push({ type: \"text\", text: textContent });\n }\n } else {\n result.push({ role: msg.role, content: textContent });\n }\n }\n\n return result;\n }\n\n async *stream(\n messages: Message[],\n systemPrompt: string,\n tools: ToolDefinition[],\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n const body: Record<string, unknown> = {\n model: this.model,\n messages: this.prepareMessages(messages),\n max_tokens: 8192,\n stream: true,\n };\n\n if (systemPrompt) {\n body.system = systemPrompt;\n }\n\n if (tools.length > 0) {\n body.tools = this.formatTools(tools);\n }\n\n const res = await fetch(`${this.baseUrl}/v1/messages`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": this.apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"Unknown error\");\n throw new Error(`Anthropic API error ${res.status}: ${text}`);\n }\n\n if (!res.body) throw new Error(\"No response body from Anthropic\");\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let currentToolId = \"\";\n let currentToolName = \"\";\n let currentToolArgs = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"data: \")) continue;\n\n const data = trimmed.slice(6);\n if (data === \"[DONE]\") continue;\n\n try {\n const event = JSON.parse(data) as Record<string, unknown>;\n const eventType = event.type as string;\n\n if (eventType === \"content_block_start\") {\n const block = event.content_block as Record<string, unknown>;\n if (block?.type === \"tool_use\") {\n currentToolId = block.id as string;\n currentToolName = block.name as string;\n currentToolArgs = \"\";\n }\n }\n\n if (eventType === \"content_block_delta\") {\n const delta = event.delta as Record<string, unknown>;\n if (delta?.type === \"text_delta\") {\n yield { type: \"text\", content: delta.text as string };\n }\n if (delta?.type === \"thinking_delta\") {\n yield { type: \"thinking\", content: delta.thinking as string };\n }\n if (delta?.type === \"input_json_delta\") {\n currentToolArgs += delta.partial_json as string;\n }\n }\n\n if (eventType === \"content_block_stop\") {\n if (currentToolId && currentToolName) {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(currentToolArgs) as Record<string, unknown>;\n } catch {\n parsedArgs = {};\n }\n yield {\n type: \"tool_call\",\n id: currentToolId,\n name: currentToolName,\n arguments: parsedArgs,\n };\n currentToolId = \"\";\n currentToolName = \"\";\n currentToolArgs = \"\";\n }\n }\n\n if (eventType === \"message_delta\") {\n const usage = (event as Record<string, unknown>).usage as Record<string, number> | undefined;\n if (usage) {\n yield {\n type: \"usage\",\n promptTokens: usage.input_tokens ?? 0,\n outputTokens: usage.output_tokens ?? 0,\n };\n }\n }\n\n if (eventType === \"message_stop\") {\n yield { type: \"done\" };\n return;\n }\n } catch {\n // Skip malformed events\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n yield { type: \"done\" };\n }\n\n formatAssistantToolUse(\n toolCallId: string,\n name: string,\n args: Record<string, unknown>,\n ): Message {\n return {\n role: \"assistant\",\n content: [\n { type: \"tool_use\", id: toolCallId, name, input: args } as ContentBlock,\n ],\n };\n }\n\n formatToolResult(\n toolCallId: string,\n _name: string,\n result: string,\n isError?: boolean,\n ): Message {\n return {\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n id: toolCallId,\n content: result,\n is_error: isError,\n } as ContentBlock,\n ],\n };\n }\n}\n","/**\n * OpenAI provider — also used for OpenAI-compatible local servers\n * like LM Studio, vLLM, and llama.cpp.\n *\n * The constructor takes a baseUrl so it can point to any\n * OpenAI-compatible endpoint. The `isLocal` flag adjusts behavior\n * (e.g., context window defaults, response token caps).\n */\n\nimport {\n BaseProvider,\n type Message,\n type StreamEvent,\n type ToolDefinition,\n} from \"./types.js\";\n\nconst CONTEXT_WINDOWS: Record<string, number> = {\n \"gpt-4o\": 128000,\n \"gpt-4o-mini\": 128000,\n \"gpt-4-turbo\": 128000,\n \"gpt-4\": 8192,\n \"gpt-3.5-turbo\": 16385,\n};\n\nexport class OpenAIProvider extends BaseProvider {\n readonly name = \"openai\";\n private baseUrl: string;\n private apiKey: string;\n private model: string;\n private isLocal: boolean;\n private maxResponseTokens?: number;\n\n constructor(opts: {\n baseUrl?: string;\n apiKey?: string;\n model: string;\n isLocal?: boolean;\n maxResponseTokens?: number;\n }) {\n super();\n this.baseUrl = (opts.baseUrl || \"https://api.openai.com\").replace(/\\/$/, \"\");\n this.apiKey = opts.apiKey || \"\";\n this.model = opts.model;\n this.isLocal = opts.isLocal ?? false;\n this.maxResponseTokens = opts.maxResponseTokens;\n }\n\n /**\n * Detect an OpenAI-compatible server by probing /v1/models.\n */\n static async detect(baseUrl: string): Promise<string[] | null> {\n try {\n const res = await fetch(`${baseUrl}/v1/models`, { signal: AbortSignal.timeout(3000) });\n if (!res.ok) return null;\n const data = (await res.json()) as { data?: Array<{ id: string }> };\n return data.data?.map((m) => m.id) ?? [];\n } catch {\n return null;\n }\n }\n\n contextWindow(): number {\n if (this.isLocal) return 32768;\n return CONTEXT_WINDOWS[this.model] ?? 128000;\n }\n\n formatTools(tools: ToolDefinition[]): unknown[] {\n return tools.map((t) => ({\n type: \"function\",\n function: {\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n },\n }));\n }\n\n private prepareMessages(\n messages: Message[],\n systemPrompt: string,\n ): Array<Record<string, unknown>> {\n const result: Array<Record<string, unknown>> = [];\n\n if (systemPrompt) {\n result.push({ role: \"system\", content: systemPrompt });\n }\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue;\n\n if (msg.role === \"tool\") {\n result.push({\n role: \"tool\",\n tool_call_id: msg.tool_call_id,\n content: typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content),\n });\n } else if (msg.role === \"assistant\" && msg.tool_calls) {\n result.push({\n role: \"assistant\",\n content: typeof msg.content === \"string\" && msg.content ? msg.content : null,\n tool_calls: msg.tool_calls,\n });\n } else {\n result.push({\n role: msg.role,\n content: typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content),\n });\n }\n }\n\n return result;\n }\n\n async *stream(\n messages: Message[],\n systemPrompt: string,\n tools: ToolDefinition[],\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n const body: Record<string, unknown> = {\n model: this.model,\n messages: this.prepareMessages(messages, systemPrompt),\n stream: true,\n stream_options: { include_usage: true },\n };\n\n if (tools.length > 0) {\n body.tools = this.formatTools(tools);\n }\n\n if (this.maxResponseTokens) {\n body.max_tokens = this.maxResponseTokens;\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.apiKey) {\n headers[\"Authorization\"] = `Bearer ${this.apiKey}`;\n }\n\n const res = await fetch(`${this.baseUrl}/v1/chat/completions`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"Unknown error\");\n throw new Error(`OpenAI API error ${res.status}: ${text}`);\n }\n\n if (!res.body) throw new Error(\"No response body from OpenAI\");\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n const toolCalls = new Map<number, { id: string; name: string; arguments: string }>();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"data: \")) continue;\n\n const data = trimmed.slice(6);\n if (data === \"[DONE]\") {\n for (const tc of toolCalls.values()) {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(tc.arguments) as Record<string, unknown>;\n } catch {\n parsedArgs = {};\n }\n yield { type: \"tool_call\", id: tc.id, name: tc.name, arguments: parsedArgs };\n }\n yield { type: \"done\" };\n return;\n }\n\n try {\n const chunk = JSON.parse(data) as {\n choices?: Array<{\n delta?: {\n content?: string | null;\n reasoning_content?: string | null;\n tool_calls?: Array<{\n index: number;\n id?: string;\n function?: { name?: string; arguments?: string };\n }>;\n };\n }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number };\n };\n\n const choice = chunk.choices?.[0];\n if (choice?.delta?.reasoning_content) {\n yield { type: \"thinking\", content: choice.delta.reasoning_content };\n }\n if (choice?.delta?.content) {\n yield { type: \"text\", content: choice.delta.content };\n }\n\n if (choice?.delta?.tool_calls) {\n for (const tc of choice.delta.tool_calls) {\n const existing = toolCalls.get(tc.index);\n if (existing) {\n if (tc.function?.arguments) existing.arguments += tc.function.arguments;\n } else {\n toolCalls.set(tc.index, {\n id: tc.id || `call_${tc.index}`,\n name: tc.function?.name || \"\",\n arguments: tc.function?.arguments || \"\",\n });\n }\n }\n }\n\n if (chunk.usage) {\n yield {\n type: \"usage\",\n promptTokens: chunk.usage.prompt_tokens ?? 0,\n outputTokens: chunk.usage.completion_tokens ?? 0,\n };\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n for (const tc of toolCalls.values()) {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(tc.arguments) as Record<string, unknown>;\n } catch {\n parsedArgs = {};\n }\n yield { type: \"tool_call\", id: tc.id, name: tc.name, arguments: parsedArgs };\n }\n yield { type: \"done\" };\n }\n\n formatAssistantToolUse(\n toolCallId: string,\n name: string,\n args: Record<string, unknown>,\n ): Message {\n return {\n role: \"assistant\",\n content: \"\",\n tool_calls: [\n {\n id: toolCallId,\n type: \"function\",\n function: { name, arguments: JSON.stringify(args) },\n },\n ],\n };\n }\n\n formatToolResult(\n toolCallId: string,\n _name: string,\n result: string,\n _isError?: boolean,\n ): Message {\n return {\n role: \"tool\",\n content: result,\n tool_call_id: toolCallId,\n };\n }\n}\n","/**\n * Google Gemini provider.\n *\n * Uses the Generative AI REST API with streaming.\n * Supports Gemini 2.0 Flash (1M context) and Gemini 1.5 Pro (2M context).\n */\n\nimport {\n BaseProvider,\n type Message,\n type StreamEvent,\n type ToolDefinition,\n} from \"./types.js\";\n\nconst CONTEXT_WINDOWS: Record<string, number> = {\n \"gemini-2.0-flash\": 1048576,\n \"gemini-1.5-flash\": 1048576,\n \"gemini-1.5-pro\": 2097152,\n};\n\n/** Map JSON Schema types to Gemini's uppercase types */\nfunction mapType(type: string): string {\n const MAP: Record<string, string> = {\n string: \"STRING\", number: \"NUMBER\", integer: \"INTEGER\",\n boolean: \"BOOLEAN\", array: \"ARRAY\", object: \"OBJECT\",\n };\n return MAP[type] || \"STRING\";\n}\n\nexport class GoogleProvider extends BaseProvider {\n readonly name = \"google\";\n private apiKey: string;\n private model: string;\n\n constructor(opts: { apiKey: string; model: string }) {\n super();\n this.apiKey = opts.apiKey;\n this.model = opts.model;\n }\n\n contextWindow(): number {\n return CONTEXT_WINDOWS[this.model] ?? 1048576;\n }\n\n formatTools(tools: ToolDefinition[]): unknown[] {\n return [{\n functionDeclarations: tools.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: convertSchema(t.parameters),\n })),\n }];\n }\n\n /**\n * Prepare messages for Gemini API.\n * Gemini uses \"user\" and \"model\" roles, and requires alternation.\n */\n private prepareContents(messages: Message[]): Array<Record<string, unknown>> {\n const contents: Array<Record<string, unknown>> = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue;\n\n const role = msg.role === \"assistant\" ? \"model\" : \"user\";\n const text = typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content);\n\n if (msg.role === \"tool\") {\n // Tool results as function responses\n contents.push({\n role: \"function\",\n parts: [{\n functionResponse: {\n name: msg.tool_call_id || \"unknown\",\n response: { content: text },\n },\n }],\n });\n continue;\n }\n\n if (msg.role === \"assistant\" && msg.tool_calls) {\n // Assistant with tool calls\n const parts: unknown[] = [];\n if (text) parts.push({ text });\n for (const tc of msg.tool_calls) {\n parts.push({\n functionCall: {\n name: tc.function.name,\n args: JSON.parse(tc.function.arguments),\n },\n });\n }\n contents.push({ role: \"model\", parts });\n continue;\n }\n\n // Merge consecutive same-role messages\n const last = contents[contents.length - 1];\n if (last && last.role === role) {\n (last.parts as unknown[]).push({ text });\n } else {\n contents.push({ role, parts: [{ text }] });\n }\n }\n\n return contents;\n }\n\n async *stream(\n messages: Message[],\n systemPrompt: string,\n tools: ToolDefinition[],\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n const contents = this.prepareContents(messages);\n\n const body: Record<string, unknown> = { contents };\n\n if (systemPrompt) {\n body.systemInstruction = { parts: [{ text: systemPrompt }] };\n }\n\n if (tools.length > 0) {\n body.tools = this.formatTools(tools);\n }\n\n const url = `https://generativelanguage.googleapis.com/v1beta/models/${this.model}:streamGenerateContent?key=${this.apiKey}&alt=sse`;\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"Unknown error\");\n throw new Error(`Google API error ${res.status}: ${text}`);\n }\n\n if (!res.body) throw new Error(\"No response body from Google\");\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"data: \")) continue;\n\n try {\n const data = JSON.parse(trimmed.slice(6)) as {\n candidates?: Array<{\n content?: {\n parts?: Array<{\n text?: string;\n functionCall?: { name: string; args: Record<string, unknown> };\n }>;\n };\n }>;\n usageMetadata?: { promptTokenCount?: number; candidatesTokenCount?: number };\n };\n\n const parts = data.candidates?.[0]?.content?.parts || [];\n for (const part of parts) {\n if (part.text) {\n yield { type: \"text\", content: part.text };\n }\n if (part.functionCall) {\n yield {\n type: \"tool_call\",\n id: `google_${Date.now()}`,\n name: part.functionCall.name,\n arguments: part.functionCall.args,\n };\n }\n }\n\n if (data.usageMetadata) {\n yield {\n type: \"usage\",\n promptTokens: data.usageMetadata.promptTokenCount ?? 0,\n outputTokens: data.usageMetadata.candidatesTokenCount ?? 0,\n };\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n yield { type: \"done\" };\n }\n\n formatAssistantToolUse(\n toolCallId: string,\n name: string,\n args: Record<string, unknown>,\n ): Message {\n return {\n role: \"assistant\",\n content: \"\",\n tool_calls: [{\n id: toolCallId,\n type: \"function\",\n function: { name, arguments: JSON.stringify(args) },\n }],\n };\n }\n\n formatToolResult(\n toolCallId: string,\n name: string,\n result: string,\n _isError?: boolean,\n ): Message {\n return {\n role: \"tool\",\n content: result,\n tool_call_id: name, // Gemini uses function name as ID\n };\n }\n}\n\n/** Convert JSON Schema to Gemini's format */\nfunction convertSchema(schema: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n if (schema.type) result.type = mapType(schema.type as string);\n if (schema.description) result.description = schema.description;\n if (schema.required) result.required = schema.required;\n\n if (schema.properties) {\n result.properties = {};\n for (const [key, value] of Object.entries(schema.properties as Record<string, Record<string, unknown>>)) {\n (result.properties as Record<string, unknown>)[key] = convertSchema(value);\n }\n }\n\n if (schema.items) {\n result.items = convertSchema(schema.items as Record<string, unknown>);\n }\n\n return result;\n}\n","/**\n * Provider router — resolves model identifiers to provider instances.\n *\n * Model identifiers use the format \"provider/model\", e.g.:\n * - \"ollama/qwen3.5\"\n * - \"anthropic/claude-sonnet-4-6\"\n * - \"openai/gpt-4o\"\n *\n * The router also handles the fallback chain: if the primary model fails,\n * it tries fallbacks in order. This is how local-first works in practice —\n * try Ollama first, fall back to cloud if needed.\n */\n\nimport { type BaseProvider, type ResolvedProvider } from \"./types.js\";\nimport { OllamaProvider } from \"./ollama.js\";\nimport { AnthropicProvider } from \"./anthropic.js\";\nimport { OpenAIProvider } from \"./openai.js\";\nimport { GoogleProvider } from \"./google.js\";\n\nexport interface ProviderConfig {\n ollama?: {\n baseUrl?: string;\n };\n anthropic?: {\n apiKey: string;\n baseUrl?: string;\n };\n openai?: {\n apiKey: string;\n baseUrl?: string;\n };\n google?: {\n apiKey: string;\n baseUrl?: string;\n };\n /** Local OpenAI-compatible servers (llamacpp, lmstudio, vllm, etc.) */\n [key: string]: { baseUrl?: string; apiKey?: string } | undefined;\n}\n\n/**\n * Parse a model identifier like \"ollama/qwen3.5\" into provider + model.\n */\nexport function parseModelId(modelId: string): { provider: string; model: string } {\n const slash = modelId.indexOf(\"/\");\n if (slash === -1) {\n // No provider prefix — assume ollama for local-first\n return { provider: \"ollama\", model: modelId };\n }\n return {\n provider: modelId.slice(0, slash),\n model: modelId.slice(slash + 1),\n };\n}\n\n/**\n * Create a provider instance for a model identifier.\n */\nexport function createProvider(\n modelId: string,\n config: ProviderConfig,\n opts?: { maxResponseTokens?: number },\n): ResolvedProvider {\n const { provider, model } = parseModelId(modelId);\n\n switch (provider) {\n case \"ollama\": {\n const p = new OllamaProvider({\n baseUrl: config.ollama?.baseUrl,\n model,\n maxResponseTokens: opts?.maxResponseTokens,\n });\n return { provider: p, providerName: \"ollama\", modelId, isLocal: true };\n }\n\n case \"anthropic\": {\n if (!config.anthropic?.apiKey) {\n throw new Error(`Anthropic API key required for model ${modelId}`);\n }\n const p = new AnthropicProvider({\n apiKey: config.anthropic.apiKey,\n model,\n baseUrl: config.anthropic.baseUrl,\n });\n return { provider: p, providerName: \"anthropic\", modelId, isLocal: false };\n }\n\n case \"openai\": {\n if (!config.openai?.apiKey) {\n throw new Error(`OpenAI API key required for model ${modelId}`);\n }\n const p = new OpenAIProvider({\n apiKey: config.openai.apiKey,\n model,\n baseUrl: config.openai.baseUrl,\n maxResponseTokens: opts?.maxResponseTokens,\n });\n return { provider: p, providerName: \"openai\", modelId, isLocal: false };\n }\n\n case \"google\": {\n if (!config.google?.apiKey) {\n throw new Error(`Google API key required for model ${modelId}`);\n }\n const p = new GoogleProvider({ apiKey: config.google.apiKey, model });\n return { provider: p, providerName: \"google\", modelId, isLocal: false };\n }\n\n case \"lmstudio\":\n case \"llamacpp\":\n case \"vllm\":\n case \"local\": {\n // These are all OpenAI-compatible local servers\n const defaultUrls: Record<string, string> = {\n lmstudio: \"http://127.0.0.1:1234\",\n llamacpp: \"http://127.0.0.1:8080\",\n vllm: \"http://127.0.0.1:8000\",\n local: \"http://127.0.0.1:8080\",\n };\n // Read base URL from config (e.g., config.llamacpp.baseUrl)\n const providerCfg = config[provider];\n const baseUrl = providerCfg?.baseUrl || defaultUrls[provider] || defaultUrls.local;\n const p = new OpenAIProvider({\n baseUrl,\n model,\n isLocal: true,\n maxResponseTokens: opts?.maxResponseTokens,\n });\n return { provider: p, providerName: provider, modelId, isLocal: true };\n }\n\n default:\n throw new Error(`Unknown provider: ${provider}`);\n }\n}\n\n/**\n * Resolve a model with fallback chain.\n *\n * Tries the primary model first, then fallbacks in order.\n * Returns the first provider that can be created successfully.\n * For Ollama, also checks if the server is reachable.\n */\nexport async function resolveWithFallback(\n primary: string,\n fallbacks: string[],\n config: ProviderConfig,\n opts?: { maxResponseTokens?: number },\n): Promise<ResolvedProvider> {\n const chain = [primary, ...fallbacks];\n\n for (const modelId of chain) {\n try {\n const resolved = createProvider(modelId, config, opts);\n\n // For local providers, verify the server is reachable\n if (resolved.isLocal && resolved.providerName === \"ollama\") {\n const models = await OllamaProvider.detect(config.ollama?.baseUrl);\n if (!models) {\n continue; // Ollama not running, try next\n }\n }\n\n return resolved;\n } catch {\n // This provider can't be created (e.g., missing API key), try next\n continue;\n }\n }\n\n throw new Error(\n `No available provider. Tried: ${chain.join(\", \")}. ` +\n `Check that your model server is running or API keys are configured.`,\n );\n}\n\n/**\n * Auto-detect available local model servers.\n * Returns a list of detected servers with their models.\n */\nexport async function detectLocalServers(): Promise<\n Array<{ provider: string; baseUrl: string; models: string[] }>\n> {\n const servers: Array<{ provider: string; baseUrl: string; models: string[] }> = [];\n\n // Check Ollama\n const ollamaModels = await OllamaProvider.detect();\n if (ollamaModels) {\n servers.push({\n provider: \"ollama\",\n baseUrl: \"http://127.0.0.1:11434\",\n models: ollamaModels,\n });\n }\n\n // Check LM Studio\n const lmStudioModels = await OpenAIProvider.detect(\"http://127.0.0.1:1234\");\n if (lmStudioModels) {\n servers.push({\n provider: \"lmstudio\",\n baseUrl: \"http://127.0.0.1:1234\",\n models: lmStudioModels,\n });\n }\n\n // Check llama.cpp (common ports)\n for (const port of [8080, 14438]) {\n const llamaCppModels = await OpenAIProvider.detect(`http://127.0.0.1:${port}`);\n if (llamaCppModels) {\n servers.push({\n provider: \"llamacpp\",\n baseUrl: `http://127.0.0.1:${port}`,\n models: llamaCppModels,\n });\n break; // Found one, stop checking\n }\n }\n\n // Check vLLM\n const vllmModels = await OpenAIProvider.detect(\"http://127.0.0.1:8000\");\n if (vllmModels) {\n servers.push({\n provider: \"vllm\",\n baseUrl: \"http://127.0.0.1:8000\",\n models: vllmModels,\n });\n }\n\n return servers;\n}\n","export { BaseProvider } from \"./types.js\";\nexport type {\n StreamEvent,\n ToolDefinition,\n Message,\n ContentBlock,\n ToolCallMessage,\n ModelCompatConfig,\n ResolvedProvider,\n ModelConfig,\n} from \"./types.js\";\n\nexport { OllamaProvider } from \"./ollama.js\";\nexport { AnthropicProvider } from \"./anthropic.js\";\nexport { OpenAIProvider } from \"./openai.js\";\nexport { GoogleProvider } from \"./google.js\";\nexport { PromptFallbackProvider } from \"./prompt-fallback.js\";\n\nexport {\n parseModelId,\n createProvider,\n resolveWithFallback,\n detectLocalServers,\n type ProviderConfig,\n} from \"./router.js\";\n","/**\n * Model tool — manage models and providers through conversation.\n */\n\nimport { loadConfig, saveConfig } from \"../../config/index.js\";\nimport { detectLocalServers } from \"../../providers/index.js\";\nimport type { Tool, ValidationResult } from \"../types.js\";\n\nexport const modelTool: Tool = {\n definition: {\n name: \"manage_model\",\n description:\n \"List available models, detect local servers, add providers, or switch the default model. \" +\n \"Use 'detect' to scan for local model servers, 'list' to see configured models, \" +\n \"'set-default' to change the primary model, 'add-provider' to add a cloud provider.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"'list', 'detect', 'set-default', or 'add-provider'\" },\n model: { type: \"string\", description: \"Model ID for set-default (e.g., 'ollama/qwen3.5')\" },\n provider: { type: \"string\", description: \"Provider name for add-provider ('anthropic', 'openai', 'google')\" },\n apiKey: { type: \"string\", description: \"API key for add-provider\" },\n },\n required: [\"action\"],\n },\n },\n\n safetyLevel: (args) => (args.action === \"list\" || args.action === \"detect\") ? \"low\" : \"medium\",\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n const action = args.action as string;\n if (![\"list\", \"detect\", \"set-default\", \"add-provider\"].includes(action)) {\n return { ok: false, error: \"Invalid action\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const config = await loadConfig();\n const action = args.action as string;\n\n if (action === \"detect\") {\n const servers = await detectLocalServers();\n if (servers.length === 0) return \"No local model servers detected.\";\n return servers.map((s) =>\n `${s.provider} at ${s.baseUrl}\\n Models: ${s.models.slice(0, 10).join(\", \")}`\n ).join(\"\\n\\n\");\n }\n\n if (action === \"list\") {\n const lines: string[] = [];\n lines.push(`Default: ${config.agents.defaults.model.primary}`);\n if (config.agents.defaults.model.fallbacks?.length) {\n lines.push(`Fallbacks: ${config.agents.defaults.model.fallbacks.join(\", \")}`);\n }\n lines.push(\"\\nProviders:\");\n for (const [name, cfg] of Object.entries(config.models.providers)) {\n const c = cfg as Record<string, unknown>;\n lines.push(` ${name}: ${c.baseUrl || c.apiKey ? \"configured\" : \"not configured\"}`);\n }\n return lines.join(\"\\n\");\n }\n\n if (action === \"set-default\") {\n if (!args.model) return \"Error: model is required\";\n config.agents.defaults.model.primary = args.model as string;\n await saveConfig(config);\n return `Default model set to ${args.model}`;\n }\n\n if (action === \"add-provider\") {\n if (!args.provider || !args.apiKey) return \"Error: provider and apiKey are required\";\n const provider = args.provider as string;\n (config.models.providers as Record<string, unknown>)[provider] = { apiKey: args.apiKey as string };\n await saveConfig(config);\n return `Provider ${provider} added with API key`;\n }\n\n return \"Unknown action\";\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `${args.action} model configuration`;\n },\n};\n","/**\n * Session store — manages conversation sessions.\n *\n * Sessions are persisted as JSON files on disk. Each session has a\n * normalized key that identifies it across channels:\n * - cli:main (CLI default session)\n * - web:main (Web UI default session)\n * - dm:telegram:123 (Telegram DM with user 123)\n * - group:discord:456 (Discord server 456)\n *\n * This cross-channel key system is what enables session continuity —\n * start in CLI, continue in the browser, check from Telegram.\n */\n\nimport { readFile, writeFile, readdir, unlink, mkdir } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport type { Message } from \"../providers/types.js\";\n\nexport interface SessionEntry {\n id: string;\n normalizedKey: string;\n label?: string;\n agentId?: string;\n model?: string;\n lastChannel?: string;\n updatedAt: number;\n createdAt: number;\n}\n\nexport interface SessionData {\n entry: SessionEntry;\n messages: Message[];\n}\n\nexport class SessionStore {\n private storeDir: string;\n private indexPath: string;\n private index: Map<string, SessionEntry> = new Map();\n\n constructor(storeDir: string) {\n this.storeDir = storeDir;\n this.indexPath = join(storeDir, \"sessions.json\");\n }\n\n /** Initialize the store — load index from disk */\n async init(): Promise<void> {\n await mkdir(this.storeDir, { recursive: true });\n\n if (existsSync(this.indexPath)) {\n try {\n const raw = await readFile(this.indexPath, \"utf-8\");\n const entries = JSON.parse(raw) as SessionEntry[];\n for (const entry of entries) {\n this.index.set(entry.normalizedKey, entry);\n }\n } catch {\n // Corrupt index — start fresh\n this.index.clear();\n }\n }\n }\n\n /** Save the index to disk */\n private async saveIndex(): Promise<void> {\n const entries = Array.from(this.index.values());\n await writeFile(this.indexPath, JSON.stringify(entries, null, 2), \"utf-8\");\n }\n\n /** Get or create a session for a normalized key */\n async resolve(normalizedKey: string, opts?: { agentId?: string; channel?: string }): Promise<SessionEntry> {\n let entry = this.index.get(normalizedKey);\n if (entry) {\n // Update last access\n entry.updatedAt = Date.now();\n if (opts?.channel) entry.lastChannel = opts.channel;\n if (opts?.agentId) entry.agentId = opts.agentId;\n await this.saveIndex();\n return entry;\n }\n\n // Create new session\n entry = {\n id: randomUUID(),\n normalizedKey,\n agentId: opts?.agentId,\n lastChannel: opts?.channel,\n updatedAt: Date.now(),\n createdAt: Date.now(),\n };\n this.index.set(normalizedKey, entry);\n await this.saveIndex();\n return entry;\n }\n\n /** Load conversation messages for a session */\n async loadMessages(sessionId: string): Promise<Message[]> {\n const path = join(this.storeDir, `${sessionId}.json`);\n if (!existsSync(path)) return [];\n\n try {\n const raw = await readFile(path, \"utf-8\");\n return JSON.parse(raw) as Message[];\n } catch {\n return [];\n }\n }\n\n /** Save conversation messages for a session */\n async saveMessages(sessionId: string, messages: Message[]): Promise<void> {\n const path = join(this.storeDir, `${sessionId}.json`);\n await writeFile(path, JSON.stringify(messages, null, 2), \"utf-8\");\n }\n\n /** List all sessions, sorted by last used */\n list(): SessionEntry[] {\n return Array.from(this.index.values()).sort((a, b) => b.updatedAt - a.updatedAt);\n }\n\n /** Delete a session */\n async delete(normalizedKey: string): Promise<boolean> {\n const entry = this.index.get(normalizedKey);\n if (!entry) return false;\n\n this.index.delete(normalizedKey);\n await this.saveIndex();\n\n // Delete conversation file\n const path = join(this.storeDir, `${entry.id}.json`);\n try {\n await unlink(path);\n } catch {\n // File may not exist\n }\n\n return true;\n }\n\n /** Reset a session (clear messages but keep the entry) */\n async reset(normalizedKey: string): Promise<SessionEntry | null> {\n const entry = this.index.get(normalizedKey);\n if (!entry) return null;\n\n // Clear messages\n const path = join(this.storeDir, `${entry.id}.json`);\n try {\n await unlink(path);\n } catch {\n // OK if file doesn't exist\n }\n\n entry.updatedAt = Date.now();\n await this.saveIndex();\n return entry;\n }\n\n /** Prune old sessions to stay under the max count */\n async prune(maxSessions: number): Promise<number> {\n const entries = this.list();\n let pruned = 0;\n\n while (entries.length - pruned > maxSessions) {\n const oldest = entries[entries.length - 1 - pruned];\n if (oldest) {\n await this.delete(oldest.normalizedKey);\n pruned++;\n } else {\n break;\n }\n }\n\n return pruned;\n }\n\n /** Update a session's label (auto-title from first message) */\n async setLabel(normalizedKey: string, label: string): Promise<void> {\n const entry = this.index.get(normalizedKey);\n if (entry) {\n entry.label = label;\n await this.saveIndex();\n }\n }\n}\n","export { SessionStore, type SessionEntry, type SessionData } from \"./store.js\";\n","/**\n * Session tool — list, manage, and spawn sessions through conversation.\n */\n\nimport { join } from \"node:path\";\nimport { getConfigDir } from \"../../config/index.js\";\nimport { SessionStore } from \"../../sessions/index.js\";\nimport type { Tool, ValidationResult } from \"../types.js\";\n\nexport const sessionTool: Tool = {\n definition: {\n name: \"manage_session\",\n description:\n \"List, inspect, reset, or delete chat sessions. \" +\n \"Use 'list' to see all sessions, 'reset' to clear a session's history, \" +\n \"'delete' to remove a session entirely.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"'list', 'reset', or 'delete'\" },\n sessionKey: { type: \"string\", description: \"Session key (for reset/delete)\" },\n },\n required: [\"action\"],\n },\n },\n\n safetyLevel: (args) => args.action === \"list\" ? \"low\" : \"medium\",\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n const action = args.action as string;\n if (![\"list\", \"reset\", \"delete\"].includes(action)) {\n return { ok: false, error: \"action must be 'list', 'reset', or 'delete'\" };\n }\n if (action !== \"list\" && !args.sessionKey) {\n return { ok: false, error: \"sessionKey is required\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const store = new SessionStore(join(getConfigDir(), \"conversations\"));\n await store.init();\n\n const action = args.action as string;\n\n if (action === \"list\") {\n const sessions = store.list();\n if (sessions.length === 0) return \"No sessions\";\n return sessions.map((s) =>\n `${s.normalizedKey} | ${s.label || \"(untitled)\"} | agent: ${s.agentId || \"default\"} | ${new Date(s.updatedAt).toLocaleString()}`\n ).join(\"\\n\");\n }\n\n const key = args.sessionKey as string;\n\n if (action === \"reset\") {\n const result = await store.reset(key);\n return result ? `Session ${key} reset` : `Session ${key} not found`;\n }\n\n if (action === \"delete\") {\n const result = await store.delete(key);\n return result ? `Session ${key} deleted` : `Session ${key} not found`;\n }\n\n return \"Unknown action\";\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `${args.action} session: ${args.sessionKey || \"all\"}`;\n },\n};\n","/**\n * Cron scheduler — runs agent tasks on a schedule.\n *\n * Jobs are stored in JSONL format. The gateway ticks every 30 seconds\n * and checks for due jobs. Each job spawns an agent session, runs the\n * prompt, and logs the result.\n *\n * Uses standard cron expressions (e.g., \"0 9 * * *\" for 9am daily).\n */\n\nimport { readFile, appendFile, mkdir, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\n\nexport interface CronJob {\n id: string;\n name: string;\n /** Standard cron expression */\n schedule: string;\n /** Agent ID to run the job */\n agentId: string;\n /** Prompt to send to the agent */\n prompt: string;\n /** Whether the job is active */\n enabled: boolean;\n /** When the job was created */\n createdAt: number;\n /** Last successful run timestamp */\n lastRunAt?: number;\n /** Last run status */\n lastStatus?: \"success\" | \"error\";\n /** Failure count for retry backoff */\n failCount: number;\n}\n\nexport interface CronRunLog {\n jobId: string;\n startedAt: number;\n completedAt: number;\n status: \"success\" | \"error\";\n output?: string;\n error?: string;\n}\n\nexport class CronScheduler {\n private jobsPath: string;\n private runsDir: string;\n private jobs: CronJob[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private running = false;\n private onJobDue?: (job: CronJob) => Promise<void>;\n\n constructor(storeDir: string) {\n this.jobsPath = join(storeDir, \"jobs.jsonl\");\n this.runsDir = join(storeDir, \"runs\");\n }\n\n /** Initialize — load jobs from disk */\n async init(): Promise<void> {\n await mkdir(this.runsDir, { recursive: true });\n await this.loadJobs();\n }\n\n /** Set callback for when a job is due */\n setHandler(handler: (job: CronJob) => Promise<void>): void {\n this.onJobDue = handler;\n }\n\n /** Start the scheduler (ticks every 30s) */\n start(): void {\n if (this.running) return;\n this.running = true;\n this.timer = setInterval(() => this.tick(), 30_000);\n // Run immediately on start\n this.tick();\n }\n\n /** Stop the scheduler */\n stop(): void {\n this.running = false;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n\n /** Check for due jobs */\n private async tick(): Promise<void> {\n const now = Date.now();\n\n for (const job of this.jobs) {\n if (!job.enabled) continue;\n\n if (this.isDue(job, now)) {\n try {\n if (this.onJobDue) {\n await this.onJobDue(job);\n }\n job.lastRunAt = now;\n job.lastStatus = \"success\";\n job.failCount = 0;\n await this.logRun({ jobId: job.id, startedAt: now, completedAt: Date.now(), status: \"success\" });\n } catch (err) {\n job.failCount++;\n job.lastStatus = \"error\";\n await this.logRun({\n jobId: job.id,\n startedAt: now,\n completedAt: Date.now(),\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n\n await this.saveJobs();\n }\n\n /** Check if a job is due to run */\n private isDue(job: CronJob, now: number): boolean {\n // Simple cron matching — check if enough time has passed\n // A full cron parser would use a library like cron-parser\n const interval = this.parseSimpleInterval(job.schedule);\n if (!interval) return false;\n\n if (!job.lastRunAt) return true;\n return now - job.lastRunAt >= interval;\n }\n\n /**\n * Parse simple schedule strings.\n * For v1, supports: \"30s\", \"5m\", \"1h\", \"24h\", \"daily\"\n * Full cron expressions will use cron-parser library later.\n */\n private parseSimpleInterval(schedule: string): number | null {\n const match = schedule.match(/^(\\d+)(s|m|h)$/);\n if (match) {\n const value = parseInt(match[1], 10);\n const unit = match[2];\n switch (unit) {\n case \"s\": return value * 1000;\n case \"m\": return value * 60_000;\n case \"h\": return value * 3600_000;\n }\n }\n if (schedule === \"daily\") return 86400_000;\n return null;\n }\n\n /** Add a new job */\n async addJob(opts: { name: string; schedule: string; agentId: string; prompt: string }): Promise<CronJob> {\n const job: CronJob = {\n id: randomUUID(),\n name: opts.name,\n schedule: opts.schedule,\n agentId: opts.agentId,\n prompt: opts.prompt,\n enabled: true,\n createdAt: Date.now(),\n failCount: 0,\n };\n this.jobs.push(job);\n await this.saveJobs();\n return job;\n }\n\n /** Remove a job */\n async removeJob(jobId: string): Promise<boolean> {\n const idx = this.jobs.findIndex((j) => j.id === jobId);\n if (idx === -1) return false;\n this.jobs.splice(idx, 1);\n await this.saveJobs();\n return true;\n }\n\n /** List all jobs */\n listJobs(): CronJob[] {\n return [...this.jobs];\n }\n\n /** Enable/disable a job */\n async toggleJob(jobId: string, enabled: boolean): Promise<void> {\n const job = this.jobs.find((j) => j.id === jobId);\n if (job) {\n job.enabled = enabled;\n await this.saveJobs();\n }\n }\n\n /** Load jobs from JSONL file */\n private async loadJobs(): Promise<void> {\n if (!existsSync(this.jobsPath)) return;\n\n try {\n const raw = await readFile(this.jobsPath, \"utf-8\");\n this.jobs = raw\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => JSON.parse(line) as CronJob);\n } catch {\n this.jobs = [];\n }\n }\n\n /** Save jobs to JSONL file */\n private async saveJobs(): Promise<void> {\n const content = this.jobs.map((j) => JSON.stringify(j)).join(\"\\n\") + \"\\n\";\n await writeFile(this.jobsPath, content, \"utf-8\");\n }\n\n /** Log a run result */\n private async logRun(log: CronRunLog): Promise<void> {\n const logPath = join(this.runsDir, `${log.jobId}.jsonl`);\n await appendFile(logPath, JSON.stringify(log) + \"\\n\", \"utf-8\");\n }\n}\n","export { CronScheduler, type CronJob, type CronRunLog } from \"./scheduler.js\";\n","/**\n * Cron tool — manage scheduled tasks through conversation.\n *\n * \"Check my email every hour\" → agent creates a cron job.\n */\n\nimport { join } from \"node:path\";\nimport { getConfigDir } from \"../../config/index.js\";\nimport { CronScheduler } from \"../../cron/index.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"../types.js\";\n\nexport const cronTool: Tool = {\n definition: {\n name: \"manage_cron\",\n description:\n \"Create, list, enable, disable, or remove scheduled tasks. \" +\n \"Schedules use simple formats: '30s', '5m', '1h', '24h', 'daily'.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"'list', 'add', 'remove', 'enable', or 'disable'\" },\n name: { type: \"string\", description: \"Job name (for add)\" },\n schedule: { type: \"string\", description: \"Schedule expression (for add)\" },\n prompt: { type: \"string\", description: \"What the agent should do (for add)\" },\n agentId: { type: \"string\", description: \"Agent to run the job (default: current)\" },\n jobId: { type: \"string\", description: \"Job ID (for remove/enable/disable)\" },\n },\n required: [\"action\"],\n },\n },\n\n safetyLevel: (args) => args.action === \"list\" ? \"low\" : \"medium\",\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n const action = args.action as string;\n if (![\"list\", \"add\", \"remove\", \"enable\", \"disable\"].includes(action)) {\n return { ok: false, error: \"Invalid action\" };\n }\n if (action === \"add\" && (!args.name || !args.schedule || !args.prompt)) {\n return { ok: false, error: \"name, schedule, and prompt are required for add\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const scheduler = new CronScheduler(join(getConfigDir(), \"cron\"));\n await scheduler.init();\n\n const action = args.action as string;\n\n if (action === \"list\") {\n const jobs = scheduler.listJobs();\n if (jobs.length === 0) return \"No scheduled jobs\";\n return jobs.map((j) =>\n `${j.id.slice(0, 8)} | ${j.name} | ${j.schedule} | ${j.enabled ? \"enabled\" : \"disabled\"} | agent: ${j.agentId}`\n ).join(\"\\n\");\n }\n\n if (action === \"add\") {\n const job = await scheduler.addJob({\n name: args.name as string,\n schedule: args.schedule as string,\n agentId: (args.agentId as string) || ctx.agentId || \"default\",\n prompt: args.prompt as string,\n });\n return `Job created: ${job.id.slice(0, 8)} — \"${job.name}\" runs every ${job.schedule}`;\n }\n\n if (action === \"remove\") {\n if (!args.jobId) return \"Error: jobId is required\";\n const removed = await scheduler.removeJob(args.jobId as string);\n return removed ? `Job ${(args.jobId as string).slice(0, 8)} removed` : \"Job not found\";\n }\n\n if (action === \"enable\" || action === \"disable\") {\n if (!args.jobId) return \"Error: jobId is required\";\n await scheduler.toggleJob(args.jobId as string, action === \"enable\");\n return `Job ${(args.jobId as string).slice(0, 8)} ${action}d`;\n }\n\n return \"Unknown action\";\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n if (args.action === \"add\") return `Schedule: \"${args.name}\" every ${args.schedule}`;\n return `${args.action} cron job`;\n },\n};\n","/**\n * Gateway WebSocket protocol v1.\n *\n * All UIs (Web, TUI, CLI, Desktop) use this same protocol.\n * JSON text frames over WebSocket. The gateway is the brain —\n * every frontend is a thin client.\n */\n\n// === Frame Types ===\n\n/** Client → Server: connection handshake */\nexport interface ConnectParams {\n type: \"connect\";\n params: {\n auth: { token?: string; pin?: string };\n mode: \"tui\" | \"web\" | \"cli\" | \"desktop\";\n version: string;\n };\n}\n\n/** Server → Client: handshake response */\nexport interface HelloFrame {\n type: \"hello\";\n protocol: number;\n version: string;\n agents: Array<{ id: string; name: string; model: string; status: string }>;\n sessions: Array<{ key: string; label?: string; agentId: string; updatedAt: number }>;\n}\n\n/** Client → Server: RPC request */\nexport interface RequestFrame {\n type: \"req\";\n id: string | number;\n method: string;\n params?: Record<string, unknown>;\n}\n\n/** Server → Client: RPC response */\nexport interface ResponseFrame {\n type: \"res\";\n id: string | number;\n ok: boolean;\n result?: unknown;\n error?: string;\n}\n\n/** Server → Client: push event */\nexport interface EventFrame {\n type: \"event\";\n event: string;\n payload: unknown;\n seq: number;\n}\n\nexport type Frame = ConnectParams | HelloFrame | RequestFrame | ResponseFrame | EventFrame;\n\n/** Protocol version */\nexport const PROTOCOL_VERSION = 1;\n\n/** Default gateway port (18790 — avoids collision with OpenClaw's 18789) */\nexport const DEFAULT_PORT = 18790;\n\n// === RPC Methods ===\n\nexport const METHODS = {\n // Chat\n CHAT_SEND: \"chat.send\",\n CHAT_HISTORY: \"chat.history\",\n CHAT_ABORT: \"chat.abort\",\n\n // Sessions\n SESSION_LIST: \"session.list\",\n SESSION_DELETE: \"session.delete\",\n SESSION_RESET: \"session.reset\",\n\n // Agents\n AGENT_LIST: \"agent.list\",\n AGENT_STATUS: \"agent.status\",\n\n // Config\n CONFIG_GET: \"config.get\",\n CONFIG_SET: \"config.set\",\n\n // Pipelines\n PIPELINE_LIST: \"pipeline.list\",\n PIPELINE_RUN: \"pipeline.run\",\n PIPELINE_STATUS: \"pipeline.status\",\n PIPELINE_ABORT: \"pipeline.abort\",\n\n // Cron\n CRON_LIST: \"cron.list\",\n CRON_CREATE: \"cron.create\",\n CRON_DELETE: \"cron.delete\",\n CRON_TRIGGER: \"cron.trigger\",\n\n // Logs\n LOG_TAIL: \"log.tail\",\n LOG_QUERY: \"log.query\",\n\n // Legacy compat\n CONNECT: \"connect\",\n SEND_MESSAGE: \"sendMessage\",\n CANCEL: \"cancel\",\n} as const;\n\n// === Event Types ===\n\nexport const EVENTS = {\n // Chat events\n CHAT_STREAM: \"chat.stream\",\n CHAT_TOOL: \"chat.tool\",\n CHAT_THINKING: \"chat.thinking\",\n CHAT_COMPLETE: \"chat.complete\",\n CHAT_ERROR: \"chat.error\",\n\n // System events\n PIPELINE_STEP: \"pipeline.step\",\n PIPELINE_COMPLETE: \"pipeline.complete\",\n AGENT_STATUS: \"agent.status\",\n CHANNEL_STATUS: \"channel.status\",\n LOG_ENTRY: \"log.entry\",\n\n // Legacy compat\n TOKEN: \"token\",\n RESPONSE_START: \"response-start\",\n RESPONSE_END: \"response-end\",\n TOOL_START: \"tool-start\",\n TOOL_RESULT: \"tool-result\",\n CONFIRM_NEEDED: \"confirm-needed\",\n CONTEXT_COMPACTING: \"context-compacting\",\n USAGE: \"usage\",\n ERROR: \"error\",\n TURN_COMPLETE: \"turn-complete\",\n} as const;\n\n// === Helpers ===\n\nexport function parseFrame(data: string): Frame | null {\n try {\n return JSON.parse(data) as Frame;\n } catch {\n return null;\n }\n}\n\nexport function serializeFrame(frame: Frame): string {\n return JSON.stringify(frame);\n}\n","/**\n * Gateway tool — check gateway status, connected clients, health.\n */\n\nimport { loadConfig } from \"../../config/index.js\";\nimport { DEFAULT_PORT } from \"../../gateway/protocol.js\";\nimport type { Tool, ValidationResult } from \"../types.js\";\n\nexport const gatewayTool: Tool = {\n definition: {\n name: \"gateway_status\",\n description: \"Check the gateway daemon status, connected clients, and system health.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"'status' or 'health'\" },\n },\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(): ValidationResult {\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const config = await loadConfig();\n const port = config.gateway.port || DEFAULT_PORT;\n\n try {\n const endpoint = (args.action === \"health\") ? \"health\" : \"status\";\n const res = await fetch(`http://127.0.0.1:${port}/${endpoint}`, {\n signal: AbortSignal.timeout(3000),\n });\n if (res.ok) {\n const data = await res.json();\n return JSON.stringify(data, null, 2);\n }\n return `Gateway returned error: ${res.status}`;\n } catch {\n return `Gateway not reachable at http://127.0.0.1:${port}`;\n }\n },\n};\n","/**\n * Message tool — send messages to channels from within agent execution.\n *\n * Lets agents proactively reach out: \"Send a summary to my Telegram\",\n * \"Post the build status in Discord\", etc.\n */\n\nimport type { Tool, ValidationResult } from \"../types.js\";\n\nexport const messageTool: Tool = {\n definition: {\n name: \"send_message\",\n description:\n \"Send a message to a specific channel or session. \" +\n \"Use this to proactively notify the user on another interface.\",\n parameters: {\n type: \"object\",\n properties: {\n channel: { type: \"string\", description: \"Target channel ('telegram', 'discord', 'web')\" },\n to: { type: \"string\", description: \"Recipient ID (chat ID, channel ID, etc.)\" },\n text: { type: \"string\", description: \"Message text to send\" },\n },\n required: [\"channel\", \"text\"],\n },\n },\n\n safetyLevel: \"high\", // Sending external messages is always high risk\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n if (!args.channel) return { ok: false, error: \"channel is required\" };\n if (!args.text) return { ok: false, error: \"text is required\" };\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n // This tool needs gateway integration to actually send messages.\n // The gateway routes the message to the appropriate channel adapter.\n // For now, return a placeholder indicating what would happen.\n return `Message queued for ${args.channel}${args.to ? `:${args.to}` : \"\"}: \"${(args.text as string).slice(0, 100)}\"`;\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `Send message to ${args.channel}: \"${(args.text as string).slice(0, 50)}\"`;\n },\n};\n","/**\n * Voice system — TTS and STT powered by integrations config.\n *\n * TTS: ElevenLabs (cloud) or piper (local)\n * STT: OpenAI Whisper API (cloud) or whisper.cpp (local)\n *\n * The agent uses these through tools — it can generate speech\n * from text and transcribe audio from voice messages.\n */\n\nimport type { ClankConfig } from \"../config/index.js\";\n\nexport interface TTSResult {\n audioBuffer: Buffer;\n format: \"mp3\" | \"wav\" | \"ogg\";\n}\n\nexport interface STTResult {\n text: string;\n language?: string;\n}\n\n/**\n * Text-to-Speech engine.\n */\nexport class TTSEngine {\n private config: ClankConfig;\n\n constructor(config: ClankConfig) {\n this.config = config;\n }\n\n /** Check if TTS is available */\n isAvailable(): boolean {\n return !!(this.config.integrations.elevenlabs?.enabled && this.config.integrations.elevenlabs?.apiKey);\n }\n\n /** Convert text to speech */\n async synthesize(text: string, opts?: { voiceId?: string }): Promise<TTSResult | null> {\n const elevenlabs = this.config.integrations.elevenlabs;\n if (!elevenlabs?.enabled || !elevenlabs.apiKey) return null;\n\n const voiceId = opts?.voiceId || elevenlabs.voiceId || \"JBFqnCBsd6RMkjVDRZzb\"; // Default: George\n const model = elevenlabs.model || \"eleven_multilingual_v2\";\n\n try {\n const res = await fetch(\n `https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"xi-api-key\": elevenlabs.apiKey,\n },\n body: JSON.stringify({\n text,\n model_id: model,\n voice_settings: {\n stability: 0.5,\n similarity_boost: 0.75,\n },\n }),\n },\n );\n\n if (!res.ok) {\n const err = await res.text().catch(() => \"\");\n console.error(`ElevenLabs TTS error ${res.status}: ${err}`);\n return null;\n }\n\n const arrayBuffer = await res.arrayBuffer();\n return {\n audioBuffer: Buffer.from(arrayBuffer),\n format: \"mp3\",\n };\n } catch (err) {\n console.error(`TTS error: ${err instanceof Error ? err.message : err}`);\n return null;\n }\n }\n\n /** List available voices from ElevenLabs */\n async listVoices(): Promise<Array<{ id: string; name: string }>> {\n const elevenlabs = this.config.integrations.elevenlabs;\n if (!elevenlabs?.enabled || !elevenlabs.apiKey) return [];\n\n try {\n const res = await fetch(\"https://api.elevenlabs.io/v1/voices\", {\n headers: { \"xi-api-key\": elevenlabs.apiKey },\n });\n if (!res.ok) return [];\n const data = await res.json() as { voices?: Array<{ voice_id: string; name: string }> };\n return (data.voices || []).map((v) => ({ id: v.voice_id, name: v.name }));\n } catch {\n return [];\n }\n }\n}\n\n/**\n * Speech-to-Text engine.\n */\nexport class STTEngine {\n private config: ClankConfig;\n\n constructor(config: ClankConfig) {\n this.config = config;\n }\n\n /** Check if STT is available */\n isAvailable(): boolean {\n const whisper = this.config.integrations.whisper;\n if (whisper?.enabled) {\n if (whisper.provider === \"openai\" && whisper.apiKey) return true;\n if (whisper.provider === \"local\") return true;\n }\n // Fall back to OpenAI key from model providers\n if (this.config.models.providers.openai?.apiKey) return true;\n return false;\n }\n\n /** Transcribe audio to text */\n async transcribe(audioBuffer: Buffer, format = \"ogg\"): Promise<STTResult | null> {\n const whisper = this.config.integrations.whisper;\n\n // Try OpenAI Whisper API\n const apiKey = whisper?.apiKey || this.config.models.providers.openai?.apiKey;\n if (apiKey && whisper?.provider !== \"local\") {\n return this.transcribeOpenAI(audioBuffer, format, apiKey);\n }\n\n // Try local whisper.cpp\n return this.transcribeLocal(audioBuffer, format);\n }\n\n /** Transcribe via OpenAI Whisper API */\n private async transcribeOpenAI(audioBuffer: Buffer, format: string, apiKey: string): Promise<STTResult | null> {\n try {\n // Build multipart form data\n const blob = new Blob([new Uint8Array(audioBuffer)], { type: `audio/${format}` });\n const formData = new FormData();\n formData.append(\"file\", blob, `audio.${format}`);\n formData.append(\"model\", \"whisper-1\");\n\n const res = await fetch(\"https://api.openai.com/v1/audio/transcriptions\", {\n method: \"POST\",\n headers: { \"Authorization\": `Bearer ${apiKey}` },\n body: formData,\n });\n\n if (!res.ok) return null;\n const data = await res.json() as { text?: string; language?: string };\n return data.text ? { text: data.text, language: data.language } : null;\n } catch {\n return null;\n }\n }\n\n /** Transcribe via local whisper.cpp */\n private async transcribeLocal(audioBuffer: Buffer, format: string): Promise<STTResult | null> {\n try {\n const { writeFile, unlink } = await import(\"node:fs/promises\");\n const { execSync } = await import(\"node:child_process\");\n const { join } = await import(\"node:path\");\n const { tmpdir } = await import(\"node:os\");\n\n const tmpFile = join(tmpdir(), `clank-stt-${Date.now()}.${format}`);\n await writeFile(tmpFile, audioBuffer);\n\n const output = execSync(`whisper \"${tmpFile}\" --model base.en --output-txt`, {\n encoding: \"utf-8\",\n timeout: 60_000,\n });\n\n await unlink(tmpFile).catch(() => {});\n return output.trim() ? { text: output.trim() } : null;\n } catch {\n return null;\n }\n }\n}\n","export { TTSEngine, STTEngine, type TTSResult, type STTResult } from \"./tts.js\";\n","/**\n * Voice tools — let the agent generate speech and transcribe audio.\n *\n * \"Read this summary out loud\" → agent uses tts tool\n * \"What did they say in that voice message?\" → agent uses stt tool\n */\n\nimport { TTSEngine, STTEngine } from \"../../voice/index.js\";\nimport { loadConfig } from \"../../config/index.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"../types.js\";\n\nexport const ttsTool: Tool = {\n definition: {\n name: \"text_to_speech\",\n description:\n \"Convert text to speech audio using ElevenLabs. Returns the audio file path. \" +\n \"Requires ElevenLabs integration to be configured.\",\n parameters: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Text to convert to speech\" },\n voice_id: { type: \"string\", description: \"ElevenLabs voice ID (optional, uses default)\" },\n },\n required: [\"text\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>): ValidationResult {\n if (!args.text || typeof args.text !== \"string\") return { ok: false, error: \"text is required\" };\n if ((args.text as string).length > 5000) return { ok: false, error: \"text too long (max 5000 chars)\" };\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const config = await loadConfig();\n const engine = new TTSEngine(config);\n\n if (!engine.isAvailable()) {\n return \"Error: ElevenLabs not configured. Tell me to set it up, or run: clank setup --section integrations\";\n }\n\n const result = await engine.synthesize(args.text as string, {\n voiceId: args.voice_id as string | undefined,\n });\n\n if (!result) return \"Error: TTS synthesis failed\";\n\n // Save to temp file and return path\n const { writeFile } = await import(\"node:fs/promises\");\n const { join } = await import(\"node:path\");\n const { tmpdir } = await import(\"node:os\");\n const outPath = join(tmpdir(), `clank-tts-${Date.now()}.${result.format}`);\n await writeFile(outPath, result.audioBuffer);\n\n return `Audio generated: ${outPath} (${result.format}, ${Math.round(result.audioBuffer.length / 1024)}KB)`;\n },\n};\n\nexport const sttTool: Tool = {\n definition: {\n name: \"speech_to_text\",\n description:\n \"Transcribe an audio file to text using Whisper (OpenAI API or local whisper.cpp). \" +\n \"Provide a file path to an audio file.\",\n parameters: {\n type: \"object\",\n properties: {\n file_path: { type: \"string\", description: \"Path to audio file (.mp3, .wav, .ogg, .m4a)\" },\n },\n required: [\"file_path\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>): ValidationResult {\n if (!args.file_path || typeof args.file_path !== \"string\") return { ok: false, error: \"file_path is required\" };\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const { readFile } = await import(\"node:fs/promises\");\n const { existsSync } = await import(\"node:fs\");\n\n const filePath = args.file_path as string;\n if (!existsSync(filePath)) return `Error: File not found: ${filePath}`;\n\n const config = await loadConfig();\n const engine = new STTEngine(config);\n\n if (!engine.isAvailable()) {\n return \"Error: Speech-to-text not configured. Need OpenAI API key or local whisper.cpp installed.\";\n }\n\n const audioBuffer = await readFile(filePath);\n const ext = filePath.split(\".\").pop() || \"wav\";\n const result = await engine.transcribe(audioBuffer, ext);\n\n if (!result) return \"Error: Transcription failed\";\n return result.text;\n },\n};\n\nexport const voiceListTool: Tool = {\n definition: {\n name: \"list_voices\",\n description: \"List available ElevenLabs voices for text-to-speech.\",\n parameters: { type: \"object\", properties: {} },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(): ValidationResult { return { ok: true }; },\n\n async execute(): Promise<string> {\n const config = await loadConfig();\n const engine = new TTSEngine(config);\n\n if (!engine.isAvailable()) {\n return \"Error: ElevenLabs not configured.\";\n }\n\n const voices = await engine.listVoices();\n if (voices.length === 0) return \"No voices found or API error.\";\n return voices.map((v) => `${v.name}: ${v.id}`).join(\"\\n\");\n },\n};\n","export { configTool } from \"./config-tool.js\";\nexport { channelTool } from \"./channel-tool.js\";\nexport { agentTool } from \"./agent-tool.js\";\nexport { modelTool } from \"./model-tool.js\";\nexport { sessionTool } from \"./session-tool.js\";\nexport { cronTool } from \"./cron-tool.js\";\nexport { gatewayTool } from \"./gateway-tool.js\";\nexport { messageTool } from \"./message-tool.js\";\nexport { ttsTool, sttTool, voiceListTool } from \"./voice-tool.js\";\n\nimport type { ToolRegistry } from \"../registry.js\";\nimport { configTool } from \"./config-tool.js\";\nimport { channelTool } from \"./channel-tool.js\";\nimport { agentTool } from \"./agent-tool.js\";\nimport { modelTool } from \"./model-tool.js\";\nimport { sessionTool } from \"./session-tool.js\";\nimport { cronTool } from \"./cron-tool.js\";\nimport { gatewayTool } from \"./gateway-tool.js\";\nimport { messageTool } from \"./message-tool.js\";\nimport { ttsTool, sttTool, voiceListTool } from \"./voice-tool.js\";\n\n/** Register all self-configuration tools into a registry */\nexport function registerSelfConfigTools(registry: ToolRegistry): void {\n registry.register(configTool);\n registry.register(channelTool);\n registry.register(agentTool);\n registry.register(modelTool);\n registry.register(sessionTool);\n registry.register(cronTool);\n registry.register(gatewayTool);\n registry.register(messageTool);\n registry.register(ttsTool);\n registry.register(sttTool);\n registry.register(voiceListTool);\n}\n","export type { Tool, ToolContext, ToolTier, SafetyLevel, ValidationResult } from \"./types.js\";\nexport { CORE_TOOL_NAMES, AUTO_TIER_TRIGGERS } from \"./types.js\";\nexport { ToolRegistry } from \"./registry.js\";\n\n// Core tools\nexport { readFileTool } from \"./read-file.js\";\nexport { writeFileTool } from \"./write-file.js\";\nexport { editFileTool } from \"./edit-file.js\";\nexport { listDirectoryTool } from \"./list-directory.js\";\nexport { searchFilesTool } from \"./search-files.js\";\nexport { globFilesTool } from \"./glob-files.js\";\nexport { bashTool } from \"./bash.js\";\nexport { gitTool } from \"./git.js\";\nexport { webSearchTool } from \"./web-search.js\";\nexport { webFetchTool } from \"./web-fetch.js\";\n\nimport { ToolRegistry } from \"./registry.js\";\nimport { readFileTool } from \"./read-file.js\";\nimport { writeFileTool } from \"./write-file.js\";\nimport { editFileTool } from \"./edit-file.js\";\nimport { listDirectoryTool } from \"./list-directory.js\";\nimport { searchFilesTool } from \"./search-files.js\";\nimport { globFilesTool } from \"./glob-files.js\";\nimport { bashTool } from \"./bash.js\";\nimport { gitTool } from \"./git.js\";\nimport { webSearchTool } from \"./web-search.js\";\nimport { webFetchTool } from \"./web-fetch.js\";\nimport { registerSelfConfigTools } from \"./self-config/index.js\";\n\n// Self-config tools\nexport { registerSelfConfigTools } from \"./self-config/index.js\";\n\n/**\n * Create a ToolRegistry pre-loaded with all core tools.\n */\nexport function createCoreRegistry(): ToolRegistry {\n const registry = new ToolRegistry();\n registry.register(readFileTool);\n registry.register(writeFileTool);\n registry.register(editFileTool);\n registry.register(listDirectoryTool);\n registry.register(searchFilesTool);\n registry.register(globFilesTool);\n registry.register(bashTool);\n registry.register(gitTool);\n registry.register(webSearchTool);\n registry.register(webFetchTool);\n return registry;\n}\n\n/**\n * Create a full registry with core + self-config tools.\n * Used when the agent should be able to configure itself.\n */\nexport function createFullRegistry(): ToolRegistry {\n const registry = createCoreRegistry();\n registerSelfConfigTools(registry);\n return registry;\n}\n","/**\n * CLI chat command — direct mode.\n *\n * This is the simplest way to use Clank: `clank chat` starts an\n * interactive session in the terminal. In direct mode (no gateway),\n * it spawns an AgentEngine inline and talks to it directly.\n *\n * Later (Sprint 2), this will also support connecting to a running\n * gateway via WebSocket. But direct mode always works as a fallback.\n */\n\nimport { createInterface } from \"node:readline\";\nimport { join } from \"node:path\";\nimport { AgentEngine, type AgentIdentity, buildSystemPrompt } from \"../engine/index.js\";\nimport { createFullRegistry } from \"../tools/index.js\";\nimport { createProvider, resolveWithFallback } from \"../providers/router.js\";\nimport { OllamaProvider } from \"../providers/ollama.js\";\nimport { loadConfig, ensureConfigDir, getConfigDir } from \"../config/index.js\";\nimport { SessionStore } from \"../sessions/index.js\";\n\n/** ANSI color helpers */\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst bold = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst yellow = (s: string) => `\\x1b[33m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\n\nexport async function runChat(opts: {\n new?: boolean;\n continue?: boolean;\n session?: string;\n direct?: boolean;\n web?: boolean;\n}): Promise<void> {\n await ensureConfigDir();\n const config = await loadConfig();\n\n // --web flag: start gateway if needed and open browser\n if (opts.web) {\n const port = config.gateway.port || 18789;\n const token = config.gateway.auth.token || \"\";\n\n // Check if gateway is running\n let gatewayRunning = false;\n try {\n const res = await fetch(`http://127.0.0.1:${port}/health`, { signal: AbortSignal.timeout(2000) });\n gatewayRunning = res.ok;\n } catch {}\n\n if (!gatewayRunning) {\n // Start gateway in background\n console.log(dim(\"Starting gateway...\"));\n const { fork } = await import(\"node:child_process\");\n const { fileURLToPath } = await import(\"node:url\");\n const { dirname, join } = await import(\"node:path\");\n const __filename = fileURLToPath(import.meta.url);\n const entryPoint = join(dirname(__filename), \"index.js\");\n\n const child = fork(entryPoint, [\"gateway\", \"start\", \"--foreground\"], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n\n // Wait for gateway to be ready\n for (let i = 0; i < 20; i++) {\n await new Promise((r) => setTimeout(r, 500));\n try {\n const res = await fetch(`http://127.0.0.1:${port}/health`, { signal: AbortSignal.timeout(1000) });\n if (res.ok) { gatewayRunning = true; break; }\n } catch {}\n }\n\n if (!gatewayRunning) {\n console.log(red(\"Failed to start gateway. Try: clank gateway start\"));\n return;\n }\n console.log(green(\"Gateway started.\"));\n }\n\n // Open browser\n const url = `http://127.0.0.1:${port}/#token=${token}`;\n console.log(dim(`Opening ${url}`));\n const { platform } = await import(\"node:os\");\n const { exec } = await import(\"node:child_process\");\n const openCmd = platform() === \"win32\" ? `start \"\" \"${url}\"` : platform() === \"darwin\" ? `open \"${url}\"` : `xdg-open \"${url}\"`;\n exec(openCmd);\n console.log(green(\"Web UI opened in browser.\"));\n return;\n }\n\n // Resolve model and create provider\n const modelConfig = config.agents.defaults.model;\n console.log(dim(`Connecting to ${modelConfig.primary}...`));\n\n let resolved;\n try {\n resolved = await resolveWithFallback(\n modelConfig.primary,\n modelConfig.fallbacks || [],\n config.models.providers,\n { maxResponseTokens: config.agents.defaults.maxResponseTokens },\n );\n console.log(green(` Connected to ${resolved.modelId}${resolved.isLocal ? \" (local)\" : \" (cloud)\"}`));\n } catch (err) {\n console.error(red(`Failed to connect to any model: ${err instanceof Error ? err.message : err}`));\n console.error(dim(\"Make sure Ollama is running or configure a cloud provider in ~/.clank/config.json5\"));\n process.exit(1);\n }\n\n // Initialize session store\n const sessionStore = new SessionStore(join(getConfigDir(), \"conversations\"));\n await sessionStore.init();\n\n // Create tool registry — full registry includes self-config tools\n const toolRegistry = createFullRegistry();\n\n // Create agent identity\n const identity: AgentIdentity = {\n id: \"default\",\n name: \"Clank\",\n model: modelConfig,\n workspace: config.agents.defaults.workspace || process.cwd(),\n toolTier: config.agents.defaults.toolTier || \"auto\",\n temperature: config.agents.defaults.temperature,\n maxResponseTokens: config.agents.defaults.maxResponseTokens,\n };\n\n // Build system prompt from workspace files\n const systemPrompt = await buildSystemPrompt({\n identity,\n workspaceDir: identity.workspace,\n channel: \"cli\",\n });\n\n // Create engine\n const engine = new AgentEngine({\n identity,\n toolRegistry,\n sessionStore,\n provider: resolved,\n autoApprove: config.tools.autoApprove,\n systemPrompt,\n });\n\n // Load session\n const sessionKey = opts.session || \"cli:main\";\n await engine.loadSession(sessionKey, \"cli\");\n\n // Wire up events\n let isStreaming = false;\n\n engine.on(\"response-start\", () => {\n isStreaming = true;\n });\n\n engine.on(\"token\", ({ content }) => {\n process.stdout.write(content);\n });\n\n engine.on(\"response-end\", ({ text }) => {\n if (isStreaming && text) {\n process.stdout.write(\"\\n\");\n }\n isStreaming = false;\n });\n\n engine.on(\"tool-start\", ({ name, arguments: args }) => {\n const summary = args.command || args.path || args.pattern || args.args || \"\";\n console.log(dim(` [${name}] ${String(summary).slice(0, 80)}`));\n });\n\n engine.on(\"tool-result\", ({ name, success, summary }) => {\n const icon = success ? green(\"ok\") : red(\"err\");\n console.log(dim(` [${name}] ${icon} ${summary.slice(0, 80)}`));\n });\n\n engine.on(\"confirm-needed\", ({ actions, resolve }) => {\n const action = actions[0];\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n rl.question(\n yellow(` Confirm: ${action.description} [y/n/always] `),\n (answer) => {\n rl.close();\n const a = answer.trim().toLowerCase();\n if (a === \"always\" || a === \"a\") resolve(\"always\");\n else if (a === \"y\" || a === \"yes\") resolve(true);\n else resolve(false);\n },\n );\n });\n\n engine.on(\"context-compacting\", () => {\n console.log(dim(\" (compacting context...)\"));\n });\n\n engine.on(\"usage\", ({ promptTokens, outputTokens, iterationCount, contextPercent }) => {\n console.log(dim(` [${promptTokens}→${outputTokens} tokens | iter ${iterationCount} | ctx ${contextPercent}%]`));\n });\n\n engine.on(\"error\", ({ message, recoverable }) => {\n console.error(red(`Error: ${message}${recoverable ? \" (recoverable)\" : \"\"}`));\n });\n\n // Print header\n console.log(\"\");\n console.log(bold(\"Clank\") + dim(` v0.1.0 | ${resolved.modelId} | ${identity.toolTier} tier`));\n console.log(dim(\"Type your message. Press Ctrl+C to exit.\\n\"));\n\n // Interactive readline loop\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n prompt: cyan(\"you > \"),\n });\n\n rl.prompt();\n\n rl.on(\"line\", async (line) => {\n const input = line.trim();\n if (!input) {\n rl.prompt();\n return;\n }\n\n // Slash commands\n if (input.startsWith(\"/\")) {\n await handleSlashCommand(input, engine, rl);\n rl.prompt();\n return;\n }\n\n console.log(\"\");\n try {\n await engine.sendMessage(input);\n } catch (err) {\n // Error already emitted via event\n }\n console.log(\"\");\n rl.prompt();\n });\n\n rl.on(\"close\", () => {\n engine.destroy();\n process.exit(0);\n });\n\n // Handle Ctrl+C during streaming\n process.on(\"SIGINT\", () => {\n if (isStreaming) {\n engine.cancel();\n console.log(dim(\"\\n (cancelled)\"));\n rl.prompt();\n } else {\n rl.close();\n }\n });\n}\n\n/** Handle slash commands */\nasync function handleSlashCommand(\n input: string,\n engine: AgentEngine,\n _rl: ReturnType<typeof createInterface>,\n): Promise<void> {\n const [cmd, ...args] = input.slice(1).split(/\\s+/);\n\n switch (cmd) {\n case \"help\":\n console.log(dim(\"Commands:\"));\n console.log(dim(\" /help — Show this help\"));\n console.log(dim(\" /model — Show current model\"));\n console.log(dim(\" /clear — Clear conversation\"));\n console.log(dim(\" /exit — Exit\"));\n break;\n\n case \"model\":\n console.log(dim(`Model: ${engine.identity.model.primary}`));\n break;\n\n case \"clear\":\n engine.getContextEngine().clear();\n console.log(dim(\"Conversation cleared.\"));\n break;\n\n case \"exit\":\n case \"quit\":\n engine.destroy();\n process.exit(0);\n\n default:\n console.log(dim(`Unknown command: /${cmd}. Type /help for available commands.`));\n }\n}\n","/**\n * Memory system — TF-IDF based long-term memory with categories and decay.\n *\n * Memories are stored as markdown files in categorized subdirectories:\n * ~/.clank/memory/identity/ — who the agent is\n * ~/.clank/memory/knowledge/ — facts and information\n * ~/.clank/memory/lessons/ — things learned from experience\n * ~/.clank/memory/context/ — project-specific context\n *\n * Each file has metadata (_meta.json) tracking access patterns for\n * decay scoring — memories that haven't been accessed fade over time.\n */\n\nimport { readFile, writeFile, readdir, mkdir, unlink } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\n\nexport interface MemoryEntry {\n id: string;\n category: \"identity\" | \"knowledge\" | \"lessons\" | \"context\";\n title: string;\n content: string;\n filePath: string;\n}\n\nexport interface MemoryMeta {\n id: string;\n lastAccessed: number;\n accessCount: number;\n createdAt: number;\n dormant: boolean;\n}\n\n/** Common English stopwords to filter from TF-IDF */\nconst STOPWORDS = new Set([\n \"the\", \"be\", \"to\", \"of\", \"and\", \"a\", \"in\", \"that\", \"have\", \"i\",\n \"it\", \"for\", \"not\", \"on\", \"with\", \"he\", \"as\", \"you\", \"do\", \"at\",\n \"this\", \"but\", \"his\", \"by\", \"from\", \"they\", \"we\", \"say\", \"her\",\n \"she\", \"or\", \"an\", \"will\", \"my\", \"one\", \"all\", \"would\", \"there\",\n \"their\", \"what\", \"so\", \"up\", \"out\", \"if\", \"about\", \"who\", \"get\",\n \"which\", \"go\", \"me\", \"when\", \"make\", \"can\", \"like\", \"time\", \"no\",\n \"just\", \"him\", \"know\", \"take\", \"people\", \"into\", \"year\", \"your\",\n \"good\", \"some\", \"could\", \"them\", \"see\", \"other\", \"than\", \"then\",\n \"now\", \"look\", \"only\", \"come\", \"its\", \"over\", \"think\", \"also\",\n \"back\", \"after\", \"use\", \"two\", \"how\", \"our\", \"work\", \"first\",\n \"well\", \"way\", \"even\", \"new\", \"want\", \"because\", \"any\", \"these\",\n \"give\", \"day\", \"most\", \"us\", \"is\", \"are\", \"was\", \"were\", \"been\",\n \"has\", \"had\", \"did\", \"does\", \"am\",\n]);\n\nexport class MemoryManager {\n private memoryDir: string;\n private metaPath: string;\n private meta: Map<string, MemoryMeta> = new Map();\n\n constructor(memoryDir: string) {\n this.memoryDir = memoryDir;\n this.metaPath = join(memoryDir, \"_meta.json\");\n }\n\n /** Initialize — create dirs and load metadata */\n async init(): Promise<void> {\n for (const cat of [\"identity\", \"knowledge\", \"lessons\", \"context\"]) {\n await mkdir(join(this.memoryDir, cat), { recursive: true });\n }\n await this.loadMeta();\n }\n\n /** Find memories relevant to a query using TF-IDF cosine similarity */\n async findRelevant(query: string, topK = 3): Promise<MemoryEntry[]> {\n const entries = await this.loadAll();\n if (entries.length === 0) return [];\n\n const queryTerms = tokenize(query);\n if (queryTerms.length === 0) return entries.slice(0, topK);\n\n // Build document frequency map\n const df = new Map<string, number>();\n const docs = entries.map((e) => {\n const terms = tokenize(e.content);\n const unique = new Set(terms);\n for (const t of unique) df.set(t, (df.get(t) || 0) + 1);\n return { entry: e, terms };\n });\n\n const N = docs.length;\n\n // Score each document\n const scored = docs.map(({ entry, terms }) => {\n const score = cosineSimilarity(queryTerms, terms, df, N);\n // Apply decay: reduce score for old, unused memories\n const meta = this.meta.get(entry.id);\n const decayFactor = meta ? this.decayScore(meta) : 0.5;\n return { entry, score: score * decayFactor };\n });\n\n // Sort by score descending\n scored.sort((a, b) => b.score - a.score);\n\n // Update access metadata for returned results\n const results = scored.slice(0, topK).filter((s) => s.score > 0.01).map((s) => s.entry);\n for (const entry of results) {\n const meta = this.meta.get(entry.id);\n if (meta) {\n meta.lastAccessed = Date.now();\n meta.accessCount++;\n }\n }\n await this.saveMeta();\n\n return results;\n }\n\n /**\n * Build the memory block for injection into the system prompt.\n * Combines global memory, project memory, and relevant topics.\n */\n async buildMemoryBlock(userMessage: string, projectRoot?: string, budgetChars = 4000): Promise<string> {\n const parts: string[] = [];\n let used = 0;\n\n // 1. Project memory (.clank.md)\n if (projectRoot) {\n for (const name of [\".clank.md\", \".clankbuild.md\", \".llamabuild.md\"]) {\n const path = join(projectRoot, name);\n if (existsSync(path)) {\n try {\n const content = await readFile(path, \"utf-8\");\n if (content.trim() && used + content.length < budgetChars) {\n parts.push(\"## Project Memory\\n\" + content.trim());\n used += content.length;\n }\n } catch { /* skip */ }\n break;\n }\n }\n }\n\n // 2. Global memory (MEMORY.md)\n const globalPath = join(this.memoryDir, \"..\", \"workspace\", \"MEMORY.md\");\n if (existsSync(globalPath)) {\n try {\n const content = await readFile(globalPath, \"utf-8\");\n if (content.trim() && used + content.length < budgetChars) {\n parts.push(\"## Global Memory\\n\" + content.trim());\n used += content.length;\n }\n } catch { /* skip */ }\n }\n\n // 3. Relevant memories (TF-IDF matched)\n const relevant = await this.findRelevant(userMessage, 3);\n for (const entry of relevant) {\n if (used + entry.content.length > budgetChars) break;\n parts.push(`## ${entry.title}\\n${entry.content}`);\n used += entry.content.length;\n }\n\n return parts.length > 0 ? parts.join(\"\\n\\n\") : \"\";\n }\n\n /** Add a new memory */\n async add(category: MemoryEntry[\"category\"], title: string, content: string): Promise<MemoryEntry> {\n const id = randomUUID();\n const filename = `${title.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").slice(0, 50)}.md`;\n const filePath = join(this.memoryDir, category, filename);\n\n await writeFile(filePath, `# ${title}\\n\\n${content}`, \"utf-8\");\n\n this.meta.set(id, {\n id,\n lastAccessed: Date.now(),\n accessCount: 0,\n createdAt: Date.now(),\n dormant: false,\n });\n await this.saveMeta();\n\n return { id, category, title, content, filePath };\n }\n\n /** Decay scores — flag dormant memories (30+ days unused) */\n async decayScores(): Promise<number> {\n const now = Date.now();\n const thirtyDays = 30 * 24 * 60 * 60 * 1000;\n let flagged = 0;\n\n for (const [, meta] of this.meta) {\n if (now - meta.lastAccessed > thirtyDays && !meta.dormant) {\n meta.dormant = true;\n flagged++;\n }\n }\n\n if (flagged > 0) await this.saveMeta();\n return flagged;\n }\n\n /** Prune dormant memories older than 90 days */\n async prune(): Promise<number> {\n const now = Date.now();\n const ninetyDays = 90 * 24 * 60 * 60 * 1000;\n let pruned = 0;\n\n for (const [id, meta] of this.meta) {\n if (meta.dormant && now - meta.lastAccessed > ninetyDays) {\n this.meta.delete(id);\n pruned++;\n }\n }\n\n if (pruned > 0) await this.saveMeta();\n return pruned;\n }\n\n /** Load all memory entries from disk */\n private async loadAll(): Promise<MemoryEntry[]> {\n const entries: MemoryEntry[] = [];\n\n for (const category of [\"identity\", \"knowledge\", \"lessons\", \"context\"] as const) {\n const dir = join(this.memoryDir, category);\n if (!existsSync(dir)) continue;\n\n try {\n const files = await readdir(dir);\n for (const file of files) {\n if (!file.endsWith(\".md\")) continue;\n const filePath = join(dir, file);\n try {\n const content = await readFile(filePath, \"utf-8\");\n const title = content.split(\"\\n\")[0]?.replace(/^#\\s*/, \"\") || file;\n entries.push({\n id: file,\n category,\n title,\n content,\n filePath,\n });\n } catch { /* skip */ }\n }\n } catch { /* skip */ }\n }\n\n return entries;\n }\n\n /** Calculate decay factor for a memory (1.0 = fresh, 0.25 = old) */\n private decayScore(meta: MemoryMeta): number {\n const daysSinceAccess = (Date.now() - meta.lastAccessed) / (24 * 60 * 60 * 1000);\n const recency = daysSinceAccess < 1 ? 1.0\n : daysSinceAccess < 30 ? 0.5\n : 0.25;\n const frequencyBoost = Math.min(1.5, 1 + meta.accessCount * 0.1);\n return recency * frequencyBoost;\n }\n\n private async loadMeta(): Promise<void> {\n if (!existsSync(this.metaPath)) return;\n try {\n const raw = await readFile(this.metaPath, \"utf-8\");\n const entries = JSON.parse(raw) as MemoryMeta[];\n for (const e of entries) this.meta.set(e.id, e);\n } catch { /* start fresh */ }\n }\n\n private async saveMeta(): Promise<void> {\n const entries = Array.from(this.meta.values());\n await writeFile(this.metaPath, JSON.stringify(entries, null, 2), \"utf-8\");\n }\n}\n\n/** Tokenize text for TF-IDF */\nfunction tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \" \")\n .split(/\\s+/)\n .filter((t) => t.length >= 3 && !STOPWORDS.has(t));\n}\n\n/** Compute TF-IDF cosine similarity between query and document */\nfunction cosineSimilarity(\n queryTerms: string[],\n docTerms: string[],\n df: Map<string, number>,\n N: number,\n): number {\n // Build TF maps\n const queryTf = new Map<string, number>();\n for (const t of queryTerms) queryTf.set(t, (queryTf.get(t) || 0) + 1);\n\n const docTf = new Map<string, number>();\n for (const t of docTerms) docTf.set(t, (docTf.get(t) || 0) + 1);\n\n // Compute TF-IDF vectors and dot product\n let dotProduct = 0;\n let queryMag = 0;\n let docMag = 0;\n\n const allTerms = new Set([...queryTf.keys(), ...docTf.keys()]);\n for (const term of allTerms) {\n const idf = Math.log(N / (df.get(term) || 1));\n const qVal = (queryTf.get(term) || 0) * idf;\n const dVal = (docTf.get(term) || 0) * idf;\n dotProduct += qVal * dVal;\n queryMag += qVal * qVal;\n docMag += dVal * dVal;\n }\n\n const magnitude = Math.sqrt(queryMag) * Math.sqrt(docMag);\n return magnitude > 0 ? dotProduct / magnitude : 0;\n}\n","export { MemoryManager, type MemoryEntry, type MemoryMeta } from \"./memory.js\";\n","/**\n * Multi-agent routing — resolves inbound messages to agents.\n *\n * Uses a binding-based priority system (matching OpenClaw's approach):\n * 1. Exact peer match (DM/group ID)\n * 2. Parent thread inheritance\n * 3. Discord guild + role\n * 4. Guild/team\n * 5. Account-level binding\n * 6. Channel-level catch-all\n * 7. Default agent\n *\n * Config-driven: bindings are defined in config.json5.\n */\n\nexport interface RouteBinding {\n agentId: string;\n /** Match criteria (evaluated in priority order) */\n match?: {\n channel?: string;\n peer?: { kind: \"dm\" | \"group\" | \"channel\"; id: string | number };\n guild?: string;\n roles?: string[];\n team?: string;\n account?: string;\n };\n /** Priority override (lower = higher priority) */\n priority?: number;\n}\n\nexport interface RouteContext {\n channel: string;\n peerId?: string | number;\n peerKind?: \"dm\" | \"group\" | \"channel\";\n guildId?: string;\n roles?: string[];\n teamId?: string;\n accountId?: string;\n threadParentId?: string | number;\n}\n\nexport interface AgentListEntry {\n id: string;\n name?: string;\n}\n\n/**\n * Resolve which agent should handle a message.\n * Evaluates bindings in priority order and returns the best match.\n */\nexport function resolveRoute(\n context: RouteContext,\n bindings: RouteBinding[],\n agents: AgentListEntry[],\n defaultAgentId: string,\n): string {\n // Sort bindings by specificity (most specific first)\n const scored = bindings.map((b) => ({\n binding: b,\n score: scoreBinding(b, context),\n }));\n\n // Filter to matches and sort by score (highest first)\n const matches = scored\n .filter((s) => s.score > 0)\n .sort((a, b) => {\n // Explicit priority overrides score\n const pA = a.binding.priority ?? 99;\n const pB = b.binding.priority ?? 99;\n if (pA !== pB) return pA - pB;\n return b.score - a.score;\n });\n\n if (matches.length > 0) {\n const agentId = matches[0].binding.agentId;\n // Verify agent exists\n if (agents.some((a) => a.id === agentId)) {\n return agentId;\n }\n }\n\n return defaultAgentId;\n}\n\n/**\n * Score a binding against a route context.\n * Higher score = more specific match.\n * Returns 0 if the binding doesn't match at all.\n */\nfunction scoreBinding(binding: RouteBinding, context: RouteContext): number {\n const match = binding.match;\n if (!match) return 0;\n\n let score = 0;\n\n // Tier 1: Exact peer match (most specific)\n if (match.peer) {\n if (\n match.peer.kind === context.peerKind &&\n String(match.peer.id) === String(context.peerId)\n ) {\n score += 100;\n } else {\n return 0; // Peer specified but doesn't match\n }\n }\n\n // Tier 2: Guild + roles\n if (match.guild && match.roles) {\n if (\n match.guild === context.guildId &&\n match.roles.some((r) => context.roles?.includes(r))\n ) {\n score += 80;\n } else if (match.guild || match.roles) {\n return 0;\n }\n }\n\n // Tier 3: Guild only\n if (match.guild && !match.roles) {\n if (match.guild === context.guildId) {\n score += 60;\n } else {\n return 0;\n }\n }\n\n // Tier 4: Team\n if (match.team) {\n if (match.team === context.teamId) {\n score += 50;\n } else {\n return 0;\n }\n }\n\n // Tier 5: Account\n if (match.account) {\n if (match.account === context.accountId) {\n score += 30;\n } else {\n return 0;\n }\n }\n\n // Tier 6: Channel catch-all\n if (match.channel) {\n if (match.channel === context.channel) {\n score += 10;\n } else {\n return 0;\n }\n }\n\n return score;\n}\n\n/**\n * Derive a normalized session key from a route context.\n */\nexport function deriveSessionKey(context: RouteContext): string {\n if (context.peerKind === \"dm\") {\n return `dm:${context.channel}:${context.peerId}`;\n }\n if (context.peerKind === \"group\" || context.peerKind === \"channel\") {\n return `group:${context.channel}:${context.peerId}`;\n }\n return `${context.channel}:main`;\n}\n","export {\n resolveRoute,\n deriveSessionKey,\n type RouteBinding,\n type RouteContext,\n type AgentListEntry,\n} from \"./resolve-route.js\";\n","/**\n * Channel adapter base interface.\n *\n * All channels (CLI, Telegram, Discord, Web, Slack, etc.) implement\n * this interface. The gateway treats them all equally — no hierarchy,\n * no \"primary\" interface. User picks what fits their workflow.\n *\n * The pattern is simple:\n * - Inbound: adapter receives platform message → normalizes → calls gateway.handleMessage()\n * - Outbound: gateway calls adapter.send() with a ReplyPayload\n */\n\nimport type { GatewayServer } from \"../gateway/server.js\";\nimport type { ClankConfig } from \"../config/index.js\";\n\n/** Normalized inbound message from any channel */\nexport interface InboundMessage {\n /** Raw text content */\n text: string;\n /** Channel identifier (telegram, discord, cli, web, etc.) */\n channel: string;\n /** Sender identifier (user ID, etc.) */\n senderId: string | number;\n /** Peer identifier (chat/group/channel ID) */\n peerId: string | number;\n /** Peer kind */\n peerKind: \"dm\" | \"group\" | \"channel\";\n /** Thread ID if applicable */\n threadId?: string | number;\n /** Whether the bot was explicitly mentioned */\n mentioned?: boolean;\n /** Optional media attachments */\n media?: Array<{ type: string; url: string }>;\n}\n\n/** Outbound reply to any channel */\nexport interface ReplyPayload {\n text?: string;\n mediaUrl?: string;\n mediaUrls?: string[];\n replyToId?: string;\n isError?: boolean;\n}\n\n/** The interface every channel adapter must implement */\nexport abstract class ChannelAdapter {\n abstract readonly id: string;\n abstract readonly name: string;\n\n /** Initialize the adapter with gateway and config references */\n abstract init(gateway: GatewayServer, config: ClankConfig): void;\n\n /** Start the adapter (connect to platform, begin polling, etc.) */\n abstract start(): Promise<void>;\n\n /** Stop the adapter (disconnect, cleanup) */\n abstract stop(): Promise<void>;\n\n /**\n * Send a reply payload to the platform.\n * Called by the gateway when an agent produces a response.\n */\n abstract send(sessionKey: string, payload: ReplyPayload): Promise<void>;\n\n /**\n * Send a streaming token to the platform.\n * Used for real-time response streaming (e.g., editing a Telegram message).\n */\n async sendToken?(sessionKey: string, content: string): Promise<void> {\n // Default: no streaming support, full response sent via send()\n }\n}\n","/**\n * Telegram channel adapter.\n *\n * Built on grammY. Refactored from the original Clank Telegram bot\n * into the ChannelAdapter pattern. Supports:\n * - DM and group chats with separate allowlists\n * - @mention checking in groups\n * - Streaming via message editing\n * - Inline keyboard confirmations\n * - Media group coalescing\n */\n\nimport { Bot } from \"grammy\";\nimport { ChannelAdapter, type InboundMessage, type ReplyPayload } from \"./base.js\";\nimport type { GatewayServer } from \"../gateway/server.js\";\nimport type { ClankConfig } from \"../config/index.js\";\n\nexport class TelegramAdapter extends ChannelAdapter {\n readonly id = \"telegram\";\n readonly name = \"Telegram\";\n private gateway: GatewayServer | null = null;\n private config: ClankConfig | null = null;\n private bot: Bot | null = null;\n private running = false;\n\n init(gateway: GatewayServer, config: ClankConfig): void {\n this.gateway = gateway;\n this.config = config;\n }\n\n async start(): Promise<void> {\n const telegramConfig = this.config?.channels?.telegram;\n if (!telegramConfig?.enabled || !telegramConfig.botToken) {\n console.log(\" Telegram: disabled or no bot token configured\");\n return;\n }\n\n try {\n this.bot = new Bot(telegramConfig.botToken);\n const bot = this.bot as Bot;\n\n // Track startup time — messages older than this are stale\n const startupTime = Math.floor(Date.now() / 1000);\n // Per-chat processing queue — prevents parallel model calls from same chat\n const chatLocks = new Map<number, Promise<void>>();\n\n // Handle text messages\n bot.on(\"message:text\", async (ctx) => {\n const msg = ctx.message;\n const chatId = msg.chat.id;\n const userId = msg.from?.id;\n const isGroup = msg.chat.type === \"group\" || msg.chat.type === \"supergroup\";\n\n // Drop stale messages from before this startup (queued while offline)\n if (msg.date < startupTime - 30) {\n console.log(` Telegram: dropping stale message from ${userId} (${startupTime - msg.date}s old)`);\n return;\n }\n\n // Permission check — allowFrom can contain user IDs (numeric) or usernames (@name)\n if (telegramConfig.allowFrom && telegramConfig.allowFrom.length > 0) {\n const username = msg.from?.username ? `@${msg.from.username}` : \"\";\n const userIdStr = String(userId || \"\");\n const allowed = telegramConfig.allowFrom.map(String);\n const isAllowed = allowed.some((a) =>\n a === userIdStr ||\n a.toLowerCase() === username.toLowerCase() ||\n a.toLowerCase() === (msg.from?.username || \"\").toLowerCase()\n );\n if (!isAllowed) return;\n }\n\n // Mention check in groups\n if (isGroup) {\n const groupConfig = telegramConfig.groups?.[String(chatId)];\n if (groupConfig?.requireMention !== false) {\n const botInfo = await bot.api.getMe();\n if (!msg.text.includes(`@${botInfo.username}`)) return;\n }\n }\n\n // Handle slash commands (lightweight, no queueing needed)\n if (msg.text.startsWith(\"/\")) {\n const reply = await this.handleCommand(msg.text, chatId, isGroup);\n if (reply) {\n await ctx.api.sendMessage(chatId, reply, { parse_mode: \"Markdown\" });\n }\n return;\n }\n\n // Queue messages per chat — process one at a time to prevent\n // parallel model calls from flooding the local model\n const processMessage = async () => {\n if (!this.gateway) return;\n\n try {\n await ctx.api.sendChatAction(chatId, \"typing\");\n\n const response = await this.gateway.handleInboundMessage(\n {\n channel: \"telegram\",\n peerId: chatId,\n peerKind: isGroup ? \"group\" : \"dm\",\n },\n msg.text,\n );\n\n if (response) {\n const chunks = splitMessage(response, 4000);\n for (const chunk of chunks) {\n await ctx.api.sendMessage(chatId, chunk);\n }\n }\n } catch (err: unknown) {\n const errMsg = err instanceof Error ? err.message : String(err);\n await ctx.api.sendMessage(chatId, `Error: ${errMsg.slice(0, 200)}`);\n }\n };\n\n // Chain onto the existing queue for this chat\n const prev = chatLocks.get(chatId) || Promise.resolve();\n const next = prev.then(processMessage).catch(() => {});\n chatLocks.set(chatId, next);\n });\n\n // Handle voice messages — transcribe and route through agent\n bot.on(\"message:voice\", async (ctx) => {\n const msg = ctx.message;\n const chatId = msg.chat.id;\n const userId = msg.from?.id;\n\n // Same permission check\n if (telegramConfig.allowFrom && telegramConfig.allowFrom.length > 0) {\n const username = msg.from?.username ? `@${msg.from.username}` : \"\";\n const userIdStr = String(userId || \"\");\n const allowed = telegramConfig.allowFrom.map(String);\n const isAllowed = allowed.some((a) =>\n a === userIdStr ||\n a.toLowerCase() === username.toLowerCase() ||\n a.toLowerCase() === (msg.from?.username || \"\").toLowerCase()\n );\n if (!isAllowed) return;\n }\n\n if (msg.date < startupTime - 30) return; // Drop stale\n\n const processVoice = async () => {\n if (!this.gateway || !this.config) return;\n\n try {\n await ctx.api.sendChatAction(chatId, \"typing\");\n\n // Download the voice file\n const file = await ctx.api.getFile(msg.voice.file_id);\n const fileUrl = `https://api.telegram.org/file/bot${telegramConfig.botToken}/${file.file_path}`;\n const res = await fetch(fileUrl);\n if (!res.ok) { await ctx.api.sendMessage(chatId, \"Error: could not download voice message\"); return; }\n const audioBuffer = Buffer.from(await res.arrayBuffer());\n\n // Transcribe\n const { STTEngine } = await import(\"../voice/index.js\");\n const { loadConfig } = await import(\"../config/index.js\");\n const config = await loadConfig();\n const stt = new STTEngine(config);\n\n if (!stt.isAvailable()) {\n await ctx.api.sendMessage(chatId, \"Voice messages require speech-to-text. Set up Whisper: /help\");\n return;\n }\n\n const transcription = await stt.transcribe(audioBuffer, \"ogg\");\n if (!transcription?.text) {\n await ctx.api.sendMessage(chatId, \"Could not transcribe voice message.\");\n return;\n }\n\n // Send transcription through the agent\n const isGroup = msg.chat.type === \"group\" || msg.chat.type === \"supergroup\";\n const response = await this.gateway.handleInboundMessage(\n { channel: \"telegram\", peerId: chatId, peerKind: isGroup ? \"group\" : \"dm\" },\n `[Voice message transcription]: ${transcription.text}`,\n );\n\n if (response) {\n // Check if TTS is available — reply with voice if so\n const { TTSEngine } = await import(\"../voice/index.js\");\n const tts = new TTSEngine(config);\n\n if (tts.isAvailable() && response.length < 2000) {\n const audio = await tts.synthesize(response);\n if (audio) {\n const { InputFile } = await import(\"grammy\");\n await ctx.api.sendVoice(chatId, new InputFile(audio.audioBuffer, \"reply.mp3\"));\n return;\n }\n }\n\n // Fall back to text\n const chunks = splitMessage(response, 4000);\n for (const chunk of chunks) {\n await ctx.api.sendMessage(chatId, chunk);\n }\n }\n } catch (err: unknown) {\n const errMsg = err instanceof Error ? err.message : String(err);\n await ctx.api.sendMessage(chatId, `Error: ${errMsg.slice(0, 200)}`);\n }\n };\n\n const prev = chatLocks.get(chatId) || Promise.resolve();\n const next = prev.then(processVoice).catch(() => {});\n chatLocks.set(chatId, next);\n });\n\n // bot.start() is blocking (resolves when bot stops) — run it without await\n bot.start({\n onStart: () => {\n this.running = true;\n console.log(\" Telegram: polling started\");\n },\n }).catch((err: Error) => {\n console.error(` Telegram: polling error — ${err.message}`);\n this.running = false;\n });\n\n console.log(\" Telegram: connecting...\");\n } catch (err) {\n console.error(` Telegram: failed to start — ${err instanceof Error ? err.message : err}`);\n }\n }\n\n async stop(): Promise<void> {\n if (this.bot && this.running) {\n (this.bot as Bot).stop();\n this.running = false;\n }\n }\n\n /** Handle slash commands from Telegram */\n private async handleCommand(text: string, chatId: number, isGroup: boolean): Promise<string | null> {\n const [cmd, ...args] = text.slice(1).split(/\\s+/);\n const command = cmd.replace(/@\\w+$/, \"\"); // Strip @botname suffix\n\n switch (command) {\n case \"help\":\n case \"start\":\n return [\n \"*Clank Commands*\",\n \"\",\n \"/help — Show this help\",\n \"/status — Agent and model info\",\n \"/agents — List available agents\",\n \"/agent <name> — Switch to a different agent\",\n \"/sessions — List recent sessions\",\n \"/new — Start a new session\",\n \"/reset — Clear current session\",\n \"/model — Show current model\",\n \"/think — Toggle thinking display\",\n ].join(\"\\n\");\n\n case \"status\": {\n const cfg = this.config;\n const model = cfg?.agents?.defaults?.model?.primary || \"unknown\";\n const agents = cfg?.agents?.list?.length || 0;\n return [\n \"*Status*\",\n `Model: \\`${model}\\``,\n `Agents: ${agents} configured`,\n `Chat: ${isGroup ? \"group\" : \"DM\"} (${chatId})`,\n ].join(\"\\n\");\n }\n\n case \"agents\": {\n const list = this.config?.agents?.list || [];\n if (list.length === 0) return \"No custom agents configured. Using default agent.\";\n return \"*Agents:*\\n\" + list.map((a) =>\n `• *${a.name || a.id}* — \\`${a.model?.primary || \"default\"}\\``\n ).join(\"\\n\");\n }\n\n case \"agent\":\n if (args[0]) {\n return `Agent switching via Telegram coming soon. Use the config tool in chat: \"switch to agent ${args[0]}\"`;\n }\n return \"Usage: /agent <name>\";\n\n case \"sessions\": {\n if (!this.gateway) return \"Gateway not connected\";\n return \"Use /new to start a fresh session, or /reset to clear the current one.\";\n }\n\n case \"new\":\n return \"New session started. Send a message to begin.\";\n\n case \"reset\":\n return \"Session reset. History cleared.\";\n\n case \"model\": {\n const model = this.config?.agents?.defaults?.model?.primary || \"unknown\";\n return `Current model: \\`${model}\\``;\n }\n\n case \"think\":\n return \"Thinking display toggled. (Note: thinking visibility is per-client in the TUI/Web UI)\";\n\n default:\n return null; // Not a recognized command — let it pass through to the agent\n }\n }\n\n async send(sessionKey: string, payload: ReplyPayload): Promise<void> {\n // Extract chat ID from session key (dm:telegram:12345 → 12345)\n const parts = sessionKey.split(\":\");\n const chatId = parts[parts.length - 1];\n if (!chatId || !this.bot) return;\n\n if (payload.text) {\n const chunks = splitMessage(payload.text, 4000);\n for (const chunk of chunks) {\n await (this.bot as Bot).api.sendMessage(Number(chatId), chunk);\n }\n }\n }\n}\n\n/** Split a long message into chunks that fit Telegram's limit */\nfunction splitMessage(text: string, maxLen: number): string[] {\n if (text.length <= maxLen) return [text];\n const chunks: string[] = [];\n let remaining = text;\n while (remaining.length > 0) {\n if (remaining.length <= maxLen) {\n chunks.push(remaining);\n break;\n }\n // Try to split at a newline\n let splitAt = remaining.lastIndexOf(\"\\n\", maxLen);\n if (splitAt < maxLen * 0.5) splitAt = maxLen; // No good newline, split at limit\n chunks.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt);\n }\n return chunks;\n}\n","/**\n * Discord channel adapter.\n *\n * Built on discord.js. Supports:\n * - Server/channel/role-based routing\n * - Thread support for long conversations\n * - Button-based confirmations\n * - Streaming via message editing\n */\n\nimport { ChannelAdapter, type InboundMessage, type ReplyPayload } from \"./base.js\";\nimport type { GatewayServer } from \"../gateway/server.js\";\nimport type { ClankConfig } from \"../config/index.js\";\n\nexport class DiscordAdapter extends ChannelAdapter {\n readonly id = \"discord\";\n readonly name = \"Discord\";\n private gateway: GatewayServer | null = null;\n private config: ClankConfig | null = null;\n private client: unknown = null; // discord.js Client — loaded dynamically\n private running = false;\n\n init(gateway: GatewayServer, config: ClankConfig): void {\n this.gateway = gateway;\n this.config = config;\n }\n\n async start(): Promise<void> {\n const discordConfig = this.config?.channels?.discord;\n if (!discordConfig?.enabled || !discordConfig.botToken) {\n console.log(\" Discord: disabled or no bot token configured\");\n return;\n }\n\n try {\n const discord = await import(\"discord.js\" as string) as any;\n this.client = new discord.Client({\n intents: [\n discord.GatewayIntentBits.Guilds,\n discord.GatewayIntentBits.GuildMessages,\n discord.GatewayIntentBits.MessageContent,\n discord.GatewayIntentBits.DirectMessages,\n ],\n });\n\n const client = this.client as any;\n\n client.on(\"ready\", () => {\n console.log(` Discord: connected as ${client.user?.tag}`);\n this.running = true;\n });\n\n client.on(\"messageCreate\", async (message: any) => {\n if (message.author.bot) return;\n\n const isDM = !message.guild;\n\n // Route through gateway\n if (!this.gateway) return;\n\n try {\n await message.channel.sendTyping();\n\n const response = await this.gateway.handleInboundMessage(\n {\n channel: \"discord\",\n peerId: isDM ? message.author.id : message.channelId,\n peerKind: isDM ? \"dm\" : \"group\",\n guildId: message.guild?.id,\n },\n message.content,\n );\n\n if (response) {\n // Discord has 2000 char limit\n const chunks = splitDiscordMessage(response, 1900);\n for (const chunk of chunks) {\n await message.reply(chunk);\n }\n }\n } catch (err: unknown) {\n const errMsg = err instanceof Error ? err.message : String(err);\n await message.reply(`Error: ${errMsg.slice(0, 200)}`);\n }\n });\n\n await client.login(discordConfig.botToken);\n } catch (err) {\n console.error(` Discord: failed to start — ${err instanceof Error ? err.message : err}`);\n }\n }\n\n async stop(): Promise<void> {\n if (this.client && this.running) {\n (this.client as { destroy: () => void }).destroy();\n this.running = false;\n }\n }\n\n async send(sessionKey: string, payload: ReplyPayload): Promise<void> {\n if (!payload.text || !this.client) return;\n const client = this.client as any;\n\n // Extract channel ID from session key\n const parts = sessionKey.split(\":\");\n const channelId = parts[parts.length - 1];\n try {\n const channel = await client.channels.fetch(channelId);\n if (channel?.send) {\n const chunks = splitDiscordMessage(payload.text, 1900);\n for (const chunk of chunks) {\n await channel.send(chunk);\n }\n }\n } catch {\n // Channel not accessible\n }\n }\n}\n\nfunction splitDiscordMessage(text: string, maxLen: number): string[] {\n if (text.length <= maxLen) return [text];\n const chunks: string[] = [];\n let remaining = text;\n while (remaining.length > 0) {\n if (remaining.length <= maxLen) { chunks.push(remaining); break; }\n let splitAt = remaining.lastIndexOf(\"\\n\", maxLen);\n if (splitAt < maxLen * 0.5) splitAt = maxLen;\n chunks.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt);\n }\n return chunks;\n}\n","/**\n * Web UI channel adapter.\n *\n * The Web UI is served as a React/Preact SPA from the gateway at /chat.\n * It connects via WebSocket (same protocol as CLI). This adapter handles\n * the server-side of that connection.\n *\n * The actual SPA will be built in src/web/ — this adapter just serves\n * the static files and manages WebSocket connections for web clients.\n */\n\nimport { ChannelAdapter, type ReplyPayload } from \"./base.js\";\nimport type { GatewayServer } from \"../gateway/server.js\";\nimport type { ClankConfig } from \"../config/index.js\";\n\nexport class WebAdapter extends ChannelAdapter {\n readonly id = \"web\";\n readonly name = \"Web UI\";\n private gateway: GatewayServer | null = null;\n private config: ClankConfig | null = null;\n\n init(gateway: GatewayServer, config: ClankConfig): void {\n this.gateway = gateway;\n this.config = config;\n }\n\n async start(): Promise<void> {\n const webConfig = this.config?.channels?.web;\n if (!webConfig?.enabled) {\n console.log(\" Web UI: disabled\");\n return;\n }\n\n // Web UI clients connect via the same WebSocket as CLI clients.\n // The gateway server already handles WebSocket connections.\n // This adapter just registers itself for the /chat HTTP route.\n console.log(\" Web UI: enabled (served at /chat)\");\n }\n\n async stop(): Promise<void> {\n // Nothing to clean up — WebSocket connections managed by gateway\n }\n\n async send(_sessionKey: string, _payload: ReplyPayload): Promise<void> {\n // Web UI clients receive messages via WebSocket events,\n // handled by the gateway server's event bridging.\n // No separate send needed.\n }\n}\n","/**\n * Plugin loader — discovers and loads plugins at runtime.\n *\n * Discovery locations:\n * 1. ~/.clank/plugins/ — user-installed plugins\n * 2. node_modules/clank-plugin-* — npm-installed plugins\n *\n * Plugins are loaded in-process via dynamic import().\n * No sandboxing for v1 — trust boundary is the user's machine.\n */\n\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type {\n PluginManifest,\n LoadedPlugin,\n HookType,\n HookHandler,\n} from \"./types.js\";\nimport type { Tool } from \"../tools/types.js\";\n\nexport class PluginLoader {\n private plugins: LoadedPlugin[] = [];\n private hookRegistry = new Map<HookType, HookHandler[]>();\n\n /** Discover and load all plugins */\n async loadAll(): Promise<LoadedPlugin[]> {\n const pluginDirs = await this.discoverPlugins();\n\n for (const dir of pluginDirs) {\n try {\n const plugin = await this.loadPlugin(dir);\n if (plugin) {\n this.plugins.push(plugin);\n // Register hooks\n for (const [hookType, handlers] of plugin.hooks) {\n const existing = this.hookRegistry.get(hookType) || [];\n existing.push(...handlers);\n this.hookRegistry.set(hookType, existing);\n }\n }\n } catch (err) {\n console.error(` Plugin error in ${dir}: ${err instanceof Error ? err.message : err}`);\n }\n }\n\n return this.plugins;\n }\n\n /** Discover plugin directories */\n private async discoverPlugins(): Promise<string[]> {\n const dirs: string[] = [];\n\n // 1. User plugins directory\n const userPluginDir = join(homedir(), \".clank\", \"plugins\");\n if (existsSync(userPluginDir)) {\n try {\n const entries = await readdir(userPluginDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n dirs.push(join(userPluginDir, entry.name));\n }\n }\n } catch {\n // Skip if can't read\n }\n }\n\n // 2. npm clank-plugin-* packages\n const nodeModulesDir = join(process.cwd(), \"node_modules\");\n if (existsSync(nodeModulesDir)) {\n try {\n const entries = await readdir(nodeModulesDir);\n for (const entry of entries) {\n if (entry.startsWith(\"clank-plugin-\")) {\n dirs.push(join(nodeModulesDir, entry));\n }\n }\n } catch {\n // Skip\n }\n }\n\n return dirs;\n }\n\n /** Load a single plugin from a directory */\n private async loadPlugin(dir: string): Promise<LoadedPlugin | null> {\n const manifestPath = join(dir, \"clank-plugin.json\");\n if (!existsSync(manifestPath)) return null;\n\n const raw = await readFile(manifestPath, \"utf-8\");\n const manifest = JSON.parse(raw) as PluginManifest;\n\n if (!manifest.name) return null;\n\n const plugin: LoadedPlugin = {\n manifest,\n path: dir,\n tools: [],\n hooks: new Map(),\n };\n\n // Load tools\n if (manifest.tools) {\n for (const toolEntry of manifest.tools) {\n try {\n const entrypoint = join(dir, toolEntry.entrypoint);\n const mod = await import(entrypoint);\n const tool = mod.default || mod.tool;\n if (tool) {\n plugin.tools.push(tool as Tool);\n }\n } catch (err) {\n console.error(` Failed to load tool ${toolEntry.name}: ${err instanceof Error ? err.message : err}`);\n }\n }\n }\n\n // Load hooks\n if (manifest.hooks) {\n for (const hookEntry of manifest.hooks) {\n try {\n const handlerPath = join(dir, hookEntry.handler);\n const mod = await import(handlerPath);\n const handler = mod.default || mod.handler;\n if (handler) {\n const existing = plugin.hooks.get(hookEntry.type) || [];\n existing.push(handler as HookHandler);\n plugin.hooks.set(hookEntry.type, existing);\n }\n } catch (err) {\n console.error(` Failed to load hook ${hookEntry.type}: ${err instanceof Error ? err.message : err}`);\n }\n }\n }\n\n return plugin;\n }\n\n /** Get all loaded plugins */\n getPlugins(): LoadedPlugin[] {\n return [...this.plugins];\n }\n\n /** Get all tools from loaded plugins */\n getTools(): Tool[] {\n return this.plugins.flatMap((p) => p.tools);\n }\n\n /** Execute hooks of a given type */\n async executeHooks(hookType: HookType, context: Record<string, unknown> = {}): Promise<void> {\n const handlers = this.hookRegistry.get(hookType) || [];\n const hookCtx = { hookType, ...context, prevented: false };\n\n for (const handler of handlers) {\n if (hookCtx.prevented) break;\n await handler(hookCtx);\n }\n }\n\n /** Check if any hook has prevented the default action */\n async executeHooksWithResult(hookType: HookType, context: Record<string, unknown> = {}): Promise<boolean> {\n const hookCtx = { hookType, ...context, prevented: false };\n const handlers = this.hookRegistry.get(hookType) || [];\n\n for (const handler of handlers) {\n await handler(hookCtx);\n if (hookCtx.prevented) return true;\n }\n return false;\n }\n}\n","export { PluginLoader } from \"./loader.js\";\nexport type {\n PluginManifest,\n PluginToolEntry,\n PluginHookEntry,\n HookType,\n HookHandler,\n HookContext,\n LoadedPlugin,\n} from \"./types.js\";\n","/**\n * Gateway server — the central daemon.\n *\n * This is what makes Clank a platform instead of a CLI tool.\n * The gateway is an HTTP + WebSocket server that:\n * - Accepts client connections (CLI, Web, Telegram, Discord)\n * - Routes messages to agent instances\n * - Streams responses back via events\n * - Serves the Web UI static files\n * - Provides a health endpoint\n */\n\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { WebSocketServer, WebSocket } from \"ws\";\nimport { readFile } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { AgentEngine, type AgentIdentity, buildSystemPrompt } from \"../engine/index.js\";\nimport { createFullRegistry, type ToolRegistry } from \"../tools/index.js\";\nimport { createProvider, resolveWithFallback, type ProviderConfig } from \"../providers/index.js\";\nimport { SessionStore } from \"../sessions/index.js\";\nimport { MemoryManager } from \"../memory/index.js\";\nimport { type ClankConfig, getConfigDir, ConfigWatcher } from \"../config/index.js\";\nimport { CronScheduler } from \"../cron/index.js\";\nimport { resolveRoute, deriveSessionKey, type RouteContext } from \"../routing/index.js\";\nimport { type ChannelAdapter } from \"../adapters/base.js\";\nimport { TelegramAdapter } from \"../adapters/telegram.js\";\nimport { DiscordAdapter } from \"../adapters/discord.js\";\nimport { WebAdapter } from \"../adapters/web.js\";\nimport { PluginLoader } from \"../plugins/index.js\";\nimport {\n type Frame,\n type RequestFrame,\n type ResponseFrame,\n type EventFrame,\n type ConnectParams,\n type HelloFrame,\n parseFrame,\n serializeFrame,\n PROTOCOL_VERSION,\n DEFAULT_PORT,\n} from \"./protocol.js\";\n\ninterface ClientConnection {\n ws: WebSocket;\n clientName: string;\n sessionKey: string;\n agentId: string;\n authenticated: boolean;\n eventSeq: number;\n}\n\nexport class GatewayServer {\n private config: ClankConfig;\n private httpServer: ReturnType<typeof createServer> | null = null;\n private wss: WebSocketServer | null = null;\n private clients = new Map<WebSocket, ClientConnection>();\n private engines = new Map<string, AgentEngine>();\n private sessionStore: SessionStore;\n private toolRegistry: ToolRegistry;\n private memoryManager: MemoryManager;\n private cronScheduler: CronScheduler;\n private configWatcher: ConfigWatcher;\n private pluginLoader: PluginLoader;\n private adapters: ChannelAdapter[] = [];\n private running = false;\n\n constructor(config: ClankConfig) {\n this.config = config;\n this.sessionStore = new SessionStore(join(getConfigDir(), \"conversations\"));\n this.toolRegistry = createFullRegistry();\n this.memoryManager = new MemoryManager(join(getConfigDir(), \"memory\"));\n this.cronScheduler = new CronScheduler(join(getConfigDir(), \"cron\"));\n this.configWatcher = new ConfigWatcher();\n this.pluginLoader = new PluginLoader();\n }\n\n /** Start the gateway server */\n async start(): Promise<void> {\n // Ensure auth token exists — generate one if missing\n if (this.config.gateway.auth.mode === \"token\" && !this.config.gateway.auth.token) {\n const { randomBytes } = await import(\"node:crypto\");\n this.config.gateway.auth.token = randomBytes(16).toString(\"hex\");\n console.log(` Generated auth token: ${this.config.gateway.auth.token.slice(0, 8)}...`);\n }\n\n // Initialize subsystems\n await this.sessionStore.init();\n await this.memoryManager.init();\n await this.cronScheduler.init();\n\n // Load plugins and register their tools\n const plugins = await this.pluginLoader.loadAll();\n for (const tool of this.pluginLoader.getTools()) {\n this.toolRegistry.register(tool);\n }\n if (plugins.length > 0) {\n console.log(` Loaded ${plugins.length} plugin(s), ${this.pluginLoader.getTools().length} tool(s)`);\n }\n\n // Start config watcher for hot-reload\n await this.configWatcher.start();\n this.configWatcher.on(\"change\", ({ newConfig }: { newConfig: ClankConfig }) => {\n this.config = newConfig;\n console.log(\" Config reloaded\");\n });\n\n // Start cron scheduler\n this.cronScheduler.setHandler(async (job) => {\n console.log(` Cron: running job \"${job.name}\"`);\n const engine = await this.getOrCreateEngine(`cron:${job.id}`, job.agentId, \"cron\");\n await engine.sendMessage(job.prompt);\n });\n this.cronScheduler.start();\n\n // Start channel adapters\n await this.startAdapters();\n\n const port = this.config.gateway.port || DEFAULT_PORT;\n const bind = this.config.gateway.bind === \"loopback\" ? \"127.0.0.1\" : \"0.0.0.0\";\n\n // Create HTTP server for health checks and static files\n this.httpServer = createServer((req, res) => this.handleHttp(req, res));\n\n // Create WebSocket server\n this.wss = new WebSocketServer({ server: this.httpServer });\n this.wss.on(\"connection\", (ws) => this.handleConnection(ws));\n\n return new Promise((resolve, reject) => {\n this.httpServer!.listen(port, bind, () => {\n this.running = true;\n console.log(`Clank Gateway running on ${bind}:${port}`);\n resolve();\n });\n this.httpServer!.on(\"error\", reject);\n });\n }\n\n /** Start all configured channel adapters */\n private async startAdapters(): Promise<void> {\n console.log(\" Starting channel adapters...\");\n\n const adapterClasses: ChannelAdapter[] = [\n new TelegramAdapter(),\n new DiscordAdapter(),\n new WebAdapter(),\n ];\n\n for (const adapter of adapterClasses) {\n adapter.init(this, this.config);\n try {\n await adapter.start();\n this.adapters.push(adapter);\n } catch (err) {\n console.error(` ${adapter.name}: failed — ${err instanceof Error ? err.message : err}`);\n }\n }\n }\n\n /**\n * Handle an inbound message from any channel adapter.\n * This is the main entry point for all non-WebSocket messages.\n */\n async handleInboundMessage(context: RouteContext, text: string): Promise<string> {\n // Resolve which agent handles this message\n const agentId = resolveRoute(\n context,\n [], // TODO: load bindings from config\n this.config.agents.list.map((a) => ({ id: a.id, name: a.name })),\n this.config.agents.list[0]?.id || \"default\",\n );\n\n const sessionKey = deriveSessionKey(context);\n const engine = await this.getOrCreateEngine(sessionKey, agentId, context.channel);\n return engine.sendMessage(text);\n }\n\n /** Stop the gateway server */\n async stop(): Promise<void> {\n this.running = false;\n\n // Stop subsystems\n this.cronScheduler.stop();\n this.configWatcher.stop();\n\n // Stop channel adapters\n for (const adapter of this.adapters) {\n try { await adapter.stop(); } catch { /* best effort */ }\n }\n this.adapters = [];\n\n // Destroy all engines\n for (const engine of this.engines.values()) {\n engine.destroy();\n }\n this.engines.clear();\n\n // Close all client connections\n for (const [ws] of this.clients) {\n ws.close(1001, \"Gateway shutting down\");\n }\n this.clients.clear();\n\n // Close servers\n return new Promise((resolve) => {\n this.wss?.close(() => {\n this.httpServer?.close(() => resolve());\n });\n });\n }\n\n /** Handle HTTP requests (health, static files) */\n private async handleHttp(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = req.url || \"/\";\n\n if (url === \"/health\" || url === \"/healthz\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n status: \"ok\",\n version: \"1.3.0\",\n uptime: process.uptime(),\n clients: this.clients.size,\n agents: this.engines.size,\n }));\n return;\n }\n\n if (url === \"/status\") {\n // Require token for status endpoint (contains session info)\n const authHeader = req.headers.authorization;\n const expectedToken = this.config.gateway.auth.token;\n if (expectedToken && authHeader !== `Bearer ${expectedToken}`) {\n res.writeHead(401, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Unauthorized\" }));\n return;\n }\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n gateway: { port: this.config.gateway.port, bind: this.config.gateway.bind },\n clients: Array.from(this.clients.values()).map((c) => ({\n clientName: c.clientName,\n sessionKey: c.sessionKey,\n agentId: c.agentId,\n })),\n sessions: this.sessionStore.list().slice(0, 20),\n }));\n return;\n }\n\n // Serve Web UI at /chat\n if (url === \"/chat\" || url === \"/\") {\n try {\n // Try to find index.html relative to this file's location\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const htmlPath = join(__dirname, \"..\", \"web\", \"index.html\");\n const html = await readFile(htmlPath, \"utf-8\");\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(html);\n return;\n } catch {\n // Fallback: try from src directory (dev mode)\n try {\n const html = await readFile(join(process.cwd(), \"src\", \"web\", \"index.html\"), \"utf-8\");\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(html);\n return;\n } catch {\n // Fall through to 404\n }\n }\n }\n\n res.writeHead(404);\n res.end(\"Not found\");\n }\n\n /** Handle a new WebSocket connection */\n private handleConnection(ws: WebSocket): void {\n const client: ClientConnection = {\n ws,\n clientName: \"unknown\",\n sessionKey: \"\",\n agentId: \"default\",\n authenticated: false,\n eventSeq: 0,\n };\n this.clients.set(ws, client);\n\n ws.on(\"message\", (data) => {\n const frame = parseFrame(data.toString());\n if (frame) this.handleFrame(client, frame);\n });\n\n ws.on(\"close\", () => {\n this.clients.delete(ws);\n });\n\n ws.on(\"error\", () => {\n this.clients.delete(ws);\n });\n }\n\n /** Handle an incoming frame from a client */\n private async handleFrame(client: ClientConnection, frame: Frame): Promise<void> {\n // Handle connect/handshake\n if (frame.type === \"connect\" || (frame.type === \"req\" && (frame as RequestFrame).method === \"connect\")) {\n await this.handleConnect(client, frame as ConnectParams | RequestFrame);\n return;\n }\n\n // All other frames require authentication\n if (!client.authenticated) {\n this.sendResponse(client, (frame as RequestFrame).id, false, undefined, \"Not authenticated\");\n return;\n }\n\n if (frame.type === \"req\") {\n await this.handleRequest(client, frame);\n }\n }\n\n /** Handle client connection/auth */\n private async handleConnect(client: ClientConnection, frame: ConnectParams | RequestFrame): Promise<void> {\n const params = frame.type === \"connect\"\n ? (frame as ConnectParams).params\n : (frame as RequestFrame).params as ConnectParams[\"params\"];\n const reqId = frame.type === \"req\" ? (frame as RequestFrame).id : 0;\n\n // Auth check\n const expectedToken = this.config.gateway.auth.token;\n const providedToken = params?.auth?.token;\n if (expectedToken && this.config.gateway.auth.mode !== \"none\" && providedToken !== expectedToken) {\n client.ws.send(serializeFrame({\n type: \"res\", id: reqId, ok: false, error: \"Invalid token\",\n } as ResponseFrame));\n return;\n }\n\n client.clientName = params?.mode || \"unknown\";\n client.authenticated = true;\n\n // Resolve default agent and session\n const agentId = this.config.agents.list[0]?.id || \"default\";\n const sessionKey = `${client.clientName}:main`;\n client.agentId = agentId;\n client.sessionKey = sessionKey;\n\n // Send hello with available agents and recent sessions\n const hello: HelloFrame = {\n type: \"hello\",\n protocol: PROTOCOL_VERSION,\n version: \"1.3.0\",\n agents: this.config.agents.list.map((a) => ({\n id: a.id,\n name: a.name || a.id,\n model: a.model?.primary || this.config.agents.defaults.model.primary,\n status: \"online\",\n })),\n sessions: this.sessionStore.list().slice(0, 50).map((s) => ({\n key: s.normalizedKey,\n label: s.label,\n agentId: s.agentId || \"default\",\n updatedAt: s.updatedAt,\n })),\n };\n client.ws.send(serializeFrame(hello));\n if (reqId) this.sendResponse(client, reqId, true, { agentId, sessionKey });\n }\n\n /** Handle a request frame */\n private async handleRequest(client: ClientConnection, frame: RequestFrame): Promise<void> {\n try {\n switch (frame.method) {\n // === Chat ===\n case \"chat.send\":\n case \"sendMessage\":\n await this.handleSendMessage(client, frame);\n break;\n\n case \"chat.abort\":\n case \"cancel\":\n this.handleCancel(client);\n this.sendResponse(client, frame.id, true);\n break;\n\n case \"chat.history\": {\n const historyKey = (frame.params?.sessionKey as string) || client.sessionKey;\n const entry = this.sessionStore.list().find((s) => s.normalizedKey === historyKey);\n const messages = entry ? await this.sessionStore.loadMessages(entry.id) : [];\n const limit = Number(frame.params?.limit) || 200;\n this.sendResponse(client, frame.id, true, messages.slice(-limit));\n break;\n }\n\n // === Sessions ===\n case \"session.list\":\n this.sendResponse(client, frame.id, true, this.sessionStore.list());\n break;\n\n case \"session.delete\": {\n const delKey = (frame.params?.sessionKey as string) || client.sessionKey;\n await this.sessionStore.delete(delKey);\n this.sendResponse(client, frame.id, true);\n break;\n }\n\n case \"session.reset\": {\n const resetKey = (frame.params?.sessionKey as string) || client.sessionKey;\n await this.sessionStore.reset(resetKey);\n const eng = this.engines.get(resetKey);\n if (eng) eng.getContextEngine().clear();\n this.sendResponse(client, frame.id, true);\n break;\n }\n\n // === Agents ===\n case \"agent.list\":\n this.sendResponse(client, frame.id, true, this.config.agents.list.map((a) => ({\n id: a.id,\n name: a.name || a.id,\n model: a.model?.primary || this.config.agents.defaults.model.primary,\n status: \"online\",\n })));\n break;\n\n case \"agent.status\": {\n const aid = frame.params?.agentId as string;\n const agentCfg = this.config.agents.list.find((a) => a.id === aid);\n this.sendResponse(client, frame.id, true, agentCfg ? {\n id: agentCfg.id,\n name: agentCfg.name,\n model: agentCfg.model?.primary || this.config.agents.defaults.model.primary,\n status: \"online\",\n } : null);\n break;\n }\n\n // === Config ===\n case \"config.get\": {\n const { redactConfig } = await import(\"../config/redact.js\");\n const section = frame.params?.section as string;\n if (section) {\n const val = (this.config as unknown as Record<string, unknown>)[section];\n this.sendResponse(client, frame.id, true, redactConfig(val));\n } else {\n this.sendResponse(client, frame.id, true, redactConfig(this.config));\n }\n break;\n }\n\n case \"config.set\": {\n const { loadConfig, saveConfig } = await import(\"../config/index.js\");\n const cfg = await loadConfig();\n const key = frame.params?.key as string;\n const value = frame.params?.value;\n\n // Protect against prototype pollution\n const BLOCKED_KEYS = [\"__proto__\", \"constructor\", \"prototype\"];\n if (key && value !== undefined) {\n const keys = key.split(\".\");\n if (keys.some((k) => BLOCKED_KEYS.includes(k))) {\n this.sendResponse(client, frame.id, false, undefined, \"Blocked: unsafe key\");\n break;\n }\n let target: Record<string, unknown> = cfg as unknown as Record<string, unknown>;\n for (let i = 0; i < keys.length - 1; i++) {\n if (!target[keys[i]] || typeof target[keys[i]] !== \"object\") target[keys[i]] = {};\n target = target[keys[i]] as Record<string, unknown>;\n }\n target[keys[keys.length - 1]] = value;\n await saveConfig(cfg);\n this.config = cfg;\n }\n this.sendResponse(client, frame.id, true);\n break;\n }\n\n // === Pipelines ===\n case \"pipeline.list\":\n this.sendResponse(client, frame.id, true, []); // TODO: wire pipeline runner\n break;\n\n case \"pipeline.run\":\n this.sendResponse(client, frame.id, false, undefined, \"Pipeline execution via UI coming soon\");\n break;\n\n case \"pipeline.status\":\n case \"pipeline.abort\":\n this.sendResponse(client, frame.id, true, null);\n break;\n\n // === Cron ===\n case \"cron.list\":\n this.sendResponse(client, frame.id, true, this.cronScheduler.listJobs());\n break;\n\n case \"cron.create\": {\n const job = await this.cronScheduler.addJob({\n name: (frame.params?.name as string) || \"Unnamed\",\n schedule: (frame.params?.schedule as string) || \"1h\",\n agentId: (frame.params?.agentId as string) || \"default\",\n prompt: (frame.params?.prompt as string) || \"\",\n });\n this.sendResponse(client, frame.id, true, job);\n break;\n }\n\n case \"cron.delete\":\n await this.cronScheduler.removeJob(frame.params?.jobId as string);\n this.sendResponse(client, frame.id, true);\n break;\n\n case \"cron.trigger\": {\n const triggerJob = this.cronScheduler.listJobs().find((j) => j.id === frame.params?.jobId);\n if (triggerJob) {\n const cronEngine = await this.getOrCreateEngine(`cron:${triggerJob.id}`, triggerJob.agentId, \"cron\");\n cronEngine.sendMessage(triggerJob.prompt); // Fire and forget\n this.sendResponse(client, frame.id, true);\n } else {\n this.sendResponse(client, frame.id, false, undefined, \"Job not found\");\n }\n break;\n }\n\n // === Logs ===\n case \"log.tail\":\n // TODO: implement log streaming\n this.sendResponse(client, frame.id, true, { subscribed: true });\n break;\n\n case \"log.query\":\n this.sendResponse(client, frame.id, true, []);\n break;\n\n default:\n this.sendResponse(client, frame.id, false, undefined, `Unknown method: ${frame.method}`);\n }\n } catch (err) {\n this.sendResponse(client, frame.id, false, undefined, err instanceof Error ? err.message : String(err));\n }\n }\n\n /** Handle sendMessage — route to agent engine */\n private async handleSendMessage(client: ClientConnection, frame: RequestFrame): Promise<void> {\n const text = (frame.params?.message || frame.params?.text) as string;\n if (!text) {\n this.sendResponse(client, frame.id, false, undefined, \"message is required\");\n return;\n }\n\n try {\n const engine = await this.getOrCreateEngine(client.sessionKey, client.agentId, client.clientName);\n\n // Wire engine events to client WebSocket\n const cleanup = this.wireEngineEvents(engine, client);\n\n try {\n const response = await engine.sendMessage(text);\n this.sendResponse(client, frame.id, true, { text: response });\n } finally {\n cleanup();\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.sendResponse(client, frame.id, false, undefined, msg);\n }\n }\n\n /** Cancel current request for a client */\n private handleCancel(client: ClientConnection): void {\n const engine = this.engines.get(client.sessionKey);\n if (engine) engine.cancel();\n }\n\n /** Get or create an agent engine for a session */\n private async getOrCreateEngine(sessionKey: string, agentId: string, channel: string): Promise<AgentEngine> {\n let engine = this.engines.get(sessionKey);\n if (engine) return engine;\n\n // Find agent config or use defaults\n const agentConfig = this.config.agents.list.find((a) => a.id === agentId);\n const modelConfig = agentConfig?.model || this.config.agents.defaults.model;\n\n // Resolve provider with fallback chain\n const resolved = await resolveWithFallback(\n modelConfig.primary,\n modelConfig.fallbacks || [],\n this.config.models.providers,\n { maxResponseTokens: this.config.agents.defaults.maxResponseTokens },\n );\n\n const identity: AgentIdentity = {\n id: agentId,\n name: agentConfig?.name || \"Clank\",\n model: modelConfig,\n workspace: agentConfig?.workspace || this.config.agents.defaults.workspace || process.cwd(),\n toolTier: agentConfig?.toolTier || this.config.agents.defaults.toolTier || \"auto\",\n tools: agentConfig?.tools,\n };\n\n // Build system prompt from workspace files + memory\n const systemPrompt = await buildSystemPrompt({\n identity,\n workspaceDir: identity.workspace,\n channel,\n });\n\n // Inject memory context into system prompt\n const memoryBlock = await this.memoryManager.buildMemoryBlock(\"\", identity.workspace);\n const fullPrompt = memoryBlock\n ? systemPrompt + \"\\n\\n---\\n\\n\" + memoryBlock\n : systemPrompt;\n\n engine = new AgentEngine({\n identity,\n toolRegistry: this.toolRegistry,\n sessionStore: this.sessionStore,\n provider: resolved,\n autoApprove: this.config.tools.autoApprove,\n systemPrompt: fullPrompt,\n });\n\n await engine.loadSession(sessionKey, channel);\n this.engines.set(sessionKey, engine);\n\n // Execute plugin hooks\n await this.pluginLoader.executeHooks(\"before_agent_start\", { agentId, sessionKey });\n\n return engine;\n }\n\n /**\n * Wire engine events to a client's WebSocket.\n * Returns a cleanup function to remove listeners.\n */\n private wireEngineEvents(engine: AgentEngine, client: ClientConnection): () => void {\n const eventMap: Record<string, string> = {\n \"token\": \"token\",\n \"response-start\": \"response-start\",\n \"response-end\": \"response-end\",\n \"tool-start\": \"tool-start\",\n \"tool-result\": \"tool-result\",\n \"context-compacting\": \"context-compacting\",\n \"usage\": \"usage\",\n \"error\": \"error\",\n \"turn-complete\": \"turn-complete\",\n };\n\n const listeners: Array<[string, (...args: unknown[]) => void]> = [];\n\n for (const [engineEvent, wireEvent] of Object.entries(eventMap)) {\n const listener = (payload: unknown) => {\n this.sendEvent(client, wireEvent, payload);\n };\n engine.on(engineEvent, listener);\n listeners.push([engineEvent, listener]);\n }\n\n // Confirmation events — respect the config autoApprove settings.\n // For channels (Telegram/Discord), use the config. For WebSocket\n // clients (TUI/Web), relay to the client for interactive approval.\n const confirmListener = (data: unknown) => {\n const { actions, resolve } = data as { actions: unknown[]; resolve: (v: boolean | \"always\") => void };\n const action = (actions as Array<{ safetyLevel: string }>)[0];\n const level = (action?.safetyLevel || \"high\") as \"low\" | \"medium\" | \"high\";\n\n // Check autoApprove config\n if (this.config.tools.autoApprove[level]) {\n resolve(true);\n return;\n }\n\n // For WebSocket clients, relay the confirmation request\n const confirmId = `confirm_${Date.now()}`;\n this.sendEvent(client, \"confirm-needed\", { id: confirmId, actions });\n\n // Default deny after 30s timeout for safety\n const timeout = setTimeout(() => resolve(false), 30_000);\n\n // Listen for resolve from client (one-shot)\n const resolveHandler = (raw: Buffer | string) => {\n const frame = parseFrame(raw.toString());\n if (frame?.type === \"req\" && (frame as RequestFrame).method === \"confirm.resolve\") {\n const params = (frame as RequestFrame).params as { id?: string; approved?: boolean | \"always\" };\n if (params?.id === confirmId) {\n clearTimeout(timeout);\n client.ws.removeListener(\"message\", resolveHandler);\n resolve(params.approved ?? false);\n }\n }\n };\n client.ws.on(\"message\", resolveHandler);\n };\n engine.on(\"confirm-needed\", confirmListener);\n listeners.push([\"confirm-needed\", confirmListener]);\n\n return () => {\n for (const [event, listener] of listeners) {\n engine.removeListener(event, listener);\n }\n };\n }\n\n /** Send a response frame to a client */\n private sendResponse(client: ClientConnection, id: number | string, ok: boolean, result?: unknown, error?: string): void {\n const frame: ResponseFrame = { type: \"res\", id, ok, result, error };\n if (client.ws.readyState === WebSocket.OPEN) {\n client.ws.send(serializeFrame(frame));\n }\n }\n\n /** Send an event frame to a client */\n private sendEvent(client: ClientConnection, event: string, payload: unknown): void {\n const frame: EventFrame = { type: \"event\", event, payload, seq: ++client.eventSeq };\n if (client.ws.readyState === WebSocket.OPEN) {\n client.ws.send(serializeFrame(frame));\n }\n }\n\n get isRunning(): boolean {\n return this.running;\n }\n}\n","export { GatewayServer } from \"./server.js\";\nexport {\n type Frame,\n type ConnectParams,\n type HelloFrame,\n type RequestFrame,\n type ResponseFrame,\n type EventFrame,\n parseFrame,\n serializeFrame,\n PROTOCOL_VERSION,\n DEFAULT_PORT,\n METHODS,\n EVENTS,\n} from \"./protocol.js\";\n","/**\n * Gateway CLI commands — start/stop/status/restart.\n *\n * The gateway runs as a background process. Telegram/Discord stay\n * alive in the background while you use CLI/TUI/Web on top.\n */\n\nimport { GatewayServer } from \"../gateway/index.js\";\nimport { loadConfig, ensureConfigDir, getConfigDir } from \"../config/index.js\";\nimport { DEFAULT_PORT } from \"../gateway/protocol.js\";\nimport { fork, exec } from \"node:child_process\";\nimport { writeFile, readFile, unlink } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __filename = fileURLToPath(import.meta.url);\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\n\n/** Check if gateway is already running */\nexport async function isGatewayRunning(port?: number): Promise<boolean> {\n const config = await loadConfig();\n const p = port || config.gateway.port || DEFAULT_PORT;\n try {\n const res = await fetch(`http://127.0.0.1:${p}/health`, { signal: AbortSignal.timeout(2000) });\n return res.ok;\n } catch {\n return false;\n }\n}\n\n/** Get the PID file path */\nfunction pidFilePath(): string {\n return join(getConfigDir(), \"gateway.pid\");\n}\n\n/**\n * Start the gateway in the foreground (blocking).\n * Used by `clank gateway start --foreground` and the background process.\n */\nexport async function gatewayStartForeground(opts: { port?: string }): Promise<void> {\n await ensureConfigDir();\n const config = await loadConfig();\n\n if (opts.port) {\n config.gateway.port = parseInt(opts.port, 10);\n }\n\n // Singleton check — only one gateway at a time\n if (await isGatewayRunning(config.gateway.port)) {\n console.log(green(` Gateway already running on port ${config.gateway.port}`));\n return;\n }\n\n // Write PID file\n await writeFile(pidFilePath(), String(process.pid), \"utf-8\");\n\n const server = new GatewayServer(config);\n\n const shutdown = async () => {\n console.log(dim(\"\\nShutting down...\"));\n try { await unlink(pidFilePath()); } catch {}\n await server.stop();\n process.exit(0);\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n try {\n await server.start();\n console.log(green(`Gateway started on port ${config.gateway.port}`));\n console.log(dim(\"Press Ctrl+C to stop\"));\n } catch (err) {\n try { await unlink(pidFilePath()); } catch {}\n console.error(red(`Failed to start gateway: ${err instanceof Error ? err.message : err}`));\n process.exit(1);\n }\n}\n\n/**\n * Start the gateway as a background process (non-blocking).\n * Returns once the gateway is confirmed running.\n */\nexport async function gatewayStartBackground(): Promise<boolean> {\n const config = await loadConfig();\n const port = config.gateway.port || DEFAULT_PORT;\n\n // Already running?\n if (await isGatewayRunning(port)) {\n return true;\n }\n\n console.log(dim(\" Starting gateway in background...\"));\n\n // Fork a detached child process running `clank gateway start --foreground`\n const entryPoint = join(dirname(__filename), \"index.js\");\n const logFile = join(getConfigDir(), \"logs\", \"gateway.log\");\n\n // Ensure logs dir exists\n const { mkdir } = await import(\"node:fs/promises\");\n await mkdir(join(getConfigDir(), \"logs\"), { recursive: true });\n\n const child = fork(entryPoint, [\"gateway\", \"start\", \"--foreground\"], {\n detached: true,\n stdio: [\"ignore\", \"ignore\", \"ignore\", \"ipc\"],\n });\n child.unref();\n child.disconnect();\n\n // Wait for gateway to be ready (up to 10 seconds)\n for (let i = 0; i < 20; i++) {\n await new Promise((r) => setTimeout(r, 500));\n if (await isGatewayRunning(port)) {\n console.log(green(` Gateway running on port ${port}`));\n return true;\n }\n }\n\n console.log(red(\" Gateway failed to start\"));\n return false;\n}\n\n/** Public entry: start gateway (background by default, foreground with --foreground) */\nexport async function gatewayStart(opts: { port?: string; foreground?: boolean }): Promise<void> {\n if (opts.foreground) {\n await gatewayStartForeground(opts);\n } else {\n const running = await gatewayStartBackground();\n if (!running) {\n process.exit(1);\n }\n }\n}\n\nexport async function gatewayStop(): Promise<void> {\n // Try to kill via PID file\n const pidPath = pidFilePath();\n if (existsSync(pidPath)) {\n try {\n const pid = parseInt(await readFile(pidPath, \"utf-8\"), 10);\n process.kill(pid, \"SIGTERM\");\n await unlink(pidPath);\n console.log(green(\"Gateway stopped\"));\n return;\n } catch {\n // PID might be stale\n try { await unlink(pidPath); } catch {}\n }\n }\n\n // Check if it's running anyway\n if (await isGatewayRunning()) {\n console.log(dim(\"Gateway is running but no PID file found.\"));\n console.log(dim(\"Kill it manually or restart the process.\"));\n } else {\n console.log(dim(\"Gateway is not running.\"));\n }\n}\n\nexport async function gatewayStatus(): Promise<void> {\n const config = await loadConfig();\n const port = config.gateway.port || DEFAULT_PORT;\n\n try {\n const res = await fetch(`http://127.0.0.1:${port}/status`, { signal: AbortSignal.timeout(3000) });\n if (res.ok) {\n const data = await res.json() as Record<string, unknown>;\n console.log(green(\"Gateway is running\"));\n console.log(dim(` Port: ${port}`));\n console.log(dim(` Clients: ${(data.clients as unknown[])?.length || 0}`));\n console.log(dim(` Sessions: ${(data.sessions as unknown[])?.length || 0}`));\n\n // Show PID\n const pidPath = pidFilePath();\n if (existsSync(pidPath)) {\n const pid = await readFile(pidPath, \"utf-8\");\n console.log(dim(` PID: ${pid.trim()}`));\n }\n } else {\n console.log(red(\"Gateway returned error\"));\n }\n } catch {\n console.log(red(\"Gateway is not running\"));\n console.log(dim(` Expected at http://127.0.0.1:${port}`));\n console.log(dim(\" Start with: clank gateway start\"));\n }\n}\n","/**\n * Daemon installer — installs Clank as a system service.\n *\n * Cross-platform:\n * - macOS: LaunchAgent plist\n * - Windows: Task Scheduler\n * - Linux: systemd --user unit\n */\n\nimport { writeFile, mkdir, unlink } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir, platform } from \"node:os\";\nimport { execSync } from \"node:child_process\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\n\nexport async function installDaemon(): Promise<void> {\n const os = platform();\n switch (os) {\n case \"darwin\":\n await installLaunchd();\n break;\n case \"win32\":\n await installTaskScheduler();\n break;\n case \"linux\":\n await installSystemd();\n break;\n default:\n console.log(red(`Unsupported platform: ${os}`));\n }\n}\n\nexport async function uninstallDaemon(): Promise<void> {\n const os = platform();\n switch (os) {\n case \"darwin\":\n await uninstallLaunchd();\n break;\n case \"win32\":\n await uninstallTaskScheduler();\n break;\n case \"linux\":\n await uninstallSystemd();\n break;\n default:\n console.log(red(`Unsupported platform: ${os}`));\n }\n}\n\nexport async function daemonStatus(): Promise<void> {\n const os = platform();\n switch (os) {\n case \"darwin\":\n try {\n const out = execSync(\"launchctl list | grep com.clank.gateway\", { encoding: \"utf-8\" });\n console.log(green(\"Daemon: running (launchd)\"));\n console.log(dim(out.trim()));\n } catch {\n console.log(dim(\"Daemon: not installed\"));\n }\n break;\n case \"win32\":\n try {\n const out = execSync('schtasks /query /tn \"ClankGateway\" /fo LIST', { encoding: \"utf-8\" });\n console.log(green(\"Daemon: installed (Task Scheduler)\"));\n console.log(dim(out.trim()));\n } catch {\n console.log(dim(\"Daemon: not installed\"));\n }\n break;\n case \"linux\":\n try {\n const out = execSync(\"systemctl --user status clank-gateway\", { encoding: \"utf-8\" });\n console.log(green(\"Daemon: running (systemd)\"));\n console.log(dim(out.trim()));\n } catch {\n console.log(dim(\"Daemon: not installed or not running\"));\n }\n break;\n }\n}\n\n// --- macOS: LaunchAgent ---\nasync function installLaunchd(): Promise<void> {\n const plistDir = join(homedir(), \"Library\", \"LaunchAgents\");\n const plistPath = join(plistDir, \"com.clank.gateway.plist\");\n const clankPath = execSync(\"which clank || echo clank\", { encoding: \"utf-8\" }).trim();\n\n await mkdir(plistDir, { recursive: true });\n\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>com.clank.gateway</string>\n <key>ProgramArguments</key>\n <array>\n <string>${clankPath}</string>\n <string>gateway</string>\n <string>start</string>\n <string>--foreground</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>StandardOutPath</key>\n <string>${join(homedir(), \".clank\", \"logs\", \"gateway.log\")}</string>\n <key>StandardErrorPath</key>\n <string>${join(homedir(), \".clank\", \"logs\", \"gateway-error.log\")}</string>\n</dict>\n</plist>`;\n\n await writeFile(plistPath, plist, \"utf-8\");\n execSync(`launchctl load \"${plistPath}\"`);\n console.log(green(\"Daemon installed (launchd)\"));\n console.log(dim(` Plist: ${plistPath}`));\n}\n\nasync function uninstallLaunchd(): Promise<void> {\n const plistPath = join(homedir(), \"Library\", \"LaunchAgents\", \"com.clank.gateway.plist\");\n try {\n execSync(`launchctl unload \"${plistPath}\"`);\n await unlink(plistPath);\n console.log(green(\"Daemon uninstalled\"));\n } catch {\n console.log(dim(\"Daemon was not installed\"));\n }\n}\n\n// --- Windows: Task Scheduler ---\nasync function installTaskScheduler(): Promise<void> {\n // Use the clank global binary path\n const { execSync: execSyncImport } = await import(\"node:child_process\");\n let clankBin = \"clank\";\n try {\n clankBin = execSyncImport(\"where clank\", { encoding: \"utf-8\" }).trim().split(\"\\n\")[0];\n } catch {}\n\n try {\n // Use /rl limited (no admin needed) instead of /rl highest\n execSync(\n `schtasks /create /tn \"ClankGateway\" /tr \"\\\\\"${clankBin}\\\\\" gateway start --foreground\" /sc onlogon /rl limited /f`,\n { encoding: \"utf-8\" },\n );\n // Also start it now\n execSync(`schtasks /run /tn \"ClankGateway\"`, { encoding: \"utf-8\" });\n console.log(green(\"Daemon installed (Task Scheduler)\"));\n console.log(dim(\" Task: ClankGateway\"));\n console.log(dim(\" Trigger: at login\"));\n } catch (err) {\n console.error(red(`Failed to install: ${err instanceof Error ? err.message : err}`));\n }\n}\n\nasync function uninstallTaskScheduler(): Promise<void> {\n try {\n execSync('schtasks /delete /tn \"ClankGateway\" /f', { encoding: \"utf-8\" });\n console.log(green(\"Daemon uninstalled\"));\n } catch {\n console.log(dim(\"Daemon was not installed\"));\n }\n}\n\n// --- Linux: systemd ---\nasync function installSystemd(): Promise<void> {\n const unitDir = join(homedir(), \".config\", \"systemd\", \"user\");\n const unitPath = join(unitDir, \"clank-gateway.service\");\n const clankPath = execSync(\"which clank || echo clank\", { encoding: \"utf-8\" }).trim();\n\n await mkdir(unitDir, { recursive: true });\n\n const unit = `[Unit]\nDescription=Clank Gateway\nAfter=network.target\n\n[Service]\nExecStart=${clankPath} gateway start --foreground\nRestart=on-failure\nRestartSec=5\n\n[Install]\nWantedBy=default.target\n`;\n\n await writeFile(unitPath, unit, \"utf-8\");\n execSync(\"systemctl --user daemon-reload\");\n execSync(\"systemctl --user enable clank-gateway\");\n execSync(\"systemctl --user start clank-gateway\");\n console.log(green(\"Daemon installed (systemd --user)\"));\n console.log(dim(` Unit: ${unitPath}`));\n}\n\nasync function uninstallSystemd(): Promise<void> {\n try {\n execSync(\"systemctl --user stop clank-gateway\");\n execSync(\"systemctl --user disable clank-gateway\");\n const unitPath = join(homedir(), \".config\", \"systemd\", \"user\", \"clank-gateway.service\");\n await unlink(unitPath);\n execSync(\"systemctl --user daemon-reload\");\n console.log(green(\"Daemon uninstalled\"));\n } catch {\n console.log(dim(\"Daemon was not installed\"));\n }\n}\n","export { installDaemon, uninstallDaemon, daemonStatus } from \"./install.js\";\n","/**\n * `clank setup` — Onboarding wizard.\n *\n * Gets the user from install to chatting in under 2 minutes.\n * Auto-detects local models, configures the gateway, and sets up\n * the user's preferred interface.\n *\n * Two flows:\n * - Quick Start: sensible defaults, minimal questions\n * - Advanced: full control over everything\n */\n\nimport { createInterface } from \"node:readline\";\nimport { randomBytes } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nimport {\n loadConfig,\n saveConfig,\n ensureConfigDir,\n defaultConfig,\n getConfigDir,\n type ClankConfig,\n} from \"../config/index.js\";\nimport { detectLocalServers } from \"../providers/index.js\";\nimport { installDaemon } from \"../daemon/index.js\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst bold = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst yellow = (s: string) => `\\x1b[33m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\n\nfunction ask(rl: ReturnType<typeof createInterface>, question: string): Promise<string> {\n return new Promise((resolve) => rl.question(question, resolve));\n}\n\nexport async function runSetup(opts: {\n quick?: boolean;\n advanced?: boolean;\n section?: string;\n nonInteractive?: boolean;\n acceptRisk?: boolean;\n}): Promise<void> {\n await ensureConfigDir();\n const config = defaultConfig();\n\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n\n try {\n // Step 1: Welcome & Security\n console.log(\"\");\n console.log(bold(\" Welcome to Clank\"));\n console.log(\"\");\n console.log(\" Clank is an AI agent that can read, write, and\");\n console.log(\" delete files, execute commands, and access the web.\");\n console.log(\" Review actions carefully.\");\n console.log(\"\");\n\n if (!opts.acceptRisk) {\n const ack = await ask(rl, cyan(\" I understand, continue? [Y/n] \"));\n if (ack.toLowerCase() === \"n\") {\n console.log(dim(\" Setup cancelled.\"));\n return;\n }\n }\n\n // Step 2: Choose Flow\n let isAdvanced = opts.advanced || false;\n if (!opts.quick && !opts.advanced) {\n console.log(\"\");\n console.log(\" How would you like to set up Clank?\");\n console.log(\"\");\n console.log(\" 1. \" + bold(\"Quick Start\") + \" (recommended)\");\n console.log(dim(\" Auto-detect local models, sensible defaults\"));\n console.log(\" 2. Advanced\");\n console.log(dim(\" Full control over gateway, models, channels\"));\n console.log(\"\");\n const choice = await ask(rl, cyan(\" Choice [1]: \"));\n isAdvanced = choice === \"2\";\n }\n\n // Step 3: Model Provider Setup\n console.log(\"\");\n console.log(dim(\" Searching for local models...\"));\n const servers = await detectLocalServers();\n\n if (servers.length > 0) {\n const primary = servers[0];\n console.log(green(` Found ${primary.provider} at ${primary.baseUrl}`));\n console.log(dim(` Models: ${primary.models.slice(0, 5).join(\", \")}`));\n\n const defaultModel = primary.models[0] || \"qwen3.5\";\n const useDefault = await ask(rl, cyan(` Use ${primary.provider}/${defaultModel} as default? [Y/n] `));\n if (useDefault.toLowerCase() !== \"n\") {\n config.agents.defaults.model.primary = `${primary.provider}/${defaultModel}`;\n // Save the detected server URL for ALL local providers\n (config.models.providers as Record<string, unknown>)[primary.provider] = { baseUrl: primary.baseUrl };\n }\n } else {\n console.log(yellow(\" No local model server detected.\"));\n console.log(dim(\" Install Ollama (recommended) or configure a cloud provider.\"));\n }\n\n // Step 3b: Cloud provider (optional fallback)\n console.log(\"\");\n const addCloud = await ask(rl, cyan(\" Add a cloud provider as fallback? [y/N] \"));\n if (addCloud.toLowerCase() === \"y\") {\n console.log(dim(\" 1. Anthropic (Claude)\"));\n console.log(dim(\" 2. OpenAI (GPT)\"));\n console.log(dim(\" 3. Google (Gemini)\"));\n const provider = await ask(rl, cyan(\" Which provider? [1]: \"));\n\n switch (provider || \"1\") {\n case \"1\": {\n const key = await ask(rl, cyan(\" Anthropic API key: \"));\n if (key.trim()) {\n config.models.providers.anthropic = { apiKey: key.trim() };\n config.agents.defaults.model.fallbacks = [\"anthropic/claude-sonnet-4-6\"];\n console.log(green(\" Anthropic configured as fallback\"));\n }\n break;\n }\n case \"2\": {\n const key = await ask(rl, cyan(\" OpenAI API key: \"));\n if (key.trim()) {\n config.models.providers.openai = { apiKey: key.trim() };\n config.agents.defaults.model.fallbacks = [\"openai/gpt-4o\"];\n console.log(green(\" OpenAI configured as fallback\"));\n }\n break;\n }\n case \"3\": {\n const key = await ask(rl, cyan(\" Google AI API key: \"));\n if (key.trim()) {\n config.models.providers.google = { apiKey: key.trim() };\n config.agents.defaults.model.fallbacks = [\"google/gemini-2.0-flash\"];\n console.log(green(\" Google configured as fallback\"));\n }\n break;\n }\n }\n }\n\n // Step 4: Gateway Configuration\n console.log(\"\");\n console.log(dim(\" Gateway settings:\"));\n if (isAdvanced) {\n const port = await ask(rl, cyan(` Port [${config.gateway.port}]: `));\n if (port.trim()) config.gateway.port = parseInt(port, 10);\n }\n\n // Generate auth token\n config.gateway.auth.token = randomBytes(16).toString(\"hex\");\n console.log(dim(` Port: ${config.gateway.port}`));\n console.log(dim(` Token: ${config.gateway.auth.token.slice(0, 8)}...`));\n\n // Step 5: Workspace Bootstrap\n console.log(\"\");\n console.log(dim(\" Creating workspace...\"));\n const { ensureWorkspaceFiles } = await import(\"../engine/system-prompt.js\");\n const templateDir = join(__dirname, \"..\", \"workspace\", \"templates\");\n const wsDir = join(getConfigDir(), \"workspace\");\n try {\n await ensureWorkspaceFiles(wsDir, templateDir);\n } catch {\n // Templates may not be found in built version — that's ok\n }\n console.log(green(\" Workspace ready at \" + getConfigDir()));\n\n // Step 6: Channel Setup\n console.log(\"\");\n console.log(\" Channel setup:\");\n console.log(dim(\" Web UI and CLI are always available.\"));\n console.log(\"\");\n\n const addTelegram = await ask(rl, cyan(\" Connect Telegram bot? [y/N] \"));\n if (addTelegram.toLowerCase() === \"y\") {\n console.log(dim(\" 1. Message @BotFather on Telegram\"));\n console.log(dim(\" 2. Send /newbot and follow prompts\"));\n console.log(dim(\" 3. Copy the bot token\"));\n const token = await ask(rl, cyan(\" Bot token: \"));\n if (token.trim()) {\n config.channels.telegram = { enabled: true, botToken: token.trim() };\n const userId = await ask(rl, cyan(\" Your Telegram user ID (for allowlist): \"));\n if (userId.trim()) {\n config.channels.telegram.allowFrom = [userId.trim()];\n }\n console.log(green(\" Telegram configured\"));\n }\n }\n\n const addDiscord = await ask(rl, cyan(\" Connect Discord bot? [y/N] \"));\n if (addDiscord.toLowerCase() === \"y\") {\n console.log(dim(\" 1. Go to discord.com/developers/applications\"));\n console.log(dim(\" 2. Create app → Bot → Copy Token\"));\n console.log(dim(\" 3. Enable MESSAGE CONTENT intent\"));\n const token = await ask(rl, cyan(\" Bot token: \"));\n if (token.trim()) {\n config.channels.discord = { enabled: true, botToken: token.trim() };\n console.log(green(\" Discord configured\"));\n }\n }\n\n // Step 7: Web Search (Brave)\n console.log(\"\");\n const addSearch = await ask(rl, cyan(\" Set up web search (Brave Search)? [y/N] \"));\n if (addSearch.toLowerCase() === \"y\") {\n console.log(dim(\" Get a free API key at: https://brave.com/search/api/\"));\n const key = await ask(rl, cyan(\" Brave Search API key: \"));\n if (key.trim()) {\n config.tools.webSearch = { enabled: true, provider: \"brave\", apiKey: key.trim() };\n console.log(green(\" Brave Search configured\"));\n }\n }\n\n // Step 8: Integrations (API services)\n console.log(\"\");\n console.log(\" API Integrations:\");\n console.log(dim(\" Add third-party services for voice, image gen, etc.\"));\n console.log(dim(\" You can also configure these later through conversation.\"));\n console.log(\"\");\n\n const addElevenLabs = await ask(rl, cyan(\" Set up ElevenLabs (text-to-speech)? [y/N] \"));\n if (addElevenLabs.toLowerCase() === \"y\") {\n console.log(dim(\" Get an API key at: https://elevenlabs.io/\"));\n const key = await ask(rl, cyan(\" ElevenLabs API key: \"));\n if (key.trim()) {\n config.integrations.elevenlabs = { enabled: true, apiKey: key.trim() };\n const voiceId = await ask(rl, cyan(\" Default voice ID (Enter to skip): \"));\n if (voiceId.trim()) {\n config.integrations.elevenlabs.voiceId = voiceId.trim();\n }\n console.log(green(\" ElevenLabs configured (TTS available)\"));\n }\n }\n\n const addWhisper = await ask(rl, cyan(\" Set up speech-to-text (Whisper)? [y/N] \"));\n if (addWhisper.toLowerCase() === \"y\") {\n console.log(dim(\" 1. OpenAI Whisper API (cloud, uses OpenAI key)\"));\n console.log(dim(\" 2. Local whisper.cpp (requires whisper installed)\"));\n const whisperChoice = await ask(rl, cyan(\" Choice [1]: \"));\n if (whisperChoice === \"2\") {\n config.integrations.whisper = { enabled: true, provider: \"local\" };\n console.log(green(\" Local whisper.cpp configured\"));\n console.log(dim(\" Make sure whisper is installed and in PATH\"));\n } else {\n // OpenAI Whisper — can reuse existing OpenAI key or add one\n const existingKey = config.models.providers.openai?.apiKey;\n if (existingKey) {\n config.integrations.whisper = { enabled: true, provider: \"openai\", apiKey: existingKey };\n console.log(green(\" Whisper configured (using existing OpenAI key)\"));\n } else {\n const key = await ask(rl, cyan(\" OpenAI API key for Whisper: \"));\n if (key.trim()) {\n config.integrations.whisper = { enabled: true, provider: \"openai\", apiKey: key.trim() };\n console.log(green(\" Whisper configured\"));\n }\n }\n }\n }\n\n // Step 9: Agents (Advanced only)\n if (isAdvanced) {\n console.log(\"\");\n const addAgents = await ask(rl, cyan(\" Define additional agents? [y/N] \"));\n if (addAgents.toLowerCase() === \"y\") {\n let adding = true;\n while (adding) {\n const id = await ask(rl, cyan(\" Agent ID: \"));\n if (!id.trim()) break;\n const name = await ask(rl, cyan(\" Name: \"));\n const model = await ask(rl, cyan(\" Model [default]: \"));\n\n config.agents.list.push({\n id: id.trim(),\n name: name.trim() || id.trim(),\n model: model.trim() ? { primary: model.trim() } : undefined,\n });\n console.log(green(` Agent ${id.trim()} added`));\n\n const more = await ask(rl, cyan(\" Add another? [y/N] \"));\n adding = more.toLowerCase() === \"y\";\n }\n }\n }\n\n // Step 10: Daemon Install\n console.log(\"\");\n const installService = await ask(rl, cyan(\" Install as system service? [Y/n] \"));\n if (installService.toLowerCase() !== \"n\") {\n try {\n await installDaemon();\n } catch (err) {\n console.log(yellow(` Skipped: ${err instanceof Error ? err.message : err}`));\n }\n }\n\n // Save config\n await saveConfig(config);\n console.log(green(\"\\n Config saved to \" + getConfigDir() + \"/config.json5\"));\n\n // Step 11: First Chat\n console.log(\"\");\n console.log(bold(\" Clank is ready!\"));\n console.log(\"\");\n console.log(\" Start chatting:\");\n console.log(dim(\" clank chat — CLI chat\"));\n console.log(dim(\" clank chat --web — Open in browser\"));\n console.log(dim(\" clank gateway start — Start the daemon\"));\n console.log(\"\");\n } finally {\n rl.close();\n }\n}\n","/**\n * `clank fix` — Diagnostics & repair utility.\n *\n * Checks all systems and reports issues. Auto-fix mode\n * attempts safe repairs for common problems.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { getConfigDir, getConfigPath, loadConfig } from \"../config/index.js\";\nimport { OllamaProvider } from \"../providers/ollama.js\";\nimport { DEFAULT_PORT } from \"../gateway/protocol.js\";\n\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\nconst yellow = (s: string) => `\\x1b[33m${s}\\x1b[0m`;\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst check = green(\"✓\");\nconst cross = red(\"✗\");\nconst warn = yellow(\"!\");\n\ninterface CheckResult {\n name: string;\n status: \"ok\" | \"warn\" | \"error\";\n message: string;\n fix?: string;\n}\n\nexport async function runFix(opts: { auto?: boolean; check?: string }): Promise<void> {\n console.log(\"\");\n console.log(\" Clank Diagnostics\");\n console.log(\"\");\n\n const results: CheckResult[] = [];\n\n // Only run specific check if requested\n const checks = opts.check ? [opts.check] : [\"config\", \"gateway\", \"models\", \"sessions\", \"workspace\"];\n\n if (checks.includes(\"config\")) results.push(await checkConfig());\n if (checks.includes(\"gateway\")) results.push(await checkGateway());\n if (checks.includes(\"models\")) results.push(await checkModels());\n if (checks.includes(\"sessions\")) results.push(await checkSessions());\n if (checks.includes(\"workspace\")) results.push(await checkWorkspace());\n\n // Print results\n for (const r of results) {\n const icon = r.status === \"ok\" ? check : r.status === \"warn\" ? warn : cross;\n console.log(` ${icon} ${r.name.padEnd(18)} ${r.message}`);\n if (r.fix && r.status !== \"ok\") {\n console.log(dim(` → ${r.fix}`));\n }\n }\n\n const issues = results.filter((r) => r.status !== \"ok\");\n console.log(\"\");\n if (issues.length === 0) {\n console.log(green(\" All checks passed.\"));\n } else {\n console.log(yellow(` ${issues.length} issue${issues.length > 1 ? \"s\" : \"\"} found.`));\n }\n console.log(\"\");\n}\n\nasync function checkConfig(): Promise<CheckResult> {\n const configPath = getConfigPath();\n if (!existsSync(configPath)) {\n return {\n name: \"Config\",\n status: \"warn\",\n message: \"No config file found\",\n fix: \"Run: clank setup\",\n };\n }\n\n try {\n await loadConfig();\n return { name: \"Config\", status: \"ok\", message: \"valid\" };\n } catch (err) {\n return {\n name: \"Config\",\n status: \"error\",\n message: `parse error: ${err instanceof Error ? err.message : err}`,\n fix: \"Check config.json5 for syntax errors\",\n };\n }\n}\n\nasync function checkGateway(): Promise<CheckResult> {\n const config = await loadConfig();\n const port = config.gateway.port || DEFAULT_PORT;\n\n try {\n const res = await fetch(`http://127.0.0.1:${port}/health`, { signal: AbortSignal.timeout(3000) });\n if (res.ok) {\n return { name: \"Gateway\", status: \"ok\", message: `running on :${port}` };\n }\n return { name: \"Gateway\", status: \"error\", message: `unhealthy on :${port}` };\n } catch {\n return {\n name: \"Gateway\",\n status: \"warn\",\n message: \"not running\",\n fix: \"Run: clank gateway start\",\n };\n }\n}\n\nasync function checkModels(): Promise<CheckResult> {\n const config = await loadConfig();\n const modelId = config.agents.defaults.model.primary;\n const provider = modelId.split(\"/\")[0];\n\n if (provider === \"ollama\") {\n const models = await OllamaProvider.detect(config.models.providers.ollama?.baseUrl);\n if (models) {\n return { name: \"Model (primary)\", status: \"ok\", message: `${modelId} — ${models.length} models available` };\n }\n return {\n name: \"Model (primary)\",\n status: \"error\",\n message: \"Ollama not reachable\",\n fix: \"Start Ollama: ollama serve\",\n };\n }\n\n if (provider === \"anthropic\") {\n if (config.models.providers.anthropic?.apiKey) {\n return { name: \"Model (primary)\", status: \"ok\", message: `${modelId} — key configured` };\n }\n return {\n name: \"Model (primary)\",\n status: \"error\",\n message: \"Anthropic API key not set\",\n fix: \"Run: clank setup --section model\",\n };\n }\n\n return { name: \"Model (primary)\", status: \"ok\", message: modelId };\n}\n\nasync function checkSessions(): Promise<CheckResult> {\n const sessDir = join(getConfigDir(), \"conversations\");\n if (!existsSync(sessDir)) {\n return { name: \"Sessions\", status: \"ok\", message: \"no sessions yet\" };\n }\n\n try {\n const files = await readdir(sessDir);\n const count = files.filter((f) => f.endsWith(\".json\") && f !== \"sessions.json\").length;\n return { name: \"Sessions\", status: \"ok\", message: `${count} session${count !== 1 ? \"s\" : \"\"}` };\n } catch {\n return { name: \"Sessions\", status: \"warn\", message: \"could not read sessions directory\" };\n }\n}\n\nasync function checkWorkspace(): Promise<CheckResult> {\n const wsDir = join(getConfigDir(), \"workspace\");\n if (!existsSync(wsDir)) {\n return {\n name: \"Workspace\",\n status: \"warn\",\n message: \"not created yet\",\n fix: \"Run: clank setup\",\n };\n }\n return { name: \"Workspace\", status: \"ok\", message: \"present\" };\n}\n","/**\n * CLI model management commands.\n */\n\nimport { loadConfig, saveConfig, ensureConfigDir } from \"../config/index.js\";\nimport { detectLocalServers } from \"../providers/index.js\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\n\nexport async function modelsList(): Promise<void> {\n const config = await loadConfig();\n console.log(\"\");\n console.log(` Default: ${config.agents.defaults.model.primary}`);\n if (config.agents.defaults.model.fallbacks?.length) {\n console.log(` Fallbacks: ${config.agents.defaults.model.fallbacks.join(\", \")}`);\n }\n console.log(\"\");\n console.log(dim(\" Configured providers:\"));\n for (const [name, cfg] of Object.entries(config.models.providers)) {\n const c = cfg as Record<string, unknown>;\n const status = c.apiKey ? green(\"key set\") : c.baseUrl ? green(\"configured\") : dim(\"not configured\");\n console.log(` ${name}: ${status}`);\n }\n\n console.log(\"\");\n console.log(dim(\" Detecting local servers...\"));\n const servers = await detectLocalServers();\n if (servers.length > 0) {\n for (const s of servers) {\n console.log(green(` ${s.provider} at ${s.baseUrl} — ${s.models.length} models`));\n for (const m of s.models.slice(0, 5)) {\n console.log(dim(` ${m}`));\n }\n if (s.models.length > 5) console.log(dim(` ... and ${s.models.length - 5} more`));\n }\n } else {\n console.log(dim(\" No local servers found\"));\n }\n console.log(\"\");\n}\n\nexport async function modelsAdd(): Promise<void> {\n const { createInterface } = await import(\"node:readline\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const ask = (q: string): Promise<string> => new Promise((r) => rl.question(q, r));\n\n try {\n await ensureConfigDir();\n const config = await loadConfig();\n\n console.log(\"\");\n console.log(\" Add a model provider:\");\n console.log(dim(\" 1. Anthropic (Claude)\"));\n console.log(dim(\" 2. OpenAI (GPT)\"));\n console.log(dim(\" 3. Google (Gemini)\"));\n console.log(dim(\" 4. Brave Search (web search)\"));\n console.log(\"\");\n\n const choice = await ask(cyan(\" Choice: \"));\n\n switch (choice) {\n case \"1\": {\n const key = await ask(cyan(\" Anthropic API key: \"));\n if (key.trim()) {\n config.models.providers.anthropic = { apiKey: key.trim() };\n await saveConfig(config);\n console.log(green(\" Anthropic added\"));\n }\n break;\n }\n case \"2\": {\n const key = await ask(cyan(\" OpenAI API key: \"));\n if (key.trim()) {\n config.models.providers.openai = { apiKey: key.trim() };\n await saveConfig(config);\n console.log(green(\" OpenAI added\"));\n }\n break;\n }\n case \"3\": {\n const key = await ask(cyan(\" Google AI API key: \"));\n if (key.trim()) {\n config.models.providers.google = { apiKey: key.trim() };\n await saveConfig(config);\n console.log(green(\" Google added\"));\n }\n break;\n }\n case \"4\": {\n const key = await ask(cyan(\" Brave Search API key: \"));\n if (key.trim()) {\n config.tools.webSearch = { enabled: true, provider: \"brave\", apiKey: key.trim() };\n await saveConfig(config);\n console.log(green(\" Brave Search added\"));\n }\n break;\n }\n default:\n console.log(dim(\" Cancelled\"));\n }\n console.log(\"\");\n } finally {\n rl.close();\n }\n}\n\nexport async function modelsTest(): Promise<void> {\n const config = await loadConfig();\n const modelId = config.agents.defaults.model.primary;\n console.log(\"\");\n console.log(dim(` Testing ${modelId}...`));\n\n try {\n const { resolveWithFallback } = await import(\"../providers/index.js\");\n const resolved = await resolveWithFallback(\n modelId,\n config.agents.defaults.model.fallbacks || [],\n config.models.providers,\n );\n console.log(green(` Connected to ${resolved.modelId} (${resolved.isLocal ? \"local\" : \"cloud\"})`));\n } catch (err) {\n console.log(` \\x1b[31mFailed: ${err instanceof Error ? err.message : err}\\x1b[0m`);\n }\n console.log(\"\");\n}\n","/**\n * CLI agent management commands.\n */\n\nimport { loadConfig, saveConfig, ensureConfigDir } from \"../config/index.js\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\n\nexport async function agentsList(): Promise<void> {\n const config = await loadConfig();\n console.log(\"\");\n console.log(dim(\" Default model: \") + config.agents.defaults.model.primary);\n console.log(dim(\" Default workspace: \") + config.agents.defaults.workspace);\n console.log(dim(\" Tool tier: \") + config.agents.defaults.toolTier);\n console.log(\"\");\n\n if (config.agents.list.length === 0) {\n console.log(dim(\" No custom agents configured. Using default agent.\"));\n console.log(dim(\" Add agents with: clank agents add\"));\n } else {\n console.log(\" Agents:\");\n for (const a of config.agents.list) {\n console.log(` ${a.id}: ${a.name || a.id}`);\n console.log(dim(` model: ${a.model?.primary || \"default\"}`));\n if (a.workspace) console.log(dim(` workspace: ${a.workspace}`));\n if (a.toolTier) console.log(dim(` tier: ${a.toolTier}`));\n }\n }\n console.log(\"\");\n}\n\nexport async function agentsAdd(): Promise<void> {\n const { createInterface } = await import(\"node:readline\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const ask = (q: string): Promise<string> => new Promise((r) => rl.question(q, r));\n\n try {\n await ensureConfigDir();\n const config = await loadConfig();\n\n console.log(\"\");\n const id = await ask(cyan(\" Agent ID (lowercase, no spaces): \"));\n if (!id.trim()) { console.log(dim(\" Cancelled\")); return; }\n\n const name = await ask(cyan(` Display name [${id.trim()}]: `));\n const model = await ask(cyan(\" Model [default]: \"));\n const workspace = await ask(cyan(\" Workspace [default]: \"));\n\n const entry: Record<string, unknown> = { id: id.trim() };\n if (name.trim()) entry.name = name.trim();\n if (model.trim()) entry.model = { primary: model.trim() };\n if (workspace.trim()) entry.workspace = workspace.trim();\n\n config.agents.list.push(entry as any);\n await saveConfig(config);\n console.log(green(` Agent ${id.trim()} added`));\n console.log(\"\");\n } finally {\n rl.close();\n }\n}\n\nexport async function agentsRouting(): Promise<void> {\n const config = await loadConfig();\n console.log(\"\");\n console.log(dim(\" Routing rules are configured in config.json5 or through conversation.\"));\n console.log(dim(\" Default: all messages go to the default agent.\"));\n console.log(\"\");\n\n if (config.agents.list.length > 0) {\n console.log(\" Configured agents:\");\n for (const a of config.agents.list) {\n console.log(` ${a.id} → model: ${a.model?.primary || \"default\"}`);\n }\n }\n\n if (config.channels?.telegram?.enabled) {\n const groups = config.channels.telegram.groups;\n if (groups && Object.keys(groups).length > 0) {\n console.log(\"\");\n console.log(\" Telegram group bindings:\");\n for (const [groupId, cfg] of Object.entries(groups)) {\n console.log(` ${groupId}: mention=${cfg.requireMention ?? true}`);\n }\n }\n }\n console.log(\"\");\n}\n","/**\n * Terminal UI (TUI) — rich interactive chat interface.\n *\n * Connects to the gateway via WebSocket (same protocol as Web UI).\n * Features: streaming, tool call cards, thinking blocks, agent/model/session\n * pickers, status bar, slash commands, shell integration.\n *\n * Keyboard shortcuts:\n * Enter — Send message\n * Esc — Abort current response\n * Ctrl+L — Model picker\n * Ctrl+G — Agent picker\n * Ctrl+P — Session picker\n * Ctrl+O — Toggle tool output\n * Ctrl+T — Toggle thinking visibility\n * Ctrl+C — Clear input (twice to exit)\n * Ctrl+D — Exit\n */\n\nimport { createInterface } from \"node:readline\";\nimport WebSocket from \"ws\";\nimport { loadConfig, getConfigDir } from \"../config/index.js\";\nimport { DEFAULT_PORT, type HelloFrame, type EventFrame, type ResponseFrame } from \"../gateway/protocol.js\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst bold = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst yellow = (s: string) => `\\x1b[33m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\nconst italic = (s: string) => `\\x1b[3m${s}\\x1b[0m`;\n\ninterface TuiState {\n ws: WebSocket | null;\n connected: boolean;\n agentId: string;\n agentName: string;\n modelId: string;\n sessionKey: string;\n agents: Array<{ id: string; name: string; model: string }>;\n sessions: Array<{ key: string; label?: string }>;\n streaming: boolean;\n showThinking: boolean;\n showToolOutput: boolean;\n reqId: number;\n ctrlCCount: number;\n}\n\nexport async function runTui(opts: {\n url?: string;\n token?: string;\n session?: string;\n}): Promise<void> {\n const config = await loadConfig();\n const port = config.gateway.port || DEFAULT_PORT;\n const wsUrl = opts.url || `ws://127.0.0.1:${port}`;\n const token = opts.token || config.gateway.auth.token || \"\";\n\n const state: TuiState = {\n ws: null,\n connected: false,\n agentId: \"default\",\n agentName: \"Clank\",\n modelId: config.agents.defaults.model.primary,\n sessionKey: opts.session || \"tui:main\",\n agents: [],\n sessions: [],\n streaming: false,\n showThinking: false,\n showToolOutput: true,\n reqId: 0,\n ctrlCCount: 0,\n };\n\n // Check if gateway is running, if not fall back to direct mode\n try {\n const health = await fetch(`http://127.0.0.1:${port}/health`, { signal: AbortSignal.timeout(2000) });\n if (!health.ok) throw new Error(\"not ok\");\n } catch {\n console.log(dim(\" Gateway not running. Starting direct mode...\"));\n console.log(dim(\" (Start gateway with: clank gateway start)\"));\n console.log(\"\");\n const { runChat } = await import(\"./chat.js\");\n await runChat({ direct: true });\n return;\n }\n\n console.log(\"\");\n console.log(bold(\" Clank TUI\") + dim(` | connecting to ${wsUrl}...`));\n\n // Connect to gateway\n const ws = new WebSocket(wsUrl);\n state.ws = ws;\n\n ws.on(\"open\", () => {\n // Send connect handshake\n ws.send(JSON.stringify({\n type: \"connect\",\n params: { auth: { token }, mode: \"tui\", version: \"1.3.0\" },\n }));\n });\n\n ws.on(\"message\", (data) => {\n const frame = JSON.parse(data.toString());\n handleFrame(state, frame);\n });\n\n ws.on(\"close\", () => {\n state.connected = false;\n console.log(red(\"\\n Disconnected from gateway.\"));\n process.exit(0);\n });\n\n ws.on(\"error\", (err) => {\n console.error(red(` Connection error: ${err.message}`));\n process.exit(1);\n });\n\n // Set up readline\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n\n // Wait for connection before prompting\n await new Promise<void>((resolve) => {\n const check = setInterval(() => {\n if (state.connected) { clearInterval(check); resolve(); }\n }, 100);\n setTimeout(() => { clearInterval(check); resolve(); }, 5000);\n });\n\n if (!state.connected) {\n console.log(red(\" Failed to connect to gateway.\"));\n process.exit(1);\n }\n\n // Print header\n printStatusBar(state);\n console.log(dim(\" Type your message. /help for commands. Ctrl+D to exit.\\n\"));\n\n rl.setPrompt(cyan(\"you > \"));\n rl.prompt();\n\n rl.on(\"line\", async (line) => {\n const input = line.trim();\n state.ctrlCCount = 0;\n\n if (!input) { rl.prompt(); return; }\n\n // Shell integration: ! prefix runs commands on host\n if (input.startsWith(\"!\")) {\n const cmd = input.slice(1).trim();\n if (cmd) {\n const { execSync } = await import(\"node:child_process\");\n try {\n const out = execSync(cmd, { encoding: \"utf-8\", timeout: 30000, env: { ...process.env, CLANK_SHELL: \"tui-local\" } });\n console.log(out);\n } catch (err: any) {\n console.log(red(err.stderr || err.message));\n }\n }\n rl.prompt();\n return;\n }\n\n // Slash commands\n if (input.startsWith(\"/\")) {\n await handleSlashCommand(state, input, rl);\n rl.prompt();\n return;\n }\n\n // Send message to agent\n console.log(\"\");\n state.streaming = true;\n state.reqId++;\n\n state.ws?.send(JSON.stringify({\n type: \"req\",\n id: state.reqId,\n method: \"chat.send\",\n params: { message: input, sessionKey: state.sessionKey, agent: state.agentId },\n }));\n\n // Wait for response to complete\n await new Promise<void>((resolve) => {\n const check = setInterval(() => {\n if (!state.streaming) { clearInterval(check); resolve(); }\n }, 100);\n });\n\n console.log(\"\");\n rl.prompt();\n });\n\n rl.on(\"close\", () => {\n ws.close();\n process.exit(0);\n });\n\n // Handle Ctrl+C\n process.on(\"SIGINT\", () => {\n if (state.streaming) {\n state.ws?.send(JSON.stringify({ type: \"req\", id: ++state.reqId, method: \"chat.abort\", params: {} }));\n state.streaming = false;\n console.log(dim(\"\\n (aborted)\"));\n rl.prompt();\n } else {\n state.ctrlCCount++;\n if (state.ctrlCCount >= 2) {\n ws.close();\n process.exit(0);\n }\n console.log(dim(\"\\n Press Ctrl+C again to exit, or Ctrl+D.\"));\n rl.prompt();\n }\n });\n}\n\nfunction handleFrame(state: TuiState, frame: any): void {\n // Hello response\n if (frame.type === \"hello\") {\n const hello = frame as HelloFrame;\n state.connected = true;\n state.agents = hello.agents || [];\n state.sessions = hello.sessions || [];\n if (state.agents.length > 0) {\n state.agentId = state.agents[0].id;\n state.agentName = state.agents[0].name;\n state.modelId = state.agents[0].model;\n }\n console.log(green(` Connected`) + dim(` | agent: ${state.agentName} | model: ${state.modelId}`));\n return;\n }\n\n // Events\n if (frame.type === \"event\") {\n const event = frame as EventFrame;\n switch (event.event) {\n case \"chat.stream\":\n case \"token\":\n process.stdout.write((event.payload as any).text || (event.payload as any).content || \"\");\n break;\n\n case \"chat.thinking\":\n case \"thinking\":\n if (state.showThinking) {\n process.stdout.write(dim(italic((event.payload as any).text || \"\")));\n }\n break;\n\n case \"chat.tool\":\n case \"tool-start\": {\n const p = event.payload as any;\n if (state.showToolOutput) {\n console.log(dim(`\\n [${p.name}] ${(p.args ? JSON.stringify(p.args) : \"\").slice(0, 80)}`));\n }\n break;\n }\n\n case \"tool-result\": {\n const p = event.payload as any;\n if (state.showToolOutput) {\n const icon = p.success ? green(\"ok\") : red(\"err\");\n console.log(dim(` [${p.name}] ${icon} ${(p.summary || \"\").slice(0, 80)}`));\n }\n break;\n }\n\n case \"chat.complete\":\n case \"response-end\":\n case \"turn-complete\":\n state.streaming = false;\n break;\n\n case \"chat.error\":\n case \"error\":\n console.log(red(`\\n Error: ${(event.payload as any).message || (event.payload as any).error || \"Unknown\"}`));\n state.streaming = false;\n break;\n\n case \"usage\": {\n const u = event.payload as any;\n console.log(dim(`\\n [${u.promptTokens}→${u.outputTokens} tokens | ctx ${u.contextPercent}%]`));\n break;\n }\n }\n return;\n }\n\n // Response frames\n if (frame.type === \"res\") {\n const res = frame as ResponseFrame;\n if (!res.ok && res.error) {\n console.log(red(`\\n Error: ${res.error}`));\n }\n state.streaming = false;\n }\n}\n\nasync function handleSlashCommand(state: TuiState, input: string, rl: any): Promise<void> {\n const [cmd, ...args] = input.slice(1).split(/\\s+/);\n\n switch (cmd) {\n case \"help\":\n console.log(dim(\" Commands:\"));\n console.log(dim(\" /help — This help\"));\n console.log(dim(\" /status — Gateway and agent status\"));\n console.log(dim(\" /agent [name] — Switch or list agents\"));\n console.log(dim(\" /session [key] — Switch or list sessions\"));\n console.log(dim(\" /model [id] — Show current model\"));\n console.log(dim(\" /think — Toggle thinking display\"));\n console.log(dim(\" /tools — Toggle tool output\"));\n console.log(dim(\" /new — Start new session\"));\n console.log(dim(\" /reset — Reset current session\"));\n console.log(dim(\" /exit — Exit\"));\n console.log(dim(\" !<command> — Run shell command\"));\n break;\n\n case \"status\":\n console.log(dim(` Agent: ${state.agentName} (${state.agentId})`));\n console.log(dim(` Model: ${state.modelId}`));\n console.log(dim(` Session: ${state.sessionKey}`));\n console.log(dim(` Connected: ${state.connected}`));\n break;\n\n case \"agent\":\n if (args[0]) {\n const agent = state.agents.find((a) => a.id === args[0] || a.name.toLowerCase() === args[0].toLowerCase());\n if (agent) {\n state.agentId = agent.id;\n state.agentName = agent.name;\n state.modelId = agent.model;\n state.sessionKey = `tui:${agent.id}:main`;\n console.log(green(` Switched to ${agent.name} (${agent.model})`));\n } else {\n console.log(red(` Agent not found: ${args[0]}`));\n }\n } else {\n console.log(dim(\" Agents:\"));\n for (const a of state.agents) {\n const active = a.id === state.agentId ? \" ←\" : \"\";\n console.log(dim(` ${a.id}: ${a.name} (${a.model})${active}`));\n }\n if (state.agents.length === 0) console.log(dim(\" (no custom agents)\"));\n }\n break;\n\n case \"session\":\n if (args[0]) {\n state.sessionKey = args[0];\n console.log(green(` Switched to session: ${args[0]}`));\n } else {\n console.log(dim(\" Sessions:\"));\n for (const s of state.sessions.slice(0, 20)) {\n const active = s.key === state.sessionKey ? \" ←\" : \"\";\n console.log(dim(` ${s.key}: ${s.label || \"(untitled)\"}${active}`));\n }\n if (state.sessions.length === 0) console.log(dim(\" (no sessions)\"));\n }\n break;\n\n case \"model\":\n console.log(dim(` Current model: ${state.modelId}`));\n break;\n\n case \"think\":\n state.showThinking = !state.showThinking;\n console.log(dim(` Thinking display: ${state.showThinking ? \"on\" : \"off\"}`));\n break;\n\n case \"tools\":\n state.showToolOutput = !state.showToolOutput;\n console.log(dim(` Tool output: ${state.showToolOutput ? \"on\" : \"off\"}`));\n break;\n\n case \"new\":\n state.sessionKey = `tui:${state.agentId}:${Date.now()}`;\n console.log(green(` New session: ${state.sessionKey}`));\n break;\n\n case \"reset\":\n state.ws?.send(JSON.stringify({\n type: \"req\", id: ++state.reqId, method: \"session.reset\",\n params: { sessionKey: state.sessionKey },\n }));\n console.log(green(\" Session reset\"));\n break;\n\n case \"exit\":\n case \"quit\":\n state.ws?.close();\n process.exit(0);\n\n default:\n console.log(dim(` Unknown command: /${cmd}. Type /help for commands.`));\n }\n}\n\nfunction printStatusBar(state: TuiState): void {\n console.log(dim(` ${state.agentName} | ${state.modelId} | ${state.sessionKey}`));\n}\n","/**\n * `clank update` — pull latest, rebuild, restart gateway.\n *\n * Updates the npm package to the latest version while preserving\n * all user config, sessions, memory, and workspace files.\n */\n\nimport { execSync } from \"node:child_process\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\n\nexport async function runUpdate(): Promise<void> {\n console.log(\"\");\n console.log(dim(\" Updating Clank...\"));\n\n // Step 1: Stop the gateway if running\n console.log(dim(\" Stopping gateway...\"));\n try {\n const { gatewayStop } = await import(\"./gateway-cmd.js\");\n await gatewayStop();\n } catch {\n // May not be running\n }\n\n // Step 2: Update the npm package\n console.log(dim(\" Pulling latest version...\"));\n try {\n const output = execSync(\"npm install -g @tractorscorch/clank@latest\", {\n encoding: \"utf-8\",\n timeout: 120_000,\n });\n console.log(dim(` ${output.trim()}`));\n } catch (err) {\n console.error(red(` Update failed: ${err instanceof Error ? err.message : err}`));\n console.error(dim(\" Try manually: npm install -g @tractorscorch/clank@latest\"));\n return;\n }\n\n // Step 3: Verify new version\n try {\n const newVersion = execSync(\"clank --version\", { encoding: \"utf-8\" }).trim();\n console.log(green(` Updated to v${newVersion}`));\n } catch {\n console.log(green(\" Package updated\"));\n }\n\n // Step 4: Restart gateway\n console.log(dim(\" Restarting gateway...\"));\n try {\n const { gatewayStartBackground } = await import(\"./gateway-cmd.js\");\n await gatewayStartBackground();\n console.log(green(\" Gateway restarted\"));\n } catch (err) {\n console.log(dim(\" Gateway not restarted. Start manually: clank gateway start\"));\n }\n\n console.log(\"\");\n console.log(green(\" Clank updated successfully.\"));\n console.log(dim(\" Config, sessions, and memory preserved.\"));\n console.log(\"\");\n}\n","/**\n * `clank uninstall` — remove everything.\n *\n * Stops the gateway, removes the daemon, deletes all data\n * (config, sessions, memory, workspace, logs, plugins, cron),\n * and unlinks the global npm package.\n */\n\nimport { createInterface } from \"node:readline\";\nimport { rm } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { getConfigDir } from \"../config/index.js\";\nimport { gatewayStop } from \"./gateway-cmd.js\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst bold = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\nconst yellow = (s: string) => `\\x1b[33m${s}\\x1b[0m`;\n\nexport async function runUninstall(opts: { yes?: boolean }): Promise<void> {\n const configDir = getConfigDir();\n\n console.log(\"\");\n console.log(bold(\" Uninstall Clank\"));\n console.log(\"\");\n console.log(\" This will permanently remove:\");\n console.log(red(` ${configDir}`));\n console.log(dim(\" ├── config.json5 (configuration)\"));\n console.log(dim(\" ├── conversations/ (chat history)\"));\n console.log(dim(\" ├── memory/ (agent memory)\"));\n console.log(dim(\" ├── workspace/ (SOUL.md, USER.md, etc.)\"));\n console.log(dim(\" ├── logs/ (gateway logs)\"));\n console.log(dim(\" ├── cron/ (scheduled jobs)\"));\n console.log(dim(\" └── plugins/ (installed plugins)\"));\n console.log(\"\");\n\n if (!opts.yes) {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((resolve) => {\n rl.question(yellow(\" Are you sure? This cannot be undone. [y/N] \"), resolve);\n });\n rl.close();\n\n if (answer.trim().toLowerCase() !== \"y\") {\n console.log(dim(\" Uninstall cancelled.\"));\n return;\n }\n }\n\n // Step 1: Stop gateway\n console.log(dim(\" Stopping gateway...\"));\n try {\n await gatewayStop();\n } catch {\n // May not be running\n }\n\n // Step 2: Remove daemon/service\n console.log(dim(\" Removing system service...\"));\n try {\n const { uninstallDaemon } = await import(\"../daemon/index.js\");\n await uninstallDaemon();\n } catch {\n // May not be installed\n }\n\n // Step 3: Delete all data\n console.log(dim(\" Deleting data...\"));\n if (existsSync(configDir)) {\n await rm(configDir, { recursive: true, force: true });\n console.log(green(` Removed ${configDir}`));\n } else {\n console.log(dim(\" No data directory found.\"));\n }\n\n // Step 4: Unlink global package\n console.log(dim(\" Uninstalling npm package...\"));\n try {\n const { execSync } = await import(\"node:child_process\");\n execSync(\"npm uninstall -g @tractorscorch/clank\", { stdio: \"ignore\" });\n console.log(green(\" npm package uninstalled\"));\n } catch {\n console.log(dim(\" Could not uninstall npm package (may not be globally installed)\"));\n }\n\n console.log(\"\");\n console.log(green(\" Clank has been completely removed.\"));\n console.log(\"\");\n}\n","#!/usr/bin/env node\n\n/**\n * Clank — Local-first AI agent gateway\n *\n * Entry point for the `clank` CLI command.\n * Routes to subcommands: chat, gateway, setup, fix, models, agents, daemon.\n */\n\nimport { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Read version from package.json\nlet version = \"1.3.0\";\ntry {\n const pkg = JSON.parse(readFileSync(join(__dirname, \"..\", \"package.json\"), \"utf-8\"));\n version = pkg.version;\n} catch {\n // Use default version\n}\n\nconst program = new Command();\n\nprogram\n .name(\"clank\")\n .description(\"Local-first AI agent gateway\")\n .version(version, \"-v, --version\");\n\n// clank chat — interactive chat (connects to gateway or direct mode)\nprogram\n .command(\"chat\")\n .description(\"Start an interactive chat session\")\n .option(\"--web\", \"Open chat in browser\")\n .option(\"--new\", \"Start a fresh session\")\n .option(\"--continue\", \"Resume last session\")\n .option(\"--session <id>\", \"Resume a specific session\")\n .option(\"--direct\", \"Force direct mode (no gateway)\")\n .action(async (opts) => {\n const { runChat } = await import(\"./chat.js\");\n await runChat(opts);\n });\n\n// clank gateway — manage the gateway daemon\nconst gateway = program\n .command(\"gateway\")\n .description(\"Manage the gateway daemon\");\n\ngateway\n .command(\"start\")\n .description(\"Start the gateway daemon\")\n .option(\"-p, --port <port>\", \"Port to listen on\")\n .option(\"--foreground\", \"Run in foreground (don't daemonize)\")\n .action(async (opts) => {\n const { gatewayStart } = await import(\"./gateway-cmd.js\");\n await gatewayStart(opts);\n });\n\ngateway\n .command(\"stop\")\n .description(\"Stop the gateway daemon\")\n .action(async () => {\n const { gatewayStop } = await import(\"./gateway-cmd.js\");\n await gatewayStop();\n });\n\ngateway\n .command(\"status\")\n .description(\"Show gateway status\")\n .action(async () => {\n const { gatewayStatus } = await import(\"./gateway-cmd.js\");\n await gatewayStatus();\n });\n\ngateway\n .command(\"restart\")\n .description(\"Restart the gateway daemon\")\n .action(async () => {\n const { gatewayStop, gatewayStartBackground } = await import(\"./gateway-cmd.js\");\n await gatewayStop();\n await new Promise((r) => setTimeout(r, 1000));\n await gatewayStartBackground();\n });\n\n// clank setup — onboarding wizard\nprogram\n .command(\"setup\")\n .description(\"Run the onboarding wizard\")\n .option(\"--quick\", \"Quick Start with sensible defaults\")\n .option(\"--advanced\", \"Advanced setup with full control\")\n .option(\"--section <name>\", \"Reconfigure a specific section\")\n .option(\"--non-interactive\", \"Non-interactive mode for scripting\")\n .option(\"--accept-risk\", \"Accept security disclaimer\")\n .action(async (opts) => {\n const { runSetup } = await import(\"./setup.js\");\n await runSetup(opts);\n });\n\n// clank fix — diagnostics & repair\nprogram\n .command(\"fix\")\n .description(\"Run diagnostics and repair\")\n .option(\"--auto\", \"Attempt automatic repairs\")\n .option(\"--check <system>\", \"Check a specific system\")\n .action(async (opts) => {\n const { runFix } = await import(\"./fix.js\");\n await runFix(opts);\n });\n\n// clank models — model management\nconst models = program\n .command(\"models\")\n .description(\"Manage models and providers\");\n\nmodels\n .command(\"list\")\n .description(\"List available models\")\n .action(async () => {\n const { modelsList } = await import(\"./models.js\");\n await modelsList();\n });\n\nmodels\n .command(\"add\")\n .description(\"Add a model provider\")\n .action(async () => {\n const { modelsAdd } = await import(\"./models.js\");\n await modelsAdd();\n });\n\nmodels\n .command(\"test\")\n .description(\"Test model connectivity\")\n .action(async () => {\n const { modelsTest } = await import(\"./models.js\");\n await modelsTest();\n });\n\n// clank agents — agent management\nconst agents = program\n .command(\"agents\")\n .description(\"Manage agents and routing\");\n\nagents\n .command(\"list\")\n .description(\"List configured agents\")\n .action(async () => {\n const { agentsList } = await import(\"./agents.js\");\n await agentsList();\n });\n\nagents\n .command(\"add\")\n .description(\"Add a new agent\")\n .action(async () => {\n const { agentsAdd } = await import(\"./agents.js\");\n await agentsAdd();\n });\n\nagents\n .command(\"routing\")\n .description(\"Show routing rules\")\n .action(async () => {\n const { agentsRouting } = await import(\"./agents.js\");\n await agentsRouting();\n });\n\n// clank daemon — system service management\nconst daemon = program\n .command(\"daemon\")\n .description(\"Manage the system service\");\n\ndaemon\n .command(\"install\")\n .description(\"Install Clank as a system service\")\n .action(async () => {\n const { installDaemon } = await import(\"../daemon/index.js\");\n await installDaemon();\n });\n\ndaemon\n .command(\"uninstall\")\n .description(\"Remove the system service\")\n .action(async () => {\n const { uninstallDaemon } = await import(\"../daemon/index.js\");\n await uninstallDaemon();\n });\n\ndaemon\n .command(\"status\")\n .description(\"Show system service status\")\n .action(async () => {\n const { daemonStatus } = await import(\"../daemon/index.js\");\n await daemonStatus();\n });\n\n// clank tui — launch TUI (connects to gateway)\nprogram\n .command(\"tui\")\n .description(\"Launch the terminal UI (connects to gateway)\")\n .option(\"--url <url>\", \"Gateway WebSocket URL\")\n .option(\"--token <token>\", \"Auth token\")\n .option(\"--session <key>\", \"Session to resume\")\n .action(async (opts) => {\n const { runTui } = await import(\"./tui.js\");\n await runTui(opts);\n });\n\n// clank dashboard — open Web UI in browser\nprogram\n .command(\"dashboard\")\n .description(\"Open the Web UI in your browser\")\n .option(\"--no-open\", \"Don't auto-open browser\")\n .action(async (opts) => {\n const { loadConfig } = await import(\"../config/index.js\");\n const config = await loadConfig();\n const port = config.gateway.port || 18789;\n const token = config.gateway.auth.token || \"\";\n const url = `http://127.0.0.1:${port}/#token=${token}`;\n console.log(`\\n Web UI: ${url}\\n`);\n if (opts.open !== false) {\n const { platform } = await import(\"node:os\");\n const { exec } = await import(\"node:child_process\");\n const cmd = platform() === \"win32\" ? `start ${url}` : platform() === \"darwin\" ? `open ${url}` : `xdg-open ${url}`;\n exec(cmd);\n }\n });\n\n// clank pipeline — manage pipelines\nconst pipeline = program\n .command(\"pipeline\")\n .description(\"Manage agent pipelines\");\n\npipeline\n .command(\"list\")\n .description(\"List pipeline definitions\")\n .action(async () => {\n console.log(\" No pipelines configured. Define pipelines in config or through conversation.\");\n });\n\npipeline\n .command(\"run <name>\")\n .description(\"Run a pipeline\")\n .option(\"--input <text>\", \"Input text for the pipeline\")\n .action(async (name, opts) => {\n console.log(` Running pipeline: ${name}...`);\n console.log(\" Pipeline CLI execution coming soon. Use the Web UI or conversation.\");\n });\n\npipeline\n .command(\"status <id>\")\n .description(\"Check pipeline execution status\")\n .action(async (id) => {\n console.log(` Pipeline ${id}: status check coming soon.`);\n });\n\n// clank cron — manage cron jobs\nconst cron = program\n .command(\"cron\")\n .description(\"Manage scheduled jobs\");\n\ncron\n .command(\"list\")\n .description(\"List cron jobs\")\n .action(async () => {\n const { join } = await import(\"node:path\");\n const { getConfigDir } = await import(\"../config/index.js\");\n const { CronScheduler } = await import(\"../cron/index.js\");\n const scheduler = new CronScheduler(join(getConfigDir(), \"cron\"));\n await scheduler.init();\n const jobs = scheduler.listJobs();\n if (jobs.length === 0) { console.log(\" No cron jobs.\"); return; }\n for (const j of jobs) {\n console.log(` ${j.id.slice(0,8)} | ${j.name} | ${j.schedule} | ${j.enabled ? \"enabled\" : \"disabled\"} | agent: ${j.agentId}`);\n }\n });\n\ncron\n .command(\"add\")\n .description(\"Add a cron job\")\n .requiredOption(\"--schedule <expr>\", \"Schedule (e.g., '1h', '30m', 'daily')\")\n .requiredOption(\"--prompt <text>\", \"What the agent should do\")\n .option(\"--name <name>\", \"Job name\")\n .option(\"--agent <id>\", \"Agent ID\", \"default\")\n .action(async (opts) => {\n const { join } = await import(\"node:path\");\n const { getConfigDir } = await import(\"../config/index.js\");\n const { CronScheduler } = await import(\"../cron/index.js\");\n const scheduler = new CronScheduler(join(getConfigDir(), \"cron\"));\n await scheduler.init();\n const job = await scheduler.addJob({\n name: opts.name || \"CLI Job\",\n schedule: opts.schedule,\n agentId: opts.agent,\n prompt: opts.prompt,\n });\n console.log(` Job created: ${job.id.slice(0,8)} — \"${job.name}\" every ${job.schedule}`);\n });\n\ncron\n .command(\"remove <id>\")\n .description(\"Remove a cron job\")\n .action(async (id) => {\n const { join } = await import(\"node:path\");\n const { getConfigDir } = await import(\"../config/index.js\");\n const { CronScheduler } = await import(\"../cron/index.js\");\n const scheduler = new CronScheduler(join(getConfigDir(), \"cron\"));\n await scheduler.init();\n const removed = await scheduler.removeJob(id);\n console.log(removed ? ` Job ${id.slice(0,8)} removed` : ` Job not found`);\n });\n\n// clank channels — channel status\nprogram\n .command(\"channels\")\n .description(\"Show channel adapter status\")\n .action(async () => {\n const { loadConfig } = await import(\"../config/index.js\");\n const config = await loadConfig();\n const channels = config.channels || {};\n console.log(\" Channels:\");\n for (const [name, cfg] of Object.entries(channels)) {\n const c = cfg as Record<string, unknown>;\n console.log(` ${name}: ${c.enabled ? \"\\x1b[32menabled\\x1b[0m\" : \"\\x1b[2mdisabled\\x1b[0m\"}`);\n }\n if (Object.keys(channels).length === 0) console.log(\" (none configured)\");\n });\n\n// clank update — pull latest, rebuild, restart\nprogram\n .command(\"update\")\n .description(\"Update Clank to the latest version and restart gateway\")\n .action(async () => {\n const { runUpdate } = await import(\"./update.js\");\n await runUpdate();\n });\n\n// clank uninstall — remove everything\nprogram\n .command(\"uninstall\")\n .description(\"Remove Clank completely (config, data, service, package)\")\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\n .action(async (opts) => {\n const { runUninstall } = await import(\"./uninstall.js\");\n await runUninstall(opts);\n });\n\n// Default: if no subcommand, ensure gateway is running then launch TUI\nprogram.action(async () => {\n const { gatewayStartBackground, isGatewayRunning } = await import(\"./gateway-cmd.js\");\n\n // Ensure gateway is running in the background (Telegram/Discord stay alive)\n if (!(await isGatewayRunning())) {\n await gatewayStartBackground();\n }\n\n // Launch TUI connected to the gateway\n const { runTui } = await import(\"./tui.js\");\n await runTui({});\n});\n\nprogram.parse();\n"],"mappings":"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","names":["resolve","mkdir","init_types","init_types","readFile","isAbsolute","readFile","writeFile","isAbsolute","stat","join","readdir","readFile","stat","join","relative","readdir","stat","join","IGNORE_DIRS","resolve","isAbsolute","platform","execFile","resolve","isAbsolute","readFile","writeFile","mkdir","existsSync","join","platform","EventEmitter","init_config","loadConfig","text","init_config","init_config","init_config","agents","last","CONTEXT_WINDOWS","CONTEXT_WINDOWS","models","init_config","readFile","writeFile","mkdir","existsSync","join","path","join","init_config","readFile","mkdir","writeFile","existsSync","join","randomUUID","join","init_config","init_config","writeFile","unlink","execSync","join","init_config","writeFile","join","readFile","existsSync","init_types","join","fork","fileURLToPath","dirname","__filename","platform","exec","resolve","rl","init_config","readFile","writeFile","readdir","mkdir","existsSync","join","randomUUID","path","init_memory","agents","gateway","STTEngine","loadConfig","TTSEngine","agents","gateway","gateway","readdir","readFile","existsSync","join","homedir","readFile","join","dirname","fileURLToPath","init_memory","init_config","randomBytes","resolve","__dirname","redactConfig","loadConfig","saveConfig","writeFile","readFile","unlink","existsSync","join","dirname","fileURLToPath","green","dim","red","__filename","mkdir","init_config","writeFile","mkdir","unlink","join","homedir","platform","red","green","dim","createInterface","dirname","join","fileURLToPath","resolve","bold","cyan","dim","green","yellow","ensureWorkspaceFiles","__dirname","init_config","existsSync","readdir","join","dim","green","yellow","models","red","init_config","dim","green","createInterface","ask","cyan","resolveWithFallback","init_config","dim","createInterface","ask","cyan","green","init_config","createInterface","WebSocket","dim","runChat","bold","red","resolve","check","cyan","execSync","handleSlashCommand","green","init_config","execSync","dim","gatewayStop","red","green","gatewayStartBackground","createInterface","existsSync","bold","red","dim","resolve","yellow","uninstallDaemon","green","execSync","init_config","fileURLToPath","dirname","join","__filename","__dirname","runChat","gatewayStart","gatewayStop","gatewayStatus","gatewayStartBackground","runSetup","runFix","modelsList","modelsAdd","modelsTest","agentsList","agentsAdd","agentsRouting","installDaemon","uninstallDaemon","daemonStatus","runTui","loadConfig","platform","exec","getConfigDir","CronScheduler","runUpdate","runUninstall","isGatewayRunning"]}
1
+ {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/engine/context-engine.ts","../src/providers/types.ts","../src/providers/ollama.ts","../src/providers/prompt-fallback.ts","../src/engine/agent.ts","../src/engine/system-prompt.ts","../src/engine/index.ts","../src/tools/types.ts","../src/tools/registry.ts","../src/tools/path-guard.ts","../src/tools/read-file.ts","../src/tools/write-file.ts","../src/tools/edit-file.ts","../src/tools/list-directory.ts","../src/tools/search-files.ts","../src/tools/glob-files.ts","../src/tools/bash.ts","../src/tools/git.ts","../src/config/config.ts","../src/config/watcher.ts","../src/config/index.ts","../src/tools/web-search.ts","../src/tools/web-fetch.ts","../src/config/redact.ts","../src/tools/self-config/config-tool.ts","../src/tools/self-config/channel-tool.ts","../src/tools/self-config/agent-tool.ts","../src/providers/anthropic.ts","../src/providers/openai.ts","../src/providers/google.ts","../src/providers/router.ts","../src/providers/index.ts","../src/tools/self-config/model-tool.ts","../src/sessions/store.ts","../src/sessions/index.ts","../src/tools/self-config/session-tool.ts","../src/cron/scheduler.ts","../src/cron/index.ts","../src/tools/self-config/cron-tool.ts","../src/gateway/protocol.ts","../src/tools/self-config/gateway-tool.ts","../src/tools/self-config/message-tool.ts","../src/voice/tts.ts","../src/voice/index.ts","../src/tools/self-config/voice-tool.ts","../src/tools/self-config/index.ts","../src/tools/index.ts","../src/cli/chat.ts","../src/memory/memory.ts","../src/memory/index.ts","../src/routing/resolve-route.ts","../src/routing/index.ts","../src/adapters/base.ts","../src/adapters/telegram.ts","../src/adapters/discord.ts","../src/adapters/web.ts","../src/plugins/loader.ts","../src/plugins/index.ts","../src/gateway/server.ts","../src/gateway/index.ts","../src/cli/gateway-cmd.ts","../src/daemon/install.ts","../src/daemon/index.ts","../src/cli/setup.ts","../src/cli/fix.ts","../src/cli/models.ts","../src/cli/agents.ts","../src/cli/tui.ts","../src/cli/update.ts","../src/cli/uninstall.ts","../src/cli/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * Context engine — two-tier compaction for local model optimization.\n *\n * Local models typically have 8K-32K context windows vs 128K-200K for cloud.\n * Smart compaction is what makes the difference between a usable local\n * agent and one that constantly errors out.\n *\n * Tier 1 (fast, every turn):\n * - System prompt token budgeting\n * - Tool result deduplication (same file read twice → keep latest)\n * - Tool result summarization (>500 chars → first 3 + last 2 lines)\n * - Long assistant message truncation (>3000 chars → first 1000)\n * - Oldest message dropping as last resort\n *\n * Tier 2 (LLM-summarized, when tier 1 isn't enough):\n * - Uses the model to generate a conversation summary\n * - Replaces oldest N messages with a single recap message\n * - Preserves meaning instead of just chopping text\n * - Adds latency but keeps the agent coherent over long sessions\n */\n\nimport type { Message } from \"../providers/types.js\";\nimport type { BaseProvider } from \"../providers/types.js\";\n\nexport interface CompactionResult {\n ok: boolean;\n tier: 1 | 2;\n messagesBefore: number;\n messagesAfter: number;\n estimatedTokensBefore: number;\n estimatedTokensAfter: number;\n}\n\n/** Budget allocation for system prompt vs conversation */\ninterface TokenBudget {\n systemPrompt: number;\n conversation: number;\n responseReserve: number;\n}\n\nexport class ContextEngine {\n private messages: Message[] = [];\n private contextWindowSize: number;\n private isLocal: boolean;\n private systemPromptTokens: number = 0;\n /** Provider for tier 2 LLM-summarized compaction */\n private provider: BaseProvider | null = null;\n private modelId: string = \"\";\n /** Cache of tool results by file path to detect duplicates */\n private toolResultHashes = new Map<string, number>();\n\n constructor(opts: { contextWindow: number; isLocal: boolean }) {\n this.contextWindowSize = opts.contextWindow;\n this.isLocal = opts.isLocal;\n }\n\n /** Set the provider for tier 2 compaction */\n setProvider(provider: BaseProvider, modelId: string): void {\n this.provider = provider;\n this.modelId = modelId;\n }\n\n /** Set the system prompt size for token budgeting */\n setSystemPromptSize(tokens: number): void {\n this.systemPromptTokens = tokens;\n }\n\n /** Get all messages */\n getMessages(): Message[] {\n return this.messages;\n }\n\n /** Set messages (e.g., when loading a session) */\n setMessages(messages: Message[]): void {\n this.messages = [...messages];\n }\n\n /** Add a message to the context */\n ingest(message: Message): void {\n this.messages.push(message);\n }\n\n /** Add multiple messages */\n ingestBatch(messages: Message[]): void {\n this.messages.push(...messages);\n }\n\n /**\n * Estimate total tokens in the current context.\n * Uses ~4 chars per token as a rough estimate.\n */\n estimateTokens(): number {\n let chars = 0;\n for (const msg of this.messages) {\n if (typeof msg.content === \"string\") {\n chars += msg.content.length;\n } else {\n chars += JSON.stringify(msg.content).length;\n }\n }\n return Math.ceil(chars / 4);\n }\n\n /** Calculate token budgets */\n private getBudget(): TokenBudget {\n // Reserve 25% of context for the model's response\n const responseReserve = Math.floor(this.contextWindowSize * 0.25);\n const available = this.contextWindowSize - responseReserve;\n // System prompt gets what it needs, conversation gets the rest\n const systemPrompt = Math.min(this.systemPromptTokens, Math.floor(available * 0.3));\n const conversation = available - systemPrompt;\n return { systemPrompt, conversation, responseReserve };\n }\n\n /** Get context utilization as a percentage of the conversation budget */\n utilizationPercent(): number {\n const budget = this.getBudget();\n return (this.estimateTokens() / budget.conversation) * 100;\n }\n\n /**\n * Check if compaction is needed.\n * Local models trigger earlier (60%) to leave room for the response.\n * Cloud models can wait longer (80%).\n */\n needsCompaction(): boolean {\n const threshold = this.isLocal ? 60 : 80;\n return this.utilizationPercent() >= threshold;\n }\n\n /**\n * Run compaction — tier 1 first, tier 2 if still over budget.\n * Returns the result with which tier was used.\n */\n async compactSmart(): Promise<CompactionResult> {\n const before = this.messages.length;\n const tokensBefore = this.estimateTokens();\n\n // Tier 1: mechanical compaction\n this.compactTier1();\n\n // Check if tier 1 was enough\n if (this.utilizationPercent() < 70) {\n return {\n ok: true,\n tier: 1,\n messagesBefore: before,\n messagesAfter: this.messages.length,\n estimatedTokensBefore: tokensBefore,\n estimatedTokensAfter: this.estimateTokens(),\n };\n }\n\n // Tier 2: LLM-summarized compaction\n if (this.provider) {\n await this.compactTier2();\n } else {\n // No provider — aggressive tier 1 fallback (drop more messages)\n this.compactTier1Aggressive();\n }\n\n return {\n ok: true,\n tier: this.provider ? 2 : 1,\n messagesBefore: before,\n messagesAfter: this.messages.length,\n estimatedTokensBefore: tokensBefore,\n estimatedTokensAfter: this.estimateTokens(),\n };\n }\n\n /** Synchronous compact (backward compat — uses tier 1 only) */\n compact(): CompactionResult {\n const before = this.messages.length;\n const tokensBefore = this.estimateTokens();\n\n this.compactTier1();\n\n if (this.utilizationPercent() >= 70) {\n this.compactTier1Aggressive();\n }\n\n return {\n ok: true,\n tier: 1,\n messagesBefore: before,\n messagesAfter: this.messages.length,\n estimatedTokensBefore: tokensBefore,\n estimatedTokensAfter: this.estimateTokens(),\n };\n }\n\n /**\n * Tier 1: Fast mechanical compaction (no LLM calls).\n */\n private compactTier1(): void {\n const protectedCount = 6;\n if (this.messages.length <= protectedCount) return;\n\n const protectedZone = this.messages.slice(-protectedCount);\n const compactable = this.messages.slice(0, -protectedCount);\n const compacted: Message[] = [];\n\n // Pass 1: Deduplicate tool results (same tool+path → keep latest only)\n const seenToolResults = new Map<string, number>();\n for (let i = compactable.length - 1; i >= 0; i--) {\n const msg = compactable[i];\n if (msg.role === \"tool\" && msg.tool_call_id) {\n const content = typeof msg.content === \"string\" ? msg.content : \"\";\n // Extract a dedup key from the tool call (e.g., read_file:/path)\n const key = msg.tool_call_id;\n if (!seenToolResults.has(key)) {\n seenToolResults.set(key, i);\n }\n }\n }\n\n // Pass 2: Compact messages\n for (let i = 0; i < compactable.length; i++) {\n const msg = compactable[i];\n\n if (msg._compacted) {\n compacted.push(msg);\n continue;\n }\n\n const content = typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content);\n\n if (msg.role === \"tool\") {\n // Summarize long tool results\n if (content.length > 500) {\n const lines = content.split(\"\\n\");\n const summary = [\n ...lines.slice(0, 3),\n `... (${lines.length - 5} lines omitted)`,\n ...lines.slice(-2),\n ].join(\"\\n\");\n compacted.push({ ...msg, content: summary, _compacted: true });\n } else {\n compacted.push(msg);\n }\n } else if (msg.role === \"assistant\") {\n // Truncate long assistant messages\n if (content.length > 3000) {\n compacted.push({\n ...msg,\n content: content.slice(0, 1000) + \"\\n... (truncated)\",\n _compacted: true,\n });\n } else {\n compacted.push(msg);\n }\n } else if (msg.role === \"user\") {\n // Truncate very long user messages\n if (content.length > 2000) {\n compacted.push({\n ...msg,\n content: content.slice(0, 800) + \"\\n... (truncated)\",\n _compacted: true,\n });\n } else {\n compacted.push(msg);\n }\n } else {\n compacted.push(msg);\n }\n }\n\n this.messages = [...compacted, ...protectedZone];\n }\n\n /**\n * Tier 1 aggressive: drop oldest messages when regular compaction isn't enough.\n */\n private compactTier1Aggressive(): void {\n const protectedCount = 6;\n const budget = this.getBudget();\n\n while (this.estimateTokens() > budget.conversation * 0.7 && this.messages.length > protectedCount + 2) {\n // Find the first non-system message to drop\n const dropIdx = this.messages.findIndex((m) => m.role !== \"system\");\n if (dropIdx === -1 || dropIdx >= this.messages.length - protectedCount) break;\n this.messages.splice(dropIdx, 1);\n }\n }\n\n /**\n * Tier 2: LLM-summarized compaction.\n *\n * Takes the oldest messages (outside protected zone), sends them to\n * the model with a summarization prompt, and replaces them with a\n * single \"conversation recap\" message. This preserves meaning that\n * mechanical truncation loses.\n */\n private async compactTier2(): Promise<void> {\n if (!this.provider) return;\n\n const protectedCount = 6;\n if (this.messages.length <= protectedCount + 2) return;\n\n // Take the older half of the conversation for summarization\n const cutoff = Math.max(2, this.messages.length - protectedCount - 2);\n const toSummarize = this.messages.slice(0, cutoff);\n const toKeep = this.messages.slice(cutoff);\n\n // Build the summarization prompt\n const conversationText = toSummarize\n .map((m) => {\n const content = typeof m.content === \"string\" ? m.content : JSON.stringify(m.content);\n const truncated = content.length > 500 ? content.slice(0, 500) + \"...\" : content;\n return `${m.role}: ${truncated}`;\n })\n .join(\"\\n\\n\");\n\n const summaryPrompt = [\n \"Summarize this conversation concisely. Capture:\",\n \"- Key decisions made\",\n \"- Files modified and why\",\n \"- Current task status\",\n \"- Important context the assistant needs going forward\",\n \"\",\n \"Be brief (under 300 words). Use bullet points.\",\n \"\",\n \"Conversation:\",\n conversationText,\n ].join(\"\\n\");\n\n try {\n // Use the model to generate a summary\n let summary = \"\";\n for await (const event of this.provider.stream(\n [{ role: \"user\", content: summaryPrompt }],\n \"You are a conversation summarizer. Output only the summary, nothing else.\",\n [], // no tools\n )) {\n if (event.type === \"text\") {\n summary += event.content;\n }\n }\n\n if (summary.trim()) {\n // Replace old messages with the summary\n const recapMessage: Message = {\n role: \"user\",\n content: `[Conversation recap — earlier messages were compacted]\\n\\n${summary.trim()}`,\n _compacted: true,\n };\n\n this.messages = [recapMessage, ...toKeep];\n }\n } catch {\n // LLM summary failed — fall back to aggressive tier 1\n this.compactTier1Aggressive();\n }\n }\n\n /** Clear all messages */\n clear(): void {\n this.messages = [];\n this.toolResultHashes.clear();\n }\n\n /** Update the context window size */\n setContextWindow(size: number): void {\n this.contextWindowSize = size;\n }\n}\n","/**\n * Provider type definitions.\n *\n * All providers return the same stream event format regardless of the\n * underlying API. This abstraction lets the agent engine treat Ollama,\n * Anthropic, OpenAI, and Google identically.\n */\n\n/** Events yielded by provider.stream() */\nexport type StreamEvent =\n | { type: \"text\"; content: string }\n | { type: \"thinking\"; content: string }\n | { type: \"tool_call\"; id: string; name: string; arguments: Record<string, unknown> }\n | { type: \"usage\"; promptTokens: number; outputTokens: number; evalDurationNs?: number }\n | { type: \"done\" };\n\n/** Tool definition in the format passed to providers */\nexport interface ToolDefinition {\n name: string;\n description: string;\n parameters: {\n type: \"object\";\n properties: Record<string, unknown>;\n required?: string[];\n };\n}\n\n/** Message in conversation history */\nexport interface Message {\n role: \"system\" | \"user\" | \"assistant\" | \"tool\";\n content: string | ContentBlock[];\n /** For tool result messages */\n tool_call_id?: string;\n /** For assistant messages with tool calls */\n tool_calls?: ToolCallMessage[];\n /** Marks messages that have been compacted */\n _compacted?: boolean;\n}\n\nexport interface ContentBlock {\n type: \"text\" | \"image\" | \"tool_use\" | \"tool_result\";\n text?: string;\n id?: string;\n name?: string;\n input?: Record<string, unknown>;\n content?: string;\n is_error?: boolean;\n}\n\nexport interface ToolCallMessage {\n id: string;\n type: \"function\";\n function: {\n name: string;\n arguments: string;\n };\n}\n\n/**\n * Per-model compatibility config.\n *\n * Different models (especially local ones) have quirks — some don't support\n * tools natively, some need different thinking formats, some have weird\n * max_tokens field names. This config lets us handle all of that.\n */\nexport interface ModelCompatConfig {\n supportsTools?: boolean;\n supportsStreaming?: boolean;\n supportsImages?: boolean;\n /** How thinking/reasoning blocks are formatted */\n thinkingFormat?: \"anthropic\" | \"openai\" | \"qwen\" | \"none\";\n /** Field name for max output tokens */\n maxTokensField?: \"max_tokens\" | \"max_completion_tokens\";\n /** Some models need tool result messages to include the tool name */\n requiresToolResultName?: boolean;\n /** Some models need an assistant message after tool results */\n requiresAssistantAfterToolResult?: boolean;\n /** Max output tokens override */\n maxOutputTokens?: number;\n}\n\n/** Provider resolution result from the router */\nexport interface ResolvedProvider {\n provider: BaseProvider;\n providerName: string;\n modelId: string;\n isLocal: boolean;\n}\n\n/** Model entry in config */\nexport interface ModelConfig {\n primary: string;\n fallbacks?: string[];\n temperature?: number;\n maxResponseTokens?: number;\n}\n\n/**\n * Base provider interface.\n *\n * Every LLM provider (Ollama, Anthropic, OpenAI, Google) implements this.\n * The stream() method is an async generator that yields StreamEvents,\n * giving the agent engine a unified interface regardless of backend.\n */\nexport abstract class BaseProvider {\n abstract readonly name: string;\n\n /** Convert tool definitions to the provider's native format */\n abstract formatTools(tools: ToolDefinition[]): unknown[];\n\n /**\n * Stream a completion from the model.\n * Yields StreamEvents in a normalized format.\n */\n abstract stream(\n messages: Message[],\n systemPrompt: string,\n tools: ToolDefinition[],\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent>;\n\n /** Rough token estimate (~4 chars per token) */\n estimateTokens(messages: Message[]): number {\n const text = messages\n .map((m) => (typeof m.content === \"string\" ? m.content : JSON.stringify(m.content)))\n .join(\"\");\n return Math.ceil(text.length / 4);\n }\n\n /** Max context window size in tokens */\n abstract contextWindow(): number;\n\n /** Format an assistant tool use for message history */\n abstract formatAssistantToolUse(\n toolCallId: string,\n name: string,\n args: Record<string, unknown>,\n ): Message;\n\n /** Format a tool result for message history */\n abstract formatToolResult(\n toolCallId: string,\n name: string,\n result: string,\n isError?: boolean,\n ): Message;\n}\n","/**\n * Ollama provider — the primary provider for Clank.\n *\n * Uses the OpenAI-compatible API that Ollama exposes at /v1/.\n * Key local-model optimizations:\n * - Dynamic context window detection via /api/show\n * - Tool support checking against known model patterns\n * - Response token capping for smaller models\n */\n\nimport {\n BaseProvider,\n type Message,\n type StreamEvent,\n type ToolDefinition,\n} from \"./types.js\";\n\n/** Models known to support native tool calling */\nconst TOOL_CAPABLE_PATTERNS = [\n /^llama3\\.[1-9]/i,\n /^llama-3\\.[1-9]/i,\n /^qwen[23]/i,\n /^mistral-nemo/i,\n /^mistral-large/i,\n /^command-r/i,\n /^firefunction/i,\n /^hermes-[23]/i,\n /^nemotron/i,\n];\n\n/** Cache for context window sizes per model */\nconst contextWindowCache = new Map<string, number>();\n\nexport class OllamaProvider extends BaseProvider {\n readonly name = \"ollama\";\n private baseUrl: string;\n private model: string;\n private maxResponseTokens?: number;\n\n constructor(opts: {\n baseUrl?: string;\n model: string;\n maxResponseTokens?: number;\n }) {\n super();\n this.baseUrl = (opts.baseUrl || \"http://127.0.0.1:11434\").replace(/\\/$/, \"\");\n this.model = opts.model;\n this.maxResponseTokens = opts.maxResponseTokens;\n }\n\n /**\n * Auto-detect Ollama by probing /api/tags.\n * Returns the list of available models, or null if Ollama isn't running.\n */\n static async detect(baseUrl = \"http://127.0.0.1:11434\"): Promise<string[] | null> {\n try {\n const res = await fetch(`${baseUrl}/api/tags`, { signal: AbortSignal.timeout(3000) });\n if (!res.ok) return null;\n const data = (await res.json()) as { models?: Array<{ name: string }> };\n return data.models?.map((m) => m.name) ?? [];\n } catch {\n return null;\n }\n }\n\n /**\n * Detect the context window for a model via /api/show.\n * Caches the result since this doesn't change at runtime.\n */\n async detectContextWindow(): Promise<number> {\n const cached = contextWindowCache.get(this.model);\n if (cached) return cached;\n\n try {\n const res = await fetch(`${this.baseUrl}/api/show`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ name: this.model }),\n signal: AbortSignal.timeout(5000),\n });\n if (!res.ok) return 32768;\n\n const data = (await res.json()) as {\n model_info?: Record<string, unknown>;\n parameters?: string;\n };\n\n // Check model_info for context length keys\n if (data.model_info) {\n for (const [key, value] of Object.entries(data.model_info)) {\n if (\n key.includes(\"context_length\") ||\n key.includes(\"context_window\") ||\n key.includes(\"num_ctx\")\n ) {\n const ctx = Number(value);\n if (ctx > 0) {\n contextWindowCache.set(this.model, ctx);\n return ctx;\n }\n }\n }\n }\n\n // Check parameters string for num_ctx\n if (data.parameters) {\n const match = data.parameters.match(/num_ctx\\s+(\\d+)/);\n if (match) {\n const ctx = parseInt(match[1], 10);\n contextWindowCache.set(this.model, ctx);\n return ctx;\n }\n }\n } catch {\n // Fall through to default\n }\n\n const defaultCtx = 32768;\n contextWindowCache.set(this.model, defaultCtx);\n return defaultCtx;\n }\n\n /** Check if a model supports native tool calling */\n static supportsTools(model: string): boolean {\n const baseName = model.split(\":\")[0];\n return TOOL_CAPABLE_PATTERNS.some((p) => p.test(baseName));\n }\n\n contextWindow(): number {\n return contextWindowCache.get(this.model) ?? 32768;\n }\n\n formatTools(tools: ToolDefinition[]): unknown[] {\n return tools.map((t) => ({\n type: \"function\",\n function: {\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n },\n }));\n }\n\n async *stream(\n messages: Message[],\n systemPrompt: string,\n tools: ToolDefinition[],\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n // Build OpenAI-compatible messages array\n const apiMessages: Array<Record<string, unknown>> = [];\n\n if (systemPrompt) {\n apiMessages.push({ role: \"system\", content: systemPrompt });\n }\n\n for (const msg of messages) {\n if (msg.role === \"tool\") {\n apiMessages.push({\n role: \"tool\",\n tool_call_id: msg.tool_call_id,\n content: typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content),\n });\n } else if (msg.role === \"assistant\" && msg.tool_calls) {\n apiMessages.push({\n role: \"assistant\",\n content: typeof msg.content === \"string\" ? msg.content : null,\n tool_calls: msg.tool_calls,\n });\n } else {\n apiMessages.push({\n role: msg.role,\n content: typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content),\n });\n }\n }\n\n const body: Record<string, unknown> = {\n model: this.model,\n messages: apiMessages,\n stream: true,\n };\n\n if (tools.length > 0 && OllamaProvider.supportsTools(this.model)) {\n body.tools = this.formatTools(tools);\n }\n\n if (this.maxResponseTokens) {\n body.max_tokens = this.maxResponseTokens;\n }\n\n const res = await fetch(`${this.baseUrl}/v1/chat/completions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"Unknown error\");\n throw new Error(`Ollama API error ${res.status}: ${text}`);\n }\n\n if (!res.body) {\n throw new Error(\"No response body from Ollama\");\n }\n\n // Parse SSE stream\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n const toolCalls = new Map<number, { id: string; name: string; arguments: string }>();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || !trimmed.startsWith(\"data: \")) continue;\n\n const data = trimmed.slice(6);\n if (data === \"[DONE]\") {\n // Emit any accumulated tool calls\n for (const tc of toolCalls.values()) {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(tc.arguments) as Record<string, unknown>;\n } catch {\n parsedArgs = {};\n }\n yield { type: \"tool_call\", id: tc.id, name: tc.name, arguments: parsedArgs };\n }\n yield { type: \"done\" };\n return;\n }\n\n try {\n const chunk = JSON.parse(data) as {\n choices?: Array<{\n delta?: {\n content?: string | null;\n tool_calls?: Array<{\n index: number;\n id?: string;\n function?: { name?: string; arguments?: string };\n }>;\n };\n finish_reason?: string | null;\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n };\n\n const choice = chunk.choices?.[0];\n if (!choice) continue;\n\n // Text content\n if (choice.delta?.content) {\n yield { type: \"text\", content: choice.delta.content };\n }\n\n // Tool calls (accumulated across chunks)\n if (choice.delta?.tool_calls) {\n for (const tc of choice.delta.tool_calls) {\n const existing = toolCalls.get(tc.index);\n if (existing) {\n if (tc.function?.arguments) {\n existing.arguments += tc.function.arguments;\n }\n } else {\n toolCalls.set(tc.index, {\n id: tc.id || `call_${tc.index}`,\n name: tc.function?.name || \"\",\n arguments: tc.function?.arguments || \"\",\n });\n }\n }\n }\n\n // Usage info\n if (chunk.usage) {\n yield {\n type: \"usage\",\n promptTokens: chunk.usage.prompt_tokens ?? 0,\n outputTokens: chunk.usage.completion_tokens ?? 0,\n };\n }\n } catch {\n // Skip malformed JSON chunks\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n // If we exit without [DONE], still emit pending tool calls and done\n for (const tc of toolCalls.values()) {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(tc.arguments) as Record<string, unknown>;\n } catch {\n parsedArgs = {};\n }\n yield { type: \"tool_call\", id: tc.id, name: tc.name, arguments: parsedArgs };\n }\n yield { type: \"done\" };\n }\n\n formatAssistantToolUse(\n toolCallId: string,\n name: string,\n args: Record<string, unknown>,\n ): Message {\n return {\n role: \"assistant\",\n content: \"\",\n tool_calls: [\n {\n id: toolCallId,\n type: \"function\",\n function: { name, arguments: JSON.stringify(args) },\n },\n ],\n };\n }\n\n formatToolResult(\n toolCallId: string,\n _name: string,\n result: string,\n _isError?: boolean,\n ): Message {\n return {\n role: \"tool\",\n content: result,\n tool_call_id: toolCallId,\n };\n }\n}\n","/**\n * Prompt fallback provider.\n *\n * Wraps any provider to add tool support for models that don't have\n * native function calling. Instead of passing tools via the API, it:\n *\n * 1. Injects tool definitions into the system prompt as JSON specs\n * 2. Asks the model to respond with a specific format when using tools\n * 3. Parses the model's text output to extract tool calls via regex\n *\n * This is how smaller local models (llama3.2 3B, phi-3, etc.) can\n * still use tools — they just need to follow a text format instead\n * of producing structured function calls.\n */\n\nimport {\n BaseProvider,\n type Message,\n type StreamEvent,\n type ToolDefinition,\n} from \"./types.js\";\n\nconst TOOL_PROMPT_TEMPLATE = `\nYou have access to the following tools. To use a tool, respond with a JSON block in this exact format:\n\n\\`\\`\\`tool_call\n{\"name\": \"tool_name\", \"arguments\": {\"arg1\": \"value1\"}}\n\\`\\`\\`\n\nAvailable tools:\n`;\n\n/** Regex to extract tool calls from model text output */\nconst TOOL_CALL_REGEX = /```tool_call\\s*\\n?\\s*(\\{[\\s\\S]*?\\})\\s*\\n?\\s*```/g;\n\nexport class PromptFallbackProvider extends BaseProvider {\n readonly name: string;\n private wrapped: BaseProvider;\n\n constructor(wrapped: BaseProvider) {\n super();\n this.wrapped = wrapped;\n this.name = `${wrapped.name}+prompt-fallback`;\n }\n\n contextWindow(): number {\n return this.wrapped.contextWindow();\n }\n\n formatTools(_tools: ToolDefinition[]): unknown[] {\n // Tools are injected into the prompt, not passed to the API\n return [];\n }\n\n /**\n * Build the tool injection block for the system prompt.\n */\n private buildToolPrompt(tools: ToolDefinition[]): string {\n if (tools.length === 0) return \"\";\n\n let prompt = TOOL_PROMPT_TEMPLATE;\n for (const tool of tools) {\n prompt += `\\n### ${tool.name}\\n`;\n prompt += `${tool.description}\\n`;\n prompt += `Parameters: ${JSON.stringify(tool.parameters, null, 2)}\\n`;\n }\n prompt += \"\\nYou can use multiple tools in one response. After each tool call, wait for the result before proceeding.\\n\";\n prompt += \"If you don't need a tool, just respond normally with text.\\n\";\n return prompt;\n }\n\n async *stream(\n messages: Message[],\n systemPrompt: string,\n tools: ToolDefinition[],\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n // Inject tools into system prompt\n const augmentedPrompt = tools.length > 0\n ? systemPrompt + \"\\n\\n\" + this.buildToolPrompt(tools)\n : systemPrompt;\n\n // Collect the full response to parse for tool calls\n let fullText = \"\";\n\n for await (const event of this.wrapped.stream(messages, augmentedPrompt, [], signal)) {\n if (event.type === \"text\") {\n fullText += event.content;\n yield event;\n } else if (event.type === \"done\") {\n // Parse tool calls from the accumulated text\n const toolCalls = this.parseToolCalls(fullText);\n for (const tc of toolCalls) {\n yield tc;\n }\n yield event;\n } else {\n yield event;\n }\n }\n }\n\n /**\n * Parse tool calls from model text output.\n */\n private parseToolCalls(text: string): StreamEvent[] {\n const calls: StreamEvent[] = [];\n let match: RegExpExecArray | null;\n let callIndex = 0;\n\n // Reset regex state\n TOOL_CALL_REGEX.lastIndex = 0;\n\n while ((match = TOOL_CALL_REGEX.exec(text)) !== null) {\n try {\n const parsed = JSON.parse(match[1]) as {\n name?: string;\n arguments?: Record<string, unknown>;\n };\n\n if (parsed.name) {\n calls.push({\n type: \"tool_call\",\n id: `prompt_call_${callIndex++}`,\n name: parsed.name,\n arguments: parsed.arguments ?? {},\n });\n }\n } catch {\n // Malformed JSON in tool call block — skip\n }\n }\n\n return calls;\n }\n\n formatAssistantToolUse(\n toolCallId: string,\n name: string,\n args: Record<string, unknown>,\n ): Message {\n // For prompt-based tools, represent the tool call as text in the\n // assistant message so the model sees its own format\n return {\n role: \"assistant\",\n content: `\\`\\`\\`tool_call\\n${JSON.stringify({ name, arguments: args })}\\n\\`\\`\\``,\n };\n }\n\n formatToolResult(\n _toolCallId: string,\n name: string,\n result: string,\n isError?: boolean,\n ): Message {\n const prefix = isError ? `Error from ${name}` : `Result from ${name}`;\n return {\n role: \"user\",\n content: `${prefix}:\\n${result}`,\n };\n }\n}\n","/**\n * AgentEngine — the core of Clank.\n *\n * This is the ReAct loop: Reason → Act → Observe → Repeat.\n * The engine streams from an LLM provider, detects tool calls,\n * executes them (with user confirmation for risky ones), feeds\n * results back, and loops until the model responds with plain text.\n *\n * Events are emitted at every stage so frontends (CLI, Web, Telegram)\n * can display progress in real-time without knowing the internals.\n */\n\nimport { EventEmitter } from \"node:events\";\nimport { ContextEngine } from \"./context-engine.js\";\nimport { ToolRegistry, type ToolContext, type Tool, type ToolTier } from \"../tools/index.js\";\nimport {\n type BaseProvider,\n type Message,\n type StreamEvent,\n type ToolDefinition,\n type ResolvedProvider,\n} from \"../providers/types.js\";\nimport { OllamaProvider } from \"../providers/ollama.js\";\nimport { PromptFallbackProvider } from \"../providers/prompt-fallback.js\";\nimport { SessionStore, type SessionEntry } from \"../sessions/index.js\";\n\n/** Agent identity — who is this agent? */\nexport interface AgentIdentity {\n id: string;\n name: string;\n model: { primary: string; fallbacks?: string[] };\n workspace: string;\n toolTier: ToolTier;\n temperature?: number;\n maxResponseTokens?: number;\n tools?: { allow?: string[]; deny?: string[] };\n}\n\n/** Events the engine emits */\nexport interface AgentEvents {\n \"thinking-start\": () => void;\n \"thinking-stop\": () => void;\n \"response-start\": () => void;\n \"token\": (data: { content: string }) => void;\n \"response-end\": (data: { text: string }) => void;\n \"tool-start\": (data: { id: string; name: string; arguments: Record<string, unknown> }) => void;\n \"tool-result\": (data: { id: string; name: string; success: boolean; summary: string }) => void;\n \"confirm-needed\": (data: { actions: ConfirmAction[]; resolve: (approved: boolean | \"always\") => void }) => void;\n \"context-compacting\": () => void;\n \"usage\": (data: { promptTokens: number; outputTokens: number; iterationCount: number; contextPercent: number }) => void;\n \"error\": (data: { message: string; recoverable: boolean }) => void;\n \"turn-complete\": () => void;\n}\n\nexport interface ConfirmAction {\n toolName: string;\n description: string;\n safetyLevel: string;\n}\n\nconst MAX_ITERATIONS = 50;\n\nexport class AgentEngine extends EventEmitter {\n readonly identity: AgentIdentity;\n private contextEngine: ContextEngine;\n private toolRegistry: ToolRegistry;\n private resolvedProvider: ResolvedProvider | null = null;\n private sessionStore: SessionStore;\n private currentSession: SessionEntry | null = null;\n private abortController: AbortController | null = null;\n private systemPrompt: string = \"\";\n private autoApprove = { low: true, medium: false, high: false };\n /** Tools the user has approved \"always\" for this session */\n private alwaysApproved = new Set<string>();\n\n constructor(opts: {\n identity: AgentIdentity;\n toolRegistry: ToolRegistry;\n sessionStore: SessionStore;\n provider: ResolvedProvider;\n autoApprove?: { low: boolean; medium: boolean; high: boolean };\n systemPrompt?: string;\n }) {\n super();\n this.identity = opts.identity;\n this.toolRegistry = opts.toolRegistry;\n this.sessionStore = opts.sessionStore;\n this.resolvedProvider = opts.provider;\n if (opts.autoApprove) this.autoApprove = opts.autoApprove;\n if (opts.systemPrompt) this.systemPrompt = opts.systemPrompt;\n\n this.contextEngine = new ContextEngine({\n contextWindow: opts.provider.provider.contextWindow(),\n isLocal: opts.provider.isLocal,\n });\n\n // Wire provider into context engine for tier 2 LLM-summarized compaction\n this.contextEngine.setProvider(opts.provider.provider, opts.identity.model.primary);\n }\n\n /** Set the system prompt */\n setSystemPrompt(prompt: string): void {\n this.systemPrompt = prompt;\n // Update token budget in context engine\n this.contextEngine.setSystemPromptSize(Math.ceil(prompt.length / 4));\n }\n\n /** Load or create a session */\n async loadSession(normalizedKey: string, channel: string): Promise<void> {\n this.currentSession = await this.sessionStore.resolve(normalizedKey, {\n agentId: this.identity.id,\n channel,\n });\n\n const messages = await this.sessionStore.loadMessages(this.currentSession.id);\n this.contextEngine.setMessages(messages);\n\n // Detect context window for Ollama models\n if (this.resolvedProvider?.provider instanceof OllamaProvider) {\n const ctxSize = await (this.resolvedProvider.provider as OllamaProvider).detectContextWindow();\n this.contextEngine.setContextWindow(ctxSize);\n }\n }\n\n /** Cancel the current request */\n cancel(): void {\n this.abortController?.abort();\n this.emit(\"cancelled\");\n }\n\n /**\n * Send a message and get a response.\n * This is THE agent loop — the heart of Clank.\n */\n async sendMessage(text: string): Promise<string> {\n if (!this.resolvedProvider) {\n throw new Error(\"No provider configured\");\n }\n\n this.abortController = new AbortController();\n const signal = this.abortController.signal;\n\n // Add user message to context\n this.contextEngine.ingest({ role: \"user\", content: text });\n\n // Auto-title session from first message\n if (this.currentSession && !this.currentSession.label) {\n const label = text.length > 60 ? text.slice(0, 57) + \"...\" : text;\n await this.sessionStore.setLabel(this.currentSession.normalizedKey, label);\n }\n\n const provider = this.resolvedProvider.provider;\n const isLocal = this.resolvedProvider.isLocal;\n\n // Wrap provider with prompt fallback if model doesn't support tools\n let activeProvider: BaseProvider = provider;\n if (isLocal && provider instanceof OllamaProvider) {\n const modelName = this.identity.model.primary.split(\"/\").pop() || \"\";\n if (!OllamaProvider.supportsTools(modelName)) {\n activeProvider = new PromptFallbackProvider(provider);\n }\n }\n\n let fullResponse = \"\";\n let iterationCount = 0;\n\n try {\n // === THE REACT LOOP ===\n while (iterationCount < MAX_ITERATIONS) {\n iterationCount++;\n\n // Check if compaction is needed\n if (this.contextEngine.needsCompaction()) {\n this.emit(\"context-compacting\");\n // Use smart (async) compaction with LLM summary if available\n const compactResult = await this.contextEngine.compactSmart();\n if (compactResult.tier === 2) {\n this.emit(\"usage\", {\n promptTokens: 0, outputTokens: 0, iterationCount,\n contextPercent: Math.round(this.contextEngine.utilizationPercent()),\n });\n }\n }\n\n // Get tool definitions for this iteration\n const toolDefs = this.toolRegistry.getDefinitions({\n tier: this.identity.toolTier,\n userMessage: text,\n allowlist: this.identity.tools?.allow,\n denylist: this.identity.tools?.deny,\n });\n\n // Stream from the provider\n let iterationText = \"\";\n const toolCalls: Array<{ id: string; name: string; arguments: Record<string, unknown> }> = [];\n let promptTokens = 0;\n let outputTokens = 0;\n\n this.emit(\"response-start\");\n\n for await (const event of activeProvider.stream(\n this.contextEngine.getMessages(),\n this.systemPrompt,\n toolDefs,\n signal,\n )) {\n switch (event.type) {\n case \"text\":\n iterationText += event.content;\n this.emit(\"token\", { content: event.content });\n break;\n\n case \"thinking\":\n this.emit(\"thinking-start\");\n // Thinking content not added to visible response\n break;\n\n case \"tool_call\":\n toolCalls.push({\n id: event.id,\n name: event.name,\n arguments: event.arguments,\n });\n break;\n\n case \"usage\":\n promptTokens = event.promptTokens;\n outputTokens = event.outputTokens;\n break;\n\n case \"done\":\n break;\n }\n }\n\n // Emit usage stats\n this.emit(\"usage\", {\n promptTokens,\n outputTokens,\n iterationCount,\n contextPercent: Math.round(this.contextEngine.utilizationPercent()),\n });\n\n // If no tool calls, we're done — this is the final response\n if (toolCalls.length === 0) {\n fullResponse = iterationText;\n this.contextEngine.ingest({ role: \"assistant\", content: iterationText });\n this.emit(\"response-end\", { text: iterationText });\n break;\n }\n\n // Add assistant message with tool calls to context\n const assistantMsg = activeProvider.formatAssistantToolUse(\n toolCalls[0].id,\n toolCalls[0].name,\n toolCalls[0].arguments,\n );\n // If there's text before tool calls, prepend it\n if (iterationText) {\n assistantMsg.content = iterationText;\n }\n // For multiple tool calls, add them all\n if (toolCalls.length > 1 && assistantMsg.tool_calls) {\n assistantMsg.tool_calls = toolCalls.map((tc) => ({\n id: tc.id,\n type: \"function\" as const,\n function: { name: tc.name, arguments: JSON.stringify(tc.arguments) },\n }));\n }\n this.contextEngine.ingest(assistantMsg);\n\n this.emit(\"response-end\", { text: iterationText });\n\n // Execute tool calls sequentially\n for (const tc of toolCalls) {\n const tool = this.toolRegistry.get(tc.name);\n if (!tool) {\n const errorResult = activeProvider.formatToolResult(tc.id, tc.name, `Error: Unknown tool \"${tc.name}\"`, true);\n this.contextEngine.ingest(errorResult);\n continue;\n }\n\n this.emit(\"tool-start\", { id: tc.id, name: tc.name, arguments: tc.arguments });\n\n // Validate\n const toolCtx: ToolContext = {\n projectRoot: this.identity.workspace,\n autoApprove: this.autoApprove,\n agentId: this.identity.id,\n signal,\n };\n\n const validation = tool.validate(tc.arguments, toolCtx);\n if (!validation.ok) {\n const result = activeProvider.formatToolResult(tc.id, tc.name, `Validation error: ${validation.error}`, true);\n this.contextEngine.ingest(result);\n this.emit(\"tool-result\", { id: tc.id, name: tc.name, success: false, summary: validation.error || \"Validation failed\" });\n continue;\n }\n\n // Check if confirmation is needed\n const level = typeof tool.safetyLevel === \"function\" ? tool.safetyLevel(tc.arguments) : tool.safetyLevel;\n const needsConfirm = !this.autoApprove[level] && !this.alwaysApproved.has(tc.name);\n\n if (needsConfirm) {\n const approved = await this.requestConfirmation(tool, tc);\n if (!approved) {\n const result = activeProvider.formatToolResult(tc.id, tc.name, \"Tool execution denied by user\", true);\n this.contextEngine.ingest(result);\n this.emit(\"tool-result\", { id: tc.id, name: tc.name, success: false, summary: \"Denied by user\" });\n continue;\n }\n }\n\n // Execute\n try {\n const output = await tool.execute(tc.arguments, toolCtx);\n const result = activeProvider.formatToolResult(tc.id, tc.name, output);\n this.contextEngine.ingest(result);\n this.emit(\"tool-result\", {\n id: tc.id,\n name: tc.name,\n success: true,\n summary: output.length > 100 ? output.slice(0, 97) + \"...\" : output,\n });\n } catch (err: unknown) {\n const errMsg = err instanceof Error ? err.message : String(err);\n const result = activeProvider.formatToolResult(tc.id, tc.name, `Error: ${errMsg}`, true);\n this.contextEngine.ingest(result);\n this.emit(\"tool-result\", { id: tc.id, name: tc.name, success: false, summary: errMsg });\n }\n }\n\n // Loop continues — the model will see tool results and decide next action\n }\n\n if (iterationCount >= MAX_ITERATIONS) {\n this.emit(\"error\", { message: \"Max iterations reached\", recoverable: true });\n }\n } catch (err: unknown) {\n if (signal.aborted) {\n return \"\";\n }\n const errMsg = err instanceof Error ? err.message : String(err);\n this.emit(\"error\", { message: errMsg, recoverable: false });\n throw err;\n } finally {\n // Save session\n if (this.currentSession) {\n await this.sessionStore.saveMessages(this.currentSession.id, this.contextEngine.getMessages());\n }\n this.emit(\"turn-complete\");\n this.abortController = null;\n }\n\n return fullResponse;\n }\n\n /**\n * Request user confirmation for a tool execution.\n * Returns a promise that resolves when the user responds.\n */\n private requestConfirmation(\n tool: Tool,\n tc: { id: string; name: string; arguments: Record<string, unknown> },\n ): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const description = tool.formatConfirmation\n ? tool.formatConfirmation(tc.arguments)\n : `Execute ${tc.name}`;\n\n const level = typeof tool.safetyLevel === \"function\" ? tool.safetyLevel(tc.arguments) : tool.safetyLevel;\n\n this.emit(\"confirm-needed\", {\n actions: [{ toolName: tc.name, description, safetyLevel: level }],\n resolve: (approved: boolean | \"always\") => {\n if (approved === \"always\") {\n this.alwaysApproved.add(tc.name);\n resolve(true);\n } else {\n resolve(approved);\n }\n },\n });\n });\n }\n\n /** Get the context engine (for direct access if needed) */\n getContextEngine(): ContextEngine {\n return this.contextEngine;\n }\n\n /** Destroy the engine and clean up */\n destroy(): void {\n this.cancel();\n this.removeAllListeners();\n }\n}\n","/**\n * System prompt builder.\n *\n * Assembles the system prompt from workspace files (SOUL.md, USER.md, etc.),\n * agent identity, runtime info, and tool descriptions. This is what gives\n * the agent its personality and context.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { platform, hostname } from \"node:os\";\nimport type { AgentIdentity } from \"./agent.js\";\n\n/** Workspace files to load into the system prompt */\nconst WORKSPACE_FILES = [\n \"SOUL.md\",\n \"USER.md\",\n \"IDENTITY.md\",\n \"AGENTS.md\",\n \"TOOLS.md\",\n \"MEMORY.md\",\n];\n\n/**\n * Build the complete system prompt for an agent.\n */\nexport async function buildSystemPrompt(opts: {\n identity: AgentIdentity;\n workspaceDir: string;\n channel?: string;\n}): Promise<string> {\n const parts: string[] = [];\n\n // Load workspace files\n const workspaceContent = await loadWorkspaceFiles(opts.workspaceDir);\n if (workspaceContent) {\n parts.push(workspaceContent);\n parts.push(\"---\");\n }\n\n // Runtime info\n parts.push(\"## Runtime\");\n parts.push(`Agent: ${opts.identity.name} (${opts.identity.id})`);\n parts.push(`Model: ${opts.identity.model.primary}`);\n parts.push(`Workspace: ${opts.identity.workspace}`);\n parts.push(`Platform: ${platform()} (${hostname()})`);\n parts.push(`Channel: ${opts.channel || \"cli\"}`);\n parts.push(`Tool tier: ${opts.identity.toolTier}`);\n parts.push(\"\");\n\n // Core instructions\n parts.push(\"## Instructions\");\n parts.push(\"You are a helpful AI assistant with access to tools for reading/writing files, running commands, and more.\");\n parts.push(\"Be concise and direct. Use tools proactively to accomplish tasks.\");\n parts.push(\"When you need to make changes, read the relevant files first to understand the context.\");\n parts.push(\"You can configure yourself — use the config, channel, agent, and model management tools to modify your own setup.\");\n parts.push(\"\");\n\n // Project context — check for .clank.md in workspace\n const projectMemory = await loadProjectMemory(opts.identity.workspace);\n if (projectMemory) {\n parts.push(\"## Project Context\");\n parts.push(projectMemory);\n parts.push(\"\");\n }\n\n return parts.join(\"\\n\");\n}\n\n/** Load workspace bootstrap files into a combined string */\nasync function loadWorkspaceFiles(workspaceDir: string): Promise<string | null> {\n const sections: string[] = [];\n\n for (const filename of WORKSPACE_FILES) {\n const filePath = join(workspaceDir, filename);\n if (existsSync(filePath)) {\n try {\n const content = await readFile(filePath, \"utf-8\");\n if (content.trim()) {\n sections.push(content.trim());\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return sections.length > 0 ? sections.join(\"\\n\\n---\\n\\n\") : null;\n}\n\n/** Load project-specific memory (.clank.md) */\nasync function loadProjectMemory(projectRoot: string): Promise<string | null> {\n const candidates = [\".clank.md\", \".clankbuild.md\", \".llamabuild.md\"];\n\n for (const filename of candidates) {\n const filePath = join(projectRoot, filename);\n if (existsSync(filePath)) {\n try {\n const content = await readFile(filePath, \"utf-8\");\n return content.trim() || null;\n } catch {\n continue;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Ensure workspace directory has all template files.\n * Creates missing files from templates.\n */\nexport async function ensureWorkspaceFiles(workspaceDir: string, templateDir: string): Promise<void> {\n const { mkdir, copyFile } = await import(\"node:fs/promises\");\n await mkdir(workspaceDir, { recursive: true });\n\n for (const filename of [...WORKSPACE_FILES, \"BOOTSTRAP.md\", \"HEARTBEAT.md\"]) {\n const target = join(workspaceDir, filename);\n const source = join(templateDir, filename);\n if (!existsSync(target) && existsSync(source)) {\n await copyFile(source, target);\n }\n }\n}\n","export { AgentEngine, type AgentIdentity, type AgentEvents, type ConfirmAction } from \"./agent.js\";\nexport { ContextEngine, type CompactionResult } from \"./context-engine.js\";\nexport { buildSystemPrompt, ensureWorkspaceFiles } from \"./system-prompt.js\";\n","/**\n * Tool system type definitions.\n *\n * Tools are the agent's hands — they let it read files, write code,\n * run commands, search the web, etc. Each tool has a safety level\n * that controls whether it needs user confirmation before executing.\n */\n\n/** Safety classification for tools */\nexport type SafetyLevel = \"low\" | \"medium\" | \"high\";\n\n/** Context passed to tool execute/validate */\nexport interface ToolContext {\n /** Working directory for file operations */\n projectRoot: string;\n /** Whether external paths are allowed */\n allowExternal?: boolean;\n /** Auto-approve settings per safety level */\n autoApprove: { low: boolean; medium: boolean; high: boolean };\n /** Agent ID (for scoping) */\n agentId?: string;\n /** Abort signal */\n signal?: AbortSignal;\n}\n\n/** Validation result from tool.validate() */\nexport interface ValidationResult {\n ok: boolean;\n error?: string;\n}\n\n/** The interface every tool must implement */\nexport interface Tool {\n /** Tool definition sent to the LLM */\n definition: {\n name: string;\n description: string;\n parameters: {\n type: \"object\";\n properties: Record<string, unknown>;\n required?: string[];\n };\n };\n\n /** Safety classification — determines if user confirmation is needed */\n safetyLevel: SafetyLevel | ((args: Record<string, unknown>) => SafetyLevel);\n\n /** Whether this tool only reads data (safe in plan mode) */\n readOnly: boolean;\n\n /** Validate arguments before execution */\n validate(args: Record<string, unknown>, context: ToolContext): ValidationResult;\n\n /** Execute the tool and return a string result */\n execute(args: Record<string, unknown>, context: ToolContext): Promise<string>;\n\n /** Human-readable confirmation message for the action */\n formatConfirmation?(args: Record<string, unknown>): string;\n}\n\n/** Tool tier for local model optimization */\nexport type ToolTier = \"full\" | \"core\" | \"auto\";\n\n/** Keywords that trigger dynamic tool injection in \"auto\" tier */\nexport const AUTO_TIER_TRIGGERS: Record<string, string[]> = {\n web_fetch: [\"web\", \"fetch\", \"url\", \"http\", \"download\", \"website\"],\n web_search: [\"search\", \"google\", \"find online\", \"look up\", \"browse\"],\n npm_install: [\"install\", \"npm\", \"package\", \"dependency\"],\n pip_install: [\"pip\", \"python package\", \"pip install\"],\n install_tool: [\"install\", \"winget\", \"choco\", \"brew\", \"apt\"],\n generate_file: [\"generate\", \"pdf\", \"create file\", \"export\"],\n};\n\n/** Core tools available at all tiers */\nexport const CORE_TOOL_NAMES = [\n \"read_file\",\n \"write_file\",\n \"edit_file\",\n \"list_directory\",\n \"search_files\",\n \"glob_files\",\n \"bash\",\n \"git\",\n];\n","/**\n * Tool registry — manages available tools and handles tiering.\n *\n * The registry holds all registered tools and can filter them based on\n * the tool tier setting. This is critical for local model optimization:\n *\n * - \"full\": All tools available (best for capable models like Claude, GPT-4o)\n * - \"core\": Only 8 essential tools (best for smaller local models)\n * - \"auto\": Start with core, dynamically add tools when user message\n * contains relevant keywords (smart middle ground)\n *\n * Why tiering matters: Smaller models get confused when given too many\n * tools. Reducing the tool count improves their tool selection accuracy.\n */\n\nimport type { Tool, ToolTier } from \"./types.js\";\nimport { CORE_TOOL_NAMES, AUTO_TIER_TRIGGERS } from \"./types.js\";\nimport type { ToolDefinition } from \"../providers/types.js\";\n\nexport class ToolRegistry {\n private tools = new Map<string, Tool>();\n\n /** Register a tool */\n register(tool: Tool): void {\n this.tools.set(tool.definition.name, tool);\n }\n\n /** Get a tool by name */\n get(name: string): Tool | undefined {\n return this.tools.get(name);\n }\n\n /** Get all registered tools */\n getAll(): Tool[] {\n return Array.from(this.tools.values());\n }\n\n /** Get tool names */\n list(): string[] {\n return Array.from(this.tools.keys());\n }\n\n /**\n * Get tool definitions for the LLM, filtered by tier.\n *\n * @param tier - Which tool tier to use\n * @param userMessage - Current user message (for \"auto\" tier keyword matching)\n * @param allowlist - Optional allowlist of tool names (for per-agent filtering)\n * @param denylist - Optional denylist of tool names\n */\n getDefinitions(opts?: {\n tier?: ToolTier;\n userMessage?: string;\n allowlist?: string[];\n denylist?: string[];\n }): ToolDefinition[] {\n const tier = opts?.tier ?? \"full\";\n const userMessage = opts?.userMessage?.toLowerCase() ?? \"\";\n\n let toolNames: string[];\n\n switch (tier) {\n case \"core\":\n toolNames = CORE_TOOL_NAMES.filter((n) => this.tools.has(n));\n break;\n\n case \"auto\": {\n // Start with core tools\n const names = new Set(CORE_TOOL_NAMES.filter((n) => this.tools.has(n)));\n\n // Dynamically add tools based on keywords in the user message\n for (const [toolName, keywords] of Object.entries(AUTO_TIER_TRIGGERS)) {\n if (this.tools.has(toolName) && keywords.some((k) => userMessage.includes(k))) {\n names.add(toolName);\n }\n }\n\n toolNames = Array.from(names);\n break;\n }\n\n case \"full\":\n default:\n toolNames = this.list();\n break;\n }\n\n // Apply allowlist/denylist\n if (opts?.allowlist) {\n const allowed = new Set(opts.allowlist);\n toolNames = toolNames.filter((n) => allowed.has(n));\n }\n if (opts?.denylist) {\n const denied = new Set(opts.denylist);\n toolNames = toolNames.filter((n) => !denied.has(n));\n }\n\n return toolNames\n .map((name) => this.tools.get(name)!)\n .map((tool) => tool.definition as ToolDefinition);\n }\n\n /**\n * Register a tool from a plugin manifest.\n * Used by the plugin system for runtime tool loading.\n */\n registerFromManifest(manifest: {\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n safetyLevel: string;\n entrypoint: string;\n }): void {\n // Plugin tool loading will be implemented in the plugin sprint\n // For now, just validate the manifest shape\n if (!manifest.name || !manifest.description) {\n throw new Error(\"Plugin tool manifest must have name and description\");\n }\n }\n}\n","/**\n * Path containment guard.\n *\n * Prevents file tools from accessing paths outside the workspace.\n * All resolved paths must be within the projectRoot or explicitly\n * allowed external paths (with user confirmation).\n */\n\nimport { resolve, isAbsolute, normalize, relative } from \"node:path\";\n\n/**\n * Resolve a path and verify it's within the allowed root.\n * Returns the resolved path, or an error string if blocked.\n */\nexport function guardPath(\n inputPath: string,\n projectRoot: string,\n opts?: { allowExternal?: boolean },\n): { ok: true; path: string } | { ok: false; error: string } {\n // Resolve the full path\n const resolved = isAbsolute(inputPath)\n ? normalize(inputPath)\n : normalize(resolve(projectRoot, inputPath));\n\n // Check containment — resolved path must start with projectRoot\n const rel = relative(projectRoot, resolved);\n const isOutside = rel.startsWith(\"..\") || isAbsolute(rel);\n\n if (isOutside && !opts?.allowExternal) {\n return {\n ok: false,\n error: `Path \"${inputPath}\" resolves outside workspace. Resolved to: ${resolved}`,\n };\n }\n\n return { ok: true, path: resolved };\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\nimport { guardPath } from \"./path-guard.js\";\n\nexport const readFileTool: Tool = {\n definition: {\n name: \"read_file\",\n description:\n \"Read the contents of a file. Returns the file content with line numbers. \" +\n \"Supports text files, detects binary files. Use offset and limit for large files.\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"File path (absolute or relative to workspace)\" },\n offset: { type: \"number\", description: \"Start reading from this line number (1-based)\" },\n limit: { type: \"number\", description: \"Maximum number of lines to read\" },\n },\n required: [\"path\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.path || typeof args.path !== \"string\") {\n return { ok: false, error: \"path is required and must be a string\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const guard = guardPath(args.path as string, ctx.projectRoot, { allowExternal: ctx.allowExternal });\n if (!guard.ok) return guard.error;\n const filePath = guard.path;\n\n try {\n const fileStats = await stat(filePath);\n if (fileStats.isDirectory()) {\n return `Error: ${filePath} is a directory, not a file. Use list_directory instead.`;\n }\n\n // Binary detection: check first 8KB for null bytes\n const probe = Buffer.alloc(8192);\n const { createReadStream } = await import(\"node:fs\");\n const stream = createReadStream(filePath, { start: 0, end: 8191 });\n let probeLen = 0;\n for await (const chunk of stream) {\n (chunk as Buffer).copy(probe, probeLen);\n probeLen += (chunk as Buffer).length;\n }\n if (probe.subarray(0, probeLen).includes(0)) {\n return `Binary file detected: ${filePath} (${fileStats.size} bytes)`;\n }\n\n const content = await readFile(filePath, \"utf-8\");\n const lines = content.split(\"\\n\");\n\n const offset = Math.max(1, Number(args.offset) || 1);\n const limit = Number(args.limit) || lines.length;\n\n const sliced = lines.slice(offset - 1, offset - 1 + limit);\n const numbered = sliced.map((line, i) => `${offset + i}\\t${line}`).join(\"\\n\");\n\n return numbered || \"(empty file)\";\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return `Error reading file: ${msg}`;\n }\n },\n};\n","import { writeFile, mkdir } from \"node:fs/promises\";\nimport { dirname, isAbsolute } from \"node:path\";\nimport { guardPath } from \"./path-guard.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\nexport const writeFileTool: Tool = {\n definition: {\n name: \"write_file\",\n description:\n \"Write content to a file. Creates the file if it doesn't exist, \" +\n \"overwrites if it does. Automatically creates parent directories.\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"File path (absolute or relative to workspace)\" },\n content: { type: \"string\", description: \"Content to write to the file\" },\n },\n required: [\"path\", \"content\"],\n },\n },\n\n safetyLevel(args: Record<string, unknown>) {\n const p = String(args.path || \"\");\n // External paths or overwriting existing files are higher risk\n if (isAbsolute(p) && !p.startsWith(process.cwd())) return \"high\";\n return \"medium\";\n },\n\n readOnly: false,\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.path || typeof args.path !== \"string\") {\n return { ok: false, error: \"path is required\" };\n }\n if (typeof args.content !== \"string\") {\n return { ok: false, error: \"content is required\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const guard = guardPath(args.path as string, ctx.projectRoot, { allowExternal: ctx.allowExternal });\n if (!guard.ok) return guard.error;\n const filePath = guard.path;\n\n try {\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, args.content as string, \"utf-8\");\n\n const lines = (args.content as string).split(\"\\n\").length;\n return `Wrote ${lines} lines to ${filePath}`;\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return `Error writing file: ${msg}`;\n }\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `Write to ${args.path}`;\n },\n};\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport { isAbsolute } from \"node:path\";\nimport { guardPath } from \"./path-guard.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\nexport const editFileTool: Tool = {\n definition: {\n name: \"edit_file\",\n description:\n \"Edit a file by replacing an exact string match with new content. \" +\n \"The old_string must match exactly (including whitespace). \" +\n \"Use replace_all to replace every occurrence.\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"File path\" },\n old_string: { type: \"string\", description: \"Exact string to find and replace\" },\n new_string: { type: \"string\", description: \"Replacement string\" },\n replace_all: { type: \"boolean\", description: \"Replace all occurrences (default: false)\" },\n },\n required: [\"path\", \"old_string\", \"new_string\"],\n },\n },\n\n safetyLevel(args: Record<string, unknown>) {\n const p = String(args.path || \"\");\n if (isAbsolute(p) && !p.startsWith(process.cwd())) return \"high\";\n return \"medium\";\n },\n\n readOnly: false,\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.path || typeof args.path !== \"string\") return { ok: false, error: \"path is required\" };\n if (typeof args.old_string !== \"string\") return { ok: false, error: \"old_string is required\" };\n if (typeof args.new_string !== \"string\") return { ok: false, error: \"new_string is required\" };\n if (args.old_string === args.new_string) return { ok: false, error: \"old_string and new_string are the same\" };\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const guard = guardPath(args.path as string, ctx.projectRoot, { allowExternal: ctx.allowExternal });\n if (!guard.ok) return guard.error;\n const filePath = guard.path;\n\n try {\n const content = await readFile(filePath, \"utf-8\");\n const oldStr = args.old_string as string;\n const newStr = args.new_string as string;\n const replaceAll = Boolean(args.replace_all);\n\n if (!content.includes(oldStr)) {\n return `Error: old_string not found in ${filePath}. Make sure it matches exactly including whitespace.`;\n }\n\n if (!replaceAll) {\n // Check uniqueness — if old_string appears more than once, reject\n const count = content.split(oldStr).length - 1;\n if (count > 1) {\n return `Error: old_string appears ${count} times in ${filePath}. Use replace_all: true or provide more context to make it unique.`;\n }\n }\n\n const updated = replaceAll\n ? content.split(oldStr).join(newStr)\n : content.replace(oldStr, newStr);\n\n await writeFile(filePath, updated, \"utf-8\");\n\n const replacements = replaceAll ? content.split(oldStr).length - 1 : 1;\n return `Edited ${filePath} (${replacements} replacement${replacements > 1 ? \"s\" : \"\"})`;\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return `Error editing file: ${msg}`;\n }\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `Edit ${args.path}`;\n },\n};\n","import { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { guardPath } from \"./path-guard.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\nexport const listDirectoryTool: Tool = {\n definition: {\n name: \"list_directory\",\n description: \"List files and directories in a path. Shows names, sizes, and types.\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"Directory path (default: workspace root)\" },\n },\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(_args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n let dirPath = ctx.projectRoot;\n if (args.path) {\n const guard = guardPath(args.path as string, ctx.projectRoot, { allowExternal: ctx.allowExternal });\n if (!guard.ok) return guard.error;\n dirPath = guard.path;\n }\n\n try {\n const entries = await readdir(dirPath);\n if (entries.length === 0) return `(empty directory: ${dirPath})`;\n\n const lines: string[] = [];\n for (const entry of entries.slice(0, 100)) {\n try {\n const full = join(dirPath, entry);\n const s = await stat(full);\n const type = s.isDirectory() ? \"dir\" : \"file\";\n const size = s.isDirectory() ? \"\" : ` (${formatSize(s.size)})`;\n lines.push(`${type}\\t${entry}${size}`);\n } catch {\n lines.push(`?\\t${entry}`);\n }\n }\n\n if (entries.length > 100) {\n lines.push(`... and ${entries.length - 100} more entries`);\n }\n\n return lines.join(\"\\n\");\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n return `Error listing directory: ${msg}`;\n }\n },\n};\n\nfunction formatSize(bytes: number): string {\n if (bytes < 1024) return `${bytes}B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n","import { readdir, readFile, stat } from \"node:fs/promises\";\nimport { join, relative } from \"node:path\";\nimport { guardPath } from \"./path-guard.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\n/** Directories to skip during search */\nconst IGNORE_DIRS = new Set([\n \"node_modules\", \".git\", \"dist\", \"build\", \".next\", \"__pycache__\",\n \".cache\", \"coverage\", \".venv\", \"venv\", \"target\",\n]);\n\nexport const searchFilesTool: Tool = {\n definition: {\n name: \"search_files\",\n description:\n \"Search for a regex pattern across files in the workspace. \" +\n \"Returns matching lines with file paths and line numbers. \" +\n \"Ignores node_modules, .git, dist, etc.\",\n parameters: {\n type: \"object\",\n properties: {\n pattern: { type: \"string\", description: \"Regex pattern to search for\" },\n path: { type: \"string\", description: \"Directory to search in (default: workspace root)\" },\n glob: { type: \"string\", description: \"File glob filter, e.g. '*.ts' or '*.py'\" },\n max_results: { type: \"number\", description: \"Maximum results to return (default: 50)\" },\n },\n required: [\"pattern\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.pattern || typeof args.pattern !== \"string\") {\n return { ok: false, error: \"pattern is required\" };\n }\n // Validate regex\n try {\n new RegExp(args.pattern as string);\n } catch {\n return { ok: false, error: \"Invalid regex pattern\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n let searchPath = ctx.projectRoot;\n if (args.path) {\n const guard = guardPath(args.path as string, ctx.projectRoot, { allowExternal: ctx.allowExternal });\n if (!guard.ok) return guard.error;\n searchPath = guard.path;\n }\n\n const maxResults = Number(args.max_results) || 50;\n const globFilter = args.glob as string | undefined;\n let regex: RegExp;\n try {\n regex = new RegExp(args.pattern as string, \"gi\");\n } catch {\n return `Error: Invalid regex pattern`;\n }\n\n const results: string[] = [];\n\n async function searchDir(dir: string): Promise<void> {\n if (results.length >= maxResults) return;\n\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (results.length >= maxResults) return;\n if (IGNORE_DIRS.has(entry)) continue;\n\n const full = join(dir, entry);\n let s;\n try {\n s = await stat(full);\n } catch {\n continue;\n }\n\n if (s.isDirectory()) {\n await searchDir(full);\n } else if (s.isFile() && s.size < 1024 * 1024) {\n // Skip files >1MB\n if (globFilter) {\n const ext = globFilter.replace(\"*\", \"\");\n if (!entry.endsWith(ext)) continue;\n }\n\n try {\n const content = await readFile(full, \"utf-8\");\n const lines = content.split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n regex.lastIndex = 0;\n if (regex.test(lines[i])) {\n const rel = relative(ctx.projectRoot, full);\n results.push(`${rel}:${i + 1}\\t${lines[i].trim()}`);\n if (results.length >= maxResults) return;\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n }\n }\n\n await searchDir(searchPath);\n\n if (results.length === 0) return `No matches found for pattern: ${args.pattern}`;\n return results.join(\"\\n\");\n },\n};\n","import { readdir, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { guardPath } from \"./path-guard.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\nconst IGNORE_DIRS = new Set([\n \"node_modules\", \".git\", \"dist\", \"build\", \".next\", \"__pycache__\",\n \".cache\", \"coverage\", \".venv\", \"venv\", \"target\",\n]);\n\nexport const globFilesTool: Tool = {\n definition: {\n name: \"glob_files\",\n description:\n \"Find files matching a glob pattern. Supports **, *, and ? wildcards. \" +\n \"Returns matching file paths sorted by modification time (newest first). Max 200 results.\",\n parameters: {\n type: \"object\",\n properties: {\n pattern: { type: \"string\", description: \"Glob pattern, e.g. '**/*.ts' or 'src/**/*.js'\" },\n path: { type: \"string\", description: \"Base directory (default: workspace root)\" },\n },\n required: [\"pattern\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.pattern || typeof args.pattern !== \"string\") {\n return { ok: false, error: \"pattern is required\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n let basePath = ctx.projectRoot;\n if (args.path) {\n const guard = guardPath(args.path as string, ctx.projectRoot, { allowExternal: ctx.allowExternal });\n if (!guard.ok) return guard.error;\n basePath = guard.path;\n }\n\n const pattern = args.pattern as string;\n const regex = globToRegex(pattern);\n const matches: Array<{ path: string; mtime: number }> = [];\n\n async function scanDir(dir: string, relDir: string): Promise<void> {\n if (matches.length >= 200) return;\n\n let entries: string[];\n try {\n entries = await readdir(dir);\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (matches.length >= 200) return;\n if (IGNORE_DIRS.has(entry)) continue;\n\n const full = join(dir, entry);\n const rel = relDir ? `${relDir}/${entry}` : entry;\n\n let s;\n try {\n s = await stat(full);\n } catch {\n continue;\n }\n\n if (s.isDirectory()) {\n await scanDir(full, rel);\n } else if (s.isFile() && regex.test(rel)) {\n matches.push({ path: rel, mtime: s.mtimeMs });\n }\n }\n }\n\n await scanDir(basePath, \"\");\n\n if (matches.length === 0) return `No files matching: ${pattern}`;\n\n // Sort by mtime descending (newest first)\n matches.sort((a, b) => b.mtime - a.mtime);\n\n return matches.map((m) => m.path).join(\"\\n\");\n },\n};\n\n/** Convert a simple glob pattern to a regex */\nfunction globToRegex(pattern: string): RegExp {\n let regex = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\") // Escape special regex chars\n .replace(/\\*\\*/g, \"{{GLOBSTAR}}\") // Temp placeholder\n .replace(/\\*/g, \"[^/]*\") // * matches within directory\n .replace(/\\?/g, \"[^/]\") // ? matches single char\n .replace(/\\{\\{GLOBSTAR\\}\\}/g, \".*\"); // ** matches across directories\n\n return new RegExp(`^${regex}$`, \"i\");\n}\n","import { execFile } from \"node:child_process\";\nimport { resolve, isAbsolute } from \"node:path\";\nimport { platform } from \"node:os\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\n/** Commands that are blocked for safety — defense in depth */\nconst BLOCKED_PATTERNS = [\n // Recursive deletion of root/system dirs\n /rm\\s+.*-[a-z]*r[a-z]*f[a-z]*\\s+\\//i,\n /rm\\s+.*-[a-z]*f[a-z]*r[a-z]*\\s+\\//i,\n /rm\\s+.*--recursive.*\\//i,\n /rm\\s+.*--force.*\\//i,\n /Remove-Item.*-Recurse/i,\n /del\\s+\\/[sS].*[\\\\\\/]/i,\n /rd\\s+\\/[sS].*[\\\\\\/]/i,\n // Disk formatting\n /\\bformat\\s+[a-z]:/i,\n /\\bmkfs\\b/i,\n /\\bdd\\s+.*of=\\/dev/i,\n /diskpart/i,\n // Force push to main branches\n /git\\s+push\\s+.*(-f|--force).*\\b(main|master)\\b/i,\n /git\\s+push\\s+.*\\b(main|master)\\b.*(-f|--force)/i,\n // Shell-in-shell execution (limits encoded payloads)\n /\\|\\s*(bash|sh|cmd|powershell|pwsh)\\b/i,\n /base64\\s+(-d|--decode).*\\|\\s*(bash|sh)/i,\n // Direct system damage\n /\\bchmod\\s+.*777\\s+\\//i,\n /\\bchown\\s+.*\\//i,\n /\\bshutdown\\b/i,\n /\\breboot\\b/i,\n // Windows-specific\n /powershell\\s+.*-[eE]ncodedCommand/i,\n /reg\\s+(delete|add).*\\\\\\\\HKLM/i,\n];\n\nconst MAX_OUTPUT = 30 * 1024; // 30KB output cap\nconst TIMEOUT_MS = 120_000; // 2 minute timeout\n\nexport const bashTool: Tool = {\n definition: {\n name: \"bash\",\n description:\n \"Execute a shell command. Use for system operations, builds, installs, etc. \" +\n \"Output is capped at 30KB. Times out after 2 minutes. \" +\n \"Dangerous commands (rm -rf /, format, etc.) are blocked.\",\n parameters: {\n type: \"object\",\n properties: {\n command: { type: \"string\", description: \"The shell command to execute\" },\n cwd: { type: \"string\", description: \"Working directory (default: workspace root)\" },\n timeout: { type: \"number\", description: \"Timeout in milliseconds (default: 120000)\" },\n },\n required: [\"command\"],\n },\n },\n\n safetyLevel: \"high\",\n readOnly: false,\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.command || typeof args.command !== \"string\") {\n return { ok: false, error: \"command is required\" };\n }\n\n const cmd = args.command as string;\n for (const pattern of BLOCKED_PATTERNS) {\n if (pattern.test(cmd)) {\n return { ok: false, error: `Blocked: dangerous command pattern detected` };\n }\n }\n\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const command = args.command as string;\n const cwd = args.cwd\n ? isAbsolute(args.cwd as string)\n ? (args.cwd as string)\n : resolve(ctx.projectRoot, args.cwd as string)\n : ctx.projectRoot;\n const timeout = Number(args.timeout) || TIMEOUT_MS;\n\n const shell = platform() === \"win32\" ? \"cmd.exe\" : \"/bin/bash\";\n const shellArgs = platform() === \"win32\" ? [\"/c\", command] : [\"-c\", command];\n\n return new Promise<string>((resolvePromise) => {\n const proc = execFile(\n shell,\n shellArgs,\n {\n cwd,\n timeout,\n maxBuffer: MAX_OUTPUT * 2,\n signal: ctx.signal,\n },\n (error, stdout, stderr) => {\n let output = \"\";\n\n if (stdout) output += stdout;\n if (stderr) output += (output ? \"\\n\" : \"\") + stderr;\n\n // Cap output\n if (output.length > MAX_OUTPUT) {\n output = output.slice(0, MAX_OUTPUT) + \"\\n... (output truncated)\";\n }\n\n if (error && !output) {\n output = `Error: ${error.message}`;\n }\n\n if (error && \"code\" in error) {\n output += `\\n(exit code: ${(error as NodeJS.ErrnoException & { code?: number }).code})`;\n }\n\n resolvePromise(output || \"(no output)\");\n },\n );\n });\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `Run: ${args.command}`;\n },\n};\n","import { execFile } from \"node:child_process\";\nimport { resolve, isAbsolute } from \"node:path\";\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\n/** Git subcommands classified by risk level */\nconst SAFE_SUBCOMMANDS = new Set([\n \"status\", \"log\", \"diff\", \"show\", \"branch\", \"tag\", \"remote\",\n \"stash\", \"blame\", \"shortlog\", \"describe\", \"rev-parse\",\n \"ls-files\", \"ls-tree\", \"cat-file\",\n]);\n\nconst DANGEROUS_SUBCOMMANDS = new Set([\n \"push\", \"reset\", \"rebase\", \"merge\", \"cherry-pick\",\n \"clean\", \"checkout\", \"restore\",\n]);\n\nexport const gitTool: Tool = {\n definition: {\n name: \"git\",\n description:\n \"Run a git command. Safe commands (status, log, diff, etc.) are low risk. \" +\n \"Mutating commands (push, reset, rebase) are high risk and need confirmation.\",\n parameters: {\n type: \"object\",\n properties: {\n args: { type: \"string\", description: \"Git arguments, e.g. 'status' or 'log --oneline -10'\" },\n cwd: { type: \"string\", description: \"Repository directory (default: workspace root)\" },\n },\n required: [\"args\"],\n },\n },\n\n safetyLevel(args: Record<string, unknown>) {\n const gitArgs = String(args.args || \"\");\n const subcommand = gitArgs.trim().split(/\\s+/)[0];\n if (SAFE_SUBCOMMANDS.has(subcommand)) return \"low\";\n if (DANGEROUS_SUBCOMMANDS.has(subcommand)) return \"high\";\n return \"medium\";\n },\n\n readOnly: false, // depends on subcommand, but conservatively false\n\n validate(args: Record<string, unknown>, _ctx: ToolContext): ValidationResult {\n if (!args.args || typeof args.args !== \"string\") {\n return { ok: false, error: \"args is required\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const gitArgs = (args.args as string).trim().split(/\\s+/);\n const cwd = args.cwd\n ? isAbsolute(args.cwd as string)\n ? (args.cwd as string)\n : resolve(ctx.projectRoot, args.cwd as string)\n : ctx.projectRoot;\n\n return new Promise<string>((resolvePromise) => {\n execFile(\n \"git\",\n gitArgs,\n { cwd, timeout: 30_000, maxBuffer: 1024 * 1024 },\n (error, stdout, stderr) => {\n let output = \"\";\n if (stdout) output += stdout;\n if (stderr) output += (output ? \"\\n\" : \"\") + stderr;\n if (error && !output) output = `Error: ${error.message}`;\n\n // Cap output\n if (output.length > 30 * 1024) {\n output = output.slice(0, 30 * 1024) + \"\\n... (output truncated)\";\n }\n\n resolvePromise(output || \"(no output)\");\n },\n );\n });\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `Run: git ${args.args}`;\n },\n};\n","/**\n * Configuration system for Clank.\n *\n * Config lives at ~/.clank/config.json5 (or %APPDATA%/Clank/config.json5 on Windows).\n * Uses JSON5 for human-friendly comments and trailing commas.\n * Supports ${ENV_VAR} substitution for secrets.\n */\n\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir, platform } from \"node:os\";\nimport JSON5 from \"json5\";\nimport type { ProviderConfig } from \"../providers/router.js\";\nimport type { ToolTier } from \"../tools/types.js\";\nimport type { ModelConfig } from \"../providers/types.js\";\n\n/** Full Clank configuration schema */\nexport interface ClankConfig {\n /** Gateway settings */\n gateway: {\n port: number;\n bind: \"loopback\" | \"lan\" | string;\n auth: {\n mode: \"token\" | \"pin\" | \"none\";\n token?: string;\n };\n };\n\n /** Agent definitions */\n agents: {\n defaults: {\n model: ModelConfig;\n workspace: string;\n toolTier: ToolTier;\n temperature?: number;\n maxResponseTokens?: number;\n };\n list: Array<{\n id: string;\n name?: string;\n model?: ModelConfig;\n workspace?: string;\n toolTier?: ToolTier;\n tools?: { allow?: string[]; deny?: string[] };\n }>;\n };\n\n /** Model provider configs */\n models: {\n providers: ProviderConfig;\n };\n\n /** Channel configs */\n channels: {\n telegram?: {\n enabled: boolean;\n botToken?: string;\n allowFrom?: Array<string | number>;\n groups?: Record<string, { requireMention?: boolean }>;\n };\n discord?: {\n enabled: boolean;\n botToken?: string;\n };\n web?: {\n enabled: boolean;\n };\n };\n\n /** Session settings */\n session: {\n dmScope: \"main\" | \"per-peer\" | \"per-channel-peer\";\n maxSessions: number;\n resetMode?: \"idle\" | \"daily\";\n resetAfterMinutes?: number;\n };\n\n /** Tool settings */\n tools: {\n autoApprove: { low: boolean; medium: boolean; high: boolean };\n webSearch?: { enabled: boolean; provider?: string; apiKey?: string };\n };\n\n /** Safety settings */\n safety: {\n confirmExternal: boolean;\n };\n\n /** Third-party API integrations */\n integrations: {\n elevenlabs?: {\n enabled: boolean;\n apiKey: string;\n voiceId?: string;\n model?: string; // e.g., \"eleven_multilingual_v2\"\n };\n whisper?: {\n enabled: boolean;\n provider: \"groq\" | \"openai\" | \"local\"; // groq = free, openai = paid, local = whisper.cpp\n apiKey?: string; // for groq or openai\n model?: string;\n };\n imageGen?: {\n enabled: boolean;\n provider: \"openai\" | \"fal\";\n apiKey?: string;\n };\n /** Generic integrations — extensible for future services */\n [key: string]: { enabled: boolean; apiKey?: string; [k: string]: unknown } | undefined;\n };\n}\n\n/** Get the config directory path */\nexport function getConfigDir(): string {\n if (platform() === \"win32\") {\n return join(process.env.APPDATA || join(homedir(), \"AppData\", \"Roaming\"), \"Clank\");\n }\n return join(homedir(), \".clank\");\n}\n\n/** Get the config file path */\nexport function getConfigPath(): string {\n return join(getConfigDir(), \"config.json5\");\n}\n\n/** Default configuration */\nexport function defaultConfig(): ClankConfig {\n return {\n gateway: {\n port: 18790,\n bind: \"loopback\",\n auth: { mode: \"token\" },\n },\n agents: {\n defaults: {\n model: { primary: \"ollama/qwen3.5\" },\n workspace: join(getConfigDir(), \"workspace\"),\n toolTier: \"auto\",\n temperature: 0.7,\n },\n list: [],\n },\n models: {\n providers: {\n ollama: { baseUrl: \"http://127.0.0.1:11434\" },\n },\n },\n channels: {\n web: { enabled: true },\n },\n session: {\n dmScope: \"main\",\n maxSessions: 50,\n },\n tools: {\n autoApprove: { low: true, medium: false, high: false },\n },\n safety: {\n confirmExternal: true,\n },\n integrations: {},\n };\n}\n\n/**\n * Substitute ${ENV_VAR} references in string values.\n * This lets users reference secrets from environment variables\n * instead of storing them in the config file.\n */\nfunction substituteEnvVars(obj: unknown): unknown {\n if (typeof obj === \"string\") {\n return obj.replace(/\\$\\{(\\w+)\\}/g, (_, varName) => {\n return process.env[varName] || \"\";\n });\n }\n if (Array.isArray(obj)) {\n return obj.map(substituteEnvVars);\n }\n if (obj && typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n result[key] = substituteEnvVars(value);\n }\n return result;\n }\n return obj;\n}\n\n/** Deep merge two objects (source overrides target) */\nfunction deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n const result = { ...target };\n for (const [key, value] of Object.entries(source)) {\n if (value && typeof value === \"object\" && !Array.isArray(value) && target[key] && typeof target[key] === \"object\") {\n result[key] = deepMerge(target[key] as Record<string, unknown>, value as Record<string, unknown>);\n } else {\n result[key] = value;\n }\n }\n return result;\n}\n\n/** Load configuration from disk, merging with defaults */\nexport async function loadConfig(): Promise<ClankConfig> {\n const configPath = getConfigPath();\n const defaults = defaultConfig();\n\n if (!existsSync(configPath)) {\n return defaults;\n }\n\n try {\n const raw = await readFile(configPath, \"utf-8\");\n const parsed = JSON5.parse(raw) as Record<string, unknown>;\n const substituted = substituteEnvVars(parsed) as Record<string, unknown>;\n return deepMerge(defaults as unknown as Record<string, unknown>, substituted) as unknown as ClankConfig;\n } catch (err) {\n console.error(`Warning: Failed to parse config at ${configPath}, using defaults`);\n return defaults;\n }\n}\n\n/** Save configuration to disk */\nexport async function saveConfig(config: ClankConfig): Promise<void> {\n const configPath = getConfigPath();\n await mkdir(getConfigDir(), { recursive: true });\n\n // JSON5 stringify with nice formatting\n const content = JSON5.stringify(config, null, 2);\n await writeFile(configPath, content, \"utf-8\");\n}\n\n/** Ensure the config directory and workspace exist */\nexport async function ensureConfigDir(): Promise<void> {\n const configDir = getConfigDir();\n await mkdir(configDir, { recursive: true });\n await mkdir(join(configDir, \"workspace\"), { recursive: true });\n await mkdir(join(configDir, \"conversations\"), { recursive: true });\n await mkdir(join(configDir, \"memory\"), { recursive: true });\n await mkdir(join(configDir, \"logs\"), { recursive: true });\n}\n","/**\n * Config hot-reload — watches config.json5 for changes.\n *\n * When the config file changes, it reloads and emits an event\n * so the gateway can apply changes without restarting.\n */\n\nimport { watch, type FSWatcher } from \"node:fs\";\nimport { EventEmitter } from \"node:events\";\nimport { loadConfig, getConfigPath, type ClankConfig } from \"./config.js\";\n\nexport class ConfigWatcher extends EventEmitter {\n private watcher: FSWatcher | null = null;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private currentConfig: ClankConfig | null = null;\n\n /** Start watching the config file */\n async start(): Promise<ClankConfig> {\n this.currentConfig = await loadConfig();\n const configPath = getConfigPath();\n\n try {\n this.watcher = watch(configPath, { persistent: false }, () => {\n // Debounce — config editors may write multiple times\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => this.reload(), 500);\n });\n } catch {\n // Config file might not exist yet — that's fine\n }\n\n return this.currentConfig;\n }\n\n /** Stop watching */\n stop(): void {\n if (this.watcher) {\n this.watcher.close();\n this.watcher = null;\n }\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n }\n\n /** Reload config and emit change event */\n private async reload(): Promise<void> {\n try {\n const newConfig = await loadConfig();\n const oldConfig = this.currentConfig;\n this.currentConfig = newConfig;\n this.emit(\"change\", { oldConfig, newConfig });\n } catch (err) {\n this.emit(\"error\", err);\n }\n }\n\n /** Get the current config */\n getConfig(): ClankConfig | null {\n return this.currentConfig;\n }\n}\n","export {\n loadConfig,\n saveConfig,\n defaultConfig,\n getConfigDir,\n getConfigPath,\n ensureConfigDir,\n type ClankConfig,\n} from \"./config.js\";\n\nexport { ConfigWatcher } from \"./watcher.js\";\n","/**\n * Web search tool — uses Brave Search API.\n *\n * Brave Search has a free tier which makes it the default choice\n * for a local-first tool. API key configured during onboarding.\n */\n\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\nexport const webSearchTool: Tool = {\n definition: {\n name: \"web_search\",\n description:\n \"Search the web using Brave Search. Returns relevant results with titles, URLs, and snippets. \" +\n \"Requires a Brave Search API key configured in settings.\",\n parameters: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Search query\" },\n count: { type: \"number\", description: \"Number of results (default: 5, max: 20)\" },\n },\n required: [\"query\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>): ValidationResult {\n if (!args.query || typeof args.query !== \"string\") {\n return { ok: false, error: \"query is required\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const query = args.query as string;\n const count = Math.min(Number(args.count) || 5, 20);\n\n // Load API key from config\n const { loadConfig } = await import(\"../config/index.js\");\n const config = await loadConfig();\n const apiKey = config.tools.webSearch?.apiKey;\n\n if (!apiKey) {\n return \"Error: Brave Search API key not configured. Run `clank setup --section search` or tell me to set it up.\";\n }\n\n try {\n const url = `https://api.search.brave.com/res/v1/web/search?q=${encodeURIComponent(query)}&count=${count}`;\n const res = await fetch(url, {\n headers: {\n \"Accept\": \"application/json\",\n \"Accept-Encoding\": \"gzip\",\n \"X-Subscription-Token\": apiKey,\n },\n signal: ctx.signal,\n });\n\n if (!res.ok) {\n return `Search error: ${res.status} ${res.statusText}`;\n }\n\n const data = await res.json() as {\n web?: { results?: Array<{ title: string; url: string; description: string }> };\n };\n\n const results = data.web?.results || [];\n if (results.length === 0) return `No results found for: ${query}`;\n\n return results.map((r, i) =>\n `${i + 1}. ${r.title}\\n ${r.url}\\n ${r.description}`\n ).join(\"\\n\\n\");\n } catch (err) {\n return `Search error: ${err instanceof Error ? err.message : err}`;\n }\n },\n};\n","/**\n * Web fetch tool — fetch content from a URL.\n */\n\nimport type { Tool, ToolContext, ValidationResult } from \"./types.js\";\n\nconst MAX_BODY = 500 * 1024; // 500KB cap\n\nexport const webFetchTool: Tool = {\n definition: {\n name: \"web_fetch\",\n description: \"Fetch content from a URL. Returns the response body as text. Max 500KB.\",\n parameters: {\n type: \"object\",\n properties: {\n url: { type: \"string\", description: \"URL to fetch\" },\n },\n required: [\"url\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>): ValidationResult {\n if (!args.url || typeof args.url !== \"string\") {\n return { ok: false, error: \"url is required\" };\n }\n try {\n const parsed = new URL(args.url as string);\n // Block SSRF targets\n if (parsed.protocol === \"file:\") return { ok: false, error: \"file:// URLs are not allowed\" };\n const host = parsed.hostname.toLowerCase();\n if (host === \"localhost\" || host === \"127.0.0.1\" || host === \"[::1]\" || host === \"0.0.0.0\") {\n return { ok: false, error: \"localhost URLs are blocked (SSRF protection)\" };\n }\n if (host === \"169.254.169.254\" || host === \"metadata.google.internal\") {\n return { ok: false, error: \"Cloud metadata endpoints are blocked\" };\n }\n if (host.endsWith(\".internal\") || host.endsWith(\".local\")) {\n return { ok: false, error: \"Internal network hostnames are blocked\" };\n }\n } catch {\n return { ok: false, error: \"Invalid URL\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const url = args.url as string;\n\n try {\n const res = await fetch(url, {\n headers: { \"User-Agent\": \"Clank/0.1.0\" },\n signal: ctx.signal || AbortSignal.timeout(30_000),\n });\n\n if (!res.ok) {\n return `HTTP ${res.status}: ${res.statusText}`;\n }\n\n const contentType = res.headers.get(\"content-type\") || \"\";\n if (contentType.includes(\"application/json\")) {\n const json = await res.json();\n const text = JSON.stringify(json, null, 2);\n return text.length > MAX_BODY ? text.slice(0, MAX_BODY) + \"\\n... (truncated)\" : text;\n }\n\n const text = await res.text();\n return text.length > MAX_BODY ? text.slice(0, MAX_BODY) + \"\\n... (truncated)\" : text;\n } catch (err) {\n return `Fetch error: ${err instanceof Error ? err.message : err}`;\n }\n },\n};\n","/**\n * Redact sensitive fields from config before exposing to LLMs or clients.\n *\n * API keys, bot tokens, and auth tokens are replaced with \"[REDACTED]\"\n * to prevent accidental leakage to cloud LLM providers or WebSocket clients.\n */\n\nconst SENSITIVE_KEYS = new Set([\n \"apikey\", \"api_key\", \"apiKey\",\n \"token\", \"bottoken\", \"botToken\",\n \"secret\", \"password\", \"pin\",\n]);\n\nexport function redactConfig(obj: unknown): unknown {\n if (typeof obj === \"string\") return obj;\n if (Array.isArray(obj)) return obj.map(redactConfig);\n if (obj && typeof obj === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n if (SENSITIVE_KEYS.has(key) && typeof value === \"string\" && value.length > 0) {\n result[key] = \"[REDACTED]\";\n } else if (typeof value === \"object\" && value !== null) {\n result[key] = redactConfig(value);\n } else {\n result[key] = value;\n }\n }\n return result;\n }\n return obj;\n}\n","/**\n * Config tool — lets the agent read and modify gateway config.\n *\n * This is the foundation of self-configuration. Instead of manually\n * editing config.json5, users just tell their agent what they want\n * and the agent uses this tool to make it happen.\n */\n\nimport { loadConfig, saveConfig, getConfigPath } from \"../../config/index.js\";\nimport { redactConfig } from \"../../config/redact.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"../types.js\";\n\nexport const configTool: Tool = {\n definition: {\n name: \"config\",\n description:\n \"Read or modify the Clank gateway configuration. Use 'read' to see current config, \" +\n \"'set' to change a value, or 'get' to read a specific key. \" +\n \"Keys use dot notation: 'gateway.port', 'agents.defaults.model.primary', etc.\",\n parameters: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n description: \"'read' (full config), 'get' (specific key), or 'set' (change a value)\",\n },\n key: { type: \"string\", description: \"Config key in dot notation (for get/set)\" },\n value: { type: \"string\", description: \"New value to set (for set action). JSON parsed if possible.\" },\n },\n required: [\"action\"],\n },\n },\n\n safetyLevel: (args) => (args.action === \"read\" || args.action === \"get\") ? \"low\" : \"medium\",\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n const action = args.action as string;\n if (![\"read\", \"get\", \"set\"].includes(action)) {\n return { ok: false, error: \"action must be 'read', 'get', or 'set'\" };\n }\n if ((action === \"get\" || action === \"set\") && !args.key) {\n return { ok: false, error: \"key is required for get/set\" };\n }\n if (action === \"set\" && args.value === undefined) {\n return { ok: false, error: \"value is required for set\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const action = args.action as string;\n const config = await loadConfig();\n\n if (action === \"read\") {\n return JSON.stringify(redactConfig(config), null, 2);\n }\n\n const key = args.key as string;\n const keys = key.split(\".\");\n\n if (action === \"get\") {\n let current: unknown = config;\n for (const k of keys) {\n if (current && typeof current === \"object\") {\n current = (current as Record<string, unknown>)[k];\n } else {\n return `Key not found: ${key}`;\n }\n }\n return typeof current === \"object\" ? JSON.stringify(current, null, 2) : String(current);\n }\n\n if (action === \"set\") {\n let parsed: unknown = args.value;\n try {\n parsed = JSON.parse(args.value as string);\n } catch {\n // Keep as string\n }\n\n // Navigate to parent and set the value\n let current: Record<string, unknown> = config as unknown as Record<string, unknown>;\n for (let i = 0; i < keys.length - 1; i++) {\n if (!current[keys[i]] || typeof current[keys[i]] !== \"object\") {\n current[keys[i]] = {};\n }\n current = current[keys[i]] as Record<string, unknown>;\n }\n current[keys[keys.length - 1]] = parsed;\n\n await saveConfig(config);\n return `Set ${key} = ${JSON.stringify(parsed)}`;\n }\n\n return \"Unknown action\";\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n if (args.action === \"set\") return `Set config: ${args.key} = ${args.value}`;\n return `Read config`;\n },\n};\n","/**\n * Channel tool — add, remove, and configure channels through conversation.\n *\n * \"Hey, connect my Telegram bot\" → agent uses this tool to add\n * the Telegram config, enable the adapter, and restart it.\n */\n\nimport { loadConfig, saveConfig } from \"../../config/index.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"../types.js\";\n\nexport const channelTool: Tool = {\n definition: {\n name: \"manage_channel\",\n description:\n \"Add, remove, or configure a messaging channel (Telegram, Discord, Slack, etc.). \" +\n \"Use 'list' to see configured channels, 'add' to set one up, 'remove' to disable, \" +\n \"'configure' to change settings.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"'list', 'add', 'remove', or 'configure'\" },\n channel: { type: \"string\", description: \"Channel name: 'telegram', 'discord', 'slack', 'web'\" },\n settings: { type: \"string\", description: \"JSON settings to apply (for add/configure)\" },\n },\n required: [\"action\"],\n },\n },\n\n safetyLevel: (args) => args.action === \"list\" ? \"low\" : \"medium\",\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n const action = args.action as string;\n if (![\"list\", \"add\", \"remove\", \"configure\"].includes(action)) {\n return { ok: false, error: \"action must be 'list', 'add', 'remove', or 'configure'\" };\n }\n if (action !== \"list\" && !args.channel) {\n return { ok: false, error: \"channel is required for add/remove/configure\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const config = await loadConfig();\n const action = args.action as string;\n\n if (action === \"list\") {\n const channels = config.channels || {};\n const entries = Object.entries(channels).map(([name, cfg]) => {\n const c = cfg as Record<string, unknown>;\n return `${name}: ${c.enabled ? \"enabled\" : \"disabled\"}`;\n });\n return entries.length > 0 ? entries.join(\"\\n\") : \"No channels configured\";\n }\n\n const channel = args.channel as string;\n\n if (action === \"add\" || action === \"configure\") {\n let settings: Record<string, unknown> = {};\n if (args.settings) {\n try {\n settings = JSON.parse(args.settings as string) as Record<string, unknown>;\n } catch {\n return \"Error: settings must be valid JSON\";\n }\n }\n\n if (!config.channels) config.channels = {};\n const existing = (config.channels as Record<string, unknown>)[channel] as Record<string, unknown> || {};\n (config.channels as Record<string, unknown>)[channel] = { ...existing, ...settings, enabled: true };\n\n await saveConfig(config);\n return `Channel ${channel} ${action === \"add\" ? \"added\" : \"updated\"} and enabled`;\n }\n\n if (action === \"remove\") {\n if (config.channels && (config.channels as Record<string, unknown>)[channel]) {\n ((config.channels as Record<string, unknown>)[channel] as Record<string, unknown>).enabled = false;\n await saveConfig(config);\n return `Channel ${channel} disabled`;\n }\n return `Channel ${channel} not found`;\n }\n\n return \"Unknown action\";\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `${args.action} channel: ${args.channel || \"all\"}`;\n },\n};\n","/**\n * Agent tool — add, configure, and manage agents through conversation.\n *\n * \"Create a new agent called Ratchet that uses Qwen 3.5 for coding\"\n * → agent uses this tool to add the definition and routing.\n */\n\nimport { loadConfig, saveConfig } from \"../../config/index.js\";\nimport type { Tool, ValidationResult } from \"../types.js\";\n\nexport const agentTool: Tool = {\n definition: {\n name: \"manage_agent\",\n description:\n \"Add, remove, list, or configure agents. Agents are named AI instances \" +\n \"with their own model, workspace, and tool access. \" +\n \"Use 'list' to see agents, 'add' to create one, 'remove' to delete, 'configure' to update.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"'list', 'add', 'remove', or 'configure'\" },\n id: { type: \"string\", description: \"Agent ID (lowercase, no spaces)\" },\n name: { type: \"string\", description: \"Display name for the agent\" },\n model: { type: \"string\", description: \"Model ID (e.g., 'ollama/qwen3.5')\" },\n workspace: { type: \"string\", description: \"Workspace directory path\" },\n toolTier: { type: \"string\", description: \"'full', 'core', or 'auto'\" },\n },\n required: [\"action\"],\n },\n },\n\n safetyLevel: (args) => args.action === \"list\" ? \"low\" : \"medium\",\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n const action = args.action as string;\n if (![\"list\", \"add\", \"remove\", \"configure\"].includes(action)) {\n return { ok: false, error: \"action must be 'list', 'add', 'remove', or 'configure'\" };\n }\n if (action !== \"list\" && !args.id) {\n return { ok: false, error: \"id is required\" };\n }\n if (action === \"add\" && !args.model) {\n return { ok: false, error: \"model is required when adding an agent\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const config = await loadConfig();\n const action = args.action as string;\n\n if (action === \"list\") {\n const agents = config.agents.list || [];\n if (agents.length === 0) return \"No agents configured (using default agent)\";\n return agents.map((a) =>\n `${a.id}: ${a.name || a.id} | model: ${a.model?.primary || \"default\"} | workspace: ${a.workspace || \"default\"}`\n ).join(\"\\n\");\n }\n\n const id = args.id as string;\n\n if (action === \"add\") {\n const existing = config.agents.list.find((a) => a.id === id);\n if (existing) return `Agent ${id} already exists. Use 'configure' to update.`;\n\n config.agents.list.push({\n id,\n name: (args.name as string) || id,\n model: { primary: args.model as string },\n workspace: args.workspace as string | undefined,\n toolTier: (args.toolTier as \"full\" | \"core\" | \"auto\") || undefined,\n });\n\n await saveConfig(config);\n return `Agent ${id} created with model ${args.model}`;\n }\n\n if (action === \"remove\") {\n const idx = config.agents.list.findIndex((a) => a.id === id);\n if (idx === -1) return `Agent ${id} not found`;\n config.agents.list.splice(idx, 1);\n await saveConfig(config);\n return `Agent ${id} removed`;\n }\n\n if (action === \"configure\") {\n const agent = config.agents.list.find((a) => a.id === id);\n if (!agent) return `Agent ${id} not found`;\n if (args.name) agent.name = args.name as string;\n if (args.model) agent.model = { primary: args.model as string };\n if (args.workspace) agent.workspace = args.workspace as string;\n if (args.toolTier) agent.toolTier = args.toolTier as \"full\" | \"core\" | \"auto\";\n await saveConfig(config);\n return `Agent ${id} updated`;\n }\n\n return \"Unknown action\";\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `${args.action} agent: ${args.id || \"all\"}`;\n },\n};\n","/**\n * Anthropic Claude provider.\n *\n * Uses the Messages API with SSE streaming. Cloud-only — used as a\n * fallback when local models can't handle a task, or when the user\n * explicitly configures a Claude model.\n */\n\nimport {\n BaseProvider,\n type Message,\n type StreamEvent,\n type ToolDefinition,\n type ContentBlock,\n} from \"./types.js\";\n\nconst CONTEXT_WINDOWS: Record<string, number> = {\n \"claude-opus-4-6\": 200000,\n \"claude-sonnet-4-6\": 200000,\n \"claude-haiku-4-5\": 200000,\n \"claude-sonnet-4-5\": 200000,\n};\n\nexport class AnthropicProvider extends BaseProvider {\n readonly name = \"anthropic\";\n private apiKey: string;\n private model: string;\n private baseUrl: string;\n\n constructor(opts: { apiKey: string; model: string; baseUrl?: string }) {\n super();\n this.apiKey = opts.apiKey;\n this.model = opts.model;\n this.baseUrl = opts.baseUrl || \"https://api.anthropic.com\";\n }\n\n contextWindow(): number {\n return CONTEXT_WINDOWS[this.model] ?? 200000;\n }\n\n formatTools(tools: ToolDefinition[]): unknown[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.parameters,\n }));\n }\n\n /**\n * Merge consecutive same-role messages.\n * Anthropic's API requires alternating user/assistant roles.\n */\n private prepareMessages(messages: Message[]): Array<Record<string, unknown>> {\n const result: Array<Record<string, unknown>> = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue; // System goes in separate param\n\n if (msg.role === \"tool\") {\n // Tool results become user messages with tool_result content blocks\n const block = {\n type: \"tool_result\",\n tool_use_id: msg.tool_call_id,\n content: typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content),\n };\n\n const last = result[result.length - 1];\n if (last && last.role === \"user\") {\n (last.content as unknown[]).push(block);\n } else {\n result.push({ role: \"user\", content: [block] });\n }\n continue;\n }\n\n if (msg.role === \"assistant\" && msg.tool_calls) {\n // Assistant with tool calls → tool_use content blocks\n const content: unknown[] = [];\n if (typeof msg.content === \"string\" && msg.content) {\n content.push({ type: \"text\", text: msg.content });\n }\n for (const tc of msg.tool_calls) {\n content.push({\n type: \"tool_use\",\n id: tc.id,\n name: tc.function.name,\n input: JSON.parse(tc.function.arguments),\n });\n }\n result.push({ role: \"assistant\", content });\n continue;\n }\n\n // Regular text message — merge with previous if same role\n const textContent = typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content);\n const last = result[result.length - 1];\n if (last && last.role === msg.role) {\n if (typeof last.content === \"string\") {\n last.content = last.content + \"\\n\" + textContent;\n } else {\n (last.content as unknown[]).push({ type: \"text\", text: textContent });\n }\n } else {\n result.push({ role: msg.role, content: textContent });\n }\n }\n\n return result;\n }\n\n async *stream(\n messages: Message[],\n systemPrompt: string,\n tools: ToolDefinition[],\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n const body: Record<string, unknown> = {\n model: this.model,\n messages: this.prepareMessages(messages),\n max_tokens: 8192,\n stream: true,\n };\n\n if (systemPrompt) {\n body.system = systemPrompt;\n }\n\n if (tools.length > 0) {\n body.tools = this.formatTools(tools);\n }\n\n const res = await fetch(`${this.baseUrl}/v1/messages`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": this.apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"Unknown error\");\n throw new Error(`Anthropic API error ${res.status}: ${text}`);\n }\n\n if (!res.body) throw new Error(\"No response body from Anthropic\");\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let currentToolId = \"\";\n let currentToolName = \"\";\n let currentToolArgs = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"data: \")) continue;\n\n const data = trimmed.slice(6);\n if (data === \"[DONE]\") continue;\n\n try {\n const event = JSON.parse(data) as Record<string, unknown>;\n const eventType = event.type as string;\n\n if (eventType === \"content_block_start\") {\n const block = event.content_block as Record<string, unknown>;\n if (block?.type === \"tool_use\") {\n currentToolId = block.id as string;\n currentToolName = block.name as string;\n currentToolArgs = \"\";\n }\n }\n\n if (eventType === \"content_block_delta\") {\n const delta = event.delta as Record<string, unknown>;\n if (delta?.type === \"text_delta\") {\n yield { type: \"text\", content: delta.text as string };\n }\n if (delta?.type === \"thinking_delta\") {\n yield { type: \"thinking\", content: delta.thinking as string };\n }\n if (delta?.type === \"input_json_delta\") {\n currentToolArgs += delta.partial_json as string;\n }\n }\n\n if (eventType === \"content_block_stop\") {\n if (currentToolId && currentToolName) {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(currentToolArgs) as Record<string, unknown>;\n } catch {\n parsedArgs = {};\n }\n yield {\n type: \"tool_call\",\n id: currentToolId,\n name: currentToolName,\n arguments: parsedArgs,\n };\n currentToolId = \"\";\n currentToolName = \"\";\n currentToolArgs = \"\";\n }\n }\n\n if (eventType === \"message_delta\") {\n const usage = (event as Record<string, unknown>).usage as Record<string, number> | undefined;\n if (usage) {\n yield {\n type: \"usage\",\n promptTokens: usage.input_tokens ?? 0,\n outputTokens: usage.output_tokens ?? 0,\n };\n }\n }\n\n if (eventType === \"message_stop\") {\n yield { type: \"done\" };\n return;\n }\n } catch {\n // Skip malformed events\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n yield { type: \"done\" };\n }\n\n formatAssistantToolUse(\n toolCallId: string,\n name: string,\n args: Record<string, unknown>,\n ): Message {\n return {\n role: \"assistant\",\n content: [\n { type: \"tool_use\", id: toolCallId, name, input: args } as ContentBlock,\n ],\n };\n }\n\n formatToolResult(\n toolCallId: string,\n _name: string,\n result: string,\n isError?: boolean,\n ): Message {\n return {\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n id: toolCallId,\n content: result,\n is_error: isError,\n } as ContentBlock,\n ],\n };\n }\n}\n","/**\n * OpenAI provider — also used for OpenAI-compatible local servers\n * like LM Studio, vLLM, and llama.cpp.\n *\n * The constructor takes a baseUrl so it can point to any\n * OpenAI-compatible endpoint. The `isLocal` flag adjusts behavior\n * (e.g., context window defaults, response token caps).\n */\n\nimport {\n BaseProvider,\n type Message,\n type StreamEvent,\n type ToolDefinition,\n} from \"./types.js\";\n\nconst CONTEXT_WINDOWS: Record<string, number> = {\n \"gpt-4o\": 128000,\n \"gpt-4o-mini\": 128000,\n \"gpt-4-turbo\": 128000,\n \"gpt-4\": 8192,\n \"gpt-3.5-turbo\": 16385,\n};\n\nexport class OpenAIProvider extends BaseProvider {\n readonly name = \"openai\";\n private baseUrl: string;\n private apiKey: string;\n private model: string;\n private isLocal: boolean;\n private maxResponseTokens?: number;\n\n constructor(opts: {\n baseUrl?: string;\n apiKey?: string;\n model: string;\n isLocal?: boolean;\n maxResponseTokens?: number;\n }) {\n super();\n this.baseUrl = (opts.baseUrl || \"https://api.openai.com\").replace(/\\/$/, \"\");\n this.apiKey = opts.apiKey || \"\";\n this.model = opts.model;\n this.isLocal = opts.isLocal ?? false;\n this.maxResponseTokens = opts.maxResponseTokens;\n }\n\n /**\n * Detect an OpenAI-compatible server by probing /v1/models.\n */\n static async detect(baseUrl: string): Promise<string[] | null> {\n try {\n const res = await fetch(`${baseUrl}/v1/models`, { signal: AbortSignal.timeout(3000) });\n if (!res.ok) return null;\n const data = (await res.json()) as { data?: Array<{ id: string }> };\n return data.data?.map((m) => m.id) ?? [];\n } catch {\n return null;\n }\n }\n\n contextWindow(): number {\n if (this.isLocal) return 32768;\n return CONTEXT_WINDOWS[this.model] ?? 128000;\n }\n\n formatTools(tools: ToolDefinition[]): unknown[] {\n return tools.map((t) => ({\n type: \"function\",\n function: {\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n },\n }));\n }\n\n private prepareMessages(\n messages: Message[],\n systemPrompt: string,\n ): Array<Record<string, unknown>> {\n const result: Array<Record<string, unknown>> = [];\n\n if (systemPrompt) {\n result.push({ role: \"system\", content: systemPrompt });\n }\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue;\n\n if (msg.role === \"tool\") {\n result.push({\n role: \"tool\",\n tool_call_id: msg.tool_call_id,\n content: typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content),\n });\n } else if (msg.role === \"assistant\" && msg.tool_calls) {\n result.push({\n role: \"assistant\",\n content: typeof msg.content === \"string\" && msg.content ? msg.content : null,\n tool_calls: msg.tool_calls,\n });\n } else {\n result.push({\n role: msg.role,\n content: typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content),\n });\n }\n }\n\n return result;\n }\n\n async *stream(\n messages: Message[],\n systemPrompt: string,\n tools: ToolDefinition[],\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n const body: Record<string, unknown> = {\n model: this.model,\n messages: this.prepareMessages(messages, systemPrompt),\n stream: true,\n stream_options: { include_usage: true },\n };\n\n if (tools.length > 0) {\n body.tools = this.formatTools(tools);\n }\n\n if (this.maxResponseTokens) {\n body.max_tokens = this.maxResponseTokens;\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.apiKey) {\n headers[\"Authorization\"] = `Bearer ${this.apiKey}`;\n }\n\n const res = await fetch(`${this.baseUrl}/v1/chat/completions`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"Unknown error\");\n throw new Error(`OpenAI API error ${res.status}: ${text}`);\n }\n\n if (!res.body) throw new Error(\"No response body from OpenAI\");\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n const toolCalls = new Map<number, { id: string; name: string; arguments: string }>();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"data: \")) continue;\n\n const data = trimmed.slice(6);\n if (data === \"[DONE]\") {\n for (const tc of toolCalls.values()) {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(tc.arguments) as Record<string, unknown>;\n } catch {\n parsedArgs = {};\n }\n yield { type: \"tool_call\", id: tc.id, name: tc.name, arguments: parsedArgs };\n }\n yield { type: \"done\" };\n return;\n }\n\n try {\n const chunk = JSON.parse(data) as {\n choices?: Array<{\n delta?: {\n content?: string | null;\n reasoning_content?: string | null;\n tool_calls?: Array<{\n index: number;\n id?: string;\n function?: { name?: string; arguments?: string };\n }>;\n };\n }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number };\n };\n\n const choice = chunk.choices?.[0];\n if (choice?.delta?.reasoning_content) {\n yield { type: \"thinking\", content: choice.delta.reasoning_content };\n }\n if (choice?.delta?.content) {\n yield { type: \"text\", content: choice.delta.content };\n }\n\n if (choice?.delta?.tool_calls) {\n for (const tc of choice.delta.tool_calls) {\n const existing = toolCalls.get(tc.index);\n if (existing) {\n if (tc.function?.arguments) existing.arguments += tc.function.arguments;\n } else {\n toolCalls.set(tc.index, {\n id: tc.id || `call_${tc.index}`,\n name: tc.function?.name || \"\",\n arguments: tc.function?.arguments || \"\",\n });\n }\n }\n }\n\n if (chunk.usage) {\n yield {\n type: \"usage\",\n promptTokens: chunk.usage.prompt_tokens ?? 0,\n outputTokens: chunk.usage.completion_tokens ?? 0,\n };\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n for (const tc of toolCalls.values()) {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(tc.arguments) as Record<string, unknown>;\n } catch {\n parsedArgs = {};\n }\n yield { type: \"tool_call\", id: tc.id, name: tc.name, arguments: parsedArgs };\n }\n yield { type: \"done\" };\n }\n\n formatAssistantToolUse(\n toolCallId: string,\n name: string,\n args: Record<string, unknown>,\n ): Message {\n return {\n role: \"assistant\",\n content: \"\",\n tool_calls: [\n {\n id: toolCallId,\n type: \"function\",\n function: { name, arguments: JSON.stringify(args) },\n },\n ],\n };\n }\n\n formatToolResult(\n toolCallId: string,\n _name: string,\n result: string,\n _isError?: boolean,\n ): Message {\n return {\n role: \"tool\",\n content: result,\n tool_call_id: toolCallId,\n };\n }\n}\n","/**\n * Google Gemini provider.\n *\n * Uses the Generative AI REST API with streaming.\n * Supports Gemini 2.0 Flash (1M context) and Gemini 1.5 Pro (2M context).\n */\n\nimport {\n BaseProvider,\n type Message,\n type StreamEvent,\n type ToolDefinition,\n} from \"./types.js\";\n\nconst CONTEXT_WINDOWS: Record<string, number> = {\n \"gemini-2.0-flash\": 1048576,\n \"gemini-1.5-flash\": 1048576,\n \"gemini-1.5-pro\": 2097152,\n};\n\n/** Map JSON Schema types to Gemini's uppercase types */\nfunction mapType(type: string): string {\n const MAP: Record<string, string> = {\n string: \"STRING\", number: \"NUMBER\", integer: \"INTEGER\",\n boolean: \"BOOLEAN\", array: \"ARRAY\", object: \"OBJECT\",\n };\n return MAP[type] || \"STRING\";\n}\n\nexport class GoogleProvider extends BaseProvider {\n readonly name = \"google\";\n private apiKey: string;\n private model: string;\n\n constructor(opts: { apiKey: string; model: string }) {\n super();\n this.apiKey = opts.apiKey;\n this.model = opts.model;\n }\n\n contextWindow(): number {\n return CONTEXT_WINDOWS[this.model] ?? 1048576;\n }\n\n formatTools(tools: ToolDefinition[]): unknown[] {\n return [{\n functionDeclarations: tools.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: convertSchema(t.parameters),\n })),\n }];\n }\n\n /**\n * Prepare messages for Gemini API.\n * Gemini uses \"user\" and \"model\" roles, and requires alternation.\n */\n private prepareContents(messages: Message[]): Array<Record<string, unknown>> {\n const contents: Array<Record<string, unknown>> = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue;\n\n const role = msg.role === \"assistant\" ? \"model\" : \"user\";\n const text = typeof msg.content === \"string\" ? msg.content : JSON.stringify(msg.content);\n\n if (msg.role === \"tool\") {\n // Tool results as function responses\n contents.push({\n role: \"function\",\n parts: [{\n functionResponse: {\n name: msg.tool_call_id || \"unknown\",\n response: { content: text },\n },\n }],\n });\n continue;\n }\n\n if (msg.role === \"assistant\" && msg.tool_calls) {\n // Assistant with tool calls\n const parts: unknown[] = [];\n if (text) parts.push({ text });\n for (const tc of msg.tool_calls) {\n parts.push({\n functionCall: {\n name: tc.function.name,\n args: JSON.parse(tc.function.arguments),\n },\n });\n }\n contents.push({ role: \"model\", parts });\n continue;\n }\n\n // Merge consecutive same-role messages\n const last = contents[contents.length - 1];\n if (last && last.role === role) {\n (last.parts as unknown[]).push({ text });\n } else {\n contents.push({ role, parts: [{ text }] });\n }\n }\n\n return contents;\n }\n\n async *stream(\n messages: Message[],\n systemPrompt: string,\n tools: ToolDefinition[],\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n const contents = this.prepareContents(messages);\n\n const body: Record<string, unknown> = { contents };\n\n if (systemPrompt) {\n body.systemInstruction = { parts: [{ text: systemPrompt }] };\n }\n\n if (tools.length > 0) {\n body.tools = this.formatTools(tools);\n }\n\n const url = `https://generativelanguage.googleapis.com/v1beta/models/${this.model}:streamGenerateContent?key=${this.apiKey}&alt=sse`;\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"Unknown error\");\n throw new Error(`Google API error ${res.status}: ${text}`);\n }\n\n if (!res.body) throw new Error(\"No response body from Google\");\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"data: \")) continue;\n\n try {\n const data = JSON.parse(trimmed.slice(6)) as {\n candidates?: Array<{\n content?: {\n parts?: Array<{\n text?: string;\n functionCall?: { name: string; args: Record<string, unknown> };\n }>;\n };\n }>;\n usageMetadata?: { promptTokenCount?: number; candidatesTokenCount?: number };\n };\n\n const parts = data.candidates?.[0]?.content?.parts || [];\n for (const part of parts) {\n if (part.text) {\n yield { type: \"text\", content: part.text };\n }\n if (part.functionCall) {\n yield {\n type: \"tool_call\",\n id: `google_${Date.now()}`,\n name: part.functionCall.name,\n arguments: part.functionCall.args,\n };\n }\n }\n\n if (data.usageMetadata) {\n yield {\n type: \"usage\",\n promptTokens: data.usageMetadata.promptTokenCount ?? 0,\n outputTokens: data.usageMetadata.candidatesTokenCount ?? 0,\n };\n }\n } catch {\n // Skip malformed chunks\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n yield { type: \"done\" };\n }\n\n formatAssistantToolUse(\n toolCallId: string,\n name: string,\n args: Record<string, unknown>,\n ): Message {\n return {\n role: \"assistant\",\n content: \"\",\n tool_calls: [{\n id: toolCallId,\n type: \"function\",\n function: { name, arguments: JSON.stringify(args) },\n }],\n };\n }\n\n formatToolResult(\n toolCallId: string,\n name: string,\n result: string,\n _isError?: boolean,\n ): Message {\n return {\n role: \"tool\",\n content: result,\n tool_call_id: name, // Gemini uses function name as ID\n };\n }\n}\n\n/** Convert JSON Schema to Gemini's format */\nfunction convertSchema(schema: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n if (schema.type) result.type = mapType(schema.type as string);\n if (schema.description) result.description = schema.description;\n if (schema.required) result.required = schema.required;\n\n if (schema.properties) {\n result.properties = {};\n for (const [key, value] of Object.entries(schema.properties as Record<string, Record<string, unknown>>)) {\n (result.properties as Record<string, unknown>)[key] = convertSchema(value);\n }\n }\n\n if (schema.items) {\n result.items = convertSchema(schema.items as Record<string, unknown>);\n }\n\n return result;\n}\n","/**\n * Provider router — resolves model identifiers to provider instances.\n *\n * Model identifiers use the format \"provider/model\", e.g.:\n * - \"ollama/qwen3.5\"\n * - \"anthropic/claude-sonnet-4-6\"\n * - \"openai/gpt-4o\"\n *\n * The router also handles the fallback chain: if the primary model fails,\n * it tries fallbacks in order. This is how local-first works in practice —\n * try Ollama first, fall back to cloud if needed.\n */\n\nimport { type BaseProvider, type ResolvedProvider } from \"./types.js\";\nimport { OllamaProvider } from \"./ollama.js\";\nimport { AnthropicProvider } from \"./anthropic.js\";\nimport { OpenAIProvider } from \"./openai.js\";\nimport { GoogleProvider } from \"./google.js\";\n\nexport interface ProviderConfig {\n ollama?: {\n baseUrl?: string;\n };\n anthropic?: {\n apiKey: string;\n baseUrl?: string;\n };\n openai?: {\n apiKey: string;\n baseUrl?: string;\n };\n google?: {\n apiKey: string;\n baseUrl?: string;\n };\n /** Local OpenAI-compatible servers (llamacpp, lmstudio, vllm, etc.) */\n [key: string]: { baseUrl?: string; apiKey?: string } | undefined;\n}\n\n/**\n * Parse a model identifier like \"ollama/qwen3.5\" into provider + model.\n */\nexport function parseModelId(modelId: string): { provider: string; model: string } {\n const slash = modelId.indexOf(\"/\");\n if (slash === -1) {\n // No provider prefix — assume ollama for local-first\n return { provider: \"ollama\", model: modelId };\n }\n return {\n provider: modelId.slice(0, slash),\n model: modelId.slice(slash + 1),\n };\n}\n\n/**\n * Create a provider instance for a model identifier.\n */\nexport function createProvider(\n modelId: string,\n config: ProviderConfig,\n opts?: { maxResponseTokens?: number },\n): ResolvedProvider {\n const { provider, model } = parseModelId(modelId);\n\n switch (provider) {\n case \"ollama\": {\n const p = new OllamaProvider({\n baseUrl: config.ollama?.baseUrl,\n model,\n maxResponseTokens: opts?.maxResponseTokens,\n });\n return { provider: p, providerName: \"ollama\", modelId, isLocal: true };\n }\n\n case \"anthropic\": {\n if (!config.anthropic?.apiKey) {\n throw new Error(`Anthropic API key required for model ${modelId}`);\n }\n const p = new AnthropicProvider({\n apiKey: config.anthropic.apiKey,\n model,\n baseUrl: config.anthropic.baseUrl,\n });\n return { provider: p, providerName: \"anthropic\", modelId, isLocal: false };\n }\n\n case \"openai\": {\n if (!config.openai?.apiKey) {\n throw new Error(`OpenAI API key required for model ${modelId}`);\n }\n const p = new OpenAIProvider({\n apiKey: config.openai.apiKey,\n model,\n baseUrl: config.openai.baseUrl,\n maxResponseTokens: opts?.maxResponseTokens,\n });\n return { provider: p, providerName: \"openai\", modelId, isLocal: false };\n }\n\n case \"google\": {\n if (!config.google?.apiKey) {\n throw new Error(`Google API key required for model ${modelId}`);\n }\n const p = new GoogleProvider({ apiKey: config.google.apiKey, model });\n return { provider: p, providerName: \"google\", modelId, isLocal: false };\n }\n\n case \"lmstudio\":\n case \"llamacpp\":\n case \"vllm\":\n case \"local\": {\n // These are all OpenAI-compatible local servers\n const defaultUrls: Record<string, string> = {\n lmstudio: \"http://127.0.0.1:1234\",\n llamacpp: \"http://127.0.0.1:8080\",\n vllm: \"http://127.0.0.1:8000\",\n local: \"http://127.0.0.1:8080\",\n };\n // Read base URL from config (e.g., config.llamacpp.baseUrl)\n const providerCfg = config[provider];\n const baseUrl = providerCfg?.baseUrl || defaultUrls[provider] || defaultUrls.local;\n const p = new OpenAIProvider({\n baseUrl,\n model,\n isLocal: true,\n maxResponseTokens: opts?.maxResponseTokens,\n });\n return { provider: p, providerName: provider, modelId, isLocal: true };\n }\n\n default:\n throw new Error(`Unknown provider: ${provider}`);\n }\n}\n\n/**\n * Resolve a model with fallback chain.\n *\n * Tries the primary model first, then fallbacks in order.\n * Returns the first provider that can be created successfully.\n * For Ollama, also checks if the server is reachable.\n */\nexport async function resolveWithFallback(\n primary: string,\n fallbacks: string[],\n config: ProviderConfig,\n opts?: { maxResponseTokens?: number },\n): Promise<ResolvedProvider> {\n const chain = [primary, ...fallbacks];\n\n for (const modelId of chain) {\n try {\n const resolved = createProvider(modelId, config, opts);\n\n // For local providers, verify the server is reachable\n if (resolved.isLocal && resolved.providerName === \"ollama\") {\n const models = await OllamaProvider.detect(config.ollama?.baseUrl);\n if (!models) {\n continue; // Ollama not running, try next\n }\n }\n\n return resolved;\n } catch {\n // This provider can't be created (e.g., missing API key), try next\n continue;\n }\n }\n\n throw new Error(\n `No available provider. Tried: ${chain.join(\", \")}. ` +\n `Check that your model server is running or API keys are configured.`,\n );\n}\n\n/**\n * Auto-detect available local model servers.\n * Returns a list of detected servers with their models.\n */\nexport async function detectLocalServers(): Promise<\n Array<{ provider: string; baseUrl: string; models: string[] }>\n> {\n const servers: Array<{ provider: string; baseUrl: string; models: string[] }> = [];\n\n // Check Ollama\n const ollamaModels = await OllamaProvider.detect();\n if (ollamaModels) {\n servers.push({\n provider: \"ollama\",\n baseUrl: \"http://127.0.0.1:11434\",\n models: ollamaModels,\n });\n }\n\n // Check LM Studio\n const lmStudioModels = await OpenAIProvider.detect(\"http://127.0.0.1:1234\");\n if (lmStudioModels) {\n servers.push({\n provider: \"lmstudio\",\n baseUrl: \"http://127.0.0.1:1234\",\n models: lmStudioModels,\n });\n }\n\n // Check llama.cpp (common ports)\n for (const port of [8080, 14438]) {\n const llamaCppModels = await OpenAIProvider.detect(`http://127.0.0.1:${port}`);\n if (llamaCppModels) {\n servers.push({\n provider: \"llamacpp\",\n baseUrl: `http://127.0.0.1:${port}`,\n models: llamaCppModels,\n });\n break; // Found one, stop checking\n }\n }\n\n // Check vLLM\n const vllmModels = await OpenAIProvider.detect(\"http://127.0.0.1:8000\");\n if (vllmModels) {\n servers.push({\n provider: \"vllm\",\n baseUrl: \"http://127.0.0.1:8000\",\n models: vllmModels,\n });\n }\n\n return servers;\n}\n","export { BaseProvider } from \"./types.js\";\nexport type {\n StreamEvent,\n ToolDefinition,\n Message,\n ContentBlock,\n ToolCallMessage,\n ModelCompatConfig,\n ResolvedProvider,\n ModelConfig,\n} from \"./types.js\";\n\nexport { OllamaProvider } from \"./ollama.js\";\nexport { AnthropicProvider } from \"./anthropic.js\";\nexport { OpenAIProvider } from \"./openai.js\";\nexport { GoogleProvider } from \"./google.js\";\nexport { PromptFallbackProvider } from \"./prompt-fallback.js\";\n\nexport {\n parseModelId,\n createProvider,\n resolveWithFallback,\n detectLocalServers,\n type ProviderConfig,\n} from \"./router.js\";\n","/**\n * Model tool — manage models and providers through conversation.\n */\n\nimport { loadConfig, saveConfig } from \"../../config/index.js\";\nimport { detectLocalServers } from \"../../providers/index.js\";\nimport type { Tool, ValidationResult } from \"../types.js\";\n\nexport const modelTool: Tool = {\n definition: {\n name: \"manage_model\",\n description:\n \"List available models, detect local servers, add providers, or switch the default model. \" +\n \"Use 'detect' to scan for local model servers, 'list' to see configured models, \" +\n \"'set-default' to change the primary model, 'add-provider' to add a cloud provider.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"'list', 'detect', 'set-default', or 'add-provider'\" },\n model: { type: \"string\", description: \"Model ID for set-default (e.g., 'ollama/qwen3.5')\" },\n provider: { type: \"string\", description: \"Provider name for add-provider ('anthropic', 'openai', 'google')\" },\n apiKey: { type: \"string\", description: \"API key for add-provider\" },\n },\n required: [\"action\"],\n },\n },\n\n safetyLevel: (args) => (args.action === \"list\" || args.action === \"detect\") ? \"low\" : \"medium\",\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n const action = args.action as string;\n if (![\"list\", \"detect\", \"set-default\", \"add-provider\"].includes(action)) {\n return { ok: false, error: \"Invalid action\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const config = await loadConfig();\n const action = args.action as string;\n\n if (action === \"detect\") {\n const servers = await detectLocalServers();\n if (servers.length === 0) return \"No local model servers detected.\";\n return servers.map((s) =>\n `${s.provider} at ${s.baseUrl}\\n Models: ${s.models.slice(0, 10).join(\", \")}`\n ).join(\"\\n\\n\");\n }\n\n if (action === \"list\") {\n const lines: string[] = [];\n lines.push(`Default: ${config.agents.defaults.model.primary}`);\n if (config.agents.defaults.model.fallbacks?.length) {\n lines.push(`Fallbacks: ${config.agents.defaults.model.fallbacks.join(\", \")}`);\n }\n lines.push(\"\\nProviders:\");\n for (const [name, cfg] of Object.entries(config.models.providers)) {\n const c = cfg as Record<string, unknown>;\n lines.push(` ${name}: ${c.baseUrl || c.apiKey ? \"configured\" : \"not configured\"}`);\n }\n return lines.join(\"\\n\");\n }\n\n if (action === \"set-default\") {\n if (!args.model) return \"Error: model is required\";\n config.agents.defaults.model.primary = args.model as string;\n await saveConfig(config);\n return `Default model set to ${args.model}`;\n }\n\n if (action === \"add-provider\") {\n if (!args.provider || !args.apiKey) return \"Error: provider and apiKey are required\";\n const provider = args.provider as string;\n (config.models.providers as Record<string, unknown>)[provider] = { apiKey: args.apiKey as string };\n await saveConfig(config);\n return `Provider ${provider} added with API key`;\n }\n\n return \"Unknown action\";\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `${args.action} model configuration`;\n },\n};\n","/**\n * Session store — manages conversation sessions.\n *\n * Sessions are persisted as JSON files on disk. Each session has a\n * normalized key that identifies it across channels:\n * - cli:main (CLI default session)\n * - web:main (Web UI default session)\n * - dm:telegram:123 (Telegram DM with user 123)\n * - group:discord:456 (Discord server 456)\n *\n * This cross-channel key system is what enables session continuity —\n * start in CLI, continue in the browser, check from Telegram.\n */\n\nimport { readFile, writeFile, readdir, unlink, mkdir } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport type { Message } from \"../providers/types.js\";\n\nexport interface SessionEntry {\n id: string;\n normalizedKey: string;\n label?: string;\n agentId?: string;\n model?: string;\n lastChannel?: string;\n updatedAt: number;\n createdAt: number;\n}\n\nexport interface SessionData {\n entry: SessionEntry;\n messages: Message[];\n}\n\nexport class SessionStore {\n private storeDir: string;\n private indexPath: string;\n private index: Map<string, SessionEntry> = new Map();\n\n constructor(storeDir: string) {\n this.storeDir = storeDir;\n this.indexPath = join(storeDir, \"sessions.json\");\n }\n\n /** Initialize the store — load index from disk */\n async init(): Promise<void> {\n await mkdir(this.storeDir, { recursive: true });\n\n if (existsSync(this.indexPath)) {\n try {\n const raw = await readFile(this.indexPath, \"utf-8\");\n const entries = JSON.parse(raw) as SessionEntry[];\n for (const entry of entries) {\n this.index.set(entry.normalizedKey, entry);\n }\n } catch {\n // Corrupt index — start fresh\n this.index.clear();\n }\n }\n }\n\n /** Save the index to disk */\n private async saveIndex(): Promise<void> {\n const entries = Array.from(this.index.values());\n await writeFile(this.indexPath, JSON.stringify(entries, null, 2), \"utf-8\");\n }\n\n /** Get or create a session for a normalized key */\n async resolve(normalizedKey: string, opts?: { agentId?: string; channel?: string }): Promise<SessionEntry> {\n let entry = this.index.get(normalizedKey);\n if (entry) {\n // Update last access\n entry.updatedAt = Date.now();\n if (opts?.channel) entry.lastChannel = opts.channel;\n if (opts?.agentId) entry.agentId = opts.agentId;\n await this.saveIndex();\n return entry;\n }\n\n // Create new session\n entry = {\n id: randomUUID(),\n normalizedKey,\n agentId: opts?.agentId,\n lastChannel: opts?.channel,\n updatedAt: Date.now(),\n createdAt: Date.now(),\n };\n this.index.set(normalizedKey, entry);\n await this.saveIndex();\n return entry;\n }\n\n /** Load conversation messages for a session */\n async loadMessages(sessionId: string): Promise<Message[]> {\n const path = join(this.storeDir, `${sessionId}.json`);\n if (!existsSync(path)) return [];\n\n try {\n const raw = await readFile(path, \"utf-8\");\n return JSON.parse(raw) as Message[];\n } catch {\n return [];\n }\n }\n\n /** Save conversation messages for a session */\n async saveMessages(sessionId: string, messages: Message[]): Promise<void> {\n const path = join(this.storeDir, `${sessionId}.json`);\n await writeFile(path, JSON.stringify(messages, null, 2), \"utf-8\");\n }\n\n /** List all sessions, sorted by last used */\n list(): SessionEntry[] {\n return Array.from(this.index.values()).sort((a, b) => b.updatedAt - a.updatedAt);\n }\n\n /** Delete a session */\n async delete(normalizedKey: string): Promise<boolean> {\n const entry = this.index.get(normalizedKey);\n if (!entry) return false;\n\n this.index.delete(normalizedKey);\n await this.saveIndex();\n\n // Delete conversation file\n const path = join(this.storeDir, `${entry.id}.json`);\n try {\n await unlink(path);\n } catch {\n // File may not exist\n }\n\n return true;\n }\n\n /** Reset a session (clear messages but keep the entry) */\n async reset(normalizedKey: string): Promise<SessionEntry | null> {\n const entry = this.index.get(normalizedKey);\n if (!entry) return null;\n\n // Clear messages\n const path = join(this.storeDir, `${entry.id}.json`);\n try {\n await unlink(path);\n } catch {\n // OK if file doesn't exist\n }\n\n entry.updatedAt = Date.now();\n await this.saveIndex();\n return entry;\n }\n\n /** Prune old sessions to stay under the max count */\n async prune(maxSessions: number): Promise<number> {\n const entries = this.list();\n let pruned = 0;\n\n while (entries.length - pruned > maxSessions) {\n const oldest = entries[entries.length - 1 - pruned];\n if (oldest) {\n await this.delete(oldest.normalizedKey);\n pruned++;\n } else {\n break;\n }\n }\n\n return pruned;\n }\n\n /** Update a session's label (auto-title from first message) */\n async setLabel(normalizedKey: string, label: string): Promise<void> {\n const entry = this.index.get(normalizedKey);\n if (entry) {\n entry.label = label;\n await this.saveIndex();\n }\n }\n}\n","export { SessionStore, type SessionEntry, type SessionData } from \"./store.js\";\n","/**\n * Session tool — list, manage, and spawn sessions through conversation.\n */\n\nimport { join } from \"node:path\";\nimport { getConfigDir } from \"../../config/index.js\";\nimport { SessionStore } from \"../../sessions/index.js\";\nimport type { Tool, ValidationResult } from \"../types.js\";\n\nexport const sessionTool: Tool = {\n definition: {\n name: \"manage_session\",\n description:\n \"List, inspect, reset, or delete chat sessions. \" +\n \"Use 'list' to see all sessions, 'reset' to clear a session's history, \" +\n \"'delete' to remove a session entirely.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"'list', 'reset', or 'delete'\" },\n sessionKey: { type: \"string\", description: \"Session key (for reset/delete)\" },\n },\n required: [\"action\"],\n },\n },\n\n safetyLevel: (args) => args.action === \"list\" ? \"low\" : \"medium\",\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n const action = args.action as string;\n if (![\"list\", \"reset\", \"delete\"].includes(action)) {\n return { ok: false, error: \"action must be 'list', 'reset', or 'delete'\" };\n }\n if (action !== \"list\" && !args.sessionKey) {\n return { ok: false, error: \"sessionKey is required\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const store = new SessionStore(join(getConfigDir(), \"conversations\"));\n await store.init();\n\n const action = args.action as string;\n\n if (action === \"list\") {\n const sessions = store.list();\n if (sessions.length === 0) return \"No sessions\";\n return sessions.map((s) =>\n `${s.normalizedKey} | ${s.label || \"(untitled)\"} | agent: ${s.agentId || \"default\"} | ${new Date(s.updatedAt).toLocaleString()}`\n ).join(\"\\n\");\n }\n\n const key = args.sessionKey as string;\n\n if (action === \"reset\") {\n const result = await store.reset(key);\n return result ? `Session ${key} reset` : `Session ${key} not found`;\n }\n\n if (action === \"delete\") {\n const result = await store.delete(key);\n return result ? `Session ${key} deleted` : `Session ${key} not found`;\n }\n\n return \"Unknown action\";\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `${args.action} session: ${args.sessionKey || \"all\"}`;\n },\n};\n","/**\n * Cron scheduler — runs agent tasks on a schedule.\n *\n * Jobs are stored in JSONL format. The gateway ticks every 30 seconds\n * and checks for due jobs. Each job spawns an agent session, runs the\n * prompt, and logs the result.\n *\n * Uses standard cron expressions (e.g., \"0 9 * * *\" for 9am daily).\n */\n\nimport { readFile, appendFile, mkdir, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\n\nexport interface CronJob {\n id: string;\n name: string;\n /** Standard cron expression */\n schedule: string;\n /** Agent ID to run the job */\n agentId: string;\n /** Prompt to send to the agent */\n prompt: string;\n /** Whether the job is active */\n enabled: boolean;\n /** When the job was created */\n createdAt: number;\n /** Last successful run timestamp */\n lastRunAt?: number;\n /** Last run status */\n lastStatus?: \"success\" | \"error\";\n /** Failure count for retry backoff */\n failCount: number;\n}\n\nexport interface CronRunLog {\n jobId: string;\n startedAt: number;\n completedAt: number;\n status: \"success\" | \"error\";\n output?: string;\n error?: string;\n}\n\nexport class CronScheduler {\n private jobsPath: string;\n private runsDir: string;\n private jobs: CronJob[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private running = false;\n private onJobDue?: (job: CronJob) => Promise<void>;\n\n constructor(storeDir: string) {\n this.jobsPath = join(storeDir, \"jobs.jsonl\");\n this.runsDir = join(storeDir, \"runs\");\n }\n\n /** Initialize — load jobs from disk */\n async init(): Promise<void> {\n await mkdir(this.runsDir, { recursive: true });\n await this.loadJobs();\n }\n\n /** Set callback for when a job is due */\n setHandler(handler: (job: CronJob) => Promise<void>): void {\n this.onJobDue = handler;\n }\n\n /** Start the scheduler (ticks every 30s) */\n start(): void {\n if (this.running) return;\n this.running = true;\n this.timer = setInterval(() => this.tick(), 30_000);\n // Run immediately on start\n this.tick();\n }\n\n /** Stop the scheduler */\n stop(): void {\n this.running = false;\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n\n /** Check for due jobs */\n private async tick(): Promise<void> {\n const now = Date.now();\n\n for (const job of this.jobs) {\n if (!job.enabled) continue;\n\n if (this.isDue(job, now)) {\n try {\n if (this.onJobDue) {\n await this.onJobDue(job);\n }\n job.lastRunAt = now;\n job.lastStatus = \"success\";\n job.failCount = 0;\n await this.logRun({ jobId: job.id, startedAt: now, completedAt: Date.now(), status: \"success\" });\n } catch (err) {\n job.failCount++;\n job.lastStatus = \"error\";\n await this.logRun({\n jobId: job.id,\n startedAt: now,\n completedAt: Date.now(),\n status: \"error\",\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n\n await this.saveJobs();\n }\n\n /** Check if a job is due to run */\n private isDue(job: CronJob, now: number): boolean {\n // Simple cron matching — check if enough time has passed\n // A full cron parser would use a library like cron-parser\n const interval = this.parseSimpleInterval(job.schedule);\n if (!interval) return false;\n\n if (!job.lastRunAt) return true;\n return now - job.lastRunAt >= interval;\n }\n\n /**\n * Parse simple schedule strings.\n * For v1, supports: \"30s\", \"5m\", \"1h\", \"24h\", \"daily\"\n * Full cron expressions will use cron-parser library later.\n */\n private parseSimpleInterval(schedule: string): number | null {\n const match = schedule.match(/^(\\d+)(s|m|h)$/);\n if (match) {\n const value = parseInt(match[1], 10);\n const unit = match[2];\n switch (unit) {\n case \"s\": return value * 1000;\n case \"m\": return value * 60_000;\n case \"h\": return value * 3600_000;\n }\n }\n if (schedule === \"daily\") return 86400_000;\n return null;\n }\n\n /** Add a new job */\n async addJob(opts: { name: string; schedule: string; agentId: string; prompt: string }): Promise<CronJob> {\n const job: CronJob = {\n id: randomUUID(),\n name: opts.name,\n schedule: opts.schedule,\n agentId: opts.agentId,\n prompt: opts.prompt,\n enabled: true,\n createdAt: Date.now(),\n failCount: 0,\n };\n this.jobs.push(job);\n await this.saveJobs();\n return job;\n }\n\n /** Remove a job */\n async removeJob(jobId: string): Promise<boolean> {\n const idx = this.jobs.findIndex((j) => j.id === jobId);\n if (idx === -1) return false;\n this.jobs.splice(idx, 1);\n await this.saveJobs();\n return true;\n }\n\n /** List all jobs */\n listJobs(): CronJob[] {\n return [...this.jobs];\n }\n\n /** Enable/disable a job */\n async toggleJob(jobId: string, enabled: boolean): Promise<void> {\n const job = this.jobs.find((j) => j.id === jobId);\n if (job) {\n job.enabled = enabled;\n await this.saveJobs();\n }\n }\n\n /** Load jobs from JSONL file */\n private async loadJobs(): Promise<void> {\n if (!existsSync(this.jobsPath)) return;\n\n try {\n const raw = await readFile(this.jobsPath, \"utf-8\");\n this.jobs = raw\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => JSON.parse(line) as CronJob);\n } catch {\n this.jobs = [];\n }\n }\n\n /** Save jobs to JSONL file */\n private async saveJobs(): Promise<void> {\n const content = this.jobs.map((j) => JSON.stringify(j)).join(\"\\n\") + \"\\n\";\n await writeFile(this.jobsPath, content, \"utf-8\");\n }\n\n /** Log a run result */\n private async logRun(log: CronRunLog): Promise<void> {\n const logPath = join(this.runsDir, `${log.jobId}.jsonl`);\n await appendFile(logPath, JSON.stringify(log) + \"\\n\", \"utf-8\");\n }\n}\n","export { CronScheduler, type CronJob, type CronRunLog } from \"./scheduler.js\";\n","/**\n * Cron tool — manage scheduled tasks through conversation.\n *\n * \"Check my email every hour\" → agent creates a cron job.\n */\n\nimport { join } from \"node:path\";\nimport { getConfigDir } from \"../../config/index.js\";\nimport { CronScheduler } from \"../../cron/index.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"../types.js\";\n\nexport const cronTool: Tool = {\n definition: {\n name: \"manage_cron\",\n description:\n \"Create, list, enable, disable, or remove scheduled tasks. \" +\n \"Schedules use simple formats: '30s', '5m', '1h', '24h', 'daily'.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"'list', 'add', 'remove', 'enable', or 'disable'\" },\n name: { type: \"string\", description: \"Job name (for add)\" },\n schedule: { type: \"string\", description: \"Schedule expression (for add)\" },\n prompt: { type: \"string\", description: \"What the agent should do (for add)\" },\n agentId: { type: \"string\", description: \"Agent to run the job (default: current)\" },\n jobId: { type: \"string\", description: \"Job ID (for remove/enable/disable)\" },\n },\n required: [\"action\"],\n },\n },\n\n safetyLevel: (args) => args.action === \"list\" ? \"low\" : \"medium\",\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n const action = args.action as string;\n if (![\"list\", \"add\", \"remove\", \"enable\", \"disable\"].includes(action)) {\n return { ok: false, error: \"Invalid action\" };\n }\n if (action === \"add\" && (!args.name || !args.schedule || !args.prompt)) {\n return { ok: false, error: \"name, schedule, and prompt are required for add\" };\n }\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>, ctx: ToolContext): Promise<string> {\n const scheduler = new CronScheduler(join(getConfigDir(), \"cron\"));\n await scheduler.init();\n\n const action = args.action as string;\n\n if (action === \"list\") {\n const jobs = scheduler.listJobs();\n if (jobs.length === 0) return \"No scheduled jobs\";\n return jobs.map((j) =>\n `${j.id.slice(0, 8)} | ${j.name} | ${j.schedule} | ${j.enabled ? \"enabled\" : \"disabled\"} | agent: ${j.agentId}`\n ).join(\"\\n\");\n }\n\n if (action === \"add\") {\n const job = await scheduler.addJob({\n name: args.name as string,\n schedule: args.schedule as string,\n agentId: (args.agentId as string) || ctx.agentId || \"default\",\n prompt: args.prompt as string,\n });\n return `Job created: ${job.id.slice(0, 8)} — \"${job.name}\" runs every ${job.schedule}`;\n }\n\n if (action === \"remove\") {\n if (!args.jobId) return \"Error: jobId is required\";\n const removed = await scheduler.removeJob(args.jobId as string);\n return removed ? `Job ${(args.jobId as string).slice(0, 8)} removed` : \"Job not found\";\n }\n\n if (action === \"enable\" || action === \"disable\") {\n if (!args.jobId) return \"Error: jobId is required\";\n await scheduler.toggleJob(args.jobId as string, action === \"enable\");\n return `Job ${(args.jobId as string).slice(0, 8)} ${action}d`;\n }\n\n return \"Unknown action\";\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n if (args.action === \"add\") return `Schedule: \"${args.name}\" every ${args.schedule}`;\n return `${args.action} cron job`;\n },\n};\n","/**\n * Gateway WebSocket protocol v1.\n *\n * All UIs (Web, TUI, CLI, Desktop) use this same protocol.\n * JSON text frames over WebSocket. The gateway is the brain —\n * every frontend is a thin client.\n */\n\n// === Frame Types ===\n\n/** Client → Server: connection handshake */\nexport interface ConnectParams {\n type: \"connect\";\n params: {\n auth: { token?: string; pin?: string };\n mode: \"tui\" | \"web\" | \"cli\" | \"desktop\";\n version: string;\n };\n}\n\n/** Server → Client: handshake response */\nexport interface HelloFrame {\n type: \"hello\";\n protocol: number;\n version: string;\n agents: Array<{ id: string; name: string; model: string; status: string }>;\n sessions: Array<{ key: string; label?: string; agentId: string; updatedAt: number }>;\n}\n\n/** Client → Server: RPC request */\nexport interface RequestFrame {\n type: \"req\";\n id: string | number;\n method: string;\n params?: Record<string, unknown>;\n}\n\n/** Server → Client: RPC response */\nexport interface ResponseFrame {\n type: \"res\";\n id: string | number;\n ok: boolean;\n result?: unknown;\n error?: string;\n}\n\n/** Server → Client: push event */\nexport interface EventFrame {\n type: \"event\";\n event: string;\n payload: unknown;\n seq: number;\n}\n\nexport type Frame = ConnectParams | HelloFrame | RequestFrame | ResponseFrame | EventFrame;\n\n/** Protocol version */\nexport const PROTOCOL_VERSION = 1;\n\n/** Default gateway port (18790 — avoids collision with OpenClaw's 18789) */\nexport const DEFAULT_PORT = 18790;\n\n// === RPC Methods ===\n\nexport const METHODS = {\n // Chat\n CHAT_SEND: \"chat.send\",\n CHAT_HISTORY: \"chat.history\",\n CHAT_ABORT: \"chat.abort\",\n\n // Sessions\n SESSION_LIST: \"session.list\",\n SESSION_DELETE: \"session.delete\",\n SESSION_RESET: \"session.reset\",\n\n // Agents\n AGENT_LIST: \"agent.list\",\n AGENT_STATUS: \"agent.status\",\n\n // Config\n CONFIG_GET: \"config.get\",\n CONFIG_SET: \"config.set\",\n\n // Pipelines\n PIPELINE_LIST: \"pipeline.list\",\n PIPELINE_RUN: \"pipeline.run\",\n PIPELINE_STATUS: \"pipeline.status\",\n PIPELINE_ABORT: \"pipeline.abort\",\n\n // Cron\n CRON_LIST: \"cron.list\",\n CRON_CREATE: \"cron.create\",\n CRON_DELETE: \"cron.delete\",\n CRON_TRIGGER: \"cron.trigger\",\n\n // Logs\n LOG_TAIL: \"log.tail\",\n LOG_QUERY: \"log.query\",\n\n // Legacy compat\n CONNECT: \"connect\",\n SEND_MESSAGE: \"sendMessage\",\n CANCEL: \"cancel\",\n} as const;\n\n// === Event Types ===\n\nexport const EVENTS = {\n // Chat events\n CHAT_STREAM: \"chat.stream\",\n CHAT_TOOL: \"chat.tool\",\n CHAT_THINKING: \"chat.thinking\",\n CHAT_COMPLETE: \"chat.complete\",\n CHAT_ERROR: \"chat.error\",\n\n // System events\n PIPELINE_STEP: \"pipeline.step\",\n PIPELINE_COMPLETE: \"pipeline.complete\",\n AGENT_STATUS: \"agent.status\",\n CHANNEL_STATUS: \"channel.status\",\n LOG_ENTRY: \"log.entry\",\n\n // Legacy compat\n TOKEN: \"token\",\n RESPONSE_START: \"response-start\",\n RESPONSE_END: \"response-end\",\n TOOL_START: \"tool-start\",\n TOOL_RESULT: \"tool-result\",\n CONFIRM_NEEDED: \"confirm-needed\",\n CONTEXT_COMPACTING: \"context-compacting\",\n USAGE: \"usage\",\n ERROR: \"error\",\n TURN_COMPLETE: \"turn-complete\",\n} as const;\n\n// === Helpers ===\n\nexport function parseFrame(data: string): Frame | null {\n try {\n return JSON.parse(data) as Frame;\n } catch {\n return null;\n }\n}\n\nexport function serializeFrame(frame: Frame): string {\n return JSON.stringify(frame);\n}\n","/**\n * Gateway tool — check gateway status, connected clients, health.\n */\n\nimport { loadConfig } from \"../../config/index.js\";\nimport { DEFAULT_PORT } from \"../../gateway/protocol.js\";\nimport type { Tool, ValidationResult } from \"../types.js\";\n\nexport const gatewayTool: Tool = {\n definition: {\n name: \"gateway_status\",\n description: \"Check the gateway daemon status, connected clients, and system health.\",\n parameters: {\n type: \"object\",\n properties: {\n action: { type: \"string\", description: \"'status' or 'health'\" },\n },\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(): ValidationResult {\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const config = await loadConfig();\n const port = config.gateway.port || DEFAULT_PORT;\n\n try {\n const endpoint = (args.action === \"health\") ? \"health\" : \"status\";\n const res = await fetch(`http://127.0.0.1:${port}/${endpoint}`, {\n signal: AbortSignal.timeout(3000),\n });\n if (res.ok) {\n const data = await res.json();\n return JSON.stringify(data, null, 2);\n }\n return `Gateway returned error: ${res.status}`;\n } catch {\n return `Gateway not reachable at http://127.0.0.1:${port}`;\n }\n },\n};\n","/**\n * Message tool — send messages to channels from within agent execution.\n *\n * Lets agents proactively reach out: \"Send a summary to my Telegram\",\n * \"Post the build status in Discord\", etc.\n */\n\nimport type { Tool, ValidationResult } from \"../types.js\";\n\nexport const messageTool: Tool = {\n definition: {\n name: \"send_message\",\n description:\n \"Send a message to a specific channel or session. \" +\n \"Use this to proactively notify the user on another interface.\",\n parameters: {\n type: \"object\",\n properties: {\n channel: { type: \"string\", description: \"Target channel ('telegram', 'discord', 'web')\" },\n to: { type: \"string\", description: \"Recipient ID (chat ID, channel ID, etc.)\" },\n text: { type: \"string\", description: \"Message text to send\" },\n },\n required: [\"channel\", \"text\"],\n },\n },\n\n safetyLevel: \"high\", // Sending external messages is always high risk\n readOnly: false,\n\n validate(args: Record<string, unknown>): ValidationResult {\n if (!args.channel) return { ok: false, error: \"channel is required\" };\n if (!args.text) return { ok: false, error: \"text is required\" };\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n // This tool needs gateway integration to actually send messages.\n // The gateway routes the message to the appropriate channel adapter.\n // For now, return a placeholder indicating what would happen.\n return `Message queued for ${args.channel}${args.to ? `:${args.to}` : \"\"}: \"${(args.text as string).slice(0, 100)}\"`;\n },\n\n formatConfirmation(args: Record<string, unknown>): string {\n return `Send message to ${args.channel}: \"${(args.text as string).slice(0, 50)}\"`;\n },\n};\n","/**\n * Voice system — TTS and STT powered by integrations config.\n *\n * TTS: ElevenLabs (cloud)\n * STT: Groq (free), OpenAI Whisper API (cloud), or whisper.cpp (local)\n *\n * Groq is the default STT — free tier, fast, supports whisper-large-v3.\n */\n\nimport type { ClankConfig } from \"../config/index.js\";\n\nexport interface TTSResult {\n audioBuffer: Buffer;\n format: \"mp3\" | \"wav\" | \"ogg\";\n}\n\nexport interface STTResult {\n text: string;\n language?: string;\n}\n\n/**\n * Text-to-Speech engine.\n */\nexport class TTSEngine {\n private config: ClankConfig;\n\n constructor(config: ClankConfig) {\n this.config = config;\n }\n\n isAvailable(): boolean {\n return !!(this.config.integrations.elevenlabs?.enabled && this.config.integrations.elevenlabs?.apiKey);\n }\n\n async synthesize(text: string, opts?: { voiceId?: string }): Promise<TTSResult | null> {\n const elevenlabs = this.config.integrations.elevenlabs;\n if (!elevenlabs?.enabled || !elevenlabs.apiKey) return null;\n\n const voiceId = opts?.voiceId || elevenlabs.voiceId || \"JBFqnCBsd6RMkjVDRZzb\";\n const model = elevenlabs.model || \"eleven_multilingual_v2\";\n\n try {\n const res = await fetch(\n `https://api.elevenlabs.io/v1/text-to-speech/${voiceId}`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"xi-api-key\": elevenlabs.apiKey as string,\n },\n body: JSON.stringify({\n text,\n model_id: model,\n voice_settings: { stability: 0.5, similarity_boost: 0.75 },\n }),\n },\n );\n\n if (!res.ok) {\n console.error(`ElevenLabs TTS error ${res.status}`);\n return null;\n }\n\n const arrayBuffer = await res.arrayBuffer();\n return { audioBuffer: Buffer.from(arrayBuffer), format: \"mp3\" };\n } catch (err) {\n console.error(`TTS error: ${err instanceof Error ? err.message : err}`);\n return null;\n }\n }\n\n async listVoices(): Promise<Array<{ id: string; name: string }>> {\n const elevenlabs = this.config.integrations.elevenlabs;\n if (!elevenlabs?.enabled || !elevenlabs.apiKey) return [];\n\n try {\n const res = await fetch(\"https://api.elevenlabs.io/v1/voices\", {\n headers: { \"xi-api-key\": elevenlabs.apiKey as string },\n });\n if (!res.ok) return [];\n const data = await res.json() as { voices?: Array<{ voice_id: string; name: string }> };\n return (data.voices || []).map((v) => ({ id: v.voice_id, name: v.name }));\n } catch {\n return [];\n }\n }\n}\n\n/**\n * Speech-to-Text engine.\n *\n * Priority order:\n * 1. Groq (free, fast) — if groq API key configured\n * 2. OpenAI Whisper API — if OpenAI key configured\n * 3. Local whisper.cpp — if installed\n */\nexport class STTEngine {\n private config: ClankConfig;\n\n constructor(config: ClankConfig) {\n this.config = config;\n }\n\n isAvailable(): boolean {\n const whisper = this.config.integrations.whisper;\n if (whisper?.enabled) {\n if (whisper.provider === \"groq\" && whisper.apiKey) return true;\n if (whisper.provider === \"openai\" && whisper.apiKey) return true;\n if (whisper.provider === \"local\") return true;\n }\n // Fall back to any available key\n if (this.config.models.providers.openai?.apiKey) return true;\n if ((this.config.integrations as Record<string, any>).groq?.apiKey) return true;\n return false;\n }\n\n async transcribe(audioBuffer: Buffer, format = \"ogg\"): Promise<STTResult | null> {\n const whisper = this.config.integrations.whisper;\n\n // Priority 1: Groq (free, fast)\n const groqKey = (whisper?.provider === \"groq\" && whisper?.apiKey)\n ? whisper.apiKey as string\n : (this.config.integrations as Record<string, any>).groq?.apiKey as string | undefined;\n\n if (groqKey) {\n const result = await this.transcribeAPI(audioBuffer, format, groqKey, \"https://api.groq.com/openai/v1/audio/transcriptions\", \"whisper-large-v3-turbo\");\n if (result) return result;\n }\n\n // Priority 2: OpenAI Whisper API\n const openaiKey = (whisper?.provider === \"openai\" && whisper?.apiKey)\n ? whisper.apiKey as string\n : this.config.models.providers.openai?.apiKey;\n\n if (openaiKey) {\n const result = await this.transcribeAPI(audioBuffer, format, openaiKey, \"https://api.openai.com/v1/audio/transcriptions\", \"whisper-1\");\n if (result) return result;\n }\n\n // Priority 3: Local whisper.cpp\n if (whisper?.provider === \"local\") {\n return this.transcribeLocal(audioBuffer, format);\n }\n\n return null;\n }\n\n /** Transcribe via OpenAI-compatible API (works for both OpenAI and Groq) */\n private async transcribeAPI(audioBuffer: Buffer, format: string, apiKey: string, endpoint: string, model: string): Promise<STTResult | null> {\n try {\n const blob = new Blob([new Uint8Array(audioBuffer)], { type: `audio/${format}` });\n const formData = new FormData();\n formData.append(\"file\", blob, `audio.${format}`);\n formData.append(\"model\", model);\n\n const res = await fetch(endpoint, {\n method: \"POST\",\n headers: { \"Authorization\": `Bearer ${apiKey}` },\n body: formData,\n });\n\n if (!res.ok) {\n const errText = await res.text().catch(() => \"\");\n console.error(`STT API error ${res.status}: ${errText.slice(0, 200)}`);\n return null;\n }\n\n const data = await res.json() as { text?: string; language?: string };\n return data.text ? { text: data.text, language: data.language } : null;\n } catch (err) {\n console.error(`STT error: ${err instanceof Error ? err.message : err}`);\n return null;\n }\n }\n\n /** Transcribe via local whisper.cpp */\n private async transcribeLocal(audioBuffer: Buffer, format: string): Promise<STTResult | null> {\n try {\n const { writeFile, unlink } = await import(\"node:fs/promises\");\n const { execSync } = await import(\"node:child_process\");\n const { join } = await import(\"node:path\");\n const { tmpdir } = await import(\"node:os\");\n\n const tmpFile = join(tmpdir(), `clank-stt-${Date.now()}.${format}`);\n await writeFile(tmpFile, audioBuffer);\n\n const output = execSync(`whisper \"${tmpFile}\" --model base.en --output-txt`, {\n encoding: \"utf-8\",\n timeout: 60_000,\n });\n\n await unlink(tmpFile).catch(() => {});\n return output.trim() ? { text: output.trim() } : null;\n } catch {\n return null;\n }\n }\n}\n","export { TTSEngine, STTEngine, type TTSResult, type STTResult } from \"./tts.js\";\n","/**\n * Voice tools — let the agent generate speech and transcribe audio.\n *\n * \"Read this summary out loud\" → agent uses tts tool\n * \"What did they say in that voice message?\" → agent uses stt tool\n */\n\nimport { TTSEngine, STTEngine } from \"../../voice/index.js\";\nimport { loadConfig } from \"../../config/index.js\";\nimport type { Tool, ToolContext, ValidationResult } from \"../types.js\";\n\nexport const ttsTool: Tool = {\n definition: {\n name: \"text_to_speech\",\n description:\n \"Convert text to speech audio using ElevenLabs. Returns the audio file path. \" +\n \"Requires ElevenLabs integration to be configured.\",\n parameters: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Text to convert to speech\" },\n voice_id: { type: \"string\", description: \"ElevenLabs voice ID (optional, uses default)\" },\n },\n required: [\"text\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>): ValidationResult {\n if (!args.text || typeof args.text !== \"string\") return { ok: false, error: \"text is required\" };\n if ((args.text as string).length > 5000) return { ok: false, error: \"text too long (max 5000 chars)\" };\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const config = await loadConfig();\n const engine = new TTSEngine(config);\n\n if (!engine.isAvailable()) {\n return \"Error: ElevenLabs not configured. Tell me to set it up, or run: clank setup --section integrations\";\n }\n\n const result = await engine.synthesize(args.text as string, {\n voiceId: args.voice_id as string | undefined,\n });\n\n if (!result) return \"Error: TTS synthesis failed\";\n\n // Save to temp file and return path\n const { writeFile } = await import(\"node:fs/promises\");\n const { join } = await import(\"node:path\");\n const { tmpdir } = await import(\"node:os\");\n const outPath = join(tmpdir(), `clank-tts-${Date.now()}.${result.format}`);\n await writeFile(outPath, result.audioBuffer);\n\n return `Audio generated: ${outPath} (${result.format}, ${Math.round(result.audioBuffer.length / 1024)}KB)`;\n },\n};\n\nexport const sttTool: Tool = {\n definition: {\n name: \"speech_to_text\",\n description:\n \"Transcribe an audio file to text using Whisper (OpenAI API or local whisper.cpp). \" +\n \"Provide a file path to an audio file.\",\n parameters: {\n type: \"object\",\n properties: {\n file_path: { type: \"string\", description: \"Path to audio file (.mp3, .wav, .ogg, .m4a)\" },\n },\n required: [\"file_path\"],\n },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(args: Record<string, unknown>): ValidationResult {\n if (!args.file_path || typeof args.file_path !== \"string\") return { ok: false, error: \"file_path is required\" };\n return { ok: true };\n },\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const { readFile } = await import(\"node:fs/promises\");\n const { existsSync } = await import(\"node:fs\");\n\n const filePath = args.file_path as string;\n if (!existsSync(filePath)) return `Error: File not found: ${filePath}`;\n\n const config = await loadConfig();\n const engine = new STTEngine(config);\n\n if (!engine.isAvailable()) {\n return \"Error: Speech-to-text not configured. Need OpenAI API key or local whisper.cpp installed.\";\n }\n\n const audioBuffer = await readFile(filePath);\n const ext = filePath.split(\".\").pop() || \"wav\";\n const result = await engine.transcribe(audioBuffer, ext);\n\n if (!result) return \"Error: Transcription failed\";\n return result.text;\n },\n};\n\nexport const voiceListTool: Tool = {\n definition: {\n name: \"list_voices\",\n description: \"List available ElevenLabs voices for text-to-speech.\",\n parameters: { type: \"object\", properties: {} },\n },\n\n safetyLevel: \"low\",\n readOnly: true,\n\n validate(): ValidationResult { return { ok: true }; },\n\n async execute(): Promise<string> {\n const config = await loadConfig();\n const engine = new TTSEngine(config);\n\n if (!engine.isAvailable()) {\n return \"Error: ElevenLabs not configured.\";\n }\n\n const voices = await engine.listVoices();\n if (voices.length === 0) return \"No voices found or API error.\";\n return voices.map((v) => `${v.name}: ${v.id}`).join(\"\\n\");\n },\n};\n","export { configTool } from \"./config-tool.js\";\nexport { channelTool } from \"./channel-tool.js\";\nexport { agentTool } from \"./agent-tool.js\";\nexport { modelTool } from \"./model-tool.js\";\nexport { sessionTool } from \"./session-tool.js\";\nexport { cronTool } from \"./cron-tool.js\";\nexport { gatewayTool } from \"./gateway-tool.js\";\nexport { messageTool } from \"./message-tool.js\";\nexport { ttsTool, sttTool, voiceListTool } from \"./voice-tool.js\";\n\nimport type { ToolRegistry } from \"../registry.js\";\nimport { configTool } from \"./config-tool.js\";\nimport { channelTool } from \"./channel-tool.js\";\nimport { agentTool } from \"./agent-tool.js\";\nimport { modelTool } from \"./model-tool.js\";\nimport { sessionTool } from \"./session-tool.js\";\nimport { cronTool } from \"./cron-tool.js\";\nimport { gatewayTool } from \"./gateway-tool.js\";\nimport { messageTool } from \"./message-tool.js\";\nimport { ttsTool, sttTool, voiceListTool } from \"./voice-tool.js\";\n\n/** Register all self-configuration tools into a registry */\nexport function registerSelfConfigTools(registry: ToolRegistry): void {\n registry.register(configTool);\n registry.register(channelTool);\n registry.register(agentTool);\n registry.register(modelTool);\n registry.register(sessionTool);\n registry.register(cronTool);\n registry.register(gatewayTool);\n registry.register(messageTool);\n registry.register(ttsTool);\n registry.register(sttTool);\n registry.register(voiceListTool);\n}\n","export type { Tool, ToolContext, ToolTier, SafetyLevel, ValidationResult } from \"./types.js\";\nexport { CORE_TOOL_NAMES, AUTO_TIER_TRIGGERS } from \"./types.js\";\nexport { ToolRegistry } from \"./registry.js\";\n\n// Core tools\nexport { readFileTool } from \"./read-file.js\";\nexport { writeFileTool } from \"./write-file.js\";\nexport { editFileTool } from \"./edit-file.js\";\nexport { listDirectoryTool } from \"./list-directory.js\";\nexport { searchFilesTool } from \"./search-files.js\";\nexport { globFilesTool } from \"./glob-files.js\";\nexport { bashTool } from \"./bash.js\";\nexport { gitTool } from \"./git.js\";\nexport { webSearchTool } from \"./web-search.js\";\nexport { webFetchTool } from \"./web-fetch.js\";\n\nimport { ToolRegistry } from \"./registry.js\";\nimport { readFileTool } from \"./read-file.js\";\nimport { writeFileTool } from \"./write-file.js\";\nimport { editFileTool } from \"./edit-file.js\";\nimport { listDirectoryTool } from \"./list-directory.js\";\nimport { searchFilesTool } from \"./search-files.js\";\nimport { globFilesTool } from \"./glob-files.js\";\nimport { bashTool } from \"./bash.js\";\nimport { gitTool } from \"./git.js\";\nimport { webSearchTool } from \"./web-search.js\";\nimport { webFetchTool } from \"./web-fetch.js\";\nimport { registerSelfConfigTools } from \"./self-config/index.js\";\n\n// Self-config tools\nexport { registerSelfConfigTools } from \"./self-config/index.js\";\n\n/**\n * Create a ToolRegistry pre-loaded with all core tools.\n */\nexport function createCoreRegistry(): ToolRegistry {\n const registry = new ToolRegistry();\n registry.register(readFileTool);\n registry.register(writeFileTool);\n registry.register(editFileTool);\n registry.register(listDirectoryTool);\n registry.register(searchFilesTool);\n registry.register(globFilesTool);\n registry.register(bashTool);\n registry.register(gitTool);\n registry.register(webSearchTool);\n registry.register(webFetchTool);\n return registry;\n}\n\n/**\n * Create a full registry with core + self-config tools.\n * Used when the agent should be able to configure itself.\n */\nexport function createFullRegistry(): ToolRegistry {\n const registry = createCoreRegistry();\n registerSelfConfigTools(registry);\n return registry;\n}\n","/**\n * CLI chat command — direct mode.\n *\n * This is the simplest way to use Clank: `clank chat` starts an\n * interactive session in the terminal. In direct mode (no gateway),\n * it spawns an AgentEngine inline and talks to it directly.\n *\n * Later (Sprint 2), this will also support connecting to a running\n * gateway via WebSocket. But direct mode always works as a fallback.\n */\n\nimport { createInterface } from \"node:readline\";\nimport { join } from \"node:path\";\nimport { AgentEngine, type AgentIdentity, buildSystemPrompt } from \"../engine/index.js\";\nimport { createFullRegistry } from \"../tools/index.js\";\nimport { createProvider, resolveWithFallback } from \"../providers/router.js\";\nimport { OllamaProvider } from \"../providers/ollama.js\";\nimport { loadConfig, ensureConfigDir, getConfigDir } from \"../config/index.js\";\nimport { SessionStore } from \"../sessions/index.js\";\n\n/** ANSI color helpers */\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst bold = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst yellow = (s: string) => `\\x1b[33m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\n\nexport async function runChat(opts: {\n new?: boolean;\n continue?: boolean;\n session?: string;\n direct?: boolean;\n web?: boolean;\n}): Promise<void> {\n await ensureConfigDir();\n const config = await loadConfig();\n\n // --web flag: start gateway if needed and open browser\n if (opts.web) {\n const port = config.gateway.port || 18789;\n const token = config.gateway.auth.token || \"\";\n\n // Check if gateway is running\n let gatewayRunning = false;\n try {\n const res = await fetch(`http://127.0.0.1:${port}/health`, { signal: AbortSignal.timeout(2000) });\n gatewayRunning = res.ok;\n } catch {}\n\n if (!gatewayRunning) {\n // Start gateway in background\n console.log(dim(\"Starting gateway...\"));\n const { fork } = await import(\"node:child_process\");\n const { fileURLToPath } = await import(\"node:url\");\n const { dirname, join } = await import(\"node:path\");\n const __filename = fileURLToPath(import.meta.url);\n const entryPoint = join(dirname(__filename), \"index.js\");\n\n const child = fork(entryPoint, [\"gateway\", \"start\", \"--foreground\"], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n\n // Wait for gateway to be ready\n for (let i = 0; i < 20; i++) {\n await new Promise((r) => setTimeout(r, 500));\n try {\n const res = await fetch(`http://127.0.0.1:${port}/health`, { signal: AbortSignal.timeout(1000) });\n if (res.ok) { gatewayRunning = true; break; }\n } catch {}\n }\n\n if (!gatewayRunning) {\n console.log(red(\"Failed to start gateway. Try: clank gateway start\"));\n return;\n }\n console.log(green(\"Gateway started.\"));\n }\n\n // Open browser\n const url = `http://127.0.0.1:${port}/#token=${token}`;\n console.log(dim(`Opening ${url}`));\n const { platform } = await import(\"node:os\");\n const { exec } = await import(\"node:child_process\");\n const openCmd = platform() === \"win32\" ? `start \"\" \"${url}\"` : platform() === \"darwin\" ? `open \"${url}\"` : `xdg-open \"${url}\"`;\n exec(openCmd);\n console.log(green(\"Web UI opened in browser.\"));\n return;\n }\n\n // Resolve model and create provider\n const modelConfig = config.agents.defaults.model;\n console.log(dim(`Connecting to ${modelConfig.primary}...`));\n\n let resolved;\n try {\n resolved = await resolveWithFallback(\n modelConfig.primary,\n modelConfig.fallbacks || [],\n config.models.providers,\n { maxResponseTokens: config.agents.defaults.maxResponseTokens },\n );\n console.log(green(` Connected to ${resolved.modelId}${resolved.isLocal ? \" (local)\" : \" (cloud)\"}`));\n } catch (err) {\n console.error(red(`Failed to connect to any model: ${err instanceof Error ? err.message : err}`));\n console.error(dim(\"Make sure Ollama is running or configure a cloud provider in ~/.clank/config.json5\"));\n process.exit(1);\n }\n\n // Initialize session store\n const sessionStore = new SessionStore(join(getConfigDir(), \"conversations\"));\n await sessionStore.init();\n\n // Create tool registry — full registry includes self-config tools\n const toolRegistry = createFullRegistry();\n\n // Create agent identity\n const identity: AgentIdentity = {\n id: \"default\",\n name: \"Clank\",\n model: modelConfig,\n workspace: config.agents.defaults.workspace || process.cwd(),\n toolTier: config.agents.defaults.toolTier || \"auto\",\n temperature: config.agents.defaults.temperature,\n maxResponseTokens: config.agents.defaults.maxResponseTokens,\n };\n\n // Build system prompt from workspace files\n const systemPrompt = await buildSystemPrompt({\n identity,\n workspaceDir: identity.workspace,\n channel: \"cli\",\n });\n\n // Create engine\n const engine = new AgentEngine({\n identity,\n toolRegistry,\n sessionStore,\n provider: resolved,\n autoApprove: config.tools.autoApprove,\n systemPrompt,\n });\n\n // Load session\n const sessionKey = opts.session || \"cli:main\";\n await engine.loadSession(sessionKey, \"cli\");\n\n // Wire up events\n let isStreaming = false;\n\n engine.on(\"response-start\", () => {\n isStreaming = true;\n });\n\n engine.on(\"token\", ({ content }) => {\n process.stdout.write(content);\n });\n\n engine.on(\"response-end\", ({ text }) => {\n if (isStreaming && text) {\n process.stdout.write(\"\\n\");\n }\n isStreaming = false;\n });\n\n engine.on(\"tool-start\", ({ name, arguments: args }) => {\n const summary = args.command || args.path || args.pattern || args.args || \"\";\n console.log(dim(` [${name}] ${String(summary).slice(0, 80)}`));\n });\n\n engine.on(\"tool-result\", ({ name, success, summary }) => {\n const icon = success ? green(\"ok\") : red(\"err\");\n console.log(dim(` [${name}] ${icon} ${summary.slice(0, 80)}`));\n });\n\n engine.on(\"confirm-needed\", ({ actions, resolve }) => {\n const action = actions[0];\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n rl.question(\n yellow(` Confirm: ${action.description} [y/n/always] `),\n (answer) => {\n rl.close();\n const a = answer.trim().toLowerCase();\n if (a === \"always\" || a === \"a\") resolve(\"always\");\n else if (a === \"y\" || a === \"yes\") resolve(true);\n else resolve(false);\n },\n );\n });\n\n engine.on(\"context-compacting\", () => {\n console.log(dim(\" (compacting context...)\"));\n });\n\n engine.on(\"usage\", ({ promptTokens, outputTokens, iterationCount, contextPercent }) => {\n console.log(dim(` [${promptTokens}→${outputTokens} tokens | iter ${iterationCount} | ctx ${contextPercent}%]`));\n });\n\n engine.on(\"error\", ({ message, recoverable }) => {\n console.error(red(`Error: ${message}${recoverable ? \" (recoverable)\" : \"\"}`));\n });\n\n // Print header\n console.log(\"\");\n console.log(bold(\"Clank\") + dim(` v0.1.0 | ${resolved.modelId} | ${identity.toolTier} tier`));\n console.log(dim(\"Type your message. Press Ctrl+C to exit.\\n\"));\n\n // Interactive readline loop\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n prompt: cyan(\"you > \"),\n });\n\n rl.prompt();\n\n rl.on(\"line\", async (line) => {\n const input = line.trim();\n if (!input) {\n rl.prompt();\n return;\n }\n\n // Slash commands\n if (input.startsWith(\"/\")) {\n await handleSlashCommand(input, engine, rl);\n rl.prompt();\n return;\n }\n\n console.log(\"\");\n try {\n await engine.sendMessage(input);\n } catch (err) {\n // Error already emitted via event\n }\n console.log(\"\");\n rl.prompt();\n });\n\n rl.on(\"close\", () => {\n engine.destroy();\n process.exit(0);\n });\n\n // Handle Ctrl+C during streaming\n process.on(\"SIGINT\", () => {\n if (isStreaming) {\n engine.cancel();\n console.log(dim(\"\\n (cancelled)\"));\n rl.prompt();\n } else {\n rl.close();\n }\n });\n}\n\n/** Handle slash commands */\nasync function handleSlashCommand(\n input: string,\n engine: AgentEngine,\n _rl: ReturnType<typeof createInterface>,\n): Promise<void> {\n const [cmd, ...args] = input.slice(1).split(/\\s+/);\n\n switch (cmd) {\n case \"help\":\n console.log(dim(\"Commands:\"));\n console.log(dim(\" /help — Show this help\"));\n console.log(dim(\" /model — Show current model\"));\n console.log(dim(\" /clear — Clear conversation\"));\n console.log(dim(\" /exit — Exit\"));\n break;\n\n case \"model\":\n console.log(dim(`Model: ${engine.identity.model.primary}`));\n break;\n\n case \"clear\":\n engine.getContextEngine().clear();\n console.log(dim(\"Conversation cleared.\"));\n break;\n\n case \"exit\":\n case \"quit\":\n engine.destroy();\n process.exit(0);\n\n default:\n console.log(dim(`Unknown command: /${cmd}. Type /help for available commands.`));\n }\n}\n","/**\n * Memory system — TF-IDF based long-term memory with categories and decay.\n *\n * Memories are stored as markdown files in categorized subdirectories:\n * ~/.clank/memory/identity/ — who the agent is\n * ~/.clank/memory/knowledge/ — facts and information\n * ~/.clank/memory/lessons/ — things learned from experience\n * ~/.clank/memory/context/ — project-specific context\n *\n * Each file has metadata (_meta.json) tracking access patterns for\n * decay scoring — memories that haven't been accessed fade over time.\n */\n\nimport { readFile, writeFile, readdir, mkdir, unlink } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\n\nexport interface MemoryEntry {\n id: string;\n category: \"identity\" | \"knowledge\" | \"lessons\" | \"context\";\n title: string;\n content: string;\n filePath: string;\n}\n\nexport interface MemoryMeta {\n id: string;\n lastAccessed: number;\n accessCount: number;\n createdAt: number;\n dormant: boolean;\n}\n\n/** Common English stopwords to filter from TF-IDF */\nconst STOPWORDS = new Set([\n \"the\", \"be\", \"to\", \"of\", \"and\", \"a\", \"in\", \"that\", \"have\", \"i\",\n \"it\", \"for\", \"not\", \"on\", \"with\", \"he\", \"as\", \"you\", \"do\", \"at\",\n \"this\", \"but\", \"his\", \"by\", \"from\", \"they\", \"we\", \"say\", \"her\",\n \"she\", \"or\", \"an\", \"will\", \"my\", \"one\", \"all\", \"would\", \"there\",\n \"their\", \"what\", \"so\", \"up\", \"out\", \"if\", \"about\", \"who\", \"get\",\n \"which\", \"go\", \"me\", \"when\", \"make\", \"can\", \"like\", \"time\", \"no\",\n \"just\", \"him\", \"know\", \"take\", \"people\", \"into\", \"year\", \"your\",\n \"good\", \"some\", \"could\", \"them\", \"see\", \"other\", \"than\", \"then\",\n \"now\", \"look\", \"only\", \"come\", \"its\", \"over\", \"think\", \"also\",\n \"back\", \"after\", \"use\", \"two\", \"how\", \"our\", \"work\", \"first\",\n \"well\", \"way\", \"even\", \"new\", \"want\", \"because\", \"any\", \"these\",\n \"give\", \"day\", \"most\", \"us\", \"is\", \"are\", \"was\", \"were\", \"been\",\n \"has\", \"had\", \"did\", \"does\", \"am\",\n]);\n\nexport class MemoryManager {\n private memoryDir: string;\n private metaPath: string;\n private meta: Map<string, MemoryMeta> = new Map();\n\n constructor(memoryDir: string) {\n this.memoryDir = memoryDir;\n this.metaPath = join(memoryDir, \"_meta.json\");\n }\n\n /** Initialize — create dirs and load metadata */\n async init(): Promise<void> {\n for (const cat of [\"identity\", \"knowledge\", \"lessons\", \"context\"]) {\n await mkdir(join(this.memoryDir, cat), { recursive: true });\n }\n await this.loadMeta();\n }\n\n /** Find memories relevant to a query using TF-IDF cosine similarity */\n async findRelevant(query: string, topK = 3): Promise<MemoryEntry[]> {\n const entries = await this.loadAll();\n if (entries.length === 0) return [];\n\n const queryTerms = tokenize(query);\n if (queryTerms.length === 0) return entries.slice(0, topK);\n\n // Build document frequency map\n const df = new Map<string, number>();\n const docs = entries.map((e) => {\n const terms = tokenize(e.content);\n const unique = new Set(terms);\n for (const t of unique) df.set(t, (df.get(t) || 0) + 1);\n return { entry: e, terms };\n });\n\n const N = docs.length;\n\n // Score each document\n const scored = docs.map(({ entry, terms }) => {\n const score = cosineSimilarity(queryTerms, terms, df, N);\n // Apply decay: reduce score for old, unused memories\n const meta = this.meta.get(entry.id);\n const decayFactor = meta ? this.decayScore(meta) : 0.5;\n return { entry, score: score * decayFactor };\n });\n\n // Sort by score descending\n scored.sort((a, b) => b.score - a.score);\n\n // Update access metadata for returned results\n const results = scored.slice(0, topK).filter((s) => s.score > 0.01).map((s) => s.entry);\n for (const entry of results) {\n const meta = this.meta.get(entry.id);\n if (meta) {\n meta.lastAccessed = Date.now();\n meta.accessCount++;\n }\n }\n await this.saveMeta();\n\n return results;\n }\n\n /**\n * Build the memory block for injection into the system prompt.\n * Combines global memory, project memory, and relevant topics.\n */\n async buildMemoryBlock(userMessage: string, projectRoot?: string, budgetChars = 4000): Promise<string> {\n const parts: string[] = [];\n let used = 0;\n\n // 1. Project memory (.clank.md)\n if (projectRoot) {\n for (const name of [\".clank.md\", \".clankbuild.md\", \".llamabuild.md\"]) {\n const path = join(projectRoot, name);\n if (existsSync(path)) {\n try {\n const content = await readFile(path, \"utf-8\");\n if (content.trim() && used + content.length < budgetChars) {\n parts.push(\"## Project Memory\\n\" + content.trim());\n used += content.length;\n }\n } catch { /* skip */ }\n break;\n }\n }\n }\n\n // 2. Global memory (MEMORY.md)\n const globalPath = join(this.memoryDir, \"..\", \"workspace\", \"MEMORY.md\");\n if (existsSync(globalPath)) {\n try {\n const content = await readFile(globalPath, \"utf-8\");\n if (content.trim() && used + content.length < budgetChars) {\n parts.push(\"## Global Memory\\n\" + content.trim());\n used += content.length;\n }\n } catch { /* skip */ }\n }\n\n // 3. Relevant memories (TF-IDF matched)\n const relevant = await this.findRelevant(userMessage, 3);\n for (const entry of relevant) {\n if (used + entry.content.length > budgetChars) break;\n parts.push(`## ${entry.title}\\n${entry.content}`);\n used += entry.content.length;\n }\n\n return parts.length > 0 ? parts.join(\"\\n\\n\") : \"\";\n }\n\n /** Add a new memory */\n async add(category: MemoryEntry[\"category\"], title: string, content: string): Promise<MemoryEntry> {\n const id = randomUUID();\n const filename = `${title.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").slice(0, 50)}.md`;\n const filePath = join(this.memoryDir, category, filename);\n\n await writeFile(filePath, `# ${title}\\n\\n${content}`, \"utf-8\");\n\n this.meta.set(id, {\n id,\n lastAccessed: Date.now(),\n accessCount: 0,\n createdAt: Date.now(),\n dormant: false,\n });\n await this.saveMeta();\n\n return { id, category, title, content, filePath };\n }\n\n /** Decay scores — flag dormant memories (30+ days unused) */\n async decayScores(): Promise<number> {\n const now = Date.now();\n const thirtyDays = 30 * 24 * 60 * 60 * 1000;\n let flagged = 0;\n\n for (const [, meta] of this.meta) {\n if (now - meta.lastAccessed > thirtyDays && !meta.dormant) {\n meta.dormant = true;\n flagged++;\n }\n }\n\n if (flagged > 0) await this.saveMeta();\n return flagged;\n }\n\n /** Prune dormant memories older than 90 days */\n async prune(): Promise<number> {\n const now = Date.now();\n const ninetyDays = 90 * 24 * 60 * 60 * 1000;\n let pruned = 0;\n\n for (const [id, meta] of this.meta) {\n if (meta.dormant && now - meta.lastAccessed > ninetyDays) {\n this.meta.delete(id);\n pruned++;\n }\n }\n\n if (pruned > 0) await this.saveMeta();\n return pruned;\n }\n\n /** Load all memory entries from disk */\n private async loadAll(): Promise<MemoryEntry[]> {\n const entries: MemoryEntry[] = [];\n\n for (const category of [\"identity\", \"knowledge\", \"lessons\", \"context\"] as const) {\n const dir = join(this.memoryDir, category);\n if (!existsSync(dir)) continue;\n\n try {\n const files = await readdir(dir);\n for (const file of files) {\n if (!file.endsWith(\".md\")) continue;\n const filePath = join(dir, file);\n try {\n const content = await readFile(filePath, \"utf-8\");\n const title = content.split(\"\\n\")[0]?.replace(/^#\\s*/, \"\") || file;\n entries.push({\n id: file,\n category,\n title,\n content,\n filePath,\n });\n } catch { /* skip */ }\n }\n } catch { /* skip */ }\n }\n\n return entries;\n }\n\n /** Calculate decay factor for a memory (1.0 = fresh, 0.25 = old) */\n private decayScore(meta: MemoryMeta): number {\n const daysSinceAccess = (Date.now() - meta.lastAccessed) / (24 * 60 * 60 * 1000);\n const recency = daysSinceAccess < 1 ? 1.0\n : daysSinceAccess < 30 ? 0.5\n : 0.25;\n const frequencyBoost = Math.min(1.5, 1 + meta.accessCount * 0.1);\n return recency * frequencyBoost;\n }\n\n private async loadMeta(): Promise<void> {\n if (!existsSync(this.metaPath)) return;\n try {\n const raw = await readFile(this.metaPath, \"utf-8\");\n const entries = JSON.parse(raw) as MemoryMeta[];\n for (const e of entries) this.meta.set(e.id, e);\n } catch { /* start fresh */ }\n }\n\n private async saveMeta(): Promise<void> {\n const entries = Array.from(this.meta.values());\n await writeFile(this.metaPath, JSON.stringify(entries, null, 2), \"utf-8\");\n }\n}\n\n/** Tokenize text for TF-IDF */\nfunction tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \" \")\n .split(/\\s+/)\n .filter((t) => t.length >= 3 && !STOPWORDS.has(t));\n}\n\n/** Compute TF-IDF cosine similarity between query and document */\nfunction cosineSimilarity(\n queryTerms: string[],\n docTerms: string[],\n df: Map<string, number>,\n N: number,\n): number {\n // Build TF maps\n const queryTf = new Map<string, number>();\n for (const t of queryTerms) queryTf.set(t, (queryTf.get(t) || 0) + 1);\n\n const docTf = new Map<string, number>();\n for (const t of docTerms) docTf.set(t, (docTf.get(t) || 0) + 1);\n\n // Compute TF-IDF vectors and dot product\n let dotProduct = 0;\n let queryMag = 0;\n let docMag = 0;\n\n const allTerms = new Set([...queryTf.keys(), ...docTf.keys()]);\n for (const term of allTerms) {\n const idf = Math.log(N / (df.get(term) || 1));\n const qVal = (queryTf.get(term) || 0) * idf;\n const dVal = (docTf.get(term) || 0) * idf;\n dotProduct += qVal * dVal;\n queryMag += qVal * qVal;\n docMag += dVal * dVal;\n }\n\n const magnitude = Math.sqrt(queryMag) * Math.sqrt(docMag);\n return magnitude > 0 ? dotProduct / magnitude : 0;\n}\n","export { MemoryManager, type MemoryEntry, type MemoryMeta } from \"./memory.js\";\n","/**\n * Multi-agent routing — resolves inbound messages to agents.\n *\n * Uses a binding-based priority system (matching OpenClaw's approach):\n * 1. Exact peer match (DM/group ID)\n * 2. Parent thread inheritance\n * 3. Discord guild + role\n * 4. Guild/team\n * 5. Account-level binding\n * 6. Channel-level catch-all\n * 7. Default agent\n *\n * Config-driven: bindings are defined in config.json5.\n */\n\nexport interface RouteBinding {\n agentId: string;\n /** Match criteria (evaluated in priority order) */\n match?: {\n channel?: string;\n peer?: { kind: \"dm\" | \"group\" | \"channel\"; id: string | number };\n guild?: string;\n roles?: string[];\n team?: string;\n account?: string;\n };\n /** Priority override (lower = higher priority) */\n priority?: number;\n}\n\nexport interface RouteContext {\n channel: string;\n peerId?: string | number;\n peerKind?: \"dm\" | \"group\" | \"channel\";\n guildId?: string;\n roles?: string[];\n teamId?: string;\n accountId?: string;\n threadParentId?: string | number;\n}\n\nexport interface AgentListEntry {\n id: string;\n name?: string;\n}\n\n/**\n * Resolve which agent should handle a message.\n * Evaluates bindings in priority order and returns the best match.\n */\nexport function resolveRoute(\n context: RouteContext,\n bindings: RouteBinding[],\n agents: AgentListEntry[],\n defaultAgentId: string,\n): string {\n // Sort bindings by specificity (most specific first)\n const scored = bindings.map((b) => ({\n binding: b,\n score: scoreBinding(b, context),\n }));\n\n // Filter to matches and sort by score (highest first)\n const matches = scored\n .filter((s) => s.score > 0)\n .sort((a, b) => {\n // Explicit priority overrides score\n const pA = a.binding.priority ?? 99;\n const pB = b.binding.priority ?? 99;\n if (pA !== pB) return pA - pB;\n return b.score - a.score;\n });\n\n if (matches.length > 0) {\n const agentId = matches[0].binding.agentId;\n // Verify agent exists\n if (agents.some((a) => a.id === agentId)) {\n return agentId;\n }\n }\n\n return defaultAgentId;\n}\n\n/**\n * Score a binding against a route context.\n * Higher score = more specific match.\n * Returns 0 if the binding doesn't match at all.\n */\nfunction scoreBinding(binding: RouteBinding, context: RouteContext): number {\n const match = binding.match;\n if (!match) return 0;\n\n let score = 0;\n\n // Tier 1: Exact peer match (most specific)\n if (match.peer) {\n if (\n match.peer.kind === context.peerKind &&\n String(match.peer.id) === String(context.peerId)\n ) {\n score += 100;\n } else {\n return 0; // Peer specified but doesn't match\n }\n }\n\n // Tier 2: Guild + roles\n if (match.guild && match.roles) {\n if (\n match.guild === context.guildId &&\n match.roles.some((r) => context.roles?.includes(r))\n ) {\n score += 80;\n } else if (match.guild || match.roles) {\n return 0;\n }\n }\n\n // Tier 3: Guild only\n if (match.guild && !match.roles) {\n if (match.guild === context.guildId) {\n score += 60;\n } else {\n return 0;\n }\n }\n\n // Tier 4: Team\n if (match.team) {\n if (match.team === context.teamId) {\n score += 50;\n } else {\n return 0;\n }\n }\n\n // Tier 5: Account\n if (match.account) {\n if (match.account === context.accountId) {\n score += 30;\n } else {\n return 0;\n }\n }\n\n // Tier 6: Channel catch-all\n if (match.channel) {\n if (match.channel === context.channel) {\n score += 10;\n } else {\n return 0;\n }\n }\n\n return score;\n}\n\n/**\n * Derive a normalized session key from a route context.\n */\nexport function deriveSessionKey(context: RouteContext): string {\n if (context.peerKind === \"dm\") {\n return `dm:${context.channel}:${context.peerId}`;\n }\n if (context.peerKind === \"group\" || context.peerKind === \"channel\") {\n return `group:${context.channel}:${context.peerId}`;\n }\n return `${context.channel}:main`;\n}\n","export {\n resolveRoute,\n deriveSessionKey,\n type RouteBinding,\n type RouteContext,\n type AgentListEntry,\n} from \"./resolve-route.js\";\n","/**\n * Channel adapter base interface.\n *\n * All channels (CLI, Telegram, Discord, Web, Slack, etc.) implement\n * this interface. The gateway treats them all equally — no hierarchy,\n * no \"primary\" interface. User picks what fits their workflow.\n *\n * The pattern is simple:\n * - Inbound: adapter receives platform message → normalizes → calls gateway.handleMessage()\n * - Outbound: gateway calls adapter.send() with a ReplyPayload\n */\n\nimport type { GatewayServer } from \"../gateway/server.js\";\nimport type { ClankConfig } from \"../config/index.js\";\n\n/** Normalized inbound message from any channel */\nexport interface InboundMessage {\n /** Raw text content */\n text: string;\n /** Channel identifier (telegram, discord, cli, web, etc.) */\n channel: string;\n /** Sender identifier (user ID, etc.) */\n senderId: string | number;\n /** Peer identifier (chat/group/channel ID) */\n peerId: string | number;\n /** Peer kind */\n peerKind: \"dm\" | \"group\" | \"channel\";\n /** Thread ID if applicable */\n threadId?: string | number;\n /** Whether the bot was explicitly mentioned */\n mentioned?: boolean;\n /** Optional media attachments */\n media?: Array<{ type: string; url: string }>;\n}\n\n/** Outbound reply to any channel */\nexport interface ReplyPayload {\n text?: string;\n mediaUrl?: string;\n mediaUrls?: string[];\n replyToId?: string;\n isError?: boolean;\n}\n\n/** The interface every channel adapter must implement */\nexport abstract class ChannelAdapter {\n abstract readonly id: string;\n abstract readonly name: string;\n\n /** Initialize the adapter with gateway and config references */\n abstract init(gateway: GatewayServer, config: ClankConfig): void;\n\n /** Start the adapter (connect to platform, begin polling, etc.) */\n abstract start(): Promise<void>;\n\n /** Stop the adapter (disconnect, cleanup) */\n abstract stop(): Promise<void>;\n\n /**\n * Send a reply payload to the platform.\n * Called by the gateway when an agent produces a response.\n */\n abstract send(sessionKey: string, payload: ReplyPayload): Promise<void>;\n\n /**\n * Send a streaming token to the platform.\n * Used for real-time response streaming (e.g., editing a Telegram message).\n */\n async sendToken?(sessionKey: string, content: string): Promise<void> {\n // Default: no streaming support, full response sent via send()\n }\n}\n","/**\n * Telegram channel adapter.\n *\n * Built on grammY. Refactored from the original Clank Telegram bot\n * into the ChannelAdapter pattern. Supports:\n * - DM and group chats with separate allowlists\n * - @mention checking in groups\n * - Streaming via message editing\n * - Inline keyboard confirmations\n * - Media group coalescing\n */\n\nimport { Bot } from \"grammy\";\nimport { ChannelAdapter, type InboundMessage, type ReplyPayload } from \"./base.js\";\nimport type { GatewayServer } from \"../gateway/server.js\";\nimport type { ClankConfig } from \"../config/index.js\";\n\nexport class TelegramAdapter extends ChannelAdapter {\n readonly id = \"telegram\";\n readonly name = \"Telegram\";\n private gateway: GatewayServer | null = null;\n private config: ClankConfig | null = null;\n private bot: Bot | null = null;\n private running = false;\n\n init(gateway: GatewayServer, config: ClankConfig): void {\n this.gateway = gateway;\n this.config = config;\n }\n\n async start(): Promise<void> {\n const telegramConfig = this.config?.channels?.telegram;\n if (!telegramConfig?.enabled || !telegramConfig.botToken) {\n console.log(\" Telegram: disabled or no bot token configured\");\n return;\n }\n\n try {\n this.bot = new Bot(telegramConfig.botToken);\n const bot = this.bot as Bot;\n\n // Track startup time — messages older than this are stale\n const startupTime = Math.floor(Date.now() / 1000);\n // Per-chat processing queue — prevents parallel model calls from same chat\n const chatLocks = new Map<number, Promise<void>>();\n\n // Handle text messages\n bot.on(\"message:text\", async (ctx) => {\n const msg = ctx.message;\n const chatId = msg.chat.id;\n const userId = msg.from?.id;\n const isGroup = msg.chat.type === \"group\" || msg.chat.type === \"supergroup\";\n\n // Drop stale messages from before this startup (queued while offline)\n if (msg.date < startupTime - 30) {\n console.log(` Telegram: dropping stale message from ${userId} (${startupTime - msg.date}s old)`);\n return;\n }\n\n // Permission check — allowFrom can contain user IDs (numeric) or usernames (@name)\n if (telegramConfig.allowFrom && telegramConfig.allowFrom.length > 0) {\n const username = msg.from?.username ? `@${msg.from.username}` : \"\";\n const userIdStr = String(userId || \"\");\n const allowed = telegramConfig.allowFrom.map(String);\n const isAllowed = allowed.some((a) =>\n a === userIdStr ||\n a.toLowerCase() === username.toLowerCase() ||\n a.toLowerCase() === (msg.from?.username || \"\").toLowerCase()\n );\n if (!isAllowed) return;\n }\n\n // Mention check in groups\n if (isGroup) {\n const groupConfig = telegramConfig.groups?.[String(chatId)];\n if (groupConfig?.requireMention !== false) {\n const botInfo = await bot.api.getMe();\n if (!msg.text.includes(`@${botInfo.username}`)) return;\n }\n }\n\n // Handle slash commands (lightweight, no queueing needed)\n if (msg.text.startsWith(\"/\")) {\n const reply = await this.handleCommand(msg.text, chatId, isGroup);\n if (reply) {\n await ctx.api.sendMessage(chatId, reply, { parse_mode: \"Markdown\" });\n }\n return;\n }\n\n // Queue messages per chat — process one at a time to prevent\n // parallel model calls from flooding the local model\n const processMessage = async () => {\n if (!this.gateway) return;\n\n try {\n await ctx.api.sendChatAction(chatId, \"typing\");\n\n const response = await this.gateway.handleInboundMessage(\n {\n channel: \"telegram\",\n peerId: chatId,\n peerKind: isGroup ? \"group\" : \"dm\",\n },\n msg.text,\n );\n\n if (response) {\n const chunks = splitMessage(response, 4000);\n for (const chunk of chunks) {\n await ctx.api.sendMessage(chatId, chunk);\n }\n }\n } catch (err: unknown) {\n const errMsg = err instanceof Error ? err.message : String(err);\n await ctx.api.sendMessage(chatId, `Error: ${errMsg.slice(0, 200)}`);\n }\n };\n\n // Chain onto the existing queue for this chat\n const prev = chatLocks.get(chatId) || Promise.resolve();\n const next = prev.then(processMessage).catch(() => {});\n chatLocks.set(chatId, next);\n });\n\n // Handle voice messages — transcribe and route through agent\n bot.on(\"message:voice\", async (ctx) => {\n const msg = ctx.message;\n const chatId = msg.chat.id;\n const userId = msg.from?.id;\n\n // Same permission check\n if (telegramConfig.allowFrom && telegramConfig.allowFrom.length > 0) {\n const username = msg.from?.username ? `@${msg.from.username}` : \"\";\n const userIdStr = String(userId || \"\");\n const allowed = telegramConfig.allowFrom.map(String);\n const isAllowed = allowed.some((a) =>\n a === userIdStr ||\n a.toLowerCase() === username.toLowerCase() ||\n a.toLowerCase() === (msg.from?.username || \"\").toLowerCase()\n );\n if (!isAllowed) return;\n }\n\n if (msg.date < startupTime - 30) return; // Drop stale\n\n const processVoice = async () => {\n if (!this.gateway || !this.config) return;\n\n try {\n await ctx.api.sendChatAction(chatId, \"typing\");\n\n // Download the voice file\n const file = await ctx.api.getFile(msg.voice.file_id);\n const fileUrl = `https://api.telegram.org/file/bot${telegramConfig.botToken}/${file.file_path}`;\n const res = await fetch(fileUrl);\n if (!res.ok) { await ctx.api.sendMessage(chatId, \"Error: could not download voice message\"); return; }\n const audioBuffer = Buffer.from(await res.arrayBuffer());\n\n // Transcribe\n const { STTEngine } = await import(\"../voice/index.js\");\n const { loadConfig } = await import(\"../config/index.js\");\n const config = await loadConfig();\n const stt = new STTEngine(config);\n\n if (!stt.isAvailable()) {\n await ctx.api.sendMessage(chatId, \"Voice messages require speech-to-text. Set up Whisper: /help\");\n return;\n }\n\n const transcription = await stt.transcribe(audioBuffer, \"ogg\");\n if (!transcription?.text) {\n await ctx.api.sendMessage(chatId, \"Could not transcribe voice message.\");\n return;\n }\n\n // Send transcription through the agent\n const isGroup = msg.chat.type === \"group\" || msg.chat.type === \"supergroup\";\n const response = await this.gateway.handleInboundMessage(\n { channel: \"telegram\", peerId: chatId, peerKind: isGroup ? \"group\" : \"dm\" },\n `[Voice message transcription]: ${transcription.text}`,\n );\n\n if (response) {\n // Check if TTS is available — reply with voice if so\n const { TTSEngine } = await import(\"../voice/index.js\");\n const tts = new TTSEngine(config);\n\n if (tts.isAvailable() && response.length < 2000) {\n const audio = await tts.synthesize(response);\n if (audio) {\n const { InputFile } = await import(\"grammy\");\n await ctx.api.sendVoice(chatId, new InputFile(audio.audioBuffer, \"reply.mp3\"));\n return;\n }\n }\n\n // Fall back to text\n const chunks = splitMessage(response, 4000);\n for (const chunk of chunks) {\n await ctx.api.sendMessage(chatId, chunk);\n }\n }\n } catch (err: unknown) {\n const errMsg = err instanceof Error ? err.message : String(err);\n await ctx.api.sendMessage(chatId, `Error: ${errMsg.slice(0, 200)}`);\n }\n };\n\n const prev = chatLocks.get(chatId) || Promise.resolve();\n const next = prev.then(processVoice).catch(() => {});\n chatLocks.set(chatId, next);\n });\n\n // bot.start() is blocking (resolves when bot stops) — run it without await\n bot.start({\n onStart: () => {\n this.running = true;\n console.log(\" Telegram: polling started\");\n },\n }).catch((err: Error) => {\n console.error(` Telegram: polling error — ${err.message}`);\n this.running = false;\n });\n\n console.log(\" Telegram: connecting...\");\n } catch (err) {\n console.error(` Telegram: failed to start — ${err instanceof Error ? err.message : err}`);\n }\n }\n\n async stop(): Promise<void> {\n if (this.bot && this.running) {\n (this.bot as Bot).stop();\n this.running = false;\n }\n }\n\n /** Handle slash commands from Telegram */\n private async handleCommand(text: string, chatId: number, isGroup: boolean): Promise<string | null> {\n const [cmd, ...args] = text.slice(1).split(/\\s+/);\n const command = cmd.replace(/@\\w+$/, \"\"); // Strip @botname suffix\n\n switch (command) {\n case \"help\":\n case \"start\":\n return [\n \"*Clank Commands*\",\n \"\",\n \"/help — Show this help\",\n \"/status — Agent and model info\",\n \"/agents — List available agents\",\n \"/agent <name> — Switch to a different agent\",\n \"/sessions — List recent sessions\",\n \"/new — Start a new session\",\n \"/reset — Clear current session\",\n \"/model — Show current model\",\n \"/think — Toggle thinking display\",\n ].join(\"\\n\");\n\n case \"status\": {\n const cfg = this.config;\n const model = cfg?.agents?.defaults?.model?.primary || \"unknown\";\n const agents = cfg?.agents?.list?.length || 0;\n return [\n \"*Status*\",\n `Model: \\`${model}\\``,\n `Agents: ${agents} configured`,\n `Chat: ${isGroup ? \"group\" : \"DM\"} (${chatId})`,\n ].join(\"\\n\");\n }\n\n case \"agents\": {\n const list = this.config?.agents?.list || [];\n if (list.length === 0) return \"No custom agents configured. Using default agent.\";\n return \"*Agents:*\\n\" + list.map((a) =>\n `• *${a.name || a.id}* — \\`${a.model?.primary || \"default\"}\\``\n ).join(\"\\n\");\n }\n\n case \"agent\":\n if (args[0]) {\n return `Agent switching via Telegram coming soon. Use the config tool in chat: \"switch to agent ${args[0]}\"`;\n }\n return \"Usage: /agent <name>\";\n\n case \"sessions\": {\n if (!this.gateway) return \"Gateway not connected\";\n return \"Use /new to start a fresh session, or /reset to clear the current one.\";\n }\n\n case \"new\":\n return \"New session started. Send a message to begin.\";\n\n case \"reset\":\n return \"Session reset. History cleared.\";\n\n case \"model\": {\n const model = this.config?.agents?.defaults?.model?.primary || \"unknown\";\n return `Current model: \\`${model}\\``;\n }\n\n case \"think\":\n return \"Thinking display toggled. (Note: thinking visibility is per-client in the TUI/Web UI)\";\n\n default:\n return null; // Not a recognized command — let it pass through to the agent\n }\n }\n\n async send(sessionKey: string, payload: ReplyPayload): Promise<void> {\n // Extract chat ID from session key (dm:telegram:12345 → 12345)\n const parts = sessionKey.split(\":\");\n const chatId = parts[parts.length - 1];\n if (!chatId || !this.bot) return;\n\n if (payload.text) {\n const chunks = splitMessage(payload.text, 4000);\n for (const chunk of chunks) {\n await (this.bot as Bot).api.sendMessage(Number(chatId), chunk);\n }\n }\n }\n}\n\n/** Split a long message into chunks that fit Telegram's limit */\nfunction splitMessage(text: string, maxLen: number): string[] {\n if (text.length <= maxLen) return [text];\n const chunks: string[] = [];\n let remaining = text;\n while (remaining.length > 0) {\n if (remaining.length <= maxLen) {\n chunks.push(remaining);\n break;\n }\n // Try to split at a newline\n let splitAt = remaining.lastIndexOf(\"\\n\", maxLen);\n if (splitAt < maxLen * 0.5) splitAt = maxLen; // No good newline, split at limit\n chunks.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt);\n }\n return chunks;\n}\n","/**\n * Discord channel adapter.\n *\n * Built on discord.js. Supports:\n * - Server/channel/role-based routing\n * - Thread support for long conversations\n * - Button-based confirmations\n * - Streaming via message editing\n */\n\nimport { ChannelAdapter, type InboundMessage, type ReplyPayload } from \"./base.js\";\nimport type { GatewayServer } from \"../gateway/server.js\";\nimport type { ClankConfig } from \"../config/index.js\";\n\nexport class DiscordAdapter extends ChannelAdapter {\n readonly id = \"discord\";\n readonly name = \"Discord\";\n private gateway: GatewayServer | null = null;\n private config: ClankConfig | null = null;\n private client: unknown = null; // discord.js Client — loaded dynamically\n private running = false;\n\n init(gateway: GatewayServer, config: ClankConfig): void {\n this.gateway = gateway;\n this.config = config;\n }\n\n async start(): Promise<void> {\n const discordConfig = this.config?.channels?.discord;\n if (!discordConfig?.enabled || !discordConfig.botToken) {\n console.log(\" Discord: disabled or no bot token configured\");\n return;\n }\n\n try {\n const discord = await import(\"discord.js\" as string) as any;\n this.client = new discord.Client({\n intents: [\n discord.GatewayIntentBits.Guilds,\n discord.GatewayIntentBits.GuildMessages,\n discord.GatewayIntentBits.MessageContent,\n discord.GatewayIntentBits.DirectMessages,\n ],\n });\n\n const client = this.client as any;\n\n client.on(\"ready\", () => {\n console.log(` Discord: connected as ${client.user?.tag}`);\n this.running = true;\n });\n\n client.on(\"messageCreate\", async (message: any) => {\n if (message.author.bot) return;\n\n const isDM = !message.guild;\n\n // Route through gateway\n if (!this.gateway) return;\n\n try {\n await message.channel.sendTyping();\n\n const response = await this.gateway.handleInboundMessage(\n {\n channel: \"discord\",\n peerId: isDM ? message.author.id : message.channelId,\n peerKind: isDM ? \"dm\" : \"group\",\n guildId: message.guild?.id,\n },\n message.content,\n );\n\n if (response) {\n // Discord has 2000 char limit\n const chunks = splitDiscordMessage(response, 1900);\n for (const chunk of chunks) {\n await message.reply(chunk);\n }\n }\n } catch (err: unknown) {\n const errMsg = err instanceof Error ? err.message : String(err);\n await message.reply(`Error: ${errMsg.slice(0, 200)}`);\n }\n });\n\n await client.login(discordConfig.botToken);\n } catch (err) {\n console.error(` Discord: failed to start — ${err instanceof Error ? err.message : err}`);\n }\n }\n\n async stop(): Promise<void> {\n if (this.client && this.running) {\n (this.client as { destroy: () => void }).destroy();\n this.running = false;\n }\n }\n\n async send(sessionKey: string, payload: ReplyPayload): Promise<void> {\n if (!payload.text || !this.client) return;\n const client = this.client as any;\n\n // Extract channel ID from session key\n const parts = sessionKey.split(\":\");\n const channelId = parts[parts.length - 1];\n try {\n const channel = await client.channels.fetch(channelId);\n if (channel?.send) {\n const chunks = splitDiscordMessage(payload.text, 1900);\n for (const chunk of chunks) {\n await channel.send(chunk);\n }\n }\n } catch {\n // Channel not accessible\n }\n }\n}\n\nfunction splitDiscordMessage(text: string, maxLen: number): string[] {\n if (text.length <= maxLen) return [text];\n const chunks: string[] = [];\n let remaining = text;\n while (remaining.length > 0) {\n if (remaining.length <= maxLen) { chunks.push(remaining); break; }\n let splitAt = remaining.lastIndexOf(\"\\n\", maxLen);\n if (splitAt < maxLen * 0.5) splitAt = maxLen;\n chunks.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt);\n }\n return chunks;\n}\n","/**\n * Web UI channel adapter.\n *\n * The Web UI is served as a React/Preact SPA from the gateway at /chat.\n * It connects via WebSocket (same protocol as CLI). This adapter handles\n * the server-side of that connection.\n *\n * The actual SPA will be built in src/web/ — this adapter just serves\n * the static files and manages WebSocket connections for web clients.\n */\n\nimport { ChannelAdapter, type ReplyPayload } from \"./base.js\";\nimport type { GatewayServer } from \"../gateway/server.js\";\nimport type { ClankConfig } from \"../config/index.js\";\n\nexport class WebAdapter extends ChannelAdapter {\n readonly id = \"web\";\n readonly name = \"Web UI\";\n private gateway: GatewayServer | null = null;\n private config: ClankConfig | null = null;\n\n init(gateway: GatewayServer, config: ClankConfig): void {\n this.gateway = gateway;\n this.config = config;\n }\n\n async start(): Promise<void> {\n const webConfig = this.config?.channels?.web;\n if (!webConfig?.enabled) {\n console.log(\" Web UI: disabled\");\n return;\n }\n\n // Web UI clients connect via the same WebSocket as CLI clients.\n // The gateway server already handles WebSocket connections.\n // This adapter just registers itself for the /chat HTTP route.\n console.log(\" Web UI: enabled (served at /chat)\");\n }\n\n async stop(): Promise<void> {\n // Nothing to clean up — WebSocket connections managed by gateway\n }\n\n async send(_sessionKey: string, _payload: ReplyPayload): Promise<void> {\n // Web UI clients receive messages via WebSocket events,\n // handled by the gateway server's event bridging.\n // No separate send needed.\n }\n}\n","/**\n * Plugin loader — discovers and loads plugins at runtime.\n *\n * Discovery locations:\n * 1. ~/.clank/plugins/ — user-installed plugins\n * 2. node_modules/clank-plugin-* — npm-installed plugins\n *\n * Plugins are loaded in-process via dynamic import().\n * No sandboxing for v1 — trust boundary is the user's machine.\n */\n\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type {\n PluginManifest,\n LoadedPlugin,\n HookType,\n HookHandler,\n} from \"./types.js\";\nimport type { Tool } from \"../tools/types.js\";\n\nexport class PluginLoader {\n private plugins: LoadedPlugin[] = [];\n private hookRegistry = new Map<HookType, HookHandler[]>();\n\n /** Discover and load all plugins */\n async loadAll(): Promise<LoadedPlugin[]> {\n const pluginDirs = await this.discoverPlugins();\n\n for (const dir of pluginDirs) {\n try {\n const plugin = await this.loadPlugin(dir);\n if (plugin) {\n this.plugins.push(plugin);\n // Register hooks\n for (const [hookType, handlers] of plugin.hooks) {\n const existing = this.hookRegistry.get(hookType) || [];\n existing.push(...handlers);\n this.hookRegistry.set(hookType, existing);\n }\n }\n } catch (err) {\n console.error(` Plugin error in ${dir}: ${err instanceof Error ? err.message : err}`);\n }\n }\n\n return this.plugins;\n }\n\n /** Discover plugin directories */\n private async discoverPlugins(): Promise<string[]> {\n const dirs: string[] = [];\n\n // 1. User plugins directory\n const userPluginDir = join(homedir(), \".clank\", \"plugins\");\n if (existsSync(userPluginDir)) {\n try {\n const entries = await readdir(userPluginDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n dirs.push(join(userPluginDir, entry.name));\n }\n }\n } catch {\n // Skip if can't read\n }\n }\n\n // 2. npm clank-plugin-* packages\n const nodeModulesDir = join(process.cwd(), \"node_modules\");\n if (existsSync(nodeModulesDir)) {\n try {\n const entries = await readdir(nodeModulesDir);\n for (const entry of entries) {\n if (entry.startsWith(\"clank-plugin-\")) {\n dirs.push(join(nodeModulesDir, entry));\n }\n }\n } catch {\n // Skip\n }\n }\n\n return dirs;\n }\n\n /** Load a single plugin from a directory */\n private async loadPlugin(dir: string): Promise<LoadedPlugin | null> {\n const manifestPath = join(dir, \"clank-plugin.json\");\n if (!existsSync(manifestPath)) return null;\n\n const raw = await readFile(manifestPath, \"utf-8\");\n const manifest = JSON.parse(raw) as PluginManifest;\n\n if (!manifest.name) return null;\n\n const plugin: LoadedPlugin = {\n manifest,\n path: dir,\n tools: [],\n hooks: new Map(),\n };\n\n // Load tools\n if (manifest.tools) {\n for (const toolEntry of manifest.tools) {\n try {\n const entrypoint = join(dir, toolEntry.entrypoint);\n const mod = await import(entrypoint);\n const tool = mod.default || mod.tool;\n if (tool) {\n plugin.tools.push(tool as Tool);\n }\n } catch (err) {\n console.error(` Failed to load tool ${toolEntry.name}: ${err instanceof Error ? err.message : err}`);\n }\n }\n }\n\n // Load hooks\n if (manifest.hooks) {\n for (const hookEntry of manifest.hooks) {\n try {\n const handlerPath = join(dir, hookEntry.handler);\n const mod = await import(handlerPath);\n const handler = mod.default || mod.handler;\n if (handler) {\n const existing = plugin.hooks.get(hookEntry.type) || [];\n existing.push(handler as HookHandler);\n plugin.hooks.set(hookEntry.type, existing);\n }\n } catch (err) {\n console.error(` Failed to load hook ${hookEntry.type}: ${err instanceof Error ? err.message : err}`);\n }\n }\n }\n\n return plugin;\n }\n\n /** Get all loaded plugins */\n getPlugins(): LoadedPlugin[] {\n return [...this.plugins];\n }\n\n /** Get all tools from loaded plugins */\n getTools(): Tool[] {\n return this.plugins.flatMap((p) => p.tools);\n }\n\n /** Execute hooks of a given type */\n async executeHooks(hookType: HookType, context: Record<string, unknown> = {}): Promise<void> {\n const handlers = this.hookRegistry.get(hookType) || [];\n const hookCtx = { hookType, ...context, prevented: false };\n\n for (const handler of handlers) {\n if (hookCtx.prevented) break;\n await handler(hookCtx);\n }\n }\n\n /** Check if any hook has prevented the default action */\n async executeHooksWithResult(hookType: HookType, context: Record<string, unknown> = {}): Promise<boolean> {\n const hookCtx = { hookType, ...context, prevented: false };\n const handlers = this.hookRegistry.get(hookType) || [];\n\n for (const handler of handlers) {\n await handler(hookCtx);\n if (hookCtx.prevented) return true;\n }\n return false;\n }\n}\n","export { PluginLoader } from \"./loader.js\";\nexport type {\n PluginManifest,\n PluginToolEntry,\n PluginHookEntry,\n HookType,\n HookHandler,\n HookContext,\n LoadedPlugin,\n} from \"./types.js\";\n","/**\n * Gateway server — the central daemon.\n *\n * This is what makes Clank a platform instead of a CLI tool.\n * The gateway is an HTTP + WebSocket server that:\n * - Accepts client connections (CLI, Web, Telegram, Discord)\n * - Routes messages to agent instances\n * - Streams responses back via events\n * - Serves the Web UI static files\n * - Provides a health endpoint\n */\n\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { WebSocketServer, WebSocket } from \"ws\";\nimport { readFile } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { AgentEngine, type AgentIdentity, buildSystemPrompt } from \"../engine/index.js\";\nimport { createFullRegistry, type ToolRegistry } from \"../tools/index.js\";\nimport { createProvider, resolveWithFallback, type ProviderConfig } from \"../providers/index.js\";\nimport { SessionStore } from \"../sessions/index.js\";\nimport { MemoryManager } from \"../memory/index.js\";\nimport { type ClankConfig, getConfigDir, ConfigWatcher } from \"../config/index.js\";\nimport { CronScheduler } from \"../cron/index.js\";\nimport { resolveRoute, deriveSessionKey, type RouteContext } from \"../routing/index.js\";\nimport { type ChannelAdapter } from \"../adapters/base.js\";\nimport { TelegramAdapter } from \"../adapters/telegram.js\";\nimport { DiscordAdapter } from \"../adapters/discord.js\";\nimport { WebAdapter } from \"../adapters/web.js\";\nimport { PluginLoader } from \"../plugins/index.js\";\nimport {\n type Frame,\n type RequestFrame,\n type ResponseFrame,\n type EventFrame,\n type ConnectParams,\n type HelloFrame,\n parseFrame,\n serializeFrame,\n PROTOCOL_VERSION,\n DEFAULT_PORT,\n} from \"./protocol.js\";\n\ninterface ClientConnection {\n ws: WebSocket;\n clientName: string;\n sessionKey: string;\n agentId: string;\n authenticated: boolean;\n eventSeq: number;\n}\n\nexport class GatewayServer {\n private config: ClankConfig;\n private httpServer: ReturnType<typeof createServer> | null = null;\n private wss: WebSocketServer | null = null;\n private clients = new Map<WebSocket, ClientConnection>();\n private engines = new Map<string, AgentEngine>();\n private sessionStore: SessionStore;\n private toolRegistry: ToolRegistry;\n private memoryManager: MemoryManager;\n private cronScheduler: CronScheduler;\n private configWatcher: ConfigWatcher;\n private pluginLoader: PluginLoader;\n private adapters: ChannelAdapter[] = [];\n private running = false;\n\n constructor(config: ClankConfig) {\n this.config = config;\n this.sessionStore = new SessionStore(join(getConfigDir(), \"conversations\"));\n this.toolRegistry = createFullRegistry();\n this.memoryManager = new MemoryManager(join(getConfigDir(), \"memory\"));\n this.cronScheduler = new CronScheduler(join(getConfigDir(), \"cron\"));\n this.configWatcher = new ConfigWatcher();\n this.pluginLoader = new PluginLoader();\n }\n\n /** Start the gateway server */\n async start(): Promise<void> {\n // Ensure auth token exists — generate one if missing\n if (this.config.gateway.auth.mode === \"token\" && !this.config.gateway.auth.token) {\n const { randomBytes } = await import(\"node:crypto\");\n this.config.gateway.auth.token = randomBytes(16).toString(\"hex\");\n console.log(` Generated auth token: ${this.config.gateway.auth.token.slice(0, 8)}...`);\n }\n\n // Initialize subsystems\n await this.sessionStore.init();\n await this.memoryManager.init();\n await this.cronScheduler.init();\n\n // Load plugins and register their tools\n const plugins = await this.pluginLoader.loadAll();\n for (const tool of this.pluginLoader.getTools()) {\n this.toolRegistry.register(tool);\n }\n if (plugins.length > 0) {\n console.log(` Loaded ${plugins.length} plugin(s), ${this.pluginLoader.getTools().length} tool(s)`);\n }\n\n // Start config watcher for hot-reload\n await this.configWatcher.start();\n this.configWatcher.on(\"change\", ({ newConfig }: { newConfig: ClankConfig }) => {\n this.config = newConfig;\n console.log(\" Config reloaded\");\n });\n\n // Start cron scheduler\n this.cronScheduler.setHandler(async (job) => {\n console.log(` Cron: running job \"${job.name}\"`);\n const engine = await this.getOrCreateEngine(`cron:${job.id}`, job.agentId, \"cron\");\n await engine.sendMessage(job.prompt);\n });\n this.cronScheduler.start();\n\n // Start channel adapters\n await this.startAdapters();\n\n const port = this.config.gateway.port || DEFAULT_PORT;\n const bind = this.config.gateway.bind === \"loopback\" ? \"127.0.0.1\" : \"0.0.0.0\";\n\n // Create HTTP server for health checks and static files\n this.httpServer = createServer((req, res) => this.handleHttp(req, res));\n\n // Create WebSocket server\n this.wss = new WebSocketServer({ server: this.httpServer });\n this.wss.on(\"connection\", (ws) => this.handleConnection(ws));\n\n return new Promise((resolve, reject) => {\n this.httpServer!.listen(port, bind, () => {\n this.running = true;\n console.log(`Clank Gateway running on ${bind}:${port}`);\n resolve();\n });\n this.httpServer!.on(\"error\", reject);\n });\n }\n\n /** Start all configured channel adapters */\n private async startAdapters(): Promise<void> {\n console.log(\" Starting channel adapters...\");\n\n const adapterClasses: ChannelAdapter[] = [\n new TelegramAdapter(),\n new DiscordAdapter(),\n new WebAdapter(),\n ];\n\n for (const adapter of adapterClasses) {\n adapter.init(this, this.config);\n try {\n await adapter.start();\n this.adapters.push(adapter);\n } catch (err) {\n console.error(` ${adapter.name}: failed — ${err instanceof Error ? err.message : err}`);\n }\n }\n }\n\n /**\n * Handle an inbound message from any channel adapter.\n * This is the main entry point for all non-WebSocket messages.\n */\n async handleInboundMessage(context: RouteContext, text: string): Promise<string> {\n // Resolve which agent handles this message\n const agentId = resolveRoute(\n context,\n [], // TODO: load bindings from config\n this.config.agents.list.map((a) => ({ id: a.id, name: a.name })),\n this.config.agents.list[0]?.id || \"default\",\n );\n\n const sessionKey = deriveSessionKey(context);\n const engine = await this.getOrCreateEngine(sessionKey, agentId, context.channel);\n return engine.sendMessage(text);\n }\n\n /** Stop the gateway server */\n async stop(): Promise<void> {\n this.running = false;\n\n // Stop subsystems\n this.cronScheduler.stop();\n this.configWatcher.stop();\n\n // Stop channel adapters\n for (const adapter of this.adapters) {\n try { await adapter.stop(); } catch { /* best effort */ }\n }\n this.adapters = [];\n\n // Destroy all engines\n for (const engine of this.engines.values()) {\n engine.destroy();\n }\n this.engines.clear();\n\n // Close all client connections\n for (const [ws] of this.clients) {\n ws.close(1001, \"Gateway shutting down\");\n }\n this.clients.clear();\n\n // Close servers\n return new Promise((resolve) => {\n this.wss?.close(() => {\n this.httpServer?.close(() => resolve());\n });\n });\n }\n\n /** Handle HTTP requests (health, static files) */\n private async handleHttp(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = req.url || \"/\";\n\n if (url === \"/health\" || url === \"/healthz\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n status: \"ok\",\n version: \"1.3.1\",\n uptime: process.uptime(),\n clients: this.clients.size,\n agents: this.engines.size,\n }));\n return;\n }\n\n if (url === \"/status\") {\n // Require token for status endpoint (contains session info)\n const authHeader = req.headers.authorization;\n const expectedToken = this.config.gateway.auth.token;\n if (expectedToken && authHeader !== `Bearer ${expectedToken}`) {\n res.writeHead(401, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Unauthorized\" }));\n return;\n }\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n gateway: { port: this.config.gateway.port, bind: this.config.gateway.bind },\n clients: Array.from(this.clients.values()).map((c) => ({\n clientName: c.clientName,\n sessionKey: c.sessionKey,\n agentId: c.agentId,\n })),\n sessions: this.sessionStore.list().slice(0, 20),\n }));\n return;\n }\n\n // Serve Web UI at /chat\n if (url === \"/chat\" || url === \"/\") {\n try {\n // Try to find index.html relative to this file's location\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const htmlPath = join(__dirname, \"..\", \"web\", \"index.html\");\n const html = await readFile(htmlPath, \"utf-8\");\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(html);\n return;\n } catch {\n // Fallback: try from src directory (dev mode)\n try {\n const html = await readFile(join(process.cwd(), \"src\", \"web\", \"index.html\"), \"utf-8\");\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(html);\n return;\n } catch {\n // Fall through to 404\n }\n }\n }\n\n res.writeHead(404);\n res.end(\"Not found\");\n }\n\n /** Handle a new WebSocket connection */\n private handleConnection(ws: WebSocket): void {\n const client: ClientConnection = {\n ws,\n clientName: \"unknown\",\n sessionKey: \"\",\n agentId: \"default\",\n authenticated: false,\n eventSeq: 0,\n };\n this.clients.set(ws, client);\n\n ws.on(\"message\", (data) => {\n const frame = parseFrame(data.toString());\n if (frame) this.handleFrame(client, frame);\n });\n\n ws.on(\"close\", () => {\n this.clients.delete(ws);\n });\n\n ws.on(\"error\", () => {\n this.clients.delete(ws);\n });\n }\n\n /** Handle an incoming frame from a client */\n private async handleFrame(client: ClientConnection, frame: Frame): Promise<void> {\n // Handle connect/handshake\n if (frame.type === \"connect\" || (frame.type === \"req\" && (frame as RequestFrame).method === \"connect\")) {\n await this.handleConnect(client, frame as ConnectParams | RequestFrame);\n return;\n }\n\n // All other frames require authentication\n if (!client.authenticated) {\n this.sendResponse(client, (frame as RequestFrame).id, false, undefined, \"Not authenticated\");\n return;\n }\n\n if (frame.type === \"req\") {\n await this.handleRequest(client, frame);\n }\n }\n\n /** Handle client connection/auth */\n private async handleConnect(client: ClientConnection, frame: ConnectParams | RequestFrame): Promise<void> {\n const params = frame.type === \"connect\"\n ? (frame as ConnectParams).params\n : (frame as RequestFrame).params as ConnectParams[\"params\"];\n const reqId = frame.type === \"req\" ? (frame as RequestFrame).id : 0;\n\n // Auth check\n const expectedToken = this.config.gateway.auth.token;\n const providedToken = params?.auth?.token;\n if (expectedToken && this.config.gateway.auth.mode !== \"none\" && providedToken !== expectedToken) {\n client.ws.send(serializeFrame({\n type: \"res\", id: reqId, ok: false, error: \"Invalid token\",\n } as ResponseFrame));\n return;\n }\n\n client.clientName = params?.mode || \"unknown\";\n client.authenticated = true;\n\n // Resolve default agent and session\n const agentId = this.config.agents.list[0]?.id || \"default\";\n const sessionKey = `${client.clientName}:main`;\n client.agentId = agentId;\n client.sessionKey = sessionKey;\n\n // Send hello with available agents and recent sessions\n const hello: HelloFrame = {\n type: \"hello\",\n protocol: PROTOCOL_VERSION,\n version: \"1.3.1\",\n agents: this.config.agents.list.map((a) => ({\n id: a.id,\n name: a.name || a.id,\n model: a.model?.primary || this.config.agents.defaults.model.primary,\n status: \"online\",\n })),\n sessions: this.sessionStore.list().slice(0, 50).map((s) => ({\n key: s.normalizedKey,\n label: s.label,\n agentId: s.agentId || \"default\",\n updatedAt: s.updatedAt,\n })),\n };\n client.ws.send(serializeFrame(hello));\n if (reqId) this.sendResponse(client, reqId, true, { agentId, sessionKey });\n }\n\n /** Handle a request frame */\n private async handleRequest(client: ClientConnection, frame: RequestFrame): Promise<void> {\n try {\n switch (frame.method) {\n // === Chat ===\n case \"chat.send\":\n case \"sendMessage\":\n await this.handleSendMessage(client, frame);\n break;\n\n case \"chat.abort\":\n case \"cancel\":\n this.handleCancel(client);\n this.sendResponse(client, frame.id, true);\n break;\n\n case \"chat.history\": {\n const historyKey = (frame.params?.sessionKey as string) || client.sessionKey;\n const entry = this.sessionStore.list().find((s) => s.normalizedKey === historyKey);\n const messages = entry ? await this.sessionStore.loadMessages(entry.id) : [];\n const limit = Number(frame.params?.limit) || 200;\n this.sendResponse(client, frame.id, true, messages.slice(-limit));\n break;\n }\n\n // === Sessions ===\n case \"session.list\":\n this.sendResponse(client, frame.id, true, this.sessionStore.list());\n break;\n\n case \"session.delete\": {\n const delKey = (frame.params?.sessionKey as string) || client.sessionKey;\n await this.sessionStore.delete(delKey);\n this.sendResponse(client, frame.id, true);\n break;\n }\n\n case \"session.reset\": {\n const resetKey = (frame.params?.sessionKey as string) || client.sessionKey;\n await this.sessionStore.reset(resetKey);\n const eng = this.engines.get(resetKey);\n if (eng) eng.getContextEngine().clear();\n this.sendResponse(client, frame.id, true);\n break;\n }\n\n // === Agents ===\n case \"agent.list\":\n this.sendResponse(client, frame.id, true, this.config.agents.list.map((a) => ({\n id: a.id,\n name: a.name || a.id,\n model: a.model?.primary || this.config.agents.defaults.model.primary,\n status: \"online\",\n })));\n break;\n\n case \"agent.status\": {\n const aid = frame.params?.agentId as string;\n const agentCfg = this.config.agents.list.find((a) => a.id === aid);\n this.sendResponse(client, frame.id, true, agentCfg ? {\n id: agentCfg.id,\n name: agentCfg.name,\n model: agentCfg.model?.primary || this.config.agents.defaults.model.primary,\n status: \"online\",\n } : null);\n break;\n }\n\n // === Config ===\n case \"config.get\": {\n const { redactConfig } = await import(\"../config/redact.js\");\n const section = frame.params?.section as string;\n if (section) {\n const val = (this.config as unknown as Record<string, unknown>)[section];\n this.sendResponse(client, frame.id, true, redactConfig(val));\n } else {\n this.sendResponse(client, frame.id, true, redactConfig(this.config));\n }\n break;\n }\n\n case \"config.set\": {\n const { loadConfig, saveConfig } = await import(\"../config/index.js\");\n const cfg = await loadConfig();\n const key = frame.params?.key as string;\n const value = frame.params?.value;\n\n // Protect against prototype pollution\n const BLOCKED_KEYS = [\"__proto__\", \"constructor\", \"prototype\"];\n if (key && value !== undefined) {\n const keys = key.split(\".\");\n if (keys.some((k) => BLOCKED_KEYS.includes(k))) {\n this.sendResponse(client, frame.id, false, undefined, \"Blocked: unsafe key\");\n break;\n }\n let target: Record<string, unknown> = cfg as unknown as Record<string, unknown>;\n for (let i = 0; i < keys.length - 1; i++) {\n if (!target[keys[i]] || typeof target[keys[i]] !== \"object\") target[keys[i]] = {};\n target = target[keys[i]] as Record<string, unknown>;\n }\n target[keys[keys.length - 1]] = value;\n await saveConfig(cfg);\n this.config = cfg;\n }\n this.sendResponse(client, frame.id, true);\n break;\n }\n\n // === Pipelines ===\n case \"pipeline.list\":\n this.sendResponse(client, frame.id, true, []); // TODO: wire pipeline runner\n break;\n\n case \"pipeline.run\":\n this.sendResponse(client, frame.id, false, undefined, \"Pipeline execution via UI coming soon\");\n break;\n\n case \"pipeline.status\":\n case \"pipeline.abort\":\n this.sendResponse(client, frame.id, true, null);\n break;\n\n // === Cron ===\n case \"cron.list\":\n this.sendResponse(client, frame.id, true, this.cronScheduler.listJobs());\n break;\n\n case \"cron.create\": {\n const job = await this.cronScheduler.addJob({\n name: (frame.params?.name as string) || \"Unnamed\",\n schedule: (frame.params?.schedule as string) || \"1h\",\n agentId: (frame.params?.agentId as string) || \"default\",\n prompt: (frame.params?.prompt as string) || \"\",\n });\n this.sendResponse(client, frame.id, true, job);\n break;\n }\n\n case \"cron.delete\":\n await this.cronScheduler.removeJob(frame.params?.jobId as string);\n this.sendResponse(client, frame.id, true);\n break;\n\n case \"cron.trigger\": {\n const triggerJob = this.cronScheduler.listJobs().find((j) => j.id === frame.params?.jobId);\n if (triggerJob) {\n const cronEngine = await this.getOrCreateEngine(`cron:${triggerJob.id}`, triggerJob.agentId, \"cron\");\n cronEngine.sendMessage(triggerJob.prompt); // Fire and forget\n this.sendResponse(client, frame.id, true);\n } else {\n this.sendResponse(client, frame.id, false, undefined, \"Job not found\");\n }\n break;\n }\n\n // === Logs ===\n case \"log.tail\":\n // TODO: implement log streaming\n this.sendResponse(client, frame.id, true, { subscribed: true });\n break;\n\n case \"log.query\":\n this.sendResponse(client, frame.id, true, []);\n break;\n\n default:\n this.sendResponse(client, frame.id, false, undefined, `Unknown method: ${frame.method}`);\n }\n } catch (err) {\n this.sendResponse(client, frame.id, false, undefined, err instanceof Error ? err.message : String(err));\n }\n }\n\n /** Handle sendMessage — route to agent engine */\n private async handleSendMessage(client: ClientConnection, frame: RequestFrame): Promise<void> {\n const text = (frame.params?.message || frame.params?.text) as string;\n if (!text) {\n this.sendResponse(client, frame.id, false, undefined, \"message is required\");\n return;\n }\n\n try {\n const engine = await this.getOrCreateEngine(client.sessionKey, client.agentId, client.clientName);\n\n // Wire engine events to client WebSocket\n const cleanup = this.wireEngineEvents(engine, client);\n\n try {\n const response = await engine.sendMessage(text);\n this.sendResponse(client, frame.id, true, { text: response });\n } finally {\n cleanup();\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.sendResponse(client, frame.id, false, undefined, msg);\n }\n }\n\n /** Cancel current request for a client */\n private handleCancel(client: ClientConnection): void {\n const engine = this.engines.get(client.sessionKey);\n if (engine) engine.cancel();\n }\n\n /** Get or create an agent engine for a session */\n private async getOrCreateEngine(sessionKey: string, agentId: string, channel: string): Promise<AgentEngine> {\n let engine = this.engines.get(sessionKey);\n if (engine) return engine;\n\n // Find agent config or use defaults\n const agentConfig = this.config.agents.list.find((a) => a.id === agentId);\n const modelConfig = agentConfig?.model || this.config.agents.defaults.model;\n\n // Resolve provider with fallback chain\n const resolved = await resolveWithFallback(\n modelConfig.primary,\n modelConfig.fallbacks || [],\n this.config.models.providers,\n { maxResponseTokens: this.config.agents.defaults.maxResponseTokens },\n );\n\n const identity: AgentIdentity = {\n id: agentId,\n name: agentConfig?.name || \"Clank\",\n model: modelConfig,\n workspace: agentConfig?.workspace || this.config.agents.defaults.workspace || process.cwd(),\n toolTier: agentConfig?.toolTier || this.config.agents.defaults.toolTier || \"auto\",\n tools: agentConfig?.tools,\n };\n\n // Build system prompt from workspace files + memory\n const systemPrompt = await buildSystemPrompt({\n identity,\n workspaceDir: identity.workspace,\n channel,\n });\n\n // Inject memory context into system prompt\n const memoryBlock = await this.memoryManager.buildMemoryBlock(\"\", identity.workspace);\n const fullPrompt = memoryBlock\n ? systemPrompt + \"\\n\\n---\\n\\n\" + memoryBlock\n : systemPrompt;\n\n engine = new AgentEngine({\n identity,\n toolRegistry: this.toolRegistry,\n sessionStore: this.sessionStore,\n provider: resolved,\n autoApprove: this.config.tools.autoApprove,\n systemPrompt: fullPrompt,\n });\n\n await engine.loadSession(sessionKey, channel);\n this.engines.set(sessionKey, engine);\n\n // Execute plugin hooks\n await this.pluginLoader.executeHooks(\"before_agent_start\", { agentId, sessionKey });\n\n return engine;\n }\n\n /**\n * Wire engine events to a client's WebSocket.\n * Returns a cleanup function to remove listeners.\n */\n private wireEngineEvents(engine: AgentEngine, client: ClientConnection): () => void {\n const eventMap: Record<string, string> = {\n \"token\": \"token\",\n \"response-start\": \"response-start\",\n \"response-end\": \"response-end\",\n \"tool-start\": \"tool-start\",\n \"tool-result\": \"tool-result\",\n \"context-compacting\": \"context-compacting\",\n \"usage\": \"usage\",\n \"error\": \"error\",\n \"turn-complete\": \"turn-complete\",\n };\n\n const listeners: Array<[string, (...args: unknown[]) => void]> = [];\n\n for (const [engineEvent, wireEvent] of Object.entries(eventMap)) {\n const listener = (payload: unknown) => {\n this.sendEvent(client, wireEvent, payload);\n };\n engine.on(engineEvent, listener);\n listeners.push([engineEvent, listener]);\n }\n\n // Confirmation events — respect the config autoApprove settings.\n // For channels (Telegram/Discord), use the config. For WebSocket\n // clients (TUI/Web), relay to the client for interactive approval.\n const confirmListener = (data: unknown) => {\n const { actions, resolve } = data as { actions: unknown[]; resolve: (v: boolean | \"always\") => void };\n const action = (actions as Array<{ safetyLevel: string }>)[0];\n const level = (action?.safetyLevel || \"high\") as \"low\" | \"medium\" | \"high\";\n\n // Check autoApprove config\n if (this.config.tools.autoApprove[level]) {\n resolve(true);\n return;\n }\n\n // For WebSocket clients, relay the confirmation request\n const confirmId = `confirm_${Date.now()}`;\n this.sendEvent(client, \"confirm-needed\", { id: confirmId, actions });\n\n // Default deny after 30s timeout for safety\n const timeout = setTimeout(() => resolve(false), 30_000);\n\n // Listen for resolve from client (one-shot)\n const resolveHandler = (raw: Buffer | string) => {\n const frame = parseFrame(raw.toString());\n if (frame?.type === \"req\" && (frame as RequestFrame).method === \"confirm.resolve\") {\n const params = (frame as RequestFrame).params as { id?: string; approved?: boolean | \"always\" };\n if (params?.id === confirmId) {\n clearTimeout(timeout);\n client.ws.removeListener(\"message\", resolveHandler);\n resolve(params.approved ?? false);\n }\n }\n };\n client.ws.on(\"message\", resolveHandler);\n };\n engine.on(\"confirm-needed\", confirmListener);\n listeners.push([\"confirm-needed\", confirmListener]);\n\n return () => {\n for (const [event, listener] of listeners) {\n engine.removeListener(event, listener);\n }\n };\n }\n\n /** Send a response frame to a client */\n private sendResponse(client: ClientConnection, id: number | string, ok: boolean, result?: unknown, error?: string): void {\n const frame: ResponseFrame = { type: \"res\", id, ok, result, error };\n if (client.ws.readyState === WebSocket.OPEN) {\n client.ws.send(serializeFrame(frame));\n }\n }\n\n /** Send an event frame to a client */\n private sendEvent(client: ClientConnection, event: string, payload: unknown): void {\n const frame: EventFrame = { type: \"event\", event, payload, seq: ++client.eventSeq };\n if (client.ws.readyState === WebSocket.OPEN) {\n client.ws.send(serializeFrame(frame));\n }\n }\n\n get isRunning(): boolean {\n return this.running;\n }\n}\n","export { GatewayServer } from \"./server.js\";\nexport {\n type Frame,\n type ConnectParams,\n type HelloFrame,\n type RequestFrame,\n type ResponseFrame,\n type EventFrame,\n parseFrame,\n serializeFrame,\n PROTOCOL_VERSION,\n DEFAULT_PORT,\n METHODS,\n EVENTS,\n} from \"./protocol.js\";\n","/**\n * Gateway CLI commands — start/stop/status/restart.\n *\n * The gateway runs as a background process. Telegram/Discord stay\n * alive in the background while you use CLI/TUI/Web on top.\n */\n\nimport { GatewayServer } from \"../gateway/index.js\";\nimport { loadConfig, ensureConfigDir, getConfigDir } from \"../config/index.js\";\nimport { DEFAULT_PORT } from \"../gateway/protocol.js\";\nimport { fork, exec } from \"node:child_process\";\nimport { writeFile, readFile, unlink } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __filename = fileURLToPath(import.meta.url);\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\n\n/** Check if gateway is already running */\nexport async function isGatewayRunning(port?: number): Promise<boolean> {\n const config = await loadConfig();\n const p = port || config.gateway.port || DEFAULT_PORT;\n try {\n const res = await fetch(`http://127.0.0.1:${p}/health`, { signal: AbortSignal.timeout(2000) });\n return res.ok;\n } catch {\n return false;\n }\n}\n\n/** Get the PID file path */\nfunction pidFilePath(): string {\n return join(getConfigDir(), \"gateway.pid\");\n}\n\n/**\n * Start the gateway in the foreground (blocking).\n * Used by `clank gateway start --foreground` and the background process.\n */\nexport async function gatewayStartForeground(opts: { port?: string }): Promise<void> {\n await ensureConfigDir();\n const config = await loadConfig();\n\n if (opts.port) {\n config.gateway.port = parseInt(opts.port, 10);\n }\n\n // Singleton check — only one gateway at a time\n if (await isGatewayRunning(config.gateway.port)) {\n console.log(green(` Gateway already running on port ${config.gateway.port}`));\n return;\n }\n\n // Write PID file\n await writeFile(pidFilePath(), String(process.pid), \"utf-8\");\n\n const server = new GatewayServer(config);\n\n const shutdown = async () => {\n console.log(dim(\"\\nShutting down...\"));\n try { await unlink(pidFilePath()); } catch {}\n await server.stop();\n process.exit(0);\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n try {\n await server.start();\n console.log(green(`Gateway started on port ${config.gateway.port}`));\n console.log(dim(\"Press Ctrl+C to stop\"));\n } catch (err) {\n try { await unlink(pidFilePath()); } catch {}\n console.error(red(`Failed to start gateway: ${err instanceof Error ? err.message : err}`));\n process.exit(1);\n }\n}\n\n/**\n * Start the gateway as a background process (non-blocking).\n * Returns once the gateway is confirmed running.\n */\nexport async function gatewayStartBackground(): Promise<boolean> {\n const config = await loadConfig();\n const port = config.gateway.port || DEFAULT_PORT;\n\n // Already running?\n if (await isGatewayRunning(port)) {\n return true;\n }\n\n console.log(dim(\" Starting gateway in background...\"));\n\n // Fork a detached child process running `clank gateway start --foreground`\n const entryPoint = join(dirname(__filename), \"index.js\");\n const logFile = join(getConfigDir(), \"logs\", \"gateway.log\");\n\n // Ensure logs dir exists\n const { mkdir } = await import(\"node:fs/promises\");\n await mkdir(join(getConfigDir(), \"logs\"), { recursive: true });\n\n const child = fork(entryPoint, [\"gateway\", \"start\", \"--foreground\"], {\n detached: true,\n stdio: [\"ignore\", \"ignore\", \"ignore\", \"ipc\"],\n });\n child.unref();\n child.disconnect();\n\n // Wait for gateway to be ready (up to 10 seconds)\n for (let i = 0; i < 20; i++) {\n await new Promise((r) => setTimeout(r, 500));\n if (await isGatewayRunning(port)) {\n console.log(green(` Gateway running on port ${port}`));\n return true;\n }\n }\n\n console.log(red(\" Gateway failed to start\"));\n return false;\n}\n\n/** Public entry: start gateway (background by default, foreground with --foreground) */\nexport async function gatewayStart(opts: { port?: string; foreground?: boolean }): Promise<void> {\n if (opts.foreground) {\n await gatewayStartForeground(opts);\n } else {\n const running = await gatewayStartBackground();\n if (!running) {\n process.exit(1);\n }\n }\n}\n\nexport async function gatewayStop(): Promise<void> {\n // Try to kill via PID file\n const pidPath = pidFilePath();\n if (existsSync(pidPath)) {\n try {\n const pid = parseInt(await readFile(pidPath, \"utf-8\"), 10);\n process.kill(pid, \"SIGTERM\");\n await unlink(pidPath);\n console.log(green(\"Gateway stopped\"));\n return;\n } catch {\n // PID might be stale\n try { await unlink(pidPath); } catch {}\n }\n }\n\n // Check if it's running anyway\n if (await isGatewayRunning()) {\n console.log(dim(\"Gateway is running but no PID file found.\"));\n console.log(dim(\"Kill it manually or restart the process.\"));\n } else {\n console.log(dim(\"Gateway is not running.\"));\n }\n}\n\nexport async function gatewayStatus(): Promise<void> {\n const config = await loadConfig();\n const port = config.gateway.port || DEFAULT_PORT;\n\n try {\n const res = await fetch(`http://127.0.0.1:${port}/status`, { signal: AbortSignal.timeout(3000) });\n if (res.ok) {\n const data = await res.json() as Record<string, unknown>;\n console.log(green(\"Gateway is running\"));\n console.log(dim(` Port: ${port}`));\n console.log(dim(` Clients: ${(data.clients as unknown[])?.length || 0}`));\n console.log(dim(` Sessions: ${(data.sessions as unknown[])?.length || 0}`));\n\n // Show PID\n const pidPath = pidFilePath();\n if (existsSync(pidPath)) {\n const pid = await readFile(pidPath, \"utf-8\");\n console.log(dim(` PID: ${pid.trim()}`));\n }\n } else {\n console.log(red(\"Gateway returned error\"));\n }\n } catch {\n console.log(red(\"Gateway is not running\"));\n console.log(dim(` Expected at http://127.0.0.1:${port}`));\n console.log(dim(\" Start with: clank gateway start\"));\n }\n}\n","/**\n * Daemon installer — installs Clank as a system service.\n *\n * Cross-platform:\n * - macOS: LaunchAgent plist\n * - Windows: Task Scheduler\n * - Linux: systemd --user unit\n */\n\nimport { writeFile, mkdir, unlink } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir, platform } from \"node:os\";\nimport { execSync } from \"node:child_process\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\n\nexport async function installDaemon(): Promise<void> {\n const os = platform();\n switch (os) {\n case \"darwin\":\n await installLaunchd();\n break;\n case \"win32\":\n await installTaskScheduler();\n break;\n case \"linux\":\n await installSystemd();\n break;\n default:\n console.log(red(`Unsupported platform: ${os}`));\n }\n}\n\nexport async function uninstallDaemon(): Promise<void> {\n const os = platform();\n switch (os) {\n case \"darwin\":\n await uninstallLaunchd();\n break;\n case \"win32\":\n await uninstallTaskScheduler();\n break;\n case \"linux\":\n await uninstallSystemd();\n break;\n default:\n console.log(red(`Unsupported platform: ${os}`));\n }\n}\n\nexport async function daemonStatus(): Promise<void> {\n const os = platform();\n switch (os) {\n case \"darwin\":\n try {\n const out = execSync(\"launchctl list | grep com.clank.gateway\", { encoding: \"utf-8\" });\n console.log(green(\"Daemon: running (launchd)\"));\n console.log(dim(out.trim()));\n } catch {\n console.log(dim(\"Daemon: not installed\"));\n }\n break;\n case \"win32\":\n try {\n const out = execSync('schtasks /query /tn \"ClankGateway\" /fo LIST', { encoding: \"utf-8\" });\n console.log(green(\"Daemon: installed (Task Scheduler)\"));\n console.log(dim(out.trim()));\n } catch {\n console.log(dim(\"Daemon: not installed\"));\n }\n break;\n case \"linux\":\n try {\n const out = execSync(\"systemctl --user status clank-gateway\", { encoding: \"utf-8\" });\n console.log(green(\"Daemon: running (systemd)\"));\n console.log(dim(out.trim()));\n } catch {\n console.log(dim(\"Daemon: not installed or not running\"));\n }\n break;\n }\n}\n\n// --- macOS: LaunchAgent ---\nasync function installLaunchd(): Promise<void> {\n const plistDir = join(homedir(), \"Library\", \"LaunchAgents\");\n const plistPath = join(plistDir, \"com.clank.gateway.plist\");\n const clankPath = execSync(\"which clank || echo clank\", { encoding: \"utf-8\" }).trim();\n\n await mkdir(plistDir, { recursive: true });\n\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>com.clank.gateway</string>\n <key>ProgramArguments</key>\n <array>\n <string>${clankPath}</string>\n <string>gateway</string>\n <string>start</string>\n <string>--foreground</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>StandardOutPath</key>\n <string>${join(homedir(), \".clank\", \"logs\", \"gateway.log\")}</string>\n <key>StandardErrorPath</key>\n <string>${join(homedir(), \".clank\", \"logs\", \"gateway-error.log\")}</string>\n</dict>\n</plist>`;\n\n await writeFile(plistPath, plist, \"utf-8\");\n execSync(`launchctl load \"${plistPath}\"`);\n console.log(green(\"Daemon installed (launchd)\"));\n console.log(dim(` Plist: ${plistPath}`));\n}\n\nasync function uninstallLaunchd(): Promise<void> {\n const plistPath = join(homedir(), \"Library\", \"LaunchAgents\", \"com.clank.gateway.plist\");\n try {\n execSync(`launchctl unload \"${plistPath}\"`);\n await unlink(plistPath);\n console.log(green(\"Daemon uninstalled\"));\n } catch {\n console.log(dim(\"Daemon was not installed\"));\n }\n}\n\n// --- Windows: Task Scheduler ---\nasync function installTaskScheduler(): Promise<void> {\n // Use the clank global binary path\n const { execSync: execSyncImport } = await import(\"node:child_process\");\n let clankBin = \"clank\";\n try {\n clankBin = execSyncImport(\"where clank\", { encoding: \"utf-8\" }).trim().split(\"\\n\")[0];\n } catch {}\n\n try {\n // Use /rl limited (no admin needed) instead of /rl highest\n execSync(\n `schtasks /create /tn \"ClankGateway\" /tr \"\\\\\"${clankBin}\\\\\" gateway start --foreground\" /sc onlogon /rl limited /f`,\n { encoding: \"utf-8\" },\n );\n // Also start it now\n execSync(`schtasks /run /tn \"ClankGateway\"`, { encoding: \"utf-8\" });\n console.log(green(\"Daemon installed (Task Scheduler)\"));\n console.log(dim(\" Task: ClankGateway\"));\n console.log(dim(\" Trigger: at login\"));\n } catch (err) {\n console.error(red(`Failed to install: ${err instanceof Error ? err.message : err}`));\n }\n}\n\nasync function uninstallTaskScheduler(): Promise<void> {\n try {\n execSync('schtasks /delete /tn \"ClankGateway\" /f', { encoding: \"utf-8\" });\n console.log(green(\"Daemon uninstalled\"));\n } catch {\n console.log(dim(\"Daemon was not installed\"));\n }\n}\n\n// --- Linux: systemd ---\nasync function installSystemd(): Promise<void> {\n const unitDir = join(homedir(), \".config\", \"systemd\", \"user\");\n const unitPath = join(unitDir, \"clank-gateway.service\");\n const clankPath = execSync(\"which clank || echo clank\", { encoding: \"utf-8\" }).trim();\n\n await mkdir(unitDir, { recursive: true });\n\n const unit = `[Unit]\nDescription=Clank Gateway\nAfter=network.target\n\n[Service]\nExecStart=${clankPath} gateway start --foreground\nRestart=on-failure\nRestartSec=5\n\n[Install]\nWantedBy=default.target\n`;\n\n await writeFile(unitPath, unit, \"utf-8\");\n execSync(\"systemctl --user daemon-reload\");\n execSync(\"systemctl --user enable clank-gateway\");\n execSync(\"systemctl --user start clank-gateway\");\n console.log(green(\"Daemon installed (systemd --user)\"));\n console.log(dim(` Unit: ${unitPath}`));\n}\n\nasync function uninstallSystemd(): Promise<void> {\n try {\n execSync(\"systemctl --user stop clank-gateway\");\n execSync(\"systemctl --user disable clank-gateway\");\n const unitPath = join(homedir(), \".config\", \"systemd\", \"user\", \"clank-gateway.service\");\n await unlink(unitPath);\n execSync(\"systemctl --user daemon-reload\");\n console.log(green(\"Daemon uninstalled\"));\n } catch {\n console.log(dim(\"Daemon was not installed\"));\n }\n}\n","export { installDaemon, uninstallDaemon, daemonStatus } from \"./install.js\";\n","/**\n * `clank setup` — Onboarding wizard.\n *\n * Gets the user from install to chatting in under 2 minutes.\n * Auto-detects local models, configures the gateway, and sets up\n * the user's preferred interface.\n *\n * Two flows:\n * - Quick Start: sensible defaults, minimal questions\n * - Advanced: full control over everything\n */\n\nimport { createInterface } from \"node:readline\";\nimport { randomBytes } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nimport {\n loadConfig,\n saveConfig,\n ensureConfigDir,\n defaultConfig,\n getConfigDir,\n type ClankConfig,\n} from \"../config/index.js\";\nimport { detectLocalServers } from \"../providers/index.js\";\nimport { installDaemon } from \"../daemon/index.js\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst bold = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst yellow = (s: string) => `\\x1b[33m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\n\nfunction ask(rl: ReturnType<typeof createInterface>, question: string): Promise<string> {\n return new Promise((resolve) => rl.question(question, resolve));\n}\n\nexport async function runSetup(opts: {\n quick?: boolean;\n advanced?: boolean;\n section?: string;\n nonInteractive?: boolean;\n acceptRisk?: boolean;\n}): Promise<void> {\n await ensureConfigDir();\n const config = defaultConfig();\n\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n\n try {\n // Step 1: Welcome & Security\n console.log(\"\");\n console.log(bold(\" Welcome to Clank\"));\n console.log(\"\");\n console.log(\" Clank is an AI agent that can read, write, and\");\n console.log(\" delete files, execute commands, and access the web.\");\n console.log(\" Review actions carefully.\");\n console.log(\"\");\n\n if (!opts.acceptRisk) {\n const ack = await ask(rl, cyan(\" I understand, continue? [Y/n] \"));\n if (ack.toLowerCase() === \"n\") {\n console.log(dim(\" Setup cancelled.\"));\n return;\n }\n }\n\n // Step 2: Choose Flow\n let isAdvanced = opts.advanced || false;\n if (!opts.quick && !opts.advanced) {\n console.log(\"\");\n console.log(\" How would you like to set up Clank?\");\n console.log(\"\");\n console.log(\" 1. \" + bold(\"Quick Start\") + \" (recommended)\");\n console.log(dim(\" Auto-detect local models, sensible defaults\"));\n console.log(\" 2. Advanced\");\n console.log(dim(\" Full control over gateway, models, channels\"));\n console.log(\"\");\n const choice = await ask(rl, cyan(\" Choice [1]: \"));\n isAdvanced = choice === \"2\";\n }\n\n // Step 3: Model Provider Setup\n console.log(\"\");\n console.log(dim(\" Searching for local models...\"));\n const servers = await detectLocalServers();\n\n if (servers.length > 0) {\n const primary = servers[0];\n console.log(green(` Found ${primary.provider} at ${primary.baseUrl}`));\n console.log(dim(` Models: ${primary.models.slice(0, 5).join(\", \")}`));\n\n const defaultModel = primary.models[0] || \"qwen3.5\";\n const useDefault = await ask(rl, cyan(` Use ${primary.provider}/${defaultModel} as default? [Y/n] `));\n if (useDefault.toLowerCase() !== \"n\") {\n config.agents.defaults.model.primary = `${primary.provider}/${defaultModel}`;\n // Save the detected server URL for ALL local providers\n (config.models.providers as Record<string, unknown>)[primary.provider] = { baseUrl: primary.baseUrl };\n }\n } else {\n console.log(yellow(\" No local model server detected.\"));\n console.log(dim(\" Install Ollama (recommended) or configure a cloud provider.\"));\n }\n\n // Step 3b: Cloud provider (optional fallback)\n console.log(\"\");\n const addCloud = await ask(rl, cyan(\" Add a cloud provider as fallback? [y/N] \"));\n if (addCloud.toLowerCase() === \"y\") {\n console.log(dim(\" 1. Anthropic (Claude)\"));\n console.log(dim(\" 2. OpenAI (GPT)\"));\n console.log(dim(\" 3. Google (Gemini)\"));\n const provider = await ask(rl, cyan(\" Which provider? [1]: \"));\n\n switch (provider || \"1\") {\n case \"1\": {\n const key = await ask(rl, cyan(\" Anthropic API key: \"));\n if (key.trim()) {\n config.models.providers.anthropic = { apiKey: key.trim() };\n config.agents.defaults.model.fallbacks = [\"anthropic/claude-sonnet-4-6\"];\n console.log(green(\" Anthropic configured as fallback\"));\n }\n break;\n }\n case \"2\": {\n const key = await ask(rl, cyan(\" OpenAI API key: \"));\n if (key.trim()) {\n config.models.providers.openai = { apiKey: key.trim() };\n config.agents.defaults.model.fallbacks = [\"openai/gpt-4o\"];\n console.log(green(\" OpenAI configured as fallback\"));\n }\n break;\n }\n case \"3\": {\n const key = await ask(rl, cyan(\" Google AI API key: \"));\n if (key.trim()) {\n config.models.providers.google = { apiKey: key.trim() };\n config.agents.defaults.model.fallbacks = [\"google/gemini-2.0-flash\"];\n console.log(green(\" Google configured as fallback\"));\n }\n break;\n }\n }\n }\n\n // Step 4: Gateway Configuration\n console.log(\"\");\n console.log(dim(\" Gateway settings:\"));\n if (isAdvanced) {\n const port = await ask(rl, cyan(` Port [${config.gateway.port}]: `));\n if (port.trim()) config.gateway.port = parseInt(port, 10);\n }\n\n // Generate auth token\n config.gateway.auth.token = randomBytes(16).toString(\"hex\");\n console.log(dim(` Port: ${config.gateway.port}`));\n console.log(dim(` Token: ${config.gateway.auth.token.slice(0, 8)}...`));\n\n // Step 5: Workspace Bootstrap\n console.log(\"\");\n console.log(dim(\" Creating workspace...\"));\n const { ensureWorkspaceFiles } = await import(\"../engine/system-prompt.js\");\n const templateDir = join(__dirname, \"..\", \"workspace\", \"templates\");\n const wsDir = join(getConfigDir(), \"workspace\");\n try {\n await ensureWorkspaceFiles(wsDir, templateDir);\n } catch {\n // Templates may not be found in built version — that's ok\n }\n console.log(green(\" Workspace ready at \" + getConfigDir()));\n\n // Step 6: Channel Setup\n console.log(\"\");\n console.log(\" Channel setup:\");\n console.log(dim(\" Web UI and CLI are always available.\"));\n console.log(\"\");\n\n const addTelegram = await ask(rl, cyan(\" Connect Telegram bot? [y/N] \"));\n if (addTelegram.toLowerCase() === \"y\") {\n console.log(dim(\" 1. Message @BotFather on Telegram\"));\n console.log(dim(\" 2. Send /newbot and follow prompts\"));\n console.log(dim(\" 3. Copy the bot token\"));\n const token = await ask(rl, cyan(\" Bot token: \"));\n if (token.trim()) {\n config.channels.telegram = { enabled: true, botToken: token.trim() };\n const userId = await ask(rl, cyan(\" Your Telegram user ID (for allowlist): \"));\n if (userId.trim()) {\n config.channels.telegram.allowFrom = [userId.trim()];\n }\n console.log(green(\" Telegram configured\"));\n }\n }\n\n const addDiscord = await ask(rl, cyan(\" Connect Discord bot? [y/N] \"));\n if (addDiscord.toLowerCase() === \"y\") {\n console.log(dim(\" 1. Go to discord.com/developers/applications\"));\n console.log(dim(\" 2. Create app → Bot → Copy Token\"));\n console.log(dim(\" 3. Enable MESSAGE CONTENT intent\"));\n const token = await ask(rl, cyan(\" Bot token: \"));\n if (token.trim()) {\n config.channels.discord = { enabled: true, botToken: token.trim() };\n console.log(green(\" Discord configured\"));\n }\n }\n\n // Step 7: Web Search (Brave)\n console.log(\"\");\n const addSearch = await ask(rl, cyan(\" Set up web search (Brave Search)? [y/N] \"));\n if (addSearch.toLowerCase() === \"y\") {\n console.log(dim(\" Get a free API key at: https://brave.com/search/api/\"));\n const key = await ask(rl, cyan(\" Brave Search API key: \"));\n if (key.trim()) {\n config.tools.webSearch = { enabled: true, provider: \"brave\", apiKey: key.trim() };\n console.log(green(\" Brave Search configured\"));\n }\n }\n\n // Step 8: Integrations (API services)\n console.log(\"\");\n console.log(\" API Integrations:\");\n console.log(dim(\" Add third-party services for voice, image gen, etc.\"));\n console.log(dim(\" You can also configure these later through conversation.\"));\n console.log(\"\");\n\n const addElevenLabs = await ask(rl, cyan(\" Set up ElevenLabs (text-to-speech)? [y/N] \"));\n if (addElevenLabs.toLowerCase() === \"y\") {\n console.log(dim(\" Get an API key at: https://elevenlabs.io/\"));\n const key = await ask(rl, cyan(\" ElevenLabs API key: \"));\n if (key.trim()) {\n config.integrations.elevenlabs = { enabled: true, apiKey: key.trim() };\n const voiceId = await ask(rl, cyan(\" Default voice ID (Enter to skip): \"));\n if (voiceId.trim()) {\n config.integrations.elevenlabs.voiceId = voiceId.trim();\n }\n console.log(green(\" ElevenLabs configured (TTS available)\"));\n }\n }\n\n const addWhisper = await ask(rl, cyan(\" Set up speech-to-text (voice messages)? [y/N] \"));\n if (addWhisper.toLowerCase() === \"y\") {\n console.log(dim(\" 1. Groq (recommended — free, fast)\"));\n console.log(dim(\" 2. OpenAI Whisper API (paid, uses OpenAI key)\"));\n console.log(dim(\" 3. Local whisper.cpp (requires manual install)\"));\n const whisperChoice = await ask(rl, cyan(\" Choice [1]: \"));\n if (whisperChoice === \"3\") {\n config.integrations.whisper = { enabled: true, provider: \"local\" };\n console.log(green(\" Local whisper.cpp configured\"));\n console.log(dim(\" Make sure whisper is installed and in PATH\"));\n } else if (whisperChoice === \"2\") {\n const existingKey = config.models.providers.openai?.apiKey;\n if (existingKey) {\n config.integrations.whisper = { enabled: true, provider: \"openai\", apiKey: existingKey };\n console.log(green(\" Whisper configured (using existing OpenAI key)\"));\n } else {\n const key = await ask(rl, cyan(\" OpenAI API key: \"));\n if (key.trim()) {\n config.integrations.whisper = { enabled: true, provider: \"openai\", apiKey: key.trim() };\n console.log(green(\" Whisper configured\"));\n }\n }\n } else {\n // Groq (default — free)\n console.log(dim(\" Get a free API key at: https://console.groq.com/keys\"));\n const key = await ask(rl, cyan(\" Groq API key: \"));\n if (key.trim()) {\n config.integrations.whisper = { enabled: true, provider: \"groq\" as any, apiKey: key.trim() };\n console.log(green(\" Groq Whisper configured (free, fast)\"));\n }\n }\n }\n\n // Step 9: Agents (Advanced only)\n if (isAdvanced) {\n console.log(\"\");\n const addAgents = await ask(rl, cyan(\" Define additional agents? [y/N] \"));\n if (addAgents.toLowerCase() === \"y\") {\n let adding = true;\n while (adding) {\n const id = await ask(rl, cyan(\" Agent ID: \"));\n if (!id.trim()) break;\n const name = await ask(rl, cyan(\" Name: \"));\n const model = await ask(rl, cyan(\" Model [default]: \"));\n\n config.agents.list.push({\n id: id.trim(),\n name: name.trim() || id.trim(),\n model: model.trim() ? { primary: model.trim() } : undefined,\n });\n console.log(green(` Agent ${id.trim()} added`));\n\n const more = await ask(rl, cyan(\" Add another? [y/N] \"));\n adding = more.toLowerCase() === \"y\";\n }\n }\n }\n\n // Step 10: Daemon Install\n console.log(\"\");\n const installService = await ask(rl, cyan(\" Install as system service? [Y/n] \"));\n if (installService.toLowerCase() !== \"n\") {\n try {\n await installDaemon();\n } catch (err) {\n console.log(yellow(` Skipped: ${err instanceof Error ? err.message : err}`));\n }\n }\n\n // Save config\n await saveConfig(config);\n console.log(green(\"\\n Config saved to \" + getConfigDir() + \"/config.json5\"));\n\n // Step 11: First Chat\n console.log(\"\");\n console.log(bold(\" Clank is ready!\"));\n console.log(\"\");\n console.log(\" Start chatting:\");\n console.log(dim(\" clank chat — CLI chat\"));\n console.log(dim(\" clank chat --web — Open in browser\"));\n console.log(dim(\" clank gateway start — Start the daemon\"));\n console.log(\"\");\n } finally {\n rl.close();\n }\n}\n","/**\n * `clank fix` — Diagnostics & repair utility.\n *\n * Checks all systems and reports issues. Auto-fix mode\n * attempts safe repairs for common problems.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { getConfigDir, getConfigPath, loadConfig } from \"../config/index.js\";\nimport { OllamaProvider } from \"../providers/ollama.js\";\nimport { DEFAULT_PORT } from \"../gateway/protocol.js\";\n\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\nconst yellow = (s: string) => `\\x1b[33m${s}\\x1b[0m`;\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst check = green(\"✓\");\nconst cross = red(\"✗\");\nconst warn = yellow(\"!\");\n\ninterface CheckResult {\n name: string;\n status: \"ok\" | \"warn\" | \"error\";\n message: string;\n fix?: string;\n}\n\nexport async function runFix(opts: { auto?: boolean; check?: string }): Promise<void> {\n console.log(\"\");\n console.log(\" Clank Diagnostics\");\n console.log(\"\");\n\n const results: CheckResult[] = [];\n\n // Only run specific check if requested\n const checks = opts.check ? [opts.check] : [\"config\", \"gateway\", \"models\", \"sessions\", \"workspace\"];\n\n if (checks.includes(\"config\")) results.push(await checkConfig());\n if (checks.includes(\"gateway\")) results.push(await checkGateway());\n if (checks.includes(\"models\")) results.push(await checkModels());\n if (checks.includes(\"sessions\")) results.push(await checkSessions());\n if (checks.includes(\"workspace\")) results.push(await checkWorkspace());\n\n // Print results\n for (const r of results) {\n const icon = r.status === \"ok\" ? check : r.status === \"warn\" ? warn : cross;\n console.log(` ${icon} ${r.name.padEnd(18)} ${r.message}`);\n if (r.fix && r.status !== \"ok\") {\n console.log(dim(` → ${r.fix}`));\n }\n }\n\n const issues = results.filter((r) => r.status !== \"ok\");\n console.log(\"\");\n if (issues.length === 0) {\n console.log(green(\" All checks passed.\"));\n } else {\n console.log(yellow(` ${issues.length} issue${issues.length > 1 ? \"s\" : \"\"} found.`));\n }\n console.log(\"\");\n}\n\nasync function checkConfig(): Promise<CheckResult> {\n const configPath = getConfigPath();\n if (!existsSync(configPath)) {\n return {\n name: \"Config\",\n status: \"warn\",\n message: \"No config file found\",\n fix: \"Run: clank setup\",\n };\n }\n\n try {\n await loadConfig();\n return { name: \"Config\", status: \"ok\", message: \"valid\" };\n } catch (err) {\n return {\n name: \"Config\",\n status: \"error\",\n message: `parse error: ${err instanceof Error ? err.message : err}`,\n fix: \"Check config.json5 for syntax errors\",\n };\n }\n}\n\nasync function checkGateway(): Promise<CheckResult> {\n const config = await loadConfig();\n const port = config.gateway.port || DEFAULT_PORT;\n\n try {\n const res = await fetch(`http://127.0.0.1:${port}/health`, { signal: AbortSignal.timeout(3000) });\n if (res.ok) {\n return { name: \"Gateway\", status: \"ok\", message: `running on :${port}` };\n }\n return { name: \"Gateway\", status: \"error\", message: `unhealthy on :${port}` };\n } catch {\n return {\n name: \"Gateway\",\n status: \"warn\",\n message: \"not running\",\n fix: \"Run: clank gateway start\",\n };\n }\n}\n\nasync function checkModels(): Promise<CheckResult> {\n const config = await loadConfig();\n const modelId = config.agents.defaults.model.primary;\n const provider = modelId.split(\"/\")[0];\n\n if (provider === \"ollama\") {\n const models = await OllamaProvider.detect(config.models.providers.ollama?.baseUrl);\n if (models) {\n return { name: \"Model (primary)\", status: \"ok\", message: `${modelId} — ${models.length} models available` };\n }\n return {\n name: \"Model (primary)\",\n status: \"error\",\n message: \"Ollama not reachable\",\n fix: \"Start Ollama: ollama serve\",\n };\n }\n\n if (provider === \"anthropic\") {\n if (config.models.providers.anthropic?.apiKey) {\n return { name: \"Model (primary)\", status: \"ok\", message: `${modelId} — key configured` };\n }\n return {\n name: \"Model (primary)\",\n status: \"error\",\n message: \"Anthropic API key not set\",\n fix: \"Run: clank setup --section model\",\n };\n }\n\n return { name: \"Model (primary)\", status: \"ok\", message: modelId };\n}\n\nasync function checkSessions(): Promise<CheckResult> {\n const sessDir = join(getConfigDir(), \"conversations\");\n if (!existsSync(sessDir)) {\n return { name: \"Sessions\", status: \"ok\", message: \"no sessions yet\" };\n }\n\n try {\n const files = await readdir(sessDir);\n const count = files.filter((f) => f.endsWith(\".json\") && f !== \"sessions.json\").length;\n return { name: \"Sessions\", status: \"ok\", message: `${count} session${count !== 1 ? \"s\" : \"\"}` };\n } catch {\n return { name: \"Sessions\", status: \"warn\", message: \"could not read sessions directory\" };\n }\n}\n\nasync function checkWorkspace(): Promise<CheckResult> {\n const wsDir = join(getConfigDir(), \"workspace\");\n if (!existsSync(wsDir)) {\n return {\n name: \"Workspace\",\n status: \"warn\",\n message: \"not created yet\",\n fix: \"Run: clank setup\",\n };\n }\n return { name: \"Workspace\", status: \"ok\", message: \"present\" };\n}\n","/**\n * CLI model management commands.\n */\n\nimport { loadConfig, saveConfig, ensureConfigDir } from \"../config/index.js\";\nimport { detectLocalServers } from \"../providers/index.js\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\n\nexport async function modelsList(): Promise<void> {\n const config = await loadConfig();\n console.log(\"\");\n console.log(` Default: ${config.agents.defaults.model.primary}`);\n if (config.agents.defaults.model.fallbacks?.length) {\n console.log(` Fallbacks: ${config.agents.defaults.model.fallbacks.join(\", \")}`);\n }\n console.log(\"\");\n console.log(dim(\" Configured providers:\"));\n for (const [name, cfg] of Object.entries(config.models.providers)) {\n const c = cfg as Record<string, unknown>;\n const status = c.apiKey ? green(\"key set\") : c.baseUrl ? green(\"configured\") : dim(\"not configured\");\n console.log(` ${name}: ${status}`);\n }\n\n console.log(\"\");\n console.log(dim(\" Detecting local servers...\"));\n const servers = await detectLocalServers();\n if (servers.length > 0) {\n for (const s of servers) {\n console.log(green(` ${s.provider} at ${s.baseUrl} — ${s.models.length} models`));\n for (const m of s.models.slice(0, 5)) {\n console.log(dim(` ${m}`));\n }\n if (s.models.length > 5) console.log(dim(` ... and ${s.models.length - 5} more`));\n }\n } else {\n console.log(dim(\" No local servers found\"));\n }\n console.log(\"\");\n}\n\nexport async function modelsAdd(): Promise<void> {\n const { createInterface } = await import(\"node:readline\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const ask = (q: string): Promise<string> => new Promise((r) => rl.question(q, r));\n\n try {\n await ensureConfigDir();\n const config = await loadConfig();\n\n console.log(\"\");\n console.log(\" Add a model provider:\");\n console.log(dim(\" 1. Anthropic (Claude)\"));\n console.log(dim(\" 2. OpenAI (GPT)\"));\n console.log(dim(\" 3. Google (Gemini)\"));\n console.log(dim(\" 4. Brave Search (web search)\"));\n console.log(\"\");\n\n const choice = await ask(cyan(\" Choice: \"));\n\n switch (choice) {\n case \"1\": {\n const key = await ask(cyan(\" Anthropic API key: \"));\n if (key.trim()) {\n config.models.providers.anthropic = { apiKey: key.trim() };\n await saveConfig(config);\n console.log(green(\" Anthropic added\"));\n }\n break;\n }\n case \"2\": {\n const key = await ask(cyan(\" OpenAI API key: \"));\n if (key.trim()) {\n config.models.providers.openai = { apiKey: key.trim() };\n await saveConfig(config);\n console.log(green(\" OpenAI added\"));\n }\n break;\n }\n case \"3\": {\n const key = await ask(cyan(\" Google AI API key: \"));\n if (key.trim()) {\n config.models.providers.google = { apiKey: key.trim() };\n await saveConfig(config);\n console.log(green(\" Google added\"));\n }\n break;\n }\n case \"4\": {\n const key = await ask(cyan(\" Brave Search API key: \"));\n if (key.trim()) {\n config.tools.webSearch = { enabled: true, provider: \"brave\", apiKey: key.trim() };\n await saveConfig(config);\n console.log(green(\" Brave Search added\"));\n }\n break;\n }\n default:\n console.log(dim(\" Cancelled\"));\n }\n console.log(\"\");\n } finally {\n rl.close();\n }\n}\n\nexport async function modelsTest(): Promise<void> {\n const config = await loadConfig();\n const modelId = config.agents.defaults.model.primary;\n console.log(\"\");\n console.log(dim(` Testing ${modelId}...`));\n\n try {\n const { resolveWithFallback } = await import(\"../providers/index.js\");\n const resolved = await resolveWithFallback(\n modelId,\n config.agents.defaults.model.fallbacks || [],\n config.models.providers,\n );\n console.log(green(` Connected to ${resolved.modelId} (${resolved.isLocal ? \"local\" : \"cloud\"})`));\n } catch (err) {\n console.log(` \\x1b[31mFailed: ${err instanceof Error ? err.message : err}\\x1b[0m`);\n }\n console.log(\"\");\n}\n","/**\n * CLI agent management commands.\n */\n\nimport { loadConfig, saveConfig, ensureConfigDir } from \"../config/index.js\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\n\nexport async function agentsList(): Promise<void> {\n const config = await loadConfig();\n console.log(\"\");\n console.log(dim(\" Default model: \") + config.agents.defaults.model.primary);\n console.log(dim(\" Default workspace: \") + config.agents.defaults.workspace);\n console.log(dim(\" Tool tier: \") + config.agents.defaults.toolTier);\n console.log(\"\");\n\n if (config.agents.list.length === 0) {\n console.log(dim(\" No custom agents configured. Using default agent.\"));\n console.log(dim(\" Add agents with: clank agents add\"));\n } else {\n console.log(\" Agents:\");\n for (const a of config.agents.list) {\n console.log(` ${a.id}: ${a.name || a.id}`);\n console.log(dim(` model: ${a.model?.primary || \"default\"}`));\n if (a.workspace) console.log(dim(` workspace: ${a.workspace}`));\n if (a.toolTier) console.log(dim(` tier: ${a.toolTier}`));\n }\n }\n console.log(\"\");\n}\n\nexport async function agentsAdd(): Promise<void> {\n const { createInterface } = await import(\"node:readline\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const ask = (q: string): Promise<string> => new Promise((r) => rl.question(q, r));\n\n try {\n await ensureConfigDir();\n const config = await loadConfig();\n\n console.log(\"\");\n const id = await ask(cyan(\" Agent ID (lowercase, no spaces): \"));\n if (!id.trim()) { console.log(dim(\" Cancelled\")); return; }\n\n const name = await ask(cyan(` Display name [${id.trim()}]: `));\n const model = await ask(cyan(\" Model [default]: \"));\n const workspace = await ask(cyan(\" Workspace [default]: \"));\n\n const entry: Record<string, unknown> = { id: id.trim() };\n if (name.trim()) entry.name = name.trim();\n if (model.trim()) entry.model = { primary: model.trim() };\n if (workspace.trim()) entry.workspace = workspace.trim();\n\n config.agents.list.push(entry as any);\n await saveConfig(config);\n console.log(green(` Agent ${id.trim()} added`));\n console.log(\"\");\n } finally {\n rl.close();\n }\n}\n\nexport async function agentsRouting(): Promise<void> {\n const config = await loadConfig();\n console.log(\"\");\n console.log(dim(\" Routing rules are configured in config.json5 or through conversation.\"));\n console.log(dim(\" Default: all messages go to the default agent.\"));\n console.log(\"\");\n\n if (config.agents.list.length > 0) {\n console.log(\" Configured agents:\");\n for (const a of config.agents.list) {\n console.log(` ${a.id} → model: ${a.model?.primary || \"default\"}`);\n }\n }\n\n if (config.channels?.telegram?.enabled) {\n const groups = config.channels.telegram.groups;\n if (groups && Object.keys(groups).length > 0) {\n console.log(\"\");\n console.log(\" Telegram group bindings:\");\n for (const [groupId, cfg] of Object.entries(groups)) {\n console.log(` ${groupId}: mention=${cfg.requireMention ?? true}`);\n }\n }\n }\n console.log(\"\");\n}\n","/**\n * Terminal UI (TUI) — rich interactive chat interface.\n *\n * Connects to the gateway via WebSocket (same protocol as Web UI).\n * Features: streaming, tool call cards, thinking blocks, agent/model/session\n * pickers, status bar, slash commands, shell integration.\n *\n * Keyboard shortcuts:\n * Enter — Send message\n * Esc — Abort current response\n * Ctrl+L — Model picker\n * Ctrl+G — Agent picker\n * Ctrl+P — Session picker\n * Ctrl+O — Toggle tool output\n * Ctrl+T — Toggle thinking visibility\n * Ctrl+C — Clear input (twice to exit)\n * Ctrl+D — Exit\n */\n\nimport { createInterface } from \"node:readline\";\nimport WebSocket from \"ws\";\nimport { loadConfig, getConfigDir } from \"../config/index.js\";\nimport { DEFAULT_PORT, type HelloFrame, type EventFrame, type ResponseFrame } from \"../gateway/protocol.js\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst bold = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst yellow = (s: string) => `\\x1b[33m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\nconst cyan = (s: string) => `\\x1b[36m${s}\\x1b[0m`;\nconst italic = (s: string) => `\\x1b[3m${s}\\x1b[0m`;\n\ninterface TuiState {\n ws: WebSocket | null;\n connected: boolean;\n agentId: string;\n agentName: string;\n modelId: string;\n sessionKey: string;\n agents: Array<{ id: string; name: string; model: string }>;\n sessions: Array<{ key: string; label?: string }>;\n streaming: boolean;\n showThinking: boolean;\n showToolOutput: boolean;\n reqId: number;\n ctrlCCount: number;\n}\n\nexport async function runTui(opts: {\n url?: string;\n token?: string;\n session?: string;\n}): Promise<void> {\n const config = await loadConfig();\n const port = config.gateway.port || DEFAULT_PORT;\n const wsUrl = opts.url || `ws://127.0.0.1:${port}`;\n const token = opts.token || config.gateway.auth.token || \"\";\n\n const state: TuiState = {\n ws: null,\n connected: false,\n agentId: \"default\",\n agentName: \"Clank\",\n modelId: config.agents.defaults.model.primary,\n sessionKey: opts.session || \"tui:main\",\n agents: [],\n sessions: [],\n streaming: false,\n showThinking: false,\n showToolOutput: true,\n reqId: 0,\n ctrlCCount: 0,\n };\n\n // Check if gateway is running, if not fall back to direct mode\n try {\n const health = await fetch(`http://127.0.0.1:${port}/health`, { signal: AbortSignal.timeout(2000) });\n if (!health.ok) throw new Error(\"not ok\");\n } catch {\n console.log(dim(\" Gateway not running. Starting direct mode...\"));\n console.log(dim(\" (Start gateway with: clank gateway start)\"));\n console.log(\"\");\n const { runChat } = await import(\"./chat.js\");\n await runChat({ direct: true });\n return;\n }\n\n console.log(\"\");\n console.log(bold(\" Clank TUI\") + dim(` | connecting to ${wsUrl}...`));\n\n // Connect to gateway\n const ws = new WebSocket(wsUrl);\n state.ws = ws;\n\n ws.on(\"open\", () => {\n // Send connect handshake\n ws.send(JSON.stringify({\n type: \"connect\",\n params: { auth: { token }, mode: \"tui\", version: \"1.3.1\" },\n }));\n });\n\n ws.on(\"message\", (data) => {\n const frame = JSON.parse(data.toString());\n handleFrame(state, frame);\n });\n\n ws.on(\"close\", () => {\n state.connected = false;\n console.log(red(\"\\n Disconnected from gateway.\"));\n process.exit(0);\n });\n\n ws.on(\"error\", (err) => {\n console.error(red(` Connection error: ${err.message}`));\n process.exit(1);\n });\n\n // Set up readline\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n\n // Wait for connection before prompting\n await new Promise<void>((resolve) => {\n const check = setInterval(() => {\n if (state.connected) { clearInterval(check); resolve(); }\n }, 100);\n setTimeout(() => { clearInterval(check); resolve(); }, 5000);\n });\n\n if (!state.connected) {\n console.log(red(\" Failed to connect to gateway.\"));\n process.exit(1);\n }\n\n // Print header\n printStatusBar(state);\n console.log(dim(\" Type your message. /help for commands. Ctrl+D to exit.\\n\"));\n\n rl.setPrompt(cyan(\"you > \"));\n rl.prompt();\n\n rl.on(\"line\", async (line) => {\n const input = line.trim();\n state.ctrlCCount = 0;\n\n if (!input) { rl.prompt(); return; }\n\n // Shell integration: ! prefix runs commands on host\n if (input.startsWith(\"!\")) {\n const cmd = input.slice(1).trim();\n if (cmd) {\n const { execSync } = await import(\"node:child_process\");\n try {\n const out = execSync(cmd, { encoding: \"utf-8\", timeout: 30000, env: { ...process.env, CLANK_SHELL: \"tui-local\" } });\n console.log(out);\n } catch (err: any) {\n console.log(red(err.stderr || err.message));\n }\n }\n rl.prompt();\n return;\n }\n\n // Slash commands\n if (input.startsWith(\"/\")) {\n await handleSlashCommand(state, input, rl);\n rl.prompt();\n return;\n }\n\n // Send message to agent\n console.log(\"\");\n state.streaming = true;\n state.reqId++;\n\n state.ws?.send(JSON.stringify({\n type: \"req\",\n id: state.reqId,\n method: \"chat.send\",\n params: { message: input, sessionKey: state.sessionKey, agent: state.agentId },\n }));\n\n // Wait for response to complete\n await new Promise<void>((resolve) => {\n const check = setInterval(() => {\n if (!state.streaming) { clearInterval(check); resolve(); }\n }, 100);\n });\n\n console.log(\"\");\n rl.prompt();\n });\n\n rl.on(\"close\", () => {\n ws.close();\n process.exit(0);\n });\n\n // Handle Ctrl+C\n process.on(\"SIGINT\", () => {\n if (state.streaming) {\n state.ws?.send(JSON.stringify({ type: \"req\", id: ++state.reqId, method: \"chat.abort\", params: {} }));\n state.streaming = false;\n console.log(dim(\"\\n (aborted)\"));\n rl.prompt();\n } else {\n state.ctrlCCount++;\n if (state.ctrlCCount >= 2) {\n ws.close();\n process.exit(0);\n }\n console.log(dim(\"\\n Press Ctrl+C again to exit, or Ctrl+D.\"));\n rl.prompt();\n }\n });\n}\n\nfunction handleFrame(state: TuiState, frame: any): void {\n // Hello response\n if (frame.type === \"hello\") {\n const hello = frame as HelloFrame;\n state.connected = true;\n state.agents = hello.agents || [];\n state.sessions = hello.sessions || [];\n if (state.agents.length > 0) {\n state.agentId = state.agents[0].id;\n state.agentName = state.agents[0].name;\n state.modelId = state.agents[0].model;\n }\n console.log(green(` Connected`) + dim(` | agent: ${state.agentName} | model: ${state.modelId}`));\n return;\n }\n\n // Events\n if (frame.type === \"event\") {\n const event = frame as EventFrame;\n switch (event.event) {\n case \"chat.stream\":\n case \"token\":\n process.stdout.write((event.payload as any).text || (event.payload as any).content || \"\");\n break;\n\n case \"chat.thinking\":\n case \"thinking\":\n if (state.showThinking) {\n process.stdout.write(dim(italic((event.payload as any).text || \"\")));\n }\n break;\n\n case \"chat.tool\":\n case \"tool-start\": {\n const p = event.payload as any;\n if (state.showToolOutput) {\n console.log(dim(`\\n [${p.name}] ${(p.args ? JSON.stringify(p.args) : \"\").slice(0, 80)}`));\n }\n break;\n }\n\n case \"tool-result\": {\n const p = event.payload as any;\n if (state.showToolOutput) {\n const icon = p.success ? green(\"ok\") : red(\"err\");\n console.log(dim(` [${p.name}] ${icon} ${(p.summary || \"\").slice(0, 80)}`));\n }\n break;\n }\n\n case \"chat.complete\":\n case \"response-end\":\n case \"turn-complete\":\n state.streaming = false;\n break;\n\n case \"chat.error\":\n case \"error\":\n console.log(red(`\\n Error: ${(event.payload as any).message || (event.payload as any).error || \"Unknown\"}`));\n state.streaming = false;\n break;\n\n case \"usage\": {\n const u = event.payload as any;\n console.log(dim(`\\n [${u.promptTokens}→${u.outputTokens} tokens | ctx ${u.contextPercent}%]`));\n break;\n }\n }\n return;\n }\n\n // Response frames\n if (frame.type === \"res\") {\n const res = frame as ResponseFrame;\n if (!res.ok && res.error) {\n console.log(red(`\\n Error: ${res.error}`));\n }\n state.streaming = false;\n }\n}\n\nasync function handleSlashCommand(state: TuiState, input: string, rl: any): Promise<void> {\n const [cmd, ...args] = input.slice(1).split(/\\s+/);\n\n switch (cmd) {\n case \"help\":\n console.log(dim(\" Commands:\"));\n console.log(dim(\" /help — This help\"));\n console.log(dim(\" /status — Gateway and agent status\"));\n console.log(dim(\" /agent [name] — Switch or list agents\"));\n console.log(dim(\" /session [key] — Switch or list sessions\"));\n console.log(dim(\" /model [id] — Show current model\"));\n console.log(dim(\" /think — Toggle thinking display\"));\n console.log(dim(\" /tools — Toggle tool output\"));\n console.log(dim(\" /new — Start new session\"));\n console.log(dim(\" /reset — Reset current session\"));\n console.log(dim(\" /exit — Exit\"));\n console.log(dim(\" !<command> — Run shell command\"));\n break;\n\n case \"status\":\n console.log(dim(` Agent: ${state.agentName} (${state.agentId})`));\n console.log(dim(` Model: ${state.modelId}`));\n console.log(dim(` Session: ${state.sessionKey}`));\n console.log(dim(` Connected: ${state.connected}`));\n break;\n\n case \"agent\":\n if (args[0]) {\n const agent = state.agents.find((a) => a.id === args[0] || a.name.toLowerCase() === args[0].toLowerCase());\n if (agent) {\n state.agentId = agent.id;\n state.agentName = agent.name;\n state.modelId = agent.model;\n state.sessionKey = `tui:${agent.id}:main`;\n console.log(green(` Switched to ${agent.name} (${agent.model})`));\n } else {\n console.log(red(` Agent not found: ${args[0]}`));\n }\n } else {\n console.log(dim(\" Agents:\"));\n for (const a of state.agents) {\n const active = a.id === state.agentId ? \" ←\" : \"\";\n console.log(dim(` ${a.id}: ${a.name} (${a.model})${active}`));\n }\n if (state.agents.length === 0) console.log(dim(\" (no custom agents)\"));\n }\n break;\n\n case \"session\":\n if (args[0]) {\n state.sessionKey = args[0];\n console.log(green(` Switched to session: ${args[0]}`));\n } else {\n console.log(dim(\" Sessions:\"));\n for (const s of state.sessions.slice(0, 20)) {\n const active = s.key === state.sessionKey ? \" ←\" : \"\";\n console.log(dim(` ${s.key}: ${s.label || \"(untitled)\"}${active}`));\n }\n if (state.sessions.length === 0) console.log(dim(\" (no sessions)\"));\n }\n break;\n\n case \"model\":\n console.log(dim(` Current model: ${state.modelId}`));\n break;\n\n case \"think\":\n state.showThinking = !state.showThinking;\n console.log(dim(` Thinking display: ${state.showThinking ? \"on\" : \"off\"}`));\n break;\n\n case \"tools\":\n state.showToolOutput = !state.showToolOutput;\n console.log(dim(` Tool output: ${state.showToolOutput ? \"on\" : \"off\"}`));\n break;\n\n case \"new\":\n state.sessionKey = `tui:${state.agentId}:${Date.now()}`;\n console.log(green(` New session: ${state.sessionKey}`));\n break;\n\n case \"reset\":\n state.ws?.send(JSON.stringify({\n type: \"req\", id: ++state.reqId, method: \"session.reset\",\n params: { sessionKey: state.sessionKey },\n }));\n console.log(green(\" Session reset\"));\n break;\n\n case \"exit\":\n case \"quit\":\n state.ws?.close();\n process.exit(0);\n\n default:\n console.log(dim(` Unknown command: /${cmd}. Type /help for commands.`));\n }\n}\n\nfunction printStatusBar(state: TuiState): void {\n console.log(dim(` ${state.agentName} | ${state.modelId} | ${state.sessionKey}`));\n}\n","/**\n * `clank update` — pull latest, rebuild, restart gateway.\n *\n * Updates the npm package to the latest version while preserving\n * all user config, sessions, memory, and workspace files.\n */\n\nimport { execSync } from \"node:child_process\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\n\nexport async function runUpdate(): Promise<void> {\n console.log(\"\");\n console.log(dim(\" Updating Clank...\"));\n\n // Step 1: Stop the gateway if running\n console.log(dim(\" Stopping gateway...\"));\n try {\n const { gatewayStop } = await import(\"./gateway-cmd.js\");\n await gatewayStop();\n } catch {\n // May not be running\n }\n\n // Step 2: Update the npm package\n console.log(dim(\" Pulling latest version...\"));\n try {\n const output = execSync(\"npm install -g @tractorscorch/clank@latest\", {\n encoding: \"utf-8\",\n timeout: 120_000,\n });\n console.log(dim(` ${output.trim()}`));\n } catch (err) {\n console.error(red(` Update failed: ${err instanceof Error ? err.message : err}`));\n console.error(dim(\" Try manually: npm install -g @tractorscorch/clank@latest\"));\n return;\n }\n\n // Step 3: Verify new version\n try {\n const newVersion = execSync(\"clank --version\", { encoding: \"utf-8\" }).trim();\n console.log(green(` Updated to v${newVersion}`));\n } catch {\n console.log(green(\" Package updated\"));\n }\n\n // Step 4: Restart gateway\n console.log(dim(\" Restarting gateway...\"));\n try {\n const { gatewayStartBackground } = await import(\"./gateway-cmd.js\");\n await gatewayStartBackground();\n console.log(green(\" Gateway restarted\"));\n } catch (err) {\n console.log(dim(\" Gateway not restarted. Start manually: clank gateway start\"));\n }\n\n console.log(\"\");\n console.log(green(\" Clank updated successfully.\"));\n console.log(dim(\" Config, sessions, and memory preserved.\"));\n console.log(\"\");\n}\n","/**\n * `clank uninstall` — remove everything.\n *\n * Stops the gateway, removes the daemon, deletes all data\n * (config, sessions, memory, workspace, logs, plugins, cron),\n * and unlinks the global npm package.\n */\n\nimport { createInterface } from \"node:readline\";\nimport { rm } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { getConfigDir } from \"../config/index.js\";\nimport { gatewayStop } from \"./gateway-cmd.js\";\n\nconst dim = (s: string) => `\\x1b[2m${s}\\x1b[0m`;\nconst bold = (s: string) => `\\x1b[1m${s}\\x1b[0m`;\nconst green = (s: string) => `\\x1b[32m${s}\\x1b[0m`;\nconst red = (s: string) => `\\x1b[31m${s}\\x1b[0m`;\nconst yellow = (s: string) => `\\x1b[33m${s}\\x1b[0m`;\n\nexport async function runUninstall(opts: { yes?: boolean }): Promise<void> {\n const configDir = getConfigDir();\n\n console.log(\"\");\n console.log(bold(\" Uninstall Clank\"));\n console.log(\"\");\n console.log(\" This will permanently remove:\");\n console.log(red(` ${configDir}`));\n console.log(dim(\" ├── config.json5 (configuration)\"));\n console.log(dim(\" ├── conversations/ (chat history)\"));\n console.log(dim(\" ├── memory/ (agent memory)\"));\n console.log(dim(\" ├── workspace/ (SOUL.md, USER.md, etc.)\"));\n console.log(dim(\" ├── logs/ (gateway logs)\"));\n console.log(dim(\" ├── cron/ (scheduled jobs)\"));\n console.log(dim(\" └── plugins/ (installed plugins)\"));\n console.log(\"\");\n\n if (!opts.yes) {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((resolve) => {\n rl.question(yellow(\" Are you sure? This cannot be undone. [y/N] \"), resolve);\n });\n rl.close();\n\n if (answer.trim().toLowerCase() !== \"y\") {\n console.log(dim(\" Uninstall cancelled.\"));\n return;\n }\n }\n\n // Step 1: Stop gateway\n console.log(dim(\" Stopping gateway...\"));\n try {\n await gatewayStop();\n } catch {\n // May not be running\n }\n\n // Step 2: Remove daemon/service\n console.log(dim(\" Removing system service...\"));\n try {\n const { uninstallDaemon } = await import(\"../daemon/index.js\");\n await uninstallDaemon();\n } catch {\n // May not be installed\n }\n\n // Step 3: Delete all data\n console.log(dim(\" Deleting data...\"));\n if (existsSync(configDir)) {\n await rm(configDir, { recursive: true, force: true });\n console.log(green(` Removed ${configDir}`));\n } else {\n console.log(dim(\" No data directory found.\"));\n }\n\n // Step 4: Unlink global package\n console.log(dim(\" Uninstalling npm package...\"));\n try {\n const { execSync } = await import(\"node:child_process\");\n execSync(\"npm uninstall -g @tractorscorch/clank\", { stdio: \"ignore\" });\n console.log(green(\" npm package uninstalled\"));\n } catch {\n console.log(dim(\" Could not uninstall npm package (may not be globally installed)\"));\n }\n\n console.log(\"\");\n console.log(green(\" Clank has been completely removed.\"));\n console.log(\"\");\n}\n","#!/usr/bin/env node\n\n/**\n * Clank — Local-first AI agent gateway\n *\n * Entry point for the `clank` CLI command.\n * Routes to subcommands: chat, gateway, setup, fix, models, agents, daemon.\n */\n\nimport { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Read version from package.json\nlet version = \"1.3.1\";\ntry {\n const pkg = JSON.parse(readFileSync(join(__dirname, \"..\", \"package.json\"), \"utf-8\"));\n version = pkg.version;\n} catch {\n // Use default version\n}\n\nconst program = new Command();\n\nprogram\n .name(\"clank\")\n .description(\"Local-first AI agent gateway\")\n .version(version, \"-v, --version\");\n\n// clank chat — interactive chat (connects to gateway or direct mode)\nprogram\n .command(\"chat\")\n .description(\"Start an interactive chat session\")\n .option(\"--web\", \"Open chat in browser\")\n .option(\"--new\", \"Start a fresh session\")\n .option(\"--continue\", \"Resume last session\")\n .option(\"--session <id>\", \"Resume a specific session\")\n .option(\"--direct\", \"Force direct mode (no gateway)\")\n .action(async (opts) => {\n const { runChat } = await import(\"./chat.js\");\n await runChat(opts);\n });\n\n// clank gateway — manage the gateway daemon\nconst gateway = program\n .command(\"gateway\")\n .description(\"Manage the gateway daemon\");\n\ngateway\n .command(\"start\")\n .description(\"Start the gateway daemon\")\n .option(\"-p, --port <port>\", \"Port to listen on\")\n .option(\"--foreground\", \"Run in foreground (don't daemonize)\")\n .action(async (opts) => {\n const { gatewayStart } = await import(\"./gateway-cmd.js\");\n await gatewayStart(opts);\n });\n\ngateway\n .command(\"stop\")\n .description(\"Stop the gateway daemon\")\n .action(async () => {\n const { gatewayStop } = await import(\"./gateway-cmd.js\");\n await gatewayStop();\n });\n\ngateway\n .command(\"status\")\n .description(\"Show gateway status\")\n .action(async () => {\n const { gatewayStatus } = await import(\"./gateway-cmd.js\");\n await gatewayStatus();\n });\n\ngateway\n .command(\"restart\")\n .description(\"Restart the gateway daemon\")\n .action(async () => {\n const { gatewayStop, gatewayStartBackground } = await import(\"./gateway-cmd.js\");\n await gatewayStop();\n await new Promise((r) => setTimeout(r, 1000));\n await gatewayStartBackground();\n });\n\n// clank setup — onboarding wizard\nprogram\n .command(\"setup\")\n .description(\"Run the onboarding wizard\")\n .option(\"--quick\", \"Quick Start with sensible defaults\")\n .option(\"--advanced\", \"Advanced setup with full control\")\n .option(\"--section <name>\", \"Reconfigure a specific section\")\n .option(\"--non-interactive\", \"Non-interactive mode for scripting\")\n .option(\"--accept-risk\", \"Accept security disclaimer\")\n .action(async (opts) => {\n const { runSetup } = await import(\"./setup.js\");\n await runSetup(opts);\n });\n\n// clank fix — diagnostics & repair\nprogram\n .command(\"fix\")\n .description(\"Run diagnostics and repair\")\n .option(\"--auto\", \"Attempt automatic repairs\")\n .option(\"--check <system>\", \"Check a specific system\")\n .action(async (opts) => {\n const { runFix } = await import(\"./fix.js\");\n await runFix(opts);\n });\n\n// clank models — model management\nconst models = program\n .command(\"models\")\n .description(\"Manage models and providers\");\n\nmodels\n .command(\"list\")\n .description(\"List available models\")\n .action(async () => {\n const { modelsList } = await import(\"./models.js\");\n await modelsList();\n });\n\nmodels\n .command(\"add\")\n .description(\"Add a model provider\")\n .action(async () => {\n const { modelsAdd } = await import(\"./models.js\");\n await modelsAdd();\n });\n\nmodels\n .command(\"test\")\n .description(\"Test model connectivity\")\n .action(async () => {\n const { modelsTest } = await import(\"./models.js\");\n await modelsTest();\n });\n\n// clank agents — agent management\nconst agents = program\n .command(\"agents\")\n .description(\"Manage agents and routing\");\n\nagents\n .command(\"list\")\n .description(\"List configured agents\")\n .action(async () => {\n const { agentsList } = await import(\"./agents.js\");\n await agentsList();\n });\n\nagents\n .command(\"add\")\n .description(\"Add a new agent\")\n .action(async () => {\n const { agentsAdd } = await import(\"./agents.js\");\n await agentsAdd();\n });\n\nagents\n .command(\"routing\")\n .description(\"Show routing rules\")\n .action(async () => {\n const { agentsRouting } = await import(\"./agents.js\");\n await agentsRouting();\n });\n\n// clank daemon — system service management\nconst daemon = program\n .command(\"daemon\")\n .description(\"Manage the system service\");\n\ndaemon\n .command(\"install\")\n .description(\"Install Clank as a system service\")\n .action(async () => {\n const { installDaemon } = await import(\"../daemon/index.js\");\n await installDaemon();\n });\n\ndaemon\n .command(\"uninstall\")\n .description(\"Remove the system service\")\n .action(async () => {\n const { uninstallDaemon } = await import(\"../daemon/index.js\");\n await uninstallDaemon();\n });\n\ndaemon\n .command(\"status\")\n .description(\"Show system service status\")\n .action(async () => {\n const { daemonStatus } = await import(\"../daemon/index.js\");\n await daemonStatus();\n });\n\n// clank tui — launch TUI (connects to gateway)\nprogram\n .command(\"tui\")\n .description(\"Launch the terminal UI (connects to gateway)\")\n .option(\"--url <url>\", \"Gateway WebSocket URL\")\n .option(\"--token <token>\", \"Auth token\")\n .option(\"--session <key>\", \"Session to resume\")\n .action(async (opts) => {\n const { runTui } = await import(\"./tui.js\");\n await runTui(opts);\n });\n\n// clank dashboard — open Web UI in browser\nprogram\n .command(\"dashboard\")\n .description(\"Open the Web UI in your browser\")\n .option(\"--no-open\", \"Don't auto-open browser\")\n .action(async (opts) => {\n const { loadConfig } = await import(\"../config/index.js\");\n const config = await loadConfig();\n const port = config.gateway.port || 18789;\n const token = config.gateway.auth.token || \"\";\n const url = `http://127.0.0.1:${port}/#token=${token}`;\n console.log(`\\n Web UI: ${url}\\n`);\n if (opts.open !== false) {\n const { platform } = await import(\"node:os\");\n const { exec } = await import(\"node:child_process\");\n const cmd = platform() === \"win32\" ? `start ${url}` : platform() === \"darwin\" ? `open ${url}` : `xdg-open ${url}`;\n exec(cmd);\n }\n });\n\n// clank pipeline — manage pipelines\nconst pipeline = program\n .command(\"pipeline\")\n .description(\"Manage agent pipelines\");\n\npipeline\n .command(\"list\")\n .description(\"List pipeline definitions\")\n .action(async () => {\n console.log(\" No pipelines configured. Define pipelines in config or through conversation.\");\n });\n\npipeline\n .command(\"run <name>\")\n .description(\"Run a pipeline\")\n .option(\"--input <text>\", \"Input text for the pipeline\")\n .action(async (name, opts) => {\n console.log(` Running pipeline: ${name}...`);\n console.log(\" Pipeline CLI execution coming soon. Use the Web UI or conversation.\");\n });\n\npipeline\n .command(\"status <id>\")\n .description(\"Check pipeline execution status\")\n .action(async (id) => {\n console.log(` Pipeline ${id}: status check coming soon.`);\n });\n\n// clank cron — manage cron jobs\nconst cron = program\n .command(\"cron\")\n .description(\"Manage scheduled jobs\");\n\ncron\n .command(\"list\")\n .description(\"List cron jobs\")\n .action(async () => {\n const { join } = await import(\"node:path\");\n const { getConfigDir } = await import(\"../config/index.js\");\n const { CronScheduler } = await import(\"../cron/index.js\");\n const scheduler = new CronScheduler(join(getConfigDir(), \"cron\"));\n await scheduler.init();\n const jobs = scheduler.listJobs();\n if (jobs.length === 0) { console.log(\" No cron jobs.\"); return; }\n for (const j of jobs) {\n console.log(` ${j.id.slice(0,8)} | ${j.name} | ${j.schedule} | ${j.enabled ? \"enabled\" : \"disabled\"} | agent: ${j.agentId}`);\n }\n });\n\ncron\n .command(\"add\")\n .description(\"Add a cron job\")\n .requiredOption(\"--schedule <expr>\", \"Schedule (e.g., '1h', '30m', 'daily')\")\n .requiredOption(\"--prompt <text>\", \"What the agent should do\")\n .option(\"--name <name>\", \"Job name\")\n .option(\"--agent <id>\", \"Agent ID\", \"default\")\n .action(async (opts) => {\n const { join } = await import(\"node:path\");\n const { getConfigDir } = await import(\"../config/index.js\");\n const { CronScheduler } = await import(\"../cron/index.js\");\n const scheduler = new CronScheduler(join(getConfigDir(), \"cron\"));\n await scheduler.init();\n const job = await scheduler.addJob({\n name: opts.name || \"CLI Job\",\n schedule: opts.schedule,\n agentId: opts.agent,\n prompt: opts.prompt,\n });\n console.log(` Job created: ${job.id.slice(0,8)} — \"${job.name}\" every ${job.schedule}`);\n });\n\ncron\n .command(\"remove <id>\")\n .description(\"Remove a cron job\")\n .action(async (id) => {\n const { join } = await import(\"node:path\");\n const { getConfigDir } = await import(\"../config/index.js\");\n const { CronScheduler } = await import(\"../cron/index.js\");\n const scheduler = new CronScheduler(join(getConfigDir(), \"cron\"));\n await scheduler.init();\n const removed = await scheduler.removeJob(id);\n console.log(removed ? ` Job ${id.slice(0,8)} removed` : ` Job not found`);\n });\n\n// clank channels — channel status\nprogram\n .command(\"channels\")\n .description(\"Show channel adapter status\")\n .action(async () => {\n const { loadConfig } = await import(\"../config/index.js\");\n const config = await loadConfig();\n const channels = config.channels || {};\n console.log(\" Channels:\");\n for (const [name, cfg] of Object.entries(channels)) {\n const c = cfg as Record<string, unknown>;\n console.log(` ${name}: ${c.enabled ? \"\\x1b[32menabled\\x1b[0m\" : \"\\x1b[2mdisabled\\x1b[0m\"}`);\n }\n if (Object.keys(channels).length === 0) console.log(\" (none configured)\");\n });\n\n// clank update — pull latest, rebuild, restart\nprogram\n .command(\"update\")\n .description(\"Update Clank to the latest version and restart gateway\")\n .action(async () => {\n const { runUpdate } = await import(\"./update.js\");\n await runUpdate();\n });\n\n// clank uninstall — remove everything\nprogram\n .command(\"uninstall\")\n .description(\"Remove Clank completely (config, data, service, package)\")\n .option(\"-y, --yes\", \"Skip confirmation prompt\")\n .action(async (opts) => {\n const { runUninstall } = await import(\"./uninstall.js\");\n await runUninstall(opts);\n });\n\n// Default: if no subcommand, ensure gateway is running then launch TUI\nprogram.action(async () => {\n const { gatewayStartBackground, isGatewayRunning } = await import(\"./gateway-cmd.js\");\n\n // Ensure gateway is running in the background (Telegram/Discord stay alive)\n if (!(await isGatewayRunning())) {\n await gatewayStartBackground();\n }\n\n // Launch TUI connected to the gateway\n const { runTui } = await import(\"./tui.js\");\n await runTui({});\n});\n\nprogram.parse();\n"],"mappings":"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","names":["resolve","mkdir","init_types","init_types","readFile","isAbsolute","readFile","writeFile","isAbsolute","stat","join","readdir","readFile","stat","join","relative","readdir","stat","join","IGNORE_DIRS","resolve","isAbsolute","platform","execFile","resolve","isAbsolute","readFile","writeFile","mkdir","existsSync","join","platform","EventEmitter","init_config","loadConfig","text","init_config","init_config","init_config","agents","last","CONTEXT_WINDOWS","CONTEXT_WINDOWS","models","init_config","readFile","writeFile","mkdir","existsSync","join","path","join","init_config","readFile","mkdir","writeFile","existsSync","join","randomUUID","join","init_config","init_config","writeFile","unlink","execSync","join","init_config","writeFile","join","readFile","existsSync","init_types","join","fork","fileURLToPath","dirname","__filename","platform","exec","resolve","rl","init_config","readFile","writeFile","readdir","mkdir","existsSync","join","randomUUID","path","init_memory","agents","gateway","STTEngine","loadConfig","TTSEngine","agents","gateway","gateway","readdir","readFile","existsSync","join","homedir","readFile","join","dirname","fileURLToPath","init_memory","init_config","randomBytes","resolve","__dirname","redactConfig","loadConfig","saveConfig","writeFile","readFile","unlink","existsSync","join","dirname","fileURLToPath","green","dim","red","__filename","mkdir","init_config","writeFile","mkdir","unlink","join","homedir","platform","red","green","dim","createInterface","dirname","join","fileURLToPath","resolve","bold","cyan","dim","green","yellow","ensureWorkspaceFiles","__dirname","init_config","existsSync","readdir","join","dim","green","yellow","models","red","init_config","dim","green","createInterface","ask","cyan","resolveWithFallback","init_config","dim","createInterface","ask","cyan","green","init_config","createInterface","WebSocket","dim","runChat","bold","red","resolve","check","cyan","execSync","handleSlashCommand","green","init_config","execSync","dim","gatewayStop","red","green","gatewayStartBackground","createInterface","existsSync","bold","red","dim","resolve","yellow","uninstallDaemon","green","execSync","init_config","fileURLToPath","dirname","join","__filename","__dirname","runChat","gatewayStart","gatewayStop","gatewayStatus","gatewayStartBackground","runSetup","runFix","modelsList","modelsAdd","modelsTest","agentsList","agentsAdd","agentsRouting","installDaemon","uninstallDaemon","daemonStatus","runTui","loadConfig","platform","exec","getConfigDir","CronScheduler","runUpdate","runUninstall","isGatewayRunning"]}