UNPKG

grix-connector

Version:

Connect local AI coding agents (Claude, Codex, Gemini, Qwen, DeepSeek, Cursor, OpenCode, Pi, OpenHuman, Reasonix) to the Grix scheduling platform. Also serves as an OpenClaw plugin for Grix channel transport.

3 lines (2 loc) 2.09 kB
import{EventEmitter as c}from"node:events";import{JsonRpcTransport as p}from"../core/transport/json-rpc.js";import{log as a}from"../core/log/index.js";import{resolveCommandPath as h,spawnCommand as m,killProcessGroup as d}from"../core/runtime/spawn.js";class _ extends c{proc=null;_transport=null;_alive=!1;bridgeLog;constructor(r){super(),this.bridgeLog=r??null}get transport(){return this._transport}get pid(){return this.proc?.pid}get alive(){return this._alive}async start(r){if(this.proc)throw new Error("process already started");const o={...process.env,...r.env},i=h(r.command,typeof o.PATH=="string"?o.PATH:void 0),e=m(i,r.args??[],{cwd:r.cwd,env:o}).process;if(this.proc=e,this._alive=!0,this.bridgeLog?.logLifecycle(`spawn command=${i} pid=${e.pid??""}`),e.on("error",t=>{this._alive=!1,this.bridgeLog?.logLifecycle(`process error: ${t.message}`),this.emitProcessError(t)}),e.on("exit",(t,s)=>{this._alive=!1,this.bridgeLog?.logLifecycle(`exit code=${t} signal=${s??""}`),a.info("agent-process",`exited command=${i} pid=${e.pid} code=${t} signal=${s}`),this.emit("exit",t)}),e.stderr?.on("data",t=>{const s=t.toString();if(s.trim()){this.bridgeLog?.logStderr(s),process.stderr.write(`[agent stderr] ${s}`);for(const l of s.split(` `))l.trim()&&a.info("agent-stderr",`[${i}] ${l.trimEnd()}`)}this.emit("stderr",t)}),!e.stdin||!e.stdout)throw new Error("failed to create stdin/stdout pipes");const n=new p(e.stdout,e.stdin,void 0,void 0,this.bridgeLog);return n.on("close",()=>{this._alive=!1}),this._transport=n,n}async close(r=5e3){if(this._transport?.close(),this._transport=null,!this.proc||!this.proc.pid){this._alive=!1;return}d(this.proc,"SIGTERM"),!(!(this.proc.exitCode!==null||this.proc.signalCode!==null)&&await Promise.race([new Promise(e=>{this.proc.once("exit",()=>e(!0))}),new Promise(e=>{setTimeout(()=>e(!1),r)})]))&&this.proc.pid&&d(this.proc,"SIGKILL"),this._alive=!1,this.proc=null}emitProcessError(r){if(this.listenerCount("error")===0){a.error("agent-process",`Process error (no listeners): ${r.message}`);return}this.emit("error",r)}}export{_ as AgentProcess};