acp-chat 0.2.7 → 0.2.8

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.
Files changed (2) hide show
  1. package/dist/cli.js +0 -1
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- #!/usr/bin/env node
3
2
  import{EventEmitter as J}from"node:events";import*as P from"node:net";function O(n){let e=JSON.stringify(n);if(e===void 0)throw new TypeError("Value is not JSON-serializable");return e+`
4
3
  `}function N(n){return JSON.parse(n)}var y={CAPACITY_EXCEEDED:-32e3,REQUEST_TIMEOUT:-32001,DISCONNECTED:-32004},C=class extends Error{code;data;constructor(e,t,s){super(t),this.name="ACPError",this.code=e,this.data=s}},S=class extends C{constructor(e="Capacity exceeded",t){super(y.CAPACITY_EXCEEDED,e,t),this.name="CapacityExceededError"}},x=class extends C{constructor(e="Request timeout",t){super(y.REQUEST_TIMEOUT,e,t),this.name="RequestTimeoutError"}},T=class extends C{constructor(e="Disconnected",t){super(y.DISCONNECTED,e,t),this.name="DisconnectedError"}};var v=class extends J{opts;socket=null;state="disconnected";reconnectAttempt=0;reconnectTimer=null;lineBuffer="";closedByUser=!1;constructor(e){super(),this.opts=e}connect(){return this.state==="connected"||this.state==="connecting"?Promise.resolve():this.state==="closed"?Promise.reject(new Error("Client has been closed")):(this.closedByUser=!1,this.reconnectAttempt=0,this.createConnection())}send(e){if(this.state!=="connected"||!this.socket)throw new T("Cannot send: not connected to stdio Bus");this.socket.write(O(e))}close(){this.closedByUser=!0,this.clearReconnectTimer();let e=this.state;return this.state="closed",e==="closed"||e==="disconnected"?Promise.resolve():new Promise(t=>{if(this.socket){let s=this.socket;if(this.socket=null,s.destroyed){t();return}s.once("close",()=>t()),s.destroy()}else t()})}isConnected(){return this.state==="connected"}getState(){return this.state}createConnection(){return new Promise((e,t)=>{this.state=this.reconnectAttempt===0?"connecting":"reconnecting",this.lineBuffer="";let s=this.buildConnectOptions(),c=P.createConnection(s);this.socket=c;let l=()=>{a(),this.state="connected",this.reconnectAttempt=0,this.wireSocketEvents(c),e()},o=d=>{a(),this.reconnectAttempt===0&&this.state==="connecting"&&(this.state="disconnected",t(d))},a=()=>{c.removeListener("connect",l),c.removeListener("error",o)};c.once("connect",l),c.once("error",o)})}buildConnectOptions(){if(this.opts.connectionType==="unix")return{path:this.opts.address};let e=this.opts.address.lastIndexOf(":");if(e===-1)throw new Error(`Invalid TCP address: expected "host:port", got "${this.opts.address}"`);let t=this.opts.address.slice(0,e),s=parseInt(this.opts.address.slice(e+1),10);if(isNaN(s))throw new Error(`Invalid TCP port in address "${this.opts.address}"`);return{host:t,port:s}}wireSocketEvents(e){e.on("data",t=>this.handleData(t.toString("utf-8"))),e.on("error",t=>this.emit("error",t)),e.on("close",()=>{this.closedByUser||this.state==="closed"||(this.state="disconnected",this.emit("disconnect"),this.scheduleReconnect())})}handleData(e){this.lineBuffer+=e;let t;for(;(t=this.lineBuffer.indexOf(`
5
4
  `))!==-1;){let s=this.lineBuffer.slice(0,t);if(this.lineBuffer=this.lineBuffer.slice(t+1),s.length!==0)try{this.emit("message",N(s))}catch(c){this.emit("framingError",s,c instanceof Error?c:new Error(String(c)))}}}scheduleReconnect(){if(this.closedByUser||this.state==="closed")return;if(this.reconnectAttempt>=this.opts.maxReconnectAttempts){this.state="disconnected",this.emit("disconnect");return}this.state="reconnecting";let e=this.reconnectAttempt++,t=Math.random()*this.opts.baseReconnectDelayMs,s=Math.min(this.opts.baseReconnectDelayMs*Math.pow(2,e)+t,this.opts.maxReconnectDelayMs);this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.emit("reconnect",this.reconnectAttempt),this.attemptReconnect()},s)}attemptReconnect(){if(this.closedByUser||this.state==="closed")return;this.lineBuffer="";let e=P.createConnection(this.buildConnectOptions());this.socket=e,e.once("connect",()=>{e.removeAllListeners("error"),this.state="connected",this.reconnectAttempt=0,this.wireSocketEvents(e)}),e.once("error",()=>{e.destroy(),this.scheduleReconnect()})}clearReconnectTimer(){this.reconnectTimer!==null&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}};var $={maxPending:4096,defaultTimeoutMs:3e4},I=1e3;function A(n){let e={...$,...n};e.defaultTimeoutMs<I&&(e.defaultTimeoutMs=I);let t=new Map;function s(o,a){if(t.size>=e.maxPending)return Promise.reject(new S(`Maximum pending requests (${e.maxPending}) exceeded`));let d=a??e.defaultTimeoutMs;return d<I&&(d=I),new Promise((h,f)=>{let R=setTimeout(()=>{t.delete(o),f(new x(`Request ${String(o)} timed out after ${d}ms`,{id:o,timeoutMs:d}))},d);R.unref&&R.unref(),t.set(o,{id:o,registeredAt:Date.now(),timeoutMs:d,timeoutHandle:R,resolve:h,reject:f})})}function c(o){let a=t.get(o.id);return a?(clearTimeout(a.timeoutHandle),t.delete(o.id),a.resolve(o),!0):!1}function l(o){for(let[,a]of t)clearTimeout(a.timeoutHandle),a.reject(o);t.clear()}return{register:s,resolve:c,cancelAll:l,pendingCount:()=>t.size,hasPending:o=>t.has(o)}}import{EventEmitter as q}from"node:events";function D(n,e){let{agentId:t,requestTimeoutMs:s=12e4,clientInfo:c}=e,l=new q,o=A({defaultTimeoutMs:s}),a=1,d=e.clientSessionId??`client-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,h=new Map;n.on("message",r=>{let i=r;if(!(!i||i.jsonrpc!=="2.0")){if("id"in i&&("result"in i||"error"in i)){o.resolve(i);return}if("method"in i&&!("id"in i)){let p=i.method,u=i.params;if(p==="session/update"&&u){let g=u.sessionId,E=u.update,w=h.get(g);w&&w.push(E),l.emit("update",g,E)}l.emit("notification",p,u)}}});function f(r,i){let p=a++,u={jsonrpc:"2.0",id:p,method:r,agentId:t,sessionId:d,params:i},g=o.register(p);return n.send(u),g}async function R(){let r=await f("initialize",{protocolVersion:1,clientCapabilities:{},clientInfo:c??{name:"acp-chat",version:"1.0.0"}});if(r.error)throw new Error(`initialize: [${r.error.code}] ${r.error.message}`);return r.result}async function U(r){let i={cwd:process.cwd(),mcpServers:[]};r?.length&&(i.configOptions=r);let p=await f("session/new",i);if(p.error)throw new Error(`session/new: [${p.error.code}] ${p.error.message}`);return{...p.result,clientSessionId:d}}async function M(r,i,p="user"){h.set(r,[]);let u=await f("session/prompt",{sessionId:r,prompt:[{type:"text",role:p,text:i}]});await new Promise(m=>setTimeout(m,200));let g=h.get(r)??[];if(h.delete(r),u.error)throw new Error(`session/prompt: [${u.error.code}] ${u.error.message}`);let E=u.result,w=[];for(let m of g)if(m.sessionUpdate==="agent_message_chunk"&&m.content?.text&&w.push(m.content.text),m.sessionUpdate==="tool_call_update"&&m.content)for(let k of m.content)k.content?.text&&w.push(k.content.text);return{stopReason:E.stopReason,updates:g,text:w.join("")}}async function _(r,i){let p=await f("session/configure",{sessionId:r,options:i});if(p.error)throw new Error(`session/configure: [${p.error.code}] ${p.error.message}`)}function b(r){n.send({jsonrpc:"2.0",method:"session/cancel",params:{sessionId:r},agentId:t,sessionId:d})}return Object.assign(l,{initialize:R,sessionNew:U,sessionPrompt:M,sessionConfigure:_,sessionCancel:b,requestTracker:o})}var B=process.env.ACP_BUS_ADDRESS??"127.0.0.1:9800",j=process.env.ACP_AGENT_ID??"codex-acp";async function z(){let n=process.argv.slice(2),e,t,s;n[0]==="new"?(n.length<2&&(console.error('Usage: acp-chat new "<message>"'),process.exit(1)),s=n[1]):(n.length<3&&(console.error('Usage: acp-chat <clientSessionId> <sessionId> "<message>"'),process.exit(1)),e=n[0],t=n[1],s=n[2]);let c=new v({address:B,connectionType:"tcp",maxReconnectAttempts:3,baseReconnectDelayMs:500,maxReconnectDelayMs:5e3});try{await c.connect();let l=D(c,{agentId:j,requestTimeoutMs:300*1e3,clientInfo:{name:"acp-chat-cli",version:"1.0.0"},clientSessionId:e});if(l.on("update",(a,d)=>{d.sessionUpdate==="agent_message_chunk"&&process.stdout.write(d.content.text)}),await l.initialize(),t)console.error(`CLIENT_SESSION_ID=${e}`),console.error(`SESSION_ID=${t} (continued)`);else{let a=await l.sessionNew();t=a.sessionId,console.error(`CLIENT_SESSION_ID=${a.clientSessionId}`),console.error(`SESSION_ID=${t}`)}let o=await l.sessionPrompt(t,s);process.stdout.write(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "acp-chat",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "ACP Chat — agent-to-agent dialogue over TCP/Unix socket using the ACP protocol.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",