jivamai 0.1.4-dev.63d462c → 0.1.4-dev.edce8f4
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-server/index.js +50 -50
- package/dist-server/index.js.map +1 -1
- package/package.json +1 -1
package/dist-server/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
"use strict";var He=Object.create;var
|
|
1
|
+
"use strict";var He=Object.create;var ie=Object.defineProperty;var Ge=Object.getOwnPropertyDescriptor;var Ve=Object.getOwnPropertyNames;var Ye=Object.getPrototypeOf,Ke=Object.prototype.hasOwnProperty;var Xe=(r,n,e)=>n in r?ie(r,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[n]=e;var Ze=(r,n,e,t)=>{if(n&&typeof n=="object"||typeof n=="function")for(let s of Ve(n))!Ke.call(r,s)&&s!==e&&ie(r,s,{get:()=>n[s],enumerable:!(t=Ge(n,s))||t.enumerable});return r};var C=(r,n,e)=>(e=r!=null?He(Ye(r)):{},Ze(n||!r||!r.__esModule?ie(e,"default",{value:r,enumerable:!0}):e,r));var x=(r,n,e)=>Xe(r,typeof n!="symbol"?n+"":n,e);const $=require("child_process"),u=require("fs"),S=require("os"),m=require("path"),E=require("express"),Qe=require("http"),$e=require("ws"),Me=require("events"),me=require("url"),pe=require("zlib");function et(){if(process.platform==="win32")return;try{const o=process.env.SHELL??"/bin/zsh",a=$.execSync(`${o} -l -c 'echo $PATH'`,{timeout:3e3}).toString().trim();if(a){process.env.PATH=a;return}}catch{}const r=S.homedir(),n=["/usr/local/bin","/opt/homebrew/bin","/opt/local/bin",`${r}/.npm-global/bin`,"/usr/local/opt/node/bin"];try{const o=m.join(r,".nvm","versions","node");if(u.existsSync(o)){const a=u.readdirSync(o).sort().reverse()[0];a&&n.push(m.join(o,a,"bin"))}}catch{}const e=process.env.PATH??"",t=new Set(e.split(":").filter(Boolean)),s=n.filter(o=>!t.has(o));s.length&&(process.env.PATH=[...s,e].join(":"))}let fe=null;const te=new Set;function tt(r){fe=new $e.WebSocketServer({server:r,path:"/ws"}),fe.on("connection",(n,e)=>{te.add(n),n.on("close",()=>te.delete(n)),n.on("error",()=>te.delete(n))})}function O(r,n){if(!fe)return;const e=JSON.stringify({type:r,...n!==null&&typeof n=="object"?n:{data:n}});for(const t of te)t.readyState===$e.WebSocket.OPEN&&t.send(e)}const ne=m.join(S.homedir(),".jiva"),ce=m.join(ne,"jiva-directive.md"),le=m.join(ne,"conversations");function nt(r=5){try{return u.existsSync(le)?u.readdirSync(le).filter(e=>e.endsWith(".json")).map(e=>{const t=m.join(le,e);try{const s=u.statSync(t),o=JSON.parse(u.readFileSync(t,"utf-8")),a=Array.isArray(o.messages)?o.messages.length:0;let i=o.summary??o.title??"";if(!i&&Array.isArray(o.messages)){const c=o.messages.find(l=>l.role==="user");c!=null&&c.content&&(i=String(c.content).slice(0,60).replace(/\n/g," "),String(c.content).length>60&&(i+="..."))}return i=i||"Untitled conversation",{stat:s,title:i,messageCount:a}}catch{return null}}).filter(Boolean).sort((e,t)=>t.stat.mtimeMs-e.stat.mtimeMs).slice(0,r).map(({stat:e,title:t,messageCount:s})=>{const o=new Date(e.mtimeMs);return{date:`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}-${String(o.getDate()).padStart(2,"0")} ${String(o.getHours()).padStart(2,"0")}:${String(o.getMinutes()).padStart(2,"0")}`,title:t,messageCount:s}}):[]}catch{return[]}}function st(r){var f;const n=new Date,e=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],t=["January","February","March","April","May","June","July","August","September","October","November","December"],s=e[n.getDay()],o=t[n.getMonth()],a=n.getDate(),i=n.getFullYear(),c=String(n.getHours()).padStart(2,"0"),l=String(n.getMinutes()).padStart(2,"0"),d=`${c}:${l}`;let p="UTC";try{p=((f=Intl.DateTimeFormat("en",{timeZoneName:"short"}).formatToParts(n).find(g=>g.type==="timeZoneName"))==null?void 0:f.value)??"UTC"}catch{const g=-n.getTimezoneOffset(),b=g>=0?"+":"-",j=String(Math.floor(Math.abs(g)/60)).padStart(2,"0"),k=String(Math.abs(g)%60).padStart(2,"0");p=`UTC${b}${j}:${k}`}const h=n.toISOString(),y=nt(5);let v;y.length===0?v="_No previous sessions found._":v=`| Date | Title | Messages |
|
|
2
2
|
|------|-------|----------|
|
|
3
|
-
${y.map(
|
|
3
|
+
${y.map(b=>`| ${b.date} | "${b.title}" | ${b.messageCount} |`).join(`
|
|
4
4
|
`)}`;const A=`# Jiva Operating Context
|
|
5
5
|
|
|
6
6
|
## Current Date & Time
|
|
7
|
-
- Date: ${s}, ${o} ${
|
|
7
|
+
- Date: ${s}, ${o} ${a}, ${i}
|
|
8
8
|
- Time: ${d} ${p}
|
|
9
9
|
- ISO: ${h}
|
|
10
10
|
|
|
11
11
|
## Important
|
|
12
12
|
- Always use the date above when referencing "today", "current year", or "recent" events
|
|
13
13
|
- Do NOT rely on training data for the current date — use only what is stated above
|
|
14
|
-
- When performing web searches, always use the year ${
|
|
14
|
+
- When performing web searches, always use the year ${i} for current events
|
|
15
15
|
|
|
16
16
|
## Recent Session Activity
|
|
17
17
|
${v}
|
|
@@ -20,14 +20,14 @@ ${v}
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
22
|
`+A:A}function he(r){const n=st(r);try{u.existsSync(ne)||u.mkdirSync(ne,{recursive:!0}),u.writeFileSync(ce,n,"utf-8"),console.log(`[DirectiveManager] Wrote directive to ${ce}`)}catch(e){console.warn("[DirectiveManager] Failed to write directive:",e)}return{path:ce,content:n}}function N(){return m.join(S.homedir(),".jivam","config.json")}function rt(){return N()}N();function P(){try{const r=N();if(u.existsSync(r)){const n=u.readFileSync(r,"utf-8");return JSON.parse(n)}return null}catch(r){return console.error("[ConfigManager] Failed to read config:",r),null}}function R(r){try{const n=N(),e=m.dirname(n);return u.existsSync(e)||u.mkdirSync(e,{recursive:!0}),u.writeFileSync(n,JSON.stringify(r,null,2),"utf-8"),!0}catch(n){return console.error("[ConfigManager] Failed to write config:",n),!1}}let ue=null;function ot(r){const n=/^---\s*\n([\s\S]*?)\n---/.exec(r);if(!n)return{};const e={};for(const t of n[1].split(`
|
|
23
|
-
`)){const s=t.indexOf(":");if(s===-1)continue;const o=t.slice(0,s).trim(),
|
|
24
|
-
`);for(const t of e){const s=t.replace(/^#+\s*/,"").replace(/\*\*/g,"").trim();if(s.length>=20)return s.length>n?s.slice(0,n-1)+"…":s}return r.slice(0,n)}async function lt(r,n,e,t,s,o){const
|
|
25
|
-
`):"(none available)",
|
|
23
|
+
`)){const s=t.indexOf(":");if(s===-1)continue;const o=t.slice(0,s).trim(),a=t.slice(s+1).trim().replace(/^["']|["']$/g,"");o&&(e[o]=a)}return e}async function at(){if(ue!==null)return ue;const r=[m.join(S.homedir(),".claude","skills"),m.join(S.homedir(),".jiva","skills")],n=[];for(const e of r){if(!u.existsSync(e))continue;let t;try{t=u.readdirSync(e,{withFileTypes:!0})}catch{continue}for(const s of t){if(!s.isDirectory())continue;const o=m.join(e,s.name),a=m.join(o,"SKILL.md");if(u.existsSync(a))try{const i=u.readFileSync(a,"utf-8"),c=ot(i),l=c.name??s.name,d=c.description??"";n.push({name:l,description:d,dir:o})}catch{}}}return ue=n,n}function M(r,n){n({timestamp:new Date().toISOString(),level:"info",tag:"brain",message:r})}const it=new Set(["thanks","thank","you","ty","ok","okay","alright","right","sure","yep","yup","yeah","nope","great","good","nice","cool","perfect","awesome","excellent","fantastic","wonderful","brilliant","well","done","job","work","bye","goodbye","later","cheers","ciao","welcome","problem","np","worries","no","we","are","were","finished","this","is","the","end","session","all","that","it","for","our","now","here","got","sounds","lol","haha","heh","wow","oh","ah","hmm","a","an","and","or","but","very","much","so","yes","s"]);function ct(r){const n=r.trim();if(n.length>80)return!1;const e=n.toLowerCase().replace(/[^a-z'\s]/g,"").trim().split(/\s+/);return e.length===0||e.length>12?!1:e.every(t=>it.has(t))}function ve(r,n=140){const e=r.split(`
|
|
24
|
+
`);for(const t of e){const s=t.replace(/^#+\s*/,"").replace(/\*\*/g,"").trim();if(s.length>=20)return s.length>n?s.slice(0,n-1)+"…":s}return r.slice(0,n)}async function lt(r,n,e,t,s,o){const a=n.length>0?n.map(h=>`- ${h.name} (${h.dir}): ${h.description}`).join(`
|
|
25
|
+
`):"(none available)",i=s?`
|
|
26
26
|
Conversation history so far:
|
|
27
27
|
${s}
|
|
28
28
|
`:"",c=o&&o.length>0?`
|
|
29
29
|
Configured MCP servers (tools the agent already has access to): ${o.join(", ")}`:`
|
|
30
|
-
Configured MCP servers: none beyond built-in filesystem and shell.`,l=`You are a senior AI coordinator. Your first job is to decide whether to answer the user DIRECTLY or DELEGATE the task to a capable AI coding worker.${
|
|
30
|
+
Configured MCP servers: none beyond built-in filesystem and shell.`,l=`You are a senior AI coordinator. Your first job is to decide whether to answer the user DIRECTLY or DELEGATE the task to a capable AI coding worker.${i}
|
|
31
31
|
ANSWER DIRECTLY (mode: "direct") when the message is:
|
|
32
32
|
- Conversational: greetings, thanks, sign-offs, "great work", "we're done", smalltalk
|
|
33
33
|
- Simple follow-up you can answer from the conversation context above ("what did you find?", "how many issues?")
|
|
@@ -53,48 +53,48 @@ ${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
|
-
${
|
|
56
|
+
${a}`,d=`User message:
|
|
57
57
|
${r}
|
|
58
58
|
|
|
59
59
|
Respond with JSON exactly (use the mode that fits):
|
|
60
60
|
{"mode":"direct","reasoning":"one sentence","explanation":"1-2 sentences for the user","directResponse":"full warm response to the user","subtasks":[]}
|
|
61
61
|
OR
|
|
62
|
-
{"mode":"delegate","reasoning":"one sentence","explanation":"1-2 sentences for the user","subtasks":[{"id":1,"label":"short 3-6 word label","prompt":"full focused self-contained prompt","complexity":"simple|medium|complex"}],"mcpRecommendations":[{"name":"server-name","reason":"why it helps"}]}`,p={mode:"delegate",reasoning:"Proceeding as a single task",explanation:"On it...",subtasks:[{id:1,label:"completing your request",prompt:r}]};try{const h=await e(l,d);if(!h)return p;const y=h.trim().replace(/^```json\s*|\s*```$/g,""),v=JSON.parse(y),A=v.mode==="direct"?"direct":"delegate",f=typeof v.reasoning=="string"?v.reasoning:"",g=typeof v.explanation=="string"&&v.explanation?v.explanation:A==="direct"?"Answering this directly.":"Handling this as a single focused task.",
|
|
63
|
-
${
|
|
62
|
+
{"mode":"delegate","reasoning":"one sentence","explanation":"1-2 sentences for the user","subtasks":[{"id":1,"label":"short 3-6 word label","prompt":"full focused self-contained prompt","complexity":"simple|medium|complex"}],"mcpRecommendations":[{"name":"server-name","reason":"why it helps"}]}`,p={mode:"delegate",reasoning:"Proceeding as a single task",explanation:"On it...",subtasks:[{id:1,label:"completing your request",prompt:r}]};try{const h=await e(l,d);if(!h)return p;const y=h.trim().replace(/^```json\s*|\s*```$/g,""),v=JSON.parse(y),A=v.mode==="direct"?"direct":"delegate",f=typeof v.reasoning=="string"?v.reasoning:"",g=typeof v.explanation=="string"&&v.explanation?v.explanation:A==="direct"?"Answering this directly.":"Handling this as a single focused task.",b=Array.isArray(v.mcpRecommendations)?v.mcpRecommendations.filter(w=>typeof w.name=="string"&&w.name.trim()).map(w=>({name:w.name,reason:typeof w.reason=="string"?w.reason:""})):void 0;if(A==="direct"){const w=typeof v.directResponse=="string"?v.directResponse:"";return{mode:"direct",reasoning:f,explanation:g,directResponse:w,subtasks:[],mcpRecommendations:b}}if(!Array.isArray(v.subtasks)||v.subtasks.length===0)return p;const j=v.subtasks.filter(w=>typeof w.label=="string"&&typeof w.prompt=="string").map((w,D)=>({id:typeof w.id=="number"?w.id:D+1,label:w.label,prompt:w.prompt,complexity:w.complexity==="simple"||w.complexity==="medium"||w.complexity==="complex"?w.complexity:"medium"}));return j.length===0?p:{mode:"delegate",reasoning:f,explanation:g,subtasks:j,mcpRecommendations:b}}catch{return p}}async function Se(r,n,e,t){M("Pulling everything together...",t);const s="You are a technical writer. Synthesize the outputs of multiple completed subtasks into one coherent final response to the user's original request. Be concise. Do not repeat implementation details — reference them. Markdown is fine.",o=n.map((i,c)=>`### Subtask ${c+1}: ${i.label}
|
|
63
|
+
${i.content}`).join(`
|
|
64
64
|
|
|
65
|
-
`),
|
|
65
|
+
`),a=`Original request:
|
|
66
66
|
${r}
|
|
67
67
|
|
|
68
68
|
Subtask results:
|
|
69
69
|
|
|
70
70
|
${o}
|
|
71
71
|
|
|
72
|
-
Write the final synthesized response.`;try{const
|
|
72
|
+
Write the final synthesized response.`;try{const i=await e(s,a);if(i)return i}catch{}return n[n.length-1].content}async function ut(r,n,e,t){M("Checking the result...",t);const s="You are verifying whether an AI agent fully completed a task. Be strict but fair — if the core request was addressed, mark it satisfied. Only mark unsatisfied if something specific and important was clearly missed or left incomplete. Respond with valid JSON only, no markdown fences.",o=`Original request:
|
|
73
73
|
${r}
|
|
74
74
|
|
|
75
75
|
Agent output (truncated to 2000 chars):
|
|
76
76
|
${n.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"}`,
|
|
79
|
+
{"satisfied":true,"follow_up":"empty if satisfied, otherwise a precise description of what is still missing"}`,a={satisfied:!0,followUp:""};try{const i=await e(s,o);if(!i)return a;const c=i.trim().replace(/^```json\s*|\s*```$/g,""),l=JSON.parse(c);return{satisfied:l.satisfied!==!1,followUp:typeof l.follow_up=="string"?l.follow_up:""}}catch{return a}}function dt(r,n){switch(r){case"simple":return Math.max(10,Math.floor(n*.4));case"complex":return Math.min(n*2,200);default:return n}}async function ke(r,n,e,t,s){M(`Adjusting my approach (attempt ${e})...`,s);const o="You are helping recover from a failed AI agent execution. The agent was given a task but encountered an error. Rewrite the task prompt to be more explicit, simpler, or to work around the failure. Do not include meta-commentary — output only the revised prompt text.",a=`Original task:
|
|
80
80
|
${r}
|
|
81
81
|
|
|
82
82
|
Error encountered:
|
|
83
83
|
${n}
|
|
84
84
|
|
|
85
|
-
Write an improved version of the task prompt that is more likely to succeed.`;try{const
|
|
85
|
+
Write an improved version of the task prompt that is more likely to succeed.`;try{const i=await t(o,a);if(i&&i.trim().length>20)return i.trim()}catch{}return r}async function be(r,n,e,t,s){M(`Ran into trouble with "${r}" — here's what happened:`,s);const o="You are a helpful AI assistant explaining a task failure to the user. Be concise, honest, and constructive. Do not expose raw error messages or stack traces. Explain what was attempted, what went wrong at a high level, and suggest what the user could try next. Use plain Markdown.",a=`Task attempted: ${r}
|
|
86
86
|
Task description: ${n}
|
|
87
87
|
Error: ${e}
|
|
88
88
|
|
|
89
|
-
Write a short, user-friendly explanation of what happened and what could be done next.`;try{const
|
|
89
|
+
Write a short, user-friendly explanation of what happened and what could be done next.`;try{const i=await t(o,a);if(i&&i.trim().length>20)return i.trim()}catch{}return`I wasn't able to complete the task **"${r}"** after multiple attempts.
|
|
90
90
|
|
|
91
91
|
The worker ran into an issue: ${e.slice(0,200)}${e.length>200?"…":""}
|
|
92
92
|
|
|
93
|
-
You may want to check your configuration or try rephrasing the request.`}const mt=[/\bplanned subtask for the worker\b/i,/\bplease proceed with this subtask\b/i,/\bonce the results are returned,?\s+i will\b/i,/\bi will review them and provide the final response\b/i,/\bprovide the final response to the user\b/i];function pt(r){const n=r.slice(0,600);return mt.some(e=>e.test(n))}const Q=2;async function Ae(r,n,e,t,s=50,o,
|
|
93
|
+
You may want to check your configuration or try rephrasing the request.`}const mt=[/\bplanned subtask for the worker\b/i,/\bplease proceed with this subtask\b/i,/\bonce the results are returned,?\s+i will\b/i,/\bi will review them and provide the final response\b/i,/\bprovide the final response to the user\b/i];function pt(r){const n=r.slice(0,600);return mt.some(e=>e.test(n))}const Q=2;async function Ae(r,n,e,t,s=50,o,a){const i=await at();if(M("Thinking...",t),ct(r)){const f=o?`
|
|
94
94
|
Conversation history:
|
|
95
|
-
${o}`:"";let g;try{g=await n(`You are a warm, helpful AI assistant. Reply naturally and concisely. Markdown is fine.${f}`,r)??"You're welcome!"}catch{g="You're welcome!"}return{content:g,toolsUsed:[],iterations:0,plan:{subtasks:[],reasoning:"Conversational response"}}}const c=await lt(r,
|
|
95
|
+
${o}`:"";let g;try{g=await n(`You are a warm, helpful AI assistant. Reply naturally and concisely. Markdown is fine.${f}`,r)??"You're welcome!"}catch{g="You're welcome!"}return{content:g,toolsUsed:[],iterations:0,plan:{subtasks:[],reasoning:"Conversational response"}}}const c=await lt(r,i,n,t,o,a);if(c.mode==="direct"){let f=c.directResponse??"";if(!f.trim())try{const g=o?`
|
|
96
96
|
Conversation history:
|
|
97
|
-
${o}`:"";f=await n(`You are a warm, helpful AI assistant. Answer the user's message naturally and concisely. Markdown is fine.${g}`,r)??"Got it!"}catch{f="Got it!"}return{content:f,toolsUsed:[],iterations:0,plan:{subtasks:[],reasoning:c.reasoning}}}if(M(c.explanation,t),c.mcpRecommendations&&c.mcpRecommendations.length>0){M("💡 You could get better results by adding these MCP servers:",t);for(const f of c.mcpRecommendations)M(` • **${f.name}** — ${f.reason}`,t);M("Browse https://mcpservers.org to find them, then add via Settings (⚙️) → MCPs.",t)}const l=c.subtasks.length;if(l>1){const f=c.subtasks.map((g,
|
|
97
|
+
${o}`:"";f=await n(`You are a warm, helpful AI assistant. Answer the user's message naturally and concisely. Markdown is fine.${g}`,r)??"Got it!"}catch{f="Got it!"}return{content:f,toolsUsed:[],iterations:0,plan:{subtasks:[],reasoning:c.reasoning}}}if(M(c.explanation,t),c.mcpRecommendations&&c.mcpRecommendations.length>0){M("💡 You could get better results by adding these MCP servers:",t);for(const f of c.mcpRecommendations)M(` • **${f.name}** — ${f.reason}`,t);M("Browse https://mcpservers.org to find them, then add via Settings (⚙️) → MCPs.",t)}const l=c.subtasks.length;if(l>1){const f=c.subtasks.map((g,b)=>`${b+1}. ${g.label}`).join(" · ");M(`My plan: ${f}`,t)}const d=[];for(const f of c.subtasks){M(`Working on step ${f.id}: ${f.label}...`,t);const g=dt(f.complexity,s);let b=null,j="";for(let k=1;k<=Q;k++)try{const w=k===1?f.prompt:await ke(f.prompt,j,k,n,t),D=Date.now(),L=setInterval(()=>{const T=Math.round((Date.now()-D)/1e3);M(`Still at it (${T}s)…`,t)},25e3);try{b=await e(w,{maxIterations:g})}finally{clearInterval(L)}break}catch(w){j=w instanceof Error?w.message:String(w),k<Q?M("Hit a snag — let me try a different approach...",t):b={content:await be(f.label,f.prompt,j,n,t),toolsUsed:[],iterations:0}}if(l>1){const k=ve(b.content);k&&M(`Step ${f.id} done: ${k}`,t)}d.push({...b,label:f.label})}let p;if(l===1?p=d[0].content:p=await Se(r,d.map(f=>({label:f.label,content:f.content})),n,t),pt(p)){M("The worker couldn't complete this one — let me answer directly...",t);const f=o?`
|
|
98
98
|
Conversation history:
|
|
99
99
|
${o}`:"";try{p=await n(`You are a helpful AI assistant. The AI agent encountered a technical issue and could not complete the task using tools. Answer the user's question directly from your knowledge. Be honest if the answer would benefit from live data that you can't access right now. Markdown is fine.${f}`,r)??p}catch{}}const h=await ut(r,p,n,t);if(!h.satisfied&&h.followUp){M("Almost there — one more thing to tackle...",t);const f=`The following was not fully addressed in your previous response:
|
|
100
100
|
|
|
@@ -106,25 +106,25 @@ ${r}
|
|
|
106
106
|
Previous work summary:
|
|
107
107
|
${p.slice(0,800)}
|
|
108
108
|
|
|
109
|
-
Please address the missing parts specifically.`;let g=null,
|
|
110
|
-
`)){const d=Ie(l);if(d){e(d);continue}const p=/(?:tool(?:\s+call)?|calling|executing)[:\s]+([^\s(]+)/i.exec(l.trim());p&&e({timestamp:new Date().toISOString(),level:"info",tag:"CodeAgent",message:`Tool: ${p[1]}`})}return o(i
|
|
111
|
-
`)){const d=Ie(l);if(d){e(d);continue}const p=/(?:tool(?:\s+call)?|calling|executing)[:\s]+([^\s(]+)/i.exec(l.trim());p&&e({timestamp:new Date().toISOString(),level:"info",tag:"jiva",message:`Tool: ${p[1]}`})}return o(i
|
|
112
|
-
`);c=f.pop()??"";for(const g of f){if(g.startsWith("event: ")){y=g.slice(7).trim();continue}if(!g.startsWith("data: "))continue;const
|
|
113
|
-
`).filter(Boolean).map(s=>({status:s.slice(0,2).trim(),file:s.slice(3).trim()})))}catch{n.json([])}});U.get("/diff-file",(r,n)=>{const{dir:e,file:t,status:s}=r.query;try{if(s==="??"){const o=m.join(e,t);try{const
|
|
114
|
-
`);return
|
|
109
|
+
Please address the missing parts specifically.`;let g=null,b="";for(let k=1;k<=Q;k++)try{const w=k===1?f:await ke(f,b,k,n,t);g=await e(w,{maxIterations:s});break}catch(w){b=w instanceof Error?w.message:String(w),k<Q?M("The follow-up hit an issue — trying once more...",t):g={content:await be("follow-up",f,b,n,t),toolsUsed:[],iterations:0}}const j=ve(g.content);j&&M(`That covers it: ${j}`,t),p=await Se(r,[{label:"Initial work",content:p},{label:"Follow-up",content:g.content}],n,t),d.push({...g,label:"follow-up"})}else h.satisfied&&M("All done — here's the result:",t);const y=d.flatMap(f=>f.toolsUsed??[]),v=[...new Set(y)],A=d.reduce((f,g)=>f+(g.iterations??0),0);return{...d[d.length-1],content:p,toolsUsed:v,iterations:A,plan:{subtasks:c.subtasks.map(f=>f.label),reasoning:c.reasoning}}}function ft(){try{const n=$.execSync("npm root -g",{timeout:5e3}).toString().trim(),e=m.join(n,"jiva-core","package.json");if(u.existsSync(e)){const s=JSON.parse(u.readFileSync(e,"utf-8")).main??"dist/index.js";return m.join(n,"jiva-core",s)}}catch{}const r=m.join(S.homedir(),".npm-global","lib","node_modules","jiva-core","dist","index.js");if(u.existsSync(r))return r;throw new Error("Could not find jiva-core. Please run: npm install -g jiva-core")}const ht=/^(\d{4}-\d{2}-\d{2}T[\d:.Z]+)\s+\[(INFO|WARN|ERROR)\]\s+\[(\w+)\]\s+(.+)$/;function Ie(r){const n=ht.exec(r.trim());return n?{timestamp:n[1],level:n[2].toLowerCase(),tag:n[3],message:n[4]}:null}class gt extends Me.EventEmitter{constructor(){super(...arguments);x(this,"agent",null);x(this,"orchestrator",null);x(this,"workspace",null);x(this,"conversationManager",null);x(this,"mcpManager",null);x(this,"codeLogger",null);x(this,"ready",!1);x(this,"deepRun",!1);x(this,"maxIterations",50)}isReady(){return this.ready}getConversationId(){return this.conversationManager?this.conversationManager.currentConversationId??null:null}async initialize(e,t,s){var V,Y;this.deepRun=(s==null?void 0:s.deepRun)??!1,this.maxIterations=(s==null?void 0:s.maxIterations)??50;const o=ft();console.log(`[CodeRunner] Loading jiva-core from: ${o}`);const a=await import(me.pathToFileURL(o).href),{configManager:i,ModelOrchestrator:c,WorkspaceManager:l,ConversationManager:d,CodeAgent:p,MCPServerManager:h,createKrutrimModel:y,createLocalProvider:v,logger:A}=a;this.codeLogger=A??null,i.validateConfig();const f=i.getReasoningModel(),b=y({endpoint:f.endpoint,apiKey:f.apiKey,model:f.defaultModel,type:"reasoning",useHarmonyFormat:f.useHarmonyFormat}),j=c;this.orchestrator=new j({reasoningModel:b});const{path:k}=he((V=P())==null?void 0:V.userDirective),w=l;this.workspace=new w({workspaceDir:e,directivePath:k}),await this.workspace.initialize();const L=await v(),T=d;this.conversationManager=new T(L,this.orchestrator),this.mcpManager=null;const F=t&&t.length>0?t:null;if(F&&h){const oe=h,ae=new oe,K=((Y=P())==null?void 0:Y.mcpServers)??{},X={};for(const q of F)K[q]&&(X[q]=K[q]);await ae.initialize(X),this.mcpManager=ae,console.log(`[CodeRunner] MCP servers loaded: ${F.join(", ")}`)}const re=p;this.agent=new re({orchestrator:this.orchestrator,workspace:this.workspace,conversationManager:this.conversationManager,maxIterations:this.maxIterations,...this.mcpManager&&F?{mcpManager:this.mcpManager,mcpServerNames:F}:{}}),this.ready=!0,console.log(`[CodeRunner] Initialized (maxIterations=${this.maxIterations}, deepRun=${this.deepRun})`)}makeCompleter(){const e=this.orchestrator;return async(t,s)=>{if(typeof e.chat!="function")return null;try{const a=await e.chat.bind(e)({messages:[{role:"system",content:t},{role:"user",content:s}],reasoningEffort:"low"});return(a==null?void 0:a.content)??null}catch(o){return console.warn("[CodeRunner] makeCompleter: chat() failed:",o),null}}}async chat(e,t,s){if((s==null?void 0:s.maxIterations)!==void 0&&s.maxIterations!==this.maxIterations){this.maxIterations=s.maxIterations;try{this.agent.maxIterations=this.maxIterations}catch{}}return(s==null?void 0:s.deepRun)!==!1&&((s==null?void 0:s.deepRun)??this.deepRun)?await Ae(e,this.makeCompleter(),(i,c)=>this.runChatWithIterations(i,t,c==null?void 0:c.maxIterations),i=>t(i),this.maxIterations,(s==null?void 0:s.conversationHistory)||void 0):this.runChat(e,t)}async runChatWithIterations(e,t,s){if(s!==void 0&&s!==this.maxIterations){this.maxIterations=s;try{this.agent.maxIterations=this.maxIterations}catch{}}return this.runChat(e,t)}hookLogger(e){const t=this.codeLogger,s=(a,i,c)=>{const l=a.toLowerCase();e({timestamp:new Date().toISOString(),level:l==="warn"||l==="error"?l:"info",tag:i,message:c})};if(t&&typeof t.on=="function"){const a=(...i)=>{if(i.length>=3&&typeof i[0]=="string")s(i[0],i[1]??"CodeAgent",i[2]);else if(i.length>=2&&typeof i[0]=="string")s("info","CodeAgent",i[1]);else if(i.length>=1&&typeof i[0]=="object"){const c=i[0];s(String(c.level??"info"),String(c.tag??c.name??"CodeAgent"),String(c.message??c.msg??""))}};try{return t.on("log",a),()=>{typeof t.off=="function"?t.off("log",a):typeof t.removeListener=="function"&&t.removeListener("log",a)}}catch{}}if(t)for(const a of["addTransport","addHandler","addSink"]){if(typeof t[a]!="function")continue;const i=a.replace("add","remove"),c={write:l=>{s(String(l.level??"info"),String(l.tag??l.name??"CodeAgent"),String(l.message??l.msg??""))},log:l=>{s(String(l.level??"info"),String(l.tag??l.name??"CodeAgent"),String(l.message??l.msg??""))}};try{return t[a](c),()=>{if(typeof t[i]=="function")try{t[i](c)}catch{}}}catch{}}const o=process.stdout.write.bind(process.stdout);return process.stdout.write=(a,...i)=>{const c=typeof a=="string"?a:Buffer.from(a).toString();for(const l of c.split(`
|
|
110
|
+
`)){const d=Ie(l);if(d){e(d);continue}const p=/(?:tool(?:\s+call)?|calling|executing)[:\s]+([^\s(]+)/i.exec(l.trim());p&&e({timestamp:new Date().toISOString(),level:"info",tag:"CodeAgent",message:`Tool: ${p[1]}`})}return o(a,...i)},()=>{process.stdout.write=o}}async runChat(e,t){var a;if(!this.agent)throw new Error("CodeRunner not initialized");const s=this.agent,o=this.hookLogger(t);try{const i=await s.chat(e);if((a=i.toolsUsed)!=null&&a.length){const c=new Set;for(const l of i.toolsUsed)c.has(l)||(c.add(l),t({timestamp:new Date().toISOString(),level:"info",tag:"CodeAgent",message:`Tool: ${l}`}))}return{content:i.content,toolsUsed:i.toolsUsed??[],iterations:i.iterations??0}}finally{o()}}stop(){this.agent&&this.agent.stop()}async cleanup(){if(this.agent)try{await this.agent.cleanup()}catch(e){console.warn("[CodeRunner] Cleanup error:",e)}if(this.mcpManager)try{await this.mcpManager.cleanup()}catch{}this.agent=null,this.orchestrator=null,this.workspace=null,this.conversationManager=null,this.mcpManager=null,this.ready=!1}}function yt(){try{const n=$.execSync("npm root -g",{timeout:5e3}).toString().trim(),e=m.join(n,"jiva-core","package.json");if(u.existsSync(e)){const s=JSON.parse(u.readFileSync(e,"utf-8")).main??"dist/index.js";return m.join(n,"jiva-core",s)}}catch{}if(process.platform==="win32"){const n=[m.join(process.env.APPDATA??"","npm","node_modules","jiva-core","dist","index.js"),m.join(process.env.LOCALAPPDATA??"","npm","node_modules","jiva-core","dist","index.js"),"C:\\Program Files\\nodejs\\node_modules\\jiva-core\\dist\\index.js"];for(const e of n)if(u.existsSync(e))return e}const r="/Users/abidev/.npm-global/lib/node_modules/jiva-core/dist/index.js";if(u.existsSync(r))return r;throw new Error("Could not find jiva-core. Please ensure it is installed globally: npm install -g jiva-core")}class wt extends Me.EventEmitter{constructor(){super(...arguments);x(this,"status","stopped");x(this,"agent",null);x(this,"orchestrator",null);x(this,"mcpManager",null);x(this,"workspace",null);x(this,"conversationManager",null);x(this,"personaManager",null);x(this,"jivaLogger",null);x(this,"currentPersona",null);x(this,"currentConversationId",null);x(this,"maxIterations",50)}getStatus(){return this.status}getCurrentConversationId(){return this.currentConversationId}async initialize(e){var t,s;this.setStatus("initializing");try{const o=yt();console.log(`[JivaRunner] Loading jiva-core from: ${o}`);const a=await import(me.pathToFileURL(o).href),{MCPServerManager:i,WorkspaceManager:c,ConversationManager:l,ModelOrchestrator:d,DualAgent:p,createKrutrimModel:h,LogLevel:y,logger:v,createLocalProvider:A}=a,f=P();if(!((s=(t=f==null?void 0:f.models)==null?void 0:t.reasoning)!=null&&s.apiKey))throw new Error("Jivam is not configured. Add your API key in Settings → Models.");const g=f.models.reasoning,b=f.models.multimodal,j=h,k=g.defaultModel??g.model??"",w=j({endpoint:g.endpoint,apiKey:g.apiKey,model:k,type:"reasoning",useHarmonyFormat:g.useHarmonyFormat,...g.reasoningEffortStrategy?{reasoningEffortStrategy:g.reasoningEffortStrategy}:{},...g.defaultMaxTokens?{defaultMaxTokens:g.defaultMaxTokens}:{}});let D;if(b!=null&&b.apiKey)try{const Z=b.defaultModel??"";D=j({endpoint:b.endpoint,apiKey:b.apiKey,model:Z,type:"multimodal"})}catch{console.warn("[JivaRunner] Failed to create multimodal model, continuing without vision")}const L=d;this.orchestrator=new L({reasoningModel:w,multimodalModel:D});const T=f.mcpServers??{},F=S.platform()==="win32"?"C:\\Users":"/Users";T.filesystem||(T.filesystem={command:"npx",args:["-y","@modelcontextprotocol/server-filesystem",F],enabled:!0});const re=i;this.mcpManager=new re,await this.mcpManager.initialize(T);const{path:V}=he(f.userDirective),Y=process.cwd(),oe=c;this.workspace=new oe({workspaceDir:Y,directivePath:V}),await this.workspace.initialize();const K=await A(),X=l;this.conversationManager=new X(K,this.orchestrator);const q=m.dirname(o),Ne=m.dirname(q),Ue=m.join(Ne,"dist","personas","persona-manager.js"),{PersonaManager:Le}=await import(me.pathToFileURL(Ue).href);this.personaManager=new Le,await this.personaManager.initialize(e??void 0);const qe=this.personaManager.getPersonaMCPServers();for(const[Z,We]of Object.entries(qe))try{await this.mcpManager.addServer(Z,We)}catch(Be){console.warn(`[JivaRunner] Failed to add persona MCP server '${Z}':`,Be)}const ze=p;this.agent=new ze({orchestrator:this.orchestrator,mcpManager:this.mcpManager,workspace:this.workspace,conversationManager:this.conversationManager,personaManager:this.personaManager,maxSubtasks:20,maxIterations:this.maxIterations,autoSave:!0,condensingThreshold:30}),this.jivaLogger=v,this.currentPersona=e??null,this.setStatus("ready"),console.log("[JivaRunner] Initialized successfully")}catch(o){const a=o instanceof Error?o.message:String(o);throw console.error("[JivaRunner] Initialization failed:",a),this.setStatus("error",a),o}}makeCompleter(){const e=this.orchestrator;return async(t,s)=>{if(typeof e.chat!="function")return null;try{const a=await e.chat.bind(e)({messages:[{role:"system",content:t},{role:"user",content:s}],reasoningEffort:"low"});return(a==null?void 0:a.content)??null}catch(o){return console.warn("[JivaRunner] makeCompleter: chat() failed:",o),null}}}hookLogger(e){const t=this.jivaLogger;if(!t)return()=>{};const s=(a,i,c)=>{const l=a.toLowerCase();e({timestamp:new Date().toISOString(),level:l==="warn"||l==="error"?l:"info",tag:i,message:c})};if(typeof t.on=="function"){const a=(...i)=>{if(i.length>=3&&typeof i[0]=="string")s(i[0],i[1]??"jiva",i[2]);else if(i.length>=2&&typeof i[0]=="string")s("info","jiva",i[1]);else if(i.length>=1&&typeof i[0]=="object"){const c=i[0];s(String(c.level??"info"),String(c.tag??c.name??"jiva"),String(c.message??c.msg??""))}};try{return t.on("log",a),()=>{typeof t.off=="function"?t.off("log",a):typeof t.removeListener=="function"&&t.removeListener("log",a)}}catch{}}for(const a of["addTransport","addHandler","addSink"]){if(typeof t[a]!="function")continue;const i=a.replace("add","remove"),c={write:l=>{s(String(l.level??"info"),String(l.tag??l.name??"jiva"),String(l.message??l.msg??""))},log:l=>{s(String(l.level??"info"),String(l.tag??l.name??"jiva"),String(l.message??l.msg??""))}};try{return t[a](c),()=>{if(typeof t[i]=="function")try{t[i](c)}catch{}}}catch{}}const o=process.stdout.write.bind(process.stdout);return process.stdout.write=(a,...i)=>{const c=typeof a=="string"?a:Buffer.from(a).toString();for(const l of c.split(`
|
|
111
|
+
`)){const d=Ie(l);if(d){e(d);continue}const p=/(?:tool(?:\s+call)?|calling|executing)[:\s]+([^\s(]+)/i.exec(l.trim());p&&e({timestamp:new Date().toISOString(),level:"info",tag:"jiva",message:`Tool: ${p[1]}`})}return o(a,...i)},()=>{process.stdout.write=o}}async runChat(e,t,s){var l,d,p;const o=s?this.hookLogger(s):null,a=this.agent;let i;try{i=await a.chat(e)}finally{o==null||o()}if(s&&((l=i.toolsUsed)!=null&&l.length))for(const h of i.toolsUsed)s({timestamp:new Date().toISOString(),level:"info",tag:"jiva",message:`Tool: ${h}`});let c=null;try{c=((p=(d=this.conversationManager).getCurrentConversationId)==null?void 0:p.call(d))??null}catch{}if(!c)try{c=await this.agent.saveConversation()}catch{}return c&&(this.currentConversationId=c),{content:i.content,iterations:i.iterations,toolsUsed:i.toolsUsed??[],plan:i.plan?{subtasks:i.plan.subtasks??[],reasoning:i.plan.reasoning}:null,durationMs:Date.now()-t,conversationId:this.currentConversationId??void 0}}async chat(e,t,s,o){var l;if(!this.agent)throw new Error("JivaRunner not initialized. Call initialize() first.");if(this.status==="busy")throw new Error("Agent is already processing a request.");if((s==null?void 0:s.maxIterations)!==void 0&&s.maxIterations!==this.maxIterations){this.maxIterations=s.maxIterations;try{this.agent.maxIterations=this.maxIterations}catch{}}this.setStatus("busy");const a=Date.now();t("planning");const i=setTimeout(()=>t("executing"),2e3),c=setTimeout(()=>t("synthesizing"),3e4);try{let d;if((s==null?void 0:s.deepRun)!==!1){const p=Object.keys(((l=P())==null?void 0:l.mcpServers)??{});d=await Ae(e,this.makeCompleter(),(h,y)=>{if((y==null?void 0:y.maxIterations)!==void 0&&y.maxIterations!==this.maxIterations){this.maxIterations=y.maxIterations;try{this.agent.maxIterations=this.maxIterations}catch{}}return this.runChat(h,a,o)},h=>o==null?void 0:o(h),this.maxIterations,(s==null?void 0:s.conversationHistory)||void 0,p)}else d=await this.runChat(e,a,o);return clearTimeout(i),clearTimeout(c),t("done"),this.setStatus("ready"),d}catch(d){throw clearTimeout(i),clearTimeout(c),this.setStatus("ready"),d}}async loadConversation(e){if(!this.agent)throw new Error("JivaRunner not initialized. Call initialize() first.");await this.agent.loadConversation(e),this.currentConversationId=e,console.log(`[JivaRunner] Loaded conversation: ${e}`)}async switchPersona(e){this.agent&&await this.cleanup(),await this.initialize(e)}resetConversation(){this.agent&&this.agent.resetConversation(),this.currentConversationId=null}getMCPTools(){var e,t;if(!this.mcpManager)return{};try{const s=((t=(e=this.mcpManager).getAllTools)==null?void 0:t.call(e))??[],o={};for(const a of s){const i=a.name.split("__"),c=i.length>1?i[0]:"unknown",l=i.length>1?i.slice(1).join("__"):a.name;o[c]||(o[c]=[]),o[c].push({name:l,description:a.description??""})}return o}catch{return{}}}async addMCPServer(e,t){if(!this.mcpManager)throw new Error("MCP manager not initialized");await this.mcpManager.addServer(e,t)}async removeMCPServer(e){if(!this.mcpManager)throw new Error("MCP manager not initialized");const t=this.mcpManager;t.removeServer?await t.removeServer(e):t.disableServer&&await t.disableServer(e)}getMCPServerStatus(){var e,t;if(!this.mcpManager)return[];try{return(((t=(e=this.mcpManager).getServerStatus)==null?void 0:t.call(e))??[]).map(o=>({...o,error:o.error??o.lastError}))}catch{return[]}}async reconnectMCPServer(e){var c,l,d;if(!this.mcpManager)throw new Error("MCP manager not initialized");const t=this.mcpManager;if(typeof t.reconnectServer=="function"){await t.reconnectServer(e);return}if(!this.getMCPServerStatus().find(p=>p.name===e))throw new Error(`MCP server "${e}" not found`);const a=((d=(l=(c=this.mcpManager).getServerStatus)==null?void 0:l.call(c))==null?void 0:d.find(p=>p.name===e))??{};await this.removeMCPServer(e);const i=a.url!=null?{type:"http",url:a.url,env:a.env,enabled:!0}:{type:"stdio",command:a.command,args:a.args,env:a.env,enabled:!0};await this.addMCPServer(e,i)}async toggleMCPServer(e,t){if(!this.mcpManager)throw new Error("MCP manager not initialized");const s=this.mcpManager;t&&s.enableServer?await s.enableServer(e):!t&&s.disableServer&&await s.disableServer(e)}async describeImage(e){var a;if(!this.orchestrator)throw new Error("JivaRunner not initialized. Call initialize() first.");const t=P();if(!((a=t==null?void 0:t.models)!=null&&a.multimodal))throw new Error("No multimodal (vision) model is configured. Enable it in Settings → Models.");return(await this.orchestrator.chat({messages:[{role:"user",content:[{type:"image_url",image_url:{url:e}},{type:"text",text:"Describe this image in detail, including all visible content, text, charts, diagrams, and any notable elements."}]}]})).content}async cleanup(){try{this.agent&&(await this.agent.cleanup(),this.agent=null),this.mcpManager&&(await this.mcpManager.cleanup(),this.mcpManager=null)}catch(e){console.warn("[JivaRunner] Cleanup error:",e)}this.orchestrator=null,this.workspace=null,this.conversationManager=null,this.personaManager=null,this.currentConversationId=null,this.setStatus("stopped")}stop(){this.agent&&this.agent.stop()}setStatus(e,t){this.status=e,this.emit("status-changed",e,{error:t})}}const ee="https://jiva-hdjcuspt2a-uc.a.run.app";class vt{constructor(){x(this,"userId",null);x(this,"sessionId",null);x(this,"_active",!1);x(this,"_abortController",null);x(this,"_readyPromise",null);x(this,"_readyResolve",null);x(this,"_readyReject",null)}startInit(){this._active||this._readyPromise||(this._readyPromise=new Promise((n,e)=>{this._readyResolve=n,this._readyReject=e}))}configure(n,e){var t;this.userId=n,this.sessionId=e,this._active=!0,(t=this._readyResolve)==null||t.call(this),this._readyResolve=null,this._readyReject=null}waitUntilReady(n){return this._active?Promise.resolve():this._readyPromise?Promise.race([this._readyPromise,new Promise((e,t)=>setTimeout(()=>t(new Error(`Cloud runner not ready after ${n}ms`)),n))]):Promise.reject(new Error("Cloud runner init not started"))}isActive(){return this._active}isInitializing(){return!this._active&&this._readyPromise!==null}deactivate(){var n;this._active=!1,this.userId=null,this.sessionId=null,(n=this._readyReject)==null||n.call(this,new Error("Cloud session deactivated")),this._readyPromise=null,this._readyResolve=null,this._readyReject=null}stop(){var n;(n=this._abortController)==null||n.abort()}get headers(){return{"Content-Type":"application/json","x-tenant-id":this.userId??"dev-tenant","x-session-id":this.sessionId??"default-session"}}async chat(n,e,t,s){if(!this._active)throw new Error("CloudRunner not configured");const o=Date.now();e("planning"),this._abortController=new AbortController;const{signal:a}=this._abortController;try{return{...await this._streamChat(n,e,s,a),durationMs:Date.now()-o}}catch(i){return i.name==="AbortError"?{content:"",iterations:0,toolsUsed:[],plan:null,durationMs:Date.now()-o}:(console.warn("[CloudRunner] SSE failed, falling back to non-streaming:",i),{...await this._nonStreamChat(n,e,a),durationMs:Date.now()-o})}finally{this._abortController=null,e("done")}}async _streamChat(n,e,t,s){const o=await fetch(`${ee}/api/chat/stream`,{method:"POST",headers:{...this.headers,Accept:"text/event-stream"},body:JSON.stringify({message:n}),signal:s});if(!o.ok||!o.body)throw new Error(`SSE request failed: ${o.status}`);const a=o.body.getReader(),i=new TextDecoder;let c="",l="",d=0;const p=[];let h=null,y=null;e:for(;;){const{done:v,value:A}=await a.read();if(v)break;c+=i.decode(A,{stream:!0});const f=c.split(`
|
|
112
|
+
`);c=f.pop()??"";for(const g of f){if(g.startsWith("event: ")){y=g.slice(7).trim();continue}if(!g.startsWith("data: "))continue;const b=g.slice(6).trim();if(!b||b==="[DONE]")continue;let j;try{j=JSON.parse(b)}catch{continue}const k=y??j.type;if(y=null,k==="status"){const w=j.message;w&&(e("executing"),t==null||t({timestamp:new Date().toISOString(),level:"info",tag:"cloud",message:`Tool: ${w}`}))}else if(k==="response")l=j.content??j.response??"",d=j.iterations??0,Array.isArray(j.toolsUsed)&&p.push(...j.toolsUsed),j.plan&&(h=j.plan);else{if(k==="error")throw new Error(j.message??"Stream error");if(k==="done")break e}}}return{content:l,iterations:d,toolsUsed:p,plan:h}}async _nonStreamChat(n,e,t){e("executing");const s=await fetch(`${ee}/api/chat`,{method:"POST",headers:this.headers,body:JSON.stringify({message:n}),signal:t});if(!s.ok){const a=await s.text();throw new Error(`Cloud chat failed (${s.status}): ${a}`)}const o=await s.json();return{content:o.response??"",iterations:o.iterations??0,toolsUsed:Array.isArray(o.toolsUsed)?o.toolsUsed:[],plan:o.plan??null}}async resetConversation(){if(this._active)try{await fetch(`${ee}/api/chat/history`,{method:"DELETE",headers:this.headers})}catch(n){console.error("[CloudRunner] resetConversation failed:",n)}}async stopMessage(){try{await fetch(`${ee}/api/chat/stop`,{method:"POST",headers:this.headers})}catch{}this.stop()}}const Pe=E.Router();Pe.get("/check",(r,n)=>{var p;let e=!1,t;try{$.execSync("npm --version",{timeout:3e3}),e=!0;try{t=$.execSync("node --version",{timeout:3e3}).toString().trim().replace(/^v/,"")}catch{}}catch{}let s=!1,o;if(e){const h=[];try{const y=$.execSync("npm root -g",{timeout:5e3}).toString().trim();h.push(m.join(y,"jiva-core","package.json"))}catch{}h.push(m.join(S.homedir(),".npm-global","lib","node_modules","jiva-core","package.json")),process.platform==="win32"&&(h.push(m.join(process.env.APPDATA??"","npm","node_modules","jiva-core","package.json")),h.push(m.join(process.env.LOCALAPPDATA??"","npm","node_modules","jiva-core","package.json")));for(const y of h)if(u.existsSync(y))try{o=JSON.parse(u.readFileSync(y,"utf-8")).version,s=!0;break}catch{}}const a=[N(),m.join(S.homedir(),".jiva","config.json")];let i=!1,c="";for(const h of a)if(u.existsSync(h))try{const y=JSON.parse(u.readFileSync(h,"utf-8")),v=((p=y==null?void 0:y.models)==null?void 0:p.reasoning)??{};if(((v==null?void 0:v.apiKey)??(y==null?void 0:y.apiKey)??"").length>0){i=!0,c=h;break}}catch{}let l=!1,d;try{const h=m.join(__dirname,"..","..","package.json");if(d=JSON.parse(u.readFileSync(h,"utf-8")).jivaCompatibleVersion,d&&o){const[v,A]=d.split(".").map(Number),[f,g]=o.split(".").map(Number);(v!==f||A!==g)&&(l=!0)}}catch{}n.json({nodejs:{ok:e,version:t},jivaCore:{ok:s,version:o},config:{ok:i,path:c||a[0]},platform:process.platform,jivaVersionMismatch:l,requiredJivaVersion:d})});const H=E.Router(),St={sarvam:{endpoint:"https://api.sarvam.ai/v1/chat/completions",defaultModel:"sarvam-105b",useHarmonyFormat:!1,reasoningEffortStrategy:"api_param",defaultMaxTokens:8192,multimodal:null},krutrim:{endpoint:"https://cloud.olakrutrim.com/v1/chat/completions",defaultModel:"gpt-oss-120b",useHarmonyFormat:!0,reasoningEffortStrategy:"system_prompt",multimodal:{defaultModel:"Llama-4-Maverick-17B-128E-Instruct"}},groq:{endpoint:"https://api.groq.com/openai/v1/chat/completions",defaultModel:"openai/gpt-oss-120b",useHarmonyFormat:!1,reasoningEffortStrategy:"api_param",multimodal:{defaultModel:"meta-llama/llama-4-maverick-17b-128e-instruct"}},"openai-compatible":{endpoint:"",defaultModel:"",useHarmonyFormat:!1,reasoningEffortStrategy:"both",multimodal:null}};H.get("/",(r,n)=>{n.json(P())});H.post("/",(r,n)=>{const e=R(r.body);n.json(e)});H.get("/path",(r,n)=>{n.json(N())});H.post("/setup-provider",(r,n)=>{const{provider:e,apiKey:t,customEndpoint:s,customModel:o}=r.body;try{const a=St[e];if(!a)return n.json({success:!1,error:`Unknown provider: ${e}`});const i=e==="openai-compatible"?s??"":a.endpoint,c=e==="openai-compatible"?o??"":a.defaultModel,d=P()??{models:{reasoning:null}};if(d.models={...d.models,reasoning:{name:"reasoning",type:"reasoning",provider:e,endpoint:i,apiKey:t,defaultModel:c,useHarmonyFormat:a.useHarmonyFormat,reasoningEffortStrategy:a.reasoningEffortStrategy,...a.defaultMaxTokens?{defaultMaxTokens:a.defaultMaxTokens}:{}},multimodal:a.multimodal?{name:"multimodal",type:"multimodal",endpoint:i,apiKey:t,defaultModel:a.multimodal.defaultModel}:void 0},!d.mcpServers){const h=process.platform==="win32"?"C:\\Users":`${S.homedir()}`;d.mcpServers={filesystem:{command:"npx",args:["-y","@modelcontextprotocol/server-filesystem",h],enabled:!0},"mcp-shell-server":{command:"npx",args:["-y","@mkusaka/mcp-shell-server"],enabled:!0}}}const p=R(d);return n.json({success:p,error:p?void 0:"Failed to write config"})}catch(a){return n.json({success:!1,error:a instanceof Error?a.message:String(a)})}});const ge=E.Router();ge.get("/",(r,n)=>{const e=m.join(S.homedir(),".jiva","conversations");try{if(!u.existsSync(e))return n.json([]);const t=u.readdirSync(e).filter(s=>s.endsWith(".json")).map(s=>{var i,c,l;const o=m.join(e,s),a=u.statSync(o);try{const d=JSON.parse(u.readFileSync(o,"utf-8"));let p=((i=d.metadata)==null?void 0:i.title)??d.summary??d.title??"";if(!p&&Array.isArray(d.messages)){const h=d.messages.find(y=>y.role==="user");if(h!=null&&h.content){const y=typeof h.content=="string"?h.content:Array.isArray(h.content)?h.content.filter(v=>v.type==="text").map(v=>v.text??"").join(""):"";p=y.slice(0,60).replace(/\n/g," "),y.length>60&&(p+="...")}}return{id:s.replace(".json",""),summary:p||"Untitled",messageCount:((c=d.messages)==null?void 0:c.length)??0,lastModified:a.mtimeMs,type:((l=d.metadata)==null?void 0:l.type)??"chat"}}catch{return null}}).filter(Boolean).sort((s,o)=>o.lastModified-s.lastModified);return n.json(t)}catch{return n.json([])}});ge.get("/:id",(r,n)=>{const e=m.join(S.homedir(),".jiva","conversations",`${r.params.id}.json`);try{return u.existsSync(e)?n.json(JSON.parse(u.readFileSync(e,"utf-8"))):n.json(null)}catch{return n.json(null)}});const U=E.Router();U.get("/is-repo",(r,n)=>{const e=r.query.dir;try{$.execFileSync("git",["rev-parse","--is-inside-work-tree"],{cwd:e,timeout:3e3}),n.json(!0)}catch{n.json(!1)}});U.get("/status",(r,n)=>{const e=r.query.dir;try{const t=$.execFileSync("git",["status","--porcelain"],{cwd:e,timeout:5e3}).toString();n.json(t.split(`
|
|
113
|
+
`).filter(Boolean).map(s=>({status:s.slice(0,2).trim(),file:s.slice(3).trim()})))}catch{n.json([])}});U.get("/diff-file",(r,n)=>{const{dir:e,file:t,status:s}=r.query;try{if(s==="??"){const o=m.join(e,t);try{const i=u.readFileSync(o,"utf-8").split(`
|
|
114
|
+
`);return i[i.length-1]===""&&i.pop(),n.json(`--- /dev/null
|
|
115
115
|
+++ b/${t}
|
|
116
|
-
@@ -0,0 +1,${
|
|
117
|
-
${
|
|
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 i=$.execFileSync("git",["rev-parse","--abbrev-ref","--symbolic-full-name","@{u}"],{cwd:e,timeout:3e3}).toString().trim();if(i){const a=$.execFileSync("git",["rev-list","--left-right","--count",`${i}...HEAD`],{cwd:e,timeout:3e3}).toString().trim().split(" ");o=parseInt(a[0])||0,s=parseInt(a[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 i=u.readdirSync(s,{withFileTypes:!0});return n.json(i.filter(a=>!a.name.startsWith(".")).map(a=>{const c=m.join(s,a.name),l=u.statSync(c);return{name:a.name,path:c,isDirectory:a.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:i,isCloud:a}=t.body;try{if(a){n.isActive()||await n.waitUntilReady(3e4);const l=await n.chat(o,d=>{O("jiva:phase-update",{phase:d})},i,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})},i,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(i){s.json({success:!1,error:i instanceof Error?i.message:String(i)})}}),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 jt(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 bt(){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 i=e.name,a=o.tags??[],c=["chat","research"];r.push({name:i,displayName:(o.name??i).replace(/-/g," ").replace(/\b\w/g,l=>l.toUpperCase()),description:o.description??`${i} persona`,tags:a,icon:jt(i,a),isBuiltIn:c.includes(i),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(bt())}),n.post("/activate",async(e,t)=>{const{name:s}=e.body,o=xt(s);if(o)try{await r.switchPersona(s)}catch(i){console.error("[Personas] Failed to switch persona:",i)}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(),i=(o==null?void 0:o.mcpServers)??{},a=new Map(s.map(l=>[l.name,l])),c=Object.entries(i).map(([l,d])=>{const p=a.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)i[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 i=P();if(!i)return t.json({success:!1,error:"Config not found"});const a={enabled:o.enabled??!0};return o.type==="stdio"?(a.command=o.command??"",a.args=o.args??[],o.env&&Object.keys(o.env).length>0&&(a.env=o.env)):(a.url=o.url??"",o.env&&Object.keys(o.env).length>0&&(a.env=o.env)),i.mcpServers||(i.mcpServers={}),i.mcpServers[s]=a,R(i),(r.getStatus()==="ready"||r.getStatus()==="busy")&&await r.addMCPServer(s,a),t.json({success:!0})}catch(i){return t.json({success:!1,error:i instanceof Error?i.message:String(i)})}}),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 i;const{name:s,enabled:o}=e.body;try{const a=P();(i=a==null?void 0:a.mcpServers)!=null&&i[s]&&(a.mcpServers[s].enabled=o,R(a)),(r.getStatus()==="ready"||r.getStatus()==="busy")&&await r.toggleMCPServer(s,o),t.json({success:!0})}catch(a){t.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),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 be(){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 a=P(),c=(a==null?void 0:a.workspaceDir)??S.homedir();await r.initialize(c)}const i=await r.chat(s,a=>{O("jiva:code-log",{event:a})},o);t.json({success:!0,...i})}catch(i){t.json({success:!1,error:i instanceof Error?i.message:String(i)})}}),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:i}=e.body;try{await r.initialize(s,o,i),t.json({success:!0})}catch(a){t.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),n.get("/mcp-for-code",(e,t)=>{try{const s=P(),o=(s==null?void 0:s.mcpServers)??{};t.json(Object.entries(o).map(([i,a])=>({name:i,enabled:a.enabled??!0,codeMode:a.codeMode===!0,command:a.command??"",url:a.url})))}catch{t.json([])}}),n.get("/conversation-id",(e,t)=>{t.json(r.getConversationId())}),n.get("/mcp-selection/:convId",(e,t)=>{t.json(be()[e.params.convId]??[])}),n.post("/mcp-selection",(e,t)=>{const{convId:s,servers:o}=e.body;try{const i=be();i[s]=o,u.mkdirSync(m.dirname(se),{recursive:!0}),u.writeFileSync(se,JSON.stringify(i,null,2)),t.json({success:!0})}catch(i){t.json({success:!1,error:i instanceof Error?i.message:String(i)})}}),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"),i=`\`\`\`${Pt[e]??e}
|
|
116
|
+
@@ -0,0 +1,${i.length} @@
|
|
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}
|
|
119
119
|
${s}
|
|
120
|
-
\`\`\``;return{name:n,category:"text",markdown:
|
|
120
|
+
\`\`\``;return{name:n,category:"text",markdown:a}}function Tt(r,n){if(u.statSync(r).size>10*1024*1024)return{name:n,category:"pdf",markdown:"",error:"PDF is too large (max 10 MB)"};const t=u.readFileSync(r),s=Ft(t);if(!s.trim())return{name:n,category:"pdf",markdown:"",error:"Could not extract text from PDF (may be a scanned/image-only PDF)"};const o=`**[PDF: ${n}]**
|
|
121
121
|
|
|
122
|
-
${s}`;return{name:n,category:"pdf",markdown:o}}function Ft(r){const n=r.toString("latin1"),e=[],t=/<<[^>]*\/Filter\s*\/FlateDecode[^>]*>>\s*stream\r?\n([\s\S]*?)\r?\nendstream/g;let s;for(;(s=t.exec(n))!==null;)try{const
|
|
123
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\\(/g,"(").replace(/\\\)/g,")").replace(/\\\\/g,"\\").replace(/[^\x20-\x7E\n\r\t]/g,"").trim();l.length>0&&n.push(l)}const
|
|
122
|
+
${s}`;return{name:n,category:"pdf",markdown:o}}function Ft(r){const n=r.toString("latin1"),e=[],t=/<<[^>]*\/Filter\s*\/FlateDecode[^>]*>>\s*stream\r?\n([\s\S]*?)\r?\nendstream/g;let s;for(;(s=t.exec(n))!==null;)try{const a=Buffer.from(s[1],"latin1"),i=pe.inflateSync(a).toString("latin1");e.push(...Ce(i))}catch{}const o=/BT([\s\S]*?)ET/g;for(;(s=o.exec(n))!==null;)e.push(...Ce(s[1]));return[...new Set(e)].join(" ").replace(/\s+/g," ").trim()}function Ce(r){const n=[],e=/BT([\s\S]*?)ET/g;let t;for(;(t=e.exec(r))!==null;){const s=t[1],o=/\(([^)\\]*(?:\\.[^)\\]*)*)\)/g;let a;for(;(a=o.exec(s))!==null;){const l=a[1].replace(/\\n/g,`
|
|
123
|
+
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\\(/g,"(").replace(/\\\)/g,")").replace(/\\\\/g,"\\").replace(/[^\x20-\x7E\n\r\t]/g,"").trim();l.length>0&&n.push(l)}const i=/<([0-9A-Fa-f\s]+)>/g;for(;(a=i.exec(s))!==null;){const c=a[1].replace(/\s/g,"");if(c.length%2!==0)continue;let l="";for(let d=0;d<c.length;d+=2){const p=parseInt(c.slice(d,d+2),16);p>=32&&p<=126&&(l+=String.fromCharCode(p))}l.trim().length>0&&n.push(l.trim())}}return n}function Rt(r,n){if(u.statSync(r).size>10*1024*1024)return{name:n,category:"docx",markdown:"",error:"DOCX is too large (max 10 MB)"};const t=u.readFileSync(r),s=_t(t,"word/document.xml");if(!s)return{name:n,category:"docx",markdown:"",error:"Could not extract content from DOCX file"};const o=Ot(s.toString("utf-8"));if(!o.trim())return{name:n,category:"docx",markdown:"",error:"DOCX appears to be empty"};const a=`**[DOCX: ${n}]**
|
|
124
124
|
|
|
125
|
-
${o}`;return{name:n,category:"docx",markdown:
|
|
125
|
+
${o}`;return{name:n,category:"docx",markdown:a}}function _t(r,n){let e=0;for(;e<r.length-30;){if(r.readUInt32LE(e)!==67324752){e++;continue}const t=r.readUInt16LE(e+8),s=r.readUInt32LE(e+18),o=r.readUInt32LE(e+22),a=r.readUInt16LE(e+26),i=r.readUInt16LE(e+28),c=r.slice(e+30,e+30+a).toString("utf-8"),l=e+30+a+i,d=l+s;if(c===n){const p=r.slice(l,d);if(t===0)return p;if(t===8)try{return pe.inflateRawSync(p)}catch{try{return pe.inflateSync(p)}catch{return null}}return null}s===0&&o===0?e=l:e=d}return null}function Ot(r){const n=[],e=/<w:p[ >]([\s\S]*?)<\/w:p>/g;let t;for(;(t=e.exec(r))!==null;){const s=[],o=/<w:t[^>]*>([^<]*)<\/w:t>/g;let a;for(;(a=o.exec(t[1]))!==null;)s.push(a[1]);const i=s.join("").trim();i&&n.push(i)}return n.join(`
|
|
126
126
|
|
|
127
|
-
`)}function Jt(r,n,e){if(u.statSync(r).size>20*1024*1024)return{name:n,category:"image",markdown:"",error:"Image is too large (max 20 MB)"};const s=Ee[e.toLowerCase()]??"image/png";return{name:n,category:"image",markdown:r,mimeType:s}}function Nt(r){const n=E.Router();return n.post("/convert",(e,t)=>{const{filePath:s}=e.body,o=S.homedir();if(!m.resolve(s).startsWith(m.resolve(o)))return t.json({name:m.basename(s),category:"unsupported",markdown:"",error:"Access denied"});const
|
|
127
|
+
`)}function Jt(r,n,e){if(u.statSync(r).size>20*1024*1024)return{name:n,category:"image",markdown:"",error:"Image is too large (max 20 MB)"};const s=Ee[e.toLowerCase()]??"image/png";return{name:n,category:"image",markdown:r,mimeType:s}}function Nt(r){const n=E.Router();return n.post("/convert",(e,t)=>{const{filePath:s}=e.body,o=S.homedir();if(!m.resolve(s).startsWith(m.resolve(o)))return t.json({name:m.basename(s),category:"unsupported",markdown:"",error:"Access denied"});const i=xe(s);if(i.category==="image"&&!i.error)try{const c=(()=>{try{return JSON.parse(u.readFileSync(m.join(S.homedir(),"Library","Preferences","jiva-nodejs","config.json"),"utf-8"))}catch{return null}})(),l=(c==null?void 0:c.workspaceDir)??o,d=m.join(l,".jiva","uploads");u.mkdirSync(d,{recursive:!0});const p=m.join(d,m.basename(s));u.copyFileSync(s,p),i.markdown=p}catch(c){i.error=`Failed to save image: ${c instanceof Error?c.message:String(c)}`}return t.json(i)}),n.post("/upload-and-convert",(e,t)=>{const{files:s}=e.body,o=S.homedir(),a=m.join(S.tmpdir(),"jivam-uploads");u.mkdirSync(a,{recursive:!0});const i=s.map(c=>{const l=m.join(a,c.name);try{u.writeFileSync(l,Buffer.from(c.data,"base64"));const d=xe(l);if(d.category==="image"&&!d.error)try{const p=(()=>{try{return JSON.parse(u.readFileSync(m.join(o,"Library","Preferences","jiva-nodejs","config.json"),"utf-8"))}catch{return null}})(),h=(p==null?void 0:p.workspaceDir)??o,y=m.join(h,".jiva","uploads");u.mkdirSync(y,{recursive:!0});const v=m.join(y,c.name);u.copyFileSync(l,v),d.markdown=v}catch{}return d}catch(d){return{name:c.name,category:"unsupported",markdown:"",error:String(d)}}finally{try{u.unlinkSync(l)}catch{}}});t.json(i)}),n.post("/describe-image",async(e,t)=>{const{dataUri:s}=e.body;try{const o=await r.describeImage(s);t.json({success:!0,description:o})}catch(o){t.json({success:!1,error:o instanceof Error?o.message:String(o)})}}),n}const Ut="https://hcomegrnonxmjupvvyus.supabase.co",Lt="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imhjb21lZ3Jub254bWp1cHZ2eXVzIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzgxNTQwMjcsImV4cCI6MjA5MzczMDAyN30.sBBOTrPsdCZk75HDEzJaIv5Mz-bE3HTuJQ-1LcJ45nk",qt="https://jiva-hdjcuspt2a-uc.a.run.app";async function De(r,n){const e=await fetch(`${Ut}${r}`,{method:"POST",headers:{"Content-Type":"application/json",apikey:Lt},body:JSON.stringify(n)}),t=await e.json();if(!e.ok){const s=t.error_description??t.error??t.message??"Auth failed";throw new Error(s)}return t}async function zt(r,n){const e=await De("/auth/v1/token?grant_type=password",{email:r,password:n});return{userId:e.user.id,email:e.user.email,accessToken:e.access_token,refreshToken:e.refresh_token}}async function Wt(r,n){const e=await De("/auth/v1/signup",{email:r,password:n}),t=e.user??e;return{userId:t.id,email:t.email,accessToken:e.access_token??"",refreshToken:e.refresh_token??""}}async function Bt(r,n){const e=await fetch(`${qt}/api/session`,{method:"POST",headers:{"Content-Type":"application/json","x-tenant-id":r,"x-session-id":n},body:JSON.stringify({})});if(!e.ok){const t=await e.text();throw new Error(`Cloud session init failed: ${t}`)}}function Ht(r){const n=E.Router();return n.post("/sign-in",async(e,t)=>{const{email:s,password:o}=e.body;try{const a=await zt(s,o);t.json({userId:a.userId,email:a.email})}catch(a){t.json({error:a instanceof Error?a.message:String(a)})}}),n.post("/sign-up",async(e,t)=>{const{email:s,password:o}=e.body;try{const a=await Wt(s,o);t.json({userId:a.userId,email:a.email})}catch(a){t.json({error:a instanceof Error?a.message:String(a)})}}),n.post("/sign-out",(e,t)=>{r.deactivate(),t.json({})}),n.post("/init",async(e,t)=>{const{userId:s,sessionId:o}=e.body;r.startInit();try{await Bt(s,o),r.configure(s,o),t.json({success:!0})}catch(a){r.deactivate(),t.json({success:!1,error:a instanceof Error?a.message:String(a)})}}),n}et();const W=parseInt(process.env.JIVAM_PORT??"7842",10),Te=process.env.NODE_ENV==="development";function Gt(r){const n=[m.join(S.homedir(),"Applications","Safari Apps"),m.join(S.homedir(),"Applications")];for(const e of n){if(!u.existsSync(e))continue;const t=u.readdirSync(e).filter(s=>s.endsWith(".app"));for(const s of t){const o=m.join(e,s,"Contents","Info.plist");if(u.existsSync(o))try{if(u.statSync(o).mtimeMs<r)continue;const i=u.readFileSync(o,"utf-8");if(i.includes("com.apple.Safari.WebApp")&&i.includes("<string>Jivam</string>"))return m.join(e,s)}catch{}}}return null}async function Vt(r){const{exec:n}=await import("child_process"),{promisify:e}=await import("util"),t=e(n);try{const{stdout:s}=await t("sw_vers -productVersion");if(parseInt(s.trim().split(".")[0]??"0",10)<14)return console.warn("Safari Add to Dock requires macOS Sonoma (14) or later — skipping."),null;const a=Date.now(),i=m.join(S.tmpdir(),"jivam-add-to-dock.applescript"),c=`
|
|
128
128
|
on run
|
|
129
129
|
tell application "Safari"
|
|
130
130
|
activate
|
|
@@ -145,12 +145,12 @@ on run
|
|
|
145
145
|
end tell
|
|
146
146
|
delay 2
|
|
147
147
|
end run
|
|
148
|
-
`;u.writeFileSync(
|
|
149
|
-
A "Add to Dock" confirmation opened in Safari — click Add to finish setting up Jivam as an app.`),console.log("Waiting up to 60s for you to click it...");for(let l=0;l<60;l++){await new Promise(p=>setTimeout(p,1e3));const d=Gt(
|
|
148
|
+
`;u.writeFileSync(i,c);try{await t(`osascript "${i}"`,{timeout:2e4})}finally{u.rmSync(i,{force:!0})}console.log(`
|
|
149
|
+
A "Add to Dock" confirmation opened in Safari — click Add to finish setting up Jivam as an app.`),console.log("Waiting up to 60s for you to click it...");for(let l=0;l<60;l++){await new Promise(p=>setTimeout(p,1e3));const d=Gt(a);if(d)return d}return console.warn("No click detected within 60s — falling back to --app mode. Run `jivam --install` again anytime to retry."),null}catch(s){const o=s instanceof Error?s.message:String(s);if(o.includes("assistive access")||o.includes("-1719")){console.warn(`
|
|
150
150
|
Safari Add to Dock needs Accessibility permission (one-time setup) to control Safari's menus.
|
|
151
151
|
Opening System Settings — enable access for Terminal (or whichever app you ran this from),
|
|
152
152
|
then re-run: jivam --install
|
|
153
|
-
Falling back to --app mode for now — Jivam will still work, just without the native single-window Dock experience.`);try{await t('open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"')}catch{}}else console.warn("Safari Add to Dock automation failed, falling back to --app mode:",s);return null}}const we="ai.karmaloop.jivam",J="JivamServer";function Fe(){return m.join(S.homedir(),"Library","LaunchAgents",`${we}.plist`)}async function
|
|
153
|
+
Falling back to --app mode for now — Jivam will still work, just without the native single-window Dock experience.`);try{await t('open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"')}catch{}}else console.warn("Safari Add to Dock automation failed, falling back to --app mode:",s);return null}}const we="ai.karmaloop.jivam",J="JivamServer";function Fe(){return m.join(S.homedir(),"Library","LaunchAgents",`${we}.plist`)}async function Yt(){const{exec:r}=await import("child_process"),{promisify:n}=await import("util"),e=n(r);try{const{stdout:o}=await e("which jivam");if(o.trim())return o.trim()}catch{}const t=["/usr/local/bin/jivam",m.join(S.homedir(),".npm-global","bin","jivam"),"/opt/homebrew/bin/jivam","/usr/bin/jivam"];for(const o of t)if(u.existsSync(o))return o;const s=m.join(S.homedir(),".nvm","versions","node");if(u.existsSync(s))try{const o=u.readdirSync(s).sort().reverse();for(const a of o){const i=m.join(s,a,"bin","jivam");if(u.existsSync(i))return i}}catch{}return`"${process.execPath}" "${process.argv[1]}"`}async function Kt(r){const n=["/usr/local/bin","/opt/homebrew/bin","/opt/homebrew/sbin",m.join(S.homedir(),".npm-global","bin"),m.join(S.homedir(),".nvm","versions","node"),"/usr/bin","/bin"].join(":"),e=m.join(S.homedir(),".jivam");u.mkdirSync(e,{recursive:!0});const t=m.join(e,"jivam.log"),o=r.startsWith('"')?r.split('" "').map(c=>c.replace(/^"|"$/g,"")):[r],a=`<?xml version="1.0" encoding="UTF-8"?>
|
|
154
154
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
155
155
|
<plist version="1.0">
|
|
156
156
|
<dict>
|
|
@@ -179,7 +179,7 @@ Falling back to --app mode for now — Jivam will still work, just without the n
|
|
|
179
179
|
</dict>
|
|
180
180
|
</dict>
|
|
181
181
|
</plist>
|
|
182
|
-
`,
|
|
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
183
|
URL="${`http://localhost:${W}`}"
|
|
184
184
|
CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
|
185
185
|
EDGE="/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"
|
|
@@ -195,7 +195,7 @@ else
|
|
|
195
195
|
osascript -e "tell application \\"Safari\\" to open location \\"$URL\\"" \\
|
|
196
196
|
-e "tell application \\"Safari\\" to activate"
|
|
197
197
|
fi
|
|
198
|
-
`;u.writeFileSync(m.join(s,"jivam-launcher"),
|
|
198
|
+
`;u.writeFileSync(m.join(s,"jivam-launcher"),i,{mode:493}),u.writeFileSync(m.join(t,"Contents","Info.plist"),`<?xml version="1.0" encoding="UTF-8"?>
|
|
199
199
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
200
200
|
<plist version="1.0">
|
|
201
201
|
<dict>
|
|
@@ -217,9 +217,9 @@ fi
|
|
|
217
217
|
<false/>
|
|
218
218
|
</dict>
|
|
219
219
|
</plist>
|
|
220
|
-
`);const d=[m.join(__dirname,"..","dist","icon-512.png"),m.join(__dirname,"..","public","icon-512.png")].find(p=>u.existsSync(p));if(d)try{const p=m.join(S.tmpdir(),"Jivam.iconset");u.mkdirSync(p,{recursive:!0});const h=[[16,"icon_16x16.png"],[32,"icon_16x16@2x.png"],[32,"icon_32x32.png"],[64,"icon_32x32@2x.png"],[128,"icon_128x128.png"],[256,"icon_128x128@2x.png"],[256,"icon_256x256.png"],[512,"icon_256x256@2x.png"],[512,"icon_512x512.png"]];for(const[y,v]of h)await e(`sips -z ${y} ${y} "${d}" --out "${m.join(p,v)}"`);await e(`iconutil -c icns "${p}" --output "${m.join(o,"Jivam.icns")}"`),u.rmSync(p,{recursive:!0,force:!0})}catch(p){console.warn("Could not convert icon (sips/iconutil failed):",p)}return t}async function
|
|
221
|
-
Done! Click the Jivam icon in your Dock to launch.`),console.log("The server runs continuously in the background — manage it with:"),console.log(" jivam stop jivam start jivam restart jivam status"),process.exit(0)}async function
|
|
222
|
-
`)[0].trim();if(
|
|
220
|
+
`);const d=[m.join(__dirname,"..","dist","icon-512.png"),m.join(__dirname,"..","public","icon-512.png")].find(p=>u.existsSync(p));if(d)try{const p=m.join(S.tmpdir(),"Jivam.iconset");u.mkdirSync(p,{recursive:!0});const h=[[16,"icon_16x16.png"],[32,"icon_16x16@2x.png"],[32,"icon_32x32.png"],[64,"icon_32x32@2x.png"],[128,"icon_128x128.png"],[256,"icon_128x128@2x.png"],[256,"icon_256x256.png"],[512,"icon_256x256@2x.png"],[512,"icon_512x512.png"]];for(const[y,v]of h)await e(`sips -z ${y} ${y} "${d}" --out "${m.join(p,v)}"`);await e(`iconutil -c icns "${p}" --output "${m.join(o,"Jivam.icns")}"`),u.rmSync(p,{recursive:!0,force:!0})}catch(p){console.warn("Could not convert icon (sips/iconutil failed):",p)}return t}async function Zt(r){const{exec:n}=await import("child_process"),{promisify:e}=await import("util"),t=e(n),s="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister";try{await t(`touch "${r}"`),await t(`"${s}" -f "${r}"`)}catch{}const o=`<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>${r}</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>`;try{await t(`defaults write com.apple.dock persistent-apps -array-add '${o}' && killall Dock`),console.log(`Added to Dock: ${r}`)}catch(a){console.warn("Could not add to Dock automatically — drag the app to your Dock manually."),console.warn(a)}}async function Qt(){process.platform!=="darwin"&&(console.error("--install is currently only supported on macOS."),process.exit(1));const r=`http://localhost:${W}`;console.log("Setting up the Jivam background service...");const n=await Yt();await Kt(n),await Re("restart");let e=!1;for(let o=0;o<30;o++){try{if((await fetch(`${r}/api/version`)).ok){e=!0;break}}catch{}await new Promise(a=>setTimeout(a,500))}e?console.log("Jivam server is running."):console.warn("Server did not come up within 15s — continuing anyway (check ~/.jivam/jivam.log)."),console.log("Installing Jivam as a Safari web app (this may take a few seconds)...");const s=await Vt(r)??await Xt();await Zt(s),console.log(`
|
|
221
|
+
Done! Click the Jivam icon in your Dock to launch.`),console.log("The server runs continuously in the background — manage it with:"),console.log(" jivam stop jivam start jivam restart jivam status"),process.exit(0)}async function en(){const{exec:r}=await import("child_process"),{promisify:n}=await import("util"),e=n(r);try{const{stdout:o}=await e("where jivam"),a=o.split(`
|
|
222
|
+
`)[0].trim();if(a)return a}catch{}const t=process.env.LOCALAPPDATA??m.join(S.homedir(),"AppData","Local"),s=[m.join(t,"npm","jivam.cmd"),m.join(process.env.APPDATA??"","npm","jivam.cmd"),"C:\\Program Files\\nodejs\\jivam.cmd"];for(const o of s)if(u.existsSync(o))return o;return`"${process.execPath}" "${process.argv[1]}"`}async function tn(r){const{exec:n}=await import("child_process"),{promisify:e}=await import("util"),t=e(n),s=r.startsWith('"'),[o,...a]=s?r.split('" "').map(d=>d.replace(/^"|"$/g,"")):[r],i=[...a,"--server-only"].join(" "),c=`<?xml version="1.0" encoding="UTF-16"?>
|
|
223
223
|
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
|
224
224
|
<Triggers>
|
|
225
225
|
<LogonTrigger>
|
|
@@ -248,11 +248,11 @@ Done! Click the Jivam icon in your Dock to launch.`),console.log("The server run
|
|
|
248
248
|
<Actions Context="Author">
|
|
249
249
|
<Exec>
|
|
250
250
|
<Command>${o}</Command>
|
|
251
|
-
<Arguments>${
|
|
251
|
+
<Arguments>${i}</Arguments>
|
|
252
252
|
</Exec>
|
|
253
253
|
</Actions>
|
|
254
254
|
</Task>
|
|
255
|
-
`,l=m.join(S.tmpdir(),"jivam-task.xml");u.writeFileSync(l,Buffer.concat([Buffer.from([255,254]),Buffer.from(c,"utf16le")]));try{await t(`schtasks /Create /TN "${J}" /XML "${l}" /F`)}finally{u.rmSync(l,{force:!0})}}async function _e(r){const{exec:n}=await import("child_process"),{promisify:e}=await import("util"),t=e(n);try{await t(`schtasks /Query /TN "${J}"`)}catch{console.log("Jivam background service is not installed. Run: jivam --install");return}if(r==="start"||r==="restart"){if(r==="restart"){try{await t(`schtasks /End /TN "${J}"`)}catch{}await new Promise(s=>setTimeout(s,1e3))}try{await t(`schtasks /Run /TN "${J}"`),console.log(`Jivam background service ${r==="restart"?"restarted":"started"}.`)}catch(s){console.error(`Failed to ${r} service:`,s)}}else if(r==="stop")try{await t(`schtasks /End /TN "${J}"`),console.log("Jivam background service stopped.")}catch{console.warn("Service was not running (or already stopped).")}else if(r==="status")try{const{stdout:s}=await t(`schtasks /Query /TN "${J}" /FO LIST /V`),o=s.match(/Status:\s*(.+)/);console.log(o?`Jivam background service status: ${o[1].trim()}`:"Jivam background service is registered.")}catch{console.log("Jivam background service is not running.")}}async function
|
|
255
|
+
`,l=m.join(S.tmpdir(),"jivam-task.xml");u.writeFileSync(l,Buffer.concat([Buffer.from([255,254]),Buffer.from(c,"utf16le")]));try{await t(`schtasks /Create /TN "${J}" /XML "${l}" /F`)}finally{u.rmSync(l,{force:!0})}}async function _e(r){const{exec:n}=await import("child_process"),{promisify:e}=await import("util"),t=e(n);try{await t(`schtasks /Query /TN "${J}"`)}catch{console.log("Jivam background service is not installed. Run: jivam --install");return}if(r==="start"||r==="restart"){if(r==="restart"){try{await t(`schtasks /End /TN "${J}"`)}catch{}await new Promise(s=>setTimeout(s,1e3))}try{await t(`schtasks /Run /TN "${J}"`),console.log(`Jivam background service ${r==="restart"?"restarted":"started"}.`)}catch(s){console.error(`Failed to ${r} service:`,s)}}else if(r==="stop")try{await t(`schtasks /End /TN "${J}"`),console.log("Jivam background service stopped.")}catch{console.warn("Service was not running (or already stopped).")}else if(r==="status")try{const{stdout:s}=await t(`schtasks /Query /TN "${J}" /FO LIST /V`),o=s.match(/Status:\s*(.+)/);console.log(o?`Jivam background service status: ${o[1].trim()}`:"Jivam background service is registered.")}catch{console.log("Jivam background service is not running.")}}async function nn(){const{exec:r}=await import("child_process"),{promisify:n}=await import("util"),e=n(r),t=process.env.LOCALAPPDATA??m.join(S.homedir(),"AppData","Local"),s=m.join(t,"Jivam"),o=m.join(s,"jivam-launcher.bat"),a=m.join(s,"jivam-launcher.vbs"),i=m.join(s,"Jivam.ico"),c=m.join(S.homedir(),"Desktop","Jivam.lnk"),l=m.join(t,"Microsoft","Windows","Start Menu","Programs"),d=m.join(l,"Jivam.lnk");u.mkdirSync(s,{recursive:!0});const p=`http://localhost:${W}`;console.log("Setting up the Jivam background service...");const h=await en();await tn(h),await _e("restart");let y=!1;for(let k=0;k<30;k++){try{if((await fetch(`${p}/api/version`)).ok){y=!0;break}}catch{}await new Promise(w=>setTimeout(w,500))}y?console.log("Jivam server is running."):console.warn("Server did not come up within 15s — continuing anyway (check %LOCALAPPDATA%\\Jivam\\jivam.log).");const v=`@echo off
|
|
256
256
|
set URL=${p}
|
|
257
257
|
set CHROME=%ProgramFiles%\\Google\\Chrome\\Application\\chrome.exe
|
|
258
258
|
set EDGE=%ProgramFiles(x86)%\\Microsoft\\Edge\\Application\\msedge.exe
|
|
@@ -266,27 +266,27 @@ if exist "%CHROME%" (
|
|
|
266
266
|
)
|
|
267
267
|
`,A=`Set oShell = CreateObject("WScript.Shell")
|
|
268
268
|
oShell.Run Chr(34) & "${o.replace(/\\/g,"\\\\")}" & Chr(34), 0, False
|
|
269
|
-
`;u.writeFileSync(o,v),u.writeFileSync(
|
|
269
|
+
`;u.writeFileSync(o,v),u.writeFileSync(a,A),console.log(`Created launcher at ${s}`);const g=[m.join(B,"..","dist","icon-512.png"),m.join(B,"..","public","icon-512.png")].find(k=>u.existsSync(k));if(g){const k=`
|
|
270
270
|
Add-Type -AssemblyName System.Drawing
|
|
271
271
|
$src = [System.Drawing.Image]::FromFile('${g.replace(/\\/g,"\\\\")}')
|
|
272
272
|
$bmp = New-Object System.Drawing.Bitmap($src, 256, 256)
|
|
273
273
|
$ico = [System.Drawing.Icon]::FromHandle($bmp.GetHicon())
|
|
274
|
-
$fs = [System.IO.File]::Create('${
|
|
274
|
+
$fs = [System.IO.File]::Create('${i.replace(/\\/g,"\\\\")}')
|
|
275
275
|
$ico.Save($fs)
|
|
276
276
|
$fs.Close()
|
|
277
277
|
$ico.Dispose()
|
|
278
278
|
$bmp.Dispose()
|
|
279
279
|
$src.Dispose()
|
|
280
280
|
Write-Host "Icon written"
|
|
281
|
-
`.trim();try{await e(`powershell -NoProfile -NonInteractive -Command "${k.replace(/"/g,'\\"').replace(/\n/g,"; ")}"`),console.log("Icon created.")}catch(w){console.warn("Could not create icon (PowerShell/System.Drawing failed):",w)}}const
|
|
281
|
+
`.trim();try{await e(`powershell -NoProfile -NonInteractive -Command "${k.replace(/"/g,'\\"').replace(/\n/g,"; ")}"`),console.log("Icon created.")}catch(w){console.warn("Could not create icon (PowerShell/System.Drawing failed):",w)}}const b=u.existsSync(i)?`$s.IconLocation = '${i.replace(/\\/g,"\\\\")}'`:"",j=k=>`
|
|
282
282
|
$ws = New-Object -ComObject WScript.Shell
|
|
283
283
|
$s = $ws.CreateShortcut('${k.replace(/\\/g,"\\\\")}')
|
|
284
284
|
$s.TargetPath = 'wscript.exe'
|
|
285
|
-
$s.Arguments = '//B "${
|
|
285
|
+
$s.Arguments = '//B "${a.replace(/\\/g,"\\\\")}"'
|
|
286
286
|
$s.WorkingDirectory = '${s.replace(/\\/g,"\\\\")}'
|
|
287
287
|
$s.Description = 'Jivam - AI Agent UI'
|
|
288
|
-
${
|
|
288
|
+
${b}
|
|
289
289
|
$s.Save()
|
|
290
|
-
`.trim();try{u.mkdirSync(l,{recursive:!0});for(const k of[c,d]){const w=
|
|
291
|
-
Done! Double-click the Jivam icon on your Desktop to launch.`),console.log("The server runs continuously in the background — manage it with:"),console.log(" jivam stop jivam start jivam restart jivam status"),process.exit(0)}const B=__dirname,I=E();I.use(E.json({limit:"50mb"}));const G=new wt,Oe=new gt,Je=new vt;I.use("/api/setup",Pe);I.use("/api/config",H);I.use("/api/conversations",ge);I.use("/api/git",U);I.use("/api/directive",ye);I.use("/api/workspace",_);I.use("/api/jiva",kt(G,Je));I.use("/api/personas",$t(G));I.use("/api/mcp",Mt(G));I.use("/api/code",At(Oe));I.use("/api/files",Nt(G));I.use("/api/cloud",Ht(Je));I.get("/api/platform",(r,n)=>n.json(process.platform));I.get("/api/version",(r,n)=>{try{const e=JSON.parse(u.readFileSync(m.join(B,"..","package.json"),"utf-8"));n.json(e.version)}catch{n.json("0.0.0")}});if(!Te){const r=m.join(B,"..","dist");u.existsSync(r)&&(I.use(E.static(r)),I.get(/(.*)/,(n,e)=>{e.sendFile(m.join(r,"index.html"))}))}async function
|
|
290
|
+
`.trim();try{u.mkdirSync(l,{recursive:!0});for(const k of[c,d]){const w=j(k);await e(`powershell -NoProfile -NonInteractive -Command "${w.replace(/"/g,'\\"').replace(/\n/g,"; ")}"`)}console.log(`Created Desktop shortcut: ${c}`),console.log(`Created Start Menu entry: ${d}`)}catch(k){console.warn("Could not create shortcuts:",k)}console.log(`
|
|
291
|
+
Done! Double-click the Jivam icon on your Desktop to launch.`),console.log("The server runs continuously in the background — manage it with:"),console.log(" jivam stop jivam start jivam restart jivam status"),process.exit(0)}const B=__dirname,I=E();I.use(E.json({limit:"50mb"}));const G=new wt,Oe=new gt,Je=new vt;I.use("/api/setup",Pe);I.use("/api/config",H);I.use("/api/conversations",ge);I.use("/api/git",U);I.use("/api/directive",ye);I.use("/api/workspace",_);I.use("/api/jiva",kt(G,Je));I.use("/api/personas",$t(G));I.use("/api/mcp",Mt(G));I.use("/api/code",At(Oe));I.use("/api/files",Nt(G));I.use("/api/cloud",Ht(Je));I.get("/api/platform",(r,n)=>n.json(process.platform));I.get("/api/version",(r,n)=>{try{const e=JSON.parse(u.readFileSync(m.join(B,"..","package.json"),"utf-8"));n.json(e.version)}catch{n.json("0.0.0")}});if(!Te){const r=m.join(B,"..","dist");u.existsSync(r)&&(I.use(E.static(r)),I.get(/(.*)/,(n,e)=>{e.sendFile(m.join(r,"index.html"))}))}async function sn(r){const{execFile:n,exec:e}=await import("child_process"),{promisify:t}=await import("util"),s=t(e),o=(process.env.JIVAM_BROWSER??"").toLowerCase();if(process.platform==="darwin"){if(o!=="chrome"&&o!=="edge"&&o!=="brave"){const a=[m.join(S.homedir(),"Applications","Safari Apps","Jivam.app"),m.join(S.homedir(),"Applications","Jivam.app"),"/Applications/Jivam.app"];for(const i of a)if(u.existsSync(i))try{await s(`open "${i}"`),console.log(`Launched Safari PWA: ${i}`);return}catch{}}if(o==="safari")try{await s(`osascript -e 'tell application "Safari" to open location "${r}"' -e 'tell application "Safari" to activate'`),console.log("Opened in Safari (tip: File → Add to Dock for app experience)");return}catch(a){console.error("Failed to open Safari:",a)}if(o!=="safari"){const a=[["chrome","/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"],["edge","/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"],["brave","/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"]];for(const[i,c]of a)if(!(o&&o!==i))try{n(c,[`--app=${r}`,"--disable-extensions"]),console.log(`Opened in app-mode window: ${c}`);return}catch{}}if(!o)try{await s(`osascript -e 'tell application "Safari" to open location "${r}"' -e 'tell application "Safari" to activate'`),console.log("Opened in Safari (tip: File → Add to Dock for app experience)");return}catch{}}else if(process.platform==="win32"){const a=[["msedge",[`--app=${r}`]],["chrome",[`--app=${r}`]],["brave",[`--app=${r}`]]];for(const[i,c]of a)try{n(`start ${i}`,c,{shell:!0});return}catch{}try{await s(`start "" "${r}"`);return}catch{}}else{const a=[["google-chrome",[`--app=${r}`]],["google-chrome-stable",[`--app=${r}`]],["chromium-browser",[`--app=${r}`]],["chromium",[`--app=${r}`]],["brave-browser",[`--app=${r}`]],["microsoft-edge",[`--app=${r}`]]];for(const[i,c]of a)try{n(i,c);return}catch{}}try{const{default:a}=await import("open");await a(r),console.log(`Opened in default browser: ${r}`)}catch(a){console.error("Could not open browser automatically:",a),console.log(`Open manually: ${r}`)}}function rn(){const n=async()=>{try{const{exec:e}=await import("child_process"),{promisify:t}=await import("util"),s=t(e),o=JSON.parse(u.readFileSync(m.join(B,"..","package.json"),"utf-8")),{stdout:a}=await s("npm view jivamai version"),i=a.trim();if(i&&i!==o.version){console.log(`Update available: jivamai ${o.version} → ${i}. Updating...`),await s("npm install -g jivamai jiva-core"),console.log("Update installed — restarting to pick it up."),process.exit(1);return}}catch(e){console.warn("Update check failed (probably offline):",e)}setTimeout(n,864e5)};setTimeout(n,864e5)}const z=process.argv[2],on=z==="start"||z==="stop"||z==="restart"||z==="status";if(process.argv.includes("--install"))(process.platform==="win32"?nn:Qt)().catch(n=>{console.error(n),process.exit(1)});else if(on)(process.platform==="win32"?_e:Re)(z).then(()=>process.exit(0)).catch(n=>{console.error(n),process.exit(1)});else{const r=process.argv.includes("--server-only"),n=Qe.createServer(I);tt(n),n.listen(W,"127.0.0.1",async()=>{const t=`http://localhost:${W}`;console.log(`Jivam server running at ${t}`),!Te&&!r&&await sn(t),r&&rn()});async function e(){await G.cleanup(),await Oe.cleanup(),n.close(),process.exit(0)}process.on("SIGINT",e),process.on("SIGTERM",e)}
|
|
292
292
|
//# sourceMappingURL=index.js.map
|