@appchy/jarvis 0.1.4 → 0.1.6

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/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/bin.ts","../src/cli.ts","../src/config.ts","../../../providers/anthropic/src/anthropic.provider.ts","../../../providers/anthropic/src/anthropic.models.ts","../../../packages/logger/src/logger.ts","../../../packages/types/src/agents/llm.types.ts","../../../packages/types/src/agents/tool.types.ts","../../../packages/types/src/media/tts.types.ts","../../../providers/anthropic/src/claude-code.provider.ts","../../../packages/sdk/src/agents/tools/tools.ts","../../../packages/sdk/src/agents/tools/plan.tool.ts","../../../packages/sdk/src/agents/tools/ask-user.tool.ts","../../../packages/sdk/src/agents/tools/think.tool.ts","../../../packages/sdk/src/agents/tools/plan-mode.tool.ts","../../../packages/sdk/src/agents/tools/agent.tools.ts","../../../packages/sdk/src/agents/skills/skills.ts","../../../packages/sdk/src/agents/prompts/mustache.ts","../../../packages/sdk/src/agents/references/reference.ts","../../../packages/sdk/src/data/tables.ts","../../../packages/sdk/src/data/connectors.ts","../../../packages/agent/src/tools/edit.tool.ts","../../../packages/agent/src/tools/bash.tool.ts","../../../packages/agent/src/tools/write.tool.ts","../../../packages/agent/src/tools/read.tool.ts","../../../packages/agent/src/tools/glob.tool.ts","../../../packages/agent/src/tools/grep.tool.ts","../../../packages/agent/src/tools/index.ts","../../../packages/agent/src/format.ts","../../../packages/agent/src/worktree.ts","../src/progress.ts","../src/agent.ts","../src/git.ts","../src/server.ts","../src/upstream.ts","../src/start.ts","../src/tui/chat.ts","../src/tui/settings.ts","../src/tui/app.tsx","../src/tui/hooks/use-agent-client.ts","../src/tui/hooks/use-messages.ts","../src/tui/hooks/use-task.ts","../src/tui/hooks/use-settings.ts","../src/tui/utils/slash-commands.ts","../src/tui/utils/auto-approve.ts","../src/tui/components/welcome-header.tsx","../src/tui/theme.ts","../src/tui/components/user-message.tsx","../src/tui/components/spinner.tsx","../src/tui/components/divider.tsx","../src/tui/hooks/use-terminal.ts","../src/tui/components/prompt-input.tsx","../src/tui/components/suggestions.tsx","../src/tui/components/file-picker.tsx","../src/tui/components/status-bar.tsx","../src/tui/utils/format-tokens.ts","../src/tui/components/permission-dialog.tsx","../src/tui/components/plan-review.tsx","../src/tui/components/max-iterations.tsx","../src/tui/components/help-menu.tsx","../src/tui/components/status-display.tsx","../src/tui/components/model-picker.tsx","../src/tui/components/mode-picker.tsx","../src/tui/components/thinking-picker.tsx","../src/tui/components/settings-dialog.tsx","../src/tui/components/notification.tsx","../src/tui/components/markdown-text.tsx"],"sourcesContent":["import dotenv from \"dotenv\";\nimport fs from \"fs\";\nimport path from \"path\";\n\nfunction findEnv(): string | undefined {\n let dir = process.cwd();\n while (dir !== path.dirname(dir)) {\n const envPath = path.join(dir, \".env\");\n if (fs.existsSync(envPath)) return envPath;\n dir = path.dirname(dir);\n }\n return undefined;\n}\ndotenv.config({ path: findEnv() });\n\nimport { createCli } from \"./cli\";\n\ncreateCli().parse();\n","/**\n * Agent CLI\n *\n * Commands:\n * connect <token> — Save cloud connection config from base64 token\n * start — Start the agent (local WS server + optional upstream)\n * status — Show current config and connection status\n * logout — Clear saved config\n */\n\nimport { Command } from \"commander\";\n\nimport { loadConfig, saveConfig, clearConfig, parseConnectToken, getConfigPath } from \"./config\";\nimport { startAgent } from \"./start\";\nimport { isPortInUse } from \"./server\";\nimport { launchChat, type ChatOptions } from \"./tui/chat\";\n\nexport function createCli(): Command {\n const program = new Command()\n .name(\"jarvis\")\n .description(\"Jarvis local agent — runs Claude Code on your machine\")\n .version(\"0.0.0\");\n\n // ---------------------------------------------------------------------------\n // connect <token>\n // ---------------------------------------------------------------------------\n\n program\n .command(\"connect <token>\")\n .description(\"Connect to Jarvis cloud using a token from the web UI\")\n .option(\"-w, --workspace <path>\", \"Workspace root path for repo operations\")\n .action((token: string, opts: { workspace?: string }) => {\n try {\n const parsed = parseConnectToken(token);\n const existing = loadConfig();\n\n saveConfig({\n ...existing,\n apiUrl: parsed.apiUrl,\n token: parsed.jwt,\n userId: parsed.userId,\n envId: parsed.envId,\n ...(opts.workspace ? { workspacePath: opts.workspace } : {}),\n connectedAt: new Date().toISOString(),\n });\n\n console.log(`Connected to Jarvis cloud`);\n console.log(` User: ${parsed.userId}`);\n console.log(` Env: ${parsed.envId}`);\n console.log(` API: ${parsed.apiUrl}`);\n console.log(` Config: ${getConfigPath()}`);\n console.log();\n console.log(`Run 'jarvis start' to begin.`);\n } catch (err) {\n console.error(`Error: ${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n });\n\n // ---------------------------------------------------------------------------\n // start\n // ---------------------------------------------------------------------------\n\n program\n .command(\"start\")\n .description(\"Start the local agent\")\n .option(\"-p, --port <port>\", \"Local WS server port\", \"7862\")\n .option(\"-w, --workspace <path>\", \"Workspace root path\")\n .option(\"--api-key <key>\", \"Anthropic API key (for local-only use)\")\n .option(\"--no-upstream\", \"Don't connect to cloud (local-only mode)\")\n .action(async (opts: { port: string; workspace?: string; apiKey?: string; upstream: boolean }) => {\n const config = loadConfig();\n const port = parseInt(opts.port, 10);\n\n // Check if agent is already running on this port\n const alreadyRunning = await isPortInUse(port);\n if (alreadyRunning) {\n console.log(`\\nJarvis agent is already running on ws://127.0.0.1:${port}`);\n console.log(`Clients (jarvis chat, VSCode) can connect to it.\\n`);\n return;\n }\n\n const workspacePath = opts.workspace ?? config?.workspacePath ?? process.cwd();\n const anthropicApiKey = opts.apiKey ?? config?.anthropicApiKey ?? process.env.ANTHROPIC_API_KEY;\n const userId = config?.userId ?? process.env.JARVIS_USER_ID ?? \"local\";\n\n if (!anthropicApiKey && !config?.useSubscription) {\n console.warn(\"Warning: No Anthropic API key set. Using subscription mode.\");\n }\n\n await startAgent({\n port,\n workspacePath,\n anthropicApiKey,\n useSubscription: !anthropicApiKey,\n userId,\n upstream:\n opts.upstream && config?.apiUrl && config?.token\n ? { apiUrl: config.apiUrl, token: config.token }\n : undefined,\n });\n });\n\n // ---------------------------------------------------------------------------\n // chat\n // ---------------------------------------------------------------------------\n\n program\n .command(\"chat\")\n .description(\"Interactive TUI — chat with Jarvis in your terminal\")\n .option(\"--model <id>\", \"Model (e.g., claude-opus-4-20250514)\")\n .option(\"--mode <mode>\", \"Permission mode: supervised|auto|plan|yolo\")\n .option(\"--thinking <config>\", \"Thinking: adaptive|enabled|disabled\")\n .option(\"--thinking-budget <n>\", \"Token budget when thinking=enabled\")\n .option(\"--max-turns <n>\", \"Max turns per task\")\n .option(\"-p, --port <port>\", \"Agent server port\", \"7862\")\n .option(\"-w, --workspace <path>\", \"Workspace root path\")\n .option(\"--no-server\", \"Connect to existing server, don't auto-start\")\n .action(async (opts: ChatOptions) => {\n await launchChat(opts);\n });\n\n // ---------------------------------------------------------------------------\n // status\n // ---------------------------------------------------------------------------\n\n program\n .command(\"status\")\n .description(\"Show agent configuration and connection status\")\n .action(() => {\n const config = loadConfig();\n if (!config) {\n console.log(\"No configuration found.\");\n console.log(`Run 'jarvis connect <token>' to set up.`);\n return;\n }\n\n console.log(\"Jarvis Agent Config:\");\n console.log(` Config: ${getConfigPath()}`);\n console.log(` User: ${config.userId}`);\n console.log(` Env: ${config.envId ?? \"local\"}`);\n console.log(` Workspace: ${config.workspacePath ?? \"(cwd)\"}`);\n console.log(` Port: ${config.port ?? 7862}`);\n console.log(` Cloud: ${config.apiUrl ?? \"(not connected)\"}`);\n if (config.connectedAt) {\n console.log(` Connected: ${config.connectedAt}`);\n }\n });\n\n // ---------------------------------------------------------------------------\n // logout\n // ---------------------------------------------------------------------------\n\n program\n .command(\"logout\")\n .description(\"Clear saved configuration\")\n .action(() => {\n clearConfig();\n console.log(\"Configuration cleared.\");\n });\n\n return program;\n}\n","/**\n * Agent Config\n *\n * Manages ~/.jarvis/config.json — saved by `jarvis connect <token>`,\n * read on `jarvis start`.\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface AgentConfig {\n /** Cloud WS API URL (from connect token) */\n apiUrl?: string;\n /** JWT auth token (from connect token) */\n token?: string;\n /** User ID */\n userId: string;\n /** Environment ID */\n envId?: string;\n /** Workspace root path for repo operations */\n workspacePath?: string;\n /** Anthropic API key (for local-only use without cloud) */\n anthropicApiKey?: string;\n /** Use Anthropic subscription instead of API key */\n useSubscription?: boolean;\n /** Local WS server port */\n port?: number;\n /** When the config was last updated */\n connectedAt?: string;\n}\n\nexport interface ConnectToken {\n apiUrl: string;\n jwt: string;\n userId: string;\n envId: string;\n}\n\n// =============================================================================\n// Paths\n// =============================================================================\n\nconst CONFIG_DIR = path.join(os.homedir(), \".jarvis\");\nconst CONFIG_FILE = path.join(CONFIG_DIR, \"config.json\");\n\n// =============================================================================\n// Operations\n// =============================================================================\n\nexport function loadConfig(): AgentConfig | null {\n try {\n const raw = fs.readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(raw) as AgentConfig;\n } catch {\n return null;\n }\n}\n\nexport function saveConfig(config: AgentConfig): void {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + \"\\n\");\n}\n\nexport function clearConfig(): void {\n try {\n fs.unlinkSync(CONFIG_FILE);\n } catch {}\n}\n\nexport function parseConnectToken(token: string): ConnectToken {\n try {\n const decoded = Buffer.from(token, \"base64\").toString(\"utf-8\");\n const parsed = JSON.parse(decoded);\n if (!parsed.apiUrl || !parsed.jwt || !parsed.userId) {\n throw new Error(\"Invalid token: missing required fields (apiUrl, jwt, userId)\");\n }\n return parsed as ConnectToken;\n } catch (err) {\n if (err instanceof SyntaxError) {\n throw new Error(\"Invalid token: not valid base64-encoded JSON\");\n }\n throw err;\n }\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n","/**\n * Anthropic provider implementation\n * Provides LLM capabilities (query, stream) using the Anthropic Messages API\n *\n * Ported from @gluoe/anthropic with @jarvis/* imports\n */\n\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport type { MessageParam } from \"@anthropic-ai/sdk/resources/messages\";\n\nimport { anthropicModels } from \"./anthropic.models\";\nimport type {\n Context,\n QueryLLMRequest,\n QueryLLMResponse,\n LLMProvider,\n LLMQueryOptions,\n Model,\n Message,\n MultimodalMessage,\n ContentPart,\n TextContentPart,\n ImageContentPart,\n} from \"@jarvis/types\";\n\nexport interface Config {\n apiKey?: string;\n baseURL?: string;\n}\n\nexport type AnthropicProvider = LLMProvider;\n\nexport function provider(config?: Config): AnthropicProvider {\n const finalConfig = {\n apiKey: config?.apiKey ?? process.env.ANTHROPIC_API_KEY,\n baseURL: config?.baseURL ?? process.env.ANTHROPIC_BASE_URL,\n };\n\n if (!finalConfig.apiKey) {\n throw new Error(\n \"Anthropic API key is required. Provide it via config.apiKey or ANTHROPIC_API_KEY environment variable\",\n );\n }\n\n const client = new Anthropic({\n apiKey: finalConfig.apiKey,\n baseURL: finalConfig.baseURL,\n });\n\n // =========================================================================\n // LLM METHODS\n // =========================================================================\n\n async function query(\n _ctx: Context,\n request: QueryLLMRequest,\n _options?: LLMQueryOptions,\n ): Promise<QueryLLMResponse> {\n try {\n const startTime = Date.now();\n const systemMessage = request.messages.find((m) => m.role === \"system\");\n\n const options = {\n max_tokens: request.options?.maxTokens ?? 4096,\n temperature: request.options?.temperature,\n top_p: request.options?.topP,\n };\n\n // Check if webSearch tool is present and convert to native web search\n const hasWebSearch = request.tools?.some((t) => t.name === \"webSearch\");\n const otherTools =\n request.tools?.filter((t) => t.name !== \"webSearch\") || [];\n\n // If structured output is requested, use tool calling approach\n const tools = request.output?.schema\n ? [\n {\n name: \"structured_output\",\n description: \"Respond with a structured JSON object\",\n input_schema: request.output.schema,\n },\n ...(hasWebSearch\n ? [\n {\n type: \"web_search_20250305\" as const,\n name: \"web_search\",\n max_uses: 5,\n },\n ]\n : []),\n ...(otherTools.length > 0 ? convertTools(otherTools) : []),\n ]\n : hasWebSearch\n ? [\n {\n type: \"web_search_20250305\" as const,\n name: \"web_search\",\n max_uses: 5,\n },\n ...(otherTools.length > 0 ? convertTools(otherTools) : []),\n ]\n : otherTools.length > 0\n ? convertTools(otherTools)\n : undefined;\n\n const tool_choice = request.output?.schema\n ? {\n type: \"tool\" as const,\n name: \"structured_output\",\n disable_parallel_tool_use: true,\n }\n : undefined;\n\n // Map ThinkingConfig to Anthropic thinking parameter\n const thinking_param = request.thinking?.type === \"disabled\"\n ? undefined\n : request.thinking?.type === \"enabled\" && request.thinking.budgetTokens\n ? { type: \"enabled\" as const, budget_tokens: request.thinking.budgetTokens }\n : request.thinking?.type === \"adaptive\"\n ? { type: \"enabled\" as const, budget_tokens: options.max_tokens - 1 }\n : undefined;\n\n const response = await client.messages.create({\n model: request.model,\n max_tokens: options.max_tokens,\n temperature: options.temperature,\n top_p: options.top_p,\n system: systemMessage?.content,\n messages: convertMessages(request.messages),\n tools,\n tool_choice,\n ...(thinking_param && { thinking: thinking_param }),\n } as any); // Type assertion needed for web_search_20250305\n\n const duration = Date.now() - startTime;\n\n let content = \"\";\n let thinking = \"\";\n let toolCalls: any[] | undefined;\n\n // Handle multiple content blocks\n for (const block of response.content) {\n if (block.type === \"text\") {\n content += block.text;\n } else if ((block as any).type === \"thinking\") {\n thinking += (block as any).thinking ?? \"\";\n } else if (block.type === \"tool_use\") {\n // If this is the structured output tool, extract content from it\n if (block.name === \"structured_output\" && request.output?.schema) {\n content = JSON.stringify(block.input || {});\n } else {\n // Regular tool call\n if (!toolCalls) toolCalls = [];\n toolCalls.push({\n id: block.id,\n name: block.name,\n args: JSON.stringify(block.input || {}),\n status: \"pending\" as const,\n });\n }\n }\n }\n\n return {\n content,\n thinking: thinking || undefined,\n toolCalls,\n metadata: {\n usage: {\n inputTokens: response.usage?.input_tokens || 0,\n outputTokens: response.usage?.output_tokens || 0,\n totalTokens:\n (response.usage?.input_tokens || 0) +\n (response.usage?.output_tokens || 0),\n cachedTokens: (response.usage as any)?.cache_read_input_tokens || 0,\n },\n model: request.model,\n options,\n duration,\n provider: \"anthropic\",\n },\n };\n } catch (error) {\n throw new Error(\n `Anthropic API error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n async function* stream(\n _ctx: Context,\n request: QueryLLMRequest,\n _options?: LLMQueryOptions,\n ): AsyncGenerator<QueryLLMResponse> {\n try {\n const options = {\n max_tokens: request.options?.maxTokens ?? 4096,\n temperature: request.options?.temperature,\n top_p: request.options?.topP,\n };\n\n const startTime = Date.now();\n\n const systemMessage = request.messages.find((m) => m.role === \"system\");\n\n // Check if webSearch tool is present and convert to native web search\n const hasWebSearch = request.tools?.some((t) => t.name === \"webSearch\");\n const otherTools =\n request.tools?.filter((t) => t.name !== \"webSearch\") || [];\n\n // If structured output is requested, use tool calling approach\n const tools = request.output?.schema\n ? [\n {\n name: \"structured_output\",\n description: \"Respond with a structured JSON object\",\n input_schema: request.output.schema,\n },\n ...(hasWebSearch\n ? [\n {\n type: \"web_search_20250305\" as const,\n name: \"web_search\",\n max_uses: 5,\n },\n ]\n : []),\n ...(otherTools.length > 0 ? convertTools(otherTools) : []),\n ]\n : hasWebSearch\n ? [\n {\n type: \"web_search_20250305\" as const,\n name: \"web_search\",\n max_uses: 5,\n },\n ...(otherTools.length > 0 ? convertTools(otherTools) : []),\n ]\n : otherTools.length > 0\n ? convertTools(otherTools)\n : undefined;\n\n const tool_choice = request.output?.schema\n ? {\n type: \"tool\" as const,\n name: \"structured_output\",\n disable_parallel_tool_use: true,\n }\n : undefined;\n\n // Map ThinkingConfig to Anthropic thinking parameter\n const thinking_param = request.thinking?.type === \"disabled\"\n ? undefined\n : request.thinking?.type === \"enabled\" && request.thinking.budgetTokens\n ? { type: \"enabled\" as const, budget_tokens: request.thinking.budgetTokens }\n : request.thinking?.type === \"adaptive\"\n ? { type: \"enabled\" as const, budget_tokens: options.max_tokens - 1 }\n : undefined;\n\n const streamResponse = client.messages.stream({\n model: request.model,\n max_tokens: options.max_tokens,\n temperature: options.temperature,\n top_p: options.top_p,\n system: systemMessage?.content,\n messages: convertMessages(request.messages),\n tools: tools as any, // Type assertion needed for web_search_20250305\n tool_choice,\n ...(thinking_param && { thinking: thinking_param }),\n });\n\n let usage = {\n input_tokens: 0,\n output_tokens: 0,\n };\n const toolCalls: any[] = [];\n let currentToolUse: {\n id: string;\n name: string;\n inputJson: string;\n } | null = null;\n\n for await (const chunk of streamResponse) {\n // Update usage from message_delta events\n if (chunk.type === \"message_delta\" && (chunk as any).usage) {\n usage = (chunk as any).usage;\n }\n\n // Track content block starts (tool_use)\n if (\n chunk.type === \"content_block_start\" &&\n (chunk as any).content_block?.type === \"tool_use\"\n ) {\n const block = (chunk as any).content_block;\n currentToolUse = {\n id: block.id,\n name: block.name,\n inputJson: \"\",\n };\n }\n\n // Handle content block deltas\n if (chunk.type === \"content_block_delta\") {\n const deltaType = (chunk.delta as any)?.type;\n\n if (deltaType === \"text_delta\") {\n // Yield text chunks\n yield {\n content: (chunk.delta as any).text || \"\",\n metadata: {\n usage: {\n inputTokens: usage.input_tokens || 0,\n outputTokens: usage.output_tokens || 0,\n totalTokens:\n (usage.input_tokens || 0) + (usage.output_tokens || 0),\n },\n model: request.model,\n options,\n duration: Date.now() - startTime,\n provider: \"anthropic\",\n },\n };\n } else if (deltaType === \"thinking_delta\") {\n // Yield thinking chunks\n yield {\n content: \"\",\n thinking: (chunk.delta as any).thinking || \"\",\n metadata: {\n usage: {\n inputTokens: usage.input_tokens || 0,\n outputTokens: usage.output_tokens || 0,\n totalTokens:\n (usage.input_tokens || 0) + (usage.output_tokens || 0),\n },\n model: request.model,\n options,\n duration: Date.now() - startTime,\n provider: \"anthropic\",\n },\n };\n } else if (deltaType === \"input_json_delta\" && currentToolUse) {\n currentToolUse.inputJson += (chunk.delta as any).partial_json || \"\";\n }\n // signature_delta — ignored\n }\n\n // Finalize tool call on content_block_stop\n if (chunk.type === \"content_block_stop\" && currentToolUse) {\n toolCalls.push({\n id: currentToolUse.id,\n name: currentToolUse.name,\n args: currentToolUse.inputJson || \"{}\",\n status: \"pending\" as const,\n });\n currentToolUse = null;\n }\n }\n\n // Yield final chunk with tool calls if any were accumulated\n if (toolCalls.length > 0) {\n yield {\n content: \"\",\n toolCalls,\n metadata: {\n usage: {\n inputTokens: usage.input_tokens || 0,\n outputTokens: usage.output_tokens || 0,\n totalTokens:\n (usage.input_tokens || 0) + (usage.output_tokens || 0),\n },\n model: request.model,\n options,\n duration: Date.now() - startTime,\n provider: \"anthropic\",\n },\n };\n }\n } catch (error) {\n throw new Error(\n `Anthropic streaming error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n async function getModels(): Promise<Model[]> {\n return anthropicModels.list();\n }\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n\n function parseToolArgs(str: string): Record<string, unknown> {\n if (!str || str.trim() === \"\") return {};\n try {\n return JSON.parse(str);\n } catch (err) {\n console.warn(\"Failed to parse tool call args:\", err);\n return {};\n }\n }\n\n function convertMessages(\n messages: (Message | MultimodalMessage)[],\n ): MessageParam[] {\n return (\n messages\n ?.filter((msg) => msg.role !== \"system\") // Anthropic handles system messages separately\n ?.map((msg): MessageParam => {\n switch (msg.role) {\n case \"user\":\n if (msg.content && Array.isArray(msg.content)) {\n return {\n role: \"user\",\n content: msg.content\n .filter(\n (\n part: ContentPart,\n ): part is TextContentPart | ImageContentPart =>\n part.type === \"text\" || part.type === \"image\",\n )\n .map((part: TextContentPart | ImageContentPart) => {\n if (part.type === \"image\") {\n return {\n type: \"image\" as const,\n source: {\n type: \"base64\" as const,\n media_type: part.mimeType as\n | \"image/jpeg\"\n | \"image/png\"\n | \"image/gif\"\n | \"image/webp\",\n data: part.data,\n },\n };\n }\n return {\n type: \"text\" as const,\n text: part.text,\n };\n }),\n };\n } else {\n return {\n role: \"user\",\n content: msg.content || \"\",\n };\n }\n\n case \"assistant\": {\n const assistantMsg = msg as any;\n\n // Check if there are tool calls\n if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {\n const content: any[] = [];\n if (assistantMsg.content) {\n content.push({\n type: \"text\" as const,\n text: assistantMsg.content,\n });\n }\n for (const tc of assistantMsg.toolCalls) {\n content.push({\n type: \"tool_use\" as const,\n id: tc.id,\n name: tc.name,\n input:\n typeof tc.args === \"string\"\n ? parseToolArgs(tc.args)\n : tc.args || {},\n });\n }\n return { role: \"assistant\", content };\n }\n\n return {\n role: \"assistant\",\n content: assistantMsg.content || \"\",\n };\n }\n\n case \"tool\": {\n // Anthropic expects tool results in user messages with tool_result content blocks\n const toolMsg = msg as any;\n return {\n role: \"user\",\n content: [\n {\n type: \"tool_result\" as const,\n tool_use_id: toolMsg.toolCallId,\n content: toolMsg.content,\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unsupported message role: ${(msg as any).role}`);\n }\n }) || []\n );\n }\n\n function convertTools(tools: any[]): any[] {\n return (\n tools?.map((tool) => ({\n name: tool.name,\n description: tool.description,\n input_schema: tool.input,\n })) || []\n );\n }\n\n function configure(overrides: Record<string, unknown>): AnthropicProvider {\n return provider({ ...finalConfig, ...overrides } as Config);\n }\n\n return {\n name: \"anthropic\",\n query,\n stream,\n getModels,\n configure,\n };\n}\n","/**\n * Anthropic model definitions\n */\n\nimport type { Model } from \"@jarvis/types\";\n\nexport const claude3Haiku: Model = {\n id: \"claude-3-haiku-20240307\",\n name: \"Claude 3 Haiku\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 4096 },\n cost: { multiplier: 8, inputTokens: 0.25, outputTokens: 1.25 },\n};\n\nexport const claude37Sonnet: Model = {\n id: \"claude-3-7-sonnet-20241022\",\n name: \"Claude 3.7 Sonnet\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 20, inputTokens: 3.00, outputTokens: 15.00 },\n options: {\n temperature: 0.4,\n topP: 0.95,\n },\n};\n\nexport const claude35Haiku: Model = {\n id: \"claude-3-5-haiku-20241022\",\n name: \"Claude 3.5 Haiku\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 8, inputTokens: 0.80, outputTokens: 4.00 },\n};\n\nexport const claude4Sonnet: Model = {\n id: \"claude-sonnet-4-20250514\",\n name: \"Claude 4 Sonnet\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 20, inputTokens: 3.00, outputTokens: 15.00 },\n};\n\nexport const claude4Opus: Model = {\n id: \"claude-opus-4-20250514\",\n name: \"Claude 4 Opus\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 50, inputTokens: 15.00, outputTokens: 75.00 },\n};\n\nexport const claudeSonnet45: Model = {\n id: \"claude-sonnet-4-5-20250929\",\n name: \"Claude Sonnet 4.5\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 20, inputTokens: 3.00, outputTokens: 15.00 },\n};\n\nexport const claudeOpus41: Model = {\n id: \"claude-opus-4-1-20250514\",\n name: \"Claude Opus 4.1\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 50, inputTokens: 15.00, outputTokens: 75.00 },\n};\n\nexport const claudeHaiku45: Model = {\n id: \"claude-haiku-4-5-20251001\",\n name: \"Claude Haiku 4.5\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 8, inputTokens: 1.00, outputTokens: 5.00 },\n};\n\nexport const claudeOpus46: Model = {\n id: \"claude-opus-4-6-20250515\",\n name: \"Claude Opus 4.6\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 16384 },\n cost: { multiplier: 50, inputTokens: 5.00, outputTokens: 25.00 },\n};\n\n// Claude Code models (routed via \"claude-code\" provider tag, not model ID)\nexport const claudeCodeSonnet: Model = {\n id: \"claude-sonnet-4-5-20250929\",\n name: \"Claude Code (Sonnet)\",\n provider: \"claude-code\",\n maxTokens: { input: 200_000, output: 16384 },\n cost: { multiplier: 20, inputTokens: 3.00, outputTokens: 15.00 },\n};\n\nexport const claudeCodeOpus: Model = {\n id: \"claude-opus-4-6-20250515\",\n name: \"Claude Code (Opus)\",\n provider: \"claude-code\",\n maxTokens: { input: 200_000, output: 16384 },\n cost: { multiplier: 50, inputTokens: 5.00, outputTokens: 25.00 },\n};\n\n// All Anthropic models\nexport const anthropicModels = {\n claude3Haiku,\n claude37Sonnet,\n claude35Haiku,\n claude4Sonnet,\n claude4Opus,\n claudeSonnet45,\n claudeOpus41,\n claudeHaiku45,\n claudeOpus46,\n\n list: (): Model[] => [\n claude3Haiku,\n claude37Sonnet,\n claude35Haiku,\n claude4Sonnet,\n claude4Opus,\n claudeSonnet45,\n claudeOpus41,\n claudeHaiku45,\n claudeOpus46,\n ],\n};\n\n// Claude Code models registry\nexport const claudeCodeModels = {\n claudeCodeSonnet,\n claudeCodeOpus,\n\n list: (): Model[] => [claudeCodeSonnet, claudeCodeOpus],\n};\n","/**\n * Logger Singleton\n *\n * Provider-agnostic logger with console default.\n * Call logger.init({ provider }) to set a real provider (e.g., pinoProvider).\n *\n * Usage:\n * ```typescript\n * import { logger } from \"@jarvis/logger\";\n * import { pinoProvider } from \"@jarvis/pino\";\n *\n * logger.init({ provider: pinoProvider({ name: \"worker\" }) });\n * logger.info(ctx, \"Hello\", { key: \"value\" });\n * logger.sys.info(\"System startup\");\n * Runtime.install({ logger: logger.runtime() });\n * ```\n */\n\nimport type { Context, LogProvider, LogMetadata, AuditEvent } from \"@jarvis/types\";\n\n// =============================================================================\n// Error resolving — handles Error objects in metadata\n// =============================================================================\n\nfunction resolveError(meta?: LogMetadata): LogMetadata {\n if (!meta) return {};\n const { error, ...rest } = meta;\n if (error === undefined) return meta;\n if (error instanceof Error) {\n return { ...rest, error: error.message, ...(error.stack ? { errorStack: error.stack } : {}) };\n }\n return { ...rest, error: typeof error === \"string\" ? error : String(error) };\n}\n\n// =============================================================================\n// Console default provider\n// =============================================================================\n\nfunction consoleProvider(): LogProvider {\n const log =\n (level: \"debug\" | \"info\" | \"warn\" | \"error\") =>\n (_ctx: Context, message: string, meta?: LogMetadata): void => {\n const fn = level === \"error\" ? console.error : level === \"warn\" ? console.warn : level === \"debug\" ? console.debug : console.info;\n fn(`[${level.toUpperCase()}]`, message, resolveError(meta));\n };\n\n return {\n debug: log(\"debug\"),\n info: log(\"info\"),\n warn: log(\"warn\"),\n error: log(\"error\"),\n audit: (_ctx, event) => console.info(\"[AUDIT]\", event.action, event.result),\n };\n}\n\n// =============================================================================\n// Console runtime logger (fallback for Temporal Runtime.install())\n// =============================================================================\n\ninterface RuntimeLogger {\n log(level: string, message: string, meta?: Record<string | symbol, unknown>): void;\n trace(message: string, meta?: Record<string | symbol, unknown>): void;\n debug(message: string, meta?: Record<string | symbol, unknown>): void;\n info(message: string, meta?: Record<string | symbol, unknown>): void;\n warn(message: string, meta?: Record<string | symbol, unknown>): void;\n error(message: string, meta?: Record<string | symbol, unknown>): void;\n}\n\nconst LEVEL_MAP: Record<string, \"debug\" | \"info\" | \"warn\" | \"error\"> = {\n TRACE: \"debug\",\n DEBUG: \"debug\",\n INFO: \"info\",\n WARN: \"warn\",\n ERROR: \"error\",\n};\n\nfunction consoleRuntimeLogger(): RuntimeLogger {\n const log = (level: string, message: string, meta?: Record<string | symbol, unknown>) => {\n const fn = console[LEVEL_MAP[level] ?? \"info\"];\n fn(message, meta ? Object.fromEntries(Object.entries(meta as Record<string, unknown>)) : \"\");\n };\n return {\n log: (level, msg, meta) => log(level, msg, meta),\n trace: (msg, meta) => log(\"TRACE\", msg, meta),\n debug: (msg, meta) => log(\"DEBUG\", msg, meta),\n info: (msg, meta) => log(\"INFO\", msg, meta),\n warn: (msg, meta) => log(\"WARN\", msg, meta),\n error: (msg, meta) => log(\"ERROR\", msg, meta),\n };\n}\n\n// =============================================================================\n// Singleton state\n// =============================================================================\n\nconst SYS_CTX: Context = { userId: \"system\" } as Context;\n\nlet _provider: LogProvider = consoleProvider();\nlet _runtimeFactory: (() => RuntimeLogger) | null = null;\n\n// =============================================================================\n// Logger singleton\n// =============================================================================\n\nexport type LogProviderWithRuntime = LogProvider & {\n runtime?: () => RuntimeLogger;\n};\n\nexport const logger = {\n /** Set the active logging provider */\n init(config: { provider: LogProviderWithRuntime }) {\n _provider = config.provider;\n _runtimeFactory = config.provider.runtime ?? null;\n },\n\n // Logging — delegates to current provider (resolves Error objects in meta)\n debug(ctx: Context, message: string, meta?: LogMetadata) { _provider.debug(ctx, message, resolveError(meta)); },\n info(ctx: Context, message: string, meta?: LogMetadata) { _provider.info(ctx, message, resolveError(meta)); },\n warn(ctx: Context, message: string, meta?: LogMetadata) { _provider.warn(ctx, message, resolveError(meta)); },\n error(ctx: Context, message: string, meta?: LogMetadata) { _provider.error(ctx, message, resolveError(meta)); },\n audit(ctx: Context, event: AuditEvent) { _provider.audit(ctx, event); },\n\n /** System-scoped shorthand (no ctx required) */\n sys: {\n debug(message: string, meta?: LogMetadata) { _provider.debug(SYS_CTX, message, meta); },\n info(message: string, meta?: LogMetadata) { _provider.info(SYS_CTX, message, meta); },\n warn(message: string, meta?: LogMetadata) { _provider.warn(SYS_CTX, message, meta); },\n error(message: string, meta?: LogMetadata) { _provider.error(SYS_CTX, message, meta); },\n },\n\n /** Get a Temporal Runtime.install() logger. Uses provider's runtime() if available, console fallback. */\n runtime(): RuntimeLogger {\n if (_runtimeFactory) return _runtimeFactory();\n return consoleRuntimeLogger();\n },\n};\n","/**\n * LLM (Large Language Model) related types\n */\n\nimport type {\n TTSVoice,\n TTSModel,\n TTSResponseFormat,\n} from \"../media/tts.types\";\n\nimport type { Message, MultimodalMessage } from \"./message.types\";\nimport type { Usage } from \"./usage.types\";\nimport { Context } from \"../core/context.types\";\nimport {\n Model,\n ResolveModelRequest,\n ResolveModelResponse,\n} from \"./model.types\";\nimport { Provider } from \"../core/provider.types\";\nimport { Schema } from \"../core/schema.types\";\nimport { ToolCall, Tool } from \"./tool.types\";\n\n// Re-export message types for backward compatibility\nexport type {\n MessageRole,\n Message,\n MultimodalMessage,\n BaseMessage,\n UserMessage,\n AssistantMessage,\n SystemMessage,\n ToolMessage,\n ContentPart,\n TextContentPart,\n AudioContentPart,\n ImageContentPart,\n} from \"./message.types\";\n\n// =============================================================================\n// OUTPUT CONFIGURATION\n// =============================================================================\n\n/** Output format types — what the response should include */\nexport type OutputFormat = \"text\" | \"audio\" | \"json\";\n\n/** Audio-specific output configuration */\nexport interface AudioOutputConfig {\n /** TTS voice (defaults to \"nova\") */\n voice?: TTSVoice;\n /** TTS model (defaults to \"tts-1\") */\n model?: TTSModel;\n /** Audio response format (defaults to \"mp3\") */\n format?: TTSResponseFormat;\n}\n\n/**\n * Output configuration for LLM response delivery.\n *\n * Controls both LLM output format (json with schema) and\n * response delivery formats (text, audio).\n *\n * Valid format combinations:\n * - `[\"text\"]` — text only (default)\n * - `[\"text\", \"audio\"]` — text + audio (voice mode)\n * - `[\"json\"]` — JSON structured output (standalone, requires schema)\n *\n * @example Text only (default)\n * ```typescript\n * { formats: [\"text\"] }\n * ```\n *\n * @example Text + audio (voice mode)\n * ```typescript\n * { formats: [\"text\", \"audio\"], audio: { voice: \"nova\" } }\n * ```\n *\n * @example JSON structured output\n * ```typescript\n * { formats: [\"json\"], schema: mySchema }\n * ```\n */\nexport interface LLMQueryOutput {\n /**\n * Which formats to include in the response. Defaults to [\"text\"].\n * Valid: [\"text\"], [\"text\", \"audio\"], or [\"json\"].\n */\n formats?: [\"text\"] | [\"text\", \"audio\"] | [\"json\"];\n /** JSON schema — required when formats is [\"json\"] */\n schema?: Schema;\n /** Audio-specific settings — used when \"audio\" is in formats */\n audio?: AudioOutputConfig;\n}\n\n/** Check if an output config includes a specific format */\nexport function hasOutputFormat(\n output: LLMQueryOutput | undefined,\n format: OutputFormat,\n): boolean {\n return (output?.formats as string[] | undefined)?.includes(format) ?? false;\n}\n\n// =============================================================================\n// THINKING CONFIG\n// =============================================================================\n\n/**\n * Thinking/reasoning configuration — provider-agnostic.\n *\n * Providers map this to their native format:\n * - Anthropic: adaptive → `thinking: { type: \"enabled\" }`, enabled → `thinking: { budget_tokens }`\n * - Gemini: maps to `thinkingConfig.thinkingLevel` or `thinkingBudget`\n * - OpenAI: maps to `reasoning_effort`\n * - Providers without support: ignore the field\n */\nexport interface ThinkingConfig {\n /** Thinking mode */\n type: \"adaptive\" | \"enabled\" | \"disabled\";\n /** Token budget for thinking (only used with type: \"enabled\") */\n budgetTokens?: number;\n}\n\n// =============================================================================\n// LLM QUERY TYPES\n// =============================================================================\n\nexport interface QueryLLMRequest {\n model: string;\n messages: (Message | MultimodalMessage)[];\n tools?: Tool[];\n output?: LLMQueryOutput;\n thinking?: ThinkingConfig;\n options?: {\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n };\n}\n\nexport interface LLMQueryOptions {\n /** Override provider selection (bypass model-based routing) */\n provider?: string;\n /** Set false to suppress Redis token streaming (for internal LLM calls like query understanding) */\n stream?: boolean;\n}\n\nexport interface QueryLLMResponse {\n content: string;\n /** JSON structured output (when output format is \"json\" and SDK returns structured_output) */\n json?: string;\n /** Error from the SDK (e.g. error_max_turns, error_max_budget_usd) */\n error?: string;\n thinking?: string;\n toolCalls?: ToolCall[];\n metadata?: QueryLLMMetadata;\n /** Claude Code session ID from the SDK (for session resume support) */\n sessionId?: string;\n /** Why the LLM stopped generating — populated by providers from API response */\n stopReason?: StopReason;\n}\n\n/** Why the LLM stopped generating */\nexport type StopReason =\n | \"end_turn\"\n | \"max_tokens\"\n | \"tool_use\"\n | \"stop_sequence\"\n | \"content_filter\";\n\nexport interface QueryLLMMetadata {\n model: string;\n usage: Usage;\n options?: {\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n };\n duration: number;\n provider: string;\n}\n\n// LLM Client interface\nexport interface LLMProvider extends Provider {\n query(\n ctx: Context,\n req: QueryLLMRequest,\n options?: LLMQueryOptions,\n ): Promise<QueryLLMResponse>;\n stream(\n ctx: Context,\n req: QueryLLMRequest,\n options?: LLMQueryOptions,\n ): AsyncGenerator<QueryLLMResponse>;\n getModels?(): Promise<Model[]>;\n /** Create a new instance with different config (e.g., different API key for BYOK) */\n configure?(config: Record<string, unknown>): LLMProvider;\n /** Optional provider-specific request validation. Called by the router before query/stream. */\n validateQuery?(ctx: Context, req: QueryLLMRequest): QueryLLMRequest;\n}\n\n// ============================================================================\n// LLM Resolvers\n// ============================================================================\n\nexport interface ResolveLLMProviderRequest {\n providerName?: string;\n providers: LLMProvider[];\n}\n\nexport interface ResolveLLMProviderResponse {\n provider: LLMProvider;\n}\n\nexport interface LLMProviderResolver extends Provider {\n resolve(\n request: ResolveLLMProviderRequest,\n ): Promise<ResolveLLMProviderResponse>;\n}\n\nexport interface ModelResolver extends Provider {\n resolve(request: ResolveModelRequest): Promise<ResolveModelResponse>;\n}\n\nexport interface ResolveOptionsRequest {\n requestOptions?: QueryLLMRequest[\"options\"];\n modelOptions?: QueryLLMRequest[\"options\"];\n}\n\nexport interface ResolveOptionsResponse {\n options?: QueryLLMRequest[\"options\"];\n}\n\nexport interface OptionsResolver extends Provider {\n resolve(request: ResolveOptionsRequest): Promise<ResolveOptionsResponse>;\n}\n","import type { Context } from \"../core/context.types\";\nimport type { TranslateFn } from \"../core/translation.types\";\nimport { Schema } from \"../core/schema.types\";\nimport type { Usage } from \"./usage.types\";\n\n// =============================================================================\n// Tool UI (Unified — MCP iframe OR chat component)\n// =============================================================================\n\n/**\n * ToolUi — discriminated union for rich rendering.\n *\n * Component variant: renders in chat via artifact router\n * Resource variant: renders as MCP iframe via ui:// resource\n */\nexport type ToolUi = ToolUiComponent | ToolUiResource;\n\nexport interface ToolUiComponent {\n /** MCP-style URI: \"ui://appId/componentType\" (e.g., \"ui://chef/recipe\") */\n uri: string;\n /** Display title for the component card */\n title: string;\n /** Data payload — auto-populated from tool output when omitted in after hook */\n data?: unknown;\n /** Preferred height in pixels */\n height?: number;\n}\n\nexport interface ToolUiResource {\n /** URI of the MCP UI resource (e.g., \"ui://server/dashboard\") */\n resourceUri: string;\n /** Title override for the artifact card */\n title?: string;\n /** Preferred iframe height in pixels */\n height?: number;\n /** Extra data passed to the rendering component (e.g., html, serverName) */\n data?: unknown;\n}\n\n// =============================================================================\n// Tool Permissions (Declarative Access Control)\n// =============================================================================\n\n/**\n * Declarative permissions for a tool.\n * Combines RBAC (roles/tiers) with risk classification.\n */\nexport interface ToolPermissions {\n /** Required roles (checked vs ctx.access.role) */\n roles?: string[];\n /** Required tiers (checked vs ctx.access.tier) */\n tiers?: string[];\n /**\n * Risk level — drives permission mode behavior:\n * - \"safe\": auto-allow (read, search, list)\n * - \"moderate\": allow by default, log (create, update)\n * - \"dangerous\": ask user first (delete, send, execute)\n */\n risk?: \"safe\" | \"moderate\" | \"dangerous\";\n /**\n * When to ask for user approval (if applicable based on risk + mode).\n * - \"before\": ask BEFORE execution (default)\n * - \"after\": execute first, then ask for confirmation\n * Only applies when the harness auto-asks (no custom hook defined).\n */\n ask?: \"before\" | \"after\";\n /** Can run in parallel with other tools (default: true) */\n concurrent?: boolean;\n /** Resource scopes (future: OAuth/MCP) */\n scopes?: string[];\n}\n\n// =============================================================================\n// Tool Metadata (all display, permissions, and provider config)\n// =============================================================================\n\n/** Context provided to metadata describe function */\nexport interface ToolMetadataContext {\n toolName: string;\n toolCallId: string;\n}\n\n/** Request passed to the describe function */\nexport interface DescribeToolRequest {\n status: ToolCallStatus;\n input: Record<string, unknown>;\n output?: unknown;\n error?: string;\n durationMs?: number;\n}\n\n/** Options passed as 3rd argument to metadata.describe() */\nexport interface DescribeToolOptions {\n t: TranslateFn;\n}\n\n/**\n * Tool metadata — all display, permissions, UI, and provider configuration.\n */\nexport interface ToolMetadata {\n /** Human-readable tool name for UI display (e.g., \"Create Recipe\") */\n label?: string;\n\n /** Generate phase description for the tool message UI */\n describe?: (\n ctx: ToolMetadataContext,\n req: DescribeToolRequest,\n options?: DescribeToolOptions,\n ) => string | undefined;\n\n /**\n * When true, tool calls are not displayed in the conversation UI.\n * The tool still runs normally — it's just invisible to the user.\n */\n hidden?: boolean;\n\n /**\n * Native provider that handles lifecycle.\n * When set, the tool is handled by the named provider's internal loop\n * rather than by callTool().\n */\n provider?: string;\n\n /** Declarative permissions — RBAC + risk classification */\n permissions?: ToolPermissions;\n\n /** UI component config — MCP iframe or chat component */\n ui?: ToolUi;\n\n /** Max tool output size in characters before truncation (default: 50000) */\n maxOutputSize?: number;\n}\n\n// =============================================================================\n// Tool Definition\n// =============================================================================\n\n/**\n * Tool definition — serializable schema + optional execution fields.\n *\n * Core fields (name, description, input, output) are always serializable.\n * Execution fields (call, hooks, metadata, build) are added by the SDK\n * `tool()` factory and used by the agent runner.\n */\nexport interface Tool {\n name: string;\n description: string;\n input: Schema;\n output: Schema;\n\n // === Execution ===\n\n /** Function to execute the tool */\n call?: CallTool;\n\n /**\n * Schema-only builder — called by buildTools() at the start of each iteration\n * to produce a tool with state-dependent schemas (e.g., dynamic enum values).\n */\n build?: (ctx: Context, req: { tool: Tool; state: unknown }) => Tool;\n\n // === Configuration ===\n\n /** All display, permissions, UI, and provider configuration */\n metadata?: ToolMetadata;\n\n // === Lifecycle Hooks ===\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n hooks?: ToolHooks<any>;\n}\n\n/**\n * Tool handler function.\n *\n * Signature: (ctx, input, options?) => output\n * ctx from runner, options pre-bound by buildTools.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type CallTool = (...args: any[]) => Promise<any>;\n\n// =============================================================================\n// Ask User (human-in-the-loop)\n// =============================================================================\n\n/** User's response action */\nexport type UserInputAction = \"allow\" | \"deny\" | \"modify\";\n\nexport interface UserInputResponse {\n action: UserInputAction;\n data?: Record<string, unknown>;\n feedback?: string;\n}\n\n/** User input with correlation ID */\nexport interface UserInput extends UserInputResponse {\n id: string;\n}\n\n/**\n * Request for user input — raw data preview, rich UI component, or reason-only.\n */\nexport type UserInputRequest =\n | { reason?: string; data: unknown; ui?: never }\n | { reason?: string; data?: never; ui: ToolUi };\n\n/**\n * Options passed to tool hooks (third argument)\n */\nexport interface ToolHookOptions {\n /** Request user input (human-in-the-loop). Pauses until user responds. */\n askUser: (req?: UserInputRequest) => Promise<UserInputResponse | null>;\n /** Current agent mode — hooks can use this to decide behavior per mode. */\n mode: string;\n}\n\n// =============================================================================\n// Tool Hook Types\n// =============================================================================\n\n/**\n * Hook called before tool execution.\n *\n * Return values:\n * - `{ action: \"allow\" }` — proceed (optionally with modified input)\n * - `{ action: \"deny\", reason }` — reject execution\n */\nexport type BeforeToolHook<TState = unknown> = (\n ctx: Context,\n req: {\n toolName: string;\n input: unknown;\n toolCallId: string;\n state: TState;\n },\n options: ToolHookOptions,\n) => Promise<{ action: \"allow\"; input?: unknown } | { action: \"deny\"; reason: string }>;\n\n/** Unified tool call status */\nexport type ToolCallStatus = \"running\" | \"completed\" | \"modify\" | \"denied\" | \"error\";\n\n/**\n * Hook called after tool execution.\n */\nexport type AfterToolHook<TState = unknown> = (\n ctx: Context,\n req: {\n toolName: string;\n input: unknown;\n output: unknown;\n toolCallId: string;\n state: TState;\n ui?: ToolUi;\n },\n options: ToolHookOptions,\n) => Promise<{\n /** Lightweight context for LLM */\n context: unknown;\n /** State update (partial merge) */\n state?: Partial<TState>;\n /** UI override — if omitted and metadata.ui exists, auto-generated from tool output */\n ui?: ToolUi;\n /** Tool call result status */\n status?: ToolCallStatus;\n /** Human-readable message */\n message?: string;\n /** Pruning instructions */\n prune?: {\n removeTools?: string[];\n keepRecent?: number;\n };\n /** Resource usage */\n usage?: Usage;\n}>;\n\n/** Tool hooks container */\nexport interface ToolHooks<TState = unknown> {\n before?: BeforeToolHook<TState>;\n after?: AfterToolHook<TState>;\n}\n\n// =============================================================================\n// Hook Identity Functions (type narrowing without generics on tool())\n// =============================================================================\n\nexport function before<TState>(fn: BeforeToolHook<TState>): BeforeToolHook<TState> {\n return fn;\n}\n\nexport function after<TState>(fn: AfterToolHook<TState>): AfterToolHook<TState> {\n return fn;\n}\n\n// =============================================================================\n// Tool Call Types\n// =============================================================================\n\nexport interface CallToolRequest {\n tool: Tool;\n args: unknown;\n}\n\nexport interface CallToolResponse {\n output: string;\n}\n\nexport interface ToolCallError {\n tool: string;\n error: string;\n args?: string;\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n args: string;\n status: \"pending\" | \"completed\" | \"failed\";\n output?: string;\n error?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ResolveToolRequest {\n tool: string | Tool;\n available: Tool[];\n}\n\nexport interface ResolveToolResponse {\n tool: Tool;\n}\n","/**\n * TTS (Text-to-Speech) related types\n *\n * Provider-agnostic TTS interface. Voice and model are opaque strings —\n * each provider interprets them in its own context (e.g., OpenAI \"nova\"\n * vs ElevenLabs voice IDs like \"cgSgspJ2msm6clMCkdW9\").\n */\n\nimport type { Context } from \"../core/context.types\";\nimport type { ModelCost } from \"../agents/model.types\";\nimport type { Provider } from \"../core/provider.types\";\n\n// =============================================================================\n// VOICE, MODEL, FORMAT\n// =============================================================================\n\n/** Provider-agnostic voice identifier (string — each provider defines its own) */\nexport type TTSVoice = string;\n\n/** Provider-agnostic model identifier */\nexport type TTSModel = string;\n\n/** Audio output format — shared across providers */\nexport type TTSResponseFormat = \"mp3\" | \"opus\" | \"aac\" | \"flac\" | \"wav\" | \"pcm\";\n\n// OpenAI-specific convenience constants\nexport const OPENAI_TTS_VOICES = [\"alloy\", \"echo\", \"fable\", \"onyx\", \"nova\", \"shimmer\"] as const;\nexport type OpenAITTSVoice = (typeof OPENAI_TTS_VOICES)[number];\n\nexport const OPENAI_TTS_MODELS = [\"tts-1\", \"tts-1-hd\"] as const;\nexport type OpenAITTSModel = (typeof OPENAI_TTS_MODELS)[number];\n\n// Backwards-compatible runtime constants (used by OpenAI provider validation)\nexport const TTS_VOICES: string[] = [...OPENAI_TTS_VOICES];\nexport const TTS_MODELS: string[] = [...OPENAI_TTS_MODELS];\nexport const TTS_FORMATS: TTSResponseFormat[] = [\"mp3\", \"opus\", \"aac\", \"flac\", \"wav\", \"pcm\"];\n\n// =============================================================================\n// REQUEST / RESPONSE\n// =============================================================================\n\nexport interface TTSRequest {\n /** The text to convert to speech */\n text: string;\n /** The voice to use for speech synthesis */\n voice?: TTSVoice;\n /** The model to use for speech synthesis */\n model?: TTSModel;\n /** Speed of the generated audio (0.25 to 4.0) */\n speed?: number;\n /** The format of the audio output */\n responseFormat?: TTSResponseFormat;\n /** Explicit provider routing (e.g., \"openai\", \"elevenlabs\") */\n provider?: string;\n /** Provider-specific voice settings (stability, similarity_boost, etc.) */\n voiceSettings?: Record<string, unknown>;\n}\n\nexport interface TTSResponse {\n /** Raw audio buffer */\n audioBuffer: Buffer;\n /** Base64-encoded audio data */\n audioBase64: string;\n /** MIME type of the audio */\n mimeType: string;\n}\n\n// =============================================================================\n// MODEL / VOICE DEFINITIONS\n// =============================================================================\n\n/** TTS model definition — follows the same pattern as Model in model.types.ts */\nexport interface TTSModelDef {\n /** Model identifier (e.g., \"tts-1\", \"eleven_turbo_v2\") */\n id: string;\n /** Human-readable name (e.g., \"TTS-1\", \"Eleven Turbo v2\") */\n name: string;\n /** Provider name (e.g., \"openai\", \"elevenlabs\") */\n provider: string;\n /** Provider-specific options */\n options?: Record<string, unknown>;\n /** Cost configuration for billing and estimation */\n cost: ModelCost;\n}\n\n/** TTS voice definition — a named voice with provider and default settings */\nexport interface TTSVoiceDef {\n /** Voice identifier (e.g., \"nova\", \"cgSgspJ2msm6clMCkdW9\") */\n id: string;\n /** Human-readable name (e.g., \"Nova\", \"Scarlett\") */\n name: string;\n /** Provider name (e.g., \"openai\", \"elevenlabs\") */\n provider: string;\n /** Default voice settings (e.g., { stability: 0.5, similarityBoost: 0.8 }) */\n options?: Record<string, unknown>;\n}\n\n// =============================================================================\n// TTS PROVIDER\n// =============================================================================\n\n/**\n * TTSProvider — platform-provided text-to-speech.\n *\n * Implementations: OpenAI (`@jarvis/openai`), ElevenLabs (`@jarvis/elevenlabs`).\n * Multi-provider routing: `@jarvis/tts`.\n */\nexport interface TTSProvider extends Provider {\n /** Convert text to speech audio */\n speech(ctx: Context, request: TTSRequest): Promise<TTSResponse>;\n /** List available TTS models for this provider */\n getModels?(): TTSModelDef[];\n /** List available voices for this provider */\n getVoices?(): TTSVoiceDef[];\n /** Create a new instance with different config (e.g., different API key for BYOK) */\n configure?(config: Record<string, unknown>): TTSProvider;\n}\n","/**\n * Claude Code provider\n *\n * Wraps the @anthropic-ai/claude-agent-sdk. Returns { content, toolCalls: undefined }\n * so the orchestrator exits after 1 iteration — Claude Code handles its own tool loop internally.\n *\n * Routing is by provider (\"claude-code\"), not model ID. The model ID passed in\n * (e.g. \"claude-sonnet-4-5-20250929\") goes straight to the SDK.\n *\n * Tool interception (canUseTool):\n * - When `onUserInput` is provided, every SDK tool call is converted to a PendingUserInput\n * and forwarded to the consumer via the callback. The consumer decides per-tool what to do.\n * - Tools with hooks.before: Provider invokes the hook, which calls wait() with artifact data.\n * The wait() creates an enriched PendingUserInput and routes through onUserInput.\n * - AskUserQuestion: Specific converter → structured questions format for AskUserPanel\n * - All other tools: Generic converter → raw toolName + input\n * - When no `onUserInput` is provided, falls back to bypassPermissions (backwards compatible)\n *\n * After-hook invocation:\n * - When a \"user\" message arrives (tool_result), the provider invokes after hooks for tracked tools.\n * - Artifacts from after hooks are attached to the message as `_toolUi` map.\n * - The worker reads `_toolUi` when creating tool completion messages.\n */\n\nimport { logger } from \"@jarvis/logger\";\nimport { claudeCodeModels } from \"./anthropic.models\";\nimport { context as createContext } from \"@jarvis/sdk\";\nimport type {\n Context,\n QueryLLMRequest,\n QueryLLMResponse,\n LLMProvider,\n LLMQueryOptions,\n Model,\n PendingUserInput,\n ToolUiData,\n UserInputResponse,\n ToolHookOptions,\n} from \"@jarvis/types\";\nimport { hasOutputFormat } from \"@jarvis/types\";\n\nimport type { ClaudeCodeConfig, ProviderTool } from \"./claude-code.types\";\n\n// SDK types imported dynamically; declare the shapes we need for canUseTool.\n// Note: SDK Zod validation requires updatedInput on the \"allow\" variant.\ntype PermissionResult =\n | {\n behavior: \"allow\";\n updatedInput: Record<string, unknown>;\n toolUseID?: string;\n }\n | {\n behavior: \"deny\";\n message: string;\n interrupt?: boolean;\n toolUseID?: string;\n };\n\nlet _idCounter = 0;\nfunction generateId(): string {\n return `pui-${Date.now()}-${++_idCounter}`;\n}\n\n/**\n * Convert AskUserQuestion tool call to a PendingUserInput\n * with structured questions format matching AskUserPanel expectations.\n */\nfunction convertAskUserQuestion(\n input: Record<string, unknown>,\n toolUseID: string,\n): PendingUserInput {\n return {\n id: generateId(),\n type: \"tool\",\n toolName: \"askUser\",\n toolCallId: toolUseID,\n output: {\n questions: input.questions,\n },\n timing: \"before\",\n };\n}\n\n/**\n * Convert any other tool call to a generic PendingUserInput.\n * The consumer (worker) decides what to do based on toolName.\n */\nfunction convertGenericTool(\n toolName: string,\n input: Record<string, unknown>,\n toolUseID: string,\n): PendingUserInput {\n return {\n id: generateId(),\n type: \"tool\",\n toolName,\n toolCallId: toolUseID,\n input,\n timing: \"before\",\n };\n}\n\n/**\n * Convert a UserInputResponse from the consumer back to an SDK PermissionResult.\n * For AskUserQuestion, the response data contains answers that need to flow back.\n */\nfunction toPermissionResult(\n toolName: string,\n originalInput: Record<string, unknown>,\n response: UserInputResponse,\n toolUseID: string,\n): PermissionResult {\n if (response.action === \"deny\") {\n return {\n behavior: \"deny\",\n message: response.feedback || \"User denied the tool call\",\n toolUseID,\n };\n }\n\n // For AskUserQuestion, pass answers back as updatedInput so the SDK\n // receives them as the tool's \"result\"\n if (toolName === \"AskUserQuestion\" && response.data) {\n return {\n behavior: \"allow\",\n updatedInput: {\n answers: response.data,\n },\n toolUseID,\n };\n }\n\n // SDK Zod schema requires updatedInput for the \"allow\" variant —\n // pass the original input through unchanged.\n return { behavior: \"allow\", updatedInput: originalInput, toolUseID };\n}\n\n// =============================================================================\n// Shared permission + hook infrastructure\n// =============================================================================\n\ninterface PermissionOptions {\n opts: Record<string, unknown>;\n toolMap: Map<string, ProviderTool>;\n toolInputTracker: Map<\n string,\n { toolName: string; input: Record<string, unknown> }\n >;\n}\n\n/**\n * Build permission options shared by both query() and stream().\n * When tools with hooks are provided, canUseTool invokes the before hook.\n */\nfunction buildPermissionOptions(\n ctx: Context,\n config: ClaudeCodeConfig,\n): PermissionOptions {\n const toolMap = new Map<string, ProviderTool>();\n for (const t of config.tools ?? []) toolMap.set(t.name, t);\n\n const toolInputTracker = new Map<\n string,\n { toolName: string; input: Record<string, unknown> }\n >();\n\n if (!config.onUserInput) {\n return {\n opts: {\n permissionMode: \"bypassPermissions\" as const,\n allowDangerouslySkipPermissions: true,\n },\n toolMap,\n toolInputTracker,\n };\n }\n\n const canUseTool = async (\n toolName: string,\n input: Record<string, unknown>,\n options: { toolUseID: string; signal: AbortSignal },\n ): Promise<PermissionResult> => {\n // Track tool input for after-hook invocation\n toolInputTracker.set(options.toolUseID, { toolName, input });\n\n const t = toolMap.get(toolName);\n\n // If tool has a before hook, invoke it — the hook creates the PendingUserInput\n // with artifact data via wait()\n if (t?.hooks?.before) {\n const req = {\n toolName,\n input,\n toolCallId: options.toolUseID,\n state: {} as unknown,\n };\n const hookOptions: ToolHookOptions = {\n mode: config.permissionMode ?? \"default\",\n askUser: async (waitOpts?) => {\n const pendingInput: PendingUserInput = {\n id: generateId(),\n type: \"tool\" as const,\n toolName,\n toolCallId: options.toolUseID,\n input,\n timing: \"before\" as const,\n ...(waitOpts?.data\n ? { output: waitOpts.data }\n : waitOpts?.ui\n ? { output: waitOpts.ui }\n : {}),\n reason: waitOpts?.reason,\n };\n return config.onUserInput!(pendingInput);\n },\n };\n\n const result = await t.hooks.before(ctx, req, hookOptions);\n if (result.action === \"deny\") {\n return {\n behavior: \"deny\",\n message: (result as { reason?: string }).reason ?? \"Denied\",\n toolUseID: options.toolUseID,\n };\n }\n return {\n behavior: \"allow\",\n updatedInput:\n ((result as { input?: unknown }).input as Record<string, unknown>) ||\n input,\n toolUseID: options.toolUseID,\n };\n }\n\n // No before hook — use specific converters for known tools, generic for others\n const pendingInput =\n toolName === \"AskUserQuestion\"\n ? convertAskUserQuestion(input, options.toolUseID)\n : convertGenericTool(toolName, input, options.toolUseID);\n\n const response = await config.onUserInput!(pendingInput);\n return toPermissionResult(toolName, input, response, options.toolUseID);\n };\n\n return {\n opts: {\n permissionMode: (config.permissionMode ?? \"default\") as\n | \"default\"\n | \"plan\",\n canUseTool,\n },\n toolMap,\n toolInputTracker,\n };\n}\n\n/**\n * Process after hooks for a \"user\" message (tool_result).\n * Returns a map of toolUseId → ToolUiData for enrichment.\n */\nasync function processAfterHooks(\n ctx: Context,\n req: {\n message: any;\n config: ClaudeCodeConfig;\n toolMap: Map<string, ProviderTool>;\n toolInputTracker: Map<\n string,\n { toolName: string; input: Record<string, unknown> }\n >;\n },\n): Promise<Record<string, ToolUiData> | null> {\n const { message, config, toolInputTracker, toolMap } = req;\n if (message.type !== \"user\" || !Array.isArray(message.message?.content))\n return null;\n\n const artifactMap: Record<string, ToolUiData> = {};\n let hasArtifacts = false;\n\n for (const block of message.message.content) {\n const toolUseId = block?.tool_use_id;\n if (!toolUseId) continue;\n\n const tracked = toolInputTracker.get(toolUseId);\n const t = tracked ? toolMap.get(tracked.toolName) : null;\n\n if (t?.hooks?.after) {\n try {\n const afterResult = await t.hooks.after(\n ctx,\n {\n toolName: tracked!.toolName,\n input: tracked!.input,\n output: block.content ?? block.output,\n toolCallId: toolUseId,\n state: {} as unknown,\n },\n { mode: config.permissionMode ?? \"default\", askUser: async () => ({ action: \"allow\" as const }) },\n );\n\n // Bridge ToolUi → ToolUiData for chat messages\n if (afterResult.ui && \"uri\" in afterResult.ui) {\n const { uri, title, data } = afterResult.ui as {\n uri: string;\n title: string;\n data?: unknown;\n };\n const match = uri.match(/^ui:\\/\\/([^/]+)\\/(.+)$/);\n artifactMap[toolUseId] = {\n type: match?.[2] || uri,\n title,\n data,\n };\n hasArtifacts = true;\n }\n } catch (err) {\n logger.sys.error(`After hook error for ${tracked!.toolName}`, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n toolInputTracker.delete(toolUseId);\n }\n\n return hasArtifacts ? artifactMap : null;\n}\n\n// =============================================================================\n// Provider\n// =============================================================================\n\nexport function claudeCodeProvider(config: ClaudeCodeConfig = {}): LLMProvider {\n const useSubscription = config.useSubscription ?? false;\n const apiKey = useSubscription\n ? undefined\n : (config.apiKey ?? process.env.ANTHROPIC_API_KEY);\n\n async function query(\n ctx: Context,\n req: QueryLLMRequest,\n _options?: LLMQueryOptions,\n ): Promise<QueryLLMResponse> {\n const { query: claudeQuery } =\n await import(\"@anthropic-ai/claude-agent-sdk\");\n if (!apiKey && !useSubscription) {\n throw new Error(\n \"Anthropic API key is required. \" +\n \"Provide it via config.apiKey, ANTHROPIC_API_KEY env var, or set useSubscription: true.\",\n );\n }\n\n const startTime = Date.now();\n\n // Extract user message and system prompt\n const userMessage = [...req.messages]\n .reverse()\n .find((m) => m.role === \"user\");\n const prompt = userMessage?.content ?? \"\";\n const systemMessage = req.messages.find((m) => m.role === \"system\");\n const systemPrompt = config.systemPrompt ?? systemMessage?.content ?? \"\";\n\n let aggregatedContent = \"\";\n let lastAssistantContent = \"\";\n let json: string | undefined;\n let sdkError: string | undefined;\n let inputTokens = 0;\n let outputTokens = 0;\n let resultSessionId: string | undefined;\n\n // When resuming, skip setting systemPrompt — SDK uses the original session's prompt\n const isResuming = !!config.session?.resume;\n const systemPromptOption = isResuming\n ? undefined\n : systemPrompt\n ? {\n type: \"preset\" as const,\n preset: \"claude_code\" as const,\n append: typeof systemPrompt === \"string\" ? systemPrompt : \"\",\n }\n : undefined;\n\n // Build permission options (shared helper — hook-aware when tools provided)\n const {\n opts: permissionOptions,\n toolMap,\n toolInputTracker,\n } = buildPermissionOptions(ctx, config);\n\n logger.info(ctx, \"[ClaudeCode] Starting query\", {\n model: req.model,\n hasApiKey: !!apiKey,\n promptLength: typeof prompt === \"string\" ? prompt.length : 0,\n cwd: config.workingDirectory,\n mcpServers: Object.keys(config.mcpServers || {}),\n });\n\n let messageCount = 0;\n try {\n for await (const message of claudeQuery({\n prompt: typeof prompt === \"string\" ? prompt : JSON.stringify(prompt),\n options: {\n model: req.model,\n systemPrompt: systemPromptOption,\n maxTurns: config.maxTurns ?? 50,\n ...permissionOptions,\n ...(config.mcpServers ? { mcpServers: config.mcpServers } : {}),\n ...(config.workingDirectory ? { cwd: config.workingDirectory } : {}),\n ...(hasOutputFormat(config.output, \"json\") && config.output?.schema\n ? {\n outputFormat: {\n type: \"json_schema\" as const,\n schema: config.output.schema,\n },\n }\n : {}),\n ...(config.disallowedTools?.length\n ? { disallowedTools: config.disallowedTools }\n : {}),\n ...(config.abortController\n ? { abortController: config.abortController }\n : {}),\n // Session resume/persistence options\n ...(config.session?.sessionId\n ? { sessionId: config.session.sessionId }\n : {}),\n ...(config.session?.resume ? { resume: config.session.resume } : {}),\n ...(config.session?.persistSession !== undefined\n ? { persistSession: config.session.persistSession }\n : {}),\n ...(config.session?.forkSession\n ? { forkSession: config.session.forkSession }\n : {}),\n env: {\n ...(apiKey ? { ANTHROPIC_API_KEY: apiKey } : {}),\n ...(useSubscription ? {} : { IS_SANDBOX: \"1\" }),\n HOME: process.env.HOME ?? \"\",\n PATH: process.env.PATH ?? \"\",\n TMPDIR: process.env.TMPDIR ?? \"\",\n NODE_ENV: process.env.NODE_ENV ?? \"\",\n },\n debugFile: \"/tmp/claude-code-debug.log\",\n stderr: (data: string) =>\n logger.error(ctx, \"[ClaudeCode stderr]\", { data }),\n },\n })) {\n messageCount++;\n logger.info(ctx, \"[ClaudeCode] SDK message\", {\n count: messageCount,\n type: message.type,\n });\n\n // Skip replayed messages during session resume — they're old history.\n // Still heartbeat so the activity stays alive during replay.\n if ((message as any).isReplay) {\n if (config.heartbeat) config.heartbeat();\n continue;\n }\n\n if (config.heartbeat) {\n config.heartbeat();\n }\n\n // Track tool inputs from \"assistant\" messages for safe tools that bypass canUseTool\n // (SDK auto-approves Read, Glob, Grep without calling canUseTool in default mode)\n if (\n message.type === \"assistant\" &&\n Array.isArray(message.message?.content)\n ) {\n for (const block of message.message.content) {\n if (block?.type === \"tool_use\" && block.id && block.name) {\n if (!toolInputTracker.has(block.id)) {\n toolInputTracker.set(block.id, {\n toolName: block.name,\n input: (block.input || {}) as Record<string, unknown>,\n });\n }\n }\n }\n }\n\n // Process after hooks for tool_result messages — enrich with artifacts\n const artifacts = await processAfterHooks(ctx, {\n message,\n config,\n toolMap,\n toolInputTracker,\n });\n if (artifacts) {\n (message as any)._toolUi = artifacts;\n }\n\n // Forward all SDK messages for rich progress tracking\n if (config.onProgress) {\n await config.onProgress(message);\n // Heartbeat after async progress handling — may take time\n if (config.heartbeat) config.heartbeat();\n }\n\n if (message.type === \"assistant\" && message.message?.content) {\n lastAssistantContent = \"\";\n for (const block of message.message.content) {\n if (typeof block === \"string\") {\n lastAssistantContent += block;\n aggregatedContent += block;\n if (config.onChunk) config.onChunk(block);\n } else if (block.type === \"text\") {\n lastAssistantContent += block.text;\n aggregatedContent += block.text;\n if (config.onChunk) config.onChunk(block.text);\n }\n }\n }\n\n if (message.type === \"result\") {\n // Detect SDK error results (max_turns, budget, etc.)\n const subtype = (message as any).subtype;\n if (subtype && subtype !== \"success\") {\n const errors = (message as any).errors as string[] | undefined;\n sdkError = `Agent ${subtype}${errors?.length ? `: ${errors.join(\", \")}` : \"\"}`;\n }\n\n // Keep structured output separate — don't overwrite text content\n const structuredOutput = (message as any).structured_output;\n if (\n structuredOutput !== undefined &&\n hasOutputFormat(config.output, \"json\")\n ) {\n json =\n typeof structuredOutput === \"string\"\n ? structuredOutput\n : JSON.stringify(structuredOutput);\n }\n\n // Text result from SDK — use as content if we have no assistant text yet\n if (\"result\" in message && !aggregatedContent) {\n aggregatedContent = (message as any).result;\n }\n\n if (\"usage\" in message) {\n const usage = (message as any).usage;\n inputTokens = usage?.input_tokens ?? 0;\n outputTokens = usage?.output_tokens ?? 0;\n }\n\n // Extract session ID for resume support\n resultSessionId = (message as any).session_id;\n }\n }\n } catch (error) {\n logger.error(ctx, \"[ClaudeCode] Query error\", {\n error: error instanceof Error ? error.message : String(error),\n model: req.model,\n apiKeyPresent: !!apiKey,\n cwd: config.workingDirectory,\n mcpServers: Object.keys(config.mcpServers || {}),\n });\n throw error;\n }\n\n logger.info(ctx, \"[ClaudeCode] Query complete\", { messageCount });\n\n return {\n content: lastAssistantContent || aggregatedContent,\n json,\n error: sdkError,\n toolCalls: undefined,\n sessionId: resultSessionId,\n metadata: {\n model: req.model,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n },\n duration: Date.now() - startTime,\n provider: \"claude-code\",\n },\n };\n }\n\n async function* stream(\n ctx: Context,\n req: QueryLLMRequest,\n _options?: LLMQueryOptions,\n ): AsyncGenerator<QueryLLMResponse> {\n const { query: claudeQuery } =\n await import(\"@anthropic-ai/claude-agent-sdk\");\n if (!apiKey && !useSubscription) {\n throw new Error(\n \"Anthropic API key is required. \" +\n \"Provide it via config.apiKey, ANTHROPIC_API_KEY env var, or set useSubscription: true.\",\n );\n }\n\n const startTime = Date.now();\n\n const userMessage = [...req.messages]\n .reverse()\n .find((m) => m.role === \"user\");\n const prompt = userMessage?.content ?? \"\";\n const systemMessage = req.messages.find((m) => m.role === \"system\");\n const systemPrompt = config.systemPrompt ?? systemMessage?.content ?? \"\";\n\n let inputTokens = 0;\n let outputTokens = 0;\n\n // When resuming, skip setting systemPrompt — SDK uses the original session's prompt\n const isResuming = !!config.session?.resume;\n const streamSystemPromptOption = isResuming\n ? undefined\n : systemPrompt\n ? {\n type: \"preset\" as const,\n preset: \"claude_code\" as const,\n append: typeof systemPrompt === \"string\" ? systemPrompt : \"\",\n }\n : undefined;\n\n // Build permission options (shared helper — hook-aware when tools provided)\n const {\n opts: permissionOptions,\n toolMap,\n toolInputTracker,\n } = buildPermissionOptions(ctx, config);\n\n logger.info(ctx, \"[ClaudeCode] Starting stream\", {\n model: req.model,\n hasApiKey: !!apiKey,\n promptLength: typeof prompt === \"string\" ? prompt.length : 0,\n cwd: config.workingDirectory,\n mcpServers: Object.keys(config.mcpServers || {}),\n });\n\n let messageCount = 0;\n try {\n for await (const message of claudeQuery({\n prompt: typeof prompt === \"string\" ? prompt : JSON.stringify(prompt),\n options: {\n model: req.model,\n systemPrompt: streamSystemPromptOption,\n maxTurns: config.maxTurns ?? 50,\n ...permissionOptions,\n ...(config.mcpServers ? { mcpServers: config.mcpServers } : {}),\n ...(config.workingDirectory ? { cwd: config.workingDirectory } : {}),\n ...(hasOutputFormat(config.output, \"json\") && config.output?.schema\n ? {\n outputFormat: {\n type: \"json_schema\" as const,\n schema: config.output.schema,\n },\n }\n : {}),\n ...(config.disallowedTools?.length\n ? { disallowedTools: config.disallowedTools }\n : {}),\n ...(config.abortController\n ? { abortController: config.abortController }\n : {}),\n // Session resume/persistence options\n ...(config.session?.sessionId\n ? { sessionId: config.session.sessionId }\n : {}),\n ...(config.session?.resume ? { resume: config.session.resume } : {}),\n ...(config.session?.persistSession !== undefined\n ? { persistSession: config.session.persistSession }\n : {}),\n ...(config.session?.forkSession\n ? { forkSession: config.session.forkSession }\n : {}),\n env: {\n ...(apiKey ? { ANTHROPIC_API_KEY: apiKey } : {}),\n ...(useSubscription ? {} : { IS_SANDBOX: \"1\" }),\n HOME: process.env.HOME ?? \"\",\n PATH: process.env.PATH ?? \"\",\n TMPDIR: process.env.TMPDIR ?? \"\",\n NODE_ENV: process.env.NODE_ENV ?? \"\",\n },\n debugFile: \"/tmp/claude-code-debug.log\",\n stderr: (data: string) =>\n logger.error(ctx, \"[ClaudeCode stderr]\", { data }),\n },\n })) {\n messageCount++;\n logger.info(ctx, \"[ClaudeCode] SDK message\", {\n count: messageCount,\n type: message.type,\n });\n\n // Skip replayed messages during session resume — they're old history.\n // Still heartbeat so the activity stays alive during replay.\n if ((message as any).isReplay) {\n if (config.heartbeat) config.heartbeat();\n continue;\n }\n\n if (config.heartbeat) config.heartbeat();\n\n // Track tool inputs from \"assistant\" messages for safe tools that bypass canUseTool\n if (\n message.type === \"assistant\" &&\n Array.isArray(message.message?.content)\n ) {\n for (const block of message.message.content) {\n if (block?.type === \"tool_use\" && block.id && block.name) {\n if (!toolInputTracker.has(block.id)) {\n toolInputTracker.set(block.id, {\n toolName: block.name,\n input: (block.input || {}) as Record<string, unknown>,\n });\n }\n }\n }\n }\n\n // Process after hooks for tool_result messages — enrich with artifacts\n const artifacts = await processAfterHooks(ctx, {\n message,\n config,\n toolMap,\n toolInputTracker,\n });\n if (artifacts) {\n (message as any)._toolUi = artifacts;\n }\n\n if (config.onProgress) {\n await config.onProgress(message);\n if (config.heartbeat) config.heartbeat();\n }\n\n // Yield incremental text chunks as Claude Code produces them\n if (message.type === \"assistant\" && message.message?.content) {\n for (const block of message.message.content) {\n const text =\n typeof block === \"string\"\n ? block\n : block.type === \"text\"\n ? block.text\n : \"\";\n if (text) {\n if (config.onChunk) config.onChunk(text);\n yield {\n content: text,\n metadata: {\n model: req.model,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n },\n duration: Date.now() - startTime,\n provider: \"claude-code\",\n },\n };\n }\n }\n }\n\n if (message.type === \"result\") {\n if (\"usage\" in message) {\n const usage = (message as any).usage;\n inputTokens = usage?.input_tokens ?? 0;\n outputTokens = usage?.output_tokens ?? 0;\n }\n // Keep structured output separate from text content\n const structuredOutput = (message as any).structured_output;\n const sc =\n structuredOutput !== undefined &&\n hasOutputFormat(config.output, \"json\")\n ? typeof structuredOutput === \"string\"\n ? structuredOutput\n : JSON.stringify(structuredOutput)\n : undefined;\n // Final yield with updated usage metadata\n yield {\n content: \"\", // Text already yielded incrementally\n json: sc,\n metadata: {\n model: req.model,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n },\n duration: Date.now() - startTime,\n provider: \"claude-code\",\n },\n };\n }\n }\n } catch (error) {\n logger.error(ctx, \"[ClaudeCode] Stream error\", {\n error: error instanceof Error ? error.message : String(error),\n model: req.model,\n apiKeyPresent: !!apiKey,\n cwd: config.workingDirectory,\n mcpServers: Object.keys(config.mcpServers || {}),\n });\n throw error;\n }\n\n logger.info(ctx, \"[ClaudeCode] Stream complete\", { messageCount });\n }\n\n async function getModels(): Promise<Model[]> {\n return claudeCodeModels.list();\n }\n\n return {\n name: \"claude-code\",\n query,\n stream,\n getModels,\n };\n}\n","/**\n * Tools Domain\n * Pure functions for creating and calling tools\n */\nimport type {\n CallTool,\n Context,\n ToolHooks,\n BeforeToolHook,\n AfterToolHook,\n Tool,\n ToolMetadata,\n Schema,\n ToolHookOptions,\n} from \"@jarvis/types\";\n\n// Re-export hook identity functions from types\nexport { before, after } from \"@jarvis/types\";\n\n// =============================================================================\n// extractHooks() - Extract hooks from tools for agent creation\n// =============================================================================\n\nexport function extractHooks<TState = unknown>(\n tools: Tool[],\n): {\n before: Record<string, BeforeToolHook<TState>>;\n after: Record<string, AfterToolHook<TState>>;\n} {\n const before: Record<string, BeforeToolHook<TState>> = {};\n const after: Record<string, AfterToolHook<TState>> = {};\n\n for (const t of tools) {\n if (t.hooks?.before) {\n before[t.name] = t.hooks.before as BeforeToolHook<TState>;\n }\n if (t.hooks?.after) {\n after[t.name] = t.hooks.after as AfterToolHook<TState>;\n }\n }\n\n return { before, after };\n}\n\n// =============================================================================\n// tool() Factory\n// =============================================================================\n\n/**\n * Create a tool with optional colocated hooks.\n *\n * @example\n * ```typescript\n * const myTool = tool({\n * name: \"createGoal\",\n * description: \"Create a new goal\",\n * schema: {\n * input: { type: \"object\", properties: { title: { type: \"string\" } } },\n * output: { type: \"object\", properties: { goalId: { type: \"string\" } } },\n * },\n * call: async (ctx, input) => ({ goalId: \"g-123\" }),\n * metadata: {\n * label: \"Create Goal\",\n * permissions: { roles: [\"editor\"], risk: \"moderate\" },\n * ui: { component: \"goals\", title: \"Goals\" },\n * },\n * hooks: {\n * before: before<MyState>(async (ctx, req, { askUser }) => ({ action: \"allow\" })),\n * after: after<MyState>(async (ctx, req) => ({\n * context: { created: true },\n * state: { goals: [...req.state.goals, req.output] },\n * })),\n * },\n * });\n * ```\n */\nexport function tool<TState = unknown>(config: {\n name: string;\n description: string;\n schema: { input: Schema; output: Schema };\n call?: CallTool;\n hooks?: ToolHooks<TState>;\n metadata?: ToolMetadata;\n build?: (ctx: unknown, req: { tool: Tool; state: TState }) => Tool;\n}): Tool {\n return {\n name: config.name,\n description: config.description,\n input: config.schema.input,\n output: config.schema.output,\n call: config.call,\n hooks: config.hooks,\n metadata: config.metadata,\n build: config.build as Tool[\"build\"],\n };\n}\n\n// =============================================================================\n// buildTools() - Apply build() to tools with current state\n// =============================================================================\n\n/**\n * Build tools by applying schema builders and pre-binding options.\n *\n * Three phases per tool:\n * 1. Apply permissions check via before hook (if metadata.permissions is set)\n * 2. Apply `build()` for schema-only changes (dynamic enums from state)\n * 3. Wrap `call()` to pre-bind options (if call has >= 2 params)\n * 4. Wrap hooks to spread app options flat into hook options\n */\nexport function buildTools(\n ctx: Context,\n req: { tools: Tool[]; state: unknown },\n options?: unknown,\n): Tool[] {\n return req.tools.map((t) => {\n // Phase 0: If tool has permissions, inject a before hook that checks roles/tiers\n const permissions = t.metadata?.permissions;\n if (permissions?.roles?.length || permissions?.tiers?.length) {\n const existingBefore = t.hooks?.before;\n t = {\n ...t,\n hooks: {\n ...t.hooks,\n before: async (hookCtx: Context, hookReq: { toolName: string; input: unknown; toolCallId: string; state: unknown }, hookOpts: ToolHookOptions) => {\n const access = (hookCtx as Context & { access?: { role?: string; tier?: string } }).access;\n const role = access?.role ?? \"\";\n const tier = access?.tier ?? \"free\";\n if (permissions.roles?.length && !permissions.roles.includes(role)) {\n return { action: \"deny\" as const, reason: \"Access denied: insufficient role\" };\n }\n if (permissions.tiers?.length && !permissions.tiers.includes(tier)) {\n return { action: \"deny\" as const, reason: \"Access denied: insufficient tier\" };\n }\n if (existingBefore) return existingBefore(hookCtx, hookReq, hookOpts);\n return { action: \"allow\" as const };\n },\n },\n };\n }\n\n // Phase 1: Apply build (schema-only, no options)\n const built = t.build ? t.build(ctx, { tool: t, state: req.state }) : t;\n if (options == null) return built;\n\n const result = { ...built };\n\n // Phase 2: Wrap call to pre-bind options (if call has >= 2 params)\n if (result.call && result.call.length >= 2) {\n const baseCall = result.call as (\n ctx: Context,\n input: unknown,\n options?: unknown,\n ) => Promise<unknown>;\n result.call = ((ctxArg: Context, input: unknown) =>\n baseCall(ctxArg, input, options)) as CallTool;\n }\n\n // Phase 3: Wrap hooks to spread app options flat into hook options\n if (result.hooks) {\n const baseHooks = result.hooks;\n result.hooks = {\n before: baseHooks.before\n ? async (ctx: Context, req: { toolName: string; input: unknown; toolCallId: string; state: unknown }, hookOpts: ToolHookOptions) =>\n baseHooks.before!(ctx, req, {\n ...hookOpts,\n ...(options as object),\n } as ToolHookOptions)\n : undefined,\n after: baseHooks.after\n ? async (ctx: Context, req: unknown, hookOpts: ToolHookOptions) =>\n baseHooks.after!(ctx, req as Parameters<NonNullable<typeof baseHooks.after>>[1], {\n ...hookOpts,\n ...(options as object),\n } as ToolHookOptions)\n : undefined,\n };\n }\n\n return result;\n });\n}\n\n/**\n * Call a tool directly (for testing or simple invocation).\n */\nexport async function call(req: { tool: Tool; input: unknown }): Promise<unknown> {\n if (!req.tool.call) {\n throw new Error(\n `Tool ${req.tool.name} has no call function.`,\n );\n }\n return await req.tool.call(req.input);\n}\n","/**\n * Plan Tool\n * Platform-level tool for presenting plans to users for approval\n *\n * This tool allows agents to present a plan (list of steps) to the user\n * and wait for approval/modification before proceeding.\n *\n * @example\n * ```typescript\n * import { planTool } from \"@jarvis/sdk\";\n *\n * const tools = [planTool, ...otherTools];\n *\n * // Agent can now use the plan tool:\n * // LLM: \"I'll create a plan for you to review\"\n * // Tool call: plan({ title: \"...\", steps: [...], reasoning: \"...\" })\n * // → User sees PlanPanel in UI\n * // → User approves/modifies/rejects\n * // → Agent continues based on user response\n * ```\n */\nimport { Context } from \"@jarvis/types\";\nimport { tool } from \"./tools\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * A single step in a plan\n */\nexport interface PlanStep {\n /** Unique identifier for the step */\n id: string;\n /** Step title (brief description) */\n title: string;\n /** Optional detailed description */\n description?: string;\n /** Optional category for grouping/styling */\n category?: string;\n}\n\n/**\n * Input for the plan tool\n */\nexport interface PlanInput {\n /** Plan title shown in the header */\n title: string;\n /** List of steps in the plan */\n steps: PlanStep[];\n /** Optional reasoning explaining why this plan */\n reasoning?: string;\n}\n\n/**\n * Output from the plan tool\n */\nexport interface PlanOutput {\n /** Plan title */\n title: string;\n /** Plan items (steps mapped to items) */\n items: PlanStep[];\n /** Optional reasoning */\n reasoning?: string;\n}\n\n// =============================================================================\n// SCHEMA\n// =============================================================================\n\nconst planInputSchema = {\n type: \"object\" as const,\n properties: {\n title: {\n type: \"string\",\n description: \"A brief title for the plan\",\n },\n steps: {\n type: \"array\",\n description: \"The steps in the plan\",\n items: {\n type: \"object\",\n properties: {\n id: {\n type: \"string\",\n description: \"Unique identifier for this step\",\n },\n title: {\n type: \"string\",\n description: \"Brief title for the step\",\n },\n description: {\n type: \"string\",\n description: \"Detailed description of what this step involves\",\n },\n category: {\n type: \"string\",\n description:\n \"Optional category for grouping (e.g., 'setup', 'implementation', 'testing')\",\n },\n },\n required: [\"id\", \"title\"],\n },\n },\n reasoning: {\n type: \"string\",\n description: \"Explanation of why this plan was chosen\",\n },\n },\n required: [\"title\", \"steps\"],\n};\n\nconst planOutputSchema = {\n type: \"object\" as const,\n properties: {\n title: { type: \"string\" },\n items: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n title: { type: \"string\" },\n description: { type: \"string\" },\n category: { type: \"string\" },\n },\n },\n },\n reasoning: { type: \"string\" },\n },\n};\n\n// =============================================================================\n// TOOL\n// =============================================================================\n\n/**\n * Plan tool for presenting plans to users\n *\n * Usage:\n * - Agent calls this tool to present a plan\n * - Tool output is shown in PlanPanel UI component\n * - User can approve, reject, or modify the plan\n * - Agent receives user's response via the after hook\n */\nexport const planTool = tool({\n name: \"plan\",\n description:\n \"Present a plan to the user for approval before executing. Use this when you need user confirmation before proceeding with a multi-step task. The user can approve, reject, or suggest modifications to the plan.\",\n schema: {\n input: planInputSchema,\n output: planOutputSchema,\n },\n // The call function simply passes through the input as output\n // The actual plan review happens in the after hook via wait()\n call: async (_ctx: Context, input: PlanInput): Promise<PlanOutput> => ({\n title: input.title,\n items: input.steps,\n reasoning: input.reasoning,\n }),\n // Hooks handle the human-in-the-loop approval flow\n hooks: {\n // After hook waits for user approval\n after: async (ctx, req, options) => {\n const planOutput = req.output as PlanOutput;\n\n // Wait for user input (shows PlanPanel in UI)\n const userInput = await options.askUser({\n reason: planOutput.title,\n data: planOutput,\n });\n\n // Handle user response\n if (!userInput || userInput.action === \"deny\") {\n return {\n context: {\n status: \"denied\",\n message: userInput?.feedback || \"Plan was rejected by user\",\n },\n status: \"denied\",\n message: userInput?.feedback || \"Plan was rejected by user\",\n };\n }\n\n if (userInput.action === \"modify\") {\n return {\n context: {\n status: \"modify\",\n userFeedback: userInput.feedback,\n originalPlan: planOutput,\n },\n status: \"modify\",\n message: userInput.feedback || \"User requested modifications\",\n };\n }\n\n // Approved\n return {\n context: {\n status: \"approved\",\n plan: planOutput,\n message: \"Plan approved by user. Proceed with execution.\",\n },\n ui: {\n uri: \"ui://sdk/plan\",\n title: planOutput.title,\n data: planOutput,\n },\n };\n },\n },\n // Metadata for UI display\n metadata: {\n describe: (ctx, req) => {\n const input = req.input as unknown as PlanInput;\n if (req.status === \"running\") {\n return `Creating plan: ${input.title}`;\n }\n if (req.status === \"completed\") {\n return `Plan \"${input.title}\" ready for review`;\n }\n return undefined;\n },\n },\n});\n","/**\n * Ask User Tool\n * Platform-level tool for asking users structured questions\n *\n * This tool allows agents to ask clarifying questions with predefined options,\n * pausing execution until the user responds. Each question appears as a tab\n * with selectable options and an \"Other\" free-text input.\n *\n * @example\n * ```typescript\n * import { askUserTool } from \"@jarvis/sdk\";\n *\n * const tools = [askUserTool, ...otherTools];\n *\n * // Agent can now use the askUser tool:\n * // LLM: \"I need to understand your preference\"\n * // Tool call: askUser({ questions: [{ header: \"Approach\", question: \"...\", options: [...] }] })\n * // → User sees AskUserPanel in UI\n * // → User selects options or types custom answer\n * // → Agent continues with user's answers\n * ```\n */\nimport { tool } from \"./tools\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * A single option within a question\n */\nexport interface AskUserOption {\n /** Display label for the option */\n label: string;\n /** Optional description explaining the option */\n description?: string;\n}\n\n/**\n * A single question with options\n */\nexport interface AskUserQuestion {\n /** Short label displayed as tab header (max ~12 chars) */\n header: string;\n /** Full question text */\n question: string;\n /** Available options (2-4) */\n options: AskUserOption[];\n /** Whether user can select multiple options (default: false) */\n multiSelect?: boolean;\n}\n\n/**\n * Input for the askUser tool\n */\nexport interface AskUserInput {\n /** Questions to ask (1-4) */\n questions: AskUserQuestion[];\n}\n\n/**\n * A single answer from the user\n */\nexport interface AskUserAnswer {\n /** Header of the question being answered */\n header: string;\n /** Selected option label(s) */\n selected: string[];\n /** Custom text if user chose \"Other\" */\n customText?: string;\n}\n\n/**\n * Output from the askUser tool\n */\nexport interface AskUserOutput {\n /** The questions that were asked */\n questions: AskUserQuestion[];\n /** User's answers (populated after user responds) */\n answers?: AskUserAnswer[];\n}\n\n// =============================================================================\n// SCHEMA\n// =============================================================================\n\nconst askUserInputSchema = {\n type: \"object\" as const,\n properties: {\n questions: {\n type: \"array\",\n description: \"Questions to ask the user (1-4 questions)\",\n minItems: 1,\n maxItems: 4,\n items: {\n type: \"object\",\n properties: {\n header: {\n type: \"string\",\n description:\n \"Short label for the tab header (e.g., 'Approach', 'Priority')\",\n },\n question: {\n type: \"string\",\n description: \"The full question to ask the user\",\n },\n options: {\n type: \"array\",\n description:\n \"Available options (2-4). User always has an 'Other' free-text option automatically.\",\n minItems: 2,\n maxItems: 4,\n items: {\n type: \"object\",\n properties: {\n label: {\n type: \"string\",\n description: \"Option display label\",\n },\n description: {\n type: \"string\",\n description: \"Optional explanation of this option\",\n },\n },\n required: [\"label\"],\n },\n },\n multiSelect: {\n type: \"boolean\",\n description:\n \"Whether user can select multiple options (default: false)\",\n },\n },\n required: [\"header\", \"question\", \"options\"],\n },\n },\n },\n required: [\"questions\"],\n};\n\nconst askUserOutputSchema = {\n type: \"object\" as const,\n properties: {\n questions: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n header: { type: \"string\" },\n question: { type: \"string\" },\n options: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n label: { type: \"string\" },\n description: { type: \"string\" },\n },\n },\n },\n multiSelect: { type: \"boolean\" },\n },\n },\n },\n answers: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n header: { type: \"string\" },\n selected: { type: \"array\", items: { type: \"string\" } },\n customText: { type: \"string\" },\n },\n },\n },\n },\n};\n\n// =============================================================================\n// TOOL\n// =============================================================================\n\n/**\n * Ask User tool for structured questions\n *\n * Usage:\n * - Agent calls this tool to ask the user questions\n * - Tool output is shown in AskUserPanel UI component\n * - User can select options or type custom answers\n * - Agent receives user's answers via the after hook\n */\nexport const askUserTool = tool({\n name: \"askUser\",\n description: `Ask the user clarifying questions when you need their input to proceed. Use this when the request is ambiguous, you need a preference between approaches, or the scope/priority is unclear. Each question has predefined options plus a free-text 'Other' option. Do NOT use this for plan approval (use exitPlanMode instead) or internal reasoning (use think instead).\n\nGuidelines:\n- Do NOT ask questions you can resolve using available tools\n- Prefer making reasonable defaults over asking — only ask when the choice genuinely matters\n- Keep header labels concise (1-4 words like 'Approach', 'Priority')\n- Mark the recommended option with '(Recommended)' suffix\n- In plan mode, questions should relate to the plan being developed`,\n schema: {\n input: askUserInputSchema,\n output: askUserOutputSchema,\n },\n // Pass-through: returns questions as output for UI rendering\n call: async (_ctx, input: AskUserInput): Promise<AskUserOutput> => ({\n questions: input.questions,\n }),\n // After hook waits for user answers\n hooks: {\n after: async (ctx, req, options) => {\n const output = req.output as AskUserOutput;\n\n // Wait for user input (shows AskUserPanel in UI)\n const userInput = await options.askUser({\n reason:\n output.questions.length === 1\n ? output.questions[0]!.question\n : `${output.questions.length} questions to answer`,\n data: output,\n });\n\n // Handle user skip/cancel\n if (!userInput || userInput.action === \"deny\") {\n return {\n context: {\n status: \"skipped\",\n message:\n userInput?.feedback ||\n \"User skipped the questions. Proceed with your best judgment.\",\n },\n status: \"denied\",\n message: userInput?.feedback || \"User skipped the questions\",\n };\n }\n\n // Extract answers from user response\n const answers = (userInput.data as { answers?: AskUserAnswer[] })\n ?.answers;\n\n if (!answers || answers.length === 0) {\n return {\n context: {\n status: \"skipped\",\n message: \"No answers provided. Proceed with your best judgment.\",\n },\n status: \"denied\",\n message: \"No answers provided\",\n };\n }\n\n // Format answers for LLM context\n const formattedAnswers = answers\n .map((a) => {\n const selection =\n a.selected.length > 0\n ? a.selected.join(\", \")\n : a.customText || \"No selection\";\n return `${a.header}: ${selection}`;\n })\n .join(\"\\n\");\n\n return {\n context: {\n status: \"answered\",\n answers,\n summary: formattedAnswers,\n message: `User answered:\\n${formattedAnswers}`,\n },\n ui: {\n uri: \"ui://sdk/ask-user\",\n title: \"User Answers\",\n data: { questions: output.questions, answers },\n },\n };\n },\n },\n // Metadata for UI display\n metadata: {\n permissions: { risk: \"safe\" },\n describe: (ctx, req) => {\n const input = req.input as unknown as AskUserInput;\n if (req.status === \"running\") {\n return input.questions?.length === 1\n ? `Asking: ${input.questions[0]!.header}`\n : `Asking ${input.questions?.length || 0} questions`;\n }\n if (req.status === \"completed\") {\n const output = req.output as AskUserOutput;\n if (output?.answers) {\n return `Answered ${output.answers.length} question${output.answers.length !== 1 ? \"s\" : \"\"}`;\n }\n return \"Questions skipped\";\n }\n return undefined;\n },\n },\n});\n","/**\n * Think Tool\n *\n * Platform-level internal reasoning tool. No side effects.\n * The agent uses this to organize thoughts, reflect, and plan\n * before taking action. Hidden from conversation UI.\n */\n\nimport { Context } from \"@jarvis/types\";\n\nimport { tool } from \"./tools\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ThinkInput {\n thought: string;\n}\n\nexport interface ThinkOutput {\n acknowledged: boolean;\n}\n\n// =============================================================================\n// Schemas\n// =============================================================================\n\nconst thinkInputSchema = {\n type: \"object\" as const,\n properties: {\n thought: {\n type: \"string\",\n description: \"Your internal reasoning, reflection, or planning\",\n },\n },\n required: [\"thought\"],\n};\n\nconst thinkOutputSchema = {\n type: \"object\" as const,\n properties: {\n acknowledged: { type: \"boolean\" },\n },\n};\n\n// =============================================================================\n// Tool\n// =============================================================================\n\n/**\n * Internal reasoning tool — no side effects, hidden from UI.\n * Use for organizing thoughts before acting.\n */\nexport const thinkTool = tool({\n name: \"think\",\n description: `Use this tool for internal reasoning, reflection, and planning your next steps. No side effects — output is never shown to the user.\n\nGood uses:\n- Breaking down complex problems into steps\n- Evaluating trade-offs between approaches\n- Synthesizing information from multiple tool results\n- Planning multi-step operations before acting\n\nThis consumes tokens like any other tool call. Use for genuinely complex reasoning, not simple decisions.`,\n schema: {\n input: thinkInputSchema,\n output: thinkOutputSchema,\n },\n call: async (_ctx: Context, _input: ThinkInput) => ({ acknowledged: true }),\n metadata: { hidden: true },\n});\n","/**\n * Plan Mode Tools\n *\n * enterPlanMode / exitPlanMode — explicit plan-first mode.\n * When active, only non-destructive + safe tools are available.\n */\n\nimport type { AgentMode } from \"@jarvis/types\";\nimport { tool, after } from \"./tools\";\n\n// =============================================================================\n// enterPlanMode\n// =============================================================================\n\nexport const enterPlanModeTool = tool({\n name: \"enterPlanMode\",\n description: `Enter planning mode to research and design before taking action. Only non-destructive and safe tools are available until exitPlanMode is called.\n\nWhen to use:\n- Complex tasks with multiple steps or approaches\n- Ambiguous requirements needing exploration\n- Tasks where the user's preference between approaches matters\n- Unfamiliar domains requiring research first\n\nWhen NOT to use:\n- Simple, direct requests with clear intent\n- Follow-up actions on an already-agreed plan\n- Quick questions or lookups\n\nDecision rule: If you're unsure how to approach the task, enter plan mode. The cost of unnecessary planning is low; the cost of a wrong approach is high.`,\n schema: {\n input: { type: \"object\" as const, properties: {} },\n output: {\n type: \"object\" as const,\n properties: { mode: { type: \"string\" } },\n },\n },\n call: async () => ({ mode: \"plan\" as AgentMode }),\n hooks: {\n after: after<{ mode?: AgentMode; previousMode?: AgentMode }>(async (_ctx, _req) => ({\n context: {\n mode: \"plan\",\n message: `Plan mode is now active. Only non-destructive tools are available.\nYour next steps:\n1. Research the task using available tools\n2. Understand the current state and constraints\n3. Identify the best approach\n4. Draft a step-by-step plan\n5. Present the plan to the user\n6. Call exitPlanMode when the plan is approved`,\n },\n state: { mode: \"plan\" as AgentMode, previousMode: \"auto\" as AgentMode },\n })),\n },\n metadata: {\n label: \"Enter Plan Mode\",\n permissions: { risk: \"safe\" },\n },\n});\n\n// =============================================================================\n// exitPlanMode\n// =============================================================================\n\nexport const exitPlanModeTool = tool({\n name: \"exitPlanMode\",\n description: `Exit planning mode and signal the plan is ready for execution. All tools become available after exit.\n\nBefore calling this:\n- You should have researched and understood the task\n- You should have presented a clear plan to the user\n- The user should have had a chance to review or adjust\n\nAfter exit: Execute the plan step by step.`,\n schema: {\n input: { type: \"object\" as const, properties: {} },\n output: {\n type: \"object\" as const,\n properties: { mode: { type: \"string\" } },\n },\n },\n call: async () => ({ mode: \"auto\" as AgentMode }),\n hooks: {\n after: after<{ mode?: AgentMode; previousMode?: AgentMode }>(async (_ctx, _req) => ({\n context: {\n mode: \"auto\",\n message: \"Plan mode exited. All tools are now available. Execute the plan you presented, working through it step by step.\",\n },\n state: { mode: \"auto\" as AgentMode, previousMode: undefined },\n })),\n },\n metadata: {\n label: \"Exit Plan Mode\",\n permissions: { risk: \"safe\" },\n },\n});\n","/**\n * Agent Tool\n *\n * Tool for spawning a sub-agent of the current agent with a different task.\n * The sub-agent runs with the same agent config but can have filtered tools.\n */\n\nimport type { SubAgentRequest, SubAgentResponse, SubAgentFn } from \"./agent.tools.types\";\nimport { tool } from \"./tools\";\n\n// =============================================================================\n// agentTool — spawn a sub-agent of self\n// =============================================================================\n\n/**\n * Spawn a sub-agent with a task and optional tool filtering.\n *\n * @example\n * ```typescript\n * import { agentTool, buildTools } from \"@jarvis/sdk\";\n *\n * const tools = buildTools(ctx, {\n * tools: [agentTool, ...otherTools],\n * state: currentState,\n * }, {\n * spawnSubAgent: async (task, context, options) => {\n * return { message: \"Done\", success: true, requestCount: 0 };\n * },\n * });\n * ```\n */\nexport const agentTool = tool({\n name: \"agent\",\n description: `Spawn a sub-agent to handle a task independently.\n\nGuidelines:\n- Use filters.tools to restrict tools for focused tasks\n- Use model override for cost optimization: smaller model for simple tasks, larger for complex reasoning\n- Provide complete context in the task description — the sub-agent doesn't share your conversation history\n- After the sub-agent completes, synthesize its findings before acting — don't just pass through results`,\n schema: {\n input: {\n type: \"object\",\n properties: {\n task: {\n type: \"string\",\n description: \"The task to delegate. Be specific and include all relevant context.\",\n },\n context: {\n type: \"object\",\n description: \"Additional context to pass to the sub-agent\",\n },\n model: {\n type: \"string\",\n description:\n \"Override model ID for the sub-agent (e.g., 'claude-sonnet-4-20250514', 'gpt-4o')\",\n },\n filters: {\n type: \"object\",\n description: \"Filters for the sub-agent\",\n properties: {\n tools: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Restrict which tools the sub-agent can use (whitelist by tool name)\",\n },\n },\n },\n },\n required: [\"task\"],\n },\n output: {\n type: \"object\",\n properties: {\n message: { type: \"string\" },\n success: { type: \"boolean\" },\n requestCount: { type: \"number\" },\n ui: { type: \"object\" },\n },\n },\n },\n\n call: async (_ctx: unknown, input: unknown, options?: Record<string, unknown>) => {\n const { task, context, model, filters } = input as SubAgentRequest;\n const spawnSubAgent = options?.spawnSubAgent as SubAgentFn | undefined;\n if (!spawnSubAgent) {\n throw new Error(\"spawnSubAgent callback not provided via buildTools options\");\n }\n return spawnSubAgent(task, context, { model, filters });\n },\n\n hooks: {\n before: async (_ctx: unknown, req: { input: unknown }) => ({\n action: \"allow\" as const,\n input: req.input,\n }),\n after: async (_ctx: unknown, req: { input: unknown; output: unknown }) => {\n const output = req.output as SubAgentResponse;\n return {\n context: {\n message: output.message,\n success: output.success,\n requestCount: output.requestCount,\n },\n ui: output.ui,\n };\n },\n },\n});\n","/**\n * Skills Domain\n * Factory function for creating skills with collection and import methods.\n *\n * The skill() factory is both a creator and a namespace:\n * - skill({...}) — create a skill inline\n * - skill.add(s) — add a skill to the registry\n * - skill.list() — get all registered skills\n * - skill.get(id) — get a skill by ID\n */\n\nimport type { Skill, Prompt, SkillHooks } from \"@jarvis/types\";\n\nimport type { Tool } from \"@jarvis/types\"; // Used by SkillConfig\n\n// =============================================================================\n// skillHooks() Factory\n// =============================================================================\n\n/**\n * Create a skill hooks container (type-safe factory).\n * Mirrors the hooks() factory for tools.\n *\n * @example\n * ```typescript\n * import { skill, skillHooks } from \"@jarvis/sdk\";\n * import type { OrchestratorState } from \"./orchestrator.types\";\n *\n * const mySkill = skill({\n * id: \"my-skill\",\n * // ...\n * hooks: skillHooks<OrchestratorState>({\n * before: async (ctx, req, options) => ({\n * action: \"allow\",\n * messages: [{ role: \"system\", content: `State: ${JSON.stringify(ctx.state)}` }],\n * }),\n * after: async (ctx, req, options) => ({\n * context: { message: req.message },\n * state: req.skillState,\n * }),\n * }),\n * });\n * ```\n */\nexport function skillHooks<TState = unknown>(\n config: SkillHooks<TState>\n): SkillHooks<TState> {\n return config;\n}\n\n// =============================================================================\n// Internal Registry\n// =============================================================================\n\nconst registry = new Map<string, Skill>();\n\n// =============================================================================\n// skill() Factory + Namespace\n// =============================================================================\n\ninterface SkillConfig {\n id: string;\n name: string;\n description: string;\n prompt: Prompt;\n tools: Tool[];\n maxIterations?: number;\n version?: string;\n author?: string;\n tags?: string[];\n hooks?: SkillHooks<unknown>;\n}\n\n/**\n * Create a skill with typed configuration\n *\n * Skills are procedural knowledge - prompts and methodology that transform\n * general-purpose agents into specialists.\n *\n * @example\n * ```typescript\n * import { skill, tool, prompt } from \"@jarvis/sdk\";\n *\n * // Inline definition\n * export const codeReviewSkill = skill({\n * id: \"code-review\",\n * name: \"Code Review\",\n * description: \"Systematic code review\",\n * prompt: codeReviewPrompt,\n * tools: [analyzeCodeTool],\n * maxIterations: 5,\n * });\n *\n * // Import from directory\n * const analyticsSkill = await skill.fromDir(\"./skills/analytics\");\n *\n * // Add to registry\n * skill.add(codeReviewSkill);\n *\n * // Load (fromDir + add)\n * await skill.load(\"./skills/research\");\n *\n * // Query registry\n * skill.list(); // -> Skill[]\n * skill.get(\"code-review\"); // -> Skill | undefined\n * ```\n */\nfunction createSkill(config: SkillConfig): Skill {\n return {\n id: config.id,\n name: config.name,\n description: config.description,\n prompt: config.prompt,\n tools: config.tools,\n maxIterations: config.maxIterations,\n version: config.version,\n author: config.author,\n tags: config.tags,\n hooks: config.hooks,\n };\n}\n\n// =============================================================================\n// Collection Methods\n// =============================================================================\n\n/**\n * Add a skill to the internal registry.\n */\nfunction add(s: Skill): Skill {\n registry.set(s.id, s);\n return s;\n}\n\n/**\n * Get all registered skills.\n */\nfunction list(): Skill[] {\n return [...registry.values()];\n}\n\n/**\n * Get a registered skill by ID.\n */\nfunction get(id: string): Skill | undefined {\n return registry.get(id);\n}\n\n// =============================================================================\n// Export: skill as callable + namespace\n// =============================================================================\n\nexport const skill = Object.assign(createSkill, {\n add,\n list,\n get,\n});\n","/**\n * Mustache Renderer\n * Simple mustache-style template renderer for prompts\n */\n\nimport type {\n PromptRenderer,\n RenderPromptRequest,\n RenderPromptResponse,\n ValidatePromptRequest,\n ValidatePromptResponse,\n Message,\n} from \"@jarvis/types\";\n\n/**\n * Render a mustache template string with variables\n * Supports:\n * - Simple variables: {{variable}}\n * - Conditional sections: {{#variable}}content{{/variable}} - render if truthy\n * - Inverted sections: {{^variable}}content{{/variable}} - render if falsy\n */\nexport function renderTemplate(template: string, args: Record<string, unknown>): string {\n let result = template;\n\n // 1. Handle inverted sections {{^variable}}...{{/variable}} (render if falsy)\n result = result.replace(\n /\\{\\{\\^(\\w+)\\}\\}([\\s\\S]*?)\\{\\{\\/\\1\\}\\}/g,\n (_match, key, content) => {\n const value = args[key];\n // Render content if value is falsy or empty array/string\n if (!value || (Array.isArray(value) && value.length === 0) || value === \"\") {\n return renderTemplate(content, args);\n }\n return \"\";\n }\n );\n\n // 2. Handle conditional sections {{#variable}}...{{/variable}}\n result = result.replace(\n /\\{\\{#(\\w+)\\}\\}([\\s\\S]*?)\\{\\{\\/\\1\\}\\}/g,\n (_match, key, content) => {\n const value = args[key];\n // Skip if value is falsy or empty array/string\n if (!value || (Array.isArray(value) && value.length === 0) || value === \"\") {\n return \"\";\n }\n // Render content with variables substituted\n return renderTemplate(content, args);\n }\n );\n\n // 3. Handle simple variables {{variable}}\n result = result.replace(/\\{\\{(\\w+)\\}\\}/g, (_match, key) => {\n const value = args[key];\n if (value === undefined || value === null) {\n return \"\";\n }\n return String(value);\n });\n\n return result;\n}\n\n/**\n * Render a message with mustache variables\n */\nfunction renderMessage(message: Message, args: Record<string, unknown>): Message {\n const content = typeof message.content === \"string\"\n ? renderTemplate(message.content, args)\n : message.content ?? \"\";\n\n return {\n ...message,\n content,\n } as Message;\n}\n\n/**\n * Create a mustache renderer instance\n */\nexport function mustacheRenderer(): PromptRenderer {\n return {\n name: \"mustache\",\n\n async render(request: RenderPromptRequest): Promise<RenderPromptResponse> {\n const { prompt, args } = request;\n\n // If prompt has messages, render each message\n if (prompt.messages && prompt.messages.length > 0) {\n const messages = prompt.messages.map((msg) => renderMessage(msg, args));\n return {\n messages,\n output: prompt.output,\n metadata: {\n promptId: prompt.id,\n promptName: prompt.name,\n version: prompt.version || \"1.0.0\",\n provider: \"mustache\",\n },\n };\n }\n\n // If prompt has content, render as a single system message\n if (prompt.content) {\n const renderedContent = renderTemplate(prompt.content, args);\n return {\n messages: [{ role: \"system\", content: renderedContent }],\n output: prompt.output,\n metadata: {\n promptId: prompt.id,\n promptName: prompt.name,\n version: prompt.version || \"1.0.0\",\n provider: \"mustache\",\n },\n };\n }\n\n // No content to render\n return {\n messages: [],\n output: prompt.output,\n metadata: {\n promptId: prompt.id,\n promptName: prompt.name,\n version: prompt.version || \"1.0.0\",\n provider: \"mustache\",\n },\n };\n },\n\n async validate(request: ValidatePromptRequest): Promise<ValidatePromptResponse> {\n const { prompt, args } = request;\n\n // Check if all required variables are provided\n if (prompt.input && prompt.input.properties) {\n const required: string[] = Array.isArray(prompt.input.required)\n ? prompt.input.required\n : [];\n for (const key of required) {\n if (args[key] === undefined) {\n return {\n valid: false,\n message: `Missing required variable: ${key}`,\n };\n }\n }\n }\n\n return { valid: true };\n },\n };\n}\n\n/**\n * Default mustache renderer instance\n */\nexport const defaultMustacheRenderer = mustacheRenderer();\n","/**\n * Reference Factory\n *\n * Factory for defining reference types with metadata and creation logic.\n * Follows the same config pattern as entity(), resolver(), tool(), etc.\n *\n * @example\n * ```typescript\n * import { ref } from \"@jarvis/sdk\";\n * import type { DateReference } from \"@jarvis/types\";\n *\n * export const dateReference = ref<DateReference>({\n * type: \"date\",\n * label: \"Date\",\n * icon: \"calendar\",\n * color: \"purple\",\n * displayName: (input) => formatDateStr(input.date),\n * });\n *\n * // Usage:\n * const myDate = dateReference.create({ date: \"2024-01-01\" });\n * ```\n */\n\nimport type {\n Reference,\n ReferenceType,\n RefConfig,\n Ref,\n EntityReference,\n DateReference,\n DateRangeReference,\n FileReference,\n UrlReference,\n TextReference,\n ResolvedReference,\n Resolver,\n} from \"@jarvis/types\";\n\n// =============================================================================\n// Internal Helpers\n// =============================================================================\n\nfunction formatDateStr(date: string): string {\n return new Date(date).toLocaleDateString(undefined, {\n weekday: \"short\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\n/** Format a date for LLM context display */\nfunction formatDateOnly(dateStr: unknown): string {\n if (!dateStr) return \"N/A\";\n try {\n const d = new Date(dateStr as string);\n return d.toLocaleDateString(\"en-US\", {\n weekday: \"short\",\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n } catch {\n return String(dateStr);\n }\n}\n\n/** Fallback formatter — selective JSON (exclude noisy fields) */\nfunction formatGeneric(name: string, type: string, data: unknown): string {\n const lines = [`### ${type}: ${name}`];\n\n if (data && typeof data === \"object\") {\n const cleanData = { ...(data as Record<string, unknown>) };\n delete cleanData.id;\n delete cleanData.userId;\n delete cleanData.createdAt;\n delete cleanData.updatedAt;\n delete cleanData.deletedAt;\n\n lines.push(\"```json\");\n lines.push(JSON.stringify(cleanData, null, 2));\n lines.push(\"```\");\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n// =============================================================================\n// Factory\n// =============================================================================\n\n/**\n * Define a reference type with metadata and creation logic.\n *\n * Returns a Ref definition with `.create()` for instantiation\n * and metadata fields (label, icon, color, format) for UI/LLM use.\n */\nexport function ref<T extends Reference>(config: RefConfig<T>): Ref<T> {\n return {\n type: config.type,\n label: config.label,\n icon: config.icon,\n color: config.color,\n format: config.format,\n create: (input) => {\n const displayName =\n input.displayName || config.displayName?.(input) || \"\";\n return {\n id: Math.random().toString(36).substring(2, 10),\n type: config.type,\n displayName,\n createdAt: new Date().toISOString(),\n ...input,\n } as T;\n },\n };\n}\n\n// =============================================================================\n// Reference Definitions\n// =============================================================================\n\nexport const entityReference = ref<EntityReference>({\n type: \"entity\",\n label: \"Entity\",\n icon: \"box\",\n color: \"blue\",\n format: (displayName: string, data: unknown) => {\n const d = data as Record<string, unknown>;\n const lines = [`### Entity: ${displayName}`];\n if (d.id) lines.push(`- **Entity ID**: \\`${d.id}\\``);\n if (d.entityType) lines.push(`- **Entity Type**: ${d.entityType}`);\n\n const cleanData = { ...d };\n delete cleanData.id;\n delete cleanData.userId;\n delete cleanData.createdAt;\n delete cleanData.updatedAt;\n delete cleanData.deletedAt;\n delete cleanData.entityType;\n\n if (Object.keys(cleanData).length > 0) {\n lines.push(\"```json\");\n lines.push(JSON.stringify(cleanData, null, 2));\n lines.push(\"```\");\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n },\n});\n\nexport const dateReference = ref<DateReference>({\n type: \"date\",\n label: \"Date\",\n icon: \"calendar\",\n color: \"purple\",\n displayName: (input) => formatDateStr(input.date),\n format: (name: string, data: unknown) => {\n const d = data as Record<string, unknown>;\n const lines = [`### Date: ${name}`];\n\n if (d.date) lines.push(`- **Date**: ${formatDateOnly(d.date)}`);\n if (d.events && Array.isArray(d.events))\n lines.push(`- **Events on this date**: ${d.events.length}`);\n if (d.tasks && Array.isArray(d.tasks))\n lines.push(`- **Tasks due**: ${d.tasks.length}`);\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n },\n});\n\nexport const dateRangeReference = ref<DateRangeReference>({\n type: \"dateRange\",\n label: \"Date Range\",\n icon: \"calendar\",\n color: \"purple\",\n displayName: (input) =>\n `${formatDateStr(input.startDate)} - ${formatDateStr(input.endDate)}`,\n});\n\nexport const fileReference = ref<FileReference>({\n type: \"file\",\n label: \"File\",\n icon: \"file\",\n color: \"gray\",\n displayName: (input) => input.path.split(\"/\").pop() || input.path,\n});\n\nexport const urlReference = ref<UrlReference>({\n type: \"url\",\n label: \"URL\",\n icon: \"link\",\n color: \"cyan\",\n displayName: (input) => new URL(input.url).hostname,\n});\n\nexport const textReference = ref<TextReference>({\n type: \"text\",\n label: \"Text\",\n icon: \"text\",\n color: \"gray\",\n displayName: (input) =>\n input.content.length > 30\n ? input.content.slice(0, 30) + \"...\"\n : input.content,\n});\n\n// =============================================================================\n// Collection\n// =============================================================================\n\nconst allRefs: Ref<Reference>[] = [\n entityReference as Ref<Reference>,\n dateReference as Ref<Reference>,\n dateRangeReference as Ref<Reference>,\n fileReference as Ref<Reference>,\n urlReference as Ref<Reference>,\n textReference as Ref<Reference>,\n];\n\nexport const references = {\n // Definitions\n entity: entityReference,\n date: dateReference,\n dateRange: dateRangeReference,\n file: fileReference,\n url: urlReference,\n text: textReference,\n\n /** Format reference for display */\n format: (r: Reference): string => {\n const meta = references.get(r.type);\n return meta ? `[${meta.icon}] ${r.displayName}` : r.displayName;\n },\n\n /** List all ref definitions */\n list: (): Ref<Reference>[] => allRefs,\n\n /** Get ref definition by type */\n get: (type: ReferenceType): Ref<Reference> | undefined =>\n allRefs.find((r) => r.type === type),\n\n /**\n * Format resolved references for LLM context.\n * Priority: resolver format → ref definition format → generic JSON fallback.\n */\n \n formatResolved: (\n resolved: ResolvedReference[],\n resolverDefs?: Resolver<Reference, unknown>[],\n ): string => {\n if (resolved.length === 0) return \"\";\n\n const sections: string[] = [\"## Referenced Context\\n\"];\n\n for (const r of resolved) {\n if (!r.resolved || !r.data) {\n sections.push(\n `### ${r.reference.displayName} (${r.reference.type}) - NOT FOUND`,\n );\n sections.push(`> ${r.error || \"Could not resolve this reference\"}`);\n sections.push(\n \"*Ask the user how to proceed or if they want to select a different item.*\\n\",\n );\n continue;\n }\n\n // Priority 1: Resolver-level format (e.g. entity.format for entity resolvers)\n const entityType =\n r.reference.type === \"entity\"\n ? (r.reference as EntityReference).entityType\n : undefined;\n const def = resolverDefs?.find(\n (d) =>\n d.type === r.reference.type &&\n (!entityType || d.entityType === entityType),\n );\n\n if (def?.format) {\n sections.push(def.format(r.reference.displayName, r.data));\n continue;\n }\n\n // Priority 2: Ref definition format\n const refDef = references.get(r.reference.type);\n if (refDef?.format) {\n sections.push(refDef.format(r.reference.displayName, r.data));\n continue;\n }\n\n // Priority 3: Generic fallback\n sections.push(\n formatGeneric(r.reference.displayName, r.reference.type, r.data),\n );\n }\n\n return sections.join(\"\\n\");\n },\n};\n","/**\n * Table Factory, Field Helpers, and Index Helpers\n *\n * table<T>() creates a pure schema definition — no CRUD methods.\n * CRUD is handled by the DatabaseProvider directly:\n * db.find(ctx, { table: usersTable, filter: { email } })\n *\n * Every column is explicit — what you declare is what the DB gets.\n * No implicit system columns.\n */\n\nimport type { Table, TableConfig } from \"@jarvis/types\";\nimport type { FieldConfig, FieldType, IndexConfig, JsonFieldSchema } from \"@jarvis/types\";\n\n// =============================================================================\n// UTILITIES\n// =============================================================================\n\n/** Convert camelCase to snake_case */\nexport function toSnakeCase(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n// =============================================================================\n// table<T>() FACTORY — Pure schema definition\n// =============================================================================\n\n/**\n * Create a typed table schema definition.\n *\n * Returns a Table<T> with name, columns, indexes — no CRUD methods.\n * CRUD is handled by the DatabaseProvider.\n *\n * @example\n * ```typescript\n * import { table, field, index } from \"@jarvis/sdk\";\n *\n * export const usersTable = table<User>({\n * name: \"users\",\n * columns: {\n * id: field.uuid({ primary: true }),\n * userId: field.string({ required: true }),\n * email: field.string({ required: true, unique: true }),\n * name: field.string({ nullable: true }),\n * preferences: field.json({ default: {} }),\n * createdAt: field.timestamp({ auto: \"create\" }),\n * updatedAt: field.timestamp({ auto: \"update\" }),\n * },\n * });\n *\n * // Usage — CRUD via db provider:\n * const result = await db.find<User>(ctx, { table: usersTable, filter: { email } });\n * ```\n */\nexport function table<T = Record<string, unknown>>(\n config: TableConfig<T>,\n): Table<T> {\n if (!config.name) {\n throw new Error(\"Table must have a name\");\n }\n if (!/^[a-z][a-z0-9_]*$/.test(config.name)) {\n throw new Error(\n `Invalid table name \"${config.name}\". Must be lowercase with underscores.`,\n );\n }\n\n const columns = config.columns;\n const indexes = config.indexes ?? [];\n\n // Collect searchable field names\n const searchableFields: string[] = [];\n for (const [fname, fconfig] of Object.entries(columns)) {\n if (fconfig.searchable) {\n searchableFields.push(fname);\n }\n if (fconfig.type === \"json\" && fconfig.schema) {\n for (const [innerName, innerConfig] of Object.entries(fconfig.schema)) {\n if (innerConfig.searchable) {\n searchableFields.push(`${fname}.${innerName}`);\n }\n }\n }\n }\n\n return {\n kind: \"table\" as const,\n name: config.name,\n columns,\n indexes,\n access: config.access,\n searchableFields,\n } as Table<T>;\n}\n\n// =============================================================================\n// FIELD HELPERS\n// =============================================================================\n\n/**\n * Field helper functions for defining column types.\n *\n * @example\n * ```typescript\n * import { field } from \"@jarvis/sdk\";\n *\n * const columns = {\n * id: field.uuid({ primary: true }),\n * name: field.string({ required: true }),\n * email: field.string({ required: true, unique: true }),\n * age: field.integer({ default: 0 }),\n * isActive: field.boolean({ default: true }),\n * bio: field.text(),\n * metadata: field.json({ default: {} }),\n * createdAt: field.timestamp({ auto: \"create\" }),\n * updatedAt: field.timestamp({ auto: \"update\" }),\n * };\n * ```\n */\nexport const field = {\n string: (options?: {\n required?: boolean;\n nullable?: boolean;\n unique?: boolean;\n default?: string;\n searchable?: boolean;\n secret?: boolean;\n }): FieldConfig => ({\n type: \"string\" as FieldType,\n required: options?.required,\n nullable: options?.nullable,\n unique: options?.unique,\n default: options?.default,\n searchable: options?.searchable,\n secret: options?.secret,\n }),\n\n text: (options?: {\n required?: boolean;\n nullable?: boolean;\n default?: string;\n searchable?: boolean;\n }): FieldConfig => ({\n type: \"text\" as FieldType,\n required: options?.required,\n nullable: options?.nullable,\n default: options?.default,\n searchable: options?.searchable,\n }),\n\n integer: (options?: {\n required?: boolean;\n default?: number;\n unique?: boolean;\n }): FieldConfig => ({\n type: \"integer\" as FieldType,\n required: options?.required,\n default: options?.default,\n unique: options?.unique,\n }),\n\n boolean: (options?: { default?: boolean }): FieldConfig => ({\n type: \"boolean\" as FieldType,\n default: options?.default,\n }),\n\n timestamp: (options?: {\n required?: boolean;\n nullable?: boolean;\n default?: string | Date;\n auto?: \"create\" | \"update\";\n }): FieldConfig => ({\n type: \"timestamp\" as FieldType,\n required: options?.required,\n nullable: options?.nullable,\n default: options?.default,\n auto: options?.auto,\n }),\n\n json: <TJ = unknown>(options?: {\n default?: TJ;\n schema?: Record<string, JsonFieldSchema>;\n }): FieldConfig => ({\n type: \"json\" as FieldType,\n default: options?.default,\n schema: options?.schema,\n }),\n\n uuid: (options?: {\n primary?: boolean;\n required?: boolean;\n unique?: boolean;\n auto?: true;\n }): FieldConfig => ({\n type: \"uuid\" as FieldType,\n primary: options?.primary,\n required: options?.required,\n unique: options?.unique,\n auto: options?.auto,\n }),\n\n enum: (values: string[], options?: { default?: string }): FieldConfig => ({\n type: \"string\" as FieldType,\n default: options?.default ?? values[0],\n }),\n\n vector: (options?: { dimensions?: number }): FieldConfig => ({\n type: \"vector\" as FieldType,\n dimensions: options?.dimensions ?? 1536,\n }),\n\n number: (options?: {\n required?: boolean;\n nullable?: boolean;\n default?: number;\n unique?: boolean;\n }): FieldConfig => ({\n type: \"integer\" as FieldType,\n required: options?.required,\n nullable: options?.nullable,\n default: options?.default,\n unique: options?.unique,\n }),\n};\n\n// =============================================================================\n// INDEX HELPERS\n// =============================================================================\n\n/**\n * Create an index configuration\n *\n * @example\n * ```typescript\n * import { index } from \"@jarvis/sdk\";\n *\n * const indexes = [\n * index(\"goals_status_idx\", [\"userId\", \"status\"]),\n * index(\"goals_email_unique\", [\"email\"], { unique: true }),\n * ];\n * ```\n */\nexport function index(\n name: string,\n columns: string[],\n options?: { unique?: boolean },\n): IndexConfig {\n return {\n name,\n columns,\n unique: options?.unique,\n };\n}\n","/**\n * Connector Factory + Registry\n *\n * Provides the connector() factory for creating external service connector definitions,\n * and a registry for aggregating all platform connectors.\n *\n * Auth is handled by platform providers. Sync via Temporal workflows.\n */\n\nimport type {\n Connector,\n ConnectorConfig,\n ConnectorInstance,\n} from \"@jarvis/types\";\n\nimport { table, field, index } from \"./tables\";\n\n// =============================================================================\n// SHARED CONNECTORS TABLE\n// =============================================================================\n\n/** Shared connectors table — persistent storage for connection tracking */\nexport const connectorsTable = table<Connector>({\n name: \"connectors\",\n columns: {\n id: field.uuid({ primary: true }),\n userId: field.string({ required: true }),\n type: field.string({ required: true }),\n accountId: field.string(),\n displayName: field.string(),\n status: field.string({ default: \"disconnected\" }),\n lastSyncedAt: field.timestamp({ nullable: true }),\n syncState: field.json(),\n metadata: field.json(),\n createdAt: field.timestamp({ auto: \"create\" }),\n updatedAt: field.timestamp({ auto: \"update\" }),\n },\n indexes: [index(\"connectors_type_idx\", [\"userId\", \"type\"])],\n});\n\n// =============================================================================\n// CONNECTOR FACTORY\n// =============================================================================\n\n/**\n * Create an external service connector definition.\n *\n * Returns a ConnectorInstance with:\n * - .configure() — app-level sync config\n * - .connect() — initiate auth (OAuth redirect, API key store, token store)\n * - .exchangeCode() — OAuth callback code exchange\n * - .disconnect() — clear credentials\n *\n * @example\n * ```typescript\n * // Platform defines:\n * export const googleCalendarConnector = connector({\n * type: \"google_calendar\",\n * name: \"Google Calendar\",\n * auth: { type: \"oauth\", providerId: \"google\", scopes: [...] },\n * });\n *\n * // App configures sync:\n * export default googleCalendarConnector.configure({\n * sync: { pull: \"./workflows/pull.workflow\", cron: \"...\" },\n * });\n * ```\n */\nexport function connector(config: ConnectorConfig): ConnectorInstance {\n if (!config.type) throw new Error(\"Connector must have a type\");\n if (!config.name) throw new Error(\"Connector must have a name\");\n\n return {\n ...config,\n\n configure(configureConfig) {\n // Merge additional scopes with base auth if provided\n let auth = config.auth;\n if (configureConfig.auth?.scopes && auth?.type === \"oauth\") {\n const merged = [\n ...new Set([...auth.scopes, ...configureConfig.auth.scopes]),\n ];\n auth = { ...auth, scopes: merged };\n }\n\n return {\n type: config.type,\n name: configureConfig.name ?? config.name,\n icon: config.icon,\n color: config.color,\n description: configureConfig.description ?? config.description,\n version: config.version,\n sync: configureConfig.sync,\n auth,\n };\n },\n\n async connect(ctx, req, deps) {\n const auth = this.auth;\n\n // OAuth: return redirect URL\n if (auth?.type === \"oauth\" && auth.provider) {\n return {\n action: \"redirect\",\n ...auth.provider.buildAuthUrl(req.state ?? \"\"),\n };\n }\n\n // API key / token: validate + store credential\n if (\n (auth?.type === \"apiKey\" || auth?.type === \"token\") &&\n req.credential\n ) {\n if (auth.type === \"apiKey\" && \"validate\" in auth && auth.validate) {\n const error = await auth.validate(req.credential);\n if (error) return { action: \"error\", message: error };\n }\n\n await deps.secrets.set(ctx, {\n scope: config.type,\n type: auth.type,\n value: req.credential,\n });\n\n await deps.onConnect?.();\n return { action: \"connected\" };\n }\n\n return { action: \"error\", message: \"Unsupported auth type\" };\n },\n\n async exchangeCode(ctx, req, deps) {\n const auth = this.auth;\n if (auth?.type !== \"oauth\" || !auth.provider) {\n throw new Error(`${config.type}: no OAuth provider`);\n }\n\n const { tokens, profile, metadata } = await auth.provider.exchangeCode(\n req.code,\n req.codeVerifier,\n );\n\n const scope = auth.providerId ?? config.type;\n\n await deps.secrets.set(ctx, {\n scope,\n type: \"oauth\",\n value: {\n accessToken: tokens.accessToken,\n refreshToken: tokens.refreshToken ?? null,\n expiresAt: tokens.expiresAt\n ? new Date(tokens.expiresAt).toISOString()\n : null,\n tokenScope: tokens.scopes.join(\" \"),\n ...(tokens.extra ?? {}),\n },\n metadata: {\n accountId: profile?.accountId ?? null,\n displayName: profile?.displayName ?? null,\n },\n });\n\n await deps.onConnect?.({\n accountId: profile?.accountId,\n displayName: profile?.displayName,\n ...profile?.metadata,\n ...metadata,\n });\n },\n\n async disconnect(ctx, _req, deps) {\n const auth = this.auth;\n const scope =\n auth?.type === \"oauth\" ? (auth.providerId ?? config.type) : config.type;\n\n await deps.secrets.delete(ctx, { scope });\n await deps.onDisconnect?.();\n },\n };\n}\n\n// =============================================================================\n// CONNECTORS COLLECTION\n// =============================================================================\n\nconst all: ConnectorInstance[] = [];\n\nexport const connectors = {\n /** List all registered connectors */\n list: () => [...all],\n\n /** Find a connector by type */\n get: (type: string) => all.find((c) => c.type === type),\n\n /** Register a connector instance */\n add: (instance: ConnectorInstance) => {\n all.push(instance);\n },\n};\n","import { tool } from \"@jarvis/sdk\";\n\nexport interface EditToolInput {\n file_path: string;\n old_string: string;\n new_string: string;\n replace_all?: boolean;\n}\n\nexport const editTool = tool({\n name: \"Edit\",\n description: \"Edit file contents with string replacement\",\n schema: {\n input: {\n type: \"object\",\n properties: {\n file_path: { type: \"string\" },\n old_string: { type: \"string\" },\n new_string: { type: \"string\" },\n replace_all: { type: \"boolean\" },\n },\n },\n output: { type: \"object\" },\n },\n metadata: {\n label: \"Edit File\",\n provider: \"claude-code\",\n describe: (_ctx, req) => {\n const input = req.input as Partial<EditToolInput>;\n const fileName = input.file_path?.split(\"/\").pop() || \"file\";\n if (req.status === \"running\") return `Editing ${fileName}...`;\n if (req.status === \"completed\") return `Edited ${fileName}`;\n return `Failed to edit ${fileName}`;\n },\n },\n hooks: {\n before: async (_ctx, req, options) => {\n const input = req.input as EditToolInput;\n const response = await options.askUser({\n ui: {\n uri: \"ui://devenv/diff\",\n title: input.file_path,\n data: {\n filePath: input.file_path,\n oldString: input.old_string,\n newString: input.new_string,\n replaceAll: input.replace_all,\n },\n },\n });\n if (response?.action === \"deny\") {\n return { action: \"deny\", reason: response.feedback || \"User denied edit\" };\n }\n return { action: \"allow\" };\n },\n after: async (_ctx, req) => {\n const input = req.input as EditToolInput;\n return {\n context: { edited: input.file_path },\n ui: {\n uri: \"ui://devenv/diff\",\n title: input.file_path,\n data: {\n filePath: input.file_path,\n oldString: input.old_string,\n newString: input.new_string,\n replaceAll: input.replace_all,\n },\n },\n };\n },\n },\n});\n","import { tool } from \"@jarvis/sdk\";\n\nexport interface BashToolInput {\n command: string;\n description?: string;\n timeout?: number;\n}\n\nexport const bashTool = tool({\n name: \"Bash\",\n description: \"Execute a bash command\",\n schema: {\n input: {\n type: \"object\",\n properties: {\n command: { type: \"string\" },\n description: { type: \"string\" },\n timeout: { type: \"number\" },\n },\n },\n output: { type: \"object\" },\n },\n metadata: {\n label: \"Run Command\",\n provider: \"claude-code\",\n describe: (_ctx, req) => {\n const input = req.input as Partial<BashToolInput>;\n if (input.description) return input.description;\n const shortCmd =\n input.command && input.command.length > 50\n ? input.command.slice(0, 47) + \"...\"\n : input.command || \"command\";\n if (req.status === \"running\") return `Running: ${shortCmd}`;\n if (req.status === \"completed\") return `Ran: ${shortCmd}`;\n return `Failed: ${shortCmd}`;\n },\n },\n hooks: {\n before: async (_ctx, req, options) => {\n const input = req.input as BashToolInput;\n const response = await options.askUser({\n ui: {\n uri: \"ui://devenv/command\",\n title: input.description || input.command,\n data: { command: input.command, description: input.description },\n },\n });\n if (response?.action === \"deny\") {\n return { action: \"deny\", reason: response.feedback || \"User denied command\" };\n }\n return { action: \"allow\" };\n },\n after: async (_ctx, req) => {\n const input = req.input as BashToolInput;\n const output = req.output as { stdout?: string; stderr?: string; exitCode?: number } | string | undefined;\n const outputText = typeof output === \"string\"\n ? output\n : output\n ? [output.stdout, output.stderr].filter(Boolean).join(\"\\n\")\n : undefined;\n const exitCode = typeof output === \"object\" && output ? output.exitCode : undefined;\n return {\n context: { command: input.command, exitCode },\n ui: {\n uri: \"ui://devenv/command\",\n title: input.description || input.command,\n data: { command: input.command, description: input.description, output: outputText, exitCode },\n },\n };\n },\n },\n});\n","import { tool } from \"@jarvis/sdk\";\n\nexport interface WriteToolInput {\n file_path: string;\n content: string;\n}\n\nfunction detectLanguage(filePath: string): string | undefined {\n const ext = filePath.split(\".\").pop()?.toLowerCase();\n const langMap: Record<string, string> = {\n ts: \"typescript\", tsx: \"typescript\", js: \"javascript\", jsx: \"javascript\",\n py: \"python\", rs: \"rust\", go: \"go\", rb: \"ruby\", java: \"java\",\n css: \"css\", scss: \"scss\", html: \"html\", json: \"json\",\n yaml: \"yaml\", yml: \"yaml\", toml: \"toml\", xml: \"xml\",\n md: \"markdown\", sql: \"sql\", sh: \"shell\", bash: \"shell\",\n };\n return ext ? langMap[ext] : undefined;\n}\n\nexport const writeTool = tool({\n name: \"Write\",\n description: \"Write content to a file\",\n schema: {\n input: {\n type: \"object\",\n properties: {\n file_path: { type: \"string\" },\n content: { type: \"string\" },\n },\n },\n output: { type: \"object\" },\n },\n metadata: {\n label: \"Write File\",\n provider: \"claude-code\",\n describe: (_ctx, req) => {\n const input = req.input as Partial<WriteToolInput>;\n const fileName = input.file_path?.split(\"/\").pop() || \"file\";\n if (req.status === \"running\") return `Writing ${fileName}...`;\n if (req.status === \"completed\") return `Wrote ${fileName}`;\n return `Failed to write ${fileName}`;\n },\n },\n hooks: {\n before: async (_ctx, req, options) => {\n const input = req.input as WriteToolInput;\n const language = detectLanguage(input.file_path);\n const response = await options.askUser({\n ui: {\n uri: \"ui://devenv/file\",\n title: input.file_path,\n data: { filePath: input.file_path, content: input.content, language },\n },\n });\n if (response?.action === \"deny\") {\n return { action: \"deny\", reason: response.feedback || \"User denied write\" };\n }\n return { action: \"allow\" };\n },\n after: async (_ctx, req) => {\n const input = req.input as WriteToolInput;\n const language = detectLanguage(input.file_path);\n return {\n context: { wrote: input.file_path },\n ui: {\n uri: \"ui://devenv/file\",\n title: input.file_path,\n data: { filePath: input.file_path, content: input.content, language },\n },\n };\n },\n },\n});\n","import { tool } from \"@jarvis/sdk\";\n\nexport interface ReadToolInput {\n file_path: string;\n offset?: number;\n limit?: number;\n}\n\nfunction stripLineNumbers(text: string): string {\n return text.replace(/^\\s*\\d+[\\t→]/gm, \"\");\n}\n\nfunction detectLanguage(filePath: string): string | undefined {\n const ext = filePath.split(\".\").pop()?.toLowerCase();\n const langMap: Record<string, string> = {\n ts: \"typescript\", tsx: \"typescript\", js: \"javascript\", jsx: \"javascript\",\n py: \"python\", rs: \"rust\", go: \"go\", rb: \"ruby\", java: \"java\",\n css: \"css\", scss: \"scss\", html: \"html\", json: \"json\",\n yaml: \"yaml\", yml: \"yaml\", toml: \"toml\", xml: \"xml\",\n md: \"markdown\", sql: \"sql\", sh: \"shell\", bash: \"shell\",\n };\n return ext ? langMap[ext] : undefined;\n}\n\nexport const readTool = tool({\n name: \"Read\",\n description: \"Read file contents\",\n schema: {\n input: {\n type: \"object\",\n properties: {\n file_path: { type: \"string\" },\n offset: { type: \"number\" },\n limit: { type: \"number\" },\n },\n },\n output: { type: \"object\" },\n },\n metadata: {\n label: \"Read File\",\n provider: \"claude-code\",\n describe: (_ctx, req) => {\n const input = req.input as Partial<ReadToolInput>;\n const fileName = input.file_path?.split(\"/\").pop() || \"file\";\n if (req.status === \"running\") return `Reading ${fileName}...`;\n if (req.status === \"completed\") return `Read ${fileName}`;\n return `Failed to read ${fileName}`;\n },\n },\n hooks: {\n after: async (_ctx, req) => {\n const input = req.input as ReadToolInput;\n const language = detectLanguage(input.file_path);\n const rawOutput = typeof req.output === \"string\"\n ? req.output\n : JSON.stringify(req.output, null, 2);\n const content = stripLineNumbers(rawOutput);\n return {\n context: { read: input.file_path },\n ui: {\n uri: \"ui://devenv/file\",\n title: input.file_path,\n data: { filePath: input.file_path, content, language, startLine: (input.offset ?? 0) + 1 },\n },\n };\n },\n },\n});\n","import { tool } from \"@jarvis/sdk\";\n\nexport interface GlobToolInput {\n pattern: string;\n path?: string;\n}\n\nexport const globTool = tool({\n name: \"Glob\",\n description: \"Search for files by pattern\",\n schema: {\n input: {\n type: \"object\",\n properties: { pattern: { type: \"string\" }, path: { type: \"string\" } },\n },\n output: { type: \"object\" },\n },\n metadata: {\n label: \"Find Files\",\n provider: \"claude-code\",\n describe: (_ctx, req) => {\n const input = req.input as Partial<GlobToolInput>;\n const pattern = input.pattern || \"files\";\n if (req.status === \"running\") return `Finding ${pattern}...`;\n if (req.status === \"completed\") return `Found files matching ${pattern}`;\n return `Failed to find ${pattern}`;\n },\n },\n hooks: {\n after: async (_ctx, req) => {\n const input = req.input as GlobToolInput;\n const output = typeof req.output === \"string\" ? req.output : JSON.stringify(req.output, null, 2);\n return {\n context: { searched: input.pattern },\n ui: {\n uri: \"ui://devenv/command\",\n title: `Find: ${input.pattern}`,\n data: {\n command: `glob ${input.pattern}${input.path ? ` in ${input.path}` : \"\"}`,\n description: `Find files matching ${input.pattern}`,\n output,\n },\n },\n };\n },\n },\n});\n","import { tool } from \"@jarvis/sdk\";\n\nexport interface GrepToolInput {\n pattern: string;\n path?: string;\n glob?: string;\n output_mode?: string;\n}\n\nexport const grepTool = tool({\n name: \"Grep\",\n description: \"Search file contents by pattern\",\n schema: {\n input: {\n type: \"object\",\n properties: {\n pattern: { type: \"string\" },\n path: { type: \"string\" },\n glob: { type: \"string\" },\n output_mode: { type: \"string\" },\n },\n },\n output: { type: \"object\" },\n },\n metadata: {\n label: \"Search Code\",\n provider: \"claude-code\",\n describe: (_ctx, req) => {\n const input = req.input as Partial<GrepToolInput>;\n const pattern = input.pattern || \"\";\n if (req.status === \"running\") return `Searching for \"${pattern}\"...`;\n if (req.status === \"completed\") return `Searched for \"${pattern}\"`;\n return `Failed to search for \"${pattern}\"`;\n },\n },\n hooks: {\n after: async (_ctx, req) => {\n const input = req.input as GrepToolInput;\n const output = typeof req.output === \"string\" ? req.output : JSON.stringify(req.output, null, 2);\n return {\n context: { searched: input.pattern },\n ui: {\n uri: \"ui://devenv/command\",\n title: `Search: \"${input.pattern}\"`,\n data: {\n command: `grep \"${input.pattern}\"${input.path ? ` in ${input.path}` : \"\"}${input.glob ? ` (${input.glob})` : \"\"}`,\n description: `Search for \"${input.pattern}\"`,\n output,\n },\n },\n };\n },\n },\n});\n","export { editTool } from \"./edit.tool\";\nexport { bashTool } from \"./bash.tool\";\nexport { writeTool } from \"./write.tool\";\nexport { readTool } from \"./read.tool\";\nexport { globTool } from \"./glob.tool\";\nexport { grepTool } from \"./grep.tool\";\n\nimport { bashTool } from \"./bash.tool\";\nimport { editTool } from \"./edit.tool\";\nimport { globTool } from \"./glob.tool\";\nimport { grepTool } from \"./grep.tool\";\nimport { readTool } from \"./read.tool\";\nimport { writeTool } from \"./write.tool\";\n\n/** All Claude Code native tools with hooks */\nexport const claudeCodeTools = [editTool, bashTool, writeTool, readTool, globTool, grepTool];\n","/**\n * Tool Description Formatter\n *\n * Human-readable descriptions for tool calls in progress messages.\n */\n\nexport function formatToolDescription(toolName: string, input?: Record<string, unknown>): string {\n if (!input) return toolName;\n switch (toolName) {\n case \"Read\":\n return `Reading ${input.file_path || \"file\"}`;\n case \"Edit\":\n return `Editing ${input.file_path || \"file\"}`;\n case \"Write\":\n return `Writing to ${input.file_path || \"file\"}`;\n case \"Bash\":\n return typeof input.command === \"string\"\n ? input.command.length > 80\n ? input.command.slice(0, 80) + \"\\u2026\"\n : input.command\n : \"Running command\";\n case \"Glob\":\n return `Searching for ${input.pattern || \"files\"}`;\n case \"Grep\":\n return `Searching for \"${input.pattern || \"\"}\"`;\n default:\n return toolName;\n }\n}\n","/**\n * Git Worktree Utilities\n *\n * Per-task isolation using git worktrees in .jarvis/worktrees/.\n */\n\nimport { exec as execCb } from \"child_process\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { promisify } from \"util\";\n\nconst exec = promisify(execCb);\n\nconst WORKTREE_DIR = \".jarvis/worktrees\";\n\nexport async function createWorktree(\n repoPath: string,\n taskId: string,\n baseBranch?: string,\n): Promise<string> {\n const branchName = `jarvis/task-${taskId}`;\n const worktreeDir = path.join(repoPath, WORKTREE_DIR, `task-${taskId}`);\n\n await fs.mkdir(path.dirname(worktreeDir), { recursive: true });\n await ensureGitignore(repoPath);\n\n // Check if worktree already exists\n if (await worktreeExists(repoPath, taskId)) {\n return worktreeDir;\n }\n\n // Create worktree + branch from specified base or current HEAD\n const startPoint = baseBranch ?? \"HEAD\";\n await exec(`git worktree add -b \"${branchName}\" \"${worktreeDir}\" \"${startPoint}\"`, {\n cwd: repoPath,\n });\n\n return worktreeDir;\n}\n\nexport async function removeWorktree(repoPath: string, taskId: string): Promise<void> {\n const branchName = `jarvis/task-${taskId}`;\n const worktreeDir = path.join(repoPath, WORKTREE_DIR, `task-${taskId}`);\n\n try {\n await exec(`git worktree remove --force \"${worktreeDir}\"`, { cwd: repoPath });\n } catch {\n // Fallback: manual cleanup\n await fs.rm(worktreeDir, { recursive: true, force: true });\n await exec(\"git worktree prune\", { cwd: repoPath }).catch(() => {});\n }\n\n // Delete branch (force if unmerged)\n await exec(`git branch -D \"${branchName}\"`, { cwd: repoPath }).catch(() => {});\n}\n\nexport async function listWorktrees(\n repoPath: string,\n): Promise<Array<{ taskId: string; path: string; branch: string }>> {\n const { stdout } = await exec(\"git worktree list --porcelain\", { cwd: repoPath });\n const worktrees: Array<{ taskId: string; path: string; branch: string }> = [];\n\n let currentPath = \"\";\n let currentBranch = \"\";\n\n for (const line of stdout.split(\"\\n\")) {\n if (line.startsWith(\"worktree \")) {\n currentPath = line.slice(9);\n } else if (line.startsWith(\"branch refs/heads/\")) {\n currentBranch = line.slice(18);\n if (currentBranch.startsWith(\"jarvis/task-\")) {\n worktrees.push({\n taskId: currentBranch.replace(\"jarvis/task-\", \"\"),\n path: currentPath,\n branch: currentBranch,\n });\n }\n }\n }\n\n return worktrees;\n}\n\nexport async function worktreeExists(repoPath: string, taskId: string): Promise<boolean> {\n const worktreeDir = path.join(repoPath, WORKTREE_DIR, `task-${taskId}`);\n try {\n await fs.access(worktreeDir);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function ensureGitignore(repoPath: string): Promise<void> {\n const gitignorePath = path.join(repoPath, \".gitignore\");\n try {\n const content = await fs.readFile(gitignorePath, \"utf-8\");\n if (!content.includes(\".jarvis/\")) {\n await fs.appendFile(gitignorePath, \"\\n.jarvis/\\n\");\n }\n } catch {\n await fs.writeFile(gitignorePath, \".jarvis/\\n\");\n }\n}\n","/**\n * WS Progress Handlers\n *\n * Same logic as workflows/devenv/src/progress.ts but publishes\n * over WebSocket instead of Redis pub/sub + Temporal signals.\n *\n * The handleProgress() and handleUserInput() functions are identical\n * in behavior — only the transport (publish/signal → ws.send) changes.\n */\n\nimport crypto from \"crypto\";\n\nimport { formatToolDescription } from \"@jarvis/agent\";\nimport type {\n ChatMessage,\n PendingUserInput,\n ToolCallData,\n ToolUi,\n ToolUiData,\n UserInputResponse,\n} from \"@jarvis/types\";\n\nimport type { OutboundMessage } from \"./protocol\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface WsProgressHandlersDeps {\n /** Send a message to all connected clients (local + upstream) */\n broadcast: (msg: OutboundMessage) => void;\n /** Send input request and wait for user response */\n requestInput: (taskId: string, input: PendingUserInput) => Promise<UserInputResponse>;\n /** Task ID for message routing */\n taskId: string;\n /** Chat ID for usage events */\n chatId: string;\n}\n\nexport interface WsProgressHandlers {\n onMessage: (msg: ChatMessage) => Promise<void>;\n completeTools: () => Promise<void>;\n waitForInput: (pendingInput: PendingUserInput) => Promise<UserInputResponse>;\n handleUserInput: (input: PendingUserInput) => Promise<UserInputResponse>;\n handleProgress: (message: unknown) => Promise<void>;\n}\n\n// =============================================================================\n// Factory\n// =============================================================================\n\nexport function createWsProgressHandlers(deps: WsProgressHandlersDeps): WsProgressHandlers {\n const { broadcast, requestInput, taskId, chatId } = deps;\n const toolIds = new Map<string, string>();\n let currentThinkingId: string | null = null;\n let currentTextId: string | null = null;\n let currentTextContent = \"\";\n\n // ---------------------------------------------------------------------------\n // Transport: single WS broadcast replaces Redis pub/sub + Temporal signal\n // ---------------------------------------------------------------------------\n\n async function onMessage(msg: ChatMessage): Promise<void> {\n broadcast({ type: \"agent:onMessage\", taskId, message: msg });\n }\n\n // ---------------------------------------------------------------------------\n // Tool lifecycle\n // ---------------------------------------------------------------------------\n\n async function completeTools(): Promise<void> {\n const now = new Date().toISOString();\n for (const [toolId, toolName] of toolIds) {\n const msg: ChatMessage = {\n id: `tool-${toolId}`,\n role: \"assistant\",\n type: \"tool\",\n content: \"\",\n toolCall: { toolName, toolCallId: toolId, status: \"completed\" },\n isPartial: false,\n createdAt: now,\n };\n await onMessage(msg);\n }\n toolIds.clear();\n }\n\n // ---------------------------------------------------------------------------\n // User input (tool approval, plan review)\n // ---------------------------------------------------------------------------\n\n async function waitForInput(pendingInput: PendingUserInput): Promise<UserInputResponse> {\n return requestInput(taskId, pendingInput);\n }\n\n async function handleUserInput(input: PendingUserInput): Promise<UserInputResponse> {\n const toolName = input.toolName ?? \"\";\n const now = new Date().toISOString();\n\n if (toolName === \"askUser\") return waitForInput(input);\n\n if (toolName === \"ExitPlanMode\") {\n return waitForInput({\n ...input,\n type: \"plan\",\n reason: (input.input?.allowedPrompts as string) || \"Plan ready for review\",\n });\n }\n\n if (toolName === \"EnterPlanMode\") {\n await onMessage({\n id: `status-plan-${crypto.randomUUID()}`,\n role: \"assistant\",\n type: \"status\",\n content: \"Planning...\",\n isPartial: true,\n createdAt: now,\n });\n return { action: \"allow\" };\n }\n\n if (toolName === \"TodoWrite\") {\n const todos =\n (input.input?.todos as Array<{ content: string; status: string; activeForm: string }>) ??\n [];\n await onMessage({\n id: \"todo-progress\",\n role: \"assistant\",\n type: \"status\",\n content: JSON.stringify({ type: \"todo\", todos }),\n isPartial: true,\n createdAt: now,\n });\n return { action: \"allow\" };\n }\n\n // Tools with UI artifact → forward for approval\n if (input.ui) return waitForInput(input);\n\n // All other tools → auto-approve\n return { action: \"allow\" };\n }\n\n // ---------------------------------------------------------------------------\n // SDK message → ChatMessage conversion (identical to devenv/progress.ts)\n // ---------------------------------------------------------------------------\n\n async function handleProgress(message: unknown): Promise<void> {\n const raw = message as {\n type?: string;\n message?: { content?: Array<Record<string, unknown>> };\n usage?: { input_tokens?: number; output_tokens?: number };\n model?: string;\n _toolUi?: Record<string, ToolUiData>;\n };\n if (!raw?.type) return;\n\n const now = new Date().toISOString();\n\n // --- Assistant messages: thinking, text, tool_use blocks ---\n if (raw.type === \"assistant\" && Array.isArray(raw.message?.content)) {\n for (const block of raw.message!.content) {\n // Thinking blocks — reuse stable ID within a turn\n if (block.type === \"thinking\" && block.thinking) {\n if (!currentThinkingId) currentThinkingId = `thinking-${crypto.randomUUID()}`;\n const msg: ChatMessage = {\n id: currentThinkingId,\n role: \"assistant\",\n type: \"thinking\",\n content: block.thinking as string,\n isPartial: true,\n createdAt: now,\n };\n await onMessage(msg);\n continue;\n }\n\n // Non-thinking block resets the thinking ID\n currentThinkingId = null;\n\n // Text blocks → stream as tokens with stable messageId\n if (block.type === \"text\" && block.text) {\n if (!currentTextId) currentTextId = `text-${crypto.randomUUID()}`;\n currentTextContent += block.text as string;\n\n // Broadcast incremental token event (content is accumulated snapshot)\n broadcast({\n type: \"agent:onToken\",\n taskId,\n messageId: currentTextId,\n content: currentTextContent,\n isComplete: false,\n });\n }\n\n // Tool use blocks — finalize any in-progress text stream first\n if (block.type === \"tool_use\" && block.id && block.name) {\n if (currentTextId) {\n broadcast({\n type: \"agent:onToken\",\n taskId,\n messageId: currentTextId,\n content: currentTextContent,\n isComplete: true,\n isFinal: false, // More content may follow after tool execution\n });\n currentTextId = null;\n currentTextContent = \"\";\n }\n const blockId = block.id as string;\n const blockName = block.name as string;\n toolIds.set(blockId, blockName);\n\n const toolCall: ToolCallData = {\n toolName: blockName,\n toolCallId: blockId,\n status: \"running\",\n input: block.input as Record<string, unknown>,\n };\n\n const msg: ChatMessage = {\n id: `tool-${blockId}`,\n role: \"assistant\",\n type: \"tool\",\n content: formatToolDescription(blockName, block.input as Record<string, unknown>),\n toolCall,\n isPartial: true,\n createdAt: now,\n };\n await onMessage(msg);\n }\n }\n }\n\n // Tool results reset thinking ID and finalize text stream\n currentThinkingId = null;\n if (currentTextId) {\n broadcast({\n type: \"agent:onToken\",\n taskId,\n messageId: currentTextId,\n content: currentTextContent,\n isComplete: true,\n });\n currentTextId = null;\n currentTextContent = \"\";\n }\n\n // --- User messages (tool results): mark tools completed ---\n if (raw.type === \"user\" && Array.isArray(raw.message?.content)) {\n for (const block of raw.message!.content) {\n if (!block.tool_use_id) continue;\n\n const toolUseId = block.tool_use_id as string;\n const output =\n typeof block.content === \"string\" ? block.content : JSON.stringify(block.content);\n const truncated = output && output.length > 1000 ? output.slice(0, 1000) + \"...\" : output;\n\n const toolUiData = raw._toolUi?.[toolUseId];\n const toolUi: ToolUi | undefined = toolUiData\n ? {\n uri: `ui://devenv/${toolUiData.type}`,\n title: toolUiData.title ?? \"\",\n data: toolUiData.data,\n }\n : undefined;\n\n const toolCall: ToolCallData = {\n toolName: toolIds.get(toolUseId) ?? \"\",\n toolCallId: toolUseId,\n status: block.is_error ? \"error\" : \"completed\",\n output: truncated,\n error: block.is_error ? (truncated ?? undefined) : undefined,\n };\n\n const msg: ChatMessage = {\n id: `tool-${toolUseId}`,\n role: \"assistant\",\n type: \"tool\",\n content: truncated ?? \"\",\n toolCall,\n ...(toolUi ? { ui: toolUi } : {}),\n isPartial: false,\n createdAt: now,\n };\n await onMessage(msg);\n toolIds.delete(toolUseId);\n }\n }\n\n // --- Result: complete remaining tools + publish usage ---\n if (raw.type === \"result\") {\n await completeTools();\n\n if (raw.usage) {\n const inputTokens = raw.usage.input_tokens ?? 0;\n const outputTokens = raw.usage.output_tokens ?? 0;\n broadcast({\n type: \"agent:onUsage\",\n taskId,\n chatId,\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n model: raw.model ?? \"unknown\",\n });\n }\n }\n }\n\n return { onMessage, completeTools, waitForInput, handleUserInput, handleProgress };\n}\n","/**\n * Agent Core\n *\n * Same execution logic as workflows/devenv/src/activities.ts\n * but without Temporal dependencies. Uses WS callbacks for progress.\n */\n\nimport { claudeCodeProvider } from \"@jarvis/anthropic\";\nimport { claudeCodeTools } from \"@jarvis/agent\";\nimport type {\n Context as AppContext,\n Message,\n PendingUserInput,\n UserInputResponse,\n} from \"@jarvis/types\";\n\nimport { createWsProgressHandlers } from \"./progress\";\nimport type { OutboundMessage, AgentDispatchMessage } from \"./protocol\";\n\nimport { logger } from \"@jarvis/logger\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface AgentDeps {\n workspacePath: string;\n anthropicApiKey?: string;\n useSubscription?: boolean;\n userId: string;\n broadcast: (msg: OutboundMessage) => void;\n requestInput: (taskId: string, input: PendingUserInput) => Promise<UserInputResponse>;\n}\n\n// =============================================================================\n// Factory\n// =============================================================================\n\nexport function createAgent(deps: AgentDeps) {\n const activeTasks = new Map<string, AbortController>();\n\n async function runTask(msg: AgentDispatchMessage): Promise<void> {\n const { taskId, chatId } = msg;\n const abortController = new AbortController();\n activeTasks.set(taskId, abortController);\n\n deps.broadcast({ type: \"agent:status\", status: \"busy\", taskId });\n\n const handlers = createWsProgressHandlers({\n broadcast: deps.broadcast,\n requestInput: deps.requestInput,\n taskId,\n chatId,\n });\n\n try {\n const wsPath = msg.worktreePath || deps.workspacePath;\n const systemMsg = msg.messages.find((m) => m.role === \"system\");\n const nonSystemMessages = msg.messages.filter((m) => m.role !== \"system\");\n\n logger.sys.info(\"[Agent] Running task\", {\n taskId,\n model: msg.model,\n worktreePath: wsPath,\n messageCount: msg.messages.length,\n });\n\n // Same claudeCodeProvider call as devenv activities.ts\n // Just different callbacks: WS broadcast instead of Redis/Temporal\n const provider = claudeCodeProvider({\n ...(deps.useSubscription ? { useSubscription: true } : { apiKey: deps.anthropicApiKey }),\n systemPrompt: (systemMsg?.content as string) ?? \"\",\n workingDirectory: wsPath,\n tools: claudeCodeTools,\n maxTurns: msg.maxTurns ?? 200,\n userId: deps.userId,\n abortController,\n heartbeat: () => {}, // No Temporal heartbeat — WS ping/pong handles liveness\n onProgress: handlers.handleProgress,\n onUserInput: handlers.handleUserInput,\n permissionMode: msg.permissionMode === \"plan\" ? (\"plan\" as const) : (\"default\" as const),\n ...(msg.disallowedTools?.length ? { disallowedTools: msg.disallowedTools } : {}),\n ...(msg.session ? { session: msg.session } : {}),\n });\n\n const ctx = { requestId: taskId, userId: deps.userId } as AppContext;\n let response = await provider.query(ctx, {\n model: msg.model ?? \"claude-sonnet-4-20250514\",\n messages: nonSystemMessages as Message[],\n });\n\n // If resume failed, retry with fresh session (same as devenv activities)\n if (response.error && msg.session?.resume) {\n const resumeError = response.error.toLowerCase();\n if (\n resumeError.includes(\"session\") ||\n resumeError.includes(\"resume\") ||\n resumeError.includes(\"not found\")\n ) {\n logger.sys.warn(\"[Agent] Resume failed, retrying with fresh session\", {\n error: response.error,\n });\n const { resume: _, forkSession: __, ...fallbackSession } = msg.session;\n const fallbackProvider = claudeCodeProvider({\n ...(deps.useSubscription\n ? { useSubscription: true }\n : { apiKey: deps.anthropicApiKey }),\n workingDirectory: wsPath,\n tools: claudeCodeTools,\n maxTurns: msg.maxTurns ?? 200,\n userId: deps.userId,\n abortController,\n heartbeat: () => {},\n onProgress: handlers.handleProgress,\n onUserInput: handlers.handleUserInput,\n ...(Object.keys(fallbackSession).length > 0 ? { session: fallbackSession } : {}),\n });\n response = await fallbackProvider.query(ctx, {\n model: msg.model ?? \"claude-sonnet-4-20250514\",\n messages: nonSystemMessages as Message[],\n });\n }\n }\n\n logger.sys.info(\"[Agent] Task completed\", {\n taskId,\n success: !response.error,\n sessionId: response.sessionId,\n });\n\n deps.broadcast({\n type: \"agent:output\",\n taskId,\n output: {\n success: !response.error,\n content: response.content ?? \"\",\n json: response.json,\n error: response.error,\n sessionId: response.sessionId,\n },\n });\n } catch (err) {\n if (abortController.signal.aborted) {\n logger.sys.info(\"[Agent] Task aborted\", { taskId });\n deps.broadcast({\n type: \"agent:output\",\n taskId,\n output: { success: false, content: \"\", error: \"Aborted\" },\n });\n } else {\n const error = err instanceof Error ? err.message : String(err);\n logger.sys.error(\"[Agent] Task failed\", { taskId, error });\n deps.broadcast({\n type: \"agent:output\",\n taskId,\n output: { success: false, content: \"\", error },\n });\n }\n } finally {\n activeTasks.delete(taskId);\n deps.broadcast({ type: \"agent:status\", status: \"idle\" });\n }\n }\n\n function cancelTask(taskId: string): void {\n const controller = activeTasks.get(taskId);\n if (controller) {\n logger.sys.info(\"[Agent] Cancelling task\", { taskId });\n controller.abort();\n }\n }\n\n function isRunning(taskId: string): boolean {\n return activeTasks.has(taskId);\n }\n\n function activeTaskCount(): number {\n return activeTasks.size;\n }\n\n return { runTask, cancelTask, isRunning, activeTaskCount };\n}\n\nexport type Agent = ReturnType<typeof createAgent>;\n","/**\n * Git Operations\n *\n * Handles git operations dispatched via WS (resolveRepo, createWorktree, commit, diffStats).\n * Same logic as workflows/devenv/src/activities.ts but without Temporal dependencies.\n */\n\nimport { exec as execCb } from \"child_process\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { promisify } from \"util\";\n\nimport { createWorktree } from \"@jarvis/agent\";\nimport { logger } from \"@jarvis/logger\";\nimport type { InboundMessage, OutboundMessage } from \"@jarvis/types\";\n\nconst exec = promisify(execCb);\n\nexport function createGitHandler(\n workspacePath: string,\n broadcast: (msg: OutboundMessage) => void,\n) {\n async function handle(msg: InboundMessage): Promise<boolean> {\n switch (msg.type) {\n case \"git:resolveRepo\":\n await handleResolveRepo(msg);\n return true;\n case \"git:createWorktree\":\n await handleCreateWorktree(msg);\n return true;\n case \"git:commit\":\n await handleCommit(msg);\n return true;\n case \"git:diffStats\":\n await handleDiffStats(msg);\n return true;\n default:\n return false;\n }\n }\n\n function respond(requestId: string, result: unknown, error?: string) {\n broadcast({ type: \"git:response\", requestId, result, error });\n }\n\n async function handleResolveRepo(msg: Extract<InboundMessage, { type: \"git:resolveRepo\" }>) {\n try {\n const repoDir = path.join(workspacePath, msg.owner, msg.name);\n\n const isCloned = await fs\n .access(path.join(repoDir, \".git\"))\n .then(() => true)\n .catch(() => false);\n\n if (!isCloned) {\n logger.sys.info(\"[Git] Cloning repo...\", { repoDir });\n await fs.mkdir(path.join(workspacePath, msg.owner), { recursive: true });\n const cloneUrl = `git@github.com:${msg.owner}/${msg.name}.git`;\n await exec(`git clone \"${cloneUrl}\" \"${repoDir}\"`, { timeout: 300000 });\n }\n\n await exec(\"git fetch origin\", { cwd: repoDir, timeout: 120000 });\n\n try {\n await exec(`git checkout \"${msg.branch}\"`, { cwd: repoDir });\n } catch {\n await exec(`git checkout -b \"${msg.branch}\" \"origin/${msg.branch}\"`, { cwd: repoDir });\n }\n\n await exec(\"git pull --ff-only\", { cwd: repoDir }).catch(() => {});\n\n logger.sys.info(\"[Git] Repo resolved\", { repoDir, branch: msg.branch });\n respond(msg.requestId, { repoPath: repoDir });\n } catch (err) {\n respond(msg.requestId, null, err instanceof Error ? err.message : String(err));\n }\n }\n\n async function handleCreateWorktree(msg: Extract<InboundMessage, { type: \"git:createWorktree\" }>) {\n try {\n const worktreePath = await createWorktree(msg.repoPath, msg.taskId, msg.branch);\n respond(msg.requestId, { worktreePath, branchName: `jarvis/task-${msg.taskId}` });\n } catch (err) {\n respond(msg.requestId, null, err instanceof Error ? err.message : String(err));\n }\n }\n\n async function handleCommit(msg: Extract<InboundMessage, { type: \"git:commit\" }>) {\n try {\n const cwd = msg.worktreePath;\n await exec(\"git add -A\", { cwd });\n const { stdout: status } = await exec(\"git status --porcelain\", { cwd });\n if (!status.trim()) {\n respond(msg.requestId, { success: true, output: \"Nothing to commit\" });\n return;\n }\n const title = msg.title.replace(/\"/g, '\\\\\"');\n const { stdout } = await exec(`git commit -m \"jarvis: ${title}\"`, { cwd });\n respond(msg.requestId, { success: true, output: stdout });\n } catch (err) {\n respond(msg.requestId, { success: false, output: \"\", error: err instanceof Error ? err.message : String(err) });\n }\n }\n\n async function handleDiffStats(msg: Extract<InboundMessage, { type: \"git:diffStats\" }>) {\n try {\n const cwd = msg.worktreePath;\n const { stdout } = await exec(\"git diff --numstat HEAD~1\", { cwd });\n const files: Array<{ file: string; additions: number; deletions: number }> = [];\n let totalAdditions = 0;\n let totalDeletions = 0;\n\n for (const line of stdout.trim().split(\"\\n\")) {\n if (!line.trim()) continue;\n const [add, del, file] = line.split(\"\\t\");\n const additions = add === \"-\" ? 0 : parseInt(add, 10) || 0;\n const deletions = del === \"-\" ? 0 : parseInt(del, 10) || 0;\n files.push({ file, additions, deletions });\n totalAdditions += additions;\n totalDeletions += deletions;\n }\n\n respond(msg.requestId, { files, additions: totalAdditions, deletions: totalDeletions });\n } catch {\n respond(msg.requestId, { files: [], additions: 0, deletions: 0 });\n }\n }\n\n return { handle };\n}\n","/**\n * Local WS Server\n *\n * Listens on 127.0.0.1 only — for VSCode extension and CLI clients.\n * No auth needed (localhost-only, same user).\n *\n * Supports multiple concurrent clients (TUI, VSCode, web — all receive broadcasts).\n */\n\nimport { WebSocketServer, WebSocket } from \"ws\";\n\nimport type { InboundMessage, OutboundMessage } from \"./protocol\";\n\n/**\n * Check if the agent port is already in use (another agent is running).\n */\nexport async function isPortInUse(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const ws = new WebSocket(`ws://127.0.0.1:${port}`);\n const timeout = setTimeout(() => {\n ws.close();\n resolve(false);\n }, 1000);\n\n ws.on(\"open\", () => {\n clearTimeout(timeout);\n ws.send(JSON.stringify({ type: \"ping\" }));\n ws.on(\"message\", () => {\n ws.close();\n resolve(true);\n });\n });\n\n ws.on(\"error\", () => {\n clearTimeout(timeout);\n resolve(false);\n });\n });\n}\n\nexport function createLocalServer(port: number) {\n const clients = new Set<WebSocket>();\n const wss = new WebSocketServer({ host: \"127.0.0.1\", port });\n\n // Handle port already in use\n wss.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n console.error(\n `\\nError: Port ${port} is already in use.` +\n `\\nAnother Jarvis agent is already running on this port.` +\n `\\nClients (jarvis chat, VSCode) can connect to the existing agent.` +\n `\\nTo use a different port: jarvis start --port <port>\\n`,\n );\n process.exit(1);\n }\n throw err;\n });\n\n wss.on(\"connection\", (ws) => {\n clients.add(ws);\n ws.on(\"close\", () => clients.delete(ws));\n ws.on(\"error\", () => clients.delete(ws));\n });\n\n /** Broadcast an outbound message to all connected local clients */\n function broadcast(msg: OutboundMessage): void {\n const data = JSON.stringify(msg);\n for (const ws of clients) {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(data);\n }\n }\n }\n\n /** Register a handler for inbound messages from local clients */\n function onMessage(handler: (msg: InboundMessage, ws: WebSocket) => void): void {\n wss.on(\"connection\", (ws) => {\n ws.on(\"message\", (raw) => {\n try {\n const msg = JSON.parse(raw.toString()) as InboundMessage;\n if (msg.type === \"ping\") {\n ws.send(JSON.stringify({ type: \"pong\" }));\n return;\n }\n handler(msg, ws);\n } catch {\n // Ignore malformed messages\n }\n });\n });\n }\n\n /** Number of connected clients */\n function clientCount(): number {\n return clients.size;\n }\n\n function close(): void {\n for (const ws of clients) ws.close();\n wss.close();\n }\n\n return { broadcast, onMessage, clientCount, close };\n}\n","/**\n * Upstream WS Client\n *\n * Connects to the cloud API so web/mobile can dispatch tasks\n * and receive progress from this local agent.\n */\n\nimport WebSocket from \"ws\";\n\nimport { logger } from \"@jarvis/logger\";\n\nimport type { InboundMessage, OutboundMessage } from \"./protocol\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface UpstreamConfig {\n apiUrl: string;\n token: string;\n}\n\n// =============================================================================\n// Client\n// =============================================================================\n\nexport function createUpstreamClient(config: UpstreamConfig) {\n let ws: WebSocket | null = null;\n let messageHandler: ((msg: InboundMessage) => void) | null = null;\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let closed = false;\n\n function connect(): void {\n if (closed) return;\n\n ws = new WebSocket(config.apiUrl, {\n headers: { authorization: `Bearer ${config.token}` },\n });\n\n ws.on(\"open\", () => {\n logger.sys.info(\"[Upstream] Connected to cloud\", { apiUrl: config.apiUrl });\n });\n\n ws.on(\"message\", (raw) => {\n try {\n const msg = JSON.parse(raw.toString()) as InboundMessage;\n if (msg.type === \"ping\") {\n ws?.send(JSON.stringify({ type: \"pong\" }));\n return;\n }\n messageHandler?.(msg);\n } catch {\n // Ignore malformed messages\n }\n });\n\n ws.on(\"close\", () => {\n if (!closed) {\n logger.sys.info(\"[Upstream] Disconnected, reconnecting in 3s...\");\n reconnectTimer = setTimeout(connect, 3000);\n }\n });\n\n ws.on(\"error\", (err) => {\n logger.sys.error(\"[Upstream] Connection error\", {\n error: err.message,\n });\n });\n }\n\n function send(msg: OutboundMessage): void {\n if (ws?.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(msg));\n }\n }\n\n function onMessage(handler: (msg: InboundMessage) => void): void {\n messageHandler = handler;\n }\n\n function isConnected(): boolean {\n return ws?.readyState === WebSocket.OPEN;\n }\n\n function close(): void {\n closed = true;\n if (reconnectTimer) clearTimeout(reconnectTimer);\n ws?.close();\n }\n\n return { connect, send, onMessage, isConnected, close };\n}\n\nexport type UpstreamClient = ReturnType<typeof createUpstreamClient>;\n","/**\n * Agent Start\n *\n * Pure WS agent — no Temporal on the user's machine.\n *\n * 1. Local WS server (VSCode/CLI clients connect here)\n * 2. Upstream WS client (cloud hub — receives dispatches from Temporal workflow)\n * 3. Runs Claude Code locally, streams progress via WS\n *\n * The Temporal workflow dispatches to this agent through the WS hub.\n * Temporal stays in the cloud as source of truth for session state.\n */\n\nimport type { InboundMessage, OutboundMessage, UserInputResponse } from \"@jarvis/types\";\n\nimport { createAgent } from \"./agent\";\nimport { createGitHandler } from \"./git\";\nimport { createLocalServer } from \"./server\";\nimport { createUpstreamClient, type UpstreamConfig } from \"./upstream\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface StartAgentOptions {\n port: number;\n workspacePath: string;\n anthropicApiKey?: string;\n useSubscription?: boolean;\n userId: string;\n upstream?: UpstreamConfig;\n}\n\n// =============================================================================\n// Start\n// =============================================================================\n\nexport async function startAgent(options: StartAgentOptions): Promise<void> {\n // Pending input requests: inputId → resolve function\n const pendingInputs = new Map<string, (response: UserInputResponse) => void>();\n\n // --- Local WS server (VSCode, CLI) ---\n const server = createLocalServer(options.port);\n\n // --- Upstream WS client (cloud — optional) ---\n const upstream = options.upstream ? createUpstreamClient(options.upstream) : null;\n\n // --- Broadcast to ALL clients (local + upstream) ---\n function broadcast(msg: OutboundMessage): void {\n server.broadcast(msg);\n upstream?.send(msg);\n }\n\n // --- Input request/response flow ---\n function requestInput(taskId: string, input: import(\"@jarvis/types\").PendingUserInput): Promise<UserInputResponse> {\n return new Promise((resolve) => {\n pendingInputs.set(input.id, resolve);\n broadcast({ type: \"agent:onUserInputRequest\", taskId, input });\n });\n }\n\n // --- Git handler ---\n const git = createGitHandler(options.workspacePath, broadcast);\n\n // --- Create the agent ---\n const agent = createAgent({\n workspacePath: options.workspacePath,\n anthropicApiKey: options.anthropicApiKey,\n useSubscription: options.useSubscription,\n userId: options.userId,\n broadcast,\n requestInput,\n });\n\n // --- Handle inbound messages (from any source — local or upstream) ---\n function handleMessage(msg: InboundMessage): void {\n // Try git operations first\n if (msg.type.startsWith(\"git:\")) {\n git.handle(msg);\n return;\n }\n\n switch (msg.type) {\n case \"agent:dispatch\":\n agent.runTask(msg);\n break;\n\n case \"agent:abort\":\n agent.cancelTask(msg.taskId);\n break;\n\n case \"agent:userInput\": {\n const response: UserInputResponse = {\n action: msg.action as UserInputResponse[\"action\"],\n data: msg.data,\n feedback: msg.feedback,\n };\n const resolve = pendingInputs.get(msg.inputId);\n if (resolve) {\n resolve(response);\n pendingInputs.delete(msg.inputId);\n }\n break;\n }\n\n case \"ping\":\n // Handled at transport level\n break;\n }\n }\n\n // Wire up message handlers\n server.onMessage((msg) => handleMessage(msg));\n upstream?.onMessage(handleMessage);\n\n // Connect upstream if configured\n upstream?.connect();\n\n // --- Status output ---\n console.log();\n console.log(`Jarvis Agent v0.0.0`);\n console.log(` Local: ws://127.0.0.1:${options.port}`);\n console.log(` Workspace: ${options.workspacePath}`);\n console.log(` User: ${options.userId}`);\n if (upstream) {\n console.log(` Cloud: ${options.upstream!.apiUrl}`);\n }\n console.log();\n console.log(\"Waiting for tasks...\");\n console.log();\n\n // --- Graceful shutdown ---\n const shutdown = () => {\n console.log(\"\\nShutting down...\");\n server.close();\n upstream?.close();\n process.exit(0);\n };\n\n process.on(\"SIGTERM\", shutdown);\n process.on(\"SIGINT\", shutdown);\n}\n","/**\n * Chat Entry Point\n *\n * Launches the interactive TUI:\n * 1. Load settings (file + CLI flags)\n * 2. Auto-start agent server as a detached child process (silent)\n * 3. Render Ink app — owns stdout/stderr exclusively\n */\n\nimport React from \"react\";\nimport { render } from \"ink\";\nimport { spawn, type ChildProcess } from \"child_process\";\nimport { fileURLToPath } from \"url\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport os from \"os\";\nimport WebSocket from \"ws\";\n\nimport { loadSettings, mergeCliFlags, type TuiSettings } from \"./settings\";\nimport { loadConfig } from \"../config\";\nimport { App } from \"./app\";\n\n/** Agent child process — killed on TUI exit */\nlet agentChild: ChildProcess | null = null;\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ChatOptions {\n model?: string;\n mode?: string;\n thinking?: string;\n thinkingBudget?: string;\n maxTurns?: string;\n port: string;\n server: boolean; // --no-server sets to false\n workspace?: string;\n}\n\n// =============================================================================\n// Launch\n// =============================================================================\n\nexport async function launchChat(opts: ChatOptions): Promise<void> {\n const port = parseInt(opts.port, 10);\n const config = loadConfig();\n\n // Load and merge settings\n const fileSettings = loadSettings();\n const settings: TuiSettings = mergeCliFlags(fileSettings, {\n model: opts.model,\n mode: opts.mode,\n thinking: opts.thinking,\n thinkingBudget: opts.thinkingBudget,\n maxTurns: opts.maxTurns,\n });\n\n const workspacePath = opts.workspace ?? config?.workspacePath ?? process.cwd();\n\n // Auto-start agent server if --no-server wasn't passed\n let weSpawnedAgent = false;\n if (opts.server) {\n const isRunning = await checkAgentRunning(port);\n if (!isRunning) {\n spawnAgentProcess(port, workspacePath);\n weSpawnedAgent = true;\n await waitForAgent(port);\n }\n }\n\n // Kill agent on exit if we spawned it\n const cleanup = () => {\n if (weSpawnedAgent && agentChild && !agentChild.killed) {\n agentChild.kill(\"SIGTERM\");\n agentChild = null;\n }\n };\n\n process.on(\"exit\", cleanup);\n process.on(\"SIGINT\", () => {\n cleanup();\n process.exit(0);\n });\n process.on(\"SIGTERM\", () => {\n cleanup();\n process.exit(0);\n });\n process.on(\"SIGHUP\", () => {\n cleanup();\n process.exit(0);\n });\n\n // Render the TUI — Ink owns stdout/stderr from here\n const { waitUntilExit } = render(\n React.createElement(App, {\n initialSettings: settings,\n port,\n workspacePath,\n }),\n );\n\n await waitUntilExit();\n cleanup();\n}\n\n// =============================================================================\n// Agent Process (child, killed on TUI exit)\n// =============================================================================\n\n/**\n * Spawn `jarvis start` as a child process.\n * stdout/stderr → ~/.jarvis/agent.log (TUI owns the terminal).\n * NOT detached — dies when the TUI process exits.\n */\nfunction spawnAgentProcess(port: number, workspacePath: string): void {\n const config = loadConfig();\n\n // Log file for agent output\n const logDir = path.join(os.homedir(), \".jarvis\");\n fs.mkdirSync(logDir, { recursive: true });\n const logFile = path.join(logDir, \"agent.log\");\n const logFd = fs.openSync(logFile, \"a\");\n\n // Find the bin entry point (same binary the user invoked)\n const __filename = fileURLToPath(import.meta.url);\n const cliRoot = path.resolve(path.dirname(__filename), \"../..\");\n const binPath = path.join(cliRoot, \"bin\", \"jarvis.mjs\");\n\n // Build args for `jarvis start`\n const args = [\"start\", \"--port\", String(port), \"--workspace\", workspacePath];\n\n if (config?.apiUrl && config?.token) {\n // upstream is auto-detected from config\n } else {\n args.push(\"--no-upstream\");\n }\n\n const apiKey = config?.anthropicApiKey ?? process.env.ANTHROPIC_API_KEY;\n if (apiKey) {\n args.push(\"--api-key\", apiKey);\n }\n\n agentChild = spawn(process.execPath, [binPath, ...args], {\n stdio: [\"ignore\", logFd, logFd],\n cwd: workspacePath,\n env: { ...process.env },\n });\n\n fs.closeSync(logFd);\n}\n\n// =============================================================================\n// Agent Health Check\n// =============================================================================\n\nasync function checkAgentRunning(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n const ws = new WebSocket(`ws://127.0.0.1:${port}`);\n const timeout = setTimeout(() => {\n ws.close();\n resolve(false);\n }, 1000);\n\n ws.on(\"open\", () => {\n clearTimeout(timeout);\n ws.send(JSON.stringify({ type: \"ping\" }));\n ws.on(\"message\", () => {\n ws.close();\n resolve(true);\n });\n });\n\n ws.on(\"error\", () => {\n clearTimeout(timeout);\n resolve(false);\n });\n } catch {\n resolve(false);\n }\n });\n}\n\nasync function waitForAgent(port: number, maxAttempts = 30): Promise<void> {\n for (let i = 0; i < maxAttempts; i++) {\n const running = await checkAgentRunning(port);\n if (running) return;\n await new Promise((r) => setTimeout(r, 250));\n }\n // Don't console.log here — TUI will show connection status in status bar\n}\n","/**\n * TUI Settings\n *\n * Load/save/merge ~/.jarvis/settings.json — user preferences for the TUI.\n * These are TUI-local and applied per agent:dispatch message.\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\n\nimport type { ThinkingConfig } from \"@jarvis/types\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type PermissionMode = \"supervised\" | \"auto\" | \"plan\" | \"yolo\";\n\nexport interface TuiSettings {\n model: string;\n thinking: ThinkingConfig;\n permissionMode: PermissionMode;\n maxTurns: number;\n theme: \"dark\" | \"light\";\n disallowedTools: string[];\n}\n\n// =============================================================================\n// Defaults\n// =============================================================================\n\nexport const DEFAULT_SETTINGS: TuiSettings = {\n model: \"claude-sonnet-4-20250514\",\n thinking: { type: \"adaptive\" },\n permissionMode: \"supervised\",\n maxTurns: 25,\n theme: \"dark\",\n disallowedTools: [],\n};\n\n// =============================================================================\n// Paths\n// =============================================================================\n\nconst SETTINGS_DIR = path.join(os.homedir(), \".jarvis\");\nconst SETTINGS_FILE = path.join(SETTINGS_DIR, \"settings.json\");\n\n// =============================================================================\n// Operations\n// =============================================================================\n\nexport function loadSettings(): TuiSettings {\n try {\n const raw = fs.readFileSync(SETTINGS_FILE, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<TuiSettings>;\n return { ...DEFAULT_SETTINGS, ...parsed };\n } catch {\n return { ...DEFAULT_SETTINGS };\n }\n}\n\nexport function saveSettings(settings: TuiSettings): void {\n fs.mkdirSync(SETTINGS_DIR, { recursive: true });\n fs.writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2) + \"\\n\");\n}\n\n/**\n * Merge CLI flags into loaded settings.\n * Only non-undefined flags override.\n */\nexport function mergeCliFlags(\n settings: TuiSettings,\n flags: {\n model?: string;\n mode?: string;\n thinking?: string;\n thinkingBudget?: string;\n maxTurns?: string;\n },\n): TuiSettings {\n const merged = { ...settings };\n\n if (flags.model) merged.model = flags.model;\n if (flags.mode) merged.permissionMode = flags.mode as PermissionMode;\n if (flags.maxTurns) merged.maxTurns = parseInt(flags.maxTurns, 10);\n\n if (flags.thinking) {\n const type = flags.thinking as ThinkingConfig[\"type\"];\n merged.thinking = { type };\n if (type === \"enabled\" && flags.thinkingBudget) {\n merged.thinking.budgetTokens = parseInt(flags.thinkingBudget, 10);\n }\n }\n\n return merged;\n}\n\nexport function getSettingsPath(): string {\n return SETTINGS_FILE;\n}\n","/**\n * Jarvis TUI App\n *\n * Rendering strategy — zero dynamic content above the input bar:\n * - ALL messages go into <Static> (rendered once, never re-rendered)\n * - Streaming text is committed to <Static> only when finalized\n * - The ONLY dynamic elements are: spinner + overlays + input bar + footer\n * - This eliminates all jumpiness during streaming\n */\n\nimport React, { useState, useCallback, useRef, useEffect } from \"react\";\nimport { Box, Static, Text, useApp, useInput } from \"ink\";\n\nimport type { OutboundMessage, AgentOnTokenEvent } from \"@jarvis/types\";\n\nimport type { TuiSettings } from \"./settings\";\nimport { useAgentClient } from \"./hooks/use-agent-client\";\nimport { useMessages, type DisplayMessage } from \"./hooks/use-messages\";\nimport { useTask } from \"./hooks/use-task\";\nimport { useSettings } from \"./hooks/use-settings\";\nimport { parseSlashCommand } from \"./utils/slash-commands\";\nimport { shouldAutoApprove } from \"./utils/auto-approve\";\n\nimport { WelcomeHeader } from \"./components/welcome-header\";\nimport { UserMessage } from \"./components/user-message\";\nimport { Spinner } from \"./components/spinner\";\nimport { Divider } from \"./components/divider\";\nimport { PromptInput } from \"./components/prompt-input\";\nimport { StatusBar } from \"./components/status-bar\";\nimport { PermissionDialog } from \"./components/permission-dialog\";\nimport { PlanReview } from \"./components/plan-review\";\nimport { MaxIterations } from \"./components/max-iterations\";\nimport { HelpMenu } from \"./components/help-menu\";\nimport { StatusDisplay } from \"./components/status-display\";\nimport { ModelPicker } from \"./components/model-picker\";\nimport { ModePicker } from \"./components/mode-picker\";\nimport { ThinkingPicker } from \"./components/thinking-picker\";\nimport { SettingsDialog } from \"./components/settings-dialog\";\nimport { Notification } from \"./components/notification\";\nimport { MarkdownText } from \"./components/markdown-text\";\nimport { t } from \"./theme\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype Overlay = \"none\" | \"help\" | \"status\" | \"config\" | \"model\" | \"mode\" | \"thinking\";\n\ninterface AppProps {\n initialSettings: TuiSettings;\n port: number;\n workspacePath: string;\n}\n\ninterface StaticItem {\n key: string;\n node: React.ReactNode;\n}\n\n// =============================================================================\n// App\n// =============================================================================\n\nexport function App({ initialSettings, port, workspacePath }: AppProps) {\n const { exit } = useApp();\n const [overlay, setOverlay] = useState<Overlay>(\"none\");\n const [notification, setNotification] = useState<string | null>(null);\n\n const { settings, setModel, setThinking, setPermissionMode, cyclePermissionMode, setMaxTurns } =\n useSettings(initialSettings);\n\n const {\n messages,\n streamingTextContent: _streamingTextContent,\n addUserMessage,\n handleChatMessage,\n handleTokenEvent,\n clearMessages,\n } = useMessages();\n\n // ==========================================================================\n // Static output — append-only list rendered by <Static>\n // ==========================================================================\n\n const [staticItems, setStaticItems] = useState<StaticItem[]>([\n {\n key: \"welcome\",\n node: <WelcomeHeader settings={settings} workspacePath={workspacePath} />,\n },\n ]);\n const committedIdsRef = useRef(new Set<string>());\n\n // Commit finalized messages to static.\n // Thinking messages are always isPartial=true (never finalized by the agent),\n // so we commit them when a newer message appears after them (thinking is over).\n useEffect(() => {\n const newItems: StaticItem[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i]!;\n if (committedIdsRef.current.has(msg.id)) continue;\n\n // Non-partial → commit immediately\n if (!msg.isPartial) {\n committedIdsRef.current.add(msg.id);\n newItems.push({ key: msg.id, node: renderMessage(msg) });\n continue;\n }\n\n // Partial thinking → commit if a later message exists (thinking phase is over)\n if (msg.type === \"thinking\" && i < messages.length - 1) {\n committedIdsRef.current.add(msg.id);\n newItems.push({ key: msg.id, node: renderMessage(msg) });\n continue;\n }\n }\n\n if (newItems.length > 0) {\n setStaticItems((prev) => [...prev, ...newItems]);\n }\n }, [messages]);\n\n // ==========================================================================\n // WS handler\n // ==========================================================================\n\n const handleWsMessage = useCallback(\n (msg: OutboundMessage) => {\n switch (msg.type) {\n case \"agent:onMessage\":\n handleChatMessage(msg.message);\n break;\n case \"agent:onToken\":\n handleTokenEvent(msg as AgentOnTokenEvent);\n break;\n case \"agent:onUsage\":\n task.addTokens(msg.totalTokens);\n break;\n case \"agent:onUserInputRequest\": {\n if (shouldAutoApprove(settings.permissionMode, msg.input)) {\n task.setPendingInput(msg.input);\n setTimeout(() => {\n if (task.currentTaskId) {\n client.respondToInput(task.currentTaskId, msg.input.id, \"allow\");\n task.setPendingInput(null);\n task.setAgentState(\"busy\");\n }\n }, 0);\n } else {\n task.setPendingInput(msg.input);\n task.setAgentState(\"awaiting-input\");\n }\n break;\n }\n case \"agent:output\":\n task.setAgentState(\"idle\");\n if (msg.output.sessionId) task.setSessionId(msg.output.sessionId);\n break;\n case \"agent:status\":\n if (msg.status === \"idle\") task.setAgentState(\"idle\");\n break;\n }\n },\n [settings.permissionMode],\n );\n\n const client = useAgentClient(port, handleWsMessage);\n const task = useTask(client, settings);\n\n // ==========================================================================\n // Keybindings\n // ==========================================================================\n\n useInput((_input, key) => {\n if (key.ctrl && _input === \"c\") {\n if (task.agentState === \"busy\") task.abort();\n else exit();\n return;\n }\n if (key.ctrl && _input === \"d\") { exit(); return; }\n if (key.shift && key.tab) {\n setNotification(`Mode: ${cyclePermissionMode()}`);\n return;\n }\n });\n\n const handleEscape = useCallback(() => {\n if (overlay !== \"none\") setOverlay(\"none\");\n else if (task.agentState === \"busy\" || task.agentState === \"awaiting-input\") task.abort();\n }, [overlay, task]);\n\n const handleHelp = useCallback(() => {\n setOverlay((prev) => (prev === \"help\" ? \"none\" : \"help\"));\n }, []);\n\n const handleSubmit = useCallback(\n (value: string) => {\n const cmd = parseSlashCommand(value);\n if (cmd) {\n switch (cmd.command) {\n case \"help\": setOverlay(\"help\"); return;\n case \"config\": setOverlay(\"config\"); return;\n case \"model\":\n if (cmd.arg) { setModel(cmd.arg); setNotification(`Model: ${cmd.arg}`); }\n else setOverlay(\"model\");\n return;\n case \"mode\":\n if (cmd.arg) { setPermissionMode(cmd.arg as TuiSettings[\"permissionMode\"]); setNotification(`Mode: ${cmd.arg}`); }\n else setOverlay(\"mode\");\n return;\n case \"thinking\":\n if (cmd.arg) {\n const tp = cmd.arg as \"adaptive\" | \"enabled\" | \"disabled\";\n setThinking({ type: tp, ...(tp === \"enabled\" ? { budgetTokens: 32768 } : {}) });\n setNotification(`Thinking: ${cmd.arg}`);\n } else setOverlay(\"thinking\");\n return;\n case \"status\": setOverlay(\"status\"); return;\n case \"clear\":\n clearMessages();\n committedIdsRef.current.clear();\n setStaticItems([{\n key: `welcome-${Date.now()}`,\n node: <WelcomeHeader settings={settings} workspacePath={workspacePath} />,\n }]);\n setNotification(\"Conversation cleared\");\n return;\n case \"compact\": setNotification(\"Compact not yet implemented\"); return;\n case \"exit\": exit(); return;\n }\n }\n addUserMessage(value);\n task.dispatch(value);\n },\n [addUserMessage, task, setModel, setThinking, setPermissionMode, clearMessages, exit, settings, workspacePath],\n );\n\n const closeOverlay = useCallback(() => setOverlay(\"none\"), []);\n\n // ==========================================================================\n // Render\n // ==========================================================================\n\n return (\n <Box flexDirection=\"column\">\n {/* All committed output — rendered once, scrolls naturally in terminal */}\n <Static items={staticItems}>\n {(item) => (\n <Box key={item.key} flexDirection=\"column\">\n {item.node}\n </Box>\n )}\n </Static>\n\n {/* === Everything below is the ONLY dynamic area === */}\n\n {/* Spinner (shown while agent is working) */}\n {task.agentState === \"busy\" && <Spinner />}\n\n {/* Overlays */}\n {overlay === \"help\" && <HelpMenu onClose={closeOverlay} />}\n {overlay === \"status\" && (\n <StatusDisplay settings={settings} connected={client.connected} port={port} sessionId={task.sessionId} totalTokens={task.totalTokens} workspacePath={workspacePath} onClose={closeOverlay} />\n )}\n {overlay === \"config\" && (\n <SettingsDialog settings={settings} onUpdateModel={setModel} onUpdateThinking={setThinking} onUpdateMode={setPermissionMode} onUpdateMaxTurns={setMaxTurns} onClose={closeOverlay} />\n )}\n {overlay === \"model\" && (\n <ModelPicker currentModel={settings.model} onSelect={setModel} onClose={closeOverlay} />\n )}\n {overlay === \"mode\" && (\n <ModePicker currentMode={settings.permissionMode} onSelect={setPermissionMode} onClose={closeOverlay} />\n )}\n {overlay === \"thinking\" && (\n <ThinkingPicker current={settings.thinking} onSelect={setThinking} onClose={closeOverlay} />\n )}\n\n {/* Permission dialogs */}\n {task.pendingInput && task.agentState === \"awaiting-input\" && (\n <>\n {task.pendingInput.type === \"tool\" && (\n <PermissionDialog input={task.pendingInput} onRespond={task.respondToInput} />\n )}\n {task.pendingInput.type === \"plan\" && (\n <PlanReview input={task.pendingInput} onRespond={task.respondToInput} />\n )}\n {task.pendingInput.type === \"max_iterations\" && (\n <MaxIterations input={task.pendingInput} onRespond={task.respondToInput} />\n )}\n </>\n )}\n\n {/* Notification */}\n <Notification message={notification} />\n\n {/* Bottom bar */}\n <Divider />\n <Box paddingX={0} marginY={0}>\n <PromptInput\n onSubmit={handleSubmit}\n onEscape={handleEscape}\n onHelp={handleHelp}\n onSlashCommand={handleSubmit}\n isLoading={task.agentState !== \"idle\"}\n workspacePath={workspacePath}\n />\n </Box>\n <Divider />\n <StatusBar\n mode={settings.permissionMode}\n model={settings.model}\n thinking={settings.thinking}\n agentState={task.agentState}\n totalTokens={task.totalTokens}\n connected={client.connected}\n sessionId={task.sessionId}\n workspacePath={workspacePath}\n />\n </Box>\n );\n}\n\n// =============================================================================\n// Message renderer — creates the React node for a committed message\n// =============================================================================\n\nfunction renderMessage(m: DisplayMessage): React.ReactNode {\n // User messages — gold arrow, extra spacing above\n if (m.type === \"user\") {\n return (\n <Box marginTop={1}>\n <UserMessage content={m.content} />\n </Box>\n );\n }\n\n // Tool calls — colored dot + tool name + description\n if (m.type === \"tool\") {\n const status = m.toolCall?.status ?? \"running\";\n const dot = status === \"completed\" ? t.toolSuccess : status === \"error\" ? t.toolError : t.toolRunning;\n const desc = getToolDesc(m.toolCall);\n return (\n <Box>\n <Box width={2} flexShrink={0}><Text color={dot}>●</Text></Box>\n <Text bold>{m.toolCall?.toolName ?? \"Tool\"}</Text>\n {desc && <Text color={t.dim}> {desc}</Text>}\n {m.toolCall?.error && <Text color={t.toolError}> {truncate(m.toolCall.error, 60)}</Text>}\n </Box>\n );\n }\n\n // Thinking — dim dot + muted content, spacing above\n if (m.type === \"thinking\") {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box>\n <Box width={2} flexShrink={0}><Text color={t.dim}>●</Text></Box>\n <Text color={t.dim} underline>Thinking</Text>\n </Box>\n {m.content && (\n <Box paddingLeft={2}>\n <Text color={t.dim}>{m.content}</Text>\n </Box>\n )}\n </Box>\n );\n }\n\n // Assistant text — green dot + markdown, spacing above\n if (m.type === \"assistant-text\") {\n return (\n <Box flexDirection=\"row\" marginTop={1}>\n <Box width={2} flexShrink={0}><Text color={t.toolSuccess}>●</Text></Box>\n <Box flexDirection=\"column\" flexGrow={1}>\n <MarkdownText content={m.content} />\n </Box>\n </Box>\n );\n }\n\n return null;\n}\n\nfunction getToolDesc(toolCall?: DisplayMessage[\"toolCall\"]): string {\n if (!toolCall) return \"\";\n const { toolName, input, output } = toolCall;\n if (toolCall.status === \"completed\" && output != null) {\n const out = String(output);\n if (out.length < 50 && !out.includes(\"\\n\")) return out;\n }\n if (!input) return \"\";\n switch (toolName) {\n case \"Read\": return String(input.file_path ?? \"\");\n case \"Write\": return String(input.file_path ?? \"\");\n case \"Edit\": return String(input.file_path ?? \"\");\n case \"Bash\": return truncate(String(input.command ?? \"\"), 50);\n case \"Glob\": return String(input.pattern ?? \"\");\n case \"Grep\": return String(input.pattern ?? \"\");\n case \"Agent\": return String(input.description ?? \"\");\n default: return \"\";\n }\n}\n\nfunction truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + \"…\";\n}\n","/**\n * useAgentClient Hook\n *\n * WS client hook that mirrors AgentClient from apps/vscode/src/agent.client.ts.\n * Connects to the local agent server on 127.0.0.1:PORT.\n */\n\nimport { useState, useEffect, useCallback, useRef } from \"react\";\nimport WebSocket from \"ws\";\n\nimport type {\n InboundMessage,\n OutboundMessage,\n AgentDispatchMessage,\n} from \"@jarvis/types\";\n\nexport interface AgentClientState {\n connected: boolean;\n send: (msg: InboundMessage) => void;\n dispatchTask: (task: AgentDispatchMessage) => void;\n abortTask: (taskId: string, reason?: string) => void;\n respondToInput: (\n taskId: string,\n inputId: string,\n action: string,\n data?: Record<string, unknown>,\n feedback?: string,\n ) => void;\n}\n\nexport function useAgentClient(\n port: number,\n onMessage: (msg: OutboundMessage) => void,\n): AgentClientState {\n const [connected, setConnected] = useState(false);\n const wsRef = useRef<WebSocket | null>(null);\n const closedRef = useRef(false);\n const onMessageRef = useRef(onMessage);\n onMessageRef.current = onMessage;\n\n useEffect(() => {\n closedRef.current = false;\n\n function tryConnect() {\n if (closedRef.current) return;\n\n try {\n const ws = new WebSocket(`ws://127.0.0.1:${port}`);\n wsRef.current = ws;\n\n ws.on(\"open\", () => setConnected(true));\n\n ws.on(\"message\", (raw) => {\n try {\n const msg = JSON.parse(raw.toString()) as OutboundMessage;\n if (msg.type === \"pong\") return;\n onMessageRef.current(msg);\n } catch {\n // Ignore malformed\n }\n });\n\n ws.on(\"close\", () => {\n setConnected(false);\n if (!closedRef.current) {\n setTimeout(tryConnect, 3000);\n }\n });\n\n ws.on(\"error\", () => {\n // Will trigger close → reconnect\n });\n } catch {\n if (!closedRef.current) {\n setTimeout(tryConnect, 3000);\n }\n }\n }\n\n tryConnect();\n\n return () => {\n closedRef.current = true;\n wsRef.current?.close();\n wsRef.current = null;\n };\n }, [port]);\n\n const send = useCallback((msg: InboundMessage) => {\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n wsRef.current.send(JSON.stringify(msg));\n }\n }, []);\n\n const dispatchTask = useCallback(\n (task: AgentDispatchMessage) => send(task),\n [send],\n );\n\n const abortTask = useCallback(\n (taskId: string, reason?: string) =>\n send({ type: \"agent:abort\", taskId, reason }),\n [send],\n );\n\n const respondToInput = useCallback(\n (\n taskId: string,\n inputId: string,\n action: string,\n data?: Record<string, unknown>,\n feedback?: string,\n ) => send({ type: \"agent:userInput\", taskId, inputId, action, data, feedback }),\n [send],\n );\n\n return { connected, send, dispatchTask, abortTask, respondToInput };\n}\n","/**\n * useMessages Hook\n *\n * Manages the message list state from agent:onMessage + agent:onToken events.\n * Messages are keyed by ID — partial messages get replaced when updated.\n * Token events are throttled to prevent excessive re-renders.\n */\n\nimport { useState, useCallback, useRef } from \"react\";\n\nimport type { ChatMessage, AgentOnTokenEvent } from \"@jarvis/types\";\n\nexport interface DisplayMessage {\n id: string;\n type: \"user\" | \"assistant-text\" | \"thinking\" | \"tool\" | \"status\";\n content: string;\n toolCall?: ChatMessage[\"toolCall\"];\n thinking?: ChatMessage[\"thinking\"];\n ui?: ChatMessage[\"ui\"];\n isPartial?: boolean;\n createdAt?: string;\n}\n\nexport interface MessagesState {\n messages: DisplayMessage[];\n streamingTextContent: string | null;\n addUserMessage: (content: string) => void;\n handleChatMessage: (msg: ChatMessage) => void;\n handleTokenEvent: (event: AgentOnTokenEvent) => void;\n clearMessages: () => void;\n}\n\nconst TOKEN_THROTTLE_MS = 80; // ~12fps for streaming text, reduces flicker\n\nexport function useMessages(): MessagesState {\n const [messages, setMessages] = useState<DisplayMessage[]>([]);\n const [streamingTextContent, setStreamingTextContent] = useState<string | null>(null);\n const streamingIdRef = useRef<string | null>(null);\n const throttleRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pendingContentRef = useRef<string | null>(null);\n\n const addUserMessage = useCallback((content: string) => {\n const msg: DisplayMessage = {\n id: `user-${Date.now()}`,\n type: \"user\",\n content,\n createdAt: new Date().toISOString(),\n };\n setMessages((prev) => [...prev, msg]);\n }, []);\n\n const handleChatMessage = useCallback((msg: ChatMessage) => {\n const display: DisplayMessage = {\n id: msg.id,\n type:\n msg.type === \"thinking\"\n ? \"thinking\"\n : msg.type === \"tool\"\n ? \"tool\"\n : msg.type === \"status\"\n ? \"status\"\n : \"assistant-text\",\n content: msg.content,\n toolCall: msg.toolCall,\n thinking: msg.thinking,\n ui: msg.ui,\n isPartial: msg.isPartial,\n createdAt: msg.createdAt,\n };\n\n setMessages((prev) => {\n const idx = prev.findIndex((m) => m.id === msg.id);\n if (idx >= 0) {\n const updated = [...prev];\n updated[idx] = display;\n return updated;\n }\n return [...prev, display];\n });\n }, []);\n\n const flushStreamingContent = useCallback(() => {\n if (pendingContentRef.current !== null) {\n setStreamingTextContent(pendingContentRef.current);\n }\n throttleRef.current = null;\n }, []);\n\n const handleTokenEvent = useCallback((event: AgentOnTokenEvent) => {\n if (event.isComplete) {\n // Finalize: flush any pending content, add as message, clear streaming\n if (throttleRef.current) {\n clearTimeout(throttleRef.current);\n throttleRef.current = null;\n }\n streamingIdRef.current = null;\n pendingContentRef.current = null;\n setStreamingTextContent(null);\n setMessages((prev) => {\n const existing = prev.findIndex((m) => m.id === event.messageId);\n const finalMsg: DisplayMessage = {\n id: event.messageId,\n type: \"assistant-text\",\n content: event.content,\n isPartial: false,\n createdAt: new Date().toISOString(),\n };\n if (existing >= 0) {\n const updated = [...prev];\n updated[existing] = finalMsg;\n return updated;\n }\n return [...prev, finalMsg];\n });\n } else {\n // Streaming: throttle updates to reduce re-renders\n streamingIdRef.current = event.messageId;\n pendingContentRef.current = event.content;\n if (!throttleRef.current) {\n // Immediately show first token, then throttle subsequent ones\n setStreamingTextContent(event.content);\n throttleRef.current = setTimeout(flushStreamingContent, TOKEN_THROTTLE_MS);\n }\n }\n }, [flushStreamingContent]);\n\n const clearMessages = useCallback(() => {\n setMessages([]);\n setStreamingTextContent(null);\n streamingIdRef.current = null;\n pendingContentRef.current = null;\n if (throttleRef.current) {\n clearTimeout(throttleRef.current);\n throttleRef.current = null;\n }\n }, []);\n\n return {\n messages,\n streamingTextContent,\n addUserMessage,\n handleChatMessage,\n handleTokenEvent,\n clearMessages,\n };\n}\n","/**\n * useTask Hook\n *\n * Manages task lifecycle: dispatch, abort, user input responses.\n * Constructs agent:dispatch messages from TUI settings.\n */\n\nimport { useState, useCallback, useRef } from \"react\";\nimport crypto from \"crypto\";\n\nimport type { AgentDispatchMessage, PendingUserInput } from \"@jarvis/types\";\n\nimport type { TuiSettings } from \"../settings\";\nimport type { AgentClientState } from \"./use-agent-client\";\n\nexport type AgentState = \"idle\" | \"busy\" | \"awaiting-input\";\n\nexport interface TaskState {\n agentState: AgentState;\n currentTaskId: string | null;\n sessionId: string | null;\n totalTokens: number;\n pendingInput: PendingUserInput | null;\n dispatch: (userMessage: string) => void;\n abort: () => void;\n respondToInput: (\n action: string,\n data?: Record<string, unknown>,\n feedback?: string,\n ) => void;\n setAgentState: (state: AgentState) => void;\n setPendingInput: (input: PendingUserInput | null) => void;\n addTokens: (tokens: number) => void;\n setSessionId: (id: string) => void;\n}\n\nexport function useTask(\n client: AgentClientState,\n settings: TuiSettings,\n): TaskState {\n const [agentState, setAgentState] = useState<AgentState>(\"idle\");\n const [currentTaskId, setCurrentTaskId] = useState<string | null>(null);\n const [sessionId, setSessionId] = useState<string | null>(null);\n const [totalTokens, setTotalTokens] = useState(0);\n const [pendingInput, setPendingInput] = useState<PendingUserInput | null>(null);\n const chatIdRef = useRef(`chat-${crypto.randomUUID()}`);\n\n const dispatch = useCallback(\n (userMessage: string) => {\n const taskId = crypto.randomUUID();\n setCurrentTaskId(taskId);\n setAgentState(\"busy\");\n\n const msg: AgentDispatchMessage = {\n type: \"agent:dispatch\",\n taskId,\n chatId: chatIdRef.current,\n messages: [{ role: \"user\", content: userMessage }],\n model: settings.model,\n maxTurns: settings.maxTurns,\n permissionMode:\n settings.permissionMode === \"yolo\"\n ? \"auto\"\n : settings.permissionMode,\n disallowedTools:\n settings.disallowedTools.length > 0\n ? settings.disallowedTools\n : undefined,\n ...(sessionId\n ? { session: { resume: sessionId, persistSession: true } }\n : { session: { persistSession: true } }),\n };\n\n client.dispatchTask(msg);\n },\n [client, settings, sessionId],\n );\n\n const abort = useCallback(() => {\n if (currentTaskId) {\n client.abortTask(currentTaskId);\n }\n }, [client, currentTaskId]);\n\n const respondToInput = useCallback(\n (\n action: string,\n data?: Record<string, unknown>,\n feedback?: string,\n ) => {\n if (currentTaskId && pendingInput) {\n client.respondToInput(\n currentTaskId,\n pendingInput.id,\n action,\n data,\n feedback,\n );\n setPendingInput(null);\n setAgentState(\"busy\");\n }\n },\n [client, currentTaskId, pendingInput],\n );\n\n const addTokens = useCallback((tokens: number) => {\n setTotalTokens((prev) => prev + tokens);\n }, []);\n\n return {\n agentState,\n currentTaskId,\n sessionId,\n totalTokens,\n pendingInput,\n dispatch,\n abort,\n respondToInput,\n setAgentState,\n setPendingInput,\n addTokens,\n setSessionId,\n };\n}\n","/**\n * useSettings Hook\n *\n * Runtime settings state with persistence to ~/.jarvis/settings.json.\n */\n\nimport { useState, useCallback } from \"react\";\n\nimport type { ThinkingConfig } from \"@jarvis/types\";\n\nimport {\n type TuiSettings,\n type PermissionMode,\n saveSettings,\n} from \"../settings\";\n\nconst MODE_CYCLE: PermissionMode[] = [\"supervised\", \"auto\", \"plan\", \"yolo\"];\n\nexport interface SettingsState {\n settings: TuiSettings;\n setModel: (model: string) => void;\n setThinking: (thinking: ThinkingConfig) => void;\n setPermissionMode: (mode: PermissionMode) => void;\n cyclePermissionMode: () => PermissionMode;\n setMaxTurns: (turns: number) => void;\n setTheme: (theme: \"dark\" | \"light\") => void;\n}\n\nexport function useSettings(initial: TuiSettings): SettingsState {\n const [settings, setSettings] = useState<TuiSettings>(initial);\n\n const update = useCallback((patch: Partial<TuiSettings>) => {\n setSettings((prev) => {\n const next = { ...prev, ...patch };\n saveSettings(next);\n return next;\n });\n }, []);\n\n const setModel = useCallback(\n (model: string) => update({ model }),\n [update],\n );\n\n const setThinking = useCallback(\n (thinking: ThinkingConfig) => update({ thinking }),\n [update],\n );\n\n const setPermissionMode = useCallback(\n (permissionMode: PermissionMode) => update({ permissionMode }),\n [update],\n );\n\n const cyclePermissionMode = useCallback(() => {\n let nextMode: PermissionMode = \"supervised\";\n setSettings((prev) => {\n const idx = MODE_CYCLE.indexOf(prev.permissionMode);\n nextMode = MODE_CYCLE[(idx + 1) % MODE_CYCLE.length]!;\n const next = { ...prev, permissionMode: nextMode };\n saveSettings(next);\n return next;\n });\n return nextMode;\n }, []);\n\n const setMaxTurns = useCallback(\n (maxTurns: number) => update({ maxTurns }),\n [update],\n );\n\n const setTheme = useCallback(\n (theme: \"dark\" | \"light\") => update({ theme }),\n [update],\n );\n\n return {\n settings,\n setModel,\n setThinking,\n setPermissionMode,\n cyclePermissionMode,\n setMaxTurns,\n setTheme,\n };\n}\n","/**\n * Slash Command Parser\n *\n * Parses /command [args] from user input.\n */\n\nexport type SlashCommand =\n | { command: \"help\" }\n | { command: \"config\" }\n | { command: \"model\"; arg?: string }\n | { command: \"mode\"; arg?: string }\n | { command: \"thinking\"; arg?: string }\n | { command: \"status\" }\n | { command: \"clear\" }\n | { command: \"compact\" }\n | { command: \"exit\" };\n\nexport function parseSlashCommand(input: string): SlashCommand | null {\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"/\")) return null;\n\n const parts = trimmed.split(/\\s+/);\n const cmd = parts[0]!.slice(1).toLowerCase();\n const arg = parts.slice(1).join(\" \") || undefined;\n\n switch (cmd) {\n case \"help\":\n case \"h\":\n return { command: \"help\" };\n case \"config\":\n case \"settings\":\n return { command: \"config\" };\n case \"model\":\n case \"m\":\n return { command: \"model\", arg };\n case \"mode\":\n return { command: \"mode\", arg };\n case \"thinking\":\n return { command: \"thinking\", arg };\n case \"status\":\n return { command: \"status\" };\n case \"clear\":\n return { command: \"clear\" };\n case \"compact\":\n return { command: \"compact\" };\n case \"exit\":\n case \"quit\":\n case \"q\":\n return { command: \"exit\" };\n default:\n return null;\n }\n}\n","/**\n * Auto-Approval Logic\n *\n * Determines whether a tool should be auto-approved based on permission mode.\n */\n\nimport type { PendingUserInput } from \"@jarvis/types\";\n\nimport type { PermissionMode } from \"../settings\";\n\n/** Tools considered safe for auto-approval in \"auto\" mode */\nconst SAFE_TOOLS = new Set([\n \"Read\",\n \"Glob\",\n \"Grep\",\n \"WebSearch\",\n \"WebFetch\",\n \"Agent\",\n \"TodoWrite\",\n \"Skill\",\n \"ToolSearch\",\n]);\n\n/**\n * Returns true if the pending input should be auto-approved without showing a dialog.\n */\nexport function shouldAutoApprove(\n mode: PermissionMode,\n input: PendingUserInput,\n): boolean {\n // Plan type always needs review in plan mode, auto-approve otherwise\n if (input.type === \"plan\") {\n return mode !== \"plan\" && mode !== \"supervised\";\n }\n\n // Max iterations: always ask\n if (input.type === \"max_iterations\") {\n return false;\n }\n\n // Yolo mode: approve everything\n if (mode === \"yolo\") return true;\n\n // Auto mode: approve safe tools, ask for dangerous\n if (mode === \"auto\") {\n const toolName = input.toolName ?? \"\";\n return SAFE_TOOLS.has(toolName);\n }\n\n // Supervised/plan: never auto-approve tools\n return false;\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport type { TuiSettings } from \"../settings\";\nimport { t } from \"../theme\";\n\ninterface WelcomeHeaderProps {\n settings: TuiSettings;\n workspacePath: string;\n}\n\nconst LOGO = [\n \" ╦╔═╗╦═╗╦ ╦╦╔═╗\",\n \" ║╠═╣╠╦╝╚╗╔╝║╚═╗\",\n \" ╚╝╩ ╩╩╚═ ╚╝ ╩╚═╝\",\n];\n\nfunction shortModel(model: string): string {\n const m = model.match(/(sonnet|opus|haiku)[- ](\\d+(?:\\.\\d+)?)/i);\n if (m) return `${m[1]![0]!.toUpperCase()}${m[1]!.slice(1)} ${m[2]}`;\n return model;\n}\n\nfunction shortPath(p: string): string {\n const home = process.env.HOME ?? \"\";\n if (home && p.startsWith(home)) return \"~\" + p.slice(home.length);\n return p;\n}\n\nexport function WelcomeHeader({ settings, workspacePath }: WelcomeHeaderProps) {\n return (\n <Box flexDirection=\"column\" paddingTop={1} paddingBottom={0}>\n <Box flexDirection=\"column\" paddingLeft={4}>\n {LOGO.map((line, i) => (\n <Text key={i} color={t.logo} bold>{line}</Text>\n ))}\n </Box>\n <Box flexDirection=\"column\" paddingLeft={4} marginTop={0}>\n <Text>\n <Text color={t.logo} bold>Jarvis</Text>\n <Text color={t.dim}>{\" v0.1.0\"}</Text>\n </Text>\n <Text color={t.dim}>\n {shortModel(settings.model)} · {settings.permissionMode}\n </Text>\n <Text color={t.dim}>\n {shortPath(workspacePath)}\n </Text>\n </Box>\n </Box>\n );\n}\n","/**\n * TUI Theme\n *\n * JARVIS terminal color palette — matches the web app theme:\n * Primary: #FFB800 (gold/amber — Iron Man's gold)\n * Secondary: #DC4545 (soft red — Iron Man's red)\n * Neutral: #1E293B (navy-tinted gray)\n *\n * Only accents/indicators are colorful. Regular text stays default.\n */\n\n// =============================================================================\n// Brand Colors (hex values for Ink's `color` prop)\n// =============================================================================\n\nexport const colors = {\n // Primary — gold\n gold: \"#FFB800\",\n goldDim: \"#B38200\",\n goldBg: \"#3D2E00\",\n\n // Secondary — red\n red: \"#DC4545\",\n redDim: \"#991B1B\",\n\n // Accent — purple (from SDK theme)\n purple: \"#8270DB\",\n\n // Status\n green: \"#22C55E\",\n yellow: \"#FFB800\",\n cyan: \"#06B6D4\",\n\n // Neutral\n navy: \"#1E293B\",\n navyLight: \"#64748B\",\n navyLighter: \"#94A3B8\",\n\n // Foreground\n text: undefined, // default terminal color\n dim: \"#64748B\",\n muted: \"#94A3B8\",\n} as const;\n\n// =============================================================================\n// Semantic tokens — what color each UI element uses\n// =============================================================================\n\nexport const t = {\n // Logo & branding\n logo: colors.gold,\n\n // Prompt\n promptArrow: colors.gold,\n\n // Spinner / working indicator\n spinner: colors.gold,\n\n // Divider\n divider: colors.navyLight,\n\n // Tool icons\n toolSuccess: colors.green,\n toolError: colors.red,\n toolRunning: colors.gold,\n\n // Permission mode indicator\n mode: {\n supervised: colors.green,\n auto: colors.gold,\n plan: colors.purple,\n yolo: colors.red,\n } as Record<string, string>,\n\n // Headings in markdown\n heading: colors.gold,\n\n // Slash commands in help menu\n command: colors.gold,\n\n // Status bar\n hint: colors.dim,\n disconnected: colors.red,\n\n // Overlays — border accents\n dialogBorder: colors.navyLight,\n dialogTitle: colors.gold,\n dialogAction: colors.gold,\n dialogDanger: colors.red,\n\n // Notification flash\n notification: colors.gold,\n\n // Dim / muted text\n dim: colors.dim,\n muted: colors.muted,\n} as const;\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { t } from \"../theme\";\n\ninterface UserMessageProps {\n content: string;\n}\n\nexport function UserMessage({ content }: UserMessageProps) {\n return (\n <Box marginTop={1}>\n <Text color={t.promptArrow} bold>{\"❯ \"}</Text>\n <Text>{content}</Text>\n </Box>\n );\n}\n","import React, { useState, useEffect, useRef } from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { t } from \"../theme\";\n\n// =============================================================================\n// Fake word generator (from packages/ui StreamingText)\n// =============================================================================\n\nconst PREFIXES = [\n \"Pro\", \"Re\", \"De\", \"Con\", \"Syn\", \"Meta\", \"Hyper\", \"Trans\",\n \"Neo\", \"Poly\", \"Multi\", \"Sub\", \"Inter\", \"Ultra\", \"Semi\",\n \"Auto\", \"Para\", \"Mono\",\n];\nconst ROOTS = [\n \"cog\", \"flux\", \"morph\", \"lex\", \"graph\", \"lys\", \"gen\", \"struct\",\n \"val\", \"duc\", \"fract\", \"gress\", \"ject\", \"spect\", \"vert\", \"tract\",\n \"form\", \"plex\", \"crypt\", \"volt\", \"quant\", \"phas\", \"nex\", \"fus\",\n];\nconst SUFFIXES = [\n \"izing\", \"ating\", \"ifying\", \"enting\", \"uting\", \"ecting\", \"uming\",\n \"ering\", \"ising\", \"ancing\", \"encing\", \"oring\", \"uring\", \"aling\",\n];\n\nfunction pick<T>(arr: T[]): T {\n return arr[Math.floor(Math.random() * arr.length)]!;\n}\n\nfunction generateWord(): string {\n const usePrefix = Math.random() > 0.3;\n const prefix = usePrefix ? pick(PREFIXES) : \"\";\n const root = pick(ROOTS);\n const suffix = pick(SUFFIXES);\n const word = prefix + root + suffix;\n return word.charAt(0).toUpperCase() + word.slice(1);\n}\n\n// =============================================================================\n// Spinner glyph — Claude Code style: growing/shrinking symbols\n// Wrapped in fixed-width Box to prevent jumpiness\n// =============================================================================\n\nconst GLYPHS =\n process.platform === \"darwin\"\n ? [\"·\", \"✢\", \"✳\", \"✶\", \"✻\", \"✽\"]\n : [\"·\", \"✢\", \"*\", \"✶\", \"✻\", \"✽\"];\n\nconst GLYPH_FRAMES = [...GLYPHS, ...[...GLYPHS].reverse()];\n\n// =============================================================================\n// Component\n// =============================================================================\n\nexport function Spinner() {\n const [glyphFrame, setGlyphFrame] = useState(0);\n const [word, setWord] = useState(generateWord);\n const [overwriteIdx, setOverwriteIdx] = useState(0);\n const [prevWord, setPrevWord] = useState(\"\");\n const [phase, setPhase] = useState<\"display\" | \"transition\">(\"display\");\n const startRef = useRef(Date.now());\n\n // Glyph animation: 120ms per frame\n useEffect(() => {\n const timer = setInterval(\n () => setGlyphFrame((f) => (f + 1) % GLYPH_FRAMES.length),\n 120,\n );\n return () => clearInterval(timer);\n }, []);\n\n // Word transition: overwrite char by char at 50ms\n useEffect(() => {\n if (phase === \"transition\") {\n const totalLen = (prevWord + \"…\").length;\n if (overwriteIdx < totalLen) {\n const timer = setTimeout(() => setOverwriteIdx((i) => i + 1), 50);\n return () => clearTimeout(timer);\n } else {\n setPhase(\"display\");\n }\n }\n }, [overwriteIdx, prevWord, phase]);\n\n // Wait then start next word transition\n useEffect(() => {\n if (phase === \"display\") {\n const timer = setTimeout(() => {\n setPrevWord(word);\n setWord(generateWord());\n setOverwriteIdx(0);\n setPhase(\"transition\");\n }, 2500);\n return () => clearTimeout(timer);\n }\n }, [phase, word]);\n\n const elapsed = Math.floor((Date.now() - startRef.current) / 1000);\n\n // Build display text\n let displayText: string;\n if (phase === \"display\") {\n displayText = word + \"…\";\n } else {\n const oldText = prevWord + \"…\";\n const newText = word + \"…\";\n displayText = newText.slice(0, overwriteIdx) + oldText.slice(overwriteIdx);\n }\n\n return (\n <Box marginTop={1}>\n <Box width={2} flexShrink={0}>\n <Text color={t.spinner}>{GLYPH_FRAMES[glyphFrame]}</Text>\n </Box>\n <Text color={t.spinner}>{displayText}</Text>\n {elapsed > 2 && <Text color={t.dim}> {elapsed}s</Text>}\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { t } from \"../theme\";\nimport { useTerminal } from \"../hooks/use-terminal\";\n\nexport function Divider() {\n const { columns } = useTerminal();\n return (\n <Box>\n <Text color={t.divider}>{\"─\".repeat(columns)}</Text>\n </Box>\n );\n}\n","/**\n * useTerminal Hook\n *\n * Terminal dimensions with resize tracking.\n */\n\nimport { useState, useEffect } from \"react\";\n\nexport interface TerminalSize {\n columns: number;\n rows: number;\n}\n\nexport function useTerminal(): TerminalSize {\n const [size, setSize] = useState<TerminalSize>({\n columns: process.stdout.columns || 80,\n rows: process.stdout.rows || 24,\n });\n\n useEffect(() => {\n const onResize = () => {\n setSize({\n columns: process.stdout.columns || 80,\n rows: process.stdout.rows || 24,\n });\n };\n\n process.stdout.on(\"resize\", onResize);\n return () => {\n process.stdout.off(\"resize\", onResize);\n };\n }, []);\n\n return size;\n}\n","/**\n * PromptInput with autocomplete\n *\n * Detects:\n * - `/` at start → slash command suggestions\n * - `@` → file picker suggestions\n * - `?` on empty input → help toggle\n * - Esc → abort/close\n * - Arrow keys → navigate suggestions when open\n * - Enter → select suggestion or submit\n * - Tab → accept suggestion\n */\n\nimport React, { useState, useCallback, useMemo } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport TextInput from \"ink-text-input\";\n\nimport { t } from \"../theme\";\nimport {\n type Suggestion,\n filterSlashCommands,\n Suggestions,\n} from \"./suggestions\";\nimport { filterFiles, FilePicker } from \"./file-picker\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype PickerMode = \"none\" | \"slash\" | \"file\";\n\ninterface PromptInputProps {\n onSubmit: (value: string) => void;\n onEscape: () => void;\n onHelp: () => void;\n onSlashCommand: (command: string) => void;\n isLoading?: boolean;\n workspacePath: string;\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\nexport function PromptInput({\n onSubmit,\n onEscape,\n onHelp,\n onSlashCommand,\n isLoading,\n workspacePath,\n}: PromptInputProps) {\n const [value, setValue] = useState(\"\");\n const [selectedIdx, setSelectedIdx] = useState(0);\n\n // Detect picker mode from input\n const pickerMode: PickerMode = useMemo(() => {\n if (isLoading) return \"none\";\n if (value.startsWith(\"/\")) return \"slash\";\n // Detect @ at start or after whitespace\n const atMatch = value.match(/(^|\\s)@([^\\s]*)$/);\n if (atMatch) return \"file\";\n return \"none\";\n }, [value, isLoading]);\n\n // Get filtered suggestions\n const suggestions: Suggestion[] = useMemo(() => {\n if (pickerMode === \"slash\") {\n return filterSlashCommands(value.slice(1)); // remove leading /\n }\n if (pickerMode === \"file\") {\n const atMatch = value.match(/(^|\\s)@([^\\s]*)$/);\n const query = atMatch?.[2] ?? \"\";\n return filterFiles(query, workspacePath);\n }\n return [];\n }, [pickerMode, value, workspacePath]);\n\n // Reset selection when suggestions change\n const prevSugLen = React.useRef(suggestions.length);\n if (suggestions.length !== prevSugLen.current) {\n prevSugLen.current = suggestions.length;\n if (selectedIdx >= suggestions.length) {\n setSelectedIdx(Math.max(0, suggestions.length - 1));\n }\n }\n\n const handleMove = useCallback(\n (delta: number) => {\n setSelectedIdx((prev) => {\n const next = prev + delta;\n if (next < 0) return suggestions.length - 1;\n if (next >= suggestions.length) return 0;\n return next;\n });\n },\n [suggestions.length],\n );\n\n const handleSelectSuggestion = useCallback(\n (item: Suggestion) => {\n if (pickerMode === \"slash\") {\n // Execute the slash command directly\n setValue(\"\");\n onSlashCommand(item.value);\n } else if (pickerMode === \"file\") {\n // Replace @query with the file path\n const before = value.replace(/(^|\\s)@[^\\s]*$/, \"$1\");\n setValue(before + item.value + \" \");\n }\n setSelectedIdx(0);\n },\n [pickerMode, value, onSlashCommand],\n );\n\n const handleChange = useCallback(\n (text: string) => {\n if (!isLoading) {\n setValue(text);\n setSelectedIdx(0);\n }\n },\n [isLoading],\n );\n\n useInput((_input, key) => {\n // Escape\n if (key.escape) {\n if (pickerMode !== \"none\") {\n // Close suggestions by clearing the trigger char\n if (pickerMode === \"slash\") setValue(\"\");\n else setValue(value.replace(/(^|\\s)@[^\\s]*$/, \"$1\"));\n setSelectedIdx(0);\n } else {\n onEscape();\n }\n return;\n }\n\n // Arrow keys when suggestions are open\n if (pickerMode !== \"none\") {\n if (key.upArrow) {\n handleMove(-1);\n return;\n }\n if (key.downArrow) {\n handleMove(1);\n return;\n }\n if (key.tab && suggestions[selectedIdx]) {\n handleSelectSuggestion(suggestions[selectedIdx]);\n return;\n }\n }\n\n // ? on empty input → help\n if (_input === \"?\" && value === \"\" && !isLoading) {\n onHelp();\n return;\n }\n\n // Enter\n if (key.return) {\n // If suggestions open and one is selected, pick it\n if (pickerMode === \"slash\" && suggestions[selectedIdx]) {\n handleSelectSuggestion(suggestions[selectedIdx]);\n return;\n }\n // Otherwise submit\n if (value.trim() && !isLoading) {\n const text = value.trim();\n setValue(\"\");\n setSelectedIdx(0);\n onSubmit(text);\n }\n }\n });\n\n return (\n <Box flexDirection=\"column\">\n {/* Suggestions dropdown (above input) */}\n {pickerMode === \"slash\" && suggestions.length > 0 && (\n <Suggestions\n items={suggestions}\n selectedIndex={selectedIdx}\n />\n )}\n {pickerMode === \"file\" && suggestions.length > 0 && (\n <FilePicker\n items={suggestions}\n selectedIndex={selectedIdx}\n />\n )}\n\n {/* Input line */}\n <Box>\n <Text color={isLoading ? t.dim : t.promptArrow} dimColor={isLoading}>\n {\"❯ \"}\n </Text>\n <TextInput\n value={value}\n onChange={handleChange}\n placeholder=\"\"\n showCursor={!isLoading}\n />\n </Box>\n </Box>\n );\n}\n","/**\n * Suggestions Dropdown\n *\n * Renders filtered slash command suggestions.\n * Navigation is handled by PromptInput — this is a pure display component.\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { t } from \"../theme\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface Suggestion {\n id: string;\n icon: string;\n label: string;\n description: string;\n value: string;\n}\n\ninterface SuggestionsProps {\n items: Suggestion[];\n selectedIndex: number;\n maxVisible?: number;\n}\n\n// =============================================================================\n// Slash Commands\n// =============================================================================\n\nexport const SLASH_COMMANDS: Suggestion[] = [\n { id: \"help\", icon: \"?\", label: \"/help\", description: \"Show available commands\", value: \"/help\" },\n { id: \"config\", icon: \"⚙\", label: \"/config\", description: \"Open settings\", value: \"/config\" },\n { id: \"model\", icon: \"◆\", label: \"/model\", description: \"Switch model\", value: \"/model\" },\n { id: \"mode\", icon: \"●\", label: \"/mode\", description: \"Switch permission mode\", value: \"/mode\" },\n { id: \"thinking\", icon: \"▸\", label: \"/thinking\", description: \"Toggle thinking config\", value: \"/thinking\" },\n { id: \"status\", icon: \"ℹ\", label: \"/status\", description: \"Show session info\", value: \"/status\" },\n { id: \"clear\", icon: \"✕\", label: \"/clear\", description: \"Clear conversation\", value: \"/clear\" },\n { id: \"compact\", icon: \"◇\", label: \"/compact\", description: \"Compact old messages\", value: \"/compact\" },\n { id: \"exit\", icon: \"→\", label: \"/exit\", description: \"Exit Jarvis\", value: \"/exit\" },\n];\n\nexport function filterSlashCommands(query: string): Suggestion[] {\n const q = query.toLowerCase();\n if (!q) return SLASH_COMMANDS;\n return SLASH_COMMANDS.filter(\n (cmd) =>\n cmd.label.toLowerCase().includes(q) ||\n cmd.description.toLowerCase().includes(q),\n );\n}\n\n// =============================================================================\n// Component (pure display — no useInput)\n// =============================================================================\n\nexport function Suggestions({\n items,\n selectedIndex,\n maxVisible = 6,\n}: SuggestionsProps) {\n if (items.length === 0) return null;\n\n const half = Math.floor(maxVisible / 2);\n const startIdx = Math.max(\n 0,\n Math.min(selectedIndex - half, items.length - maxVisible),\n );\n const visible = items.slice(startIdx, startIdx + maxVisible);\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2} marginBottom={0}>\n {visible.map((item, i) => {\n const realIdx = startIdx + i;\n const selected = realIdx === selectedIndex;\n return (\n <Box key={item.id}>\n <Text color={selected ? t.dialogTitle : t.dim}>\n {selected ? \"❯ \" : \" \"}\n </Text>\n <Text color={selected ? t.dialogTitle : undefined} bold={selected}>\n {item.icon} {item.label}\n </Text>\n <Text color={t.dim}>{\" \"}{item.description}</Text>\n </Box>\n );\n })}\n </Box>\n );\n}\n","/**\n * File Picker\n *\n * Triggered by @ in the input. Shows files matching the query.\n * Pure display component — navigation handled by PromptInput.\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport path from \"path\";\nimport fs from \"fs\";\n\nimport { t } from \"../theme\";\nimport type { Suggestion } from \"./suggestions\";\n\n// =============================================================================\n// File scanning\n// =============================================================================\n\nlet cachedFiles: string[] | null = null;\n\nfunction scanFiles(workspacePath: string): string[] {\n if (cachedFiles) return cachedFiles;\n\n const results: string[] = [];\n const ignoreSet = new Set([\n \"node_modules\", \".git\", \"dist\", \"build\", \".next\", \"coverage\",\n \".turbo\", \".cache\", \"__pycache__\", \".DS_Store\",\n ]);\n\n function walk(dir: string, depth: number) {\n if (depth > 4) return;\n try {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (ignoreSet.has(entry.name) || entry.name.startsWith(\".\")) continue;\n const full = path.join(dir, entry.name);\n const rel = path.relative(workspacePath, full);\n if (entry.isDirectory()) {\n results.push(rel + \"/\");\n walk(full, depth + 1);\n } else {\n results.push(rel);\n }\n if (results.length > 500) return;\n }\n } catch {\n // permission errors\n }\n }\n\n walk(workspacePath, 0);\n cachedFiles = results;\n return results;\n}\n\nexport function filterFiles(query: string, workspacePath: string): Suggestion[] {\n const files = scanFiles(workspacePath);\n const q = query.toLowerCase();\n\n const matches = q\n ? files.filter((f) => f.toLowerCase().includes(q))\n : files.slice(0, 20);\n\n return matches.slice(0, 20).map((f) => ({\n id: `file-${f}`,\n icon: f.endsWith(\"/\") ? \"📁\" : \"📄\",\n label: f,\n description: \"\",\n value: f,\n }));\n}\n\nexport function resetFileCache(): void {\n cachedFiles = null;\n}\n\n// =============================================================================\n// Component (pure display — no useInput)\n// =============================================================================\n\ninterface FilePickerProps {\n items: Suggestion[];\n selectedIndex: number;\n maxVisible?: number;\n}\n\nexport function FilePicker({\n items,\n selectedIndex,\n maxVisible = 8,\n}: FilePickerProps) {\n if (items.length === 0) {\n return (\n <Box paddingLeft={2}>\n <Text color={t.dim}>No files found</Text>\n </Box>\n );\n }\n\n const half = Math.floor(maxVisible / 2);\n const startIdx = Math.max(\n 0,\n Math.min(selectedIndex - half, items.length - maxVisible),\n );\n const visible = items.slice(startIdx, startIdx + maxVisible);\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2} marginBottom={0}>\n {visible.map((item, i) => {\n const realIdx = startIdx + i;\n const selected = realIdx === selectedIndex;\n return (\n <Box key={item.id}>\n <Text color={selected ? t.dialogTitle : t.dim}>\n {selected ? \"❯ \" : \" \"}\n </Text>\n <Text color={selected ? t.dialogTitle : undefined} bold={selected}>\n {item.icon} {item.label}\n </Text>\n </Box>\n );\n })}\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport type { PermissionMode } from \"../settings\";\nimport type { AgentState } from \"../hooks/use-task\";\nimport type { ThinkingConfig } from \"@jarvis/types\";\nimport { formatTokens } from \"../utils/format-tokens\";\nimport { useTerminal } from \"../hooks/use-terminal\";\nimport { t } from \"../theme\";\n\ninterface StatusBarProps {\n mode: PermissionMode;\n model: string;\n thinking: ThinkingConfig;\n agentState: AgentState;\n totalTokens: number;\n connected: boolean;\n sessionId: string | null;\n workspacePath: string;\n}\n\nfunction shortModel(model: string): string {\n const m = model.match(/(sonnet|opus|haiku)[- ](\\d)/i);\n if (m) return `${m[1]![0]!.toUpperCase()}${m[1]!.slice(1)} ${m[2]}`;\n return model;\n}\n\nfunction getThinkingLabel(thinking: ThinkingConfig): string {\n if (thinking.type === \"disabled\") return \"\";\n if (thinking.type === \"adaptive\") return \"thinking\";\n return thinking.budgetTokens\n ? `thinking (${Math.round(thinking.budgetTokens / 1024)}k)`\n : \"thinking\";\n}\n\nfunction shortPath(p: string): string {\n const home = process.env.HOME ?? \"\";\n if (home && p.startsWith(home)) return \"~\" + p.slice(home.length);\n return p;\n}\n\nexport function StatusBar({\n mode,\n model,\n thinking,\n agentState,\n totalTokens,\n connected,\n sessionId,\n workspacePath,\n}: StatusBarProps) {\n const { columns } = useTerminal();\n\n // --- Row 1: left hints · right info ---\n\n // Left\n let leftText: string;\n if (agentState === \"awaiting-input\") {\n leftText = \"y/n to respond\";\n } else if (agentState === \"busy\") {\n leftText = \"esc to interrupt\";\n } else {\n leftText = \"? for shortcuts\";\n }\n\n // Right: model · mode · thinking · tokens\n const thinkingLabel = getThinkingLabel(thinking);\n const modelStr = shortModel(model);\n const tokenStr = totalTokens > 0 ? ` · ${formatTokens(totalTokens)} tokens` : \"\";\n const thinkingStr = thinkingLabel ? ` · ${thinkingLabel}` : \"\";\n const rightPlain = `${modelStr} · ${mode}${thinkingStr}${tokenStr}`;\n\n const gap1 = Math.max(1, columns - leftText.length - rightPlain.length - 2);\n\n // --- Row 2: left empty · right context info ---\n const contextParts: string[] = [];\n if (!connected) contextParts.push(\"disconnected\");\n if (sessionId) contextParts.push(`session: ${sessionId.slice(0, 8)}`);\n const row2Right = contextParts.length > 0\n ? contextParts.join(\" · \")\n : shortPath(workspacePath);\n\n return (\n <Box flexDirection=\"column\" paddingX={1}>\n {/* Row 1 */}\n <Box>\n <Text color={t.hint}>{leftText}</Text>\n <Text>{\" \".repeat(gap1)}</Text>\n {!connected ? (\n <Text color={t.disconnected}>{rightPlain}</Text>\n ) : (\n <Text>\n <Text color={t.hint}>{modelStr} · </Text>\n <Text color={t.mode[mode]}>{mode}</Text>\n {thinkingStr && <Text color={t.hint}>{thinkingStr}</Text>}\n {tokenStr && <Text color={t.hint}>{tokenStr}</Text>}\n </Text>\n )}\n </Box>\n {/* Row 2 */}\n <Box justifyContent=\"flex-end\">\n <Text color={t.hint}>{row2Right}</Text>\n </Box>\n </Box>\n );\n}\n","/**\n * Token formatting utilities\n */\n\nexport function formatTokens(count: number): string {\n if (count === 0) return \"0\";\n return count.toLocaleString(\"en-US\");\n}\n\nexport function formatDuration(startMs: number): string {\n const elapsed = (Date.now() - startMs) / 1000;\n if (elapsed < 60) return `${elapsed.toFixed(1)}s`;\n const mins = Math.floor(elapsed / 60);\n const secs = Math.floor(elapsed % 60);\n return `${mins}m${secs}s`;\n}\n","import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nimport type { PendingUserInput } from \"@jarvis/types\";\nimport { t } from \"../theme\";\n\ninterface PermissionDialogProps {\n input: PendingUserInput;\n onRespond: (action: string, data?: Record<string, unknown>, feedback?: string) => void;\n}\n\nexport function PermissionDialog({ input, onRespond }: PermissionDialogProps) {\n useInput((char) => {\n switch (char.toLowerCase()) {\n case \"y\": onRespond(\"allow\"); break;\n case \"n\": onRespond(\"deny\"); break;\n case \"a\": onRespond(\"allow\", { always: true }); break;\n }\n });\n\n const toolName = input.toolName ?? \"unknown\";\n const description = getInputDescription(input);\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>{\"╭─ \"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.dialogTitle} bold>Jarvis wants to use: {toolName}</Text>\n </Box>\n {description && (\n <>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n {description.split(\"\\n\").map((line, i) => (\n <Box key={i}>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text>{line}</Text>\n </Box>\n ))}\n </>\n )}\n {input.ui?.data != null && (\n <>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text dimColor>{truncate(JSON.stringify(input.ui.data, null, 2), 500)}</Text>\n </Box>\n </>\n )}\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.toolSuccess} bold>Allow (y)</Text>\n <Text>{\" \"}</Text>\n <Text color={t.dialogDanger} bold>Reject (n)</Text>\n <Text>{\" \"}</Text>\n <Text color={t.dialogAction} bold>Always allow (a)</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"╰─\"}</Text>\n </Box>\n );\n}\n\nfunction getInputDescription(input: PendingUserInput): string | null {\n const toolName = input.toolName ?? \"\";\n const inp = input.input ?? {};\n\n switch (toolName) {\n case \"Bash\":\n return `Command: ${inp.command ?? \"\"}${inp.description ? `\\nDescription: ${inp.description}` : \"\"}`;\n case \"Write\": return `File: ${inp.file_path ?? \"\"}`;\n case \"Edit\": return `File: ${inp.file_path ?? \"\"}`;\n case \"NotebookEdit\": return `Notebook: ${inp.notebook_path ?? \"\"}`;\n default:\n if (input.reason) return input.reason;\n return null;\n }\n}\n\nfunction truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 3) + \"...\";\n}\n","import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nimport type { PendingUserInput } from \"@jarvis/types\";\nimport { t } from \"../theme\";\n\ninterface PlanReviewProps {\n input: PendingUserInput;\n onRespond: (action: string, data?: Record<string, unknown>, feedback?: string) => void;\n}\n\nexport function PlanReview({ input, onRespond }: PlanReviewProps) {\n useInput((char) => {\n switch (char.toLowerCase()) {\n case \"y\": onRespond(\"allow\"); break;\n case \"n\": onRespond(\"deny\"); break;\n }\n });\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>{\"╭─ Plan ─\"}</Text>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n {input.items?.map((item, i) => (\n <Box key={item.id}>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text>{i + 1}. {item.title}</Text>\n </Box>\n ))}\n {input.reason && !input.items?.length && (\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text>{input.reason}</Text>\n </Box>\n )}\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.toolSuccess} bold>Approve plan (y)</Text>\n <Text>{\" \"}</Text>\n <Text color={t.dialogDanger} bold>Reject (n)</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"╰─\"}</Text>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nimport type { PendingUserInput } from \"@jarvis/types\";\nimport { t } from \"../theme\";\n\ninterface MaxIterationsProps {\n input: PendingUserInput;\n onRespond: (action: string, data?: Record<string, unknown>) => void;\n}\n\nexport function MaxIterations({ input, onRespond }: MaxIterationsProps) {\n useInput((char) => {\n switch (char.toLowerCase()) {\n case \"y\": onRespond(\"allow\"); break;\n case \"n\": onRespond(\"deny\"); break;\n }\n });\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>{\"╭─ \"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.dialogTitle} bold>\n Reached {input.iteration ?? \"?\"}/{input.maxIterations ?? \"?\"} turns\n </Text>\n </Box>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text>Continue for {input.initialMaxIterations ?? input.maxIterations ?? 25} more turns?</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.toolSuccess} bold>Continue (y)</Text>\n <Text>{\" \"}</Text>\n <Text color={t.dialogDanger} bold>Stop (n)</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"╰─\"}</Text>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nimport { t } from \"../theme\";\n\ninterface HelpMenuProps {\n onClose: () => void;\n}\n\nconst COMMANDS: [string, string][] = [\n [\"/config\", \"Open settings (model, thinking, mode)\"],\n [\"/model\", \"Quick model switch\"],\n [\"/mode\", \"Quick permission mode switch\"],\n [\"/thinking\", \"Toggle thinking config\"],\n [\"/status\", \"Show connection & session info\"],\n [\"/clear\", \"Clear conversation history and free up context\"],\n [\"/compact\", \"Compact old messages\"],\n [\"/help\", \"Show this help\"],\n [\"/exit\", \"Exit Jarvis\"],\n];\n\nexport function HelpMenu({ onClose }: HelpMenuProps) {\n useInput((_input, key) => {\n if (key.escape || _input === \"q\" || key.return) onClose();\n });\n\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={1}>\n {COMMANDS.map(([cmd, desc]) => (\n <Box key={cmd}>\n <Text color={t.command}>{cmd!.padEnd(16)}</Text>\n <Text>{desc}</Text>\n </Box>\n ))}\n <Box marginTop={1}>\n <Text color={t.hint}>Shift+Tab to cycle modes · Ctrl+C to interrupt · Esc to close</Text>\n </Box>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nimport type { TuiSettings } from \"../settings\";\nimport { formatTokens } from \"../utils/format-tokens\";\nimport { t } from \"../theme\";\n\ninterface StatusDisplayProps {\n settings: TuiSettings;\n connected: boolean;\n port: number;\n sessionId: string | null;\n totalTokens: number;\n workspacePath: string;\n onClose: () => void;\n}\n\nexport function StatusDisplay({\n settings,\n connected,\n port,\n sessionId,\n totalTokens,\n workspacePath,\n onClose,\n}: StatusDisplayProps) {\n useInput((_input, key) => {\n if (key.escape || _input === \"q\") onClose();\n });\n\n const thinkingLabel =\n settings.thinking.type === \"enabled\"\n ? `enabled (${settings.thinking.budgetTokens ?? 32768})`\n : settings.thinking.type;\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>\n {\"┌─ \"}\n <Text color={t.dialogTitle}>Jarvis Status</Text>\n {\" ─\"}\n </Text>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n {[\n [\"Agent\", `ws://127.0.0.1:${port} (${connected ? \"connected\" : \"disconnected\"})`],\n [\"Session\", sessionId ?? \"none\"],\n [\"Model\", settings.model],\n [\"Mode\", settings.permissionMode],\n [\"Thinking\", thinkingLabel],\n [\"Max turns\", String(settings.maxTurns)],\n [\"Workspace\", workspacePath],\n [\"Tokens used\", `${formatTokens(totalTokens)} (session)`],\n ].map(([label, value]) => (\n <Box key={label}>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text bold>{label!.padEnd(14)}</Text>\n <Text dimColor>{value}</Text>\n </Box>\n ))}\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.hint}>Press Esc or q to close</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"└─\"}</Text>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport SelectInput from \"ink-select-input\";\n\nimport { t } from \"../theme\";\n\ninterface ModelPickerProps {\n currentModel: string;\n onSelect: (model: string) => void;\n onClose: () => void;\n}\n\nconst MODELS = [\n { label: \"claude-sonnet-4-20250514\", value: \"claude-sonnet-4-20250514\" },\n { label: \"claude-opus-4-20250514\", value: \"claude-opus-4-20250514\" },\n { label: \"claude-haiku-4-5-20251001\", value: \"claude-haiku-4-5-20251001\" },\n];\n\nexport function ModelPicker({ currentModel, onSelect, onClose }: ModelPickerProps) {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>{\"┌─ \"}<Text color={t.dialogTitle}>Model</Text>{\" ─\"}</Text>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text dimColor>Current: {currentModel}</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box paddingLeft={2}>\n <SelectInput\n items={MODELS}\n initialIndex={MODELS.findIndex((m) => m.value === currentModel)}\n onSelect={(item) => { onSelect(item.value); onClose(); }}\n />\n </Box>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.hint}>↑/↓ select · Enter confirm · Esc cancel</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"└─\"}</Text>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport SelectInput from \"ink-select-input\";\n\nimport type { PermissionMode } from \"../settings\";\nimport { t } from \"../theme\";\n\ninterface ModePickerProps {\n currentMode: PermissionMode;\n onSelect: (mode: PermissionMode) => void;\n onClose: () => void;\n}\n\nconst MODES = [\n { label: \"Supervised — Ask before dangerous tools\", value: \"supervised\" as const },\n { label: \"Auto — Auto-approve safe tools\", value: \"auto\" as const },\n { label: \"Plan — Plan first, then execute\", value: \"plan\" as const },\n { label: \"Yolo — Bypass all permissions\", value: \"yolo\" as const },\n];\n\nexport function ModePicker({ currentMode, onSelect, onClose }: ModePickerProps) {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>{\"┌─ \"}<Text color={t.dialogTitle}>Permission Mode</Text>{\" ─\"}</Text>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box paddingLeft={2}>\n <SelectInput\n items={MODES}\n initialIndex={MODES.findIndex((m) => m.value === currentMode)}\n onSelect={(item) => { onSelect(item.value); onClose(); }}\n />\n </Box>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.hint}>↑/↓ select · Enter confirm · Esc cancel</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"└─\"}</Text>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport SelectInput from \"ink-select-input\";\n\nimport type { ThinkingConfig } from \"@jarvis/types\";\nimport { t } from \"../theme\";\n\ninterface ThinkingPickerProps {\n current: ThinkingConfig;\n onSelect: (config: ThinkingConfig) => void;\n onClose: () => void;\n}\n\nconst OPTIONS = [\n { label: \"Adaptive — Model decides when to think\", value: \"adaptive\" },\n { label: \"Enabled — Always think (budget: 32768)\", value: \"enabled\" },\n { label: \"Disabled — No extended thinking\", value: \"disabled\" },\n];\n\nexport function ThinkingPicker({ current, onSelect, onClose }: ThinkingPickerProps) {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>{\"┌─ \"}<Text color={t.dialogTitle}>Thinking</Text>{\" ─\"}</Text>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box paddingLeft={2}>\n <SelectInput\n items={OPTIONS}\n initialIndex={OPTIONS.findIndex((o) => o.value === current.type)}\n onSelect={(item) => {\n const config: ThinkingConfig = { type: item.value as ThinkingConfig[\"type\"] };\n if (item.value === \"enabled\") config.budgetTokens = 32768;\n onSelect(config);\n onClose();\n }}\n />\n </Box>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.hint}>↑/↓ select · Enter confirm · Esc cancel</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"└─\"}</Text>\n </Box>\n );\n}\n","import React, { useState } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport SelectInput from \"ink-select-input\";\n\nimport type { ThinkingConfig } from \"@jarvis/types\";\nimport type { PermissionMode, TuiSettings } from \"../settings\";\nimport { t } from \"../theme\";\n\ninterface SettingsDialogProps {\n settings: TuiSettings;\n onUpdateModel: (model: string) => void;\n onUpdateThinking: (thinking: ThinkingConfig) => void;\n onUpdateMode: (mode: PermissionMode) => void;\n onUpdateMaxTurns: (turns: number) => void;\n onClose: () => void;\n}\n\ntype Section = \"model\" | \"thinking\" | \"mode\" | \"maxTurns\";\nconst SECTIONS: Section[] = [\"model\", \"thinking\", \"mode\", \"maxTurns\"];\n\nconst MODELS = [\n { label: \"claude-sonnet-4-20250514\", value: \"claude-sonnet-4-20250514\" },\n { label: \"claude-opus-4-20250514\", value: \"claude-opus-4-20250514\" },\n { label: \"claude-haiku-4-5-20251001\", value: \"claude-haiku-4-5-20251001\" },\n];\n\nconst THINKING_OPTIONS = [\n { label: \"Adaptive — Model decides\", value: \"adaptive\" },\n { label: \"Enabled — Always (32k budget)\", value: \"enabled\" },\n { label: \"Disabled — Never\", value: \"disabled\" },\n];\n\nconst MODE_OPTIONS = [\n { label: \"Supervised\", value: \"supervised\" },\n { label: \"Auto\", value: \"auto\" },\n { label: \"Plan\", value: \"plan\" },\n { label: \"Yolo\", value: \"yolo\" },\n];\n\nconst MAX_TURNS_OPTIONS = [\n { label: \"10\", value: \"10\" },\n { label: \"25 (default)\", value: \"25\" },\n { label: \"50\", value: \"50\" },\n { label: \"100\", value: \"100\" },\n { label: \"200\", value: \"200\" },\n];\n\nexport function SettingsDialog({\n settings,\n onUpdateModel,\n onUpdateThinking,\n onUpdateMode,\n onUpdateMaxTurns,\n onClose,\n}: SettingsDialogProps) {\n const [activeSection, setActiveSection] = useState<Section>(\"model\");\n\n useInput((_input, key) => {\n if (key.escape) onClose();\n if (key.tab) {\n const idx = SECTIONS.indexOf(activeSection);\n setActiveSection(SECTIONS[(idx + 1) % SECTIONS.length]!);\n }\n });\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>\n {\"╭─ \"}\n <Text color={t.dialogTitle}>Settings</Text>\n {\" ─\"}\n </Text>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n\n {/* Model */}\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text bold color={activeSection === \"model\" ? t.dialogTitle : undefined}>\n Model\n </Text>\n </Box>\n {activeSection === \"model\" && (\n <Box paddingLeft={4}>\n <SelectInput\n items={MODELS}\n initialIndex={MODELS.findIndex((m) => m.value === settings.model)}\n onSelect={(item) => onUpdateModel(item.value)}\n />\n </Box>\n )}\n\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n\n {/* Thinking */}\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text bold color={activeSection === \"thinking\" ? t.dialogTitle : undefined}>\n Thinking\n </Text>\n </Box>\n {activeSection === \"thinking\" && (\n <Box paddingLeft={4}>\n <SelectInput\n items={THINKING_OPTIONS}\n initialIndex={THINKING_OPTIONS.findIndex((o) => o.value === settings.thinking.type)}\n onSelect={(item) => {\n const config: ThinkingConfig = { type: item.value as ThinkingConfig[\"type\"] };\n if (item.value === \"enabled\") config.budgetTokens = 32768;\n onUpdateThinking(config);\n }}\n />\n </Box>\n )}\n\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n\n {/* Permission Mode */}\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text bold color={activeSection === \"mode\" ? t.dialogTitle : undefined}>\n Permission Mode\n </Text>\n </Box>\n {activeSection === \"mode\" && (\n <Box paddingLeft={4}>\n <SelectInput\n items={MODE_OPTIONS}\n initialIndex={MODE_OPTIONS.findIndex((m) => m.value === settings.permissionMode)}\n onSelect={(item) => onUpdateMode(item.value as PermissionMode)}\n />\n </Box>\n )}\n\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n\n {/* Max Turns */}\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text bold color={activeSection === \"maxTurns\" ? t.dialogTitle : undefined}>\n Max Turns\n </Text>\n </Box>\n {activeSection === \"maxTurns\" && (\n <Box paddingLeft={4}>\n <SelectInput\n items={MAX_TURNS_OPTIONS}\n initialIndex={MAX_TURNS_OPTIONS.findIndex((o) => o.value === String(settings.maxTurns))}\n onSelect={(item) => onUpdateMaxTurns(parseInt(item.value, 10))}\n />\n </Box>\n )}\n\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.hint}>Tab to switch section · Esc to close</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"╰─\"}</Text>\n </Box>\n );\n}\n","import React, { useEffect, useState } from \"react\";\nimport { Text } from \"ink\";\n\nimport { t } from \"../theme\";\n\ninterface NotificationProps {\n message: string | null;\n duration?: number;\n}\n\nexport function Notification({ message, duration = 2000 }: NotificationProps) {\n const [visible, setVisible] = useState(false);\n const [text, setText] = useState(\"\");\n\n useEffect(() => {\n if (message) {\n setText(message);\n setVisible(true);\n const timer = setTimeout(() => setVisible(false), duration);\n return () => clearTimeout(timer);\n }\n }, [message, duration]);\n\n if (!visible || !text) return null;\n return <Text color={t.notification}>{text}</Text>;\n}\n","/**\n * Markdown Text Renderer\n *\n * Simple terminal markdown: bold, headers, lists, code blocks, inline code.\n * Matches Claude Code's clean output style.\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\n\ninterface MarkdownTextProps {\n content: string;\n}\n\nexport function MarkdownText({ content }: MarkdownTextProps) {\n if (!content) return null;\n\n const lines = content.split(\"\\n\");\n const elements: React.ReactNode[] = [];\n let inCodeBlock = false;\n let codeLines: string[] = [];\n let codeLanguage = \"\";\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n\n // Code block start/end\n if (line.startsWith(\"```\")) {\n if (inCodeBlock) {\n // End code block\n elements.push(\n <Box key={`code-${i}`} flexDirection=\"column\" marginTop={0} marginBottom={0} paddingLeft={2}>\n {codeLanguage && (\n <Text dimColor>{codeLanguage}</Text>\n )}\n {codeLines.map((cl, j) => (\n <Text key={j} color=\"gray\">{cl}</Text>\n ))}\n </Box>,\n );\n codeLines = [];\n codeLanguage = \"\";\n inCodeBlock = false;\n } else {\n inCodeBlock = true;\n codeLanguage = line.slice(3).trim();\n }\n continue;\n }\n\n if (inCodeBlock) {\n codeLines.push(line);\n continue;\n }\n\n // Empty line\n if (line.trim() === \"\") {\n elements.push(<Text key={`empty-${i}`}>{\"\"}</Text>);\n continue;\n }\n\n // Headers\n const h1 = line.match(/^# (.+)/);\n if (h1) {\n elements.push(\n <Text key={`h1-${i}`} bold color=\"white\">\n {renderInline(h1[1]!)}\n </Text>,\n );\n continue;\n }\n\n const h2 = line.match(/^## (.+)/);\n if (h2) {\n elements.push(\n <Text key={`h2-${i}`} bold>\n {renderInline(h2[1]!)}\n </Text>,\n );\n continue;\n }\n\n const h3 = line.match(/^### (.+)/);\n if (h3) {\n elements.push(\n <Text key={`h3-${i}`} bold dimColor>\n {renderInline(h3[1]!)}\n </Text>,\n );\n continue;\n }\n\n // Unordered list items\n const ul = line.match(/^(\\s*)[-*] (.+)/);\n if (ul) {\n const indent = Math.floor((ul[1]?.length ?? 0) / 2);\n elements.push(\n <Box key={`ul-${i}`} paddingLeft={indent * 2}>\n <Text dimColor>{\"– \"}</Text>\n <Text>{renderInline(ul[2]!)}</Text>\n </Box>,\n );\n continue;\n }\n\n // Ordered list items\n const ol = line.match(/^(\\s*)\\d+\\. (.+)/);\n if (ol) {\n const indent = Math.floor((ol[1]?.length ?? 0) / 2);\n const num = line.match(/^(\\s*)(\\d+)\\./);\n elements.push(\n <Box key={`ol-${i}`} paddingLeft={indent * 2}>\n <Text dimColor>{`${num?.[2]}. `}</Text>\n <Text>{renderInline(ol[2]!)}</Text>\n </Box>,\n );\n continue;\n }\n\n // Horizontal rule\n if (/^---+$/.test(line.trim()) || /^\\*\\*\\*+$/.test(line.trim())) {\n elements.push(\n <Text key={`hr-${i}`} dimColor>{\"─\".repeat(40)}</Text>,\n );\n continue;\n }\n\n // Regular paragraph\n elements.push(\n <Text key={`p-${i}`}>{renderInline(line)}</Text>,\n );\n }\n\n return <Box flexDirection=\"column\">{elements}</Box>;\n}\n\n/**\n * Render inline markdown: **bold**, `code`, *italic*\n * Returns a string with ANSI escape sequences.\n *\n * Note: Ink <Text> doesn't support mixed inline styles easily,\n * so we return plain text with markdown stripped for now.\n * Bold is rendered via chalk-style markup.\n */\nfunction renderInline(text: string): string {\n return text\n // Remove bold markers (Ink doesn't support inline bold mixing easily)\n .replace(/\\*\\*(.+?)\\*\\*/g, \"$1\")\n // Remove italic markers\n .replace(/\\*(.+?)\\*/g, \"$1\")\n // Remove inline code markers\n .replace(/`(.+?)`/g, \"$1\");\n}\n"],"mappings":"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","names":["fs","path","t","pendingInput","prompt","context","prompt","detectLanguage","fs","path","path","fs","crypto","crypto","provider","execCb","fs","path","promisify","exec","promisify","execCb","path","fs","add","WebSocket","WebSocket","agent","React","render","path","fs","os","WebSocket","fs","path","os","useState","useCallback","useRef","useEffect","Box","Text","useInput","WebSocket","useState","useCallback","useRef","useState","useCallback","useRef","crypto","useState","useCallback","useState","useCallback","Box","Text","jsx","jsxs","Box","Text","useState","useEffect","useRef","Box","Text","jsx","jsxs","useState","useRef","useEffect","Box","Text","Box","Text","useState","useEffect","jsx","Box","Text","React","useState","useCallback","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","path","fs","jsx","jsxs","fs","path","jsx","Box","Text","jsxs","jsx","jsxs","useState","React","useCallback","before","Box","Text","Box","Text","jsx","jsxs","shortModel","shortPath","Box","Text","Box","Text","useInput","jsx","jsxs","useInput","Box","Text","Box","Text","useInput","jsx","jsxs","useInput","Box","Text","Box","Text","useInput","jsx","jsxs","useInput","Box","Text","Box","Text","useInput","jsx","jsxs","useInput","Box","Text","Box","Text","useInput","jsx","jsxs","useInput","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","SelectInput","jsx","jsxs","Box","Text","SelectInput","Box","Text","SelectInput","jsx","jsxs","Box","Text","SelectInput","useState","Box","Text","useInput","SelectInput","jsx","jsxs","MODELS","useState","useInput","Box","Text","SelectInput","useEffect","useState","Text","jsx","useState","useEffect","Text","Box","Text","jsx","jsxs","Fragment","jsx","jsxs","useState","useRef","useEffect","renderMessage","useCallback","useInput","Box","Text","truncate","render","React","path","os","fs","WebSocket","path","fs"]}
1
+ {"version":3,"sources":["../src/bin.ts","../src/cli.ts","../src/config.ts","../../../providers/anthropic/src/anthropic.provider.ts","../../../providers/anthropic/src/anthropic.models.ts","../../../packages/logger/src/logger.ts","../../../packages/types/src/agents/llm.types.ts","../../../packages/types/src/agents/tool.types.ts","../../../packages/types/src/media/tts.types.ts","../../../providers/anthropic/src/claude-code.provider.ts","../../../packages/sdk/src/agents/tools/tools.ts","../../../packages/sdk/src/agents/tools/plan.tool.ts","../../../packages/sdk/src/agents/tools/ask-user.tool.ts","../../../packages/sdk/src/agents/tools/think.tool.ts","../../../packages/sdk/src/agents/tools/plan-mode.tool.ts","../../../packages/sdk/src/agents/tools/agent.tools.ts","../../../packages/sdk/src/agents/skills/skills.ts","../../../packages/sdk/src/agents/prompts/mustache.ts","../../../packages/sdk/src/agents/references/reference.ts","../../../packages/sdk/src/data/tables.ts","../../../packages/sdk/src/data/connectors.ts","../../../packages/agent/src/tools/edit.tool.ts","../../../packages/agent/src/tools/bash.tool.ts","../../../packages/agent/src/tools/write.tool.ts","../../../packages/agent/src/tools/read.tool.ts","../../../packages/agent/src/tools/glob.tool.ts","../../../packages/agent/src/tools/grep.tool.ts","../../../packages/agent/src/tools/index.ts","../../../packages/agent/src/format.ts","../../../packages/agent/src/worktree.ts","../src/progress.ts","../src/agent.ts","../src/git.ts","../src/server.ts","../src/upstream.ts","../src/start.ts","../src/tui/chat.ts","../src/tui/settings.ts","../src/tui/app.tsx","../src/tui/hooks/use-agent-client.ts","../src/tui/hooks/use-messages.ts","../src/tui/hooks/use-task.ts","../src/tui/hooks/use-settings.ts","../src/tui/utils/slash-commands.ts","../src/tui/utils/auto-approve.ts","../src/tui/components/welcome-header.tsx","../src/tui/theme.ts","../src/tui/components/user-message.tsx","../src/tui/components/spinner.tsx","../src/tui/components/divider.tsx","../src/tui/hooks/use-terminal.ts","../src/tui/components/prompt-input.tsx","../src/tui/components/suggestions.tsx","../src/tui/components/file-picker.tsx","../src/tui/components/status-bar.tsx","../src/tui/utils/format-tokens.ts","../src/tui/components/permission-dialog.tsx","../src/tui/components/plan-review.tsx","../src/tui/components/max-iterations.tsx","../src/tui/components/help-menu.tsx","../src/tui/components/status-display.tsx","../src/tui/components/model-picker.tsx","../src/tui/components/mode-picker.tsx","../src/tui/components/thinking-picker.tsx","../src/tui/components/settings-dialog.tsx","../src/tui/components/notification.tsx","../src/tui/components/markdown-text.tsx"],"sourcesContent":["import dotenv from \"dotenv\";\nimport fs from \"fs\";\nimport path from \"path\";\n\nfunction findEnv(): string | undefined {\n let dir = process.cwd();\n while (dir !== path.dirname(dir)) {\n const envPath = path.join(dir, \".env\");\n if (fs.existsSync(envPath)) return envPath;\n dir = path.dirname(dir);\n }\n return undefined;\n}\ndotenv.config({ path: findEnv() });\n\nimport { createCli } from \"./cli\";\n\ncreateCli().parse();\n","/**\n * Agent CLI\n *\n * Commands:\n * connect <token> — Save cloud connection config\n * start — Start the agent (daemon by default)\n * stop — Stop the running agent\n * restart — Restart the agent\n * logs — Tail agent logs\n * chat — Interactive TUI\n * status — Show config and connection status\n * logout — Clear saved config\n */\n\nimport { Command } from \"commander\";\nimport { spawn, execSync } from \"child_process\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\n\nimport { loadConfig, saveConfig, clearConfig, parseConnectToken, getConfigPath } from \"./config\";\nimport { startAgent } from \"./start\";\nimport { isPortInUse } from \"./server\";\nimport { launchChat, type ChatOptions } from \"./tui/chat\";\n\nimport { createRequire } from \"module\";\nconst _require = createRequire(import.meta.url);\nconst PKG_VERSION: string = _require(\"../package.json\").version ?? \"dev\";\n\nconst LOG_DIR = path.join(os.homedir(), \".jarvis\");\nconst LOG_FILE = path.join(LOG_DIR, \"agent.log\");\nconst PID_FILE = path.join(LOG_DIR, \"agent.pid\");\n\n// =============================================================================\n// PID helpers\n// =============================================================================\n\nfunction savePid(pid: number): void {\n fs.mkdirSync(LOG_DIR, { recursive: true });\n fs.writeFileSync(PID_FILE, String(pid));\n}\n\nfunction readPid(): number | null {\n try {\n const pid = parseInt(fs.readFileSync(PID_FILE, \"utf-8\").trim(), 10);\n if (isNaN(pid)) return null;\n // Check if process is alive\n try {\n process.kill(pid, 0);\n return pid;\n } catch {\n // Process not running, clean up stale PID\n fs.unlinkSync(PID_FILE);\n return null;\n }\n } catch {\n return null;\n }\n}\n\nfunction clearPid(): void {\n try { fs.unlinkSync(PID_FILE); } catch {}\n}\n\nexport function createCli(): Command {\n const program = new Command()\n .name(\"jarvis\")\n .description(\"Jarvis local agent — runs Claude Code on your machine\")\n .version(PKG_VERSION);\n\n // ---------------------------------------------------------------------------\n // connect <token>\n // ---------------------------------------------------------------------------\n\n program\n .command(\"connect <token>\")\n .description(\"Connect to Jarvis cloud using a token from the web UI\")\n .option(\"-w, --workspace <path>\", \"Workspace root path for repo operations\")\n .action((token: string, opts: { workspace?: string }) => {\n try {\n const parsed = parseConnectToken(token);\n const existing = loadConfig();\n\n saveConfig({\n ...existing,\n apiUrl: parsed.apiUrl,\n token: parsed.jwt,\n userId: parsed.userId,\n envId: parsed.envId,\n ...(opts.workspace ? { workspacePath: opts.workspace } : {}),\n connectedAt: new Date().toISOString(),\n });\n\n console.log(`Connected to Jarvis cloud`);\n console.log(` User: ${parsed.userId}`);\n console.log(` Env: ${parsed.envId}`);\n console.log(` API: ${parsed.apiUrl}`);\n console.log(` Config: ${getConfigPath()}`);\n console.log();\n console.log(`Run 'jarvis start' to begin.`);\n } catch (err) {\n console.error(`Error: ${err instanceof Error ? err.message : err}`);\n process.exit(1);\n }\n });\n\n // ---------------------------------------------------------------------------\n // start\n // ---------------------------------------------------------------------------\n\n program\n .command(\"start\")\n .description(\"Start the local agent (runs as background daemon)\")\n .option(\"-p, --port <port>\", \"Local WS server port\", \"7862\")\n .option(\"-w, --workspace <path>\", \"Workspace root path\")\n .option(\"--api-key <key>\", \"Anthropic API key (for local-only use)\")\n .option(\"--no-upstream\", \"Don't connect to cloud (local-only mode)\")\n .option(\"--foreground\", \"Run in foreground (don't daemonize)\")\n .action(async (opts: { port: string; workspace?: string; apiKey?: string; upstream: boolean; foreground?: boolean }) => {\n const config = loadConfig();\n const port = parseInt(opts.port, 10);\n\n // Check if agent is already running\n const alreadyRunning = await isPortInUse(port);\n if (alreadyRunning) {\n console.log(`Jarvis agent is already running on ws://127.0.0.1:${port}`);\n console.log(`Use 'jarvis restart' to restart, or 'jarvis logs' to view logs.`);\n return;\n }\n\n const workspacePath = opts.workspace ?? config?.workspacePath ?? process.cwd();\n const anthropicApiKey = opts.apiKey ?? config?.anthropicApiKey ?? process.env.ANTHROPIC_API_KEY;\n const userId = config?.userId ?? process.env.JARVIS_USER_ID ?? \"local\";\n\n if (!anthropicApiKey && !config?.useSubscription) {\n console.warn(\"Warning: No Anthropic API key set. Using subscription mode.\");\n }\n\n // Foreground mode — run directly (for debugging)\n if (opts.foreground) {\n await startAgent({\n port,\n workspacePath,\n anthropicApiKey,\n useSubscription: !anthropicApiKey,\n userId,\n upstream:\n opts.upstream && config?.apiUrl && config?.token\n ? { apiUrl: config.apiUrl, token: config.token }\n : undefined,\n });\n return;\n }\n\n // Daemon mode — spawn detached background process\n fs.mkdirSync(LOG_DIR, { recursive: true });\n const logFd = fs.openSync(LOG_FILE, \"a\");\n\n // Build args for the foreground process\n const args = [\n \"start\", \"--foreground\",\n \"--port\", String(port),\n \"--workspace\", workspacePath,\n ];\n\n if (!opts.upstream) {\n args.push(\"--no-upstream\");\n }\n\n if (anthropicApiKey) {\n args.push(\"--api-key\", anthropicApiKey);\n }\n\n // Resolve the entry point — prefer dist build for daemon stability\n const binPath = process.argv[1]!;\n const cliRoot = path.resolve(path.dirname(binPath), \"..\");\n const distEntry = path.join(cliRoot, \"dist\", \"bin.js\");\n const useDistEntry = fs.existsSync(distEntry);\n\n const child = spawn(\n process.execPath,\n useDistEntry ? [distEntry, ...args] : [binPath, ...args],\n {\n detached: true,\n stdio: [\"ignore\", logFd, logFd],\n cwd: workspacePath,\n env: { ...process.env, NODE_NO_WARNINGS: \"1\" },\n },\n );\n\n child.unref();\n fs.closeSync(logFd);\n\n savePid(child.pid!);\n\n console.log(`Jarvis agent started (PID: ${child.pid})`);\n console.log(` Local: ws://127.0.0.1:${port}`);\n console.log(` Workspace: ${workspacePath}`);\n console.log(` Logs: ${LOG_FILE}`);\n if (config?.apiUrl) {\n console.log(` Cloud: ${config.apiUrl}`);\n }\n console.log();\n console.log(`Commands:`);\n console.log(` jarvis logs — View agent logs`);\n console.log(` jarvis stop — Stop the agent`);\n console.log(` jarvis restart — Restart the agent`);\n });\n\n // ---------------------------------------------------------------------------\n // stop\n // ---------------------------------------------------------------------------\n\n program\n .command(\"stop\")\n .description(\"Stop the running agent\")\n .action(async () => {\n const pid = readPid();\n if (pid) {\n try {\n process.kill(pid, \"SIGTERM\");\n clearPid();\n console.log(`Agent stopped (PID: ${pid})`);\n } catch {\n clearPid();\n console.log(\"Agent process not found. Cleaned up PID file.\");\n }\n return;\n }\n\n // Fallback: check if port is in use\n const running = await isPortInUse(7862);\n if (running) {\n // Try to find the process by port\n try {\n const output = execSync(\"lsof -ti :7862\", { encoding: \"utf-8\" }).trim();\n if (output) {\n const pids = output.split(\"\\n\");\n for (const p of pids) {\n try { process.kill(parseInt(p, 10), \"SIGTERM\"); } catch {}\n }\n console.log(\"Agent stopped.\");\n return;\n }\n } catch {}\n }\n\n console.log(\"No agent is running.\");\n });\n\n // ---------------------------------------------------------------------------\n // restart\n // ---------------------------------------------------------------------------\n\n program\n .command(\"restart\")\n .description(\"Restart the agent\")\n .action(async () => {\n // Stop first\n const pid = readPid();\n if (pid) {\n try { process.kill(pid, \"SIGTERM\"); } catch {}\n clearPid();\n console.log(`Stopped agent (PID: ${pid})`);\n // Wait briefly for port to free up\n await new Promise((r) => setTimeout(r, 1000));\n }\n\n // Start again — delegate to start command\n console.log(\"Starting agent...\");\n await program.parseAsync([\"node\", \"jarvis\", \"start\"]);\n });\n\n // ---------------------------------------------------------------------------\n // logs\n // ---------------------------------------------------------------------------\n\n program\n .command(\"logs\")\n .description(\"View agent logs\")\n .option(\"-f, --follow\", \"Follow log output (like tail -f)\")\n .option(\"-n, --lines <n>\", \"Number of lines to show\", \"50\")\n .action((opts: { follow?: boolean; lines: string }) => {\n if (!fs.existsSync(LOG_FILE)) {\n console.log(\"No log file found. Start the agent first: jarvis start\");\n return;\n }\n\n if (opts.follow) {\n // Tail -f mode\n const tail = spawn(\"tail\", [\"-f\", \"-n\", opts.lines, LOG_FILE], {\n stdio: \"inherit\",\n });\n process.on(\"SIGINT\", () => {\n tail.kill();\n process.exit(0);\n });\n tail.on(\"exit\", () => process.exit(0));\n } else {\n // Show last N lines\n const content = execSync(`tail -n ${opts.lines} \"${LOG_FILE}\"`, { encoding: \"utf-8\" });\n process.stdout.write(content);\n }\n });\n\n // ---------------------------------------------------------------------------\n // chat\n // ---------------------------------------------------------------------------\n\n program\n .command(\"chat\")\n .description(\"Interactive TUI — chat with Jarvis in your terminal\")\n .option(\"--model <id>\", \"Model (e.g., claude-opus-4-20250514)\")\n .option(\"--mode <mode>\", \"Permission mode: supervised|auto|plan|yolo\")\n .option(\"--thinking <config>\", \"Thinking: adaptive|enabled|disabled\")\n .option(\"--thinking-budget <n>\", \"Token budget when thinking=enabled\")\n .option(\"--max-turns <n>\", \"Max turns per task\")\n .option(\"-p, --port <port>\", \"Agent server port\", \"7862\")\n .option(\"-w, --workspace <path>\", \"Workspace root path\")\n .option(\"--no-server\", \"Connect to existing server, don't auto-start\")\n .action(async (opts: ChatOptions) => {\n await launchChat(opts);\n });\n\n // ---------------------------------------------------------------------------\n // status\n // ---------------------------------------------------------------------------\n\n program\n .command(\"status\")\n .description(\"Show agent configuration and connection status\")\n .action(async () => {\n const config = loadConfig();\n const pid = readPid();\n const port = config?.port ?? 7862;\n const running = await isPortInUse(port);\n\n console.log(`Jarvis Agent v${PKG_VERSION}:`);\n console.log(` Status: ${running ? `\\x1b[32mrunning\\x1b[0m` : `\\x1b[31mstopped\\x1b[0m`}${pid ? ` (PID: ${pid})` : \"\"}`);\n console.log(` Port: ${port}`);\n console.log(` Config: ${getConfigPath()}`);\n\n if (config) {\n console.log(` User: ${config.userId}`);\n console.log(` Env: ${config.envId ?? \"local\"}`);\n console.log(` Workspace: ${config.workspacePath ?? \"(cwd)\"}`);\n console.log(` Cloud: ${config.apiUrl ?? \"(not connected)\"}`);\n if (config.connectedAt) {\n console.log(` Connected: ${config.connectedAt}`);\n }\n } else {\n console.log(` Config: Not set up. Run 'jarvis connect <token>'`);\n }\n\n console.log(` Logs: ${LOG_FILE}`);\n });\n\n // ---------------------------------------------------------------------------\n // logout\n // ---------------------------------------------------------------------------\n\n program\n .command(\"logout\")\n .description(\"Clear saved configuration\")\n .action(() => {\n clearConfig();\n console.log(\"Configuration cleared.\");\n });\n\n return program;\n}\n","/**\n * Agent Config\n *\n * Manages ~/.jarvis/config.json — saved by `jarvis connect <token>`,\n * read on `jarvis start`.\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface AgentConfig {\n /** Cloud WS API URL (from connect token) */\n apiUrl?: string;\n /** JWT auth token (from connect token) */\n token?: string;\n /** User ID */\n userId: string;\n /** Environment ID */\n envId?: string;\n /** Workspace root path for repo operations */\n workspacePath?: string;\n /** Anthropic API key (for local-only use without cloud) */\n anthropicApiKey?: string;\n /** Use Anthropic subscription instead of API key */\n useSubscription?: boolean;\n /** Local WS server port */\n port?: number;\n /** When the config was last updated */\n connectedAt?: string;\n}\n\nexport interface ConnectToken {\n apiUrl: string;\n jwt: string;\n userId: string;\n envId: string;\n}\n\n// =============================================================================\n// Paths\n// =============================================================================\n\nconst CONFIG_DIR = path.join(os.homedir(), \".jarvis\");\nconst CONFIG_FILE = path.join(CONFIG_DIR, \"config.json\");\n\n// =============================================================================\n// Operations\n// =============================================================================\n\nexport function loadConfig(): AgentConfig | null {\n try {\n const raw = fs.readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(raw) as AgentConfig;\n } catch {\n return null;\n }\n}\n\nexport function saveConfig(config: AgentConfig): void {\n fs.mkdirSync(CONFIG_DIR, { recursive: true });\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + \"\\n\");\n}\n\nexport function clearConfig(): void {\n try {\n fs.unlinkSync(CONFIG_FILE);\n } catch {}\n}\n\nexport function parseConnectToken(token: string): ConnectToken {\n try {\n const decoded = Buffer.from(token, \"base64\").toString(\"utf-8\");\n const parsed = JSON.parse(decoded);\n if (!parsed.apiUrl || !parsed.jwt || !parsed.userId) {\n throw new Error(\"Invalid token: missing required fields (apiUrl, jwt, userId)\");\n }\n return parsed as ConnectToken;\n } catch (err) {\n if (err instanceof SyntaxError) {\n throw new Error(\"Invalid token: not valid base64-encoded JSON\");\n }\n throw err;\n }\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n","/**\n * Anthropic provider implementation\n * Provides LLM capabilities (query, stream) using the Anthropic Messages API\n *\n * Ported from @gluoe/anthropic with @jarvis/* imports\n */\n\nimport Anthropic from \"@anthropic-ai/sdk\";\nimport type { MessageParam } from \"@anthropic-ai/sdk/resources/messages\";\n\nimport { anthropicModels } from \"./anthropic.models\";\nimport type {\n Context,\n QueryLLMRequest,\n QueryLLMResponse,\n LLMProvider,\n LLMQueryOptions,\n Model,\n Message,\n MultimodalMessage,\n ContentPart,\n TextContentPart,\n ImageContentPart,\n} from \"@jarvis/types\";\n\nexport interface Config {\n apiKey?: string;\n baseURL?: string;\n}\n\nexport type AnthropicProvider = LLMProvider;\n\nexport function provider(config?: Config): AnthropicProvider {\n const finalConfig = {\n apiKey: config?.apiKey ?? process.env.ANTHROPIC_API_KEY,\n baseURL: config?.baseURL ?? process.env.ANTHROPIC_BASE_URL,\n };\n\n if (!finalConfig.apiKey) {\n throw new Error(\n \"Anthropic API key is required. Provide it via config.apiKey or ANTHROPIC_API_KEY environment variable\",\n );\n }\n\n const client = new Anthropic({\n apiKey: finalConfig.apiKey,\n baseURL: finalConfig.baseURL,\n });\n\n // =========================================================================\n // LLM METHODS\n // =========================================================================\n\n async function query(\n _ctx: Context,\n request: QueryLLMRequest,\n _options?: LLMQueryOptions,\n ): Promise<QueryLLMResponse> {\n try {\n const startTime = Date.now();\n const systemMessage = request.messages.find((m) => m.role === \"system\");\n\n const options = {\n max_tokens: request.options?.maxTokens ?? 4096,\n temperature: request.options?.temperature,\n top_p: request.options?.topP,\n };\n\n // Check if webSearch tool is present and convert to native web search\n const hasWebSearch = request.tools?.some((t) => t.name === \"webSearch\");\n const otherTools =\n request.tools?.filter((t) => t.name !== \"webSearch\") || [];\n\n // If structured output is requested, use tool calling approach\n const tools = request.output?.schema\n ? [\n {\n name: \"structured_output\",\n description: \"Respond with a structured JSON object\",\n input_schema: request.output.schema,\n },\n ...(hasWebSearch\n ? [\n {\n type: \"web_search_20250305\" as const,\n name: \"web_search\",\n max_uses: 5,\n },\n ]\n : []),\n ...(otherTools.length > 0 ? convertTools(otherTools) : []),\n ]\n : hasWebSearch\n ? [\n {\n type: \"web_search_20250305\" as const,\n name: \"web_search\",\n max_uses: 5,\n },\n ...(otherTools.length > 0 ? convertTools(otherTools) : []),\n ]\n : otherTools.length > 0\n ? convertTools(otherTools)\n : undefined;\n\n const tool_choice = request.output?.schema\n ? {\n type: \"tool\" as const,\n name: \"structured_output\",\n disable_parallel_tool_use: true,\n }\n : undefined;\n\n // Map ThinkingConfig to Anthropic thinking parameter\n const thinking_param = request.thinking?.type === \"disabled\"\n ? undefined\n : request.thinking?.type === \"enabled\" && request.thinking.budgetTokens\n ? { type: \"enabled\" as const, budget_tokens: request.thinking.budgetTokens }\n : request.thinking?.type === \"adaptive\"\n ? { type: \"enabled\" as const, budget_tokens: options.max_tokens - 1 }\n : undefined;\n\n const response = await client.messages.create({\n model: request.model,\n max_tokens: options.max_tokens,\n temperature: options.temperature,\n top_p: options.top_p,\n system: systemMessage?.content,\n messages: convertMessages(request.messages),\n tools,\n tool_choice,\n ...(thinking_param && { thinking: thinking_param }),\n } as any); // Type assertion needed for web_search_20250305\n\n const duration = Date.now() - startTime;\n\n let content = \"\";\n let thinking = \"\";\n let toolCalls: any[] | undefined;\n\n // Handle multiple content blocks\n for (const block of response.content) {\n if (block.type === \"text\") {\n content += block.text;\n } else if ((block as any).type === \"thinking\") {\n thinking += (block as any).thinking ?? \"\";\n } else if (block.type === \"tool_use\") {\n // If this is the structured output tool, extract content from it\n if (block.name === \"structured_output\" && request.output?.schema) {\n content = JSON.stringify(block.input || {});\n } else {\n // Regular tool call\n if (!toolCalls) toolCalls = [];\n toolCalls.push({\n id: block.id,\n name: block.name,\n args: JSON.stringify(block.input || {}),\n status: \"pending\" as const,\n });\n }\n }\n }\n\n return {\n content,\n thinking: thinking || undefined,\n toolCalls,\n metadata: {\n usage: {\n inputTokens: response.usage?.input_tokens || 0,\n outputTokens: response.usage?.output_tokens || 0,\n totalTokens:\n (response.usage?.input_tokens || 0) +\n (response.usage?.output_tokens || 0),\n cachedTokens: (response.usage as any)?.cache_read_input_tokens || 0,\n },\n model: request.model,\n options,\n duration,\n provider: \"anthropic\",\n },\n };\n } catch (error) {\n throw new Error(\n `Anthropic API error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n async function* stream(\n _ctx: Context,\n request: QueryLLMRequest,\n _options?: LLMQueryOptions,\n ): AsyncGenerator<QueryLLMResponse> {\n try {\n const options = {\n max_tokens: request.options?.maxTokens ?? 4096,\n temperature: request.options?.temperature,\n top_p: request.options?.topP,\n };\n\n const startTime = Date.now();\n\n const systemMessage = request.messages.find((m) => m.role === \"system\");\n\n // Check if webSearch tool is present and convert to native web search\n const hasWebSearch = request.tools?.some((t) => t.name === \"webSearch\");\n const otherTools =\n request.tools?.filter((t) => t.name !== \"webSearch\") || [];\n\n // If structured output is requested, use tool calling approach\n const tools = request.output?.schema\n ? [\n {\n name: \"structured_output\",\n description: \"Respond with a structured JSON object\",\n input_schema: request.output.schema,\n },\n ...(hasWebSearch\n ? [\n {\n type: \"web_search_20250305\" as const,\n name: \"web_search\",\n max_uses: 5,\n },\n ]\n : []),\n ...(otherTools.length > 0 ? convertTools(otherTools) : []),\n ]\n : hasWebSearch\n ? [\n {\n type: \"web_search_20250305\" as const,\n name: \"web_search\",\n max_uses: 5,\n },\n ...(otherTools.length > 0 ? convertTools(otherTools) : []),\n ]\n : otherTools.length > 0\n ? convertTools(otherTools)\n : undefined;\n\n const tool_choice = request.output?.schema\n ? {\n type: \"tool\" as const,\n name: \"structured_output\",\n disable_parallel_tool_use: true,\n }\n : undefined;\n\n // Map ThinkingConfig to Anthropic thinking parameter\n const thinking_param = request.thinking?.type === \"disabled\"\n ? undefined\n : request.thinking?.type === \"enabled\" && request.thinking.budgetTokens\n ? { type: \"enabled\" as const, budget_tokens: request.thinking.budgetTokens }\n : request.thinking?.type === \"adaptive\"\n ? { type: \"enabled\" as const, budget_tokens: options.max_tokens - 1 }\n : undefined;\n\n const streamResponse = client.messages.stream({\n model: request.model,\n max_tokens: options.max_tokens,\n temperature: options.temperature,\n top_p: options.top_p,\n system: systemMessage?.content,\n messages: convertMessages(request.messages),\n tools: tools as any, // Type assertion needed for web_search_20250305\n tool_choice,\n ...(thinking_param && { thinking: thinking_param }),\n });\n\n let usage = {\n input_tokens: 0,\n output_tokens: 0,\n };\n const toolCalls: any[] = [];\n let currentToolUse: {\n id: string;\n name: string;\n inputJson: string;\n } | null = null;\n\n for await (const chunk of streamResponse) {\n // Update usage from message_delta events\n if (chunk.type === \"message_delta\" && (chunk as any).usage) {\n usage = (chunk as any).usage;\n }\n\n // Track content block starts (tool_use)\n if (\n chunk.type === \"content_block_start\" &&\n (chunk as any).content_block?.type === \"tool_use\"\n ) {\n const block = (chunk as any).content_block;\n currentToolUse = {\n id: block.id,\n name: block.name,\n inputJson: \"\",\n };\n }\n\n // Handle content block deltas\n if (chunk.type === \"content_block_delta\") {\n const deltaType = (chunk.delta as any)?.type;\n\n if (deltaType === \"text_delta\") {\n // Yield text chunks\n yield {\n content: (chunk.delta as any).text || \"\",\n metadata: {\n usage: {\n inputTokens: usage.input_tokens || 0,\n outputTokens: usage.output_tokens || 0,\n totalTokens:\n (usage.input_tokens || 0) + (usage.output_tokens || 0),\n },\n model: request.model,\n options,\n duration: Date.now() - startTime,\n provider: \"anthropic\",\n },\n };\n } else if (deltaType === \"thinking_delta\") {\n // Yield thinking chunks\n yield {\n content: \"\",\n thinking: (chunk.delta as any).thinking || \"\",\n metadata: {\n usage: {\n inputTokens: usage.input_tokens || 0,\n outputTokens: usage.output_tokens || 0,\n totalTokens:\n (usage.input_tokens || 0) + (usage.output_tokens || 0),\n },\n model: request.model,\n options,\n duration: Date.now() - startTime,\n provider: \"anthropic\",\n },\n };\n } else if (deltaType === \"input_json_delta\" && currentToolUse) {\n currentToolUse.inputJson += (chunk.delta as any).partial_json || \"\";\n }\n // signature_delta — ignored\n }\n\n // Finalize tool call on content_block_stop\n if (chunk.type === \"content_block_stop\" && currentToolUse) {\n toolCalls.push({\n id: currentToolUse.id,\n name: currentToolUse.name,\n args: currentToolUse.inputJson || \"{}\",\n status: \"pending\" as const,\n });\n currentToolUse = null;\n }\n }\n\n // Yield final chunk with tool calls if any were accumulated\n if (toolCalls.length > 0) {\n yield {\n content: \"\",\n toolCalls,\n metadata: {\n usage: {\n inputTokens: usage.input_tokens || 0,\n outputTokens: usage.output_tokens || 0,\n totalTokens:\n (usage.input_tokens || 0) + (usage.output_tokens || 0),\n },\n model: request.model,\n options,\n duration: Date.now() - startTime,\n provider: \"anthropic\",\n },\n };\n }\n } catch (error) {\n throw new Error(\n `Anthropic streaming error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n async function getModels(): Promise<Model[]> {\n return anthropicModels.list();\n }\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n\n function parseToolArgs(str: string): Record<string, unknown> {\n if (!str || str.trim() === \"\") return {};\n try {\n return JSON.parse(str);\n } catch (err) {\n console.warn(\"Failed to parse tool call args:\", err);\n return {};\n }\n }\n\n function convertMessages(\n messages: (Message | MultimodalMessage)[],\n ): MessageParam[] {\n return (\n messages\n ?.filter((msg) => msg.role !== \"system\") // Anthropic handles system messages separately\n ?.map((msg): MessageParam => {\n switch (msg.role) {\n case \"user\":\n if (msg.content && Array.isArray(msg.content)) {\n return {\n role: \"user\",\n content: msg.content\n .filter(\n (\n part: ContentPart,\n ): part is TextContentPart | ImageContentPart =>\n part.type === \"text\" || part.type === \"image\",\n )\n .map((part: TextContentPart | ImageContentPart) => {\n if (part.type === \"image\") {\n return {\n type: \"image\" as const,\n source: {\n type: \"base64\" as const,\n media_type: part.mimeType as\n | \"image/jpeg\"\n | \"image/png\"\n | \"image/gif\"\n | \"image/webp\",\n data: part.data,\n },\n };\n }\n return {\n type: \"text\" as const,\n text: part.text,\n };\n }),\n };\n } else {\n return {\n role: \"user\",\n content: msg.content || \"\",\n };\n }\n\n case \"assistant\": {\n const assistantMsg = msg as any;\n\n // Check if there are tool calls\n if (assistantMsg.toolCalls && assistantMsg.toolCalls.length > 0) {\n const content: any[] = [];\n if (assistantMsg.content) {\n content.push({\n type: \"text\" as const,\n text: assistantMsg.content,\n });\n }\n for (const tc of assistantMsg.toolCalls) {\n content.push({\n type: \"tool_use\" as const,\n id: tc.id,\n name: tc.name,\n input:\n typeof tc.args === \"string\"\n ? parseToolArgs(tc.args)\n : tc.args || {},\n });\n }\n return { role: \"assistant\", content };\n }\n\n return {\n role: \"assistant\",\n content: assistantMsg.content || \"\",\n };\n }\n\n case \"tool\": {\n // Anthropic expects tool results in user messages with tool_result content blocks\n const toolMsg = msg as any;\n return {\n role: \"user\",\n content: [\n {\n type: \"tool_result\" as const,\n tool_use_id: toolMsg.toolCallId,\n content: toolMsg.content,\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unsupported message role: ${(msg as any).role}`);\n }\n }) || []\n );\n }\n\n function convertTools(tools: any[]): any[] {\n return (\n tools?.map((tool) => ({\n name: tool.name,\n description: tool.description,\n input_schema: tool.input,\n })) || []\n );\n }\n\n function configure(overrides: Record<string, unknown>): AnthropicProvider {\n return provider({ ...finalConfig, ...overrides } as Config);\n }\n\n return {\n name: \"anthropic\",\n query,\n stream,\n getModels,\n configure,\n };\n}\n","/**\n * Anthropic model definitions\n */\n\nimport type { Model } from \"@jarvis/types\";\n\nexport const claude3Haiku: Model = {\n id: \"claude-3-haiku-20240307\",\n name: \"Claude 3 Haiku\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 4096 },\n cost: { multiplier: 8, inputTokens: 0.25, outputTokens: 1.25 },\n};\n\nexport const claude37Sonnet: Model = {\n id: \"claude-3-7-sonnet-20241022\",\n name: \"Claude 3.7 Sonnet\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 20, inputTokens: 3.00, outputTokens: 15.00 },\n options: {\n temperature: 0.4,\n topP: 0.95,\n },\n};\n\nexport const claude35Haiku: Model = {\n id: \"claude-3-5-haiku-20241022\",\n name: \"Claude 3.5 Haiku\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 8, inputTokens: 0.80, outputTokens: 4.00 },\n};\n\nexport const claude4Sonnet: Model = {\n id: \"claude-sonnet-4-20250514\",\n name: \"Claude 4 Sonnet\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 20, inputTokens: 3.00, outputTokens: 15.00 },\n};\n\nexport const claude4Opus: Model = {\n id: \"claude-opus-4-20250514\",\n name: \"Claude 4 Opus\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 50, inputTokens: 15.00, outputTokens: 75.00 },\n};\n\nexport const claudeSonnet45: Model = {\n id: \"claude-sonnet-4-5-20250929\",\n name: \"Claude Sonnet 4.5\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 20, inputTokens: 3.00, outputTokens: 15.00 },\n};\n\nexport const claudeOpus41: Model = {\n id: \"claude-opus-4-1-20250514\",\n name: \"Claude Opus 4.1\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 50, inputTokens: 15.00, outputTokens: 75.00 },\n};\n\nexport const claudeHaiku45: Model = {\n id: \"claude-haiku-4-5-20251001\",\n name: \"Claude Haiku 4.5\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 8192 },\n cost: { multiplier: 8, inputTokens: 1.00, outputTokens: 5.00 },\n};\n\nexport const claudeOpus46: Model = {\n id: \"claude-opus-4-6-20250515\",\n name: \"Claude Opus 4.6\",\n provider: \"anthropic\",\n maxTokens: { input: 200_000, output: 16384 },\n cost: { multiplier: 50, inputTokens: 5.00, outputTokens: 25.00 },\n};\n\n// Claude Code models (routed via \"claude-code\" provider tag, not model ID)\nexport const claudeCodeSonnet: Model = {\n id: \"claude-sonnet-4-5-20250929\",\n name: \"Claude Code (Sonnet)\",\n provider: \"claude-code\",\n maxTokens: { input: 200_000, output: 16384 },\n cost: { multiplier: 20, inputTokens: 3.00, outputTokens: 15.00 },\n};\n\nexport const claudeCodeOpus: Model = {\n id: \"claude-opus-4-6-20250515\",\n name: \"Claude Code (Opus)\",\n provider: \"claude-code\",\n maxTokens: { input: 200_000, output: 16384 },\n cost: { multiplier: 50, inputTokens: 5.00, outputTokens: 25.00 },\n};\n\n// All Anthropic models\nexport const anthropicModels = {\n claude3Haiku,\n claude37Sonnet,\n claude35Haiku,\n claude4Sonnet,\n claude4Opus,\n claudeSonnet45,\n claudeOpus41,\n claudeHaiku45,\n claudeOpus46,\n\n list: (): Model[] => [\n claude3Haiku,\n claude37Sonnet,\n claude35Haiku,\n claude4Sonnet,\n claude4Opus,\n claudeSonnet45,\n claudeOpus41,\n claudeHaiku45,\n claudeOpus46,\n ],\n};\n\n// Claude Code models registry\nexport const claudeCodeModels = {\n claudeCodeSonnet,\n claudeCodeOpus,\n\n list: (): Model[] => [claudeCodeSonnet, claudeCodeOpus],\n};\n","/**\n * Logger Singleton\n *\n * Provider-agnostic logger with console default.\n * Call logger.init({ provider }) to set a real provider (e.g., pinoProvider).\n *\n * Usage:\n * ```typescript\n * import { logger } from \"@jarvis/logger\";\n * import { pinoProvider } from \"@jarvis/pino\";\n *\n * logger.init({ provider: pinoProvider({ name: \"worker\" }) });\n * logger.info(ctx, \"Hello\", { key: \"value\" });\n * logger.sys.info(\"System startup\");\n * Runtime.install({ logger: logger.runtime() });\n * ```\n */\n\nimport type { Context, LogProvider, LogMetadata, AuditEvent } from \"@jarvis/types\";\n\n// =============================================================================\n// Error resolving — handles Error objects in metadata\n// =============================================================================\n\nfunction resolveError(meta?: LogMetadata): LogMetadata {\n if (!meta) return {};\n const { error, ...rest } = meta;\n if (error === undefined) return meta;\n if (error instanceof Error) {\n return { ...rest, error: error.message, ...(error.stack ? { errorStack: error.stack } : {}) };\n }\n return { ...rest, error: typeof error === \"string\" ? error : String(error) };\n}\n\n// =============================================================================\n// Console default provider\n// =============================================================================\n\nfunction consoleProvider(): LogProvider {\n const log =\n (level: \"debug\" | \"info\" | \"warn\" | \"error\") =>\n (_ctx: Context, message: string, meta?: LogMetadata): void => {\n const fn = level === \"error\" ? console.error : level === \"warn\" ? console.warn : level === \"debug\" ? console.debug : console.info;\n fn(`[${level.toUpperCase()}]`, message, resolveError(meta));\n };\n\n return {\n debug: log(\"debug\"),\n info: log(\"info\"),\n warn: log(\"warn\"),\n error: log(\"error\"),\n audit: (_ctx, event) => console.info(\"[AUDIT]\", event.action, event.result),\n };\n}\n\n// =============================================================================\n// Console runtime logger (fallback for Temporal Runtime.install())\n// =============================================================================\n\ninterface RuntimeLogger {\n log(level: string, message: string, meta?: Record<string | symbol, unknown>): void;\n trace(message: string, meta?: Record<string | symbol, unknown>): void;\n debug(message: string, meta?: Record<string | symbol, unknown>): void;\n info(message: string, meta?: Record<string | symbol, unknown>): void;\n warn(message: string, meta?: Record<string | symbol, unknown>): void;\n error(message: string, meta?: Record<string | symbol, unknown>): void;\n}\n\nconst LEVEL_MAP: Record<string, \"debug\" | \"info\" | \"warn\" | \"error\"> = {\n TRACE: \"debug\",\n DEBUG: \"debug\",\n INFO: \"info\",\n WARN: \"warn\",\n ERROR: \"error\",\n};\n\nfunction consoleRuntimeLogger(): RuntimeLogger {\n const log = (level: string, message: string, meta?: Record<string | symbol, unknown>) => {\n const fn = console[LEVEL_MAP[level] ?? \"info\"];\n fn(message, meta ? Object.fromEntries(Object.entries(meta as Record<string, unknown>)) : \"\");\n };\n return {\n log: (level, msg, meta) => log(level, msg, meta),\n trace: (msg, meta) => log(\"TRACE\", msg, meta),\n debug: (msg, meta) => log(\"DEBUG\", msg, meta),\n info: (msg, meta) => log(\"INFO\", msg, meta),\n warn: (msg, meta) => log(\"WARN\", msg, meta),\n error: (msg, meta) => log(\"ERROR\", msg, meta),\n };\n}\n\n// =============================================================================\n// Singleton state\n// =============================================================================\n\nconst SYS_CTX: Context = { userId: \"system\" } as Context;\n\nlet _provider: LogProvider = consoleProvider();\nlet _runtimeFactory: (() => RuntimeLogger) | null = null;\n\n// =============================================================================\n// Logger singleton\n// =============================================================================\n\nexport type LogProviderWithRuntime = LogProvider & {\n runtime?: () => RuntimeLogger;\n};\n\nexport const logger = {\n /** Set the active logging provider */\n init(config: { provider: LogProviderWithRuntime }) {\n _provider = config.provider;\n _runtimeFactory = config.provider.runtime ?? null;\n },\n\n // Logging — delegates to current provider (resolves Error objects in meta)\n debug(ctx: Context, message: string, meta?: LogMetadata) { _provider.debug(ctx, message, resolveError(meta)); },\n info(ctx: Context, message: string, meta?: LogMetadata) { _provider.info(ctx, message, resolveError(meta)); },\n warn(ctx: Context, message: string, meta?: LogMetadata) { _provider.warn(ctx, message, resolveError(meta)); },\n error(ctx: Context, message: string, meta?: LogMetadata) { _provider.error(ctx, message, resolveError(meta)); },\n audit(ctx: Context, event: AuditEvent) { _provider.audit(ctx, event); },\n\n /** System-scoped shorthand (no ctx required) */\n sys: {\n debug(message: string, meta?: LogMetadata) { _provider.debug(SYS_CTX, message, meta); },\n info(message: string, meta?: LogMetadata) { _provider.info(SYS_CTX, message, meta); },\n warn(message: string, meta?: LogMetadata) { _provider.warn(SYS_CTX, message, meta); },\n error(message: string, meta?: LogMetadata) { _provider.error(SYS_CTX, message, meta); },\n },\n\n /** Get a Temporal Runtime.install() logger. Uses provider's runtime() if available, console fallback. */\n runtime(): RuntimeLogger {\n if (_runtimeFactory) return _runtimeFactory();\n return consoleRuntimeLogger();\n },\n};\n","/**\n * LLM (Large Language Model) related types\n */\n\nimport type {\n TTSVoice,\n TTSModel,\n TTSResponseFormat,\n} from \"../media/tts.types\";\n\nimport type { Message, MultimodalMessage } from \"./message.types\";\nimport type { Usage } from \"./usage.types\";\nimport { Context } from \"../core/context.types\";\nimport {\n Model,\n ResolveModelRequest,\n ResolveModelResponse,\n} from \"./model.types\";\nimport { Provider } from \"../core/provider.types\";\nimport { Schema } from \"../core/schema.types\";\nimport { ToolCall, Tool } from \"./tool.types\";\n\n// Re-export message types for backward compatibility\nexport type {\n MessageRole,\n Message,\n MultimodalMessage,\n BaseMessage,\n UserMessage,\n AssistantMessage,\n SystemMessage,\n ToolMessage,\n ContentPart,\n TextContentPart,\n AudioContentPart,\n ImageContentPart,\n} from \"./message.types\";\n\n// =============================================================================\n// OUTPUT CONFIGURATION\n// =============================================================================\n\n/** Output format types — what the response should include */\nexport type OutputFormat = \"text\" | \"audio\" | \"json\";\n\n/** Audio-specific output configuration */\nexport interface AudioOutputConfig {\n /** TTS voice (defaults to \"nova\") */\n voice?: TTSVoice;\n /** TTS model (defaults to \"tts-1\") */\n model?: TTSModel;\n /** Audio response format (defaults to \"mp3\") */\n format?: TTSResponseFormat;\n}\n\n/**\n * Output configuration for LLM response delivery.\n *\n * Controls both LLM output format (json with schema) and\n * response delivery formats (text, audio).\n *\n * Valid format combinations:\n * - `[\"text\"]` — text only (default)\n * - `[\"text\", \"audio\"]` — text + audio (voice mode)\n * - `[\"json\"]` — JSON structured output (standalone, requires schema)\n *\n * @example Text only (default)\n * ```typescript\n * { formats: [\"text\"] }\n * ```\n *\n * @example Text + audio (voice mode)\n * ```typescript\n * { formats: [\"text\", \"audio\"], audio: { voice: \"nova\" } }\n * ```\n *\n * @example JSON structured output\n * ```typescript\n * { formats: [\"json\"], schema: mySchema }\n * ```\n */\nexport interface LLMQueryOutput {\n /**\n * Which formats to include in the response. Defaults to [\"text\"].\n * Valid: [\"text\"], [\"text\", \"audio\"], or [\"json\"].\n */\n formats?: [\"text\"] | [\"text\", \"audio\"] | [\"json\"];\n /** JSON schema — required when formats is [\"json\"] */\n schema?: Schema;\n /** Audio-specific settings — used when \"audio\" is in formats */\n audio?: AudioOutputConfig;\n}\n\n/** Check if an output config includes a specific format */\nexport function hasOutputFormat(\n output: LLMQueryOutput | undefined,\n format: OutputFormat,\n): boolean {\n return (output?.formats as string[] | undefined)?.includes(format) ?? false;\n}\n\n// =============================================================================\n// THINKING CONFIG\n// =============================================================================\n\n/**\n * Thinking/reasoning configuration — provider-agnostic.\n *\n * Providers map this to their native format:\n * - Anthropic: adaptive → `thinking: { type: \"enabled\" }`, enabled → `thinking: { budget_tokens }`\n * - Gemini: maps to `thinkingConfig.thinkingLevel` or `thinkingBudget`\n * - OpenAI: maps to `reasoning_effort`\n * - Providers without support: ignore the field\n */\nexport interface ThinkingConfig {\n /** Thinking mode */\n type: \"adaptive\" | \"enabled\" | \"disabled\";\n /** Token budget for thinking (only used with type: \"enabled\") */\n budgetTokens?: number;\n}\n\n// =============================================================================\n// LLM QUERY TYPES\n// =============================================================================\n\nexport interface QueryLLMRequest {\n model: string;\n messages: (Message | MultimodalMessage)[];\n tools?: Tool[];\n output?: LLMQueryOutput;\n thinking?: ThinkingConfig;\n options?: {\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n };\n}\n\nexport interface LLMQueryOptions {\n /** Override provider selection (bypass model-based routing) */\n provider?: string;\n /** Set false to suppress Redis token streaming (for internal LLM calls like query understanding) */\n stream?: boolean;\n}\n\nexport interface QueryLLMResponse {\n content: string;\n /** JSON structured output (when output format is \"json\" and SDK returns structured_output) */\n json?: string;\n /** Error from the SDK (e.g. error_max_turns, error_max_budget_usd) */\n error?: string;\n thinking?: string;\n toolCalls?: ToolCall[];\n metadata?: QueryLLMMetadata;\n /** Claude Code session ID from the SDK (for session resume support) */\n sessionId?: string;\n /** Why the LLM stopped generating — populated by providers from API response */\n stopReason?: StopReason;\n}\n\n/** Why the LLM stopped generating */\nexport type StopReason =\n | \"end_turn\"\n | \"max_tokens\"\n | \"tool_use\"\n | \"stop_sequence\"\n | \"content_filter\";\n\nexport interface QueryLLMMetadata {\n model: string;\n usage: Usage;\n options?: {\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n };\n duration: number;\n provider: string;\n}\n\n// LLM Client interface\nexport interface LLMProvider extends Provider {\n query(\n ctx: Context,\n req: QueryLLMRequest,\n options?: LLMQueryOptions,\n ): Promise<QueryLLMResponse>;\n stream(\n ctx: Context,\n req: QueryLLMRequest,\n options?: LLMQueryOptions,\n ): AsyncGenerator<QueryLLMResponse>;\n getModels?(): Promise<Model[]>;\n /** Create a new instance with different config (e.g., different API key for BYOK) */\n configure?(config: Record<string, unknown>): LLMProvider;\n /** Optional provider-specific request validation. Called by the router before query/stream. */\n validateQuery?(ctx: Context, req: QueryLLMRequest): QueryLLMRequest;\n}\n\n// ============================================================================\n// LLM Resolvers\n// ============================================================================\n\nexport interface ResolveLLMProviderRequest {\n providerName?: string;\n providers: LLMProvider[];\n}\n\nexport interface ResolveLLMProviderResponse {\n provider: LLMProvider;\n}\n\nexport interface LLMProviderResolver extends Provider {\n resolve(\n request: ResolveLLMProviderRequest,\n ): Promise<ResolveLLMProviderResponse>;\n}\n\nexport interface ModelResolver extends Provider {\n resolve(request: ResolveModelRequest): Promise<ResolveModelResponse>;\n}\n\nexport interface ResolveOptionsRequest {\n requestOptions?: QueryLLMRequest[\"options\"];\n modelOptions?: QueryLLMRequest[\"options\"];\n}\n\nexport interface ResolveOptionsResponse {\n options?: QueryLLMRequest[\"options\"];\n}\n\nexport interface OptionsResolver extends Provider {\n resolve(request: ResolveOptionsRequest): Promise<ResolveOptionsResponse>;\n}\n","import type { Context } from \"../core/context.types\";\nimport type { TranslateFn } from \"../core/translation.types\";\nimport { Schema } from \"../core/schema.types\";\nimport type { Usage } from \"./usage.types\";\n\n// =============================================================================\n// Tool UI (Unified — MCP iframe OR chat component)\n// =============================================================================\n\n/**\n * ToolUi — discriminated union for rich rendering.\n *\n * Component variant: renders in chat via artifact router\n * Resource variant: renders as MCP iframe via ui:// resource\n */\nexport type ToolUi = ToolUiComponent | ToolUiResource;\n\nexport interface ToolUiComponent {\n /** MCP-style URI: \"ui://appId/componentType\" (e.g., \"ui://chef/recipe\") */\n uri: string;\n /** Display title for the component card */\n title: string;\n /** Data payload — auto-populated from tool output when omitted in after hook */\n data?: unknown;\n /** Preferred height in pixels */\n height?: number;\n}\n\nexport interface ToolUiResource {\n /** URI of the MCP UI resource (e.g., \"ui://server/dashboard\") */\n resourceUri: string;\n /** Title override for the artifact card */\n title?: string;\n /** Preferred iframe height in pixels */\n height?: number;\n /** Extra data passed to the rendering component (e.g., html, serverName) */\n data?: unknown;\n}\n\n// =============================================================================\n// Tool Permissions (Declarative Access Control)\n// =============================================================================\n\n/**\n * Declarative permissions for a tool.\n * Combines RBAC (roles/tiers) with risk classification.\n */\nexport interface ToolPermissions {\n /** Required roles (checked vs ctx.access.role) */\n roles?: string[];\n /** Required tiers (checked vs ctx.access.tier) */\n tiers?: string[];\n /**\n * Risk level — drives permission mode behavior:\n * - \"safe\": auto-allow (read, search, list)\n * - \"moderate\": allow by default, log (create, update)\n * - \"dangerous\": ask user first (delete, send, execute)\n */\n risk?: \"safe\" | \"moderate\" | \"dangerous\";\n /**\n * When to ask for user approval (if applicable based on risk + mode).\n * - \"before\": ask BEFORE execution (default)\n * - \"after\": execute first, then ask for confirmation\n * Only applies when the harness auto-asks (no custom hook defined).\n */\n ask?: \"before\" | \"after\";\n /** Can run in parallel with other tools (default: true) */\n concurrent?: boolean;\n /** Resource scopes (future: OAuth/MCP) */\n scopes?: string[];\n}\n\n// =============================================================================\n// Tool Metadata (all display, permissions, and provider config)\n// =============================================================================\n\n/** Context provided to metadata describe function */\nexport interface ToolMetadataContext {\n toolName: string;\n toolCallId: string;\n}\n\n/** Request passed to the describe function */\nexport interface DescribeToolRequest {\n status: ToolCallStatus;\n input: Record<string, unknown>;\n output?: unknown;\n error?: string;\n durationMs?: number;\n}\n\n/** Options passed as 3rd argument to metadata.describe() */\nexport interface DescribeToolOptions {\n t: TranslateFn;\n}\n\n/**\n * Tool metadata — all display, permissions, UI, and provider configuration.\n */\nexport interface ToolMetadata {\n /** Human-readable tool name for UI display (e.g., \"Create Recipe\") */\n label?: string;\n\n /** Generate phase description for the tool message UI */\n describe?: (\n ctx: ToolMetadataContext,\n req: DescribeToolRequest,\n options?: DescribeToolOptions,\n ) => string | undefined;\n\n /**\n * When true, tool calls are not displayed in the conversation UI.\n * The tool still runs normally — it's just invisible to the user.\n */\n hidden?: boolean;\n\n /**\n * Native provider that handles lifecycle.\n * When set, the tool is handled by the named provider's internal loop\n * rather than by callTool().\n */\n provider?: string;\n\n /** Declarative permissions — RBAC + risk classification */\n permissions?: ToolPermissions;\n\n /** UI component config — MCP iframe or chat component */\n ui?: ToolUi;\n\n /** Max tool output size in characters before truncation (default: 50000) */\n maxOutputSize?: number;\n}\n\n// =============================================================================\n// Tool Definition\n// =============================================================================\n\n/**\n * Tool definition — serializable schema + optional execution fields.\n *\n * Core fields (name, description, input, output) are always serializable.\n * Execution fields (call, hooks, metadata, build) are added by the SDK\n * `tool()` factory and used by the agent runner.\n */\nexport interface Tool {\n name: string;\n description: string;\n input: Schema;\n output: Schema;\n\n // === Execution ===\n\n /** Function to execute the tool */\n call?: CallTool;\n\n /**\n * Schema-only builder — called by buildTools() at the start of each iteration\n * to produce a tool with state-dependent schemas (e.g., dynamic enum values).\n */\n build?: (ctx: Context, req: { tool: Tool; state: unknown }) => Tool;\n\n // === Configuration ===\n\n /** All display, permissions, UI, and provider configuration */\n metadata?: ToolMetadata;\n\n // === Lifecycle Hooks ===\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n hooks?: ToolHooks<any>;\n}\n\n/**\n * Tool handler function.\n *\n * Signature: (ctx, input, options?) => output\n * ctx from runner, options pre-bound by buildTools.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type CallTool = (...args: any[]) => Promise<any>;\n\n// =============================================================================\n// Ask User (human-in-the-loop)\n// =============================================================================\n\n/** User's response action */\nexport type UserInputAction = \"allow\" | \"deny\" | \"modify\";\n\nexport interface UserInputResponse {\n action: UserInputAction;\n data?: Record<string, unknown>;\n feedback?: string;\n}\n\n/** User input with correlation ID */\nexport interface UserInput extends UserInputResponse {\n id: string;\n}\n\n/**\n * Request for user input — raw data preview, rich UI component, or reason-only.\n */\nexport type UserInputRequest =\n | { reason?: string; data: unknown; ui?: never }\n | { reason?: string; data?: never; ui: ToolUi };\n\n/**\n * Options passed to tool hooks (third argument)\n */\nexport interface ToolHookOptions {\n /** Request user input (human-in-the-loop). Pauses until user responds. */\n askUser: (req?: UserInputRequest) => Promise<UserInputResponse | null>;\n /** Current agent mode — hooks can use this to decide behavior per mode. */\n mode: string;\n}\n\n// =============================================================================\n// Tool Hook Types\n// =============================================================================\n\n/**\n * Hook called before tool execution.\n *\n * Return values:\n * - `{ action: \"allow\" }` — proceed (optionally with modified input)\n * - `{ action: \"deny\", reason }` — reject execution\n */\nexport type BeforeToolHook<TState = unknown> = (\n ctx: Context,\n req: {\n toolName: string;\n input: unknown;\n toolCallId: string;\n state: TState;\n },\n options: ToolHookOptions,\n) => Promise<{ action: \"allow\"; input?: unknown } | { action: \"deny\"; reason: string }>;\n\n/** Unified tool call status */\nexport type ToolCallStatus = \"running\" | \"completed\" | \"modify\" | \"denied\" | \"error\";\n\n/**\n * Hook called after tool execution.\n */\nexport type AfterToolHook<TState = unknown> = (\n ctx: Context,\n req: {\n toolName: string;\n input: unknown;\n output: unknown;\n toolCallId: string;\n state: TState;\n ui?: ToolUi;\n },\n options: ToolHookOptions,\n) => Promise<{\n /** Lightweight context for LLM */\n context: unknown;\n /** State update (partial merge) */\n state?: Partial<TState>;\n /** UI override — if omitted and metadata.ui exists, auto-generated from tool output */\n ui?: ToolUi;\n /** Tool call result status */\n status?: ToolCallStatus;\n /** Human-readable message */\n message?: string;\n /** Pruning instructions */\n prune?: {\n removeTools?: string[];\n keepRecent?: number;\n };\n /** Resource usage */\n usage?: Usage;\n}>;\n\n/** Tool hooks container */\nexport interface ToolHooks<TState = unknown> {\n before?: BeforeToolHook<TState>;\n after?: AfterToolHook<TState>;\n}\n\n// =============================================================================\n// Hook Identity Functions (type narrowing without generics on tool())\n// =============================================================================\n\nexport function before<TState>(fn: BeforeToolHook<TState>): BeforeToolHook<TState> {\n return fn;\n}\n\nexport function after<TState>(fn: AfterToolHook<TState>): AfterToolHook<TState> {\n return fn;\n}\n\n// =============================================================================\n// Tool Call Types\n// =============================================================================\n\nexport interface CallToolRequest {\n tool: Tool;\n args: unknown;\n}\n\nexport interface CallToolResponse {\n output: string;\n}\n\nexport interface ToolCallError {\n tool: string;\n error: string;\n args?: string;\n}\n\nexport interface ToolCall {\n id: string;\n name: string;\n args: string;\n status: \"pending\" | \"completed\" | \"failed\";\n output?: string;\n error?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ResolveToolRequest {\n tool: string | Tool;\n available: Tool[];\n}\n\nexport interface ResolveToolResponse {\n tool: Tool;\n}\n","/**\n * TTS (Text-to-Speech) related types\n *\n * Provider-agnostic TTS interface. Voice and model are opaque strings —\n * each provider interprets them in its own context (e.g., OpenAI \"nova\"\n * vs ElevenLabs voice IDs like \"cgSgspJ2msm6clMCkdW9\").\n */\n\nimport type { Context } from \"../core/context.types\";\nimport type { ModelCost } from \"../agents/model.types\";\nimport type { Provider } from \"../core/provider.types\";\n\n// =============================================================================\n// VOICE, MODEL, FORMAT\n// =============================================================================\n\n/** Provider-agnostic voice identifier (string — each provider defines its own) */\nexport type TTSVoice = string;\n\n/** Provider-agnostic model identifier */\nexport type TTSModel = string;\n\n/** Audio output format — shared across providers */\nexport type TTSResponseFormat = \"mp3\" | \"opus\" | \"aac\" | \"flac\" | \"wav\" | \"pcm\";\n\n// OpenAI-specific convenience constants\nexport const OPENAI_TTS_VOICES = [\"alloy\", \"echo\", \"fable\", \"onyx\", \"nova\", \"shimmer\"] as const;\nexport type OpenAITTSVoice = (typeof OPENAI_TTS_VOICES)[number];\n\nexport const OPENAI_TTS_MODELS = [\"tts-1\", \"tts-1-hd\"] as const;\nexport type OpenAITTSModel = (typeof OPENAI_TTS_MODELS)[number];\n\n// Backwards-compatible runtime constants (used by OpenAI provider validation)\nexport const TTS_VOICES: string[] = [...OPENAI_TTS_VOICES];\nexport const TTS_MODELS: string[] = [...OPENAI_TTS_MODELS];\nexport const TTS_FORMATS: TTSResponseFormat[] = [\"mp3\", \"opus\", \"aac\", \"flac\", \"wav\", \"pcm\"];\n\n// =============================================================================\n// REQUEST / RESPONSE\n// =============================================================================\n\nexport interface TTSRequest {\n /** The text to convert to speech */\n text: string;\n /** The voice to use for speech synthesis */\n voice?: TTSVoice;\n /** The model to use for speech synthesis */\n model?: TTSModel;\n /** Speed of the generated audio (0.25 to 4.0) */\n speed?: number;\n /** The format of the audio output */\n responseFormat?: TTSResponseFormat;\n /** Explicit provider routing (e.g., \"openai\", \"elevenlabs\") */\n provider?: string;\n /** Provider-specific voice settings (stability, similarity_boost, etc.) */\n voiceSettings?: Record<string, unknown>;\n}\n\nexport interface TTSResponse {\n /** Raw audio buffer */\n audioBuffer: Buffer;\n /** Base64-encoded audio data */\n audioBase64: string;\n /** MIME type of the audio */\n mimeType: string;\n}\n\n// =============================================================================\n// MODEL / VOICE DEFINITIONS\n// =============================================================================\n\n/** TTS model definition — follows the same pattern as Model in model.types.ts */\nexport interface TTSModelDef {\n /** Model identifier (e.g., \"tts-1\", \"eleven_turbo_v2\") */\n id: string;\n /** Human-readable name (e.g., \"TTS-1\", \"Eleven Turbo v2\") */\n name: string;\n /** Provider name (e.g., \"openai\", \"elevenlabs\") */\n provider: string;\n /** Provider-specific options */\n options?: Record<string, unknown>;\n /** Cost configuration for billing and estimation */\n cost: ModelCost;\n}\n\n/** TTS voice definition — a named voice with provider and default settings */\nexport interface TTSVoiceDef {\n /** Voice identifier (e.g., \"nova\", \"cgSgspJ2msm6clMCkdW9\") */\n id: string;\n /** Human-readable name (e.g., \"Nova\", \"Scarlett\") */\n name: string;\n /** Provider name (e.g., \"openai\", \"elevenlabs\") */\n provider: string;\n /** Default voice settings (e.g., { stability: 0.5, similarityBoost: 0.8 }) */\n options?: Record<string, unknown>;\n}\n\n// =============================================================================\n// TTS PROVIDER\n// =============================================================================\n\n/**\n * TTSProvider — platform-provided text-to-speech.\n *\n * Implementations: OpenAI (`@jarvis/openai`), ElevenLabs (`@jarvis/elevenlabs`).\n * Multi-provider routing: `@jarvis/tts`.\n */\nexport interface TTSProvider extends Provider {\n /** Convert text to speech audio */\n speech(ctx: Context, request: TTSRequest): Promise<TTSResponse>;\n /** List available TTS models for this provider */\n getModels?(): TTSModelDef[];\n /** List available voices for this provider */\n getVoices?(): TTSVoiceDef[];\n /** Create a new instance with different config (e.g., different API key for BYOK) */\n configure?(config: Record<string, unknown>): TTSProvider;\n}\n","/**\n * Claude Code provider\n *\n * Wraps the @anthropic-ai/claude-agent-sdk. Returns { content, toolCalls: undefined }\n * so the orchestrator exits after 1 iteration — Claude Code handles its own tool loop internally.\n *\n * Routing is by provider (\"claude-code\"), not model ID. The model ID passed in\n * (e.g. \"claude-sonnet-4-5-20250929\") goes straight to the SDK.\n *\n * Tool interception (canUseTool):\n * - When `onUserInput` is provided, every SDK tool call is converted to a PendingUserInput\n * and forwarded to the consumer via the callback. The consumer decides per-tool what to do.\n * - Tools with hooks.before: Provider invokes the hook, which calls wait() with artifact data.\n * The wait() creates an enriched PendingUserInput and routes through onUserInput.\n * - AskUserQuestion: Specific converter → structured questions format for AskUserPanel\n * - All other tools: Generic converter → raw toolName + input\n * - When no `onUserInput` is provided, falls back to bypassPermissions (backwards compatible)\n *\n * After-hook invocation:\n * - When a \"user\" message arrives (tool_result), the provider invokes after hooks for tracked tools.\n * - Artifacts from after hooks are attached to the message as `_toolUi` map.\n * - The worker reads `_toolUi` when creating tool completion messages.\n */\n\nimport { logger } from \"@jarvis/logger\";\nimport { claudeCodeModels } from \"./anthropic.models\";\nimport { context as createContext } from \"@jarvis/sdk\";\nimport type {\n Context,\n QueryLLMRequest,\n QueryLLMResponse,\n LLMProvider,\n LLMQueryOptions,\n Model,\n PendingUserInput,\n ToolUiData,\n UserInputResponse,\n ToolHookOptions,\n} from \"@jarvis/types\";\nimport { hasOutputFormat } from \"@jarvis/types\";\n\nimport type { ClaudeCodeConfig, ProviderTool } from \"./claude-code.types\";\n\n// SDK types imported dynamically; declare the shapes we need for canUseTool.\n// Note: SDK Zod validation requires updatedInput on the \"allow\" variant.\ntype PermissionResult =\n | {\n behavior: \"allow\";\n updatedInput: Record<string, unknown>;\n toolUseID?: string;\n }\n | {\n behavior: \"deny\";\n message: string;\n interrupt?: boolean;\n toolUseID?: string;\n };\n\nlet _idCounter = 0;\nfunction generateId(): string {\n return `pui-${Date.now()}-${++_idCounter}`;\n}\n\n/**\n * Convert AskUserQuestion tool call to a PendingUserInput\n * with structured questions format matching AskUserPanel expectations.\n */\nfunction convertAskUserQuestion(\n input: Record<string, unknown>,\n toolUseID: string,\n): PendingUserInput {\n return {\n id: generateId(),\n type: \"tool\",\n toolName: \"askUser\",\n toolCallId: toolUseID,\n output: {\n questions: input.questions,\n },\n timing: \"before\",\n };\n}\n\n/**\n * Convert any other tool call to a generic PendingUserInput.\n * The consumer (worker) decides what to do based on toolName.\n */\nfunction convertGenericTool(\n toolName: string,\n input: Record<string, unknown>,\n toolUseID: string,\n): PendingUserInput {\n return {\n id: generateId(),\n type: \"tool\",\n toolName,\n toolCallId: toolUseID,\n input,\n timing: \"before\",\n };\n}\n\n/**\n * Convert a UserInputResponse from the consumer back to an SDK PermissionResult.\n * For AskUserQuestion, the response data contains answers that need to flow back.\n */\nfunction toPermissionResult(\n toolName: string,\n originalInput: Record<string, unknown>,\n response: UserInputResponse,\n toolUseID: string,\n): PermissionResult {\n if (response.action === \"deny\") {\n return {\n behavior: \"deny\",\n message: response.feedback || \"User denied the tool call\",\n toolUseID,\n };\n }\n\n // For AskUserQuestion, pass answers back as updatedInput so the SDK\n // receives them as the tool's \"result\"\n if (toolName === \"AskUserQuestion\" && response.data) {\n return {\n behavior: \"allow\",\n updatedInput: {\n answers: response.data,\n },\n toolUseID,\n };\n }\n\n // SDK Zod schema requires updatedInput for the \"allow\" variant —\n // pass the original input through unchanged.\n return { behavior: \"allow\", updatedInput: originalInput, toolUseID };\n}\n\n// =============================================================================\n// Shared permission + hook infrastructure\n// =============================================================================\n\ninterface PermissionOptions {\n opts: Record<string, unknown>;\n toolMap: Map<string, ProviderTool>;\n toolInputTracker: Map<\n string,\n { toolName: string; input: Record<string, unknown> }\n >;\n}\n\n/**\n * Build permission options shared by both query() and stream().\n * When tools with hooks are provided, canUseTool invokes the before hook.\n */\nfunction buildPermissionOptions(\n ctx: Context,\n config: ClaudeCodeConfig,\n): PermissionOptions {\n const toolMap = new Map<string, ProviderTool>();\n for (const t of config.tools ?? []) toolMap.set(t.name, t);\n\n const toolInputTracker = new Map<\n string,\n { toolName: string; input: Record<string, unknown> }\n >();\n\n if (!config.onUserInput) {\n return {\n opts: {\n permissionMode: \"bypassPermissions\" as const,\n allowDangerouslySkipPermissions: true,\n },\n toolMap,\n toolInputTracker,\n };\n }\n\n const canUseTool = async (\n toolName: string,\n input: Record<string, unknown>,\n options: { toolUseID: string; signal: AbortSignal },\n ): Promise<PermissionResult> => {\n // Track tool input for after-hook invocation\n toolInputTracker.set(options.toolUseID, { toolName, input });\n\n const t = toolMap.get(toolName);\n\n // If tool has a before hook, invoke it — the hook creates the PendingUserInput\n // with artifact data via wait()\n if (t?.hooks?.before) {\n const req = {\n toolName,\n input,\n toolCallId: options.toolUseID,\n state: {} as unknown,\n };\n const hookOptions: ToolHookOptions = {\n mode: config.permissionMode ?? \"default\",\n askUser: async (waitOpts?) => {\n const pendingInput: PendingUserInput = {\n id: generateId(),\n type: \"tool\" as const,\n toolName,\n toolCallId: options.toolUseID,\n input,\n timing: \"before\" as const,\n ...(waitOpts?.data\n ? { output: waitOpts.data }\n : waitOpts?.ui\n ? { output: waitOpts.ui }\n : {}),\n reason: waitOpts?.reason,\n };\n return config.onUserInput!(pendingInput);\n },\n };\n\n const result = await t.hooks.before(ctx, req, hookOptions);\n if (result.action === \"deny\") {\n return {\n behavior: \"deny\",\n message: (result as { reason?: string }).reason ?? \"Denied\",\n toolUseID: options.toolUseID,\n };\n }\n return {\n behavior: \"allow\",\n updatedInput:\n ((result as { input?: unknown }).input as Record<string, unknown>) ||\n input,\n toolUseID: options.toolUseID,\n };\n }\n\n // No before hook — use specific converters for known tools, generic for others\n const pendingInput =\n toolName === \"AskUserQuestion\"\n ? convertAskUserQuestion(input, options.toolUseID)\n : convertGenericTool(toolName, input, options.toolUseID);\n\n const response = await config.onUserInput!(pendingInput);\n return toPermissionResult(toolName, input, response, options.toolUseID);\n };\n\n return {\n opts: {\n permissionMode: (config.permissionMode ?? \"default\") as\n | \"default\"\n | \"plan\",\n canUseTool,\n },\n toolMap,\n toolInputTracker,\n };\n}\n\n/**\n * Process after hooks for a \"user\" message (tool_result).\n * Returns a map of toolUseId → ToolUiData for enrichment.\n */\nasync function processAfterHooks(\n ctx: Context,\n req: {\n message: any;\n config: ClaudeCodeConfig;\n toolMap: Map<string, ProviderTool>;\n toolInputTracker: Map<\n string,\n { toolName: string; input: Record<string, unknown> }\n >;\n },\n): Promise<Record<string, ToolUiData> | null> {\n const { message, config, toolInputTracker, toolMap } = req;\n if (message.type !== \"user\" || !Array.isArray(message.message?.content))\n return null;\n\n const artifactMap: Record<string, ToolUiData> = {};\n let hasArtifacts = false;\n\n for (const block of message.message.content) {\n const toolUseId = block?.tool_use_id;\n if (!toolUseId) continue;\n\n const tracked = toolInputTracker.get(toolUseId);\n const t = tracked ? toolMap.get(tracked.toolName) : null;\n\n if (t?.hooks?.after) {\n try {\n const afterResult = await t.hooks.after(\n ctx,\n {\n toolName: tracked!.toolName,\n input: tracked!.input,\n output: block.content ?? block.output,\n toolCallId: toolUseId,\n state: {} as unknown,\n },\n { mode: config.permissionMode ?? \"default\", askUser: async () => ({ action: \"allow\" as const }) },\n );\n\n // Bridge ToolUi → ToolUiData for chat messages\n if (afterResult.ui && \"uri\" in afterResult.ui) {\n const { uri, title, data } = afterResult.ui as {\n uri: string;\n title: string;\n data?: unknown;\n };\n const match = uri.match(/^ui:\\/\\/([^/]+)\\/(.+)$/);\n artifactMap[toolUseId] = {\n type: match?.[2] || uri,\n title,\n data,\n };\n hasArtifacts = true;\n }\n } catch (err) {\n logger.sys.error(`After hook error for ${tracked!.toolName}`, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n toolInputTracker.delete(toolUseId);\n }\n\n return hasArtifacts ? artifactMap : null;\n}\n\n// =============================================================================\n// Provider\n// =============================================================================\n\nexport function claudeCodeProvider(config: ClaudeCodeConfig = {}): LLMProvider {\n const useSubscription = config.useSubscription ?? false;\n const apiKey = useSubscription\n ? undefined\n : (config.apiKey ?? process.env.ANTHROPIC_API_KEY);\n\n async function query(\n ctx: Context,\n req: QueryLLMRequest,\n _options?: LLMQueryOptions,\n ): Promise<QueryLLMResponse> {\n const { query: claudeQuery } =\n await import(\"@anthropic-ai/claude-agent-sdk\");\n if (!apiKey && !useSubscription) {\n throw new Error(\n \"Anthropic API key is required. \" +\n \"Provide it via config.apiKey, ANTHROPIC_API_KEY env var, or set useSubscription: true.\",\n );\n }\n\n const startTime = Date.now();\n\n // Extract user message and system prompt\n const userMessage = [...req.messages]\n .reverse()\n .find((m) => m.role === \"user\");\n const prompt = userMessage?.content ?? \"\";\n const systemMessage = req.messages.find((m) => m.role === \"system\");\n const systemPrompt = config.systemPrompt ?? systemMessage?.content ?? \"\";\n\n let aggregatedContent = \"\";\n let lastAssistantContent = \"\";\n let json: string | undefined;\n let sdkError: string | undefined;\n let inputTokens = 0;\n let outputTokens = 0;\n let resultSessionId: string | undefined;\n\n // When resuming, skip setting systemPrompt — SDK uses the original session's prompt\n const isResuming = !!config.session?.resume;\n const systemPromptOption = isResuming\n ? undefined\n : systemPrompt\n ? {\n type: \"preset\" as const,\n preset: \"claude_code\" as const,\n append: typeof systemPrompt === \"string\" ? systemPrompt : \"\",\n }\n : undefined;\n\n // Build permission options (shared helper — hook-aware when tools provided)\n const {\n opts: permissionOptions,\n toolMap,\n toolInputTracker,\n } = buildPermissionOptions(ctx, config);\n\n logger.info(ctx, \"[ClaudeCode] Starting query\", {\n model: req.model,\n hasApiKey: !!apiKey,\n promptLength: typeof prompt === \"string\" ? prompt.length : 0,\n cwd: config.workingDirectory,\n mcpServers: Object.keys(config.mcpServers || {}),\n });\n\n let messageCount = 0;\n try {\n for await (const message of claudeQuery({\n prompt: typeof prompt === \"string\" ? prompt : JSON.stringify(prompt),\n options: {\n model: req.model,\n systemPrompt: systemPromptOption,\n ...(config.maxTurns ? { maxTurns: config.maxTurns } : {}),\n ...permissionOptions,\n ...(config.mcpServers ? { mcpServers: config.mcpServers } : {}),\n ...(config.workingDirectory ? { cwd: config.workingDirectory } : {}),\n ...(hasOutputFormat(config.output, \"json\") && config.output?.schema\n ? {\n outputFormat: {\n type: \"json_schema\" as const,\n schema: config.output.schema,\n },\n }\n : {}),\n ...(config.disallowedTools?.length\n ? { disallowedTools: config.disallowedTools }\n : {}),\n ...(config.abortController\n ? { abortController: config.abortController }\n : {}),\n // Session resume/persistence options\n ...(config.session?.sessionId\n ? { sessionId: config.session.sessionId }\n : {}),\n ...(config.session?.resume ? { resume: config.session.resume } : {}),\n ...(config.session?.persistSession !== undefined\n ? { persistSession: config.session.persistSession }\n : {}),\n ...(config.session?.forkSession\n ? { forkSession: config.session.forkSession }\n : {}),\n env: {\n ...(apiKey ? { ANTHROPIC_API_KEY: apiKey } : {}),\n ...(useSubscription ? {} : { IS_SANDBOX: \"1\" }),\n HOME: process.env.HOME ?? \"\",\n PATH: process.env.PATH ?? \"\",\n TMPDIR: process.env.TMPDIR ?? \"\",\n NODE_ENV: process.env.NODE_ENV ?? \"\",\n },\n debugFile: \"/tmp/claude-code-debug.log\",\n stderr: (data: string) =>\n logger.error(ctx, \"[ClaudeCode stderr]\", { data }),\n },\n })) {\n messageCount++;\n logger.info(ctx, \"[ClaudeCode] SDK message\", {\n count: messageCount,\n type: message.type,\n });\n\n // Skip replayed messages during session resume — they're old history.\n // Still heartbeat so the activity stays alive during replay.\n if ((message as any).isReplay) {\n if (config.heartbeat) config.heartbeat();\n continue;\n }\n\n if (config.heartbeat) {\n config.heartbeat();\n }\n\n // Track tool inputs from \"assistant\" messages for safe tools that bypass canUseTool\n // (SDK auto-approves Read, Glob, Grep without calling canUseTool in default mode)\n if (\n message.type === \"assistant\" &&\n Array.isArray(message.message?.content)\n ) {\n for (const block of message.message.content) {\n if (block?.type === \"tool_use\" && block.id && block.name) {\n if (!toolInputTracker.has(block.id)) {\n toolInputTracker.set(block.id, {\n toolName: block.name,\n input: (block.input || {}) as Record<string, unknown>,\n });\n }\n }\n }\n }\n\n // Process after hooks for tool_result messages — enrich with artifacts\n const artifacts = await processAfterHooks(ctx, {\n message,\n config,\n toolMap,\n toolInputTracker,\n });\n if (artifacts) {\n (message as any)._toolUi = artifacts;\n }\n\n // Forward all SDK messages for rich progress tracking\n if (config.onProgress) {\n await config.onProgress(message);\n // Heartbeat after async progress handling — may take time\n if (config.heartbeat) config.heartbeat();\n }\n\n if (message.type === \"assistant\" && message.message?.content) {\n lastAssistantContent = \"\";\n for (const block of message.message.content) {\n if (typeof block === \"string\") {\n lastAssistantContent += block;\n aggregatedContent += block;\n if (config.onChunk) config.onChunk(block);\n } else if (block.type === \"text\") {\n lastAssistantContent += block.text;\n aggregatedContent += block.text;\n if (config.onChunk) config.onChunk(block.text);\n }\n }\n }\n\n if (message.type === \"result\") {\n // Detect SDK error results (max_turns, budget, etc.)\n const subtype = (message as any).subtype;\n if (subtype && subtype !== \"success\") {\n const errors = (message as any).errors as string[] | undefined;\n sdkError = `Agent ${subtype}${errors?.length ? `: ${errors.join(\", \")}` : \"\"}`;\n }\n\n // Keep structured output separate — don't overwrite text content\n const structuredOutput = (message as any).structured_output;\n if (\n structuredOutput !== undefined &&\n hasOutputFormat(config.output, \"json\")\n ) {\n json =\n typeof structuredOutput === \"string\"\n ? structuredOutput\n : JSON.stringify(structuredOutput);\n }\n\n // Text result from SDK — use as content if we have no assistant text yet\n if (\"result\" in message && !aggregatedContent) {\n aggregatedContent = (message as any).result;\n }\n\n if (\"usage\" in message) {\n const usage = (message as any).usage;\n inputTokens = usage?.input_tokens ?? 0;\n outputTokens = usage?.output_tokens ?? 0;\n }\n\n // Extract session ID for resume support\n resultSessionId = (message as any).session_id;\n }\n }\n } catch (error) {\n logger.error(ctx, \"[ClaudeCode] Query error\", {\n error: error instanceof Error ? error.message : String(error),\n model: req.model,\n apiKeyPresent: !!apiKey,\n cwd: config.workingDirectory,\n mcpServers: Object.keys(config.mcpServers || {}),\n });\n throw error;\n }\n\n logger.info(ctx, \"[ClaudeCode] Query complete\", { messageCount });\n\n return {\n content: lastAssistantContent || aggregatedContent,\n json,\n error: sdkError,\n toolCalls: undefined,\n sessionId: resultSessionId,\n metadata: {\n model: req.model,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n },\n duration: Date.now() - startTime,\n provider: \"claude-code\",\n },\n };\n }\n\n async function* stream(\n ctx: Context,\n req: QueryLLMRequest,\n _options?: LLMQueryOptions,\n ): AsyncGenerator<QueryLLMResponse> {\n const { query: claudeQuery } =\n await import(\"@anthropic-ai/claude-agent-sdk\");\n if (!apiKey && !useSubscription) {\n throw new Error(\n \"Anthropic API key is required. \" +\n \"Provide it via config.apiKey, ANTHROPIC_API_KEY env var, or set useSubscription: true.\",\n );\n }\n\n const startTime = Date.now();\n\n const userMessage = [...req.messages]\n .reverse()\n .find((m) => m.role === \"user\");\n const prompt = userMessage?.content ?? \"\";\n const systemMessage = req.messages.find((m) => m.role === \"system\");\n const systemPrompt = config.systemPrompt ?? systemMessage?.content ?? \"\";\n\n let inputTokens = 0;\n let outputTokens = 0;\n\n // When resuming, skip setting systemPrompt — SDK uses the original session's prompt\n const isResuming = !!config.session?.resume;\n const streamSystemPromptOption = isResuming\n ? undefined\n : systemPrompt\n ? {\n type: \"preset\" as const,\n preset: \"claude_code\" as const,\n append: typeof systemPrompt === \"string\" ? systemPrompt : \"\",\n }\n : undefined;\n\n // Build permission options (shared helper — hook-aware when tools provided)\n const {\n opts: permissionOptions,\n toolMap,\n toolInputTracker,\n } = buildPermissionOptions(ctx, config);\n\n logger.info(ctx, \"[ClaudeCode] Starting stream\", {\n model: req.model,\n hasApiKey: !!apiKey,\n promptLength: typeof prompt === \"string\" ? prompt.length : 0,\n cwd: config.workingDirectory,\n mcpServers: Object.keys(config.mcpServers || {}),\n });\n\n let messageCount = 0;\n try {\n for await (const message of claudeQuery({\n prompt: typeof prompt === \"string\" ? prompt : JSON.stringify(prompt),\n options: {\n model: req.model,\n systemPrompt: streamSystemPromptOption,\n ...(config.maxTurns ? { maxTurns: config.maxTurns } : {}),\n ...permissionOptions,\n ...(config.mcpServers ? { mcpServers: config.mcpServers } : {}),\n ...(config.workingDirectory ? { cwd: config.workingDirectory } : {}),\n ...(hasOutputFormat(config.output, \"json\") && config.output?.schema\n ? {\n outputFormat: {\n type: \"json_schema\" as const,\n schema: config.output.schema,\n },\n }\n : {}),\n ...(config.disallowedTools?.length\n ? { disallowedTools: config.disallowedTools }\n : {}),\n ...(config.abortController\n ? { abortController: config.abortController }\n : {}),\n // Session resume/persistence options\n ...(config.session?.sessionId\n ? { sessionId: config.session.sessionId }\n : {}),\n ...(config.session?.resume ? { resume: config.session.resume } : {}),\n ...(config.session?.persistSession !== undefined\n ? { persistSession: config.session.persistSession }\n : {}),\n ...(config.session?.forkSession\n ? { forkSession: config.session.forkSession }\n : {}),\n env: {\n ...(apiKey ? { ANTHROPIC_API_KEY: apiKey } : {}),\n ...(useSubscription ? {} : { IS_SANDBOX: \"1\" }),\n HOME: process.env.HOME ?? \"\",\n PATH: process.env.PATH ?? \"\",\n TMPDIR: process.env.TMPDIR ?? \"\",\n NODE_ENV: process.env.NODE_ENV ?? \"\",\n },\n debugFile: \"/tmp/claude-code-debug.log\",\n stderr: (data: string) =>\n logger.error(ctx, \"[ClaudeCode stderr]\", { data }),\n },\n })) {\n messageCount++;\n logger.info(ctx, \"[ClaudeCode] SDK message\", {\n count: messageCount,\n type: message.type,\n });\n\n // Skip replayed messages during session resume — they're old history.\n // Still heartbeat so the activity stays alive during replay.\n if ((message as any).isReplay) {\n if (config.heartbeat) config.heartbeat();\n continue;\n }\n\n if (config.heartbeat) config.heartbeat();\n\n // Track tool inputs from \"assistant\" messages for safe tools that bypass canUseTool\n if (\n message.type === \"assistant\" &&\n Array.isArray(message.message?.content)\n ) {\n for (const block of message.message.content) {\n if (block?.type === \"tool_use\" && block.id && block.name) {\n if (!toolInputTracker.has(block.id)) {\n toolInputTracker.set(block.id, {\n toolName: block.name,\n input: (block.input || {}) as Record<string, unknown>,\n });\n }\n }\n }\n }\n\n // Process after hooks for tool_result messages — enrich with artifacts\n const artifacts = await processAfterHooks(ctx, {\n message,\n config,\n toolMap,\n toolInputTracker,\n });\n if (artifacts) {\n (message as any)._toolUi = artifacts;\n }\n\n if (config.onProgress) {\n await config.onProgress(message);\n if (config.heartbeat) config.heartbeat();\n }\n\n // Yield incremental text chunks as Claude Code produces them\n if (message.type === \"assistant\" && message.message?.content) {\n for (const block of message.message.content) {\n const text =\n typeof block === \"string\"\n ? block\n : block.type === \"text\"\n ? block.text\n : \"\";\n if (text) {\n if (config.onChunk) config.onChunk(text);\n yield {\n content: text,\n metadata: {\n model: req.model,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n },\n duration: Date.now() - startTime,\n provider: \"claude-code\",\n },\n };\n }\n }\n }\n\n if (message.type === \"result\") {\n if (\"usage\" in message) {\n const usage = (message as any).usage;\n inputTokens = usage?.input_tokens ?? 0;\n outputTokens = usage?.output_tokens ?? 0;\n }\n // Keep structured output separate from text content\n const structuredOutput = (message as any).structured_output;\n const sc =\n structuredOutput !== undefined &&\n hasOutputFormat(config.output, \"json\")\n ? typeof structuredOutput === \"string\"\n ? structuredOutput\n : JSON.stringify(structuredOutput)\n : undefined;\n // Final yield with updated usage metadata\n yield {\n content: \"\", // Text already yielded incrementally\n json: sc,\n metadata: {\n model: req.model,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n },\n duration: Date.now() - startTime,\n provider: \"claude-code\",\n },\n };\n }\n }\n } catch (error) {\n logger.error(ctx, \"[ClaudeCode] Stream error\", {\n error: error instanceof Error ? error.message : String(error),\n model: req.model,\n apiKeyPresent: !!apiKey,\n cwd: config.workingDirectory,\n mcpServers: Object.keys(config.mcpServers || {}),\n });\n throw error;\n }\n\n logger.info(ctx, \"[ClaudeCode] Stream complete\", { messageCount });\n }\n\n async function getModels(): Promise<Model[]> {\n return claudeCodeModels.list();\n }\n\n return {\n name: \"claude-code\",\n query,\n stream,\n getModels,\n };\n}\n","/**\n * Tools Domain\n * Pure functions for creating and calling tools\n */\nimport type {\n CallTool,\n Context,\n ToolHooks,\n BeforeToolHook,\n AfterToolHook,\n Tool,\n ToolMetadata,\n Schema,\n ToolHookOptions,\n} from \"@jarvis/types\";\n\n// Re-export hook identity functions from types\nexport { before, after } from \"@jarvis/types\";\n\n// =============================================================================\n// extractHooks() - Extract hooks from tools for agent creation\n// =============================================================================\n\nexport function extractHooks<TState = unknown>(\n tools: Tool[],\n): {\n before: Record<string, BeforeToolHook<TState>>;\n after: Record<string, AfterToolHook<TState>>;\n} {\n const before: Record<string, BeforeToolHook<TState>> = {};\n const after: Record<string, AfterToolHook<TState>> = {};\n\n for (const t of tools) {\n if (t.hooks?.before) {\n before[t.name] = t.hooks.before as BeforeToolHook<TState>;\n }\n if (t.hooks?.after) {\n after[t.name] = t.hooks.after as AfterToolHook<TState>;\n }\n }\n\n return { before, after };\n}\n\n// =============================================================================\n// tool() Factory\n// =============================================================================\n\n/**\n * Create a tool with optional colocated hooks.\n *\n * @example\n * ```typescript\n * const myTool = tool({\n * name: \"createGoal\",\n * description: \"Create a new goal\",\n * schema: {\n * input: { type: \"object\", properties: { title: { type: \"string\" } } },\n * output: { type: \"object\", properties: { goalId: { type: \"string\" } } },\n * },\n * call: async (ctx, input) => ({ goalId: \"g-123\" }),\n * metadata: {\n * label: \"Create Goal\",\n * permissions: { roles: [\"editor\"], risk: \"moderate\" },\n * ui: { component: \"goals\", title: \"Goals\" },\n * },\n * hooks: {\n * before: before<MyState>(async (ctx, req, { askUser }) => ({ action: \"allow\" })),\n * after: after<MyState>(async (ctx, req) => ({\n * context: { created: true },\n * state: { goals: [...req.state.goals, req.output] },\n * })),\n * },\n * });\n * ```\n */\nexport function tool<TState = unknown>(config: {\n name: string;\n description: string;\n schema: { input: Schema; output: Schema };\n call?: CallTool;\n hooks?: ToolHooks<TState>;\n metadata?: ToolMetadata;\n build?: (ctx: unknown, req: { tool: Tool; state: TState }) => Tool;\n}): Tool {\n return {\n name: config.name,\n description: config.description,\n input: config.schema.input,\n output: config.schema.output,\n call: config.call,\n hooks: config.hooks,\n metadata: config.metadata,\n build: config.build as Tool[\"build\"],\n };\n}\n\n// =============================================================================\n// buildTools() - Apply build() to tools with current state\n// =============================================================================\n\n/**\n * Build tools by applying schema builders and pre-binding options.\n *\n * Three phases per tool:\n * 1. Apply permissions check via before hook (if metadata.permissions is set)\n * 2. Apply `build()` for schema-only changes (dynamic enums from state)\n * 3. Wrap `call()` to pre-bind options (if call has >= 2 params)\n * 4. Wrap hooks to spread app options flat into hook options\n */\nexport function buildTools(\n ctx: Context,\n req: { tools: Tool[]; state: unknown },\n options?: unknown,\n): Tool[] {\n return req.tools.map((t) => {\n // Phase 0: If tool has permissions, inject a before hook that checks roles/tiers\n const permissions = t.metadata?.permissions;\n if (permissions?.roles?.length || permissions?.tiers?.length) {\n const existingBefore = t.hooks?.before;\n t = {\n ...t,\n hooks: {\n ...t.hooks,\n before: async (hookCtx: Context, hookReq: { toolName: string; input: unknown; toolCallId: string; state: unknown }, hookOpts: ToolHookOptions) => {\n const access = (hookCtx as Context & { access?: { role?: string; tier?: string } }).access;\n const role = access?.role ?? \"\";\n const tier = access?.tier ?? \"free\";\n if (permissions.roles?.length && !permissions.roles.includes(role)) {\n return { action: \"deny\" as const, reason: \"Access denied: insufficient role\" };\n }\n if (permissions.tiers?.length && !permissions.tiers.includes(tier)) {\n return { action: \"deny\" as const, reason: \"Access denied: insufficient tier\" };\n }\n if (existingBefore) return existingBefore(hookCtx, hookReq, hookOpts);\n return { action: \"allow\" as const };\n },\n },\n };\n }\n\n // Phase 1: Apply build (schema-only, no options)\n const built = t.build ? t.build(ctx, { tool: t, state: req.state }) : t;\n if (options == null) return built;\n\n const result = { ...built };\n\n // Phase 2: Wrap call to pre-bind options (if call has >= 2 params)\n if (result.call && result.call.length >= 2) {\n const baseCall = result.call as (\n ctx: Context,\n input: unknown,\n options?: unknown,\n ) => Promise<unknown>;\n result.call = ((ctxArg: Context, input: unknown) =>\n baseCall(ctxArg, input, options)) as CallTool;\n }\n\n // Phase 3: Wrap hooks to spread app options flat into hook options\n if (result.hooks) {\n const baseHooks = result.hooks;\n result.hooks = {\n before: baseHooks.before\n ? async (ctx: Context, req: { toolName: string; input: unknown; toolCallId: string; state: unknown }, hookOpts: ToolHookOptions) =>\n baseHooks.before!(ctx, req, {\n ...hookOpts,\n ...(options as object),\n } as ToolHookOptions)\n : undefined,\n after: baseHooks.after\n ? async (ctx: Context, req: unknown, hookOpts: ToolHookOptions) =>\n baseHooks.after!(ctx, req as Parameters<NonNullable<typeof baseHooks.after>>[1], {\n ...hookOpts,\n ...(options as object),\n } as ToolHookOptions)\n : undefined,\n };\n }\n\n return result;\n });\n}\n\n/**\n * Call a tool directly (for testing or simple invocation).\n */\nexport async function call(req: { tool: Tool; input: unknown }): Promise<unknown> {\n if (!req.tool.call) {\n throw new Error(\n `Tool ${req.tool.name} has no call function.`,\n );\n }\n return await req.tool.call(req.input);\n}\n","/**\n * Plan Tool\n * Platform-level tool for presenting plans to users for approval\n *\n * This tool allows agents to present a plan (list of steps) to the user\n * and wait for approval/modification before proceeding.\n *\n * @example\n * ```typescript\n * import { planTool } from \"@jarvis/sdk\";\n *\n * const tools = [planTool, ...otherTools];\n *\n * // Agent can now use the plan tool:\n * // LLM: \"I'll create a plan for you to review\"\n * // Tool call: plan({ title: \"...\", steps: [...], reasoning: \"...\" })\n * // → User sees PlanPanel in UI\n * // → User approves/modifies/rejects\n * // → Agent continues based on user response\n * ```\n */\nimport { Context } from \"@jarvis/types\";\nimport { tool } from \"./tools\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * A single step in a plan\n */\nexport interface PlanStep {\n /** Unique identifier for the step */\n id: string;\n /** Step title (brief description) */\n title: string;\n /** Optional detailed description */\n description?: string;\n /** Optional category for grouping/styling */\n category?: string;\n}\n\n/**\n * Input for the plan tool\n */\nexport interface PlanInput {\n /** Plan title shown in the header */\n title: string;\n /** List of steps in the plan */\n steps: PlanStep[];\n /** Optional reasoning explaining why this plan */\n reasoning?: string;\n}\n\n/**\n * Output from the plan tool\n */\nexport interface PlanOutput {\n /** Plan title */\n title: string;\n /** Plan items (steps mapped to items) */\n items: PlanStep[];\n /** Optional reasoning */\n reasoning?: string;\n}\n\n// =============================================================================\n// SCHEMA\n// =============================================================================\n\nconst planInputSchema = {\n type: \"object\" as const,\n properties: {\n title: {\n type: \"string\",\n description: \"A brief title for the plan\",\n },\n steps: {\n type: \"array\",\n description: \"The steps in the plan\",\n items: {\n type: \"object\",\n properties: {\n id: {\n type: \"string\",\n description: \"Unique identifier for this step\",\n },\n title: {\n type: \"string\",\n description: \"Brief title for the step\",\n },\n description: {\n type: \"string\",\n description: \"Detailed description of what this step involves\",\n },\n category: {\n type: \"string\",\n description:\n \"Optional category for grouping (e.g., 'setup', 'implementation', 'testing')\",\n },\n },\n required: [\"id\", \"title\"],\n },\n },\n reasoning: {\n type: \"string\",\n description: \"Explanation of why this plan was chosen\",\n },\n },\n required: [\"title\", \"steps\"],\n};\n\nconst planOutputSchema = {\n type: \"object\" as const,\n properties: {\n title: { type: \"string\" },\n items: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n title: { type: \"string\" },\n description: { type: \"string\" },\n category: { type: \"string\" },\n },\n },\n },\n reasoning: { type: \"string\" },\n },\n};\n\n// =============================================================================\n// TOOL\n// =============================================================================\n\n/**\n * Plan tool for presenting plans to users\n *\n * Usage:\n * - Agent calls this tool to present a plan\n * - Tool output is shown in PlanPanel UI component\n * - User can approve, reject, or modify the plan\n * - Agent receives user's response via the after hook\n */\nexport const planTool = tool({\n name: \"plan\",\n description:\n \"Present a plan to the user for approval before executing. Use this when you need user confirmation before proceeding with a multi-step task. The user can approve, reject, or suggest modifications to the plan.\",\n schema: {\n input: planInputSchema,\n output: planOutputSchema,\n },\n // The call function simply passes through the input as output\n // The actual plan review happens in the after hook via wait()\n call: async (_ctx: Context, input: PlanInput): Promise<PlanOutput> => ({\n title: input.title,\n items: input.steps,\n reasoning: input.reasoning,\n }),\n // Hooks handle the human-in-the-loop approval flow\n hooks: {\n // After hook waits for user approval\n after: async (ctx, req, options) => {\n const planOutput = req.output as PlanOutput;\n\n // Wait for user input (shows PlanPanel in UI)\n const userInput = await options.askUser({\n reason: planOutput.title,\n data: planOutput,\n });\n\n // Handle user response\n if (!userInput || userInput.action === \"deny\") {\n return {\n context: {\n status: \"denied\",\n message: userInput?.feedback || \"Plan was rejected by user\",\n },\n status: \"denied\",\n message: userInput?.feedback || \"Plan was rejected by user\",\n };\n }\n\n if (userInput.action === \"modify\") {\n return {\n context: {\n status: \"modify\",\n userFeedback: userInput.feedback,\n originalPlan: planOutput,\n },\n status: \"modify\",\n message: userInput.feedback || \"User requested modifications\",\n };\n }\n\n // Approved\n return {\n context: {\n status: \"approved\",\n plan: planOutput,\n message: \"Plan approved by user. Proceed with execution.\",\n },\n ui: {\n uri: \"ui://sdk/plan\",\n title: planOutput.title,\n data: planOutput,\n },\n };\n },\n },\n // Metadata for UI display\n metadata: {\n describe: (ctx, req) => {\n const input = req.input as unknown as PlanInput;\n if (req.status === \"running\") {\n return `Creating plan: ${input.title}`;\n }\n if (req.status === \"completed\") {\n return `Plan \"${input.title}\" ready for review`;\n }\n return undefined;\n },\n },\n});\n","/**\n * Ask User Tool\n * Platform-level tool for asking users structured questions\n *\n * This tool allows agents to ask clarifying questions with predefined options,\n * pausing execution until the user responds. Each question appears as a tab\n * with selectable options and an \"Other\" free-text input.\n *\n * @example\n * ```typescript\n * import { askUserTool } from \"@jarvis/sdk\";\n *\n * const tools = [askUserTool, ...otherTools];\n *\n * // Agent can now use the askUser tool:\n * // LLM: \"I need to understand your preference\"\n * // Tool call: askUser({ questions: [{ header: \"Approach\", question: \"...\", options: [...] }] })\n * // → User sees AskUserPanel in UI\n * // → User selects options or types custom answer\n * // → Agent continues with user's answers\n * ```\n */\nimport { tool } from \"./tools\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * A single option within a question\n */\nexport interface AskUserOption {\n /** Display label for the option */\n label: string;\n /** Optional description explaining the option */\n description?: string;\n}\n\n/**\n * A single question with options\n */\nexport interface AskUserQuestion {\n /** Short label displayed as tab header (max ~12 chars) */\n header: string;\n /** Full question text */\n question: string;\n /** Available options (2-4) */\n options: AskUserOption[];\n /** Whether user can select multiple options (default: false) */\n multiSelect?: boolean;\n}\n\n/**\n * Input for the askUser tool\n */\nexport interface AskUserInput {\n /** Questions to ask (1-4) */\n questions: AskUserQuestion[];\n}\n\n/**\n * A single answer from the user\n */\nexport interface AskUserAnswer {\n /** Header of the question being answered */\n header: string;\n /** Selected option label(s) */\n selected: string[];\n /** Custom text if user chose \"Other\" */\n customText?: string;\n}\n\n/**\n * Output from the askUser tool\n */\nexport interface AskUserOutput {\n /** The questions that were asked */\n questions: AskUserQuestion[];\n /** User's answers (populated after user responds) */\n answers?: AskUserAnswer[];\n}\n\n// =============================================================================\n// SCHEMA\n// =============================================================================\n\nconst askUserInputSchema = {\n type: \"object\" as const,\n properties: {\n questions: {\n type: \"array\",\n description: \"Questions to ask the user (1-4 questions)\",\n minItems: 1,\n maxItems: 4,\n items: {\n type: \"object\",\n properties: {\n header: {\n type: \"string\",\n description:\n \"Short label for the tab header (e.g., 'Approach', 'Priority')\",\n },\n question: {\n type: \"string\",\n description: \"The full question to ask the user\",\n },\n options: {\n type: \"array\",\n description:\n \"Available options (2-4). User always has an 'Other' free-text option automatically.\",\n minItems: 2,\n maxItems: 4,\n items: {\n type: \"object\",\n properties: {\n label: {\n type: \"string\",\n description: \"Option display label\",\n },\n description: {\n type: \"string\",\n description: \"Optional explanation of this option\",\n },\n },\n required: [\"label\"],\n },\n },\n multiSelect: {\n type: \"boolean\",\n description:\n \"Whether user can select multiple options (default: false)\",\n },\n },\n required: [\"header\", \"question\", \"options\"],\n },\n },\n },\n required: [\"questions\"],\n};\n\nconst askUserOutputSchema = {\n type: \"object\" as const,\n properties: {\n questions: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n header: { type: \"string\" },\n question: { type: \"string\" },\n options: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n label: { type: \"string\" },\n description: { type: \"string\" },\n },\n },\n },\n multiSelect: { type: \"boolean\" },\n },\n },\n },\n answers: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n header: { type: \"string\" },\n selected: { type: \"array\", items: { type: \"string\" } },\n customText: { type: \"string\" },\n },\n },\n },\n },\n};\n\n// =============================================================================\n// TOOL\n// =============================================================================\n\n/**\n * Ask User tool for structured questions\n *\n * Usage:\n * - Agent calls this tool to ask the user questions\n * - Tool output is shown in AskUserPanel UI component\n * - User can select options or type custom answers\n * - Agent receives user's answers via the after hook\n */\nexport const askUserTool = tool({\n name: \"askUser\",\n description: `Ask the user clarifying questions when you need their input to proceed. Use this when the request is ambiguous, you need a preference between approaches, or the scope/priority is unclear. Each question has predefined options plus a free-text 'Other' option. Do NOT use this for plan approval (use exitPlanMode instead) or internal reasoning (use think instead).\n\nGuidelines:\n- Do NOT ask questions you can resolve using available tools\n- Prefer making reasonable defaults over asking — only ask when the choice genuinely matters\n- Keep header labels concise (1-4 words like 'Approach', 'Priority')\n- Mark the recommended option with '(Recommended)' suffix\n- In plan mode, questions should relate to the plan being developed`,\n schema: {\n input: askUserInputSchema,\n output: askUserOutputSchema,\n },\n // Pass-through: returns questions as output for UI rendering\n call: async (_ctx, input: AskUserInput): Promise<AskUserOutput> => ({\n questions: input.questions,\n }),\n // After hook waits for user answers\n hooks: {\n after: async (ctx, req, options) => {\n const output = req.output as AskUserOutput;\n\n // Wait for user input (shows AskUserPanel in UI)\n const userInput = await options.askUser({\n reason:\n output.questions.length === 1\n ? output.questions[0]!.question\n : `${output.questions.length} questions to answer`,\n data: output,\n });\n\n // Handle user skip/cancel\n if (!userInput || userInput.action === \"deny\") {\n return {\n context: {\n status: \"skipped\",\n message:\n userInput?.feedback ||\n \"User skipped the questions. Proceed with your best judgment.\",\n },\n status: \"denied\",\n message: userInput?.feedback || \"User skipped the questions\",\n };\n }\n\n // Extract answers from user response\n const answers = (userInput.data as { answers?: AskUserAnswer[] })\n ?.answers;\n\n if (!answers || answers.length === 0) {\n return {\n context: {\n status: \"skipped\",\n message: \"No answers provided. Proceed with your best judgment.\",\n },\n status: \"denied\",\n message: \"No answers provided\",\n };\n }\n\n // Format answers for LLM context\n const formattedAnswers = answers\n .map((a) => {\n const selection =\n a.selected.length > 0\n ? a.selected.join(\", \")\n : a.customText || \"No selection\";\n return `${a.header}: ${selection}`;\n })\n .join(\"\\n\");\n\n return {\n context: {\n status: \"answered\",\n answers,\n summary: formattedAnswers,\n message: `User answered:\\n${formattedAnswers}`,\n },\n ui: {\n uri: \"ui://sdk/ask-user\",\n title: \"User Answers\",\n data: { questions: output.questions, answers },\n },\n };\n },\n },\n // Metadata for UI display\n metadata: {\n permissions: { risk: \"safe\" },\n describe: (ctx, req) => {\n const input = req.input as unknown as AskUserInput;\n if (req.status === \"running\") {\n return input.questions?.length === 1\n ? `Asking: ${input.questions[0]!.header}`\n : `Asking ${input.questions?.length || 0} questions`;\n }\n if (req.status === \"completed\") {\n const output = req.output as AskUserOutput;\n if (output?.answers) {\n return `Answered ${output.answers.length} question${output.answers.length !== 1 ? \"s\" : \"\"}`;\n }\n return \"Questions skipped\";\n }\n return undefined;\n },\n },\n});\n","/**\n * Think Tool\n *\n * Platform-level internal reasoning tool. No side effects.\n * The agent uses this to organize thoughts, reflect, and plan\n * before taking action. Hidden from conversation UI.\n */\n\nimport { Context } from \"@jarvis/types\";\n\nimport { tool } from \"./tools\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ThinkInput {\n thought: string;\n}\n\nexport interface ThinkOutput {\n acknowledged: boolean;\n}\n\n// =============================================================================\n// Schemas\n// =============================================================================\n\nconst thinkInputSchema = {\n type: \"object\" as const,\n properties: {\n thought: {\n type: \"string\",\n description: \"Your internal reasoning, reflection, or planning\",\n },\n },\n required: [\"thought\"],\n};\n\nconst thinkOutputSchema = {\n type: \"object\" as const,\n properties: {\n acknowledged: { type: \"boolean\" },\n },\n};\n\n// =============================================================================\n// Tool\n// =============================================================================\n\n/**\n * Internal reasoning tool — no side effects, hidden from UI.\n * Use for organizing thoughts before acting.\n */\nexport const thinkTool = tool({\n name: \"think\",\n description: `Use this tool for internal reasoning, reflection, and planning your next steps. No side effects — output is never shown to the user.\n\nGood uses:\n- Breaking down complex problems into steps\n- Evaluating trade-offs between approaches\n- Synthesizing information from multiple tool results\n- Planning multi-step operations before acting\n\nThis consumes tokens like any other tool call. Use for genuinely complex reasoning, not simple decisions.`,\n schema: {\n input: thinkInputSchema,\n output: thinkOutputSchema,\n },\n call: async (_ctx: Context, _input: ThinkInput) => ({ acknowledged: true }),\n metadata: { hidden: true },\n});\n","/**\n * Plan Mode Tools\n *\n * enterPlanMode / exitPlanMode — explicit plan-first mode.\n * When active, only non-destructive + safe tools are available.\n */\n\nimport type { AgentMode } from \"@jarvis/types\";\nimport { tool, after } from \"./tools\";\n\n// =============================================================================\n// enterPlanMode\n// =============================================================================\n\nexport const enterPlanModeTool = tool({\n name: \"enterPlanMode\",\n description: `Enter planning mode to research and design before taking action. Only non-destructive and safe tools are available until exitPlanMode is called.\n\nWhen to use:\n- Complex tasks with multiple steps or approaches\n- Ambiguous requirements needing exploration\n- Tasks where the user's preference between approaches matters\n- Unfamiliar domains requiring research first\n\nWhen NOT to use:\n- Simple, direct requests with clear intent\n- Follow-up actions on an already-agreed plan\n- Quick questions or lookups\n\nDecision rule: If you're unsure how to approach the task, enter plan mode. The cost of unnecessary planning is low; the cost of a wrong approach is high.`,\n schema: {\n input: { type: \"object\" as const, properties: {} },\n output: {\n type: \"object\" as const,\n properties: { mode: { type: \"string\" } },\n },\n },\n call: async () => ({ mode: \"plan\" as AgentMode }),\n hooks: {\n after: after<{ mode?: AgentMode; previousMode?: AgentMode }>(async (_ctx, _req) => ({\n context: {\n mode: \"plan\",\n message: `Plan mode is now active. Only non-destructive tools are available.\nYour next steps:\n1. Research the task using available tools\n2. Understand the current state and constraints\n3. Identify the best approach\n4. Draft a step-by-step plan\n5. Present the plan to the user\n6. Call exitPlanMode when the plan is approved`,\n },\n state: { mode: \"plan\" as AgentMode, previousMode: \"auto\" as AgentMode },\n })),\n },\n metadata: {\n label: \"Enter Plan Mode\",\n permissions: { risk: \"safe\" },\n },\n});\n\n// =============================================================================\n// exitPlanMode\n// =============================================================================\n\nexport const exitPlanModeTool = tool({\n name: \"exitPlanMode\",\n description: `Exit planning mode and signal the plan is ready for execution. All tools become available after exit.\n\nBefore calling this:\n- You should have researched and understood the task\n- You should have presented a clear plan to the user\n- The user should have had a chance to review or adjust\n\nAfter exit: Execute the plan step by step.`,\n schema: {\n input: { type: \"object\" as const, properties: {} },\n output: {\n type: \"object\" as const,\n properties: { mode: { type: \"string\" } },\n },\n },\n call: async () => ({ mode: \"auto\" as AgentMode }),\n hooks: {\n after: after<{ mode?: AgentMode; previousMode?: AgentMode }>(async (_ctx, _req) => ({\n context: {\n mode: \"auto\",\n message: \"Plan mode exited. All tools are now available. Execute the plan you presented, working through it step by step.\",\n },\n state: { mode: \"auto\" as AgentMode, previousMode: undefined },\n })),\n },\n metadata: {\n label: \"Exit Plan Mode\",\n permissions: { risk: \"safe\" },\n },\n});\n","/**\n * Agent Tool\n *\n * Tool for spawning a sub-agent of the current agent with a different task.\n * The sub-agent runs with the same agent config but can have filtered tools.\n */\n\nimport type { SubAgentRequest, SubAgentResponse, SubAgentFn } from \"./agent.tools.types\";\nimport { tool } from \"./tools\";\n\n// =============================================================================\n// agentTool — spawn a sub-agent of self\n// =============================================================================\n\n/**\n * Spawn a sub-agent with a task and optional tool filtering.\n *\n * @example\n * ```typescript\n * import { agentTool, buildTools } from \"@jarvis/sdk\";\n *\n * const tools = buildTools(ctx, {\n * tools: [agentTool, ...otherTools],\n * state: currentState,\n * }, {\n * spawnSubAgent: async (task, context, options) => {\n * return { message: \"Done\", success: true, requestCount: 0 };\n * },\n * });\n * ```\n */\nexport const agentTool = tool({\n name: \"agent\",\n description: `Spawn a sub-agent to handle a task independently.\n\nGuidelines:\n- Use filters.tools to restrict tools for focused tasks\n- Use model override for cost optimization: smaller model for simple tasks, larger for complex reasoning\n- Provide complete context in the task description — the sub-agent doesn't share your conversation history\n- After the sub-agent completes, synthesize its findings before acting — don't just pass through results`,\n schema: {\n input: {\n type: \"object\",\n properties: {\n task: {\n type: \"string\",\n description: \"The task to delegate. Be specific and include all relevant context.\",\n },\n context: {\n type: \"object\",\n description: \"Additional context to pass to the sub-agent\",\n },\n model: {\n type: \"string\",\n description:\n \"Override model ID for the sub-agent (e.g., 'claude-sonnet-4-20250514', 'gpt-4o')\",\n },\n filters: {\n type: \"object\",\n description: \"Filters for the sub-agent\",\n properties: {\n tools: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Restrict which tools the sub-agent can use (whitelist by tool name)\",\n },\n },\n },\n },\n required: [\"task\"],\n },\n output: {\n type: \"object\",\n properties: {\n message: { type: \"string\" },\n success: { type: \"boolean\" },\n requestCount: { type: \"number\" },\n ui: { type: \"object\" },\n },\n },\n },\n\n call: async (_ctx: unknown, input: unknown, options?: Record<string, unknown>) => {\n const { task, context, model, filters } = input as SubAgentRequest;\n const spawnSubAgent = options?.spawnSubAgent as SubAgentFn | undefined;\n if (!spawnSubAgent) {\n throw new Error(\"spawnSubAgent callback not provided via buildTools options\");\n }\n return spawnSubAgent(task, context, { model, filters });\n },\n\n hooks: {\n before: async (_ctx: unknown, req: { input: unknown }) => ({\n action: \"allow\" as const,\n input: req.input,\n }),\n after: async (_ctx: unknown, req: { input: unknown; output: unknown }) => {\n const output = req.output as SubAgentResponse;\n return {\n context: {\n message: output.message,\n success: output.success,\n requestCount: output.requestCount,\n },\n ui: output.ui,\n };\n },\n },\n});\n","/**\n * Skills Domain\n * Factory function for creating skills with collection and import methods.\n *\n * The skill() factory is both a creator and a namespace:\n * - skill({...}) — create a skill inline\n * - skill.add(s) — add a skill to the registry\n * - skill.list() — get all registered skills\n * - skill.get(id) — get a skill by ID\n */\n\nimport type { Skill, Prompt, SkillHooks } from \"@jarvis/types\";\n\nimport type { Tool } from \"@jarvis/types\"; // Used by SkillConfig\n\n// =============================================================================\n// skillHooks() Factory\n// =============================================================================\n\n/**\n * Create a skill hooks container (type-safe factory).\n * Mirrors the hooks() factory for tools.\n *\n * @example\n * ```typescript\n * import { skill, skillHooks } from \"@jarvis/sdk\";\n * import type { OrchestratorState } from \"./orchestrator.types\";\n *\n * const mySkill = skill({\n * id: \"my-skill\",\n * // ...\n * hooks: skillHooks<OrchestratorState>({\n * before: async (ctx, req, options) => ({\n * action: \"allow\",\n * messages: [{ role: \"system\", content: `State: ${JSON.stringify(ctx.state)}` }],\n * }),\n * after: async (ctx, req, options) => ({\n * context: { message: req.message },\n * state: req.skillState,\n * }),\n * }),\n * });\n * ```\n */\nexport function skillHooks<TState = unknown>(\n config: SkillHooks<TState>\n): SkillHooks<TState> {\n return config;\n}\n\n// =============================================================================\n// Internal Registry\n// =============================================================================\n\nconst registry = new Map<string, Skill>();\n\n// =============================================================================\n// skill() Factory + Namespace\n// =============================================================================\n\ninterface SkillConfig {\n id: string;\n name: string;\n description: string;\n prompt: Prompt;\n tools: Tool[];\n maxIterations?: number;\n version?: string;\n author?: string;\n tags?: string[];\n hooks?: SkillHooks<unknown>;\n}\n\n/**\n * Create a skill with typed configuration\n *\n * Skills are procedural knowledge - prompts and methodology that transform\n * general-purpose agents into specialists.\n *\n * @example\n * ```typescript\n * import { skill, tool, prompt } from \"@jarvis/sdk\";\n *\n * // Inline definition\n * export const codeReviewSkill = skill({\n * id: \"code-review\",\n * name: \"Code Review\",\n * description: \"Systematic code review\",\n * prompt: codeReviewPrompt,\n * tools: [analyzeCodeTool],\n * maxIterations: 5,\n * });\n *\n * // Import from directory\n * const analyticsSkill = await skill.fromDir(\"./skills/analytics\");\n *\n * // Add to registry\n * skill.add(codeReviewSkill);\n *\n * // Load (fromDir + add)\n * await skill.load(\"./skills/research\");\n *\n * // Query registry\n * skill.list(); // -> Skill[]\n * skill.get(\"code-review\"); // -> Skill | undefined\n * ```\n */\nfunction createSkill(config: SkillConfig): Skill {\n return {\n id: config.id,\n name: config.name,\n description: config.description,\n prompt: config.prompt,\n tools: config.tools,\n maxIterations: config.maxIterations,\n version: config.version,\n author: config.author,\n tags: config.tags,\n hooks: config.hooks,\n };\n}\n\n// =============================================================================\n// Collection Methods\n// =============================================================================\n\n/**\n * Add a skill to the internal registry.\n */\nfunction add(s: Skill): Skill {\n registry.set(s.id, s);\n return s;\n}\n\n/**\n * Get all registered skills.\n */\nfunction list(): Skill[] {\n return [...registry.values()];\n}\n\n/**\n * Get a registered skill by ID.\n */\nfunction get(id: string): Skill | undefined {\n return registry.get(id);\n}\n\n// =============================================================================\n// Export: skill as callable + namespace\n// =============================================================================\n\nexport const skill = Object.assign(createSkill, {\n add,\n list,\n get,\n});\n","/**\n * Mustache Renderer\n * Simple mustache-style template renderer for prompts\n */\n\nimport type {\n PromptRenderer,\n RenderPromptRequest,\n RenderPromptResponse,\n ValidatePromptRequest,\n ValidatePromptResponse,\n Message,\n} from \"@jarvis/types\";\n\n/**\n * Render a mustache template string with variables\n * Supports:\n * - Simple variables: {{variable}}\n * - Conditional sections: {{#variable}}content{{/variable}} - render if truthy\n * - Inverted sections: {{^variable}}content{{/variable}} - render if falsy\n */\nexport function renderTemplate(template: string, args: Record<string, unknown>): string {\n let result = template;\n\n // 1. Handle inverted sections {{^variable}}...{{/variable}} (render if falsy)\n result = result.replace(\n /\\{\\{\\^(\\w+)\\}\\}([\\s\\S]*?)\\{\\{\\/\\1\\}\\}/g,\n (_match, key, content) => {\n const value = args[key];\n // Render content if value is falsy or empty array/string\n if (!value || (Array.isArray(value) && value.length === 0) || value === \"\") {\n return renderTemplate(content, args);\n }\n return \"\";\n }\n );\n\n // 2. Handle conditional sections {{#variable}}...{{/variable}}\n result = result.replace(\n /\\{\\{#(\\w+)\\}\\}([\\s\\S]*?)\\{\\{\\/\\1\\}\\}/g,\n (_match, key, content) => {\n const value = args[key];\n // Skip if value is falsy or empty array/string\n if (!value || (Array.isArray(value) && value.length === 0) || value === \"\") {\n return \"\";\n }\n // Render content with variables substituted\n return renderTemplate(content, args);\n }\n );\n\n // 3. Handle simple variables {{variable}}\n result = result.replace(/\\{\\{(\\w+)\\}\\}/g, (_match, key) => {\n const value = args[key];\n if (value === undefined || value === null) {\n return \"\";\n }\n return String(value);\n });\n\n return result;\n}\n\n/**\n * Render a message with mustache variables\n */\nfunction renderMessage(message: Message, args: Record<string, unknown>): Message {\n const content = typeof message.content === \"string\"\n ? renderTemplate(message.content, args)\n : message.content ?? \"\";\n\n return {\n ...message,\n content,\n } as Message;\n}\n\n/**\n * Create a mustache renderer instance\n */\nexport function mustacheRenderer(): PromptRenderer {\n return {\n name: \"mustache\",\n\n async render(request: RenderPromptRequest): Promise<RenderPromptResponse> {\n const { prompt, args } = request;\n\n // If prompt has messages, render each message\n if (prompt.messages && prompt.messages.length > 0) {\n const messages = prompt.messages.map((msg) => renderMessage(msg, args));\n return {\n messages,\n output: prompt.output,\n metadata: {\n promptId: prompt.id,\n promptName: prompt.name,\n version: prompt.version || \"1.0.0\",\n provider: \"mustache\",\n },\n };\n }\n\n // If prompt has content, render as a single system message\n if (prompt.content) {\n const renderedContent = renderTemplate(prompt.content, args);\n return {\n messages: [{ role: \"system\", content: renderedContent }],\n output: prompt.output,\n metadata: {\n promptId: prompt.id,\n promptName: prompt.name,\n version: prompt.version || \"1.0.0\",\n provider: \"mustache\",\n },\n };\n }\n\n // No content to render\n return {\n messages: [],\n output: prompt.output,\n metadata: {\n promptId: prompt.id,\n promptName: prompt.name,\n version: prompt.version || \"1.0.0\",\n provider: \"mustache\",\n },\n };\n },\n\n async validate(request: ValidatePromptRequest): Promise<ValidatePromptResponse> {\n const { prompt, args } = request;\n\n // Check if all required variables are provided\n if (prompt.input && prompt.input.properties) {\n const required: string[] = Array.isArray(prompt.input.required)\n ? prompt.input.required\n : [];\n for (const key of required) {\n if (args[key] === undefined) {\n return {\n valid: false,\n message: `Missing required variable: ${key}`,\n };\n }\n }\n }\n\n return { valid: true };\n },\n };\n}\n\n/**\n * Default mustache renderer instance\n */\nexport const defaultMustacheRenderer = mustacheRenderer();\n","/**\n * Reference Factory\n *\n * Factory for defining reference types with metadata and creation logic.\n * Follows the same config pattern as entity(), resolver(), tool(), etc.\n *\n * @example\n * ```typescript\n * import { ref } from \"@jarvis/sdk\";\n * import type { DateReference } from \"@jarvis/types\";\n *\n * export const dateReference = ref<DateReference>({\n * type: \"date\",\n * label: \"Date\",\n * icon: \"calendar\",\n * color: \"purple\",\n * displayName: (input) => formatDateStr(input.date),\n * });\n *\n * // Usage:\n * const myDate = dateReference.create({ date: \"2024-01-01\" });\n * ```\n */\n\nimport type {\n Reference,\n ReferenceType,\n RefConfig,\n Ref,\n EntityReference,\n DateReference,\n DateRangeReference,\n FileReference,\n UrlReference,\n TextReference,\n ResolvedReference,\n Resolver,\n} from \"@jarvis/types\";\n\n// =============================================================================\n// Internal Helpers\n// =============================================================================\n\nfunction formatDateStr(date: string): string {\n return new Date(date).toLocaleDateString(undefined, {\n weekday: \"short\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\n/** Format a date for LLM context display */\nfunction formatDateOnly(dateStr: unknown): string {\n if (!dateStr) return \"N/A\";\n try {\n const d = new Date(dateStr as string);\n return d.toLocaleDateString(\"en-US\", {\n weekday: \"short\",\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n } catch {\n return String(dateStr);\n }\n}\n\n/** Fallback formatter — selective JSON (exclude noisy fields) */\nfunction formatGeneric(name: string, type: string, data: unknown): string {\n const lines = [`### ${type}: ${name}`];\n\n if (data && typeof data === \"object\") {\n const cleanData = { ...(data as Record<string, unknown>) };\n delete cleanData.id;\n delete cleanData.userId;\n delete cleanData.createdAt;\n delete cleanData.updatedAt;\n delete cleanData.deletedAt;\n\n lines.push(\"```json\");\n lines.push(JSON.stringify(cleanData, null, 2));\n lines.push(\"```\");\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n// =============================================================================\n// Factory\n// =============================================================================\n\n/**\n * Define a reference type with metadata and creation logic.\n *\n * Returns a Ref definition with `.create()` for instantiation\n * and metadata fields (label, icon, color, format) for UI/LLM use.\n */\nexport function ref<T extends Reference>(config: RefConfig<T>): Ref<T> {\n return {\n type: config.type,\n label: config.label,\n icon: config.icon,\n color: config.color,\n format: config.format,\n create: (input) => {\n const displayName =\n input.displayName || config.displayName?.(input) || \"\";\n return {\n id: Math.random().toString(36).substring(2, 10),\n type: config.type,\n displayName,\n createdAt: new Date().toISOString(),\n ...input,\n } as T;\n },\n };\n}\n\n// =============================================================================\n// Reference Definitions\n// =============================================================================\n\nexport const entityReference = ref<EntityReference>({\n type: \"entity\",\n label: \"Entity\",\n icon: \"box\",\n color: \"blue\",\n format: (displayName: string, data: unknown) => {\n const d = data as Record<string, unknown>;\n const lines = [`### Entity: ${displayName}`];\n if (d.id) lines.push(`- **Entity ID**: \\`${d.id}\\``);\n if (d.entityType) lines.push(`- **Entity Type**: ${d.entityType}`);\n\n const cleanData = { ...d };\n delete cleanData.id;\n delete cleanData.userId;\n delete cleanData.createdAt;\n delete cleanData.updatedAt;\n delete cleanData.deletedAt;\n delete cleanData.entityType;\n\n if (Object.keys(cleanData).length > 0) {\n lines.push(\"```json\");\n lines.push(JSON.stringify(cleanData, null, 2));\n lines.push(\"```\");\n }\n lines.push(\"\");\n return lines.join(\"\\n\");\n },\n});\n\nexport const dateReference = ref<DateReference>({\n type: \"date\",\n label: \"Date\",\n icon: \"calendar\",\n color: \"purple\",\n displayName: (input) => formatDateStr(input.date),\n format: (name: string, data: unknown) => {\n const d = data as Record<string, unknown>;\n const lines = [`### Date: ${name}`];\n\n if (d.date) lines.push(`- **Date**: ${formatDateOnly(d.date)}`);\n if (d.events && Array.isArray(d.events))\n lines.push(`- **Events on this date**: ${d.events.length}`);\n if (d.tasks && Array.isArray(d.tasks))\n lines.push(`- **Tasks due**: ${d.tasks.length}`);\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n },\n});\n\nexport const dateRangeReference = ref<DateRangeReference>({\n type: \"dateRange\",\n label: \"Date Range\",\n icon: \"calendar\",\n color: \"purple\",\n displayName: (input) =>\n `${formatDateStr(input.startDate)} - ${formatDateStr(input.endDate)}`,\n});\n\nexport const fileReference = ref<FileReference>({\n type: \"file\",\n label: \"File\",\n icon: \"file\",\n color: \"gray\",\n displayName: (input) => input.path.split(\"/\").pop() || input.path,\n});\n\nexport const urlReference = ref<UrlReference>({\n type: \"url\",\n label: \"URL\",\n icon: \"link\",\n color: \"cyan\",\n displayName: (input) => new URL(input.url).hostname,\n});\n\nexport const textReference = ref<TextReference>({\n type: \"text\",\n label: \"Text\",\n icon: \"text\",\n color: \"gray\",\n displayName: (input) =>\n input.content.length > 30\n ? input.content.slice(0, 30) + \"...\"\n : input.content,\n});\n\n// =============================================================================\n// Collection\n// =============================================================================\n\nconst allRefs: Ref<Reference>[] = [\n entityReference as Ref<Reference>,\n dateReference as Ref<Reference>,\n dateRangeReference as Ref<Reference>,\n fileReference as Ref<Reference>,\n urlReference as Ref<Reference>,\n textReference as Ref<Reference>,\n];\n\nexport const references = {\n // Definitions\n entity: entityReference,\n date: dateReference,\n dateRange: dateRangeReference,\n file: fileReference,\n url: urlReference,\n text: textReference,\n\n /** Format reference for display */\n format: (r: Reference): string => {\n const meta = references.get(r.type);\n return meta ? `[${meta.icon}] ${r.displayName}` : r.displayName;\n },\n\n /** List all ref definitions */\n list: (): Ref<Reference>[] => allRefs,\n\n /** Get ref definition by type */\n get: (type: ReferenceType): Ref<Reference> | undefined =>\n allRefs.find((r) => r.type === type),\n\n /**\n * Format resolved references for LLM context.\n * Priority: resolver format → ref definition format → generic JSON fallback.\n */\n \n formatResolved: (\n resolved: ResolvedReference[],\n resolverDefs?: Resolver<Reference, unknown>[],\n ): string => {\n if (resolved.length === 0) return \"\";\n\n const sections: string[] = [\"## Referenced Context\\n\"];\n\n for (const r of resolved) {\n if (!r.resolved || !r.data) {\n sections.push(\n `### ${r.reference.displayName} (${r.reference.type}) - NOT FOUND`,\n );\n sections.push(`> ${r.error || \"Could not resolve this reference\"}`);\n sections.push(\n \"*Ask the user how to proceed or if they want to select a different item.*\\n\",\n );\n continue;\n }\n\n // Priority 1: Resolver-level format (e.g. entity.format for entity resolvers)\n const entityType =\n r.reference.type === \"entity\"\n ? (r.reference as EntityReference).entityType\n : undefined;\n const def = resolverDefs?.find(\n (d) =>\n d.type === r.reference.type &&\n (!entityType || d.entityType === entityType),\n );\n\n if (def?.format) {\n sections.push(def.format(r.reference.displayName, r.data));\n continue;\n }\n\n // Priority 2: Ref definition format\n const refDef = references.get(r.reference.type);\n if (refDef?.format) {\n sections.push(refDef.format(r.reference.displayName, r.data));\n continue;\n }\n\n // Priority 3: Generic fallback\n sections.push(\n formatGeneric(r.reference.displayName, r.reference.type, r.data),\n );\n }\n\n return sections.join(\"\\n\");\n },\n};\n","/**\n * Table Factory, Field Helpers, and Index Helpers\n *\n * table<T>() creates a pure schema definition — no CRUD methods.\n * CRUD is handled by the DatabaseProvider directly:\n * db.find(ctx, { table: usersTable, filter: { email } })\n *\n * Every column is explicit — what you declare is what the DB gets.\n * No implicit system columns.\n */\n\nimport type { Table, TableConfig } from \"@jarvis/types\";\nimport type { FieldConfig, FieldType, IndexConfig, JsonFieldSchema } from \"@jarvis/types\";\n\n// =============================================================================\n// UTILITIES\n// =============================================================================\n\n/** Convert camelCase to snake_case */\nexport function toSnakeCase(str: string): string {\n return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);\n}\n\n// =============================================================================\n// table<T>() FACTORY — Pure schema definition\n// =============================================================================\n\n/**\n * Create a typed table schema definition.\n *\n * Returns a Table<T> with name, columns, indexes — no CRUD methods.\n * CRUD is handled by the DatabaseProvider.\n *\n * @example\n * ```typescript\n * import { table, field, index } from \"@jarvis/sdk\";\n *\n * export const usersTable = table<User>({\n * name: \"users\",\n * columns: {\n * id: field.uuid({ primary: true }),\n * userId: field.string({ required: true }),\n * email: field.string({ required: true, unique: true }),\n * name: field.string({ nullable: true }),\n * preferences: field.json({ default: {} }),\n * createdAt: field.timestamp({ auto: \"create\" }),\n * updatedAt: field.timestamp({ auto: \"update\" }),\n * },\n * });\n *\n * // Usage — CRUD via db provider:\n * const result = await db.find<User>(ctx, { table: usersTable, filter: { email } });\n * ```\n */\nexport function table<T = Record<string, unknown>>(\n config: TableConfig<T>,\n): Table<T> {\n if (!config.name) {\n throw new Error(\"Table must have a name\");\n }\n if (!/^[a-z][a-z0-9_]*$/.test(config.name)) {\n throw new Error(\n `Invalid table name \"${config.name}\". Must be lowercase with underscores.`,\n );\n }\n\n const columns = config.columns;\n const indexes = config.indexes ?? [];\n\n // Collect searchable field names\n const searchableFields: string[] = [];\n for (const [fname, fconfig] of Object.entries(columns)) {\n if (fconfig.searchable) {\n searchableFields.push(fname);\n }\n if (fconfig.type === \"json\" && fconfig.schema) {\n for (const [innerName, innerConfig] of Object.entries(fconfig.schema)) {\n if (innerConfig.searchable) {\n searchableFields.push(`${fname}.${innerName}`);\n }\n }\n }\n }\n\n return {\n kind: \"table\" as const,\n name: config.name,\n columns,\n indexes,\n access: config.access,\n searchableFields,\n } as Table<T>;\n}\n\n// =============================================================================\n// FIELD HELPERS\n// =============================================================================\n\n/**\n * Field helper functions for defining column types.\n *\n * @example\n * ```typescript\n * import { field } from \"@jarvis/sdk\";\n *\n * const columns = {\n * id: field.uuid({ primary: true }),\n * name: field.string({ required: true }),\n * email: field.string({ required: true, unique: true }),\n * age: field.integer({ default: 0 }),\n * isActive: field.boolean({ default: true }),\n * bio: field.text(),\n * metadata: field.json({ default: {} }),\n * createdAt: field.timestamp({ auto: \"create\" }),\n * updatedAt: field.timestamp({ auto: \"update\" }),\n * };\n * ```\n */\nexport const field = {\n string: (options?: {\n required?: boolean;\n nullable?: boolean;\n unique?: boolean;\n default?: string;\n searchable?: boolean;\n secret?: boolean;\n }): FieldConfig => ({\n type: \"string\" as FieldType,\n required: options?.required,\n nullable: options?.nullable,\n unique: options?.unique,\n default: options?.default,\n searchable: options?.searchable,\n secret: options?.secret,\n }),\n\n text: (options?: {\n required?: boolean;\n nullable?: boolean;\n default?: string;\n searchable?: boolean;\n }): FieldConfig => ({\n type: \"text\" as FieldType,\n required: options?.required,\n nullable: options?.nullable,\n default: options?.default,\n searchable: options?.searchable,\n }),\n\n integer: (options?: {\n required?: boolean;\n default?: number;\n unique?: boolean;\n }): FieldConfig => ({\n type: \"integer\" as FieldType,\n required: options?.required,\n default: options?.default,\n unique: options?.unique,\n }),\n\n boolean: (options?: { default?: boolean }): FieldConfig => ({\n type: \"boolean\" as FieldType,\n default: options?.default,\n }),\n\n timestamp: (options?: {\n required?: boolean;\n nullable?: boolean;\n default?: string | Date;\n auto?: \"create\" | \"update\";\n }): FieldConfig => ({\n type: \"timestamp\" as FieldType,\n required: options?.required,\n nullable: options?.nullable,\n default: options?.default,\n auto: options?.auto,\n }),\n\n json: <TJ = unknown>(options?: {\n default?: TJ;\n schema?: Record<string, JsonFieldSchema>;\n }): FieldConfig => ({\n type: \"json\" as FieldType,\n default: options?.default,\n schema: options?.schema,\n }),\n\n uuid: (options?: {\n primary?: boolean;\n required?: boolean;\n unique?: boolean;\n auto?: true;\n }): FieldConfig => ({\n type: \"uuid\" as FieldType,\n primary: options?.primary,\n required: options?.required,\n unique: options?.unique,\n auto: options?.auto,\n }),\n\n enum: (values: string[], options?: { default?: string }): FieldConfig => ({\n type: \"string\" as FieldType,\n default: options?.default ?? values[0],\n }),\n\n vector: (options?: { dimensions?: number }): FieldConfig => ({\n type: \"vector\" as FieldType,\n dimensions: options?.dimensions ?? 1536,\n }),\n\n number: (options?: {\n required?: boolean;\n nullable?: boolean;\n default?: number;\n unique?: boolean;\n }): FieldConfig => ({\n type: \"integer\" as FieldType,\n required: options?.required,\n nullable: options?.nullable,\n default: options?.default,\n unique: options?.unique,\n }),\n};\n\n// =============================================================================\n// INDEX HELPERS\n// =============================================================================\n\n/**\n * Create an index configuration\n *\n * @example\n * ```typescript\n * import { index } from \"@jarvis/sdk\";\n *\n * const indexes = [\n * index(\"goals_status_idx\", [\"userId\", \"status\"]),\n * index(\"goals_email_unique\", [\"email\"], { unique: true }),\n * ];\n * ```\n */\nexport function index(\n name: string,\n columns: string[],\n options?: { unique?: boolean },\n): IndexConfig {\n return {\n name,\n columns,\n unique: options?.unique,\n };\n}\n","/**\n * Connector Factory + Registry\n *\n * Provides the connector() factory for creating external service connector definitions,\n * and a registry for aggregating all platform connectors.\n *\n * Auth is handled by platform providers. Sync via Temporal workflows.\n */\n\nimport type {\n Connector,\n ConnectorConfig,\n ConnectorInstance,\n} from \"@jarvis/types\";\n\nimport { table, field, index } from \"./tables\";\n\n// =============================================================================\n// SHARED CONNECTORS TABLE\n// =============================================================================\n\n/** Shared connectors table — persistent storage for connection tracking */\nexport const connectorsTable = table<Connector>({\n name: \"connectors\",\n columns: {\n id: field.uuid({ primary: true }),\n userId: field.string({ required: true }),\n type: field.string({ required: true }),\n accountId: field.string(),\n displayName: field.string(),\n status: field.string({ default: \"disconnected\" }),\n lastSyncedAt: field.timestamp({ nullable: true }),\n syncState: field.json(),\n metadata: field.json(),\n createdAt: field.timestamp({ auto: \"create\" }),\n updatedAt: field.timestamp({ auto: \"update\" }),\n },\n indexes: [index(\"connectors_type_idx\", [\"userId\", \"type\"])],\n});\n\n// =============================================================================\n// CONNECTOR FACTORY\n// =============================================================================\n\n/**\n * Create an external service connector definition.\n *\n * Returns a ConnectorInstance with:\n * - .configure() — app-level sync config\n * - .connect() — initiate auth (OAuth redirect, API key store, token store)\n * - .exchangeCode() — OAuth callback code exchange\n * - .disconnect() — clear credentials\n *\n * @example\n * ```typescript\n * // Platform defines:\n * export const googleCalendarConnector = connector({\n * type: \"google_calendar\",\n * name: \"Google Calendar\",\n * auth: { type: \"oauth\", providerId: \"google\", scopes: [...] },\n * });\n *\n * // App configures sync:\n * export default googleCalendarConnector.configure({\n * sync: { pull: \"./workflows/pull.workflow\", cron: \"...\" },\n * });\n * ```\n */\nexport function connector(config: ConnectorConfig): ConnectorInstance {\n if (!config.type) throw new Error(\"Connector must have a type\");\n if (!config.name) throw new Error(\"Connector must have a name\");\n\n return {\n ...config,\n\n configure(configureConfig) {\n // Merge additional scopes with base auth if provided\n let auth = config.auth;\n if (configureConfig.auth?.scopes && auth?.type === \"oauth\") {\n const merged = [\n ...new Set([...auth.scopes, ...configureConfig.auth.scopes]),\n ];\n auth = { ...auth, scopes: merged };\n }\n\n return {\n type: config.type,\n name: configureConfig.name ?? config.name,\n icon: config.icon,\n color: config.color,\n description: configureConfig.description ?? config.description,\n version: config.version,\n sync: configureConfig.sync,\n auth,\n };\n },\n\n async connect(ctx, req, deps) {\n const auth = this.auth;\n\n // OAuth: return redirect URL\n if (auth?.type === \"oauth\" && auth.provider) {\n return {\n action: \"redirect\",\n ...auth.provider.buildAuthUrl(req.state ?? \"\"),\n };\n }\n\n // API key / token: validate + store credential\n if (\n (auth?.type === \"apiKey\" || auth?.type === \"token\") &&\n req.credential\n ) {\n if (auth.type === \"apiKey\" && \"validate\" in auth && auth.validate) {\n const error = await auth.validate(req.credential);\n if (error) return { action: \"error\", message: error };\n }\n\n await deps.secrets.set(ctx, {\n scope: config.type,\n type: auth.type,\n value: req.credential,\n });\n\n await deps.onConnect?.();\n return { action: \"connected\" };\n }\n\n return { action: \"error\", message: \"Unsupported auth type\" };\n },\n\n async exchangeCode(ctx, req, deps) {\n const auth = this.auth;\n if (auth?.type !== \"oauth\" || !auth.provider) {\n throw new Error(`${config.type}: no OAuth provider`);\n }\n\n const { tokens, profile, metadata } = await auth.provider.exchangeCode(\n req.code,\n req.codeVerifier,\n );\n\n const scope = auth.providerId ?? config.type;\n\n await deps.secrets.set(ctx, {\n scope,\n type: \"oauth\",\n value: {\n accessToken: tokens.accessToken,\n refreshToken: tokens.refreshToken ?? null,\n expiresAt: tokens.expiresAt\n ? new Date(tokens.expiresAt).toISOString()\n : null,\n tokenScope: tokens.scopes.join(\" \"),\n ...(tokens.extra ?? {}),\n },\n metadata: {\n accountId: profile?.accountId ?? null,\n displayName: profile?.displayName ?? null,\n },\n });\n\n await deps.onConnect?.({\n accountId: profile?.accountId,\n displayName: profile?.displayName,\n ...profile?.metadata,\n ...metadata,\n });\n },\n\n async disconnect(ctx, _req, deps) {\n const auth = this.auth;\n const scope =\n auth?.type === \"oauth\" ? (auth.providerId ?? config.type) : config.type;\n\n await deps.secrets.delete(ctx, { scope });\n await deps.onDisconnect?.();\n },\n };\n}\n\n// =============================================================================\n// CONNECTORS COLLECTION\n// =============================================================================\n\nconst all: ConnectorInstance[] = [];\n\nexport const connectors = {\n /** List all registered connectors */\n list: () => [...all],\n\n /** Find a connector by type */\n get: (type: string) => all.find((c) => c.type === type),\n\n /** Register a connector instance */\n add: (instance: ConnectorInstance) => {\n all.push(instance);\n },\n};\n","import { tool } from \"@jarvis/sdk\";\n\nexport interface EditToolInput {\n file_path: string;\n old_string: string;\n new_string: string;\n replace_all?: boolean;\n}\n\nexport const editTool = tool({\n name: \"Edit\",\n description: \"Edit file contents with string replacement\",\n schema: {\n input: {\n type: \"object\",\n properties: {\n file_path: { type: \"string\" },\n old_string: { type: \"string\" },\n new_string: { type: \"string\" },\n replace_all: { type: \"boolean\" },\n },\n },\n output: { type: \"object\" },\n },\n metadata: {\n label: \"Edit File\",\n provider: \"claude-code\",\n describe: (_ctx, req) => {\n const input = req.input as Partial<EditToolInput>;\n const fileName = input.file_path?.split(\"/\").pop() || \"file\";\n if (req.status === \"running\") return `Editing ${fileName}...`;\n if (req.status === \"completed\") return `Edited ${fileName}`;\n return `Failed to edit ${fileName}`;\n },\n },\n hooks: {\n before: async (_ctx, req, options) => {\n const input = req.input as EditToolInput;\n const response = await options.askUser({\n ui: {\n uri: \"ui://devenv/diff\",\n title: input.file_path,\n data: {\n filePath: input.file_path,\n oldString: input.old_string,\n newString: input.new_string,\n replaceAll: input.replace_all,\n },\n },\n });\n if (response?.action === \"deny\") {\n return { action: \"deny\", reason: response.feedback || \"User denied edit\" };\n }\n return { action: \"allow\" };\n },\n after: async (_ctx, req) => {\n const input = req.input as EditToolInput;\n return {\n context: { edited: input.file_path },\n ui: {\n uri: \"ui://devenv/diff\",\n title: input.file_path,\n data: {\n filePath: input.file_path,\n oldString: input.old_string,\n newString: input.new_string,\n replaceAll: input.replace_all,\n },\n },\n };\n },\n },\n});\n","import { tool } from \"@jarvis/sdk\";\n\nexport interface BashToolInput {\n command: string;\n description?: string;\n timeout?: number;\n}\n\nexport const bashTool = tool({\n name: \"Bash\",\n description: \"Execute a bash command\",\n schema: {\n input: {\n type: \"object\",\n properties: {\n command: { type: \"string\" },\n description: { type: \"string\" },\n timeout: { type: \"number\" },\n },\n },\n output: { type: \"object\" },\n },\n metadata: {\n label: \"Run Command\",\n provider: \"claude-code\",\n describe: (_ctx, req) => {\n const input = req.input as Partial<BashToolInput>;\n if (input.description) return input.description;\n const shortCmd =\n input.command && input.command.length > 50\n ? input.command.slice(0, 47) + \"...\"\n : input.command || \"command\";\n if (req.status === \"running\") return `Running: ${shortCmd}`;\n if (req.status === \"completed\") return `Ran: ${shortCmd}`;\n return `Failed: ${shortCmd}`;\n },\n },\n hooks: {\n before: async (_ctx, req, options) => {\n const input = req.input as BashToolInput;\n const response = await options.askUser({\n ui: {\n uri: \"ui://devenv/command\",\n title: input.description || input.command,\n data: { command: input.command, description: input.description },\n },\n });\n if (response?.action === \"deny\") {\n return { action: \"deny\", reason: response.feedback || \"User denied command\" };\n }\n return { action: \"allow\" };\n },\n after: async (_ctx, req) => {\n const input = req.input as BashToolInput;\n const output = req.output as { stdout?: string; stderr?: string; exitCode?: number } | string | undefined;\n const outputText = typeof output === \"string\"\n ? output\n : output\n ? [output.stdout, output.stderr].filter(Boolean).join(\"\\n\")\n : undefined;\n const exitCode = typeof output === \"object\" && output ? output.exitCode : undefined;\n return {\n context: { command: input.command, exitCode },\n ui: {\n uri: \"ui://devenv/command\",\n title: input.description || input.command,\n data: { command: input.command, description: input.description, output: outputText, exitCode },\n },\n };\n },\n },\n});\n","import { tool } from \"@jarvis/sdk\";\n\nexport interface WriteToolInput {\n file_path: string;\n content: string;\n}\n\nfunction detectLanguage(filePath: string): string | undefined {\n const ext = filePath.split(\".\").pop()?.toLowerCase();\n const langMap: Record<string, string> = {\n ts: \"typescript\", tsx: \"typescript\", js: \"javascript\", jsx: \"javascript\",\n py: \"python\", rs: \"rust\", go: \"go\", rb: \"ruby\", java: \"java\",\n css: \"css\", scss: \"scss\", html: \"html\", json: \"json\",\n yaml: \"yaml\", yml: \"yaml\", toml: \"toml\", xml: \"xml\",\n md: \"markdown\", sql: \"sql\", sh: \"shell\", bash: \"shell\",\n };\n return ext ? langMap[ext] : undefined;\n}\n\nexport const writeTool = tool({\n name: \"Write\",\n description: \"Write content to a file\",\n schema: {\n input: {\n type: \"object\",\n properties: {\n file_path: { type: \"string\" },\n content: { type: \"string\" },\n },\n },\n output: { type: \"object\" },\n },\n metadata: {\n label: \"Write File\",\n provider: \"claude-code\",\n describe: (_ctx, req) => {\n const input = req.input as Partial<WriteToolInput>;\n const fileName = input.file_path?.split(\"/\").pop() || \"file\";\n if (req.status === \"running\") return `Writing ${fileName}...`;\n if (req.status === \"completed\") return `Wrote ${fileName}`;\n return `Failed to write ${fileName}`;\n },\n },\n hooks: {\n before: async (_ctx, req, options) => {\n const input = req.input as WriteToolInput;\n const language = detectLanguage(input.file_path);\n const response = await options.askUser({\n ui: {\n uri: \"ui://devenv/file\",\n title: input.file_path,\n data: { filePath: input.file_path, content: input.content, language },\n },\n });\n if (response?.action === \"deny\") {\n return { action: \"deny\", reason: response.feedback || \"User denied write\" };\n }\n return { action: \"allow\" };\n },\n after: async (_ctx, req) => {\n const input = req.input as WriteToolInput;\n const language = detectLanguage(input.file_path);\n return {\n context: { wrote: input.file_path },\n ui: {\n uri: \"ui://devenv/file\",\n title: input.file_path,\n data: { filePath: input.file_path, content: input.content, language },\n },\n };\n },\n },\n});\n","import { tool } from \"@jarvis/sdk\";\n\nexport interface ReadToolInput {\n file_path: string;\n offset?: number;\n limit?: number;\n}\n\nfunction stripLineNumbers(text: string): string {\n return text.replace(/^\\s*\\d+[\\t→]/gm, \"\");\n}\n\nfunction detectLanguage(filePath: string): string | undefined {\n const ext = filePath.split(\".\").pop()?.toLowerCase();\n const langMap: Record<string, string> = {\n ts: \"typescript\", tsx: \"typescript\", js: \"javascript\", jsx: \"javascript\",\n py: \"python\", rs: \"rust\", go: \"go\", rb: \"ruby\", java: \"java\",\n css: \"css\", scss: \"scss\", html: \"html\", json: \"json\",\n yaml: \"yaml\", yml: \"yaml\", toml: \"toml\", xml: \"xml\",\n md: \"markdown\", sql: \"sql\", sh: \"shell\", bash: \"shell\",\n };\n return ext ? langMap[ext] : undefined;\n}\n\nexport const readTool = tool({\n name: \"Read\",\n description: \"Read file contents\",\n schema: {\n input: {\n type: \"object\",\n properties: {\n file_path: { type: \"string\" },\n offset: { type: \"number\" },\n limit: { type: \"number\" },\n },\n },\n output: { type: \"object\" },\n },\n metadata: {\n label: \"Read File\",\n provider: \"claude-code\",\n describe: (_ctx, req) => {\n const input = req.input as Partial<ReadToolInput>;\n const fileName = input.file_path?.split(\"/\").pop() || \"file\";\n if (req.status === \"running\") return `Reading ${fileName}...`;\n if (req.status === \"completed\") return `Read ${fileName}`;\n return `Failed to read ${fileName}`;\n },\n },\n hooks: {\n after: async (_ctx, req) => {\n const input = req.input as ReadToolInput;\n const language = detectLanguage(input.file_path);\n const rawOutput = typeof req.output === \"string\"\n ? req.output\n : JSON.stringify(req.output, null, 2);\n const content = stripLineNumbers(rawOutput);\n return {\n context: { read: input.file_path },\n ui: {\n uri: \"ui://devenv/file\",\n title: input.file_path,\n data: { filePath: input.file_path, content, language, startLine: (input.offset ?? 0) + 1 },\n },\n };\n },\n },\n});\n","import { tool } from \"@jarvis/sdk\";\n\nexport interface GlobToolInput {\n pattern: string;\n path?: string;\n}\n\nexport const globTool = tool({\n name: \"Glob\",\n description: \"Search for files by pattern\",\n schema: {\n input: {\n type: \"object\",\n properties: { pattern: { type: \"string\" }, path: { type: \"string\" } },\n },\n output: { type: \"object\" },\n },\n metadata: {\n label: \"Find Files\",\n provider: \"claude-code\",\n describe: (_ctx, req) => {\n const input = req.input as Partial<GlobToolInput>;\n const pattern = input.pattern || \"files\";\n if (req.status === \"running\") return `Finding ${pattern}...`;\n if (req.status === \"completed\") return `Found files matching ${pattern}`;\n return `Failed to find ${pattern}`;\n },\n },\n hooks: {\n after: async (_ctx, req) => {\n const input = req.input as GlobToolInput;\n const output = typeof req.output === \"string\" ? req.output : JSON.stringify(req.output, null, 2);\n return {\n context: { searched: input.pattern },\n ui: {\n uri: \"ui://devenv/command\",\n title: `Find: ${input.pattern}`,\n data: {\n command: `glob ${input.pattern}${input.path ? ` in ${input.path}` : \"\"}`,\n description: `Find files matching ${input.pattern}`,\n output,\n },\n },\n };\n },\n },\n});\n","import { tool } from \"@jarvis/sdk\";\n\nexport interface GrepToolInput {\n pattern: string;\n path?: string;\n glob?: string;\n output_mode?: string;\n}\n\nexport const grepTool = tool({\n name: \"Grep\",\n description: \"Search file contents by pattern\",\n schema: {\n input: {\n type: \"object\",\n properties: {\n pattern: { type: \"string\" },\n path: { type: \"string\" },\n glob: { type: \"string\" },\n output_mode: { type: \"string\" },\n },\n },\n output: { type: \"object\" },\n },\n metadata: {\n label: \"Search Code\",\n provider: \"claude-code\",\n describe: (_ctx, req) => {\n const input = req.input as Partial<GrepToolInput>;\n const pattern = input.pattern || \"\";\n if (req.status === \"running\") return `Searching for \"${pattern}\"...`;\n if (req.status === \"completed\") return `Searched for \"${pattern}\"`;\n return `Failed to search for \"${pattern}\"`;\n },\n },\n hooks: {\n after: async (_ctx, req) => {\n const input = req.input as GrepToolInput;\n const output = typeof req.output === \"string\" ? req.output : JSON.stringify(req.output, null, 2);\n return {\n context: { searched: input.pattern },\n ui: {\n uri: \"ui://devenv/command\",\n title: `Search: \"${input.pattern}\"`,\n data: {\n command: `grep \"${input.pattern}\"${input.path ? ` in ${input.path}` : \"\"}${input.glob ? ` (${input.glob})` : \"\"}`,\n description: `Search for \"${input.pattern}\"`,\n output,\n },\n },\n };\n },\n },\n});\n","export { editTool } from \"./edit.tool\";\nexport { bashTool } from \"./bash.tool\";\nexport { writeTool } from \"./write.tool\";\nexport { readTool } from \"./read.tool\";\nexport { globTool } from \"./glob.tool\";\nexport { grepTool } from \"./grep.tool\";\n\nimport { bashTool } from \"./bash.tool\";\nimport { editTool } from \"./edit.tool\";\nimport { globTool } from \"./glob.tool\";\nimport { grepTool } from \"./grep.tool\";\nimport { readTool } from \"./read.tool\";\nimport { writeTool } from \"./write.tool\";\n\n/** All Claude Code native tools with hooks */\nexport const claudeCodeTools = [editTool, bashTool, writeTool, readTool, globTool, grepTool];\n","/**\n * Tool Description Formatter\n *\n * Human-readable descriptions for tool calls in progress messages.\n */\n\nexport function formatToolDescription(toolName: string, input?: Record<string, unknown>): string {\n if (!input) return toolName;\n switch (toolName) {\n case \"Read\":\n return `Reading ${input.file_path || \"file\"}`;\n case \"Edit\":\n return `Editing ${input.file_path || \"file\"}`;\n case \"Write\":\n return `Writing to ${input.file_path || \"file\"}`;\n case \"Bash\":\n return typeof input.command === \"string\"\n ? input.command.length > 80\n ? input.command.slice(0, 80) + \"\\u2026\"\n : input.command\n : \"Running command\";\n case \"Glob\":\n return `Searching for ${input.pattern || \"files\"}`;\n case \"Grep\":\n return `Searching for \"${input.pattern || \"\"}\"`;\n default:\n return toolName;\n }\n}\n","/**\n * Git Worktree Utilities\n *\n * Per-task isolation using git worktrees in .jarvis/worktrees/.\n */\n\nimport { exec as execCb } from \"child_process\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { promisify } from \"util\";\n\nconst exec = promisify(execCb);\n\nconst WORKTREE_DIR = \".jarvis/worktrees\";\n\nexport async function createWorktree(\n repoPath: string,\n taskId: string,\n baseBranch?: string,\n): Promise<string> {\n const branchName = `jarvis/task-${taskId}`;\n const worktreeDir = path.join(repoPath, WORKTREE_DIR, `task-${taskId}`);\n\n await fs.mkdir(path.dirname(worktreeDir), { recursive: true });\n await ensureGitignore(repoPath);\n\n // Check if worktree already exists\n if (await worktreeExists(repoPath, taskId)) {\n return worktreeDir;\n }\n\n // Create worktree + branch from specified base or current HEAD\n const startPoint = baseBranch ?? \"HEAD\";\n await exec(`git worktree add -b \"${branchName}\" \"${worktreeDir}\" \"${startPoint}\"`, {\n cwd: repoPath,\n });\n\n return worktreeDir;\n}\n\nexport async function removeWorktree(repoPath: string, taskId: string): Promise<void> {\n const branchName = `jarvis/task-${taskId}`;\n const worktreeDir = path.join(repoPath, WORKTREE_DIR, `task-${taskId}`);\n\n try {\n await exec(`git worktree remove --force \"${worktreeDir}\"`, { cwd: repoPath });\n } catch {\n // Fallback: manual cleanup\n await fs.rm(worktreeDir, { recursive: true, force: true });\n await exec(\"git worktree prune\", { cwd: repoPath }).catch(() => {});\n }\n\n // Delete branch (force if unmerged)\n await exec(`git branch -D \"${branchName}\"`, { cwd: repoPath }).catch(() => {});\n}\n\nexport async function listWorktrees(\n repoPath: string,\n): Promise<Array<{ taskId: string; path: string; branch: string }>> {\n const { stdout } = await exec(\"git worktree list --porcelain\", { cwd: repoPath });\n const worktrees: Array<{ taskId: string; path: string; branch: string }> = [];\n\n let currentPath = \"\";\n let currentBranch = \"\";\n\n for (const line of stdout.split(\"\\n\")) {\n if (line.startsWith(\"worktree \")) {\n currentPath = line.slice(9);\n } else if (line.startsWith(\"branch refs/heads/\")) {\n currentBranch = line.slice(18);\n if (currentBranch.startsWith(\"jarvis/task-\")) {\n worktrees.push({\n taskId: currentBranch.replace(\"jarvis/task-\", \"\"),\n path: currentPath,\n branch: currentBranch,\n });\n }\n }\n }\n\n return worktrees;\n}\n\nexport async function worktreeExists(repoPath: string, taskId: string): Promise<boolean> {\n const worktreeDir = path.join(repoPath, WORKTREE_DIR, `task-${taskId}`);\n try {\n await fs.access(worktreeDir);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function ensureGitignore(repoPath: string): Promise<void> {\n const gitignorePath = path.join(repoPath, \".gitignore\");\n try {\n const content = await fs.readFile(gitignorePath, \"utf-8\");\n if (!content.includes(\".jarvis/\")) {\n await fs.appendFile(gitignorePath, \"\\n.jarvis/\\n\");\n }\n } catch {\n await fs.writeFile(gitignorePath, \".jarvis/\\n\");\n }\n}\n","/**\n * WS Progress Handlers\n *\n * Same logic as workflows/devenv/src/progress.ts but publishes\n * over WebSocket instead of Redis pub/sub + Temporal signals.\n *\n * The handleProgress() and handleUserInput() functions are identical\n * in behavior — only the transport (publish/signal → ws.send) changes.\n */\n\nimport crypto from \"crypto\";\n\nimport { formatToolDescription } from \"@jarvis/agent\";\nimport type {\n ChatMessage,\n PendingUserInput,\n ToolCallData,\n ToolUi,\n ToolUiData,\n UserInputResponse,\n} from \"@jarvis/types\";\n\nimport type { OutboundMessage } from \"./protocol\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface WsProgressHandlersDeps {\n /** Send a message to all connected clients (local + upstream) */\n broadcast: (msg: OutboundMessage) => void;\n /** Send input request and wait for user response */\n requestInput: (taskId: string, input: PendingUserInput) => Promise<UserInputResponse>;\n /** Task ID for message routing */\n taskId: string;\n /** Chat ID for usage events */\n chatId: string;\n}\n\nexport interface WsProgressHandlers {\n onMessage: (msg: ChatMessage) => Promise<void>;\n completeTools: () => Promise<void>;\n waitForInput: (pendingInput: PendingUserInput) => Promise<UserInputResponse>;\n handleUserInput: (input: PendingUserInput) => Promise<UserInputResponse>;\n handleProgress: (message: unknown) => Promise<void>;\n}\n\n// =============================================================================\n// Factory\n// =============================================================================\n\nexport function createWsProgressHandlers(deps: WsProgressHandlersDeps): WsProgressHandlers {\n const { broadcast, requestInput, taskId, chatId } = deps;\n const toolIds = new Map<string, string>();\n let currentThinkingId: string | null = null;\n let currentTextId: string | null = null;\n let currentTextContent = \"\";\n\n // ---------------------------------------------------------------------------\n // Transport: single WS broadcast replaces Redis pub/sub + Temporal signal\n // ---------------------------------------------------------------------------\n\n async function onMessage(msg: ChatMessage): Promise<void> {\n broadcast({ type: \"agent:onMessage\", taskId, message: msg });\n }\n\n // ---------------------------------------------------------------------------\n // Tool lifecycle\n // ---------------------------------------------------------------------------\n\n async function completeTools(): Promise<void> {\n const now = new Date().toISOString();\n for (const [toolId, toolName] of toolIds) {\n const msg: ChatMessage = {\n id: `tool-${toolId}`,\n role: \"assistant\",\n type: \"tool\",\n content: \"\",\n toolCall: { toolName, toolCallId: toolId, status: \"completed\" },\n isPartial: false,\n createdAt: now,\n };\n await onMessage(msg);\n }\n toolIds.clear();\n }\n\n // ---------------------------------------------------------------------------\n // User input (tool approval, plan review)\n // ---------------------------------------------------------------------------\n\n async function waitForInput(pendingInput: PendingUserInput): Promise<UserInputResponse> {\n return requestInput(taskId, pendingInput);\n }\n\n async function handleUserInput(input: PendingUserInput): Promise<UserInputResponse> {\n const toolName = input.toolName ?? \"\";\n const now = new Date().toISOString();\n\n if (toolName === \"askUser\") return waitForInput(input);\n\n if (toolName === \"ExitPlanMode\") {\n return waitForInput({\n ...input,\n type: \"plan\",\n reason: (input.input?.allowedPrompts as string) || \"Plan ready for review\",\n });\n }\n\n if (toolName === \"EnterPlanMode\") {\n await onMessage({\n id: `status-plan-${crypto.randomUUID()}`,\n role: \"assistant\",\n type: \"status\",\n content: \"Planning\",\n isPartial: true,\n createdAt: now,\n });\n return { action: \"allow\" };\n }\n\n if (toolName === \"TodoWrite\") {\n const todos =\n (input.input?.todos as Array<{ content: string; status: string; activeForm: string }>) ??\n [];\n await onMessage({\n id: \"todo-progress\",\n role: \"assistant\",\n type: \"status\",\n content: JSON.stringify({ type: \"todo\", todos }),\n isPartial: true,\n createdAt: now,\n });\n return { action: \"allow\" };\n }\n\n // Tools with UI artifact → forward for approval\n if (input.ui) return waitForInput(input);\n\n // All other tools → auto-approve\n return { action: \"allow\" };\n }\n\n // ---------------------------------------------------------------------------\n // SDK message → ChatMessage conversion (identical to devenv/progress.ts)\n // ---------------------------------------------------------------------------\n\n async function handleProgress(message: unknown): Promise<void> {\n const raw = message as {\n type?: string;\n message?: { content?: Array<Record<string, unknown>> };\n usage?: { input_tokens?: number; output_tokens?: number };\n model?: string;\n _toolUi?: Record<string, ToolUiData>;\n };\n if (!raw?.type) return;\n\n const now = new Date().toISOString();\n\n // --- Assistant messages: thinking, text, tool_use blocks ---\n if (raw.type === \"assistant\" && Array.isArray(raw.message?.content)) {\n for (const block of raw.message!.content) {\n // Thinking blocks — reuse stable ID within a turn\n if (block.type === \"thinking\" && block.thinking) {\n if (!currentThinkingId) currentThinkingId = `thinking-${crypto.randomUUID()}`;\n const msg: ChatMessage = {\n id: currentThinkingId,\n role: \"assistant\",\n type: \"thinking\",\n content: block.thinking as string,\n isPartial: true,\n createdAt: now,\n };\n await onMessage(msg);\n continue;\n }\n\n // Non-thinking block resets the thinking ID\n currentThinkingId = null;\n\n // Text blocks → stream as tokens with stable messageId\n if (block.type === \"text\" && block.text) {\n if (!currentTextId) currentTextId = `text-${crypto.randomUUID()}`;\n currentTextContent += block.text as string;\n\n // Broadcast incremental token event (content is accumulated snapshot)\n broadcast({\n type: \"agent:onToken\",\n taskId,\n messageId: currentTextId,\n content: currentTextContent,\n isComplete: false,\n });\n }\n\n // Tool use blocks — finalize any in-progress text stream first\n if (block.type === \"tool_use\" && block.id && block.name) {\n if (currentTextId) {\n broadcast({\n type: \"agent:onToken\",\n taskId,\n messageId: currentTextId,\n content: currentTextContent,\n isComplete: true,\n isFinal: false, // More content may follow after tool execution\n });\n currentTextId = null;\n currentTextContent = \"\";\n }\n const blockId = block.id as string;\n const blockName = block.name as string;\n toolIds.set(blockId, blockName);\n\n const toolCall: ToolCallData = {\n toolName: blockName,\n toolCallId: blockId,\n status: \"running\",\n input: block.input as Record<string, unknown>,\n };\n\n const msg: ChatMessage = {\n id: `tool-${blockId}`,\n role: \"assistant\",\n type: \"tool\",\n content: formatToolDescription(blockName, block.input as Record<string, unknown>),\n toolCall,\n isPartial: true,\n createdAt: now,\n };\n await onMessage(msg);\n }\n }\n }\n\n // Tool results reset thinking ID and finalize text stream\n currentThinkingId = null;\n if (currentTextId) {\n broadcast({\n type: \"agent:onToken\",\n taskId,\n messageId: currentTextId,\n content: currentTextContent,\n isComplete: true,\n });\n currentTextId = null;\n currentTextContent = \"\";\n }\n\n // --- User messages (tool results): mark tools completed ---\n if (raw.type === \"user\" && Array.isArray(raw.message?.content)) {\n for (const block of raw.message!.content) {\n if (!block.tool_use_id) continue;\n\n const toolUseId = block.tool_use_id as string;\n const output =\n typeof block.content === \"string\" ? block.content : JSON.stringify(block.content);\n const truncated = output && output.length > 1000 ? output.slice(0, 1000) + \"...\" : output;\n\n const toolUiData = raw._toolUi?.[toolUseId];\n const toolUi: ToolUi | undefined = toolUiData\n ? {\n uri: `ui://devenv/${toolUiData.type}`,\n title: toolUiData.title ?? \"\",\n data: toolUiData.data,\n }\n : undefined;\n\n const toolCall: ToolCallData = {\n toolName: toolIds.get(toolUseId) ?? \"\",\n toolCallId: toolUseId,\n status: block.is_error ? \"error\" : \"completed\",\n output: truncated,\n error: block.is_error ? (truncated ?? undefined) : undefined,\n };\n\n const msg: ChatMessage = {\n id: `tool-${toolUseId}`,\n role: \"assistant\",\n type: \"tool\",\n content: truncated ?? \"\",\n toolCall,\n ...(toolUi ? { ui: toolUi } : {}),\n isPartial: false,\n createdAt: now,\n };\n await onMessage(msg);\n toolIds.delete(toolUseId);\n }\n }\n\n // --- Result: complete remaining tools + publish usage ---\n if (raw.type === \"result\") {\n await completeTools();\n\n if (raw.usage) {\n const inputTokens = raw.usage.input_tokens ?? 0;\n const outputTokens = raw.usage.output_tokens ?? 0;\n broadcast({\n type: \"agent:onUsage\",\n taskId,\n chatId,\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n model: raw.model ?? \"unknown\",\n });\n }\n }\n }\n\n return { onMessage, completeTools, waitForInput, handleUserInput, handleProgress };\n}\n","/**\n * Agent Core\n *\n * Same execution logic as workflows/devenv/src/activities.ts\n * but without Temporal dependencies. Uses WS callbacks for progress.\n */\n\nimport { claudeCodeProvider } from \"@jarvis/anthropic\";\nimport { claudeCodeTools } from \"@jarvis/agent\";\nimport type {\n Context as AppContext,\n Message,\n PendingUserInput,\n UserInputResponse,\n} from \"@jarvis/types\";\n\nimport { createWsProgressHandlers } from \"./progress\";\nimport type { OutboundMessage, AgentDispatchMessage } from \"./protocol\";\n\nimport { logger } from \"@jarvis/logger\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface AgentDeps {\n workspacePath: string;\n anthropicApiKey?: string;\n useSubscription?: boolean;\n userId: string;\n broadcast: (msg: OutboundMessage) => void;\n requestInput: (taskId: string, input: PendingUserInput) => Promise<UserInputResponse>;\n}\n\n// =============================================================================\n// Factory\n// =============================================================================\n\nexport function createAgent(deps: AgentDeps) {\n const activeTasks = new Map<string, AbortController>();\n\n async function runTask(msg: AgentDispatchMessage): Promise<void> {\n const { taskId, chatId } = msg;\n const abortController = new AbortController();\n activeTasks.set(taskId, abortController);\n\n deps.broadcast({ type: \"agent:status\", status: \"busy\", taskId });\n\n const handlers = createWsProgressHandlers({\n broadcast: deps.broadcast,\n requestInput: deps.requestInput,\n taskId,\n chatId,\n });\n\n try {\n const wsPath = msg.worktreePath || deps.workspacePath;\n const systemMsg = msg.messages.find((m) => m.role === \"system\");\n const nonSystemMessages = msg.messages.filter((m) => m.role !== \"system\");\n\n logger.sys.info(\"[Agent] Running task\", {\n taskId,\n model: msg.model,\n worktreePath: wsPath,\n messageCount: msg.messages.length,\n });\n\n // Same claudeCodeProvider call as devenv activities.ts\n // Just different callbacks: WS broadcast instead of Redis/Temporal\n const provider = claudeCodeProvider({\n ...(deps.useSubscription ? { useSubscription: true } : { apiKey: deps.anthropicApiKey }),\n systemPrompt: (systemMsg?.content as string) ?? \"\",\n workingDirectory: wsPath,\n tools: claudeCodeTools,\n ...(msg.maxTurns ? { maxTurns: msg.maxTurns } : {}),\n userId: deps.userId,\n abortController,\n heartbeat: () => {}, // No Temporal heartbeat — WS ping/pong handles liveness\n onProgress: handlers.handleProgress,\n onUserInput: handlers.handleUserInput,\n permissionMode: msg.permissionMode === \"plan\" ? (\"plan\" as const) : (\"default\" as const),\n ...(msg.disallowedTools?.length ? { disallowedTools: msg.disallowedTools } : {}),\n ...(msg.session ? { session: msg.session } : {}),\n });\n\n const ctx = { requestId: taskId, userId: deps.userId } as AppContext;\n let response = await provider.query(ctx, {\n model: msg.model ?? \"claude-sonnet-4-20250514\",\n messages: nonSystemMessages as Message[],\n });\n\n // If resume failed, retry with fresh session (same as devenv activities)\n if (response.error && msg.session?.resume) {\n const resumeError = response.error.toLowerCase();\n if (\n resumeError.includes(\"session\") ||\n resumeError.includes(\"resume\") ||\n resumeError.includes(\"not found\")\n ) {\n logger.sys.warn(\"[Agent] Resume failed, retrying with fresh session\", {\n error: response.error,\n });\n const { resume: _, forkSession: __, ...fallbackSession } = msg.session;\n const fallbackProvider = claudeCodeProvider({\n ...(deps.useSubscription\n ? { useSubscription: true }\n : { apiKey: deps.anthropicApiKey }),\n workingDirectory: wsPath,\n tools: claudeCodeTools,\n ...(msg.maxTurns ? { maxTurns: msg.maxTurns } : {}),\n userId: deps.userId,\n abortController,\n heartbeat: () => {},\n onProgress: handlers.handleProgress,\n onUserInput: handlers.handleUserInput,\n ...(Object.keys(fallbackSession).length > 0 ? { session: fallbackSession } : {}),\n });\n response = await fallbackProvider.query(ctx, {\n model: msg.model ?? \"claude-sonnet-4-20250514\",\n messages: nonSystemMessages as Message[],\n });\n }\n }\n\n logger.sys.info(\"[Agent] Task completed\", {\n taskId,\n success: !response.error,\n sessionId: response.sessionId,\n });\n\n deps.broadcast({\n type: \"agent:output\",\n taskId,\n output: {\n success: !response.error,\n content: response.content ?? \"\",\n json: response.json,\n error: response.error,\n sessionId: response.sessionId,\n },\n });\n } catch (err) {\n if (abortController.signal.aborted) {\n logger.sys.info(\"[Agent] Task aborted\", { taskId });\n deps.broadcast({\n type: \"agent:output\",\n taskId,\n output: { success: false, content: \"\", error: \"Aborted\" },\n });\n } else {\n const error = err instanceof Error ? err.message : String(err);\n logger.sys.error(\"[Agent] Task failed\", { taskId, error });\n deps.broadcast({\n type: \"agent:output\",\n taskId,\n output: { success: false, content: \"\", error },\n });\n }\n } finally {\n activeTasks.delete(taskId);\n deps.broadcast({ type: \"agent:status\", status: \"idle\" });\n }\n }\n\n function cancelTask(taskId: string): void {\n const controller = activeTasks.get(taskId);\n if (controller) {\n logger.sys.info(\"[Agent] Cancelling task\", { taskId });\n controller.abort();\n }\n }\n\n function isRunning(taskId: string): boolean {\n return activeTasks.has(taskId);\n }\n\n function activeTaskCount(): number {\n return activeTasks.size;\n }\n\n return { runTask, cancelTask, isRunning, activeTaskCount };\n}\n\nexport type Agent = ReturnType<typeof createAgent>;\n","/**\n * Git Operations\n *\n * Handles git operations dispatched via WS (resolveRepo, createWorktree, commit, diffStats).\n * Same logic as workflows/devenv/src/activities.ts but without Temporal dependencies.\n */\n\nimport { exec as execCb } from \"child_process\";\nimport fs from \"fs/promises\";\nimport path from \"path\";\nimport { promisify } from \"util\";\n\nimport { createWorktree } from \"@jarvis/agent\";\nimport { logger } from \"@jarvis/logger\";\nimport type { InboundMessage, OutboundMessage } from \"@jarvis/types\";\n\nconst exec = promisify(execCb);\n\nexport function createGitHandler(\n workspacePath: string,\n broadcast: (msg: OutboundMessage) => void,\n) {\n async function handle(msg: InboundMessage): Promise<boolean> {\n switch (msg.type) {\n case \"git:resolveRepo\":\n await handleResolveRepo(msg);\n return true;\n case \"git:createWorktree\":\n await handleCreateWorktree(msg);\n return true;\n case \"git:commit\":\n await handleCommit(msg);\n return true;\n case \"git:diffStats\":\n await handleDiffStats(msg);\n return true;\n default:\n return false;\n }\n }\n\n function respond(requestId: string, result: unknown, error?: string) {\n broadcast({ type: \"git:response\", requestId, result, error });\n }\n\n async function handleResolveRepo(msg: Extract<InboundMessage, { type: \"git:resolveRepo\" }>) {\n try {\n const repoDir = path.join(workspacePath, msg.owner, msg.name);\n\n const isCloned = await fs\n .access(path.join(repoDir, \".git\"))\n .then(() => true)\n .catch(() => false);\n\n if (!isCloned) {\n logger.sys.info(\"[Git] Cloning repo...\", { repoDir });\n await fs.mkdir(path.join(workspacePath, msg.owner), { recursive: true });\n const cloneUrl = `git@github.com:${msg.owner}/${msg.name}.git`;\n await exec(`git clone \"${cloneUrl}\" \"${repoDir}\"`, { timeout: 300000 });\n }\n\n await exec(\"git fetch origin\", { cwd: repoDir, timeout: 120000 });\n\n try {\n await exec(`git checkout \"${msg.branch}\"`, { cwd: repoDir });\n } catch {\n await exec(`git checkout -b \"${msg.branch}\" \"origin/${msg.branch}\"`, { cwd: repoDir });\n }\n\n await exec(\"git pull --ff-only\", { cwd: repoDir }).catch(() => {});\n\n logger.sys.info(\"[Git] Repo resolved\", { repoDir, branch: msg.branch });\n respond(msg.requestId, { repoPath: repoDir });\n } catch (err) {\n respond(msg.requestId, null, err instanceof Error ? err.message : String(err));\n }\n }\n\n async function handleCreateWorktree(msg: Extract<InboundMessage, { type: \"git:createWorktree\" }>) {\n try {\n const worktreePath = await createWorktree(msg.repoPath, msg.taskId, msg.branch);\n respond(msg.requestId, { worktreePath, branchName: `jarvis/task-${msg.taskId}` });\n } catch (err) {\n respond(msg.requestId, null, err instanceof Error ? err.message : String(err));\n }\n }\n\n async function handleCommit(msg: Extract<InboundMessage, { type: \"git:commit\" }>) {\n try {\n const cwd = msg.worktreePath;\n await exec(\"git add -A\", { cwd });\n const { stdout: status } = await exec(\"git status --porcelain\", { cwd });\n if (!status.trim()) {\n respond(msg.requestId, { success: true, output: \"Nothing to commit\" });\n return;\n }\n const title = msg.title.replace(/\"/g, '\\\\\"');\n const { stdout } = await exec(`git commit -m \"jarvis: ${title}\"`, { cwd });\n respond(msg.requestId, { success: true, output: stdout });\n } catch (err) {\n respond(msg.requestId, { success: false, output: \"\", error: err instanceof Error ? err.message : String(err) });\n }\n }\n\n async function handleDiffStats(msg: Extract<InboundMessage, { type: \"git:diffStats\" }>) {\n try {\n const cwd = msg.worktreePath;\n const { stdout } = await exec(\"git diff --numstat HEAD~1\", { cwd });\n const files: Array<{ file: string; additions: number; deletions: number }> = [];\n let totalAdditions = 0;\n let totalDeletions = 0;\n\n for (const line of stdout.trim().split(\"\\n\")) {\n if (!line.trim()) continue;\n const [add, del, file] = line.split(\"\\t\");\n const additions = add === \"-\" ? 0 : parseInt(add, 10) || 0;\n const deletions = del === \"-\" ? 0 : parseInt(del, 10) || 0;\n files.push({ file, additions, deletions });\n totalAdditions += additions;\n totalDeletions += deletions;\n }\n\n respond(msg.requestId, { files, additions: totalAdditions, deletions: totalDeletions });\n } catch {\n respond(msg.requestId, { files: [], additions: 0, deletions: 0 });\n }\n }\n\n return { handle };\n}\n","/**\n * Local WS Server\n *\n * Listens on 127.0.0.1 only — for VSCode extension and CLI clients.\n * No auth needed (localhost-only, same user).\n *\n * Supports multiple concurrent clients (TUI, VSCode, web — all receive broadcasts).\n */\n\nimport { WebSocketServer, WebSocket } from \"ws\";\n\nimport type { InboundMessage, OutboundMessage } from \"./protocol\";\n\n/**\n * Check if the agent port is already in use (another agent is running).\n */\nexport async function isPortInUse(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const ws = new WebSocket(`ws://127.0.0.1:${port}`);\n const timeout = setTimeout(() => {\n ws.close();\n resolve(false);\n }, 1000);\n\n ws.on(\"open\", () => {\n clearTimeout(timeout);\n ws.send(JSON.stringify({ type: \"ping\" }));\n ws.on(\"message\", () => {\n ws.close();\n resolve(true);\n });\n });\n\n ws.on(\"error\", () => {\n clearTimeout(timeout);\n resolve(false);\n });\n });\n}\n\nexport function createLocalServer(port: number) {\n const clients = new Set<WebSocket>();\n const wss = new WebSocketServer({ host: \"127.0.0.1\", port });\n\n // Handle port already in use\n wss.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n console.error(\n `\\nError: Port ${port} is already in use.` +\n `\\nAnother Jarvis agent is already running on this port.` +\n `\\nClients (jarvis chat, VSCode) can connect to the existing agent.` +\n `\\nTo use a different port: jarvis start --port <port>\\n`,\n );\n process.exit(1);\n }\n throw err;\n });\n\n wss.on(\"connection\", (ws) => {\n clients.add(ws);\n ws.on(\"close\", () => clients.delete(ws));\n ws.on(\"error\", () => clients.delete(ws));\n });\n\n /** Broadcast an outbound message to all connected local clients */\n function broadcast(msg: OutboundMessage): void {\n const data = JSON.stringify(msg);\n for (const ws of clients) {\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(data);\n }\n }\n }\n\n /** Register a handler for inbound messages from local clients */\n function onMessage(handler: (msg: InboundMessage, ws: WebSocket) => void): void {\n wss.on(\"connection\", (ws) => {\n ws.on(\"message\", (raw) => {\n try {\n const msg = JSON.parse(raw.toString()) as InboundMessage;\n if (msg.type === \"ping\") {\n ws.send(JSON.stringify({ type: \"pong\" }));\n return;\n }\n handler(msg, ws);\n } catch {\n // Ignore malformed messages\n }\n });\n });\n }\n\n /** Number of connected clients */\n function clientCount(): number {\n return clients.size;\n }\n\n function close(): void {\n for (const ws of clients) ws.close();\n wss.close();\n }\n\n return { broadcast, onMessage, clientCount, close };\n}\n","/**\n * Upstream WS Client\n *\n * Connects to the cloud API so web/mobile can dispatch tasks\n * and receive progress from this local agent.\n */\n\nimport WebSocket from \"ws\";\n\nimport { logger } from \"@jarvis/logger\";\n\nimport type { InboundMessage, OutboundMessage } from \"./protocol\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface UpstreamConfig {\n apiUrl: string;\n token: string;\n}\n\n// =============================================================================\n// Client\n// =============================================================================\n\nexport function createUpstreamClient(config: UpstreamConfig) {\n let ws: WebSocket | null = null;\n let messageHandler: ((msg: InboundMessage) => void) | null = null;\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n let closed = false;\n\n function connect(): void {\n if (closed) return;\n\n ws = new WebSocket(config.apiUrl, {\n headers: { authorization: `Bearer ${config.token}` },\n });\n\n ws.on(\"open\", () => {\n logger.sys.info(\"[Upstream] Connected to cloud\", { apiUrl: config.apiUrl });\n });\n\n ws.on(\"message\", (raw) => {\n try {\n const msg = JSON.parse(raw.toString()) as InboundMessage;\n if (msg.type === \"ping\") {\n ws?.send(JSON.stringify({ type: \"pong\" }));\n return;\n }\n messageHandler?.(msg);\n } catch {\n // Ignore malformed messages\n }\n });\n\n ws.on(\"close\", () => {\n if (!closed) {\n logger.sys.info(\"[Upstream] Disconnected, reconnecting in 3s...\");\n reconnectTimer = setTimeout(connect, 3000);\n }\n });\n\n ws.on(\"error\", (err) => {\n logger.sys.error(\"[Upstream] Connection error\", {\n error: err.message,\n });\n });\n }\n\n function send(msg: OutboundMessage): void {\n if (ws?.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(msg));\n }\n }\n\n function onMessage(handler: (msg: InboundMessage) => void): void {\n messageHandler = handler;\n }\n\n function isConnected(): boolean {\n return ws?.readyState === WebSocket.OPEN;\n }\n\n function close(): void {\n closed = true;\n if (reconnectTimer) clearTimeout(reconnectTimer);\n ws?.close();\n }\n\n return { connect, send, onMessage, isConnected, close };\n}\n\nexport type UpstreamClient = ReturnType<typeof createUpstreamClient>;\n","/**\n * Agent Start\n *\n * Pure WS agent — no Temporal on the user's machine.\n *\n * 1. Local WS server (VSCode/CLI clients connect here)\n * 2. Upstream WS client (cloud hub — receives dispatches from Temporal workflow)\n * 3. Runs Claude Code locally, streams progress via WS\n *\n * The Temporal workflow dispatches to this agent through the WS hub.\n * Temporal stays in the cloud as source of truth for session state.\n */\n\nimport type { InboundMessage, OutboundMessage, UserInputResponse } from \"@jarvis/types\";\n\nimport { createAgent } from \"./agent\";\nimport { createGitHandler } from \"./git\";\nimport { createLocalServer } from \"./server\";\nimport { createUpstreamClient, type UpstreamConfig } from \"./upstream\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface StartAgentOptions {\n port: number;\n workspacePath: string;\n anthropicApiKey?: string;\n useSubscription?: boolean;\n userId: string;\n upstream?: UpstreamConfig;\n}\n\n// =============================================================================\n// Start\n// =============================================================================\n\nexport async function startAgent(options: StartAgentOptions): Promise<void> {\n // Pending input requests: inputId → resolve function\n const pendingInputs = new Map<string, (response: UserInputResponse) => void>();\n\n // --- Local WS server (VSCode, CLI) ---\n const server = createLocalServer(options.port);\n\n // --- Upstream WS client (cloud — optional) ---\n const upstream = options.upstream ? createUpstreamClient(options.upstream) : null;\n\n // --- Broadcast to ALL clients (local + upstream) ---\n function broadcast(msg: OutboundMessage): void {\n server.broadcast(msg);\n upstream?.send(msg);\n }\n\n // --- Input request/response flow ---\n function requestInput(taskId: string, input: import(\"@jarvis/types\").PendingUserInput): Promise<UserInputResponse> {\n return new Promise((resolve) => {\n pendingInputs.set(input.id, resolve);\n broadcast({ type: \"agent:onUserInputRequest\", taskId, input });\n });\n }\n\n // --- Git handler ---\n const git = createGitHandler(options.workspacePath, broadcast);\n\n // --- Create the agent ---\n const agent = createAgent({\n workspacePath: options.workspacePath,\n anthropicApiKey: options.anthropicApiKey,\n useSubscription: options.useSubscription,\n userId: options.userId,\n broadcast,\n requestInput,\n });\n\n // --- Handle inbound messages (from any source — local or upstream) ---\n function handleMessage(msg: InboundMessage): void {\n // Try git operations first\n if (msg.type.startsWith(\"git:\")) {\n git.handle(msg);\n return;\n }\n\n switch (msg.type) {\n case \"agent:dispatch\":\n agent.runTask(msg);\n break;\n\n case \"agent:abort\":\n agent.cancelTask(msg.taskId);\n break;\n\n case \"agent:userInput\": {\n const response: UserInputResponse = {\n action: msg.action as UserInputResponse[\"action\"],\n data: msg.data,\n feedback: msg.feedback,\n };\n const resolve = pendingInputs.get(msg.inputId);\n if (resolve) {\n resolve(response);\n pendingInputs.delete(msg.inputId);\n }\n break;\n }\n\n case \"ping\":\n // Handled at transport level\n break;\n }\n }\n\n // Wire up message handlers\n server.onMessage((msg) => handleMessage(msg));\n upstream?.onMessage(handleMessage);\n\n // Connect upstream if configured\n upstream?.connect();\n\n // --- Status output ---\n console.log();\n console.log(`Jarvis Agent v0.0.0`);\n console.log(` Local: ws://127.0.0.1:${options.port}`);\n console.log(` Workspace: ${options.workspacePath}`);\n console.log(` User: ${options.userId}`);\n if (upstream) {\n console.log(` Cloud: ${options.upstream!.apiUrl}`);\n }\n console.log();\n console.log(\"Waiting for tasks...\");\n console.log();\n\n // --- Graceful shutdown ---\n const shutdown = () => {\n console.log(\"\\nShutting down...\");\n server.close();\n upstream?.close();\n process.exit(0);\n };\n\n process.on(\"SIGTERM\", shutdown);\n process.on(\"SIGINT\", shutdown);\n}\n","/**\n * Chat Entry Point\n *\n * Launches the interactive TUI:\n * 1. Load settings (file + CLI flags)\n * 2. Auto-start agent server as a detached child process (silent)\n * 3. Render Ink app — owns stdout/stderr exclusively\n */\n\nimport React from \"react\";\nimport { render } from \"ink\";\nimport { spawn, type ChildProcess } from \"child_process\";\nimport { fileURLToPath } from \"url\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport os from \"os\";\nimport WebSocket from \"ws\";\n\nimport { loadSettings, mergeCliFlags, type TuiSettings } from \"./settings\";\nimport { loadConfig } from \"../config\";\nimport { App } from \"./app\";\n\n/** Agent child process — killed on TUI exit */\nlet agentChild: ChildProcess | null = null;\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ChatOptions {\n model?: string;\n mode?: string;\n thinking?: string;\n thinkingBudget?: string;\n maxTurns?: string;\n port: string;\n server: boolean; // --no-server sets to false\n workspace?: string;\n}\n\n// =============================================================================\n// Launch\n// =============================================================================\n\nexport async function launchChat(opts: ChatOptions): Promise<void> {\n const port = parseInt(opts.port, 10);\n const config = loadConfig();\n\n // Load and merge settings\n const fileSettings = loadSettings();\n const settings: TuiSettings = mergeCliFlags(fileSettings, {\n model: opts.model,\n mode: opts.mode,\n thinking: opts.thinking,\n thinkingBudget: opts.thinkingBudget,\n maxTurns: opts.maxTurns,\n });\n\n const workspacePath = opts.workspace ?? config?.workspacePath ?? process.cwd();\n\n // Auto-start agent server if --no-server wasn't passed\n let weSpawnedAgent = false;\n if (opts.server) {\n const isRunning = await checkAgentRunning(port);\n if (!isRunning) {\n spawnAgentProcess(port, workspacePath);\n weSpawnedAgent = true;\n await waitForAgent(port);\n }\n }\n\n // Kill agent on exit if we spawned it\n const cleanup = () => {\n if (weSpawnedAgent && agentChild && !agentChild.killed) {\n agentChild.kill(\"SIGTERM\");\n agentChild = null;\n }\n };\n\n process.on(\"exit\", cleanup);\n process.on(\"SIGINT\", () => {\n cleanup();\n process.exit(0);\n });\n process.on(\"SIGTERM\", () => {\n cleanup();\n process.exit(0);\n });\n process.on(\"SIGHUP\", () => {\n cleanup();\n process.exit(0);\n });\n\n // Render the TUI — Ink owns stdout/stderr from here\n const { waitUntilExit } = render(\n React.createElement(App, {\n initialSettings: settings,\n port,\n workspacePath,\n }),\n );\n\n await waitUntilExit();\n cleanup();\n}\n\n// =============================================================================\n// Agent Process (child, killed on TUI exit)\n// =============================================================================\n\n/**\n * Spawn `jarvis start` as a child process.\n * stdout/stderr → ~/.jarvis/agent.log (TUI owns the terminal).\n * NOT detached — dies when the TUI process exits.\n */\nfunction spawnAgentProcess(port: number, workspacePath: string): void {\n const config = loadConfig();\n\n // Log file for agent output\n const logDir = path.join(os.homedir(), \".jarvis\");\n fs.mkdirSync(logDir, { recursive: true });\n const logFile = path.join(logDir, \"agent.log\");\n const logFd = fs.openSync(logFile, \"a\");\n\n // Find the bin entry point (same binary the user invoked)\n const __filename = fileURLToPath(import.meta.url);\n const cliRoot = path.resolve(path.dirname(__filename), \"../..\");\n const binPath = path.join(cliRoot, \"bin\", \"jarvis.mjs\");\n\n // Build args for `jarvis start`\n const args = [\"start\", \"--port\", String(port), \"--workspace\", workspacePath];\n\n if (config?.apiUrl && config?.token) {\n // upstream is auto-detected from config\n } else {\n args.push(\"--no-upstream\");\n }\n\n const apiKey = config?.anthropicApiKey ?? process.env.ANTHROPIC_API_KEY;\n if (apiKey) {\n args.push(\"--api-key\", apiKey);\n }\n\n agentChild = spawn(process.execPath, [binPath, ...args], {\n stdio: [\"ignore\", logFd, logFd],\n cwd: workspacePath,\n env: { ...process.env },\n });\n\n fs.closeSync(logFd);\n}\n\n// =============================================================================\n// Agent Health Check\n// =============================================================================\n\nasync function checkAgentRunning(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n const ws = new WebSocket(`ws://127.0.0.1:${port}`);\n const timeout = setTimeout(() => {\n ws.close();\n resolve(false);\n }, 1000);\n\n ws.on(\"open\", () => {\n clearTimeout(timeout);\n ws.send(JSON.stringify({ type: \"ping\" }));\n ws.on(\"message\", () => {\n ws.close();\n resolve(true);\n });\n });\n\n ws.on(\"error\", () => {\n clearTimeout(timeout);\n resolve(false);\n });\n } catch {\n resolve(false);\n }\n });\n}\n\nasync function waitForAgent(port: number, maxAttempts = 30): Promise<void> {\n for (let i = 0; i < maxAttempts; i++) {\n const running = await checkAgentRunning(port);\n if (running) return;\n await new Promise((r) => setTimeout(r, 250));\n }\n // Don't console.log here — TUI will show connection status in status bar\n}\n","/**\n * TUI Settings\n *\n * Load/save/merge ~/.jarvis/settings.json — user preferences for the TUI.\n * These are TUI-local and applied per agent:dispatch message.\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\n\nimport type { ThinkingConfig } from \"@jarvis/types\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type PermissionMode = \"supervised\" | \"auto\" | \"plan\" | \"yolo\";\n\nexport interface TuiSettings {\n model: string;\n thinking: ThinkingConfig;\n permissionMode: PermissionMode;\n maxTurns: number;\n theme: \"dark\" | \"light\";\n disallowedTools: string[];\n}\n\n// =============================================================================\n// Defaults\n// =============================================================================\n\nexport const DEFAULT_SETTINGS: TuiSettings = {\n model: \"claude-sonnet-4-20250514\",\n thinking: { type: \"adaptive\" },\n permissionMode: \"supervised\",\n maxTurns: 25,\n theme: \"dark\",\n disallowedTools: [],\n};\n\n// =============================================================================\n// Paths\n// =============================================================================\n\nconst SETTINGS_DIR = path.join(os.homedir(), \".jarvis\");\nconst SETTINGS_FILE = path.join(SETTINGS_DIR, \"settings.json\");\n\n// =============================================================================\n// Operations\n// =============================================================================\n\nexport function loadSettings(): TuiSettings {\n try {\n const raw = fs.readFileSync(SETTINGS_FILE, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<TuiSettings>;\n return { ...DEFAULT_SETTINGS, ...parsed };\n } catch {\n return { ...DEFAULT_SETTINGS };\n }\n}\n\nexport function saveSettings(settings: TuiSettings): void {\n fs.mkdirSync(SETTINGS_DIR, { recursive: true });\n fs.writeFileSync(SETTINGS_FILE, JSON.stringify(settings, null, 2) + \"\\n\");\n}\n\n/**\n * Merge CLI flags into loaded settings.\n * Only non-undefined flags override.\n */\nexport function mergeCliFlags(\n settings: TuiSettings,\n flags: {\n model?: string;\n mode?: string;\n thinking?: string;\n thinkingBudget?: string;\n maxTurns?: string;\n },\n): TuiSettings {\n const merged = { ...settings };\n\n if (flags.model) merged.model = flags.model;\n if (flags.mode) merged.permissionMode = flags.mode as PermissionMode;\n if (flags.maxTurns) merged.maxTurns = parseInt(flags.maxTurns, 10);\n\n if (flags.thinking) {\n const type = flags.thinking as ThinkingConfig[\"type\"];\n merged.thinking = { type };\n if (type === \"enabled\" && flags.thinkingBudget) {\n merged.thinking.budgetTokens = parseInt(flags.thinkingBudget, 10);\n }\n }\n\n return merged;\n}\n\nexport function getSettingsPath(): string {\n return SETTINGS_FILE;\n}\n","/**\n * Jarvis TUI App\n *\n * Rendering strategy — zero dynamic content above the input bar:\n * - ALL messages go into <Static> (rendered once, never re-rendered)\n * - Streaming text is committed to <Static> only when finalized\n * - The ONLY dynamic elements are: spinner + overlays + input bar + footer\n * - This eliminates all jumpiness during streaming\n */\n\nimport React, { useState, useCallback, useRef, useEffect } from \"react\";\nimport { Box, Static, Text, useApp, useInput } from \"ink\";\n\nimport type { OutboundMessage, AgentOnTokenEvent } from \"@jarvis/types\";\n\nimport type { TuiSettings } from \"./settings\";\nimport { useAgentClient } from \"./hooks/use-agent-client\";\nimport { useMessages, type DisplayMessage } from \"./hooks/use-messages\";\nimport { useTask } from \"./hooks/use-task\";\nimport { useSettings } from \"./hooks/use-settings\";\nimport { parseSlashCommand } from \"./utils/slash-commands\";\nimport { shouldAutoApprove } from \"./utils/auto-approve\";\n\nimport { WelcomeHeader } from \"./components/welcome-header\";\nimport { UserMessage } from \"./components/user-message\";\nimport { Spinner } from \"./components/spinner\";\nimport { Divider } from \"./components/divider\";\nimport { PromptInput } from \"./components/prompt-input\";\nimport { StatusBar } from \"./components/status-bar\";\nimport { PermissionDialog } from \"./components/permission-dialog\";\nimport { PlanReview } from \"./components/plan-review\";\nimport { MaxIterations } from \"./components/max-iterations\";\nimport { HelpMenu } from \"./components/help-menu\";\nimport { StatusDisplay } from \"./components/status-display\";\nimport { ModelPicker } from \"./components/model-picker\";\nimport { ModePicker } from \"./components/mode-picker\";\nimport { ThinkingPicker } from \"./components/thinking-picker\";\nimport { SettingsDialog } from \"./components/settings-dialog\";\nimport { Notification } from \"./components/notification\";\nimport { MarkdownText } from \"./components/markdown-text\";\nimport { t } from \"./theme\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype Overlay = \"none\" | \"help\" | \"status\" | \"config\" | \"model\" | \"mode\" | \"thinking\";\n\ninterface AppProps {\n initialSettings: TuiSettings;\n port: number;\n workspacePath: string;\n}\n\ninterface StaticItem {\n key: string;\n node: React.ReactNode;\n}\n\n// =============================================================================\n// App\n// =============================================================================\n\nexport function App({ initialSettings, port, workspacePath }: AppProps) {\n const { exit } = useApp();\n const [overlay, setOverlay] = useState<Overlay>(\"none\");\n const [notification, setNotification] = useState<string | null>(null);\n\n const { settings, setModel, setThinking, setPermissionMode, cyclePermissionMode, setMaxTurns } =\n useSettings(initialSettings);\n\n const {\n messages,\n streamingTextContent: _streamingTextContent,\n addUserMessage,\n handleChatMessage,\n handleTokenEvent,\n clearMessages,\n } = useMessages();\n\n // ==========================================================================\n // Static output — append-only list rendered by <Static>\n // ==========================================================================\n\n const [staticItems, setStaticItems] = useState<StaticItem[]>([\n {\n key: \"welcome\",\n node: <WelcomeHeader settings={settings} workspacePath={workspacePath} />,\n },\n ]);\n const committedIdsRef = useRef(new Set<string>());\n\n // Commit finalized messages to static.\n // Thinking messages are always isPartial=true (never finalized by the agent),\n // so we commit them when a newer message appears after them (thinking is over).\n useEffect(() => {\n const newItems: StaticItem[] = [];\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i]!;\n if (committedIdsRef.current.has(msg.id)) continue;\n\n // Non-partial → commit immediately\n if (!msg.isPartial) {\n committedIdsRef.current.add(msg.id);\n newItems.push({ key: msg.id, node: renderMessage(msg) });\n continue;\n }\n\n // Partial thinking → commit if a later message exists (thinking phase is over)\n if (msg.type === \"thinking\" && i < messages.length - 1) {\n committedIdsRef.current.add(msg.id);\n newItems.push({ key: msg.id, node: renderMessage(msg) });\n continue;\n }\n }\n\n if (newItems.length > 0) {\n setStaticItems((prev) => [...prev, ...newItems]);\n }\n }, [messages]);\n\n // ==========================================================================\n // WS handler\n // ==========================================================================\n\n const handleWsMessage = useCallback(\n (msg: OutboundMessage) => {\n switch (msg.type) {\n case \"agent:onMessage\":\n handleChatMessage(msg.message);\n break;\n case \"agent:onToken\":\n handleTokenEvent(msg as AgentOnTokenEvent);\n break;\n case \"agent:onUsage\":\n task.addTokens(msg.totalTokens);\n break;\n case \"agent:onUserInputRequest\": {\n if (shouldAutoApprove(settings.permissionMode, msg.input)) {\n task.setPendingInput(msg.input);\n setTimeout(() => {\n if (task.currentTaskId) {\n client.respondToInput(task.currentTaskId, msg.input.id, \"allow\");\n task.setPendingInput(null);\n task.setAgentState(\"busy\");\n }\n }, 0);\n } else {\n task.setPendingInput(msg.input);\n task.setAgentState(\"awaiting-input\");\n }\n break;\n }\n case \"agent:output\":\n task.setAgentState(\"idle\");\n if (msg.output.sessionId) task.setSessionId(msg.output.sessionId);\n break;\n case \"agent:status\":\n if (msg.status === \"idle\") task.setAgentState(\"idle\");\n break;\n }\n },\n [settings.permissionMode],\n );\n\n const client = useAgentClient(port, handleWsMessage);\n const task = useTask(client, settings);\n\n // ==========================================================================\n // Keybindings\n // ==========================================================================\n\n useInput((_input, key) => {\n if (key.ctrl && _input === \"c\") {\n if (task.agentState === \"busy\") task.abort();\n else exit();\n return;\n }\n if (key.ctrl && _input === \"d\") { exit(); return; }\n if (key.shift && key.tab) {\n setNotification(`Mode: ${cyclePermissionMode()}`);\n return;\n }\n });\n\n const handleEscape = useCallback(() => {\n if (overlay !== \"none\") setOverlay(\"none\");\n else if (task.agentState === \"busy\" || task.agentState === \"awaiting-input\") task.abort();\n }, [overlay, task]);\n\n const handleHelp = useCallback(() => {\n setOverlay((prev) => (prev === \"help\" ? \"none\" : \"help\"));\n }, []);\n\n const handleSubmit = useCallback(\n (value: string) => {\n const cmd = parseSlashCommand(value);\n if (cmd) {\n switch (cmd.command) {\n case \"help\": setOverlay(\"help\"); return;\n case \"config\": setOverlay(\"config\"); return;\n case \"model\":\n if (cmd.arg) { setModel(cmd.arg); setNotification(`Model: ${cmd.arg}`); }\n else setOverlay(\"model\");\n return;\n case \"mode\":\n if (cmd.arg) { setPermissionMode(cmd.arg as TuiSettings[\"permissionMode\"]); setNotification(`Mode: ${cmd.arg}`); }\n else setOverlay(\"mode\");\n return;\n case \"thinking\":\n if (cmd.arg) {\n const tp = cmd.arg as \"adaptive\" | \"enabled\" | \"disabled\";\n setThinking({ type: tp, ...(tp === \"enabled\" ? { budgetTokens: 32768 } : {}) });\n setNotification(`Thinking: ${cmd.arg}`);\n } else setOverlay(\"thinking\");\n return;\n case \"status\": setOverlay(\"status\"); return;\n case \"clear\":\n clearMessages();\n committedIdsRef.current.clear();\n setStaticItems([{\n key: `welcome-${Date.now()}`,\n node: <WelcomeHeader settings={settings} workspacePath={workspacePath} />,\n }]);\n setNotification(\"Conversation cleared\");\n return;\n case \"compact\": setNotification(\"Compact not yet implemented\"); return;\n case \"exit\": exit(); return;\n }\n }\n addUserMessage(value);\n task.dispatch(value);\n },\n [addUserMessage, task, setModel, setThinking, setPermissionMode, clearMessages, exit, settings, workspacePath],\n );\n\n const closeOverlay = useCallback(() => setOverlay(\"none\"), []);\n\n // ==========================================================================\n // Render\n // ==========================================================================\n\n return (\n <Box flexDirection=\"column\">\n {/* All committed output — rendered once, scrolls naturally in terminal */}\n <Static items={staticItems}>\n {(item) => (\n <Box key={item.key} flexDirection=\"column\">\n {item.node}\n </Box>\n )}\n </Static>\n\n {/* === Everything below is the ONLY dynamic area === */}\n\n {/* Spinner (shown while agent is working) */}\n {task.agentState === \"busy\" && <Spinner />}\n\n {/* Overlays */}\n {overlay === \"help\" && <HelpMenu onClose={closeOverlay} />}\n {overlay === \"status\" && (\n <StatusDisplay settings={settings} connected={client.connected} port={port} sessionId={task.sessionId} totalTokens={task.totalTokens} workspacePath={workspacePath} onClose={closeOverlay} />\n )}\n {overlay === \"config\" && (\n <SettingsDialog settings={settings} onUpdateModel={setModel} onUpdateThinking={setThinking} onUpdateMode={setPermissionMode} onUpdateMaxTurns={setMaxTurns} onClose={closeOverlay} />\n )}\n {overlay === \"model\" && (\n <ModelPicker currentModel={settings.model} onSelect={setModel} onClose={closeOverlay} />\n )}\n {overlay === \"mode\" && (\n <ModePicker currentMode={settings.permissionMode} onSelect={setPermissionMode} onClose={closeOverlay} />\n )}\n {overlay === \"thinking\" && (\n <ThinkingPicker current={settings.thinking} onSelect={setThinking} onClose={closeOverlay} />\n )}\n\n {/* Permission dialogs */}\n {task.pendingInput && task.agentState === \"awaiting-input\" && (\n <>\n {task.pendingInput.type === \"tool\" && (\n <PermissionDialog input={task.pendingInput} onRespond={task.respondToInput} />\n )}\n {task.pendingInput.type === \"plan\" && (\n <PlanReview input={task.pendingInput} onRespond={task.respondToInput} />\n )}\n {task.pendingInput.type === \"max_iterations\" && (\n <MaxIterations input={task.pendingInput} onRespond={task.respondToInput} />\n )}\n </>\n )}\n\n {/* Notification */}\n <Notification message={notification} />\n\n {/* Bottom bar */}\n <Divider />\n <Box paddingX={0} marginY={0}>\n <PromptInput\n onSubmit={handleSubmit}\n onEscape={handleEscape}\n onHelp={handleHelp}\n onSlashCommand={handleSubmit}\n isLoading={task.agentState !== \"idle\"}\n workspacePath={workspacePath}\n />\n </Box>\n <Divider />\n <StatusBar\n mode={settings.permissionMode}\n model={settings.model}\n thinking={settings.thinking}\n agentState={task.agentState}\n totalTokens={task.totalTokens}\n connected={client.connected}\n sessionId={task.sessionId}\n workspacePath={workspacePath}\n />\n </Box>\n );\n}\n\n// =============================================================================\n// Message renderer — creates the React node for a committed message\n// =============================================================================\n\nfunction renderMessage(m: DisplayMessage): React.ReactNode {\n // User messages — gold arrow, extra spacing above\n if (m.type === \"user\") {\n return (\n <Box marginTop={1}>\n <UserMessage content={m.content} />\n </Box>\n );\n }\n\n // Tool calls — colored dot + tool name + description\n if (m.type === \"tool\") {\n const status = m.toolCall?.status ?? \"running\";\n const dot = status === \"completed\" ? t.toolSuccess : status === \"error\" ? t.toolError : t.toolRunning;\n const desc = getToolDesc(m.toolCall);\n return (\n <Box>\n <Box width={2} flexShrink={0}><Text color={dot}>●</Text></Box>\n <Text bold>{m.toolCall?.toolName ?? \"Tool\"}</Text>\n {desc && <Text color={t.dim}> {desc}</Text>}\n {m.toolCall?.error && <Text color={t.toolError}> {truncate(m.toolCall.error, 60)}</Text>}\n </Box>\n );\n }\n\n // Thinking — dim dot + muted content, spacing above\n if (m.type === \"thinking\") {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box>\n <Box width={2} flexShrink={0}><Text color={t.dim}>●</Text></Box>\n <Text color={t.dim} underline>Thinking</Text>\n </Box>\n {m.content && (\n <Box paddingLeft={2}>\n <Text color={t.dim}>{m.content}</Text>\n </Box>\n )}\n </Box>\n );\n }\n\n // Assistant text — green dot + markdown, spacing above\n if (m.type === \"assistant-text\") {\n return (\n <Box flexDirection=\"row\" marginTop={1}>\n <Box width={2} flexShrink={0}><Text color={t.toolSuccess}>●</Text></Box>\n <Box flexDirection=\"column\" flexGrow={1}>\n <MarkdownText content={m.content} />\n </Box>\n </Box>\n );\n }\n\n return null;\n}\n\nfunction getToolDesc(toolCall?: DisplayMessage[\"toolCall\"]): string {\n if (!toolCall) return \"\";\n const { toolName, input, output } = toolCall;\n if (toolCall.status === \"completed\" && output != null) {\n const out = String(output);\n if (out.length < 50 && !out.includes(\"\\n\")) return out;\n }\n if (!input) return \"\";\n switch (toolName) {\n case \"Read\": return String(input.file_path ?? \"\");\n case \"Write\": return String(input.file_path ?? \"\");\n case \"Edit\": return String(input.file_path ?? \"\");\n case \"Bash\": return truncate(String(input.command ?? \"\"), 50);\n case \"Glob\": return String(input.pattern ?? \"\");\n case \"Grep\": return String(input.pattern ?? \"\");\n case \"Agent\": return String(input.description ?? \"\");\n default: return \"\";\n }\n}\n\nfunction truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 1) + \"…\";\n}\n","/**\n * useAgentClient Hook\n *\n * WS client hook that mirrors AgentClient from apps/vscode/src/agent.client.ts.\n * Connects to the local agent server on 127.0.0.1:PORT.\n */\n\nimport { useState, useEffect, useCallback, useRef } from \"react\";\nimport WebSocket from \"ws\";\n\nimport type {\n InboundMessage,\n OutboundMessage,\n AgentDispatchMessage,\n} from \"@jarvis/types\";\n\nexport interface AgentClientState {\n connected: boolean;\n send: (msg: InboundMessage) => void;\n dispatchTask: (task: AgentDispatchMessage) => void;\n abortTask: (taskId: string, reason?: string) => void;\n respondToInput: (\n taskId: string,\n inputId: string,\n action: string,\n data?: Record<string, unknown>,\n feedback?: string,\n ) => void;\n}\n\nexport function useAgentClient(\n port: number,\n onMessage: (msg: OutboundMessage) => void,\n): AgentClientState {\n const [connected, setConnected] = useState(false);\n const wsRef = useRef<WebSocket | null>(null);\n const closedRef = useRef(false);\n const onMessageRef = useRef(onMessage);\n onMessageRef.current = onMessage;\n\n useEffect(() => {\n closedRef.current = false;\n\n function tryConnect() {\n if (closedRef.current) return;\n\n try {\n const ws = new WebSocket(`ws://127.0.0.1:${port}`);\n wsRef.current = ws;\n\n ws.on(\"open\", () => setConnected(true));\n\n ws.on(\"message\", (raw) => {\n try {\n const msg = JSON.parse(raw.toString()) as OutboundMessage;\n if (msg.type === \"pong\") return;\n onMessageRef.current(msg);\n } catch {\n // Ignore malformed\n }\n });\n\n ws.on(\"close\", () => {\n setConnected(false);\n if (!closedRef.current) {\n setTimeout(tryConnect, 3000);\n }\n });\n\n ws.on(\"error\", () => {\n // Will trigger close → reconnect\n });\n } catch {\n if (!closedRef.current) {\n setTimeout(tryConnect, 3000);\n }\n }\n }\n\n tryConnect();\n\n return () => {\n closedRef.current = true;\n wsRef.current?.close();\n wsRef.current = null;\n };\n }, [port]);\n\n const send = useCallback((msg: InboundMessage) => {\n if (wsRef.current?.readyState === WebSocket.OPEN) {\n wsRef.current.send(JSON.stringify(msg));\n }\n }, []);\n\n const dispatchTask = useCallback(\n (task: AgentDispatchMessage) => send(task),\n [send],\n );\n\n const abortTask = useCallback(\n (taskId: string, reason?: string) =>\n send({ type: \"agent:abort\", taskId, reason }),\n [send],\n );\n\n const respondToInput = useCallback(\n (\n taskId: string,\n inputId: string,\n action: string,\n data?: Record<string, unknown>,\n feedback?: string,\n ) => send({ type: \"agent:userInput\", taskId, inputId, action, data, feedback }),\n [send],\n );\n\n return { connected, send, dispatchTask, abortTask, respondToInput };\n}\n","/**\n * useMessages Hook\n *\n * Manages the message list state from agent:onMessage + agent:onToken events.\n * Messages are keyed by ID — partial messages get replaced when updated.\n * Token events are throttled to prevent excessive re-renders.\n */\n\nimport { useState, useCallback, useRef } from \"react\";\n\nimport type { ChatMessage, AgentOnTokenEvent } from \"@jarvis/types\";\n\nexport interface DisplayMessage {\n id: string;\n type: \"user\" | \"assistant-text\" | \"thinking\" | \"tool\" | \"status\";\n content: string;\n toolCall?: ChatMessage[\"toolCall\"];\n thinking?: ChatMessage[\"thinking\"];\n ui?: ChatMessage[\"ui\"];\n isPartial?: boolean;\n createdAt?: string;\n}\n\nexport interface MessagesState {\n messages: DisplayMessage[];\n streamingTextContent: string | null;\n addUserMessage: (content: string) => void;\n handleChatMessage: (msg: ChatMessage) => void;\n handleTokenEvent: (event: AgentOnTokenEvent) => void;\n clearMessages: () => void;\n}\n\nconst TOKEN_THROTTLE_MS = 80; // ~12fps for streaming text, reduces flicker\n\nexport function useMessages(): MessagesState {\n const [messages, setMessages] = useState<DisplayMessage[]>([]);\n const [streamingTextContent, setStreamingTextContent] = useState<string | null>(null);\n const streamingIdRef = useRef<string | null>(null);\n const throttleRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pendingContentRef = useRef<string | null>(null);\n\n const addUserMessage = useCallback((content: string) => {\n const msg: DisplayMessage = {\n id: `user-${Date.now()}`,\n type: \"user\",\n content,\n createdAt: new Date().toISOString(),\n };\n setMessages((prev) => [...prev, msg]);\n }, []);\n\n const handleChatMessage = useCallback((msg: ChatMessage) => {\n const display: DisplayMessage = {\n id: msg.id,\n type:\n msg.type === \"thinking\"\n ? \"thinking\"\n : msg.type === \"tool\"\n ? \"tool\"\n : msg.type === \"status\"\n ? \"status\"\n : \"assistant-text\",\n content: msg.content,\n toolCall: msg.toolCall,\n thinking: msg.thinking,\n ui: msg.ui,\n isPartial: msg.isPartial,\n createdAt: msg.createdAt,\n };\n\n setMessages((prev) => {\n const idx = prev.findIndex((m) => m.id === msg.id);\n if (idx >= 0) {\n const updated = [...prev];\n updated[idx] = display;\n return updated;\n }\n return [...prev, display];\n });\n }, []);\n\n const flushStreamingContent = useCallback(() => {\n if (pendingContentRef.current !== null) {\n setStreamingTextContent(pendingContentRef.current);\n }\n throttleRef.current = null;\n }, []);\n\n const handleTokenEvent = useCallback((event: AgentOnTokenEvent) => {\n if (event.isComplete) {\n // Finalize: flush any pending content, add as message, clear streaming\n if (throttleRef.current) {\n clearTimeout(throttleRef.current);\n throttleRef.current = null;\n }\n streamingIdRef.current = null;\n pendingContentRef.current = null;\n setStreamingTextContent(null);\n setMessages((prev) => {\n const existing = prev.findIndex((m) => m.id === event.messageId);\n const finalMsg: DisplayMessage = {\n id: event.messageId,\n type: \"assistant-text\",\n content: event.content,\n isPartial: false,\n createdAt: new Date().toISOString(),\n };\n if (existing >= 0) {\n const updated = [...prev];\n updated[existing] = finalMsg;\n return updated;\n }\n return [...prev, finalMsg];\n });\n } else {\n // Streaming: throttle updates to reduce re-renders\n streamingIdRef.current = event.messageId;\n pendingContentRef.current = event.content;\n if (!throttleRef.current) {\n // Immediately show first token, then throttle subsequent ones\n setStreamingTextContent(event.content);\n throttleRef.current = setTimeout(flushStreamingContent, TOKEN_THROTTLE_MS);\n }\n }\n }, [flushStreamingContent]);\n\n const clearMessages = useCallback(() => {\n setMessages([]);\n setStreamingTextContent(null);\n streamingIdRef.current = null;\n pendingContentRef.current = null;\n if (throttleRef.current) {\n clearTimeout(throttleRef.current);\n throttleRef.current = null;\n }\n }, []);\n\n return {\n messages,\n streamingTextContent,\n addUserMessage,\n handleChatMessage,\n handleTokenEvent,\n clearMessages,\n };\n}\n","/**\n * useTask Hook\n *\n * Manages task lifecycle: dispatch, abort, user input responses.\n * Constructs agent:dispatch messages from TUI settings.\n */\n\nimport { useState, useCallback, useRef } from \"react\";\nimport crypto from \"crypto\";\n\nimport type { AgentDispatchMessage, PendingUserInput } from \"@jarvis/types\";\n\nimport type { TuiSettings } from \"../settings\";\nimport type { AgentClientState } from \"./use-agent-client\";\n\nexport type AgentState = \"idle\" | \"busy\" | \"awaiting-input\";\n\nexport interface TaskState {\n agentState: AgentState;\n currentTaskId: string | null;\n sessionId: string | null;\n totalTokens: number;\n pendingInput: PendingUserInput | null;\n dispatch: (userMessage: string) => void;\n abort: () => void;\n respondToInput: (\n action: string,\n data?: Record<string, unknown>,\n feedback?: string,\n ) => void;\n setAgentState: (state: AgentState) => void;\n setPendingInput: (input: PendingUserInput | null) => void;\n addTokens: (tokens: number) => void;\n setSessionId: (id: string) => void;\n}\n\nexport function useTask(\n client: AgentClientState,\n settings: TuiSettings,\n): TaskState {\n const [agentState, setAgentState] = useState<AgentState>(\"idle\");\n const [currentTaskId, setCurrentTaskId] = useState<string | null>(null);\n const [sessionId, setSessionId] = useState<string | null>(null);\n const [totalTokens, setTotalTokens] = useState(0);\n const [pendingInput, setPendingInput] = useState<PendingUserInput | null>(null);\n const chatIdRef = useRef(`chat-${crypto.randomUUID()}`);\n\n const dispatch = useCallback(\n (userMessage: string) => {\n const taskId = crypto.randomUUID();\n setCurrentTaskId(taskId);\n setAgentState(\"busy\");\n\n const msg: AgentDispatchMessage = {\n type: \"agent:dispatch\",\n taskId,\n chatId: chatIdRef.current,\n messages: [{ role: \"user\", content: userMessage }],\n model: settings.model,\n maxTurns: settings.maxTurns,\n permissionMode:\n settings.permissionMode === \"yolo\"\n ? \"auto\"\n : settings.permissionMode,\n disallowedTools:\n settings.disallowedTools.length > 0\n ? settings.disallowedTools\n : undefined,\n ...(sessionId\n ? { session: { resume: sessionId, persistSession: true } }\n : { session: { persistSession: true } }),\n };\n\n client.dispatchTask(msg);\n },\n [client, settings, sessionId],\n );\n\n const abort = useCallback(() => {\n if (currentTaskId) {\n client.abortTask(currentTaskId);\n }\n }, [client, currentTaskId]);\n\n const respondToInput = useCallback(\n (\n action: string,\n data?: Record<string, unknown>,\n feedback?: string,\n ) => {\n if (currentTaskId && pendingInput) {\n client.respondToInput(\n currentTaskId,\n pendingInput.id,\n action,\n data,\n feedback,\n );\n setPendingInput(null);\n setAgentState(\"busy\");\n }\n },\n [client, currentTaskId, pendingInput],\n );\n\n const addTokens = useCallback((tokens: number) => {\n setTotalTokens((prev) => prev + tokens);\n }, []);\n\n return {\n agentState,\n currentTaskId,\n sessionId,\n totalTokens,\n pendingInput,\n dispatch,\n abort,\n respondToInput,\n setAgentState,\n setPendingInput,\n addTokens,\n setSessionId,\n };\n}\n","/**\n * useSettings Hook\n *\n * Runtime settings state with persistence to ~/.jarvis/settings.json.\n */\n\nimport { useState, useCallback } from \"react\";\n\nimport type { ThinkingConfig } from \"@jarvis/types\";\n\nimport {\n type TuiSettings,\n type PermissionMode,\n saveSettings,\n} from \"../settings\";\n\nconst MODE_CYCLE: PermissionMode[] = [\"supervised\", \"auto\", \"plan\", \"yolo\"];\n\nexport interface SettingsState {\n settings: TuiSettings;\n setModel: (model: string) => void;\n setThinking: (thinking: ThinkingConfig) => void;\n setPermissionMode: (mode: PermissionMode) => void;\n cyclePermissionMode: () => PermissionMode;\n setMaxTurns: (turns: number) => void;\n setTheme: (theme: \"dark\" | \"light\") => void;\n}\n\nexport function useSettings(initial: TuiSettings): SettingsState {\n const [settings, setSettings] = useState<TuiSettings>(initial);\n\n const update = useCallback((patch: Partial<TuiSettings>) => {\n setSettings((prev) => {\n const next = { ...prev, ...patch };\n saveSettings(next);\n return next;\n });\n }, []);\n\n const setModel = useCallback(\n (model: string) => update({ model }),\n [update],\n );\n\n const setThinking = useCallback(\n (thinking: ThinkingConfig) => update({ thinking }),\n [update],\n );\n\n const setPermissionMode = useCallback(\n (permissionMode: PermissionMode) => update({ permissionMode }),\n [update],\n );\n\n const cyclePermissionMode = useCallback(() => {\n let nextMode: PermissionMode = \"supervised\";\n setSettings((prev) => {\n const idx = MODE_CYCLE.indexOf(prev.permissionMode);\n nextMode = MODE_CYCLE[(idx + 1) % MODE_CYCLE.length]!;\n const next = { ...prev, permissionMode: nextMode };\n saveSettings(next);\n return next;\n });\n return nextMode;\n }, []);\n\n const setMaxTurns = useCallback(\n (maxTurns: number) => update({ maxTurns }),\n [update],\n );\n\n const setTheme = useCallback(\n (theme: \"dark\" | \"light\") => update({ theme }),\n [update],\n );\n\n return {\n settings,\n setModel,\n setThinking,\n setPermissionMode,\n cyclePermissionMode,\n setMaxTurns,\n setTheme,\n };\n}\n","/**\n * Slash Command Parser\n *\n * Parses /command [args] from user input.\n */\n\nexport type SlashCommand =\n | { command: \"help\" }\n | { command: \"config\" }\n | { command: \"model\"; arg?: string }\n | { command: \"mode\"; arg?: string }\n | { command: \"thinking\"; arg?: string }\n | { command: \"status\" }\n | { command: \"clear\" }\n | { command: \"compact\" }\n | { command: \"exit\" };\n\nexport function parseSlashCommand(input: string): SlashCommand | null {\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"/\")) return null;\n\n const parts = trimmed.split(/\\s+/);\n const cmd = parts[0]!.slice(1).toLowerCase();\n const arg = parts.slice(1).join(\" \") || undefined;\n\n switch (cmd) {\n case \"help\":\n case \"h\":\n return { command: \"help\" };\n case \"config\":\n case \"settings\":\n return { command: \"config\" };\n case \"model\":\n case \"m\":\n return { command: \"model\", arg };\n case \"mode\":\n return { command: \"mode\", arg };\n case \"thinking\":\n return { command: \"thinking\", arg };\n case \"status\":\n return { command: \"status\" };\n case \"clear\":\n return { command: \"clear\" };\n case \"compact\":\n return { command: \"compact\" };\n case \"exit\":\n case \"quit\":\n case \"q\":\n return { command: \"exit\" };\n default:\n return null;\n }\n}\n","/**\n * Auto-Approval Logic\n *\n * Determines whether a tool should be auto-approved based on permission mode.\n */\n\nimport type { PendingUserInput } from \"@jarvis/types\";\n\nimport type { PermissionMode } from \"../settings\";\n\n/** Tools considered safe for auto-approval in \"auto\" mode */\nconst SAFE_TOOLS = new Set([\n \"Read\",\n \"Glob\",\n \"Grep\",\n \"WebSearch\",\n \"WebFetch\",\n \"Agent\",\n \"TodoWrite\",\n \"Skill\",\n \"ToolSearch\",\n]);\n\n/**\n * Returns true if the pending input should be auto-approved without showing a dialog.\n */\nexport function shouldAutoApprove(\n mode: PermissionMode,\n input: PendingUserInput,\n): boolean {\n // Plan type always needs review in plan mode, auto-approve otherwise\n if (input.type === \"plan\") {\n return mode !== \"plan\" && mode !== \"supervised\";\n }\n\n // Max iterations: always ask\n if (input.type === \"max_iterations\") {\n return false;\n }\n\n // Yolo mode: approve everything\n if (mode === \"yolo\") return true;\n\n // Auto mode: approve safe tools, ask for dangerous\n if (mode === \"auto\") {\n const toolName = input.toolName ?? \"\";\n return SAFE_TOOLS.has(toolName);\n }\n\n // Supervised/plan: never auto-approve tools\n return false;\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport type { TuiSettings } from \"../settings\";\nimport { t } from \"../theme\";\n\ninterface WelcomeHeaderProps {\n settings: TuiSettings;\n workspacePath: string;\n}\n\nconst LOGO = [\n \" ╦╔═╗╦═╗╦ ╦╦╔═╗\",\n \" ║╠═╣╠╦╝╚╗╔╝║╚═╗\",\n \" ╚╝╩ ╩╩╚═ ╚╝ ╩╚═╝\",\n];\n\nfunction shortModel(model: string): string {\n const m = model.match(/(sonnet|opus|haiku)[- ](\\d+(?:\\.\\d+)?)/i);\n if (m) return `${m[1]![0]!.toUpperCase()}${m[1]!.slice(1)} ${m[2]}`;\n return model;\n}\n\nfunction shortPath(p: string): string {\n const home = process.env.HOME ?? \"\";\n if (home && p.startsWith(home)) return \"~\" + p.slice(home.length);\n return p;\n}\n\nexport function WelcomeHeader({ settings, workspacePath }: WelcomeHeaderProps) {\n return (\n <Box flexDirection=\"column\" paddingTop={1} paddingBottom={0}>\n <Box flexDirection=\"column\" paddingLeft={4}>\n {LOGO.map((line, i) => (\n <Text key={i} color={t.logo} bold>{line}</Text>\n ))}\n </Box>\n <Box flexDirection=\"column\" paddingLeft={4} marginTop={0}>\n <Text>\n <Text color={t.logo} bold>Jarvis</Text>\n <Text color={t.dim}>{\" v0.1.0\"}</Text>\n </Text>\n <Text color={t.dim}>\n {shortModel(settings.model)} · {settings.permissionMode}\n </Text>\n <Text color={t.dim}>\n {shortPath(workspacePath)}\n </Text>\n </Box>\n </Box>\n );\n}\n","/**\n * TUI Theme\n *\n * JARVIS terminal color palette — matches the web app theme:\n * Primary: #FFB800 (gold/amber — Iron Man's gold)\n * Secondary: #DC4545 (soft red — Iron Man's red)\n * Neutral: #1E293B (navy-tinted gray)\n *\n * Only accents/indicators are colorful. Regular text stays default.\n */\n\n// =============================================================================\n// Brand Colors (hex values for Ink's `color` prop)\n// =============================================================================\n\nexport const colors = {\n // Primary — gold\n gold: \"#FFB800\",\n goldDim: \"#B38200\",\n goldBg: \"#3D2E00\",\n\n // Secondary — red\n red: \"#DC4545\",\n redDim: \"#991B1B\",\n\n // Accent — purple (from SDK theme)\n purple: \"#8270DB\",\n\n // Status\n green: \"#22C55E\",\n yellow: \"#FFB800\",\n cyan: \"#06B6D4\",\n\n // Neutral\n navy: \"#1E293B\",\n navyLight: \"#64748B\",\n navyLighter: \"#94A3B8\",\n\n // Foreground\n text: undefined, // default terminal color\n dim: \"#64748B\",\n muted: \"#94A3B8\",\n} as const;\n\n// =============================================================================\n// Semantic tokens — what color each UI element uses\n// =============================================================================\n\nexport const t = {\n // Logo & branding\n logo: colors.gold,\n\n // Prompt\n promptArrow: colors.gold,\n\n // Spinner / working indicator\n spinner: colors.gold,\n\n // Divider\n divider: colors.navyLight,\n\n // Tool icons\n toolSuccess: colors.green,\n toolError: colors.red,\n toolRunning: colors.gold,\n\n // Permission mode indicator\n mode: {\n supervised: colors.green,\n auto: colors.gold,\n plan: colors.purple,\n yolo: colors.red,\n } as Record<string, string>,\n\n // Headings in markdown\n heading: colors.gold,\n\n // Slash commands in help menu\n command: colors.gold,\n\n // Status bar\n hint: colors.dim,\n disconnected: colors.red,\n\n // Overlays — border accents\n dialogBorder: colors.navyLight,\n dialogTitle: colors.gold,\n dialogAction: colors.gold,\n dialogDanger: colors.red,\n\n // Notification flash\n notification: colors.gold,\n\n // Dim / muted text\n dim: colors.dim,\n muted: colors.muted,\n} as const;\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { t } from \"../theme\";\n\ninterface UserMessageProps {\n content: string;\n}\n\nexport function UserMessage({ content }: UserMessageProps) {\n return (\n <Box marginTop={1}>\n <Text color={t.promptArrow} bold>{\"❯ \"}</Text>\n <Text>{content}</Text>\n </Box>\n );\n}\n","import React, { useState, useEffect, useRef } from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { t } from \"../theme\";\n\n// =============================================================================\n// Fake word generator (from packages/ui StreamingText)\n// =============================================================================\n\nconst PREFIXES = [\n \"Pro\", \"Re\", \"De\", \"Con\", \"Syn\", \"Meta\", \"Hyper\", \"Trans\",\n \"Neo\", \"Poly\", \"Multi\", \"Sub\", \"Inter\", \"Ultra\", \"Semi\",\n \"Auto\", \"Para\", \"Mono\",\n];\nconst ROOTS = [\n \"cog\", \"flux\", \"morph\", \"lex\", \"graph\", \"lys\", \"gen\", \"struct\",\n \"val\", \"duc\", \"fract\", \"gress\", \"ject\", \"spect\", \"vert\", \"tract\",\n \"form\", \"plex\", \"crypt\", \"volt\", \"quant\", \"phas\", \"nex\", \"fus\",\n];\nconst SUFFIXES = [\n \"izing\", \"ating\", \"ifying\", \"enting\", \"uting\", \"ecting\", \"uming\",\n \"ering\", \"ising\", \"ancing\", \"encing\", \"oring\", \"uring\", \"aling\",\n];\n\nfunction pick<T>(arr: T[]): T {\n return arr[Math.floor(Math.random() * arr.length)]!;\n}\n\nfunction generateWord(): string {\n const usePrefix = Math.random() > 0.3;\n const prefix = usePrefix ? pick(PREFIXES) : \"\";\n const root = pick(ROOTS);\n const suffix = pick(SUFFIXES);\n const word = prefix + root + suffix;\n return word.charAt(0).toUpperCase() + word.slice(1);\n}\n\n// =============================================================================\n// Spinner glyph — Claude Code style: growing/shrinking symbols\n// Wrapped in fixed-width Box to prevent jumpiness\n// =============================================================================\n\nconst GLYPHS =\n process.platform === \"darwin\"\n ? [\"·\", \"✢\", \"✳\", \"✶\", \"✻\", \"✽\"]\n : [\"·\", \"✢\", \"*\", \"✶\", \"✻\", \"✽\"];\n\nconst GLYPH_FRAMES = [...GLYPHS, ...[...GLYPHS].reverse()];\n\n// =============================================================================\n// Component\n// =============================================================================\n\nexport function Spinner() {\n const [glyphFrame, setGlyphFrame] = useState(0);\n const [word, setWord] = useState(generateWord);\n const [overwriteIdx, setOverwriteIdx] = useState(0);\n const [prevWord, setPrevWord] = useState(\"\");\n const [phase, setPhase] = useState<\"display\" | \"transition\">(\"display\");\n const startRef = useRef(Date.now());\n\n // Glyph animation: 120ms per frame\n useEffect(() => {\n const timer = setInterval(\n () => setGlyphFrame((f) => (f + 1) % GLYPH_FRAMES.length),\n 120,\n );\n return () => clearInterval(timer);\n }, []);\n\n // Word transition: overwrite char by char at 50ms\n useEffect(() => {\n if (phase === \"transition\") {\n const totalLen = (prevWord + \"…\").length;\n if (overwriteIdx < totalLen) {\n const timer = setTimeout(() => setOverwriteIdx((i) => i + 1), 50);\n return () => clearTimeout(timer);\n } else {\n setPhase(\"display\");\n }\n }\n }, [overwriteIdx, prevWord, phase]);\n\n // Wait then start next word transition\n useEffect(() => {\n if (phase === \"display\") {\n const timer = setTimeout(() => {\n setPrevWord(word);\n setWord(generateWord());\n setOverwriteIdx(0);\n setPhase(\"transition\");\n }, 2500);\n return () => clearTimeout(timer);\n }\n }, [phase, word]);\n\n const elapsed = Math.floor((Date.now() - startRef.current) / 1000);\n\n // Build display text\n let displayText: string;\n if (phase === \"display\") {\n displayText = word + \"…\";\n } else {\n const oldText = prevWord + \"…\";\n const newText = word + \"…\";\n displayText = newText.slice(0, overwriteIdx) + oldText.slice(overwriteIdx);\n }\n\n return (\n <Box marginTop={1}>\n <Box width={2} flexShrink={0}>\n <Text color={t.spinner}>{GLYPH_FRAMES[glyphFrame]}</Text>\n </Box>\n <Text color={t.spinner}>{displayText}</Text>\n {elapsed > 2 && <Text color={t.dim}> {elapsed}s</Text>}\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { t } from \"../theme\";\nimport { useTerminal } from \"../hooks/use-terminal\";\n\nexport function Divider() {\n const { columns } = useTerminal();\n return (\n <Box>\n <Text color={t.divider}>{\"─\".repeat(columns)}</Text>\n </Box>\n );\n}\n","/**\n * useTerminal Hook\n *\n * Terminal dimensions with resize tracking.\n */\n\nimport { useState, useEffect } from \"react\";\n\nexport interface TerminalSize {\n columns: number;\n rows: number;\n}\n\nexport function useTerminal(): TerminalSize {\n const [size, setSize] = useState<TerminalSize>({\n columns: process.stdout.columns || 80,\n rows: process.stdout.rows || 24,\n });\n\n useEffect(() => {\n const onResize = () => {\n setSize({\n columns: process.stdout.columns || 80,\n rows: process.stdout.rows || 24,\n });\n };\n\n process.stdout.on(\"resize\", onResize);\n return () => {\n process.stdout.off(\"resize\", onResize);\n };\n }, []);\n\n return size;\n}\n","/**\n * PromptInput with autocomplete\n *\n * Detects:\n * - `/` at start → slash command suggestions\n * - `@` → file picker suggestions\n * - `?` on empty input → help toggle\n * - Esc → abort/close\n * - Arrow keys → navigate suggestions when open\n * - Enter → select suggestion or submit\n * - Tab → accept suggestion\n */\n\nimport React, { useState, useCallback, useMemo } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport TextInput from \"ink-text-input\";\n\nimport { t } from \"../theme\";\nimport {\n type Suggestion,\n filterSlashCommands,\n Suggestions,\n} from \"./suggestions\";\nimport { filterFiles, FilePicker } from \"./file-picker\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype PickerMode = \"none\" | \"slash\" | \"file\";\n\ninterface PromptInputProps {\n onSubmit: (value: string) => void;\n onEscape: () => void;\n onHelp: () => void;\n onSlashCommand: (command: string) => void;\n isLoading?: boolean;\n workspacePath: string;\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\nexport function PromptInput({\n onSubmit,\n onEscape,\n onHelp,\n onSlashCommand,\n isLoading,\n workspacePath,\n}: PromptInputProps) {\n const [value, setValue] = useState(\"\");\n const [selectedIdx, setSelectedIdx] = useState(0);\n\n // Detect picker mode from input\n const pickerMode: PickerMode = useMemo(() => {\n if (isLoading) return \"none\";\n if (value.startsWith(\"/\")) return \"slash\";\n // Detect @ at start or after whitespace\n const atMatch = value.match(/(^|\\s)@([^\\s]*)$/);\n if (atMatch) return \"file\";\n return \"none\";\n }, [value, isLoading]);\n\n // Get filtered suggestions\n const suggestions: Suggestion[] = useMemo(() => {\n if (pickerMode === \"slash\") {\n return filterSlashCommands(value.slice(1)); // remove leading /\n }\n if (pickerMode === \"file\") {\n const atMatch = value.match(/(^|\\s)@([^\\s]*)$/);\n const query = atMatch?.[2] ?? \"\";\n return filterFiles(query, workspacePath);\n }\n return [];\n }, [pickerMode, value, workspacePath]);\n\n // Reset selection when suggestions change\n const prevSugLen = React.useRef(suggestions.length);\n if (suggestions.length !== prevSugLen.current) {\n prevSugLen.current = suggestions.length;\n if (selectedIdx >= suggestions.length) {\n setSelectedIdx(Math.max(0, suggestions.length - 1));\n }\n }\n\n const handleMove = useCallback(\n (delta: number) => {\n setSelectedIdx((prev) => {\n const next = prev + delta;\n if (next < 0) return suggestions.length - 1;\n if (next >= suggestions.length) return 0;\n return next;\n });\n },\n [suggestions.length],\n );\n\n const handleSelectSuggestion = useCallback(\n (item: Suggestion) => {\n if (pickerMode === \"slash\") {\n // Execute the slash command directly\n setValue(\"\");\n onSlashCommand(item.value);\n } else if (pickerMode === \"file\") {\n // Replace @query with the file path\n const before = value.replace(/(^|\\s)@[^\\s]*$/, \"$1\");\n setValue(before + item.value + \" \");\n }\n setSelectedIdx(0);\n },\n [pickerMode, value, onSlashCommand],\n );\n\n const handleChange = useCallback(\n (text: string) => {\n if (!isLoading) {\n setValue(text);\n setSelectedIdx(0);\n }\n },\n [isLoading],\n );\n\n useInput((_input, key) => {\n // Escape\n if (key.escape) {\n if (pickerMode !== \"none\") {\n // Close suggestions by clearing the trigger char\n if (pickerMode === \"slash\") setValue(\"\");\n else setValue(value.replace(/(^|\\s)@[^\\s]*$/, \"$1\"));\n setSelectedIdx(0);\n } else {\n onEscape();\n }\n return;\n }\n\n // Arrow keys when suggestions are open\n if (pickerMode !== \"none\") {\n if (key.upArrow) {\n handleMove(-1);\n return;\n }\n if (key.downArrow) {\n handleMove(1);\n return;\n }\n if (key.tab && suggestions[selectedIdx]) {\n handleSelectSuggestion(suggestions[selectedIdx]);\n return;\n }\n }\n\n // ? on empty input → help\n if (_input === \"?\" && value === \"\" && !isLoading) {\n onHelp();\n return;\n }\n\n // Enter\n if (key.return) {\n // If suggestions open and one is selected, pick it\n if (pickerMode === \"slash\" && suggestions[selectedIdx]) {\n handleSelectSuggestion(suggestions[selectedIdx]);\n return;\n }\n // Otherwise submit\n if (value.trim() && !isLoading) {\n const text = value.trim();\n setValue(\"\");\n setSelectedIdx(0);\n onSubmit(text);\n }\n }\n });\n\n return (\n <Box flexDirection=\"column\">\n {/* Suggestions dropdown (above input) */}\n {pickerMode === \"slash\" && suggestions.length > 0 && (\n <Suggestions\n items={suggestions}\n selectedIndex={selectedIdx}\n />\n )}\n {pickerMode === \"file\" && suggestions.length > 0 && (\n <FilePicker\n items={suggestions}\n selectedIndex={selectedIdx}\n />\n )}\n\n {/* Input line */}\n <Box>\n <Text color={isLoading ? t.dim : t.promptArrow} dimColor={isLoading}>\n {\"❯ \"}\n </Text>\n <TextInput\n value={value}\n onChange={handleChange}\n placeholder=\"\"\n showCursor={!isLoading}\n />\n </Box>\n </Box>\n );\n}\n","/**\n * Suggestions Dropdown\n *\n * Renders filtered slash command suggestions.\n * Navigation is handled by PromptInput — this is a pure display component.\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport { t } from \"../theme\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface Suggestion {\n id: string;\n icon: string;\n label: string;\n description: string;\n value: string;\n}\n\ninterface SuggestionsProps {\n items: Suggestion[];\n selectedIndex: number;\n maxVisible?: number;\n}\n\n// =============================================================================\n// Slash Commands\n// =============================================================================\n\nexport const SLASH_COMMANDS: Suggestion[] = [\n { id: \"help\", icon: \"?\", label: \"/help\", description: \"Show available commands\", value: \"/help\" },\n { id: \"config\", icon: \"⚙\", label: \"/config\", description: \"Open settings\", value: \"/config\" },\n { id: \"model\", icon: \"◆\", label: \"/model\", description: \"Switch model\", value: \"/model\" },\n { id: \"mode\", icon: \"●\", label: \"/mode\", description: \"Switch permission mode\", value: \"/mode\" },\n { id: \"thinking\", icon: \"▸\", label: \"/thinking\", description: \"Toggle thinking config\", value: \"/thinking\" },\n { id: \"status\", icon: \"ℹ\", label: \"/status\", description: \"Show session info\", value: \"/status\" },\n { id: \"clear\", icon: \"✕\", label: \"/clear\", description: \"Clear conversation\", value: \"/clear\" },\n { id: \"compact\", icon: \"◇\", label: \"/compact\", description: \"Compact old messages\", value: \"/compact\" },\n { id: \"exit\", icon: \"→\", label: \"/exit\", description: \"Exit Jarvis\", value: \"/exit\" },\n];\n\nexport function filterSlashCommands(query: string): Suggestion[] {\n const q = query.toLowerCase();\n if (!q) return SLASH_COMMANDS;\n return SLASH_COMMANDS.filter(\n (cmd) =>\n cmd.label.toLowerCase().includes(q) ||\n cmd.description.toLowerCase().includes(q),\n );\n}\n\n// =============================================================================\n// Component (pure display — no useInput)\n// =============================================================================\n\nexport function Suggestions({\n items,\n selectedIndex,\n maxVisible = 6,\n}: SuggestionsProps) {\n if (items.length === 0) return null;\n\n const half = Math.floor(maxVisible / 2);\n const startIdx = Math.max(\n 0,\n Math.min(selectedIndex - half, items.length - maxVisible),\n );\n const visible = items.slice(startIdx, startIdx + maxVisible);\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2} marginBottom={0}>\n {visible.map((item, i) => {\n const realIdx = startIdx + i;\n const selected = realIdx === selectedIndex;\n return (\n <Box key={item.id}>\n <Text color={selected ? t.dialogTitle : t.dim}>\n {selected ? \"❯ \" : \" \"}\n </Text>\n <Text color={selected ? t.dialogTitle : undefined} bold={selected}>\n {item.icon} {item.label}\n </Text>\n <Text color={t.dim}>{\" \"}{item.description}</Text>\n </Box>\n );\n })}\n </Box>\n );\n}\n","/**\n * File Picker\n *\n * Triggered by @ in the input. Shows files matching the query.\n * Pure display component — navigation handled by PromptInput.\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport path from \"path\";\nimport fs from \"fs\";\n\nimport { t } from \"../theme\";\nimport type { Suggestion } from \"./suggestions\";\n\n// =============================================================================\n// File scanning\n// =============================================================================\n\nlet cachedFiles: string[] | null = null;\n\nfunction scanFiles(workspacePath: string): string[] {\n if (cachedFiles) return cachedFiles;\n\n const results: string[] = [];\n const ignoreSet = new Set([\n \"node_modules\", \".git\", \"dist\", \"build\", \".next\", \"coverage\",\n \".turbo\", \".cache\", \"__pycache__\", \".DS_Store\",\n ]);\n\n function walk(dir: string, depth: number) {\n if (depth > 4) return;\n try {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (ignoreSet.has(entry.name) || entry.name.startsWith(\".\")) continue;\n const full = path.join(dir, entry.name);\n const rel = path.relative(workspacePath, full);\n if (entry.isDirectory()) {\n results.push(rel + \"/\");\n walk(full, depth + 1);\n } else {\n results.push(rel);\n }\n if (results.length > 500) return;\n }\n } catch {\n // permission errors\n }\n }\n\n walk(workspacePath, 0);\n cachedFiles = results;\n return results;\n}\n\nexport function filterFiles(query: string, workspacePath: string): Suggestion[] {\n const files = scanFiles(workspacePath);\n const q = query.toLowerCase();\n\n const matches = q\n ? files.filter((f) => f.toLowerCase().includes(q))\n : files.slice(0, 20);\n\n return matches.slice(0, 20).map((f) => ({\n id: `file-${f}`,\n icon: f.endsWith(\"/\") ? \"📁\" : \"📄\",\n label: f,\n description: \"\",\n value: f,\n }));\n}\n\nexport function resetFileCache(): void {\n cachedFiles = null;\n}\n\n// =============================================================================\n// Component (pure display — no useInput)\n// =============================================================================\n\ninterface FilePickerProps {\n items: Suggestion[];\n selectedIndex: number;\n maxVisible?: number;\n}\n\nexport function FilePicker({\n items,\n selectedIndex,\n maxVisible = 8,\n}: FilePickerProps) {\n if (items.length === 0) {\n return (\n <Box paddingLeft={2}>\n <Text color={t.dim}>No files found</Text>\n </Box>\n );\n }\n\n const half = Math.floor(maxVisible / 2);\n const startIdx = Math.max(\n 0,\n Math.min(selectedIndex - half, items.length - maxVisible),\n );\n const visible = items.slice(startIdx, startIdx + maxVisible);\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2} marginBottom={0}>\n {visible.map((item, i) => {\n const realIdx = startIdx + i;\n const selected = realIdx === selectedIndex;\n return (\n <Box key={item.id}>\n <Text color={selected ? t.dialogTitle : t.dim}>\n {selected ? \"❯ \" : \" \"}\n </Text>\n <Text color={selected ? t.dialogTitle : undefined} bold={selected}>\n {item.icon} {item.label}\n </Text>\n </Box>\n );\n })}\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\n\nimport type { PermissionMode } from \"../settings\";\nimport type { AgentState } from \"../hooks/use-task\";\nimport type { ThinkingConfig } from \"@jarvis/types\";\nimport { formatTokens } from \"../utils/format-tokens\";\nimport { useTerminal } from \"../hooks/use-terminal\";\nimport { t } from \"../theme\";\n\ninterface StatusBarProps {\n mode: PermissionMode;\n model: string;\n thinking: ThinkingConfig;\n agentState: AgentState;\n totalTokens: number;\n connected: boolean;\n sessionId: string | null;\n workspacePath: string;\n}\n\nfunction shortModel(model: string): string {\n const m = model.match(/(sonnet|opus|haiku)[- ](\\d)/i);\n if (m) return `${m[1]![0]!.toUpperCase()}${m[1]!.slice(1)} ${m[2]}`;\n return model;\n}\n\nfunction getThinkingLabel(thinking: ThinkingConfig): string {\n if (thinking.type === \"disabled\") return \"\";\n if (thinking.type === \"adaptive\") return \"thinking\";\n return thinking.budgetTokens\n ? `thinking (${Math.round(thinking.budgetTokens / 1024)}k)`\n : \"thinking\";\n}\n\nfunction shortPath(p: string): string {\n const home = process.env.HOME ?? \"\";\n if (home && p.startsWith(home)) return \"~\" + p.slice(home.length);\n return p;\n}\n\nexport function StatusBar({\n mode,\n model,\n thinking,\n agentState,\n totalTokens,\n connected,\n sessionId,\n workspacePath,\n}: StatusBarProps) {\n const { columns } = useTerminal();\n\n // --- Row 1: left hints · right info ---\n\n // Left\n let leftText: string;\n if (agentState === \"awaiting-input\") {\n leftText = \"y/n to respond\";\n } else if (agentState === \"busy\") {\n leftText = \"esc to interrupt\";\n } else {\n leftText = \"? for shortcuts\";\n }\n\n // Right: model · mode · thinking · tokens\n const thinkingLabel = getThinkingLabel(thinking);\n const modelStr = shortModel(model);\n const tokenStr = totalTokens > 0 ? ` · ${formatTokens(totalTokens)} tokens` : \"\";\n const thinkingStr = thinkingLabel ? ` · ${thinkingLabel}` : \"\";\n const rightPlain = `${modelStr} · ${mode}${thinkingStr}${tokenStr}`;\n\n const gap1 = Math.max(1, columns - leftText.length - rightPlain.length - 2);\n\n // --- Row 2: left empty · right context info ---\n const contextParts: string[] = [];\n if (!connected) contextParts.push(\"disconnected\");\n if (sessionId) contextParts.push(`session: ${sessionId.slice(0, 8)}`);\n const row2Right = contextParts.length > 0\n ? contextParts.join(\" · \")\n : shortPath(workspacePath);\n\n return (\n <Box flexDirection=\"column\" paddingX={1}>\n {/* Row 1 */}\n <Box>\n <Text color={t.hint}>{leftText}</Text>\n <Text>{\" \".repeat(gap1)}</Text>\n {!connected ? (\n <Text color={t.disconnected}>{rightPlain}</Text>\n ) : (\n <Text>\n <Text color={t.hint}>{modelStr} · </Text>\n <Text color={t.mode[mode]}>{mode}</Text>\n {thinkingStr && <Text color={t.hint}>{thinkingStr}</Text>}\n {tokenStr && <Text color={t.hint}>{tokenStr}</Text>}\n </Text>\n )}\n </Box>\n {/* Row 2 */}\n <Box justifyContent=\"flex-end\">\n <Text color={t.hint}>{row2Right}</Text>\n </Box>\n </Box>\n );\n}\n","/**\n * Token formatting utilities\n */\n\nexport function formatTokens(count: number): string {\n if (count === 0) return \"0\";\n return count.toLocaleString(\"en-US\");\n}\n\nexport function formatDuration(startMs: number): string {\n const elapsed = (Date.now() - startMs) / 1000;\n if (elapsed < 60) return `${elapsed.toFixed(1)}s`;\n const mins = Math.floor(elapsed / 60);\n const secs = Math.floor(elapsed % 60);\n return `${mins}m${secs}s`;\n}\n","import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nimport type { PendingUserInput } from \"@jarvis/types\";\nimport { t } from \"../theme\";\n\ninterface PermissionDialogProps {\n input: PendingUserInput;\n onRespond: (action: string, data?: Record<string, unknown>, feedback?: string) => void;\n}\n\nexport function PermissionDialog({ input, onRespond }: PermissionDialogProps) {\n useInput((char) => {\n switch (char.toLowerCase()) {\n case \"y\": onRespond(\"allow\"); break;\n case \"n\": onRespond(\"deny\"); break;\n case \"a\": onRespond(\"allow\", { always: true }); break;\n }\n });\n\n const toolName = input.toolName ?? \"unknown\";\n const description = getInputDescription(input);\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>{\"╭─ \"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.dialogTitle} bold>Jarvis wants to use: {toolName}</Text>\n </Box>\n {description && (\n <>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n {description.split(\"\\n\").map((line, i) => (\n <Box key={i}>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text>{line}</Text>\n </Box>\n ))}\n </>\n )}\n {input.ui?.data != null && (\n <>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text dimColor>{truncate(JSON.stringify(input.ui.data, null, 2), 500)}</Text>\n </Box>\n </>\n )}\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.toolSuccess} bold>Allow (y)</Text>\n <Text>{\" \"}</Text>\n <Text color={t.dialogDanger} bold>Reject (n)</Text>\n <Text>{\" \"}</Text>\n <Text color={t.dialogAction} bold>Always allow (a)</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"╰─\"}</Text>\n </Box>\n );\n}\n\nfunction getInputDescription(input: PendingUserInput): string | null {\n const toolName = input.toolName ?? \"\";\n const inp = input.input ?? {};\n\n switch (toolName) {\n case \"Bash\":\n return `Command: ${inp.command ?? \"\"}${inp.description ? `\\nDescription: ${inp.description}` : \"\"}`;\n case \"Write\": return `File: ${inp.file_path ?? \"\"}`;\n case \"Edit\": return `File: ${inp.file_path ?? \"\"}`;\n case \"NotebookEdit\": return `Notebook: ${inp.notebook_path ?? \"\"}`;\n default:\n if (input.reason) return input.reason;\n return null;\n }\n}\n\nfunction truncate(str: string, max: number): string {\n if (str.length <= max) return str;\n return str.slice(0, max - 3) + \"...\";\n}\n","import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nimport type { PendingUserInput } from \"@jarvis/types\";\nimport { t } from \"../theme\";\n\ninterface PlanReviewProps {\n input: PendingUserInput;\n onRespond: (action: string, data?: Record<string, unknown>, feedback?: string) => void;\n}\n\nexport function PlanReview({ input, onRespond }: PlanReviewProps) {\n useInput((char) => {\n switch (char.toLowerCase()) {\n case \"y\": onRespond(\"allow\"); break;\n case \"n\": onRespond(\"deny\"); break;\n }\n });\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>{\"╭─ Plan ─\"}</Text>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n {input.items?.map((item, i) => (\n <Box key={item.id}>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text>{i + 1}. {item.title}</Text>\n </Box>\n ))}\n {input.reason && !input.items?.length && (\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text>{input.reason}</Text>\n </Box>\n )}\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.toolSuccess} bold>Approve plan (y)</Text>\n <Text>{\" \"}</Text>\n <Text color={t.dialogDanger} bold>Reject (n)</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"╰─\"}</Text>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nimport type { PendingUserInput } from \"@jarvis/types\";\nimport { t } from \"../theme\";\n\ninterface MaxIterationsProps {\n input: PendingUserInput;\n onRespond: (action: string, data?: Record<string, unknown>) => void;\n}\n\nexport function MaxIterations({ input, onRespond }: MaxIterationsProps) {\n useInput((char) => {\n switch (char.toLowerCase()) {\n case \"y\": onRespond(\"allow\"); break;\n case \"n\": onRespond(\"deny\"); break;\n }\n });\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>{\"╭─ \"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.dialogTitle} bold>\n Reached {input.iteration ?? \"?\"}/{input.maxIterations ?? \"?\"} turns\n </Text>\n </Box>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text>Continue for {input.initialMaxIterations ?? input.maxIterations ?? 25} more turns?</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.toolSuccess} bold>Continue (y)</Text>\n <Text>{\" \"}</Text>\n <Text color={t.dialogDanger} bold>Stop (n)</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"╰─\"}</Text>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nimport { t } from \"../theme\";\n\ninterface HelpMenuProps {\n onClose: () => void;\n}\n\nconst COMMANDS: [string, string][] = [\n [\"/config\", \"Open settings (model, thinking, mode)\"],\n [\"/model\", \"Quick model switch\"],\n [\"/mode\", \"Quick permission mode switch\"],\n [\"/thinking\", \"Toggle thinking config\"],\n [\"/status\", \"Show connection & session info\"],\n [\"/clear\", \"Clear conversation history and free up context\"],\n [\"/compact\", \"Compact old messages\"],\n [\"/help\", \"Show this help\"],\n [\"/exit\", \"Exit Jarvis\"],\n];\n\nexport function HelpMenu({ onClose }: HelpMenuProps) {\n useInput((_input, key) => {\n if (key.escape || _input === \"q\" || key.return) onClose();\n });\n\n return (\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={1}>\n {COMMANDS.map(([cmd, desc]) => (\n <Box key={cmd}>\n <Text color={t.command}>{cmd!.padEnd(16)}</Text>\n <Text>{desc}</Text>\n </Box>\n ))}\n <Box marginTop={1}>\n <Text color={t.hint}>Shift+Tab to cycle modes · Ctrl+C to interrupt · Esc to close</Text>\n </Box>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nimport type { TuiSettings } from \"../settings\";\nimport { formatTokens } from \"../utils/format-tokens\";\nimport { t } from \"../theme\";\n\ninterface StatusDisplayProps {\n settings: TuiSettings;\n connected: boolean;\n port: number;\n sessionId: string | null;\n totalTokens: number;\n workspacePath: string;\n onClose: () => void;\n}\n\nexport function StatusDisplay({\n settings,\n connected,\n port,\n sessionId,\n totalTokens,\n workspacePath,\n onClose,\n}: StatusDisplayProps) {\n useInput((_input, key) => {\n if (key.escape || _input === \"q\") onClose();\n });\n\n const thinkingLabel =\n settings.thinking.type === \"enabled\"\n ? `enabled (${settings.thinking.budgetTokens ?? 32768})`\n : settings.thinking.type;\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>\n {\"┌─ \"}\n <Text color={t.dialogTitle}>Jarvis Status</Text>\n {\" ─\"}\n </Text>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n {[\n [\"Agent\", `ws://127.0.0.1:${port} (${connected ? \"connected\" : \"disconnected\"})`],\n [\"Session\", sessionId ?? \"none\"],\n [\"Model\", settings.model],\n [\"Mode\", settings.permissionMode],\n [\"Thinking\", thinkingLabel],\n [\"Max turns\", String(settings.maxTurns)],\n [\"Workspace\", workspacePath],\n [\"Tokens used\", `${formatTokens(totalTokens)} (session)`],\n ].map(([label, value]) => (\n <Box key={label}>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text bold>{label!.padEnd(14)}</Text>\n <Text dimColor>{value}</Text>\n </Box>\n ))}\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.hint}>Press Esc or q to close</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"└─\"}</Text>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport SelectInput from \"ink-select-input\";\n\nimport { t } from \"../theme\";\n\ninterface ModelPickerProps {\n currentModel: string;\n onSelect: (model: string) => void;\n onClose: () => void;\n}\n\nconst MODELS = [\n { label: \"claude-sonnet-4-20250514\", value: \"claude-sonnet-4-20250514\" },\n { label: \"claude-opus-4-20250514\", value: \"claude-opus-4-20250514\" },\n { label: \"claude-haiku-4-5-20251001\", value: \"claude-haiku-4-5-20251001\" },\n];\n\nexport function ModelPicker({ currentModel, onSelect, onClose }: ModelPickerProps) {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>{\"┌─ \"}<Text color={t.dialogTitle}>Model</Text>{\" ─\"}</Text>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text dimColor>Current: {currentModel}</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box paddingLeft={2}>\n <SelectInput\n items={MODELS}\n initialIndex={MODELS.findIndex((m) => m.value === currentModel)}\n onSelect={(item) => { onSelect(item.value); onClose(); }}\n />\n </Box>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.hint}>↑/↓ select · Enter confirm · Esc cancel</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"└─\"}</Text>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport SelectInput from \"ink-select-input\";\n\nimport type { PermissionMode } from \"../settings\";\nimport { t } from \"../theme\";\n\ninterface ModePickerProps {\n currentMode: PermissionMode;\n onSelect: (mode: PermissionMode) => void;\n onClose: () => void;\n}\n\nconst MODES = [\n { label: \"Supervised — Ask before dangerous tools\", value: \"supervised\" as const },\n { label: \"Auto — Auto-approve safe tools\", value: \"auto\" as const },\n { label: \"Plan — Plan first, then execute\", value: \"plan\" as const },\n { label: \"Yolo — Bypass all permissions\", value: \"yolo\" as const },\n];\n\nexport function ModePicker({ currentMode, onSelect, onClose }: ModePickerProps) {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>{\"┌─ \"}<Text color={t.dialogTitle}>Permission Mode</Text>{\" ─\"}</Text>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box paddingLeft={2}>\n <SelectInput\n items={MODES}\n initialIndex={MODES.findIndex((m) => m.value === currentMode)}\n onSelect={(item) => { onSelect(item.value); onClose(); }}\n />\n </Box>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.hint}>↑/↓ select · Enter confirm · Esc cancel</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"└─\"}</Text>\n </Box>\n );\n}\n","import React from \"react\";\nimport { Box, Text } from \"ink\";\nimport SelectInput from \"ink-select-input\";\n\nimport type { ThinkingConfig } from \"@jarvis/types\";\nimport { t } from \"../theme\";\n\ninterface ThinkingPickerProps {\n current: ThinkingConfig;\n onSelect: (config: ThinkingConfig) => void;\n onClose: () => void;\n}\n\nconst OPTIONS = [\n { label: \"Adaptive — Model decides when to think\", value: \"adaptive\" },\n { label: \"Enabled — Always think (budget: 32768)\", value: \"enabled\" },\n { label: \"Disabled — No extended thinking\", value: \"disabled\" },\n];\n\nexport function ThinkingPicker({ current, onSelect, onClose }: ThinkingPickerProps) {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>{\"┌─ \"}<Text color={t.dialogTitle}>Thinking</Text>{\" ─\"}</Text>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box paddingLeft={2}>\n <SelectInput\n items={OPTIONS}\n initialIndex={OPTIONS.findIndex((o) => o.value === current.type)}\n onSelect={(item) => {\n const config: ThinkingConfig = { type: item.value as ThinkingConfig[\"type\"] };\n if (item.value === \"enabled\") config.budgetTokens = 32768;\n onSelect(config);\n onClose();\n }}\n />\n </Box>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.hint}>↑/↓ select · Enter confirm · Esc cancel</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"└─\"}</Text>\n </Box>\n );\n}\n","import React, { useState } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport SelectInput from \"ink-select-input\";\n\nimport type { ThinkingConfig } from \"@jarvis/types\";\nimport type { PermissionMode, TuiSettings } from \"../settings\";\nimport { t } from \"../theme\";\n\ninterface SettingsDialogProps {\n settings: TuiSettings;\n onUpdateModel: (model: string) => void;\n onUpdateThinking: (thinking: ThinkingConfig) => void;\n onUpdateMode: (mode: PermissionMode) => void;\n onUpdateMaxTurns: (turns: number) => void;\n onClose: () => void;\n}\n\ntype Section = \"model\" | \"thinking\" | \"mode\" | \"maxTurns\";\nconst SECTIONS: Section[] = [\"model\", \"thinking\", \"mode\", \"maxTurns\"];\n\nconst MODELS = [\n { label: \"claude-sonnet-4-20250514\", value: \"claude-sonnet-4-20250514\" },\n { label: \"claude-opus-4-20250514\", value: \"claude-opus-4-20250514\" },\n { label: \"claude-haiku-4-5-20251001\", value: \"claude-haiku-4-5-20251001\" },\n];\n\nconst THINKING_OPTIONS = [\n { label: \"Adaptive — Model decides\", value: \"adaptive\" },\n { label: \"Enabled — Always (32k budget)\", value: \"enabled\" },\n { label: \"Disabled — Never\", value: \"disabled\" },\n];\n\nconst MODE_OPTIONS = [\n { label: \"Supervised\", value: \"supervised\" },\n { label: \"Auto\", value: \"auto\" },\n { label: \"Plan\", value: \"plan\" },\n { label: \"Yolo\", value: \"yolo\" },\n];\n\nconst MAX_TURNS_OPTIONS = [\n { label: \"10\", value: \"10\" },\n { label: \"25 (default)\", value: \"25\" },\n { label: \"50\", value: \"50\" },\n { label: \"100\", value: \"100\" },\n { label: \"200\", value: \"200\" },\n];\n\nexport function SettingsDialog({\n settings,\n onUpdateModel,\n onUpdateThinking,\n onUpdateMode,\n onUpdateMaxTurns,\n onClose,\n}: SettingsDialogProps) {\n const [activeSection, setActiveSection] = useState<Section>(\"model\");\n\n useInput((_input, key) => {\n if (key.escape) onClose();\n if (key.tab) {\n const idx = SECTIONS.indexOf(activeSection);\n setActiveSection(SECTIONS[(idx + 1) % SECTIONS.length]!);\n }\n });\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color={t.dialogBorder}>\n {\"╭─ \"}\n <Text color={t.dialogTitle}>Settings</Text>\n {\" ─\"}\n </Text>\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n\n {/* Model */}\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text bold color={activeSection === \"model\" ? t.dialogTitle : undefined}>\n Model\n </Text>\n </Box>\n {activeSection === \"model\" && (\n <Box paddingLeft={4}>\n <SelectInput\n items={MODELS}\n initialIndex={MODELS.findIndex((m) => m.value === settings.model)}\n onSelect={(item) => onUpdateModel(item.value)}\n />\n </Box>\n )}\n\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n\n {/* Thinking */}\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text bold color={activeSection === \"thinking\" ? t.dialogTitle : undefined}>\n Thinking\n </Text>\n </Box>\n {activeSection === \"thinking\" && (\n <Box paddingLeft={4}>\n <SelectInput\n items={THINKING_OPTIONS}\n initialIndex={THINKING_OPTIONS.findIndex((o) => o.value === settings.thinking.type)}\n onSelect={(item) => {\n const config: ThinkingConfig = { type: item.value as ThinkingConfig[\"type\"] };\n if (item.value === \"enabled\") config.budgetTokens = 32768;\n onUpdateThinking(config);\n }}\n />\n </Box>\n )}\n\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n\n {/* Permission Mode */}\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text bold color={activeSection === \"mode\" ? t.dialogTitle : undefined}>\n Permission Mode\n </Text>\n </Box>\n {activeSection === \"mode\" && (\n <Box paddingLeft={4}>\n <SelectInput\n items={MODE_OPTIONS}\n initialIndex={MODE_OPTIONS.findIndex((m) => m.value === settings.permissionMode)}\n onSelect={(item) => onUpdateMode(item.value as PermissionMode)}\n />\n </Box>\n )}\n\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n\n {/* Max Turns */}\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text bold color={activeSection === \"maxTurns\" ? t.dialogTitle : undefined}>\n Max Turns\n </Text>\n </Box>\n {activeSection === \"maxTurns\" && (\n <Box paddingLeft={4}>\n <SelectInput\n items={MAX_TURNS_OPTIONS}\n initialIndex={MAX_TURNS_OPTIONS.findIndex((o) => o.value === String(settings.maxTurns))}\n onSelect={(item) => onUpdateMaxTurns(parseInt(item.value, 10))}\n />\n </Box>\n )}\n\n <Text color={t.dialogBorder}>{\"│\"}</Text>\n <Box>\n <Text color={t.dialogBorder}>{\"│ \"}</Text>\n <Text color={t.hint}>Tab to switch section · Esc to close</Text>\n </Box>\n <Text color={t.dialogBorder}>{\"╰─\"}</Text>\n </Box>\n );\n}\n","import React, { useEffect, useState } from \"react\";\nimport { Text } from \"ink\";\n\nimport { t } from \"../theme\";\n\ninterface NotificationProps {\n message: string | null;\n duration?: number;\n}\n\nexport function Notification({ message, duration = 2000 }: NotificationProps) {\n const [visible, setVisible] = useState(false);\n const [text, setText] = useState(\"\");\n\n useEffect(() => {\n if (message) {\n setText(message);\n setVisible(true);\n const timer = setTimeout(() => setVisible(false), duration);\n return () => clearTimeout(timer);\n }\n }, [message, duration]);\n\n if (!visible || !text) return null;\n return <Text color={t.notification}>{text}</Text>;\n}\n","/**\n * Markdown Text Renderer\n *\n * Simple terminal markdown: bold, headers, lists, code blocks, inline code.\n * Matches Claude Code's clean output style.\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\n\ninterface MarkdownTextProps {\n content: string;\n}\n\nexport function MarkdownText({ content }: MarkdownTextProps) {\n if (!content) return null;\n\n const lines = content.split(\"\\n\");\n const elements: React.ReactNode[] = [];\n let inCodeBlock = false;\n let codeLines: string[] = [];\n let codeLanguage = \"\";\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!;\n\n // Code block start/end\n if (line.startsWith(\"```\")) {\n if (inCodeBlock) {\n // End code block\n elements.push(\n <Box key={`code-${i}`} flexDirection=\"column\" marginTop={0} marginBottom={0} paddingLeft={2}>\n {codeLanguage && (\n <Text dimColor>{codeLanguage}</Text>\n )}\n {codeLines.map((cl, j) => (\n <Text key={j} color=\"gray\">{cl}</Text>\n ))}\n </Box>,\n );\n codeLines = [];\n codeLanguage = \"\";\n inCodeBlock = false;\n } else {\n inCodeBlock = true;\n codeLanguage = line.slice(3).trim();\n }\n continue;\n }\n\n if (inCodeBlock) {\n codeLines.push(line);\n continue;\n }\n\n // Empty line\n if (line.trim() === \"\") {\n elements.push(<Text key={`empty-${i}`}>{\"\"}</Text>);\n continue;\n }\n\n // Headers\n const h1 = line.match(/^# (.+)/);\n if (h1) {\n elements.push(\n <Text key={`h1-${i}`} bold color=\"white\">\n {renderInline(h1[1]!)}\n </Text>,\n );\n continue;\n }\n\n const h2 = line.match(/^## (.+)/);\n if (h2) {\n elements.push(\n <Text key={`h2-${i}`} bold>\n {renderInline(h2[1]!)}\n </Text>,\n );\n continue;\n }\n\n const h3 = line.match(/^### (.+)/);\n if (h3) {\n elements.push(\n <Text key={`h3-${i}`} bold dimColor>\n {renderInline(h3[1]!)}\n </Text>,\n );\n continue;\n }\n\n // Unordered list items\n const ul = line.match(/^(\\s*)[-*] (.+)/);\n if (ul) {\n const indent = Math.floor((ul[1]?.length ?? 0) / 2);\n elements.push(\n <Box key={`ul-${i}`} paddingLeft={indent * 2}>\n <Text dimColor>{\"– \"}</Text>\n <Text>{renderInline(ul[2]!)}</Text>\n </Box>,\n );\n continue;\n }\n\n // Ordered list items\n const ol = line.match(/^(\\s*)\\d+\\. (.+)/);\n if (ol) {\n const indent = Math.floor((ol[1]?.length ?? 0) / 2);\n const num = line.match(/^(\\s*)(\\d+)\\./);\n elements.push(\n <Box key={`ol-${i}`} paddingLeft={indent * 2}>\n <Text dimColor>{`${num?.[2]}. `}</Text>\n <Text>{renderInline(ol[2]!)}</Text>\n </Box>,\n );\n continue;\n }\n\n // Horizontal rule\n if (/^---+$/.test(line.trim()) || /^\\*\\*\\*+$/.test(line.trim())) {\n elements.push(\n <Text key={`hr-${i}`} dimColor>{\"─\".repeat(40)}</Text>,\n );\n continue;\n }\n\n // Regular paragraph\n elements.push(\n <Text key={`p-${i}`}>{renderInline(line)}</Text>,\n );\n }\n\n return <Box flexDirection=\"column\">{elements}</Box>;\n}\n\n/**\n * Render inline markdown: **bold**, `code`, *italic*\n * Returns a string with ANSI escape sequences.\n *\n * Note: Ink <Text> doesn't support mixed inline styles easily,\n * so we return plain text with markdown stripped for now.\n * Bold is rendered via chalk-style markup.\n */\nfunction renderInline(text: string): string {\n return text\n // Remove bold markers (Ink doesn't support inline bold mixing easily)\n .replace(/\\*\\*(.+?)\\*\\*/g, \"$1\")\n // Remove italic markers\n .replace(/\\*(.+?)\\*/g, \"$1\")\n // Remove inline code markers\n .replace(/`(.+?)`/g, \"$1\");\n}\n"],"mappings":"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","names":["fs","path","spawn","fs","path","os","t","pendingInput","prompt","context","prompt","detectLanguage","fs","path","path","fs","crypto","crypto","provider","execCb","fs","path","promisify","exec","promisify","execCb","path","fs","add","WebSocket","WebSocket","agent","React","render","path","fs","os","WebSocket","fs","path","os","useState","useCallback","useRef","useEffect","Box","Text","useInput","WebSocket","useState","useCallback","useRef","useState","useCallback","useRef","crypto","useState","useCallback","useState","useCallback","Box","Text","jsx","jsxs","Box","Text","useState","useEffect","useRef","Box","Text","jsx","jsxs","useState","useRef","useEffect","Box","Text","Box","Text","useState","useEffect","jsx","Box","Text","React","useState","useCallback","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","path","fs","jsx","jsxs","fs","path","jsx","Box","Text","jsxs","jsx","jsxs","useState","React","useCallback","before","Box","Text","Box","Text","jsx","jsxs","shortModel","shortPath","Box","Text","Box","Text","useInput","jsx","jsxs","useInput","Box","Text","Box","Text","useInput","jsx","jsxs","useInput","Box","Text","Box","Text","useInput","jsx","jsxs","useInput","Box","Text","Box","Text","useInput","jsx","jsxs","useInput","Box","Text","Box","Text","useInput","jsx","jsxs","useInput","Box","Text","Box","Text","jsx","jsxs","Box","Text","Box","Text","SelectInput","jsx","jsxs","Box","Text","SelectInput","Box","Text","SelectInput","jsx","jsxs","Box","Text","SelectInput","useState","Box","Text","useInput","SelectInput","jsx","jsxs","MODELS","useState","useInput","Box","Text","SelectInput","useEffect","useState","Text","jsx","useState","useEffect","Text","Box","Text","jsx","jsxs","Fragment","jsx","jsxs","useState","useRef","useEffect","renderMessage","useCallback","useInput","Box","Text","truncate","render","React","path","os","fs","WebSocket","path","os","fs","spawn","path","fs"]}