jivamai 0.1.4-dev.edce8f4 → 0.2.0-dev.08fad0b
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/assets/index--KfyNhBy.js +31 -0
- package/dist/assets/index-BZnT-rRg.css +10 -0
- package/dist/index.html +2 -2
- package/dist-server/index.js +1 -292
- package/package.json +4 -2
- package/dist/assets/index-CisS1YJo.css +0 -10
- package/dist/assets/index-DftBqc_W.js +0 -510
- package/dist-server/index.js.map +0 -1
- package/docs/README.md +0 -55
- package/docs/architecture/cloud-mode.md +0 -204
- package/docs/architecture/code-agent-integration.md +0 -276
- package/docs/architecture/ipc-contract.md +0 -162
- package/docs/architecture/jiva-core-integration.md +0 -147
- package/docs/architecture/overview.md +0 -87
- package/docs/architecture/startup-flow.md +0 -108
- package/docs/architecture/state-management.md +0 -153
- package/docs/guides/adding-features.md +0 -196
- package/docs/guides/design-guide.md +0 -308
- package/docs/release_notes/.gitkeep +0 -0
package/dist-server/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../server/path-helper.ts","../server/ws.ts","../server/directive-manager.ts","../server/config-manager.ts","../server/harness.ts","../server/code-runner.ts","../server/jiva-runner.ts","../server/cloud-runner.ts","../server/routes/setup.ts","../server/routes/config.ts","../server/routes/conversations.ts","../server/routes/git.ts","../server/routes/directive.ts","../server/routes/workspace.ts","../server/routes/jiva.ts","../server/persona-manager.ts","../server/routes/personas.ts","../server/routes/mcp.ts","../server/routes/code.ts","../server/file-converter.ts","../server/routes/files.ts","../server/cloud-auth.ts","../server/routes/cloud.ts","../server/index.ts"],"sourcesContent":["import { execSync } from 'child_process'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\n\nexport function augmentPath() {\n if (process.platform === 'win32') return\n try {\n const shell = process.env.SHELL ?? '/bin/zsh'\n const shellPath = execSync(`${shell} -l -c 'echo $PATH'`, { timeout: 3000 }).toString().trim()\n if (shellPath) {\n process.env.PATH = shellPath\n return\n }\n } catch {}\n const home = os.homedir()\n const candidates = [\n '/usr/local/bin',\n '/opt/homebrew/bin',\n '/opt/local/bin',\n `${home}/.npm-global/bin`,\n '/usr/local/opt/node/bin',\n ]\n try {\n const nvmDir = path.join(home, '.nvm', 'versions', 'node')\n if (fs.existsSync(nvmDir)) {\n const v = fs.readdirSync(nvmDir).sort().reverse()[0]\n if (v) candidates.push(path.join(nvmDir, v, 'bin'))\n }\n } catch {}\n const current = process.env.PATH ?? ''\n const existing = new Set(current.split(':').filter(Boolean))\n const toAdd = candidates.filter(p => !existing.has(p))\n if (toAdd.length) process.env.PATH = [...toAdd, current].join(':')\n}\n","import { WebSocketServer, WebSocket } from 'ws'\nimport type { IncomingMessage } from 'http'\nimport type { Server } from 'http'\n\nlet wss: WebSocketServer | null = null\nconst clients = new Set<WebSocket>()\n\nexport function initWebSocketServer(server: Server) {\n wss = new WebSocketServer({ server, path: '/ws' })\n wss.on('connection', (ws: WebSocket, _req: IncomingMessage) => {\n clients.add(ws)\n ws.on('close', () => clients.delete(ws))\n ws.on('error', () => clients.delete(ws))\n })\n}\n\nexport function broadcast(type: string, payload: unknown) {\n if (!wss) return\n const msg = JSON.stringify({ type, ...( payload !== null && typeof payload === 'object' ? payload : { data: payload }) })\n for (const client of clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(msg)\n }\n }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport os from 'os'\n\nconst JIVA_DIR = path.join(os.homedir(), '.jiva')\nconst DIRECTIVE_PATH = path.join(JIVA_DIR, 'jiva-directive.md')\nconst CONVERSATIONS_DIR = path.join(JIVA_DIR, 'conversations')\n\ninterface ConversationMeta {\n date: string\n title: string\n messageCount: number\n}\n\n/**\n * Read the last N conversation files (sorted by modified time, newest first)\n * and extract metadata for the activity table.\n */\nfunction readRecentConversations(limit = 5): ConversationMeta[] {\n try {\n if (!fs.existsSync(CONVERSATIONS_DIR)) return []\n\n const files = fs\n .readdirSync(CONVERSATIONS_DIR)\n .filter((f) => f.endsWith('.json'))\n .map((f) => {\n const filePath = path.join(CONVERSATIONS_DIR, f)\n try {\n const stat = fs.statSync(filePath)\n const raw = JSON.parse(fs.readFileSync(filePath, 'utf-8'))\n const messageCount: number = Array.isArray(raw.messages) ? raw.messages.length : 0\n // Use summary or title from the file, fallback to first user message content\n let title: string = raw.summary ?? raw.title ?? ''\n if (!title && Array.isArray(raw.messages)) {\n const firstUser = raw.messages.find(\n (m: { role?: string; content?: string }) => m.role === 'user'\n )\n if (firstUser?.content) {\n title = String(firstUser.content).slice(0, 60).replace(/\\n/g, ' ')\n if (String(firstUser.content).length > 60) title += '...'\n }\n }\n title = title || 'Untitled conversation'\n return { stat, title, messageCount }\n } catch {\n return null\n }\n })\n .filter(Boolean)\n .sort((a, b) => b!.stat.mtimeMs - a!.stat.mtimeMs)\n .slice(0, limit)\n\n return (files as NonNullable<(typeof files)[number]>[]).map(({ stat, title, messageCount }) => {\n const d = new Date(stat.mtimeMs)\n const date = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`\n return { date, title, messageCount }\n })\n } catch {\n return []\n }\n}\n\n/**\n * Build the content of the date-aware jiva-directive.md.\n * @param userDirective Optional user-authored instructions prepended before the dynamic context block.\n */\nexport function buildDirectiveContent(userDirective?: string): string {\n const now = new Date()\n\n const weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']\n const months = [\n 'January', 'February', 'March', 'April', 'May', 'June',\n 'July', 'August', 'September', 'October', 'November', 'December',\n ]\n\n const weekday = weekdays[now.getDay()]\n const month = months[now.getMonth()]\n const day = now.getDate()\n const year = now.getFullYear()\n const hours = String(now.getHours()).padStart(2, '0')\n const minutes = String(now.getMinutes()).padStart(2, '0')\n const time = `${hours}:${minutes}`\n\n // Get timezone abbreviation (e.g. \"IST\", \"UTC\", \"EST\")\n let timezone = 'UTC'\n try {\n timezone = Intl.DateTimeFormat('en', { timeZoneName: 'short' })\n .formatToParts(now)\n .find((p) => p.type === 'timeZoneName')?.value ?? 'UTC'\n } catch {\n // Fallback to UTC offset\n const offset = -now.getTimezoneOffset()\n const sign = offset >= 0 ? '+' : '-'\n const absH = String(Math.floor(Math.abs(offset) / 60)).padStart(2, '0')\n const absM = String(Math.abs(offset) % 60).padStart(2, '0')\n timezone = `UTC${sign}${absH}:${absM}`\n }\n\n const iso = now.toISOString()\n\n // Build recent activity table\n const recent = readRecentConversations(5)\n let recentActivity: string\n if (recent.length === 0) {\n recentActivity = '_No previous sessions found._'\n } else {\n const rows = recent\n .map((c) => `| ${c.date} | \"${c.title}\" | ${c.messageCount} |`)\n .join('\\n')\n recentActivity = `| Date | Title | Messages |\\n|------|-------|----------|\\n${rows}`\n }\n\n const dynamicContext = `# Jiva Operating Context\n\n## Current Date & Time\n- Date: ${weekday}, ${month} ${day}, ${year}\n- Time: ${time} ${timezone}\n- ISO: ${iso}\n\n## Important\n- Always use the date above when referencing \"today\", \"current year\", or \"recent\" events\n- Do NOT rely on training data for the current date — use only what is stated above\n- When performing web searches, always use the year ${year} for current events\n\n## Recent Session Activity\n${recentActivity}\n`\n\n if (userDirective?.trim()) {\n return userDirective.trim() + '\\n\\n---\\n\\n' + dynamicContext\n }\n return dynamicContext\n}\n\n/**\n * Write the date-aware directive to ~/.jiva/jiva-directive.md and return the path.\n * This is called before WorkspaceManager.initialize() so the directive is picked up\n * as a system-level instruction for the agent.\n */\nexport function writeDirective(userDirective?: string): { path: string; content: string } {\n const content = buildDirectiveContent(userDirective)\n try {\n if (!fs.existsSync(JIVA_DIR)) {\n fs.mkdirSync(JIVA_DIR, { recursive: true })\n }\n fs.writeFileSync(DIRECTIVE_PATH, content, 'utf-8')\n console.log(`[DirectiveManager] Wrote directive to ${DIRECTIVE_PATH}`)\n } catch (err) {\n console.warn('[DirectiveManager] Failed to write directive:', err)\n }\n return { path: DIRECTIVE_PATH, content }\n}\n","import fs from 'fs'\nimport path from 'path'\nimport os from 'os'\n\n/** Returns the Jivam-specific config path (separate from jiva-core's global config). */\nexport function getJivamConfigPath(): string {\n return path.join(os.homedir(), '.jivam', 'config.json')\n}\n\n/**\n * Returns the path where jiva-core (the CLI) stores its own config.\n * Used for one-time migration only — Jivam never writes here directly.\n */\nexport function getJivaCoreConfigPath(): string {\n switch (process.platform) {\n case 'win32': {\n const appData = process.env.APPDATA ?? path.join(os.homedir(), 'AppData', 'Roaming')\n return path.join(appData, 'jiva-nodejs', 'Config', 'config.json')\n }\n case 'darwin':\n return path.join(os.homedir(), 'Library', 'Preferences', 'jiva-nodejs', 'config.json')\n default:\n return path.join(\n process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), '.config'),\n 'jiva-nodejs', 'config.json'\n )\n }\n}\n\n/** @deprecated Use getJivamConfigPath() — kept for callers that haven't migrated yet */\nexport function getJivaConfigPath(): string {\n return getJivamConfigPath()\n}\n\n/**\n * On first run: if ~/.jivam/config.json doesn't exist but jiva-core's config does,\n * copy it so the user's existing `jiva setup` credentials carry over.\n * Jivam will manage its own copy from that point on.\n */\nexport function migrateFromJivaCoreIfNeeded(): void {\n const jivamPath = getJivamConfigPath()\n if (fs.existsSync(jivamPath)) return // already set up, nothing to do\n\n const jivaCorePath = getJivaCoreConfigPath()\n if (!fs.existsSync(jivaCorePath)) return // no jiva-core config to import\n\n try {\n const dir = path.dirname(jivamPath)\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n fs.copyFileSync(jivaCorePath, jivamPath)\n console.log('[ConfigManager] Imported config from jiva-core:', jivamPath)\n } catch (err) {\n console.warn('[ConfigManager] Could not migrate jiva-core config:', err)\n }\n}\n\nconst JIVAM_CONFIG_PATH = getJivamConfigPath()\n\nexport interface JivaReasoningConfig {\n provider?: string\n apiKey?: string\n endpoint?: string\n defaultModel?: string\n model?: string // legacy alias — jiva-core reads defaultModel\n useHarmonyFormat?: boolean\n reasoningEffortStrategy?: string\n defaultMaxTokens?: number\n name?: string\n type?: string\n}\n\nexport interface JivaMultimodalConfig {\n apiKey?: string\n endpoint?: string\n defaultModel?: string\n name?: string\n type?: string\n}\n\nexport interface JivaConfig {\n models: {\n reasoning: JivaReasoningConfig | null\n multimodal?: JivaMultimodalConfig | null\n toolCalling?: unknown\n }\n mcpServers?: Record<string, {\n command?: string // stdio servers: present; http servers: absent\n args?: string[]\n env?: Record<string, string>\n url?: string // http servers\n enabled: boolean\n }>\n workspaceDir?: string // configurable workspace directory for the Files browser\n userDirective?: string // user-authored directive prefix, prepended before dynamic context\n debug?: boolean\n autoSave?: boolean\n}\n\nexport function readConfig(): JivaConfig | null {\n try {\n const configPath = getJivamConfigPath()\n if (fs.existsSync(configPath)) {\n const raw = fs.readFileSync(configPath, 'utf-8')\n return JSON.parse(raw) as JivaConfig\n }\n return null\n } catch (err) {\n console.error('[ConfigManager] Failed to read config:', err)\n return null\n }\n}\n\nexport function writeConfig(config: JivaConfig): boolean {\n try {\n const configPath = getJivamConfigPath()\n const dir = path.dirname(configPath)\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true })\n }\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf-8')\n return true\n } catch (err) {\n console.error('[ConfigManager] Failed to write config:', err)\n return false\n }\n}\n","import fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport type { CodeLogEvent } from '../src/types/electron'\n\nexport interface Skill {\n name: string\n description: string\n dir: string\n}\n\n// Provided by the runner so harness can call the model without knowing jiva-core internals.\n// Returns the model's text response, or null on failure.\nexport type Completer = (systemPrompt: string, userPrompt: string) => Promise<string | null>\n\n// Internal types for the brain's task decomposition\ninterface SubtaskSpec {\n id: number\n label: string\n prompt: string\n complexity?: 'simple' | 'medium' | 'complex'\n}\n\ninterface McpRecommendation {\n name: string // npm package / server name (e.g. \"@modelcontextprotocol/server-github\")\n reason: string // one sentence: why this server would help\n}\n\ninterface SubtaskPlan {\n mode: 'direct' | 'delegate'\n subtasks: SubtaskSpec[]\n reasoning: string\n explanation: string // human-readable thought process emitted to the user\n directResponse?: string // populated when mode === 'direct'\n mcpRecommendations?: McpRecommendation[] // suggested MCP servers the user should configure\n}\n\nlet skillCache: Skill[] | null = null\n\nfunction parseFrontmatter(content: string): Record<string, string> {\n const match = /^---\\s*\\n([\\s\\S]*?)\\n---/.exec(content)\n if (!match) return {}\n const result: Record<string, string> = {}\n for (const line of match[1].split('\\n')) {\n const colon = line.indexOf(':')\n if (colon === -1) continue\n const key = line.slice(0, colon).trim()\n const value = line.slice(colon + 1).trim().replace(/^[\"']|[\"']$/g, '')\n if (key) result[key] = value\n }\n return result\n}\n\nexport async function discoverSkills(): Promise<Skill[]> {\n if (skillCache !== null) return skillCache\n\n const searchDirs = [\n path.join(os.homedir(), '.claude', 'skills'),\n path.join(os.homedir(), '.jiva', 'skills'),\n ]\n\n const skills: Skill[] = []\n\n for (const dir of searchDirs) {\n if (!fs.existsSync(dir)) continue\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true })\n } catch {\n continue\n }\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n const skillDir = path.join(dir, entry.name)\n const skillMdPath = path.join(skillDir, 'SKILL.md')\n if (!fs.existsSync(skillMdPath)) continue\n try {\n const content = fs.readFileSync(skillMdPath, 'utf-8')\n const fm = parseFrontmatter(content)\n const name = fm.name ?? entry.name\n const description = fm.description ?? ''\n skills.push({ name, description, dir: skillDir })\n } catch {\n // skip unreadable skill\n }\n }\n }\n\n skillCache = skills\n return skills\n}\n\nfunction emitBrain(msg: string, onBrainLog: (e: CodeLogEvent) => void): void {\n onBrainLog({\n timestamp: new Date().toISOString(),\n level: 'info',\n tag: 'brain',\n message: msg,\n })\n}\n\n// Words that only appear in conversational/acknowledgment messages.\n// If ALL words in a short message are in this set we bypass planning entirely.\nconst CONVO_SAFE_WORDS = new Set([\n // Thanks\n 'thanks', 'thank', 'you', 'ty',\n // Acknowledgments\n 'ok', 'okay', 'alright', 'right', 'sure', 'yep', 'yup', 'yeah', 'nope',\n // Positive reactions\n 'great', 'good', 'nice', 'cool', 'perfect', 'awesome', 'excellent',\n 'fantastic', 'wonderful', 'brilliant', 'well', 'done', 'job', 'work',\n // Sign-offs\n 'bye', 'goodbye', 'later', 'cheers', 'ciao',\n // \"No problem\" / \"You're welcome\"\n 'welcome', 'problem', 'np', 'worries', 'no',\n // Session-end phrases: \"we are done for this session\", \"that's all\"\n 'we', 'are', 'were', 'finished', 'this', 'is', 'the', 'end',\n 'session', 'all', 'that', 'it', 'for', 'our', 'now', 'here',\n // Misc conversational\n 'got', 'sounds', 'lol', 'haha', 'heh', 'wow', 'oh', 'ah', 'hmm',\n 'a', 'an', 'and', 'or', 'but', 'very', 'much', 'so', 'yes', 's',\n])\n\n/**\n * Returns true for messages like \"alright thanks\", \"great work, we are done\",\n * \"cheers\", \"ok\", etc. — messages where every word is a safe conversational word\n * and the total length is short. These skip planExecution() entirely.\n */\nfunction looksConversational(prompt: string): boolean {\n const trimmed = prompt.trim()\n if (trimmed.length > 80) return false\n const words = trimmed.toLowerCase().replace(/[^a-z'\\s]/g, '').trim().split(/\\s+/)\n if (words.length === 0 || words.length > 12) return false\n return words.every(w => CONVO_SAFE_WORDS.has(w))\n}\n\n// Extract a brief meaningful summary from an agent result (first non-empty line of substance)\nfunction extractSummary(content: string, maxLen = 140): string {\n const lines = content.split('\\n')\n for (const line of lines) {\n const trimmed = line.replace(/^#+\\s*/, '').replace(/\\*\\*/g, '').trim()\n if (trimmed.length >= 20) {\n return trimmed.length > maxLen ? trimmed.slice(0, maxLen - 1) + '…' : trimmed\n }\n }\n return content.slice(0, maxLen)\n}\n\nasync function planExecution(\n userPrompt: string,\n skills: Skill[],\n completer: Completer,\n onBrainLog: (e: CodeLogEvent) => void,\n conversationContext?: string,\n configuredMcpServers?: string[]\n): Promise<SubtaskPlan> {\n const skillList = skills.length > 0\n ? skills.map(s => `- ${s.name} (${s.dir}): ${s.description}`).join('\\n')\n : '(none available)'\n\n const contextSection = conversationContext\n ? `\\nConversation history so far:\\n${conversationContext}\\n`\n : ''\n\n const mcpSection = configuredMcpServers && configuredMcpServers.length > 0\n ? `\\nConfigured MCP servers (tools the agent already has access to): ${configuredMcpServers.join(', ')}`\n : `\\nConfigured MCP servers: none beyond built-in filesystem and shell.`\n\n const systemPrompt = `You are a senior AI coordinator. Your first job is to decide whether to answer the user DIRECTLY or DELEGATE the task to a capable AI coding worker.${contextSection}\nANSWER DIRECTLY (mode: \"direct\") when the message is:\n- Conversational: greetings, thanks, sign-offs, \"great work\", \"we're done\", smalltalk\n- Simple follow-up you can answer from the conversation context above (\"what did you find?\", \"how many issues?\")\n- Meta-questions about the session: \"are we done?\", \"can you summarise what we covered?\"\n- Anything that would be bizarre to run shell commands for\n\nDELEGATE (mode: \"delegate\") when the message genuinely requires:\n- Code execution, file operations, web research, data analysis\n- Reading, writing, or modifying files in a workspace\n- Iterative tool use, running tests, building, or searching\n\nFor DIRECT: write a warm, natural response in \"directResponse\". Be concise.\nFor DELEGATE: decompose into 1-5 focused subtasks. Prefer 1 subtask unless distinct phases are truly needed.\n\nRules for delegation:\n- Each subtask prompt must be self-contained and include all relevant context.\n- Write subtask prompts as clean, direct task instructions — no internal headers (\"Goal:\", \"Requirements:\", \"Planned Subtask for the Worker\"), no scaffolding phrases (\"Please proceed with...\", \"Once the results are returned, I will review them\", \"provide the final response to the user\"). Brief the worker as you would a colleague: just the task.\n- \"explanation\" is 1-2 plain-English sentences for the user about your approach.\n- Set \"complexity\" per subtask: \"simple\" for quick single-file edits, \"complex\" for multi-file refactors or build cycles, \"medium\" for everything else.\n- Respond with valid JSON only. No markdown fences.\n${mcpSection}\n\nMCP recommendations: If the user's request would be meaningfully better with an MCP server that is NOT currently configured (e.g. they want to browse the web but no browser MCP is present, interact with GitHub but no GitHub MCP is set up, send Slack messages, query databases, etc.), include an \"mcpRecommendations\" array. Each entry: {\"name\":\"package-or-server-name\",\"reason\":\"one sentence why\"}. Only recommend when genuinely useful — skip for tasks that can be done with the current tools. The user can discover and install MCP servers at https://mcpservers.org and configure them in Jivam via Settings (gear icon) → MCPs.\n\nAvailable skills:\n${skillList}`\n\n const userMsg = `User message:\n${userPrompt}\n\nRespond with JSON exactly (use the mode that fits):\n{\"mode\":\"direct\",\"reasoning\":\"one sentence\",\"explanation\":\"1-2 sentences for the user\",\"directResponse\":\"full warm response to the user\",\"subtasks\":[]}\nOR\n{\"mode\":\"delegate\",\"reasoning\":\"one sentence\",\"explanation\":\"1-2 sentences for the user\",\"subtasks\":[{\"id\":1,\"label\":\"short 3-6 word label\",\"prompt\":\"full focused self-contained prompt\",\"complexity\":\"simple|medium|complex\"}],\"mcpRecommendations\":[{\"name\":\"server-name\",\"reason\":\"why it helps\"}]}`\n\n const fallback: SubtaskPlan = {\n mode: 'delegate',\n reasoning: 'Proceeding as a single task',\n explanation: 'On it...',\n subtasks: [{ id: 1, label: 'completing your request', prompt: userPrompt }],\n }\n\n try {\n const raw = await completer(systemPrompt, userMsg)\n if (!raw) return fallback\n\n const cleaned = raw.trim().replace(/^```json\\s*|\\s*```$/g, '')\n const parsed = JSON.parse(cleaned) as {\n mode?: string\n reasoning?: string\n explanation?: string\n directResponse?: string\n subtasks?: Array<{ id?: number; label?: string; prompt?: string; complexity?: string }>\n mcpRecommendations?: Array<{ name?: string; reason?: string }>\n }\n\n const mode = parsed.mode === 'direct' ? 'direct' : 'delegate'\n const reasoning = typeof parsed.reasoning === 'string' ? parsed.reasoning : ''\n const explanation = typeof parsed.explanation === 'string' && parsed.explanation\n ? parsed.explanation\n : mode === 'direct' ? 'Answering this directly.' : 'Handling this as a single focused task.'\n\n // Parse optional MCP recommendations\n const mcpRecommendations: McpRecommendation[] | undefined =\n Array.isArray(parsed.mcpRecommendations)\n ? parsed.mcpRecommendations\n .filter(r => typeof r.name === 'string' && r.name.trim())\n .map(r => ({ name: r.name as string, reason: typeof r.reason === 'string' ? r.reason : '' }))\n : undefined\n\n // Direct response path — no worker needed\n if (mode === 'direct') {\n const directResponse = typeof parsed.directResponse === 'string' ? parsed.directResponse : ''\n return { mode: 'direct', reasoning, explanation, directResponse, subtasks: [], mcpRecommendations }\n }\n\n // Delegate path — parse subtasks\n if (!Array.isArray(parsed.subtasks) || parsed.subtasks.length === 0) return fallback\n\n const subtasks: SubtaskSpec[] = parsed.subtasks\n .filter(s => typeof s.label === 'string' && typeof s.prompt === 'string')\n .map((s, i) => ({\n id: typeof s.id === 'number' ? s.id : i + 1,\n label: s.label as string,\n prompt: s.prompt as string,\n complexity: (s.complexity === 'simple' || s.complexity === 'medium' || s.complexity === 'complex')\n ? s.complexity\n : 'medium',\n }))\n\n if (subtasks.length === 0) return fallback\n\n const plan: SubtaskPlan = { mode: 'delegate', reasoning, explanation, subtasks, mcpRecommendations }\n return plan\n } catch {\n return fallback\n }\n}\n\nasync function synthesize(\n userPrompt: string,\n results: Array<{ label: string; content: string }>,\n completer: Completer,\n onBrainLog: (e: CodeLogEvent) => void\n): Promise<string> {\n emitBrain('Pulling everything together...', onBrainLog)\n\n const systemPrompt = `You are a technical writer. Synthesize the outputs of multiple completed subtasks into one coherent final response to the user's original request. Be concise. Do not repeat implementation details — reference them. Markdown is fine.`\n\n const subtaskBlocks = results\n .map((r, i) => `### Subtask ${i + 1}: ${r.label}\\n${r.content}`)\n .join('\\n\\n')\n\n const userMsg = `Original request:\\n${userPrompt}\\n\\nSubtask results:\\n\\n${subtaskBlocks}\\n\\nWrite the final synthesized response.`\n\n try {\n const raw = await completer(systemPrompt, userMsg)\n if (raw) return raw\n } catch {\n // fall through\n }\n\n return results[results.length - 1].content\n}\n\nasync function validate(\n userPrompt: string,\n result: string,\n completer: Completer,\n onBrainLog: (e: CodeLogEvent) => void\n): Promise<{ satisfied: boolean; followUp: string }> {\n emitBrain('Checking the result...', onBrainLog)\n\n const systemPrompt = `You are verifying whether an AI agent fully completed a task. Be strict but fair — if the core request was addressed, mark it satisfied. Only mark unsatisfied if something specific and important was clearly missed or left incomplete. Respond with valid JSON only, no markdown fences.`\n\n const userMsg = `Original request:\\n${userPrompt}\\n\\nAgent output (truncated to 2000 chars):\\n${result.slice(0, 2000)}\\n\\nRespond with JSON:\\n{\"satisfied\":true,\"follow_up\":\"empty if satisfied, otherwise a precise description of what is still missing\"}`\n\n const fallback = { satisfied: true, followUp: '' }\n\n try {\n const raw = await completer(systemPrompt, userMsg)\n if (!raw) return fallback\n\n const cleaned = raw.trim().replace(/^```json\\s*|\\s*```$/g, '')\n const parsed = JSON.parse(cleaned) as { satisfied?: boolean; follow_up?: string }\n\n return {\n satisfied: parsed.satisfied !== false,\n followUp: typeof parsed.follow_up === 'string' ? parsed.follow_up : '',\n }\n } catch {\n return fallback\n }\n}\n\n// Compute per-subtask iteration limit based on brain's complexity hint\nfunction subtaskMaxIterations(\n complexity: SubtaskSpec['complexity'],\n userMaxIterations: number\n): number {\n switch (complexity) {\n case 'simple': return Math.max(10, Math.floor(userMaxIterations * 0.4))\n case 'complex': return Math.min(userMaxIterations * 2, 200)\n default: return userMaxIterations // 'medium' or undefined\n }\n}\n\n// Ask the model to reframe the prompt given the error, so a retry has a better angle\nasync function reformulateForRetry(\n originalPrompt: string,\n error: string,\n attempt: number,\n completer: Completer,\n onBrainLog: (e: CodeLogEvent) => void\n): Promise<string> {\n emitBrain(`Adjusting my approach (attempt ${attempt})...`, onBrainLog)\n\n const systemPrompt = `You are helping recover from a failed AI agent execution. The agent was given a task but encountered an error. Rewrite the task prompt to be more explicit, simpler, or to work around the failure. Do not include meta-commentary — output only the revised prompt text.`\n const userMsg = `Original task:\\n${originalPrompt}\\n\\nError encountered:\\n${error}\\n\\nWrite an improved version of the task prompt that is more likely to succeed.`\n\n try {\n const revised = await completer(systemPrompt, userMsg)\n if (revised && revised.trim().length > 20) return revised.trim()\n } catch {}\n\n return originalPrompt // fall back to original if completer fails\n}\n\n// Generate a user-friendly explanation of why the task could not be completed\nasync function generateFailureExplanation(\n subtaskLabel: string,\n originalPrompt: string,\n error: string,\n completer: Completer,\n onBrainLog: (e: CodeLogEvent) => void\n): Promise<string> {\n emitBrain(`Ran into trouble with \"${subtaskLabel}\" — here's what happened:`, onBrainLog)\n\n const systemPrompt = `You are a helpful AI assistant explaining a task failure to the user. Be concise, honest, and constructive. Do not expose raw error messages or stack traces. Explain what was attempted, what went wrong at a high level, and suggest what the user could try next. Use plain Markdown.`\n const userMsg = `Task attempted: ${subtaskLabel}\\nTask description: ${originalPrompt}\\nError: ${error}\\n\\nWrite a short, user-friendly explanation of what happened and what could be done next.`\n\n try {\n const explanation = await completer(systemPrompt, userMsg)\n if (explanation && explanation.trim().length > 20) return explanation.trim()\n } catch {}\n\n // Fallback template\n return `I wasn't able to complete the task **\"${subtaskLabel}\"** after multiple attempts.\\n\\nThe worker ran into an issue: ${error.slice(0, 200)}${error.length > 200 ? '…' : ''}\\n\\nYou may want to check your configuration or try rephrasing the request.`\n}\n\n// Patterns that indicate the worker echoed the brain's internal subtask prompt\n// rather than actually executing the task.\nconst LEAKED_PROMPT_PATTERNS = [\n /\\bplanned subtask for the worker\\b/i,\n /\\bplease proceed with this subtask\\b/i,\n /\\bonce the results are returned,?\\s+i will\\b/i,\n /\\bi will review them and provide the final response\\b/i,\n /\\bprovide the final response to the user\\b/i,\n]\n\nfunction looksLikeLeakedPrompt(content: string): boolean {\n const head = content.slice(0, 600)\n return LEAKED_PROMPT_PATTERNS.some(re => re.test(head))\n}\n\nconst MAX_WORKER_RETRIES = 2\n\nexport async function run<T extends { content: string; toolsUsed: string[]; iterations: number }>(\n userPrompt: string,\n completer: Completer,\n execute: (prompt: string, opts?: { maxIterations?: number }) => Promise<T>,\n onBrainLog: (event: CodeLogEvent) => void,\n userMaxIterations = 50,\n conversationContext?: string,\n configuredMcpServers?: string[]\n): Promise<T & { plan: { subtasks: string[]; reasoning: string } }> {\n const skills = await discoverSkills()\n\n // \"Thinking...\" fires once here for ALL paths — fast, direct, and delegate alike\n emitBrain('Thinking...', onBrainLog)\n\n // ── Fast path: obviously conversational messages bypass planning entirely ────\n // Deterministic word-set check — no LLM, no JSON, no bias risk.\n if (looksConversational(userPrompt)) {\n const ctx = conversationContext ? `\\nConversation history:\\n${conversationContext}` : ''\n let content: string\n try {\n content = await completer(\n `You are a warm, helpful AI assistant. Reply naturally and concisely. Markdown is fine.${ctx}`,\n userPrompt\n ) ?? \"You're welcome!\"\n } catch {\n content = \"You're welcome!\"\n }\n return {\n content,\n toolsUsed: [],\n iterations: 0,\n plan: { subtasks: [], reasoning: 'Conversational response' },\n } as unknown as T & { plan: { subtasks: string[]; reasoning: string } }\n }\n\n const plan = await planExecution(userPrompt, skills, completer, onBrainLog, conversationContext, configuredMcpServers)\n\n // ── Direct response: brain answers without invoking the worker ──────────────\n if (plan.mode === 'direct') {\n let content = plan.directResponse ?? ''\n\n // If the model forgot to include the response, generate it now\n if (!content.trim()) {\n try {\n const ctx = conversationContext ? `\\nConversation history:\\n${conversationContext}` : ''\n content = await completer(\n `You are a warm, helpful AI assistant. Answer the user's message naturally and concisely. Markdown is fine.${ctx}`,\n userPrompt\n ) ?? \"Got it!\"\n } catch {\n content = \"Got it!\"\n }\n }\n\n return {\n content,\n toolsUsed: [],\n iterations: 0,\n plan: { subtasks: [], reasoning: plan.reasoning },\n } as unknown as T & { plan: { subtasks: string[]; reasoning: string } }\n }\n\n // ── Delegate path ──────────────────────────────────────────────────────────\n // Always announce the plan — even when planExecution() fell back to the default\n // single-task plan (explanation = \"On it...\") so the user sees something.\n emitBrain(plan.explanation, onBrainLog)\n\n // Emit MCP recommendations if the brain spotted useful servers the user hasn't configured yet\n if (plan.mcpRecommendations && plan.mcpRecommendations.length > 0) {\n emitBrain('💡 You could get better results by adding these MCP servers:', onBrainLog)\n for (const rec of plan.mcpRecommendations) {\n emitBrain(` • **${rec.name}** — ${rec.reason}`, onBrainLog)\n }\n emitBrain('Browse https://mcpservers.org to find them, then add via Settings (⚙️) → MCPs.', onBrainLog)\n }\n\n const N = plan.subtasks.length\n if (N > 1) {\n const labels = plan.subtasks.map((s, i) => `${i + 1}. ${s.label}`).join(' · ')\n emitBrain(`My plan: ${labels}`, onBrainLog)\n }\n\n const workerResults: Array<T & { label: string }> = []\n\n for (const subtask of plan.subtasks) {\n // Announce every subtask start (not just multi-subtask plans)\n emitBrain(`Working on step ${subtask.id}: ${subtask.label}...`, onBrainLog)\n\n const iterLimit = subtaskMaxIterations(subtask.complexity, userMaxIterations)\n\n let workerResult: T | null = null\n let lastError = ''\n\n for (let attempt = 1; attempt <= MAX_WORKER_RETRIES; attempt++) {\n try {\n const prompt = attempt === 1\n ? subtask.prompt\n : await reformulateForRetry(subtask.prompt, lastError, attempt, completer, onBrainLog)\n\n // Heartbeat: let the user know we're still alive on long-running tasks\n const execStart = Date.now()\n const heartbeat = setInterval(() => {\n const secs = Math.round((Date.now() - execStart) / 1000)\n emitBrain(`Still at it (${secs}s)…`, onBrainLog)\n }, 25_000)\n\n try {\n workerResult = await execute(prompt, { maxIterations: iterLimit })\n } finally {\n clearInterval(heartbeat)\n }\n\n break // success\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err)\n if (attempt < MAX_WORKER_RETRIES) {\n emitBrain('Hit a snag — let me try a different approach...', onBrainLog)\n } else {\n // All retries exhausted — generate a friendly explanation instead of throwing\n const explanation = await generateFailureExplanation(\n subtask.label, subtask.prompt, lastError, completer, onBrainLog\n )\n workerResult = { content: explanation, toolsUsed: [], iterations: 0 } as unknown as T\n }\n }\n }\n\n // For multi-subtask: emit a brief preview of what each step produced\n if (N > 1) {\n const summary = extractSummary(workerResult!.content)\n if (summary) emitBrain(`Step ${subtask.id} done: ${summary}`, onBrainLog)\n }\n\n workerResults.push({ ...workerResult!, label: subtask.label })\n }\n\n let finalContent: string\n if (N === 1) {\n finalContent = workerResults[0].content\n } else {\n finalContent = await synthesize(\n userPrompt,\n workerResults.map(r => ({ label: r.label, content: r.content })),\n completer,\n onBrainLog\n )\n }\n\n // ── Leak guard: if the worker echoed the internal subtask prompt instead of\n // executing it, recover by answering directly so the user never sees scaffolding ──\n if (looksLikeLeakedPrompt(finalContent)) {\n emitBrain('The worker couldn\\'t complete this one — let me answer directly...', onBrainLog)\n const ctx = conversationContext ? `\\nConversation history:\\n${conversationContext}` : ''\n try {\n finalContent = await completer(\n `You are a helpful AI assistant. The AI agent encountered a technical issue and could not complete the task using tools. Answer the user's question directly from your knowledge. Be honest if the answer would benefit from live data that you can't access right now. Markdown is fine.${ctx}`,\n userPrompt\n ) ?? finalContent\n } catch {\n // keep whatever we had — it gets returned rather than crashing the turn\n }\n }\n\n // Validate the result and optionally run a follow-up worker\n const validation = await validate(userPrompt, finalContent, completer, onBrainLog)\n\n if (!validation.satisfied && validation.followUp) {\n emitBrain('Almost there — one more thing to tackle...', onBrainLog)\n\n const followUpPrompt = `The following was not fully addressed in your previous response:\n\n${validation.followUp}\n\nOriginal request:\n${userPrompt}\n\nPrevious work summary:\n${finalContent.slice(0, 800)}\n\nPlease address the missing parts specifically.`\n\n let followUpResult: T | null = null\n let followUpLastError = ''\n\n for (let attempt = 1; attempt <= MAX_WORKER_RETRIES; attempt++) {\n try {\n const prompt = attempt === 1\n ? followUpPrompt\n : await reformulateForRetry(followUpPrompt, followUpLastError, attempt, completer, onBrainLog)\n followUpResult = await execute(prompt, { maxIterations: userMaxIterations })\n break\n } catch (err) {\n followUpLastError = err instanceof Error ? err.message : String(err)\n if (attempt < MAX_WORKER_RETRIES) {\n emitBrain('The follow-up hit an issue — trying once more...', onBrainLog)\n } else {\n const explanation = await generateFailureExplanation(\n 'follow-up', followUpPrompt, followUpLastError, completer, onBrainLog\n )\n followUpResult = { content: explanation, toolsUsed: [], iterations: 0 } as unknown as T\n }\n }\n }\n\n const followUpSummary = extractSummary(followUpResult!.content)\n if (followUpSummary) emitBrain(`That covers it: ${followUpSummary}`, onBrainLog)\n\n // Merge the follow-up into the final content\n finalContent = await synthesize(\n userPrompt,\n [\n { label: 'Initial work', content: finalContent },\n { label: 'Follow-up', content: followUpResult!.content },\n ],\n completer,\n onBrainLog\n )\n\n // Add follow-up tools/iterations to the aggregate\n workerResults.push({ ...followUpResult!, label: 'follow-up' })\n } else if (validation.satisfied) {\n emitBrain('All done — here\\'s the result:', onBrainLog)\n }\n\n // Aggregate tool usage and iteration counts across all workers\n const allTools = workerResults.flatMap(r => r.toolsUsed ?? [])\n const uniqueTools = [...new Set(allTools)]\n const totalIterations = workerResults.reduce((sum, r) => sum + (r.iterations ?? 0), 0)\n\n return {\n ...workerResults[workerResults.length - 1],\n content: finalContent,\n toolsUsed: uniqueTools,\n iterations: totalIterations,\n plan: {\n subtasks: plan.subtasks.map(s => s.label),\n reasoning: plan.reasoning,\n },\n }\n}\n","import { EventEmitter } from 'events'\nimport { execSync } from 'child_process'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport { pathToFileURL } from 'url'\nimport { writeDirective } from './directive-manager'\nimport { readConfig } from './config-manager'\nimport * as harness from './harness'\nimport type { Completer } from './harness'\n\nexport interface CodeLogEvent {\n timestamp: string\n level: 'info' | 'warn' | 'error'\n tag: string\n message: string\n}\n\nexport interface CodeRunResult {\n content: string\n toolsUsed: string[]\n iterations: number\n}\n\nfunction resolveJivaCoreEntryPath(): string {\n try {\n const npmRoot = execSync('npm root -g', { timeout: 5000 }).toString().trim()\n const pkgJson = path.join(npmRoot, 'jiva-core', 'package.json')\n if (fs.existsSync(pkgJson)) {\n const pkg = JSON.parse(fs.readFileSync(pkgJson, 'utf-8'))\n const main = pkg.main ?? 'dist/index.js'\n return path.join(npmRoot, 'jiva-core', main)\n }\n } catch {}\n\n const known = path.join(os.homedir(), '.npm-global', 'lib', 'node_modules', 'jiva-core', 'dist', 'index.js')\n if (fs.existsSync(known)) return known\n\n throw new Error('Could not find jiva-core. Please run: npm install -g jiva-core')\n}\n\n// Parses a jiva-core log line into a structured event\n// Format: \"2026-03-13T10:28:32.695Z [INFO] [CodeAgent] Tool: glob\"\nconst LOG_RE = /^(\\d{4}-\\d{2}-\\d{2}T[\\d:.Z]+)\\s+\\[(INFO|WARN|ERROR)\\]\\s+\\[(\\w+)\\]\\s+(.+)$/\n\nexport function parseLogLine(line: string): CodeLogEvent | null {\n const m = LOG_RE.exec(line.trim())\n if (!m) return null\n return {\n timestamp: m[1],\n level: m[2].toLowerCase() as CodeLogEvent['level'],\n tag: m[3],\n message: m[4],\n }\n}\n\nexport class CodeRunner extends EventEmitter {\n private agent: unknown = null\n private orchestrator: unknown = null\n private workspace: unknown = null\n private conversationManager: unknown = null\n private mcpManager: unknown = null\n private codeLogger: unknown = null // jiva-core logger singleton (for direct hook)\n private ready = false\n private deepRun = false\n private maxIterations = 50\n\n isReady(): boolean {\n return this.ready\n }\n\n getConversationId(): string | null {\n if (!this.conversationManager) return null\n return (this.conversationManager as Record<string, unknown>).currentConversationId as string ?? null\n }\n\n async initialize(workspaceDir: string, mcpServerNames?: string[], opts?: { deepRun?: boolean; maxIterations?: number }): Promise<void> {\n this.deepRun = opts?.deepRun ?? false\n this.maxIterations = opts?.maxIterations ?? 50\n\n const entry = resolveJivaCoreEntryPath()\n console.log(`[CodeRunner] Loading jiva-core from: ${entry}`)\n\n const jiva = await import(pathToFileURL(entry).href)\n\n const {\n configManager,\n ModelOrchestrator,\n WorkspaceManager,\n ConversationManager,\n CodeAgent,\n MCPServerManager,\n createKrutrimModel,\n createLocalProvider,\n logger,\n } = jiva as Record<string, unknown>\n\n // Store the jiva-core logger so runChat() can hook into it for tool event capture\n this.codeLogger = logger ?? null\n\n // 1. Validate config\n ;(configManager as { validateConfig(): void }).validateConfig()\n\n const reasoningConfig = (configManager as {\n getReasoningModel(): { endpoint: string; apiKey: string; defaultModel: string; useHarmonyFormat?: boolean }\n }).getReasoningModel()\n\n // 2. Create model + orchestrator\n const createModel = createKrutrimModel as (config: unknown) => unknown\n const reasoningModel = createModel({\n endpoint: reasoningConfig.endpoint,\n apiKey: reasoningConfig.apiKey,\n model: reasoningConfig.defaultModel,\n type: 'reasoning',\n useHarmonyFormat: reasoningConfig.useHarmonyFormat,\n })\n\n const OrchestratorClass = ModelOrchestrator as new (config: unknown) => unknown\n this.orchestrator = new OrchestratorClass({ reasoningModel })\n\n // 3. Write directive + workspace\n const { path: directivePath } = writeDirective(\n (readConfig() as unknown as Record<string, unknown>)?.userDirective as string | undefined\n )\n const WsClass = WorkspaceManager as new (config: unknown) => { initialize(): Promise<void> }\n this.workspace = new WsClass({ workspaceDir, directivePath })\n await (this.workspace as { initialize(): Promise<void> }).initialize()\n\n // 4. Conversation manager (auto-saves to ~/.jiva/conversations/)\n const createProvider = createLocalProvider as () => Promise<unknown>\n const storageProvider = await createProvider()\n const ConvManagerClass = ConversationManager as new (provider: unknown, orchestrator?: unknown) => unknown\n this.conversationManager = new ConvManagerClass(storageProvider, this.orchestrator)\n\n // 5. Optionally create MCPServerManager for requested code-mode servers\n this.mcpManager = null\n const activeMcpNames = mcpServerNames && mcpServerNames.length > 0 ? mcpServerNames : null\n if (activeMcpNames && MCPServerManager) {\n const MgrClass = MCPServerManager as new () => { initialize(servers: Record<string, unknown>): Promise<void> }\n const mgr = new MgrClass()\n const allServers = (readConfig() as unknown as Record<string, unknown>)?.mcpServers as Record<string, unknown> ?? {}\n const selectedServers: Record<string, unknown> = {}\n for (const name of activeMcpNames) {\n if (allServers[name]) selectedServers[name] = allServers[name]\n }\n await mgr.initialize(selectedServers)\n this.mcpManager = mgr\n console.log(`[CodeRunner] MCP servers loaded: ${activeMcpNames.join(', ')}`)\n }\n\n // 6. Create CodeAgent\n const AgentClass = CodeAgent as new (config: unknown) => {\n chat(prompt: string, onChunk?: (text: string) => void): Promise<{ content: string; toolsUsed: string[]; iterations: number }>\n cleanup(): Promise<void>\n resetConversation(): void\n }\n\n this.agent = new AgentClass({\n orchestrator: this.orchestrator,\n workspace: this.workspace,\n conversationManager: this.conversationManager,\n maxIterations: this.maxIterations,\n ...(this.mcpManager && activeMcpNames ? { mcpManager: this.mcpManager, mcpServerNames: activeMcpNames } : {}),\n })\n\n this.ready = true\n console.log(`[CodeRunner] Initialized (maxIterations=${this.maxIterations}, deepRun=${this.deepRun})`)\n }\n\n private makeCompleter(): Completer {\n const orch = this.orchestrator as Record<string, unknown>\n return async (systemPrompt: string, userPrompt: string): Promise<string | null> => {\n if (typeof orch['chat'] !== 'function') return null\n try {\n const chatFn = (orch['chat'] as (opts: {\n messages: Array<{ role: string; content: string }>\n reasoningEffort?: string\n }) => Promise<{ content: string }>).bind(orch)\n const result = await chatFn({\n messages: [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n reasoningEffort: 'low',\n })\n return result?.content ?? null\n } catch (err) {\n console.warn('[CodeRunner] makeCompleter: chat() failed:', err)\n return null\n }\n }\n }\n\n async chat(\n prompt: string,\n onLog: (event: CodeLogEvent) => void,\n opts?: { deepRun?: boolean; maxIterations?: number; conversationHistory?: string }\n ): Promise<CodeRunResult> {\n // Sync maxIterations from caller and propagate to agent instance lazily\n if (opts?.maxIterations !== undefined && opts.maxIterations !== this.maxIterations) {\n this.maxIterations = opts.maxIterations\n try { (this.agent as Record<string, unknown>).maxIterations = this.maxIterations } catch {}\n }\n\n const useDeepRun = opts?.deepRun !== false && (opts?.deepRun ?? this.deepRun)\n if (useDeepRun) {\n const result = await harness.run(\n prompt,\n this.makeCompleter(),\n (p, execOpts) => this.runChatWithIterations(p, onLog, execOpts?.maxIterations),\n (brainEvent) => onLog(brainEvent),\n this.maxIterations,\n opts?.conversationHistory || undefined\n )\n return result\n }\n return this.runChat(prompt, onLog)\n }\n\n private async runChatWithIterations(\n prompt: string,\n onLog: (event: CodeLogEvent) => void,\n maxIterations?: number\n ): Promise<CodeRunResult> {\n if (maxIterations !== undefined && maxIterations !== this.maxIterations) {\n this.maxIterations = maxIterations\n try { (this.agent as Record<string, unknown>).maxIterations = this.maxIterations } catch {}\n }\n return this.runChat(prompt, onLog)\n }\n\n /**\n * Attach a per-call handler to the jiva-core logger.\n * Tries multiple hook patterns since the logger's exact API is version-dependent.\n * Returns a cleanup function that removes the handler.\n */\n private hookLogger(onLog: (event: CodeLogEvent) => void): () => void {\n const log = this.codeLogger as Record<string, unknown> | null\n\n const emit = (level: string, tag: string, message: string) => {\n const lvl = level.toLowerCase()\n onLog({\n timestamp: new Date().toISOString(),\n level: (lvl === 'warn' || lvl === 'error' ? lvl : 'info') as CodeLogEvent['level'],\n tag,\n message,\n })\n }\n\n // Pattern 1: EventEmitter 'log' event\n if (log && typeof log.on === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const handler = (...args: any[]) => {\n if (args.length >= 3 && typeof args[0] === 'string') {\n emit(args[0], args[1] ?? 'CodeAgent', args[2])\n } else if (args.length >= 2 && typeof args[0] === 'string') {\n emit('info', 'CodeAgent', args[1])\n } else if (args.length >= 1 && typeof args[0] === 'object') {\n const e = args[0] as Record<string, unknown>\n emit(String(e.level ?? 'info'), String(e.tag ?? e.name ?? 'CodeAgent'), String(e.message ?? e.msg ?? ''))\n }\n }\n try {\n ;(log.on as (e: string, fn: unknown) => void)('log', handler)\n return () => {\n if (typeof log.off === 'function') (log.off as (e: string, fn: unknown) => void)('log', handler)\n else if (typeof log.removeListener === 'function') (log.removeListener as (e: string, fn: unknown) => void)('log', handler)\n }\n } catch {}\n }\n\n // Pattern 2: addTransport / addHandler / addSink\n if (log) {\n for (const addMethod of ['addTransport', 'addHandler', 'addSink']) {\n if (typeof log[addMethod] !== 'function') continue\n const removeMethod = addMethod.replace('add', 'remove')\n const transport = {\n write: (entry: Record<string, unknown>) => {\n emit(String(entry.level ?? 'info'), String(entry.tag ?? entry.name ?? 'CodeAgent'), String(entry.message ?? entry.msg ?? ''))\n },\n log: (entry: Record<string, unknown>) => {\n emit(String(entry.level ?? 'info'), String(entry.tag ?? entry.name ?? 'CodeAgent'), String(entry.message ?? entry.msg ?? ''))\n },\n }\n try {\n ;(log[addMethod] as (t: unknown) => void)(transport)\n return () => {\n if (typeof log[removeMethod] === 'function') {\n try { (log[removeMethod] as (t: unknown) => void)(transport) } catch {}\n }\n }\n } catch {}\n }\n }\n\n // Pattern 3: stdout interception — fallback for loggers that write to stdout\n const origWrite = process.stdout.write.bind(process.stdout)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n process.stdout.write = (data: string | Uint8Array, ...args: any[]) => {\n const text = typeof data === 'string' ? data : Buffer.from(data).toString()\n for (const line of text.split('\\n')) {\n const structured = parseLogLine(line)\n if (structured) { onLog(structured); continue }\n // Lenient fallback: any line mentioning a tool call\n const toolMatch = /(?:tool(?:\\s+call)?|calling|executing)[:\\s]+([^\\s(]+)/i.exec(line.trim())\n if (toolMatch) {\n onLog({ timestamp: new Date().toISOString(), level: 'info', tag: 'CodeAgent', message: `Tool: ${toolMatch[1]}` })\n }\n }\n return origWrite(data, ...args)\n }\n return () => { process.stdout.write = origWrite }\n }\n\n private async runChat(\n prompt: string,\n onLog: (event: CodeLogEvent) => void\n ): Promise<CodeRunResult> {\n if (!this.agent) {\n throw new Error('CodeRunner not initialized')\n }\n\n const agent = this.agent as {\n chat(prompt: string, onChunk?: (text: string) => void): Promise<{ content: string; toolsUsed: string[]; iterations: number }>\n }\n\n const unhook = this.hookLogger(onLog)\n\n try {\n const result = await agent.chat(prompt)\n\n // Emit one Tool: event per distinct tool used as a guaranteed fallback,\n // in case the logger hook didn't fire live events during execution\n if (result.toolsUsed?.length) {\n const seen = new Set<string>()\n for (const tool of result.toolsUsed) {\n if (!seen.has(tool)) {\n seen.add(tool)\n onLog({ timestamp: new Date().toISOString(), level: 'info', tag: 'CodeAgent', message: `Tool: ${tool}` })\n }\n }\n }\n\n return {\n content: result.content,\n toolsUsed: result.toolsUsed ?? [],\n iterations: result.iterations ?? 0,\n }\n } finally {\n unhook()\n }\n }\n\n stop(): void {\n if (this.agent) {\n (this.agent as { stop(): void }).stop()\n }\n }\n\n async cleanup(): Promise<void> {\n if (this.agent) {\n try {\n await (this.agent as { cleanup(): Promise<void> }).cleanup()\n } catch (err) {\n console.warn('[CodeRunner] Cleanup error:', err)\n }\n }\n if (this.mcpManager) {\n try {\n await (this.mcpManager as { cleanup(): Promise<void> }).cleanup()\n } catch {}\n }\n this.agent = null\n this.orchestrator = null\n this.workspace = null\n this.conversationManager = null\n this.mcpManager = null\n this.ready = false\n }\n}\n","import { EventEmitter } from 'events'\nimport { execSync } from 'child_process'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport { pathToFileURL } from 'url'\nimport { writeDirective } from './directive-manager'\nimport { readConfig } from './config-manager'\nimport * as harness from './harness'\nimport type { Completer } from './harness'\nimport { parseLogLine } from './code-runner'\nimport type { CodeLogEvent } from './code-runner'\n\n/**\n * Resolve the absolute path to jiva-core's main entry point.\n * jiva-core is installed globally (npm install -g jiva-core), so we can't\n * use a bare `import('jiva-core')` from within dist-electron/ — Node.js\n * resolves bare specifiers relative to the file's directory, not the project root.\n * We detect the global npm root at runtime and build the absolute path.\n */\nfunction resolveJivaCoreEntryPath(): string {\n // Try npm root -g\n try {\n const npmRoot = execSync('npm root -g', { timeout: 5000 }).toString().trim()\n const pkgJson = path.join(npmRoot, 'jiva-core', 'package.json')\n if (fs.existsSync(pkgJson)) {\n const pkg = JSON.parse(fs.readFileSync(pkgJson, 'utf-8'))\n const main = pkg.main ?? 'dist/index.js'\n return path.join(npmRoot, 'jiva-core', main)\n }\n } catch {}\n\n // Try to find in common Windows locations\n if (process.platform === 'win32') {\n const possiblePaths = [\n path.join(process.env.APPDATA ?? '', 'npm', 'node_modules', 'jiva-core', 'dist', 'index.js'),\n path.join(process.env.LOCALAPPDATA ?? '', 'npm', 'node_modules', 'jiva-core', 'dist', 'index.js'),\n 'C:\\\\Program Files\\\\nodejs\\\\node_modules\\\\jiva-core\\\\dist\\\\index.js',\n ]\n for (const known of possiblePaths) {\n if (fs.existsSync(known)) return known\n }\n }\n\n // Known macOS/Linux fallback path\n const known = '/Users/abidev/.npm-global/lib/node_modules/jiva-core/dist/index.js'\n if (fs.existsSync(known)) return known\n\n throw new Error(\n 'Could not find jiva-core. Please ensure it is installed globally: npm install -g jiva-core'\n )\n}\n\nexport type RunnerStatus = 'stopped' | 'initializing' | 'ready' | 'busy' | 'error'\n\nexport interface JivaRunResult {\n content: string\n iterations: number\n toolsUsed: string[]\n plan: {\n subtasks: string[]\n reasoning?: string\n } | null\n durationMs: number\n conversationId?: string\n}\n\nexport type PhaseUpdate = 'initializing' | 'planning' | 'executing' | 'synthesizing' | 'done'\n\n/**\n * JivaRunner — integrates jiva-core SDK directly in the Electron main process.\n *\n * Uses dynamic import() for ESM compatibility: jiva-core is \"type\": \"module\",\n * while our Electron main is compiled as CJS. The standard interop is\n * `await import('jiva-core')` which works in Node.js >= 12.\n *\n * Architecture:\n * Renderer ─ IPC invoke ─▶ Main (JivaRunner) ─▶ DualAgent SDK\n * │\n * IPC send (phase events)\n * │\n * Renderer ◀────────────────────────┘\n */\nexport class JivaRunner extends EventEmitter {\n private status: RunnerStatus = 'stopped'\n private agent: unknown = null // DualAgent instance (typed as unknown for CJS→ESM)\n private orchestrator: unknown = null // ModelOrchestrator\n private mcpManager: unknown = null // MCPServerManager\n private workspace: unknown = null // WorkspaceManager\n private conversationManager: unknown = null\n private personaManager: unknown = null\n private jivaLogger: unknown = null // jiva-core logger singleton (for direct hook)\n private currentPersona: string | null = null\n private currentConversationId: string | null = null\n private maxIterations = 50 // user-configured; synced from chat() opts each call\n\n getStatus(): RunnerStatus {\n return this.status\n }\n\n getCurrentConversationId(): string | null {\n return this.currentConversationId\n }\n\n /**\n * Initialize the Jiva agent with current config.\n * Call once on app startup, and re-call when persona changes.\n */\n async initialize(persona?: string): Promise<void> {\n this.setStatus('initializing')\n\n try {\n // Resolve the absolute path to jiva-core's entry point.\n // We can't use bare `import('jiva-core')` from dist-electron/ because Node.js\n // resolves relative to the compiled file location, not the project root.\n const jivaCoreEntry = resolveJivaCoreEntryPath()\n console.log(`[JivaRunner] Loading jiva-core from: ${jivaCoreEntry}`)\n\n // Dynamic ESM import — the only way to load \"type\":\"module\" packages from CJS\n // Must use file:// URL on Windows for ESM compatibility\n const jiva = await import(pathToFileURL(jivaCoreEntry).href)\n\n const {\n MCPServerManager,\n WorkspaceManager,\n ConversationManager,\n ModelOrchestrator,\n DualAgent,\n createKrutrimModel,\n LogLevel,\n logger,\n createLocalProvider,\n } = jiva as Record<string, unknown>\n\n // --- 1. Load config from Jivam's own config file (not jiva-core's global singleton) ---\n const jivaConfig = readConfig()\n if (!jivaConfig?.models?.reasoning?.apiKey) {\n throw new Error('Jivam is not configured. Add your API key in Settings → Models.')\n }\n\n const reasoningConfig = jivaConfig.models.reasoning as {\n endpoint?: string; apiKey?: string; defaultModel?: string; model?: string\n useHarmonyFormat?: boolean; reasoningEffortStrategy?: string; defaultMaxTokens?: number\n }\n const multimodalConfig = jivaConfig.models.multimodal as {\n endpoint?: string; apiKey?: string; defaultModel?: string\n } | null | undefined\n\n // --- 2. Create models ---\n const createModel = createKrutrimModel as (config: unknown) => unknown\n // defaultModel is the canonical field; fall back to model for legacy configs\n const resolvedReasoningModel = reasoningConfig.defaultModel ?? reasoningConfig.model ?? ''\n const reasoningModel = createModel({\n endpoint: reasoningConfig.endpoint,\n apiKey: reasoningConfig.apiKey,\n model: resolvedReasoningModel,\n type: 'reasoning',\n useHarmonyFormat: reasoningConfig.useHarmonyFormat,\n ...(reasoningConfig.reasoningEffortStrategy ? { reasoningEffortStrategy: reasoningConfig.reasoningEffortStrategy } : {}),\n ...(reasoningConfig.defaultMaxTokens ? { defaultMaxTokens: reasoningConfig.defaultMaxTokens } : {}),\n })\n\n let multimodalModel: unknown\n if (multimodalConfig?.apiKey) {\n try {\n const resolvedMmModel = multimodalConfig.defaultModel ?? ''\n multimodalModel = createModel({\n endpoint: multimodalConfig.endpoint,\n apiKey: multimodalConfig.apiKey,\n model: resolvedMmModel,\n type: 'multimodal',\n })\n } catch {\n console.warn('[JivaRunner] Failed to create multimodal model, continuing without vision')\n }\n }\n\n // --- 3. Create orchestrator ---\n const OrchestratorClass = ModelOrchestrator as new (config: unknown) => unknown\n this.orchestrator = new OrchestratorClass({ reasoningModel, multimodalModel })\n\n // --- 4. Initialize MCP servers ---\n const mcpServers = (jivaConfig.mcpServers ?? {}) as Record<string, unknown>\n const allowedPath = os.platform() === 'win32' ? 'C:\\\\Users' : '/Users'\n\n // Ensure filesystem MCP server always exists\n if (!(mcpServers as Record<string, unknown>)['filesystem']) {\n (mcpServers as Record<string, unknown>)['filesystem'] = {\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', allowedPath],\n enabled: true,\n }\n }\n\n const McpManagerClass = MCPServerManager as new () => {\n initialize(servers: unknown): Promise<void>\n addServer(name: string, config: unknown): Promise<void>\n cleanup(): Promise<void>\n }\n this.mcpManager = new McpManagerClass()\n await (this.mcpManager as ReturnType<typeof McpManagerClass['prototype']['constructor']> & {\n initialize(servers: unknown): Promise<void>\n }).initialize(mcpServers)\n\n // --- 5. Write date-aware directive + Initialize workspace ---\n // The directive injects current date/time + recent activity so the LLM always\n // knows the correct date without relying on its training data.\n const { path: directivePath } = writeDirective(jivaConfig.userDirective)\n\n const workspaceDir = process.cwd()\n const WsClass = WorkspaceManager as new (config: unknown) => { initialize(): Promise<void> }\n this.workspace = new WsClass({ workspaceDir, directivePath })\n await (this.workspace as { initialize(): Promise<void> }).initialize()\n\n // --- 6. Initialize conversation manager ---\n const createProvider = createLocalProvider as () => Promise<unknown>\n const storageProvider = await createProvider()\n const ConvManagerClass = ConversationManager as new (provider: unknown, orchestrator?: unknown) => unknown\n this.conversationManager = new ConvManagerClass(storageProvider, this.orchestrator)\n\n // --- 7. Initialize persona manager ---\n // PersonaManager is not exported from the main index — use dynamic path import\n const jivaCoreDir = path.dirname(jivaCoreEntry) // dist/\n const jivaCoreRoot = path.dirname(jivaCoreDir) // jiva-core root\n const personaManagerPath = path.join(jivaCoreRoot, 'dist', 'personas', 'persona-manager.js')\n const { PersonaManager } = await import(\n pathToFileURL(personaManagerPath).href\n ) as { PersonaManager: new () => {\n initialize(persona?: string): Promise<void>\n getPersonaMCPServers(): Record<string, unknown>\n setActivePersona(name: string | null): void\n }}\n this.personaManager = new PersonaManager()\n await (this.personaManager as { initialize(p?: string): Promise<void> }).initialize(\n persona ?? undefined\n )\n\n // Merge persona-specific MCP servers\n const personaMCPServers = (this.personaManager as {\n getPersonaMCPServers(): Record<string, unknown>\n }).getPersonaMCPServers()\n\n for (const [name, config] of Object.entries(personaMCPServers)) {\n try {\n await (this.mcpManager as {\n addServer(name: string, config: unknown): Promise<void>\n }).addServer(name, config)\n } catch (err) {\n console.warn(`[JivaRunner] Failed to add persona MCP server '${name}':`, err)\n }\n }\n\n // --- 8. Create DualAgent ---\n const AgentClass = DualAgent as new (config: unknown) => {\n chat(prompt: string): Promise<{\n content: string\n iterations: number\n toolsUsed: string[]\n plan?: { subtasks: string[]; reasoning: string }\n }>\n cleanup(): Promise<void>\n resetConversation(): void\n saveConversation(): Promise<string | null>\n loadConversation(id: string): Promise<void>\n listConversations(): Promise<unknown[]>\n }\n\n this.agent = new AgentClass({\n orchestrator: this.orchestrator,\n mcpManager: this.mcpManager,\n workspace: this.workspace,\n conversationManager: this.conversationManager,\n personaManager: this.personaManager,\n maxSubtasks: 20,\n maxIterations: this.maxIterations,\n autoSave: true,\n condensingThreshold: 30,\n })\n\n // Store the jiva-core logger so runChat() can hook into it per call\n this.jivaLogger = logger\n\n this.currentPersona = persona ?? null\n this.setStatus('ready')\n console.log('[JivaRunner] Initialized successfully')\n\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error('[JivaRunner] Initialization failed:', msg)\n this.setStatus('error', msg)\n throw err\n }\n }\n\n private makeCompleter(): Completer {\n const orch = this.orchestrator as Record<string, unknown>\n return async (systemPrompt: string, userPrompt: string): Promise<string | null> => {\n if (typeof orch['chat'] !== 'function') return null\n try {\n const chatFn = (orch['chat'] as (opts: {\n messages: Array<{ role: string; content: string }>\n reasoningEffort?: string\n }) => Promise<{ content: string }>).bind(orch)\n const result = await chatFn({\n messages: [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n reasoningEffort: 'low',\n })\n return result?.content ?? null\n } catch (err) {\n console.warn('[JivaRunner] makeCompleter: chat() failed:', err)\n return null\n }\n }\n }\n\n /**\n * Send a message to the Jiva agent and return the result.\n * Emits 'phase-update' events as execution progresses.\n *\n * Since DualAgent.chat() is synchronous end-to-end (no event emitter),\n * we emit a simulated phase timeline based on typical durations.\n */\n /**\n * Attach a per-call handler to the jiva-core logger.\n * Tries multiple hook patterns since we can't guarantee the logger's exact API.\n * Returns a cleanup function that removes the handler.\n */\n private hookLogger(onLog: (event: CodeLogEvent) => void): () => void {\n const log = this.jivaLogger as Record<string, unknown> | null\n if (!log) return () => {}\n\n const emit = (level: string, tag: string, message: string) => {\n const lvl = level.toLowerCase()\n onLog({\n timestamp: new Date().toISOString(),\n level: (lvl === 'warn' || lvl === 'error' ? lvl : 'info') as CodeLogEvent['level'],\n tag,\n message,\n })\n }\n\n // Pattern 1: EventEmitter 'log' event — common for custom loggers\n // Signature variants: (level, tag, msg) or ({ level, tag, message }) or (level, msg)\n if (typeof log.on === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const handler = (...args: any[]) => {\n if (args.length >= 3 && typeof args[0] === 'string') {\n emit(args[0], args[1] ?? 'jiva', args[2])\n } else if (args.length >= 2 && typeof args[0] === 'string') {\n emit('info', 'jiva', args[1])\n } else if (args.length >= 1 && typeof args[0] === 'object') {\n const e = args[0] as Record<string, unknown>\n emit(String(e.level ?? 'info'), String(e.tag ?? e.name ?? 'jiva'), String(e.message ?? e.msg ?? ''))\n }\n }\n try {\n ;(log.on as (e: string, fn: unknown) => void)('log', handler)\n return () => {\n if (typeof log.off === 'function') (log.off as (e: string, fn: unknown) => void)('log', handler)\n else if (typeof log.removeListener === 'function') (log.removeListener as (e: string, fn: unknown) => void)('log', handler)\n }\n } catch {}\n }\n\n // Pattern 2: addTransport / addHandler\n for (const addMethod of ['addTransport', 'addHandler', 'addSink']) {\n if (typeof log[addMethod] !== 'function') continue\n const removeMethod = addMethod.replace('add', 'remove')\n const transport = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n write: (entry: Record<string, unknown>) => {\n emit(String(entry.level ?? 'info'), String(entry.tag ?? entry.name ?? 'jiva'), String(entry.message ?? entry.msg ?? ''))\n },\n // Some loggers call log() instead of write()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n log: (entry: Record<string, unknown>) => {\n emit(String(entry.level ?? 'info'), String(entry.tag ?? entry.name ?? 'jiva'), String(entry.message ?? entry.msg ?? ''))\n },\n }\n try {\n ;(log[addMethod] as (t: unknown) => void)(transport)\n return () => {\n if (typeof log[removeMethod] === 'function') {\n try { (log[removeMethod] as (t: unknown) => void)(transport) } catch {}\n }\n }\n } catch {}\n }\n\n // Pattern 3: stdout interception — last resort for loggers that only write to stdout\n const origWrite = process.stdout.write.bind(process.stdout)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n process.stdout.write = (data: string | Uint8Array, ...args: any[]) => {\n const text = typeof data === 'string' ? data : Buffer.from(data).toString()\n for (const line of text.split('\\n')) {\n // Try strict structured format first\n const structured = parseLogLine(line)\n if (structured) { onLog(structured); continue }\n // Lenient fallback: any line mentioning a tool call\n const toolMatch = /(?:tool(?:\\s+call)?|calling|executing)[:\\s]+([^\\s(]+)/i.exec(line.trim())\n if (toolMatch) {\n onLog({ timestamp: new Date().toISOString(), level: 'info', tag: 'jiva', message: `Tool: ${toolMatch[1]}` })\n }\n }\n return origWrite(data, ...args)\n }\n return () => { process.stdout.write = origWrite }\n }\n\n private async runChat(\n prompt: string,\n startTime: number,\n onLog?: (event: CodeLogEvent) => void\n ): Promise<JivaRunResult> {\n const unhook = onLog ? this.hookLogger(onLog) : null\n\n const agent = this.agent as {\n chat(prompt: string): Promise<{\n content: string\n iterations: number\n toolsUsed: string[]\n plan?: { subtasks: string[]; reasoning: string }\n }>\n }\n\n let response: { content: string; iterations: number; toolsUsed: string[]; plan?: { subtasks: string[]; reasoning: string } }\n try {\n response = await agent.chat(prompt)\n } finally {\n unhook?.()\n }\n\n // Synthesise tool events from toolsUsed if none were emitted during execution\n // (covers the case where DualAgent doesn't log intermediately)\n if (onLog && response.toolsUsed?.length) {\n for (const tool of response.toolsUsed) {\n onLog({ timestamp: new Date().toISOString(), level: 'info', tag: 'jiva', message: `Tool: ${tool}` })\n }\n }\n\n // Capture conversation ID (auto-saved by DualAgent).\n let convId: string | null = null\n try {\n convId = (this.conversationManager as {\n getCurrentConversationId?(): string | null\n }).getCurrentConversationId?.() ?? null\n } catch {}\n\n if (!convId) {\n try {\n convId = await (this.agent as {\n saveConversation(): Promise<string | null>\n }).saveConversation()\n } catch {}\n }\n\n if (convId) this.currentConversationId = convId\n\n return {\n content: response.content,\n iterations: response.iterations,\n toolsUsed: response.toolsUsed ?? [],\n plan: response.plan\n ? { subtasks: response.plan.subtasks ?? [], reasoning: response.plan.reasoning }\n : null,\n durationMs: Date.now() - startTime,\n conversationId: this.currentConversationId ?? undefined,\n }\n }\n\n /**\n * Send a message to the Jiva agent and return the result.\n * Emits 'phase-update' events as execution progresses.\n *\n * Since DualAgent.chat() is synchronous end-to-end (no event emitter),\n * we emit a simulated phase timeline based on typical durations.\n */\n async chat(\n prompt: string,\n onPhase: (phase: PhaseUpdate) => void,\n opts?: { deepRun?: boolean; maxIterations?: number; conversationHistory?: string },\n onLog?: (event: CodeLogEvent) => void\n ): Promise<JivaRunResult> {\n if (!this.agent) {\n throw new Error('JivaRunner not initialized. Call initialize() first.')\n }\n if (this.status === 'busy') {\n throw new Error('Agent is already processing a request.')\n }\n\n // Sync maxIterations from caller and propagate to agent instance lazily\n if (opts?.maxIterations !== undefined && opts.maxIterations !== this.maxIterations) {\n this.maxIterations = opts.maxIterations\n try { (this.agent as Record<string, unknown>).maxIterations = this.maxIterations } catch {}\n }\n\n this.setStatus('busy')\n const startTime = Date.now()\n\n onPhase('planning')\n const executingTimer = setTimeout(() => onPhase('executing'), 2000)\n const synthesizingTimer = setTimeout(() => onPhase('synthesizing'), 30000)\n\n try {\n let result: JivaRunResult\n\n if (opts?.deepRun !== false) {\n // Collect names of currently configured MCP servers so the brain can recommend\n // additional ones the user hasn't set up yet.\n const mcpServerNames = Object.keys(readConfig()?.mcpServers ?? {})\n\n result = await harness.run(\n prompt,\n this.makeCompleter(),\n (p, execOpts) => {\n // Apply per-subtask iteration limit from the brain's complexity hint\n if (execOpts?.maxIterations !== undefined && execOpts.maxIterations !== this.maxIterations) {\n this.maxIterations = execOpts.maxIterations\n try { (this.agent as Record<string, unknown>).maxIterations = this.maxIterations } catch {}\n }\n return this.runChat(p, startTime, onLog)\n },\n (brainEvent) => onLog?.(brainEvent),\n this.maxIterations,\n opts?.conversationHistory || undefined,\n mcpServerNames\n )\n } else {\n result = await this.runChat(prompt, startTime, onLog)\n }\n\n clearTimeout(executingTimer)\n clearTimeout(synthesizingTimer)\n onPhase('done')\n this.setStatus('ready')\n\n return result\n } catch (err) {\n clearTimeout(executingTimer)\n clearTimeout(synthesizingTimer)\n this.setStatus('ready')\n throw err\n }\n }\n\n /**\n * Load a past conversation into the agent by ID.\n * This restores the full conversation history so subsequent chat() calls continue in context.\n */\n async loadConversation(id: string): Promise<void> {\n if (!this.agent) {\n throw new Error('JivaRunner not initialized. Call initialize() first.')\n }\n await (this.agent as { loadConversation(id: string): Promise<void> }).loadConversation(id)\n this.currentConversationId = id\n console.log(`[JivaRunner] Loaded conversation: ${id}`)\n }\n\n /**\n * Switch to a different persona. Re-initializes the agent with new persona config.\n */\n async switchPersona(persona: string): Promise<void> {\n if (this.agent) {\n await this.cleanup()\n }\n await this.initialize(persona)\n }\n\n /**\n * Reset conversation history without re-initializing.\n */\n resetConversation(): void {\n if (this.agent) {\n ;(this.agent as { resetConversation(): void }).resetConversation()\n }\n this.currentConversationId = null\n }\n\n // ─── MCP Server Management ────────────────────────────────────────────────\n\n /**\n * Get all tools grouped by server name.\n */\n getMCPTools(): Record<string, Array<{ name: string; description: string }>> {\n if (!this.mcpManager) return {}\n try {\n const allTools = (this.mcpManager as {\n getAllTools?(): Array<{ name: string; description?: string }>\n }).getAllTools?.() ?? []\n\n const grouped: Record<string, Array<{ name: string; description: string }>> = {}\n for (const tool of allTools) {\n // Tool names are prefixed as \"serverName__toolName\"\n const parts = tool.name.split('__')\n const serverName = parts.length > 1 ? parts[0] : 'unknown'\n const toolName = parts.length > 1 ? parts.slice(1).join('__') : tool.name\n if (!grouped[serverName]) grouped[serverName] = []\n grouped[serverName].push({ name: toolName, description: tool.description ?? '' })\n }\n return grouped\n } catch {\n return {}\n }\n }\n\n /**\n * Add a new MCP server to the running manager.\n * The caller is responsible for persisting to config.\n */\n async addMCPServer(name: string, config: unknown): Promise<void> {\n if (!this.mcpManager) throw new Error('MCP manager not initialized')\n await (this.mcpManager as {\n addServer(name: string, config: unknown): Promise<void>\n }).addServer(name, config)\n }\n\n /**\n * Remove an MCP server from the running manager.\n * The caller is responsible for updating config.\n */\n async removeMCPServer(name: string): Promise<void> {\n if (!this.mcpManager) throw new Error('MCP manager not initialized')\n const manager = this.mcpManager as {\n removeServer?(name: string): Promise<void>\n disableServer?(name: string): Promise<void>\n }\n if (manager.removeServer) {\n await manager.removeServer(name)\n } else if (manager.disableServer) {\n await manager.disableServer(name)\n }\n }\n\n /**\n * Get status of all connected MCP servers, including any error info.\n */\n getMCPServerStatus(): Array<{ name: string; enabled: boolean; connected: boolean; toolCount: number; error?: string }> {\n if (!this.mcpManager) return []\n try {\n const statuses = (this.mcpManager as {\n getServerStatus?(): Array<{ name: string; enabled: boolean; connected: boolean; toolCount: number }>\n }).getServerStatus?.() ?? []\n return statuses.map(s => ({\n ...s,\n error: (s as Record<string, unknown>).error as string | undefined\n ?? (s as Record<string, unknown>).lastError as string | undefined,\n }))\n } catch {\n return []\n }\n }\n\n /**\n * Reconnect an MCP server without touching config.\n * Tries native reconnect first, falls back to remove + re-add.\n */\n async reconnectMCPServer(name: string): Promise<void> {\n if (!this.mcpManager) throw new Error('MCP manager not initialized')\n const manager = this.mcpManager as Record<string, unknown>\n\n // Try native reconnect if available\n if (typeof manager.reconnectServer === 'function') {\n await (manager.reconnectServer as (n: string) => Promise<void>)(name)\n return\n }\n\n // Fallback: get current status, remove from manager, re-add\n const statuses = this.getMCPServerStatus()\n const srv = statuses.find(s => s.name === name)\n if (!srv) throw new Error(`MCP server \"${name}\" not found`)\n\n const fullStatus = (this.mcpManager as {\n getServerStatus?(): Array<Record<string, unknown>>\n }).getServerStatus?.()?.find((s) => s.name === name) ?? {}\n\n await this.removeMCPServer(name)\n const config = (fullStatus.url != null)\n ? { type: 'http' as const, url: fullStatus.url as string, env: fullStatus.env as Record<string, string> | undefined, enabled: true }\n : { type: 'stdio' as const, command: fullStatus.command as string, args: fullStatus.args as string[] | undefined, env: fullStatus.env as Record<string, string> | undefined, enabled: true }\n await this.addMCPServer(name, config)\n }\n\n /**\n * Enable or disable an MCP server at runtime.\n * The caller is responsible for updating config.\n */\n async toggleMCPServer(name: string, enabled: boolean): Promise<void> {\n if (!this.mcpManager) throw new Error('MCP manager not initialized')\n const manager = this.mcpManager as {\n enableServer?(name: string): Promise<void>\n disableServer?(name: string): Promise<void>\n }\n if (enabled && manager.enableServer) {\n await manager.enableServer(name)\n } else if (!enabled && manager.disableServer) {\n await manager.disableServer(name)\n }\n }\n\n /**\n * Describe an image using the configured multimodal model.\n * Returns a text description suitable for injection into a text prompt.\n * Throws if no multimodal model is configured or runner is not initialized.\n */\n async describeImage(base64DataUri: string): Promise<string> {\n if (!this.orchestrator) {\n throw new Error('JivaRunner not initialized. Call initialize() first.')\n }\n\n const config = readConfig()\n if (!config?.models?.multimodal) {\n throw new Error('No multimodal (vision) model is configured. Enable it in Settings → Models.')\n }\n\n const orchestrator = this.orchestrator as {\n chat(options: unknown): Promise<{ content: string }>\n }\n\n const response = await orchestrator.chat({\n messages: [{\n role: 'user',\n content: [\n { type: 'image_url', image_url: { url: base64DataUri } },\n { type: 'text', text: 'Describe this image in detail, including all visible content, text, charts, diagrams, and any notable elements.' },\n ],\n }],\n })\n\n return response.content\n }\n\n /**\n * Clean up all resources (MCP servers, agent).\n */\n async cleanup(): Promise<void> {\n try {\n if (this.agent) {\n await (this.agent as { cleanup(): Promise<void> }).cleanup()\n this.agent = null\n }\n if (this.mcpManager) {\n await (this.mcpManager as { cleanup(): Promise<void> }).cleanup()\n this.mcpManager = null\n }\n } catch (err) {\n console.warn('[JivaRunner] Cleanup error:', err)\n }\n this.orchestrator = null\n this.workspace = null\n this.conversationManager = null\n this.personaManager = null\n this.currentConversationId = null\n this.setStatus('stopped')\n }\n\n stop(): void {\n if (this.agent) {\n (this.agent as { stop(): void }).stop()\n }\n }\n\n private setStatus(status: RunnerStatus, error?: string) {\n this.status = status\n this.emit('status-changed', status, { error })\n }\n}\n","/**\n * CloudRunner — HTTP/SSE client to the deployed Jiva Cloud Run instance.\n * Implements the same public interface as JivaRunner so ipc-handlers.ts\n * can route transparently between local and cloud modes.\n */\n\nimport type { CodeLogEvent } from './code-runner'\n\nconst CLOUD_RUN_URL = 'https://jiva-hdjcuspt2a-uc.a.run.app'\n\nexport type PhaseUpdate = 'initializing' | 'planning' | 'executing' | 'synthesizing' | 'done'\n\nexport interface CloudRunResult {\n content: string\n iterations: number\n toolsUsed: string[]\n plan: { subtasks: string[]; reasoning?: string } | null\n durationMs: number\n conversationId?: string\n}\n\n\nexport class CloudRunner {\n private userId: string | null = null\n private sessionId: string | null = null\n private _active = false\n private _abortController: AbortController | null = null\n private _readyPromise: Promise<void> | null = null\n private _readyResolve: (() => void) | null = null\n private _readyReject: ((err: Error) => void) | null = null\n\n /** Call this as soon as cloud:init starts — before the async session HTTP call. */\n startInit(): void {\n if (this._active) return\n if (!this._readyPromise) {\n this._readyPromise = new Promise<void>((resolve, reject) => {\n this._readyResolve = resolve\n this._readyReject = reject\n })\n }\n }\n\n configure(userId: string, sessionId: string): void {\n this.userId = userId\n this.sessionId = sessionId\n this._active = true\n this._readyResolve?.()\n this._readyResolve = null\n this._readyReject = null\n }\n\n /**\n * Wait until the runner is configured, up to timeoutMs.\n * Resolves immediately if already active.\n * Rejects if init was never started or times out.\n */\n waitUntilReady(timeoutMs: number): Promise<void> {\n if (this._active) return Promise.resolve()\n if (!this._readyPromise) return Promise.reject(new Error('Cloud runner init not started'))\n return Promise.race([\n this._readyPromise,\n new Promise<void>((_, reject) =>\n setTimeout(() => reject(new Error(`Cloud runner not ready after ${timeoutMs}ms`)), timeoutMs)\n ),\n ])\n }\n\n isActive(): boolean {\n return this._active\n }\n\n isInitializing(): boolean {\n return !this._active && this._readyPromise !== null\n }\n\n deactivate(): void {\n this._active = false\n this.userId = null\n this.sessionId = null\n // Reject any pending waitUntilReady callers\n this._readyReject?.(new Error('Cloud session deactivated'))\n this._readyPromise = null\n this._readyResolve = null\n this._readyReject = null\n }\n\n stop(): void {\n this._abortController?.abort()\n }\n\n private get headers(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n 'x-tenant-id': this.userId ?? 'dev-tenant',\n 'x-session-id': this.sessionId ?? 'default-session',\n }\n }\n\n async chat(\n prompt: string,\n onPhase: (phase: PhaseUpdate) => void,\n _opts?: { deepRun?: boolean },\n onLog?: (event: CodeLogEvent) => void\n ): Promise<CloudRunResult> {\n if (!this._active) throw new Error('CloudRunner not configured')\n\n const startTime = Date.now()\n onPhase('planning')\n\n this._abortController = new AbortController()\n const { signal } = this._abortController\n\n try {\n const result = await this._streamChat(prompt, onPhase, onLog, signal)\n return { ...result, durationMs: Date.now() - startTime }\n } catch (err) {\n if ((err as Error).name === 'AbortError') {\n return {\n content: '',\n iterations: 0,\n toolsUsed: [],\n plan: null,\n durationMs: Date.now() - startTime,\n }\n }\n // SSE failed — fall back to non-streaming\n console.warn('[CloudRunner] SSE failed, falling back to non-streaming:', err)\n const result = await this._nonStreamChat(prompt, onPhase, signal)\n return { ...result, durationMs: Date.now() - startTime }\n } finally {\n this._abortController = null\n onPhase('done')\n }\n }\n\n private async _streamChat(\n prompt: string,\n onPhase: (phase: PhaseUpdate) => void,\n onLog: ((event: CodeLogEvent) => void) | undefined,\n signal: AbortSignal\n ): Promise<Omit<CloudRunResult, 'durationMs'>> {\n const res = await fetch(`${CLOUD_RUN_URL}/api/chat/stream`, {\n method: 'POST',\n headers: { ...this.headers, 'Accept': 'text/event-stream' },\n body: JSON.stringify({ message: prompt }),\n signal,\n })\n\n if (!res.ok || !res.body) {\n throw new Error(`SSE request failed: ${res.status}`)\n }\n\n const reader = res.body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n let content = ''\n let iterations = 0\n const toolsUsed: string[] = []\n let plan: CloudRunResult['plan'] = null\n // Track the current SSE event type from `event:` lines (per SSE spec)\n let currentEventType: string | null = null\n\n outer: while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? ''\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEventType = line.slice(7).trim()\n continue\n }\n if (!line.startsWith('data: ')) continue\n const raw = line.slice(6).trim()\n if (!raw || raw === '[DONE]') continue\n\n let d: Record<string, unknown>\n try {\n d = JSON.parse(raw) as Record<string, unknown>\n } catch {\n continue\n }\n\n // Use the SSE `event:` type; fall back to a `type` field in the payload\n const evtType = currentEventType ?? (d.type as string | undefined)\n currentEventType = null\n\n if (evtType === 'status') {\n const msg = d.message as string | undefined\n if (msg) {\n onPhase('executing')\n onLog?.({\n timestamp: new Date().toISOString(),\n level: 'info',\n tag: 'cloud',\n message: `Tool: ${msg}`,\n })\n }\n } else if (evtType === 'response') {\n content = (d.content ?? d.response ?? '') as string\n iterations = (d.iterations ?? 0) as number\n if (Array.isArray(d.toolsUsed)) toolsUsed.push(...(d.toolsUsed as string[]))\n if (d.plan) plan = d.plan as CloudRunResult['plan']\n } else if (evtType === 'error') {\n throw new Error(d.message as string ?? 'Stream error')\n } else if (evtType === 'done') {\n break outer\n }\n }\n }\n\n return { content, iterations, toolsUsed, plan }\n }\n\n private async _nonStreamChat(\n prompt: string,\n onPhase: (phase: PhaseUpdate) => void,\n signal: AbortSignal\n ): Promise<Omit<CloudRunResult, 'durationMs'>> {\n onPhase('executing')\n const res = await fetch(`${CLOUD_RUN_URL}/api/chat`, {\n method: 'POST',\n headers: this.headers,\n body: JSON.stringify({ message: prompt }),\n signal,\n })\n if (!res.ok) {\n const text = await res.text()\n throw new Error(`Cloud chat failed (${res.status}): ${text}`)\n }\n const d = await res.json() as Record<string, unknown>\n return {\n content: (d.response ?? '') as string,\n iterations: (d.iterations ?? 0) as number,\n toolsUsed: Array.isArray(d.toolsUsed) ? (d.toolsUsed as string[]) : [],\n plan: (d.plan ?? null) as CloudRunResult['plan'],\n }\n }\n\n async resetConversation(): Promise<void> {\n if (!this._active) return\n try {\n await fetch(`${CLOUD_RUN_URL}/api/chat/history`, {\n method: 'DELETE',\n headers: this.headers,\n })\n } catch (e) {\n console.error('[CloudRunner] resetConversation failed:', e)\n }\n }\n\n async stopMessage(): Promise<void> {\n try {\n await fetch(`${CLOUD_RUN_URL}/api/chat/stop`, {\n method: 'POST',\n headers: this.headers,\n })\n } catch {}\n this.stop()\n }\n}\n","import { Router } from 'express'\nimport { execSync } from 'child_process'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport { getJivamConfigPath } from '../config-manager'\n\nconst router = Router()\n\nrouter.get('/check', (_req, res) => {\n // Node.js\n let nodejsOk = false\n let nodejsVersion: string | undefined\n try {\n execSync('npm --version', { timeout: 3000 })\n nodejsOk = true\n try {\n nodejsVersion = execSync('node --version', { timeout: 3000 })\n .toString().trim().replace(/^v/, '')\n } catch {}\n } catch {}\n\n // jiva-core\n let jivaCoreOk = false\n let jivaCoreVersion: string | undefined\n if (nodejsOk) {\n const candidates: string[] = []\n try {\n const npmRoot = execSync('npm root -g', { timeout: 5000 }).toString().trim()\n candidates.push(path.join(npmRoot, 'jiva-core', 'package.json'))\n } catch {}\n candidates.push(path.join(os.homedir(), '.npm-global', 'lib', 'node_modules', 'jiva-core', 'package.json'))\n if (process.platform === 'win32') {\n candidates.push(path.join(process.env.APPDATA ?? '', 'npm', 'node_modules', 'jiva-core', 'package.json'))\n candidates.push(path.join(process.env.LOCALAPPDATA ?? '', 'npm', 'node_modules', 'jiva-core', 'package.json'))\n }\n for (const p of candidates) {\n if (fs.existsSync(p)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(p, 'utf-8')) as { version?: string }\n jivaCoreVersion = pkg.version\n jivaCoreOk = true\n break\n } catch {}\n }\n }\n }\n\n // Config\n const configCandidates = [\n getJivamConfigPath(),\n path.join(os.homedir(), '.jiva', 'config.json'),\n ]\n let configOk = false\n let foundConfigPath = ''\n for (const candidate of configCandidates) {\n if (!fs.existsSync(candidate)) continue\n try {\n const cfg = JSON.parse(fs.readFileSync(candidate, 'utf-8')) as Record<string, unknown>\n const reasoning = ((cfg?.models as Record<string, unknown>)?.reasoning ?? {}) as Record<string, unknown>\n const apiKey = ((reasoning?.apiKey ?? cfg?.apiKey) ?? '') as string\n if (apiKey.length > 0) {\n configOk = true\n foundConfigPath = candidate\n break\n }\n } catch {}\n }\n\n // Version compat\n let jivaVersionMismatch = false\n let requiredJivaVersion: string | undefined\n try {\n const appPkgPath = path.join(__dirname, '..', '..', 'package.json')\n const appPkg = JSON.parse(fs.readFileSync(appPkgPath, 'utf-8')) as Record<string, unknown>\n requiredJivaVersion = appPkg.jivaCompatibleVersion as string | undefined\n if (requiredJivaVersion && jivaCoreVersion) {\n const [reqMaj, reqMin] = requiredJivaVersion.split('.').map(Number)\n const [instMaj, instMin] = jivaCoreVersion.split('.').map(Number)\n if (reqMaj !== instMaj || reqMin !== instMin) jivaVersionMismatch = true\n }\n } catch {}\n\n res.json({\n nodejs: { ok: nodejsOk, version: nodejsVersion },\n jivaCore: { ok: jivaCoreOk, version: jivaCoreVersion },\n config: { ok: configOk, path: foundConfigPath || configCandidates[0] },\n platform: process.platform,\n jivaVersionMismatch,\n requiredJivaVersion,\n })\n})\n\nexport default router\n","import { Router } from 'express'\nimport { readConfig, writeConfig, getJivamConfigPath } from '../config-manager'\nimport os from 'os'\n\nconst router = Router()\n\ntype ProviderKey = 'sarvam' | 'krutrim' | 'groq' | 'openai-compatible'\n\nconst PROVIDER_PRESETS: Record<ProviderKey, {\n endpoint: string\n defaultModel: string\n useHarmonyFormat: boolean\n reasoningEffortStrategy: string\n defaultMaxTokens?: number\n multimodal: { defaultModel: string } | null\n}> = {\n sarvam: {\n endpoint: 'https://api.sarvam.ai/v1/chat/completions',\n defaultModel: 'sarvam-105b',\n useHarmonyFormat: false,\n reasoningEffortStrategy: 'api_param',\n defaultMaxTokens: 8192,\n multimodal: null,\n },\n krutrim: {\n endpoint: 'https://cloud.olakrutrim.com/v1/chat/completions',\n defaultModel: 'gpt-oss-120b',\n useHarmonyFormat: true,\n reasoningEffortStrategy: 'system_prompt',\n multimodal: { defaultModel: 'Llama-4-Maverick-17B-128E-Instruct' },\n },\n groq: {\n endpoint: 'https://api.groq.com/openai/v1/chat/completions',\n defaultModel: 'openai/gpt-oss-120b',\n useHarmonyFormat: false,\n reasoningEffortStrategy: 'api_param',\n multimodal: { defaultModel: 'meta-llama/llama-4-maverick-17b-128e-instruct' },\n },\n 'openai-compatible': {\n endpoint: '',\n defaultModel: '',\n useHarmonyFormat: false,\n reasoningEffortStrategy: 'both',\n multimodal: null,\n },\n}\n\nrouter.get('/', (_req, res) => {\n res.json(readConfig())\n})\n\nrouter.post('/', (req, res) => {\n const ok = writeConfig(req.body)\n res.json(ok)\n})\n\nrouter.get('/path', (_req, res) => {\n res.json(getJivamConfigPath())\n})\n\nrouter.post('/setup-provider', (req, res) => {\n const { provider, apiKey, customEndpoint, customModel } = req.body as {\n provider: ProviderKey\n apiKey: string\n customEndpoint?: string\n customModel?: string\n }\n try {\n const preset = PROVIDER_PRESETS[provider]\n if (!preset) return res.json({ success: false, error: `Unknown provider: ${provider}` })\n\n const endpoint = provider === 'openai-compatible' ? (customEndpoint ?? '') : preset.endpoint\n const defaultModel = provider === 'openai-compatible' ? (customModel ?? '') : preset.defaultModel\n\n const existing = readConfig()\n const config = existing ?? { models: { reasoning: null } }\n\n config.models = {\n ...config.models,\n reasoning: {\n name: 'reasoning',\n type: 'reasoning',\n provider,\n endpoint,\n apiKey,\n defaultModel,\n useHarmonyFormat: preset.useHarmonyFormat,\n reasoningEffortStrategy: preset.reasoningEffortStrategy,\n ...(preset.defaultMaxTokens ? { defaultMaxTokens: preset.defaultMaxTokens } : {}),\n } as Parameters<typeof writeConfig>[0]['models']['reasoning'],\n multimodal: (preset.multimodal\n ? { name: 'multimodal', type: 'multimodal', endpoint, apiKey, defaultModel: preset.multimodal.defaultModel }\n : undefined) as Parameters<typeof writeConfig>[0]['models']['multimodal'],\n }\n\n if (!config.mcpServers) {\n const allowedPath = process.platform === 'win32' ? 'C:\\\\Users' : `${os.homedir()}`\n config.mcpServers = {\n filesystem: { command: 'npx', args: ['-y', '@modelcontextprotocol/server-filesystem', allowedPath], enabled: true },\n 'mcp-shell-server': { command: 'npx', args: ['-y', '@mkusaka/mcp-shell-server'], enabled: true },\n }\n }\n\n const ok = writeConfig(config)\n return res.json({ success: ok, error: ok ? undefined : 'Failed to write config' })\n } catch (err) {\n return res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n})\n\nexport default router\n","import { Router } from 'express'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\n\nconst router = Router()\n\nrouter.get('/', (_req, res) => {\n const convsDir = path.join(os.homedir(), '.jiva', 'conversations')\n try {\n if (!fs.existsSync(convsDir)) return res.json([])\n const files = fs.readdirSync(convsDir)\n .filter(f => f.endsWith('.json'))\n .map(f => {\n const filePath = path.join(convsDir, f)\n const stat = fs.statSync(filePath)\n try {\n const raw = JSON.parse(fs.readFileSync(filePath, 'utf-8'))\n let summary: string = raw.metadata?.title ?? raw.summary ?? raw.title ?? ''\n if (!summary && Array.isArray(raw.messages)) {\n const firstUser = raw.messages.find(\n (m: { role?: string }) => m.role === 'user'\n )\n if (firstUser?.content) {\n const text = typeof firstUser.content === 'string'\n ? firstUser.content\n : Array.isArray(firstUser.content)\n ? firstUser.content.filter((p: { type: string }) => p.type === 'text').map((p: { text?: string }) => p.text ?? '').join('')\n : ''\n summary = text.slice(0, 60).replace(/\\n/g, ' ')\n if (text.length > 60) summary += '...'\n }\n }\n return {\n id: f.replace('.json', ''),\n summary: summary || 'Untitled',\n messageCount: raw.messages?.length ?? 0,\n lastModified: stat.mtimeMs,\n type: (raw.metadata?.type ?? 'chat') as 'chat' | 'code',\n }\n } catch { return null }\n })\n .filter(Boolean)\n .sort((a, b) => b!.lastModified - a!.lastModified)\n return res.json(files)\n } catch {\n return res.json([])\n }\n})\n\nrouter.get('/:id', (req, res) => {\n const filePath = path.join(os.homedir(), '.jiva', 'conversations', `${req.params.id}.json`)\n try {\n if (!fs.existsSync(filePath)) return res.json(null)\n return res.json(JSON.parse(fs.readFileSync(filePath, 'utf-8')))\n } catch {\n return res.json(null)\n }\n})\n\nexport default router\n","import { Router } from 'express'\nimport { execFileSync } from 'child_process'\nimport fs from 'fs'\nimport path from 'path'\n\nconst router = Router()\n\nrouter.get('/is-repo', (req, res) => {\n const dir = req.query.dir as string\n try {\n execFileSync('git', ['rev-parse', '--is-inside-work-tree'], { cwd: dir, timeout: 3000 })\n res.json(true)\n } catch { res.json(false) }\n})\n\nrouter.get('/status', (req, res) => {\n const dir = req.query.dir as string\n try {\n const output = execFileSync('git', ['status', '--porcelain'], { cwd: dir, timeout: 5000 }).toString()\n res.json(output.split('\\n').filter(Boolean).map(line => ({ status: line.slice(0, 2).trim(), file: line.slice(3).trim() })))\n } catch { res.json([]) }\n})\n\nrouter.get('/diff-file', (req, res) => {\n const { dir, file, status } = req.query as { dir: string; file: string; status?: string }\n try {\n if (status === '??') {\n const fullPath = path.join(dir, file)\n try {\n const content = fs.readFileSync(fullPath, 'utf-8')\n const lines = content.split('\\n')\n if (lines[lines.length - 1] === '') lines.pop()\n return res.json(`--- /dev/null\\n+++ b/${file}\\n@@ -0,0 +1,${lines.length} @@\\n${lines.map(l => `+${l}`).join('\\n')}`)\n } catch { return res.json(null) }\n }\n if (status === 'A') {\n try {\n const diff = execFileSync('git', ['diff', '--cached', '--', file], { cwd: dir, timeout: 5000 }).toString()\n if (diff.trim()) return res.json(diff)\n } catch {}\n }\n try {\n const diff = execFileSync('git', ['diff', 'HEAD', '--', file], { cwd: dir, timeout: 5000 }).toString()\n if (diff.trim()) return res.json(diff)\n } catch {}\n try {\n const diff = execFileSync('git', ['diff', '--cached', '--', file], { cwd: dir, timeout: 5000 }).toString()\n if (diff.trim()) return res.json(diff)\n } catch {}\n try {\n const diff = execFileSync('git', ['diff', '--', file], { cwd: dir, timeout: 5000 }).toString()\n if (diff.trim()) return res.json(diff)\n } catch {}\n return res.json(null)\n } catch { return res.json(null) }\n})\n\nrouter.post('/init-repo', (req, res) => {\n const { dir } = req.body as { dir: string }\n try {\n execFileSync('git', ['init'], { cwd: dir, timeout: 10000 })\n res.json({ success: true })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n})\n\nrouter.get('/branch-info', (req, res) => {\n const dir = req.query.dir as string\n try {\n const branch = execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd: dir, timeout: 3000 }).toString().trim()\n let ahead = 0, behind = 0\n try {\n const tracking = execFileSync('git', ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'], { cwd: dir, timeout: 3000 }).toString().trim()\n if (tracking) {\n const ab = execFileSync('git', ['rev-list', '--left-right', '--count', `${tracking}...HEAD`], { cwd: dir, timeout: 3000 }).toString().trim().split('\\t')\n behind = parseInt(ab[0]) || 0\n ahead = parseInt(ab[1]) || 0\n }\n } catch {}\n res.json({ branch, ahead, behind })\n } catch { res.json(null) }\n})\n\nexport default router\n","import { Router } from 'express'\nimport { readConfig, writeConfig } from '../config-manager'\nimport { writeDirective } from '../directive-manager'\n\nconst router = Router()\n\nrouter.get('/', (_req, res) => {\n const config = readConfig()\n res.json((config as unknown as Record<string, unknown>)?.userDirective as string ?? '')\n})\n\nrouter.post('/', (req, res) => {\n const { content } = req.body as { content: string }\n const config = readConfig() ?? { models: { reasoning: null } }\n writeConfig({ ...config, userDirective: content } as Parameters<typeof writeConfig>[0])\n writeDirective(content || undefined)\n res.json({ success: true })\n})\n\nexport default router\n","import { Router } from 'express'\nimport { execSync } from 'child_process'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport { readConfig, writeConfig } from '../config-manager'\n\nconst router = Router()\n\nrouter.get('/dir', (_req, res) => {\n const config = readConfig()\n res.json(config?.workspaceDir ?? os.homedir())\n})\n\nrouter.post('/dir', (req, res) => {\n const { dir } = req.body as { dir: string }\n try {\n const config = readConfig() ?? { models: { reasoning: null } }\n writeConfig({ ...config, workspaceDir: dir })\n res.json({ success: true })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n})\n\n// Opens a native OS folder picker dialog from the server process\nrouter.post('/pick-dir', async (_req, res) => {\n try {\n let picked: string | null = null\n if (process.platform === 'darwin') {\n const result = execSync(\n `osascript -e 'POSIX path of (choose folder with prompt \"Select Workspace Directory\")'`,\n { timeout: 60_000 }\n ).toString().trim()\n if (result) picked = result.replace(/\\/$/, '')\n } else if (process.platform === 'win32') {\n const ps = [\n '[System.Reflection.Assembly]::LoadWithPartialName(\"System.Windows.Forms\") | Out-Null',\n '$f = New-Object System.Windows.Forms.FolderBrowserDialog',\n '$f.Description = \"Select Workspace Directory\"',\n 'if ($f.ShowDialog() -eq \"OK\") { $f.SelectedPath }',\n ].join('; ')\n const result = execSync(`powershell -Command \"${ps}\"`, { timeout: 60_000 }).toString().trim()\n if (result) picked = result\n } else {\n // Linux: try zenity, then kdialog\n try {\n const result = execSync('zenity --file-selection --directory --title=\"Select Workspace Directory\"', { timeout: 60_000 }).toString().trim()\n if (result) picked = result\n } catch {\n try {\n const result = execSync('kdialog --getexistingdirectory \"Select Workspace Directory\"', { timeout: 60_000 }).toString().trim()\n if (result) picked = result\n } catch {}\n }\n }\n res.json(picked)\n } catch {\n res.json(null)\n }\n})\n\nrouter.get('/files', (req, res) => {\n const dirPath = req.query.path as string\n try {\n const homeDir = os.homedir()\n const resolvedDir = path.resolve(dirPath)\n const resolvedHome = path.resolve(homeDir)\n if (!resolvedDir.startsWith(resolvedHome) && resolvedDir !== resolvedHome) return res.json([])\n if (!fs.existsSync(resolvedDir)) return res.json([])\n const entries = fs.readdirSync(resolvedDir, { withFileTypes: true })\n return res.json(\n entries\n .filter(e => !e.name.startsWith('.'))\n .map(e => {\n const fullPath = path.join(resolvedDir, e.name)\n const stat = fs.statSync(fullPath)\n return { name: e.name, path: fullPath, isDirectory: e.isDirectory(), size: stat.size, modified: stat.mtimeMs }\n })\n )\n } catch { return res.json([]) }\n})\n\nrouter.get('/file', (req, res) => {\n const filePath = req.query.path as string\n try {\n const homeDir = os.homedir()\n const resolvedFile = path.resolve(filePath)\n if (!resolvedFile.startsWith(path.resolve(homeDir))) return res.json(null)\n if (!fs.existsSync(resolvedFile)) return res.json(null)\n const stat = fs.statSync(resolvedFile)\n if (stat.size > 512 * 1024) return res.json('[File too large to preview — open in an external editor]')\n return res.json(fs.readFileSync(resolvedFile, 'utf-8'))\n } catch { return res.json(null) }\n})\n\nrouter.post('/open-external', (req, res) => {\n const { filePath } = req.body as { filePath: string }\n try {\n const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'explorer' : 'xdg-open'\n execSync(`${cmd} \"${filePath}\"`, { timeout: 5000 })\n } catch {}\n res.json({})\n})\n\nexport default router\n","import { Router } from 'express'\nimport { JivaRunner } from '../jiva-runner'\nimport { CloudRunner } from '../cloud-runner'\nimport { broadcast } from '../ws'\n\nexport function createJivaRouter(jivaRunner: JivaRunner, cloudRunner: CloudRunner) {\n const router = Router()\n\n router.post('/start', async (_req, res) => {\n try {\n if (jivaRunner.getStatus() === 'stopped' || jivaRunner.getStatus() === 'error') {\n await jivaRunner.initialize()\n }\n res.json({ success: true, status: jivaRunner.getStatus() })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n router.post('/stop', async (_req, res) => {\n try {\n await jivaRunner.cleanup()\n res.json({ success: true })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n router.post('/restart', async (_req, res) => {\n try {\n await jivaRunner.cleanup()\n await jivaRunner.initialize()\n res.json({ success: true, status: jivaRunner.getStatus() })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n router.get('/status', (_req, res) => {\n const status = jivaRunner.getStatus()\n res.json({ status: status === 'ready' || status === 'busy' ? 'running' : status, port: 0 })\n })\n\n router.post('/send-message', async (req, res) => {\n const { prompt, opts, isCloud } = req.body as {\n prompt: string\n opts?: { deepRun?: boolean }\n isCloud?: boolean\n }\n try {\n if (isCloud) {\n if (!cloudRunner.isActive()) await cloudRunner.waitUntilReady(30_000)\n const result = await cloudRunner.chat(prompt, (phase) => {\n broadcast('jiva:phase-update', { phase })\n }, opts, (logEvent) => {\n broadcast('jiva:jiva-log', { event: logEvent })\n })\n return res.json({ success: true, result, conversationId: result.conversationId })\n }\n\n if (jivaRunner.getStatus() === 'stopped' || jivaRunner.getStatus() === 'error') {\n await jivaRunner.initialize()\n }\n const result = await jivaRunner.chat(prompt, (phase) => {\n broadcast('jiva:phase-update', { phase })\n }, opts, (logEvent) => {\n broadcast('jiva:jiva-log', { event: logEvent })\n })\n return res.json({ success: true, result, conversationId: result.conversationId })\n } catch (err) {\n return res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n router.post('/stop-message', (_req, res) => {\n jivaRunner.stop()\n res.json({ success: true })\n })\n\n router.post('/reset-conversation', (_req, res) => {\n jivaRunner.resetConversation()\n res.json({ success: true })\n })\n\n router.post('/load-conversation', async (req, res) => {\n const { id } = req.body as { id: string }\n try {\n if (jivaRunner.getStatus() === 'stopped' || jivaRunner.getStatus() === 'error') {\n await jivaRunner.initialize()\n }\n await jivaRunner.loadConversation(id)\n res.json({ success: true })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n // Wire up status-changed events to WebSocket broadcasts\n jivaRunner.on('status-changed', (status: string, data: unknown) => {\n const serverStatus = status === 'ready' || status === 'busy' ? 'running' : status\n broadcast('jiva:server:status-changed', { status: serverStatus, data })\n })\n\n return router\n}\n","import fs from 'fs'\nimport path from 'path'\nimport os from 'os'\nimport { getJivaConfigPath } from './config-manager'\n\nconst PERSONAS_DIR = path.join(os.homedir(), '.jiva', 'personas')\n\nexport interface PersonaInfo {\n name: string\n displayName: string\n description: string\n tags: string[]\n icon: string\n isBuiltIn: boolean\n dirPath: string\n}\n\n/**\n * Returns a lucide-react icon name string for this persona.\n * The renderer resolves the name to a component via a lookup map in PersonaCard.tsx.\n */\nfunction getPersonaIcon(name: string, tags: string[]): string {\n if (name === 'chat' || tags.includes('chat')) return 'MessageSquare'\n if (name === 'research' || tags.includes('research')) return 'Search'\n if (name === 'developer' || name === 'code-reviewer' || tags.includes('code')) return 'Code2'\n if (name === 'engineering-manager' || tags.includes('management')) return 'Layers'\n if (name === 'tester' || tags.includes('testing')) return 'FlaskConical'\n if (name === 'data-analyst' || tags.includes('data')) return 'BarChart3'\n return 'Bot'\n}\n\nexport function listPersonas(): PersonaInfo[] {\n const personas: PersonaInfo[] = []\n\n if (!fs.existsSync(PERSONAS_DIR)) {\n return personas\n }\n\n try {\n const entries = fs.readdirSync(PERSONAS_DIR, { withFileTypes: true })\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue\n if (entry.name === 'skills') continue // skip skills subdirectory\n\n const personaDir = path.join(PERSONAS_DIR, entry.name)\n const pluginJsonPath = path.join(personaDir, '.jiva-plugin', 'plugin.json')\n\n let manifest: { name?: string; description?: string; tags?: string[] } = {}\n\n if (fs.existsSync(pluginJsonPath)) {\n try {\n const raw = fs.readFileSync(pluginJsonPath, 'utf-8')\n manifest = JSON.parse(raw)\n } catch {\n // Use defaults\n }\n }\n\n const name = entry.name\n const tags = manifest.tags ?? []\n const builtInNames = ['chat', 'research']\n\n personas.push({\n name,\n displayName: (manifest.name ?? name).replace(/-/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase()),\n description: manifest.description ?? `${name} persona`,\n tags,\n icon: getPersonaIcon(name, tags),\n isBuiltIn: builtInNames.includes(name),\n dirPath: personaDir,\n })\n }\n } catch (err) {\n console.error('[PersonaManager] Failed to list personas:', err)\n }\n\n // Sort: built-ins first, then alphabetical\n return personas.sort((a, b) => {\n if (a.isBuiltIn && !b.isBuiltIn) return -1\n if (!a.isBuiltIn && b.isBuiltIn) return 1\n return a.name.localeCompare(b.name)\n })\n}\n\nexport function activatePersona(name: string): boolean {\n const { execSync } = require('child_process') as typeof import('child_process')\n try {\n execSync(`jiva persona activate ${name}`, { timeout: 10000, stdio: 'ignore' })\n return true\n } catch {\n // Try writing to active persona file directly\n const activeFile = path.join(os.homedir(), '.jiva', 'active-persona.txt')\n try {\n fs.writeFileSync(activeFile, name, 'utf-8')\n return true\n } catch {\n return false\n }\n }\n}\n\nexport function getActivePersona(): string | null {\n try {\n const jivaConfigPath = getJivaConfigPath()\n if (fs.existsSync(jivaConfigPath)) {\n const config = JSON.parse(fs.readFileSync(jivaConfigPath, 'utf-8'))\n if (config.activePersona) return config.activePersona\n }\n const activeFile = path.join(os.homedir(), '.jiva', 'active-persona.txt')\n if (fs.existsSync(activeFile)) {\n return fs.readFileSync(activeFile, 'utf-8').trim()\n }\n } catch {}\n return null\n}\n","import { Router } from 'express'\nimport { listPersonas, activatePersona, getActivePersona } from '../persona-manager'\nimport { JivaRunner } from '../jiva-runner'\n\nexport function createPersonasRouter(jivaRunner: JivaRunner) {\n const router = Router()\n\n router.get('/', (_req, res) => {\n res.json(listPersonas())\n })\n\n router.post('/activate', async (req, res) => {\n const { name } = req.body as { name: string }\n const success = activatePersona(name)\n if (success) {\n try {\n await jivaRunner.switchPersona(name)\n } catch (err) {\n console.error('[Personas] Failed to switch persona:', err)\n }\n }\n res.json({ success })\n })\n\n router.get('/active', (_req, res) => {\n res.json(getActivePersona())\n })\n\n return router\n}\n","import { Router } from 'express'\nimport { readConfig, writeConfig } from '../config-manager'\nimport { JivaRunner } from '../jiva-runner'\n\nexport function createMcpRouter(jivaRunner: JivaRunner) {\n const router = Router()\n\n router.get('/status', (_req, res) => {\n try {\n const runtimeStatus = jivaRunner.getMCPServerStatus()\n const config = readConfig()\n const configServers: Record<string, { command?: string; args?: string[]; env?: Record<string, string>; url?: string; enabled: boolean }> = config?.mcpServers ?? {}\n const statusMap = new Map(runtimeStatus.map((s) => [s.name, s]))\n\n const allServers = Object.entries(configServers).map(([name, serverCfg]) => {\n const rt = statusMap.get(name)\n return {\n name, enabled: serverCfg.enabled ?? true,\n connected: rt?.connected ?? false, toolCount: rt?.toolCount ?? 0,\n command: serverCfg.command ?? '', args: serverCfg.args ?? [],\n env: serverCfg.env ?? {}, url: (serverCfg as Record<string, unknown>).url as string | undefined,\n type: serverCfg.command ? 'stdio' : 'http', error: rt?.error,\n }\n })\n for (const rt of runtimeStatus) {\n if (!configServers[rt.name]) {\n allServers.push({ name: rt.name, enabled: rt.enabled, connected: rt.connected,\n toolCount: rt.toolCount, command: '', args: [], env: {}, url: undefined, type: 'stdio', error: undefined })\n }\n }\n res.json(allServers)\n } catch { res.json([]) }\n })\n\n router.get('/tools', (_req, res) => {\n try { res.json(jivaRunner.getMCPTools()) } catch { res.json({}) }\n })\n\n router.post('/add', async (req, res) => {\n const { name, config: serverConfig } = req.body as {\n name: string\n config: { command?: string; args?: string[]; env?: Record<string, string>; url?: string; type: 'stdio' | 'http'; enabled?: boolean }\n }\n try {\n const config = readConfig()\n if (!config) return res.json({ success: false, error: 'Config not found' })\n const mcpEntry: Record<string, unknown> = { enabled: serverConfig.enabled ?? true }\n if (serverConfig.type === 'stdio') {\n mcpEntry.command = serverConfig.command ?? ''\n mcpEntry.args = serverConfig.args ?? []\n if (serverConfig.env && Object.keys(serverConfig.env).length > 0) mcpEntry.env = serverConfig.env\n } else {\n mcpEntry.url = serverConfig.url ?? ''\n if (serverConfig.env && Object.keys(serverConfig.env).length > 0) mcpEntry.env = serverConfig.env\n }\n if (!config.mcpServers) config.mcpServers = {}\n ;(config.mcpServers as unknown as Record<string, unknown>)[name] = mcpEntry\n writeConfig(config)\n if (jivaRunner.getStatus() === 'ready' || jivaRunner.getStatus() === 'busy') {\n await jivaRunner.addMCPServer(name, mcpEntry)\n }\n return res.json({ success: true })\n } catch (err) {\n return res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n router.post('/remove', async (req, res) => {\n const { name } = req.body as { name: string }\n try {\n const config = readConfig()\n if (config?.mcpServers) { delete config.mcpServers[name]; writeConfig(config) }\n if (jivaRunner.getStatus() === 'ready' || jivaRunner.getStatus() === 'busy') {\n await jivaRunner.removeMCPServer(name)\n }\n res.json({ success: true })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n router.post('/toggle', async (req, res) => {\n const { name, enabled } = req.body as { name: string; enabled: boolean }\n try {\n const config = readConfig()\n if (config?.mcpServers?.[name]) { config.mcpServers[name].enabled = enabled; writeConfig(config) }\n if (jivaRunner.getStatus() === 'ready' || jivaRunner.getStatus() === 'busy') {\n await jivaRunner.toggleMCPServer(name, enabled)\n }\n res.json({ success: true })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n router.post('/reconnect', async (req, res) => {\n const { name } = req.body as { name: string }\n try {\n await jivaRunner.reconnectMCPServer(name)\n res.json({ success: true })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n return router\n}\n","import { Router } from 'express'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport { CodeRunner } from '../code-runner'\nimport { readConfig } from '../config-manager'\nimport { broadcast } from '../ws'\n\nconst MCP_SELECTIONS_PATH = path.join(os.homedir(), '.jiva', 'jivam-mcp-selections.json')\n\nfunction readMcpSelections(): Record<string, string[]> {\n try {\n if (fs.existsSync(MCP_SELECTIONS_PATH)) {\n return JSON.parse(fs.readFileSync(MCP_SELECTIONS_PATH, 'utf-8')) as Record<string, string[]>\n }\n } catch {}\n return {}\n}\n\nexport function createCodeRouter(codeRunner: CodeRunner) {\n const router = Router()\n\n router.post('/send-message', async (req, res) => {\n const { prompt, opts } = req.body as { prompt: string; opts?: { deepRun?: boolean } }\n try {\n if (!codeRunner.isReady()) {\n const config = readConfig()\n const workspaceDir = (config as unknown as Record<string, unknown>)?.workspaceDir as string | undefined ?? os.homedir()\n await codeRunner.initialize(workspaceDir)\n }\n const result = await codeRunner.chat(prompt, (event) => {\n broadcast('jiva:code-log', { event })\n }, opts)\n res.json({ success: true, ...result })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n router.post('/stop-message', (_req, res) => {\n codeRunner.stop()\n res.json({ success: true })\n })\n\n router.post('/reset-session', async (_req, res) => {\n try {\n await codeRunner.cleanup()\n res.json({ success: true })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n router.post('/init', async (req, res) => {\n const { dir, mcpServers, opts } = req.body as {\n dir: string; mcpServers?: string[]; opts?: { deepRun?: boolean; maxIterations?: number }\n }\n try {\n await codeRunner.initialize(dir, mcpServers, opts)\n res.json({ success: true })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n router.get('/mcp-for-code', (_req, res) => {\n try {\n const config = readConfig()\n const servers = (config as unknown as Record<string, unknown>)?.mcpServers as Record<string, Record<string, unknown>> ?? {}\n res.json(Object.entries(servers).map(([name, cfg]) => ({\n name, enabled: (cfg.enabled ?? true) as boolean,\n codeMode: cfg.codeMode === true, command: (cfg.command ?? '') as string,\n url: cfg.url as string | undefined,\n })))\n } catch { res.json([]) }\n })\n\n router.get('/conversation-id', (_req, res) => {\n res.json(codeRunner.getConversationId())\n })\n\n router.get('/mcp-selection/:convId', (req, res) => {\n res.json(readMcpSelections()[req.params.convId] ?? [])\n })\n\n router.post('/mcp-selection', (req, res) => {\n const { convId, servers } = req.body as { convId: string; servers: string[] }\n try {\n const data = readMcpSelections()\n data[convId] = servers\n fs.mkdirSync(path.dirname(MCP_SELECTIONS_PATH), { recursive: true })\n fs.writeFileSync(MCP_SELECTIONS_PATH, JSON.stringify(data, null, 2))\n res.json({ success: true })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n return router\n}\n","import fs from 'fs'\nimport path from 'path'\nimport zlib from 'zlib'\n\nexport type FileCategory = 'text' | 'pdf' | 'docx' | 'image' | 'unsupported'\n\nexport interface ConvertedFile {\n name: string\n category: FileCategory\n markdown: string // text/pdf/docx → markdown content; image → base64 data URI\n mimeType?: string // images only\n error?: string\n}\n\nconst TEXT_EXTENSIONS = new Set([\n 'txt', 'md', 'markdown', 'rst', 'log',\n 'js', 'jsx', 'ts', 'tsx', 'mjs', 'cjs',\n 'py', 'rb', 'go', 'rs', 'java', 'kt', 'swift',\n 'c', 'cpp', 'cc', 'h', 'hpp', 'cs',\n 'css', 'scss', 'sass', 'less',\n 'html', 'htm', 'xml', 'svg', 'xhtml',\n 'json', 'jsonc', 'yaml', 'yml', 'toml', 'ini', 'cfg', 'conf',\n 'sh', 'bash', 'zsh', 'fish', 'ps1', 'bat', 'cmd',\n 'sql', 'graphql', 'gql', 'proto',\n 'env', 'editorconfig', 'gitignore', 'gitattributes',\n 'dockerfile', 'makefile', 'cmake', 'gradle',\n 'r', 'jl', 'scala', 'clj', 'ex', 'exs', 'erl', 'hs', 'lua', 'pl',\n 'vue', 'svelte', 'astro',\n 'lock', 'mod', 'sum',\n])\n\nconst IMAGE_EXTENSIONS: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n webp: 'image/webp',\n bmp: 'image/bmp',\n}\n\nconst LANG_MAP: Record<string, string> = {\n js: 'javascript', jsx: 'jsx', ts: 'typescript', tsx: 'tsx',\n py: 'python', rb: 'ruby', go: 'go', rs: 'rust',\n java: 'java', kt: 'kotlin', swift: 'swift', cs: 'csharp',\n c: 'c', cpp: 'cpp', h: 'c', hpp: 'cpp',\n css: 'css', scss: 'scss', sass: 'sass', less: 'less',\n html: 'html', htm: 'html', xml: 'xml', svg: 'xml',\n json: 'json', jsonc: 'json', yaml: 'yaml', yml: 'yaml', toml: 'toml',\n sh: 'bash', bash: 'bash', zsh: 'bash', fish: 'fish', ps1: 'powershell',\n sql: 'sql', graphql: 'graphql', gql: 'graphql', proto: 'protobuf',\n md: 'markdown', markdown: 'markdown', rst: 'rst',\n r: 'r', jl: 'julia', scala: 'scala', lua: 'lua',\n vue: 'vue', svelte: 'svelte',\n}\n\nexport function getFileCategory(ext: string): FileCategory {\n const lower = ext.toLowerCase().replace(/^\\./, '')\n if (TEXT_EXTENSIONS.has(lower)) return 'text'\n if (lower in IMAGE_EXTENSIONS) return 'image'\n if (lower === 'pdf') return 'pdf'\n if (lower === 'docx') return 'docx'\n return 'unsupported'\n}\n\nexport function convertFile(filePath: string): ConvertedFile {\n const name = path.basename(filePath)\n const ext = path.extname(filePath).toLowerCase().replace(/^\\./, '')\n const category = getFileCategory(ext)\n\n try {\n switch (category) {\n case 'text': return convertTextFile(filePath, name, ext)\n case 'pdf': return convertPdf(filePath, name)\n case 'docx': return convertDocx(filePath, name)\n case 'image': return convertImage(filePath, name, ext)\n default: return { name, category: 'unsupported', markdown: '', error: `File type .${ext} is not supported` }\n }\n } catch (err) {\n return {\n name,\n category,\n markdown: '',\n error: err instanceof Error ? err.message : 'Failed to read file',\n }\n }\n}\n\nfunction convertTextFile(filePath: string, name: string, ext: string): ConvertedFile {\n const stat = fs.statSync(filePath)\n if (stat.size > 2 * 1024 * 1024) {\n return { name, category: 'text', markdown: '', error: 'File is too large (max 2 MB for text files)' }\n }\n const content = fs.readFileSync(filePath, 'utf-8')\n const lang = LANG_MAP[ext] ?? ext\n const markdown = `\\`\\`\\`${lang}\\n${content}\\n\\`\\`\\``\n return { name, category: 'text', markdown }\n}\n\n// ---------------------------------------------------------------------------\n// PDF: extract text from PDF content streams using BT/ET markers\n// ---------------------------------------------------------------------------\nfunction convertPdf(filePath: string, name: string): ConvertedFile {\n const stat = fs.statSync(filePath)\n if (stat.size > 10 * 1024 * 1024) {\n return { name, category: 'pdf', markdown: '', error: 'PDF is too large (max 10 MB)' }\n }\n\n const buffer = fs.readFileSync(filePath)\n const text = extractPdfText(buffer)\n\n if (!text.trim()) {\n return { name, category: 'pdf', markdown: '', error: 'Could not extract text from PDF (may be a scanned/image-only PDF)' }\n }\n\n const markdown = `**[PDF: ${name}]**\\n\\n${text}`\n return { name, category: 'pdf', markdown }\n}\n\nfunction extractPdfText(buffer: Buffer): string {\n // Work on a latin1 string so byte values map 1:1\n const raw = buffer.toString('latin1')\n const parts: string[] = []\n\n // Find compressed object streams (FlateDecode) and decompress them\n const compressedStreamRe = /<<[^>]*\\/Filter\\s*\\/FlateDecode[^>]*>>\\s*stream\\r?\\n([\\s\\S]*?)\\r?\\nendstream/g\n let m: RegExpExecArray | null\n while ((m = compressedStreamRe.exec(raw)) !== null) {\n try {\n const buf = Buffer.from(m[1], 'latin1')\n const decompressed = zlib.inflateSync(buf).toString('latin1')\n parts.push(...extractTextFromStream(decompressed))\n } catch { /* skip undecompressable streams */ }\n }\n\n // Also scan uncompressed text streams\n const btEtRe = /BT([\\s\\S]*?)ET/g\n while ((m = btEtRe.exec(raw)) !== null) {\n parts.push(...extractTextFromStream(m[1]))\n }\n\n // Deduplicate and join\n return [...new Set(parts)].join(' ').replace(/\\s+/g, ' ').trim()\n}\n\nfunction extractTextFromStream(stream: string): string[] {\n const results: string[] = []\n\n // Collect BT..ET blocks\n const btEtRe = /BT([\\s\\S]*?)ET/g\n let m: RegExpExecArray | null\n while ((m = btEtRe.exec(stream)) !== null) {\n const block = m[1]\n // Literal strings: (text)\n const litRe = /\\(([^)\\\\]*(?:\\\\.[^)\\\\]*)*)\\)/g\n let s: RegExpExecArray | null\n while ((s = litRe.exec(block)) !== null) {\n const decoded = s[1]\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\r/g, '\\r')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\\\(/g, '(')\n .replace(/\\\\\\)/g, ')')\n .replace(/\\\\\\\\/g, '\\\\')\n const clean = decoded.replace(/[^\\x20-\\x7E\\n\\r\\t]/g, '').trim()\n if (clean.length > 0) results.push(clean)\n }\n\n // Hex strings: <4865...>\n const hexRe = /<([0-9A-Fa-f\\s]+)>/g\n while ((s = hexRe.exec(block)) !== null) {\n const hex = s[1].replace(/\\s/g, '')\n if (hex.length % 2 !== 0) continue\n let str = ''\n for (let i = 0; i < hex.length; i += 2) {\n const code = parseInt(hex.slice(i, i + 2), 16)\n if (code >= 0x20 && code <= 0x7E) str += String.fromCharCode(code)\n }\n if (str.trim().length > 0) results.push(str.trim())\n }\n }\n\n return results\n}\n\n// ---------------------------------------------------------------------------\n// DOCX: parse ZIP, extract word/document.xml, strip XML tags\n// ---------------------------------------------------------------------------\nfunction convertDocx(filePath: string, name: string): ConvertedFile {\n const stat = fs.statSync(filePath)\n if (stat.size > 10 * 1024 * 1024) {\n return { name, category: 'docx', markdown: '', error: 'DOCX is too large (max 10 MB)' }\n }\n\n const buffer = fs.readFileSync(filePath)\n const xml = extractFromZip(buffer, 'word/document.xml')\n\n if (!xml) {\n return { name, category: 'docx', markdown: '', error: 'Could not extract content from DOCX file' }\n }\n\n const text = parseDocumentXml(xml.toString('utf-8'))\n\n if (!text.trim()) {\n return { name, category: 'docx', markdown: '', error: 'DOCX appears to be empty' }\n }\n\n const markdown = `**[DOCX: ${name}]**\\n\\n${text}`\n return { name, category: 'docx', markdown }\n}\n\nfunction extractFromZip(buffer: Buffer, targetPath: string): Buffer | null {\n let offset = 0\n\n while (offset < buffer.length - 30) {\n // Local file header signature: PK\\x03\\x04\n if (buffer.readUInt32LE(offset) !== 0x04034b50) {\n offset++\n continue\n }\n\n const compressionMethod = buffer.readUInt16LE(offset + 8)\n const compressedSize = buffer.readUInt32LE(offset + 18)\n const uncompressedSize = buffer.readUInt32LE(offset + 22)\n const filenameLen = buffer.readUInt16LE(offset + 26)\n const extraLen = buffer.readUInt16LE(offset + 28)\n\n const filename = buffer.slice(offset + 30, offset + 30 + filenameLen).toString('utf-8')\n const dataStart = offset + 30 + filenameLen + extraLen\n const dataEnd = dataStart + compressedSize\n\n if (filename === targetPath) {\n const compressed = buffer.slice(dataStart, dataEnd)\n if (compressionMethod === 0) {\n // Stored (no compression)\n return compressed\n } else if (compressionMethod === 8) {\n // Deflated — use inflateRawSync (raw deflate, no zlib header)\n try {\n return zlib.inflateRawSync(compressed)\n } catch {\n // Some DOCX use standard deflate with zlib header\n try {\n return zlib.inflateSync(compressed)\n } catch {\n return null\n }\n }\n }\n return null\n }\n\n // Skip to next local file header\n if (compressedSize === 0 && uncompressedSize === 0) {\n offset = dataStart\n } else {\n offset = dataEnd\n }\n }\n\n return null\n}\n\nfunction parseDocumentXml(xml: string): string {\n // Extract paragraph text, preserving paragraph breaks\n const paragraphs: string[] = []\n const paraRe = /<w:p[ >]([\\s\\S]*?)<\\/w:p>/g\n let m: RegExpExecArray | null\n\n while ((m = paraRe.exec(xml)) !== null) {\n // Extract text runs within the paragraph\n const runs: string[] = []\n const runRe = /<w:t[^>]*>([^<]*)<\\/w:t>/g\n let r: RegExpExecArray | null\n while ((r = runRe.exec(m[1])) !== null) {\n runs.push(r[1])\n }\n const text = runs.join('').trim()\n if (text) paragraphs.push(text)\n }\n\n return paragraphs.join('\\n\\n')\n}\n\n// ---------------------------------------------------------------------------\n// Image: base64 encode for multimodal model consumption\n// ---------------------------------------------------------------------------\nfunction convertImage(filePath: string, name: string, ext: string): ConvertedFile {\n const stat = fs.statSync(filePath)\n if (stat.size > 20 * 1024 * 1024) {\n return { name, category: 'image', markdown: '', error: 'Image is too large (max 20 MB)' }\n }\n\n const mimeType = IMAGE_EXTENSIONS[ext.toLowerCase()] ?? 'image/png'\n // Return the original path — the IPC handler will copy it to the workspace uploads dir\n return { name, category: 'image', markdown: filePath, mimeType }\n}\n","import { Router } from 'express'\nimport fs from 'fs'\nimport os from 'os'\nimport path from 'path'\nimport { convertFile } from '../file-converter'\nimport { JivaRunner } from '../jiva-runner'\n\nexport function createFilesRouter(jivaRunner: JivaRunner) {\n const router = Router()\n\n // Convert a file already on disk (used for paths returned by the workspace picker)\n router.post('/convert', (req, res) => {\n const { filePath } = req.body as { filePath: string }\n const homeDir = os.homedir()\n const resolved = path.resolve(filePath)\n if (!resolved.startsWith(path.resolve(homeDir))) {\n return res.json({ name: path.basename(filePath), category: 'unsupported', markdown: '', error: 'Access denied' })\n }\n const result = convertFile(filePath)\n if (result.category === 'image' && !result.error) {\n try {\n const config = (() => { try { return JSON.parse(fs.readFileSync(path.join(os.homedir(), 'Library', 'Preferences', 'jiva-nodejs', 'config.json'), 'utf-8')) } catch { return null } })()\n const workspaceDir = (config as Record<string, unknown>)?.workspaceDir as string ?? homeDir\n const uploadsDir = path.join(workspaceDir, '.jiva', 'uploads')\n fs.mkdirSync(uploadsDir, { recursive: true })\n const destPath = path.join(uploadsDir, path.basename(filePath))\n fs.copyFileSync(filePath, destPath)\n result.markdown = destPath\n } catch (err) {\n result.error = `Failed to save image: ${err instanceof Error ? err.message : String(err)}`\n }\n }\n return res.json(result)\n })\n\n // Upload files from browser as base64, convert on server\n router.post('/upload-and-convert', (req, res) => {\n const { files } = req.body as {\n files: Array<{ name: string; data: string; mimeType: string }>\n }\n const homeDir = os.homedir()\n const tmpDir = path.join(os.tmpdir(), 'jivam-uploads')\n fs.mkdirSync(tmpDir, { recursive: true })\n\n const results = files.map(f => {\n const tmpPath = path.join(tmpDir, f.name)\n try {\n fs.writeFileSync(tmpPath, Buffer.from(f.data, 'base64'))\n const result = convertFile(tmpPath)\n if (result.category === 'image' && !result.error) {\n try {\n const config = (() => { try { return JSON.parse(fs.readFileSync(path.join(homeDir, 'Library', 'Preferences', 'jiva-nodejs', 'config.json'), 'utf-8')) } catch { return null } })()\n const workspaceDir = (config as Record<string, unknown>)?.workspaceDir as string ?? homeDir\n const uploadsDir = path.join(workspaceDir, '.jiva', 'uploads')\n fs.mkdirSync(uploadsDir, { recursive: true })\n const destPath = path.join(uploadsDir, f.name)\n fs.copyFileSync(tmpPath, destPath)\n result.markdown = destPath\n } catch {}\n }\n return result\n } catch (err) {\n return { name: f.name, category: 'unsupported' as const, markdown: '', error: String(err) }\n } finally {\n try { fs.unlinkSync(tmpPath) } catch {}\n }\n })\n\n res.json(results)\n })\n\n router.post('/describe-image', async (req, res) => {\n const { dataUri } = req.body as { dataUri: string }\n try {\n const description = await jivaRunner.describeImage(dataUri)\n res.json({ success: true, description })\n } catch (err) {\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n return router\n}\n","/**\n * Supabase Auth — fetch-based, no SDK.\n * Project: hcomegrnonxmjupvvyus\n */\n\nconst SUPABASE_URL = 'https://hcomegrnonxmjupvvyus.supabase.co'\nconst SUPABASE_ANON_KEY =\n 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imhjb21lZ3Jub254bWp1cHZ2eXVzIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzgxNTQwMjcsImV4cCI6MjA5MzczMDAyN30.sBBOTrPsdCZk75HDEzJaIv5Mz-bE3HTuJQ-1LcJ45nk'\n\nconst CLOUD_RUN_URL = 'https://jiva-hdjcuspt2a-uc.a.run.app'\n\nexport interface CloudUser {\n userId: string\n email: string\n accessToken: string\n refreshToken: string\n}\n\nasync function supabaseFetch(path: string, body: Record<string, unknown>): Promise<Record<string, unknown>> {\n const res = await fetch(`${SUPABASE_URL}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'apikey': SUPABASE_ANON_KEY,\n },\n body: JSON.stringify(body),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n const msg = (data.error_description ?? data.error ?? data.message ?? 'Auth failed') as string\n throw new Error(msg)\n }\n return data\n}\n\nexport async function cloudSignIn(email: string, password: string): Promise<CloudUser> {\n const data = await supabaseFetch('/auth/v1/token?grant_type=password', { email, password })\n return {\n userId: (data.user as Record<string, unknown>).id as string,\n email: (data.user as Record<string, unknown>).email as string,\n accessToken: data.access_token as string,\n refreshToken: data.refresh_token as string,\n }\n}\n\nexport async function cloudSignUp(email: string, password: string): Promise<CloudUser> {\n const data = await supabaseFetch('/auth/v1/signup', { email, password })\n // Supabase signup response varies by project config:\n // - Auto-confirm ON: { access_token, refresh_token, user: { id, email, ... } }\n // - Email confirmation required: user object at top level, no access_token\n const userObj = ((data.user ?? data) as Record<string, unknown>)\n return {\n userId: userObj.id as string,\n email: userObj.email as string,\n accessToken: (data.access_token ?? '') as string,\n refreshToken: (data.refresh_token ?? '') as string,\n }\n}\n\nexport async function cloudSignOut(accessToken: string): Promise<void> {\n await fetch(`${SUPABASE_URL}/auth/v1/logout`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'apikey': SUPABASE_ANON_KEY,\n 'Authorization': `Bearer ${accessToken}`,\n },\n })\n}\n\n/**\n * Create or restore a Cloud Run session for the given user.\n * Returns the sessionId to use for subsequent API calls.\n */\nexport async function initCloudSession(userId: string, sessionId: string): Promise<void> {\n const res = await fetch(`${CLOUD_RUN_URL}/api/session`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-tenant-id': userId,\n 'x-session-id': sessionId,\n },\n body: JSON.stringify({}),\n })\n if (!res.ok) {\n const text = await res.text()\n throw new Error(`Cloud session init failed: ${text}`)\n }\n}\n","import { Router } from 'express'\nimport { cloudSignIn, cloudSignUp, cloudSignOut, initCloudSession } from '../cloud-auth'\nimport { CloudRunner } from '../cloud-runner'\n\nexport function createCloudRouter(cloudRunner: CloudRunner) {\n const router = Router()\n\n router.post('/sign-in', async (req, res) => {\n const { email, password } = req.body as { email: string; password: string }\n try {\n const user = await cloudSignIn(email, password)\n res.json({ userId: user.userId, email: user.email })\n } catch (err) {\n res.json({ error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n router.post('/sign-up', async (req, res) => {\n const { email, password } = req.body as { email: string; password: string }\n try {\n const user = await cloudSignUp(email, password)\n res.json({ userId: user.userId, email: user.email })\n } catch (err) {\n res.json({ error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n router.post('/sign-out', (_req, res) => {\n cloudRunner.deactivate()\n res.json({})\n })\n\n router.post('/init', async (req, res) => {\n const { userId, sessionId } = req.body as { userId: string; sessionId: string }\n cloudRunner.startInit()\n try {\n await initCloudSession(userId, sessionId)\n cloudRunner.configure(userId, sessionId)\n res.json({ success: true })\n } catch (err) {\n cloudRunner.deactivate()\n res.json({ success: false, error: err instanceof Error ? err.message : String(err) })\n }\n })\n\n return router\n}\n","import { augmentPath } from './path-helper'\naugmentPath()\n\nimport express from 'express'\nimport http from 'http'\nimport path from 'path'\nimport fs from 'fs'\nimport os from 'os'\nimport { initWebSocketServer } from './ws'\nimport { JivaRunner } from './jiva-runner'\nimport { CodeRunner } from './code-runner'\nimport { CloudRunner } from './cloud-runner'\n\nimport setupRouter from './routes/setup'\nimport configRouter from './routes/config'\nimport conversationsRouter from './routes/conversations'\nimport gitRouter from './routes/git'\nimport directiveRouter from './routes/directive'\nimport workspaceRouter from './routes/workspace'\nimport { createJivaRouter } from './routes/jiva'\nimport { createPersonasRouter } from './routes/personas'\nimport { createMcpRouter } from './routes/mcp'\nimport { createCodeRouter } from './routes/code'\nimport { createFilesRouter } from './routes/files'\nimport { createCloudRouter } from './routes/cloud'\n\nconst PORT = parseInt(process.env.JIVAM_PORT ?? '7842', 10)\nconst IS_DEV = process.env.NODE_ENV === 'development'\n\n// ---------------------------------------------------------------------------\n// jivam --install (macOS only for now)\n// Creates ~/Applications/Jivam.app — a self-contained shell wrapper that\n// starts the server if not running, waits for it, then opens Chrome --app.\n// Also adds the app to the Dock via `defaults write`.\n// ---------------------------------------------------------------------------\n/**\n * Install Jivam as a genuine Safari web app — a real, separate .app bundle\n * under ~/Applications/Safari Apps/ with its own bundle identifier\n * (com.apple.Safari.WebApp.<uuid>). This gives native macOS Dock semantics\n * for free: a distinct Dock icon and click-to-focus on the existing window\n * instead of spawning duplicates, which `chrome --app=` can never provide\n * (it shares Chrome's bundle ID).\n *\n * Safari's \"Add to Dock\" (macOS Sonoma+) has no CLI or URL-scheme trigger,\n * so this drives the File > Add to Dock menu item via System Events UI\n * scripting. This requires the user to grant Accessibility permission\n * (System Settings → Privacy & Security → Accessibility) to the calling\n * process (e.g. Terminal) the first time — if that's denied, or the OS is\n * pre-Sonoma, or anything else about this fails, it returns null and the\n * caller falls back to `chrome/edge/brave --app=` or plain Safari.\n */\nfunction findSafariWebAppBundle(sinceMs: number): string | null {\n // Safari writes the bundle either into ~/Applications/Safari Apps/ or\n // directly into ~/Applications/, depending on macOS version — and when a\n // same-named bundle already exists there (e.g. our own fallback wrapper,\n // or a previous install), it overwrites it IN PLACE rather than picking a\n // new name. So identify by Info.plist content (not \"is this a new\n // directory entry\") and only accept it if its Info.plist was written\n // after `sinceMs`, so we don't false-positive on an unrelated older bundle.\n const searchDirs = [\n path.join(os.homedir(), 'Applications', 'Safari Apps'),\n path.join(os.homedir(), 'Applications'),\n ]\n for (const dir of searchDirs) {\n if (!fs.existsSync(dir)) continue\n const entries = fs.readdirSync(dir).filter(f => f.endsWith('.app'))\n for (const entry of entries) {\n const plistPath = path.join(dir, entry, 'Contents', 'Info.plist')\n if (!fs.existsSync(plistPath)) continue\n try {\n const stat = fs.statSync(plistPath)\n if (stat.mtimeMs < sinceMs) continue\n const plistContent = fs.readFileSync(plistPath, 'utf-8')\n if (plistContent.includes('com.apple.Safari.WebApp') && plistContent.includes('<string>Jivam</string>')) {\n return path.join(dir, entry)\n }\n } catch {}\n }\n }\n return null\n}\n\n/**\n * Install Jivam as a genuine Safari web app — a real, separate .app bundle\n * with its own bundle identifier (com.apple.Safari.WebApp.<uuid>). This\n * gives native macOS Dock semantics for free: a distinct Dock icon and\n * click-to-focus on the existing window instead of spawning duplicates,\n * which `chrome --app=` can never provide (it shares Chrome's bundle ID).\n *\n * Assumes `url` is already reachable — the caller is responsible for\n * ensuring the server is running before calling this.\n *\n * Safari's \"Add to Dock\" (macOS Sonoma+) has no CLI or URL-scheme trigger,\n * so this drives the File > Add to Dock… menu item via System Events UI\n * scripting. This requires the user to grant Accessibility permission\n * (System Settings → Privacy & Security → Accessibility) to the calling\n * process (e.g. Terminal) the first time — if that's denied, or the OS is\n * pre-Sonoma, or anything else about this fails, it returns null and the\n * caller falls back to a plain `--app=` wrapper.\n */\nasync function installSafariAddToDock(url: string): Promise<string | null> {\n const { exec } = await import('child_process')\n const { promisify } = await import('util')\n const execAsync = promisify(exec)\n\n try {\n // Add to Dock requires macOS Sonoma (14) or later\n const { stdout: versionOut } = await execAsync('sw_vers -productVersion')\n const majorVersion = parseInt(versionOut.trim().split('.')[0] ?? '0', 10)\n if (majorVersion < 14) {\n console.warn('Safari Add to Dock requires macOS Sonoma (14) or later — skipping.')\n return null\n }\n\n const automationStartMs = Date.now()\n\n const scriptPath = path.join(os.tmpdir(), 'jivam-add-to-dock.applescript')\n // Note: the real menu item name has a trailing ellipsis (\"Add to Dock…\").\n // It's also disabled unless Safari's process is explicitly frontmost via\n // System Events (not just `activate`), hence the extra frontmost dance.\n const script = `\non run\n tell application \"Safari\"\n activate\n if (count of windows) = 0 then\n make new document\n end if\n set URL of front document to \"${url}\"\n end tell\n delay 2\n tell application \"Safari\" to activate\n delay 1\n tell application \"System Events\" to tell process \"Safari\" to set frontmost to true\n delay 1\n tell application \"System Events\"\n tell process \"Safari\"\n click menu item \"Add to Dock…\" of menu \"File\" of menu bar 1\n end tell\n end tell\n delay 2\nend run\n`\n fs.writeFileSync(scriptPath, script)\n try {\n await execAsync(`osascript \"${scriptPath}\"`, { timeout: 20000 })\n } finally {\n fs.rmSync(scriptPath, { force: true })\n }\n\n // Safari's confirmation panel is deliberately excluded from the\n // Accessibility API (same category as Touch ID/Apple Pay prompts) —\n // installing an app is a security-sensitive action Apple requires a\n // genuine human click for, and that can't (and shouldn't) be scripted\n // around. Prompt the user, then poll for the resulting bundle.\n console.log('\\nA \"Add to Dock\" confirmation opened in Safari — click Add to finish setting up Jivam as an app.')\n console.log('Waiting up to 60s for you to click it...')\n for (let i = 0; i < 60; i++) {\n await new Promise(resolve => setTimeout(resolve, 1000))\n const found = findSafariWebAppBundle(automationStartMs)\n if (found) return found\n }\n\n console.warn('No click detected within 60s — falling back to --app mode. Run `jivam --install` again anytime to retry.')\n return null\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n if (message.includes('assistive access') || message.includes('-1719')) {\n console.warn(\n '\\nSafari Add to Dock needs Accessibility permission (one-time setup) to control Safari\\'s menus.\\n' +\n 'Opening System Settings — enable access for Terminal (or whichever app you ran this from),\\n' +\n 'then re-run: jivam --install\\n' +\n 'Falling back to --app mode for now — Jivam will still work, just without the native single-window Dock experience.',\n )\n try {\n await execAsync('open \"x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility\"')\n } catch {}\n } else {\n console.warn('Safari Add to Dock automation failed, falling back to --app mode:', err)\n }\n return null\n }\n}\n\n// ---------------------------------------------------------------------------\n// Background service management (macOS: launchd, Windows: Task Scheduler)\n//\n// The Jivam server now runs persistently in the background — started at\n// login and kept alive by the OS — instead of being launched on-demand by\n// whatever opens the Dock/Desktop icon. This removes the \"click icon before\n// server is up\" race entirely: by the time any icon is clicked, the server\n// has (almost certainly) already been running for a while.\n// ---------------------------------------------------------------------------\n\nconst JIVAM_LABEL = 'ai.karmaloop.jivam'\nconst WIN_TASK_NAME = 'JivamServer'\n\nfunction macPlistPath(): string {\n return path.join(os.homedir(), 'Library', 'LaunchAgents', `${JIVAM_LABEL}.plist`)\n}\n\nasync function macFindJivamBin(): Promise<string> {\n const { exec } = await import('child_process')\n const { promisify } = await import('util')\n const execAsync = promisify(exec)\n\n try {\n const { stdout } = await execAsync('which jivam')\n if (stdout.trim()) return stdout.trim()\n } catch {}\n\n const candidates = [\n '/usr/local/bin/jivam',\n path.join(os.homedir(), '.npm-global', 'bin', 'jivam'),\n '/opt/homebrew/bin/jivam',\n '/usr/bin/jivam',\n ]\n for (const c of candidates) {\n if (fs.existsSync(c)) return c\n }\n const nvmDir = path.join(os.homedir(), '.nvm', 'versions', 'node')\n if (fs.existsSync(nvmDir)) {\n try {\n const versions = fs.readdirSync(nvmDir).sort().reverse()\n for (const v of versions) {\n const p = path.join(nvmDir, v, 'bin', 'jivam')\n if (fs.existsSync(p)) return p\n }\n } catch {}\n }\n return `\"${process.execPath}\" \"${process.argv[1]}\"`\n}\n\nasync function macWriteLaunchAgent(jivamBinPath: string): Promise<string> {\n const extraPaths = [\n '/usr/local/bin',\n '/opt/homebrew/bin',\n '/opt/homebrew/sbin',\n path.join(os.homedir(), '.npm-global', 'bin'),\n path.join(os.homedir(), '.nvm', 'versions', 'node'),\n '/usr/bin',\n '/bin',\n ].join(':')\n\n const jivamHome = path.join(os.homedir(), '.jivam')\n fs.mkdirSync(jivamHome, { recursive: true })\n const logPath = path.join(jivamHome, 'jivam.log')\n\n const isQuotedCmd = jivamBinPath.startsWith('\"')\n const programArgs = isQuotedCmd\n // \"node\" \"script\" form — split back into two <string> entries\n ? jivamBinPath.split('\" \"').map(s => s.replace(/^\"|\"$/g, ''))\n : [jivamBinPath]\n\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${JIVAM_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n ${programArgs.map(a => `<string>${a}</string>`).join('\\n ')}\n <string>--server-only</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <true/>\n <key>ThrottleInterval</key>\n <integer>5</integer>\n <key>StandardOutPath</key>\n <string>${logPath}</string>\n <key>StandardErrorPath</key>\n <string>${logPath}</string>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PATH</key>\n <string>${extraPaths}:/usr/bin:/bin</string>\n </dict>\n</dict>\n</plist>\n`\n const plistPath = macPlistPath()\n fs.mkdirSync(path.dirname(plistPath), { recursive: true })\n fs.writeFileSync(plistPath, plist)\n return plistPath\n}\n\nasync function macServiceControl(action: 'start' | 'stop' | 'restart' | 'status'): Promise<void> {\n const { exec } = await import('child_process')\n const { promisify } = await import('util')\n const execAsync = promisify(exec)\n\n const plistPath = macPlistPath()\n const uid = process.getuid?.() ?? 0\n const domainTarget = `gui/${uid}`\n const serviceTarget = `${domainTarget}/${JIVAM_LABEL}`\n\n if (!fs.existsSync(plistPath)) {\n console.log('Jivam background service is not installed. Run: jivam --install')\n return\n }\n\n if (action === 'start') {\n try {\n await execAsync(`launchctl bootstrap ${domainTarget} \"${plistPath}\"`)\n console.log('Jivam background service started.')\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n if (message.includes('already bootstrapped') || message.includes('Service already loaded')) {\n console.log('Jivam background service is already running.')\n } else {\n console.error('Failed to start service:', err)\n }\n }\n } else if (action === 'stop') {\n try {\n await execAsync(`launchctl bootout ${serviceTarget}`)\n console.log('Jivam background service stopped.')\n } catch (err) {\n console.warn('Service was not running (or already stopped).')\n }\n } else if (action === 'restart') {\n try {\n await execAsync(`launchctl kickstart -k ${serviceTarget}`)\n console.log('Jivam background service restarted.')\n } catch (err) {\n // Not loaded yet — just start it fresh\n try {\n await execAsync(`launchctl bootstrap ${domainTarget} \"${plistPath}\"`)\n console.log('Jivam background service started.')\n } catch (startErr) {\n console.error('Failed to restart service:', startErr)\n }\n }\n } else if (action === 'status') {\n try {\n const { stdout } = await execAsync(`launchctl print ${serviceTarget}`)\n const isRunning = /state = running/.test(stdout)\n console.log(isRunning ? 'Jivam background service is running.' : 'Jivam background service is loaded but not running.')\n const pidMatch = stdout.match(/pid = (\\d+)/)\n if (pidMatch) console.log(` PID: ${pidMatch[1]}`)\n } catch {\n console.log('Jivam background service is not running.')\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// jivam --install (macOS)\n// Sets up a launchd LaunchAgent so the server runs persistently in the\n// background (started at login, restarted automatically if it crashes),\n// then installs Jivam as a genuine Safari web app for a native Dock icon.\n// ---------------------------------------------------------------------------\n/**\n * Creates a minimal fallback .app wrapper that just opens Chrome/Edge/Brave\n * in --app= mode (or Safari as a last resort). No server-start logic is\n * needed here anymore — the LaunchAgent guarantees the server is already\n * running — so this is much simpler than the old wrapper.\n */\nasync function macCreateFallbackWrapper(): Promise<string> {\n const { exec } = await import('child_process')\n const { promisify } = await import('util')\n const execAsync = promisify(exec)\n\n const appPath = path.join(os.homedir(), 'Applications', 'Jivam.app')\n const macOSDir = path.join(appPath, 'Contents', 'MacOS')\n const resourcesDir = path.join(appPath, 'Contents', 'Resources')\n fs.mkdirSync(macOSDir, { recursive: true })\n fs.mkdirSync(resourcesDir, { recursive: true })\n\n const url = `http://localhost:${PORT}`\n const launcherScript = `#!/bin/bash\nURL=\"${url}\"\nCHROME=\"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\"\nEDGE=\"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge\"\nBRAVE=\"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser\"\n\nif [ -f \"$CHROME\" ]; then\n \"$CHROME\" --app=\"$URL\" --disable-extensions &\nelif [ -f \"$EDGE\" ]; then\n \"$EDGE\" --app=\"$URL\" --disable-extensions &\nelif [ -f \"$BRAVE\" ]; then\n \"$BRAVE\" --app=\"$URL\" --disable-extensions &\nelse\n osascript -e \"tell application \\\\\"Safari\\\\\" to open location \\\\\"$URL\\\\\"\" \\\\\n -e \"tell application \\\\\"Safari\\\\\" to activate\"\nfi\n`\n fs.writeFileSync(path.join(macOSDir, 'jivam-launcher'), launcherScript, { mode: 0o755 })\n\n const infoPlist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>CFBundleExecutable</key>\n <string>jivam-launcher</string>\n <key>CFBundleIdentifier</key>\n <string>ai.karmaloop.jivam</string>\n <key>CFBundleName</key>\n <string>Jivam</string>\n <key>CFBundleDisplayName</key>\n <string>Jivam</string>\n <key>CFBundleIconFile</key>\n <string>Jivam</string>\n <key>CFBundleVersion</key>\n <string>1</string>\n <key>CFBundlePackageType</key>\n <string>APPL</string>\n <key>LSUIElement</key>\n <false/>\n</dict>\n</plist>\n`\n fs.writeFileSync(path.join(appPath, 'Contents', 'Info.plist'), infoPlist)\n\n // Convert PNG → .icns via sips + iconutil\n const iconSrcCandidates = [\n path.join(__dirname, '..', 'dist', 'icon-512.png'),\n path.join(__dirname, '..', 'public', 'icon-512.png'),\n ]\n const iconSrc = iconSrcCandidates.find(p => fs.existsSync(p))\n if (iconSrc) {\n try {\n const iconsetDir = path.join(os.tmpdir(), 'Jivam.iconset')\n fs.mkdirSync(iconsetDir, { recursive: true })\n const sizes: Array<[number, string]> = [\n [16, 'icon_16x16.png'], [32, 'icon_16x16@2x.png'], [32, 'icon_32x32.png'],\n [64, 'icon_32x32@2x.png'], [128, 'icon_128x128.png'], [256, 'icon_128x128@2x.png'],\n [256, 'icon_256x256.png'], [512, 'icon_256x256@2x.png'], [512, 'icon_512x512.png'],\n ]\n for (const [size, name] of sizes) {\n await execAsync(`sips -z ${size} ${size} \"${iconSrc}\" --out \"${path.join(iconsetDir, name)}\"`)\n }\n await execAsync(`iconutil -c icns \"${iconsetDir}\" --output \"${path.join(resourcesDir, 'Jivam.icns')}\"`)\n fs.rmSync(iconsetDir, { recursive: true, force: true })\n } catch (err) {\n console.warn('Could not convert icon (sips/iconutil failed):', err)\n }\n }\n\n return appPath\n}\n\nasync function macAddToDock(appPath: string): Promise<void> {\n const { exec } = await import('child_process')\n const { promisify } = await import('util')\n const execAsync = promisify(exec)\n\n // Bust the Dock's icon cache and force LaunchServices to re-read the bundle\n const lsregister = '/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister'\n try {\n await execAsync(`touch \"${appPath}\"`)\n await execAsync(`\"${lsregister}\" -f \"${appPath}\"`)\n } catch {}\n\n const dockEntry = `<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>${appPath}</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>`\n try {\n await execAsync(`defaults write com.apple.dock persistent-apps -array-add '${dockEntry}' && killall Dock`)\n console.log(`Added to Dock: ${appPath}`)\n } catch (err) {\n console.warn('Could not add to Dock automatically — drag the app to your Dock manually.')\n console.warn(err)\n }\n}\n\n// ---------------------------------------------------------------------------\n// jivam --install (macOS)\n// Sets up a launchd LaunchAgent so the server runs persistently in the\n// background (started at login, restarted automatically if it crashes),\n// then installs Jivam as a genuine Safari web app for a native Dock icon.\n// ---------------------------------------------------------------------------\nasync function runInstall(): Promise<void> {\n if (process.platform !== 'darwin') {\n console.error('--install is currently only supported on macOS.')\n process.exit(1)\n }\n\n const url = `http://localhost:${PORT}`\n\n // ── 1. Resolve the jivam binary and set up the LaunchAgent ────────────────\n console.log('Setting up the Jivam background service...')\n const jivamBinPath = await macFindJivamBin()\n await macWriteLaunchAgent(jivamBinPath)\n await macServiceControl('restart') // bootstraps if not loaded, kickstarts if it is\n\n // ── 2. Wait for the server to come up ──────────────────────────────────────\n let serverReady = false\n for (let i = 0; i < 30; i++) {\n try {\n const res = await fetch(`${url}/api/version`)\n if (res.ok) { serverReady = true; break }\n } catch {}\n await new Promise(resolve => setTimeout(resolve, 500))\n }\n if (!serverReady) {\n console.warn('Server did not come up within 15s — continuing anyway (check ~/.jivam/jivam.log).')\n } else {\n console.log('Jivam server is running.')\n }\n\n // ── 3. Install as a genuine Safari web app (best experience) ──────────────\n console.log('Installing Jivam as a Safari web app (this may take a few seconds)...')\n const pwaAppPath = await installSafariAddToDock(url)\n\n // ── 4. Add the resulting app to the Dock, falling back to a plain wrapper ──\n const appToAdd = pwaAppPath ?? await macCreateFallbackWrapper()\n await macAddToDock(appToAdd)\n\n console.log('\\nDone! Click the Jivam icon in your Dock to launch.')\n console.log('The server runs continuously in the background — manage it with:')\n console.log(' jivam stop jivam start jivam restart jivam status')\n process.exit(0)\n}\n\n// ---------------------------------------------------------------------------\n// jivam --install (Windows)\n// Creates %LOCALAPPDATA%\\Jivam\\jivam-launcher.bat (hidden via a VBScript\n// wrapper so no terminal flickers), a .ico icon, and Desktop + Start-Menu\n// shortcuts with the icon baked in.\n// ---------------------------------------------------------------------------\nasync function winFindJivamBin(): Promise<string> {\n const { exec } = await import('child_process')\n const { promisify } = await import('util')\n const execAsync = promisify(exec)\n\n try {\n const { stdout } = await execAsync('where jivam')\n const first = stdout.split('\\n')[0].trim()\n if (first) return first\n } catch {}\n\n const localAppData = process.env.LOCALAPPDATA ?? path.join(os.homedir(), 'AppData', 'Local')\n const candidates = [\n path.join(localAppData, 'npm', 'jivam.cmd'),\n path.join(process.env.APPDATA ?? '', 'npm', 'jivam.cmd'),\n 'C:\\\\Program Files\\\\nodejs\\\\jivam.cmd',\n ]\n for (const c of candidates) {\n if (fs.existsSync(c)) return c\n }\n return `\"${process.execPath}\" \"${process.argv[1]}\"`\n}\n\n/**\n * Registers \"JivamServer\" as a Windows Scheduled Task: starts at logon,\n * restarts automatically on failure, runs hidden (no console window). This\n * is the Windows equivalent of the macOS LaunchAgent — the server runs\n * persistently in the background instead of being started on-demand by\n * whatever opens the Desktop/Start Menu shortcut.\n */\nasync function winRegisterTask(jivamBinPath: string): Promise<void> {\n const { exec } = await import('child_process')\n const { promisify } = await import('util')\n const execAsync = promisify(exec)\n\n const isQuotedCmd = jivamBinPath.startsWith('\"')\n const [command, ...restArgs] = isQuotedCmd\n ? jivamBinPath.split('\" \"').map(s => s.replace(/^\"|\"$/g, ''))\n : [jivamBinPath]\n const args = [...restArgs, '--server-only'].join(' ')\n\n const taskXml = `<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n<Task version=\"1.2\" xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\">\n <Triggers>\n <LogonTrigger>\n <Enabled>true</Enabled>\n </LogonTrigger>\n </Triggers>\n <Principals>\n <Principal id=\"Author\">\n <LogonType>InteractiveToken</LogonType>\n <RunLevel>LeastPrivilege</RunLevel>\n </Principal>\n </Principals>\n <Settings>\n <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>\n <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>\n <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>\n <StartWhenAvailable>true</StartWhenAvailable>\n <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>\n <Hidden>true</Hidden>\n <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>\n <RestartOnFailure>\n <Interval>PT1M</Interval>\n <Count>999</Count>\n </RestartOnFailure>\n </Settings>\n <Actions Context=\"Author\">\n <Exec>\n <Command>${command}</Command>\n <Arguments>${args}</Arguments>\n </Exec>\n </Actions>\n</Task>\n`\n const xmlPath = path.join(os.tmpdir(), 'jivam-task.xml')\n // Task Scheduler XML must be UTF-16LE with BOM\n fs.writeFileSync(xmlPath, Buffer.concat([Buffer.from([0xFF, 0xFE]), Buffer.from(taskXml, 'utf16le')]))\n try {\n await execAsync(`schtasks /Create /TN \"${WIN_TASK_NAME}\" /XML \"${xmlPath}\" /F`)\n } finally {\n fs.rmSync(xmlPath, { force: true })\n }\n}\n\nasync function winServiceControl(action: 'start' | 'stop' | 'restart' | 'status'): Promise<void> {\n const { exec } = await import('child_process')\n const { promisify } = await import('util')\n const execAsync = promisify(exec)\n\n try {\n await execAsync(`schtasks /Query /TN \"${WIN_TASK_NAME}\"`)\n } catch {\n console.log('Jivam background service is not installed. Run: jivam --install')\n return\n }\n\n if (action === 'start' || action === 'restart') {\n if (action === 'restart') {\n try { await execAsync(`schtasks /End /TN \"${WIN_TASK_NAME}\"`) } catch {}\n await new Promise(resolve => setTimeout(resolve, 1000))\n }\n try {\n await execAsync(`schtasks /Run /TN \"${WIN_TASK_NAME}\"`)\n console.log(`Jivam background service ${action === 'restart' ? 'restarted' : 'started'}.`)\n } catch (err) {\n console.error(`Failed to ${action} service:`, err)\n }\n } else if (action === 'stop') {\n try {\n await execAsync(`schtasks /End /TN \"${WIN_TASK_NAME}\"`)\n console.log('Jivam background service stopped.')\n } catch {\n console.warn('Service was not running (or already stopped).')\n }\n } else if (action === 'status') {\n try {\n const { stdout } = await execAsync(`schtasks /Query /TN \"${WIN_TASK_NAME}\" /FO LIST /V`)\n const statusMatch = stdout.match(/Status:\\s*(.+)/)\n console.log(statusMatch ? `Jivam background service status: ${statusMatch[1].trim()}` : 'Jivam background service is registered.')\n } catch {\n console.log('Jivam background service is not running.')\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// jivam --install (Windows)\n// Registers a Scheduled Task so the server runs persistently in the\n// background (started at logon, restarted automatically on failure), then\n// creates Desktop + Start Menu shortcuts that just open the browser — no\n// server-start logic needed there anymore since the task keeps it alive.\n// ---------------------------------------------------------------------------\nasync function runInstallWindows(): Promise<void> {\n const { exec } = await import('child_process')\n const { promisify } = await import('util')\n const execAsync = promisify(exec)\n\n const localAppData = process.env.LOCALAPPDATA ?? path.join(os.homedir(), 'AppData', 'Local')\n const installDir = path.join(localAppData, 'Jivam')\n const batPath = path.join(installDir, 'jivam-launcher.bat')\n const vbsPath = path.join(installDir, 'jivam-launcher.vbs')\n const icoPath = path.join(installDir, 'Jivam.ico')\n const desktopPath = path.join(os.homedir(), 'Desktop', 'Jivam.lnk')\n const startMenuDir = path.join(localAppData, 'Microsoft', 'Windows', 'Start Menu', 'Programs')\n const startMenuPath = path.join(startMenuDir, 'Jivam.lnk')\n\n fs.mkdirSync(installDir, { recursive: true })\n\n const url = `http://localhost:${PORT}`\n\n // ── 1. Resolve the jivam binary and register the background task ─────────\n console.log('Setting up the Jivam background service...')\n const jivamBinPath = await winFindJivamBin()\n await winRegisterTask(jivamBinPath)\n await winServiceControl('restart')\n\n // ── 2. Wait for the server to come up ──────────────────────────────────────\n let serverReady = false\n for (let i = 0; i < 30; i++) {\n try {\n const res = await fetch(`${url}/api/version`)\n if (res.ok) { serverReady = true; break }\n } catch {}\n await new Promise(resolve => setTimeout(resolve, 500))\n }\n if (!serverReady) {\n console.warn('Server did not come up within 15s — continuing anyway (check %LOCALAPPDATA%\\\\Jivam\\\\jivam.log).')\n } else {\n console.log('Jivam server is running.')\n }\n\n // ── 3. Shortcut launcher — just opens the browser (server is already up) ──\n const batScript = `@echo off\nset URL=${url}\nset CHROME=%ProgramFiles%\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\nset EDGE=%ProgramFiles(x86)%\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe\n\nif exist \"%CHROME%\" (\n start \"\" \"%CHROME%\" --app=%URL% --disable-extensions\n) else if exist \"%EDGE%\" (\n start \"\" \"%EDGE%\" --app=%URL% --disable-extensions\n) else (\n start \"\" %URL%\n)\n`\n\n // ── VBScript wrapper — runs the .bat silently (no terminal window) ─────────\n const vbsScript = `Set oShell = CreateObject(\"WScript.Shell\")\noShell.Run Chr(34) & \"${batPath.replace(/\\\\/g, '\\\\\\\\')}\" & Chr(34), 0, False\n`\n\n fs.writeFileSync(batPath, batScript)\n fs.writeFileSync(vbsPath, vbsScript)\n console.log(`Created launcher at ${installDir}`)\n\n // ── Convert PNG → .ico via PowerShell + System.Drawing ───────────────────\n const iconSrcCandidates = [\n path.join(__dirname_cjs, '..', 'dist', 'icon-512.png'),\n path.join(__dirname_cjs, '..', 'public', 'icon-512.png'),\n ]\n const iconSrc = iconSrcCandidates.find(p => fs.existsSync(p))\n\n if (iconSrc) {\n // PowerShell script: resize to 256×256 and save as .ico\n const ps1 = `\nAdd-Type -AssemblyName System.Drawing\n$src = [System.Drawing.Image]::FromFile('${iconSrc.replace(/\\\\/g, '\\\\\\\\')}')\n$bmp = New-Object System.Drawing.Bitmap($src, 256, 256)\n$ico = [System.Drawing.Icon]::FromHandle($bmp.GetHicon())\n$fs = [System.IO.File]::Create('${icoPath.replace(/\\\\/g, '\\\\\\\\')}')\n$ico.Save($fs)\n$fs.Close()\n$ico.Dispose()\n$bmp.Dispose()\n$src.Dispose()\nWrite-Host \"Icon written\"\n`.trim()\n try {\n await execAsync(`powershell -NoProfile -NonInteractive -Command \"${ps1.replace(/\"/g, '\\\\\"').replace(/\\n/g, '; ')}\"`)\n console.log('Icon created.')\n } catch (err) {\n console.warn('Could not create icon (PowerShell/System.Drawing failed):', err)\n }\n }\n\n // ── Create .lnk shortcuts via PowerShell ─────────────────────────────────\n const iconArg = fs.existsSync(icoPath) ? `$s.IconLocation = '${icoPath.replace(/\\\\/g, '\\\\\\\\')}'` : ''\n\n const mkShortcut = (lnkPath: string) => `\n$ws = New-Object -ComObject WScript.Shell\n$s = $ws.CreateShortcut('${lnkPath.replace(/\\\\/g, '\\\\\\\\')}')\n$s.TargetPath = 'wscript.exe'\n$s.Arguments = '//B \"${vbsPath.replace(/\\\\/g, '\\\\\\\\')}\"'\n$s.WorkingDirectory = '${installDir.replace(/\\\\/g, '\\\\\\\\')}'\n$s.Description = 'Jivam - AI Agent UI'\n${iconArg}\n$s.Save()\n`.trim()\n\n try {\n fs.mkdirSync(startMenuDir, { recursive: true })\n for (const lnkPath of [desktopPath, startMenuPath]) {\n const ps = mkShortcut(lnkPath)\n await execAsync(`powershell -NoProfile -NonInteractive -Command \"${ps.replace(/\"/g, '\\\\\"').replace(/\\n/g, '; ')}\"`)\n }\n console.log(`Created Desktop shortcut: ${desktopPath}`)\n console.log(`Created Start Menu entry: ${startMenuPath}`)\n } catch (err) {\n console.warn('Could not create shortcuts:', err)\n }\n\n console.log('\\nDone! Double-click the Jivam icon on your Desktop to launch.')\n console.log('The server runs continuously in the background — manage it with:')\n console.log(' jivam stop jivam start jivam restart jivam status')\n process.exit(0)\n}\n\nconst __dirname_cjs = __dirname\n\nconst app = express()\napp.use(express.json({ limit: '50mb' }))\n\n// Initialise runners\nconst jivaRunner = new JivaRunner()\nconst codeRunner = new CodeRunner()\nconst cloudRunner = new CloudRunner()\n\n// API routes\napp.use('/api/setup', setupRouter)\napp.use('/api/config', configRouter)\napp.use('/api/conversations', conversationsRouter)\napp.use('/api/git', gitRouter)\napp.use('/api/directive', directiveRouter)\napp.use('/api/workspace', workspaceRouter)\napp.use('/api/jiva', createJivaRouter(jivaRunner, cloudRunner))\napp.use('/api/personas', createPersonasRouter(jivaRunner))\napp.use('/api/mcp', createMcpRouter(jivaRunner))\napp.use('/api/code', createCodeRouter(codeRunner))\napp.use('/api/files', createFilesRouter(jivaRunner))\napp.use('/api/cloud', createCloudRouter(cloudRunner))\n\n// Platform + version endpoints for the frontend shim\napp.get('/api/platform', (_req, res) => res.json(process.platform))\napp.get('/api/version', (_req, res) => {\n try {\n const pkg = JSON.parse(fs.readFileSync(path.join(__dirname_cjs, '..', 'package.json'), 'utf-8')) as { version: string }\n res.json(pkg.version)\n } catch { res.json('0.0.0') }\n})\n\n// Serve built frontend in production\nif (!IS_DEV) {\n const distDir = path.join(__dirname_cjs, '..', 'dist')\n if (fs.existsSync(distDir)) {\n app.use(express.static(distDir))\n app.get(/(.*)/, (_req, res) => {\n res.sendFile(path.join(distDir, 'index.html'))\n })\n }\n}\n\n/**\n * Open Jivam in a clean app-mode window (no address bar, no tabs).\n * Tries Chrome/Edge/Brave --app flag first (best experience), then Safari\n * app mode on macOS, then falls back to the default browser.\n */\nasync function openAppWindow(url: string): Promise<void> {\n const { execFile, exec } = await import('child_process')\n const { promisify } = await import('util')\n const execAsync = promisify(exec)\n\n // JIVAM_BROWSER=safari|chrome|edge|brave overrides auto-detection\n const browserOverride = (process.env.JIVAM_BROWSER ?? '').toLowerCase()\n\n if (process.platform === 'darwin') {\n // If the PWA was previously installed via Safari \"Add to Dock\",\n // it lives in ~/Applications/Safari Apps/Jivam.app — launch it directly.\n if (browserOverride !== 'chrome' && browserOverride !== 'edge' && browserOverride !== 'brave') {\n const safariAppPaths = [\n path.join(os.homedir(), 'Applications', 'Safari Apps', 'Jivam.app'),\n path.join(os.homedir(), 'Applications', 'Jivam.app'),\n '/Applications/Jivam.app',\n ]\n for (const appPath of safariAppPaths) {\n if (fs.existsSync(appPath)) {\n try {\n await execAsync(`open \"${appPath}\"`)\n console.log(`Launched Safari PWA: ${appPath}`)\n return\n } catch {}\n }\n }\n }\n\n if (browserOverride === 'safari') {\n // Safari regular window — user hasn't installed PWA yet\n try {\n await execAsync(\n `osascript -e 'tell application \"Safari\" to open location \"${url}\"' -e 'tell application \"Safari\" to activate'`\n )\n console.log('Opened in Safari (tip: File → Add to Dock for app experience)')\n return\n } catch (err) {\n console.error('Failed to open Safari:', err)\n }\n }\n\n if (browserOverride !== 'safari') {\n // Try Chrome, Edge, Brave — all support --app flag\n const macBrowsers: Array<[string, string]> = [\n ['chrome', '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'],\n ['edge', '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'],\n ['brave', '/Applications/Brave Browser.app/Contents/MacOS/Brave Browser'],\n ]\n for (const [key, browserPath] of macBrowsers) {\n if (browserOverride && browserOverride !== key) continue\n try {\n execFile(browserPath, [`--app=${url}`, '--disable-extensions'])\n console.log(`Opened in app-mode window: ${browserPath}`)\n return\n } catch {}\n }\n }\n\n // Safari fallback when no Chromium found and no override\n if (!browserOverride) {\n try {\n await execAsync(\n `osascript -e 'tell application \"Safari\" to open location \"${url}\"' -e 'tell application \"Safari\" to activate'`\n )\n console.log('Opened in Safari (tip: File → Add to Dock for app experience)')\n return\n } catch {}\n }\n } else if (process.platform === 'win32') {\n const winBrowsers = [\n ['msedge', [`--app=${url}`]],\n ['chrome', [`--app=${url}`]],\n ['brave', [`--app=${url}`]],\n ] as Array<[string, string[]]>\n for (const [browser, args] of winBrowsers) {\n try {\n execFile(`start ${browser}`, args, { shell: true })\n return\n } catch {}\n }\n // PowerShell fallback\n try {\n await execAsync(`start \"\" \"${url}\"`)\n return\n } catch {}\n } else {\n // Linux\n const linuxBrowsers = [\n ['google-chrome', [`--app=${url}`]],\n ['google-chrome-stable', [`--app=${url}`]],\n ['chromium-browser', [`--app=${url}`]],\n ['chromium', [`--app=${url}`]],\n ['brave-browser', [`--app=${url}`]],\n ['microsoft-edge', [`--app=${url}`]],\n ] as Array<[string, string[]]>\n for (const [browser, args] of linuxBrowsers) {\n try {\n execFile(browser, args)\n return\n } catch {}\n }\n }\n\n // Universal fallback — open in default browser (will have address bar)\n try {\n const { default: open } = await import('open')\n await open(url)\n console.log(`Opened in default browser: ${url}`)\n } catch (err) {\n console.error('Could not open browser automatically:', err)\n console.log(`Open manually: ${url}`)\n }\n}\n\n/**\n * Checks once a day whether newer jivamai/jiva-core versions are published.\n * If so, runs the update then exits — the OS-level service manager\n * (launchd KeepAlive on macOS, Scheduled Task RestartOnFailure on Windows)\n * brings the process back up running the new code. Only active in\n * --server-only mode (the persistent background instance).\n */\nfunction scheduleUpdateCheck(): void {\n const DAY_MS = 24 * 60 * 60 * 1000\n\n const check = async () => {\n try {\n const { exec } = await import('child_process')\n const { promisify } = await import('util')\n const execAsync = promisify(exec)\n\n const currentPkg = JSON.parse(\n fs.readFileSync(path.join(__dirname_cjs, '..', 'package.json'), 'utf-8'),\n ) as { version: string }\n const { stdout } = await execAsync('npm view jivamai version')\n const latest = stdout.trim()\n\n if (latest && latest !== currentPkg.version) {\n console.log(`Update available: jivamai ${currentPkg.version} → ${latest}. Updating...`)\n await execAsync('npm install -g jivamai jiva-core')\n console.log('Update installed — restarting to pick it up.')\n process.exit(1) // non-zero so Windows RestartOnFailure also triggers; macOS KeepAlive restarts regardless\n return\n }\n } catch (err) {\n console.warn('Update check failed (probably offline):', err)\n }\n setTimeout(check, DAY_MS)\n }\n\n // First check after 24h — the install script already updates at install time\n setTimeout(check, DAY_MS)\n}\n\n// ---------------------------------------------------------------------------\n// CLI dispatch\n// ---------------------------------------------------------------------------\nconst cliSubcommand = process.argv[2]\nconst isServiceAction = cliSubcommand === 'start' || cliSubcommand === 'stop'\n || cliSubcommand === 'restart' || cliSubcommand === 'status'\n\nif (process.argv.includes('--install')) {\n const installFn = process.platform === 'win32' ? runInstallWindows : runInstall\n installFn().catch(err => { console.error(err); process.exit(1) })\n} else if (isServiceAction) {\n const controlFn = process.platform === 'win32' ? winServiceControl : macServiceControl\n controlFn(cliSubcommand as 'start' | 'stop' | 'restart' | 'status')\n .then(() => process.exit(0))\n .catch(err => { console.error(err); process.exit(1) })\n} else {\n\nconst isServerOnly = process.argv.includes('--server-only')\n\nconst server = http.createServer(app)\ninitWebSocketServer(server)\n\nserver.listen(PORT, '127.0.0.1', async () => {\n const url = `http://localhost:${PORT}`\n console.log(`Jivam server running at ${url}`)\n\n if (!IS_DEV && !isServerOnly) {\n await openAppWindow(url)\n }\n if (isServerOnly) {\n scheduleUpdateCheck()\n }\n})\n\n// Graceful shutdown\nasync function shutdown() {\n await jivaRunner.cleanup()\n await codeRunner.cleanup()\n server.close()\n process.exit(0)\n}\n\nprocess.on('SIGINT', shutdown)\nprocess.on('SIGTERM', shutdown)\n\n} // end of non-install/non-service-action block\n"],"names":["augmentPath","shell","shellPath","execSync","home","os","candidates","nvmDir","path","fs","v","current","existing","toAdd","p","wss","clients","initWebSocketServer","server","WebSocketServer","ws","_req","broadcast","type","payload","msg","client","WebSocket","JIVA_DIR","DIRECTIVE_PATH","CONVERSATIONS_DIR","readRecentConversations","limit","f","filePath","stat","raw","messageCount","title","firstUser","m","a","b","d","buildDirectiveContent","userDirective","now","weekdays","months","weekday","month","day","year","hours","minutes","time","timezone","_a","offset","sign","absH","absM","iso","recent","recentActivity","c","dynamicContext","writeDirective","content","err","getJivamConfigPath","getJivaConfigPath","readConfig","configPath","writeConfig","config","dir","skillCache","parseFrontmatter","match","result","line","colon","key","value","discoverSkills","searchDirs","skills","entries","entry","skillDir","skillMdPath","fm","name","description","emitBrain","onBrainLog","CONVO_SAFE_WORDS","looksConversational","prompt","trimmed","words","w","extractSummary","maxLen","lines","planExecution","userPrompt","completer","conversationContext","configuredMcpServers","skillList","s","contextSection","mcpSection","systemPrompt","userMsg","fallback","cleaned","parsed","mode","reasoning","explanation","mcpRecommendations","r","directResponse","subtasks","i","synthesize","results","subtaskBlocks","validate","subtaskMaxIterations","complexity","userMaxIterations","reformulateForRetry","originalPrompt","error","attempt","revised","generateFailureExplanation","subtaskLabel","LEAKED_PROMPT_PATTERNS","looksLikeLeakedPrompt","head","re","MAX_WORKER_RETRIES","run","execute","ctx","plan","rec","N","labels","workerResults","subtask","iterLimit","workerResult","lastError","execStart","heartbeat","secs","summary","finalContent","validation","followUpPrompt","followUpResult","followUpLastError","followUpSummary","allTools","uniqueTools","totalIterations","sum","resolveJivaCoreEntryPath","npmRoot","pkgJson","main","known","LOG_RE","parseLogLine","CodeRunner","EventEmitter","__publicField","workspaceDir","mcpServerNames","opts","jiva","pathToFileURL","configManager","ModelOrchestrator","WorkspaceManager","ConversationManager","CodeAgent","MCPServerManager","createKrutrimModel","createLocalProvider","logger","reasoningConfig","reasoningModel","OrchestratorClass","directivePath","WsClass","storageProvider","ConvManagerClass","activeMcpNames","MgrClass","mgr","allServers","_b","selectedServers","AgentClass","orch","onLog","harness.run","execOpts","brainEvent","maxIterations","log","emit","level","tag","message","lvl","handler","args","e","addMethod","removeMethod","transport","origWrite","data","text","structured","toolMatch","agent","unhook","seen","tool","possiblePaths","JivaRunner","persona","jivaCoreEntry","DualAgent","LogLevel","jivaConfig","multimodalConfig","createModel","resolvedReasoningModel","multimodalModel","resolvedMmModel","mcpServers","allowedPath","McpManagerClass","jivaCoreDir","jivaCoreRoot","personaManagerPath","PersonaManager","personaMCPServers","startTime","response","convId","_c","onPhase","executingTimer","synthesizingTimer","id","grouped","parts","serverName","toolName","manager","fullStatus","enabled","base64DataUri","status","CLOUD_RUN_URL","CloudRunner","resolve","reject","userId","sessionId","timeoutMs","_","_opts","signal","res","reader","decoder","buffer","iterations","toolsUsed","currentEventType","outer","done","evtType","router","Router","nodejsOk","nodejsVersion","jivaCoreOk","jivaCoreVersion","configCandidates","configOk","foundConfigPath","candidate","cfg","jivaVersionMismatch","requiredJivaVersion","appPkgPath","reqMaj","reqMin","instMaj","instMin","PROVIDER_PRESETS","req","ok","provider","apiKey","customEndpoint","customModel","preset","endpoint","defaultModel","convsDir","files","execFileSync","output","file","fullPath","l","diff","branch","ahead","behind","tracking","ab","picked","ps","dirPath","homeDir","resolvedDir","resolvedHome","resolvedFile","cmd","createJivaRouter","jivaRunner","cloudRunner","isCloud","phase","logEvent","PERSONAS_DIR","getPersonaIcon","tags","listPersonas","personas","personaDir","pluginJsonPath","manifest","builtInNames","activatePersona","activeFile","getActivePersona","jivaConfigPath","createPersonasRouter","success","createMcpRouter","runtimeStatus","configServers","statusMap","serverCfg","rt","serverConfig","mcpEntry","MCP_SELECTIONS_PATH","readMcpSelections","createCodeRouter","codeRunner","event","servers","TEXT_EXTENSIONS","IMAGE_EXTENSIONS","LANG_MAP","getFileCategory","ext","lower","convertFile","category","convertTextFile","convertPdf","convertDocx","convertImage","markdown","extractPdfText","compressedStreamRe","buf","decompressed","zlib","extractTextFromStream","btEtRe","stream","block","litRe","clean","hexRe","hex","str","code","xml","extractFromZip","parseDocumentXml","targetPath","compressionMethod","compressedSize","uncompressedSize","filenameLen","extraLen","filename","dataStart","dataEnd","compressed","paragraphs","paraRe","runs","runRe","mimeType","createFilesRouter","uploadsDir","destPath","tmpDir","tmpPath","dataUri","SUPABASE_URL","SUPABASE_ANON_KEY","supabaseFetch","body","cloudSignIn","email","password","cloudSignUp","userObj","initCloudSession","createCloudRouter","user","PORT","IS_DEV","findSafariWebAppBundle","sinceMs","plistPath","plistContent","installSafariAddToDock","url","exec","promisify","execAsync","versionOut","automationStartMs","scriptPath","script","found","JIVAM_LABEL","WIN_TASK_NAME","macPlistPath","macFindJivamBin","stdout","versions","macWriteLaunchAgent","jivamBinPath","extraPaths","jivamHome","logPath","programArgs","plist","macServiceControl","action","domainTarget","serviceTarget","startErr","isRunning","pidMatch","macCreateFallbackWrapper","appPath","macOSDir","resourcesDir","launcherScript","iconSrc","iconsetDir","sizes","size","macAddToDock","lsregister","dockEntry","runInstall","serverReady","appToAdd","winFindJivamBin","first","localAppData","winRegisterTask","isQuotedCmd","command","restArgs","taskXml","xmlPath","winServiceControl","statusMatch","runInstallWindows","installDir","batPath","vbsPath","icoPath","desktopPath","startMenuDir","startMenuPath","batScript","vbsScript","__dirname_cjs","ps1","iconArg","mkShortcut","lnkPath","app","express","setupRouter","configRouter","conversationsRouter","gitRouter","directiveRouter","workspaceRouter","pkg","distDir","openAppWindow","execFile","browserOverride","safariAppPaths","macBrowsers","browserPath","winBrowsers","browser","linuxBrowsers","open","scheduleUpdateCheck","check","currentPkg","latest","cliSubcommand","isServiceAction","isServerOnly","http","shutdown"],"mappings":"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"}
|