@iflow-ai/iflow-cli-sdk 0.2.0 → 0.2.1-beta.1
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/CHANGELOG.md +18 -0
- package/README_CN.md +39 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +312 -54
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,24 @@
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
### 新增能力
|
|
13
|
+
- **stdio 传输模式**:
|
|
14
|
+
- 新增 `TransportMode.STDIO` 传输模式,支持通过标准输入输出与 iFlow CLI 通信
|
|
15
|
+
- 新增 `StdioTransport` 类,实现基于 stdio 的消息传输
|
|
16
|
+
- 新增 `ITransport` 接口,统一 WebSocket 和 stdio 两种传输方式
|
|
17
|
+
- 配置选项新增 `transportMode` 参数,可选择 `websocket` 或 `stdio` 模式
|
|
18
|
+
- stdio 模式提供更低延迟和更简单的架构,特别适合本地开发和测试
|
|
19
|
+
- **示例代码**:
|
|
20
|
+
- 新增 `examples/stdio-mode.ts` - stdio 模式基本用法示例
|
|
21
|
+
- 新增 `examples/compare-transports.ts` - 对比两种传输模式的示例
|
|
22
|
+
|
|
23
|
+
### 文档
|
|
24
|
+
- 新增 `STDIO_TRANSPORT.md` - stdio 传输模式完整文档
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
10
28
|
## [0.2.0] - 2026-02-04
|
|
11
29
|
|
|
12
30
|
### 新增能力
|
package/README_CN.md
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
- 🚀 **自动进程管理** - 零配置设置!SDK 自动启动和管理 iFlow CLI
|
|
15
15
|
- 🔌 **智能端口检测** - 自动查找可用端口,无冲突
|
|
16
16
|
- 🔄 **双向通信** - 实时流式传输消息和响应
|
|
17
|
+
- 📡 **多种传输模式** - 支持 WebSocket 和 stdio 两种传输方式,stdio 模式提供更低延迟
|
|
17
18
|
- 🛠️ **工具调用管理** - 通过细粒度权限处理和控制工具执行
|
|
18
19
|
- 🔐 **权限请求处理** - 管理和响应工具执行权限请求
|
|
19
20
|
- 🤖 **子代理支持** - 通过 `agentId` 传播跟踪和管理多个 AI 代理
|
|
@@ -108,6 +109,32 @@ async function main() {
|
|
|
108
109
|
iflow --experimental-acp --port 8090
|
|
109
110
|
```
|
|
110
111
|
|
|
112
|
+
### 高级:stdio 传输模式
|
|
113
|
+
|
|
114
|
+
SDK 现在支持 stdio 传输模式,提供更低延迟和更简单的架构,特别适合本地开发:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { IFlowClient, TransportMode } from "@iflow-ai/iflow-cli-sdk";
|
|
118
|
+
|
|
119
|
+
async function main() {
|
|
120
|
+
const client = new IFlowClient({
|
|
121
|
+
transportMode: TransportMode.STDIO, // 使用 stdio 模式
|
|
122
|
+
autoStartProcess: true, // 自动启动进程
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
await client.connect();
|
|
126
|
+
await client.sendMessage("Hello, iFlow!");
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**特点:**
|
|
131
|
+
- ✅ 更低延迟(无网络层开销)
|
|
132
|
+
- ✅ 更简单的架构(无需端口管理)
|
|
133
|
+
- ✅ 适合本地开发和测试
|
|
134
|
+
- ⚠️ 仅支持本地通信(不支持远程连接)
|
|
135
|
+
|
|
136
|
+
详细信息请参阅 [STDIO_TRANSPORT.md](STDIO_TRANSPORT.md)。
|
|
137
|
+
|
|
111
138
|
### 简单示例
|
|
112
139
|
|
|
113
140
|
#### 简单查询
|
|
@@ -392,6 +419,18 @@ await client.connect();
|
|
|
392
419
|
const models = await client.config.get("models");
|
|
393
420
|
console.log("可用模型:", models);
|
|
394
421
|
|
|
422
|
+
// 查看模型能力
|
|
423
|
+
models.forEach((model) => {
|
|
424
|
+
console.log(`${model.name}:`);
|
|
425
|
+
const caps = model.capabilities;
|
|
426
|
+
if (caps) {
|
|
427
|
+
if (caps.thinking) console.log(" - 支持深度思考");
|
|
428
|
+
if (caps.image) console.log(" - 支持图像理解");
|
|
429
|
+
if (caps.audio) console.log(" - 支持音频理解");
|
|
430
|
+
if (caps.video) console.log(" - 支持视频理解");
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
|
|
395
434
|
const currentModel = await client.config.get("model");
|
|
396
435
|
console.log("当前模型:", currentModel);
|
|
397
436
|
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("fs"),t=require("path"),s=require("ws"),o=require("fs/promises"),n=require("os"),i=require("net"),r=require("child_process"),a=require("assert"),l=require("events"),c=require("buffer"),d=require("stream"),u=require("util");function p(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(s){if("default"!==s){var o=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,o.get?o:{enumerable:!0,get:function(){return e[s]}})}}),t.default=e,Object.freeze(t)}var h,g,m,f,w,y,S,x,E,I,T,v,_,b=p(e),P=p(t),A=p(o),R=p(n),C=p(i),O=p(r);class $ extends Error{constructor(e,t){super(e),this.name="IFlowError",this.details=t||{}}}class M extends ${constructor(e,t){super(e,t),this.name="TimeoutError"}}class N extends ${constructor(e,t){super(e,{rawData:t}),this.name="JSONDecodeError",this.rawData=t}}class L extends ${constructor(e,t){super(e,t),this.name="IFlowNotInstalledError"}}class k extends ${constructor(e,t){super(e,t),this.name="IFlowProcessError"}}class F extends ${constructor(e,t){super(e,t),this.name="PortNotAvailableError"}}class q extends ${constructor(e,t){super(e,t),this.name="ConnectionError"}}class U extends ${constructor(e,t){super(e,t),this.name="TransportError"}}class D extends ${constructor(e,t){super(e,t),this.name="PermissionError"}}class j extends ${constructor(e,t){super(e,t),this.name="ValidationError"}}class G extends ${constructor(e,t){super(e,t),this.name="ProtocolError"}}class H extends ${constructor(e,t){super(e,t),this.name="AuthenticationError"}}exports.LogLevel=void 0,(h=exports.LogLevel||(exports.LogLevel={}))[h.DEBUG=0]="DEBUG",h[h.INFO=1]="INFO",h[h.WARN=2]="WARN",h[h.ERROR=3]="ERROR",exports.PermissionMode=void 0,(g=exports.PermissionMode||(exports.PermissionMode={})).AUTO="auto",g.MANUAL="manual",g.SELECTIVE="selective",exports.ApprovalMode=void 0,(m=exports.ApprovalMode||(exports.ApprovalMode={})).DEFAULT="default",m.AUTO_EDIT="autoEdit",m.YOLO="yolo",m.PLAN="plan",exports.HookEventType=void 0,(f=exports.HookEventType||(exports.HookEventType={})).PRE_TOOL_USE="PreToolUse",f.POST_TOOL_USE="PostToolUse",f.STOP="Stop",f.SUBAGENT_STOP="SubagentStop",f.SET_UP_ENVIRONMENT="SetUpEnvironment",exports.PlanPriority=void 0,(w=exports.PlanPriority||(exports.PlanPriority={})).HIGH="high",w.MEDIUM="medium",w.LOW="low",exports.PlanStatus=void 0,(y=exports.PlanStatus||(exports.PlanStatus={})).PENDING="pending",y.IN_PROGRESS="in_progress",y.COMPLETED="completed",exports.StopReason=void 0,(S=exports.StopReason||(exports.StopReason={})).END_TURN="end_turn",S.MAX_TOKENS="max_tokens",S.REFUSAL="refusal",S.CANCELLED="cancelled",exports.ToolCallStatus=void 0,(x=exports.ToolCallStatus||(exports.ToolCallStatus={})).PENDING="pending",x.IN_PROGRESS="in_progress",x.COMPLETED="completed",x.FAILED="failed",exports.ToolCallContentType=void 0,(E=exports.ToolCallContentType||(exports.ToolCallContentType={})).DIFF="diff",E.MARKDOWN="markdown",exports.ToolCallConfirmationType=void 0,(I=exports.ToolCallConfirmationType||(exports.ToolCallConfirmationType={})).EDIT="edit",I.EXECUTE="execute",I.MCP="mcp",I.FETCH="fetch",I.OTHER="other",exports.ToolCallConfirmationOutcome=void 0,(T=exports.ToolCallConfirmationOutcome||(exports.ToolCallConfirmationOutcome={})).ALLOW="allow",T.ALWAYS_ALLOW="alwaysAllow",T.ALWAYS_ALLOW_TOOL="alwaysAllowTool",T.ALWAYS_ALLOW_MCP_SERVER="alwaysAllowMcpServer",T.REJECT="reject",exports.ToolCallIconType=void 0,(v=exports.ToolCallIconType||(exports.ToolCallIconType={})).URL="url",v.EMOJI="emoji",exports.MessageType=void 0,(_=exports.MessageType||(exports.MessageType={})).PLAN="plan",_.USER="user",_.ASSISTANT="assistant",_.TOOL_CALL="tool_call",_.ERROR="error",_.TASK_FINISH="task_finish",_.ASK_USER_QUESTIONS="ask_user_questions",_.EXIT_PLAN_MODE="exit_plan_mode",_.PERMISSION_REQUEST="permission_request";const W="2.0";var Q,K,B,z;function X(e){if(e instanceof Error){const t=e,s=t.details?.data?.details;return s?`${e.message}\n${s}`:e.message}return e?String(e):"unknown error"}!function(e){e.INITIALIZE="initialize",e.AUTHENTICATE="authenticate",e.SESSION_NEW="session/new",e.SESSION_LOAD="session/load",e.SESSION_PROMPT="session/prompt",e.SESSION_CANCEL="session/cancel",e.SESSION_SET_MODE="session/set_mode",e.SESSION_SET_MODEL="session/set_model",e.SESSION_SET_THINK="session/set_think"}(Q||(Q={})),function(e){e.SESSION_UPDATE="session/update",e.SESSION_REQUEST_PERMISSION="session/request_permission",e.FS_READ_TEXT_FILE="fs/read_text_file",e.FS_WRITE_TEXT_FILE="fs/write_text_file",e.PUSH_TOOL_CALL="pushToolCall",e.UPDATE_TOOL_CALL="updateToolCall",e.NOTIFY_TASK_FINISH="notifyTaskFinish",e.ASK_USER_QUESTIONS="_iflow/user/questions",e.EXIT_PLAN_MODE="_iflow/plan/exit"}(K||(K={})),function(e){e.PLAN="plan",e.TOOL_CALL="tool_call",e.TOOL_CALL_UPDATE="tool_call_update",e.USER_MESSAGE_CHUNK="user_message_chunk",e.AGENT_MESSAGE_CHUNK="agent_message_chunk",e.AGENT_THOUGHT_CHUNK="agent_thought_chunk"}(B||(B={})),function(e){e.ERROR="error",e.RESPONSE="response",e.FILE_READ="file_read",e.FILE_WRITE="file_write",e.SESSION_UPDATE="session_update",e.TOOL_CALL="tool_call",e.TOOL_UPDATE="tool_update",e.TASK_FINISH="task_finish",e.ASK_USER_QUESTIONS="ask_user_questions",e.EXIT_PLAN_MODE="exit_plan_mode",e.PERMISSION_REQUEST="permission_request",e.UNKNOWN="unknown"}(z||(z={}));class J{constructor(e={}){const t=e.level||"INFO";this.level=exports.LogLevel[t]}debug(e){this.log(exports.LogLevel.DEBUG,e)}info(e){this.log(exports.LogLevel.INFO,e)}warn(e){this.log(exports.LogLevel.WARN,e)}error(e,t){this.log(exports.LogLevel.ERROR,e,t)}log(e,t,s){if(e<this.level)return;const o=`[${(new Date).toLocaleString("sv-SE").replace("T"," ")}] ${exports.LogLevel[e]}: ${t}${s?`\n${s.stack}`:""}`;switch(e){case exports.LogLevel.DEBUG:console.debug(o);break;case exports.LogLevel.INFO:console.info(o);break;case exports.LogLevel.WARN:console.warn(o);break;case exports.LogLevel.ERROR:console.error(o)}}}const V=new J;function Y(e){return!!e&&"id"in e&&"result"in e&&null!=e.result}function Z(e){return!!e&&"id"in e&&"error"in e&&null!=e.error}function ee(e){return!!e&&"method"in e&&!("result"in e)&&!("error"in e)}class te{constructor(e){this.requestId=0,this.initialized=!1,this.authenticated=!1,this.pendingPermissionRequests=new Map,this.maxPendingRequests=10,this.requestTtl=300,this.logger=e.logger||V,this.transport=e.transport,this.fileHandler=e.fileHandler,this.permissionMode=e.permissionMode||exports.PermissionMode.AUTO,this.autoApproveTypes=e.autoApproveTypes||["read","fetch","list"]}nextRequestId(){return++this.requestId}checkAuthenticated(){if(!this.initialized)throw new G("Protocol not initialized. Call initialize() first.");if(!this.authenticated)throw new G("Not authenticated. Call authenticate() first.")}async sendResult(e,t){const s={jsonrpc:W,id:e,result:t};await this.transport.send(s)}async sendError(e,t,s){const o={jsonrpc:W,id:e,error:{code:t,message:s}};await this.transport.send(o)}async waitForReadySignal(){for await(const e of this.transport.receive()){const t=e.trim();if("//ready"===t){this.logger.info("Received //ready signal");break}t.startsWith("//")&&this.logger.debug(`Control message: ${t}`)}}async waitForMessageResponse(e,t,s){const{timeout:o,timeoutMsg:n=`Timeout after ${o} seconds`}=s||{};let i=null;try{const s=this.transport.waitForResponse(e),r=o&&o>0?await Promise.race([s,new Promise((e,t)=>{i=setTimeout(()=>t(new M(n)),o)})]):await s;let a;try{a=JSON.parse(r.trim())}catch(e){throw this.logger.error(`Failed to parse response: ${X(e)}`),new N("Invalid JSON received",r)}return t(a)}catch(e){if(e instanceof M)throw e;throw e}finally{null!==i&&clearTimeout(i)}}async initialize(e={}){if(this.initialized)return this.logger.warn("Protocol already initialized"),{protocolVersion:1,isAuthenticated:this.authenticated};this.logger.info("Waiting for //ready signal..."),await this.waitForReadySignal();const t=this.nextRequestId(),s={jsonrpc:W,id:t,method:Q.INITIALIZE,params:{protocolVersion:1,clientCapabilities:{fs:{readTextFile:!1,writeTextFile:!1},terminal:!1},...e}};await this.transport.send(s),this.logger.info("Sent initialize request");const o=await this.waitForMessageResponse(t,e=>{if("error"in e)throw new G(`Initialize failed: ${e.error?.message}`,e.error);const t=e.result||{};return this.initialized=!0,this.authenticated=t.isAuthenticated||!1,this.logger.info(`Initialized with protocol version: ${t.protocolVersion}, authenticated: ${this.authenticated}`),t},{timeout:1e4,timeoutMsg:"Initialize timeout after 10 seconds"});if(o)return o;throw new G("Connection closed during initialization")}async authenticate(e={}){if(this.authenticated)return void this.logger.warn("Already authenticated");const t=e.methodId||"iflow",s=this.nextRequestId(),o={jsonrpc:W,id:s,method:Q.AUTHENTICATE,params:{...e,methodId:t}};await this.transport.send(o),this.logger.info(`Sent authenticate request with method: ${o.params.methodId}`);if(!await this.waitForMessageResponse(s,e=>{if("error"in e)throw new H(`Authentication failed: ${e.error?.message}`,e.error);const s=e.result||{};return s.methodId===t?(this.authenticated=!0,this.logger.info(`Authentication successful with method: ${s.methodId}`),!0):(this.authenticated=!0,this.logger.warn(`Unexpected methodId in response: ${s.methodId} (expected ${t})`),!0)},{timeout:1e4,timeoutMsg:"Authentication timeout after 10 seconds"}))throw new H("Connection closed during authentication")}async createSession(e={}){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:W,id:t,method:Q.SESSION_NEW,params:{...e,cwd:e.cwd||process.cwd(),mcpServers:e.mcpServers||[]}};await this.transport.send(s),this.logger.info(`Sent session/new request with cwd: ${e.cwd}`);const o=await this.waitForMessageResponse(t,e=>{if("error"in e)throw new G(`session/new failed: ${e.error?.message}`,e.error);const t=e.result||{};if(t.sessionId)return this.logger.info(`Created session: ${t.sessionId}`),t;throw new G(`Invalid session/new response: ${JSON.stringify(t)}`)},{timeout:1e4,timeoutMsg:"Session creation timeout after 10 seconds"});if(o)return o;throw new G("Connection closed while waiting for session/new response")}async loadSession(e){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:W,id:t,method:Q.SESSION_LOAD,params:{...e,cwd:e.cwd||process.cwd(),mcpServers:e.mcpServers||[]}};await this.transport.send(s),this.logger.info(`Sent session/load request for session: ${e.sessionId}`);if(!await this.waitForMessageResponse(t,t=>{if("error"in t){if(-32601===t.error.code)throw new G("session/load is not supported by the current iFlow version. Use session/new to create a new session instead.",t.error);throw new G(`session/load failed: ${t.error?.message}`,t.error)}return this.logger.info(`Session loaded successfully: ${e.sessionId}`),!0},{timeout:1e4,timeoutMsg:"Session load timeout after 10 seconds"}))throw new G("Connection closed while waiting for session/load response")}async sendPrompt(e){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:W,id:t,method:Q.SESSION_PROMPT,params:e};return await this.transport.send(s),this.logger.info(`Sent prompt with ${e.prompt.length} content blocks`),t}async cancelSession(e){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:W,id:t,method:Q.SESSION_CANCEL,params:e};await this.transport.send(s),this.logger.info("Sent session/cancel request")}async setMode(e){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:W,id:t,method:Q.SESSION_SET_MODE,params:e};await this.transport.send(s),this.logger.info(`Sent session/set_mode request with modeId: ${e.modeId}`);try{const e=await this.waitForMessageResponse(t,e=>{if("error"in e)throw new G(`session/set_mode failed: ${e.error?.message}`,e.error);return e.result},{timeout:1e4,timeoutMsg:"Set mode timeout after 10 seconds"});if(!e?.success)throw new G("session/set_mode failed: operation unsuccessful");return e.currentModeId}catch(t){throw this.logger.error(`Failed to set mode to ${e.modeId}: ${X(t)}`),t}}async setModel(e){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:W,id:t,method:Q.SESSION_SET_MODEL,params:e};await this.transport.send(s),this.logger.info(`Sent session/set_model request with modelId: ${e.modelId}`);try{const e=await this.waitForMessageResponse(t,e=>{if("error"in e)throw new G(`session/set_model failed: ${e.error?.message}`,e.error);return e.result},{timeout:1e4,timeoutMsg:"Set model timeout after 10 seconds"});if(!e?.success)throw new G("session/set_model failed: operation unsuccessful");return e.currentModelId}catch(t){throw this.logger.error(`Failed to set model to ${e.modelId}: ${X(t)}`),t}}async setThink(e){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:W,id:t,method:Q.SESSION_SET_THINK,params:e};await this.transport.send(s),this.logger.info(`Sent session/set_think request with thinkEnabled: ${e.thinkEnabled}, thinkConfig: ${e.thinkConfig||"default"}`);try{const e=await this.waitForMessageResponse(t,e=>{if("error"in e)throw new G(`session/set_think failed: ${e.error?.message}`,e.error);return e.result},{timeout:1e4,timeoutMsg:"Set think timeout after 10 seconds"});if(!e?.success)throw new G("session/set_think failed: operation unsuccessful");return e}catch(e){throw this.logger.error(`Failed to set think: ${X(e)}`),e}}async respondToAskUserQuestions(e,t){const s={answers:t};await this.sendResult(e,s),this.logger.info(`Sent ask_user_questions response with ${Object.keys(t).length} answers`)}async respondToExitPlanMode(e,t){const s={approved:t};await this.sendResult(e,s),this.logger.info("Sent exit_plan_mode response: "+(t?"approved":"rejected"))}async sendPermissionResponse(e,t){if(!this.pendingPermissionRequests.has(e))throw new Error(`Unknown permission request: ${e}`);const s={outcome:{outcome:"selected",optionId:t}};try{await this.sendResult(e,s),this.pendingPermissionRequests.delete(e),this.logger.info(`Sent permission response for request ${e}: ${t}`)}catch(t){throw this.logger.error(`Failed to send permission response for request ${e}: ${X(t)}`),t}}async cancelPermissionResponse(e){if(!this.pendingPermissionRequests.has(e))throw new Error(`Unknown permission request: ${e}`);const t={outcome:{outcome:"cancelled"}};try{await this.sendResult(e,t),this.pendingPermissionRequests.delete(e),this.logger.info(`Cancelled permission request: ${e}`)}catch(t){throw this.logger.error(`Failed to cancel permission request ${e}: ${X(t)}`),t}}async*handleMessages(){for await(const e of this.transport.receive()){if(e.trim().startsWith("//")){this.logger.debug(`Control message: ${e.trim()}`);continue}let t;try{t=JSON.parse(e.trim())}catch(t){throw this.logger.error(`Failed to parse message: ${X(t)}`),new N("Invalid JSON received",e)}if(ee(t)){const e=await this.handleClientMessage(t);yield e}else Y(t)?yield{type:"response",id:t.id,result:t.result}:Z(t)&&(yield{type:"error",code:t.error.code,error:`${t.error.message}, detail: ${t.error.data?.details||"unknown"}`})}}async handleClientMessage(e){const{method:t}=e;switch(t){case K.FS_READ_TEXT_FILE:return await this.handleReadTextFile(e);case K.FS_WRITE_TEXT_FILE:return await this.handleWriteTextFile(e);case K.SESSION_UPDATE:return await this.handleSessionUpdate(e);case K.SESSION_REQUEST_PERMISSION:return await this.handleRequestPermission(e);case K.PUSH_TOOL_CALL:return await this.handlePushToolCall(e);case K.UPDATE_TOOL_CALL:return await this.handleUpdateToolCall(e);case K.NOTIFY_TASK_FINISH:return await this.handleNotifyTaskFinish(e);case K.ASK_USER_QUESTIONS:return await this.handleAskUserQuestions(e);case K.EXIT_PLAN_MODE:return await this.handleExitPlanMode(e);default:return await this.handleUnknownMessage(e)}}async handleReadTextFile(e){const{id:t,method:s,params:o}=e,{path:n,limit:i,line:r}=o||{};let a;if(this.logger.info(`fs/read_text_file request for: ${n}`),!this.fileHandler){const e="File system access not configured";return void 0!==t&&await this.sendError(t,-32603,e),{type:"error",code:-32603,error:e,method:s}}try{a=await this.fileHandler.readFile(n,r,i)}catch(e){const o=X(e);return this.logger.error(`Error reading file ${n}: ${o}`),void 0!==t&&await this.sendError(t,-32603,o),{type:"error",code:-32603,error:o,method:s}}return void 0!==t&&await this.sendResult(t,{content:a}),{type:"file_read",path:n,content:a}}async handleWriteTextFile(e){const{id:t,method:s,params:o}=e,{path:n,content:i}=o||{};if(this.logger.info(`fs/write_text_file request for: ${n}`),!this.fileHandler){const e="File system access not configured";return void 0!==t&&await this.sendError(t,-32603,e),{type:"error",code:-32603,error:e,method:s}}try{await this.fileHandler.writeFile(n,i)}catch(e){const o=X(e);return this.logger.error(`Error writing file ${n}: ${o}`),void 0!==t&&await this.sendError(t,-32603,o),{type:"error",code:-32603,error:o,method:s}}return void 0!==t&&await this.sendResult(t,{success:!0}),{type:"file_write",path:n,content:i}}async handleSessionUpdate(e){const{params:t}=e,{sessionId:s,update:o}=t;return{type:"session_update",sessionId:s,updateData:o}}async handleRequestPermission(e){const{id:t,params:s}=e,o=s.toolCall||{},n=s.options||[],i=s.sessionId;return void 0!==t?this.pendingPermissionRequests.size>=this.maxPendingRequests?(this.logger.error(`Max pending permission requests limit reached (${this.maxPendingRequests}). Rejecting new request to prevent memory leak.`),await this.sendError(t,-32e3,`Too many pending requests (${this.maxPendingRequests})`),{type:"error",code:-32e3,error:`Too many pending requests (${this.maxPendingRequests})`,method:"session/request_permission"}):(this.pendingPermissionRequests.set(t,{created_at:Date.now(),ttl:this.requestTtl,toolCall:o,options:n}),this.logger.info(`Received permission request for tool '${o.title||"unknown"}', waiting for user response (pending: ${this.pendingPermissionRequests.size}/${this.maxPendingRequests})`),{type:z.PERMISSION_REQUEST,requestId:t,sessionId:i,toolCall:o,options:n,needsUserResponse:!0}):(this.logger.error("Permission request without request_id - cannot track response"),{type:"error",code:-32600,error:"Permission request without request_id - cannot track response",method:"session/request_permission"})}async handlePushToolCall(e){const{id:t,params:s}=e,o=`tool_${this.nextRequestId()}`,n={id:o};return void 0!==t&&await this.sendResult(t,n),{type:"tool_call",id:o,params:s}}async handleUpdateToolCall(e){const{id:t,params:s}=e;return void 0!==t&&await this.sendResult(t,null),{type:"tool_update",params:s}}async handleNotifyTaskFinish(e){const{id:t,params:s}=e;return void 0!==t&&await this.sendResult(t,null),{type:"task_finish",params:s}}async handleAskUserQuestions(e){const{id:t,params:s}=e;return this.logger.info(`ask_user_questions request with ${s?.questions?.length||0} questions`),{type:"ask_user_questions",requestId:t,params:s}}async handleExitPlanMode(e){const{id:t,params:s}=e;return this.logger.info(`exit_plan_mode request with plan: ${s?.plan?.substring(0,50)}...`),{type:"exit_plan_mode",requestId:t,params:s}}async handleUnknownMessage(e){const{id:t,method:s,params:o}=e;return this.logger.warn(`Unknown method: ${s}`),void 0!==t&&await this.sendError(t,-32601,"Method not found"),{type:"unknown",method:s,params:o}}}class se{constructor(e){this.ws=null,this.connected=!1,this.messageQueue=[],this.waitingResolvers=new Map,this.generalWaiters=[],this.url=e.url,this.logger=e.logger||V,this.timeout=e.timeout||3e5}get isConnected(){return!!this.ws&&this.connected}checkConnected(){if(!this.isConnected)throw new q("Not connected")}async connect(){if(this.connected)this.logger.warn(`Already connected to ${this.url}`);else try{this.logger.info(`Connecting to ${this.url}`),this.ws=await new Promise((e,t)=>{const o=new s(this.url),n=setTimeout(()=>{o.close(),t(new M(`Connected to ${this.url} timeout after ${this.timeout/1e3}s`))},this.timeout);o.on("open",()=>{clearTimeout(n),this.connected=!0,this.logger.info(`Connected to ${this.url} successfully`),e(o)}),o.on("error",e=>{clearTimeout(n),this.connected=!1,t(e)}),o.on("close",(e,s)=>{clearTimeout(n),this.connected=!1,t(new Error(`${s} (code: ${e})`))})}),this.setupMessageListener()}catch(e){if(e instanceof M)throw e;throw new q(`Failed to connect to ${this.url}: ${X(e)}`)}}setupMessageListener(){this.ws&&(this.ws.on("message",e=>{const t=e.toString("utf8");let s;this.logger.debug(`Received message: ${t}`);try{const e=JSON.parse(t);!e||"number"!=typeof e.id&&"string"!=typeof e.id||(s=e.id)}catch(e){}if(void 0!==s&&this.waitingResolvers.has(s)){const e=this.waitingResolvers.get(s);return this.waitingResolvers.delete(s),void e.resolve(t)}if(this.generalWaiters.length>0){return void this.generalWaiters.shift().resolve(t)}this.messageQueue.push(t)}),this.ws.on("error",e=>{this.connected=!1,this.rejectAllWaiters(e)}),this.ws.on("close",()=>{this.connected=!1,this.rejectAllWaiters(new q("Connection closed",{isClosed:!0})),this.logger.info("Connection closed")}))}rejectAllWaiters(e){for(const[t,s]of this.waitingResolvers.entries())s.reject(e);for(this.waitingResolvers.clear();this.generalWaiters.length>0;){const t=this.generalWaiters.shift();t&&t.reject(e)}}async close(){if(this.ws&&this.connected)try{this.ws.removeAllListeners(),this.ws.close(),this.logger.info("Connection closed")}catch(e){this.logger.warn(`Error closing connection: ${X(e)}`)}this.ws=null,this.connected=!1,this.messageQueue=[],this.rejectAllWaiters(new q("Connection closed by client",{clientInitiated:!0}))}async send(e){this.checkConnected();try{const t="string"==typeof e?e:JSON.stringify(e);await new Promise((e,s)=>{this.ws.send(t,o=>{o?s(o):(this.logger.debug(`Sent message: ${t}`),e())})})}catch(e){throw this.connected=!1,new U(`Failed to send message: ${X(e)}`)}}async waitForResponse(e){return this.checkConnected(),this.receiveRawData(e)}async*receive(){for(this.checkConnected();this.isConnected;)try{const e=await this.receiveRawData();yield e}catch(e){if(this.connected=!1,e instanceof q&&(e.details.isClosed||e.details.clientInitiated)){e.details.clientInitiated?this.logger.debug("Connection closed by client"):this.logger.info("Connection closed");break}throw new U(`Failed to receive message: ${X(e)}`)}}receiveRawData(e){return new Promise((t,s)=>{if(!this.isConnected)return void s(new q("Not connected"));if(void 0!==e)return void this.waitingResolvers.set(e,{resolve:t,reject:s});const o=this.messageQueue.shift();void 0===o?this.generalWaiters.push({resolve:t,reject:s}):t(o)})}}class oe{constructor(e={}){this.cwd=e.cwd||process.cwd(),this.logger=e.logger||V,this.readOnly=e.readOnly||!1,this.maxFileSize=e.maxFileSize||10485760,e.allowedDirs?this.allowedDirs=new Set(e.allowedDirs.map(e=>P.resolve(this.cwd,e))):this.allowedDirs=new Set([this.cwd]),this.logger.info(`File handler initialized with ${this.allowedDirs.size} allowed directories`);for(const e of this.allowedDirs)this.logger.debug(` Allowed: ${e}`)}isPathAllowed(e){try{const t=P.resolve(this.cwd,e);for(const e of this.allowedDirs)if(t.startsWith(e))return!0;return this.logger.warn(`Path not in allowed directories: ${t}`),!1}catch(e){return e instanceof Error&&this.logger.error(`Error checking path: ${e.message}`,e),!1}}async readFile(e,t,s){if(!this.isPathAllowed(e))throw new D(`Access denied: ${e}`);const o=P.resolve(this.cwd,e);try{if(!b.existsSync(o))throw new j(`File not found: ${e}`);try{await A.access(o,b.constants.R_OK)}catch{throw new D(`Permission denied: ${e}`)}const n=await A.stat(o);if(!n.isFile())throw new j(`Not a file: ${e}`);if(n.size>this.maxFileSize)throw new j(`File too large: ${n.size} bytes (max: ${this.maxFileSize})`);const i=await A.readFile(o,"utf-8");if(void 0!==t||void 0!==s){const o=i.split("\n"),n=t?t-1:0,r=s?n+s:o.length,a=Math.max(0,n),l=Math.min(o.length,r);return this.logger.debug(`Read ${l-a} lines from ${e}`),o.slice(a,l).join("\n")}return this.logger.debug(`Read ${i.length} bytes from ${e}`),i}catch(e){if(e instanceof j||e instanceof D)throw e;throw new j(`Failed to read file: ${X(e)}`)}}async writeFile(e,t){if(this.readOnly)throw new D("File system is in read-only mode");if(!this.isPathAllowed(e))throw new D(`Access denied: ${e}`);const s=P.resolve(this.cwd,e);try{await A.mkdir(P.dirname(s),{recursive:!0}),await A.writeFile(s,t,"utf-8"),this.logger.debug(`Wrote ${t.length} bytes to ${e}`)}catch(e){throw new j(`Failed to write file: ${X(e)}`)}}async addAllowedDir(e){const t=P.resolve(this.cwd,e);try{if(!b.existsSync(t))throw new j(`Directory does not exist: ${t}`);if(!(await A.stat(t)).isDirectory())throw new j(`Not a directory: ${t}`);this.allowedDirs.add(t),this.logger.info(`Added allowed directory: ${t}`)}catch(e){if(e instanceof j)throw e;throw new j(`Failed to add ${t} as allowed directory: ${X(e)}`)}}removeAllowedDir(e){const t=P.resolve(this.cwd,e);this.allowedDirs.delete(t),this.logger.info(`Removed allowed directory: ${t}`)}}var ne="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function ie(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var re,ae,le,ce,de,ue,pe,he,ge={exports:{}},me={exports:{}};function fe(){if(ae)return re;ae=1,re=o,o.sync=function(e,o){return s(t.statSync(e),e,o)};var t=e;function s(e,t,s){return!(!e.isSymbolicLink()&&!e.isFile())&&function(e,t){var s=void 0!==t.pathExt?t.pathExt:process.env.PATHEXT;if(!s)return!0;if(-1!==(s=s.split(";")).indexOf(""))return!0;for(var o=0;o<s.length;o++){var n=s[o].toLowerCase();if(n&&e.substr(-n.length).toLowerCase()===n)return!0}return!1}(t,s)}function o(e,o,n){t.stat(e,function(t,i){n(t,!t&&s(i,e,o))})}return re}function we(){if(ce)return le;ce=1,le=s,s.sync=function(e,s){return o(t.statSync(e),s)};var t=e;function s(e,s,n){t.stat(e,function(e,t){n(e,!e&&o(t,s))})}function o(e,t){return e.isFile()&&function(e,t){var s=e.mode,o=e.uid,n=e.gid,i=void 0!==t.uid?t.uid:process.getuid&&process.getuid(),r=void 0!==t.gid?t.gid:process.getgid&&process.getgid(),a=parseInt("100",8),l=parseInt("010",8),c=parseInt("001",8),d=a|l;return s&c||s&l&&n===r||s&a&&o===i||s&d&&0===i}(e,t)}return le}function ye(){if(he)return pe;he=1;const e="win32"===process.platform||"cygwin"===process.env.OSTYPE||"msys"===process.env.OSTYPE,s=t,o=e?";":":",n=function(){if(ue)return de;var e;function t(s,o,n){if("function"==typeof o&&(n=o,o={}),!n){if("function"!=typeof Promise)throw new TypeError("callback not provided");return new Promise(function(e,n){t(s,o||{},function(t,s){t?n(t):e(s)})})}e(s,o||{},function(e,t){e&&("EACCES"===e.code||o&&o.ignoreErrors)&&(e=null,t=!1),n(e,t)})}return ue=1,e="win32"===process.platform||ne.TESTING_WINDOWS?fe():we(),de=t,t.sync=function(t,s){try{return e.sync(t,s||{})}catch(e){if(s&&s.ignoreErrors||"EACCES"===e.code)return!1;throw e}},de}(),i=e=>Object.assign(new Error(`not found: ${e}`),{code:"ENOENT"}),r=(t,s)=>{const n=s.colon||o,i=t.match(/\//)||e&&t.match(/\\/)?[""]:[...e?[process.cwd()]:[],...(s.path||process.env.PATH||"").split(n)],r=e?s.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",a=e?r.split(n):[""];return e&&-1!==t.indexOf(".")&&""!==a[0]&&a.unshift(""),{pathEnv:i,pathExt:a,pathExtExe:r}},a=(e,t,o)=>{"function"==typeof t&&(o=t,t={}),t||(t={});const{pathEnv:a,pathExt:l,pathExtExe:c}=r(e,t),d=[],u=o=>new Promise((n,r)=>{if(o===a.length)return t.all&&d.length?n(d):r(i(e));const l=a[o],c=/^".*"$/.test(l)?l.slice(1,-1):l,u=s.join(c,e),h=!c&&/^\.[\\\/]/.test(e)?e.slice(0,2)+u:u;n(p(h,o,0))}),p=(e,s,o)=>new Promise((i,r)=>{if(o===l.length)return i(u(s+1));const a=l[o];n(e+a,{pathExt:c},(n,r)=>{if(!n&&r){if(!t.all)return i(e+a);d.push(e+a)}return i(p(e,s,o+1))})});return o?u(0).then(e=>o(null,e),o):u(0)};return pe=a,a.sync=(e,t)=>{t=t||{};const{pathEnv:o,pathExt:a,pathExtExe:l}=r(e,t),c=[];for(let i=0;i<o.length;i++){const r=o[i],d=/^".*"$/.test(r)?r.slice(1,-1):r,u=s.join(d,e),p=!d&&/^\.[\\\/]/.test(e)?e.slice(0,2)+u:u;for(let e=0;e<a.length;e++){const s=p+a[e];try{if(n.sync(s,{pathExt:l})){if(!t.all)return s;c.push(s)}}catch(e){}}}if(t.all&&c.length)return c;if(t.nothrow)return null;throw i(e)},pe}var Se,xe,Ee,Ie={exports:{}};function Te(){if(Se)return Ie.exports;Se=1;const e=(e={})=>{const t=e.env||process.env;return"win32"!==(e.platform||process.platform)?"PATH":Object.keys(t).reverse().find(e=>"PATH"===e.toUpperCase())||"Path"};return Ie.exports=e,Ie.exports.default=e,Ie.exports}var ve,_e,be,Pe,Ae,Re,Ce,Oe,$e,Me,Ne,Le,ke,Fe,qe={};function Ue(){return be?_e:(be=1,_e=/^#!(.*)/)}function De(){if(Ae)return Pe;Ae=1;const e=Ue();return Pe=(t="")=>{const s=t.match(e);if(!s)return null;const[o,n]=s[0].replace(/#! ?/,"").split(" "),i=o.split("/").pop();return"env"===i?n:n?`${i} ${n}`:i},Pe}function je(){if($e)return Oe;$e=1;const s=t,o=function(){if(Ee)return xe;Ee=1;const e=t,s=ye(),o=Te();function n(t,n){const i=t.options.env||process.env,r=process.cwd(),a=null!=t.options.cwd,l=a&&void 0!==process.chdir&&!process.chdir.disabled;if(l)try{process.chdir(t.options.cwd)}catch(e){}let c;try{c=s.sync(t.command,{path:i[o({env:i})],pathExt:n?e.delimiter:void 0})}catch(e){}finally{l&&process.chdir(r)}return c&&(c=e.resolve(a?t.options.cwd:"",c)),c}return xe=function(e){return n(e)||n(e,!0)}}(),n=function(){if(ve)return qe;ve=1;const e=/([()\][%!^"`<>&|;, *?])/g;return qe.command=function(t){return t.replace(e,"^$1")},qe.argument=function(t,s){return t=(t=`"${t=(t=(t=`${t}`).replace(/(?=(\\+?)?)\1"/g,'$1$1\\"')).replace(/(?=(\\+?)?)\1$/,"$1$1")}"`).replace(e,"^$1"),s&&(t=t.replace(e,"^$1")),t},qe}(),i=function(){if(Ce)return Re;Ce=1;const t=e,s=De();return Re=function(e){const o=Buffer.alloc(150);let n;try{n=t.openSync(e,"r"),t.readSync(n,o,0,150,0),t.closeSync(n)}catch(e){}return s(o.toString())},Re}(),r="win32"===process.platform,a=/\.(?:com|exe)$/i,l=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function c(e){if(!r)return e;const t=function(e){e.file=o(e);const t=e.file&&i(e.file);return t?(e.args.unshift(e.file),e.command=t,o(e)):e.file}(e),c=!a.test(t);if(e.options.forceShell||c){const o=l.test(t);e.command=s.normalize(e.command),e.command=n.command(e.command),e.args=e.args.map(e=>n.argument(e,o));const i=[e.command].concat(e.args).join(" ");e.args=["/d","/s","/c",`"${i}"`],e.command=process.env.comspec||"cmd.exe",e.options.windowsVerbatimArguments=!0}return e}return Oe=function(e,t,s){t&&!Array.isArray(t)&&(s=t,t=null);const o={command:e,args:t=t?t.slice(0):[],options:s=Object.assign({},s),file:void 0,original:{command:e,args:t}};return s.shell?o:c(o)},Oe}function Ge(){if(Ne)return Me;Ne=1;const e="win32"===process.platform;function t(e,t){return Object.assign(new Error(`${t} ${e.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${t} ${e.command}`,path:e.command,spawnargs:e.args})}function s(s,o){return e&&1===s&&!o.file?t(o.original,"spawn"):null}return Me={hookChildProcess:function(t,o){if(!e)return;const n=t.emit;t.emit=function(e,i){if("exit"===e){const e=s(i,o);if(e)return n.call(t,"error",e)}return n.apply(t,arguments)}},verifyENOENT:s,verifyENOENTSync:function(s,o){return e&&1===s&&!o.file?t(o.original,"spawnSync"):null},notFoundError:t},Me}function He(){if(Le)return me.exports;Le=1;const e=r,t=je(),s=Ge();function o(o,n,i){const r=t(o,n,i),a=e.spawn(r.command,r.args,r.options);return s.hookChildProcess(a,r),a}return me.exports=o,me.exports.spawn=o,me.exports.sync=function(o,n,i){const r=t(o,n,i),a=e.spawnSync(r.command,r.args,r.options);return a.error=a.error||s.verifyENOENTSync(a.status,r),a},me.exports._parse=t,me.exports._enoent=s,me.exports}function We(){return Fe?ke:(Fe=1,ke=e=>{const t="string"==typeof e?"\n":"\n".charCodeAt(),s="string"==typeof e?"\r":"\r".charCodeAt();return e[e.length-1]===t&&(e=e.slice(0,e.length-1)),e[e.length-1]===s&&(e=e.slice(0,e.length-1)),e})}var Qe,Ke={exports:{}};function Be(){return Qe||(Qe=1,function(e){const s=t,o=Te(),n=e=>{let t;e={cwd:process.cwd(),path:process.env[o()],execPath:process.execPath,...e};let n=s.resolve(e.cwd);const i=[];for(;t!==n;)i.push(s.join(n,"node_modules/.bin")),t=n,n=s.resolve(n,"..");const r=s.resolve(e.cwd,e.execPath,"..");return i.push(r),i.concat(e.path).join(s.delimiter)};e.exports=n,e.exports.default=n,e.exports.env=t=>{const s={...(t={env:process.env,...t}).env},n=o({env:s});return t.path=s[n],s[n]=e.exports(t),s}}(Ke)),Ke.exports}var ze,Xe,Je={exports:{}},Ve={exports:{}};function Ye(){if(ze)return Ve.exports;ze=1;const e=(e,t)=>{for(const s of Reflect.ownKeys(t))Object.defineProperty(e,s,Object.getOwnPropertyDescriptor(t,s));return e};return Ve.exports=e,Ve.exports.default=e,Ve.exports}function Ze(){if(Xe)return Je.exports;Xe=1;const e=Ye(),t=new WeakMap,s=(s,o={})=>{if("function"!=typeof s)throw new TypeError("Expected a function");let n,i=0;const r=s.displayName||s.name||"<anonymous>",a=function(...e){if(t.set(a,++i),1===i)n=s.apply(this,e),s=null;else if(!0===o.throw)throw new Error(`Function \`${r}\` can only be called once`);return n};return e(a,s),t.set(a,i),a};return Je.exports=s,Je.exports.default=s,Je.exports.callCount=e=>{if(!t.has(e))throw new Error(`The given function \`${e.name}\` is not wrapped by the \`onetime\` package`);return t.get(e)},Je.exports}var et,tt={},st={},ot={};var nt,it,rt,at,lt,ct={};function dt(){if(nt)return ct;nt=1,Object.defineProperty(ct,"__esModule",{value:!0}),ct.SIGRTMAX=ct.getRealtimeSignals=void 0;ct.getRealtimeSignals=function(){const o=s-t+1;return Array.from({length:o},e)};const e=function(e,s){return{name:`SIGRT${s+1}`,number:t+s,action:"terminate",description:"Application-specific signal (realtime)",standard:"posix"}},t=34,s=64;return ct.SIGRTMAX=s,ct}function ut(){if(it)return st;it=1,Object.defineProperty(st,"__esModule",{value:!0}),st.getSignals=void 0;var e=n,t=(et||(et=1,Object.defineProperty(ot,"__esModule",{value:!0}),ot.SIGNALS=void 0,ot.SIGNALS=[{name:"SIGHUP",number:1,action:"terminate",description:"Terminal closed",standard:"posix"},{name:"SIGINT",number:2,action:"terminate",description:"User interruption with CTRL-C",standard:"ansi"},{name:"SIGQUIT",number:3,action:"core",description:"User interruption with CTRL-\\",standard:"posix"},{name:"SIGILL",number:4,action:"core",description:"Invalid machine instruction",standard:"ansi"},{name:"SIGTRAP",number:5,action:"core",description:"Debugger breakpoint",standard:"posix"},{name:"SIGABRT",number:6,action:"core",description:"Aborted",standard:"ansi"},{name:"SIGIOT",number:6,action:"core",description:"Aborted",standard:"bsd"},{name:"SIGBUS",number:7,action:"core",description:"Bus error due to misaligned, non-existing address or paging error",standard:"bsd"},{name:"SIGEMT",number:7,action:"terminate",description:"Command should be emulated but is not implemented",standard:"other"},{name:"SIGFPE",number:8,action:"core",description:"Floating point arithmetic error",standard:"ansi"},{name:"SIGKILL",number:9,action:"terminate",description:"Forced termination",standard:"posix",forced:!0},{name:"SIGUSR1",number:10,action:"terminate",description:"Application-specific signal",standard:"posix"},{name:"SIGSEGV",number:11,action:"core",description:"Segmentation fault",standard:"ansi"},{name:"SIGUSR2",number:12,action:"terminate",description:"Application-specific signal",standard:"posix"},{name:"SIGPIPE",number:13,action:"terminate",description:"Broken pipe or socket",standard:"posix"},{name:"SIGALRM",number:14,action:"terminate",description:"Timeout or timer",standard:"posix"},{name:"SIGTERM",number:15,action:"terminate",description:"Termination",standard:"ansi"},{name:"SIGSTKFLT",number:16,action:"terminate",description:"Stack is empty or overflowed",standard:"other"},{name:"SIGCHLD",number:17,action:"ignore",description:"Child process terminated, paused or unpaused",standard:"posix"},{name:"SIGCLD",number:17,action:"ignore",description:"Child process terminated, paused or unpaused",standard:"other"},{name:"SIGCONT",number:18,action:"unpause",description:"Unpaused",standard:"posix",forced:!0},{name:"SIGSTOP",number:19,action:"pause",description:"Paused",standard:"posix",forced:!0},{name:"SIGTSTP",number:20,action:"pause",description:'Paused using CTRL-Z or "suspend"',standard:"posix"},{name:"SIGTTIN",number:21,action:"pause",description:"Background process cannot read terminal input",standard:"posix"},{name:"SIGBREAK",number:21,action:"terminate",description:"User interruption with CTRL-BREAK",standard:"other"},{name:"SIGTTOU",number:22,action:"pause",description:"Background process cannot write to terminal output",standard:"posix"},{name:"SIGURG",number:23,action:"ignore",description:"Socket received out-of-band data",standard:"bsd"},{name:"SIGXCPU",number:24,action:"core",description:"Process timed out",standard:"bsd"},{name:"SIGXFSZ",number:25,action:"core",description:"File too big",standard:"bsd"},{name:"SIGVTALRM",number:26,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGPROF",number:27,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGWINCH",number:28,action:"ignore",description:"Terminal window size changed",standard:"bsd"},{name:"SIGIO",number:29,action:"terminate",description:"I/O is available",standard:"other"},{name:"SIGPOLL",number:29,action:"terminate",description:"Watched event",standard:"other"},{name:"SIGINFO",number:29,action:"ignore",description:"Request for process information",standard:"other"},{name:"SIGPWR",number:30,action:"terminate",description:"Device running out of power",standard:"systemv"},{name:"SIGSYS",number:31,action:"core",description:"Invalid system call",standard:"other"},{name:"SIGUNUSED",number:31,action:"terminate",description:"Invalid system call",standard:"other"}]),ot),s=dt();st.getSignals=function(){const e=(0,s.getRealtimeSignals)();return[...t.SIGNALS,...e].map(o)};const o=function({name:t,number:s,description:o,action:n,forced:i=!1,standard:r}){const{signals:{[t]:a}}=e.constants,l=void 0!==a;return{name:t,number:l?a:s,description:o,supported:l,action:n,forced:i,standard:r}};return st}function pt(){if(lt)return at;lt=1;const{signalsByName:e}=function(){if(rt)return tt;rt=1,Object.defineProperty(tt,"__esModule",{value:!0}),tt.signalsByNumber=tt.signalsByName=void 0;var e=n,t=ut(),s=dt();const o=function(e,{name:t,number:s,description:o,supported:n,action:i,forced:r,standard:a}){return{...e,[t]:{name:t,number:s,description:o,supported:n,action:i,forced:r,standard:a}}},i=(0,t.getSignals)().reduce(o,{});tt.signalsByName=i;const r=function(e,t){const s=a(e,t);if(void 0===s)return{};const{name:o,description:n,supported:i,action:r,forced:l,standard:c}=s;return{[e]:{name:o,number:e,description:n,supported:i,action:r,forced:l,standard:c}}},a=function(t,s){const o=s.find(({name:s})=>e.constants.signals[s]===t);return void 0!==o?o:s.find(e=>e.number===t)},l=function(){const e=(0,t.getSignals)(),o=s.SIGRTMAX+1,n=Array.from({length:o},(t,s)=>r(s,e));return Object.assign({},...n)}();return tt.signalsByNumber=l,tt}();return at=({stdout:t,stderr:s,all:o,error:n,signal:i,exitCode:r,command:a,escapedCommand:l,timedOut:c,isCanceled:d,killed:u,parsed:{options:{timeout:p}}})=>{r=null===r?void 0:r;const h=void 0===(i=null===i?void 0:i)?void 0:e[i].description,g=(({timedOut:e,timeout:t,errorCode:s,signal:o,signalDescription:n,exitCode:i,isCanceled:r})=>e?`timed out after ${t} milliseconds`:r?"was canceled":void 0!==s?`failed with ${s}`:void 0!==o?`was killed with ${o} (${n})`:void 0!==i?`failed with exit code ${i}`:"failed")({timedOut:c,timeout:p,errorCode:n&&n.code,signal:i,signalDescription:h,exitCode:r,isCanceled:d}),m=`Command ${g}: ${a}`,f="[object Error]"===Object.prototype.toString.call(n),w=f?`${m}\n${n.message}`:m,y=[w,s,t].filter(Boolean).join("\n");return f?(n.originalMessage=n.message,n.message=y):n=new Error(y),n.shortMessage=w,n.command=a,n.escapedCommand=l,n.exitCode=r,n.signal=i,n.signalDescription=h,n.stdout=t,n.stderr=s,void 0!==o&&(n.all=o),"bufferedData"in n&&delete n.bufferedData,n.failed=!0,n.timedOut=Boolean(c),n.isCanceled=d,n.killed=u&&!c,n},at}var ht,gt={exports:{}};function mt(){if(ht)return gt.exports;ht=1;const e=["stdin","stdout","stderr"],t=t=>{if(!t)return;const{stdio:s}=t;if(void 0===s)return e.map(e=>t[e]);if((t=>e.some(e=>void 0!==t[e]))(t))throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${e.map(e=>`\`${e}\``).join(", ")}`);if("string"==typeof s)return s;if(!Array.isArray(s))throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof s}\``);const o=Math.max(s.length,e.length);return Array.from({length:o},(e,t)=>s[t])};return gt.exports=t,gt.exports.node=e=>{const s=t(e);return"ipc"===s?"ipc":void 0===s||"string"==typeof s?[s,s,s,"ipc"]:s.includes("ipc")?s:[...s,"ipc"]},gt.exports}var ft,wt,yt,St,xt,Et,It={exports:{}},Tt={exports:{}};function vt(){return ft||(ft=1,(e=Tt).exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"],"win32"!==process.platform&&e.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT"),"linux"===process.platform&&e.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")),Tt.exports;var e}function _t(){if(St)return yt;St=1;const e=n,t=function(){if(wt)return It.exports;wt=1;var e=ne.process;const t=function(e){return e&&"object"==typeof e&&"function"==typeof e.removeListener&&"function"==typeof e.emit&&"function"==typeof e.reallyExit&&"function"==typeof e.listeners&&"function"==typeof e.kill&&"number"==typeof e.pid&&"function"==typeof e.on};if(t(e)){var s,o=a,n=vt(),i=/^win/i.test(e.platform),r=l;"function"!=typeof r&&(r=r.EventEmitter),e.__signal_exit_emitter__?s=e.__signal_exit_emitter__:((s=e.__signal_exit_emitter__=new r).count=0,s.emitted={}),s.infinite||(s.setMaxListeners(1/0),s.infinite=!0),It.exports=function(e,n){if(!t(ne.process))return function(){};o.equal(typeof e,"function","a callback must be provided for exit handler"),!1===p&&h();var i="exit";return n&&n.alwaysLast&&(i="afterexit"),s.on(i,e),function(){s.removeListener(i,e),0===s.listeners("exit").length&&0===s.listeners("afterexit").length&&c()}};var c=function(){p&&t(ne.process)&&(p=!1,n.forEach(function(t){try{e.removeListener(t,u[t])}catch(e){}}),e.emit=f,e.reallyExit=g,s.count-=1)};It.exports.unload=c;var d=function(e,t,o){s.emitted[e]||(s.emitted[e]=!0,s.emit(e,t,o))},u={};n.forEach(function(o){u[o]=function(){t(ne.process)&&e.listeners(o).length===s.count&&(c(),d("exit",null,o),d("afterexit",null,o),i&&"SIGHUP"===o&&(o="SIGINT"),e.kill(e.pid,o))}}),It.exports.signals=function(){return n};var p=!1,h=function(){!p&&t(ne.process)&&(p=!0,s.count+=1,n=n.filter(function(t){try{return e.on(t,u[t]),!0}catch(e){return!1}}),e.emit=w,e.reallyExit=m)};It.exports.load=h;var g=e.reallyExit,m=function(s){t(ne.process)&&(e.exitCode=s||0,d("exit",e.exitCode,null),d("afterexit",e.exitCode,null),g.call(e,e.exitCode))},f=e.emit,w=function(s,o){if("exit"===s&&t(ne.process)){void 0!==o&&(e.exitCode=o);var n=f.apply(this,arguments);return d("exit",e.exitCode,null),d("afterexit",e.exitCode,null),n}return f.apply(this,arguments)}}else It.exports=function(){return function(){}};return It.exports}(),s=(e,t,s,n)=>{if(!o(t,s,n))return;const i=r(s),a=setTimeout(()=>{e("SIGKILL")},i);a.unref&&a.unref()},o=(e,{forceKillAfterTimeout:t},s)=>i(e)&&!1!==t&&s,i=t=>t===e.constants.signals.SIGTERM||"string"==typeof t&&"SIGTERM"===t.toUpperCase(),r=({forceKillAfterTimeout:e=!0})=>{if(!0===e)return 5e3;if(!Number.isFinite(e)||e<0)throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${e}\` (${typeof e})`);return e};return yt={spawnedKill:(e,t="SIGTERM",o={})=>{const n=e(t);return s(e,t,o,n),n},spawnedCancel:(e,t)=>{e.kill()&&(t.isCanceled=!0)},setupTimeout:(e,{timeout:t,killSignal:s="SIGTERM"},o)=>{if(0===t||void 0===t)return o;let n;const i=new Promise((o,i)=>{n=setTimeout(()=>{((e,t,s)=>{e.kill(t),s(Object.assign(new Error("Timed out"),{timedOut:!0,signal:t}))})(e,s,i)},t)}),r=o.finally(()=>{clearTimeout(n)});return Promise.race([i,r])},validateTimeout:({timeout:e})=>{if(void 0!==e&&(!Number.isFinite(e)||e<0))throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${e}\` (${typeof e})`)},setExitHandler:async(e,{cleanup:s,detached:o},n)=>{if(!s||o)return n;const i=t(()=>{e.kill()});return n.finally(()=>{i()})}}}var bt,Pt,At,Rt,Ct,Ot,$t,Mt,Nt,Lt,kt,Ft,qt={exports:{}};function Ut(){if(Pt)return bt;Pt=1;const{PassThrough:e}=d;return bt=t=>{t={...t};const{array:s}=t;let{encoding:o}=t;const n="buffer"===o;let i=!1;s?i=!(o||n):o=o||"utf8",n&&(o=null);const r=new e({objectMode:i});o&&r.setEncoding(o);let a=0;const l=[];return r.on("data",e=>{l.push(e),i?a=l.length:a+=e.length}),r.getBufferedValue=()=>s?l:n?Buffer.concat(l,a):l.join(""),r.getBufferedLength=()=>a,r},bt}function Dt(){if(At)return qt.exports;At=1;const{constants:e}=c,t=d,{promisify:s}=u,o=Ut(),n=s(t.pipeline);class i extends Error{constructor(){super("maxBuffer exceeded"),this.name="MaxBufferError"}}async function r(t,s){if(!t)throw new Error("Expected a stream");s={maxBuffer:1/0,...s};const{maxBuffer:r}=s,a=o(s);return await new Promise((s,o)=>{const l=t=>{t&&a.getBufferedLength()<=e.MAX_LENGTH&&(t.bufferedData=a.getBufferedValue()),o(t)};(async()=>{try{await n(t,a),s()}catch(e){l(e)}})(),a.on("data",()=>{a.getBufferedLength()>r&&l(new i)})}),a.getBufferedValue()}return qt.exports=r,qt.exports.buffer=(e,t)=>r(e,{...t,encoding:"buffer"}),qt.exports.array=(e,t)=>r(e,{...t,array:!0}),qt.exports.MaxBufferError=i,qt.exports}function jt(){if(Ct)return Rt;Ct=1;const{PassThrough:e}=d;return Rt=function(){var t=[],s=new e({objectMode:!0});return s.setMaxListeners(0),s.add=o,s.isEmpty=function(){return 0==t.length},s.on("unpipe",n),Array.prototype.slice.call(arguments).forEach(o),s;function o(e){return Array.isArray(e)?(e.forEach(o),this):(t.push(e),e.once("end",n.bind(null,e)),e.once("error",s.emit.bind(s,"error")),e.pipe(s,{end:!1}),this)}function n(e){!(t=t.filter(function(t){return t!==e})).length&&s.readable&&s.end()}},Rt}function Gt(){if($t)return Ot;$t=1;const e=function(){if(Et)return xt;Et=1;const e=e=>null!==e&&"object"==typeof e&&"function"==typeof e.pipe;return e.writable=t=>e(t)&&!1!==t.writable&&"function"==typeof t._write&&"object"==typeof t._writableState,e.readable=t=>e(t)&&!1!==t.readable&&"function"==typeof t._read&&"object"==typeof t._readableState,e.duplex=t=>e.writable(t)&&e.readable(t),e.transform=t=>e.duplex(t)&&"function"==typeof t._transform,xt=e}(),t=Dt(),s=jt(),o=async(e,t)=>{if(e){e.destroy();try{return await t}catch(e){return e.bufferedData}}},n=(e,{encoding:s,buffer:o,maxBuffer:n})=>{if(e&&o)return s?t(e,{encoding:s,maxBuffer:n}):t.buffer(e,{maxBuffer:n})};return Ot={handleInput:(t,s)=>{void 0!==s&&void 0!==t.stdin&&(e(s)?s.pipe(t.stdin):t.stdin.end(s))},makeAllStream:(e,{all:t})=>{if(!t||!e.stdout&&!e.stderr)return;const o=s();return e.stdout&&o.add(e.stdout),e.stderr&&o.add(e.stderr),o},getSpawnedResult:async({stdout:e,stderr:t,all:s},{encoding:i,buffer:r,maxBuffer:a},l)=>{const c=n(e,{encoding:i,buffer:r,maxBuffer:a}),d=n(t,{encoding:i,buffer:r,maxBuffer:a}),u=n(s,{encoding:i,buffer:r,maxBuffer:2*a});try{return await Promise.all([l,c,d,u])}catch(n){return Promise.all([{error:n,signal:n.signal,timedOut:n.timedOut},o(e,c),o(t,d),o(s,u)])}},validateInputSync:({input:t})=>{if(e(t))throw new TypeError("The `input` option cannot be a stream in sync mode")}},Ot}function Ht(){if(kt)return Lt;kt=1;const e=(e,t=[])=>Array.isArray(t)?[e,...t]:[e],t=/^[\w.-]+$/,s=/"/g,o=/ +/g;return Lt={joinCommand:(t,s)=>e(t,s).join(" "),getEscapedCommand:(o,n)=>e(o,n).map(e=>(e=>"string"!=typeof e||t.test(e)?e:`"${e.replace(s,'\\"')}"`)(e)).join(" "),parseCommand:e=>{const t=[];for(const s of e.trim().split(o)){const e=t[t.length-1];e&&e.endsWith("\\")?t[t.length-1]=`${e.slice(0,-1)} ${s}`:t.push(s)}return t}}}var Wt=function(){if(Ft)return ge.exports;Ft=1;const e=t,s=r,o=He(),n=We(),i=Be(),a=Ze(),l=pt(),c=mt(),{spawnedKill:d,spawnedCancel:u,setupTimeout:p,validateTimeout:h,setExitHandler:g}=_t(),{handleInput:m,getSpawnedResult:f,makeAllStream:w,validateInputSync:y}=Gt(),{mergePromise:S,getSpawnedPromise:x}=function(){if(Nt)return Mt;Nt=1;const e=(async()=>{})().constructor.prototype,t=["then","catch","finally"].map(t=>[t,Reflect.getOwnPropertyDescriptor(e,t)]);return Mt={mergePromise:(e,s)=>{for(const[o,n]of t){const t="function"==typeof s?(...e)=>Reflect.apply(n.value,s(),e):n.value.bind(s);Reflect.defineProperty(e,o,{...n,value:t})}return e},getSpawnedPromise:e=>new Promise((t,s)=>{e.on("exit",(e,s)=>{t({exitCode:e,signal:s})}),e.on("error",e=>{s(e)}),e.stdin&&e.stdin.on("error",e=>{s(e)})})},Mt}(),{joinCommand:E,parseCommand:I,getEscapedCommand:T}=Ht(),v=(t,s,n={})=>{const r=o._parse(t,s,n);return t=r.command,s=r.args,(n={maxBuffer:1e8,buffer:!0,stripFinalNewline:!0,extendEnv:!0,preferLocal:!1,localDir:(n=r.options).cwd||process.cwd(),execPath:process.execPath,encoding:"utf8",reject:!0,cleanup:!0,all:!1,windowsHide:!0,...n}).env=(({env:e,extendEnv:t,preferLocal:s,localDir:o,execPath:n})=>{const r=t?{...process.env,...e}:e;return s?i.env({env:r,cwd:o,execPath:n}):r})(n),n.stdio=c(n),"win32"===process.platform&&"cmd"===e.basename(t,".exe")&&s.unshift("/q"),{file:t,args:s,options:n,parsed:r}},_=(e,t,s)=>"string"==typeof t||Buffer.isBuffer(t)?e.stripFinalNewline?n(t):t:void 0===s?void 0:"",b=(e,t,o)=>{const n=v(e,t,o),i=E(e,t),r=T(e,t);let c;h(n.options);try{c=s.spawn(n.file,n.args,n.options)}catch(e){const t=new s.ChildProcess,o=Promise.reject(l({error:e,stdout:"",stderr:"",all:"",command:i,escapedCommand:r,parsed:n,timedOut:!1,isCanceled:!1,killed:!1}));return S(t,o)}const y=x(c),I=p(c,n.options,y),b=g(c,n.options,I),P={isCanceled:!1};c.kill=d.bind(null,c.kill.bind(c)),c.cancel=u.bind(null,c,P);const A=a(async()=>{const[{error:e,exitCode:t,signal:s,timedOut:o},a,d,u]=await f(c,n.options,b),p=_(n.options,a),h=_(n.options,d),g=_(n.options,u);if(e||0!==t||null!==s){const a=l({error:e,exitCode:t,signal:s,stdout:p,stderr:h,all:g,command:i,escapedCommand:r,parsed:n,timedOut:o,isCanceled:P.isCanceled,killed:c.killed});if(!n.options.reject)return a;throw a}return{command:i,escapedCommand:r,exitCode:0,stdout:p,stderr:h,all:g,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}});return m(c,n.options.input),c.all=w(c,n.options),S(c,A)};return ge.exports=b,ge.exports.sync=(e,t,o)=>{const n=v(e,t,o),i=E(e,t),r=T(e,t);let a;y(n.options);try{a=s.spawnSync(n.file,n.args,n.options)}catch(e){throw l({error:e,stdout:"",stderr:"",all:"",command:i,escapedCommand:r,parsed:n,timedOut:!1,isCanceled:!1,killed:!1})}const c=_(n.options,a.stdout,a.error),d=_(n.options,a.stderr,a.error);if(a.error||0!==a.status||null!==a.signal){const e=l({stdout:c,stderr:d,error:a.error,signal:a.signal,exitCode:a.status,command:i,escapedCommand:r,parsed:n,timedOut:a.error&&"ETIMEDOUT"===a.error.code,isCanceled:!1,killed:null!==a.signal});if(!n.options.reject)return e;throw e}return{command:i,escapedCommand:r,exitCode:0,stdout:c,stderr:d,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}},ge.exports.command=(e,t)=>{const[s,...o]=I(e);return b(s,o,t)},ge.exports.commandSync=(e,t)=>{const[s,...o]=I(e);return b.sync(s,o,t)},ge.exports.node=(e,t,s={})=>{t&&!Array.isArray(t)&&"object"==typeof t&&(s=t,t=[]);const o=c.node(s),n=process.execArgv.filter(e=>!e.startsWith("--inspect")),{nodePath:i=process.execPath,nodeOptions:r=n}=s;return b(i,[...r,e,...Array.isArray(t)?t:[]],{...s,stdin:void 0,stdout:void 0,stderr:void 0,stdio:o,shell:!1})},ge.exports}(),Qt=ie(Wt);class Kt{constructor(e={}){this.port=null,this.process=null,this.iflowPath=null,this.exitHandler=null,this.isCleaningUp=!1,this.logger=e.logger||V,this.startPort=e.startPort||8090,this.stream=e.stream||!1}get url(){if(!this.port)throw new k("iFlow process not started");return`ws://localhost:${this.port}/acp`}isRunning(){return!!this.process&&!this.process.killed&&null===this.process.exitCode}isWindows(){return"win32"===R.platform()}which(e){try{const t=this.isWindows()?"where":"which",s=O.execSync(`${t} ${e}`,{encoding:"utf-8",windowsHide:!0});return s.trim().split("\n")[0].trim()||null}catch{return null}}fileExists(e){try{return b.existsSync(e)&&b.statSync(e).isFile()}catch{return!1}}getFallbackLocations(){const e=R.homedir(),t=R.platform();if(this.isWindows())return[P.join(e,"AppData","Roaming","npm","iflow.cmd"),P.join(e,"AppData","Local","npm","iflow.cmd"),P.join(e,"AppData","Roaming","npm","iflow.exe"),P.join("C:","Program Files","nodejs","iflow.cmd"),P.join("C:","Program Files (x86)","nodejs","iflow.cmd"),P.join(e,".npm-global","iflow.cmd"),P.join(e,"node_modules",".bin","iflow.cmd")];{const s=["/usr/local/bin/iflow",P.join(e,".npm-global","bin","iflow"),P.join(e,".local","bin","iflow"),P.join(e,"node_modules",".bin","iflow"),P.join(e,".yarn","bin","iflow"),P.join(e,".config","yarn","global","node_modules",".bin","iflow"),P.join(e,".local","share","pnpm","iflow"),"/usr/bin/iflow"];return"darwin"===t&&"arm64"===R.arch()&&s.unshift("/opt/homebrew/bin/iflow"),s}}findIflowPath(){let e=this.which("iflow");if(e){if(this.isWindows()&&!e.endsWith(".cmd")&&!e.endsWith(".exe")){const t=e+".cmd";this.fileExists(t)&&(e=t)}return this.logger.debug(`Found iflow at: ${e}`),e}const t=this.getFallbackLocations();for(const e of t)if(this.fileExists(e))return this.logger.debug(`Found iflow at: ${e}`),e;const s=null!==this.which("npm"),o=null!==this.which("node");let n;throw n=this.isWindows()?s||o?"iFlow CLI not found. Please install it using one of the following commands:\n\nUsing npm (recommended):\n npm install -g @iflow-ai/iflow-cli@latest\n\nUsing Yarn:\n yarn global add @iflow-ai/iflow-cli@latest\n\nUsing pnpm:\n pnpm add -g @iflow-ai/iflow-cli@latest\n\nAfter installation, please restart your terminal or command prompt.":"iFlow requires Node.js, but it is not installed on your system.\n\nPlease install Node.js first: https://nodejs.org/\n\nAfter installing Node.js, install iFlow with:\n npm install -g @iflow-ai/iflow-cli@latest":'iFlow CLI not found. Please install it using one of the following methods:\n\n🍎 Mac/Linux users (recommended installation script):\n bash -c "$(curl -fsSL https://cloud.iflow.cn/iflow-cli/install.sh)"\n\nOr using npm:\n npm install -g @iflow-ai/iflow-cli@latest\n\nOr using Yarn:\n yarn global add @iflow-ai/iflow-cli@latest\n\nOr using pnpm:\n pnpm add -g @iflow-ai/iflow-cli@latest\n\n🐧 Ubuntu/Debian users may need:\n sudo npm install -g @iflow-ai/iflow-cli@latest',new L(n)}isPortAvailable(e,t=1e3){return new Promise(s=>{const o=C.createServer(),n=setTimeout(()=>{o.close(),s(!1)},t);o.listen(e,"localhost",()=>{clearTimeout(n),o.once("close",()=>{s(!0)}),o.close()}),o.once("error",()=>{clearTimeout(n),s(!1)})})}async findAvailablePort(){for(let e=0;e<10;e++){const t=this.startPort+e;if(await this.isPortAvailable(t))return this.logger.debug(`Found available port: ${t}`),t}throw new F(`No available port found in range ${this.startPort}-${this.startPort+10-1}. Please specify a different port range or free up some ports.`)}async start(){if(this.isRunning())return this.url;this.iflowPath=this.findIflowPath(),this.port=await this.findAvailablePort();const e=[this.iflowPath,"--experimental-acp","--port",this.port.toString()];this.stream&&e.push("--stream"),this.logger.info(`Starting iFlow process: ${e.join(" ")}`);try{if(this.process=Qt(e[0],e.slice(1),{stdio:["ignore","pipe","pipe"],detached:!1,cleanup:!0,windowsHide:!0,reject:!1,encoding:"utf8",env:{...process.env,LANG:process.env.LANG||"en_US.UTF-8"}}),await this.onSpawn(),!this.isRunning()){let e="iFlow process exited immediately";throw this.process.stderr&&(e+=`: ${this.process.stderr}`),new Error(e)}return this.registerExitHandler(),this.logger.info(`iFlow process started on port ${this.port} (PID: ${this.process.pid})`),this.url}catch(e){throw this.port=null,this.process=null,new k(`Failed to start iFlow process: ${X(e)}`)}}registerExitHandler(){this.exitHandler||(this.exitHandler=()=>{if(!this.isCleaningUp&&this.process&&this.isRunning()){this.isCleaningUp=!0,this.logger.debug("Parent process exiting, cleaning up child process");try{if(this.isWindows())try{O.execSync(`taskkill /F /T /PID ${this.process.pid}`,{windowsHide:!0,timeout:Kt.TASKKILL_TIMEOUT_EXIT_HANDLER,stdio:"ignore"})}catch(e){this.logger.debug(`taskkill failed: ${X(e)}`)}else this.process.kill("SIGKILL")}catch(e){this.logger.debug(`Error during process cleanup: ${X(e)}`)}finally{this.isCleaningUp=!1}}},process.on("exit",this.exitHandler),process.on("SIGINT",this.exitHandler),process.on("SIGTERM",this.exitHandler),this.isWindows()&&process.on("SIGBREAK",this.exitHandler))}unregisterExitHandler(){this.exitHandler&&(process.off("exit",this.exitHandler),process.off("SIGINT",this.exitHandler),process.off("SIGTERM",this.exitHandler),this.isWindows()&&process.off("SIGBREAK",this.exitHandler),this.exitHandler=null)}async stop(){if(this.process){if(this.unregisterExitHandler(),!this.isRunning())return this.port=null,void(this.process=null);this.logger.info(`Stopping iFlow process (PID: ${this.process.pid})`);try{if(this.isWindows())try{O.execSync(`taskkill /T /PID ${this.process.pid}`,{windowsHide:!0,timeout:3e3,stdio:"ignore"})}catch(e){this.logger.debug(`taskkill (graceful shutdown) failed: ${X(e)}`)}else this.process.kill("SIGTERM");if(await Promise.race([this.process.then(()=>{},()=>{}),new Promise(e=>setTimeout(()=>e(),5e3))]),this.isRunning()){if(this.logger.warn("iFlow process did not terminate gracefully, forcing kill"),this.isWindows())try{O.execSync(`taskkill /F /T /PID ${this.process.pid}`,{windowsHide:!0,timeout:Kt.TASKKILL_TIMEOUT_STOP,stdio:"ignore"})}catch(e){this.logger.warn(`taskkill /F /T failed, process may have already exited or is inaccessible: ${X(e)}`)}else this.process.kill("SIGKILL");await this.process.then(()=>{},()=>{})}else this.logger.info("iFlow process terminated gracefully")}catch(e){this.logger.error(`Error stopping iFlow process: ${X(e)}`)}finally{this.port=null,this.process=null}}}async onSpawn(e=5e3){return new Promise((t,s)=>{if(!this.process)return void s(new Error("Process not initialized"));const o=setTimeout(()=>{s(new Error(`Process spawn timeout after ${e}ms`))},e);this.process.once("spawn",()=>{clearTimeout(o),setTimeout(t,2e3)})})}}Kt.TASKKILL_TIMEOUT_EXIT_HANDLER=3e3,Kt.TASKKILL_TIMEOUT_STOP=5e3;class Bt{constructor(e={}){this.protocol=null,this.transport=null,this.connected=!1,this.authenticated=!1,this.messageTask=null,this.messageQueue=[],this.pendingToolCalls=new Map,this.pendingAskUserQuestionsRequestId=null,this.pendingQuestions=[],this.pendingExitPlanModeRequestId=null,this.pendingPermissionRequests=new Map,this.url=null,this.sessionId=null,this.processManager=null,this.processStarted=!1,this.connectingPromise=null,this.modes=null,this.models=null,this.availableCommands=[],this.availableAgents=[],this.availableSkills=[],this.availableMcpServers=[],this.config={get:async e=>{switch(e){case"models":return this.models?.availableModels||[];case"model":return this.models?.currentModelId||null;case"modes":return this.modes?.availableModes||[];case"mode":return this.modes?.currentModeId||null;case"commands":return this.availableCommands;case"agents":return this.availableAgents;case"skills":return this.availableSkills;case"mcpServers":return this.availableMcpServers;default:throw new Error(`Unknown config key: ${e}`)}},set:async(e,t)=>{if(!this.connected||!this.protocol||!this.sessionId)throw new q("Not connected. Call connect() first.");switch(e){case"model":try{const e=await this.protocol.setModel({sessionId:this.sessionId,modelId:t});if(!e||!this.models){throw new Error(e?"Models not available":"No result returned from server")}this.models.currentModelId=e,this.logger.info(`Set model to: ${e}`)}catch(e){throw this.logger.error(`Failed to set model to ${t}: ${X(e)}`),e}return;case"mode":try{const e=await this.protocol.setMode({sessionId:this.sessionId,modeId:t});if(!e||!this.modes){throw new Error(e?"Modes not available":"No result returned from server")}this.modes.currentModeId=e,this.logger.info(`Set mode to: ${e}`)}catch(e){throw this.logger.error(`Failed to set mode to ${t}: ${X(e)}`),e}return;case"think":{const e=t;try{const t=await this.protocol.setThink({sessionId:this.sessionId,thinkEnabled:e.enabled,thinkConfig:e.config});return this.logger.info(`Set think mode: enabled=${t.currentThinkEnabled}, config=${t.currentThinkConfig||"default"}`),t}catch(e){throw this.logger.error(`Failed to set think mode: ${X(e)}`),e}}default:throw new Error(`Cannot set config key: ${e}. Only 'model', 'mode', and 'think' are supported.`)}}},this.options={url:"ws://localhost:8090/acp",cwd:process.cwd(),timeout:3e4,logLevel:"INFO",fileMaxSize:10485760,permissionMode:exports.PermissionMode.AUTO,authMethodId:"iflow",autoStartProcess:!0,processStartPort:8090,...e},this.logger=new J({level:this.options.logLevel})}isConnected(){return this.connected}getConnectionState(){return this.connected?"connected":this.connectingPromise?"connecting":"disconnected"}async connect(){if(this.connectingPromise)return this.logger.info("Connection already in progress, waiting for it to complete"),this.connectingPromise;if(this.connected)this.logger.debug("Already connected, skipping connection attempt");else{this.connectingPromise=this._doConnect();try{await this.connectingPromise}finally{this.connectingPromise=null}}}async _doConnect(){try{if(this.options.autoStartProcess&&(this.options.url?.startsWith("ws://localhost:")||this.options.url?.startsWith("ws://127.0.0.1:"))){const e=new se({url:this.options.url,logger:this.logger,timeout:2e3});try{await e.connect(),await e.close(),this.url=this.options.url,this.logger.info(`iFlow already running at ${this.options.url}`)}catch{this.logger.info("iFlow not running, starting process..."),this.processManager=new Kt({logger:this.logger,startPort:this.options.processStartPort,stream:this.options.stream});try{const e=await this.processManager.start();this.url=e,this.processStarted=!0,this.logger.info(`Started iFlow process at ${e}`),await new Promise(e=>setTimeout(e,1e3))}catch(e){throw e instanceof L?(this.logger.error("iFlow not installed"),L):(this.logger.error(`Failed to start iFlow process: ${X(e)}`),new q(`Failed to start iFlow process: ${X(e)}`))}}}let e=null;this.options.fileAccess&&(e=new oe({cwd:this.options.cwd,logger:this.logger,readOnly:this.options.fileReadOnly,maxFileSize:this.options.fileMaxSize,allowedDirs:this.options.fileAllowedDirs}),this.logger.info(`File system access enabled with ${this.options.fileReadOnly?"read-only":"read-write"} mode`)),this.transport=new se({url:this.options.url,logger:this.logger,timeout:this.options.timeout}),this.protocol=new te({logger:this.logger,transport:this.transport,fileHandler:e,permissionMode:this.options.permissionMode,autoApproveTypes:this.options.autoApproveTypes}),await this.transport.connect();const t=await this.protocol.initialize({mcpServers:this.options.mcpServers,hooks:this.options.hooks,commands:this.options.commands,agents:this.options.agents});let s;if(this.authenticated=t.isAuthenticated||!1,this.authenticated||(await this.protocol.authenticate({methodId:this.options.authMethodId,methodInfo:this.options.authMethodInfo}),this.authenticated=!0),this.options.sessionId)this.logger.info(`Loading existing session: ${this.options.sessionId}`),await this.protocol.loadSession({sessionId:this.options.sessionId,mcpServers:this.options.mcpServers}),this.sessionId=this.options.sessionId,s=null;else{if(this.logger.info("Creating new session"),s=await this.protocol.createSession({cwd:this.options.cwd||process.cwd(),mcpServers:this.options.mcpServers,hooks:this.options.hooks,commands:this.options.commands,agents:this.options.agents,settings:this.options.sessionSettings}),!s||!s.sessionId)throw new q("Failed to create session: invalid session result");this.sessionId=s.sessionId}s&&(s.modes&&(this.modes=s.modes),s._meta?.models&&(this.models=s._meta.models),s._meta?.availableCommands&&(this.availableCommands=s._meta.availableCommands),s._meta?.availableAgents&&(this.availableAgents=s._meta.availableAgents),s._meta?.availableSkills&&(this.availableSkills=s._meta.availableSkills),s._meta?.availableMcpServers&&(this.availableMcpServers=s._meta.availableMcpServers)),this.connected=!0,this.messageTask=this.handleMessages(),this.logger.info("Connected to iFlow")}catch(e){throw await this.disconnect(),new q(`Failed to connect: ${X(e)}`)}}async loadSession(e){if(!this.connected||!this.protocol)throw new q("Not connected. Call connect() first.");await this.protocol.loadSession({sessionId:e,cwd:this.options.cwd||process.cwd(),mcpServers:this.options.mcpServers}),this.sessionId=e,this.logger.info(`Loaded session: ${e}`)}async disconnect(){this.connected=!1,this.transport&&await this.transport.close(),this.processManager&&this.processStarted&&await this.processManager.stop(),this.url=null,this.protocol=null,this.transport=null,this.messageTask=null,this.authenticated=!1,this.processManager=null,this.processStarted=!1,this.logger.info("Disconnected from iFlow")}async sendMessage(e,t){if(!this.connected||!this.protocol||!this.sessionId)throw new q("Not connected. Call connect() first.");const s=[{type:"text",text:e}];if(t?.length)for(const e of t)if("object"!=typeof e||"image"!==e.type){if("object"==typeof e&&"selection"===e.type){const t={activeFile:{path:e.uri,cursor:{line:e.line?.start||0,character:0},selectedText:e.data}},o=`Here is the user's editor context as a JSON object. This is for your information only.\n\`\`\`json\n${JSON.stringify(t,null,2)}\n\`\`\``;s.push({type:"text",text:o}),this.logger.debug("Added selection context");continue}if("string"==typeof e){const t=P.resolve(this.options.cwd||process.cwd(),e),o=P.parse(e);if(!b.existsSync(t)){this.logger.warn(`File not found, skipping: ${t}`);continue}const n=o.ext.toLowerCase();if([".png",".jpg",".jpeg",".gif",".bmp",".webp",".svg"].includes(n))try{const e=b.readFileSync(t).toString("base64"),i={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".bmp":"image/bmp",".webp":"image/webp",".svg":"image/svg+xml"};s.push({type:"image",data:e,mimeType:i[n]||"image/unknown"}),this.logger.debug(`Added image file: ${o.base}`)}catch(e){this.logger.error(`Failed to read image file ${t}: ${X(e)}`);continue}else if([".mp3",".wav",".m4a",".ogg",".flac"].includes(n))try{const e=b.readFileSync(t).toString("base64"),i={".mp3":"audio/mpeg",".wav":"audio/wav",".m4a":"audio/mp4",".ogg":"audio/ogg",".flac":"audio/flac"};s.push({type:"audio",data:e,mimeType:i[n]||"audio/unknown"}),this.logger.debug(`Added audio file: ${o.base}`)}catch(e){this.logger.error(`Failed to read audio file ${t}: ${X(e)}`);continue}else{const e=b.statSync(t);s.push({type:"resource_link",uri:`file://${t}`,name:o.base,title:o.name,size:e.size}),this.logger.debug(`Added resource link: ${o.base}`)}}}else s.push({type:"image",data:e.data,mimeType:e.mimeType}),this.logger.debug("Added image data");await this.protocol.sendPrompt({sessionId:this.sessionId,prompt:s})}async interrupt(){if(!this.connected||!this.protocol||!this.sessionId)throw new q("Not connected");await this.protocol.cancelSession({sessionId:this.sessionId}),this.logger.info("Sent interrupt signal")}async*receiveMessages(){if(!this.connected)throw new q("Not connected");for(;this.connected;)try{this.messageQueue.length>0?yield this.messageQueue.shift():await new Promise(e=>setTimeout(e,100))}catch{continue}}async approveToolCall(e,t=exports.ToolCallConfirmationOutcome.ALLOW){if(!this.pendingToolCalls.has(e))throw new Error(`Unknown tool call: ${e}`);this.logger.info(`Approved tool call ${e} with outcome ${t}`),this.pendingToolCalls.delete(e)}async rejectToolCall(e){if(!this.pendingToolCalls.has(e))throw new Error(`Unknown tool call: ${e}`);this.logger.info(`Rejected tool call ${e}`),this.pendingToolCalls.delete(e)}async respondToAskUserQuestions(e){if(!this.connected||!this.protocol)throw new q("Not connected");if(null===this.pendingAskUserQuestionsRequestId)throw new Error("No pending ask_user_questions request");for(const t of this.pendingQuestions){const s=e[t.header];if(void 0===s)throw new j(`Missing answer for question: ${t.header}`);if(t.multiSelect){if(!Array.isArray(s))throw new j(`Question "${t.header}" requires multiple selections (array)`);const e=t.options?.map(e=>e.label)||[];for(const o of s)if(!e.includes(o))throw new j(`Invalid option "${o}" for question "${t.header}"`)}else{if(Array.isArray(s))throw new j(`Question "${t.header}" requires single selection (string)`);if(!(t.options?.map(e=>e.label)||[]).includes(s))throw new j(`Invalid option "${s}" for question "${t.header}"`)}}await this.protocol.respondToAskUserQuestions(this.pendingAskUserQuestionsRequestId,e),this.pendingAskUserQuestionsRequestId=null,this.pendingQuestions=[],this.logger.info("Sent ask_user_questions response")}async respondToExitPlanMode(e){if(!this.connected||!this.protocol)throw new q("Not connected");if(null===this.pendingExitPlanModeRequestId)throw new Error("No pending exit_plan_mode request");await this.protocol.respondToExitPlanMode(this.pendingExitPlanModeRequestId,e),this.pendingExitPlanModeRequestId=null,this.logger.info("Sent exit_plan_mode response: "+(e?"approved":"rejected"))}async respondToToolConfirmation(e,t){if(!this.connected||!this.protocol)throw new q("Not connected");if(!this.pendingPermissionRequests.has(e))throw new Error(`No pending permission request with ID: ${e}`);await this.protocol.sendPermissionResponse(e,t),this.pendingPermissionRequests.delete(e),this.logger.info(`Sent tool confirmation response for request ${e}: ${t}`)}async cancelToolConfirmation(e){if(!this.connected||!this.protocol)throw new q("Not connected");if(!this.pendingPermissionRequests.has(e))throw new Error(`No pending permission request with ID: ${e}`);await this.protocol.cancelPermissionResponse(e),this.pendingPermissionRequests.delete(e),this.logger.info(`Cancelled tool confirmation request: ${e}`)}async handleMessages(){if(this.protocol)try{for await(const e of this.protocol.handleMessages()){const t=this.processProtocolMessage(e);t&&this.messageQueue.push(t)}}catch(e){if(e instanceof q&&e.details.clientInitiated)this.logger.debug("Message handler stopped: connection closed by client");else{const t=X(e);this.logger.error(`Error in message handler: ${t}`);const s={type:exports.MessageType.ERROR,code:-1,message:String(t)};this.messageQueue.push(s)}}}processProtocolMessage(e){switch(e.type){case z.SESSION_UPDATE:{const{updateData:t}=e;let s,o;switch("agentId"in t&&t.agentId&&(s=t.agentId,o=function(e){const t=e.split("-");return"subagent"!==t[0]||t.length<4?{agentId:e}:4===t.length?{agentId:e,taskId:["null","undefined"].includes(t[1])?void 0:t[1],agentIndex:parseInt(t[2])||void 0,timestamp:parseInt(t[3])||void 0}:{agentId:e,taskId:t.slice(1,-2).join("-"),agentIndex:parseInt(t[t.length-2])||void 0,timestamp:parseInt(t[t.length-1])||void 0}}(s)),t.sessionUpdate){case B.PLAN:{const e=t.entries?.map(e=>({content:e.content||"",status:e.status||exports.PlanStatus.PENDING,priority:e.priority||exports.PlanPriority.MEDIUM}));return e&&e?.length>0?{type:exports.MessageType.PLAN,entries:e}:null}case B.TOOL_CALL:{const e={type:exports.MessageType.TOOL_CALL,id:t.toolCallId||"",label:t.title||"Tool",icon:{type:exports.ToolCallIconType.EMOJI,value:"🔧"},status:t.status||exports.ToolCallStatus.IN_PROGRESS,toolName:t.toolName,args:t.args};return s&&(e.agentId=s,e.agentInfo=o),this.pendingToolCalls.set(e.id,e),{...e}}case B.TOOL_CALL_UPDATE:{const e=t.toolCallId;let n;if(this.pendingToolCalls.has(e)?(n=this.pendingToolCalls.get(e),n.status=t.status||exports.ToolCallStatus.COMPLETED,n.args=t.args,t.toolName&&(n.toolName=t.toolName),!n.agentId&&s&&(n.agentId=s),!n.agentInfo&&o&&(n.agentInfo=o)):(n={type:exports.MessageType.TOOL_CALL,id:e,label:t.title||"Tool",icon:{type:exports.ToolCallIconType.EMOJI,value:"🔧"},status:t.status||exports.ToolCallStatus.COMPLETED,toolName:t.toolName,args:t.args},s&&(n.agentId=s,n.agentInfo=o),this.pendingToolCalls.set(e,n)),t.content&&t.content?.length>0){let e;const s=[];for(const o of t.content)"args"in o&&(e=o.args),"content"===o.type&&"text"===o.content?.type&&s.push(o.content.text||"");void 0!==e&&void 0===n.args&&(n.args=e),s.length>0&&(n.output=s.join("\n"))}return{...n}}case B.USER_MESSAGE_CHUNK:{const e=t.content;if("text"===e?.type){const t=e.text||"";if(t)return{type:exports.MessageType.USER,chunks:[{text:t}]}}return null}case B.AGENT_MESSAGE_CHUNK:{const e=t.content;if("text"===e?.type){const t=e.text||"";if(t){const e={type:exports.MessageType.ASSISTANT,chunk:{text:t}};return s&&(e.agentId=s,e.agentInfo=o),e}}return null}case B.AGENT_THOUGHT_CHUNK:{const e=t.content;if("text"===e?.type){const t=e.text||"";if(t){const e={type:exports.MessageType.ASSISTANT,chunk:{thought:t}};return s&&(e.agentId=s,e.agentInfo=o),e}}}default:return null}}case z.RESPONSE:{const t=e.result;return t&&"object"==typeof t&&"stopReason"in t?{type:exports.MessageType.TASK_FINISH,stopReason:t.stopReason}:null}case z.ERROR:return{type:exports.MessageType.ERROR,code:e.code||-1,message:e.error||"Unknown error"};case z.ASK_USER_QUESTIONS:{const t=e,{questions:s}=t.params||{};return null!==this.pendingAskUserQuestionsRequestId?(this.logger.warn("Another ask_user_questions request is already pending, ignoring new request"),null):(this.pendingAskUserQuestionsRequestId=t.requestId,this.pendingQuestions=s||[],{type:exports.MessageType.ASK_USER_QUESTIONS,questions:s||[]})}case z.EXIT_PLAN_MODE:{const t=e,{plan:s}=t.params||{};return null!==this.pendingExitPlanModeRequestId?(this.logger.warn("Another exit_plan_mode request is already pending, ignoring new request"),null):(this.pendingExitPlanModeRequestId=t.requestId,{type:exports.MessageType.EXIT_PLAN_MODE,plan:s||""})}case"permission_request":{const t=e,{requestId:s,sessionId:o,toolCall:n,options:i}=t;return this.pendingPermissionRequests.has(s)?(this.logger.warn(`Permission request ${s} is already pending, ignoring new request`),null):(this.pendingPermissionRequests.set(s,{toolCall:n,options:i,sessionId:o}),{type:exports.MessageType.PERMISSION_REQUEST,requestId:s,sessionId:o,toolCall:n,options:i})}default:return null}}}function zt(e){let t,s=!1,o="text";if(e.startsWith("//"))s=!0,o="control";else try{t=JSON.parse(e),t&&"method"in t?o=`method:${t.method}`:t&&("result"in t||"error"in t)?o="response":t&&"type"in t&&(o=t.type)}catch{}return{isControl:s,messageType:o,rawData:e,jsonData:t,timestamp:Date.now()}}exports.AuthenticationError=H,exports.ConnectionError=q,exports.IFlowClient=Bt,exports.IFlowError=$,exports.IFlowNotInstalledError=L,exports.IFlowProcessError=k,exports.JSONDecodeError=N,exports.PermissionError=D,exports.PortNotAvailableError=F,exports.ProtocolError=G,exports.RawDataClient=class extends Bt{constructor(e,t=!0){super(e),this.rawQueue=[],this.rawHistory=[],this.rawQueueResolvers=[],this.messageQueueResolvers=[],this.captureRaw=t}async handleMessages(){if(this.protocol)try{if(this.captureRaw&&this.transport){const e=this.captureRawStream(),t=this.handleParsedStream();await Promise.all([e,t])}else await super.handleMessages()}catch(e){e instanceof q&&e.details.clientInitiated?this.logger.debug("Message handler stopped: connection closed by client"):this.logger.error(`Error in message handler: ${X(e)}`)}}async captureRawStream(){if(this.transport)try{for await(const e of this.transport.receive()){const t=zt("string"==typeof e?e:JSON.stringify(e));this.rawQueue.push(t),this.rawHistory.push(t);const s=this.rawQueueResolvers.shift();s&&s(t)}}catch(e){e instanceof q&&e.details.clientInitiated||this.logger.error(`Error capturing raw stream: ${X(e)}`)}}async handleParsedStream(){if(this.protocol)for await(const e of this.protocol.handleMessages()){const t=this.processProtocolMessage(e);if(t){const e=this.messageQueueResolvers.shift();e&&e(t)}}}async*receiveRawMessages(){for(;this.connected||this.rawQueue.length>0;)try{if(this.rawQueue.length>0)yield this.rawQueue.shift();else{const e=await Promise.race([new Promise(e=>{this.rawQueueResolvers.push(e)}),new Promise((e,t)=>{setTimeout(()=>t(new Error("Timeout")),100)})]);yield e}}catch(e){if(e instanceof Error&&"Timeout"===e.message)continue;throw e}}async*receiveDualStream(){const e=[],t=[];for(;this.connected||this.rawQueue.length>0||e.length>0||t.length>0;)try{let e,t;e=this.rawQueue.length>0?this.rawQueue.shift():await Promise.race([new Promise(e=>{this.rawQueueResolvers.push(e)}),new Promise((e,t)=>{setTimeout(()=>t(new Error("Timeout")),10)})]);try{t=await Promise.race([new Promise(e=>{this.messageQueueResolvers.push(e)}),new Promise((e,t)=>{setTimeout(()=>t(new Error("Timeout")),10)})])}catch{}e.parsedMessage=t,yield[e,t]}catch(e){if(!(e instanceof Error&&"Timeout"===e.message))throw e;try{const e=await Promise.race([new Promise(e=>{this.messageQueueResolvers.push(e)}),new Promise((e,t)=>{setTimeout(()=>t(new Error("Timeout")),10)})]),t=zt("<no-raw-data>");t.messageType="parsed_only",yield[t,e]}catch(e){if(e instanceof Error&&"Timeout"===e.message)continue;throw e}}}getRawHistory(){return[...this.rawHistory]}getProtocolStats(){const e={totalMessages:this.rawHistory.length,messageTypes:{},controlMessages:0,jsonMessages:0,textMessages:0,errors:0};for(const t of this.rawHistory)t.messageType&&(e.messageTypes[t.messageType]=(e.messageTypes[t.messageType]||0)+1),t.isControl?e.controlMessages++:t.jsonData?e.jsonMessages++:e.textMessages++,t.jsonData&&"error"in t.jsonData&&e.errors++;return e}async sendRaw(e){if(!this.transport)throw new Error("Not connected");await this.transport.send(e);const t="string"==typeof e?e:JSON.stringify(e).substring(0,100);this.logger.info(`Sent raw data: ${t}`)}},exports.TimeoutError=M,exports.TransportError=U,exports.ValidationError=j,exports.query=async function(e,t,s){const o=[],n=new Bt(s);await n.connect();try{await n.sendMessage(e,t);for await(const e of n.receiveMessages())if(e.type===exports.MessageType.ASSISTANT&&e.chunk.text)o.push(e.chunk.text);else if(e.type===exports.MessageType.TASK_FINISH)break}finally{await n.disconnect()}return o.join("")},exports.queryStream=async function*(e,t,s){const o=new Bt(s);await o.connect();try{await o.sendMessage(e,t);for await(const e of o.receiveMessages())if(e.type===exports.MessageType.ASSISTANT&&e.chunk.text)yield e.chunk.text;else if(e.type===exports.MessageType.TASK_FINISH)break}finally{await o.disconnect()}};
|
|
1
|
+
"use strict";var e=require("fs"),t=require("path"),s=require("ws"),o=require("readline"),i=require("fs/promises"),n=require("os"),r=require("net"),a=require("child_process"),c=require("assert"),l=require("events"),d=require("buffer"),h=require("stream"),u=require("util");function p(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(s){if("default"!==s){var o=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,o.get?o:{enumerable:!0,get:function(){return e[s]}})}}),t.default=e,Object.freeze(t)}var f,g,m,w,y,S,x,I,E,T,v,P,b,_,C=p(e),R=p(t),A=p(o),$=p(i),O=p(n),M=p(r),N=p(a);class k extends Error{constructor(e,t){super(e),this.name="IFlowError",this.details=t||{}}}class L extends k{constructor(e,t){super(e,t),this.name="TimeoutError"}}class F extends k{constructor(e,t){super(e,{rawData:t}),this.name="JSONDecodeError",this.rawData=t}}class q extends k{constructor(e,t){super(e,t),this.name="IFlowNotInstalledError"}}class U extends k{constructor(e,t){super(e,t),this.name="IFlowProcessError"}}class D extends k{constructor(e,t){super(e,t),this.name="PortNotAvailableError"}}class j extends k{constructor(e,t){super(e,t),this.name="ConnectionError"}}class G extends k{constructor(e,t){super(e,t),this.name="TransportError"}}class H extends k{constructor(e,t){super(e,t),this.name="PermissionError"}}class W extends k{constructor(e,t){super(e,t),this.name="ValidationError"}}class Q extends k{constructor(e,t){super(e,t),this.name="ProtocolError"}}class K extends k{constructor(e,t){super(e,t),this.name="AuthenticationError"}}exports.LogLevel=void 0,(f=exports.LogLevel||(exports.LogLevel={}))[f.DEBUG=0]="DEBUG",f[f.INFO=1]="INFO",f[f.WARN=2]="WARN",f[f.ERROR=3]="ERROR",exports.PermissionMode=void 0,(g=exports.PermissionMode||(exports.PermissionMode={})).AUTO="auto",g.MANUAL="manual",g.SELECTIVE="selective",exports.ApprovalMode=void 0,(m=exports.ApprovalMode||(exports.ApprovalMode={})).DEFAULT="default",m.AUTO_EDIT="autoEdit",m.YOLO="yolo",m.PLAN="plan",exports.HookEventType=void 0,(w=exports.HookEventType||(exports.HookEventType={})).PRE_TOOL_USE="PreToolUse",w.POST_TOOL_USE="PostToolUse",w.STOP="Stop",w.SUBAGENT_STOP="SubagentStop",w.SET_UP_ENVIRONMENT="SetUpEnvironment",exports.TransportMode=void 0,(y=exports.TransportMode||(exports.TransportMode={})).WEBSOCKET="websocket",y.STDIO="stdio",exports.PlanPriority=void 0,(S=exports.PlanPriority||(exports.PlanPriority={})).HIGH="high",S.MEDIUM="medium",S.LOW="low",exports.PlanStatus=void 0,(x=exports.PlanStatus||(exports.PlanStatus={})).PENDING="pending",x.IN_PROGRESS="in_progress",x.COMPLETED="completed",exports.StopReason=void 0,(I=exports.StopReason||(exports.StopReason={})).END_TURN="end_turn",I.MAX_TOKENS="max_tokens",I.REFUSAL="refusal",I.CANCELLED="cancelled",exports.ToolCallStatus=void 0,(E=exports.ToolCallStatus||(exports.ToolCallStatus={})).PENDING="pending",E.IN_PROGRESS="in_progress",E.COMPLETED="completed",E.FAILED="failed",exports.ToolCallContentType=void 0,(T=exports.ToolCallContentType||(exports.ToolCallContentType={})).DIFF="diff",T.MARKDOWN="markdown",exports.ToolCallConfirmationType=void 0,(v=exports.ToolCallConfirmationType||(exports.ToolCallConfirmationType={})).EDIT="edit",v.EXECUTE="execute",v.MCP="mcp",v.FETCH="fetch",v.OTHER="other",exports.ToolCallConfirmationOutcome=void 0,(P=exports.ToolCallConfirmationOutcome||(exports.ToolCallConfirmationOutcome={})).ALLOW="allow",P.ALWAYS_ALLOW="alwaysAllow",P.ALWAYS_ALLOW_TOOL="alwaysAllowTool",P.ALWAYS_ALLOW_MCP_SERVER="alwaysAllowMcpServer",P.REJECT="reject",exports.ToolCallIconType=void 0,(b=exports.ToolCallIconType||(exports.ToolCallIconType={})).URL="url",b.EMOJI="emoji",exports.MessageType=void 0,(_=exports.MessageType||(exports.MessageType={})).PLAN="plan",_.USER="user",_.ASSISTANT="assistant",_.TOOL_CALL="tool_call",_.ERROR="error",_.TASK_FINISH="task_finish",_.ASK_USER_QUESTIONS="ask_user_questions",_.EXIT_PLAN_MODE="exit_plan_mode",_.PERMISSION_REQUEST="permission_request";const B="2.0";var z,X,J,V;function Y(e){if(e instanceof Error){const t=e,s=t.details?.data?.details;return s?`${e.message}\n${s}`:e.message}return e?String(e):"unknown error"}!function(e){e.INITIALIZE="initialize",e.AUTHENTICATE="authenticate",e.SESSION_NEW="session/new",e.SESSION_LOAD="session/load",e.SESSION_PROMPT="session/prompt",e.SESSION_CANCEL="session/cancel",e.SESSION_SET_MODE="session/set_mode",e.SESSION_SET_MODEL="session/set_model",e.SESSION_SET_THINK="session/set_think"}(z||(z={})),function(e){e.SESSION_UPDATE="session/update",e.SESSION_REQUEST_PERMISSION="session/request_permission",e.FS_READ_TEXT_FILE="fs/read_text_file",e.FS_WRITE_TEXT_FILE="fs/write_text_file",e.PUSH_TOOL_CALL="pushToolCall",e.UPDATE_TOOL_CALL="updateToolCall",e.NOTIFY_TASK_FINISH="notifyTaskFinish",e.ASK_USER_QUESTIONS="_iflow/user/questions",e.EXIT_PLAN_MODE="_iflow/plan/exit"}(X||(X={})),function(e){e.PLAN="plan",e.TOOL_CALL="tool_call",e.TOOL_CALL_UPDATE="tool_call_update",e.USER_MESSAGE_CHUNK="user_message_chunk",e.AGENT_MESSAGE_CHUNK="agent_message_chunk",e.AGENT_THOUGHT_CHUNK="agent_thought_chunk"}(J||(J={})),function(e){e.ERROR="error",e.RESPONSE="response",e.FILE_READ="file_read",e.FILE_WRITE="file_write",e.SESSION_UPDATE="session_update",e.TOOL_CALL="tool_call",e.TOOL_UPDATE="tool_update",e.TASK_FINISH="task_finish",e.ASK_USER_QUESTIONS="ask_user_questions",e.EXIT_PLAN_MODE="exit_plan_mode",e.PERMISSION_REQUEST="permission_request",e.UNKNOWN="unknown"}(V||(V={}));class Z{constructor(e={}){const t=e.level||"INFO";this.level=exports.LogLevel[t]}debug(e){this.log(exports.LogLevel.DEBUG,e)}info(e){this.log(exports.LogLevel.INFO,e)}warn(e){this.log(exports.LogLevel.WARN,e)}error(e,t){this.log(exports.LogLevel.ERROR,e,t)}log(e,t,s){if(e<this.level)return;const o=`[${(new Date).toLocaleString("sv-SE").replace("T"," ")}] ${exports.LogLevel[e]}: ${t}${s?`\n${s.stack}`:""}`;switch(e){case exports.LogLevel.DEBUG:console.debug(o);break;case exports.LogLevel.INFO:console.info(o);break;case exports.LogLevel.WARN:console.warn(o);break;case exports.LogLevel.ERROR:console.error(o)}}}const ee=new Z;function te(e){return!!e&&"id"in e&&"result"in e&&null!=e.result}function se(e){return!!e&&"id"in e&&"error"in e&&null!=e.error}function oe(e){return!!e&&"method"in e&&!("result"in e)&&!("error"in e)}class ie{constructor(e){this.requestId=0,this.initialized=!1,this.authenticated=!1,this.pendingPermissionRequests=new Map,this.maxPendingRequests=10,this.requestTtl=300,this.logger=e.logger||ee,this.transport=e.transport,this.fileHandler=e.fileHandler,this.permissionMode=e.permissionMode||exports.PermissionMode.AUTO,this.autoApproveTypes=e.autoApproveTypes||["read","fetch","list"]}nextRequestId(){return++this.requestId}checkAuthenticated(){if(!this.initialized)throw new Q("Protocol not initialized. Call initialize() first.");if(!this.authenticated)throw new Q("Not authenticated. Call authenticate() first.")}async sendResult(e,t){const s={jsonrpc:B,id:e,result:t};await this.transport.send(s)}async sendError(e,t,s){const o={jsonrpc:B,id:e,error:{code:t,message:s}};await this.transport.send(o)}async waitForReadySignal(){let e=null,t=!1;const s=new Promise(s=>{e=setTimeout(()=>{t=!0,this.logger.info("//ready signal timeout, proceeding anyway"),s()},5e3)}),o=(async()=>{for await(const e of this.transport.receive()){if(t)break;const s=e.trim();if("//ready"===s){this.logger.info("Received //ready signal");break}if(!s.startsWith("//")){this.logger.info("Received first message, assuming ready");break}this.logger.debug(`Control message: ${s}`)}})();await Promise.race([o,s]),t=!0,null!==e&&clearTimeout(e)}async waitForMessageResponse(e,t,s){const{timeout:o,timeoutMsg:i=`Timeout after ${o} seconds`}=s||{};let n=null;try{const s=this.transport.waitForResponse(e),r=o&&o>0?await Promise.race([s,new Promise((e,t)=>{n=setTimeout(()=>t(new L(i)),o)})]):await s;let a;try{a=JSON.parse(r.trim())}catch(e){throw this.logger.error(`Failed to parse response: ${Y(e)}`),new F("Invalid JSON received",r)}return t(a)}catch(e){if(e instanceof L)throw e;throw e}finally{null!==n&&clearTimeout(n)}}async initialize(e={}){if(this.initialized)return this.logger.warn("Protocol already initialized"),{protocolVersion:1,isAuthenticated:this.authenticated};this.logger.info("Waiting for //ready signal..."),await this.waitForReadySignal();const t=this.nextRequestId(),s={jsonrpc:B,id:t,method:z.INITIALIZE,params:{protocolVersion:1,clientCapabilities:{fs:{readTextFile:!1,writeTextFile:!1},terminal:!1},...e}};await this.transport.send(s),this.logger.info("Sent initialize request");const o=await this.waitForMessageResponse(t,e=>{if("error"in e)throw new Q(`Initialize failed: ${e.error?.message}`,e.error);const t=e.result||{};return this.initialized=!0,this.authenticated=t.isAuthenticated||!1,this.logger.info(`Initialized with protocol version: ${t.protocolVersion}, authenticated: ${this.authenticated}`),t},{timeout:1e4,timeoutMsg:"Initialize timeout after 10 seconds"});if(o)return o;throw new Q("Connection closed during initialization")}async authenticate(e={}){if(this.authenticated)return void this.logger.warn("Already authenticated");const t=e.methodId||"iflow",s=this.nextRequestId(),o={jsonrpc:B,id:s,method:z.AUTHENTICATE,params:{...e,methodId:t}};await this.transport.send(o),this.logger.info(`Sent authenticate request with method: ${o.params.methodId}`);if(!await this.waitForMessageResponse(s,e=>{if("error"in e)throw new K(`Authentication failed: ${e.error?.message}`,e.error);const s=e.result||{};return s.methodId===t?(this.authenticated=!0,this.logger.info(`Authentication successful with method: ${s.methodId}`),!0):(this.authenticated=!0,this.logger.warn(`Unexpected methodId in response: ${s.methodId} (expected ${t})`),!0)},{timeout:1e4,timeoutMsg:"Authentication timeout after 10 seconds"}))throw new K("Connection closed during authentication")}async createSession(e={}){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:B,id:t,method:z.SESSION_NEW,params:{...e,cwd:e.cwd||process.cwd(),mcpServers:e.mcpServers||[]}};await this.transport.send(s),this.logger.info(`Sent session/new request with cwd: ${e.cwd}`);const o=await this.waitForMessageResponse(t,e=>{if("error"in e)throw new Q(`session/new failed: ${e.error?.message}`,e.error);const t=e.result||{};if(t.sessionId)return this.logger.info(`Created session: ${t.sessionId}`),t;throw new Q(`Invalid session/new response: ${JSON.stringify(t)}`)},{timeout:1e4,timeoutMsg:"Session creation timeout after 10 seconds"});if(o)return o;throw new Q("Connection closed while waiting for session/new response")}async loadSession(e){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:B,id:t,method:z.SESSION_LOAD,params:{...e,cwd:e.cwd||process.cwd(),mcpServers:e.mcpServers||[]}};await this.transport.send(s),this.logger.info(`Sent session/load request for session: ${e.sessionId}`);if(!await this.waitForMessageResponse(t,t=>{if("error"in t){if(-32601===t.error.code)throw new Q("session/load is not supported by the current iFlow version. Use session/new to create a new session instead.",t.error);throw new Q(`session/load failed: ${t.error?.message}`,t.error)}return this.logger.info(`Session loaded successfully: ${e.sessionId}`),!0},{timeout:1e4,timeoutMsg:"Session load timeout after 10 seconds"}))throw new Q("Connection closed while waiting for session/load response")}async sendPrompt(e){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:B,id:t,method:z.SESSION_PROMPT,params:e};return await this.transport.send(s),this.logger.info(`Sent prompt with ${e.prompt.length} content blocks`),t}async cancelSession(e){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:B,id:t,method:z.SESSION_CANCEL,params:e};await this.transport.send(s),this.logger.info("Sent session/cancel request")}async setMode(e){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:B,id:t,method:z.SESSION_SET_MODE,params:e};await this.transport.send(s),this.logger.info(`Sent session/set_mode request with modeId: ${e.modeId}`);try{const e=await this.waitForMessageResponse(t,e=>{if("error"in e)throw new Q(`session/set_mode failed: ${e.error?.message}`,e.error);return e.result},{timeout:1e4,timeoutMsg:"Set mode timeout after 10 seconds"});if(!e?.success)throw new Q("session/set_mode failed: operation unsuccessful");return e.currentModeId}catch(t){throw this.logger.error(`Failed to set mode to ${e.modeId}: ${Y(t)}`),t}}async setModel(e){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:B,id:t,method:z.SESSION_SET_MODEL,params:e};await this.transport.send(s),this.logger.info(`Sent session/set_model request with modelId: ${e.modelId}`);try{const e=await this.waitForMessageResponse(t,e=>{if("error"in e)throw new Q(`session/set_model failed: ${e.error?.message}`,e.error);return e.result},{timeout:1e4,timeoutMsg:"Set model timeout after 10 seconds"});if(!e?.success)throw new Q("session/set_model failed: operation unsuccessful");return e.currentModelId}catch(t){throw this.logger.error(`Failed to set model to ${e.modelId}: ${Y(t)}`),t}}async setThink(e){this.checkAuthenticated();const t=this.nextRequestId(),s={jsonrpc:B,id:t,method:z.SESSION_SET_THINK,params:e};await this.transport.send(s),this.logger.info(`Sent session/set_think request with thinkEnabled: ${e.thinkEnabled}, thinkConfig: ${e.thinkConfig||"default"}`);try{const e=await this.waitForMessageResponse(t,e=>{if("error"in e)throw new Q(`session/set_think failed: ${e.error?.message}`,e.error);return e.result},{timeout:1e4,timeoutMsg:"Set think timeout after 10 seconds"});if(!e?.success)throw new Q("session/set_think failed: operation unsuccessful");return e}catch(e){throw this.logger.error(`Failed to set think: ${Y(e)}`),e}}async respondToAskUserQuestions(e,t){const s={answers:t};await this.sendResult(e,s),this.logger.info(`Sent ask_user_questions response with ${Object.keys(t).length} answers`)}async respondToExitPlanMode(e,t){const s={approved:t};await this.sendResult(e,s),this.logger.info("Sent exit_plan_mode response: "+(t?"approved":"rejected"))}async sendPermissionResponse(e,t){if(!this.pendingPermissionRequests.has(e))throw new Error(`Unknown permission request: ${e}`);const s={outcome:{outcome:"selected",optionId:t}};try{await this.sendResult(e,s),this.pendingPermissionRequests.delete(e),this.logger.info(`Sent permission response for request ${e}: ${t}`)}catch(t){throw this.logger.error(`Failed to send permission response for request ${e}: ${Y(t)}`),t}}async cancelPermissionResponse(e){if(!this.pendingPermissionRequests.has(e))throw new Error(`Unknown permission request: ${e}`);const t={outcome:{outcome:"cancelled"}};try{await this.sendResult(e,t),this.pendingPermissionRequests.delete(e),this.logger.info(`Cancelled permission request: ${e}`)}catch(t){throw this.logger.error(`Failed to cancel permission request ${e}: ${Y(t)}`),t}}async*handleMessages(){for await(const e of this.transport.receive()){if(e.trim().startsWith("//")){this.logger.debug(`Control message: ${e.trim()}`);continue}let t;try{t=JSON.parse(e.trim())}catch(t){throw this.logger.error(`Failed to parse message: ${Y(t)}`),new F("Invalid JSON received",e)}if(oe(t)){const e=await this.handleClientMessage(t);yield e}else te(t)?yield{type:"response",id:t.id,result:t.result}:se(t)&&(yield{type:"error",code:t.error.code,error:`${t.error.message}, detail: ${t.error.data?.details||"unknown"}`})}}async handleClientMessage(e){const{method:t}=e;switch(t){case X.FS_READ_TEXT_FILE:return await this.handleReadTextFile(e);case X.FS_WRITE_TEXT_FILE:return await this.handleWriteTextFile(e);case X.SESSION_UPDATE:return await this.handleSessionUpdate(e);case X.SESSION_REQUEST_PERMISSION:return await this.handleRequestPermission(e);case X.PUSH_TOOL_CALL:return await this.handlePushToolCall(e);case X.UPDATE_TOOL_CALL:return await this.handleUpdateToolCall(e);case X.NOTIFY_TASK_FINISH:return await this.handleNotifyTaskFinish(e);case X.ASK_USER_QUESTIONS:return await this.handleAskUserQuestions(e);case X.EXIT_PLAN_MODE:return await this.handleExitPlanMode(e);default:return await this.handleUnknownMessage(e)}}async handleReadTextFile(e){const{id:t,method:s,params:o}=e,{path:i,limit:n,line:r}=o||{};let a;if(this.logger.info(`fs/read_text_file request for: ${i}`),!this.fileHandler){const e="File system access not configured";return void 0!==t&&await this.sendError(t,-32603,e),{type:"error",code:-32603,error:e,method:s}}try{a=await this.fileHandler.readFile(i,r,n)}catch(e){const o=Y(e);return this.logger.error(`Error reading file ${i}: ${o}`),void 0!==t&&await this.sendError(t,-32603,o),{type:"error",code:-32603,error:o,method:s}}return void 0!==t&&await this.sendResult(t,{content:a}),{type:"file_read",path:i,content:a}}async handleWriteTextFile(e){const{id:t,method:s,params:o}=e,{path:i,content:n}=o||{};if(this.logger.info(`fs/write_text_file request for: ${i}`),!this.fileHandler){const e="File system access not configured";return void 0!==t&&await this.sendError(t,-32603,e),{type:"error",code:-32603,error:e,method:s}}try{await this.fileHandler.writeFile(i,n)}catch(e){const o=Y(e);return this.logger.error(`Error writing file ${i}: ${o}`),void 0!==t&&await this.sendError(t,-32603,o),{type:"error",code:-32603,error:o,method:s}}return void 0!==t&&await this.sendResult(t,{success:!0}),{type:"file_write",path:i,content:n}}async handleSessionUpdate(e){const{params:t}=e,{sessionId:s,update:o}=t;return{type:"session_update",sessionId:s,updateData:o}}async handleRequestPermission(e){const{id:t,params:s}=e,o=s.toolCall||{},i=s.options||[],n=s.sessionId;return void 0!==t?this.pendingPermissionRequests.size>=this.maxPendingRequests?(this.logger.error(`Max pending permission requests limit reached (${this.maxPendingRequests}). Rejecting new request to prevent memory leak.`),await this.sendError(t,-32e3,`Too many pending requests (${this.maxPendingRequests})`),{type:"error",code:-32e3,error:`Too many pending requests (${this.maxPendingRequests})`,method:"session/request_permission"}):(this.pendingPermissionRequests.set(t,{created_at:Date.now(),ttl:this.requestTtl,toolCall:o,options:i}),this.logger.info(`Received permission request for tool '${o.title||"unknown"}', waiting for user response (pending: ${this.pendingPermissionRequests.size}/${this.maxPendingRequests})`),{type:V.PERMISSION_REQUEST,requestId:t,sessionId:n,toolCall:o,options:i,needsUserResponse:!0}):(this.logger.error("Permission request without request_id - cannot track response"),{type:"error",code:-32600,error:"Permission request without request_id - cannot track response",method:"session/request_permission"})}async handlePushToolCall(e){const{id:t,params:s}=e,o=`tool_${this.nextRequestId()}`,i={id:o};return void 0!==t&&await this.sendResult(t,i),{type:"tool_call",id:o,params:s}}async handleUpdateToolCall(e){const{id:t,params:s}=e;return void 0!==t&&await this.sendResult(t,null),{type:"tool_update",params:s}}async handleNotifyTaskFinish(e){const{id:t,params:s}=e;return void 0!==t&&await this.sendResult(t,null),{type:"task_finish",params:s}}async handleAskUserQuestions(e){const{id:t,params:s}=e;return this.logger.info(`ask_user_questions request with ${s?.questions?.length||0} questions`),{type:"ask_user_questions",requestId:t,params:s}}async handleExitPlanMode(e){const{id:t,params:s}=e;return this.logger.info(`exit_plan_mode request with plan: ${s?.plan?.substring(0,50)}...`),{type:"exit_plan_mode",requestId:t,params:s}}async handleUnknownMessage(e){const{id:t,method:s,params:o}=e;return this.logger.warn(`Unknown method: ${s}`),void 0!==t&&await this.sendError(t,-32601,"Method not found"),{type:"unknown",method:s,params:o}}}class ne{constructor(e){this.ws=null,this.connected=!1,this.messageQueue=[],this.waitingResolvers=new Map,this.generalWaiters=[],this.url=e.url,this.logger=e.logger||ee,this.timeout=e.timeout||3e5}get isConnected(){return!!this.ws&&this.connected}checkConnected(){if(!this.isConnected)throw new j("Not connected")}async connect(){if(this.connected)this.logger.warn(`Already connected to ${this.url}`);else try{this.logger.info(`Connecting to ${this.url}`),this.ws=await new Promise((e,t)=>{const o=new s(this.url),i=setTimeout(()=>{o.close(),t(new L(`Connected to ${this.url} timeout after ${this.timeout/1e3}s`))},this.timeout);o.on("open",()=>{clearTimeout(i),this.connected=!0,this.logger.info(`Connected to ${this.url} successfully`),e(o)}),o.on("error",e=>{clearTimeout(i),this.connected=!1,t(e)}),o.on("close",(e,s)=>{clearTimeout(i),this.connected=!1,t(new Error(`${s} (code: ${e})`))})}),this.setupMessageListener()}catch(e){if(e instanceof L)throw e;throw new j(`Failed to connect to ${this.url}: ${Y(e)}`)}}setupMessageListener(){this.ws&&(this.ws.on("message",e=>{const t=e.toString("utf8");let s;this.logger.debug(`Received message: ${t}`);try{const e=JSON.parse(t);!e||"number"!=typeof e.id&&"string"!=typeof e.id||(s=e.id)}catch(e){}if(void 0!==s&&this.waitingResolvers.has(s)){const e=this.waitingResolvers.get(s);return this.waitingResolvers.delete(s),void e.resolve(t)}if(this.generalWaiters.length>0){return void this.generalWaiters.shift().resolve(t)}this.messageQueue.push(t)}),this.ws.on("error",e=>{this.connected=!1,this.rejectAllWaiters(e)}),this.ws.on("close",()=>{this.connected=!1,this.rejectAllWaiters(new j("Connection closed",{isClosed:!0})),this.logger.info("Connection closed")}))}rejectAllWaiters(e){for(const[t,s]of this.waitingResolvers.entries())s.reject(e);for(this.waitingResolvers.clear();this.generalWaiters.length>0;){const t=this.generalWaiters.shift();t&&t.reject(e)}}async close(){if(this.ws&&this.connected)try{this.ws.removeAllListeners(),this.ws.close(),this.logger.info("Connection closed")}catch(e){this.logger.warn(`Error closing connection: ${Y(e)}`)}this.ws=null,this.connected=!1,this.messageQueue=[],this.rejectAllWaiters(new j("Connection closed by client",{clientInitiated:!0}))}async send(e){this.checkConnected();try{const t="string"==typeof e?e:JSON.stringify(e);await new Promise((e,s)=>{this.ws.send(t,o=>{o?s(o):(this.logger.debug(`Sent message: ${t}`),e())})})}catch(e){throw this.connected=!1,new G(`Failed to send message: ${Y(e)}`)}}async waitForResponse(e){return this.checkConnected(),this.receiveRawData(e)}async*receive(){for(this.checkConnected();this.isConnected;)try{const e=await this.receiveRawData();yield e}catch(e){if(this.connected=!1,e instanceof j&&(e.details.isClosed||e.details.clientInitiated)){e.details.clientInitiated?this.logger.debug("Connection closed by client"):this.logger.info("Connection closed");break}throw new G(`Failed to receive message: ${Y(e)}`)}}receiveRawData(e){return new Promise((t,s)=>{if(!this.isConnected)return void s(new j("Not connected"));if(void 0!==e)return void this.waitingResolvers.set(e,{resolve:t,reject:s});const o=this.messageQueue.shift();void 0===o?this.generalWaiters.push({resolve:t,reject:s}):t(o)})}}class re{constructor(e){this.connected=!1,this.readlineInterface=null,this.errorHandler=null,this.exitHandler=null,this.messageQueue=[],this.waitingResolvers=new Map,this.generalWaiters=[],this.childProcess=e.process,this.logger=e.logger||ee,this.timeout=e.timeout||3e5,this.maxQueueSize=e.maxQueueSize||1e3}get isConnected(){return this.connected&&!!this.childProcess&&!this.childProcess.killed}checkConnected(){if(!this.isConnected)throw new j("Not connected")}async connect(){if(this.connected)this.logger.warn("Already connected to stdio process");else try{if(this.logger.info("Connecting to stdio process"),!this.childProcess||!this.childProcess.stdout||!this.childProcess.stdin)throw new j("Invalid process: stdin/stdout not available");await new Promise((e,t)=>{const s=setTimeout(()=>{this.childProcess.off("error",o),this.childProcess.off("exit",i),this.childProcess.off("spawn",n),t(new L(`Connection to stdio process timeout after ${this.timeout/1e3}s`))},this.timeout),o=e=>{clearTimeout(s),this.childProcess.off("error",o),this.childProcess.off("exit",i),this.childProcess.off("spawn",n),t(e)},i=e=>{clearTimeout(s),this.childProcess.off("error",o),this.childProcess.off("exit",i),this.childProcess.off("spawn",n),t(new Error(`Process exited with code ${e}`))},n=()=>{clearTimeout(s),this.childProcess.off("error",o),this.childProcess.off("exit",i),this.childProcess.off("spawn",n),this.connected=!0,this.logger.info("Connected to stdio process successfully"),e()};this.childProcess.once("error",o),this.childProcess.once("exit",i),void 0!==this.childProcess.pid?n():this.childProcess.once("spawn",n)}),this.setupMessageListener()}catch(e){if(e instanceof L)throw e;throw new j(`Failed to connect to stdio process: ${Y(e)}`)}}setupMessageListener(){this.childProcess.stdout&&(this.readlineInterface=A.createInterface({input:this.childProcess.stdout,crlfDelay:1/0}),this.readlineInterface.on("line",e=>{const t=e.trim();if(!t)return;let s;this.logger.debug(`Received message: ${t}`);try{const e=JSON.parse(t);!e||"number"!=typeof e.id&&"string"!=typeof e.id||(s=e.id)}catch(e){}if(void 0!==s&&this.waitingResolvers.has(s)){const e=this.waitingResolvers.get(s);return this.waitingResolvers.delete(s),void e.resolve(t)}if(this.generalWaiters.length>0){return void this.generalWaiters.shift().resolve(t)}this.messageQueue.length>=this.maxQueueSize&&(this.logger.warn(`Message queue full (${this.maxQueueSize}), dropping oldest message`),this.messageQueue.shift()),this.messageQueue.push(t)}),this.readlineInterface.on("error",e=>{this.connected=!1,this.rejectAllWaiters(e)}),this.readlineInterface.on("close",()=>{this.connected=!1,this.rejectAllWaiters(new j("Connection closed",{isClosed:!0})),this.logger.info("Connection closed")}),this.errorHandler=e=>{this.connected=!1,this.rejectAllWaiters(e)},this.exitHandler=e=>{this.connected=!1,this.rejectAllWaiters(new j(`Process exited with code ${e}`,{isClosed:!0})),this.logger.info(`Process exited with code ${e}`)},this.childProcess.on("error",this.errorHandler),this.childProcess.on("exit",this.exitHandler))}rejectAllWaiters(e){for(const[t,s]of this.waitingResolvers.entries())s.reject(e);for(this.waitingResolvers.clear();this.generalWaiters.length>0;){const t=this.generalWaiters.shift();t&&t.reject(e)}}async close(){if(this.connected)try{this.errorHandler&&(this.childProcess.off("error",this.errorHandler),this.errorHandler=null),this.exitHandler&&(this.childProcess.off("exit",this.exitHandler),this.exitHandler=null),this.readlineInterface&&(this.readlineInterface.close(),this.readlineInterface=null),this.childProcess.stdin&&this.childProcess.stdin.end(),this.logger.info("Connection closed")}catch(e){this.logger.warn(`Error closing connection: ${Y(e)}`)}this.connected=!1,this.messageQueue=[],this.rejectAllWaiters(new j("Connection closed by client",{clientInitiated:!0}))}async send(e){if(this.checkConnected(),!this.childProcess.stdin)throw new G("stdin not available");try{const t="string"==typeof e?e:JSON.stringify(e);await new Promise((e,s)=>{this.childProcess.stdin.write(t+"\n",o=>{o?s(o):(this.logger.debug(`Sent message: ${t}`),e())})})}catch(e){throw this.connected=!1,new G(`Failed to send message: ${Y(e)}`)}}async waitForResponse(e){return this.checkConnected(),this.receiveRawData(e)}async*receive(){for(this.checkConnected();this.isConnected;)try{const e=await this.receiveRawData();yield e}catch(e){if(this.connected=!1,e instanceof j&&(e.details.isClosed||e.details.clientInitiated)){e.details.clientInitiated?this.logger.debug("Connection closed by client"):this.logger.info("Connection closed");break}throw new G(`Failed to receive message: ${Y(e)}`)}}receiveRawData(e){return new Promise((t,s)=>{if(!this.isConnected)return void s(new j("Not connected"));if(void 0!==e)return void this.waitingResolvers.set(e,{resolve:t,reject:s});const o=this.messageQueue.shift();void 0===o?this.generalWaiters.push({resolve:t,reject:s}):t(o)})}}class ae{constructor(e={}){this.cwd=e.cwd||process.cwd(),this.logger=e.logger||ee,this.readOnly=e.readOnly||!1,this.maxFileSize=e.maxFileSize||10485760,e.allowedDirs?this.allowedDirs=new Set(e.allowedDirs.map(e=>R.resolve(this.cwd,e))):this.allowedDirs=new Set([this.cwd]),this.logger.info(`File handler initialized with ${this.allowedDirs.size} allowed directories`);for(const e of this.allowedDirs)this.logger.debug(` Allowed: ${e}`)}isPathAllowed(e){try{const t=R.resolve(this.cwd,e);for(const e of this.allowedDirs)if(t.startsWith(e))return!0;return this.logger.warn(`Path not in allowed directories: ${t}`),!1}catch(e){return e instanceof Error&&this.logger.error(`Error checking path: ${e.message}`,e),!1}}async readFile(e,t,s){if(!this.isPathAllowed(e))throw new H(`Access denied: ${e}`);const o=R.resolve(this.cwd,e);try{if(!C.existsSync(o))throw new W(`File not found: ${e}`);try{await $.access(o,C.constants.R_OK)}catch{throw new H(`Permission denied: ${e}`)}const i=await $.stat(o);if(!i.isFile())throw new W(`Not a file: ${e}`);if(i.size>this.maxFileSize)throw new W(`File too large: ${i.size} bytes (max: ${this.maxFileSize})`);const n=await $.readFile(o,"utf-8");if(void 0!==t||void 0!==s){const o=n.split("\n"),i=t?t-1:0,r=s?i+s:o.length,a=Math.max(0,i),c=Math.min(o.length,r);return this.logger.debug(`Read ${c-a} lines from ${e}`),o.slice(a,c).join("\n")}return this.logger.debug(`Read ${n.length} bytes from ${e}`),n}catch(e){if(e instanceof W||e instanceof H)throw e;throw new W(`Failed to read file: ${Y(e)}`)}}async writeFile(e,t){if(this.readOnly)throw new H("File system is in read-only mode");if(!this.isPathAllowed(e))throw new H(`Access denied: ${e}`);const s=R.resolve(this.cwd,e);try{await $.mkdir(R.dirname(s),{recursive:!0}),await $.writeFile(s,t,"utf-8"),this.logger.debug(`Wrote ${t.length} bytes to ${e}`)}catch(e){throw new W(`Failed to write file: ${Y(e)}`)}}async addAllowedDir(e){const t=R.resolve(this.cwd,e);try{if(!C.existsSync(t))throw new W(`Directory does not exist: ${t}`);if(!(await $.stat(t)).isDirectory())throw new W(`Not a directory: ${t}`);this.allowedDirs.add(t),this.logger.info(`Added allowed directory: ${t}`)}catch(e){if(e instanceof W)throw e;throw new W(`Failed to add ${t} as allowed directory: ${Y(e)}`)}}removeAllowedDir(e){const t=R.resolve(this.cwd,e);this.allowedDirs.delete(t),this.logger.info(`Removed allowed directory: ${t}`)}}var ce="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function le(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var de,he,ue,pe,fe,ge,me,we,ye={exports:{}},Se={exports:{}};function xe(){if(he)return de;he=1,de=o,o.sync=function(e,o){return s(t.statSync(e),e,o)};var t=e;function s(e,t,s){return!(!e.isSymbolicLink()&&!e.isFile())&&function(e,t){var s=void 0!==t.pathExt?t.pathExt:process.env.PATHEXT;if(!s)return!0;if(-1!==(s=s.split(";")).indexOf(""))return!0;for(var o=0;o<s.length;o++){var i=s[o].toLowerCase();if(i&&e.substr(-i.length).toLowerCase()===i)return!0}return!1}(t,s)}function o(e,o,i){t.stat(e,function(t,n){i(t,!t&&s(n,e,o))})}return de}function Ie(){if(pe)return ue;pe=1,ue=s,s.sync=function(e,s){return o(t.statSync(e),s)};var t=e;function s(e,s,i){t.stat(e,function(e,t){i(e,!e&&o(t,s))})}function o(e,t){return e.isFile()&&function(e,t){var s=e.mode,o=e.uid,i=e.gid,n=void 0!==t.uid?t.uid:process.getuid&&process.getuid(),r=void 0!==t.gid?t.gid:process.getgid&&process.getgid(),a=parseInt("100",8),c=parseInt("010",8),l=parseInt("001",8),d=a|c;return s&l||s&c&&i===r||s&a&&o===n||s&d&&0===n}(e,t)}return ue}function Ee(){if(we)return me;we=1;const e="win32"===process.platform||"cygwin"===process.env.OSTYPE||"msys"===process.env.OSTYPE,s=t,o=e?";":":",i=function(){if(ge)return fe;var e;function t(s,o,i){if("function"==typeof o&&(i=o,o={}),!i){if("function"!=typeof Promise)throw new TypeError("callback not provided");return new Promise(function(e,i){t(s,o||{},function(t,s){t?i(t):e(s)})})}e(s,o||{},function(e,t){e&&("EACCES"===e.code||o&&o.ignoreErrors)&&(e=null,t=!1),i(e,t)})}return ge=1,e="win32"===process.platform||ce.TESTING_WINDOWS?xe():Ie(),fe=t,t.sync=function(t,s){try{return e.sync(t,s||{})}catch(e){if(s&&s.ignoreErrors||"EACCES"===e.code)return!1;throw e}},fe}(),n=e=>Object.assign(new Error(`not found: ${e}`),{code:"ENOENT"}),r=(t,s)=>{const i=s.colon||o,n=t.match(/\//)||e&&t.match(/\\/)?[""]:[...e?[process.cwd()]:[],...(s.path||process.env.PATH||"").split(i)],r=e?s.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",a=e?r.split(i):[""];return e&&-1!==t.indexOf(".")&&""!==a[0]&&a.unshift(""),{pathEnv:n,pathExt:a,pathExtExe:r}},a=(e,t,o)=>{"function"==typeof t&&(o=t,t={}),t||(t={});const{pathEnv:a,pathExt:c,pathExtExe:l}=r(e,t),d=[],h=o=>new Promise((i,r)=>{if(o===a.length)return t.all&&d.length?i(d):r(n(e));const c=a[o],l=/^".*"$/.test(c)?c.slice(1,-1):c,h=s.join(l,e),p=!l&&/^\.[\\\/]/.test(e)?e.slice(0,2)+h:h;i(u(p,o,0))}),u=(e,s,o)=>new Promise((n,r)=>{if(o===c.length)return n(h(s+1));const a=c[o];i(e+a,{pathExt:l},(i,r)=>{if(!i&&r){if(!t.all)return n(e+a);d.push(e+a)}return n(u(e,s,o+1))})});return o?h(0).then(e=>o(null,e),o):h(0)};return me=a,a.sync=(e,t)=>{t=t||{};const{pathEnv:o,pathExt:a,pathExtExe:c}=r(e,t),l=[];for(let n=0;n<o.length;n++){const r=o[n],d=/^".*"$/.test(r)?r.slice(1,-1):r,h=s.join(d,e),u=!d&&/^\.[\\\/]/.test(e)?e.slice(0,2)+h:h;for(let e=0;e<a.length;e++){const s=u+a[e];try{if(i.sync(s,{pathExt:c})){if(!t.all)return s;l.push(s)}}catch(e){}}}if(t.all&&l.length)return l;if(t.nothrow)return null;throw n(e)},me}var Te,ve,Pe,be={exports:{}};function _e(){if(Te)return be.exports;Te=1;const e=(e={})=>{const t=e.env||process.env;return"win32"!==(e.platform||process.platform)?"PATH":Object.keys(t).reverse().find(e=>"PATH"===e.toUpperCase())||"Path"};return be.exports=e,be.exports.default=e,be.exports}var Ce,Re,Ae,$e,Oe,Me,Ne,ke,Le,Fe,qe,Ue,De,je,Ge={};function He(){return Ae?Re:(Ae=1,Re=/^#!(.*)/)}function We(){if(Oe)return $e;Oe=1;const e=He();return $e=(t="")=>{const s=t.match(e);if(!s)return null;const[o,i]=s[0].replace(/#! ?/,"").split(" "),n=o.split("/").pop();return"env"===n?i:i?`${n} ${i}`:n},$e}function Qe(){if(Le)return ke;Le=1;const s=t,o=function(){if(Pe)return ve;Pe=1;const e=t,s=Ee(),o=_e();function i(t,i){const n=t.options.env||process.env,r=process.cwd(),a=null!=t.options.cwd,c=a&&void 0!==process.chdir&&!process.chdir.disabled;if(c)try{process.chdir(t.options.cwd)}catch(e){}let l;try{l=s.sync(t.command,{path:n[o({env:n})],pathExt:i?e.delimiter:void 0})}catch(e){}finally{c&&process.chdir(r)}return l&&(l=e.resolve(a?t.options.cwd:"",l)),l}return ve=function(e){return i(e)||i(e,!0)}}(),i=function(){if(Ce)return Ge;Ce=1;const e=/([()\][%!^"`<>&|;, *?])/g;return Ge.command=function(t){return t.replace(e,"^$1")},Ge.argument=function(t,s){return t=(t=`"${t=(t=(t=`${t}`).replace(/(?=(\\+?)?)\1"/g,'$1$1\\"')).replace(/(?=(\\+?)?)\1$/,"$1$1")}"`).replace(e,"^$1"),s&&(t=t.replace(e,"^$1")),t},Ge}(),n=function(){if(Ne)return Me;Ne=1;const t=e,s=We();return Me=function(e){const o=Buffer.alloc(150);let i;try{i=t.openSync(e,"r"),t.readSync(i,o,0,150,0),t.closeSync(i)}catch(e){}return s(o.toString())},Me}(),r="win32"===process.platform,a=/\.(?:com|exe)$/i,c=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;function l(e){if(!r)return e;const t=function(e){e.file=o(e);const t=e.file&&n(e.file);return t?(e.args.unshift(e.file),e.command=t,o(e)):e.file}(e),l=!a.test(t);if(e.options.forceShell||l){const o=c.test(t);e.command=s.normalize(e.command),e.command=i.command(e.command),e.args=e.args.map(e=>i.argument(e,o));const n=[e.command].concat(e.args).join(" ");e.args=["/d","/s","/c",`"${n}"`],e.command=process.env.comspec||"cmd.exe",e.options.windowsVerbatimArguments=!0}return e}return ke=function(e,t,s){t&&!Array.isArray(t)&&(s=t,t=null);const o={command:e,args:t=t?t.slice(0):[],options:s=Object.assign({},s),file:void 0,original:{command:e,args:t}};return s.shell?o:l(o)},ke}function Ke(){if(qe)return Fe;qe=1;const e="win32"===process.platform;function t(e,t){return Object.assign(new Error(`${t} ${e.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${t} ${e.command}`,path:e.command,spawnargs:e.args})}function s(s,o){return e&&1===s&&!o.file?t(o.original,"spawn"):null}return Fe={hookChildProcess:function(t,o){if(!e)return;const i=t.emit;t.emit=function(e,n){if("exit"===e){const e=s(n,o);if(e)return i.call(t,"error",e)}return i.apply(t,arguments)}},verifyENOENT:s,verifyENOENTSync:function(s,o){return e&&1===s&&!o.file?t(o.original,"spawnSync"):null},notFoundError:t},Fe}function Be(){if(Ue)return Se.exports;Ue=1;const e=a,t=Qe(),s=Ke();function o(o,i,n){const r=t(o,i,n),a=e.spawn(r.command,r.args,r.options);return s.hookChildProcess(a,r),a}return Se.exports=o,Se.exports.spawn=o,Se.exports.sync=function(o,i,n){const r=t(o,i,n),a=e.spawnSync(r.command,r.args,r.options);return a.error=a.error||s.verifyENOENTSync(a.status,r),a},Se.exports._parse=t,Se.exports._enoent=s,Se.exports}function ze(){return je?De:(je=1,De=e=>{const t="string"==typeof e?"\n":"\n".charCodeAt(),s="string"==typeof e?"\r":"\r".charCodeAt();return e[e.length-1]===t&&(e=e.slice(0,e.length-1)),e[e.length-1]===s&&(e=e.slice(0,e.length-1)),e})}var Xe,Je={exports:{}};function Ve(){return Xe||(Xe=1,function(e){const s=t,o=_e(),i=e=>{let t;e={cwd:process.cwd(),path:process.env[o()],execPath:process.execPath,...e};let i=s.resolve(e.cwd);const n=[];for(;t!==i;)n.push(s.join(i,"node_modules/.bin")),t=i,i=s.resolve(i,"..");const r=s.resolve(e.cwd,e.execPath,"..");return n.push(r),n.concat(e.path).join(s.delimiter)};e.exports=i,e.exports.default=i,e.exports.env=t=>{const s={...(t={env:process.env,...t}).env},i=o({env:s});return t.path=s[i],s[i]=e.exports(t),s}}(Je)),Je.exports}var Ye,Ze,et={exports:{}},tt={exports:{}};function st(){if(Ye)return tt.exports;Ye=1;const e=(e,t)=>{for(const s of Reflect.ownKeys(t))Object.defineProperty(e,s,Object.getOwnPropertyDescriptor(t,s));return e};return tt.exports=e,tt.exports.default=e,tt.exports}function ot(){if(Ze)return et.exports;Ze=1;const e=st(),t=new WeakMap,s=(s,o={})=>{if("function"!=typeof s)throw new TypeError("Expected a function");let i,n=0;const r=s.displayName||s.name||"<anonymous>",a=function(...e){if(t.set(a,++n),1===n)i=s.apply(this,e),s=null;else if(!0===o.throw)throw new Error(`Function \`${r}\` can only be called once`);return i};return e(a,s),t.set(a,n),a};return et.exports=s,et.exports.default=s,et.exports.callCount=e=>{if(!t.has(e))throw new Error(`The given function \`${e.name}\` is not wrapped by the \`onetime\` package`);return t.get(e)},et.exports}var it,nt={},rt={},at={};var ct,lt,dt,ht,ut,pt={};function ft(){if(ct)return pt;ct=1,Object.defineProperty(pt,"__esModule",{value:!0}),pt.SIGRTMAX=pt.getRealtimeSignals=void 0;pt.getRealtimeSignals=function(){const o=s-t+1;return Array.from({length:o},e)};const e=function(e,s){return{name:`SIGRT${s+1}`,number:t+s,action:"terminate",description:"Application-specific signal (realtime)",standard:"posix"}},t=34,s=64;return pt.SIGRTMAX=s,pt}function gt(){if(lt)return rt;lt=1,Object.defineProperty(rt,"__esModule",{value:!0}),rt.getSignals=void 0;var e=n,t=(it||(it=1,Object.defineProperty(at,"__esModule",{value:!0}),at.SIGNALS=void 0,at.SIGNALS=[{name:"SIGHUP",number:1,action:"terminate",description:"Terminal closed",standard:"posix"},{name:"SIGINT",number:2,action:"terminate",description:"User interruption with CTRL-C",standard:"ansi"},{name:"SIGQUIT",number:3,action:"core",description:"User interruption with CTRL-\\",standard:"posix"},{name:"SIGILL",number:4,action:"core",description:"Invalid machine instruction",standard:"ansi"},{name:"SIGTRAP",number:5,action:"core",description:"Debugger breakpoint",standard:"posix"},{name:"SIGABRT",number:6,action:"core",description:"Aborted",standard:"ansi"},{name:"SIGIOT",number:6,action:"core",description:"Aborted",standard:"bsd"},{name:"SIGBUS",number:7,action:"core",description:"Bus error due to misaligned, non-existing address or paging error",standard:"bsd"},{name:"SIGEMT",number:7,action:"terminate",description:"Command should be emulated but is not implemented",standard:"other"},{name:"SIGFPE",number:8,action:"core",description:"Floating point arithmetic error",standard:"ansi"},{name:"SIGKILL",number:9,action:"terminate",description:"Forced termination",standard:"posix",forced:!0},{name:"SIGUSR1",number:10,action:"terminate",description:"Application-specific signal",standard:"posix"},{name:"SIGSEGV",number:11,action:"core",description:"Segmentation fault",standard:"ansi"},{name:"SIGUSR2",number:12,action:"terminate",description:"Application-specific signal",standard:"posix"},{name:"SIGPIPE",number:13,action:"terminate",description:"Broken pipe or socket",standard:"posix"},{name:"SIGALRM",number:14,action:"terminate",description:"Timeout or timer",standard:"posix"},{name:"SIGTERM",number:15,action:"terminate",description:"Termination",standard:"ansi"},{name:"SIGSTKFLT",number:16,action:"terminate",description:"Stack is empty or overflowed",standard:"other"},{name:"SIGCHLD",number:17,action:"ignore",description:"Child process terminated, paused or unpaused",standard:"posix"},{name:"SIGCLD",number:17,action:"ignore",description:"Child process terminated, paused or unpaused",standard:"other"},{name:"SIGCONT",number:18,action:"unpause",description:"Unpaused",standard:"posix",forced:!0},{name:"SIGSTOP",number:19,action:"pause",description:"Paused",standard:"posix",forced:!0},{name:"SIGTSTP",number:20,action:"pause",description:'Paused using CTRL-Z or "suspend"',standard:"posix"},{name:"SIGTTIN",number:21,action:"pause",description:"Background process cannot read terminal input",standard:"posix"},{name:"SIGBREAK",number:21,action:"terminate",description:"User interruption with CTRL-BREAK",standard:"other"},{name:"SIGTTOU",number:22,action:"pause",description:"Background process cannot write to terminal output",standard:"posix"},{name:"SIGURG",number:23,action:"ignore",description:"Socket received out-of-band data",standard:"bsd"},{name:"SIGXCPU",number:24,action:"core",description:"Process timed out",standard:"bsd"},{name:"SIGXFSZ",number:25,action:"core",description:"File too big",standard:"bsd"},{name:"SIGVTALRM",number:26,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGPROF",number:27,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGWINCH",number:28,action:"ignore",description:"Terminal window size changed",standard:"bsd"},{name:"SIGIO",number:29,action:"terminate",description:"I/O is available",standard:"other"},{name:"SIGPOLL",number:29,action:"terminate",description:"Watched event",standard:"other"},{name:"SIGINFO",number:29,action:"ignore",description:"Request for process information",standard:"other"},{name:"SIGPWR",number:30,action:"terminate",description:"Device running out of power",standard:"systemv"},{name:"SIGSYS",number:31,action:"core",description:"Invalid system call",standard:"other"},{name:"SIGUNUSED",number:31,action:"terminate",description:"Invalid system call",standard:"other"}]),at),s=ft();rt.getSignals=function(){const e=(0,s.getRealtimeSignals)();return[...t.SIGNALS,...e].map(o)};const o=function({name:t,number:s,description:o,action:i,forced:n=!1,standard:r}){const{signals:{[t]:a}}=e.constants,c=void 0!==a;return{name:t,number:c?a:s,description:o,supported:c,action:i,forced:n,standard:r}};return rt}function mt(){if(ut)return ht;ut=1;const{signalsByName:e}=function(){if(dt)return nt;dt=1,Object.defineProperty(nt,"__esModule",{value:!0}),nt.signalsByNumber=nt.signalsByName=void 0;var e=n,t=gt(),s=ft();const o=function(e,{name:t,number:s,description:o,supported:i,action:n,forced:r,standard:a}){return{...e,[t]:{name:t,number:s,description:o,supported:i,action:n,forced:r,standard:a}}},i=(0,t.getSignals)().reduce(o,{});nt.signalsByName=i;const r=function(e,t){const s=a(e,t);if(void 0===s)return{};const{name:o,description:i,supported:n,action:r,forced:c,standard:l}=s;return{[e]:{name:o,number:e,description:i,supported:n,action:r,forced:c,standard:l}}},a=function(t,s){const o=s.find(({name:s})=>e.constants.signals[s]===t);return void 0!==o?o:s.find(e=>e.number===t)},c=function(){const e=(0,t.getSignals)(),o=s.SIGRTMAX+1,i=Array.from({length:o},(t,s)=>r(s,e));return Object.assign({},...i)}();return nt.signalsByNumber=c,nt}();return ht=({stdout:t,stderr:s,all:o,error:i,signal:n,exitCode:r,command:a,escapedCommand:c,timedOut:l,isCanceled:d,killed:h,parsed:{options:{timeout:u}}})=>{r=null===r?void 0:r;const p=void 0===(n=null===n?void 0:n)?void 0:e[n].description,f=(({timedOut:e,timeout:t,errorCode:s,signal:o,signalDescription:i,exitCode:n,isCanceled:r})=>e?`timed out after ${t} milliseconds`:r?"was canceled":void 0!==s?`failed with ${s}`:void 0!==o?`was killed with ${o} (${i})`:void 0!==n?`failed with exit code ${n}`:"failed")({timedOut:l,timeout:u,errorCode:i&&i.code,signal:n,signalDescription:p,exitCode:r,isCanceled:d}),g=`Command ${f}: ${a}`,m="[object Error]"===Object.prototype.toString.call(i),w=m?`${g}\n${i.message}`:g,y=[w,s,t].filter(Boolean).join("\n");return m?(i.originalMessage=i.message,i.message=y):i=new Error(y),i.shortMessage=w,i.command=a,i.escapedCommand=c,i.exitCode=r,i.signal=n,i.signalDescription=p,i.stdout=t,i.stderr=s,void 0!==o&&(i.all=o),"bufferedData"in i&&delete i.bufferedData,i.failed=!0,i.timedOut=Boolean(l),i.isCanceled=d,i.killed=h&&!l,i},ht}var wt,yt={exports:{}};function St(){if(wt)return yt.exports;wt=1;const e=["stdin","stdout","stderr"],t=t=>{if(!t)return;const{stdio:s}=t;if(void 0===s)return e.map(e=>t[e]);if((t=>e.some(e=>void 0!==t[e]))(t))throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${e.map(e=>`\`${e}\``).join(", ")}`);if("string"==typeof s)return s;if(!Array.isArray(s))throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof s}\``);const o=Math.max(s.length,e.length);return Array.from({length:o},(e,t)=>s[t])};return yt.exports=t,yt.exports.node=e=>{const s=t(e);return"ipc"===s?"ipc":void 0===s||"string"==typeof s?[s,s,s,"ipc"]:s.includes("ipc")?s:[...s,"ipc"]},yt.exports}var xt,It,Et,Tt,vt,Pt,bt={exports:{}},_t={exports:{}};function Ct(){return xt||(xt=1,(e=_t).exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"],"win32"!==process.platform&&e.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT"),"linux"===process.platform&&e.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")),_t.exports;var e}function Rt(){if(Tt)return Et;Tt=1;const e=n,t=function(){if(It)return bt.exports;It=1;var e=ce.process;const t=function(e){return e&&"object"==typeof e&&"function"==typeof e.removeListener&&"function"==typeof e.emit&&"function"==typeof e.reallyExit&&"function"==typeof e.listeners&&"function"==typeof e.kill&&"number"==typeof e.pid&&"function"==typeof e.on};if(t(e)){var s,o=c,i=Ct(),n=/^win/i.test(e.platform),r=l;"function"!=typeof r&&(r=r.EventEmitter),e.__signal_exit_emitter__?s=e.__signal_exit_emitter__:((s=e.__signal_exit_emitter__=new r).count=0,s.emitted={}),s.infinite||(s.setMaxListeners(1/0),s.infinite=!0),bt.exports=function(e,i){if(!t(ce.process))return function(){};o.equal(typeof e,"function","a callback must be provided for exit handler"),!1===u&&p();var n="exit";return i&&i.alwaysLast&&(n="afterexit"),s.on(n,e),function(){s.removeListener(n,e),0===s.listeners("exit").length&&0===s.listeners("afterexit").length&&a()}};var a=function(){u&&t(ce.process)&&(u=!1,i.forEach(function(t){try{e.removeListener(t,h[t])}catch(e){}}),e.emit=m,e.reallyExit=f,s.count-=1)};bt.exports.unload=a;var d=function(e,t,o){s.emitted[e]||(s.emitted[e]=!0,s.emit(e,t,o))},h={};i.forEach(function(o){h[o]=function(){t(ce.process)&&e.listeners(o).length===s.count&&(a(),d("exit",null,o),d("afterexit",null,o),n&&"SIGHUP"===o&&(o="SIGINT"),e.kill(e.pid,o))}}),bt.exports.signals=function(){return i};var u=!1,p=function(){!u&&t(ce.process)&&(u=!0,s.count+=1,i=i.filter(function(t){try{return e.on(t,h[t]),!0}catch(e){return!1}}),e.emit=w,e.reallyExit=g)};bt.exports.load=p;var f=e.reallyExit,g=function(s){t(ce.process)&&(e.exitCode=s||0,d("exit",e.exitCode,null),d("afterexit",e.exitCode,null),f.call(e,e.exitCode))},m=e.emit,w=function(s,o){if("exit"===s&&t(ce.process)){void 0!==o&&(e.exitCode=o);var i=m.apply(this,arguments);return d("exit",e.exitCode,null),d("afterexit",e.exitCode,null),i}return m.apply(this,arguments)}}else bt.exports=function(){return function(){}};return bt.exports}(),s=(e,t,s,i)=>{if(!o(t,s,i))return;const n=r(s),a=setTimeout(()=>{e("SIGKILL")},n);a.unref&&a.unref()},o=(e,{forceKillAfterTimeout:t},s)=>i(e)&&!1!==t&&s,i=t=>t===e.constants.signals.SIGTERM||"string"==typeof t&&"SIGTERM"===t.toUpperCase(),r=({forceKillAfterTimeout:e=!0})=>{if(!0===e)return 5e3;if(!Number.isFinite(e)||e<0)throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${e}\` (${typeof e})`);return e};return Et={spawnedKill:(e,t="SIGTERM",o={})=>{const i=e(t);return s(e,t,o,i),i},spawnedCancel:(e,t)=>{e.kill()&&(t.isCanceled=!0)},setupTimeout:(e,{timeout:t,killSignal:s="SIGTERM"},o)=>{if(0===t||void 0===t)return o;let i;const n=new Promise((o,n)=>{i=setTimeout(()=>{((e,t,s)=>{e.kill(t),s(Object.assign(new Error("Timed out"),{timedOut:!0,signal:t}))})(e,s,n)},t)}),r=o.finally(()=>{clearTimeout(i)});return Promise.race([n,r])},validateTimeout:({timeout:e})=>{if(void 0!==e&&(!Number.isFinite(e)||e<0))throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${e}\` (${typeof e})`)},setExitHandler:async(e,{cleanup:s,detached:o},i)=>{if(!s||o)return i;const n=t(()=>{e.kill()});return i.finally(()=>{n()})}}}var At,$t,Ot,Mt,Nt,kt,Lt,Ft,qt,Ut,Dt,jt,Gt={exports:{}};function Ht(){if($t)return At;$t=1;const{PassThrough:e}=h;return At=t=>{t={...t};const{array:s}=t;let{encoding:o}=t;const i="buffer"===o;let n=!1;s?n=!(o||i):o=o||"utf8",i&&(o=null);const r=new e({objectMode:n});o&&r.setEncoding(o);let a=0;const c=[];return r.on("data",e=>{c.push(e),n?a=c.length:a+=e.length}),r.getBufferedValue=()=>s?c:i?Buffer.concat(c,a):c.join(""),r.getBufferedLength=()=>a,r},At}function Wt(){if(Ot)return Gt.exports;Ot=1;const{constants:e}=d,t=h,{promisify:s}=u,o=Ht(),i=s(t.pipeline);class n extends Error{constructor(){super("maxBuffer exceeded"),this.name="MaxBufferError"}}async function r(t,s){if(!t)throw new Error("Expected a stream");s={maxBuffer:1/0,...s};const{maxBuffer:r}=s,a=o(s);return await new Promise((s,o)=>{const c=t=>{t&&a.getBufferedLength()<=e.MAX_LENGTH&&(t.bufferedData=a.getBufferedValue()),o(t)};(async()=>{try{await i(t,a),s()}catch(e){c(e)}})(),a.on("data",()=>{a.getBufferedLength()>r&&c(new n)})}),a.getBufferedValue()}return Gt.exports=r,Gt.exports.buffer=(e,t)=>r(e,{...t,encoding:"buffer"}),Gt.exports.array=(e,t)=>r(e,{...t,array:!0}),Gt.exports.MaxBufferError=n,Gt.exports}function Qt(){if(Nt)return Mt;Nt=1;const{PassThrough:e}=h;return Mt=function(){var t=[],s=new e({objectMode:!0});return s.setMaxListeners(0),s.add=o,s.isEmpty=function(){return 0==t.length},s.on("unpipe",i),Array.prototype.slice.call(arguments).forEach(o),s;function o(e){return Array.isArray(e)?(e.forEach(o),this):(t.push(e),e.once("end",i.bind(null,e)),e.once("error",s.emit.bind(s,"error")),e.pipe(s,{end:!1}),this)}function i(e){!(t=t.filter(function(t){return t!==e})).length&&s.readable&&s.end()}},Mt}function Kt(){if(Lt)return kt;Lt=1;const e=function(){if(Pt)return vt;Pt=1;const e=e=>null!==e&&"object"==typeof e&&"function"==typeof e.pipe;return e.writable=t=>e(t)&&!1!==t.writable&&"function"==typeof t._write&&"object"==typeof t._writableState,e.readable=t=>e(t)&&!1!==t.readable&&"function"==typeof t._read&&"object"==typeof t._readableState,e.duplex=t=>e.writable(t)&&e.readable(t),e.transform=t=>e.duplex(t)&&"function"==typeof t._transform,vt=e}(),t=Wt(),s=Qt(),o=async(e,t)=>{if(e){e.destroy();try{return await t}catch(e){return e.bufferedData}}},i=(e,{encoding:s,buffer:o,maxBuffer:i})=>{if(e&&o)return s?t(e,{encoding:s,maxBuffer:i}):t.buffer(e,{maxBuffer:i})};return kt={handleInput:(t,s)=>{void 0!==s&&void 0!==t.stdin&&(e(s)?s.pipe(t.stdin):t.stdin.end(s))},makeAllStream:(e,{all:t})=>{if(!t||!e.stdout&&!e.stderr)return;const o=s();return e.stdout&&o.add(e.stdout),e.stderr&&o.add(e.stderr),o},getSpawnedResult:async({stdout:e,stderr:t,all:s},{encoding:n,buffer:r,maxBuffer:a},c)=>{const l=i(e,{encoding:n,buffer:r,maxBuffer:a}),d=i(t,{encoding:n,buffer:r,maxBuffer:a}),h=i(s,{encoding:n,buffer:r,maxBuffer:2*a});try{return await Promise.all([c,l,d,h])}catch(i){return Promise.all([{error:i,signal:i.signal,timedOut:i.timedOut},o(e,l),o(t,d),o(s,h)])}},validateInputSync:({input:t})=>{if(e(t))throw new TypeError("The `input` option cannot be a stream in sync mode")}},kt}function Bt(){if(Dt)return Ut;Dt=1;const e=(e,t=[])=>Array.isArray(t)?[e,...t]:[e],t=/^[\w.-]+$/,s=/"/g,o=/ +/g;return Ut={joinCommand:(t,s)=>e(t,s).join(" "),getEscapedCommand:(o,i)=>e(o,i).map(e=>(e=>"string"!=typeof e||t.test(e)?e:`"${e.replace(s,'\\"')}"`)(e)).join(" "),parseCommand:e=>{const t=[];for(const s of e.trim().split(o)){const e=t[t.length-1];e&&e.endsWith("\\")?t[t.length-1]=`${e.slice(0,-1)} ${s}`:t.push(s)}return t}}}var zt=function(){if(jt)return ye.exports;jt=1;const e=t,s=a,o=Be(),i=ze(),n=Ve(),r=ot(),c=mt(),l=St(),{spawnedKill:d,spawnedCancel:h,setupTimeout:u,validateTimeout:p,setExitHandler:f}=Rt(),{handleInput:g,getSpawnedResult:m,makeAllStream:w,validateInputSync:y}=Kt(),{mergePromise:S,getSpawnedPromise:x}=function(){if(qt)return Ft;qt=1;const e=(async()=>{})().constructor.prototype,t=["then","catch","finally"].map(t=>[t,Reflect.getOwnPropertyDescriptor(e,t)]);return Ft={mergePromise:(e,s)=>{for(const[o,i]of t){const t="function"==typeof s?(...e)=>Reflect.apply(i.value,s(),e):i.value.bind(s);Reflect.defineProperty(e,o,{...i,value:t})}return e},getSpawnedPromise:e=>new Promise((t,s)=>{e.on("exit",(e,s)=>{t({exitCode:e,signal:s})}),e.on("error",e=>{s(e)}),e.stdin&&e.stdin.on("error",e=>{s(e)})})},Ft}(),{joinCommand:I,parseCommand:E,getEscapedCommand:T}=Bt(),v=(t,s,i={})=>{const r=o._parse(t,s,i);return t=r.command,s=r.args,(i={maxBuffer:1e8,buffer:!0,stripFinalNewline:!0,extendEnv:!0,preferLocal:!1,localDir:(i=r.options).cwd||process.cwd(),execPath:process.execPath,encoding:"utf8",reject:!0,cleanup:!0,all:!1,windowsHide:!0,...i}).env=(({env:e,extendEnv:t,preferLocal:s,localDir:o,execPath:i})=>{const r=t?{...process.env,...e}:e;return s?n.env({env:r,cwd:o,execPath:i}):r})(i),i.stdio=l(i),"win32"===process.platform&&"cmd"===e.basename(t,".exe")&&s.unshift("/q"),{file:t,args:s,options:i,parsed:r}},P=(e,t,s)=>"string"==typeof t||Buffer.isBuffer(t)?e.stripFinalNewline?i(t):t:void 0===s?void 0:"",b=(e,t,o)=>{const i=v(e,t,o),n=I(e,t),a=T(e,t);let l;p(i.options);try{l=s.spawn(i.file,i.args,i.options)}catch(e){const t=new s.ChildProcess,o=Promise.reject(c({error:e,stdout:"",stderr:"",all:"",command:n,escapedCommand:a,parsed:i,timedOut:!1,isCanceled:!1,killed:!1}));return S(t,o)}const y=x(l),E=u(l,i.options,y),b=f(l,i.options,E),_={isCanceled:!1};l.kill=d.bind(null,l.kill.bind(l)),l.cancel=h.bind(null,l,_);const C=r(async()=>{const[{error:e,exitCode:t,signal:s,timedOut:o},r,d,h]=await m(l,i.options,b),u=P(i.options,r),p=P(i.options,d),f=P(i.options,h);if(e||0!==t||null!==s){const r=c({error:e,exitCode:t,signal:s,stdout:u,stderr:p,all:f,command:n,escapedCommand:a,parsed:i,timedOut:o,isCanceled:_.isCanceled,killed:l.killed});if(!i.options.reject)return r;throw r}return{command:n,escapedCommand:a,exitCode:0,stdout:u,stderr:p,all:f,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}});return g(l,i.options.input),l.all=w(l,i.options),S(l,C)};return ye.exports=b,ye.exports.sync=(e,t,o)=>{const i=v(e,t,o),n=I(e,t),r=T(e,t);let a;y(i.options);try{a=s.spawnSync(i.file,i.args,i.options)}catch(e){throw c({error:e,stdout:"",stderr:"",all:"",command:n,escapedCommand:r,parsed:i,timedOut:!1,isCanceled:!1,killed:!1})}const l=P(i.options,a.stdout,a.error),d=P(i.options,a.stderr,a.error);if(a.error||0!==a.status||null!==a.signal){const e=c({stdout:l,stderr:d,error:a.error,signal:a.signal,exitCode:a.status,command:n,escapedCommand:r,parsed:i,timedOut:a.error&&"ETIMEDOUT"===a.error.code,isCanceled:!1,killed:null!==a.signal});if(!i.options.reject)return e;throw e}return{command:n,escapedCommand:r,exitCode:0,stdout:l,stderr:d,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}},ye.exports.command=(e,t)=>{const[s,...o]=E(e);return b(s,o,t)},ye.exports.commandSync=(e,t)=>{const[s,...o]=E(e);return b.sync(s,o,t)},ye.exports.node=(e,t,s={})=>{t&&!Array.isArray(t)&&"object"==typeof t&&(s=t,t=[]);const o=l.node(s),i=process.execArgv.filter(e=>!e.startsWith("--inspect")),{nodePath:n=process.execPath,nodeOptions:r=i}=s;return b(n,[...r,e,...Array.isArray(t)?t:[]],{...s,stdin:void 0,stdout:void 0,stderr:void 0,stdio:o,shell:!1})},ye.exports}(),Xt=le(zt);class Jt{constructor(e={}){this.port=null,this.process=null,this.iflowPath=null,this.exitHandler=null,this.isCleaningUp=!1,this.logger=e.logger||ee,this.startPort=e.startPort||8090,this.stream=e.stream||!1,this.transportMode=e.transportMode||"websocket",this.customIflowPath=e.iflowPath}get url(){if("stdio"===this.transportMode)return"stdio://";if(!this.port)throw new U("iFlow process not started");return`ws://localhost:${this.port}/acp`}get childProcess(){return this.process}isRunning(){return!!this.process&&!this.process.killed&&null===this.process.exitCode}isWindows(){return"win32"===O.platform()}which(e){try{const t=this.isWindows()?"where":"which",s=N.execSync(`${t} ${e}`,{encoding:"utf-8",windowsHide:!0});return s.trim().split("\n")[0].trim()||null}catch{return null}}fileExists(e){try{return C.existsSync(e)&&C.statSync(e).isFile()}catch{return!1}}isExecutable(e){try{return C.accessSync(e,C.constants.F_OK|C.constants.X_OK),!0}catch{return!1}}isAbsolutePath(e){return R.isAbsolute(e)}getFallbackLocations(){const e=O.homedir(),t=O.platform();if(this.isWindows())return[R.join(e,"AppData","Roaming","npm","iflow.cmd"),R.join(e,"AppData","Local","npm","iflow.cmd"),R.join(e,"AppData","Roaming","npm","iflow.exe"),R.join("C:","Program Files","nodejs","iflow.cmd"),R.join("C:","Program Files (x86)","nodejs","iflow.cmd"),R.join(e,".npm-global","iflow.cmd"),R.join(e,"node_modules",".bin","iflow.cmd")];{const s=["/usr/local/bin/iflow",R.join(e,".npm-global","bin","iflow"),R.join(e,".local","bin","iflow"),R.join(e,"node_modules",".bin","iflow"),R.join(e,".yarn","bin","iflow"),R.join(e,".config","yarn","global","node_modules",".bin","iflow"),R.join(e,".local","share","pnpm","iflow"),"/usr/bin/iflow"];return"darwin"===t&&"arm64"===O.arch()&&s.unshift("/opt/homebrew/bin/iflow"),s}}findIflowPath(){if(this.customIflowPath){if(!this.isAbsolutePath(this.customIflowPath))throw new q(`Custom iflow path must be an absolute path: ${this.customIflowPath}`);if(!this.isExecutable(this.customIflowPath)){const e=this.fileExists(this.customIflowPath);throw new q(e?`Custom iflow path is not executable: ${this.customIflowPath}`:`Custom iflow path not found: ${this.customIflowPath}`)}return this.logger.debug(`Using custom iflow path: ${this.customIflowPath}`),this.customIflowPath}let e=this.which("iflow");if(e){if(this.isWindows()&&!e.endsWith(".cmd")&&!e.endsWith(".exe")){const t=e+".cmd";this.fileExists(t)&&(e=t)}return this.logger.debug(`Found iflow at: ${e}`),e}const t=this.getFallbackLocations();for(const e of t)if(this.fileExists(e))return this.logger.debug(`Found iflow at: ${e}`),e;const s=null!==this.which("npm"),o=null!==this.which("node");let i;throw i=this.isWindows()?s||o?"iFlow CLI not found. Please install it using one of the following commands:\n\nUsing npm (recommended):\n npm install -g @iflow-ai/iflow-cli@latest\n\nUsing Yarn:\n yarn global add @iflow-ai/iflow-cli@latest\n\nUsing pnpm:\n pnpm add -g @iflow-ai/iflow-cli@latest\n\nAfter installation, please restart your terminal or command prompt.":"iFlow requires Node.js, but it is not installed on your system.\n\nPlease install Node.js first: https://nodejs.org/\n\nAfter installing Node.js, install iFlow with:\n npm install -g @iflow-ai/iflow-cli@latest":'iFlow CLI not found. Please install it using one of the following methods:\n\n🍎 Mac/Linux users (recommended installation script):\n bash -c "$(curl -fsSL https://cloud.iflow.cn/iflow-cli/install.sh)"\n\nOr using npm:\n npm install -g @iflow-ai/iflow-cli@latest\n\nOr using Yarn:\n yarn global add @iflow-ai/iflow-cli@latest\n\nOr using pnpm:\n pnpm add -g @iflow-ai/iflow-cli@latest\n\n🐧 Ubuntu/Debian users may need:\n sudo npm install -g @iflow-ai/iflow-cli@latest',new q(i)}isPortAvailable(e,t=1e3){return new Promise(s=>{const o=M.createServer(),i=setTimeout(()=>{o.close(),s(!1)},t);o.listen(e,"localhost",()=>{clearTimeout(i),o.once("close",()=>{s(!0)}),o.close()}),o.once("error",()=>{clearTimeout(i),s(!1)})})}async findAvailablePort(){for(let e=0;e<10;e++){const t=this.startPort+e;if(await this.isPortAvailable(t))return this.logger.debug(`Found available port: ${t}`),t}throw new D(`No available port found in range ${this.startPort}-${this.startPort+10-1}. Please specify a different port range or free up some ports.`)}async start(){if(this.isRunning())return this.url;this.iflowPath=this.findIflowPath();const e=[this.iflowPath,"--experimental-acp"];"websocket"===this.transportMode&&(this.port=await this.findAvailablePort(),e.push("--port",this.port.toString())),this.stream&&e.push("--stream"),this.logger.info(`Starting iFlow process: ${e.join(" ")}`);try{if(this.process=Xt(e[0],e.slice(1),{stdio:"stdio"===this.transportMode?["pipe","pipe","pipe"]:["ignore","pipe","pipe"],detached:!1,cleanup:!0,windowsHide:!0,reject:!1,encoding:"utf8",env:{...process.env,LANG:process.env.LANG||"en_US.UTF-8"}}),await this.onSpawn(),!this.isRunning()){let e="iFlow process exited immediately";throw this.process.stderr&&(e+=`: ${this.process.stderr}`),new Error(e)}return"websocket"===this.transportMode&&await this.waitForServiceReady(this.port),this.registerExitHandler(),this.logger.info(`iFlow process started on port ${this.port} (PID: ${this.process.pid})`),this.url}catch(e){throw this.port=null,this.process=null,new U(`Failed to start iFlow process: ${Y(e)}`)}}registerExitHandler(){this.exitHandler||(this.exitHandler=()=>{if(!this.isCleaningUp&&this.process&&this.isRunning()){this.isCleaningUp=!0,this.logger.debug("Parent process exiting, cleaning up child process");try{if(this.isWindows())try{N.execSync(`taskkill /F /T /PID ${this.process.pid}`,{windowsHide:!0,timeout:Jt.TASKKILL_TIMEOUT_EXIT_HANDLER,stdio:"ignore"})}catch(e){this.logger.debug(`taskkill failed: ${Y(e)}`)}else this.process.kill("SIGKILL")}catch(e){this.logger.debug(`Error during process cleanup: ${Y(e)}`)}finally{this.isCleaningUp=!1}}},process.on("exit",this.exitHandler),process.on("SIGINT",this.exitHandler),process.on("SIGTERM",this.exitHandler),this.isWindows()&&process.on("SIGBREAK",this.exitHandler))}unregisterExitHandler(){this.exitHandler&&(process.off("exit",this.exitHandler),process.off("SIGINT",this.exitHandler),process.off("SIGTERM",this.exitHandler),this.isWindows()&&process.off("SIGBREAK",this.exitHandler),this.exitHandler=null)}async stop(){if(this.process){if(this.unregisterExitHandler(),!this.isRunning())return this.port=null,void(this.process=null);this.logger.info(`Stopping iFlow process (PID: ${this.process.pid})`);try{if(this.isWindows())try{N.execSync(`taskkill /T /PID ${this.process.pid}`,{windowsHide:!0,timeout:3e3,stdio:"ignore"})}catch(e){this.logger.debug(`taskkill (graceful shutdown) failed: ${Y(e)}`)}else this.process.kill("SIGTERM");if(await Promise.race([this.process.then(()=>{},()=>{}),new Promise(e=>setTimeout(()=>e(),5e3))]),this.isRunning()){if(this.logger.warn("iFlow process did not terminate gracefully, forcing kill"),this.isWindows())try{N.execSync(`taskkill /F /T /PID ${this.process.pid}`,{windowsHide:!0,timeout:Jt.TASKKILL_TIMEOUT_STOP,stdio:"ignore"})}catch(e){this.logger.warn(`taskkill /F /T failed, process may have already exited or is inaccessible: ${Y(e)}`)}else this.process.kill("SIGKILL");await this.process.then(()=>{},()=>{})}else this.logger.info("iFlow process terminated gracefully")}catch(e){this.logger.error(`Error stopping iFlow process: ${Y(e)}`)}finally{this.port=null,this.process=null}}}async onSpawn(e=5e3){return new Promise((t,s)=>{if(!this.process)return void s(new Error("Process not initialized"));const o=setTimeout(()=>{s(new Error(`Process spawn timeout after ${e}ms`))},e);this.process.once("spawn",()=>{clearTimeout(o),t()})})}async waitForServiceReady(e){const t=15e3,s=await import("net");await new Promise(e=>setTimeout(e,1e3));const o=Date.now();let i=0;for(this.logger.info(`Waiting for service to be ready on port ${e}...`);Date.now()-o<t;){i++;try{await this.probePort(e,s);const t=Date.now()-o;return void this.logger.info(`✅ Service ready on port ${e} after ${t}ms (${i} attempts)`)}catch(s){if(!this.isConnectionError(s))throw new U(`Unexpected error while probing port ${e}: ${Y(s)}`);const n=t-(Date.now()-o);if(!(n>300))throw new U(`Service failed to start on port ${e} after 15000ms (${i} attempts).\nPossible causes:\n 1. Slow system performance (Windows typically requires more time)\n 2. Antivirus software interfering with the process\n 3. iFlow CLI dependencies missing or corrupted\n\nTroubleshooting:\n - Check iFlow CLI is installed: run 'iflow --version'\n - Review logs above for errors\n - Try manually starting: 'iflow --experimental-acp --port ${e}'`);this.logger.debug(`Port ${e} not ready, attempt ${i} failed, retrying... (${Math.round(n/1e3)}s remaining)`),await new Promise(e=>setTimeout(e,300))}}}isConnectionError(e){const t=["ECONNREFUSED","ETIMEDOUT","ECONNRESET","EHOSTUNREACH","ENETUNREACH","ENOTFOUND"];if(e?.code&&t.includes(e.code))return!0;const s=(e?.message||"").toLowerCase();return t.some(e=>s.includes(e.toLowerCase()))||s.includes("connection timeout")}async probePort(e,t){return new Promise((s,o)=>{const i=new t.Socket;let n=!1;const r=e=>{n||(n=!0,i.removeAllListeners(),i.destroy(),e?o(e):s())};i.setTimeout(1e3),i.once("connect",()=>r()),i.once("timeout",()=>r(new Error("Connection timeout"))),i.once("error",e=>r(e)),i.connect(e,"127.0.0.1")})}}Jt.TASKKILL_TIMEOUT_EXIT_HANDLER=3e3,Jt.TASKKILL_TIMEOUT_STOP=5e3;class Vt{constructor(e={}){this.protocol=null,this.transport=null,this.connected=!1,this.authenticated=!1,this.messageTask=null,this.messageQueue=[],this.pendingToolCalls=new Map,this.pendingAskUserQuestionsRequestId=null,this.pendingQuestions=[],this.pendingExitPlanModeRequestId=null,this.pendingPermissionRequests=new Map,this.url=null,this.sessionId=null,this.processManager=null,this.processStarted=!1,this.connectingPromise=null,this.modes=null,this.models=null,this.availableCommands=[],this.availableAgents=[],this.availableSkills=[],this.availableMcpServers=[],this.config={get:async e=>{switch(e){case"models":return this.models?.availableModels||[];case"model":return this.models?.currentModelId||null;case"modes":return this.modes?.availableModes||[];case"mode":return this.modes?.currentModeId||null;case"commands":return this.availableCommands;case"agents":return this.availableAgents;case"skills":return this.availableSkills;case"mcpServers":return this.availableMcpServers;default:throw new Error(`Unknown config key: ${e}`)}},set:async(e,t)=>{if(!this.connected||!this.protocol||!this.sessionId)throw new j("Not connected. Call connect() first.");switch(e){case"model":try{const e=await this.protocol.setModel({sessionId:this.sessionId,modelId:t});if(!e||!this.models){throw new Error(e?"Models not available":"No result returned from server")}this.models.currentModelId=e,this.logger.info(`Set model to: ${e}`)}catch(e){throw this.logger.error(`Failed to set model to ${t}: ${Y(e)}`),e}return;case"mode":try{const e=await this.protocol.setMode({sessionId:this.sessionId,modeId:t});if(!e||!this.modes){throw new Error(e?"Modes not available":"No result returned from server")}this.modes.currentModeId=e,this.logger.info(`Set mode to: ${e}`)}catch(e){throw this.logger.error(`Failed to set mode to ${t}: ${Y(e)}`),e}return;case"think":{const e=t;try{const t=await this.protocol.setThink({sessionId:this.sessionId,thinkEnabled:e.enabled,thinkConfig:e.config});return this.logger.info(`Set think mode: enabled=${t.currentThinkEnabled}, config=${t.currentThinkConfig||"default"}`),t}catch(e){throw this.logger.error(`Failed to set think mode: ${Y(e)}`),e}}default:throw new Error(`Cannot set config key: ${e}. Only 'model', 'mode', and 'think' are supported.`)}}},this.options={url:"ws://localhost:8090/acp",cwd:process.cwd(),timeout:3e4,logLevel:"INFO",fileMaxSize:10485760,permissionMode:exports.PermissionMode.AUTO,authMethodId:"iflow",autoStartProcess:!0,processStartPort:8090,...e},this.logger=new Z({level:this.options.logLevel})}isConnected(){return this.connected}getConnectionState(){return this.connected?"connected":this.connectingPromise?"connecting":"disconnected"}getSessionId(){return this.sessionId}async connect({skipSession:e=!1}={}){if(this.connectingPromise)return this.logger.info("Connection already in progress, waiting for it to complete"),this.connectingPromise;if(this.connected)this.logger.debug("Already connected, skipping connection attempt");else{this.connectingPromise=this._doConnect({skipSession:e});try{await this.connectingPromise}finally{this.connectingPromise=null}}}async _doConnect({skipSession:e}){try{const t=this.options.transportMode||"websocket";if(this.options.autoStartProcess)if("stdio"===t){this.logger.info("Starting iFlow process for stdio mode..."),this.processManager=new Jt({logger:this.logger,startPort:this.options.processStartPort,stream:this.options.stream,transportMode:"stdio",iflowPath:this.options.iflowPath});try{const e=await this.processManager.start();this.url=e,this.processStarted=!0,this.logger.info("Started iFlow process for stdio mode"),await new Promise(e=>setTimeout(e,1e3))}catch(e){throw e instanceof q?(this.logger.error("iFlow not installed"),e):(this.logger.error(`Failed to start iFlow process: ${Y(e)}`),new j(`Failed to start iFlow process: ${Y(e)}`))}}else if(this.options.url?.startsWith("ws://localhost:")||this.options.url?.startsWith("ws://127.0.0.1:")){const e=new ne({url:this.options.url,logger:this.logger,timeout:2e3});try{await e.connect(),await e.close(),this.url=this.options.url,this.logger.info(`iFlow already running at ${this.options.url}`)}catch{this.logger.info("iFlow not running, starting process..."),this.processManager=new Jt({logger:this.logger,startPort:this.options.processStartPort,stream:this.options.stream,transportMode:"websocket",iflowPath:this.options.iflowPath});try{const e=await this.processManager.start();this.url=e,this.processStarted=!0,this.logger.info(`Started iFlow process at ${e}`)}catch(e){throw e instanceof q?(this.logger.error("iFlow not installed"),q):(this.logger.error(`Failed to start iFlow process: ${Y(e)}`),new j(`Failed to start iFlow process: ${Y(e)}`))}}}let s=null;if(this.options.fileAccess&&(s=new ae({cwd:this.options.cwd,logger:this.logger,readOnly:this.options.fileReadOnly,maxFileSize:this.options.fileMaxSize,allowedDirs:this.options.fileAllowedDirs}),this.logger.info(`File system access enabled with ${this.options.fileReadOnly?"read-only":"read-write"} mode`)),"stdio"===t){if(!this.processManager||!this.processManager.childProcess)throw new j("stdio mode requires process to be started");this.transport=new re({process:this.processManager.childProcess,logger:this.logger,timeout:this.options.timeout})}else this.transport=new ne({url:this.url,logger:this.logger,timeout:this.options.timeout});if(this.protocol=new ie({logger:this.logger,transport:this.transport,fileHandler:s,permissionMode:this.options.permissionMode,autoApproveTypes:this.options.autoApproveTypes}),await this.transport.connect(),await this._ensureAuthenticated(),e)return this.connected=!0,void this.logger.info("Connected to iFlow (session initialization skipped)");await this._initializeSession(),this.connected=!0,this.messageTask=this.handleMessages(),this.logger.info("Connected to iFlow")}catch(e){throw await this.disconnect(),new j(`Failed to connect: ${Y(e)}`)}}async _ensureAuthenticated(){if(!this.protocol)throw new j("Protocol not initialized");const e=await this.protocol.initialize({mcpServers:this.options.mcpServers,hooks:this.options.hooks,commands:this.options.commands,agents:this.options.agents});this.authenticated=e.isAuthenticated||!1,this.authenticated||(await this.protocol.authenticate({methodId:this.options.authMethodId,methodInfo:this.options.authMethodInfo}),this.authenticated=!0)}async _createNewSession(){if(!this.protocol)throw new j("Protocol not initialized");this.logger.info("Creating new session");const e=await this.protocol.createSession({cwd:this.options.cwd||process.cwd(),mcpServers:this.options.mcpServers,hooks:this.options.hooks,commands:this.options.commands,agents:this.options.agents,settings:this.options.sessionSettings});if(!e||!e.sessionId)throw new j("Failed to create session: invalid session result");return this.sessionId=e.sessionId,e.modes&&(this.modes=e.modes),e._meta?.models&&(this.models=e._meta.models),e._meta?.availableCommands&&(this.availableCommands=e._meta.availableCommands),e._meta?.availableAgents&&(this.availableAgents=e._meta.availableAgents),e._meta?.availableSkills&&(this.availableSkills=e._meta.availableSkills),e._meta?.availableMcpServers&&(this.availableMcpServers=e._meta.availableMcpServers),this.messageTask||(this.messageTask=this.handleMessages()),this.logger.info(`Created new session: ${this.sessionId}`),this.sessionId}async _initializeSession(){if(!this.protocol)throw new j("Protocol not initialized");if(this.options.sessionId)return this.logger.info(`Loading existing session: ${this.options.sessionId}`),await this.protocol.loadSession({sessionId:this.options.sessionId,mcpServers:this.options.mcpServers}),void(this.sessionId=this.options.sessionId);await this._createNewSession()}async loadSession(e){if(!this.connected||!this.protocol)throw new j("Not connected. Call connect() first.");await this.protocol.loadSession({sessionId:e,cwd:this.options.cwd||process.cwd(),mcpServers:this.options.mcpServers}),this.sessionId=e,this.logger.info(`Loaded session: ${e}`)}async newSession(){if(!this.connected||!this.protocol)throw new j("Not connected. Call connect() first.");return await this._createNewSession()}async disconnect(){this.connected=!1,this.transport&&await this.transport.close(),this.processManager&&this.processStarted&&await this.processManager.stop(),this.url=null,this.protocol=null,this.transport=null,this.messageTask=null,this.authenticated=!1,this.processManager=null,this.processStarted=!1,this.logger.info("Disconnected from iFlow")}async sendMessage(e,t){if(!this.connected||!this.protocol||!this.sessionId)throw new j("Not connected. Call connect() first.");const s=[{type:"text",text:e}];if(t?.length)for(const e of t)if("object"!=typeof e||"image"!==e.type){if("object"==typeof e&&"selection"===e.type){const t={activeFile:{path:e.uri,cursor:{line:e.line?.start||0,character:0},selectedText:e.data}},o=`Here is the user's editor context as a JSON object. This is for your information only.\n\`\`\`json\n${JSON.stringify(t,null,2)}\n\`\`\``;s.push({type:"text",text:o}),this.logger.debug("Added selection context");continue}if("string"==typeof e){const t=R.resolve(this.options.cwd||process.cwd(),e),o=R.parse(e);if(!C.existsSync(t)){this.logger.warn(`File not found, skipping: ${t}`);continue}const i=o.ext.toLowerCase();if([".png",".jpg",".jpeg",".gif",".bmp",".webp",".svg"].includes(i))try{const e=C.readFileSync(t).toString("base64"),n={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".bmp":"image/bmp",".webp":"image/webp",".svg":"image/svg+xml"};s.push({type:"image",data:e,mimeType:n[i]||"image/unknown"}),this.logger.debug(`Added image file: ${o.base}`)}catch(e){this.logger.error(`Failed to read image file ${t}: ${Y(e)}`);continue}else if([".mp3",".wav",".m4a",".ogg",".flac"].includes(i))try{const e=C.readFileSync(t).toString("base64"),n={".mp3":"audio/mpeg",".wav":"audio/wav",".m4a":"audio/mp4",".ogg":"audio/ogg",".flac":"audio/flac"};s.push({type:"audio",data:e,mimeType:n[i]||"audio/unknown"}),this.logger.debug(`Added audio file: ${o.base}`)}catch(e){this.logger.error(`Failed to read audio file ${t}: ${Y(e)}`);continue}else{const e=C.statSync(t);s.push({type:"resource_link",uri:`file://${t}`,name:o.base,title:o.name,size:e.size}),this.logger.debug(`Added resource link: ${o.base}`)}}}else s.push({type:"image",data:e.data,mimeType:e.mimeType}),this.logger.debug("Added image data");await this.protocol.sendPrompt({sessionId:this.sessionId,prompt:s})}async interrupt(){if(!this.connected||!this.protocol||!this.sessionId)throw new j("Not connected");await this.protocol.cancelSession({sessionId:this.sessionId}),this.logger.info("Sent interrupt signal")}async*receiveMessages(){if(!this.connected)throw new j("Not connected");for(;this.connected;)try{this.messageQueue.length>0?yield this.messageQueue.shift():await new Promise(e=>setTimeout(e,100))}catch{continue}}async approveToolCall(e,t=exports.ToolCallConfirmationOutcome.ALLOW){if(!this.pendingToolCalls.has(e))throw new Error(`Unknown tool call: ${e}`);this.logger.info(`Approved tool call ${e} with outcome ${t}`),this.pendingToolCalls.delete(e)}async rejectToolCall(e){if(!this.pendingToolCalls.has(e))throw new Error(`Unknown tool call: ${e}`);this.logger.info(`Rejected tool call ${e}`),this.pendingToolCalls.delete(e)}async respondToAskUserQuestions(e){if(!this.connected||!this.protocol)throw new j("Not connected");if(null===this.pendingAskUserQuestionsRequestId)throw new Error("No pending ask_user_questions request");for(const t of this.pendingQuestions){const s=e[t.header];if(void 0===s)throw new W(`Missing answer for question: ${t.header}`);if(t.multiSelect){if(!Array.isArray(s))throw new W(`Question "${t.header}" requires multiple selections (array)`);const e=t.options?.map(e=>e.label)||[];for(const o of s)if(!e.includes(o))throw new W(`Invalid option "${o}" for question "${t.header}"`)}else{if(Array.isArray(s))throw new W(`Question "${t.header}" requires single selection (string)`);if(!(t.options?.map(e=>e.label)||[]).includes(s))throw new W(`Invalid option "${s}" for question "${t.header}"`)}}await this.protocol.respondToAskUserQuestions(this.pendingAskUserQuestionsRequestId,e),this.pendingAskUserQuestionsRequestId=null,this.pendingQuestions=[],this.logger.info("Sent ask_user_questions response")}async respondToExitPlanMode(e){if(!this.connected||!this.protocol)throw new j("Not connected");if(null===this.pendingExitPlanModeRequestId)throw new Error("No pending exit_plan_mode request");await this.protocol.respondToExitPlanMode(this.pendingExitPlanModeRequestId,e),this.pendingExitPlanModeRequestId=null,this.logger.info("Sent exit_plan_mode response: "+(e?"approved":"rejected"))}async respondToToolConfirmation(e,t){if(!this.connected||!this.protocol)throw new j("Not connected");if(!this.pendingPermissionRequests.has(e))throw new Error(`No pending permission request with ID: ${e}`);await this.protocol.sendPermissionResponse(e,t),this.pendingPermissionRequests.delete(e),this.logger.info(`Sent tool confirmation response for request ${e}: ${t}`)}async cancelToolConfirmation(e){if(!this.connected||!this.protocol)throw new j("Not connected");if(!this.pendingPermissionRequests.has(e))throw new Error(`No pending permission request with ID: ${e}`);await this.protocol.cancelPermissionResponse(e),this.pendingPermissionRequests.delete(e),this.logger.info(`Cancelled tool confirmation request: ${e}`)}async handleMessages(){if(this.protocol)try{for await(const e of this.protocol.handleMessages()){const t=this.processProtocolMessage(e);t&&this.messageQueue.push(t)}}catch(e){if(e instanceof j&&e.details.clientInitiated)this.logger.debug("Message handler stopped: connection closed by client");else{const t=Y(e);this.logger.error(`Error in message handler: ${t}`);const s={type:exports.MessageType.ERROR,code:-1,message:String(t)};this.messageQueue.push(s)}}}processProtocolMessage(e){switch(e.type){case V.SESSION_UPDATE:{const{updateData:t}=e;let s,o;switch("agentId"in t&&t.agentId&&(s=t.agentId,o=function(e){const t=e.split("-");return"subagent"!==t[0]||t.length<4?{agentId:e}:4===t.length?{agentId:e,taskId:["null","undefined"].includes(t[1])?void 0:t[1],agentIndex:parseInt(t[2])||void 0,timestamp:parseInt(t[3])||void 0}:{agentId:e,taskId:t.slice(1,-2).join("-"),agentIndex:parseInt(t[t.length-2])||void 0,timestamp:parseInt(t[t.length-1])||void 0}}(s)),t.sessionUpdate){case J.PLAN:{const e=t.entries?.map(e=>({content:e.content||"",status:e.status||exports.PlanStatus.PENDING,priority:e.priority||exports.PlanPriority.MEDIUM}));return e&&e?.length>0?{type:exports.MessageType.PLAN,entries:e}:null}case J.TOOL_CALL:{const e={type:exports.MessageType.TOOL_CALL,id:t.toolCallId||"",label:t.title||"Tool",icon:{type:exports.ToolCallIconType.EMOJI,value:"🔧"},status:t.status||exports.ToolCallStatus.IN_PROGRESS,toolName:t.toolName,args:t.args};return s&&(e.agentId=s,e.agentInfo=o),this.pendingToolCalls.set(e.id,e),{...e}}case J.TOOL_CALL_UPDATE:{const e=t.toolCallId;let i;if(this.pendingToolCalls.has(e)?(i=this.pendingToolCalls.get(e),i.status=t.status||exports.ToolCallStatus.COMPLETED,i.args=t.args,t.toolName&&(i.toolName=t.toolName),!i.agentId&&s&&(i.agentId=s),!i.agentInfo&&o&&(i.agentInfo=o)):(i={type:exports.MessageType.TOOL_CALL,id:e,label:t.title||"Tool",icon:{type:exports.ToolCallIconType.EMOJI,value:"🔧"},status:t.status||exports.ToolCallStatus.COMPLETED,toolName:t.toolName,args:t.args},s&&(i.agentId=s,i.agentInfo=o),this.pendingToolCalls.set(e,i)),t.content&&t.content?.length>0){let e;const s=[];for(const o of t.content)"args"in o&&(e=o.args),"content"===o.type&&"text"===o.content?.type&&s.push(o.content.text||"");void 0!==e&&void 0===i.args&&(i.args=e),s.length>0&&(i.output=s.join("\n"))}return{...i}}case J.USER_MESSAGE_CHUNK:{const e=t.content;if("text"===e?.type){const t=e.text||"";if(t)return{type:exports.MessageType.USER,chunks:[{text:t}]}}return null}case J.AGENT_MESSAGE_CHUNK:{const e=t.content;if("text"===e?.type){const t=e.text||"";if(t){const e={type:exports.MessageType.ASSISTANT,chunk:{text:t}};return s&&(e.agentId=s,e.agentInfo=o),e}}return null}case J.AGENT_THOUGHT_CHUNK:{const e=t.content;if("text"===e?.type){const t=e.text||"";if(t){const e={type:exports.MessageType.ASSISTANT,chunk:{thought:t}};return s&&(e.agentId=s,e.agentInfo=o),e}}}default:return null}}case V.RESPONSE:{const t=e.result;return t&&"object"==typeof t&&"stopReason"in t?{type:exports.MessageType.TASK_FINISH,stopReason:t.stopReason}:null}case V.ERROR:return{type:exports.MessageType.ERROR,code:e.code||-1,message:e.error||"Unknown error"};case V.ASK_USER_QUESTIONS:{const t=e,{questions:s}=t.params||{};return null!==this.pendingAskUserQuestionsRequestId?(this.logger.warn("Another ask_user_questions request is already pending, ignoring new request"),null):(this.pendingAskUserQuestionsRequestId=t.requestId,this.pendingQuestions=s||[],{type:exports.MessageType.ASK_USER_QUESTIONS,questions:s||[]})}case V.EXIT_PLAN_MODE:{const t=e,{plan:s}=t.params||{};return null!==this.pendingExitPlanModeRequestId?(this.logger.warn("Another exit_plan_mode request is already pending, ignoring new request"),null):(this.pendingExitPlanModeRequestId=t.requestId,{type:exports.MessageType.EXIT_PLAN_MODE,plan:s||""})}case"permission_request":{const t=e,{requestId:s,sessionId:o,toolCall:i,options:n}=t;return this.pendingPermissionRequests.has(s)?(this.logger.warn(`Permission request ${s} is already pending, ignoring new request`),null):(this.pendingPermissionRequests.set(s,{toolCall:i,options:n,sessionId:o}),{type:exports.MessageType.PERMISSION_REQUEST,requestId:s,sessionId:o,toolCall:i,options:n})}default:return null}}}function Yt(e){let t,s=!1,o="text";if(e.startsWith("//"))s=!0,o="control";else try{t=JSON.parse(e),t&&"method"in t?o=`method:${t.method}`:t&&("result"in t||"error"in t)?o="response":t&&"type"in t&&(o=t.type)}catch{}return{isControl:s,messageType:o,rawData:e,jsonData:t,timestamp:Date.now()}}exports.AuthenticationError=K,exports.ConnectionError=j,exports.IFlowClient=Vt,exports.IFlowError=k,exports.IFlowNotInstalledError=q,exports.IFlowProcessError=U,exports.JSONDecodeError=F,exports.PermissionError=H,exports.PortNotAvailableError=D,exports.ProtocolError=Q,exports.RawDataClient=class extends Vt{constructor(e,t=!0){super(e),this.rawQueue=[],this.rawHistory=[],this.rawQueueResolvers=[],this.messageQueueResolvers=[],this.captureRaw=t}async handleMessages(){if(this.protocol)try{if(this.captureRaw&&this.transport){const e=this.captureRawStream(),t=this.handleParsedStream();await Promise.all([e,t])}else await super.handleMessages()}catch(e){e instanceof j&&e.details.clientInitiated?this.logger.debug("Message handler stopped: connection closed by client"):this.logger.error(`Error in message handler: ${Y(e)}`)}}async captureRawStream(){if(this.transport)try{for await(const e of this.transport.receive()){const t=Yt("string"==typeof e?e:JSON.stringify(e));this.rawQueue.push(t),this.rawHistory.push(t);const s=this.rawQueueResolvers.shift();s&&s(t)}}catch(e){e instanceof j&&e.details.clientInitiated||this.logger.error(`Error capturing raw stream: ${Y(e)}`)}}async handleParsedStream(){if(this.protocol)for await(const e of this.protocol.handleMessages()){const t=this.processProtocolMessage(e);if(t){const e=this.messageQueueResolvers.shift();e&&e(t)}}}async*receiveRawMessages(){for(;this.connected||this.rawQueue.length>0;)try{if(this.rawQueue.length>0)yield this.rawQueue.shift();else{const e=await Promise.race([new Promise(e=>{this.rawQueueResolvers.push(e)}),new Promise((e,t)=>{setTimeout(()=>t(new Error("Timeout")),100)})]);yield e}}catch(e){if(e instanceof Error&&"Timeout"===e.message)continue;throw e}}async*receiveDualStream(){const e=[],t=[];for(;this.connected||this.rawQueue.length>0||e.length>0||t.length>0;)try{let e,t;e=this.rawQueue.length>0?this.rawQueue.shift():await Promise.race([new Promise(e=>{this.rawQueueResolvers.push(e)}),new Promise((e,t)=>{setTimeout(()=>t(new Error("Timeout")),10)})]);try{t=await Promise.race([new Promise(e=>{this.messageQueueResolvers.push(e)}),new Promise((e,t)=>{setTimeout(()=>t(new Error("Timeout")),10)})])}catch{}e.parsedMessage=t,yield[e,t]}catch(e){if(!(e instanceof Error&&"Timeout"===e.message))throw e;try{const e=await Promise.race([new Promise(e=>{this.messageQueueResolvers.push(e)}),new Promise((e,t)=>{setTimeout(()=>t(new Error("Timeout")),10)})]),t=Yt("<no-raw-data>");t.messageType="parsed_only",yield[t,e]}catch(e){if(e instanceof Error&&"Timeout"===e.message)continue;throw e}}}getRawHistory(){return[...this.rawHistory]}getProtocolStats(){const e={totalMessages:this.rawHistory.length,messageTypes:{},controlMessages:0,jsonMessages:0,textMessages:0,errors:0};for(const t of this.rawHistory)t.messageType&&(e.messageTypes[t.messageType]=(e.messageTypes[t.messageType]||0)+1),t.isControl?e.controlMessages++:t.jsonData?e.jsonMessages++:e.textMessages++,t.jsonData&&"error"in t.jsonData&&e.errors++;return e}async sendRaw(e){if(!this.transport)throw new Error("Not connected");await this.transport.send(e);const t="string"==typeof e?e:JSON.stringify(e).substring(0,100);this.logger.info(`Sent raw data: ${t}`)}},exports.StdioTransport=re,exports.TimeoutError=L,exports.Transport=ne,exports.TransportError=G,exports.ValidationError=W,exports.query=async function(e,t,s){const o=[],i=new Vt(s);await i.connect();try{await i.sendMessage(e,t);for await(const e of i.receiveMessages())if(e.type===exports.MessageType.ASSISTANT&&e.chunk.text)o.push(e.chunk.text);else if(e.type===exports.MessageType.TASK_FINISH)break}finally{await i.disconnect()}return o.join("")},exports.queryStream=async function*(e,t,s){const o=new Vt(s);await o.connect();try{await o.sendMessage(e,t);for await(const e of o.receiveMessages())if(e.type===exports.MessageType.ASSISTANT&&e.chunk.text)yield e.chunk.text;else if(e.type===exports.MessageType.TASK_FINISH)break}finally{await o.disconnect()}};
|