ideawave 0.0.89 → 0.0.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.mjs +2 -2
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1060,7 +1060,7 @@ ${J}`:null].filter(Boolean).join(`
1060
1060
 
1061
1061
  ${Z}`)}function bX(X){if(!Array.isArray(X))return null;let Z=X.flatMap((W)=>{if(!W||typeof W!=="object")return[];let K=W;if(typeof K.path!=="string"||!K.path.trim())return[];let J=typeof K.line==="number"?`:${K.line}`:"";return[`${K.path}${J}`]});return Z.length>0?Z.slice(0,5):null}function X4(X){let{ctx:Z,appendText:W,appendToolActivity:K}=X,J=X.flushIntervalMs??U5,V="",H="",U=0,F=null,w=!1,B={},b=new Map,v=(R)=>{if(b.set(R.toolCallId,R),!K)return;K({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,entry:R}).catch((O)=>{console.warn("[streamAdapter] appendToolActivity failed",O)})},y=(R)=>{let O=`${Z.runId}:thought`,$=b.get(O);if(!$||$.status!=="running")return;v({...$,status:"completed",completedAt:$.completedAt??R})},x=(R)=>{for(let O of b.values()){if(O.status!=="running"||O.rawTitle.toLowerCase()!=="toolsearch")continue;v({...O,status:"completed",completedAt:O.completedAt??R})}},C=(R)=>{for(let O of Array.from(b.values())){if(O.status!=="running")continue;if(O.kind==="thought"||O.rawTitle==="agent_thought")continue;v({...O,status:"completed",completedAt:O.completedAt??R})}},M="",h=0,g=null,N=null,G=(R)=>{if(R===M)return;M=R,h=Date.now(),W({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,text:R}).catch((O)=>{console.warn("[streamAdapter] appendText failed",O)})},u=()=>{if(g!==null)clearTimeout(g),g=null;if(N!==null){let R=N;N=null,G(R)}},D=(R)=>{let O=Date.now()-h;if(O>=J&&g===null){G(R);return}if(N=R,g===null){let $=Math.max(0,J-O);g=setTimeout(()=>{g=null,u()},$)}};return{onSessionUpdate:async(R)=>{X.onAnyUpdate?.();let O=R.update;switch(B[O.sessionUpdate]=(B[O.sessionUpdate]??0)+1,O.sessionUpdate){case"agent_message_chunk":{let $=new Date().toISOString();if(y($),O.content.type==="text"){if(O.content.text.length>0){if(w&&V.length>0&&!/\s$/.test(V)&&!/^\s/.test(O.content.text))V+=`
1062
1062
 
