jivamai 0.1.4-dev.edce8f4 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,12 @@
1
- "use strict";var He=Object.create;var ie=Object.defineProperty;var Ge=Object.getOwnPropertyDescriptor;var Ve=Object.getOwnPropertyNames;var Ye=Object.getPrototypeOf,Ke=Object.prototype.hasOwnProperty;var Xe=(r,n,e)=>n in r?ie(r,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[n]=e;var Ze=(r,n,e,t)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of Ve(n))!Ke.call(r,s)&&s!==e&&ie(r,s,{get:()=>n[s],enumerable:!(t=Ge(n,s))||t.enumerable});return r};var C=(r,n,e)=>(e=r!=null?He(Ye(r)):{},Ze(n||!r||!r.__esModule?ie(e,"default",{value:r,enumerable:!0}):e,r));var x=(r,n,e)=>Xe(r,typeof n!="symbol"?n+"":n,e);const $=require("child_process"),u=require("fs"),S=require("os"),m=require("path"),E=require("express"),Qe=require("http"),$e=require("ws"),Me=require("events"),me=require("url"),pe=require("zlib");function et(){if(process.platform==="win32")return;try{const o=process.env.SHELL??"/bin/zsh",a=$.execSync(`${o} -l -c 'echo $PATH'`,{timeout:3e3}).toString().trim();if(a){process.env.PATH=a;return}}catch{}const r=S.homedir(),n=["/usr/local/bin","/opt/homebrew/bin","/opt/local/bin",`${r}/.npm-global/bin`,"/usr/local/opt/node/bin"];try{const o=m.join(r,".nvm","versions","node");if(u.existsSync(o)){const a=u.readdirSync(o).sort().reverse()[0];a&&n.push(m.join(o,a,"bin"))}}catch{}const e=process.env.PATH??"",t=new Set(e.split(":").filter(Boolean)),s=n.filter(o=>!t.has(o));s.length&&(process.env.PATH=[...s,e].join(":"))}let fe=null;const te=new Set;function tt(r){fe=new $e.WebSocketServer({server:r,path:"/ws"}),fe.on("connection",(n,e)=>{te.add(n),n.on("close",()=>te.delete(n)),n.on("error",()=>te.delete(n))})}function O(r,n){if(!fe)return;const e=JSON.stringify({type:r,...n!==null&&typeof n=="object"?n:{data:n}});for(const t of te)t.readyState===$e.WebSocket.OPEN&&t.send(e)}const ne=m.join(S.homedir(),".jiva"),ce=m.join(ne,"jiva-directive.md"),le=m.join(ne,"conversations");function nt(r=5){try{return u.existsSync(le)?u.readdirSync(le).filter(e=>e.endsWith(".json")).map(e=>{const t=m.join(le,e);try{const s=u.statSync(t),o=JSON.parse(u.readFileSync(t,"utf-8")),a=Array.isArray(o.messages)?o.messages.length:0;let i=o.summary??o.title??"";if(!i&&Array.isArray(o.messages)){const c=o.messages.find(l=>l.role==="user");c!=null&&c.content&&(i=String(c.content).slice(0,60).replace(/\n/g," "),String(c.content).length>60&&(i+="..."))}return i=i||"Untitled conversation",{stat:s,title:i,messageCount:a}}catch{return null}}).filter(Boolean).sort((e,t)=>t.stat.mtimeMs-e.stat.mtimeMs).slice(0,r).map(({stat:e,title:t,messageCount:s})=>{const o=new Date(e.mtimeMs);return{date:`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}-${String(o.getDate()).padStart(2,"0")} ${String(o.getHours()).padStart(2,"0")}:${String(o.getMinutes()).padStart(2,"0")}`,title:t,messageCount:s}}):[]}catch{return[]}}function st(r){var f;const n=new Date,e=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],t=["January","February","March","April","May","June","July","August","September","October","November","December"],s=e[n.getDay()],o=t[n.getMonth()],a=n.getDate(),i=n.getFullYear(),c=String(n.getHours()).padStart(2,"0"),l=String(n.getMinutes()).padStart(2,"0"),d=`${c}:${l}`;let p="UTC";try{p=((f=Intl.DateTimeFormat("en",{timeZoneName:"short"}).formatToParts(n).find(g=>g.type==="timeZoneName"))==null?void 0:f.value)??"UTC"}catch{const g=-n.getTimezoneOffset(),b=g>=0?"+":"-",j=String(Math.floor(Math.abs(g)/60)).padStart(2,"0"),k=String(Math.abs(g)%60).padStart(2,"0");p=`UTC${b}${j}:${k}`}const h=n.toISOString(),y=nt(5);let v;y.length===0?v="_No previous sessions found._":v=`| Date | Title | Messages |
1
+ "use strict";var Ne=Object.create;var re=Object.defineProperty;var qe=Object.getOwnPropertyDescriptor;var Le=Object.getOwnPropertyNames;var ze=Object.getPrototypeOf,We=Object.prototype.hasOwnProperty;var He=(r,t,e)=>t in r?re(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var Be=(r,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Le(t))!We.call(r,s)&&s!==e&&re(r,s,{get:()=>t[s],enumerable:!(n=qe(t,s))||n.enumerable});return r};var O=(r,t,e)=>(e=r!=null?Ne(ze(r)):{},Be(t||!r||!r.__esModule?re(e,"default",{value:r,enumerable:!0}):e,r));var x=(r,t,e)=>He(r,typeof t!="symbol"?t+"":t,e);const C=require("child_process"),d=require("fs"),b=require("os"),u=require("path"),I=require("express"),Ge=require("http"),ke=require("ws"),xe=require("events"),le=require("url"),ue=require("zlib");function Ve(){if(process.platform==="win32")return;try{const o=process.env.SHELL??"/bin/zsh",a=C.execSync(`${o} -l -c 'echo $PATH'`,{timeout:3e3}).toString().trim();if(a){process.env.PATH=a;return}}catch{}const r=b.homedir(),t=["/usr/local/bin","/opt/homebrew/bin","/opt/local/bin",`${r}/.npm-global/bin`,"/usr/local/opt/node/bin"];try{const o=u.join(r,".nvm","versions","node");if(d.existsSync(o)){const a=d.readdirSync(o).sort().reverse()[0];a&&t.push(u.join(o,a,"bin"))}}catch{}const e=process.env.PATH??"",n=new Set(e.split(":").filter(Boolean)),s=t.filter(o=>!n.has(o));s.length&&(process.env.PATH=[...s,e].join(":"))}let de=null;const Z=new Set;function Ye(r){de=new ke.WebSocketServer({server:r,path:"/ws"}),de.on("connection",(t,e)=>{Z.add(t),t.on("close",()=>Z.delete(t)),t.on("error",()=>Z.delete(t))})}function J(r,t){if(!de)return;const e=JSON.stringify({type:r,...t!==null&&typeof t=="object"?t:{data:t}});for(const n of Z)n.readyState===ke.WebSocket.OPEN&&n.send(e)}const Q=u.join(b.homedir(),".jiva"),oe=u.join(Q,"jiva-directive.md"),ae=u.join(Q,"conversations");function Ke(r=5){try{return d.existsSync(ae)?d.readdirSync(ae).filter(e=>e.endsWith(".json")).map(e=>{const n=u.join(ae,e);try{const s=d.statSync(n),o=JSON.parse(d.readFileSync(n,"utf-8")),a=Array.isArray(o.messages)?o.messages.length:0;let i=o.summary??o.title??"";if(!i&&Array.isArray(o.messages)){const c=o.messages.find(l=>l.role==="user");c!=null&&c.content&&(i=String(c.content).slice(0,60).replace(/\n/g," "),String(c.content).length>60&&(i+="..."))}return i=i||"Untitled conversation",{stat:s,title:i,messageCount:a}}catch{return null}}).filter(Boolean).sort((e,n)=>n.stat.mtimeMs-e.stat.mtimeMs).slice(0,r).map(({stat:e,title:n,messageCount:s})=>{const o=new Date(e.mtimeMs);return{date:`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}-${String(o.getDate()).padStart(2,"0")} ${String(o.getHours()).padStart(2,"0")}:${String(o.getMinutes()).padStart(2,"0")}`,title:n,messageCount:s}}):[]}catch{return[]}}function Xe(r){var h;const t=new Date,e=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],n=["January","February","March","April","May","June","July","August","September","October","November","December"],s=e[t.getDay()],o=n[t.getMonth()],a=t.getDate(),i=t.getFullYear(),c=String(t.getHours()).padStart(2,"0"),l=String(t.getMinutes()).padStart(2,"0"),p=`${c}:${l}`;let m="UTC";try{m=((h=Intl.DateTimeFormat("en",{timeZoneName:"short"}).formatToParts(t).find(v=>v.type==="timeZoneName"))==null?void 0:h.value)??"UTC"}catch{const v=-t.getTimezoneOffset(),j=v>=0?"+":"-",k=String(Math.floor(Math.abs(v)/60)).padStart(2,"0"),f=String(Math.abs(v)%60).padStart(2,"0");m=`UTC${j}${k}:${f}`}const y=t.toISOString(),w=Ke(5);let S;w.length===0?S="_No previous sessions found._":S=`| Date | Title | Messages |
2
2
  |------|-------|----------|
3
- ${y.map(b=>`| ${b.date} | "${b.title}" | ${b.messageCount} |`).join(`
4
- `)}`;const A=`# Jiva Operating Context
3
+ ${w.map(j=>`| ${j.date} | "${j.title}" | ${j.messageCount} |`).join(`
4
+ `)}`;const M=`# Jiva Operating Context
5
5
 
6
6
  ## Current Date & Time
7
7
  - Date: ${s}, ${o} ${a}, ${i}
8
- - Time: ${d} ${p}
9
- - ISO: ${h}
8
+ - Time: ${p} ${m}
9
+ - ISO: ${y}
10
10
 
11
11
  ## Important
12
12
  - Always use the date above when referencing "today", "current year", or "recent" events
