@z_ptah/agent 0.0.30 → 0.0.31
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/cli.js +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -29,9 +29,9 @@ server {
|
|
|
29
29
|
}
|
|
30
30
|
`,a=`/etc/nginx/sites-available/${n}`,p=`/etc/nginx/sites-enabled/${n}`;await _t(a,l);try{await T("ln",["-sf",a,p])}catch{}return await T("nginx",["-t"]),await T("nginx",["-s","reload"]),console.log(`Nginx configured for ${n}`),n}async function Se(e){try{await T("certbot",["--nginx","-d",e,"--non-interactive","--agree-tos","--email","ssl@mybptah.com"]),console.log(`SSL configured for ${e}`)}catch(t){console.error(`SSL setup failed for ${e}:`,t)}}var ke=d(()=>{"use strict"});function E(e,t,o){let r={type:"agent:deploy-status",payload:{commandId:e.commandId,deploymentId:e.deploymentId,status:t,...o}};i(r)}async function xe(e){try{E(e,"building"),await ye(e.projectDir),E(e,"deploying");let r=await ve(e.projectCode,e.orgCode,3001,3002);await Se(r).catch(()=>{});let s=`https://${r}`;E(e,"live",{demoUrl:s}),console.log(`Deploy complete: ${s}`)}catch(t){let o=t instanceof Error?t.message:"Unknown deploy error";console.error("Deploy failed:",o),E(e,"failed",{errorMessage:o})}}var we=d(()=>{"use strict";he();ke();k()});import{execSync as N}from"child_process";function be(){try{return N(`docker ps -a --format '{"id":"{{.ID}}","name":"{{.Names}}","image":"{{.Image}}","status":"{{.Status}}","state":"{{.State}}","ports":"{{.Ports}}","createdAt":"{{.CreatedAt}}"}'`,{encoding:"utf-8",timeout:1e4}).trim().split(`
|
|
31
31
|
`).filter(t=>t.trim()).map(t=>{let o=JSON.parse(t),r=o.name.match(/^ptah-([a-f0-9-]+)/);return{...o,projectId:r?.[1]||void 0}})}catch(e){return console.error("[docker] Failed to list containers:",e),[]}}function $e(e){try{return N(`docker stop ${e}`,{encoding:"utf-8",timeout:3e4}),{success:!0}}catch(t){return{success:!1,error:t.message}}}function _e(e){try{return N(`docker start ${e}`,{encoding:"utf-8",timeout:3e4}),{success:!0}}catch(t){return{success:!1,error:t.message}}}function Ie(e){try{return N(`docker rm -f ${e}`,{encoding:"utf-8",timeout:3e4}),{success:!0}}catch(t){return{success:!1,error:t.message}}}var Ce=d(()=>{"use strict"});async function Ct(){if(Ae)return V;Ae=!0;try{let{createRequire:e}=await import("module");V=e(import.meta.url)("node-pty"),console.log("[terminal] node-pty loaded successfully")}catch(e){console.warn("[terminal] node-pty not available \u2014 terminal feature disabled",e.message)}return V}function At(e){let t=v.get(e);t&&(clearTimeout(t.idleTimer),t.idleTimer=setTimeout(()=>{console.log(`[terminal] ${e} idle timeout \u2014 killing`),D(e)},Me))}async function Pe(e,t,o){let r=await Ct();if(!r){i({type:"agent:terminal-exit",payload:{terminalId:e,exitCode:1}});return}if(v.has(e)){console.warn(`[terminal] Terminal ${e} already exists`);return}let s=process.env.SHELL||"/bin/bash",n=r.spawn(s,[],{name:"xterm-256color",cols:t,rows:o,cwd:process.env.HOME||"/",env:process.env}),l=setTimeout(()=>{console.log(`[terminal] ${e} idle timeout \u2014 killing`),D(e)},Me);v.set(e,{pty:n,idleTimer:l}),n.onData(a=>{i({type:"agent:terminal-output",payload:{terminalId:e,data:a}})}),n.onExit(({exitCode:a})=>{let p=v.get(e);p&&clearTimeout(p.idleTimer),v.delete(e),i({type:"agent:terminal-exit",payload:{terminalId:e,exitCode:a}})}),console.log(`[terminal] Opened ${e} (${t}x${o})`)}function Te(e,t){let o=v.get(e);o&&(o.pty.write(t),At(e))}function Ee(e,t,o){let r=v.get(e);r&&r.pty.resize(t,o)}function D(e){let t=v.get(e);t&&(clearTimeout(t.idleTimer),t.pty.kill(),v.delete(e),console.log(`[terminal] Closed ${e}`))}var V,Ae,Me,v,Ne=d(()=>{"use strict";k();V=null,Ae=!1;Me=5*60*1e3,v=new Map});import{mkdirSync as De,writeFileSync as Re,readdirSync as Mt,unlinkSync as Pt}from"fs";import{join as I}from"path";import{homedir as Tt}from"os";function Ue(e){return`${Oe}${e}.md`}function je(e){let t=["---"];return t.push(`name: ${e.name}`),e.description&&t.push(`description: ${e.description}`),t.push("---"),t.push(""),t.push(e.content),t.join(`
|
|
32
|
-
`)}function ze(e){try{let t=Mt(e);for(let o of t)o.startsWith(Oe)&&o.endsWith(".md")&&Pt(I(e,o))}catch{}}function He(e){De(R,{recursive:!0}),ze(R);for(let t of e){let o=I(R,Ue(t.code));Re(o,je(t),"utf-8")}console.log(`[skills] Wrote ${e.length} org skills to ${R}`)}function Le(e,t){let o=I(c.projectsDir,e,".claude","commands");De(o,{recursive:!0}),ze(o);for(let r of t){let s=I(o,Ue(r.code));Re(s,je(r),"utf-8")}console.log(`[skills] Wrote ${t.length} project skills for ${e}`)}var Oe,R,Fe=d(()=>{"use strict";y();Oe="ptah-",R=I(Tt(),".claude","commands")});import{execSync as B}from"child_process";function qe(e){switch(e.type){case"server:auth-result":e.payload.success||(console.error("Authentication failed:",e.payload.error),process.exit(1));break;case"server:command":console.log(`Received command: ${e.payload.action}`,e.payload);break;case"server:doc-sync":console.log(`Doc sync: ${e.payload.action} ${e.payload.fileName}`);break;case"server:claude-start":{let{commandId:t,sessionId:o,projectId:r,message:s,claudeSessionId:n,projectDir:l,systemPrompt:a}=e.payload;console.log(`Starting Claude session ${o} for project ${r}`),fe({commandId:t,sessionId:o,projectId:r,projectDir:l,message:s,claudeSessionId:n,systemPrompt:a});break}case"server:claude-stop":{console.log(`Stop requested for session ${e.payload.sessionId}`);break}case"server:chat-history-request":{let{sessionId:t,projectId:o}=e.payload;console.log(`Chat history request for session ${t}`);let r=ie(o,t);i({type:"agent:chat-history",payload:{sessionId:t,messages:r}});break}case"server:deploy-start":{let{commandId:t,deploymentId:o,projectId:r,projectCode:s,orgCode:n,projectDir:l}=e.payload;console.log(`Starting deployment for project ${s}`),xe({commandId:t,deploymentId:o,projectId:r,projectCode:s,orgCode:n,projectDir:l});break}case"server:docker-list":{let{requestId:t}=e.payload;console.log(`Docker list request: ${t}`);let o=be();i({type:"agent:docker-list",payload:{requestId:t,containers:o}});break}case"server:docker-start":{let{requestId:t,containerId:o}=e.payload;console.log(`Docker start: ${o}`);let r=_e(o);i({type:"agent:docker-action",payload:{requestId:t,...r}});break}case"server:docker-stop":{let{requestId:t,containerId:o}=e.payload;console.log(`Docker stop: ${o}`);let r=$e(o);i({type:"agent:docker-action",payload:{requestId:t,...r}});break}case"server:docker-remove":{let{requestId:t,containerId:o}=e.payload;console.log(`Docker remove: ${o}`);let r=Ie(o);i({type:"agent:docker-action",payload:{requestId:t,...r}});break}case"server:terminal-open":{let{terminalId:t,cols:o,rows:r}=e.payload;Pe(t,o,r);break}case"server:terminal-input":{Te(e.payload.terminalId,e.payload.data);break}case"server:terminal-resize":{let{terminalId:t,cols:o,rows:r}=e.payload;Ee(t,o,r);break}case"server:terminal-close":{D(e.payload.terminalId);break}case"server:skills-sync":{try{He(e.payload.skills),i({type:"agent:skills-sync-result",payload:{success:!0}})}catch(t){let o=t.message;console.error("[skills] Sync failed:",o),i({type:"agent:skills-sync-result",payload:{success:!1,error:o}})}break}case"server:project-skills-sync":{try{Le(e.payload.projectId,e.payload.skills),i({type:"agent:skills-sync-result",payload:{success:!0}})}catch(t){let o=t.message;console.error("[skills] Project sync failed:",o),i({type:"agent:skills-sync-result",payload:{success:!1,error:o}})}break}case"server:agent-info":{let{requestId:t}=e.payload;i({type:"agent:info",payload:{requestId:t,version:"0.0.
|
|
32
|
+
`)}function ze(e){try{let t=Mt(e);for(let o of t)o.startsWith(Oe)&&o.endsWith(".md")&&Pt(I(e,o))}catch{}}function He(e){De(R,{recursive:!0}),ze(R);for(let t of e){let o=I(R,Ue(t.code));Re(o,je(t),"utf-8")}console.log(`[skills] Wrote ${e.length} org skills to ${R}`)}function Le(e,t){let o=I(c.projectsDir,e,".claude","commands");De(o,{recursive:!0}),ze(o);for(let r of t){let s=I(o,Ue(r.code));Re(s,je(r),"utf-8")}console.log(`[skills] Wrote ${t.length} project skills for ${e}`)}var Oe,R,Fe=d(()=>{"use strict";y();Oe="ptah-",R=I(Tt(),".claude","commands")});import{execSync as B}from"child_process";function qe(e){switch(e.type){case"server:auth-result":e.payload.success||(console.error("Authentication failed:",e.payload.error),process.exit(1));break;case"server:command":console.log(`Received command: ${e.payload.action}`,e.payload);break;case"server:doc-sync":console.log(`Doc sync: ${e.payload.action} ${e.payload.fileName}`);break;case"server:claude-start":{let{commandId:t,sessionId:o,projectId:r,message:s,claudeSessionId:n,projectDir:l,systemPrompt:a}=e.payload;console.log(`Starting Claude session ${o} for project ${r}`),fe({commandId:t,sessionId:o,projectId:r,projectDir:l,message:s,claudeSessionId:n,systemPrompt:a});break}case"server:claude-stop":{console.log(`Stop requested for session ${e.payload.sessionId}`);break}case"server:chat-history-request":{let{sessionId:t,projectId:o}=e.payload;console.log(`Chat history request for session ${t}`);let r=ie(o,t);i({type:"agent:chat-history",payload:{sessionId:t,messages:r}});break}case"server:deploy-start":{let{commandId:t,deploymentId:o,projectId:r,projectCode:s,orgCode:n,projectDir:l}=e.payload;console.log(`Starting deployment for project ${s}`),xe({commandId:t,deploymentId:o,projectId:r,projectCode:s,orgCode:n,projectDir:l});break}case"server:docker-list":{let{requestId:t}=e.payload;console.log(`Docker list request: ${t}`);let o=be();i({type:"agent:docker-list",payload:{requestId:t,containers:o}});break}case"server:docker-start":{let{requestId:t,containerId:o}=e.payload;console.log(`Docker start: ${o}`);let r=_e(o);i({type:"agent:docker-action",payload:{requestId:t,...r}});break}case"server:docker-stop":{let{requestId:t,containerId:o}=e.payload;console.log(`Docker stop: ${o}`);let r=$e(o);i({type:"agent:docker-action",payload:{requestId:t,...r}});break}case"server:docker-remove":{let{requestId:t,containerId:o}=e.payload;console.log(`Docker remove: ${o}`);let r=Ie(o);i({type:"agent:docker-action",payload:{requestId:t,...r}});break}case"server:terminal-open":{let{terminalId:t,cols:o,rows:r}=e.payload;Pe(t,o,r);break}case"server:terminal-input":{Te(e.payload.terminalId,e.payload.data);break}case"server:terminal-resize":{let{terminalId:t,cols:o,rows:r}=e.payload;Ee(t,o,r);break}case"server:terminal-close":{D(e.payload.terminalId);break}case"server:skills-sync":{try{He(e.payload.skills),i({type:"agent:skills-sync-result",payload:{success:!0}})}catch(t){let o=t.message;console.error("[skills] Sync failed:",o),i({type:"agent:skills-sync-result",payload:{success:!1,error:o}})}break}case"server:project-skills-sync":{try{Le(e.payload.projectId,e.payload.skills),i({type:"agent:skills-sync-result",payload:{success:!0}})}catch(t){let o=t.message;console.error("[skills] Project sync failed:",o),i({type:"agent:skills-sync-result",payload:{success:!1,error:o}})}break}case"server:agent-info":{let{requestId:t}=e.payload;i({type:"agent:info",payload:{requestId:t,version:"0.0.31",nodeVersion:process.version,uptime:Math.floor(process.uptime()),platform:process.platform,arch:process.arch,memoryUsage:Math.round(process.memoryUsage().rss/1024/1024),projectsDir:c.projectsDir}});break}case"server:agent-upgrade":{let{requestId:t}=e.payload,o="0.0.31";console.log("[agent] Upgrade requested...");try{B("sudo npm install -g @z_ptah/agent@latest --prefer-online",{encoding:"utf-8",timeout:12e4,shell:"/bin/bash"});let r=B("ptah version",{encoding:"utf-8"}).trim().replace("ptah-agent v","");i({type:"agent:upgrade-result",payload:{requestId:t,success:!0,previousVersion:o,newVersion:r}})}catch(r){i({type:"agent:upgrade-result",payload:{requestId:t,success:!1,previousVersion:o,error:r.message}})}break}case"server:agent-restart":{let{requestId:t}=e.payload;console.log("[agent] Restart requested..."),i({type:"agent:restart-result",payload:{requestId:t,success:!0}}),setTimeout(()=>{try{B("systemctl restart ptah-agent",{timeout:1e4})}catch{}},500);break}default:console.warn("Unknown message type:",e.type)}}var Je=d(()=>{"use strict";y();q();we();z();Ce();Ne();Fe();k()});import{spawn as Et}from"child_process";async function Ve(){return new Promise(e=>{let t=Et(c.claudePath,["auth","status"],{env:{...process.env},stdio:["pipe","pipe","pipe"]}),o="";t.stdout.on("data",r=>{o+=r.toString()}),t.stderr.on("data",r=>{o+=r.toString()}),t.on("close",()=>{try{let r=JSON.parse(o.trim());e({loggedIn:r.loggedIn===!0,email:r.email,subscriptionType:r.subscriptionType})}catch{e({loggedIn:!1})}}),t.on("error",()=>{e({loggedIn:!1})})})}function Be(e){G({loggedIn:e.loggedIn,email:e.email}),i({type:"agent:claude-status",payload:e})}var Ge=d(()=>{"use strict";k();y()});import W from"ws";function G(e){We=e}function i(e){m?.readyState===W.OPEN&&m.send(JSON.stringify(e))}function Dt(){K(),O=setInterval(()=>{let e={type:"agent:heartbeat",payload:{cpuUsage:0,memoryUsage:Math.round(process.memoryUsage().heapUsed/1024/1024),activeProjects:0,claude:We}};i(e)},c.heartbeatIntervalMs)}function K(){O&&(clearInterval(O),O=null)}function Rt(){if(w)return;let e=Math.min(c.reconnectIntervalMs*Math.pow(2,U),Nt);U++,console.log(`Reconnecting in ${e/1e3}s (attempt ${U})...`),w=setTimeout(()=>{w=null,X()},e)}function X(){C||m?.readyState===W.OPEN||(C=!0,console.log(`Connecting to ${c.serverUrl}...`),m=new W(c.serverUrl),m.on("open",()=>{C=!1,console.log("Connected to Ptah Server");let e={type:"agent:auth",payload:{token:c.token}};i(e)}),m.on("message",e=>{try{let t=JSON.parse(e.toString());qe(t),t.type==="server:auth-result"&&t.payload?.success&&(console.log(`Authenticated as VPS ${t.payload.vpsId}`),U=0,Dt(),Ve().then(o=>{G({loggedIn:o.loggedIn,email:o.email}),Be(o)}))}catch(t){console.error("Failed to parse message:",t)}}),m.on("close",()=>{C=!1,K(),console.log("Disconnected from Ptah Server"),Rt()}),m.on("error",e=>{C=!1,console.error("WebSocket error:",e.message)}))}function Y(){w&&(clearTimeout(w),w=null),K(),m&&(m.close(),m=null)}var m,O,w,C,U,We,Nt,k=d(()=>{"use strict";y();Je();Ge();m=null,O=null,w=null,C=!1,U=0,We={loggedIn:!1};Nt=6e4});import Ot from"fastify";async function Ke(){await Q.listen({port:c.healthPort,host:"0.0.0.0"}),console.log(`Agent health server on http://0.0.0.0:${c.healthPort}`)}async function Z(){await Q.close()}var Q,Xe=d(()=>{"use strict";y();Q=Ot({logger:!1});Q.get("/health",async()=>({status:"ok",timestamp:new Date().toISOString(),uptime:process.uptime()}))});var jt={};async function Ut(){console.log("Starting Ptah Agent..."),console.log(` Server: ${c.serverUrl}`),console.log(` Health port: ${c.healthPort}`),console.log(` Projects dir: ${c.projectsDir}`),await Ke(),X()}var Ye=d(()=>{"use strict";y();k();Xe();process.on("SIGINT",async()=>{console.log(`
|
|
33
33
|
Shutting down...`),Y(),await Z(),process.exit(0)});process.on("SIGTERM",async()=>{console.log(`
|
|
34
|
-
Shutting down...`),Y(),await Z(),process.exit(0)});Ut().catch(e=>{console.error("Failed to start agent:",e),process.exit(1)})});import{execSync as A}from"child_process";var M="0.0.
|
|
34
|
+
Shutting down...`),Y(),await Z(),process.exit(0)});Ut().catch(e=>{console.error("Failed to start agent:",e),process.exit(1)})});import{execSync as A}from"child_process";var M="0.0.31",Qe="@z_ptah/agent",b="ptah-agent",te={start:{description:"Start the agent (via systemd)",action:()=>j(`sudo systemctl start ${b}`)},stop:{description:"Stop the agent",action:()=>j(`sudo systemctl stop ${b}`)},restart:{description:"Restart the agent",action:()=>j(`sudo systemctl restart ${b}`)},status:{description:"Show agent service status",action:()=>j(`systemctl status ${b} --no-pager`)},logs:{description:"Show agent logs (live, Ctrl+C to stop)",action:()=>{let e=process.argv[3]||"50";zt(`journalctl -u ${b} -f -n ${e}`)}},upgrade:{description:"Upgrade agent to latest version",action:Ht},version:{description:"Show current version",action:()=>console.log(`ptah-agent v${M}`)},help:{description:"Show this help message",action:Lt}};function j(e){try{A(e,{stdio:"inherit"})}catch{}}function zt(e){try{A(e,{stdio:"inherit"})}catch{}}function Ht(){console.log(`Current version: v${M}`),console.log("Checking for updates...");try{let e=A(`npm view ${Qe} version`,{encoding:"utf-8"}).trim();if(e===M){console.log(`Already on latest version (v${M})`);return}console.log(`New version available: v${e}`),console.log("Upgrading..."),A(`sudo npm cache clean --force 2>/dev/null; sudo npm install -g ${Qe}@latest --prefer-online`,{stdio:"inherit",shell:"/bin/bash"}),console.log(`
|
|
35
35
|
Upgraded to v${e}`),console.log("Restarting agent...");try{A(`sudo systemctl restart ${b}`,{stdio:"inherit"}),console.log("Agent restarted successfully.")}catch{console.log("Auto-restart failed. Run `ptah restart` manually.")}}catch(e){console.error("Upgrade failed:",e.message),process.exit(1)}}function Lt(){console.log(`
|
|
36
36
|
ptah-agent v${M}
|
|
37
37
|
`),console.log(`Usage: ptah <command>
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,6 @@ server {
|
|
|
29
29
|
}
|
|
30
30
|
`,a=`/etc/nginx/sites-available/${n}`,p=`/etc/nginx/sites-enabled/${n}`;await Ze(a,l);try{await I("ln",["-sf",a,p])}catch{}return await I("nginx",["-t"]),await I("nginx",["-s","reload"]),console.log(`Nginx configured for ${n}`),n}async function re(e){try{await I("certbot",["--nginx","-d",e,"--non-interactive","--agree-tos","--email","ssl@mybptah.com"]),console.log(`SSL configured for ${e}`)}catch(t){console.error(`SSL setup failed for ${e}:`,t)}}function $(e,t,o){let r={type:"agent:deploy-status",payload:{commandId:e.commandId,deploymentId:e.deploymentId,status:t,...o}};i(r)}async function se(e){try{$(e,"building"),await te(e.projectDir),$(e,"deploying");let r=await oe(e.projectCode,e.orgCode,3001,3002);await re(r).catch(()=>{});let s=`https://${r}`;$(e,"live",{demoUrl:s}),console.log(`Deploy complete: ${s}`)}catch(t){let o=t instanceof Error?t.message:"Unknown deploy error";console.error("Deploy failed:",o),$(e,"failed",{errorMessage:o})}}import{execSync as C}from"child_process";function ne(){try{return C(`docker ps -a --format '{"id":"{{.ID}}","name":"{{.Names}}","image":"{{.Image}}","status":"{{.Status}}","state":"{{.State}}","ports":"{{.Ports}}","createdAt":"{{.CreatedAt}}"}'`,{encoding:"utf-8",timeout:1e4}).trim().split(`
|
|
31
31
|
`).filter(t=>t.trim()).map(t=>{let o=JSON.parse(t),r=o.name.match(/^ptah-([a-f0-9-]+)/);return{...o,projectId:r?.[1]||void 0}})}catch(e){return console.error("[docker] Failed to list containers:",e),[]}}function ae(e){try{return C(`docker stop ${e}`,{encoding:"utf-8",timeout:3e4}),{success:!0}}catch(t){return{success:!1,error:t.message}}}function ie(e){try{return C(`docker start ${e}`,{encoding:"utf-8",timeout:3e4}),{success:!0}}catch(t){return{success:!1,error:t.message}}}function ce(e){try{return C(`docker rm -f ${e}`,{encoding:"utf-8",timeout:3e4}),{success:!0}}catch(t){return{success:!1,error:t.message}}}var O=null,le=!1;async function tt(){if(le)return O;le=!0;try{let{createRequire:e}=await import("module");O=e(import.meta.url)("node-pty"),console.log("[terminal] node-pty loaded successfully")}catch(e){console.warn("[terminal] node-pty not available \u2014 terminal feature disabled",e.message)}return O}var pe=5*60*1e3,y=new Map;function ot(e){let t=y.get(e);t&&(clearTimeout(t.idleTimer),t.idleTimer=setTimeout(()=>{console.log(`[terminal] ${e} idle timeout \u2014 killing`),P(e)},pe))}async function de(e,t,o){let r=await tt();if(!r){i({type:"agent:terminal-exit",payload:{terminalId:e,exitCode:1}});return}if(y.has(e)){console.warn(`[terminal] Terminal ${e} already exists`);return}let s=process.env.SHELL||"/bin/bash",n=r.spawn(s,[],{name:"xterm-256color",cols:t,rows:o,cwd:process.env.HOME||"/",env:process.env}),l=setTimeout(()=>{console.log(`[terminal] ${e} idle timeout \u2014 killing`),P(e)},pe);y.set(e,{pty:n,idleTimer:l}),n.onData(a=>{i({type:"agent:terminal-output",payload:{terminalId:e,data:a}})}),n.onExit(({exitCode:a})=>{let p=y.get(e);p&&clearTimeout(p.idleTimer),y.delete(e),i({type:"agent:terminal-exit",payload:{terminalId:e,exitCode:a}})}),console.log(`[terminal] Opened ${e} (${t}x${o})`)}function ue(e,t){let o=y.get(e);o&&(o.pty.write(t),ot(e))}function ge(e,t,o){let r=y.get(e);r&&r.pty.resize(t,o)}function P(e){let t=y.get(e);t&&(clearTimeout(t.idleTimer),t.pty.kill(),y.delete(e),console.log(`[terminal] Closed ${e}`))}import{mkdirSync as me,writeFileSync as fe,readdirSync as rt,unlinkSync as st}from"fs";import{join as w}from"path";import{homedir as nt}from"os";var ye="ptah-",A=w(nt(),".claude","commands");function he(e){return`${ye}${e}.md`}function ve(e){let t=["---"];return t.push(`name: ${e.name}`),e.description&&t.push(`description: ${e.description}`),t.push("---"),t.push(""),t.push(e.content),t.join(`
|
|
32
|
-
`)}function ke(e){try{let t=rt(e);for(let o of t)o.startsWith(ye)&&o.endsWith(".md")&&st(w(e,o))}catch{}}function Se(e){me(A,{recursive:!0}),ke(A);for(let t of e){let o=w(A,he(t.code));fe(o,ve(t),"utf-8")}console.log(`[skills] Wrote ${e.length} org skills to ${A}`)}function xe(e,t){let o=w(c.projectsDir,e,".claude","commands");me(o,{recursive:!0}),ke(o);for(let r of t){let s=w(o,he(r.code));fe(s,ve(r),"utf-8")}console.log(`[skills] Wrote ${t.length} project skills for ${e}`)}function we(e){switch(e.type){case"server:auth-result":e.payload.success||(console.error("Authentication failed:",e.payload.error),process.exit(1));break;case"server:command":console.log(`Received command: ${e.payload.action}`,e.payload);break;case"server:doc-sync":console.log(`Doc sync: ${e.payload.action} ${e.payload.fileName}`);break;case"server:claude-start":{let{commandId:t,sessionId:o,projectId:r,message:s,claudeSessionId:n,projectDir:l,systemPrompt:a}=e.payload;console.log(`Starting Claude session ${o} for project ${r}`),ee({commandId:t,sessionId:o,projectId:r,projectDir:l,message:s,claudeSessionId:n,systemPrompt:a});break}case"server:claude-stop":{console.log(`Stop requested for session ${e.payload.sessionId}`);break}case"server:chat-history-request":{let{sessionId:t,projectId:o}=e.payload;console.log(`Chat history request for session ${t}`);let r=K(o,t);i({type:"agent:chat-history",payload:{sessionId:t,messages:r}});break}case"server:deploy-start":{let{commandId:t,deploymentId:o,projectId:r,projectCode:s,orgCode:n,projectDir:l}=e.payload;console.log(`Starting deployment for project ${s}`),se({commandId:t,deploymentId:o,projectId:r,projectCode:s,orgCode:n,projectDir:l});break}case"server:docker-list":{let{requestId:t}=e.payload;console.log(`Docker list request: ${t}`);let o=ne();i({type:"agent:docker-list",payload:{requestId:t,containers:o}});break}case"server:docker-start":{let{requestId:t,containerId:o}=e.payload;console.log(`Docker start: ${o}`);let r=ie(o);i({type:"agent:docker-action",payload:{requestId:t,...r}});break}case"server:docker-stop":{let{requestId:t,containerId:o}=e.payload;console.log(`Docker stop: ${o}`);let r=ae(o);i({type:"agent:docker-action",payload:{requestId:t,...r}});break}case"server:docker-remove":{let{requestId:t,containerId:o}=e.payload;console.log(`Docker remove: ${o}`);let r=ce(o);i({type:"agent:docker-action",payload:{requestId:t,...r}});break}case"server:terminal-open":{let{terminalId:t,cols:o,rows:r}=e.payload;de(t,o,r);break}case"server:terminal-input":{ue(e.payload.terminalId,e.payload.data);break}case"server:terminal-resize":{let{terminalId:t,cols:o,rows:r}=e.payload;ge(t,o,r);break}case"server:terminal-close":{P(e.payload.terminalId);break}case"server:skills-sync":{try{Se(e.payload.skills),i({type:"agent:skills-sync-result",payload:{success:!0}})}catch(t){let o=t.message;console.error("[skills] Sync failed:",o),i({type:"agent:skills-sync-result",payload:{success:!1,error:o}})}break}case"server:project-skills-sync":{try{xe(e.payload.projectId,e.payload.skills),i({type:"agent:skills-sync-result",payload:{success:!0}})}catch(t){let o=t.message;console.error("[skills] Project sync failed:",o),i({type:"agent:skills-sync-result",payload:{success:!1,error:o}})}break}case"server:agent-info":{let{requestId:t}=e.payload;i({type:"agent:info",payload:{requestId:t,version:"0.0.
|
|
32
|
+
`)}function ke(e){try{let t=rt(e);for(let o of t)o.startsWith(ye)&&o.endsWith(".md")&&st(w(e,o))}catch{}}function Se(e){me(A,{recursive:!0}),ke(A);for(let t of e){let o=w(A,he(t.code));fe(o,ve(t),"utf-8")}console.log(`[skills] Wrote ${e.length} org skills to ${A}`)}function xe(e,t){let o=w(c.projectsDir,e,".claude","commands");me(o,{recursive:!0}),ke(o);for(let r of t){let s=w(o,he(r.code));fe(s,ve(r),"utf-8")}console.log(`[skills] Wrote ${t.length} project skills for ${e}`)}function we(e){switch(e.type){case"server:auth-result":e.payload.success||(console.error("Authentication failed:",e.payload.error),process.exit(1));break;case"server:command":console.log(`Received command: ${e.payload.action}`,e.payload);break;case"server:doc-sync":console.log(`Doc sync: ${e.payload.action} ${e.payload.fileName}`);break;case"server:claude-start":{let{commandId:t,sessionId:o,projectId:r,message:s,claudeSessionId:n,projectDir:l,systemPrompt:a}=e.payload;console.log(`Starting Claude session ${o} for project ${r}`),ee({commandId:t,sessionId:o,projectId:r,projectDir:l,message:s,claudeSessionId:n,systemPrompt:a});break}case"server:claude-stop":{console.log(`Stop requested for session ${e.payload.sessionId}`);break}case"server:chat-history-request":{let{sessionId:t,projectId:o}=e.payload;console.log(`Chat history request for session ${t}`);let r=K(o,t);i({type:"agent:chat-history",payload:{sessionId:t,messages:r}});break}case"server:deploy-start":{let{commandId:t,deploymentId:o,projectId:r,projectCode:s,orgCode:n,projectDir:l}=e.payload;console.log(`Starting deployment for project ${s}`),se({commandId:t,deploymentId:o,projectId:r,projectCode:s,orgCode:n,projectDir:l});break}case"server:docker-list":{let{requestId:t}=e.payload;console.log(`Docker list request: ${t}`);let o=ne();i({type:"agent:docker-list",payload:{requestId:t,containers:o}});break}case"server:docker-start":{let{requestId:t,containerId:o}=e.payload;console.log(`Docker start: ${o}`);let r=ie(o);i({type:"agent:docker-action",payload:{requestId:t,...r}});break}case"server:docker-stop":{let{requestId:t,containerId:o}=e.payload;console.log(`Docker stop: ${o}`);let r=ae(o);i({type:"agent:docker-action",payload:{requestId:t,...r}});break}case"server:docker-remove":{let{requestId:t,containerId:o}=e.payload;console.log(`Docker remove: ${o}`);let r=ce(o);i({type:"agent:docker-action",payload:{requestId:t,...r}});break}case"server:terminal-open":{let{terminalId:t,cols:o,rows:r}=e.payload;de(t,o,r);break}case"server:terminal-input":{ue(e.payload.terminalId,e.payload.data);break}case"server:terminal-resize":{let{terminalId:t,cols:o,rows:r}=e.payload;ge(t,o,r);break}case"server:terminal-close":{P(e.payload.terminalId);break}case"server:skills-sync":{try{Se(e.payload.skills),i({type:"agent:skills-sync-result",payload:{success:!0}})}catch(t){let o=t.message;console.error("[skills] Sync failed:",o),i({type:"agent:skills-sync-result",payload:{success:!1,error:o}})}break}case"server:project-skills-sync":{try{xe(e.payload.projectId,e.payload.skills),i({type:"agent:skills-sync-result",payload:{success:!0}})}catch(t){let o=t.message;console.error("[skills] Project sync failed:",o),i({type:"agent:skills-sync-result",payload:{success:!1,error:o}})}break}case"server:agent-info":{let{requestId:t}=e.payload;i({type:"agent:info",payload:{requestId:t,version:"0.0.31",nodeVersion:process.version,uptime:Math.floor(process.uptime()),platform:process.platform,arch:process.arch,memoryUsage:Math.round(process.memoryUsage().rss/1024/1024),projectsDir:c.projectsDir}});break}case"server:agent-upgrade":{let{requestId:t}=e.payload,o="0.0.31";console.log("[agent] Upgrade requested...");try{U("sudo npm install -g @z_ptah/agent@latest --prefer-online",{encoding:"utf-8",timeout:12e4,shell:"/bin/bash"});let r=U("ptah version",{encoding:"utf-8"}).trim().replace("ptah-agent v","");i({type:"agent:upgrade-result",payload:{requestId:t,success:!0,previousVersion:o,newVersion:r}})}catch(r){i({type:"agent:upgrade-result",payload:{requestId:t,success:!1,previousVersion:o,error:r.message}})}break}case"server:agent-restart":{let{requestId:t}=e.payload;console.log("[agent] Restart requested..."),i({type:"agent:restart-result",payload:{requestId:t,success:!0}}),setTimeout(()=>{try{U("systemctl restart ptah-agent",{timeout:1e4})}catch{}},500);break}default:console.warn("Unknown message type:",e.type)}}import{spawn as at}from"child_process";async function be(){return new Promise(e=>{let t=at(c.claudePath,["auth","status"],{env:{...process.env},stdio:["pipe","pipe","pipe"]}),o="";t.stdout.on("data",r=>{o+=r.toString()}),t.stderr.on("data",r=>{o+=r.toString()}),t.on("close",()=>{try{let r=JSON.parse(o.trim());e({loggedIn:r.loggedIn===!0,email:r.email,subscriptionType:r.subscriptionType})}catch{e({loggedIn:!1})}}),t.on("error",()=>{e({loggedIn:!1})})})}function _e(e){j({loggedIn:e.loggedIn,email:e.email}),i({type:"agent:claude-status",payload:e})}var g=null,M=null,k=null,b=!1,T=0,Ie={loggedIn:!1};function j(e){Ie=e}var it=6e4;function i(e){g?.readyState===z.OPEN&&g.send(JSON.stringify(e))}function ct(){H(),M=setInterval(()=>{let e={type:"agent:heartbeat",payload:{cpuUsage:0,memoryUsage:Math.round(process.memoryUsage().heapUsed/1024/1024),activeProjects:0,claude:Ie}};i(e)},c.heartbeatIntervalMs)}function H(){M&&(clearInterval(M),M=null)}function lt(){if(k)return;let e=Math.min(c.reconnectIntervalMs*Math.pow(2,T),it);T++,console.log(`Reconnecting in ${e/1e3}s (attempt ${T})...`),k=setTimeout(()=>{k=null,L()},e)}function L(){b||g?.readyState===z.OPEN||(b=!0,console.log(`Connecting to ${c.serverUrl}...`),g=new z(c.serverUrl),g.on("open",()=>{b=!1,console.log("Connected to Ptah Server");let e={type:"agent:auth",payload:{token:c.token}};i(e)}),g.on("message",e=>{try{let t=JSON.parse(e.toString());we(t),t.type==="server:auth-result"&&t.payload?.success&&(console.log(`Authenticated as VPS ${t.payload.vpsId}`),T=0,ct(),be().then(o=>{j({loggedIn:o.loggedIn,email:o.email}),_e(o)}))}catch(t){console.error("Failed to parse message:",t)}}),g.on("close",()=>{b=!1,H(),console.log("Disconnected from Ptah Server"),lt()}),g.on("error",e=>{b=!1,console.error("WebSocket error:",e.message)}))}function F(){k&&(clearTimeout(k),k=null),H(),g&&(g.close(),g=null)}import pt from"fastify";var q=pt({logger:!1});q.get("/health",async()=>({status:"ok",timestamp:new Date().toISOString(),uptime:process.uptime()}));async function $e(){await q.listen({port:c.healthPort,host:"0.0.0.0"}),console.log(`Agent health server on http://0.0.0.0:${c.healthPort}`)}async function J(){await q.close()}async function dt(){console.log("Starting Ptah Agent..."),console.log(` Server: ${c.serverUrl}`),console.log(` Health port: ${c.healthPort}`),console.log(` Projects dir: ${c.projectsDir}`),await $e(),L()}process.on("SIGINT",async()=>{console.log(`
|
|
33
33
|
Shutting down...`),F(),await J(),process.exit(0)});process.on("SIGTERM",async()=>{console.log(`
|
|
34
34
|
Shutting down...`),F(),await J(),process.exit(0)});dt().catch(e=>{console.error("Failed to start agent:",e),process.exit(1)});
|