1063
- `;V+=O.content.text,w=!1,D(V)}}else{let A=`agent_message_chunk:${O.content.type}`;B[A]=(B[A]??0)+1}return}case"agent_thought_chunk":{if(O.content.type!=="text")return;H+=O.content.text;let $=new Date().toISOString(),A=`${Z.runId}:thought`,s=b.get(A);v({toolCallId:A,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:s?.startedAt??$,completedAt:null,contentPreview:_0(H.trim())});return}case"user_message_chunk":return;case"tool_call":{U+=1,w=V.length>0;let $=n3(O.title),A=BX(O.status),s=new Date().toISOString();y(s),x(s),v({toolCallId:O.toolCallId,rawTitle:$,title:PX($,O.rawInput),kind:LX(O.kind),status:A,startedAt:s,completedAt:A==="running"?null:s,inputPreview:x0(O.rawInput),outputPreview:xX(O.rawOutput),contentPreview:w2(O.content),locations:bX(O.locations)});return}case"tool_call_update":{let $=b.get(O.toolCallId);if(!$){let Q0=n3(O.title),r=BX(O.status),w0=new Date().toISOString();v({toolCallId:O.toolCallId,rawTitle:Q0,title:PX(Q0,O.rawInput),kind:LX(O.kind),status:r,startedAt:w0,completedAt:r==="running"?null:w0,inputPreview:x0(O.rawInput),outputPreview:xX(O.rawOutput),contentPreview:w2(O.content),locations:bX(O.locations)});return}let A=O.status===void 0||O.status===null?$.status:BX(O.status),s=typeof O.title==="string"&&O.title.trim().length>0?O.title:$.rawTitle,b0=typeof O.title==="string"&&O.title.trim().length>0,k=A==="running"?$.completedAt:$.completedAt??new Date().toISOString(),d=O.content===void 0?$.contentPreview:e3($.contentPreview,w2(O.content)),T=O.rawOutput===void 0?$.outputPreview:e3($.outputPreview,xX(O.rawOutput));v({...$,rawTitle:s,title:b0?PX(s,O.rawInput):$.title,kind:O.kind===void 0?$.kind:LX(O.kind),status:A,completedAt:k,inputPreview:O.rawInput===void 0?$.inputPreview:x0(O.rawInput),outputPreview:T,contentPreview:d,locations:O.locations===void 0?$.locations:bX(O.locations)});return}case"plan":F=O.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>V,getToolCallCount:()=>U,getLatestPlan:()=>F,getUpdateTypeCounts:()=>({...B}),flush:(R)=>{let O=new Date().toISOString();if(y(O),R?.completeOpenToolCalls)C(O);u()}}}var q5=new Set(["ECONNRESET","EPIPE"]);function F2(X){if(!X||typeof X!=="object")return!1;if(X instanceof Error&&X.message==="ACP connection closed")return!0;let Z="code"in X?X.code:void 0;return typeof Z==="string"&&q5.has(Z)}var P1=1,Z4=-32000;function W4(X){if(X.awaitingInput)return!1;return X.nowMs-X.lastUpdateMs>=X.windowMs}function J4(X){if(!X||typeof X!=="object")return!1;return X.code===Z4}var P5=300000,x5=P5,b5=5000;function v5(X){let Z=Math.max(1,Math.round(X/1000));return`Runtime has not responded for ${Z} ${Z===1?"second":"seconds"}. Retry the agent run.`}function V4(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.89".trim()?"0.0.89":"dev"}}function Y4(X){if(X===P1)return;throw new I(`Unsupported ACP protocol version ${X}; expected ${P1}`)}function z4(X){return B5.toWeb(X)}function j4(X){return L5.toWeb(X)}function vX(X){return X!==null&&typeof X==="object"}function y5(X){if(!Array.isArray(X))return[];let Z=[];for(let W of X){if(!vX(W))continue;if(typeof W.group==="string"&&Array.isArray(W.options)){let K=typeof W.name==="string"?W.name:W.group;for(let J of W.options){if(!vX(J))continue;if(typeof J.value!=="string"||typeof J.name!=="string")continue;Z.push({value:J.value,name:J.name,description:typeof J.description==="string"?J.description:null,group:W.group,groupName:K})}continue}if(typeof W.value!=="string"||typeof W.name!=="string")continue;Z.push({value:W.value,name:W.name,description:typeof W.description==="string"?W.description:null,group:null,groupName:null})}return Z}function f5(X){if(!vX(X))return null;if(typeof X.id!=="string"||typeof X.name!=="string")return null;let Z=typeof X.category==="string"?X.category:null,W=typeof X.description==="string"?X.description:null;if(X.type==="select"){let K=typeof X.currentValue==="string"?X.currentValue:null;return{id:X.id,name:X.name,category:Z,description:W,type:"select",currentValue:K,options:y5(X.options)}}if(X.type==="boolean"){let K=typeof X.currentValue==="boolean"?X.currentValue:typeof X.value==="boolean"?X.value:null;return{id:X.id,name:X.name,category:Z,description:W,type:"boolean",currentValue:K,options:[]}}return null}function yX(X){let Z=(X.configOptions??[]).map(f5).filter((U)=>U!==null),W=Z.find((U)=>U.type==="select"&&U.category==="model")??Z.find((U)=>U.type==="select"&&U.id==="model")??null,K=W?.options.map((U)=>({id:U.value,name:U.name,description:U.description??null})),J=O5(X.models),V=K&&K.length>0?K:J&&J.length>0?J:null,H=(typeof W?.currentValue==="string"?W.currentValue:null)??R5(X.models)??null;return{models:V,currentModelId:H,configOptions:Z,modelConfigId:W?.id??null}}function O5(X){if(!X||!Array.isArray(X.availableModels))return null;let Z=[];for(let W of X.availableModels){if(typeof W.modelId!=="string")continue;Z.push({id:W.modelId,name:typeof W.name==="string"?W.name:null,description:typeof W.description==="string"?W.description:null})}return Z.length>0?Z:null}function R5(X){return typeof X?.currentModelId==="string"?X.currentModelId:null}function C5(X,Z){let W=[];if(X.trim())W.push({type:"text",text:X});for(let K of Z)if(K.content.trim())W.push({type:"text",text:K.content});return W}var h5=500;function H4(X){return new Promise((Z)=>{let W=setTimeout(()=>Z({code:null,signal:null,stderr:""}),h5);X.then((K)=>{clearTimeout(W),Z(K)})})}function N5(X){if(typeof X.value==="boolean")return{sessionId:X.sessionId,configId:X.configId,type:"boolean",value:X.value};return{sessionId:X.sessionId,configId:X.configId,value:X.value}}function M5(X,Z){let W=yX({configOptions:Z.configOptions});return{models:W.models??X.models,currentModelId:W.currentModelId??X.currentModelId,configOptions:W.configOptions,modelConfigId:W.modelConfigId??X.modelConfigId}}function w4(X,Z){if(X==="default")return null;if(!Z||Z.length===0)return X;let W=Z.find((w)=>w.id===X);if(W)return W.id;let K=X.toLowerCase(),J=K.includes("opus")?"opus":K.includes("sonnet")?"sonnet":K.includes("haiku")?"haiku":null;if(!J)return X;let V=(w)=>`${w.id} ${w.name??""} ${w.description??""}`.toLowerCase(),H=Z.filter((w)=>V(w).includes(J));if(H.length===0)return X;let F=(K.includes("1m")?H.find((w)=>V(w).includes("1m")):void 0)??H[0];return F?F.id:X}async function q2(X){try{let Z=await X.conn.setSessionConfigOption(N5({sessionId:X.sessionId,configId:X.configId,value:X.value}));return M5(X.metadata,Z)}catch(Z){return console.warn(`[acp] setSessionConfigOption(${X.label}) failed; using agent default.`,Z instanceof Error?Z.message:Z),X.metadata}}async function fX(X){let Z=FX(X.spawn),W=[],K=0,J=4096;Z.stderr.on("data",(k)=>{W.push(k),K+=k.length;while(K>J*2&&W.length>1){let d=W.shift();if(d)K-=d.length}});let V=()=>{let k=Buffer.concat(W).toString("utf8");return k.length>J?k.slice(-J):k},H=o3(X.spawn.cwd),U={current:null},F={current:null},w={at:Date.now()},B=null,b=j4(Z.stdin),v=z4(Z.stdout),y=K4(b,v),C=new Q4((k)=>({requestPermission:async(d)=>{let T=d.options,Q0=T?.find((r)=>r.kind==="allow_once")??T?.find((r)=>r.kind==="allow_always");if(Q0)return{outcome:{outcome:"selected",optionId:Q0.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(d)=>{w.at=Date.now();let T=F.current;if(T){let r=d.update.sessionUpdate;if(T.updateCount+=1,T.updateCount===1||T.lastUpdateType!==r||r==="tool_call"||r==="tool_call_update")E("acp.session_update",{runId:T.runId,cardId:T.cardId,sessionId:B,updateType:r,updateCount:T.updateCount,elapsedMs:Date.now()-T.startedAt});T.lastUpdateType=r}let Q0=U.current;if(Q0)await Q0.onSessionUpdate(d)},readTextFile:H.readTextFile}),y),M=()=>Z.kill();if(X.signal)X.signal.addEventListener("abort",M);let h=()=>{if(X.signal)X.signal.removeEventListener("abort",M)},g=async(k,d)=>{if(h(),Z.kill(),J4(k))throw new l0(k.message??"Authentication required",d);if(F2(k)){if(X.signal?.aborted)throw new I("ACP session cancelled: abort signal received");let T=await H4(Z.waitForExit);throw new I(`Runtime process exited before completion: ${T.stderr?.trim()??""}`)}throw k},N;try{N=await C.initialize({protocolVersion:P1,clientCapabilities:UX,clientInfo:V4()})}catch(k){throw await g(k,[]),Error("unreachable")}try{Y4(N.protocolVersion)}catch(k){throw h(),Z.kill(),k}let G=N.authMethods?.map((k)=>k.id)??[],u;try{u=await C.newSession({cwd:X.spawn.cwd,mcpServers:X.mcpServers??[]})}catch(k){throw await g(k,G),Error("unreachable")}let D=u.sessionId;B=D;let R=yX(u),O=X.modelId??null,$=O?w4(O,R.models):null;if($&&$!==R.currentModelId)if(R.modelConfigId)R=await q2({conn:C,sessionId:D,configId:R.modelConfigId,value:$,metadata:R,label:`${R.modelConfigId}=${$}`});else console.warn(`[acp] runtime did not advertise a model config option for ${$}; using agent default.`);for(let[k,d]of Object.entries(X.configValues??{}).sort(([T],[Q0])=>T.localeCompare(Q0))){if(k===R.modelConfigId)continue;if(!R.configOptions.some((T)=>T.id===k))continue;R=await q2({conn:C,sessionId:D,configId:k,value:d,metadata:R,label:`${k}=${String(d)}`})}h();let A=!1,s=async()=>{if(A)return;A=!0,Z.kill(),await Promise.race([Z.waitForExit,new Promise((k)=>setTimeout(k,2000))])},b0=!1;return Z.processCrashed.then(()=>{b0=!0}),{sessionId:D,availableModels:R.models,currentModelId:R.currentModelId,availableConfigOptions:R.configOptions,isAlive:()=>!A&&!b0,dispose:s,prompt:(k)=>g5({proc:Z,conn:C,sessionId:D,activeAdapter:U,activeTrace:F,lastUpdate:w,collectStderrTail:V},k)}}async function g5(X,Z){let{proc:W,conn:K,sessionId:J,activeAdapter:V,activeTrace:H,lastUpdate:U}=X,F=Date.now(),w=Z.heartbeatMs??x5,B=v5(w),b={boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId},v=X4({ctx:b,appendText:Z.appendText,appendToolActivity:Z.appendToolActivity,onAnyUpdate:Z.onAnyUpdate});V.current=v,H.current={runId:Z.runId,cardId:Z.cardId,startedAt:F,updateCount:0,lastUpdateType:null},U.at=Date.now(),E("acp.prompt_started",{runId:Z.runId,cardId:Z.cardId,sessionId:J,heartbeatWindowMs:w});let y=!1,x=null,C=()=>W.kill();Z.signal.addEventListener("abort",C);try{let M=async()=>{let G=Math.min(b5,Math.max(50,Math.floor(w/2)));x=setInterval(()=>{let D=Z.isAwaitingInput?.()??!1;if(D){U.at=Date.now();return}if(W4({nowMs:Date.now(),lastUpdateMs:U.at,windowMs:w,awaitingInput:D}))y=!0,E("acp.inactivity_timeout",{runId:Z.runId,cardId:Z.cardId,sessionId:J,windowMs:w,silentForMs:Date.now()-U.at}),K.cancel({sessionId:J}).catch(()=>{return}),W.kill()},G);let u=C5(Z.prompt.systemPrompt,Z.prompt.messages);await K.prompt({sessionId:J,prompt:u}),E("acp.prompt_resolved",{runId:Z.runId,cardId:Z.cardId,sessionId:J,elapsedMs:Date.now()-F}),v.flush({completeOpenToolCalls:!0})},h=W.waitForExit.then((G)=>({kind:"exited",exit:G})),g=M().then(()=>({kind:"ok"})).catch(async(G)=>{if(F2(G))return W.kill(),{kind:"crashed",exit:await H4(W.waitForExit)};throw G}),N;try{N=await Promise.race([g,W.processCrashed.then((G)=>({kind:"crashed",exit:G})),h])}catch(G){if(y)throw new U0(B);throw G}if(y)throw new U0(B);if(N.kind!=="ok"&&Z.signal.aborted)throw new I("ACP session cancelled: abort signal received");if(N.kind==="crashed")throw new I(`Runtime process exited before completion: ${N.exit.stderr.trim()}`);if(N.kind==="exited"){if(y)throw new U0(B);throw new I(`Runtime process exited unexpectedly: ${N.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:v.getFinalText(),toolCallsExecuted:v.getToolCallCount(),stderrTail:X.collectStderrTail(),updateTypeCounts:v.getUpdateTypeCounts()}}finally{if(E("acp.prompt_finished",{runId:Z.runId,cardId:Z.cardId,sessionId:J,elapsedMs:Date.now()-F,timedOut:y,updateCount:H.current?.updateCount??0}),x!==null)clearInterval(x);Z.signal.removeEventListener("abort",C),v.flush({completeOpenToolCalls:!0}),V.current=null,H.current=null}}var D5=30000;async function U4(X){let Z=FX(X.spawn),W=j4(Z.stdin),K=z4(Z.stdout),J=K4(W,K),H=new Q4((w)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),J),U=()=>Z.kill();if(X.signal)X.signal.addEventListener("abort",U);let F=null;try{let w=(async()=>{let b=await H.initialize({protocolVersion:P1,clientCapabilities:UX,clientInfo:V4()});Y4(b.protocolVersion);let v=b.authMethods?.map((N)=>N.id)??[],y;try{y=await H.newSession({cwd:X.spawn.cwd,mcpServers:[]})}catch(N){if(J4(N))throw new l0(N.message??"Authentication required",v);throw N}let x=yX(y),C=X.modelId??null,M=C?w4(C,x.models):null;if(M&&M!==x.currentModelId)if(x.modelConfigId)x=await q2({conn:H,sessionId:y.sessionId,configId:x.modelConfigId,value:M,metadata:x,label:`${x.modelConfigId}=${M}`});else console.warn(`[acp] runtime did not advertise a model config option for ${M}; discovering agent default models.`);for(let[N,G]of Object.entries(X.configValues??{}).sort(([u],[D])=>u.localeCompare(D))){if(N===x.modelConfigId)continue;if(!x.configOptions.some((u)=>u.id===N))continue;x=await q2({conn:H,sessionId:y.sessionId,configId:N,value:G,metadata:x,label:`${N}=${String(G)}`})}let h=x.models??[],g=x.currentModelId;return H.cancel({sessionId:y.sessionId}).catch(()=>{return}),{models:h,configOptions:x.configOptions,currentModelId:g}})(),B=new Promise((b,v)=>{F=setTimeout(()=>{v(new U0)},D5)});return await Promise.race([w,B])}catch(w){if(F2(w)){if(X.signal?.aborted)throw new I("ACP model discovery cancelled: abort signal received");throw new I("Runtime process exited during model discovery.")}throw w}finally{if(F)clearTimeout(F);if(X.signal)X.signal.removeEventListener("abort",U);Z.kill()}}import m5 from"node:fs/promises";import B2 from"node:os";async function F4(X){let Z={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},W;try{W=await m5.readFile(X,"utf-8")}catch(K){if(K.code==="ENOENT")return structuredClone(Z);throw K}return $1.parse(JSON.parse(W))}function OX(X,Z,W){return{...X.defaultConfigValues??{},...Z?.configValues??{},...W?.configValues??{}}}async function C0(X){let Z=X.configPath?await F4(X.configPath):await K0(),W=X.cardId?Z.cardOverrides[X.cardId]:void 0;if(W?.runtimeConfigId){let J=Z.runtimes.find((V)=>V.id===W.runtimeConfigId);if(J)return{entry:J,adapter:F0(J),runFolder:W.runFolder??J.runFolder??B2.homedir(),modelId:W.modelId??J.defaultModelId??null,configValues:OX(J,void 0,W)}}let K=Z.boardOverrides[X.boardId];if(K?.runtimeConfigId){let J=Z.runtimes.find((V)=>V.id===K.runtimeConfigId);if(J)return{entry:J,adapter:F0(J),runFolder:K.runFolder??J.runFolder??B2.homedir(),modelId:K.modelId??J.defaultModelId??null,configValues:OX(J,K)}}if(Z.globalDefaultConfigId){let J=Z.runtimes.find((V)=>V.id===Z.globalDefaultConfigId);if(J)return{entry:J,adapter:F0(J),runFolder:W?.runFolder??K?.runFolder??J.runFolder??B2.homedir(),modelId:W?.modelId??K?.modelId??J.defaultModelId??null,configValues:OX(J,K,W)}}throw new D0}async function q4(X,Z={}){let K=(Z.configPath?await F4(Z.configPath):await K0()).runtimes.find((J)=>J.id===X);if(!K)return null;return{entry:K,adapter:F0(K),runFolder:K.runFolder??B2.homedir(),modelId:Z.modelId??K.defaultModelId??null,configValues:{...K.defaultConfigValues??{},...Z.configValues??{}}}}var B4=new Map;function RX(X,Z){if(!X)return;B4.set(X,Z)}function L4(X){if(!X)return!1;return B4.get(X)??!1}var k0=new Map,CX=new Set;function hX(X){k0.get(X)?.controller.abort()}function P4(X){for(let[Z,W]of k0){if(W.frontendSessionId!==X)continue;W.controller.abort(),k0.delete(Z)}}function x4(){for(let X of k0.values())X.controller.abort();k0.clear()}function b4(X,Z){if(Z?.aborted)return!0;return X instanceof Error&&/abort signal received|session cancelled/i.test(X.message)}function v4(X,Z,W,K){if((!Z.availableModels||Z.availableModels.length===0)&&Z.availableConfigOptions.length===0)return;z0((J)=>{let V=J.runtimes.find((H)=>H.id===X);if(V){if(Z.availableModels&&Z.availableModels.length>0)V.discoveredModels=Y2({adapterId:W,models:Z.availableModels,currentModelId:Z.currentModelId??K});if(Z.availableConfigOptions.length>0)V.discoveredConfigOptions=Z.availableConfigOptions}}).catch(()=>{return})}function $5(X,Z){return`${X}
1063
+ `;V+=O.content.text,w=!1,D(V)}}else{let A=`agent_message_chunk:${O.content.type}`;B[A]=(B[A]??0)+1}return}case"agent_thought_chunk":{if(O.content.type!=="text")return;H+=O.content.text;let $=new Date().toISOString(),A=`${Z.runId}:thought`,s=b.get(A);v({toolCallId:A,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:s?.startedAt??$,completedAt:null,contentPreview:_0(H.trim())});return}case"user_message_chunk":return;case"tool_call":{U+=1,w=V.length>0;let $=n3(O.title),A=BX(O.status),s=new Date().toISOString();y(s),x(s),v({toolCallId:O.toolCallId,rawTitle:$,title:PX($,O.rawInput),kind:LX(O.kind),status:A,startedAt:s,completedAt:A==="running"?null:s,inputPreview:x0(O.rawInput),outputPreview:xX(O.rawOutput),contentPreview:w2(O.content),locations:bX(O.locations)});return}case"tool_call_update":{let $=b.get(O.toolCallId);if(!$){let Q0=n3(O.title),r=BX(O.status),w0=new Date().toISOString();v({toolCallId:O.toolCallId,rawTitle:Q0,title:PX(Q0,O.rawInput),kind:LX(O.kind),status:r,startedAt:w0,completedAt:r==="running"?null:w0,inputPreview:x0(O.rawInput),outputPreview:xX(O.rawOutput),contentPreview:w2(O.content),locations:bX(O.locations)});return}let A=O.status===void 0||O.status===null?$.status:BX(O.status),s=typeof O.title==="string"&&O.title.trim().length>0?O.title:$.rawTitle,b0=typeof O.title==="string"&&O.title.trim().length>0,k=A==="running"?$.completedAt:$.completedAt??new Date().toISOString(),d=O.content===void 0?$.contentPreview:e3($.contentPreview,w2(O.content)),T=O.rawOutput===void 0?$.outputPreview:e3($.outputPreview,xX(O.rawOutput));v({...$,rawTitle:s,title:b0?PX(s,O.rawInput):$.title,kind:O.kind===void 0?$.kind:LX(O.kind),status:A,completedAt:k,inputPreview:O.rawInput===void 0?$.inputPreview:x0(O.rawInput),outputPreview:T,contentPreview:d,locations:O.locations===void 0?$.locations:bX(O.locations)});return}case"plan":F=O.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>V,getToolCallCount:()=>U,getLatestPlan:()=>F,getUpdateTypeCounts:()=>({...B}),flush:(R)=>{let O=new Date().toISOString();if(y(O),R?.completeOpenToolCalls)C(O);u()}}}var q5=new Set(["ECONNRESET","EPIPE"]);function F2(X){if(!X||typeof X!=="object")return!1;if(X instanceof Error&&X.message==="ACP connection closed")return!0;let Z="code"in X?X.code:void 0;return typeof Z==="string"&&q5.has(Z)}var P1=1,Z4=-32000;function W4(X){if(X.awaitingInput)return!1;return X.nowMs-X.lastUpdateMs>=X.windowMs}function J4(X){if(!X||typeof X!=="object")return!1;return X.code===Z4}var P5=300000,x5=P5,b5=5000;function v5(X){let Z=Math.max(1,Math.round(X/1000));return`Runtime has not responded for ${Z} ${Z===1?"second":"seconds"}. Retry the agent run.`}function V4(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.90".trim()?"0.0.90":"dev"}}function Y4(X){if(X===P1)return;throw new I(`Unsupported ACP protocol version ${X}; expected ${P1}`)}function z4(X){return B5.toWeb(X)}function j4(X){return L5.toWeb(X)}function vX(X){return X!==null&&typeof X==="object"}function y5(X){if(!Array.isArray(X))return[];let Z=[];for(let W of X){if(!vX(W))continue;if(typeof W.group==="string"&&Array.isArray(W.options)){let K=typeof W.name==="string"?W.name:W.group;for(let J of W.options){if(!vX(J))continue;if(typeof J.value!=="string"||typeof J.name!=="string")continue;Z.push({value:J.value,name:J.name,description:typeof J.description==="string"?J.description:null,group:W.group,groupName:K})}continue}if(typeof W.value!=="string"||typeof W.name!=="string")continue;Z.push({value:W.value,name:W.name,description:typeof W.description==="string"?W.description:null,group:null,groupName:null})}return Z}function f5(X){if(!vX(X))return null;if(typeof X.id!=="string"||typeof X.name!=="string")return null;let Z=typeof X.category==="string"?X.category:null,W=typeof X.description==="string"?X.description:null;if(X.type==="select"){let K=typeof X.currentValue==="string"?X.currentValue:null;return{id:X.id,name:X.name,category:Z,description:W,type:"select",currentValue:K,options:y5(X.options)}}if(X.type==="boolean"){let K=typeof X.currentValue==="boolean"?X.currentValue:typeof X.value==="boolean"?X.value:null;return{id:X.id,name:X.name,category:Z,description:W,type:"boolean",currentValue:K,options:[]}}return null}function yX(X){let Z=(X.configOptions??[]).map(f5).filter((U)=>U!==null),W=Z.find((U)=>U.type==="select"&&U.category==="model")??Z.find((U)=>U.type==="select"&&U.id==="model")??null,K=W?.options.map((U)=>({id:U.value,name:U.name,description:U.description??null})),J=O5(X.models),V=K&&K.length>0?K:J&&J.length>0?J:null,H=(typeof W?.currentValue==="string"?W.currentValue:null)??R5(X.models)??null;return{models:V,currentModelId:H,configOptions:Z,modelConfigId:W?.id??null}}function O5(X){if(!X||!Array.isArray(X.availableModels))return null;let Z=[];for(let W of X.availableModels){if(typeof W.modelId!=="string")continue;Z.push({id:W.modelId,name:typeof W.name==="string"?W.name:null,description:typeof W.description==="string"?W.description:null})}return Z.length>0?Z:null}function R5(X){return typeof X?.currentModelId==="string"?X.currentModelId:null}function C5(X,Z){let W=[];if(X.trim())W.push({type:"text",text:X});for(let K of Z)if(K.content.trim())W.push({type:"text",text:K.content});return W}var h5=500;function H4(X){return new Promise((Z)=>{let W=setTimeout(()=>Z({code:null,signal:null,stderr:""}),h5);X.then((K)=>{clearTimeout(W),Z(K)})})}function N5(X){if(typeof X.value==="boolean")return{sessionId:X.sessionId,configId:X.configId,type:"boolean",value:X.value};return{sessionId:X.sessionId,configId:X.configId,value:X.value}}function M5(X,Z){let W=yX({configOptions:Z.configOptions});return{models:W.models??X.models,currentModelId:W.currentModelId??X.currentModelId,configOptions:W.configOptions,modelConfigId:W.modelConfigId??X.modelConfigId}}function w4(X,Z){if(X==="default")return null;if(!Z||Z.length===0)return X;let W=Z.find((w)=>w.id===X);if(W)return W.id;let K=X.toLowerCase(),J=K.includes("opus")?"opus":K.includes("sonnet")?"sonnet":K.includes("haiku")?"haiku":null;if(!J)return X;let V=(w)=>`${w.id} ${w.name??""} ${w.description??""}`.toLowerCase(),H=Z.filter((w)=>V(w).includes(J));if(H.length===0)return X;let F=(K.includes("1m")?H.find((w)=>V(w).includes("1m")):void 0)??H[0];return F?F.id:X}async function q2(X){try{let Z=await X.conn.setSessionConfigOption(N5({sessionId:X.sessionId,configId:X.configId,value:X.value}));return M5(X.metadata,Z)}catch(Z){return console.warn(`[acp] setSessionConfigOption(${X.label}) failed; using agent default.`,Z instanceof Error?Z.message:Z),X.metadata}}async function fX(X){let Z=FX(X.spawn),W=[],K=0,J=4096;Z.stderr.on("data",(k)=>{W.push(k),K+=k.length;while(K>J*2&&W.length>1){let d=W.shift();if(d)K-=d.length}});let V=()=>{let k=Buffer.concat(W).toString("utf8");return k.length>J?k.slice(-J):k},H=o3(X.spawn.cwd),U={current:null},F={current:null},w={at:Date.now()},B=null,b=j4(Z.stdin),v=z4(Z.stdout),y=K4(b,v),C=new Q4((k)=>({requestPermission:async(d)=>{let T=d.options,Q0=T?.find((r)=>r.kind==="allow_once")??T?.find((r)=>r.kind==="allow_always");if(Q0)return{outcome:{outcome:"selected",optionId:Q0.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(d)=>{w.at=Date.now();let T=F.current;if(T){let r=d.update.sessionUpdate;if(T.updateCount+=1,T.updateCount===1||T.lastUpdateType!==r||r==="tool_call"||r==="tool_call_update")E("acp.session_update",{runId:T.runId,cardId:T.cardId,sessionId:B,updateType:r,updateCount:T.updateCount,elapsedMs:Date.now()-T.startedAt});T.lastUpdateType=r}let Q0=U.current;if(Q0)await Q0.onSessionUpdate(d)},readTextFile:H.readTextFile}),y),M=()=>Z.kill();if(X.signal)X.signal.addEventListener("abort",M);let h=()=>{if(X.signal)X.signal.removeEventListener("abort",M)},g=async(k,d)=>{if(h(),Z.kill(),J4(k))throw new l0(k.message??"Authentication required",d);if(F2(k)){if(X.signal?.aborted)throw new I("ACP session cancelled: abort signal received");let T=await H4(Z.waitForExit);throw new I(`Runtime process exited before completion: ${T.stderr?.trim()??""}`)}throw k},N;try{N=await C.initialize({protocolVersion:P1,clientCapabilities:UX,clientInfo:V4()})}catch(k){throw await g(k,[]),Error("unreachable")}try{Y4(N.protocolVersion)}catch(k){throw h(),Z.kill(),k}let G=N.authMethods?.map((k)=>k.id)??[],u;try{u=await C.newSession({cwd:X.spawn.cwd,mcpServers:X.mcpServers??[]})}catch(k){throw await g(k,G),Error("unreachable")}let D=u.sessionId;B=D;let R=yX(u),O=X.modelId??null,$=O?w4(O,R.models):null;if($&&$!==R.currentModelId)if(R.modelConfigId)R=await q2({conn:C,sessionId:D,configId:R.modelConfigId,value:$,metadata:R,label:`${R.modelConfigId}=${$}`});else console.warn(`[acp] runtime did not advertise a model config option for ${$}; using agent default.`);for(let[k,d]of Object.entries(X.configValues??{}).sort(([T],[Q0])=>T.localeCompare(Q0))){if(k===R.modelConfigId)continue;if(!R.configOptions.some((T)=>T.id===k))continue;R=await q2({conn:C,sessionId:D,configId:k,value:d,metadata:R,label:`${k}=${String(d)}`})}h();let A=!1,s=async()=>{if(A)return;A=!0,Z.kill(),await Promise.race([Z.waitForExit,new Promise((k)=>setTimeout(k,2000))])},b0=!1;return Z.processCrashed.then(()=>{b0=!0}),{sessionId:D,availableModels:R.models,currentModelId:R.currentModelId,availableConfigOptions:R.configOptions,isAlive:()=>!A&&!b0,dispose:s,prompt:(k)=>g5({proc:Z,conn:C,sessionId:D,activeAdapter:U,activeTrace:F,lastUpdate:w,collectStderrTail:V},k)}}async function g5(X,Z){let{proc:W,conn:K,sessionId:J,activeAdapter:V,activeTrace:H,lastUpdate:U}=X,F=Date.now(),w=Z.heartbeatMs??x5,B=v5(w),b={boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId},v=X4({ctx:b,appendText:Z.appendText,appendToolActivity:Z.appendToolActivity,onAnyUpdate:Z.onAnyUpdate});V.current=v,H.current={runId:Z.runId,cardId:Z.cardId,startedAt:F,updateCount:0,lastUpdateType:null},U.at=Date.now(),E("acp.prompt_started",{runId:Z.runId,cardId:Z.cardId,sessionId:J,heartbeatWindowMs:w});let y=!1,x=null,C=()=>W.kill();Z.signal.addEventListener("abort",C);try{let M=async()=>{let G=Math.min(b5,Math.max(50,Math.floor(w/2)));x=setInterval(()=>{let D=Z.isAwaitingInput?.()??!1;if(D){U.at=Date.now();return}if(W4({nowMs:Date.now(),lastUpdateMs:U.at,windowMs:w,awaitingInput:D}))y=!0,E("acp.inactivity_timeout",{runId:Z.runId,cardId:Z.cardId,sessionId:J,windowMs:w,silentForMs:Date.now()-U.at}),K.cancel({sessionId:J}).catch(()=>{return}),W.kill()},G);let u=C5(Z.prompt.systemPrompt,Z.prompt.messages);await K.prompt({sessionId:J,prompt:u}),E("acp.prompt_resolved",{runId:Z.runId,cardId:Z.cardId,sessionId:J,elapsedMs:Date.now()-F}),v.flush({completeOpenToolCalls:!0})},h=W.waitForExit.then((G)=>({kind:"exited",exit:G})),g=M().then(()=>({kind:"ok"})).catch(async(G)=>{if(F2(G))return W.kill(),{kind:"crashed",exit:await H4(W.waitForExit)};throw G}),N;try{N=await Promise.race([g,W.processCrashed.then((G)=>({kind:"crashed",exit:G})),h])}catch(G){if(y)throw new U0(B);throw G}if(y)throw new U0(B);if(N.kind!=="ok"&&Z.signal.aborted)throw new I("ACP session cancelled: abort signal received");if(N.kind==="crashed")throw new I(`Runtime process exited before completion: ${N.exit.stderr.trim()}`);if(N.kind==="exited"){if(y)throw new U0(B);throw new I(`Runtime process exited unexpectedly: ${N.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:v.getFinalText(),toolCallsExecuted:v.getToolCallCount(),stderrTail:X.collectStderrTail(),updateTypeCounts:v.getUpdateTypeCounts()}}finally{if(E("acp.prompt_finished",{runId:Z.runId,cardId:Z.cardId,sessionId:J,elapsedMs:Date.now()-F,timedOut:y,updateCount:H.current?.updateCount??0}),x!==null)clearInterval(x);Z.signal.removeEventListener("abort",C),v.flush({completeOpenToolCalls:!0}),V.current=null,H.current=null}}var D5=30000;async function U4(X){let Z=FX(X.spawn),W=j4(Z.stdin),K=z4(Z.stdout),J=K4(W,K),H=new Q4((w)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),J),U=()=>Z.kill();if(X.signal)X.signal.addEventListener("abort",U);let F=null;try{let w=(async()=>{let b=await H.initialize({protocolVersion:P1,clientCapabilities:UX,clientInfo:V4()});Y4(b.protocolVersion);let v=b.authMethods?.map((N)=>N.id)??[],y;try{y=await H.newSession({cwd:X.spawn.cwd,mcpServers:[]})}catch(N){if(J4(N))throw new l0(N.message??"Authentication required",v);throw N}let x=yX(y),C=X.modelId??null,M=C?w4(C,x.models):null;if(M&&M!==x.currentModelId)if(x.modelConfigId)x=await q2({conn:H,sessionId:y.sessionId,configId:x.modelConfigId,value:M,metadata:x,label:`${x.modelConfigId}=${M}`});else console.warn(`[acp] runtime did not advertise a model config option for ${M}; discovering agent default models.`);for(let[N,G]of Object.entries(X.configValues??{}).sort(([u],[D])=>u.localeCompare(D))){if(N===x.modelConfigId)continue;if(!x.configOptions.some((u)=>u.id===N))continue;x=await q2({conn:H,sessionId:y.sessionId,configId:N,value:G,metadata:x,label:`${N}=${String(G)}`})}let h=x.models??[],g=x.currentModelId;return H.cancel({sessionId:y.sessionId}).catch(()=>{return}),{models:h,configOptions:x.configOptions,currentModelId:g}})(),B=new Promise((b,v)=>{F=setTimeout(()=>{v(new U0)},D5)});return await Promise.race([w,B])}catch(w){if(F2(w)){if(X.signal?.aborted)throw new I("ACP model discovery cancelled: abort signal received");throw new I("Runtime process exited during model discovery.")}throw w}finally{if(F)clearTimeout(F);if(X.signal)X.signal.removeEventListener("abort",U);Z.kill()}}import m5 from"node:fs/promises";import B2 from"node:os";async function F4(X){let Z={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},W;try{W=await m5.readFile(X,"utf-8")}catch(K){if(K.code==="ENOENT")return structuredClone(Z);throw K}return $1.parse(JSON.parse(W))}function OX(X,Z,W){return{...X.defaultConfigValues??{},...Z?.configValues??{},...W?.configValues??{}}}async function C0(X){let Z=X.configPath?await F4(X.configPath):await K0(),W=X.cardId?Z.cardOverrides[X.cardId]:void 0;if(W?.runtimeConfigId){let J=Z.runtimes.find((V)=>V.id===W.runtimeConfigId);if(J)return{entry:J,adapter:F0(J),runFolder:W.runFolder??J.runFolder??B2.homedir(),modelId:W.modelId??J.defaultModelId??null,configValues:OX(J,void 0,W)}}let K=Z.boardOverrides[X.boardId];if(K?.runtimeConfigId){let J=Z.runtimes.find((V)=>V.id===K.runtimeConfigId);if(J)return{entry:J,adapter:F0(J),runFolder:K.runFolder??J.runFolder??B2.homedir(),modelId:K.modelId??J.defaultModelId??null,configValues:OX(J,K)}}if(Z.globalDefaultConfigId){let J=Z.runtimes.find((V)=>V.id===Z.globalDefaultConfigId);if(J)return{entry:J,adapter:F0(J),runFolder:W?.runFolder??K?.runFolder??J.runFolder??B2.homedir(),modelId:W?.modelId??K?.modelId??J.defaultModelId??null,configValues:OX(J,K,W)}}throw new D0}async function q4(X,Z={}){let K=(Z.configPath?await F4(Z.configPath):await K0()).runtimes.find((J)=>J.id===X);if(!K)return null;return{entry:K,adapter:F0(K),runFolder:K.runFolder??B2.homedir(),modelId:Z.modelId??K.defaultModelId??null,configValues:{...K.defaultConfigValues??{},...Z.configValues??{}}}}var B4=new Map;function RX(X,Z){if(!X)return;B4.set(X,Z)}function L4(X){if(!X)return!1;return B4.get(X)??!1}var k0=new Map,CX=new Set;function hX(X){k0.get(X)?.controller.abort()}function P4(X){for(let[Z,W]of k0){if(W.frontendSessionId!==X)continue;W.controller.abort(),k0.delete(Z)}}function x4(){for(let X of k0.values())X.controller.abort();k0.clear()}function b4(X,Z){if(Z?.aborted)return!0;return X instanceof Error&&/abort signal received|session cancelled/i.test(X.message)}function v4(X,Z,W,K){if((!Z.availableModels||Z.availableModels.length===0)&&Z.availableConfigOptions.length===0)return;z0((J)=>{let V=J.runtimes.find((H)=>H.id===X);if(V){if(Z.availableModels&&Z.availableModels.length>0)V.discoveredModels=Y2({adapterId:W,models:Z.availableModels,currentModelId:Z.currentModelId??K});if(Z.availableConfigOptions.length>0)V.discoveredConfigOptions=Z.availableConfigOptions}}).catch(()=>{return})}function $5(X,Z){return`${X}
1064
1064
 
1065
1065
  Runtime run folder:
1066
1066
  - Effective run folder: ${Z}
@@ -1070,4 +1070,4 @@ Runtime run folder:
1070
1070
  Connection: close\r
1071
1071
  Content-Length: ${Buffer.byteLength(W)}\r
1072
1072
  \r
1073
- ${W}`),X.destroy()}function f7(X,Z){return new Promise((W,K)=>{let J=(H)=>{X.off("listening",V),K(H)},V=()=>{X.off("error",J);let H=X.address();if(!H||typeof H==="string"){K(Error("Failed to read CLI bridge server address"));return}W(H.port)};X.once("error",J),X.once("listening",V),X.listen(Z,"127.0.0.1")})}function S4(X){return new Promise((Z,W)=>{X.close((K)=>{if(K)W(K);else Z()})})}async function c4(X,Z=_X()){let W=new Map,K=new Map,J=X.maxMessageSize??H7,V=!1,H=(y)=>{let x=K.get(y);if(x)clearTimeout(x);K.delete(y)},U=(y)=>{K.delete(y);let{activeRunIds:x}=X.registry.disconnect(y);X.onDisconnect(y,x)},F=(y,x)=>{let C={type:"cli_status",connected:!0,runtime:X.runtime,mcpReady:X.mcpReady(),error:x,capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()};if(y){let M=W.get(y);if(M)o0(M,C);return}for(let M of W.values())o0(M,C)},w=(y,x)=>{let C=x.sessionId.trim(),M=x.userId.trim();if(!C||!M){o0(y,{type:"cli_status",connected:!1,runtime:X.runtime,mcpReady:X.mcpReady(),error:"Missing frontend session or user id"}),y.close();return}H(C);let h=W.get(C);if(h&&h!==y)h.close();y.data.frontendSessionId=C,W.set(C,y),X.registry.register({frontendSessionId:C,userId:M,tools:x.tools,send:(g)=>o0(y,g)}),F(C),X.onToolMetadata?.(C)},B=(y,x)=>{let C=X.registry.getUserId(y);if(!C)return;switch(x.type){case"bridge_ping":{let M=W.get(y);if(M)o0(M,{type:"bridge_pong"});break}case"tool_metadata":X.registry.setMetadata(y,x.tools),X.onToolMetadata?.(y);break;case"tool_result":X.registry.handleToolResult(y,x);break;case"run_turn":E("bridge.run_received",{runId:x.run.runId,cardId:x.run.cardId,frontendSessionId:y}),X.registry.markRunActive(y,x.run.runId,x.run.cardId),X.onRunTurn(y,{...x.run,frontendSessionId:y,userId:C});break;case"cancel_run":if(X.registry.ownsRun(y,x.runId))X.onCancelRun(y,x.runId);break;case"runtime_rpc":X.onRuntimeRpc(y,x);break;case"browser_rpc":X.onBrowserRpc?.(y,W.get(y)?.data.frontendOrigin??"",x);break;case"warmup_run":X.onWarmupRun(y,{...x,frontendSessionId:y},C);break;default:break}},b=(y,x)=>{let C=v2(y.headers.origin),M=kX(C),h={Vary:"Origin"};if(M&&C)h["Access-Control-Allow-Origin"]=C,h["Access-Control-Allow-Private-Network"]="true";if(y.method==="OPTIONS"){x.writeHead(204,{...h,"Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*","Access-Control-Max-Age":"600"}),x.end();return}if(y.method!=="GET"){x.writeHead(405,h),x.end();return}x.writeHead(200,{...h,"content-type":"application/json","cache-control":"no-store"}),x.end(JSON.stringify({ideawave:!0,runtime:X.runtime,mcpReady:X.mcpReady(),capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()}))},v=(y,x)=>{let C=v2(y.headers.origin),M=kX(C),h={Vary:"Origin"};if(M&&C)h["Access-Control-Allow-Origin"]=C,h["Access-Control-Allow-Private-Network"]="true";if(y.method==="OPTIONS"){x.writeHead(204,{...h,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"content-type","Access-Control-Max-Age":"600"}),x.end();return}if(!M){x.writeHead(403,h),x.end();return}if(y.method!=="POST"){x.writeHead(405,h),x.end();return}let g={...h,"content-type":"application/json"},N=(D,R)=>{x.writeHead(D,g),x.end(JSON.stringify(R))},G="",u=!1;y.on("data",(D)=>{if(G+=D.toString("utf8"),G.length>q7)u=!0,y.destroy()}),y.on("end",()=>{if(u){N(400,{ok:!1,error:"Request body too large"});return}let D;try{D=JSON.parse(G)}catch{N(400,{ok:!1,error:"Invalid JSON body"});return}let R=typeof D.url==="string"?D.url:"";if(!_4(R)){N(400,{ok:!1,error:"url must be an http(s) loopback or /static_boards/ page URL"});return}let O=($,A)=>{let s=typeof $==="number"?$:Number.NaN;if(!Number.isFinite(s))return A;return Math.min(4000,Math.max(200,Math.round(s)))};k4({url:R,width:O(D.width,1440),height:O(D.height,900)}).then(($)=>N(200,{ok:!0,path:$.path,engine:$.engine})).catch(($)=>{let A=$ instanceof b1?503:$ instanceof b2?429:500;N(A,{ok:!1,...$ instanceof b1?{installing:!0}:{},error:$ instanceof Error?$.message:String($)})})})};for(let y of Z){let x=z7((h,g)=>{(async()=>{let N=new URL(h.url??"/","http://127.0.0.1").pathname;if(N===m4){b(h,g);return}if(N===F7){v(h,g);return}if(await X.onHttpRequest?.(h,g))return;g.writeHead(404,{"content-type":"text/plain"}),g.end("IdeaWave CLI bridge")})().catch((N)=>{if(g.headersSent){g.destroy(N instanceof Error?N:void 0);return}g.writeHead(500,{"content-type":"text/plain"}),g.end("IdeaWave CLI bridge request failed")})}),C=new j7({noServer:!0,maxPayload:J}),M=(h)=>{if(h.idleTimer)clearTimeout(h.idleTimer);h.idleTimer=setTimeout(()=>{h.close()},w7),h.idleTimer.unref?.()};C.on("connection",(h,g)=>{let N=h;N.data={id:Y7(),frontendSessionId:null,frontendOrigin:new URL(v2(g.headers.origin)??A4).origin},N.idleTimer=null,M(N),N.on("ping",()=>M(N)),N.on("pong",()=>M(N)),N.on("error",()=>{if(N.idleTimer)clearTimeout(N.idleTimer);N.close()}),N.on("message",(G)=>{M(N);let u=y7(G);if(J>0&&u.length>J)return;let D=M1(u);if(!D)return;let R=N.data.frontendSessionId;if(!R){if(D.type==="bridge_probe")o0(N,{type:"bridge_probe_ack",protocolVersion:D.protocolVersion});else if(D.type==="frontend_hello")w(N,D);return}B(R,D)}),N.on("close",()=>{if(N.idleTimer)clearTimeout(N.idleTimer);let G=N.data.frontendSessionId;if(!G)return;if(W.get(G)!==N)return;if(W.delete(G),H(G),V)return;K.set(G,setTimeout(()=>U(G),U7))})}),x.on("upgrade",(h,g,N)=>{let G=new URL(h.url??"/","http://127.0.0.1").pathname;if(X.onHttpUpgrade?.(h,g,N))return;if(G!==EX){I4(g,404,"Not Found");return}if(!kX(v2(h.headers.origin))){I4(g,403,"Forbidden");return}C.handleUpgrade(h,g,N,(u)=>{C.emit("connection",u,h)})});try{let h=await f7(x,y);return{url:`ws://127.0.0.1:${h}${EX}`,port:h,sendStatus:F,close:async()=>{V=!0;for(let g of K.values())clearTimeout(g);K.clear();for(let g of C.clients){let N=g;if(N.idleTimer)clearTimeout(N.idleTimer);N.close()}C.close(),await S4(x).catch(()=>{return})}}}catch(h){if(C.close(),await S4(x).catch(()=>{return}),h?.code==="EADDRINUSE")continue;throw h}}throw Error(`No free IdeaWave CLI bridge port found in ${Z[0]}-${Z.at(-1)}`)}import{lstat as I7,readFile as S7}from"node:fs/promises";import l7 from"node:os";import y1 from"node:path";import{Server as A7}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as T7,ListToolsRequestSchema as c7}from"@modelcontextprotocol/sdk/types.js";var uX=new Set(["list_boards","get_board","screenshot_board","list_nodes","list_edges","inspect_node","list_context_sources","read_context_card","read_context_file","read_context_image","list_context_folder","get_board_wiki","search_board","get_card_messages","list_agent_cards","inspect_neighbors"]),O7=["screenshot_board","inspect_diagram","ask_user_question","create_agent_card","append_user_message","spawn_child_agents"],R7=new Set(O7),jY=new Set([...uX].filter((X)=>!R7.has(X)));import{randomUUID as h7}from"node:crypto";import{createServer as N7}from"node:http";import{StreamableHTTPServerTransport as M7}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as p4}from"@modelcontextprotocol/sdk/types.js";var a4=new Set(["127.0.0.1","localhost","[::1]","::1"]);function C7(X){let Z=X.trim();if(Z.length===0)return null;if(Z.startsWith("[")){let V=Z.indexOf("]");if(V===-1)return null;let H=Z.slice(0,V+1),U=Z.slice(V+1);if(U.length===0)return{host:H,port:null};if(!U.startsWith(":"))return null;let F=Number(U.slice(1));if(!Number.isInteger(F)||F<=0||F>65535)return null;return{host:H,port:F}}let W=Z.lastIndexOf(":");if(W===-1)return{host:Z,port:null};let K=Z.slice(W+1),J=Number(K);if(!Number.isInteger(J)||J<=0||J>65535)return{host:Z,port:null};return{host:Z.slice(0,W),port:J}}function i4(X){return a4.has(X)||a4.has(X.toLowerCase())}function d4(X,Z){let W=X.headers.host;if(typeof W!=="string")return{ok:!1,status:403,reason:"missing-host"};let K=C7(W);if(!K)return{ok:!1,status:403,reason:"bad-host"};if(!i4(K.host))return{ok:!1,status:403,reason:"non-loopback-host"};if(K.port!==null&&K.port!==Z)return{ok:!1,status:403,reason:"host-port-mismatch"};let J=X.headers.origin;if(typeof J==="string"&&J.length>0){if(J!=="null"){let V;try{V=new URL(J)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!i4(V.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var s4="/mcp",g7=43274,o4=16777216,D7=1800000,m7=300000,r4=200,$7=-32700,N0=-32600,IX=-32603;function Y0(X,Z,W,K,J){X.statusCode=Z,X.setHeader("content-type","application/json"),X.end(JSON.stringify({jsonrpc:"2.0",error:{code:W,message:K,...J?{data:J}:{}},id:null}))}class SX extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class lX extends Error{constructor(){super(`body exceeds ${o4} bytes`);this.name="BodyTooLargeError"}}async function G7(X){if(X.method&&X.method!=="POST")return;let Z=X.headers["content-type"];if(typeof Z==="string"&&Z.trim().length>0){if(!Z.toLowerCase().includes("application/json"))throw new SX}let W=0,K=[];for await(let V of X){let H=typeof V==="string"?Buffer.from(V):V;if(W+=H.byteLength,W>o4)throw new lX;K.push(H)}if(K.length===0)return;let J=Buffer.concat(K).toString("utf8");if(J.length===0)return;return JSON.parse(J)}function E7(X){if(Array.isArray(X))return X.some(p4);return p4(X)}function _7(X){if(typeof X==="number")return X;let Z=process.env.IDEAWAVE_MCP_PORT;if(Z&&Z.trim().length>0){let W=Number(Z);if(Number.isInteger(W)&&W>=0&&W<65536)return W}return g7}async function k7(X,Z){let W=(J)=>new Promise((V,H)=>{let U=(w)=>{X.off("listening",F),H(w)},F=()=>{X.off("error",U),V()};X.once("error",U),X.once("listening",F),X.listen(J,"127.0.0.1")});try{await W(Z)}catch(J){if(J.code!=="EADDRINUSE"||Z===0)throw J;console.warn(`[mcp] port ${Z} in use, falling back to an OS-assigned port; external CLIs will need to re-paste the install command from Settings → External agents`),await W(0)}let K=X.address();if(K==null||typeof K==="string")throw Error("[mcp] failed to read bound address");return K.port}function u7(X,Z){if(Z&&typeof Z==="object"&&!Array.isArray(Z)){let K=Z.params;if(K&&typeof K==="object"&&!Array.isArray(K)){let J=K.clientInfo;if(J&&typeof J==="object"&&!Array.isArray(J)){let V=J.name;if(typeof V==="string"&&V.trim().length>0)return V.trim()}}}let W=X.headers["user-agent"];if(typeof W==="string"&&W.trim().length>0)return W.trim();return null}async function n4(X){let Z=new Map,W=0;function K(w){let B=Z.get(w);if(B)B.lastActivity=Date.now()}async function J(w,B){Z.delete(w),await B.transport.close().catch(()=>{return})}async function V(){let w=null,B=1/0;for(let[b,v]of Z)if(v.lastActivity<B)B=v.lastActivity,w=b;if(w!==null){let b=Z.get(w);if(b)console.warn(`[mcp] session cap of ${r4} reached; evicting ${w}`),await J(w,b)}}let H=setInterval(()=>{let w=Date.now()-D7;for(let[B,b]of Z)if(b.lastActivity<w)console.log(`[mcp] sweeping idle session ${B}`),J(B,b)},m7);H.unref?.();let U=N7((w,B)=>{(async()=>{let b;try{b=new URL(w.url??"/","http://127.0.0.1").pathname}catch{Y0(B,400,N0,"bad-url");return}if(b!==s4){Y0(B,404,N0,"not-found");return}let v=w.method??"POST";if(v!=="POST"&&v!=="GET"&&v!=="DELETE"){B.setHeader("Allow","GET, POST, DELETE"),Y0(B,405,N0,"method-not-allowed");return}let y=d4(w,W);if(!y.ok){Y0(B,y.status,N0,"forbidden",{reason:y.reason});return}let x=w.headers["mcp-session-id"],C=typeof x==="string"?x:void 0;if(v==="GET"||v==="DELETE"){if(!C||!Z.has(C)){Y0(B,400,N0,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let g=Z.get(C).transport;K(C);try{await g.handleRequest(w,B)}catch(N){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",N),!B.headersSent)Y0(B,500,IX,"internal")}return}let M;try{M=await G7(w)}catch(g){if(g instanceof SX){Y0(B,415,N0,"expected-application-json");return}if(g instanceof lX){Y0(B,413,N0,"body-too-large");return}Y0(B,400,$7,"invalid-json");return}let h;if(C&&Z.has(C))h=Z.get(C).transport,K(C);else if(!C&&M!==void 0&&E7(M)){let g=w.headers["x-ideawave-user-id"],N=typeof g==="string"&&g.trim().length>0?g.trim():null,G=w.headers["x-ideawave-frontend-session-id"],u=typeof G==="string"&&G.trim().length>0?G.trim():null,D=w.headers["x-ideawave-tool-surface"],R=typeof D==="string"&&D.trim()==="read"?"read":"full",O=w.headers["x-ideawave-images-supported"],$=typeof O==="string"&&O.trim()==="1",A=w.headers["x-ideawave-card-id"],s=typeof A==="string"&&A.trim().length>0?A.trim():null,b0=w.headers["x-ideawave-board-id"],k=typeof b0==="string"&&b0.trim().length>0?b0.trim():null,d=w.headers["x-ideawave-run-folder"],T=typeof d==="string"&&d.trim().length>0?d.trim():null,Q0=u7(w,M);if(Z.size>=r4)await V();let r=null,w0=new M7({sessionIdGenerator:()=>h7(),onsessioninitialized:(S0)=>{r=S0,Z.set(S0,{transport:w0,lastActivity:Date.now()})},onsessionclosed:(S0)=>{Z.delete(S0)}});w0.onclose=()=>{if(w0.sessionId)Z.delete(w0.sessionId)};try{await X.buildServer({userId:N,frontendSessionId:u,boardId:k,toolSurface:R,imagesSupported:$,cardId:s,runFolder:T,clientHint:Q0}).connect(w0)}catch(S0){if(console.error("[mcp] buildServer/connect failed",S0),r)Z.delete(r);await w0.close().catch(()=>{return}),Y0(B,500,IX,"server-init-failed");return}h=w0}else{Y0(B,400,N0,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await h.handleRequest(w,B,M)}catch(g){if(console.error("[mcp] transport.handleRequest threw",g),!B.headersSent)Y0(B,500,IX,"internal")}})().catch((b)=>{console.error("[mcp] unhandled request handler error:",b)})});return W=await k7(U,_7(X.port)),{url:`http://127.0.0.1:${W}${s4}`,port:W,close:async()=>{clearInterval(H);for(let w of Z.values())await w.transport.close().catch(()=>{return});Z.clear(),await new Promise((w)=>U.close(()=>w()))}}}var a7={name:"ideawave-board",version:"1.0.0"},y2="list_run_folder",f2="read_run_folder_file",X8=new Set([...uX,y2,f2]),Z8=new Set(["inspect_diagram"]),i7=[{name:y2,description:"List visible files and folders under the selected runtime run folder. Hidden/config folders are omitted.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Optional relative path inside the selected run folder. Defaults to the run-folder root."}},additionalProperties:!1}},{name:f2,description:"Read a text file inside the selected runtime run folder. Hidden/config paths and outside-folder paths are denied.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Relative path to a text file inside the selected run folder."}},required:["path"],additionalProperties:!1}}];function AX(X){return{content:[{type:"text",text:X}]}}function d7(X){return AX(JSON.stringify(X,null,2))}function t4(X){return{...AX(X),isError:!0}}async function p7(X,Z){if(!Z||X.isError)return X;let W=X.content.find((V)=>V.type==="text");if(!W)return X;let K;try{let V=JSON.parse(W.text);if(typeof V.path!=="string")return X;K=y1.resolve(V.path)}catch{return X}let J=y1.resolve(y1.join(l7.tmpdir(),"ideawave-screenshots"));if(y1.dirname(K)!==J||!/^board-[a-z0-9-]+\.png$/i.test(y1.basename(K)))return X;try{if(!(await I7(K)).isFile())return X;let H=await S7(K);if(H.byteLength<1024||H.byteLength>26214400||!H.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return X;return{...X,content:[...X.content,{type:"image",data:H.toString("base64"),mimeType:"image/png"}]}}catch{return X}}function s7(X,Z,W="full",K=!1){return X.getMetadata(Z).filter((J)=>{let V=H2(J.name);if(W==="read"&&!X8.has(V))return!1;if(!K&&Z8.has(V))return!1;return!0}).map((J)=>({name:J.name,description:J.description,inputSchema:J.inputSchema}))}function r7(X,Z,W={}){let K=s7(X,Z,W.toolSurface??"full",W.imagesSupported??!1);return W.includeRunFolderTools?[...K,...i7]:K}function e4(X,Z){if(!X||typeof X!=="object"||Array.isArray(X))return null;let W=X[Z];return typeof W==="string"?W:null}async function o7(X,Z,W){if(W&&W.trim().length>0)return W.trim();if(!X||!Z)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await C0({boardId:X,cardId:Z})).runFolder}async function n7(X){let Z=await o7(X.boardId,X.cardId,X.runFolder);if(X.name===y2){let W=e4(X.args,"path")??"",K=await r3(Z,W);return d7(K)}if(X.name===f2){let W=e4(X.args,"path");if(!W)return t4("read_run_folder_file requires a path.");return AX(await j2(Z,W))}return t4(`Unknown local tool "${X.name}"`)}function t7(X,Z,W,K,J,V="full",H=!1){let U=new A7(a7,{capabilities:{tools:{}}}),F=async()=>{if(H)return!0;if(L4(K))return!0;if(W&&K)try{return(await C0({boardId:W,cardId:K})).adapter.supportsImages===!0}catch{return!1}return!1};return U.setRequestHandler(c7,async()=>({tools:r7(X,Z,{includeRunFolderTools:Boolean(J||W&&K),toolSurface:V,imagesSupported:await F()})})),U.setRequestHandler(T7,async(w)=>{let{name:B,arguments:b}=w.params,v=H2(B),y=Date.now();E("mcp.tool_call_received",{frontendSessionId:Z,cardId:K,toolName:v});try{if(v===y2||v===f2)return await n7({name:v,args:b,boardId:W,cardId:K,runFolder:J});if(V==="read"&&!X8.has(v))throw Error(`Tool "${B}" is not available in read-only mode`);if(Z8.has(v)&&!await F())throw Error(`Tool "${B}" requires a runtime that supports image input`);let x=await X.callTool(Z,v,b??{},void 0,K??void 0);if(E("mcp.tool_result_returned",{frontendSessionId:Z,cardId:K,toolName:v,elapsedMs:Date.now()-y}),x&&typeof x==="object"&&Array.isArray(x.content)){let C=x;return v==="screenshot_board"?await p7(C,await F()):C}return{content:[{type:"text",text:typeof x==="string"?x:JSON.stringify(x)}]}}catch(x){return E("mcp.tool_result_returned",{frontendSessionId:Z,cardId:K,toolName:v,elapsedMs:Date.now()-y,hasError:!0}),{content:[{type:"text",text:x instanceof Error?x.message:"Tool call failed"}],isError:!0}}}),U}function W8(X,Z){return n4({buildServer:(W)=>t7(X,W.frontendSessionId,W.boardId,W.cardId,W.runFolder,W.toolSurface,W.imagesSupported),port:Z})}import O2 from"node:fs/promises";import TX from"node:os";import R2 from"node:path";function Q8(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function e7(){let[X,Z]=await Promise.all([K0(),u6()]),W=X.globalDefaultConfigId?X.runtimes.find((K)=>K.id===X.globalDefaultConfigId)??null:null;return{runtimes:X.runtimes,globalDefaultConfigId:X.globalDefaultConfigId,globalDefaultEffective:W?{runFolder:W.runFolder??TX.homedir(),modelId:W.defaultModelId??null,configValues:W.defaultConfigValues??{}}:null,knownAdapters:T0().map((K)=>({id:K.id,displayName:K.displayName})),readiness:Z}}async function XQ(X){try{let Z=await C0({boardId:X.boardId,cardId:X.cardId});return{resolved:{configId:Z.entry.id,adapterId:Z.entry.kind==="registered"?Z.entry.adapterId:null,displayName:Z.entry.displayName,runFolder:Z.runFolder,modelId:Z.modelId,configValues:Z.configValues}}}catch(Z){if(Z instanceof D0)return{resolved:null};throw Z}}async function ZQ(X){return z0((Z)=>{let W=Z.runtimes.find((V)=>V.kind==="registered"&&V.adapterId===X.adapterId);if(W)return W;let K=T0().find((V)=>V.id===X.adapterId);if(!K)throw Error(`Unknown adapterId: ${X.adapterId}`);let J={id:Q8(),kind:"registered",adapterId:X.adapterId,displayName:K.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(J),J})}async function WQ(X){return z0((Z)=>{let W={id:Q8(),kind:"custom",displayName:X.displayName,command:X.command,args:X.args,env:X.env,runFolder:X.runFolder,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(W),W})}async function QQ(X){await z0((Z)=>{if(Z.runtimes=Z.runtimes.filter((W)=>W.id!==X.runtimeConfigId),Z.globalDefaultConfigId===X.runtimeConfigId)Z.globalDefaultConfigId=null;for(let W of Object.keys(Z.boardOverrides))if(Z.boardOverrides[W].runtimeConfigId===X.runtimeConfigId)delete Z.boardOverrides[W];for(let W of Object.keys(Z.cardOverrides))if(Z.cardOverrides[W].runtimeConfigId===X.runtimeConfigId)delete Z.cardOverrides[W]})}async function KQ(X){await z0((Z)=>{let W=Z.runtimes.find((K)=>K.id===X.runtimeConfigId);if(!W)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);if(Z.globalDefaultConfigId=X.runtimeConfigId,X.runFolder!==void 0)W.runFolder=X.runFolder;if(X.modelId!==void 0)W.defaultModelId=X.modelId;if(X.configValues!==void 0)W.defaultConfigValues=X.configValues})}async function JQ(X){X.boardId,await z0((Z)=>{if(X.runtimeConfigId===null){delete Z.cardOverrides[X.cardId];return}if(!Z.runtimes.some((J)=>J.id===X.runtimeConfigId))throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let K=Z.cardOverrides[X.cardId];Z.cardOverrides[X.cardId]={runtimeConfigId:X.runtimeConfigId,runFolder:X.runFolder!==void 0?X.runFolder:K?.runFolder??null,modelId:X.modelId!==void 0?X.modelId:K?.modelId??null,configValues:X.configValues!==void 0?X.configValues:K?.configValues??{}}})}async function VQ(X){let W=(await K0()).runtimes.find((H)=>H.id===X.runtimeConfigId);if(!W)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let K=F0(W),J=await K.resolveSpawnConfig(W),V=W.runFolder??TX.homedir();try{let H=await U4({spawn:{...J,cwd:V},modelId:X.modelId??W.defaultModelId??null,configValues:X.configValues??W.defaultConfigValues??{}}),U=Y2({adapterId:K.id,models:H.models,currentModelId:H.currentModelId}),F=new Date().toISOString();return await z0((w)=>{let B=w.runtimes.find((b)=>b.id===X.runtimeConfigId);if(B)B.discoveredModels=U,B.discoveredConfigOptions=H.configOptions,B.discoveredAt=F}),{ok:!0,models:U,configOptions:H.configOptions,currentModelId:H.currentModelId}}catch(H){if(H instanceof l0)throw Error(`${H.message}${K.authHint?` ${K.authHint}`:""}`);if(H instanceof I||H instanceof U0)throw Error(H.message);throw H}}async function YQ(X){let Z=TX.homedir(),W=X.path?.trim()?X.path.trim():Z,K=R2.resolve(W),J=!0;try{if(!(await O2.stat(K)).isDirectory())K=R2.dirname(K)}catch{J=!1,K=Z}let V=[];try{V=(await O2.readdir(K,{withFileTypes:!0})).filter((F)=>F.isDirectory()&&!F.name.startsWith(".")).map((F)=>({name:F.name,path:R2.join(K,F.name)})).sort((F,w)=>F.name.localeCompare(w.name))}catch{V=[]}let H=R2.dirname(K);return{path:K,parent:H===K?null:H,home:Z,exists:J,entries:V}}var K8={list:e7,getEffectiveForCard:XQ,registerRegistered:ZQ,registerCustom:WQ,unregister:QQ,setUserDefault:KQ,setCardOverride:JQ,refreshModels:VQ,browseFolder:YQ};var zQ=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function jQ(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function J8(){try{let X=await K0();if(X.globalDefaultConfigId){if(X.runtimes.some((W)=>W.id===X.globalDefaultConfigId))return X.globalDefaultConfigId}for(let Z of zQ){if((await I6(Z.id))?.status!=="ready")continue;let K=null;if(await z0((J)=>{if(J.globalDefaultConfigId){if(J.runtimes.some((U)=>U.id===J.globalDefaultConfigId)){K=J.globalDefaultConfigId;return}}let V=J.runtimes.find((H)=>H.kind==="registered"&&H.adapterId===Z.id);if(!V){let H={id:jQ(),kind:"registered",adapterId:Z.id,displayName:Z.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};J.runtimes.push(H),V=H}J.globalDefaultConfigId=V.id,K=V.id}),K)return console.log(`[ideawave-cli] using agent runtime: ${Z.displayName}`),K}return console.warn("[ideawave-cli] no agent runtime detected on PATH (tried claude, codex, gh copilot, opencode). Install one to run agents."),null}catch(X){return console.warn("[ideawave-cli] runtime auto-seed failed",X),null}}var HQ=240000;function wQ(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class cX{sessions=new Map;createCallId;toolCallTimeoutMs;constructor(X={}){this.createCallId=X.createCallId??wQ,this.toolCallTimeoutMs=X.toolCallTimeoutMs??HQ}register(X){let Z=this.sessions.get(X.frontendSessionId);if(Z){if(Z.userId!==X.userId)this.rejectPending(Z,"frontend session user changed"),Z.activeRunIds.clear();this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:Z.pendingToolCalls,activeRunIds:Z.activeRunIds,activeRunCardIds:Z.activeRunCardIds});return}this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:new Map,activeRunIds:new Set,activeRunCardIds:new Map})}disconnect(X,Z="frontend session disconnected"){let W=this.sessions.get(X);if(!W)return{activeRunIds:[]};return this.sessions.delete(X),this.rejectPending(W,Z),{activeRunIds:Array.from(W.activeRunIds)}}sessionCount(){return this.sessions.size}has(X){return this.sessions.has(X)}getUserId(X){return this.sessions.get(X)?.userId??null}setMetadata(X,Z){let W=this.sessions.get(X);if(W)W.tools=Z}getMetadata(X){if(!X)return[];return this.sessions.get(X)?.tools??[]}sendToSession(X,Z){let W=this.sessions.get(X);if(!W)return!1;return W.send(Z),!0}callTool(X,Z,W,K,J){if(!X)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let V=this.sessions.get(X);if(!V)return Promise.reject(Error(`Frontend session ${X} is not connected`));let H=this.createCallId();return new Promise((U,F)=>{let w=K??(J?this.getActiveRunIdForCard(V,J):this.getSoleActiveRunId(V)),B=J??(w?V.activeRunCardIds.get(w):void 0),b=Date.now(),v=setTimeout(()=>{V.pendingToolCalls.delete(H),E("tool_queue.timeout",{frontendSessionId:X,runId:w,cardId:B,callId:H,toolName:Z,elapsedMs:Date.now()-b,queueDepth:V.pendingToolCalls.size}),F(Error(`Tool "${Z}" timed out waiting for the frontend`))},this.toolCallTimeoutMs);V.pendingToolCalls.set(H,{resolve:U,reject:F,timer:v,name:Z,runId:w??null,cardId:B??null,startedAt:b}),E("tool_queue.forwarded_to_browser",{frontendSessionId:X,runId:w,cardId:B,callId:H,toolName:Z,queueDepth:V.pendingToolCalls.size}),V.send({type:"tool_call",callId:H,name:Z,args:W,...w?{runId:w}:{},...B?{cardId:B}:{}})})}handleToolResult(X,Z){let W=this.sessions.get(X);if(!W)return;let K=W.pendingToolCalls.get(Z.callId);if(!K)return;if(W.pendingToolCalls.delete(Z.callId),clearTimeout(K.timer),E("tool_queue.result_received",{frontendSessionId:X,runId:K.runId,cardId:K.cardId,callId:Z.callId,toolName:K.name,elapsedMs:Date.now()-K.startedAt,queueDepth:W.pendingToolCalls.size,ok:Z.ok}),Z.ok){K.resolve(Z.result);return}let J=Z.result;if(J&&typeof J==="object"&&Array.isArray(J.content)){K.resolve({...J,isError:!0});return}K.reject(Error(Z.error??"Tool execution failed"))}markRunActive(X,Z,W){let K=this.sessions.get(X);if(!K)return;if(K.activeRunIds.add(Z),W)K.activeRunCardIds.set(Z,W)}markRunSettled(X,Z){let W=this.sessions.get(X);if(!W)return;W.activeRunIds.delete(Z),W.activeRunCardIds.delete(Z)}ownsRun(X,Z){return this.sessions.get(X)?.activeRunIds.has(Z)??!1}rejectPending(X,Z){for(let W of X.pendingToolCalls.values())clearTimeout(W.timer),E("tool_queue.rejected",{frontendSessionId:X.frontendSessionId,runId:W.runId,cardId:W.cardId,toolName:W.name,elapsedMs:Date.now()-W.startedAt}),W.reject(Error(Z));X.pendingToolCalls.clear()}getSoleActiveRunId(X){return X.activeRunIds.size===1?X.activeRunIds.values().next().value:void 0}getActiveRunIdForCard(X,Z){let W=[...X.activeRunCardIds.entries()].filter(([K,J])=>X.activeRunIds.has(K)&&J===Z).map(([K])=>K);return W.length===1?W[0]:void 0}}function Y8(){return"0.0.89".trim()?"0.0.89":"dev"}var UQ=process.argv.slice(2),iX=u4(UQ,process.env);if(iX.allowRailwayPrPreviews)process.env[v1]="1";var g0=iX.cliArgs[0],{browserKitEnabled:O1,captureEngineEnabled:FQ}=iX;if(g0==="--help"||g0==="-h"||g0==="help")console.log("ideawave — host the local bridge for a running ideawave.app session."),console.log(""),console.log("Usage:"),console.log(" ideawave Serve the browser bridge and MCP forwarder."),console.log(" ideawave --version Print the CLI version."),process.exit(0);if(g0==="--version"||g0==="-v"||g0==="version")console.log(Y8()),process.exit(0);if(g0)console.error(`Unknown command: ${g0}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var R1=new cX,I0=null,qQ=O1?{phase:"ready",message:"Local browser-kit proxy is ready"}:{phase:"idle"},n0=new V2;function M0(X,Z){R1.sendToSession(X,Z)}async function BQ(X,Z){try{let W=K8[Z.method],K=await W(Z.params);M0(X,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!0,result:K})}catch(W){M0(X,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!1,error:W instanceof Error?W.message:String(W)})}}var C1=!1,f1=null;async function aX(){if(C1)return;if(f1)return f1;return f1=(async()=>{try{let X=await W8(R1);eX({...X,requestedPort:X.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${X.url}`);try{await x6({onStatusChange:(Z)=>{if(S6(),I0?.sendStatus(),Z.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${Z.packageName}: ${Z.error??"unknown error"}`)}})}catch(Z){console.warn("[ideawave-cli] ACP bridge setup skipped:",Z instanceof Error?Z.message:String(Z))}await J8(),C1=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),I0?.sendStatus()}catch(X){console.error("[ideawave-cli] failed to start agent host:",X),I0?.sendStatus(void 0,X instanceof Error?X.message:String(X))}finally{f1=null}})(),f1}if(process.env.APP_ENV!=="development"){let X=await T4();if(X)console.error(`[ideawave-cli] An IdeaWave CLI is already running at ${X}.`),console.error("[ideawave-cli] Only one CLI per machine is supported — it already serves every browser tab. Exiting."),process.exit(0)}if(FQ)N4().then((X)=>{if(X.phase==="ready")console.log("[ideawave-cli] screenshot engine ready");else if(X.phase==="failed")console.warn(`[ideawave-cli] screenshot engine setup failed: ${X.error??"unknown error"}`)});I0=await c4({registry:R1,runtime:null,mcpReady:()=>C1,capabilities:O1?[X6,Z6,W6]:[],cliVersion:Y8(),browserRuntimeStatus:()=>qQ,onToolMetadata:(X)=>{console.log(`[ideawave-cli] session ${X} advertised ${R1.getMetadata(X).length} tools`),aX()},onRunTurn:(X,Z)=>{console.log(`[ideawave-cli] running agent turn for card ${Z.cardId} (session ${X})`),(async()=>{if(await aX(),!C1){M0(X,{type:"run_settled",runId:Z.runId,cardId:Z.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"IdeaWave CLI agent host is not ready",partialText:null}});return}await y4(Z,(W)=>M0(X,W))})().catch(()=>{return}).finally(()=>R1.markRunSettled(X,Z.runId))},onCancelRun:(X,Z)=>{hX(Z)},onRuntimeRpc:(X,Z)=>{BQ(X,Z)},onBrowserRpc:(X,Z,W)=>{if(!O1){M0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!1,error:"The development browser-kit proxy is not enabled"});return}n0.handleRpc(X,Z,W).then((K)=>{M0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!0,result:K})},(K)=>{M0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!1,error:K instanceof Error?K.message:String(K)})})},onHttpRequest:(X,Z)=>O1?n0.handleHttpRequest(X,Z):!1,onHttpUpgrade:(X,Z,W)=>O1?n0.handleUpgrade(X,Z,W):!1,onWarmupRun:(X,Z,W)=>{(async()=>{if(await aX(),!C1)return{status:"retryable",error:"agent host is not ready"};return f4({cardId:Z.cardId,boardId:Z.boardId,userId:W,frontendSessionId:X})})().then((K)=>{if(!Z.warmupId)return;M0(X,{type:"warmup_result",warmupId:Z.warmupId,cardId:Z.cardId,...K})})},onDisconnect:(X,Z)=>{n0.closeFrontendSession(X),P4(X);for(let W of Z)hX(W);E("bridge.frontend_disconnected",{frontendSessionId:X,activeRuns:Z.length}),sX(X).catch((W)=>{console.warn(`[ideawave-cli] failed to evict sessions for ${X}:`,W instanceof Error?W.message:String(W))}),console.log(`[ideawave-cli] browser session ${X} disconnected`)}});n0.setPort(I0.port);console.log(`[ideawave-cli] browser bridge listening on ${I0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var V8=!1;for(let X of["SIGINT","SIGTERM"])process.once(X,()=>{if(V8)return;V8=!0,x4(),(async()=>{await n0.close(),await D4(),await I0?.close().catch(()=>{return}),process.exit(0)})()});
1073
+ ${W}`),X.destroy()}function f7(X,Z){return new Promise((W,K)=>{let J=(H)=>{X.off("listening",V),K(H)},V=()=>{X.off("error",J);let H=X.address();if(!H||typeof H==="string"){K(Error("Failed to read CLI bridge server address"));return}W(H.port)};X.once("error",J),X.once("listening",V),X.listen(Z,"127.0.0.1")})}function S4(X){return new Promise((Z,W)=>{X.close((K)=>{if(K)W(K);else Z()})})}async function c4(X,Z=_X()){let W=new Map,K=new Map,J=X.maxMessageSize??H7,V=!1,H=(y)=>{let x=K.get(y);if(x)clearTimeout(x);K.delete(y)},U=(y)=>{K.delete(y);let{activeRunIds:x}=X.registry.disconnect(y);X.onDisconnect(y,x)},F=(y,x)=>{let C={type:"cli_status",connected:!0,runtime:X.runtime,mcpReady:X.mcpReady(),error:x,capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()};if(y){let M=W.get(y);if(M)o0(M,C);return}for(let M of W.values())o0(M,C)},w=(y,x)=>{let C=x.sessionId.trim(),M=x.userId.trim();if(!C||!M){o0(y,{type:"cli_status",connected:!1,runtime:X.runtime,mcpReady:X.mcpReady(),error:"Missing frontend session or user id"}),y.close();return}H(C);let h=W.get(C);if(h&&h!==y)h.close();y.data.frontendSessionId=C,W.set(C,y),X.registry.register({frontendSessionId:C,userId:M,tools:x.tools,send:(g)=>o0(y,g)}),F(C),X.onToolMetadata?.(C)},B=(y,x)=>{let C=X.registry.getUserId(y);if(!C)return;switch(x.type){case"bridge_ping":{let M=W.get(y);if(M)o0(M,{type:"bridge_pong"});break}case"tool_metadata":X.registry.setMetadata(y,x.tools),X.onToolMetadata?.(y);break;case"tool_result":X.registry.handleToolResult(y,x);break;case"run_turn":E("bridge.run_received",{runId:x.run.runId,cardId:x.run.cardId,frontendSessionId:y}),X.registry.markRunActive(y,x.run.runId,x.run.cardId),X.onRunTurn(y,{...x.run,frontendSessionId:y,userId:C});break;case"cancel_run":if(X.registry.ownsRun(y,x.runId))X.onCancelRun(y,x.runId);break;case"runtime_rpc":X.onRuntimeRpc(y,x);break;case"browser_rpc":X.onBrowserRpc?.(y,W.get(y)?.data.frontendOrigin??"",x);break;case"warmup_run":X.onWarmupRun(y,{...x,frontendSessionId:y},C);break;default:break}},b=(y,x)=>{let C=v2(y.headers.origin),M=kX(C),h={Vary:"Origin"};if(M&&C)h["Access-Control-Allow-Origin"]=C,h["Access-Control-Allow-Private-Network"]="true";if(y.method==="OPTIONS"){x.writeHead(204,{...h,"Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*","Access-Control-Max-Age":"600"}),x.end();return}if(y.method!=="GET"){x.writeHead(405,h),x.end();return}x.writeHead(200,{...h,"content-type":"application/json","cache-control":"no-store"}),x.end(JSON.stringify({ideawave:!0,runtime:X.runtime,mcpReady:X.mcpReady(),capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()}))},v=(y,x)=>{let C=v2(y.headers.origin),M=kX(C),h={Vary:"Origin"};if(M&&C)h["Access-Control-Allow-Origin"]=C,h["Access-Control-Allow-Private-Network"]="true";if(y.method==="OPTIONS"){x.writeHead(204,{...h,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"content-type","Access-Control-Max-Age":"600"}),x.end();return}if(!M){x.writeHead(403,h),x.end();return}if(y.method!=="POST"){x.writeHead(405,h),x.end();return}let g={...h,"content-type":"application/json"},N=(D,R)=>{x.writeHead(D,g),x.end(JSON.stringify(R))},G="",u=!1;y.on("data",(D)=>{if(G+=D.toString("utf8"),G.length>q7)u=!0,y.destroy()}),y.on("end",()=>{if(u){N(400,{ok:!1,error:"Request body too large"});return}let D;try{D=JSON.parse(G)}catch{N(400,{ok:!1,error:"Invalid JSON body"});return}let R=typeof D.url==="string"?D.url:"";if(!_4(R)){N(400,{ok:!1,error:"url must be an http(s) loopback or /static_boards/ page URL"});return}let O=($,A)=>{let s=typeof $==="number"?$:Number.NaN;if(!Number.isFinite(s))return A;return Math.min(4000,Math.max(200,Math.round(s)))};k4({url:R,width:O(D.width,1440),height:O(D.height,900)}).then(($)=>N(200,{ok:!0,path:$.path,engine:$.engine})).catch(($)=>{let A=$ instanceof b1?503:$ instanceof b2?429:500;N(A,{ok:!1,...$ instanceof b1?{installing:!0}:{},error:$ instanceof Error?$.message:String($)})})})};for(let y of Z){let x=z7((h,g)=>{(async()=>{let N=new URL(h.url??"/","http://127.0.0.1").pathname;if(N===m4){b(h,g);return}if(N===F7){v(h,g);return}if(await X.onHttpRequest?.(h,g))return;g.writeHead(404,{"content-type":"text/plain"}),g.end("IdeaWave CLI bridge")})().catch((N)=>{if(g.headersSent){g.destroy(N instanceof Error?N:void 0);return}g.writeHead(500,{"content-type":"text/plain"}),g.end("IdeaWave CLI bridge request failed")})}),C=new j7({noServer:!0,maxPayload:J}),M=(h)=>{if(h.idleTimer)clearTimeout(h.idleTimer);h.idleTimer=setTimeout(()=>{h.close()},w7),h.idleTimer.unref?.()};C.on("connection",(h,g)=>{let N=h;N.data={id:Y7(),frontendSessionId:null,frontendOrigin:new URL(v2(g.headers.origin)??A4).origin},N.idleTimer=null,M(N),N.on("ping",()=>M(N)),N.on("pong",()=>M(N)),N.on("error",()=>{if(N.idleTimer)clearTimeout(N.idleTimer);N.close()}),N.on("message",(G)=>{M(N);let u=y7(G);if(J>0&&u.length>J)return;let D=M1(u);if(!D)return;let R=N.data.frontendSessionId;if(!R){if(D.type==="bridge_probe")o0(N,{type:"bridge_probe_ack",protocolVersion:D.protocolVersion});else if(D.type==="frontend_hello")w(N,D);return}B(R,D)}),N.on("close",()=>{if(N.idleTimer)clearTimeout(N.idleTimer);let G=N.data.frontendSessionId;if(!G)return;if(W.get(G)!==N)return;if(W.delete(G),H(G),V)return;K.set(G,setTimeout(()=>U(G),U7))})}),x.on("upgrade",(h,g,N)=>{let G=new URL(h.url??"/","http://127.0.0.1").pathname;if(X.onHttpUpgrade?.(h,g,N))return;if(G!==EX){I4(g,404,"Not Found");return}if(!kX(v2(h.headers.origin))){I4(g,403,"Forbidden");return}C.handleUpgrade(h,g,N,(u)=>{C.emit("connection",u,h)})});try{let h=await f7(x,y);return{url:`ws://127.0.0.1:${h}${EX}`,port:h,sendStatus:F,close:async()=>{V=!0;for(let g of K.values())clearTimeout(g);K.clear();for(let g of C.clients){let N=g;if(N.idleTimer)clearTimeout(N.idleTimer);N.close()}C.close(),await S4(x).catch(()=>{return})}}}catch(h){if(C.close(),await S4(x).catch(()=>{return}),h?.code==="EADDRINUSE")continue;throw h}}throw Error(`No free IdeaWave CLI bridge port found in ${Z[0]}-${Z.at(-1)}`)}import{lstat as I7,readFile as S7}from"node:fs/promises";import l7 from"node:os";import y1 from"node:path";import{Server as A7}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as T7,ListToolsRequestSchema as c7}from"@modelcontextprotocol/sdk/types.js";var uX=new Set(["list_boards","get_board","screenshot_board","list_nodes","list_edges","inspect_node","list_context_sources","read_context_card","read_context_file","read_context_image","list_context_folder","get_board_wiki","search_board","get_card_messages","list_agent_cards","inspect_neighbors"]),O7=["screenshot_board","inspect_diagram","ask_user_question","create_agent_card","append_user_message","spawn_child_agents"],R7=new Set(O7),jY=new Set([...uX].filter((X)=>!R7.has(X)));import{randomUUID as h7}from"node:crypto";import{createServer as N7}from"node:http";import{StreamableHTTPServerTransport as M7}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as p4}from"@modelcontextprotocol/sdk/types.js";var a4=new Set(["127.0.0.1","localhost","[::1]","::1"]);function C7(X){let Z=X.trim();if(Z.length===0)return null;if(Z.startsWith("[")){let V=Z.indexOf("]");if(V===-1)return null;let H=Z.slice(0,V+1),U=Z.slice(V+1);if(U.length===0)return{host:H,port:null};if(!U.startsWith(":"))return null;let F=Number(U.slice(1));if(!Number.isInteger(F)||F<=0||F>65535)return null;return{host:H,port:F}}let W=Z.lastIndexOf(":");if(W===-1)return{host:Z,port:null};let K=Z.slice(W+1),J=Number(K);if(!Number.isInteger(J)||J<=0||J>65535)return{host:Z,port:null};return{host:Z.slice(0,W),port:J}}function i4(X){return a4.has(X)||a4.has(X.toLowerCase())}function d4(X,Z){let W=X.headers.host;if(typeof W!=="string")return{ok:!1,status:403,reason:"missing-host"};let K=C7(W);if(!K)return{ok:!1,status:403,reason:"bad-host"};if(!i4(K.host))return{ok:!1,status:403,reason:"non-loopback-host"};if(K.port!==null&&K.port!==Z)return{ok:!1,status:403,reason:"host-port-mismatch"};let J=X.headers.origin;if(typeof J==="string"&&J.length>0){if(J!=="null"){let V;try{V=new URL(J)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!i4(V.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var s4="/mcp",g7=43274,o4=16777216,D7=1800000,m7=300000,r4=200,$7=-32700,N0=-32600,IX=-32603;function Y0(X,Z,W,K,J){X.statusCode=Z,X.setHeader("content-type","application/json"),X.end(JSON.stringify({jsonrpc:"2.0",error:{code:W,message:K,...J?{data:J}:{}},id:null}))}class SX extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class lX extends Error{constructor(){super(`body exceeds ${o4} bytes`);this.name="BodyTooLargeError"}}async function G7(X){if(X.method&&X.method!=="POST")return;let Z=X.headers["content-type"];if(typeof Z==="string"&&Z.trim().length>0){if(!Z.toLowerCase().includes("application/json"))throw new SX}let W=0,K=[];for await(let V of X){let H=typeof V==="string"?Buffer.from(V):V;if(W+=H.byteLength,W>o4)throw new lX;K.push(H)}if(K.length===0)return;let J=Buffer.concat(K).toString("utf8");if(J.length===0)return;return JSON.parse(J)}function E7(X){if(Array.isArray(X))return X.some(p4);return p4(X)}function _7(X){if(typeof X==="number")return X;let Z=process.env.IDEAWAVE_MCP_PORT;if(Z&&Z.trim().length>0){let W=Number(Z);if(Number.isInteger(W)&&W>=0&&W<65536)return W}return g7}async function k7(X,Z){let W=(J)=>new Promise((V,H)=>{let U=(w)=>{X.off("listening",F),H(w)},F=()=>{X.off("error",U),V()};X.once("error",U),X.once("listening",F),X.listen(J,"127.0.0.1")});try{await W(Z)}catch(J){if(J.code!=="EADDRINUSE"||Z===0)throw J;console.warn(`[mcp] port ${Z} in use, falling back to an OS-assigned port; external CLIs will need to re-paste the install command from Settings → External agents`),await W(0)}let K=X.address();if(K==null||typeof K==="string")throw Error("[mcp] failed to read bound address");return K.port}function u7(X,Z){if(Z&&typeof Z==="object"&&!Array.isArray(Z)){let K=Z.params;if(K&&typeof K==="object"&&!Array.isArray(K)){let J=K.clientInfo;if(J&&typeof J==="object"&&!Array.isArray(J)){let V=J.name;if(typeof V==="string"&&V.trim().length>0)return V.trim()}}}let W=X.headers["user-agent"];if(typeof W==="string"&&W.trim().length>0)return W.trim();return null}async function n4(X){let Z=new Map,W=0;function K(w){let B=Z.get(w);if(B)B.lastActivity=Date.now()}async function J(w,B){Z.delete(w),await B.transport.close().catch(()=>{return})}async function V(){let w=null,B=1/0;for(let[b,v]of Z)if(v.lastActivity<B)B=v.lastActivity,w=b;if(w!==null){let b=Z.get(w);if(b)console.warn(`[mcp] session cap of ${r4} reached; evicting ${w}`),await J(w,b)}}let H=setInterval(()=>{let w=Date.now()-D7;for(let[B,b]of Z)if(b.lastActivity<w)console.log(`[mcp] sweeping idle session ${B}`),J(B,b)},m7);H.unref?.();let U=N7((w,B)=>{(async()=>{let b;try{b=new URL(w.url??"/","http://127.0.0.1").pathname}catch{Y0(B,400,N0,"bad-url");return}if(b!==s4){Y0(B,404,N0,"not-found");return}let v=w.method??"POST";if(v!=="POST"&&v!=="GET"&&v!=="DELETE"){B.setHeader("Allow","GET, POST, DELETE"),Y0(B,405,N0,"method-not-allowed");return}let y=d4(w,W);if(!y.ok){Y0(B,y.status,N0,"forbidden",{reason:y.reason});return}let x=w.headers["mcp-session-id"],C=typeof x==="string"?x:void 0;if(v==="GET"||v==="DELETE"){if(!C||!Z.has(C)){Y0(B,400,N0,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let g=Z.get(C).transport;K(C);try{await g.handleRequest(w,B)}catch(N){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",N),!B.headersSent)Y0(B,500,IX,"internal")}return}let M;try{M=await G7(w)}catch(g){if(g instanceof SX){Y0(B,415,N0,"expected-application-json");return}if(g instanceof lX){Y0(B,413,N0,"body-too-large");return}Y0(B,400,$7,"invalid-json");return}let h;if(C&&Z.has(C))h=Z.get(C).transport,K(C);else if(!C&&M!==void 0&&E7(M)){let g=w.headers["x-ideawave-user-id"],N=typeof g==="string"&&g.trim().length>0?g.trim():null,G=w.headers["x-ideawave-frontend-session-id"],u=typeof G==="string"&&G.trim().length>0?G.trim():null,D=w.headers["x-ideawave-tool-surface"],R=typeof D==="string"&&D.trim()==="read"?"read":"full",O=w.headers["x-ideawave-images-supported"],$=typeof O==="string"&&O.trim()==="1",A=w.headers["x-ideawave-card-id"],s=typeof A==="string"&&A.trim().length>0?A.trim():null,b0=w.headers["x-ideawave-board-id"],k=typeof b0==="string"&&b0.trim().length>0?b0.trim():null,d=w.headers["x-ideawave-run-folder"],T=typeof d==="string"&&d.trim().length>0?d.trim():null,Q0=u7(w,M);if(Z.size>=r4)await V();let r=null,w0=new M7({sessionIdGenerator:()=>h7(),onsessioninitialized:(S0)=>{r=S0,Z.set(S0,{transport:w0,lastActivity:Date.now()})},onsessionclosed:(S0)=>{Z.delete(S0)}});w0.onclose=()=>{if(w0.sessionId)Z.delete(w0.sessionId)};try{await X.buildServer({userId:N,frontendSessionId:u,boardId:k,toolSurface:R,imagesSupported:$,cardId:s,runFolder:T,clientHint:Q0}).connect(w0)}catch(S0){if(console.error("[mcp] buildServer/connect failed",S0),r)Z.delete(r);await w0.close().catch(()=>{return}),Y0(B,500,IX,"server-init-failed");return}h=w0}else{Y0(B,400,N0,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await h.handleRequest(w,B,M)}catch(g){if(console.error("[mcp] transport.handleRequest threw",g),!B.headersSent)Y0(B,500,IX,"internal")}})().catch((b)=>{console.error("[mcp] unhandled request handler error:",b)})});return W=await k7(U,_7(X.port)),{url:`http://127.0.0.1:${W}${s4}`,port:W,close:async()=>{clearInterval(H);for(let w of Z.values())await w.transport.close().catch(()=>{return});Z.clear(),await new Promise((w)=>U.close(()=>w()))}}}var a7={name:"ideawave-board",version:"1.0.0"},y2="list_run_folder",f2="read_run_folder_file",X8=new Set([...uX,y2,f2]),Z8=new Set(["inspect_diagram"]),i7=[{name:y2,description:"List visible files and folders under the selected runtime run folder. Hidden/config folders are omitted.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Optional relative path inside the selected run folder. Defaults to the run-folder root."}},additionalProperties:!1}},{name:f2,description:"Read a text file inside the selected runtime run folder. Hidden/config paths and outside-folder paths are denied.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Relative path to a text file inside the selected run folder."}},required:["path"],additionalProperties:!1}}];function AX(X){return{content:[{type:"text",text:X}]}}function d7(X){return AX(JSON.stringify(X,null,2))}function t4(X){return{...AX(X),isError:!0}}async function p7(X,Z){if(!Z||X.isError)return X;let W=X.content.find((V)=>V.type==="text");if(!W)return X;let K;try{let V=JSON.parse(W.text);if(typeof V.path!=="string")return X;K=y1.resolve(V.path)}catch{return X}let J=y1.resolve(y1.join(l7.tmpdir(),"ideawave-screenshots"));if(y1.dirname(K)!==J||!/^board-[a-z0-9-]+\.png$/i.test(y1.basename(K)))return X;try{if(!(await I7(K)).isFile())return X;let H=await S7(K);if(H.byteLength<1024||H.byteLength>26214400||!H.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return X;return{...X,content:[...X.content,{type:"image",data:H.toString("base64"),mimeType:"image/png"}]}}catch{return X}}function s7(X,Z,W="full",K=!1){return X.getMetadata(Z).filter((J)=>{let V=H2(J.name);if(W==="read"&&!X8.has(V))return!1;if(!K&&Z8.has(V))return!1;return!0}).map((J)=>({name:J.name,description:J.description,inputSchema:J.inputSchema}))}function r7(X,Z,W={}){let K=s7(X,Z,W.toolSurface??"full",W.imagesSupported??!1);return W.includeRunFolderTools?[...K,...i7]:K}function e4(X,Z){if(!X||typeof X!=="object"||Array.isArray(X))return null;let W=X[Z];return typeof W==="string"?W:null}async function o7(X,Z,W){if(W&&W.trim().length>0)return W.trim();if(!X||!Z)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await C0({boardId:X,cardId:Z})).runFolder}async function n7(X){let Z=await o7(X.boardId,X.cardId,X.runFolder);if(X.name===y2){let W=e4(X.args,"path")??"",K=await r3(Z,W);return d7(K)}if(X.name===f2){let W=e4(X.args,"path");if(!W)return t4("read_run_folder_file requires a path.");return AX(await j2(Z,W))}return t4(`Unknown local tool "${X.name}"`)}function t7(X,Z,W,K,J,V="full",H=!1){let U=new A7(a7,{capabilities:{tools:{}}}),F=async()=>{if(H)return!0;if(L4(K))return!0;if(W&&K)try{return(await C0({boardId:W,cardId:K})).adapter.supportsImages===!0}catch{return!1}return!1};return U.setRequestHandler(c7,async()=>({tools:r7(X,Z,{includeRunFolderTools:Boolean(J||W&&K),toolSurface:V,imagesSupported:await F()})})),U.setRequestHandler(T7,async(w)=>{let{name:B,arguments:b}=w.params,v=H2(B),y=Date.now();E("mcp.tool_call_received",{frontendSessionId:Z,cardId:K,toolName:v});try{if(v===y2||v===f2)return await n7({name:v,args:b,boardId:W,cardId:K,runFolder:J});if(V==="read"&&!X8.has(v))throw Error(`Tool "${B}" is not available in read-only mode`);if(Z8.has(v)&&!await F())throw Error(`Tool "${B}" requires a runtime that supports image input`);let x=await X.callTool(Z,v,b??{},void 0,K??void 0);if(E("mcp.tool_result_returned",{frontendSessionId:Z,cardId:K,toolName:v,elapsedMs:Date.now()-y}),x&&typeof x==="object"&&Array.isArray(x.content)){let C=x;return v==="screenshot_board"?await p7(C,await F()):C}return{content:[{type:"text",text:typeof x==="string"?x:JSON.stringify(x)}]}}catch(x){return E("mcp.tool_result_returned",{frontendSessionId:Z,cardId:K,toolName:v,elapsedMs:Date.now()-y,hasError:!0}),{content:[{type:"text",text:x instanceof Error?x.message:"Tool call failed"}],isError:!0}}}),U}function W8(X,Z){return n4({buildServer:(W)=>t7(X,W.frontendSessionId,W.boardId,W.cardId,W.runFolder,W.toolSurface,W.imagesSupported),port:Z})}import O2 from"node:fs/promises";import TX from"node:os";import R2 from"node:path";function Q8(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function e7(){let[X,Z]=await Promise.all([K0(),u6()]),W=X.globalDefaultConfigId?X.runtimes.find((K)=>K.id===X.globalDefaultConfigId)??null:null;return{runtimes:X.runtimes,globalDefaultConfigId:X.globalDefaultConfigId,globalDefaultEffective:W?{runFolder:W.runFolder??TX.homedir(),modelId:W.defaultModelId??null,configValues:W.defaultConfigValues??{}}:null,knownAdapters:T0().map((K)=>({id:K.id,displayName:K.displayName})),readiness:Z}}async function XQ(X){try{let Z=await C0({boardId:X.boardId,cardId:X.cardId});return{resolved:{configId:Z.entry.id,adapterId:Z.entry.kind==="registered"?Z.entry.adapterId:null,displayName:Z.entry.displayName,runFolder:Z.runFolder,modelId:Z.modelId,configValues:Z.configValues}}}catch(Z){if(Z instanceof D0)return{resolved:null};throw Z}}async function ZQ(X){return z0((Z)=>{let W=Z.runtimes.find((V)=>V.kind==="registered"&&V.adapterId===X.adapterId);if(W)return W;let K=T0().find((V)=>V.id===X.adapterId);if(!K)throw Error(`Unknown adapterId: ${X.adapterId}`);let J={id:Q8(),kind:"registered",adapterId:X.adapterId,displayName:K.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(J),J})}async function WQ(X){return z0((Z)=>{let W={id:Q8(),kind:"custom",displayName:X.displayName,command:X.command,args:X.args,env:X.env,runFolder:X.runFolder,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(W),W})}async function QQ(X){await z0((Z)=>{if(Z.runtimes=Z.runtimes.filter((W)=>W.id!==X.runtimeConfigId),Z.globalDefaultConfigId===X.runtimeConfigId)Z.globalDefaultConfigId=null;for(let W of Object.keys(Z.boardOverrides))if(Z.boardOverrides[W].runtimeConfigId===X.runtimeConfigId)delete Z.boardOverrides[W];for(let W of Object.keys(Z.cardOverrides))if(Z.cardOverrides[W].runtimeConfigId===X.runtimeConfigId)delete Z.cardOverrides[W]})}async function KQ(X){await z0((Z)=>{let W=Z.runtimes.find((K)=>K.id===X.runtimeConfigId);if(!W)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);if(Z.globalDefaultConfigId=X.runtimeConfigId,X.runFolder!==void 0)W.runFolder=X.runFolder;if(X.modelId!==void 0)W.defaultModelId=X.modelId;if(X.configValues!==void 0)W.defaultConfigValues=X.configValues})}async function JQ(X){X.boardId,await z0((Z)=>{if(X.runtimeConfigId===null){delete Z.cardOverrides[X.cardId];return}if(!Z.runtimes.some((J)=>J.id===X.runtimeConfigId))throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let K=Z.cardOverrides[X.cardId];Z.cardOverrides[X.cardId]={runtimeConfigId:X.runtimeConfigId,runFolder:X.runFolder!==void 0?X.runFolder:K?.runFolder??null,modelId:X.modelId!==void 0?X.modelId:K?.modelId??null,configValues:X.configValues!==void 0?X.configValues:K?.configValues??{}}})}async function VQ(X){let W=(await K0()).runtimes.find((H)=>H.id===X.runtimeConfigId);if(!W)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let K=F0(W),J=await K.resolveSpawnConfig(W),V=W.runFolder??TX.homedir();try{let H=await U4({spawn:{...J,cwd:V},modelId:X.modelId??W.defaultModelId??null,configValues:X.configValues??W.defaultConfigValues??{}}),U=Y2({adapterId:K.id,models:H.models,currentModelId:H.currentModelId}),F=new Date().toISOString();return await z0((w)=>{let B=w.runtimes.find((b)=>b.id===X.runtimeConfigId);if(B)B.discoveredModels=U,B.discoveredConfigOptions=H.configOptions,B.discoveredAt=F}),{ok:!0,models:U,configOptions:H.configOptions,currentModelId:H.currentModelId}}catch(H){if(H instanceof l0)throw Error(`${H.message}${K.authHint?` ${K.authHint}`:""}`);if(H instanceof I||H instanceof U0)throw Error(H.message);throw H}}async function YQ(X){let Z=TX.homedir(),W=X.path?.trim()?X.path.trim():Z,K=R2.resolve(W),J=!0;try{if(!(await O2.stat(K)).isDirectory())K=R2.dirname(K)}catch{J=!1,K=Z}let V=[];try{V=(await O2.readdir(K,{withFileTypes:!0})).filter((F)=>F.isDirectory()&&!F.name.startsWith(".")).map((F)=>({name:F.name,path:R2.join(K,F.name)})).sort((F,w)=>F.name.localeCompare(w.name))}catch{V=[]}let H=R2.dirname(K);return{path:K,parent:H===K?null:H,home:Z,exists:J,entries:V}}var K8={list:e7,getEffectiveForCard:XQ,registerRegistered:ZQ,registerCustom:WQ,unregister:QQ,setUserDefault:KQ,setCardOverride:JQ,refreshModels:VQ,browseFolder:YQ};var zQ=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function jQ(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function J8(){try{let X=await K0();if(X.globalDefaultConfigId){if(X.runtimes.some((W)=>W.id===X.globalDefaultConfigId))return X.globalDefaultConfigId}for(let Z of zQ){if((await I6(Z.id))?.status!=="ready")continue;let K=null;if(await z0((J)=>{if(J.globalDefaultConfigId){if(J.runtimes.some((U)=>U.id===J.globalDefaultConfigId)){K=J.globalDefaultConfigId;return}}let V=J.runtimes.find((H)=>H.kind==="registered"&&H.adapterId===Z.id);if(!V){let H={id:jQ(),kind:"registered",adapterId:Z.id,displayName:Z.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};J.runtimes.push(H),V=H}J.globalDefaultConfigId=V.id,K=V.id}),K)return console.log(`[ideawave-cli] using agent runtime: ${Z.displayName}`),K}return console.warn("[ideawave-cli] no agent runtime detected on PATH (tried claude, codex, gh copilot, opencode). Install one to run agents."),null}catch(X){return console.warn("[ideawave-cli] runtime auto-seed failed",X),null}}var HQ=240000;function wQ(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class cX{sessions=new Map;createCallId;toolCallTimeoutMs;constructor(X={}){this.createCallId=X.createCallId??wQ,this.toolCallTimeoutMs=X.toolCallTimeoutMs??HQ}register(X){let Z=this.sessions.get(X.frontendSessionId);if(Z){if(Z.userId!==X.userId)this.rejectPending(Z,"frontend session user changed"),Z.activeRunIds.clear();this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:Z.pendingToolCalls,activeRunIds:Z.activeRunIds,activeRunCardIds:Z.activeRunCardIds});return}this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:new Map,activeRunIds:new Set,activeRunCardIds:new Map})}disconnect(X,Z="frontend session disconnected"){let W=this.sessions.get(X);if(!W)return{activeRunIds:[]};return this.sessions.delete(X),this.rejectPending(W,Z),{activeRunIds:Array.from(W.activeRunIds)}}sessionCount(){return this.sessions.size}has(X){return this.sessions.has(X)}getUserId(X){return this.sessions.get(X)?.userId??null}setMetadata(X,Z){let W=this.sessions.get(X);if(W)W.tools=Z}getMetadata(X){if(!X)return[];return this.sessions.get(X)?.tools??[]}sendToSession(X,Z){let W=this.sessions.get(X);if(!W)return!1;return W.send(Z),!0}callTool(X,Z,W,K,J){if(!X)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let V=this.sessions.get(X);if(!V)return Promise.reject(Error(`Frontend session ${X} is not connected`));let H=this.createCallId();return new Promise((U,F)=>{let w=K??(J?this.getActiveRunIdForCard(V,J):this.getSoleActiveRunId(V)),B=J??(w?V.activeRunCardIds.get(w):void 0),b=Date.now(),v=setTimeout(()=>{V.pendingToolCalls.delete(H),E("tool_queue.timeout",{frontendSessionId:X,runId:w,cardId:B,callId:H,toolName:Z,elapsedMs:Date.now()-b,queueDepth:V.pendingToolCalls.size}),F(Error(`Tool "${Z}" timed out waiting for the frontend`))},this.toolCallTimeoutMs);V.pendingToolCalls.set(H,{resolve:U,reject:F,timer:v,name:Z,runId:w??null,cardId:B??null,startedAt:b}),E("tool_queue.forwarded_to_browser",{frontendSessionId:X,runId:w,cardId:B,callId:H,toolName:Z,queueDepth:V.pendingToolCalls.size}),V.send({type:"tool_call",callId:H,name:Z,args:W,...w?{runId:w}:{},...B?{cardId:B}:{}})})}handleToolResult(X,Z){let W=this.sessions.get(X);if(!W)return;let K=W.pendingToolCalls.get(Z.callId);if(!K)return;if(W.pendingToolCalls.delete(Z.callId),clearTimeout(K.timer),E("tool_queue.result_received",{frontendSessionId:X,runId:K.runId,cardId:K.cardId,callId:Z.callId,toolName:K.name,elapsedMs:Date.now()-K.startedAt,queueDepth:W.pendingToolCalls.size,ok:Z.ok}),Z.ok){K.resolve(Z.result);return}let J=Z.result;if(J&&typeof J==="object"&&Array.isArray(J.content)){K.resolve({...J,isError:!0});return}K.reject(Error(Z.error??"Tool execution failed"))}markRunActive(X,Z,W){let K=this.sessions.get(X);if(!K)return;if(K.activeRunIds.add(Z),W)K.activeRunCardIds.set(Z,W)}markRunSettled(X,Z){let W=this.sessions.get(X);if(!W)return;W.activeRunIds.delete(Z),W.activeRunCardIds.delete(Z)}ownsRun(X,Z){return this.sessions.get(X)?.activeRunIds.has(Z)??!1}rejectPending(X,Z){for(let W of X.pendingToolCalls.values())clearTimeout(W.timer),E("tool_queue.rejected",{frontendSessionId:X.frontendSessionId,runId:W.runId,cardId:W.cardId,toolName:W.name,elapsedMs:Date.now()-W.startedAt}),W.reject(Error(Z));X.pendingToolCalls.clear()}getSoleActiveRunId(X){return X.activeRunIds.size===1?X.activeRunIds.values().next().value:void 0}getActiveRunIdForCard(X,Z){let W=[...X.activeRunCardIds.entries()].filter(([K,J])=>X.activeRunIds.has(K)&&J===Z).map(([K])=>K);return W.length===1?W[0]:void 0}}function Y8(){return"0.0.90".trim()?"0.0.90":"dev"}var UQ=process.argv.slice(2),iX=u4(UQ,process.env);if(iX.allowRailwayPrPreviews)process.env[v1]="1";var g0=iX.cliArgs[0],{browserKitEnabled:O1,captureEngineEnabled:FQ}=iX;if(g0==="--help"||g0==="-h"||g0==="help")console.log("ideawave — host the local bridge for a running ideawave.app session."),console.log(""),console.log("Usage:"),console.log(" ideawave Serve the browser bridge and MCP forwarder."),console.log(" ideawave --version Print the CLI version."),process.exit(0);if(g0==="--version"||g0==="-v"||g0==="version")console.log(Y8()),process.exit(0);if(g0)console.error(`Unknown command: ${g0}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var R1=new cX,I0=null,qQ=O1?{phase:"ready",message:"Local browser-kit proxy is ready"}:{phase:"idle"},n0=new V2;function M0(X,Z){R1.sendToSession(X,Z)}async function BQ(X,Z){try{let W=K8[Z.method],K=await W(Z.params);M0(X,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!0,result:K})}catch(W){M0(X,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!1,error:W instanceof Error?W.message:String(W)})}}var C1=!1,f1=null;async function aX(){if(C1)return;if(f1)return f1;return f1=(async()=>{try{let X=await W8(R1);eX({...X,requestedPort:X.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${X.url}`);try{await x6({onStatusChange:(Z)=>{if(S6(),I0?.sendStatus(),Z.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${Z.packageName}: ${Z.error??"unknown error"}`)}})}catch(Z){console.warn("[ideawave-cli] ACP bridge setup skipped:",Z instanceof Error?Z.message:String(Z))}await J8(),C1=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),I0?.sendStatus()}catch(X){console.error("[ideawave-cli] failed to start agent host:",X),I0?.sendStatus(void 0,X instanceof Error?X.message:String(X))}finally{f1=null}})(),f1}if(process.env.APP_ENV!=="development"){let X=await T4();if(X)console.error(`[ideawave-cli] An IdeaWave CLI is already running at ${X}.`),console.error("[ideawave-cli] Only one CLI per machine is supported — it already serves every browser tab. Exiting."),process.exit(0)}if(FQ)N4().then((X)=>{if(X.phase==="ready")console.log("[ideawave-cli] screenshot engine ready");else if(X.phase==="failed")console.warn(`[ideawave-cli] screenshot engine setup failed: ${X.error??"unknown error"}`)});I0=await c4({registry:R1,runtime:null,mcpReady:()=>C1,capabilities:O1?[X6,Z6,W6]:[],cliVersion:Y8(),browserRuntimeStatus:()=>qQ,onToolMetadata:(X)=>{console.log(`[ideawave-cli] session ${X} advertised ${R1.getMetadata(X).length} tools`),aX()},onRunTurn:(X,Z)=>{console.log(`[ideawave-cli] running agent turn for card ${Z.cardId} (session ${X})`),(async()=>{if(await aX(),!C1){M0(X,{type:"run_settled",runId:Z.runId,cardId:Z.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"IdeaWave CLI agent host is not ready",partialText:null}});return}await y4(Z,(W)=>M0(X,W))})().catch(()=>{return}).finally(()=>R1.markRunSettled(X,Z.runId))},onCancelRun:(X,Z)=>{hX(Z)},onRuntimeRpc:(X,Z)=>{BQ(X,Z)},onBrowserRpc:(X,Z,W)=>{if(!O1){M0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!1,error:"The development browser-kit proxy is not enabled"});return}n0.handleRpc(X,Z,W).then((K)=>{M0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!0,result:K})},(K)=>{M0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!1,error:K instanceof Error?K.message:String(K)})})},onHttpRequest:(X,Z)=>O1?n0.handleHttpRequest(X,Z):!1,onHttpUpgrade:(X,Z,W)=>O1?n0.handleUpgrade(X,Z,W):!1,onWarmupRun:(X,Z,W)=>{(async()=>{if(await aX(),!C1)return{status:"retryable",error:"agent host is not ready"};return f4({cardId:Z.cardId,boardId:Z.boardId,userId:W,frontendSessionId:X})})().then((K)=>{if(!Z.warmupId)return;M0(X,{type:"warmup_result",warmupId:Z.warmupId,cardId:Z.cardId,...K})})},onDisconnect:(X,Z)=>{n0.closeFrontendSession(X),P4(X);for(let W of Z)hX(W);E("bridge.frontend_disconnected",{frontendSessionId:X,activeRuns:Z.length}),sX(X).catch((W)=>{console.warn(`[ideawave-cli] failed to evict sessions for ${X}:`,W instanceof Error?W.message:String(W))}),console.log(`[ideawave-cli] browser session ${X} disconnected`)}});n0.setPort(I0.port);console.log(`[ideawave-cli] browser bridge listening on ${I0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var V8=!1;for(let X of["SIGINT","SIGTERM"])process.once(X,()=>{if(V8)return;V8=!0,x4(),(async()=>{await n0.close(),await D4(),await I0?.close().catch(()=>{return}),process.exit(0)})()});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ideawave",
3
- "version": "0.0.89",
3
+ "version": "0.0.90",
4
4
  "description": "IdeaWave CLI",
5
5
  "type": "module",
6
6
  "bin": {