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.
- package/dist/manifest.json +0 -1
- package/dist-electron/main.js +131 -0
- package/dist-electron/main.js.map +1 -0
- package/dist-electron/preload.js +2 -0
- package/dist-electron/preload.js.map +1 -0
- package/dist-server/index.js +145 -143
- package/dist-server/index.js.map +1 -1
- package/dist-server/manifest.json +0 -1
- package/package.json +1 -1
- package/public/manifest.json +0 -1
package/dist-server/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
"use strict";var
|
|
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
|
-
${
|
|
4
|
-
`)}`;const
|
|
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: ${
|
|
9
|
-
- ISO: ${
|
|
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
|
-
${
|
|
17
|
+
${S}
|
|
18
18
|
`;return r!=null&&r.trim()?r.trim()+`
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
`+
|
|
23
|
-
`)){const s=
|
|
24
|
-
`);for(const
|
|
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}`,
|
|
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"}]}`,
|
|
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
|
|
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
|
-
${
|
|
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
|
|
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
|
-
${
|
|
83
|
+
${t}
|
|
84
84
|
|
|
85
|
-
Write an improved version of the task prompt that is more likely to succeed.`;try{const i=await
|
|
86
|
-
Task description: ${
|
|
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
|
|
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
|
|
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
|
|
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}`:"";
|
|
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{
|
|
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
|
-
${
|
|
101
|
+
${y.followUp}
|
|
102
102
|
|
|
103
103
|
Original request:
|
|
104
104
|
${r}
|
|
105
105
|
|
|
106
106
|
Previous work summary:
|
|
107
|
-
${
|
|
108
|
-
|
|
109
|
-
Please address the missing parts specifically.`;let
|
|
110
|
-
`)){const
|
|
111
|
-
`)){const
|
|
112
|
-
`);c=
|
|
113
|
-
`).filter(Boolean).map(s=>({status:s.slice(0,2).trim(),file:s.slice(3).trim()})))}catch{
|
|
114
|
-
`);return i[i.length-1]===""&&i.pop(),
|
|
115
|
-
+++ b/${
|
|
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:
|
|
121
|
-
|
|
122
|
-
${s}`;return{name:
|
|
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&&
|
|
124
|
-
|
|
125
|
-
${o}`;return{name:
|
|
126
|
-
|
|
127
|
-
`)}function
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
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
|
-
|
|
221
|
-
Done! Click the Jivam icon in your Dock to launch.`),
|
|
222
|
-
`)[0].trim()
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
`,
|
|
269
|
+
`,M=`Set oShell = CreateObject("WScript.Shell")
|
|
268
270
|
oShell.Run Chr(34) & "${o.replace(/\\/g,"\\\\")}" & Chr(34), 0, False
|
|
269
|
-
`;
|
|
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('${
|
|
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 "${
|
|
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('${
|
|
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
|
-
${
|
|
290
|
+
${j}
|
|
289
291
|
$s.Save()
|
|
290
|
-
`.trim();try{
|
|
291
|
-
Done! Double-click the Jivam icon on your Desktop to launch.`),
|
|
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
|