@@ -14,14 +14,14 @@ ${y.map(b=>`| ${b.date} | "${b.title}" | ${b.messageCount} |`).join(`
14
14
  - When performing web searches, always use the year ${i} for current events
15
15
 
16
16
  ## Recent Session Activity
17
- ${v}
17
+ ${S}
18
18
  `;return r!=null&&r.trim()?r.trim()+`
19
19
 
20
20
  ---
21
21
 
22
- `+A:A}function he(r){const n=st(r);try{u.existsSync(ne)||u.mkdirSync(ne,{recursive:!0}),u.writeFileSync(ce,n,"utf-8"),console.log(`[DirectiveManager] Wrote directive to ${ce}`)}catch(e){console.warn("[DirectiveManager] Failed to write directive:",e)}return{path:ce,content:n}}function N(){return m.join(S.homedir(),".jivam","config.json")}function rt(){return N()}N();function P(){try{const r=N();if(u.existsSync(r)){const n=u.readFileSync(r,"utf-8");return JSON.parse(n)}return null}catch(r){return console.error("[ConfigManager] Failed to read config:",r),null}}function R(r){try{const n=N(),e=m.dirname(n);return u.existsSync(e)||u.mkdirSync(e,{recursive:!0}),u.writeFileSync(n,JSON.stringify(r,null,2),"utf-8"),!0}catch(n){return console.error("[ConfigManager] Failed to write config:",n),!1}}let ue=null;function ot(r){const n=/^---\s*\n([\s\S]*?)\n---/.exec(r);if(!n)return{};const e={};for(const t of n[1].split(`
23
- `)){const s=t.indexOf(":");if(s===-1)continue;const o=t.slice(0,s).trim(),a=t.slice(s+1).trim().replace(/^["']|["']$/g,"");o&&(e[o]=a)}return e}async function at(){if(ue!==null)return ue;const r=[m.join(S.homedir(),".claude","skills"),m.join(S.homedir(),".jiva","skills")],n=[];for(const e of r){if(!u.existsSync(e))continue;let t;try{t=u.readdirSync(e,{withFileTypes:!0})}catch{continue}for(const s of t){if(!s.isDirectory())continue;const o=m.join(e,s.name),a=m.join(o,"SKILL.md");if(u.existsSync(a))try{const i=u.readFileSync(a,"utf-8"),c=ot(i),l=c.name??s.name,d=c.description??"";n.push({name:l,description:d,dir:o})}catch{}}}return ue=n,n}function M(r,n){n({timestamp:new Date().toISOString(),level:"info",tag:"brain",message:r})}const it=new Set(["thanks","thank","you","ty","ok","okay","alright","right","sure","yep","yup","yeah","nope","great","good","nice","cool","perfect","awesome","excellent","fantastic","wonderful","brilliant","well","done","job","work","bye","goodbye","later","cheers","ciao","welcome","problem","np","worries","no","we","are","were","finished","this","is","the","end","session","all","that","it","for","our","now","here","got","sounds","lol","haha","heh","wow","oh","ah","hmm","a","an","and","or","but","very","much","so","yes","s"]);function ct(r){const n=r.trim();if(n.length>80)return!1;const e=n.toLowerCase().replace(/[^a-z'\s]/g,"").trim().split(/\s+/);return e.length===0||e.length>12?!1:e.every(t=>it.has(t))}function ve(r,n=140){const e=r.split(`
24
- `);for(const t of e){const s=t.replace(/^#+\s*/,"").replace(/\*\*/g,"").trim();if(s.length>=20)return s.length>n?s.slice(0,n-1)+"…":s}return r.slice(0,n)}async function lt(r,n,e,t,s,o){const a=n.length>0?n.map(h=>`- ${h.name} (${h.dir}): ${h.description}`).join(`
22
+ `+M:M}function pe(r){const t=Xe(r);try{d.existsSync(Q)||d.mkdirSync(Q,{recursive:!0}),d.writeFileSync(oe,t,"utf-8"),console.log(`[DirectiveManager] Wrote directive to ${oe}`)}catch(e){console.warn("[DirectiveManager] Failed to write directive:",e)}return{path:oe,content:t}}function N(){return u.join(b.homedir(),".jivam","config.json")}function Ze(){return N()}N();function E(){try{const r=N();if(d.existsSync(r)){const t=d.readFileSync(r,"utf-8");return JSON.parse(t)}return null}catch(r){return console.error("[ConfigManager] Failed to read config:",r),null}}function R(r){try{const t=N(),e=u.dirname(t);return d.existsSync(e)||d.mkdirSync(e,{recursive:!0}),d.writeFileSync(t,JSON.stringify(r,null,2),"utf-8"),!0}catch(t){return console.error("[ConfigManager] Failed to write config:",t),!1}}let ie=null;function Qe(r){const t=/^---\s*\n([\s\S]*?)\n---/.exec(r);if(!t)return{};const e={};for(const n of t[1].split(`
23
+ `)){const s=n.indexOf(":");if(s===-1)continue;const o=n.slice(0,s).trim(),a=n.slice(s+1).trim().replace(/^["']|["']$/g,"");o&&(e[o]=a)}return e}async function et(){if(ie!==null)return ie;const r=[u.join(b.homedir(),".claude","skills"),u.join(b.homedir(),".jiva","skills")],t=[];for(const e of r){if(!d.existsSync(e))continue;let n;try{n=d.readdirSync(e,{withFileTypes:!0})}catch{continue}for(const s of n){if(!s.isDirectory())continue;const o=u.join(e,s.name),a=u.join(o,"SKILL.md");if(d.existsSync(a))try{const i=d.readFileSync(a,"utf-8"),c=Qe(i),l=c.name??s.name,p=c.description??"";t.push({name:l,description:p,dir:o})}catch{}}}return ie=t,t}function $(r,t){t({timestamp:new Date().toISOString(),level:"info",tag:"brain",message:r})}const tt=new Set(["thanks","thank","you","ty","ok","okay","alright","right","sure","yep","yup","yeah","nope","great","good","nice","cool","perfect","awesome","excellent","fantastic","wonderful","brilliant","well","done","job","work","bye","goodbye","later","cheers","ciao","welcome","problem","np","worries","no","we","are","were","finished","this","is","the","end","session","all","that","it","for","our","now","here","got","sounds","lol","haha","heh","wow","oh","ah","hmm","a","an","and","or","but","very","much","so","yes","s"]);function nt(r){const t=r.trim();if(t.length>80)return!1;const e=t.toLowerCase().replace(/[^a-z'\s]/g,"").trim().split(/\s+/);return e.length===0||e.length>12?!1:e.every(n=>tt.has(n))}function fe(r,t=140){const e=r.split(`
24
+ `);for(const n of e){const s=n.replace(/^#+\s*/,"").replace(/\*\*/g,"").trim();if(s.length>=20)return s.length>t?s.slice(0,t-1)+"…":s}return r.slice(0,t)}async function st(r,t,e,n,s,o){const a=t.length>0?t.map(y=>`- ${y.name} (${y.dir}): ${y.description}`).join(`
25
25
  `):"(none available)",i=s?`
26
26
  Conversation history so far:
27
27
  ${s}
@@ -53,13 +53,13 @@ ${c}
53
53
  MCP 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.
54
54
 
55
55
  Available skills:
56
- ${a}`,d=`User message:
56
+ ${a}`,p=`User message:
57
57
  ${r}
58
58
 
59
59
  Respond with JSON exactly (use the mode that fits):
60
60
  {"mode":"direct","reasoning":"one sentence","explanation":"1-2 sentences for the user","directResponse":"full warm response to the user","subtasks":[]}
61
61
  OR
62
- {"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"}]}`,p={mode:"delegate",reasoning:"Proceeding as a single task",explanation:"On it...",subtasks:[{id:1,label:"completing your request",prompt:r}]};try{const h=await e(l,d);if(!h)return p;const y=h.trim().replace(/^```json\s*|\s*```$/g,""),v=JSON.parse(y),A=v.mode==="direct"?"direct":"delegate",f=typeof v.reasoning=="string"?v.reasoning:"",g=typeof v.explanation=="string"&&v.explanation?v.explanation:A==="direct"?"Answering this directly.":"Handling this as a single focused task.",b=Array.isArray(v.mcpRecommendations)?v.mcpRecommendations.filter(w=>typeof w.name=="string"&&w.name.trim()).map(w=>({name:w.name,reason:typeof w.reason=="string"?w.reason:""})):void 0;if(A==="direct"){const w=typeof v.directResponse=="string"?v.directResponse:"";return{mode:"direct",reasoning:f,explanation:g,directResponse:w,subtasks:[],mcpRecommendations:b}}if(!Array.isArray(v.subtasks)||v.subtasks.length===0)return p;const j=v.subtasks.filter(w=>typeof w.label=="string"&&typeof w.prompt=="string").map((w,D)=>({id:typeof w.id=="number"?w.id:D+1,label:w.label,prompt:w.prompt,complexity:w.complexity==="simple"||w.complexity==="medium"||w.complexity==="complex"?w.complexity:"medium"}));return j.length===0?p:{mode:"delegate",reasoning:f,explanation:g,subtasks:j,mcpRecommendations:b}}catch{return p}}async function Se(r,n,e,t){M("Pulling everything together...",t);const s="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.",o=n.map((i,c)=>`### Subtask ${c+1}: ${i.label}
62
+ {"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"}]}`,m={mode:"delegate",reasoning:"Proceeding as a single task",explanation:"On it...",subtasks:[{id:1,label:"completing your request",prompt:r}]};try{const y=await e(l,p);if(!y)return m;const w=y.trim().replace(/^```json\s*|\s*```$/g,""),S=JSON.parse(w),M=S.mode==="direct"?"direct":"delegate",h=typeof S.reasoning=="string"?S.reasoning:"",v=typeof S.explanation=="string"&&S.explanation?S.explanation:M==="direct"?"Answering this directly.":"Handling this as a single focused task.",j=Array.isArray(S.mcpRecommendations)?S.mcpRecommendations.filter(g=>typeof g.name=="string"&&g.name.trim()).map(g=>({name:g.name,reason:typeof g.reason=="string"?g.reason:""})):void 0;if(M==="direct"){const g=typeof S.directResponse=="string"?S.directResponse:"";return{mode:"direct",reasoning:h,explanation:v,directResponse:g,subtasks:[],mcpRecommendations:j}}if(!Array.isArray(S.subtasks)||S.subtasks.length===0)return m;const k=S.subtasks.filter(g=>typeof g.label=="string"&&typeof g.prompt=="string").map((g,A)=>({id:typeof g.id=="number"?g.id:A+1,label:g.label,prompt:g.prompt,complexity:g.complexity==="simple"||g.complexity==="medium"||g.complexity==="complex"?g.complexity:"medium"}));return k.length===0?m:{mode:"delegate",reasoning:h,explanation:v,subtasks:k,mcpRecommendations:j}}catch{return m}}async function ge(r,t,e,n){$("Pulling everything together...",n);const s="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.",o=t.map((i,c)=>`### Subtask ${c+1}: ${i.label}
63
63
  ${i.content}`).join(`
64
64
 
65
65
  `),a=`Original request:
@@ -69,118 +69,109 @@ Subtask results:
69
69
 
70
70
  ${o}
71
71
 
72
- Write the final synthesized response.`;try{const i=await e(s,a);if(i)return i}catch{}return n[n.length-1].content}async function ut(r,n,e,t){M("Checking the result...",t);const s="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.",o=`Original request:
72
+ Write the final synthesized response.`;try{const i=await e(s,a);if(i)return i}catch{}return t[t.length-1].content}async function rt(r,t,e,n){$("Checking the result...",n);const s="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.",o=`Original request:
73
73
  ${r}
74
74
 
75
75
  Agent output (truncated to 2000 chars):
76
- ${n.slice(0,2e3)}
76
+ ${t.slice(0,2e3)}
77
77
 
78
78
  Respond with JSON:
79
- {"satisfied":true,"follow_up":"empty if satisfied, otherwise a precise description of what is still missing"}`,a={satisfied:!0,followUp:""};try{const i=await e(s,o);if(!i)return a;const c=i.trim().replace(/^```json\s*|\s*```$/g,""),l=JSON.parse(c);return{satisfied:l.satisfied!==!1,followUp:typeof l.follow_up=="string"?l.follow_up:""}}catch{return a}}function dt(r,n){switch(r){case"simple":return Math.max(10,Math.floor(n*.4));case"complex":return Math.min(n*2,200);default:return n}}async function ke(r,n,e,t,s){M(`Adjusting my approach (attempt ${e})...`,s);const o="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.",a=`Original task:
79
+ {"satisfied":true,"follow_up":"empty if satisfied, otherwise a precise description of what is still missing"}`,a={satisfied:!0,followUp:""};try{const i=await e(s,o);if(!i)return a;const c=i.trim().replace(/^```json\s*|\s*```$/g,""),l=JSON.parse(c);return{satisfied:l.satisfied!==!1,followUp:typeof l.follow_up=="string"?l.follow_up:""}}catch{return a}}function ot(r,t){switch(r){case"simple":return Math.max(10,Math.floor(t*.4));case"complex":return Math.min(t*2,200);default:return t}}async function ye(r,t,e,n,s){$(`Adjusting my approach (attempt ${e})...`,s);const o="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.",a=`Original task:
80
80
  ${r}
81
81
 
82
82
  Error encountered:
83
- ${n}
83
+ ${t}
84
84
 
85
- Write an improved version of the task prompt that is more likely to succeed.`;try{const i=await t(o,a);if(i&&i.trim().length>20)return i.trim()}catch{}return r}async function be(r,n,e,t,s){M(`Ran into trouble with "${r}" — here's what happened:`,s);const o="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.",a=`Task attempted: ${r}
86
- Task description: ${n}
85
+ Write an improved version of the task prompt that is more likely to succeed.`;try{const i=await n(o,a);if(i&&i.trim().length>20)return i.trim()}catch{}return r}async function ve(r,t,e,n,s){$(`Ran into trouble with "${r}" — here's what happened:`,s);const o="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.",a=`Task attempted: ${r}
86
+ Task description: ${t}
87
87
  Error: ${e}
88
88
 
89
- Write a short, user-friendly explanation of what happened and what could be done next.`;try{const i=await t(o,a);if(i&&i.trim().length>20)return i.trim()}catch{}return`I wasn't able to complete the task **"${r}"** after multiple attempts.
89
+ Write a short, user-friendly explanation of what happened and what could be done next.`;try{const i=await n(o,a);if(i&&i.trim().length>20)return i.trim()}catch{}return`I wasn't able to complete the task **"${r}"** after multiple attempts.
90
90
 
91
91
  The worker ran into an issue: ${e.slice(0,200)}${e.length>200?"…":""}
92
92
 
93
- You may want to check your configuration or try rephrasing the request.`}const mt=[/\bplanned subtask for the worker\b/i,/\bplease proceed with this subtask\b/i,/\bonce the results are returned,?\s+i will\b/i,/\bi will review them and provide the final response\b/i,/\bprovide the final response to the user\b/i];function pt(r){const n=r.slice(0,600);return mt.some(e=>e.test(n))}const Q=2;async function Ae(r,n,e,t,s=50,o,a){const i=await at();if(M("Thinking...",t),ct(r)){const f=o?`
93
+ You may want to check your configuration or try rephrasing the request.`}const at=[/\bplanned subtask for the worker\b/i,/\bplease proceed with this subtask\b/i,/\bonce the results are returned,?\s+i will\b/i,/\bi will review them and provide the final response\b/i,/\bprovide the final response to the user\b/i];function it(r){const t=r.slice(0,600);return at.some(e=>e.test(t))}const K=2;async function Ce(r,t,e,n,s=50,o,a){const i=await et();if($("Thinking...",n),nt(r)){const h=o?`
94
94
  Conversation history:
95
- ${o}`:"";let g;try{g=await n(`You are a warm, helpful AI assistant. Reply naturally and concisely. Markdown is fine.${f}`,r)??"You're welcome!"}catch{g="You're welcome!"}return{content:g,toolsUsed:[],iterations:0,plan:{subtasks:[],reasoning:"Conversational response"}}}const c=await lt(r,i,n,t,o,a);if(c.mode==="direct"){let f=c.directResponse??"";if(!f.trim())try{const g=o?`
95
+ ${o}`:"";let v;try{v=await t(`You are a warm, helpful AI assistant. Reply naturally and concisely. Markdown is fine.${h}`,r)??"You're welcome!"}catch{v="You're welcome!"}return{content:v,toolsUsed:[],iterations:0,plan:{subtasks:[],reasoning:"Conversational response"}}}const c=await st(r,i,t,n,o,a);if(c.mode==="direct"){let h=c.directResponse??"";if(!h.trim())try{const v=o?`
96
96
  Conversation history:
97
- ${o}`:"";f=await n(`You are a warm, helpful AI assistant. Answer the user's message naturally and concisely. Markdown is fine.${g}`,r)??"Got it!"}catch{f="Got it!"}return{content:f,toolsUsed:[],iterations:0,plan:{subtasks:[],reasoning:c.reasoning}}}if(M(c.explanation,t),c.mcpRecommendations&&c.mcpRecommendations.length>0){M("💡 You could get better results by adding these MCP servers:",t);for(const f of c.mcpRecommendations)M(` • **${f.name}** — ${f.reason}`,t);M("Browse https://mcpservers.org to find them, then add via Settings (⚙️) → MCPs.",t)}const l=c.subtasks.length;if(l>1){const f=c.subtasks.map((g,b)=>`${b+1}. ${g.label}`).join(" · ");M(`My plan: ${f}`,t)}const d=[];for(const f of c.subtasks){M(`Working on step ${f.id}: ${f.label}...`,t);const g=dt(f.complexity,s);let b=null,j="";for(let k=1;k<=Q;k++)try{const w=k===1?f.prompt:await ke(f.prompt,j,k,n,t),D=Date.now(),L=setInterval(()=>{const T=Math.round((Date.now()-D)/1e3);M(`Still at it (${T}s)…`,t)},25e3);try{b=await e(w,{maxIterations:g})}finally{clearInterval(L)}break}catch(w){j=w instanceof Error?w.message:String(w),k<Q?M("Hit a snag — let me try a different approach...",t):b={content:await be(f.label,f.prompt,j,n,t),toolsUsed:[],iterations:0}}if(l>1){const k=ve(b.content);k&&M(`Step ${f.id} done: ${k}`,t)}d.push({...b,label:f.label})}let p;if(l===1?p=d[0].content:p=await Se(r,d.map(f=>({label:f.label,content:f.content})),n,t),pt(p)){M("The worker couldn't complete this one — let me answer directly...",t);const f=o?`
97
+ ${o}`:"";h=await t(`You are a warm, helpful AI assistant. Answer the user's message naturally and concisely. Markdown is fine.${v}`,r)??"Got it!"}catch{h="Got it!"}return{content:h,toolsUsed:[],iterations:0,plan:{subtasks:[],reasoning:c.reasoning}}}if($(c.explanation,n),c.mcpRecommendations&&c.mcpRecommendations.length>0){$("💡 You could get better results by adding these MCP servers:",n);for(const h of c.mcpRecommendations)$(` • **${h.name}** — ${h.reason}`,n);$("Browse https://mcpservers.org to find them, then add via Settings (⚙️) → MCPs.",n)}const l=c.subtasks.length;if(l>1){const h=c.subtasks.map((v,j)=>`${j+1}. ${v.label}`).join(" · ");$(`My plan: ${h}`,n)}const p=[];for(const h of c.subtasks){$(`Working on step ${h.id}: ${h.label}...`,n);const v=ot(h.complexity,s);let j=null,k="";for(let f=1;f<=K;f++)try{const g=f===1?h.prompt:await ye(h.prompt,k,f,t,n),A=Date.now(),_=setInterval(()=>{const D=Math.round((Date.now()-A)/1e3);$(`Still at it (${D}s)…`,n)},25e3);try{j=await e(g,{maxIterations:v})}finally{clearInterval(_)}break}catch(g){k=g instanceof Error?g.message:String(g),f<K?$("Hit a snag — let me try a different approach...",n):j={content:await ve(h.label,h.prompt,k,t,n),toolsUsed:[],iterations:0}}if(l>1){const f=fe(j.content);f&&$(`Step ${h.id} done: ${f}`,n)}p.push({...j,label:h.label})}let m;if(l===1?m=p[0].content:m=await ge(r,p.map(h=>({label:h.label,content:h.content})),t,n),it(m)){$("The worker couldn't complete this one — let me answer directly...",n);const h=o?`
98
98
  Conversation history:
99
- ${o}`:"";try{p=await 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.${f}`,r)??p}catch{}}const h=await ut(r,p,n,t);if(!h.satisfied&&h.followUp){M("Almost there — one more thing to tackle...",t);const f=`The following was not fully addressed in your previous response:
99
+ ${o}`:"";try{m=await t(`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.${h}`,r)??m}catch{}}const y=await rt(r,m,t,n);if(!y.satisfied&&y.followUp){$("Almost there — one more thing to tackle...",n);const h=`The following was not fully addressed in your previous response:
100
100
 
101
- ${h.followUp}
101
+ ${y.followUp}
102
102
 
103
103
  Original request:
104
104
  ${r}
105
105
 
106
106
  Previous work summary:
107
- ${p.slice(0,800)}
108
-
109
- Please address the missing parts specifically.`;let g=null,b="";for(let k=1;k<=Q;k++)try{const w=k===1?f:await ke(f,b,k,n,t);g=await e(w,{maxIterations:s});break}catch(w){b=w instanceof Error?w.message:String(w),k<Q?M("The follow-up hit an issue — trying once more...",t):g={content:await be("follow-up",f,b,n,t),toolsUsed:[],iterations:0}}const j=ve(g.content);j&&M(`That covers it: ${j}`,t),p=await Se(r,[{label:"Initial work",content:p},{label:"Follow-up",content:g.content}],n,t),d.push({...g,label:"follow-up"})}else h.satisfied&&M("All done — here's the result:",t);const y=d.flatMap(f=>f.toolsUsed??[]),v=[...new Set(y)],A=d.reduce((f,g)=>f+(g.iterations??0),0);return{...d[d.length-1],content:p,toolsUsed:v,iterations:A,plan:{subtasks:c.subtasks.map(f=>f.label),reasoning:c.reasoning}}}function ft(){try{const n=$.execSync("npm root -g",{timeout:5e3}).toString().trim(),e=m.join(n,"jiva-core","package.json");if(u.existsSync(e)){const s=JSON.parse(u.readFileSync(e,"utf-8")).main??"dist/index.js";return m.join(n,"jiva-core",s)}}catch{}const r=m.join(S.homedir(),".npm-global","lib","node_modules","jiva-core","dist","index.js");if(u.existsSync(r))return r;throw new Error("Could not find jiva-core. Please run: npm install -g jiva-core")}const ht=/^(\d{4}-\d{2}-\d{2}T[\d:.Z]+)\s+\[(INFO|WARN|ERROR)\]\s+\[(\w+)\]\s+(.+)$/;function Ie(r){const n=ht.exec(r.trim());return n?{timestamp:n[1],level:n[2].toLowerCase(),tag:n[3],message:n[4]}:null}class gt extends Me.EventEmitter{constructor(){super(...arguments);x(this,"agent",null);x(this,"orchestrator",null);x(this,"workspace",null);x(this,"conversationManager",null);x(this,"mcpManager",null);x(this,"codeLogger",null);x(this,"ready",!1);x(this,"deepRun",!1);x(this,"maxIterations",50)}isReady(){return this.ready}getConversationId(){return this.conversationManager?this.conversationManager.currentConversationId??null:null}async initialize(e,t,s){var V,Y;this.deepRun=(s==null?void 0:s.deepRun)??!1,this.maxIterations=(s==null?void 0:s.maxIterations)??50;const o=ft();console.log(`[CodeRunner] Loading jiva-core from: ${o}`);const a=await import(me.pathToFileURL(o).href),{configManager:i,ModelOrchestrator:c,WorkspaceManager:l,ConversationManager:d,CodeAgent:p,MCPServerManager:h,createKrutrimModel:y,createLocalProvider:v,logger:A}=a;this.codeLogger=A??null,i.validateConfig();const f=i.getReasoningModel(),b=y({endpoint:f.endpoint,apiKey:f.apiKey,model:f.defaultModel,type:"reasoning",useHarmonyFormat:f.useHarmonyFormat}),j=c;this.orchestrator=new j({reasoningModel:b});const{path:k}=he((V=P())==null?void 0:V.userDirective),w=l;this.workspace=new w({workspaceDir:e,directivePath:k}),await this.workspace.initialize();const L=await v(),T=d;this.conversationManager=new T(L,this.orchestrator),this.mcpManager=null;const F=t&&t.length>0?t:null;if(F&&h){const oe=h,ae=new oe,K=((Y=P())==null?void 0:Y.mcpServers)??{},X={};for(const q of F)K[q]&&(X[q]=K[q]);await ae.initialize(X),this.mcpManager=ae,console.log(`[CodeRunner] MCP servers loaded: ${F.join(", ")}`)}const re=p;this.agent=new re({orchestrator:this.orchestrator,workspace:this.workspace,conversationManager:this.conversationManager,maxIterations:this.maxIterations,...this.mcpManager&&F?{mcpManager:this.mcpManager,mcpServerNames:F}:{}}),this.ready=!0,console.log(`[CodeRunner] Initialized (maxIterations=${this.maxIterations}, deepRun=${this.deepRun})`)}makeCompleter(){const e=this.orchestrator;return async(t,s)=>{if(typeof e.chat!="function")return null;try{const a=await e.chat.bind(e)({messages:[{role:"system",content:t},{role:"user",content:s}],reasoningEffort:"low"});return(a==null?void 0:a.content)??null}catch(o){return console.warn("[CodeRunner] makeCompleter: chat() failed:",o),null}}}async chat(e,t,s){if((s==null?void 0:s.maxIterations)!==void 0&&s.maxIterations!==this.maxIterations){this.maxIterations=s.maxIterations;try{this.agent.maxIterations=this.maxIterations}catch{}}return(s==null?void 0:s.deepRun)!==!1&&((s==null?void 0:s.deepRun)??this.deepRun)?await Ae(e,this.makeCompleter(),(i,c)=>this.runChatWithIterations(i,t,c==null?void 0:c.maxIterations),i=>t(i),this.maxIterations,(s==null?void 0:s.conversationHistory)||void 0):this.runChat(e,t)}async runChatWithIterations(e,t,s){if(s!==void 0&&s!==this.maxIterations){this.maxIterations=s;try{this.agent.maxIterations=this.maxIterations}catch{}}return this.runChat(e,t)}hookLogger(e){const t=this.codeLogger,s=(a,i,c)=>{const l=a.toLowerCase();e({timestamp:new Date().toISOString(),level:l==="warn"||l==="error"?l:"info",tag:i,message:c})};if(t&&typeof t.on=="function"){const a=(...i)=>{if(i.length>=3&&typeof i[0]=="string")s(i[0],i[1]??"CodeAgent",i[2]);else if(i.length>=2&&typeof i[0]=="string")s("info","CodeAgent",i[1]);else if(i.length>=1&&typeof i[0]=="object"){const c=i[0];s(String(c.level??"info"),String(c.tag??c.name??"CodeAgent"),String(c.message??c.msg??""))}};try{return t.on("log",a),()=>{typeof t.off=="function"?t.off("log",a):typeof t.removeListener=="function"&&t.removeListener("log",a)}}catch{}}if(t)for(const a of["addTransport","addHandler","addSink"]){if(typeof t[a]!="function")continue;const i=a.replace("add","remove"),c={write:l=>{s(String(l.level??"info"),String(l.tag??l.name??"CodeAgent"),String(l.message??l.msg??""))},log:l=>{s(String(l.level??"info"),String(l.tag??l.name??"CodeAgent"),String(l.message??l.msg??""))}};try{return t[a](c),()=>{if(typeof t[i]=="function")try{t[i](c)}catch{}}}catch{}}const o=process.stdout.write.bind(process.stdout);return process.stdout.write=(a,...i)=>{const c=typeof a=="string"?a:Buffer.from(a).toString();for(const l of c.split(`
110
- `)){const d=Ie(l);if(d){e(d);continue}const p=/(?:tool(?:\s+call)?|calling|executing)[:\s]+([^\s(]+)/i.exec(l.trim());p&&e({timestamp:new Date().toISOString(),level:"info",tag:"CodeAgent",message:`Tool: ${p[1]}`})}return o(a,...i)},()=>{process.stdout.write=o}}async runChat(e,t){var a;if(!this.agent)throw new Error("CodeRunner not initialized");const s=this.agent,o=this.hookLogger(t);try{const i=await s.chat(e);if((a=i.toolsUsed)!=null&&a.length){const c=new Set;for(const l of i.toolsUsed)c.has(l)||(c.add(l),t({timestamp:new Date().toISOString(),level:"info",tag:"CodeAgent",message:`Tool: ${l}`}))}return{content:i.content,toolsUsed:i.toolsUsed??[],iterations:i.iterations??0}}finally{o()}}stop(){this.agent&&this.agent.stop()}async cleanup(){if(this.agent)try{await this.agent.cleanup()}catch(e){console.warn("[CodeRunner] Cleanup error:",e)}if(this.mcpManager)try{await this.mcpManager.cleanup()}catch{}this.agent=null,this.orchestrator=null,this.workspace=null,this.conversationManager=null,this.mcpManager=null,this.ready=!1}}function yt(){try{const n=$.execSync("npm root -g",{timeout:5e3}).toString().trim(),e=m.join(n,"jiva-core","package.json");if(u.existsSync(e)){const s=JSON.parse(u.readFileSync(e,"utf-8")).main??"dist/index.js";return m.join(n,"jiva-core",s)}}catch{}if(process.platform==="win32"){const n=[m.join(process.env.APPDATA??"","npm","node_modules","jiva-core","dist","index.js"),m.join(process.env.LOCALAPPDATA??"","npm","node_modules","jiva-core","dist","index.js"),"C:\\Program Files\\nodejs\\node_modules\\jiva-core\\dist\\index.js"];for(const e of n)if(u.existsSync(e))return e}const r="/Users/abidev/.npm-global/lib/node_modules/jiva-core/dist/index.js";if(u.existsSync(r))return r;throw new Error("Could not find jiva-core. Please ensure it is installed globally: npm install -g jiva-core")}class wt extends Me.EventEmitter{constructor(){super(...arguments);x(this,"status","stopped");x(this,"agent",null);x(this,"orchestrator",null);x(this,"mcpManager",null);x(this,"workspace",null);x(this,"conversationManager",null);x(this,"personaManager",null);x(this,"jivaLogger",null);x(this,"currentPersona",null);x(this,"currentConversationId",null);x(this,"maxIterations",50)}getStatus(){return this.status}getCurrentConversationId(){return this.currentConversationId}async initialize(e){var t,s;this.setStatus("initializing");try{const o=yt();console.log(`[JivaRunner] Loading jiva-core from: ${o}`);const a=await import(me.pathToFileURL(o).href),{MCPServerManager:i,WorkspaceManager:c,ConversationManager:l,ModelOrchestrator:d,DualAgent:p,createKrutrimModel:h,LogLevel:y,logger:v,createLocalProvider:A}=a,f=P();if(!((s=(t=f==null?void 0:f.models)==null?void 0:t.reasoning)!=null&&s.apiKey))throw new Error("Jivam is not configured. Add your API key in Settings → Models.");const g=f.models.reasoning,b=f.models.multimodal,j=h,k=g.defaultModel??g.model??"",w=j({endpoint:g.endpoint,apiKey:g.apiKey,model:k,type:"reasoning",useHarmonyFormat:g.useHarmonyFormat,...g.reasoningEffortStrategy?{reasoningEffortStrategy:g.reasoningEffortStrategy}:{},...g.defaultMaxTokens?{defaultMaxTokens:g.defaultMaxTokens}:{}});let D;if(b!=null&&b.apiKey)try{const Z=b.defaultModel??"";D=j({endpoint:b.endpoint,apiKey:b.apiKey,model:Z,type:"multimodal"})}catch{console.warn("[JivaRunner] Failed to create multimodal model, continuing without vision")}const L=d;this.orchestrator=new L({reasoningModel:w,multimodalModel:D});const T=f.mcpServers??{},F=S.platform()==="win32"?"C:\\Users":"/Users";T.filesystem||(T.filesystem={command:"npx",args:["-y","@modelcontextprotocol/server-filesystem",F],enabled:!0});const re=i;this.mcpManager=new re,await this.mcpManager.initialize(T);const{path:V}=he(f.userDirective),Y=process.cwd(),oe=c;this.workspace=new oe({workspaceDir:Y,directivePath:V}),await this.workspace.initialize();const K=await A(),X=l;this.conversationManager=new X(K,this.orchestrator);const q=m.dirname(o),Ne=m.dirname(q),Ue=m.join(Ne,"dist","personas","persona-manager.js"),{PersonaManager:Le}=await import(me.pathToFileURL(Ue).href);this.personaManager=new Le,await this.personaManager.initialize(e??void 0);const qe=this.personaManager.getPersonaMCPServers();for(const[Z,We]of Object.entries(qe))try{await this.mcpManager.addServer(Z,We)}catch(Be){console.warn(`[JivaRunner] Failed to add persona MCP server '${Z}':`,Be)}const ze=p;this.agent=new ze({orchestrator:this.orchestrator,mcpManager:this.mcpManager,workspace:this.workspace,conversationManager:this.conversationManager,personaManager:this.personaManager,maxSubtasks:20,maxIterations:this.maxIterations,autoSave:!0,condensingThreshold:30}),this.jivaLogger=v,this.currentPersona=e??null,this.setStatus("ready"),console.log("[JivaRunner] Initialized successfully")}catch(o){const a=o instanceof Error?o.message:String(o);throw console.error("[JivaRunner] Initialization failed:",a),this.setStatus("error",a),o}}makeCompleter(){const e=this.orchestrator;return async(t,s)=>{if(typeof e.chat!="function")return null;try{const a=await e.chat.bind(e)({messages:[{role:"system",content:t},{role:"user",content:s}],reasoningEffort:"low"});return(a==null?void 0:a.content)??null}catch(o){return console.warn("[JivaRunner] makeCompleter: chat() failed:",o),null}}}hookLogger(e){const t=this.jivaLogger;if(!t)return()=>{};const s=(a,i,c)=>{const l=a.toLowerCase();e({timestamp:new Date().toISOString(),level:l==="warn"||l==="error"?l:"info",tag:i,message:c})};if(typeof t.on=="function"){const a=(...i)=>{if(i.length>=3&&typeof i[0]=="string")s(i[0],i[1]??"jiva",i[2]);else if(i.length>=2&&typeof i[0]=="string")s("info","jiva",i[1]);else if(i.length>=1&&typeof i[0]=="object"){const c=i[0];s(String(c.level??"info"),String(c.tag??c.name??"jiva"),String(c.message??c.msg??""))}};try{return t.on("log",a),()=>{typeof t.off=="function"?t.off("log",a):typeof t.removeListener=="function"&&t.removeListener("log",a)}}catch{}}for(const a of["addTransport","addHandler","addSink"]){if(typeof t[a]!="function")continue;const i=a.replace("add","remove"),c={write:l=>{s(String(l.level??"info"),String(l.tag??l.name??"jiva"),String(l.message??l.msg??""))},log:l=>{s(String(l.level??"info"),String(l.tag??l.name??"jiva"),String(l.message??l.msg??""))}};try{return t[a](c),()=>{if(typeof t[i]=="function")try{t[i](c)}catch{}}}catch{}}const o=process.stdout.write.bind(process.stdout);return process.stdout.write=(a,...i)=>{const c=typeof a=="string"?a:Buffer.from(a).toString();for(const l of c.split(`
111
- `)){const d=Ie(l);if(d){e(d);continue}const p=/(?:tool(?:\s+call)?|calling|executing)[:\s]+([^\s(]+)/i.exec(l.trim());p&&e({timestamp:new Date().toISOString(),level:"info",tag:"jiva",message:`Tool: ${p[1]}`})}return o(a,...i)},()=>{process.stdout.write=o}}async runChat(e,t,s){var l,d,p;const o=s?this.hookLogger(s):null,a=this.agent;let i;try{i=await a.chat(e)}finally{o==null||o()}if(s&&((l=i.toolsUsed)!=null&&l.length))for(const h of i.toolsUsed)s({timestamp:new Date().toISOString(),level:"info",tag:"jiva",message:`Tool: ${h}`});let c=null;try{c=((p=(d=this.conversationManager).getCurrentConversationId)==null?void 0:p.call(d))??null}catch{}if(!c)try{c=await this.agent.saveConversation()}catch{}return c&&(this.currentConversationId=c),{content:i.content,iterations:i.iterations,toolsUsed:i.toolsUsed??[],plan:i.plan?{subtasks:i.plan.subtasks??[],reasoning:i.plan.reasoning}:null,durationMs:Date.now()-t,conversationId:this.currentConversationId??void 0}}async chat(e,t,s,o){var l;if(!this.agent)throw new Error("JivaRunner not initialized. Call initialize() first.");if(this.status==="busy")throw new Error("Agent is already processing a request.");if((s==null?void 0:s.maxIterations)!==void 0&&s.maxIterations!==this.maxIterations){this.maxIterations=s.maxIterations;try{this.agent.maxIterations=this.maxIterations}catch{}}this.setStatus("busy");const a=Date.now();t("planning");const i=setTimeout(()=>t("executing"),2e3),c=setTimeout(()=>t("synthesizing"),3e4);try{let d;if((s==null?void 0:s.deepRun)!==!1){const p=Object.keys(((l=P())==null?void 0:l.mcpServers)??{});d=await Ae(e,this.makeCompleter(),(h,y)=>{if((y==null?void 0:y.maxIterations)!==void 0&&y.maxIterations!==this.maxIterations){this.maxIterations=y.maxIterations;try{this.agent.maxIterations=this.maxIterations}catch{}}return this.runChat(h,a,o)},h=>o==null?void 0:o(h),this.maxIterations,(s==null?void 0:s.conversationHistory)||void 0,p)}else d=await this.runChat(e,a,o);return clearTimeout(i),clearTimeout(c),t("done"),this.setStatus("ready"),d}catch(d){throw clearTimeout(i),clearTimeout(c),this.setStatus("ready"),d}}async loadConversation(e){if(!this.agent)throw new Error("JivaRunner not initialized. Call initialize() first.");await this.agent.loadConversation(e),this.currentConversationId=e,console.log(`[JivaRunner] Loaded conversation: ${e}`)}async switchPersona(e){this.agent&&await this.cleanup(),await this.initialize(e)}resetConversation(){this.agent&&this.agent.resetConversation(),this.currentConversationId=null}getMCPTools(){var e,t;if(!this.mcpManager)return{};try{const s=((t=(e=this.mcpManager).getAllTools)==null?void 0:t.call(e))??[],o={};for(const a of s){const i=a.name.split("__"),c=i.length>1?i[0]:"unknown",l=i.length>1?i.slice(1).join("__"):a.name;o[c]||(o[c]=[]),o[c].push({name:l,description:a.description??""})}return o}catch{return{}}}async addMCPServer(e,t){if(!this.mcpManager)throw new Error("MCP manager not initialized");await this.mcpManager.addServer(e,t)}async removeMCPServer(e){if(!this.mcpManager)throw new Error("MCP manager not initialized");const t=this.mcpManager;t.removeServer?await t.removeServer(e):t.disableServer&&await t.disableServer(e)}getMCPServerStatus(){var e,t;if(!this.mcpManager)return[];try{return(((t=(e=this.mcpManager).getServerStatus)==null?void 0:t.call(e))??[]).map(o=>({...o,error:o.error??o.lastError}))}catch{return[]}}async reconnectMCPServer(e){var c,l,d;if(!this.mcpManager)throw new Error("MCP manager not initialized");const t=this.mcpManager;if(typeof t.reconnectServer=="function"){await t.reconnectServer(e);return}if(!this.getMCPServerStatus().find(p=>p.name===e))throw new Error(`MCP server "${e}" not found`);const a=((d=(l=(c=this.mcpManager).getServerStatus)==null?void 0:l.call(c))==null?void 0:d.find(p=>p.name===e))??{};await this.removeMCPServer(e);const i=a.url!=null?{type:"http",url:a.url,env:a.env,enabled:!0}:{type:"stdio",command:a.command,args:a.args,env:a.env,enabled:!0};await this.addMCPServer(e,i)}async toggleMCPServer(e,t){if(!this.mcpManager)throw new Error("MCP manager not initialized");const s=this.mcpManager;t&&s.enableServer?await s.enableServer(e):!t&&s.disableServer&&await s.disableServer(e)}async describeImage(e){var a;if(!this.orchestrator)throw new Error("JivaRunner not initialized. Call initialize() first.");const t=P();if(!((a=t==null?void 0:t.models)!=null&&a.multimodal))throw new Error("No multimodal (vision) model is configured. Enable it in Settings → Models.");return(await this.orchestrator.chat({messages:[{role:"user",content:[{type:"image_url",image_url:{url:e}},{type:"text",text:"Describe this image in detail, including all visible content, text, charts, diagrams, and any notable elements."}]}]})).content}async cleanup(){try{this.agent&&(await this.agent.cleanup(),this.agent=null),this.mcpManager&&(await this.mcpManager.cleanup(),this.mcpManager=null)}catch(e){console.warn("[JivaRunner] Cleanup error:",e)}this.orchestrator=null,this.workspace=null,this.conversationManager=null,this.personaManager=null,this.currentConversationId=null,this.setStatus("stopped")}stop(){this.agent&&this.agent.stop()}setStatus(e,t){this.status=e,this.emit("status-changed",e,{error:t})}}const ee="https://jiva-hdjcuspt2a-uc.a.run.app";class vt{constructor(){x(this,"userId",null);x(this,"sessionId",null);x(this,"_active",!1);x(this,"_abortController",null);x(this,"_readyPromise",null);x(this,"_readyResolve",null);x(this,"_readyReject",null)}startInit(){this._active||this._readyPromise||(this._readyPromise=new Promise((n,e)=>{this._readyResolve=n,this._readyReject=e}))}configure(n,e){var t;this.userId=n,this.sessionId=e,this._active=!0,(t=this._readyResolve)==null||t.call(this),this._readyResolve=null,this._readyReject=null}waitUntilReady(n){return this._active?Promise.resolve():this._readyPromise?Promise.race([this._readyPromise,new Promise((e,t)=>setTimeout(()=>t(new Error(`Cloud runner not ready after ${n}ms`)),n))]):Promise.reject(new Error("Cloud runner init not started"))}isActive(){return this._active}isInitializing(){return!this._active&&this._readyPromise!==null}deactivate(){var n;this._active=!1,this.userId=null,this.sessionId=null,(n=this._readyReject)==null||n.call(this,new Error("Cloud session deactivated")),this._readyPromise=null,this._readyResolve=null,this._readyReject=null}stop(){var n;(n=this._abortController)==null||n.abort()}get headers(){return{"Content-Type":"application/json","x-tenant-id":this.userId??"dev-tenant","x-session-id":this.sessionId??"default-session"}}async chat(n,e,t,s){if(!this._active)throw new Error("CloudRunner not configured");const o=Date.now();e("planning"),this._abortController=new AbortController;const{signal:a}=this._abortController;try{return{...await this._streamChat(n,e,s,a),durationMs:Date.now()-o}}catch(i){return i.name==="AbortError"?{content:"",iterations:0,toolsUsed:[],plan:null,durationMs:Date.now()-o}:(console.warn("[CloudRunner] SSE failed, falling back to non-streaming:",i),{...await this._nonStreamChat(n,e,a),durationMs:Date.now()-o})}finally{this._abortController=null,e("done")}}async _streamChat(n,e,t,s){const o=await fetch(`${ee}/api/chat/stream`,{method:"POST",headers:{...this.headers,Accept:"text/event-stream"},body:JSON.stringify({message:n}),signal:s});if(!o.ok||!o.body)throw new Error(`SSE request failed: ${o.status}`);const a=o.body.getReader(),i=new TextDecoder;let c="",l="",d=0;const p=[];let h=null,y=null;e:for(;;){const{done:v,value:A}=await a.read();if(v)break;c+=i.decode(A,{stream:!0});const f=c.split(`
112
- `);c=f.pop()??"";for(const g of f){if(g.startsWith("event: ")){y=g.slice(7).trim();continue}if(!g.startsWith("data: "))continue;const b=g.slice(6).trim();if(!b||b==="[DONE]")continue;let j;try{j=JSON.parse(b)}catch{continue}const k=y??j.type;if(y=null,k==="status"){const w=j.message;w&&(e("executing"),t==null||t({timestamp:new Date().toISOString(),level:"info",tag:"cloud",message:`Tool: ${w}`}))}else if(k==="response")l=j.content??j.response??"",d=j.iterations??0,Array.isArray(j.toolsUsed)&&p.push(...j.toolsUsed),j.plan&&(h=j.plan);else{if(k==="error")throw new Error(j.message??"Stream error");if(k==="done")break e}}}return{content:l,iterations:d,toolsUsed:p,plan:h}}async _nonStreamChat(n,e,t){e("executing");const s=await fetch(`${ee}/api/chat`,{method:"POST",headers:this.headers,body:JSON.stringify({message:n}),signal:t});if(!s.ok){const a=await s.text();throw new Error(`Cloud chat failed (${s.status}): ${a}`)}const o=await s.json();return{content:o.response??"",iterations:o.iterations??0,toolsUsed:Array.isArray(o.toolsUsed)?o.toolsUsed:[],plan:o.plan??null}}async resetConversation(){if(this._active)try{await fetch(`${ee}/api/chat/history`,{method:"DELETE",headers:this.headers})}catch(n){console.error("[CloudRunner] resetConversation failed:",n)}}async stopMessage(){try{await fetch(`${ee}/api/chat/stop`,{method:"POST",headers:this.headers})}catch{}this.stop()}}const Pe=E.Router();Pe.get("/check",(r,n)=>{var p;let e=!1,t;try{$.execSync("npm --version",{timeout:3e3}),e=!0;try{t=$.execSync("node --version",{timeout:3e3}).toString().trim().replace(/^v/,"")}catch{}}catch{}let s=!1,o;if(e){const h=[];try{const y=$.execSync("npm root -g",{timeout:5e3}).toString().trim();h.push(m.join(y,"jiva-core","package.json"))}catch{}h.push(m.join(S.homedir(),".npm-global","lib","node_modules","jiva-core","package.json")),process.platform==="win32"&&(h.push(m.join(process.env.APPDATA??"","npm","node_modules","jiva-core","package.json")),h.push(m.join(process.env.LOCALAPPDATA??"","npm","node_modules","jiva-core","package.json")));for(const y of h)if(u.existsSync(y))try{o=JSON.parse(u.readFileSync(y,"utf-8")).version,s=!0;break}catch{}}const a=[N(),m.join(S.homedir(),".jiva","config.json")];let i=!1,c="";for(const h of a)if(u.existsSync(h))try{const y=JSON.parse(u.readFileSync(h,"utf-8")),v=((p=y==null?void 0:y.models)==null?void 0:p.reasoning)??{};if(((v==null?void 0:v.apiKey)??(y==null?void 0:y.apiKey)??"").length>0){i=!0,c=h;break}}catch{}let l=!1,d;try{const h=m.join(__dirname,"..","..","package.json");if(d=JSON.parse(u.readFileSync(h,"utf-8")).jivaCompatibleVersion,d&&o){const[v,A]=d.split(".").map(Number),[f,g]=o.split(".").map(Number);(v!==f||A!==g)&&(l=!0)}}catch{}n.json({nodejs:{ok:e,version:t},jivaCore:{ok:s,version:o},config:{ok:i,path:c||a[0]},platform:process.platform,jivaVersionMismatch:l,requiredJivaVersion:d})});const H=E.Router(),St={sarvam:{endpoint:"https://api.sarvam.ai/v1/chat/completions",defaultModel:"sarvam-105b",useHarmonyFormat:!1,reasoningEffortStrategy:"api_param",defaultMaxTokens:8192,multimodal:null},krutrim:{endpoint:"https://cloud.olakrutrim.com/v1/chat/completions",defaultModel:"gpt-oss-120b",useHarmonyFormat:!0,reasoningEffortStrategy:"system_prompt",multimodal:{defaultModel:"Llama-4-Maverick-17B-128E-Instruct"}},groq:{endpoint:"https://api.groq.com/openai/v1/chat/completions",defaultModel:"openai/gpt-oss-120b",useHarmonyFormat:!1,reasoningEffortStrategy:"api_param",multimodal:{defaultModel:"meta-llama/llama-4-maverick-17b-128e-instruct"}},"openai-compatible":{endpoint:"",defaultModel:"",useHarmonyFormat:!1,reasoningEffortStrategy:"both",multimodal:null}};H.get("/",(r,n)=>{n.json(P())});H.post("/",(r,n)=>{const e=R(r.body);n.json(e)});H.get("/path",(r,n)=>{n.json(N())});H.post("/setup-provider",(r,n)=>{const{provider:e,apiKey:t,customEndpoint:s,customModel:o}=r.body;try{const a=St[e];if(!a)return n.json({success:!1,error:`Unknown provider: ${e}`});const i=e==="openai-compatible"?s??"":a.endpoint,c=e==="openai-compatible"?o??"":a.defaultModel,d=P()??{models:{reasoning:null}};if(d.models={...d.models,reasoning:{name:"reasoning",type:"reasoning",provider:e,endpoint:i,apiKey:t,defaultModel:c,useHarmonyFormat:a.useHarmonyFormat,reasoningEffortStrategy:a.reasoningEffortStrategy,...a.defaultMaxTokens?{defaultMaxTokens:a.defaultMaxTokens}:{}},multimodal:a.multimodal?{name:"multimodal",type:"multimodal",endpoint:i,apiKey:t,defaultModel:a.multimodal.defaultModel}:void 0},!d.mcpServers){const h=process.platform==="win32"?"C:\\Users":`${S.homedir()}`;d.mcpServers={filesystem:{command:"npx",args:["-y","@modelcontextprotocol/server-filesystem",h],enabled:!0},"mcp-shell-server":{command:"npx",args:["-y","@mkusaka/mcp-shell-server"],enabled:!0}}}const p=R(d);return n.json({success:p,error:p?void 0:"Failed to write config"})}catch(a){return n.json({success:!1,error:a instanceof Error?a.message:String(a)})}});const ge=E.Router();ge.get("/",(r,n)=>{const e=m.join(S.homedir(),".jiva","conversations");try{if(!u.existsSync(e))return n.json([]);const t=u.readdirSync(e).filter(s=>s.endsWith(".json")).map(s=>{var i,c,l;const o=m.join(e,s),a=u.statSync(o);try{const d=JSON.parse(u.readFileSync(o,"utf-8"));let p=((i=d.metadata)==null?void 0:i.title)??d.summary??d.title??"";if(!p&&Array.isArray(d.messages)){const h=d.messages.find(y=>y.role==="user");if(h!=null&&h.content){const y=typeof h.content=="string"?h.content:Array.isArray(h.content)?h.content.filter(v=>v.type==="text").map(v=>v.text??"").join(""):"";p=y.slice(0,60).replace(/\n/g," "),y.length>60&&(p+="...")}}return{id:s.replace(".json",""),summary:p||"Untitled",messageCount:((c=d.messages)==null?void 0:c.length)??0,lastModified:a.mtimeMs,type:((l=d.metadata)==null?void 0:l.type)??"chat"}}catch{return null}}).filter(Boolean).sort((s,o)=>o.lastModified-s.lastModified);return n.json(t)}catch{return n.json([])}});ge.get("/:id",(r,n)=>{const e=m.join(S.homedir(),".jiva","conversations",`${r.params.id}.json`);try{return u.existsSync(e)?n.json(JSON.parse(u.readFileSync(e,"utf-8"))):n.json(null)}catch{return n.json(null)}});const U=E.Router();U.get("/is-repo",(r,n)=>{const e=r.query.dir;try{$.execFileSync("git",["rev-parse","--is-inside-work-tree"],{cwd:e,timeout:3e3}),n.json(!0)}catch{n.json(!1)}});U.get("/status",(r,n)=>{const e=r.query.dir;try{const t=$.execFileSync("git",["status","--porcelain"],{cwd:e,timeout:5e3}).toString();n.json(t.split(`
113
- `).filter(Boolean).map(s=>({status:s.slice(0,2).trim(),file:s.slice(3).trim()})))}catch{n.json([])}});U.get("/diff-file",(r,n)=>{const{dir:e,file:t,status:s}=r.query;try{if(s==="??"){const o=m.join(e,t);try{const i=u.readFileSync(o,"utf-8").split(`
114
- `);return i[i.length-1]===""&&i.pop(),n.json(`--- /dev/null
115
- +++ b/${t}
107
+ ${m.slice(0,800)}
108
+
109
+ Please address the missing parts specifically.`;let v=null,j="";for(let f=1;f<=K;f++)try{const g=f===1?h:await ye(h,j,f,t,n);v=await e(g,{maxIterations:s});break}catch(g){j=g instanceof Error?g.message:String(g),f<K?$("The follow-up hit an issue — trying once more...",n):v={content:await ve("follow-up",h,j,t,n),toolsUsed:[],iterations:0}}const k=fe(v.content);k&&$(`That covers it: ${k}`,n),m=await ge(r,[{label:"Initial work",content:m},{label:"Follow-up",content:v.content}],t,n),p.push({...v,label:"follow-up"})}else y.satisfied&&$("All done — here's the result:",n);const w=p.flatMap(h=>h.toolsUsed??[]),S=[...new Set(w)],M=p.reduce((h,v)=>h+(v.iterations??0),0);return{...p[p.length-1],content:m,toolsUsed:S,iterations:M,plan:{subtasks:c.subtasks.map(h=>h.label),reasoning:c.reasoning}}}function ct(){try{const t=C.execSync("npm root -g",{timeout:5e3}).toString().trim(),e=u.join(t,"jiva-core","package.json");if(d.existsSync(e)){const s=JSON.parse(d.readFileSync(e,"utf-8")).main??"dist/index.js";return u.join(t,"jiva-core",s)}}catch{}const r=u.join(b.homedir(),".npm-global","lib","node_modules","jiva-core","dist","index.js");if(d.existsSync(r))return r;throw new Error("Could not find jiva-core. Please run: npm install -g jiva-core")}const lt=/^(\d{4}-\d{2}-\d{2}T[\d:.Z]+)\s+\[(INFO|WARN|ERROR)\]\s+\[(\w+)\]\s+(.+)$/;function Me(r){const t=lt.exec(r.trim());return t?{timestamp:t[1],level:t[2].toLowerCase(),tag:t[3],message:t[4]}:null}class ut extends xe.EventEmitter{constructor(){super(...arguments);x(this,"agent",null);x(this,"orchestrator",null);x(this,"workspace",null);x(this,"conversationManager",null);x(this,"mcpManager",null);x(this,"codeLogger",null);x(this,"ready",!1);x(this,"deepRun",!1);x(this,"maxIterations",50)}isReady(){return this.ready}getConversationId(){return this.conversationManager?this.conversationManager.currentConversationId??null:null}async initialize(e,n,s){var H,B;this.deepRun=(s==null?void 0:s.deepRun)??!1,this.maxIterations=(s==null?void 0:s.maxIterations)??50;const o=ct();console.log(`[CodeRunner] Loading jiva-core from: ${o}`);const a=await import(le.pathToFileURL(o).href),{configManager:i,ModelOrchestrator:c,WorkspaceManager:l,ConversationManager:p,CodeAgent:m,MCPServerManager:y,createKrutrimModel:w,createLocalProvider:S,logger:M}=a;this.codeLogger=M??null,i.validateConfig();const h=i.getReasoningModel(),j=w({endpoint:h.endpoint,apiKey:h.apiKey,model:h.defaultModel,type:"reasoning",useHarmonyFormat:h.useHarmonyFormat}),k=c;this.orchestrator=new k({reasoningModel:j});const{path:f}=pe((H=E())==null?void 0:H.userDirective),g=l;this.workspace=new g({workspaceDir:e,directivePath:f}),await this.workspace.initialize();const _=await S(),D=p;this.conversationManager=new D(_,this.orchestrator),this.mcpManager=null;const T=n&&n.length>0?n:null;if(T&&y){const ne=y,se=new ne,G=((B=E())==null?void 0:B.mcpServers)??{},V={};for(const L of T)G[L]&&(V[L]=G[L]);await se.initialize(V),this.mcpManager=se,console.log(`[CodeRunner] MCP servers loaded: ${T.join(", ")}`)}const te=m;this.agent=new te({orchestrator:this.orchestrator,workspace:this.workspace,conversationManager:this.conversationManager,maxIterations:this.maxIterations,...this.mcpManager&&T?{mcpManager:this.mcpManager,mcpServerNames:T}:{}}),this.ready=!0,console.log(`[CodeRunner] Initialized (maxIterations=${this.maxIterations}, deepRun=${this.deepRun})`)}makeCompleter(){const e=this.orchestrator;return async(n,s)=>{if(typeof e.chat!="function")return null;try{const a=await e.chat.bind(e)({messages:[{role:"system",content:n},{role:"user",content:s}],reasoningEffort:"low"});return(a==null?void 0:a.content)??null}catch(o){return console.warn("[CodeRunner] makeCompleter: chat() failed:",o),null}}}async chat(e,n,s){if((s==null?void 0:s.maxIterations)!==void 0&&s.maxIterations!==this.maxIterations){this.maxIterations=s.maxIterations;try{this.agent.maxIterations=this.maxIterations}catch{}}return(s==null?void 0:s.deepRun)!==!1&&((s==null?void 0:s.deepRun)??this.deepRun)?await Ce(e,this.makeCompleter(),(i,c)=>this.runChatWithIterations(i,n,c==null?void 0:c.maxIterations),i=>n(i),this.maxIterations,(s==null?void 0:s.conversationHistory)||void 0):this.runChat(e,n)}async runChatWithIterations(e,n,s){if(s!==void 0&&s!==this.maxIterations){this.maxIterations=s;try{this.agent.maxIterations=this.maxIterations}catch{}}return this.runChat(e,n)}hookLogger(e){const n=this.codeLogger,s=(a,i,c)=>{const l=a.toLowerCase();e({timestamp:new Date().toISOString(),level:l==="warn"||l==="error"?l:"info",tag:i,message:c})};if(n&&typeof n.on=="function"){const a=(...i)=>{if(i.length>=3&&typeof i[0]=="string")s(i[0],i[1]??"CodeAgent",i[2]);else if(i.length>=2&&typeof i[0]=="string")s("info","CodeAgent",i[1]);else if(i.length>=1&&typeof i[0]=="object"){const c=i[0];s(String(c.level??"info"),String(c.tag??c.name??"CodeAgent"),String(c.message??c.msg??""))}};try{return n.on("log",a),()=>{typeof n.off=="function"?n.off("log",a):typeof n.removeListener=="function"&&n.removeListener("log",a)}}catch{}}if(n)for(const a of["addTransport","addHandler","addSink"]){if(typeof n[a]!="function")continue;const i=a.replace("add","remove"),c={write:l=>{s(String(l.level??"info"),String(l.tag??l.name??"CodeAgent"),String(l.message??l.msg??""))},log:l=>{s(String(l.level??"info"),String(l.tag??l.name??"CodeAgent"),String(l.message??l.msg??""))}};try{return n[a](c),()=>{if(typeof n[i]=="function")try{n[i](c)}catch{}}}catch{}}const o=process.stdout.write.bind(process.stdout);return process.stdout.write=(a,...i)=>{const c=typeof a=="string"?a:Buffer.from(a).toString();for(const l of c.split(`
110
+ `)){const p=Me(l);if(p){e(p);continue}const m=/(?:tool(?:\s+call)?|calling|executing)[:\s]+([^\s(]+)/i.exec(l.trim());m&&e({timestamp:new Date().toISOString(),level:"info",tag:"CodeAgent",message:`Tool: ${m[1]}`})}return o(a,...i)},()=>{process.stdout.write=o}}async runChat(e,n){var a;if(!this.agent)throw new Error("CodeRunner not initialized");const s=this.agent,o=this.hookLogger(n);try{const i=await s.chat(e);if((a=i.toolsUsed)!=null&&a.length){const c=new Set;for(const l of i.toolsUsed)c.has(l)||(c.add(l),n({timestamp:new Date().toISOString(),level:"info",tag:"CodeAgent",message:`Tool: ${l}`}))}return{content:i.content,toolsUsed:i.toolsUsed??[],iterations:i.iterations??0}}finally{o()}}stop(){this.agent&&this.agent.stop()}async cleanup(){if(this.agent)try{await this.agent.cleanup()}catch(e){console.warn("[CodeRunner] Cleanup error:",e)}if(this.mcpManager)try{await this.mcpManager.cleanup()}catch{}this.agent=null,this.orchestrator=null,this.workspace=null,this.conversationManager=null,this.mcpManager=null,this.ready=!1}}function dt(){try{const t=C.execSync("npm root -g",{timeout:5e3}).toString().trim(),e=u.join(t,"jiva-core","package.json");if(d.existsSync(e)){const s=JSON.parse(d.readFileSync(e,"utf-8")).main??"dist/index.js";return u.join(t,"jiva-core",s)}}catch{}if(process.platform==="win32"){const t=[u.join(process.env.APPDATA??"","npm","node_modules","jiva-core","dist","index.js"),u.join(process.env.LOCALAPPDATA??"","npm","node_modules","jiva-core","dist","index.js"),"C:\\Program Files\\nodejs\\node_modules\\jiva-core\\dist\\index.js"];for(const e of t)if(d.existsSync(e))return e}const r="/Users/abidev/.npm-global/lib/node_modules/jiva-core/dist/index.js";if(d.existsSync(r))return r;throw new Error("Could not find jiva-core. Please ensure it is installed globally: npm install -g jiva-core")}class pt extends xe.EventEmitter{constructor(){super(...arguments);x(this,"status","stopped");x(this,"agent",null);x(this,"orchestrator",null);x(this,"mcpManager",null);x(this,"workspace",null);x(this,"conversationManager",null);x(this,"personaManager",null);x(this,"jivaLogger",null);x(this,"currentPersona",null);x(this,"currentConversationId",null);x(this,"maxIterations",50)}getStatus(){return this.status}getCurrentConversationId(){return this.currentConversationId}async initialize(e){var n,s;this.setStatus("initializing");try{const o=dt();console.log(`[JivaRunner] Loading jiva-core from: ${o}`);const a=await import(le.pathToFileURL(o).href),{MCPServerManager:i,WorkspaceManager:c,ConversationManager:l,ModelOrchestrator:p,DualAgent:m,createKrutrimModel:y,LogLevel:w,logger:S,createLocalProvider:M}=a,h=E();if(!((s=(n=h==null?void 0:h.models)==null?void 0:n.reasoning)!=null&&s.apiKey))throw new Error("Jivam is not configured. Add your API key in Settings → Models.");const v=h.models.reasoning,j=h.models.multimodal,k=y,f=v.defaultModel??v.model??"",g=k({endpoint:v.endpoint,apiKey:v.apiKey,model:f,type:"reasoning",useHarmonyFormat:v.useHarmonyFormat,...v.reasoningEffortStrategy?{reasoningEffortStrategy:v.reasoningEffortStrategy}:{},...v.defaultMaxTokens?{defaultMaxTokens:v.defaultMaxTokens}:{}});let A;if(j!=null&&j.apiKey)try{const Y=j.defaultModel??"";A=k({endpoint:j.endpoint,apiKey:j.apiKey,model:Y,type:"multimodal"})}catch{console.warn("[JivaRunner] Failed to create multimodal model, continuing without vision")}const _=p;this.orchestrator=new _({reasoningModel:g,multimodalModel:A});const D=h.mcpServers??{},T=b.platform()==="win32"?"C:\\Users":"/Users";D.filesystem||(D.filesystem={command:"npx",args:["-y","@modelcontextprotocol/server-filesystem",T],enabled:!0});const te=i;this.mcpManager=new te,await this.mcpManager.initialize(D);const{path:H}=pe(h.userDirective),B=process.cwd(),ne=c;this.workspace=new ne({workspaceDir:B,directivePath:H}),await this.workspace.initialize();const G=await M(),V=l;this.conversationManager=new V(G,this.orchestrator);const L=u.dirname(o),_e=u.dirname(L),Te=u.join(_e,"dist","personas","persona-manager.js"),{PersonaManager:Oe}=await import(le.pathToFileURL(Te).href);this.personaManager=new Oe,await this.personaManager.initialize(e??void 0);const Re=this.personaManager.getPersonaMCPServers();for(const[Y,Je]of Object.entries(Re))try{await this.mcpManager.addServer(Y,Je)}catch(Ue){console.warn(`[JivaRunner] Failed to add persona MCP server '${Y}':`,Ue)}const Fe=m;this.agent=new Fe({orchestrator:this.orchestrator,mcpManager:this.mcpManager,workspace:this.workspace,conversationManager:this.conversationManager,personaManager:this.personaManager,maxSubtasks:20,maxIterations:this.maxIterations,autoSave:!0,condensingThreshold:30}),this.jivaLogger=S,this.currentPersona=e??null,this.setStatus("ready"),console.log("[JivaRunner] Initialized successfully")}catch(o){const a=o instanceof Error?o.message:String(o);throw console.error("[JivaRunner] Initialization failed:",a),this.setStatus("error",a),o}}makeCompleter(){const e=this.orchestrator;return async(n,s)=>{if(typeof e.chat!="function")return null;try{const a=await e.chat.bind(e)({messages:[{role:"system",content:n},{role:"user",content:s}],reasoningEffort:"low"});return(a==null?void 0:a.content)??null}catch(o){return console.warn("[JivaRunner] makeCompleter: chat() failed:",o),null}}}hookLogger(e){const n=this.jivaLogger;if(!n)return()=>{};const s=(a,i,c)=>{const l=a.toLowerCase();e({timestamp:new Date().toISOString(),level:l==="warn"||l==="error"?l:"info",tag:i,message:c})};if(typeof n.on=="function"){const a=(...i)=>{if(i.length>=3&&typeof i[0]=="string")s(i[0],i[1]??"jiva",i[2]);else if(i.length>=2&&typeof i[0]=="string")s("info","jiva",i[1]);else if(i.length>=1&&typeof i[0]=="object"){const c=i[0];s(String(c.level??"info"),String(c.tag??c.name??"jiva"),String(c.message??c.msg??""))}};try{return n.on("log",a),()=>{typeof n.off=="function"?n.off("log",a):typeof n.removeListener=="function"&&n.removeListener("log",a)}}catch{}}for(const a of["addTransport","addHandler","addSink"]){if(typeof n[a]!="function")continue;const i=a.replace("add","remove"),c={write:l=>{s(String(l.level??"info"),String(l.tag??l.name??"jiva"),String(l.message??l.msg??""))},log:l=>{s(String(l.level??"info"),String(l.tag??l.name??"jiva"),String(l.message??l.msg??""))}};try{return n[a](c),()=>{if(typeof n[i]=="function")try{n[i](c)}catch{}}}catch{}}const o=process.stdout.write.bind(process.stdout);return process.stdout.write=(a,...i)=>{const c=typeof a=="string"?a:Buffer.from(a).toString();for(const l of c.split(`
111
+ `)){const p=Me(l);if(p){e(p);continue}const m=/(?:tool(?:\s+call)?|calling|executing)[:\s]+([^\s(]+)/i.exec(l.trim());m&&e({timestamp:new Date().toISOString(),level:"info",tag:"jiva",message:`Tool: ${m[1]}`})}return o(a,...i)},()=>{process.stdout.write=o}}async runChat(e,n,s){var l,p,m;const o=s?this.hookLogger(s):null,a=this.agent;let i;try{i=await a.chat(e)}finally{o==null||o()}if(s&&((l=i.toolsUsed)!=null&&l.length))for(const y of i.toolsUsed)s({timestamp:new Date().toISOString(),level:"info",tag:"jiva",message:`Tool: ${y}`});let c=null;try{c=((m=(p=this.conversationManager).getCurrentConversationId)==null?void 0:m.call(p))??null}catch{}if(!c)try{c=await this.agent.saveConversation()}catch{}return c&&(this.currentConversationId=c),{content:i.content,iterations:i.iterations,toolsUsed:i.toolsUsed??[],plan:i.plan?{subtasks:i.plan.subtasks??[],reasoning:i.plan.reasoning}:null,durationMs:Date.now()-n,conversationId:this.currentConversationId??void 0}}async chat(e,n,s,o){var l;if(!this.agent)throw new Error("JivaRunner not initialized. Call initialize() first.");if(this.status==="busy")throw new Error("Agent is already processing a request.");if((s==null?void 0:s.maxIterations)!==void 0&&s.maxIterations!==this.maxIterations){this.maxIterations=s.maxIterations;try{this.agent.maxIterations=this.maxIterations}catch{}}this.setStatus("busy");const a=Date.now();n("planning");const i=setTimeout(()=>n("executing"),2e3),c=setTimeout(()=>n("synthesizing"),3e4);try{let p;if((s==null?void 0:s.deepRun)!==!1){const m=Object.keys(((l=E())==null?void 0:l.mcpServers)??{});p=await Ce(e,this.makeCompleter(),(y,w)=>{if((w==null?void 0:w.maxIterations)!==void 0&&w.maxIterations!==this.maxIterations){this.maxIterations=w.maxIterations;try{this.agent.maxIterations=this.maxIterations}catch{}}return this.runChat(y,a,o)},y=>o==null?void 0:o(y),this.maxIterations,(s==null?void 0:s.conversationHistory)||void 0,m)}else p=await this.runChat(e,a,o);return clearTimeout(i),clearTimeout(c),n("done"),this.setStatus("ready"),p}catch(p){throw clearTimeout(i),clearTimeout(c),this.setStatus("ready"),p}}async loadConversation(e){if(!this.agent)throw new Error("JivaRunner not initialized. Call initialize() first.");await this.agent.loadConversation(e),this.currentConversationId=e,console.log(`[JivaRunner] Loaded conversation: ${e}`)}async switchPersona(e){this.agent&&await this.cleanup(),await this.initialize(e)}resetConversation(){this.agent&&this.agent.resetConversation(),this.currentConversationId=null}getMCPTools(){var e,n;if(!this.mcpManager)return{};try{const s=((n=(e=this.mcpManager).getAllTools)==null?void 0:n.call(e))??[],o={};for(const a of s){const i=a.name.split("__"),c=i.length>1?i[0]:"unknown",l=i.length>1?i.slice(1).join("__"):a.name;o[c]||(o[c]=[]),o[c].push({name:l,description:a.description??""})}return o}catch{return{}}}async addMCPServer(e,n){if(!this.mcpManager)throw new Error("MCP manager not initialized");await this.mcpManager.addServer(e,n)}async removeMCPServer(e){if(!this.mcpManager)throw new Error("MCP manager not initialized");const n=this.mcpManager;n.removeServer?await n.removeServer(e):n.disableServer&&await n.disableServer(e)}getMCPServerStatus(){var e,n;if(!this.mcpManager)return[];try{return(((n=(e=this.mcpManager).getServerStatus)==null?void 0:n.call(e))??[]).map(o=>({...o,error:o.error??o.lastError}))}catch{return[]}}async reconnectMCPServer(e){var c,l,p;if(!this.mcpManager)throw new Error("MCP manager not initialized");const n=this.mcpManager;if(typeof n.reconnectServer=="function"){await n.reconnectServer(e);return}if(!this.getMCPServerStatus().find(m=>m.name===e))throw new Error(`MCP server "${e}" not found`);const a=((p=(l=(c=this.mcpManager).getServerStatus)==null?void 0:l.call(c))==null?void 0:p.find(m=>m.name===e))??{};await this.removeMCPServer(e);const i=a.url!=null?{type:"http",url:a.url,env:a.env,enabled:!0}:{type:"stdio",command:a.command,args:a.args,env:a.env,enabled:!0};await this.addMCPServer(e,i)}async toggleMCPServer(e,n){if(!this.mcpManager)throw new Error("MCP manager not initialized");const s=this.mcpManager;n&&s.enableServer?await s.enableServer(e):!n&&s.disableServer&&await s.disableServer(e)}async describeImage(e){var a;if(!this.orchestrator)throw new Error("JivaRunner not initialized. Call initialize() first.");const n=E();if(!((a=n==null?void 0:n.models)!=null&&a.multimodal))throw new Error("No multimodal (vision) model is configured. Enable it in Settings → Models.");return(await this.orchestrator.chat({messages:[{role:"user",content:[{type:"image_url",image_url:{url:e}},{type:"text",text:"Describe this image in detail, including all visible content, text, charts, diagrams, and any notable elements."}]}]})).content}async cleanup(){try{this.agent&&(await this.agent.cleanup(),this.agent=null),this.mcpManager&&(await this.mcpManager.cleanup(),this.mcpManager=null)}catch(e){console.warn("[JivaRunner] Cleanup error:",e)}this.orchestrator=null,this.workspace=null,this.conversationManager=null,this.personaManager=null,this.currentConversationId=null,this.setStatus("stopped")}stop(){this.agent&&this.agent.stop()}setStatus(e,n){this.status=e,this.emit("status-changed",e,{error:n})}}const X="https://jiva-hdjcuspt2a-uc.a.run.app";class mt{constructor(){x(this,"userId",null);x(this,"sessionId",null);x(this,"_active",!1);x(this,"_abortController",null);x(this,"_readyPromise",null);x(this,"_readyResolve",null);x(this,"_readyReject",null)}startInit(){this._active||this._readyPromise||(this._readyPromise=new Promise((t,e)=>{this._readyResolve=t,this._readyReject=e}))}configure(t,e){var n;this.userId=t,this.sessionId=e,this._active=!0,(n=this._readyResolve)==null||n.call(this),this._readyResolve=null,this._readyReject=null}waitUntilReady(t){return this._active?Promise.resolve():this._readyPromise?Promise.race([this._readyPromise,new Promise((e,n)=>setTimeout(()=>n(new Error(`Cloud runner not ready after ${t}ms`)),t))]):Promise.reject(new Error("Cloud runner init not started"))}isActive(){return this._active}isInitializing(){return!this._active&&this._readyPromise!==null}deactivate(){var t;this._active=!1,this.userId=null,this.sessionId=null,(t=this._readyReject)==null||t.call(this,new Error("Cloud session deactivated")),this._readyPromise=null,this._readyResolve=null,this._readyReject=null}stop(){var t;(t=this._abortController)==null||t.abort()}get headers(){return{"Content-Type":"application/json","x-tenant-id":this.userId??"dev-tenant","x-session-id":this.sessionId??"default-session"}}async chat(t,e,n,s){if(!this._active)throw new Error("CloudRunner not configured");const o=Date.now();e("planning"),this._abortController=new AbortController;const{signal:a}=this._abortController;try{return{...await this._streamChat(t,e,s,a),durationMs:Date.now()-o}}catch(i){return i.name==="AbortError"?{content:"",iterations:0,toolsUsed:[],plan:null,durationMs:Date.now()-o}:(console.warn("[CloudRunner] SSE failed, falling back to non-streaming:",i),{...await this._nonStreamChat(t,e,a),durationMs:Date.now()-o})}finally{this._abortController=null,e("done")}}async _streamChat(t,e,n,s){const o=await fetch(`${X}/api/chat/stream`,{method:"POST",headers:{...this.headers,Accept:"text/event-stream"},body:JSON.stringify({message:t}),signal:s});if(!o.ok||!o.body)throw new Error(`SSE request failed: ${o.status}`);const a=o.body.getReader(),i=new TextDecoder;let c="",l="",p=0;const m=[];let y=null,w=null;e:for(;;){const{done:S,value:M}=await a.read();if(S)break;c+=i.decode(M,{stream:!0});const h=c.split(`
112
+ `);c=h.pop()??"";for(const v of h){if(v.startsWith("event: ")){w=v.slice(7).trim();continue}if(!v.startsWith("data: "))continue;const j=v.slice(6).trim();if(!j||j==="[DONE]")continue;let k;try{k=JSON.parse(j)}catch{continue}const f=w??k.type;if(w=null,f==="status"){const g=k.message;g&&(e("executing"),n==null||n({timestamp:new Date().toISOString(),level:"info",tag:"cloud",message:`Tool: ${g}`}))}else if(f==="response")l=k.content??k.response??"",p=k.iterations??0,Array.isArray(k.toolsUsed)&&m.push(...k.toolsUsed),k.plan&&(y=k.plan);else{if(f==="error")throw new Error(k.message??"Stream error");if(f==="done")break e}}}return{content:l,iterations:p,toolsUsed:m,plan:y}}async _nonStreamChat(t,e,n){e("executing");const s=await fetch(`${X}/api/chat`,{method:"POST",headers:this.headers,body:JSON.stringify({message:t}),signal:n});if(!s.ok){const a=await s.text();throw new Error(`Cloud chat failed (${s.status}): ${a}`)}const o=await s.json();return{content:o.response??"",iterations:o.iterations??0,toolsUsed:Array.isArray(o.toolsUsed)?o.toolsUsed:[],plan:o.plan??null}}async resetConversation(){if(this._active)try{await fetch(`${X}/api/chat/history`,{method:"DELETE",headers:this.headers})}catch(t){console.error("[CloudRunner] resetConversation failed:",t)}}async stopMessage(){try{await fetch(`${X}/api/chat/stop`,{method:"POST",headers:this.headers})}catch{}this.stop()}}const $e=I.Router();$e.get("/check",(r,t)=>{var m;let e=!1,n;try{C.execSync("npm --version",{timeout:3e3}),e=!0;try{n=C.execSync("node --version",{timeout:3e3}).toString().trim().replace(/^v/,"")}catch{}}catch{}let s=!1,o;if(e){const y=[];try{const w=C.execSync("npm root -g",{timeout:5e3}).toString().trim();y.push(u.join(w,"jiva-core","package.json"))}catch{}y.push(u.join(b.homedir(),".npm-global","lib","node_modules","jiva-core","package.json")),process.platform==="win32"&&(y.push(u.join(process.env.APPDATA??"","npm","node_modules","jiva-core","package.json")),y.push(u.join(process.env.LOCALAPPDATA??"","npm","node_modules","jiva-core","package.json")));for(const w of y)if(d.existsSync(w))try{o=JSON.parse(d.readFileSync(w,"utf-8")).version,s=!0;break}catch{}}const a=[N(),u.join(b.homedir(),".jiva","config.json")];let i=!1,c="";for(const y of a)if(d.existsSync(y))try{const w=JSON.parse(d.readFileSync(y,"utf-8")),S=((m=w==null?void 0:w.models)==null?void 0:m.reasoning)??{};if(((S==null?void 0:S.apiKey)??(w==null?void 0:w.apiKey)??"").length>0){i=!0,c=y;break}}catch{}let l=!1,p;try{const y=u.join(__dirname,"..","..","package.json");if(p=JSON.parse(d.readFileSync(y,"utf-8")).jivaCompatibleVersion,p&&o){const[S,M]=p.split(".").map(Number),[h,v]=o.split(".").map(Number);(S!==h||M!==v)&&(l=!0)}}catch{}t.json({nodejs:{ok:e,version:n},jivaCore:{ok:s,version:o},config:{ok:i,path:c||a[0]},platform:process.platform,jivaVersionMismatch:l,requiredJivaVersion:p})});const z=I.Router(),ht={sarvam:{endpoint:"https://api.sarvam.ai/v1/chat/completions",defaultModel:"sarvam-105b",useHarmonyFormat:!1,reasoningEffortStrategy:"api_param",defaultMaxTokens:8192,multimodal:null},krutrim:{endpoint:"https://cloud.olakrutrim.com/v1/chat/completions",defaultModel:"gpt-oss-120b",useHarmonyFormat:!0,reasoningEffortStrategy:"system_prompt",multimodal:{defaultModel:"Llama-4-Maverick-17B-128E-Instruct"}},groq:{endpoint:"https://api.groq.com/openai/v1/chat/completions",defaultModel:"openai/gpt-oss-120b",useHarmonyFormat:!1,reasoningEffortStrategy:"api_param",multimodal:{defaultModel:"meta-llama/llama-4-maverick-17b-128e-instruct"}},"openai-compatible":{endpoint:"",defaultModel:"",useHarmonyFormat:!1,reasoningEffortStrategy:"both",multimodal:null}};z.get("/",(r,t)=>{t.json(E())});z.post("/",(r,t)=>{const e=R(r.body);t.json(e)});z.get("/path",(r,t)=>{t.json(N())});z.post("/setup-provider",(r,t)=>{const{provider:e,apiKey:n,customEndpoint:s,customModel:o}=r.body;try{const a=ht[e];if(!a)return t.json({success:!1,error:`Unknown provider: ${e}`});const i=e==="openai-compatible"?s??"":a.endpoint,c=e==="openai-compatible"?o??"":a.defaultModel,p=E()??{models:{reasoning:null}};if(p.models={...p.models,reasoning:{name:"reasoning",type:"reasoning",provider:e,endpoint:i,apiKey:n,defaultModel:c,useHarmonyFormat:a.useHarmonyFormat,reasoningEffortStrategy:a.reasoningEffortStrategy,...a.defaultMaxTokens?{defaultMaxTokens:a.defaultMaxTokens}:{}},multimodal:a.multimodal?{name:"multimodal",type:"multimodal",endpoint:i,apiKey:n,defaultModel:a.multimodal.defaultModel}:void 0},!p.mcpServers){const y=process.platform==="win32"?"C:\\Users":`${b.homedir()}`;p.mcpServers={filesystem:{command:"npx",args:["-y","@modelcontextprotocol/server-filesystem",y],enabled:!0},"mcp-shell-server":{command:"npx",args:["-y","@mkusaka/mcp-shell-server"],enabled:!0}}}const m=R(p);return t.json({success:m,error:m?void 0:"Failed to write config"})}catch(a){return t.json({success:!1,error:a instanceof Error?a.message:String(a)})}});const me=I.Router();me.get("/",(r,t)=>{const e=u.join(b.homedir(),".jiva","conversations");try{if(!d.existsSync(e))return t.json([]);const n=d.readdirSync(e).filter(s=>s.endsWith(".json")).map(s=>{var i,c,l;const o=u.join(e,s),a=d.statSync(o);try{const p=JSON.parse(d.readFileSync(o,"utf-8"));let m=((i=p.metadata)==null?void 0:i.title)??p.summary??p.title??"";if(!m&&Array.isArray(p.messages)){const y=p.messages.find(w=>w.role==="user");if(y!=null&&y.content){const w=typeof y.content=="string"?y.content:Array.isArray(y.content)?y.content.filter(S=>S.type==="text").map(S=>S.text??"").join(""):"";m=w.slice(0,60).replace(/\n/g," "),w.length>60&&(m+="...")}}return{id:s.replace(".json",""),summary:m||"Untitled",messageCount:((c=p.messages)==null?void 0:c.length)??0,lastModified:a.mtimeMs,type:((l=p.metadata)==null?void 0:l.type)??"chat"}}catch{return null}}).filter(Boolean).sort((s,o)=>o.lastModified-s.lastModified);return t.json(n)}catch{return t.json([])}});me.get("/:id",(r,t)=>{const e=u.join(b.homedir(),".jiva","conversations",`${r.params.id}.json`);try{return d.existsSync(e)?t.json(JSON.parse(d.readFileSync(e,"utf-8"))):t.json(null)}catch{return t.json(null)}});const q=I.Router();q.get("/is-repo",(r,t)=>{const e=r.query.dir;try{C.execFileSync("git",["rev-parse","--is-inside-work-tree"],{cwd:e,timeout:3e3}),t.json(!0)}catch{t.json(!1)}});q.get("/status",(r,t)=>{const e=r.query.dir;try{const n=C.execFileSync("git",["status","--porcelain"],{cwd:e,timeout:5e3}).toString();t.json(n.split(`
113
+ `).filter(Boolean).map(s=>({status:s.slice(0,2).trim(),file:s.slice(3).trim()})))}catch{t.json([])}});q.get("/diff-file",(r,t)=>{const{dir:e,file:n,status:s}=r.query;try{if(s==="??"){const o=u.join(e,n);try{const i=d.readFileSync(o,"utf-8").split(`
114
+ `);return i[i.length-1]===""&&i.pop(),t.json(`--- /dev/null
115
+ +++ b/${n}
116
116
  @@ -0,0 +1,${i.length} @@
117
117
  ${i.map(c=>`+${c}`).join(`
118
- `)}`)}catch{return n.json(null)}}if(s==="A")try{const o=$.execFileSync("git",["diff","--cached","--",t],{cwd:e,timeout:5e3}).toString();if(o.trim())return n.json(o)}catch{}try{const o=$.execFileSync("git",["diff","HEAD","--",t],{cwd:e,timeout:5e3}).toString();if(o.trim())return n.json(o)}catch{}try{const o=$.execFileSync("git",["diff","--cached","--",t],{cwd:e,timeout:5e3}).toString();if(o.trim())return n.json(o)}catch{}try{const o=$.execFileSync("git",["diff","--",t],{cwd:e,timeout:5e3}).toString();if(o.trim())return n.json(o)}catch{}return n.json(null)}catch{return n.json(null)}});U.post("/init-repo",(r,n)=>{const{dir:e}=r.body;try{$.execFileSync("git",["init"],{cwd:e,timeout:1e4}),n.json({success:!0})}catch(t){n.json({success:!1,error:t instanceof Error?t.message:String(t)})}});U.get("/branch-info",(r,n)=>{const e=r.query.dir;try{const t=$.execFileSync("git",["rev-parse","--abbrev-ref","HEAD"],{cwd:e,timeout:3e3}).toString().trim();let s=0,o=0;try{const a=$.execFileSync("git",["rev-parse","--abbrev-ref","--symbolic-full-name","@{u}"],{cwd:e,timeout:3e3}).toString().trim();if(a){const i=$.execFileSync("git",["rev-list","--left-right","--count",`${a}...HEAD`],{cwd:e,timeout:3e3}).toString().trim().split(" ");o=parseInt(i[0])||0,s=parseInt(i[1])||0}}catch{}n.json({branch:t,ahead:s,behind:o})}catch{n.json(null)}});const ye=E.Router();ye.get("/",(r,n)=>{const e=P();n.json((e==null?void 0:e.userDirective)??"")});ye.post("/",(r,n)=>{const{content:e}=r.body,t=P()??{models:{reasoning:null}};R({...t,userDirective:e}),he(e||void 0),n.json({success:!0})});const _=E.Router();_.get("/dir",(r,n)=>{const e=P();n.json((e==null?void 0:e.workspaceDir)??S.homedir())});_.post("/dir",(r,n)=>{const{dir:e}=r.body;try{const t=P()??{models:{reasoning:null}};R({...t,workspaceDir:e}),n.json({success:!0})}catch(t){n.json({success:!1,error:t instanceof Error?t.message:String(t)})}});_.post("/pick-dir",async(r,n)=>{try{let e=null;if(process.platform==="darwin"){const t=$.execSync(`osascript -e 'POSIX path of (choose folder with prompt "Select Workspace Directory")'`,{timeout:6e4}).toString().trim();t&&(e=t.replace(/\/$/,""))}else if(process.platform==="win32"){const t=['[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null',"$f = New-Object System.Windows.Forms.FolderBrowserDialog",'$f.Description = "Select Workspace Directory"','if ($f.ShowDialog() -eq "OK") { $f.SelectedPath }'].join("; "),s=$.execSync(`powershell -Command "${t}"`,{timeout:6e4}).toString().trim();s&&(e=s)}else try{const t=$.execSync('zenity --file-selection --directory --title="Select Workspace Directory"',{timeout:6e4}).toString().trim();t&&(e=t)}catch{try{const t=$.execSync('kdialog --getexistingdirectory "Select Workspace Directory"',{timeout:6e4}).toString().trim();t&&(e=t)}catch{}}n.json(e)}catch{n.json(null)}});_.get("/files",(r,n)=>{const e=r.query.path;try{const t=S.homedir(),s=m.resolve(e),o=m.resolve(t);if(!s.startsWith(o)&&s!==o)return n.json([]);if(!u.existsSync(s))return n.json([]);const a=u.readdirSync(s,{withFileTypes:!0});return n.json(a.filter(i=>!i.name.startsWith(".")).map(i=>{const c=m.join(s,i.name),l=u.statSync(c);return{name:i.name,path:c,isDirectory:i.isDirectory(),size:l.size,modified:l.mtimeMs}}))}catch{return n.json([])}});_.get("/file",(r,n)=>{const e=r.query.path;try{const t=S.homedir(),s=m.resolve(e);return!s.startsWith(m.resolve(t))||!u.existsSync(s)?n.json(null):u.statSync(s).size>512*1024?n.json("[File too large to preview — open in an external editor]"):n.json(u.readFileSync(s,"utf-8"))}catch{return n.json(null)}});_.post("/open-external",(r,n)=>{const{filePath:e}=r.body;try{const t=process.platform==="darwin"?"open":process.platform==="win32"?"explorer":"xdg-open";$.execSync(`${t} "${e}"`,{timeout:5e3})}catch{}n.json({})});function kt(r,n){const e=E.Router();return e.post("/start",async(t,s)=>{try{(r.getStatus()==="stopped"||r.getStatus()==="error")&&await r.initialize(),s.json({success:!0,status:r.getStatus()})}catch(o){s.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),e.post("/stop",async(t,s)=>{try{await r.cleanup(),s.json({success:!0})}catch(o){s.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),e.post("/restart",async(t,s)=>{try{await r.cleanup(),await r.initialize(),s.json({success:!0,status:r.getStatus()})}catch(o){s.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),e.get("/status",(t,s)=>{const o=r.getStatus();s.json({status:o==="ready"||o==="busy"?"running":o,port:0})}),e.post("/send-message",async(t,s)=>{const{prompt:o,opts:a,isCloud:i}=t.body;try{if(i){n.isActive()||await n.waitUntilReady(3e4);const l=await n.chat(o,d=>{O("jiva:phase-update",{phase:d})},a,d=>{O("jiva:jiva-log",{event:d})});return s.json({success:!0,result:l,conversationId:l.conversationId})}(r.getStatus()==="stopped"||r.getStatus()==="error")&&await r.initialize();const c=await r.chat(o,l=>{O("jiva:phase-update",{phase:l})},a,l=>{O("jiva:jiva-log",{event:l})});return s.json({success:!0,result:c,conversationId:c.conversationId})}catch(c){return s.json({success:!1,error:c instanceof Error?c.message:String(c)})}}),e.post("/stop-message",(t,s)=>{r.stop(),s.json({success:!0})}),e.post("/reset-conversation",(t,s)=>{r.resetConversation(),s.json({success:!0})}),e.post("/load-conversation",async(t,s)=>{const{id:o}=t.body;try{(r.getStatus()==="stopped"||r.getStatus()==="error")&&await r.initialize(),await r.loadConversation(o),s.json({success:!0})}catch(a){s.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),r.on("status-changed",(t,s)=>{O("jiva:server:status-changed",{status:t==="ready"||t==="busy"?"running":t,data:s})}),e}const de=m.join(S.homedir(),".jiva","personas");function bt(r,n){return r==="chat"||n.includes("chat")?"MessageSquare":r==="research"||n.includes("research")?"Search":r==="developer"||r==="code-reviewer"||n.includes("code")?"Code2":r==="engineering-manager"||n.includes("management")?"Layers":r==="tester"||n.includes("testing")?"FlaskConical":r==="data-analyst"||n.includes("data")?"BarChart3":"Bot"}function jt(){const r=[];if(!u.existsSync(de))return r;try{const n=u.readdirSync(de,{withFileTypes:!0});for(const e of n){if(!e.isDirectory()||e.name==="skills")continue;const t=m.join(de,e.name),s=m.join(t,".jiva-plugin","plugin.json");let o={};if(u.existsSync(s))try{const l=u.readFileSync(s,"utf-8");o=JSON.parse(l)}catch{}const a=e.name,i=o.tags??[],c=["chat","research"];r.push({name:a,displayName:(o.name??a).replace(/-/g," ").replace(/\b\w/g,l=>l.toUpperCase()),description:o.description??`${a} persona`,tags:i,icon:bt(a,i),isBuiltIn:c.includes(a),dirPath:t})}}catch(n){console.error("[PersonaManager] Failed to list personas:",n)}return r.sort((n,e)=>n.isBuiltIn&&!e.isBuiltIn?-1:!n.isBuiltIn&&e.isBuiltIn?1:n.name.localeCompare(e.name))}function xt(r){const{execSync:n}=require("child_process");try{return n(`jiva persona activate ${r}`,{timeout:1e4,stdio:"ignore"}),!0}catch{const e=m.join(S.homedir(),".jiva","active-persona.txt");try{return u.writeFileSync(e,r,"utf-8"),!0}catch{return!1}}}function Ct(){try{const r=rt();if(u.existsSync(r)){const e=JSON.parse(u.readFileSync(r,"utf-8"));if(e.activePersona)return e.activePersona}const n=m.join(S.homedir(),".jiva","active-persona.txt");if(u.existsSync(n))return u.readFileSync(n,"utf-8").trim()}catch{}return null}function $t(r){const n=E.Router();return n.get("/",(e,t)=>{t.json(jt())}),n.post("/activate",async(e,t)=>{const{name:s}=e.body,o=xt(s);if(o)try{await r.switchPersona(s)}catch(a){console.error("[Personas] Failed to switch persona:",a)}t.json({success:o})}),n.get("/active",(e,t)=>{t.json(Ct())}),n}function Mt(r){const n=E.Router();return n.get("/status",(e,t)=>{try{const s=r.getMCPServerStatus(),o=P(),a=(o==null?void 0:o.mcpServers)??{},i=new Map(s.map(l=>[l.name,l])),c=Object.entries(a).map(([l,d])=>{const p=i.get(l);return{name:l,enabled:d.enabled??!0,connected:(p==null?void 0:p.connected)??!1,toolCount:(p==null?void 0:p.toolCount)??0,command:d.command??"",args:d.args??[],env:d.env??{},url:d.url,type:d.command?"stdio":"http",error:p==null?void 0:p.error}});for(const l of s)a[l.name]||c.push({name:l.name,enabled:l.enabled,connected:l.connected,toolCount:l.toolCount,command:"",args:[],env:{},url:void 0,type:"stdio",error:void 0});t.json(c)}catch{t.json([])}}),n.get("/tools",(e,t)=>{try{t.json(r.getMCPTools())}catch{t.json({})}}),n.post("/add",async(e,t)=>{const{name:s,config:o}=e.body;try{const a=P();if(!a)return t.json({success:!1,error:"Config not found"});const i={enabled:o.enabled??!0};return o.type==="stdio"?(i.command=o.command??"",i.args=o.args??[],o.env&&Object.keys(o.env).length>0&&(i.env=o.env)):(i.url=o.url??"",o.env&&Object.keys(o.env).length>0&&(i.env=o.env)),a.mcpServers||(a.mcpServers={}),a.mcpServers[s]=i,R(a),(r.getStatus()==="ready"||r.getStatus()==="busy")&&await r.addMCPServer(s,i),t.json({success:!0})}catch(a){return t.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),n.post("/remove",async(e,t)=>{const{name:s}=e.body;try{const o=P();o!=null&&o.mcpServers&&(delete o.mcpServers[s],R(o)),(r.getStatus()==="ready"||r.getStatus()==="busy")&&await r.removeMCPServer(s),t.json({success:!0})}catch(o){t.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),n.post("/toggle",async(e,t)=>{var a;const{name:s,enabled:o}=e.body;try{const i=P();(a=i==null?void 0:i.mcpServers)!=null&&a[s]&&(i.mcpServers[s].enabled=o,R(i)),(r.getStatus()==="ready"||r.getStatus()==="busy")&&await r.toggleMCPServer(s,o),t.json({success:!0})}catch(i){t.json({success:!1,error:i instanceof Error?i.message:String(i)})}}),n.post("/reconnect",async(e,t)=>{const{name:s}=e.body;try{await r.reconnectMCPServer(s),t.json({success:!0})}catch(o){t.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),n}const se=m.join(S.homedir(),".jiva","jivam-mcp-selections.json");function je(){try{if(u.existsSync(se))return JSON.parse(u.readFileSync(se,"utf-8"))}catch{}return{}}function At(r){const n=E.Router();return n.post("/send-message",async(e,t)=>{const{prompt:s,opts:o}=e.body;try{if(!r.isReady()){const i=P(),c=(i==null?void 0:i.workspaceDir)??S.homedir();await r.initialize(c)}const a=await r.chat(s,i=>{O("jiva:code-log",{event:i})},o);t.json({success:!0,...a})}catch(a){t.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),n.post("/stop-message",(e,t)=>{r.stop(),t.json({success:!0})}),n.post("/reset-session",async(e,t)=>{try{await r.cleanup(),t.json({success:!0})}catch(s){t.json({success:!1,error:s instanceof Error?s.message:String(s)})}}),n.post("/init",async(e,t)=>{const{dir:s,mcpServers:o,opts:a}=e.body;try{await r.initialize(s,o,a),t.json({success:!0})}catch(i){t.json({success:!1,error:i instanceof Error?i.message:String(i)})}}),n.get("/mcp-for-code",(e,t)=>{try{const s=P(),o=(s==null?void 0:s.mcpServers)??{};t.json(Object.entries(o).map(([a,i])=>({name:a,enabled:i.enabled??!0,codeMode:i.codeMode===!0,command:i.command??"",url:i.url})))}catch{t.json([])}}),n.get("/conversation-id",(e,t)=>{t.json(r.getConversationId())}),n.get("/mcp-selection/:convId",(e,t)=>{t.json(je()[e.params.convId]??[])}),n.post("/mcp-selection",(e,t)=>{const{convId:s,servers:o}=e.body;try{const a=je();a[s]=o,u.mkdirSync(m.dirname(se),{recursive:!0}),u.writeFileSync(se,JSON.stringify(a,null,2)),t.json({success:!0})}catch(a){t.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),n}const It=new Set(["txt","md","markdown","rst","log","js","jsx","ts","tsx","mjs","cjs","py","rb","go","rs","java","kt","swift","c","cpp","cc","h","hpp","cs","css","scss","sass","less","html","htm","xml","svg","xhtml","json","jsonc","yaml","yml","toml","ini","cfg","conf","sh","bash","zsh","fish","ps1","bat","cmd","sql","graphql","gql","proto","env","editorconfig","gitignore","gitattributes","dockerfile","makefile","cmake","gradle","r","jl","scala","clj","ex","exs","erl","hs","lua","pl","vue","svelte","astro","lock","mod","sum"]),Ee={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",bmp:"image/bmp"},Pt={js:"javascript",jsx:"jsx",ts:"typescript",tsx:"tsx",py:"python",rb:"ruby",go:"go",rs:"rust",java:"java",kt:"kotlin",swift:"swift",cs:"csharp",c:"c",cpp:"cpp",h:"c",hpp:"cpp",css:"css",scss:"scss",sass:"sass",less:"less",html:"html",htm:"html",xml:"xml",svg:"xml",json:"json",jsonc:"json",yaml:"yaml",yml:"yaml",toml:"toml",sh:"bash",bash:"bash",zsh:"bash",fish:"fish",ps1:"powershell",sql:"sql",graphql:"graphql",gql:"graphql",proto:"protobuf",md:"markdown",markdown:"markdown",rst:"rst",r:"r",jl:"julia",scala:"scala",lua:"lua",vue:"vue",svelte:"svelte"};function Et(r){const n=r.toLowerCase().replace(/^\./,"");return It.has(n)?"text":n in Ee?"image":n==="pdf"?"pdf":n==="docx"?"docx":"unsupported"}function xe(r){const n=m.basename(r),e=m.extname(r).toLowerCase().replace(/^\./,""),t=Et(e);try{switch(t){case"text":return Dt(r,n,e);case"pdf":return Tt(r,n);case"docx":return Rt(r,n);case"image":return Jt(r,n,e);default:return{name:n,category:"unsupported",markdown:"",error:`File type .${e} is not supported`}}}catch(s){return{name:n,category:t,markdown:"",error:s instanceof Error?s.message:"Failed to read file"}}}function Dt(r,n,e){if(u.statSync(r).size>2*1024*1024)return{name:n,category:"text",markdown:"",error:"File is too large (max 2 MB for text files)"};const s=u.readFileSync(r,"utf-8"),a=`\`\`\`${Pt[e]??e}
118
+ `)}`)}catch{return t.json(null)}}if(s==="A")try{const o=C.execFileSync("git",["diff","--cached","--",n],{cwd:e,timeout:5e3}).toString();if(o.trim())return t.json(o)}catch{}try{const o=C.execFileSync("git",["diff","HEAD","--",n],{cwd:e,timeout:5e3}).toString();if(o.trim())return t.json(o)}catch{}try{const o=C.execFileSync("git",["diff","--cached","--",n],{cwd:e,timeout:5e3}).toString();if(o.trim())return t.json(o)}catch{}try{const o=C.execFileSync("git",["diff","--",n],{cwd:e,timeout:5e3}).toString();if(o.trim())return t.json(o)}catch{}return t.json(null)}catch{return t.json(null)}});q.post("/init-repo",(r,t)=>{const{dir:e}=r.body;try{C.execFileSync("git",["init"],{cwd:e,timeout:1e4}),t.json({success:!0})}catch(n){t.json({success:!1,error:n instanceof Error?n.message:String(n)})}});q.get("/branch-info",(r,t)=>{const e=r.query.dir;try{const n=C.execFileSync("git",["rev-parse","--abbrev-ref","HEAD"],{cwd:e,timeout:3e3}).toString().trim();let s=0,o=0;try{const a=C.execFileSync("git",["rev-parse","--abbrev-ref","--symbolic-full-name","@{u}"],{cwd:e,timeout:3e3}).toString().trim();if(a){const i=C.execFileSync("git",["rev-list","--left-right","--count",`${a}...HEAD`],{cwd:e,timeout:3e3}).toString().trim().split(" ");o=parseInt(i[0])||0,s=parseInt(i[1])||0}}catch{}t.json({branch:n,ahead:s,behind:o})}catch{t.json(null)}});const he=I.Router();he.get("/",(r,t)=>{const e=E();t.json((e==null?void 0:e.userDirective)??"")});he.post("/",(r,t)=>{const{content:e}=r.body,n=E()??{models:{reasoning:null}};R({...n,userDirective:e}),pe(e||void 0),t.json({success:!0})});const F=I.Router();F.get("/dir",(r,t)=>{const e=E();t.json((e==null?void 0:e.workspaceDir)??b.homedir())});F.post("/dir",(r,t)=>{const{dir:e}=r.body;try{const n=E()??{models:{reasoning:null}};R({...n,workspaceDir:e}),t.json({success:!0})}catch(n){t.json({success:!1,error:n instanceof Error?n.message:String(n)})}});F.post("/pick-dir",async(r,t)=>{try{let e=null;if(process.platform==="darwin"){const n=C.execSync(`osascript -e 'POSIX path of (choose folder with prompt "Select Workspace Directory")'`,{timeout:6e4}).toString().trim();n&&(e=n.replace(/\/$/,""))}else if(process.platform==="win32"){const n=['[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null',"$f = New-Object System.Windows.Forms.FolderBrowserDialog",'$f.Description = "Select Workspace Directory"','if ($f.ShowDialog() -eq "OK") { $f.SelectedPath }'].join("; "),s=C.execSync(`powershell -Command "${n}"`,{timeout:6e4}).toString().trim();s&&(e=s)}else try{const n=C.execSync('zenity --file-selection --directory --title="Select Workspace Directory"',{timeout:6e4}).toString().trim();n&&(e=n)}catch{try{const n=C.execSync('kdialog --getexistingdirectory "Select Workspace Directory"',{timeout:6e4}).toString().trim();n&&(e=n)}catch{}}t.json(e)}catch{t.json(null)}});F.get("/files",(r,t)=>{const e=r.query.path;try{const n=b.homedir(),s=u.resolve(e),o=u.resolve(n);if(!s.startsWith(o)&&s!==o)return t.json([]);if(!d.existsSync(s))return t.json([]);const a=d.readdirSync(s,{withFileTypes:!0});return t.json(a.filter(i=>!i.name.startsWith(".")).map(i=>{const c=u.join(s,i.name),l=d.statSync(c);return{name:i.name,path:c,isDirectory:i.isDirectory(),size:l.size,modified:l.mtimeMs}}))}catch{return t.json([])}});F.get("/file",(r,t)=>{const e=r.query.path;try{const n=b.homedir(),s=u.resolve(e);return!s.startsWith(u.resolve(n))||!d.existsSync(s)?t.json(null):d.statSync(s).size>512*1024?t.json("[File too large to preview — open in an external editor]"):t.json(d.readFileSync(s,"utf-8"))}catch{return t.json(null)}});F.post("/open-external",(r,t)=>{const{filePath:e}=r.body;try{const n=process.platform==="darwin"?"open":process.platform==="win32"?"explorer":"xdg-open";C.execSync(`${n} "${e}"`,{timeout:5e3})}catch{}t.json({})});function ft(r,t){const e=I.Router();return e.post("/start",async(n,s)=>{try{(r.getStatus()==="stopped"||r.getStatus()==="error")&&await r.initialize(),s.json({success:!0,status:r.getStatus()})}catch(o){s.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),e.post("/stop",async(n,s)=>{try{await r.cleanup(),s.json({success:!0})}catch(o){s.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),e.post("/restart",async(n,s)=>{try{await r.cleanup(),await r.initialize(),s.json({success:!0,status:r.getStatus()})}catch(o){s.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),e.get("/status",(n,s)=>{const o=r.getStatus();s.json({status:o==="ready"||o==="busy"?"running":o,port:0})}),e.post("/send-message",async(n,s)=>{const{prompt:o,opts:a,isCloud:i}=n.body;try{if(i){t.isActive()||await t.waitUntilReady(3e4);const l=await t.chat(o,p=>{J("jiva:phase-update",{phase:p})},a,p=>{J("jiva:jiva-log",{event:p})});return s.json({success:!0,result:l,conversationId:l.conversationId})}(r.getStatus()==="stopped"||r.getStatus()==="error")&&await r.initialize();const c=await r.chat(o,l=>{J("jiva:phase-update",{phase:l})},a,l=>{J("jiva:jiva-log",{event:l})});return s.json({success:!0,result:c,conversationId:c.conversationId})}catch(c){return s.json({success:!1,error:c instanceof Error?c.message:String(c)})}}),e.post("/stop-message",(n,s)=>{r.stop(),s.json({success:!0})}),e.post("/reset-conversation",(n,s)=>{r.resetConversation(),s.json({success:!0})}),e.post("/load-conversation",async(n,s)=>{const{id:o}=n.body;try{(r.getStatus()==="stopped"||r.getStatus()==="error")&&await r.initialize(),await r.loadConversation(o),s.json({success:!0})}catch(a){s.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),r.on("status-changed",(n,s)=>{J("jiva:server:status-changed",{status:n==="ready"||n==="busy"?"running":n,data:s})}),e}const ce=u.join(b.homedir(),".jiva","personas");function gt(r,t){return r==="chat"||t.includes("chat")?"MessageSquare":r==="research"||t.includes("research")?"Search":r==="developer"||r==="code-reviewer"||t.includes("code")?"Code2":r==="engineering-manager"||t.includes("management")?"Layers":r==="tester"||t.includes("testing")?"FlaskConical":r==="data-analyst"||t.includes("data")?"BarChart3":"Bot"}function yt(){const r=[];if(!d.existsSync(ce))return r;try{const t=d.readdirSync(ce,{withFileTypes:!0});for(const e of t){if(!e.isDirectory()||e.name==="skills")continue;const n=u.join(ce,e.name),s=u.join(n,".jiva-plugin","plugin.json");let o={};if(d.existsSync(s))try{const l=d.readFileSync(s,"utf-8");o=JSON.parse(l)}catch{}const a=e.name,i=o.tags??[],c=["chat","research"];r.push({name:a,displayName:(o.name??a).replace(/-/g," ").replace(/\b\w/g,l=>l.toUpperCase()),description:o.description??`${a} persona`,tags:i,icon:gt(a,i),isBuiltIn:c.includes(a),dirPath:n})}}catch(t){console.error("[PersonaManager] Failed to list personas:",t)}return r.sort((t,e)=>t.isBuiltIn&&!e.isBuiltIn?-1:!t.isBuiltIn&&e.isBuiltIn?1:t.name.localeCompare(e.name))}function vt(r){const{execSync:t}=require("child_process");try{return t(`jiva persona activate ${r}`,{timeout:1e4,stdio:"ignore"}),!0}catch{const e=u.join(b.homedir(),".jiva","active-persona.txt");try{return d.writeFileSync(e,r,"utf-8"),!0}catch{return!1}}}function wt(){try{const r=Ze();if(d.existsSync(r)){const e=JSON.parse(d.readFileSync(r,"utf-8"));if(e.activePersona)return e.activePersona}const t=u.join(b.homedir(),".jiva","active-persona.txt");if(d.existsSync(t))return d.readFileSync(t,"utf-8").trim()}catch{}return null}function St(r){const t=I.Router();return t.get("/",(e,n)=>{n.json(yt())}),t.post("/activate",async(e,n)=>{const{name:s}=e.body,o=vt(s);if(o)try{await r.switchPersona(s)}catch(a){console.error("[Personas] Failed to switch persona:",a)}n.json({success:o})}),t.get("/active",(e,n)=>{n.json(wt())}),t}function jt(r){const t=I.Router();return t.get("/status",(e,n)=>{try{const s=r.getMCPServerStatus(),o=E(),a=(o==null?void 0:o.mcpServers)??{},i=new Map(s.map(l=>[l.name,l])),c=Object.entries(a).map(([l,p])=>{const m=i.get(l);return{name:l,enabled:p.enabled??!0,connected:(m==null?void 0:m.connected)??!1,toolCount:(m==null?void 0:m.toolCount)??0,command:p.command??"",args:p.args??[],env:p.env??{},url:p.url,type:p.command?"stdio":"http",error:m==null?void 0:m.error}});for(const l of s)a[l.name]||c.push({name:l.name,enabled:l.enabled,connected:l.connected,toolCount:l.toolCount,command:"",args:[],env:{},url:void 0,type:"stdio",error:void 0});n.json(c)}catch{n.json([])}}),t.get("/tools",(e,n)=>{try{n.json(r.getMCPTools())}catch{n.json({})}}),t.post("/add",async(e,n)=>{const{name:s,config:o}=e.body;try{const a=E();if(!a)return n.json({success:!1,error:"Config not found"});const i={enabled:o.enabled??!0};return o.type==="stdio"?(i.command=o.command??"",i.args=o.args??[],o.env&&Object.keys(o.env).length>0&&(i.env=o.env)):(i.url=o.url??"",o.env&&Object.keys(o.env).length>0&&(i.env=o.env)),a.mcpServers||(a.mcpServers={}),a.mcpServers[s]=i,R(a),(r.getStatus()==="ready"||r.getStatus()==="busy")&&await r.addMCPServer(s,i),n.json({success:!0})}catch(a){return n.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),t.post("/remove",async(e,n)=>{const{name:s}=e.body;try{const o=E();o!=null&&o.mcpServers&&(delete o.mcpServers[s],R(o)),(r.getStatus()==="ready"||r.getStatus()==="busy")&&await r.removeMCPServer(s),n.json({success:!0})}catch(o){n.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),t.post("/toggle",async(e,n)=>{var a;const{name:s,enabled:o}=e.body;try{const i=E();(a=i==null?void 0:i.mcpServers)!=null&&a[s]&&(i.mcpServers[s].enabled=o,R(i)),(r.getStatus()==="ready"||r.getStatus()==="busy")&&await r.toggleMCPServer(s,o),n.json({success:!0})}catch(i){n.json({success:!1,error:i instanceof Error?i.message:String(i)})}}),t.post("/reconnect",async(e,n)=>{const{name:s}=e.body;try{await r.reconnectMCPServer(s),n.json({success:!0})}catch(o){n.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),t}const ee=u.join(b.homedir(),".jiva","jivam-mcp-selections.json");function we(){try{if(d.existsSync(ee))return JSON.parse(d.readFileSync(ee,"utf-8"))}catch{}return{}}function bt(r){const t=I.Router();return t.post("/send-message",async(e,n)=>{const{prompt:s,opts:o}=e.body;try{if(!r.isReady()){const i=E(),c=(i==null?void 0:i.workspaceDir)??b.homedir();await r.initialize(c)}const a=await r.chat(s,i=>{J("jiva:code-log",{event:i})},o);n.json({success:!0,...a})}catch(a){n.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),t.post("/stop-message",(e,n)=>{r.stop(),n.json({success:!0})}),t.post("/reset-session",async(e,n)=>{try{await r.cleanup(),n.json({success:!0})}catch(s){n.json({success:!1,error:s instanceof Error?s.message:String(s)})}}),t.post("/init",async(e,n)=>{const{dir:s,mcpServers:o,opts:a}=e.body;try{await r.initialize(s,o,a),n.json({success:!0})}catch(i){n.json({success:!1,error:i instanceof Error?i.message:String(i)})}}),t.get("/mcp-for-code",(e,n)=>{try{const s=E(),o=(s==null?void 0:s.mcpServers)??{};n.json(Object.entries(o).map(([a,i])=>({name:a,enabled:i.enabled??!0,codeMode:i.codeMode===!0,command:i.command??"",url:i.url})))}catch{n.json([])}}),t.get("/conversation-id",(e,n)=>{n.json(r.getConversationId())}),t.get("/mcp-selection/:convId",(e,n)=>{n.json(we()[e.params.convId]??[])}),t.post("/mcp-selection",(e,n)=>{const{convId:s,servers:o}=e.body;try{const a=we();a[s]=o,d.mkdirSync(u.dirname(ee),{recursive:!0}),d.writeFileSync(ee,JSON.stringify(a,null,2)),n.json({success:!0})}catch(a){n.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),t}const kt=new Set(["txt","md","markdown","rst","log","js","jsx","ts","tsx","mjs","cjs","py","rb","go","rs","java","kt","swift","c","cpp","cc","h","hpp","cs","css","scss","sass","less","html","htm","xml","svg","xhtml","json","jsonc","yaml","yml","toml","ini","cfg","conf","sh","bash","zsh","fish","ps1","bat","cmd","sql","graphql","gql","proto","env","editorconfig","gitignore","gitattributes","dockerfile","makefile","cmake","gradle","r","jl","scala","clj","ex","exs","erl","hs","lua","pl","vue","svelte","astro","lock","mod","sum"]),Pe={png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",bmp:"image/bmp"},xt={js:"javascript",jsx:"jsx",ts:"typescript",tsx:"tsx",py:"python",rb:"ruby",go:"go",rs:"rust",java:"java",kt:"kotlin",swift:"swift",cs:"csharp",c:"c",cpp:"cpp",h:"c",hpp:"cpp",css:"css",scss:"scss",sass:"sass",less:"less",html:"html",htm:"html",xml:"xml",svg:"xml",json:"json",jsonc:"json",yaml:"yaml",yml:"yaml",toml:"toml",sh:"bash",bash:"bash",zsh:"bash",fish:"fish",ps1:"powershell",sql:"sql",graphql:"graphql",gql:"graphql",proto:"protobuf",md:"markdown",markdown:"markdown",rst:"rst",r:"r",jl:"julia",scala:"scala",lua:"lua",vue:"vue",svelte:"svelte"};function Ct(r){const t=r.toLowerCase().replace(/^\./,"");return kt.has(t)?"text":t in Pe?"image":t==="pdf"?"pdf":t==="docx"?"docx":"unsupported"}function Se(r){const t=u.basename(r),e=u.extname(r).toLowerCase().replace(/^\./,""),n=Ct(e);try{switch(n){case"text":return Mt(r,t,e);case"pdf":return $t(r,t);case"docx":return Et(r,t);case"image":return Dt(r,t,e);default:return{name:t,category:"unsupported",markdown:"",error:`File type .${e} is not supported`}}}catch(s){return{name:t,category:n,markdown:"",error:s instanceof Error?s.message:"Failed to read file"}}}function Mt(r,t,e){if(d.statSync(r).size>2*1024*1024)return{name:t,category:"text",markdown:"",error:"File is too large (max 2 MB for text files)"};const s=d.readFileSync(r,"utf-8"),a=`\`\`\`${xt[e]??e}
119
119
  ${s}
120
- \`\`\``;return{name:n,category:"text",markdown:a}}function Tt(r,n){if(u.statSync(r).size>10*1024*1024)return{name:n,category:"pdf",markdown:"",error:"PDF is too large (max 10 MB)"};const t=u.readFileSync(r),s=Ft(t);if(!s.trim())return{name:n,category:"pdf",markdown:"",error:"Could not extract text from PDF (may be a scanned/image-only PDF)"};const o=`**[PDF: ${n}]**
121
-
122
- ${s}`;return{name:n,category:"pdf",markdown:o}}function Ft(r){const n=r.toString("latin1"),e=[],t=/<<[^>]*\/Filter\s*\/FlateDecode[^>]*>>\s*stream\r?\n([\s\S]*?)\r?\nendstream/g;let s;for(;(s=t.exec(n))!==null;)try{const a=Buffer.from(s[1],"latin1"),i=pe.inflateSync(a).toString("latin1");e.push(...Ce(i))}catch{}const o=/BT([\s\S]*?)ET/g;for(;(s=o.exec(n))!==null;)e.push(...Ce(s[1]));return[...new Set(e)].join(" ").replace(/\s+/g," ").trim()}function Ce(r){const n=[],e=/BT([\s\S]*?)ET/g;let t;for(;(t=e.exec(r))!==null;){const s=t[1],o=/\(([^)\\]*(?:\\.[^)\\]*)*)\)/g;let a;for(;(a=o.exec(s))!==null;){const l=a[1].replace(/\\n/g,`
123
- `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\\(/g,"(").replace(/\\\)/g,")").replace(/\\\\/g,"\\").replace(/[^\x20-\x7E\n\r\t]/g,"").trim();l.length>0&&n.push(l)}const i=/<([0-9A-Fa-f\s]+)>/g;for(;(a=i.exec(s))!==null;){const c=a[1].replace(/\s/g,"");if(c.length%2!==0)continue;let l="";for(let d=0;d<c.length;d+=2){const p=parseInt(c.slice(d,d+2),16);p>=32&&p<=126&&(l+=String.fromCharCode(p))}l.trim().length>0&&n.push(l.trim())}}return n}function Rt(r,n){if(u.statSync(r).size>10*1024*1024)return{name:n,category:"docx",markdown:"",error:"DOCX is too large (max 10 MB)"};const t=u.readFileSync(r),s=_t(t,"word/document.xml");if(!s)return{name:n,category:"docx",markdown:"",error:"Could not extract content from DOCX file"};const o=Ot(s.toString("utf-8"));if(!o.trim())return{name:n,category:"docx",markdown:"",error:"DOCX appears to be empty"};const a=`**[DOCX: ${n}]**
124
-
125
- ${o}`;return{name:n,category:"docx",markdown:a}}function _t(r,n){let e=0;for(;e<r.length-30;){if(r.readUInt32LE(e)!==67324752){e++;continue}const t=r.readUInt16LE(e+8),s=r.readUInt32LE(e+18),o=r.readUInt32LE(e+22),a=r.readUInt16LE(e+26),i=r.readUInt16LE(e+28),c=r.slice(e+30,e+30+a).toString("utf-8"),l=e+30+a+i,d=l+s;if(c===n){const p=r.slice(l,d);if(t===0)return p;if(t===8)try{return pe.inflateRawSync(p)}catch{try{return pe.inflateSync(p)}catch{return null}}return null}s===0&&o===0?e=l:e=d}return null}function Ot(r){const n=[],e=/<w:p[ >]([\s\S]*?)<\/w:p>/g;let t;for(;(t=e.exec(r))!==null;){const s=[],o=/<w:t[^>]*>([^<]*)<\/w:t>/g;let a;for(;(a=o.exec(t[1]))!==null;)s.push(a[1]);const i=s.join("").trim();i&&n.push(i)}return n.join(`
126
-
127
- `)}function Jt(r,n,e){if(u.statSync(r).size>20*1024*1024)return{name:n,category:"image",markdown:"",error:"Image is too large (max 20 MB)"};const s=Ee[e.toLowerCase()]??"image/png";return{name:n,category:"image",markdown:r,mimeType:s}}function Nt(r){const n=E.Router();return n.post("/convert",(e,t)=>{const{filePath:s}=e.body,o=S.homedir();if(!m.resolve(s).startsWith(m.resolve(o)))return t.json({name:m.basename(s),category:"unsupported",markdown:"",error:"Access denied"});const i=xe(s);if(i.category==="image"&&!i.error)try{const c=(()=>{try{return JSON.parse(u.readFileSync(m.join(S.homedir(),"Library","Preferences","jiva-nodejs","config.json"),"utf-8"))}catch{return null}})(),l=(c==null?void 0:c.workspaceDir)??o,d=m.join(l,".jiva","uploads");u.mkdirSync(d,{recursive:!0});const p=m.join(d,m.basename(s));u.copyFileSync(s,p),i.markdown=p}catch(c){i.error=`Failed to save image: ${c instanceof Error?c.message:String(c)}`}return t.json(i)}),n.post("/upload-and-convert",(e,t)=>{const{files:s}=e.body,o=S.homedir(),a=m.join(S.tmpdir(),"jivam-uploads");u.mkdirSync(a,{recursive:!0});const i=s.map(c=>{const l=m.join(a,c.name);try{u.writeFileSync(l,Buffer.from(c.data,"base64"));const d=xe(l);if(d.category==="image"&&!d.error)try{const p=(()=>{try{return JSON.parse(u.readFileSync(m.join(o,"Library","Preferences","jiva-nodejs","config.json"),"utf-8"))}catch{return null}})(),h=(p==null?void 0:p.workspaceDir)??o,y=m.join(h,".jiva","uploads");u.mkdirSync(y,{recursive:!0});const v=m.join(y,c.name);u.copyFileSync(l,v),d.markdown=v}catch{}return d}catch(d){return{name:c.name,category:"unsupported",markdown:"",error:String(d)}}finally{try{u.unlinkSync(l)}catch{}}});t.json(i)}),n.post("/describe-image",async(e,t)=>{const{dataUri:s}=e.body;try{const o=await r.describeImage(s);t.json({success:!0,description:o})}catch(o){t.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),n}const Ut="https://hcomegrnonxmjupvvyus.supabase.co",Lt="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imhjb21lZ3Jub254bWp1cHZ2eXVzIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzgxNTQwMjcsImV4cCI6MjA5MzczMDAyN30.sBBOTrPsdCZk75HDEzJaIv5Mz-bE3HTuJQ-1LcJ45nk",qt="https://jiva-hdjcuspt2a-uc.a.run.app";async function De(r,n){const e=await fetch(`${Ut}${r}`,{method:"POST",headers:{"Content-Type":"application/json",apikey:Lt},body:JSON.stringify(n)}),t=await e.json();if(!e.ok){const s=t.error_description??t.error??t.message??"Auth failed";throw new Error(s)}return t}async function zt(r,n){const e=await De("/auth/v1/token?grant_type=password",{email:r,password:n});return{userId:e.user.id,email:e.user.email,accessToken:e.access_token,refreshToken:e.refresh_token}}async function Wt(r,n){const e=await De("/auth/v1/signup",{email:r,password:n}),t=e.user??e;return{userId:t.id,email:t.email,accessToken:e.access_token??"",refreshToken:e.refresh_token??""}}async function Bt(r,n){const e=await fetch(`${qt}/api/session`,{method:"POST",headers:{"Content-Type":"application/json","x-tenant-id":r,"x-session-id":n},body:JSON.stringify({})});if(!e.ok){const t=await e.text();throw new Error(`Cloud session init failed: ${t}`)}}function Ht(r){const n=E.Router();return n.post("/sign-in",async(e,t)=>{const{email:s,password:o}=e.body;try{const a=await zt(s,o);t.json({userId:a.userId,email:a.email})}catch(a){t.json({error:a instanceof Error?a.message:String(a)})}}),n.post("/sign-up",async(e,t)=>{const{email:s,password:o}=e.body;try{const a=await Wt(s,o);t.json({userId:a.userId,email:a.email})}catch(a){t.json({error:a instanceof Error?a.message:String(a)})}}),n.post("/sign-out",(e,t)=>{r.deactivate(),t.json({})}),n.post("/init",async(e,t)=>{const{userId:s,sessionId:o}=e.body;r.startInit();try{await Bt(s,o),r.configure(s,o),t.json({success:!0})}catch(a){r.deactivate(),t.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),n}et();const W=parseInt(process.env.JIVAM_PORT??"7842",10),Te=process.env.NODE_ENV==="development";function Gt(r){const n=[m.join(S.homedir(),"Applications","Safari Apps"),m.join(S.homedir(),"Applications")];for(const e of n){if(!u.existsSync(e))continue;const t=u.readdirSync(e).filter(s=>s.endsWith(".app"));for(const s of t){const o=m.join(e,s,"Contents","Info.plist");if(u.existsSync(o))try{if(u.statSync(o).mtimeMs<r)continue;const i=u.readFileSync(o,"utf-8");if(i.includes("com.apple.Safari.WebApp")&&i.includes("<string>Jivam</string>"))return m.join(e,s)}catch{}}}return null}async function Vt(r){const{exec:n}=await import("child_process"),{promisify:e}=await import("util"),t=e(n);try{const{stdout:s}=await t("sw_vers -productVersion");if(parseInt(s.trim().split(".")[0]??"0",10)<14)return console.warn("Safari Add to Dock requires macOS Sonoma (14) or later — skipping."),null;const a=Date.now(),i=m.join(S.tmpdir(),"jivam-add-to-dock.applescript"),c=`
128
- on run
129
- tell application "Safari"
130
- activate
131
- if (count of windows) = 0 then
132
- make new document
133
- end if
134
- set URL of front document to "${r}"
135
- end tell
136
- delay 2
137
- tell application "Safari" to activate
138
- delay 1
139
- tell application "System Events" to tell process "Safari" to set frontmost to true
140
- delay 1
141
- tell application "System Events"
142
- tell process "Safari"
143
- click menu item "Add to Dock…" of menu "File" of menu bar 1
144
- end tell
145
- end tell
146
- delay 2
147
- end run
148
- `;u.writeFileSync(i,c);try{await t(`osascript "${i}"`,{timeout:2e4})}finally{u.rmSync(i,{force:!0})}console.log(`
149
- A "Add to Dock" confirmation opened in Safari — click Add to finish setting up Jivam as an app.`),console.log("Waiting up to 60s for you to click it...");for(let l=0;l<60;l++){await new Promise(p=>setTimeout(p,1e3));const d=Gt(a);if(d)return d}return console.warn("No click detected within 60s — falling back to --app mode. Run `jivam --install` again anytime to retry."),null}catch(s){const o=s instanceof Error?s.message:String(s);if(o.includes("assistive access")||o.includes("-1719")){console.warn(`
150
- Safari Add to Dock needs Accessibility permission (one-time setup) to control Safari's menus.
151
- Opening System Settings — enable access for Terminal (or whichever app you ran this from),
152
- then re-run: jivam --install
153
- Falling back to --app mode for now — Jivam will still work, just without the native single-window Dock experience.`);try{await t('open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"')}catch{}}else console.warn("Safari Add to Dock automation failed, falling back to --app mode:",s);return null}}const we="ai.karmaloop.jivam",J="JivamServer";function Fe(){return m.join(S.homedir(),"Library","LaunchAgents",`${we}.plist`)}async function Yt(){const{exec:r}=await import("child_process"),{promisify:n}=await import("util"),e=n(r);try{const{stdout:o}=await e("which jivam");if(o.trim())return o.trim()}catch{}const t=["/usr/local/bin/jivam",m.join(S.homedir(),".npm-global","bin","jivam"),"/opt/homebrew/bin/jivam","/usr/bin/jivam"];for(const o of t)if(u.existsSync(o))return o;const s=m.join(S.homedir(),".nvm","versions","node");if(u.existsSync(s))try{const o=u.readdirSync(s).sort().reverse();for(const a of o){const i=m.join(s,a,"bin","jivam");if(u.existsSync(i))return i}}catch{}return`"${process.execPath}" "${process.argv[1]}"`}async function Kt(r){const n=["/usr/local/bin","/opt/homebrew/bin","/opt/homebrew/sbin",m.join(S.homedir(),".npm-global","bin"),m.join(S.homedir(),".nvm","versions","node"),"/usr/bin","/bin"].join(":"),e=m.join(S.homedir(),".jivam");u.mkdirSync(e,{recursive:!0});const t=m.join(e,"jivam.log"),o=r.startsWith('"')?r.split('" "').map(c=>c.replace(/^"|"$/g,"")):[r],a=`<?xml version="1.0" encoding="UTF-8"?>
154
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
155
- <plist version="1.0">
156
- <dict>
157
- <key>Label</key>
158
- <string>${we}</string>
159
- <key>ProgramArguments</key>
160
- <array>
161
- ${o.map(c=>`<string>${c}</string>`).join(`
162
- `)}
163
- <string>--server-only</string>
164
- </array>
165
- <key>RunAtLoad</key>
166
- <true/>
167
- <key>KeepAlive</key>
168
- <true/>
169
- <key>ThrottleInterval</key>
170
- <integer>5</integer>
171
- <key>StandardOutPath</key>
172
- <string>${t}</string>
173
- <key>StandardErrorPath</key>
174
- <string>${t}</string>
175
- <key>EnvironmentVariables</key>
176
- <dict>
177
- <key>PATH</key>
178
- <string>${n}:/usr/bin:/bin</string>
179
- </dict>
180
- </dict>
181
- </plist>
182
- `,i=Fe();return u.mkdirSync(m.dirname(i),{recursive:!0}),u.writeFileSync(i,a),i}async function Re(r){var c;const{exec:n}=await import("child_process"),{promisify:e}=await import("util"),t=e(n),s=Fe(),a=`gui/${((c=process.getuid)==null?void 0:c.call(process))??0}`,i=`${a}/${we}`;if(!u.existsSync(s)){console.log("Jivam background service is not installed. Run: jivam --install");return}if(r==="start")try{await t(`launchctl bootstrap ${a} "${s}"`),console.log("Jivam background service started.")}catch(l){const d=l instanceof Error?l.message:String(l);d.includes("already bootstrapped")||d.includes("Service already loaded")?console.log("Jivam background service is already running."):console.error("Failed to start service:",l)}else if(r==="stop")try{await t(`launchctl bootout ${i}`),console.log("Jivam background service stopped.")}catch{console.warn("Service was not running (or already stopped).")}else if(r==="restart")try{await t(`launchctl kickstart -k ${i}`),console.log("Jivam background service restarted.")}catch{try{await t(`launchctl bootstrap ${a} "${s}"`),console.log("Jivam background service started.")}catch(d){console.error("Failed to restart service:",d)}}else if(r==="status")try{const{stdout:l}=await t(`launchctl print ${i}`),d=/state = running/.test(l);console.log(d?"Jivam background service is running.":"Jivam background service is loaded but not running.");const p=l.match(/pid = (\d+)/);p&&console.log(` PID: ${p[1]}`)}catch{console.log("Jivam background service is not running.")}}async function Xt(){const{exec:r}=await import("child_process"),{promisify:n}=await import("util"),e=n(r),t=m.join(S.homedir(),"Applications","Jivam.app"),s=m.join(t,"Contents","MacOS"),o=m.join(t,"Contents","Resources");u.mkdirSync(s,{recursive:!0}),u.mkdirSync(o,{recursive:!0});const i=`#!/bin/bash
183
- URL="${`http://localhost:${W}`}"
120
+ \`\`\``;return{name:t,category:"text",markdown:a}}function $t(r,t){if(d.statSync(r).size>10*1024*1024)return{name:t,category:"pdf",markdown:"",error:"PDF is too large (max 10 MB)"};const n=d.readFileSync(r),s=Pt(n);if(!s.trim())return{name:t,category:"pdf",markdown:"",error:"Could not extract text from PDF (may be a scanned/image-only PDF)"};const o=`**[PDF: ${t}]**
121
+
122
+ ${s}`;return{name:t,category:"pdf",markdown:o}}function Pt(r){const t=r.toString("latin1"),e=[],n=/<<[^>]*\/Filter\s*\/FlateDecode[^>]*>>\s*stream\r?\n([\s\S]*?)\r?\nendstream/g;let s;for(;(s=n.exec(t))!==null;)try{const a=Buffer.from(s[1],"latin1"),i=ue.inflateSync(a).toString("latin1");e.push(...je(i))}catch{}const o=/BT([\s\S]*?)ET/g;for(;(s=o.exec(t))!==null;)e.push(...je(s[1]));return[...new Set(e)].join(" ").replace(/\s+/g," ").trim()}function je(r){const t=[],e=/BT([\s\S]*?)ET/g;let n;for(;(n=e.exec(r))!==null;){const s=n[1],o=/\(([^)\\]*(?:\\.[^)\\]*)*)\)/g;let a;for(;(a=o.exec(s))!==null;){const l=a[1].replace(/\\n/g,`
123
+ `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\\(/g,"(").replace(/\\\)/g,")").replace(/\\\\/g,"\\").replace(/[^\x20-\x7E\n\r\t]/g,"").trim();l.length>0&&t.push(l)}const i=/<([0-9A-Fa-f\s]+)>/g;for(;(a=i.exec(s))!==null;){const c=a[1].replace(/\s/g,"");if(c.length%2!==0)continue;let l="";for(let p=0;p<c.length;p+=2){const m=parseInt(c.slice(p,p+2),16);m>=32&&m<=126&&(l+=String.fromCharCode(m))}l.trim().length>0&&t.push(l.trim())}}return t}function Et(r,t){if(d.statSync(r).size>10*1024*1024)return{name:t,category:"docx",markdown:"",error:"DOCX is too large (max 10 MB)"};const n=d.readFileSync(r),s=It(n,"word/document.xml");if(!s)return{name:t,category:"docx",markdown:"",error:"Could not extract content from DOCX file"};const o=At(s.toString("utf-8"));if(!o.trim())return{name:t,category:"docx",markdown:"",error:"DOCX appears to be empty"};const a=`**[DOCX: ${t}]**
124
+
125
+ ${o}`;return{name:t,category:"docx",markdown:a}}function It(r,t){let e=0;for(;e<r.length-30;){if(r.readUInt32LE(e)!==67324752){e++;continue}const n=r.readUInt16LE(e+8),s=r.readUInt32LE(e+18),o=r.readUInt32LE(e+22),a=r.readUInt16LE(e+26),i=r.readUInt16LE(e+28),c=r.slice(e+30,e+30+a).toString("utf-8"),l=e+30+a+i,p=l+s;if(c===t){const m=r.slice(l,p);if(n===0)return m;if(n===8)try{return ue.inflateRawSync(m)}catch{try{return ue.inflateSync(m)}catch{return null}}return null}s===0&&o===0?e=l:e=p}return null}function At(r){const t=[],e=/<w:p[ >]([\s\S]*?)<\/w:p>/g;let n;for(;(n=e.exec(r))!==null;){const s=[],o=/<w:t[^>]*>([^<]*)<\/w:t>/g;let a;for(;(a=o.exec(n[1]))!==null;)s.push(a[1]);const i=s.join("").trim();i&&t.push(i)}return t.join(`
126
+
127
+ `)}function Dt(r,t,e){if(d.statSync(r).size>20*1024*1024)return{name:t,category:"image",markdown:"",error:"Image is too large (max 20 MB)"};const s=Pe[e.toLowerCase()]??"image/png";return{name:t,category:"image",markdown:r,mimeType:s}}function _t(r){const t=I.Router();return t.post("/convert",(e,n)=>{const{filePath:s}=e.body,o=b.homedir();if(!u.resolve(s).startsWith(u.resolve(o)))return n.json({name:u.basename(s),category:"unsupported",markdown:"",error:"Access denied"});const i=Se(s);if(i.category==="image"&&!i.error)try{const c=(()=>{try{return JSON.parse(d.readFileSync(u.join(b.homedir(),"Library","Preferences","jiva-nodejs","config.json"),"utf-8"))}catch{return null}})(),l=(c==null?void 0:c.workspaceDir)??o,p=u.join(l,".jiva","uploads");d.mkdirSync(p,{recursive:!0});const m=u.join(p,u.basename(s));d.copyFileSync(s,m),i.markdown=m}catch(c){i.error=`Failed to save image: ${c instanceof Error?c.message:String(c)}`}return n.json(i)}),t.post("/upload-and-convert",(e,n)=>{const{files:s}=e.body,o=b.homedir(),a=u.join(b.tmpdir(),"jivam-uploads");d.mkdirSync(a,{recursive:!0});const i=s.map(c=>{const l=u.join(a,c.name);try{d.writeFileSync(l,Buffer.from(c.data,"base64"));const p=Se(l);if(p.category==="image"&&!p.error)try{const m=(()=>{try{return JSON.parse(d.readFileSync(u.join(o,"Library","Preferences","jiva-nodejs","config.json"),"utf-8"))}catch{return null}})(),y=(m==null?void 0:m.workspaceDir)??o,w=u.join(y,".jiva","uploads");d.mkdirSync(w,{recursive:!0});const S=u.join(w,c.name);d.copyFileSync(l,S),p.markdown=S}catch{}return p}catch(p){return{name:c.name,category:"unsupported",markdown:"",error:String(p)}}finally{try{d.unlinkSync(l)}catch{}}});n.json(i)}),t.post("/describe-image",async(e,n)=>{const{dataUri:s}=e.body;try{const o=await r.describeImage(s);n.json({success:!0,description:o})}catch(o){n.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),t}const Tt="https://hcomegrnonxmjupvvyus.supabase.co",Ot="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imhjb21lZ3Jub254bWp1cHZ2eXVzIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzgxNTQwMjcsImV4cCI6MjA5MzczMDAyN30.sBBOTrPsdCZk75HDEzJaIv5Mz-bE3HTuJQ-1LcJ45nk",Rt="https://jiva-hdjcuspt2a-uc.a.run.app";async function Ee(r,t){const e=await fetch(`${Tt}${r}`,{method:"POST",headers:{"Content-Type":"application/json",apikey:Ot},body:JSON.stringify(t)}),n=await e.json();if(!e.ok){const s=n.error_description??n.error??n.message??"Auth failed";throw new Error(s)}return n}async function Ft(r,t){const e=await Ee("/auth/v1/token?grant_type=password",{email:r,password:t});return{userId:e.user.id,email:e.user.email,accessToken:e.access_token,refreshToken:e.refresh_token}}async function Jt(r,t){const e=await Ee("/auth/v1/signup",{email:r,password:t}),n=e.user??e;return{userId:n.id,email:n.email,accessToken:e.access_token??"",refreshToken:e.refresh_token??""}}async function Ut(r,t){const e=await fetch(`${Rt}/api/session`,{method:"POST",headers:{"Content-Type":"application/json","x-tenant-id":r,"x-session-id":t},body:JSON.stringify({})});if(!e.ok){const n=await e.text();throw new Error(`Cloud session init failed: ${n}`)}}function Nt(r){const t=I.Router();return t.post("/sign-in",async(e,n)=>{const{email:s,password:o}=e.body;try{const a=await Ft(s,o);n.json({userId:a.userId,email:a.email})}catch(a){n.json({error:a instanceof Error?a.message:String(a)})}}),t.post("/sign-up",async(e,n)=>{const{email:s,password:o}=e.body;try{const a=await Jt(s,o);n.json({userId:a.userId,email:a.email})}catch(a){n.json({error:a instanceof Error?a.message:String(a)})}}),t.post("/sign-out",(e,n)=>{r.deactivate(),n.json({})}),t.post("/init",async(e,n)=>{const{userId:s,sessionId:o}=e.body;r.startInit();try{await Ut(s,o),r.configure(s,o),n.json({success:!0})}catch(a){r.deactivate(),n.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),t}Ve();const be=parseInt(process.env.JIVAM_PORT??"7842",10),Ie=process.env.NODE_ENV==="development";async function qt(){process.platform!=="darwin"&&(console.error("--install is currently only supported on macOS."),process.exit(1));const{exec:r}=await import("child_process"),{promisify:t}=await import("util"),e=t(r),n=b.tmpdir(),s=u.join(b.homedir(),"Applications"),o=u.join(s,"Jivam.app"),a=u.join(o,"Contents","MacOS"),i=u.join(o,"Contents","Resources");let c="";try{const{stdout:f}=await e("which jivam");c=f.trim()}catch{const f=["/usr/local/bin/jivam",u.join(b.homedir(),".npm-global","bin","jivam"),u.join(b.homedir(),".nvm","versions","node"),"/opt/homebrew/bin/jivam","/usr/bin/jivam"];for(const g of f)if(d.existsSync(g)){c=g;break}if(!c){const g=u.join(b.homedir(),".nvm","versions","node");if(d.existsSync(g))try{const A=d.readdirSync(g).sort().reverse();for(const _ of A){const D=u.join(g,_,"bin","jivam");if(d.existsSync(D)){c=D;break}}}catch{}}}if(!c){const f=process.execPath,g=process.argv[1];c=`"${f}" "${g}"`}const l=["/usr/local/bin","/opt/homebrew/bin","/opt/homebrew/sbin",u.join(b.homedir(),".npm-global","bin"),u.join(b.homedir(),".nvm","versions","node"),"/usr/bin","/bin"].join(":"),p=u.dirname(c.replace(/^"/,"").replace(/"$/,"").split('"')[0]),m=u.join(p,"npm"),y=d.existsSync(m)?`"${m}"`:"npm",w=`#!/bin/bash
128
+ # Jivam launcher — auto-updates jivam + jiva-core, starts the server, opens Chrome --app.
129
+ export PATH="${l}:$PATH"
130
+
131
+ PORT=7842
132
+ URL="http://localhost:$PORT"
133
+ LOG="$HOME/.jivam/jivam.log"
134
+ UPDATE_STAMP="$HOME/.jivam/.last-update"
135
+
136
+ mkdir -p "$HOME/.jivam"
137
+ echo "--- $(date): launcher started ---" >> "$LOG"
138
+
139
+ # ── Auto-update (at most once per day, runs in background so launch stays fast)
140
+ should_update=false
141
+ if [ ! -f "$UPDATE_STAMP" ]; then
142
+ should_update=true
143
+ else
144
+ # mtime of stamp file vs now — update if older than 86400 s
145
+ stamp_age=$(( $(date +%s) - $(stat -f %m "$UPDATE_STAMP" 2>/dev/null || echo 0) ))
146
+ [ "$stamp_age" -gt 86400 ] && should_update=true
147
+ fi
148
+
149
+ if [ "$should_update" = true ]; then
150
+ (
151
+ echo "$(date): checking for updates..." >> "$LOG"
152
+ touch "$UPDATE_STAMP"
153
+ ${y} install -g jivamai jiva-core >> "$LOG" 2>&1
154
+ echo "$(date): update check complete" >> "$LOG"
155
+ ) &
156
+ fi
157
+
158
+ # ── Start server if not already running
159
+ if ! curl -sf "$URL/api/version" > /dev/null 2>&1; then
160
+ ${c} >> "$LOG" 2>&1 &
161
+ SERVER_PID=$!
162
+ echo "$(date): started jivam server (pid $SERVER_PID)" >> "$LOG"
163
+
164
+ # Wait up to 20 s for the server to become ready (40 × 0.5 s)
165
+ for i in $(seq 1 40); do
166
+ sleep 0.5
167
+ if curl -sf "$URL/api/version" > /dev/null 2>&1; then
168
+ echo "$(date): server ready" >> "$LOG"
169
+ break
170
+ fi
171
+ done
172
+ fi
173
+
174
+ # ── Open in Chrome --app mode (best experience), fall back to Safari
184
175
  CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
185
176
  EDGE="/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"
186
177
  BRAVE="/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"
@@ -195,7 +186,7 @@ else
195
186
  osascript -e "tell application \\"Safari\\" to open location \\"$URL\\"" \\
196
187
  -e "tell application \\"Safari\\" to activate"
197
188
  fi
198
- `;u.writeFileSync(m.join(s,"jivam-launcher"),i,{mode:493}),u.writeFileSync(m.join(t,"Contents","Info.plist"),`<?xml version="1.0" encoding="UTF-8"?>
189
+ `,S=`<?xml version="1.0" encoding="UTF-8"?>
199
190
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
200
191
  <plist version="1.0">
201
192
  <dict>
@@ -217,43 +208,54 @@ fi
217
208
  <false/>
218
209
  </dict>
219
210
  </plist>
220
- `);const d=[m.join(__dirname,"..","dist","icon-512.png"),m.join(__dirname,"..","public","icon-512.png")].find(p=>u.existsSync(p));if(d)try{const p=m.join(S.tmpdir(),"Jivam.iconset");u.mkdirSync(p,{recursive:!0});const h=[[16,"icon_16x16.png"],[32,"icon_16x16@2x.png"],[32,"icon_32x32.png"],[64,"icon_32x32@2x.png"],[128,"icon_128x128.png"],[256,"icon_128x128@2x.png"],[256,"icon_256x256.png"],[512,"icon_256x256@2x.png"],[512,"icon_512x512.png"]];for(const[y,v]of h)await e(`sips -z ${y} ${y} "${d}" --out "${m.join(p,v)}"`);await e(`iconutil -c icns "${p}" --output "${m.join(o,"Jivam.icns")}"`),u.rmSync(p,{recursive:!0,force:!0})}catch(p){console.warn("Could not convert icon (sips/iconutil failed):",p)}return t}async function Zt(r){const{exec:n}=await import("child_process"),{promisify:e}=await import("util"),t=e(n),s="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister";try{await t(`touch "${r}"`),await t(`"${s}" -f "${r}"`)}catch{}const o=`<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>${r}</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>`;try{await t(`defaults write com.apple.dock persistent-apps -array-add '${o}' && killall Dock`),console.log(`Added to Dock: ${r}`)}catch(a){console.warn("Could not add to Dock automatically — drag the app to your Dock manually."),console.warn(a)}}async function Qt(){process.platform!=="darwin"&&(console.error("--install is currently only supported on macOS."),process.exit(1));const r=`http://localhost:${W}`;console.log("Setting up the Jivam background service...");const n=await Yt();await Kt(n),await Re("restart");let e=!1;for(let o=0;o<30;o++){try{if((await fetch(`${r}/api/version`)).ok){e=!0;break}}catch{}await new Promise(a=>setTimeout(a,500))}e?console.log("Jivam server is running."):console.warn("Server did not come up within 15s — continuing anyway (check ~/.jivam/jivam.log)."),console.log("Installing Jivam as a Safari web app (this may take a few seconds)...");const s=await Vt(r)??await Xt();await Zt(s),console.log(`
221
- Done! Click the Jivam icon in your Dock to launch.`),console.log("The server runs continuously in the background — manage it with:"),console.log(" jivam stop jivam start jivam restart jivam status"),process.exit(0)}async function en(){const{exec:r}=await import("child_process"),{promisify:n}=await import("util"),e=n(r);try{const{stdout:o}=await e("where jivam"),a=o.split(`
222
- `)[0].trim();if(a)return a}catch{}const t=process.env.LOCALAPPDATA??m.join(S.homedir(),"AppData","Local"),s=[m.join(t,"npm","jivam.cmd"),m.join(process.env.APPDATA??"","npm","jivam.cmd"),"C:\\Program Files\\nodejs\\jivam.cmd"];for(const o of s)if(u.existsSync(o))return o;return`"${process.execPath}" "${process.argv[1]}"`}async function tn(r){const{exec:n}=await import("child_process"),{promisify:e}=await import("util"),t=e(n),s=r.startsWith('"'),[o,...a]=s?r.split('" "').map(d=>d.replace(/^"|"$/g,"")):[r],i=[...a,"--server-only"].join(" "),c=`<?xml version="1.0" encoding="UTF-16"?>
223
- <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
224
- <Triggers>
225
- <LogonTrigger>
226
- <Enabled>true</Enabled>
227
- </LogonTrigger>
228
- </Triggers>
229
- <Principals>
230
- <Principal id="Author">
231
- <LogonType>InteractiveToken</LogonType>
232
- <RunLevel>LeastPrivilege</RunLevel>
233
- </Principal>
234
- </Principals>
235
- <Settings>
236
- <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
237
- <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
238
- <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
239
- <StartWhenAvailable>true</StartWhenAvailable>
240
- <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
241
- <Hidden>true</Hidden>
242
- <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
243
- <RestartOnFailure>
244
- <Interval>PT1M</Interval>
245
- <Count>999</Count>
246
- </RestartOnFailure>
247
- </Settings>
248
- <Actions Context="Author">
249
- <Exec>
250
- <Command>${o}</Command>
251
- <Arguments>${i}</Arguments>
252
- </Exec>
253
- </Actions>
254
- </Task>
255
- `,l=m.join(S.tmpdir(),"jivam-task.xml");u.writeFileSync(l,Buffer.concat([Buffer.from([255,254]),Buffer.from(c,"utf16le")]));try{await t(`schtasks /Create /TN "${J}" /XML "${l}" /F`)}finally{u.rmSync(l,{force:!0})}}async function _e(r){const{exec:n}=await import("child_process"),{promisify:e}=await import("util"),t=e(n);try{await t(`schtasks /Query /TN "${J}"`)}catch{console.log("Jivam background service is not installed. Run: jivam --install");return}if(r==="start"||r==="restart"){if(r==="restart"){try{await t(`schtasks /End /TN "${J}"`)}catch{}await new Promise(s=>setTimeout(s,1e3))}try{await t(`schtasks /Run /TN "${J}"`),console.log(`Jivam background service ${r==="restart"?"restarted":"started"}.`)}catch(s){console.error(`Failed to ${r} service:`,s)}}else if(r==="stop")try{await t(`schtasks /End /TN "${J}"`),console.log("Jivam background service stopped.")}catch{console.warn("Service was not running (or already stopped).")}else if(r==="status")try{const{stdout:s}=await t(`schtasks /Query /TN "${J}" /FO LIST /V`),o=s.match(/Status:\s*(.+)/);console.log(o?`Jivam background service status: ${o[1].trim()}`:"Jivam background service is registered.")}catch{console.log("Jivam background service is not running.")}}async function nn(){const{exec:r}=await import("child_process"),{promisify:n}=await import("util"),e=n(r),t=process.env.LOCALAPPDATA??m.join(S.homedir(),"AppData","Local"),s=m.join(t,"Jivam"),o=m.join(s,"jivam-launcher.bat"),a=m.join(s,"jivam-launcher.vbs"),i=m.join(s,"Jivam.ico"),c=m.join(S.homedir(),"Desktop","Jivam.lnk"),l=m.join(t,"Microsoft","Windows","Start Menu","Programs"),d=m.join(l,"Jivam.lnk");u.mkdirSync(s,{recursive:!0});const p=`http://localhost:${W}`;console.log("Setting up the Jivam background service...");const h=await en();await tn(h),await _e("restart");let y=!1;for(let k=0;k<30;k++){try{if((await fetch(`${p}/api/version`)).ok){y=!0;break}}catch{}await new Promise(w=>setTimeout(w,500))}y?console.log("Jivam server is running."):console.warn("Server did not come up within 15s — continuing anyway (check %LOCALAPPDATA%\\Jivam\\jivam.log).");const v=`@echo off
256
- set URL=${p}
211
+ `;d.mkdirSync(a,{recursive:!0}),d.mkdirSync(i,{recursive:!0});const M=u.join(a,"jivam-launcher");d.writeFileSync(M,w,{mode:493}),d.writeFileSync(u.join(o,"Contents","Info.plist"),S);const v=[u.join(U,"..","dist","icon-512.png"),u.join(U,"..","public","icon-512.png")].find(f=>d.existsSync(f));if(v)try{const f=u.join(n,"Jivam.iconset");d.mkdirSync(f,{recursive:!0});const g=[[16,"icon_16x16.png"],[32,"icon_16x16@2x.png"],[32,"icon_32x32.png"],[64,"icon_32x32@2x.png"],[128,"icon_128x128.png"],[256,"icon_128x128@2x.png"],[256,"icon_256x256.png"],[512,"icon_256x256@2x.png"],[512,"icon_512x512.png"]];for(const[_,D]of g)await e(`sips -z ${_} ${_} "${v}" --out "${u.join(f,D)}"`);const A=u.join(i,"Jivam.icns");await e(`iconutil -c icns "${f}" --output "${A}"`),d.rmSync(f,{recursive:!0,force:!0}),console.log("Icon created successfully.")}catch(f){console.warn("Could not convert icon (sips/iconutil failed):",f)}else console.warn("No icon found at dist/icon-512.png or public/icon-512.png — app will use default macOS icon.");console.log(`Created ${o}`);const j="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister";try{await e(`touch "${o}"`),await e(`"${j}" -f "${o}"`)}catch{}const k=`<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>${o}</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>`;try{await e(`defaults write com.apple.dock persistent-apps -array-add '${k}' && killall Dock`),console.log("Added Jivam to the Dock.")}catch(f){console.warn("Could not add to Dock automatically — drag Jivam.app to your Dock manually."),console.warn(f)}console.log(`
212
+ Done! Click the Jivam icon in your Dock to launch.`),process.exit(0)}async function Lt(){const{exec:r}=await import("child_process"),{promisify:t}=await import("util"),e=t(r),n=process.env.LOCALAPPDATA??u.join(b.homedir(),"AppData","Local"),s=u.join(n,"Jivam"),o=u.join(s,"jivam-launcher.bat"),a=u.join(s,"jivam-launcher.vbs"),i=u.join(s,"Jivam.ico"),c=u.join(b.homedir(),"Desktop","Jivam.lnk"),l=u.join(n,"Microsoft","Windows","Start Menu","Programs"),p=u.join(l,"Jivam.lnk");d.mkdirSync(s,{recursive:!0});let m="";try{const{stdout:f}=await e("where jivam");m=f.split(`
213
+ `)[0].trim()}catch{const f=[u.join(n,"npm","jivam.cmd"),u.join(process.env.APPDATA??"","npm","jivam.cmd"),"C:\\Program Files\\nodejs\\jivam.cmd"];for(const g of f)if(d.existsSync(g)){m=g;break}}m||(m=`"${process.execPath}" "${process.argv[1]}"`);const y=u.join(u.dirname(m),"npm.cmd"),S=`@echo off
214
+ setlocal enabledelayedexpansion
215
+ set PORT=7842
216
+ set URL=http://localhost:%PORT%
217
+ set JIVAM_DIR=%LOCALAPPDATA%\\Jivam
218
+ set LOG=%JIVAM_DIR%\\jivam.log
219
+ set UPDATE_STAMP=%JIVAM_DIR%\\.last-update
220
+
221
+ if not exist "%JIVAM_DIR%" mkdir "%JIVAM_DIR%"
222
+ echo --- %date% %time%: launcher started --- >> "%LOG%"
223
+
224
+ :: ── Auto-update (at most once per day, runs async so launch is fast)
225
+ set DO_UPDATE=0
226
+ if not exist "%UPDATE_STAMP%" (
227
+ set DO_UPDATE=1
228
+ ) else (
229
+ :: Compare today's date to the stamp file's date
230
+ for /F "usebackq" %%A in ('%UPDATE_STAMP%') do set STAMP_DATE=%%~tA
231
+ if not "%STAMP_DATE:~0,10%" == "%date%" set DO_UPDATE=1
232
+ )
233
+
234
+ if "%DO_UPDATE%"=="1" (
235
+ echo %date% %time%: checking for updates >> "%LOG%"
236
+ echo. > "%UPDATE_STAMP%"
237
+ start /B "" cmd /C "${d.existsSync(y)?`"${y}"`:"npm"} install -g jivamai jiva-core >> "%LOG%" 2>&1"
238
+ )
239
+
240
+ :: ── Start server if not already running
241
+ curl -sf %URL%/api/version > nul 2>&1
242
+ if %errorlevel% neq 0 (
243
+ echo %date% %time%: starting jivam server >> "%LOG%"
244
+ start /B "" "${m}" >> "%LOG%" 2>&1
245
+
246
+ :: Wait up to 20 s (40 x 500 ms)
247
+ for /L %%i in (1,1,40) do (
248
+ ping -n 1 -w 500 127.0.0.1 > nul
249
+ curl -sf %URL%/api/version > nul 2>&1
250
+ if !errorlevel! equ 0 (
251
+ echo %date% %time%: server ready >> "%LOG%"
252
+ goto :open
253
+ )
254
+ )
255
+ )
256
+
257
+ :open
258
+ :: Open in Chrome --app mode; fall back to Edge, then default browser
257
259
  set CHROME=%ProgramFiles%\\Google\\Chrome\\Application\\chrome.exe
258
260
  set EDGE=%ProgramFiles(x86)%\\Microsoft\\Edge\\Application\\msedge.exe
259
261
 
@@ -264,11 +266,11 @@ if exist "%CHROME%" (
264
266
  ) else (
265
267
  start "" %URL%
266
268
  )
267
- `,A=`Set oShell = CreateObject("WScript.Shell")
269
+ `,M=`Set oShell = CreateObject("WScript.Shell")
268
270
  oShell.Run Chr(34) & "${o.replace(/\\/g,"\\\\")}" & Chr(34), 0, False
269
- `;u.writeFileSync(o,v),u.writeFileSync(a,A),console.log(`Created launcher at ${s}`);const g=[m.join(B,"..","dist","icon-512.png"),m.join(B,"..","public","icon-512.png")].find(k=>u.existsSync(k));if(g){const k=`
271
+ `;d.writeFileSync(o,S),d.writeFileSync(a,M),console.log(`Created launcher at ${s}`);const v=[u.join(U,"..","dist","icon-512.png"),u.join(U,"..","public","icon-512.png")].find(f=>d.existsSync(f));if(v){const f=`
270
272
  Add-Type -AssemblyName System.Drawing
271
- $src = [System.Drawing.Image]::FromFile('${g.replace(/\\/g,"\\\\")}')
273
+ $src = [System.Drawing.Image]::FromFile('${v.replace(/\\/g,"\\\\")}')
272
274
  $bmp = New-Object System.Drawing.Bitmap($src, 256, 256)
273
275
  $ico = [System.Drawing.Icon]::FromHandle($bmp.GetHicon())
274
276
  $fs = [System.IO.File]::Create('${i.replace(/\\/g,"\\\\")}')
@@ -278,15 +280,15 @@ $ico.Dispose()
278
280
  $bmp.Dispose()
279
281
  $src.Dispose()
280
282
  Write-Host "Icon written"
281
- `.trim();try{await e(`powershell -NoProfile -NonInteractive -Command "${k.replace(/"/g,'\\"').replace(/\n/g,"; ")}"`),console.log("Icon created.")}catch(w){console.warn("Could not create icon (PowerShell/System.Drawing failed):",w)}}const b=u.existsSync(i)?`$s.IconLocation = '${i.replace(/\\/g,"\\\\")}'`:"",j=k=>`
283
+ `.trim();try{await e(`powershell -NoProfile -NonInteractive -Command "${f.replace(/"/g,'\\"').replace(/\n/g,"; ")}"`),console.log("Icon created.")}catch(g){console.warn("Could not create icon (PowerShell/System.Drawing failed):",g)}}const j=d.existsSync(i)?`$s.IconLocation = '${i.replace(/\\/g,"\\\\")}'`:"",k=f=>`
282
284
  $ws = New-Object -ComObject WScript.Shell
283
- $s = $ws.CreateShortcut('${k.replace(/\\/g,"\\\\")}')
285
+ $s = $ws.CreateShortcut('${f.replace(/\\/g,"\\\\")}')
284
286
  $s.TargetPath = 'wscript.exe'
285
287
  $s.Arguments = '//B "${a.replace(/\\/g,"\\\\")}"'
286
288
  $s.WorkingDirectory = '${s.replace(/\\/g,"\\\\")}'
287
289
  $s.Description = 'Jivam - AI Agent UI'
288
- ${b}
290
+ ${j}
289
291
  $s.Save()
290
- `.trim();try{u.mkdirSync(l,{recursive:!0});for(const k of[c,d]){const w=j(k);await e(`powershell -NoProfile -NonInteractive -Command "${w.replace(/"/g,'\\"').replace(/\n/g,"; ")}"`)}console.log(`Created Desktop shortcut: ${c}`),console.log(`Created Start Menu entry: ${d}`)}catch(k){console.warn("Could not create shortcuts:",k)}console.log(`
291
- Done! Double-click the Jivam icon on your Desktop to launch.`),console.log("The server runs continuously in the background — manage it with:"),console.log(" jivam stop jivam start jivam restart jivam status"),process.exit(0)}const B=__dirname,I=E();I.use(E.json({limit:"50mb"}));const G=new wt,Oe=new gt,Je=new vt;I.use("/api/setup",Pe);I.use("/api/config",H);I.use("/api/conversations",ge);I.use("/api/git",U);I.use("/api/directive",ye);I.use("/api/workspace",_);I.use("/api/jiva",kt(G,Je));I.use("/api/personas",$t(G));I.use("/api/mcp",Mt(G));I.use("/api/code",At(Oe));I.use("/api/files",Nt(G));I.use("/api/cloud",Ht(Je));I.get("/api/platform",(r,n)=>n.json(process.platform));I.get("/api/version",(r,n)=>{try{const e=JSON.parse(u.readFileSync(m.join(B,"..","package.json"),"utf-8"));n.json(e.version)}catch{n.json("0.0.0")}});if(!Te){const r=m.join(B,"..","dist");u.existsSync(r)&&(I.use(E.static(r)),I.get(/(.*)/,(n,e)=>{e.sendFile(m.join(r,"index.html"))}))}async function sn(r){const{execFile:n,exec:e}=await import("child_process"),{promisify:t}=await import("util"),s=t(e),o=(process.env.JIVAM_BROWSER??"").toLowerCase();if(process.platform==="darwin"){if(o!=="chrome"&&o!=="edge"&&o!=="brave"){const a=[m.join(S.homedir(),"Applications","Safari Apps","Jivam.app"),m.join(S.homedir(),"Applications","Jivam.app"),"/Applications/Jivam.app"];for(const i of a)if(u.existsSync(i))try{await s(`open "${i}"`),console.log(`Launched Safari PWA: ${i}`);return}catch{}}if(o==="safari")try{await s(`osascript -e 'tell application "Safari" to open location "${r}"' -e 'tell application "Safari" to activate'`),console.log("Opened in Safari (tip: File → Add to Dock for app experience)");return}catch(a){console.error("Failed to open Safari:",a)}if(o!=="safari"){const a=[["chrome","/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"],["edge","/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"],["brave","/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"]];for(const[i,c]of a)if(!(o&&o!==i))try{n(c,[`--app=${r}`,"--disable-extensions"]),console.log(`Opened in app-mode window: ${c}`);return}catch{}}if(!o)try{await s(`osascript -e 'tell application "Safari" to open location "${r}"' -e 'tell application "Safari" to activate'`),console.log("Opened in Safari (tip: File → Add to Dock for app experience)");return}catch{}}else if(process.platform==="win32"){const a=[["msedge",[`--app=${r}`]],["chrome",[`--app=${r}`]],["brave",[`--app=${r}`]]];for(const[i,c]of a)try{n(`start ${i}`,c,{shell:!0});return}catch{}try{await s(`start "" "${r}"`);return}catch{}}else{const a=[["google-chrome",[`--app=${r}`]],["google-chrome-stable",[`--app=${r}`]],["chromium-browser",[`--app=${r}`]],["chromium",[`--app=${r}`]],["brave-browser",[`--app=${r}`]],["microsoft-edge",[`--app=${r}`]]];for(const[i,c]of a)try{n(i,c);return}catch{}}try{const{default:a}=await import("open");await a(r),console.log(`Opened in default browser: ${r}`)}catch(a){console.error("Could not open browser automatically:",a),console.log(`Open manually: ${r}`)}}function rn(){const n=async()=>{try{const{exec:e}=await import("child_process"),{promisify:t}=await import("util"),s=t(e),o=JSON.parse(u.readFileSync(m.join(B,"..","package.json"),"utf-8")),{stdout:a}=await s("npm view jivamai version"),i=a.trim();if(i&&i!==o.version){console.log(`Update available: jivamai ${o.version} → ${i}. Updating...`),await s("npm install -g jivamai jiva-core"),console.log("Update installed — restarting to pick it up."),process.exit(1);return}}catch(e){console.warn("Update check failed (probably offline):",e)}setTimeout(n,864e5)};setTimeout(n,864e5)}const z=process.argv[2],on=z==="start"||z==="stop"||z==="restart"||z==="status";if(process.argv.includes("--install"))(process.platform==="win32"?nn:Qt)().catch(n=>{console.error(n),process.exit(1)});else if(on)(process.platform==="win32"?_e:Re)(z).then(()=>process.exit(0)).catch(n=>{console.error(n),process.exit(1)});else{const r=process.argv.includes("--server-only"),n=Qe.createServer(I);tt(n),n.listen(W,"127.0.0.1",async()=>{const t=`http://localhost:${W}`;console.log(`Jivam server running at ${t}`),!Te&&!r&&await sn(t),r&&rn()});async function e(){await G.cleanup(),await Oe.cleanup(),n.close(),process.exit(0)}process.on("SIGINT",e),process.on("SIGTERM",e)}
292
+ `.trim();try{d.mkdirSync(l,{recursive:!0});for(const f of[c,p]){const g=k(f);await e(`powershell -NoProfile -NonInteractive -Command "${g.replace(/"/g,'\\"').replace(/\n/g,"; ")}"`)}console.log(`Created Desktop shortcut: ${c}`),console.log(`Created Start Menu entry: ${p}`)}catch(f){console.warn("Could not create shortcuts:",f)}console.log(`
293
+ Done! Double-click the Jivam icon on your Desktop to launch.`),process.exit(0)}const U=__dirname,P=I();P.use(I.json({limit:"50mb"}));const W=new pt,Ae=new ut,De=new mt;P.use("/api/setup",$e);P.use("/api/config",z);P.use("/api/conversations",me);P.use("/api/git",q);P.use("/api/directive",he);P.use("/api/workspace",F);P.use("/api/jiva",ft(W,De));P.use("/api/personas",St(W));P.use("/api/mcp",jt(W));P.use("/api/code",bt(Ae));P.use("/api/files",_t(W));P.use("/api/cloud",Nt(De));P.get("/api/platform",(r,t)=>t.json(process.platform));P.get("/api/version",(r,t)=>{try{const e=JSON.parse(d.readFileSync(u.join(U,"..","package.json"),"utf-8"));t.json(e.version)}catch{t.json("0.0.0")}});if(!Ie){const r=u.join(U,"..","dist");d.existsSync(r)&&(P.use(I.static(r)),P.get(/(.*)/,(t,e)=>{e.sendFile(u.join(r,"index.html"))}))}async function zt(r){const{execFile:t,exec:e}=await import("child_process"),{promisify:n}=await import("util"),s=n(e),o=(process.env.JIVAM_BROWSER??"").toLowerCase();if(process.platform==="darwin"){if(o!=="chrome"&&o!=="edge"&&o!=="brave"){const a=[u.join(b.homedir(),"Applications","Safari Apps","Jivam.app"),u.join(b.homedir(),"Applications","Jivam.app"),"/Applications/Jivam.app"];for(const i of a)if(d.existsSync(i))try{await s(`open "${i}"`),console.log(`Launched Safari PWA: ${i}`);return}catch{}}if(o==="safari")try{await s(`osascript -e 'tell application "Safari" to open location "${r}"' -e 'tell application "Safari" to activate'`),console.log("Opened in Safari (tip: File → Add to Dock for app experience)");return}catch(a){console.error("Failed to open Safari:",a)}if(o!=="safari"){const a=[["chrome","/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"],["edge","/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"],["brave","/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"]];for(const[i,c]of a)if(!(o&&o!==i))try{t(c,[`--app=${r}`,"--disable-extensions"]),console.log(`Opened in app-mode window: ${c}`);return}catch{}}if(!o)try{await s(`osascript -e 'tell application "Safari" to open location "${r}"' -e 'tell application "Safari" to activate'`),console.log("Opened in Safari (tip: File → Add to Dock for app experience)");return}catch{}}else if(process.platform==="win32"){const a=[["msedge",[`--app=${r}`]],["chrome",[`--app=${r}`]],["brave",[`--app=${r}`]]];for(const[i,c]of a)try{t(`start ${i}`,c,{shell:!0});return}catch{}try{await s(`start "" "${r}"`);return}catch{}}else{const a=[["google-chrome",[`--app=${r}`]],["google-chrome-stable",[`--app=${r}`]],["chromium-browser",[`--app=${r}`]],["chromium",[`--app=${r}`]],["brave-browser",[`--app=${r}`]],["microsoft-edge",[`--app=${r}`]]];for(const[i,c]of a)try{t(i,c);return}catch{}}try{const{default:a}=await import("open");await a(r),console.log(`Opened in default browser: ${r}`)}catch(a){console.error("Could not open browser automatically:",a),console.log(`Open manually: ${r}`)}}if(process.argv.includes("--install"))(process.platform==="win32"?Lt:qt)().catch(t=>{console.error(t),process.exit(1)});else{const r=Ge.createServer(P);Ye(r),r.listen(be,"127.0.0.1",async()=>{const e=`http://localhost:${be}`;console.log(`Jivam server running at ${e}`),Ie||await zt(e)});async function t(){await W.cleanup(),await Ae.cleanup(),r.close(),process.exit(0)}process.on("SIGINT",t),process.on("SIGTERM",t)}
292
294
  //# sourceMappingURL=index.js.map