ideawave 0.0.69 → 0.0.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -933,7 +933,7 @@ ${W}`:null].filter(Boolean).join(`
|
|
|
933
933
|
|
|
934
934
|
`));return o(X)}function k$(X,$){if(!$)return X;if(!X)return $;if(X===$||X.endsWith($))return X;if($.startsWith(X))return $;return V0(`${X}
|
|
935
935
|
|
|
936
|
-
${$}`)}function iX(X){if(!Array.isArray(X))return null;let $=X.flatMap((Z)=>{if(!Z||typeof Z!=="object")return[];let Q=Z;if(typeof Q.path!=="string"||!Q.path.trim())return[];let W=typeof Q.line==="number"?`:${Q.line}`:"";return[`${Q.path}${W}`]});return $.length>0?$.slice(0,5):null}function q$(X){let{ctx:$,appendText:Z,appendToolActivity:Q}=X,W=X.flushIntervalMs??e6,K="",Y="",V=0,z=null,J={},G=new Map,M=(P)=>{if(G.set(P.toolCallId,P),!Q)return;Q({boardId:$.boardId,cardId:$.cardId,runId:$.runId,entry:P}).catch((j)=>{console.warn("[streamAdapter] appendToolActivity failed",j)})},L=(P)=>{let j=`${$.runId}:thought`,k=G.get(j);if(!k||k.status!=="running")return;M({...k,status:"completed",completedAt:k.completedAt??P})},x=(P)=>{for(let j of G.values()){if(j.status!=="running"||j.rawTitle.toLowerCase()!=="toolsearch")continue;M({...j,status:"completed",completedAt:j.completedAt??P})}},U=(P)=>{for(let j of Array.from(G.values())){if(j.status!=="running")continue;if(j.kind==="thought"||j.rawTitle==="agent_thought")continue;M({...j,status:"completed",completedAt:j.completedAt??P})}},D="",w=0,H=null,B=null,N=(P)=>{if(P===D)return;D=P,w=Date.now(),Z({boardId:$.boardId,cardId:$.cardId,runId:$.runId,text:P}).catch((j)=>{console.warn("[streamAdapter] appendText failed",j)})},O=()=>{if(H!==null)clearTimeout(H),H=null;if(B!==null){let P=B;B=null,N(P)}},C=(P)=>{let j=Date.now()-w;if(j>=W&&H===null){N(P);return}if(B=P,H===null){let k=Math.max(0,W-j);H=setTimeout(()=>{H=null,O()},k)}};return{onSessionUpdate:async(P)=>{let j=P.update;switch(J[j.sessionUpdate]=(J[j.sessionUpdate]??0)+1,j.sessionUpdate){case"agent_message_chunk":{let k=new Date().toISOString();if(L(k),j.content.type==="text")K+=j.content.text,C(K);else{let _=`agent_message_chunk:${j.content.type}`;J[_]=(J[_]??0)+1}return}case"agent_thought_chunk":{if(j.content.type!=="text")return;Y+=j.content.text;let k=new Date().toISOString(),_=`${$.runId}:thought`,b=G.get(_);M({toolCallId:_,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:b?.startedAt??k,completedAt:null,contentPreview:V0(Y.trim())});return}case"user_message_chunk":return;case"tool_call":{V+=1;let k=F$(j.title),_=pX(j.status),b=new Date().toISOString();L(b),x(b),M({toolCallId:j.toolCallId,rawTitle:k,title:aX(k,j.rawInput),kind:uX(j.kind),status:_,startedAt:b,completedAt:_==="running"?null:b,inputPreview:o(j.rawInput),outputPreview:dX(j.rawOutput),contentPreview:ZX(j.content),locations:iX(j.locations)});return}case"tool_call_update":{let k=G.get(j.toolCallId);if(!k){let y=F$(j.title),I=pX(j.status),h=new Date().toISOString();M({toolCallId:j.toolCallId,rawTitle:y,title:aX(y,j.rawInput),kind:uX(j.kind),status:I,startedAt:h,completedAt:I==="running"?null:h,inputPreview:o(j.rawInput),outputPreview:dX(j.rawOutput),contentPreview:ZX(j.content),locations:iX(j.locations)});return}let _=j.status===void 0||j.status===null?k.status:pX(j.status),b=typeof j.title==="string"&&j.title.trim().length>0?j.title:k.rawTitle,d=typeof j.title==="string"&&j.title.trim().length>0,n=_==="running"?k.completedAt:k.completedAt??new Date().toISOString(),A=j.content===void 0?k.contentPreview:k$(k.contentPreview,ZX(j.content)),v=j.rawOutput===void 0?k.outputPreview:k$(k.outputPreview,dX(j.rawOutput));M({...k,rawTitle:b,title:d?aX(b,j.rawInput):k.title,kind:j.kind===void 0?k.kind:uX(j.kind),status:_,completedAt:n,inputPreview:j.rawInput===void 0?k.inputPreview:o(j.rawInput),outputPreview:v,contentPreview:A,locations:j.locations===void 0?k.locations:iX(j.locations)});return}case"plan":z=j.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>K,getToolCallCount:()=>V,getLatestPlan:()=>z,getUpdateTypeCounts:()=>({...J}),flush:(P)=>{let j=new Date().toISOString();if(L(j),P?.completeOpenToolCalls)U(j);O()}}}var A0=1,_$=-32000;function A$(X){if(X.awaitingInput)return!1;return X.nowMs-X.lastUpdateMs>=X.windowMs}function f$(X){if(!X||typeof X!=="object")return!1;return X.code===_$}var Q3=60000,W3=Q3,K3=5000;function Y3(X){let $=Math.max(1,Math.round(X/1000));return`Runtime has not responded for ${$} ${$===1?"second":"seconds"}. Retry the agent run.`}function y$(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.69".trim()?"0.0.69":"dev"}}function b$(X){if(X===A0)return;throw new R(`Unsupported ACP protocol version ${X}; expected ${A0}`)}function E$(X){return $3.toWeb(X)}function T$(X){return Z3.toWeb(X)}function oX(X){return X!==null&&typeof X==="object"}function J3(X){if(!Array.isArray(X))return[];let $=[];for(let Z of X){if(!oX(Z))continue;if(typeof Z.group==="string"&&Array.isArray(Z.options)){let Q=typeof Z.name==="string"?Z.name:Z.group;for(let W of Z.options){if(!oX(W))continue;if(typeof W.value!=="string"||typeof W.name!=="string")continue;$.push({value:W.value,name:W.name,description:typeof W.description==="string"?W.description:null,group:Z.group,groupName:Q})}continue}if(typeof Z.value!=="string"||typeof Z.name!=="string")continue;$.push({value:Z.value,name:Z.name,description:typeof Z.description==="string"?Z.description:null,group:null,groupName:null})}return $}function V3(X){if(!oX(X))return null;if(typeof X.id!=="string"||typeof X.name!=="string")return null;let $=typeof X.category==="string"?X.category:null,Z=typeof X.description==="string"?X.description:null;if(X.type==="select"){let Q=typeof X.currentValue==="string"?X.currentValue:null;return{id:X.id,name:X.name,category:$,description:Z,type:"select",currentValue:Q,options:J3(X.options)}}if(X.type==="boolean"){let Q=typeof X.currentValue==="boolean"?X.currentValue:typeof X.value==="boolean"?X.value:null;return{id:X.id,name:X.name,category:$,description:Z,type:"boolean",currentValue:Q,options:[]}}return null}function nX(X){let $=(X.configOptions??[]).map(V3).filter((V)=>V!==null),Z=$.find((V)=>V.type==="select"&&V.category==="model")??$.find((V)=>V.type==="select"&&V.id==="model")??null,Q=Z?.options.map((V)=>({id:V.value,name:V.name,description:V.description??null})),W=j3(X.models),K=Q&&Q.length>0?Q:W&&W.length>0?W:null,Y=(typeof Z?.currentValue==="string"?Z.currentValue:null)??G3(X.models)??null;return{models:K,currentModelId:Y,configOptions:$,modelConfigId:Z?.id??null}}function j3(X){if(!X||!Array.isArray(X.availableModels))return null;let $=[];for(let Z of X.availableModels){if(typeof Z.modelId!=="string")continue;$.push({id:Z.modelId,name:typeof Z.name==="string"?Z.name:null,description:typeof Z.description==="string"?Z.description:null})}return $.length>0?$:null}function G3(X){return typeof X?.currentModelId==="string"?X.currentModelId:null}function z3(X,$){let Z=[];if(X.trim())Z.push({type:"text",text:X});for(let Q of $)if(Q.content.trim())Z.push({type:"text",text:Q.content});return Z}function U3(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 H3(X,$){let Z=nX({configOptions:$.configOptions});return{models:Z.models??X.models,currentModelId:Z.currentModelId??X.currentModelId,configOptions:Z.configOptions,modelConfigId:Z.modelConfigId??X.modelConfigId}}function v$(X,$){if(X==="default")return null;if(!$||$.length===0)return X;let Z=$.find((J)=>J.id===X);if(Z)return Z.id;let Q=X.toLowerCase(),W=Q.includes("opus")?"opus":Q.includes("sonnet")?"sonnet":Q.includes("haiku")?"haiku":null;if(!W)return X;let K=(J)=>`${J.id} ${J.name??""} ${J.description??""}`.toLowerCase(),Y=$.filter((J)=>K(J).includes(W));if(Y.length===0)return X;let z=(Q.includes("1m")?Y.find((J)=>K(J).includes("1m")):void 0)??Y[0];return z?z.id:X}async function WX(X){try{let $=await X.conn.setSessionConfigOption(U3({sessionId:X.sessionId,configId:X.configId,value:X.value}));return H3(X.metadata,$)}catch($){return console.warn(`[acp] setSessionConfigOption(${X.label}) failed; using agent default.`,$ instanceof Error?$.message:$),X.metadata}}async function tX(X){let $=cX(X.spawn),Z=[],Q=0,W=4096;$.stderr.on("data",(A)=>{Z.push(A),Q+=A.length;while(Q>W*2&&Z.length>1){let v=Z.shift();if(v)Q-=v.length}});let K=()=>{let A=Buffer.concat(Z).toString("utf8");return A.length>W?A.slice(-W):A},Y=B$(X.spawn.cwd),V={current:null},z={current:null},J={at:Date.now()},G=null,M=T$($.stdin),L=E$($.stdout),x=R$(M,L),D=new C$((A)=>({requestPermission:async(v)=>{let y=v.options,I=y?.find((h)=>h.kind==="allow_once")??y?.find((h)=>h.kind==="allow_always");if(I)return{outcome:{outcome:"selected",optionId:I.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(v)=>{J.at=Date.now();let y=z.current;if(y){let h=v.update.sessionUpdate;if(y.updateCount+=1,y.updateCount===1||y.lastUpdateType!==h||h==="tool_call"||h==="tool_call_update")q("acp.session_update",{runId:y.runId,cardId:y.cardId,sessionId:G,updateType:h,updateCount:y.updateCount,elapsedMs:Date.now()-y.startedAt});y.lastUpdateType=h}let I=V.current;if(I)await I.onSessionUpdate(v)},readTextFile:Y.readTextFile}),x),w=()=>$.kill();if(X.signal)X.signal.addEventListener("abort",w);let H=()=>{if(X.signal)X.signal.removeEventListener("abort",w)},B=async(A,v)=>{if(H(),$.kill(),f$(A))throw new H0(A.message??"Authentication required",v);if(A instanceof Error&&A.message==="ACP connection closed"){if(X.signal?.aborted)throw new R("ACP session cancelled: abort signal received");let y=await Promise.race([$.processCrashed,$.waitForExit,new Promise((I)=>setTimeout(()=>I({stderr:""}),500))]);throw new R(`Runtime process exited before completion: ${y.stderr?.trim()??""}`)}throw A},N;try{N=await D.initialize({protocolVersion:A0,clientCapabilities:mX,clientInfo:y$()})}catch(A){throw await B(A,[]),Error("unreachable")}try{b$(N.protocolVersion)}catch(A){throw H(),$.kill(),A}let O=N.authMethods?.map((A)=>A.id)??[],C;try{C=await D.newSession({cwd:X.spawn.cwd,mcpServers:X.mcpServers??[]})}catch(A){throw await B(A,O),Error("unreachable")}let P=C.sessionId;G=P;let j=nX(C),k=X.modelId??null,_=k?v$(k,j.models):null;if(_&&_!==j.currentModelId)if(j.modelConfigId)j=await WX({conn:D,sessionId:P,configId:j.modelConfigId,value:_,metadata:j,label:`${j.modelConfigId}=${_}`});else console.warn(`[acp] runtime did not advertise a model config option for ${_}; using agent default.`);for(let[A,v]of Object.entries(X.configValues??{}).sort(([y],[I])=>y.localeCompare(I))){if(A===j.modelConfigId)continue;if(!j.configOptions.some((y)=>y.id===A))continue;j=await WX({conn:D,sessionId:P,configId:A,value:v,metadata:j,label:`${A}=${String(v)}`})}H();let b=!1,d=async()=>{if(b)return;b=!0,$.kill(),await Promise.race([$.waitForExit,new Promise((A)=>setTimeout(A,2000))])},n=!1;return $.processCrashed.then(()=>{n=!0}),{sessionId:P,availableModels:j.models,currentModelId:j.currentModelId,availableConfigOptions:j.configOptions,isAlive:()=>!b&&!n,dispose:d,prompt:(A)=>x3({proc:$,conn:D,sessionId:P,activeAdapter:V,activeTrace:z,lastUpdate:J,collectStderrTail:K},A)}}async function x3(X,$){let{proc:Z,conn:Q,sessionId:W,activeAdapter:K,activeTrace:Y,lastUpdate:V}=X,z=Date.now(),J=$.heartbeatMs??W3,G=Y3(J),M={boardId:$.boardId,cardId:$.cardId,runId:$.runId},L=q$({ctx:M,appendText:$.appendText,appendToolActivity:$.appendToolActivity});K.current=L,Y.current={runId:$.runId,cardId:$.cardId,startedAt:z,updateCount:0,lastUpdateType:null},V.at=Date.now(),q("acp.prompt_started",{runId:$.runId,cardId:$.cardId,sessionId:W,heartbeatWindowMs:J});let x=!1,U=null,D=()=>Z.kill();$.signal.addEventListener("abort",D);try{let w=async()=>{let O=Math.min(K3,Math.max(50,Math.floor(J/2)));U=setInterval(()=>{let P=$.isAwaitingInput?.()??!1;if(P){V.at=Date.now();return}if(A$({nowMs:Date.now(),lastUpdateMs:V.at,windowMs:J,awaitingInput:P}))x=!0,q("acp.inactivity_timeout",{runId:$.runId,cardId:$.cardId,sessionId:W,windowMs:J,silentForMs:Date.now()-V.at}),Q.cancel({sessionId:W}).catch(()=>{return}),Z.kill()},O);let C=z3($.prompt.systemPrompt,$.prompt.messages);await Q.prompt({sessionId:W,prompt:C}),q("acp.prompt_resolved",{runId:$.runId,cardId:$.cardId,sessionId:W,elapsedMs:Date.now()-z}),L.flush({completeOpenToolCalls:!0})},H=Z.waitForExit.then((O)=>({kind:"exited",exit:O})),B=w().then(()=>({kind:"ok"})).catch(async(O)=>{if(O instanceof Error&&O.message==="ACP connection closed")return{kind:"crashed",exit:await Promise.race([Z.processCrashed,Z.waitForExit])};throw O}),N;try{N=await Promise.race([B,Z.processCrashed.then((O)=>({kind:"crashed",exit:O})),H])}catch(O){if(x)throw new u(G);throw O}if(x)throw new u(G);if(N.kind==="crashed")throw new R(`Runtime process exited before completion: ${N.exit.stderr.trim()}`);if(N.kind==="exited"){if($.signal.aborted)throw new R("ACP session cancelled: abort signal received");if(x)throw new u(G);throw new R(`Runtime process exited unexpectedly: ${N.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:L.getFinalText(),toolCallsExecuted:L.getToolCallCount(),stderrTail:X.collectStderrTail(),updateTypeCounts:L.getUpdateTypeCounts()}}finally{if(q("acp.prompt_finished",{runId:$.runId,cardId:$.cardId,sessionId:W,elapsedMs:Date.now()-z,timedOut:x,updateCount:Y.current?.updateCount??0}),U!==null)clearInterval(U);$.signal.removeEventListener("abort",D),L.flush({completeOpenToolCalls:!0}),K.current=null,Y.current=null}}var D3=30000;async function h$(X){let $=cX(X.spawn),Z=T$($.stdin),Q=E$($.stdout),W=R$(Z,Q),Y=new C$((J)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),W),V=()=>$.kill();if(X.signal)X.signal.addEventListener("abort",V);let z=null;try{let J=(async()=>{let M=await Y.initialize({protocolVersion:A0,clientCapabilities:mX,clientInfo:y$()});b$(M.protocolVersion);let L=M.authMethods?.map((N)=>N.id)??[],x;try{x=await Y.newSession({cwd:X.spawn.cwd,mcpServers:[]})}catch(N){if(f$(N))throw new H0(N.message??"Authentication required",L);throw N}let U=nX(x),D=X.modelId??null,w=D?v$(D,U.models):null;if(w&&w!==U.currentModelId)if(U.modelConfigId)U=await WX({conn:Y,sessionId:x.sessionId,configId:U.modelConfigId,value:w,metadata:U,label:`${U.modelConfigId}=${w}`});else console.warn(`[acp] runtime did not advertise a model config option for ${w}; discovering agent default models.`);for(let[N,O]of Object.entries(X.configValues??{}).sort(([C],[P])=>C.localeCompare(P))){if(N===U.modelConfigId)continue;if(!U.configOptions.some((C)=>C.id===N))continue;U=await WX({conn:Y,sessionId:x.sessionId,configId:N,value:O,metadata:U,label:`${N}=${String(O)}`})}let H=U.models??[],B=U.currentModelId;return Y.cancel({sessionId:x.sessionId}).catch(()=>{return}),{models:H,configOptions:U.configOptions,currentModelId:B}})(),G=new Promise((M,L)=>{z=setTimeout(()=>{L(new u)},D3)});return await Promise.race([J,G])}catch(J){if(J instanceof Error&&J.message==="ACP connection closed"){if(X.signal?.aborted)throw new R("ACP model discovery cancelled: abort signal received");throw new R("Runtime process exited during model discovery.")}throw J}finally{if(z)clearTimeout(z);if(X.signal)X.signal.removeEventListener("abort",V);$.kill()}}import w3 from"node:fs/promises";import KX from"node:os";async function I$(X){let $={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},Z;try{Z=await w3.readFile(X,"utf-8")}catch(Q){if(Q.code==="ENOENT")return structuredClone($);throw Q}return c0.parse(JSON.parse(Z))}function rX(X,$,Z){return{...X.defaultConfigValues??{},...$?.configValues??{},...Z?.configValues??{}}}async function X0(X){let $=X.configPath?await I$(X.configPath):await m(),Z=X.cardId?$.cardOverrides[X.cardId]:void 0;if(Z?.runtimeConfigId){let W=$.runtimes.find((K)=>K.id===Z.runtimeConfigId);if(W)return{entry:W,adapter:a(W),runFolder:Z.runFolder??W.runFolder??KX.homedir(),modelId:Z.modelId??W.defaultModelId??null,configValues:rX(W,void 0,Z)}}let Q=$.boardOverrides[X.boardId];if(Q?.runtimeConfigId){let W=$.runtimes.find((K)=>K.id===Q.runtimeConfigId);if(W)return{entry:W,adapter:a(W),runFolder:Q.runFolder??W.runFolder??KX.homedir(),modelId:Q.modelId??W.defaultModelId??null,configValues:rX(W,Q)}}if($.globalDefaultConfigId){let W=$.runtimes.find((K)=>K.id===$.globalDefaultConfigId);if(W)return{entry:W,adapter:a(W),runFolder:Z?.runFolder??Q?.runFolder??W.runFolder??KX.homedir(),modelId:Z?.modelId??Q?.modelId??W.defaultModelId??null,configValues:rX(W,Q,Z)}}throw new Y0}async function S$(X,$={}){let Q=($.configPath?await I$($.configPath):await m()).runtimes.find((W)=>W.id===X);if(!Q)return null;return{entry:Q,adapter:a(Q),runFolder:Q.runFolder??KX.homedir(),modelId:$.modelId??Q.defaultModelId??null,configValues:{...Q.defaultConfigValues??{},...$.configValues??{}}}}var g$=new Map;function sX(X,$){if(!X)return;g$.set(X,$)}function m$(X){if(!X)return!1;return g$.get(X)??!1}var j0=new Map,eX=new Set;function $1(X){j0.get(X)?.controller.abort()}function c$(X){for(let[$,Z]of j0){if(Z.frontendSessionId!==X)continue;Z.controller.abort(),j0.delete($)}}function l$(){for(let X of j0.values())X.controller.abort();j0.clear()}function X1(X,$){if($?.aborted)return!0;return X instanceof Error&&/abort signal received|session cancelled/i.test(X.message)}function p$(X,$,Z,Q){if((!$.availableModels||$.availableModels.length===0)&&$.availableConfigOptions.length===0)return;p((W)=>{let K=W.runtimes.find((Y)=>Y.id===X);if(K){if($.availableModels&&$.availableModels.length>0)K.discoveredModels=s0({adapterId:Z,models:$.availableModels,currentModelId:$.currentModelId??Q});if($.availableConfigOptions.length>0)K.discoveredConfigOptions=$.availableConfigOptions}}).catch(()=>{return})}function N3(X,$){return`${X}
|
|
936
|
+
${$}`)}function iX(X){if(!Array.isArray(X))return null;let $=X.flatMap((Z)=>{if(!Z||typeof Z!=="object")return[];let Q=Z;if(typeof Q.path!=="string"||!Q.path.trim())return[];let W=typeof Q.line==="number"?`:${Q.line}`:"";return[`${Q.path}${W}`]});return $.length>0?$.slice(0,5):null}function q$(X){let{ctx:$,appendText:Z,appendToolActivity:Q}=X,W=X.flushIntervalMs??e6,K="",Y="",V=0,z=null,J={},G=new Map,M=(P)=>{if(G.set(P.toolCallId,P),!Q)return;Q({boardId:$.boardId,cardId:$.cardId,runId:$.runId,entry:P}).catch((j)=>{console.warn("[streamAdapter] appendToolActivity failed",j)})},L=(P)=>{let j=`${$.runId}:thought`,k=G.get(j);if(!k||k.status!=="running")return;M({...k,status:"completed",completedAt:k.completedAt??P})},x=(P)=>{for(let j of G.values()){if(j.status!=="running"||j.rawTitle.toLowerCase()!=="toolsearch")continue;M({...j,status:"completed",completedAt:j.completedAt??P})}},U=(P)=>{for(let j of Array.from(G.values())){if(j.status!=="running")continue;if(j.kind==="thought"||j.rawTitle==="agent_thought")continue;M({...j,status:"completed",completedAt:j.completedAt??P})}},D="",w=0,H=null,B=null,N=(P)=>{if(P===D)return;D=P,w=Date.now(),Z({boardId:$.boardId,cardId:$.cardId,runId:$.runId,text:P}).catch((j)=>{console.warn("[streamAdapter] appendText failed",j)})},O=()=>{if(H!==null)clearTimeout(H),H=null;if(B!==null){let P=B;B=null,N(P)}},C=(P)=>{let j=Date.now()-w;if(j>=W&&H===null){N(P);return}if(B=P,H===null){let k=Math.max(0,W-j);H=setTimeout(()=>{H=null,O()},k)}};return{onSessionUpdate:async(P)=>{let j=P.update;switch(J[j.sessionUpdate]=(J[j.sessionUpdate]??0)+1,j.sessionUpdate){case"agent_message_chunk":{let k=new Date().toISOString();if(L(k),j.content.type==="text")K+=j.content.text,C(K);else{let _=`agent_message_chunk:${j.content.type}`;J[_]=(J[_]??0)+1}return}case"agent_thought_chunk":{if(j.content.type!=="text")return;Y+=j.content.text;let k=new Date().toISOString(),_=`${$.runId}:thought`,b=G.get(_);M({toolCallId:_,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:b?.startedAt??k,completedAt:null,contentPreview:V0(Y.trim())});return}case"user_message_chunk":return;case"tool_call":{V+=1;let k=F$(j.title),_=pX(j.status),b=new Date().toISOString();L(b),x(b),M({toolCallId:j.toolCallId,rawTitle:k,title:aX(k,j.rawInput),kind:uX(j.kind),status:_,startedAt:b,completedAt:_==="running"?null:b,inputPreview:o(j.rawInput),outputPreview:dX(j.rawOutput),contentPreview:ZX(j.content),locations:iX(j.locations)});return}case"tool_call_update":{let k=G.get(j.toolCallId);if(!k){let y=F$(j.title),I=pX(j.status),h=new Date().toISOString();M({toolCallId:j.toolCallId,rawTitle:y,title:aX(y,j.rawInput),kind:uX(j.kind),status:I,startedAt:h,completedAt:I==="running"?null:h,inputPreview:o(j.rawInput),outputPreview:dX(j.rawOutput),contentPreview:ZX(j.content),locations:iX(j.locations)});return}let _=j.status===void 0||j.status===null?k.status:pX(j.status),b=typeof j.title==="string"&&j.title.trim().length>0?j.title:k.rawTitle,d=typeof j.title==="string"&&j.title.trim().length>0,n=_==="running"?k.completedAt:k.completedAt??new Date().toISOString(),A=j.content===void 0?k.contentPreview:k$(k.contentPreview,ZX(j.content)),v=j.rawOutput===void 0?k.outputPreview:k$(k.outputPreview,dX(j.rawOutput));M({...k,rawTitle:b,title:d?aX(b,j.rawInput):k.title,kind:j.kind===void 0?k.kind:uX(j.kind),status:_,completedAt:n,inputPreview:j.rawInput===void 0?k.inputPreview:o(j.rawInput),outputPreview:v,contentPreview:A,locations:j.locations===void 0?k.locations:iX(j.locations)});return}case"plan":z=j.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>K,getToolCallCount:()=>V,getLatestPlan:()=>z,getUpdateTypeCounts:()=>({...J}),flush:(P)=>{let j=new Date().toISOString();if(L(j),P?.completeOpenToolCalls)U(j);O()}}}var A0=1,_$=-32000;function A$(X){if(X.awaitingInput)return!1;return X.nowMs-X.lastUpdateMs>=X.windowMs}function f$(X){if(!X||typeof X!=="object")return!1;return X.code===_$}var Q3=60000,W3=Q3,K3=5000;function Y3(X){let $=Math.max(1,Math.round(X/1000));return`Runtime has not responded for ${$} ${$===1?"second":"seconds"}. Retry the agent run.`}function y$(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.70".trim()?"0.0.70":"dev"}}function b$(X){if(X===A0)return;throw new R(`Unsupported ACP protocol version ${X}; expected ${A0}`)}function E$(X){return $3.toWeb(X)}function T$(X){return Z3.toWeb(X)}function oX(X){return X!==null&&typeof X==="object"}function J3(X){if(!Array.isArray(X))return[];let $=[];for(let Z of X){if(!oX(Z))continue;if(typeof Z.group==="string"&&Array.isArray(Z.options)){let Q=typeof Z.name==="string"?Z.name:Z.group;for(let W of Z.options){if(!oX(W))continue;if(typeof W.value!=="string"||typeof W.name!=="string")continue;$.push({value:W.value,name:W.name,description:typeof W.description==="string"?W.description:null,group:Z.group,groupName:Q})}continue}if(typeof Z.value!=="string"||typeof Z.name!=="string")continue;$.push({value:Z.value,name:Z.name,description:typeof Z.description==="string"?Z.description:null,group:null,groupName:null})}return $}function V3(X){if(!oX(X))return null;if(typeof X.id!=="string"||typeof X.name!=="string")return null;let $=typeof X.category==="string"?X.category:null,Z=typeof X.description==="string"?X.description:null;if(X.type==="select"){let Q=typeof X.currentValue==="string"?X.currentValue:null;return{id:X.id,name:X.name,category:$,description:Z,type:"select",currentValue:Q,options:J3(X.options)}}if(X.type==="boolean"){let Q=typeof X.currentValue==="boolean"?X.currentValue:typeof X.value==="boolean"?X.value:null;return{id:X.id,name:X.name,category:$,description:Z,type:"boolean",currentValue:Q,options:[]}}return null}function nX(X){let $=(X.configOptions??[]).map(V3).filter((V)=>V!==null),Z=$.find((V)=>V.type==="select"&&V.category==="model")??$.find((V)=>V.type==="select"&&V.id==="model")??null,Q=Z?.options.map((V)=>({id:V.value,name:V.name,description:V.description??null})),W=j3(X.models),K=Q&&Q.length>0?Q:W&&W.length>0?W:null,Y=(typeof Z?.currentValue==="string"?Z.currentValue:null)??G3(X.models)??null;return{models:K,currentModelId:Y,configOptions:$,modelConfigId:Z?.id??null}}function j3(X){if(!X||!Array.isArray(X.availableModels))return null;let $=[];for(let Z of X.availableModels){if(typeof Z.modelId!=="string")continue;$.push({id:Z.modelId,name:typeof Z.name==="string"?Z.name:null,description:typeof Z.description==="string"?Z.description:null})}return $.length>0?$:null}function G3(X){return typeof X?.currentModelId==="string"?X.currentModelId:null}function z3(X,$){let Z=[];if(X.trim())Z.push({type:"text",text:X});for(let Q of $)if(Q.content.trim())Z.push({type:"text",text:Q.content});return Z}function U3(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 H3(X,$){let Z=nX({configOptions:$.configOptions});return{models:Z.models??X.models,currentModelId:Z.currentModelId??X.currentModelId,configOptions:Z.configOptions,modelConfigId:Z.modelConfigId??X.modelConfigId}}function v$(X,$){if(X==="default")return null;if(!$||$.length===0)return X;let Z=$.find((J)=>J.id===X);if(Z)return Z.id;let Q=X.toLowerCase(),W=Q.includes("opus")?"opus":Q.includes("sonnet")?"sonnet":Q.includes("haiku")?"haiku":null;if(!W)return X;let K=(J)=>`${J.id} ${J.name??""} ${J.description??""}`.toLowerCase(),Y=$.filter((J)=>K(J).includes(W));if(Y.length===0)return X;let z=(Q.includes("1m")?Y.find((J)=>K(J).includes("1m")):void 0)??Y[0];return z?z.id:X}async function WX(X){try{let $=await X.conn.setSessionConfigOption(U3({sessionId:X.sessionId,configId:X.configId,value:X.value}));return H3(X.metadata,$)}catch($){return console.warn(`[acp] setSessionConfigOption(${X.label}) failed; using agent default.`,$ instanceof Error?$.message:$),X.metadata}}async function tX(X){let $=cX(X.spawn),Z=[],Q=0,W=4096;$.stderr.on("data",(A)=>{Z.push(A),Q+=A.length;while(Q>W*2&&Z.length>1){let v=Z.shift();if(v)Q-=v.length}});let K=()=>{let A=Buffer.concat(Z).toString("utf8");return A.length>W?A.slice(-W):A},Y=B$(X.spawn.cwd),V={current:null},z={current:null},J={at:Date.now()},G=null,M=T$($.stdin),L=E$($.stdout),x=R$(M,L),D=new C$((A)=>({requestPermission:async(v)=>{let y=v.options,I=y?.find((h)=>h.kind==="allow_once")??y?.find((h)=>h.kind==="allow_always");if(I)return{outcome:{outcome:"selected",optionId:I.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(v)=>{J.at=Date.now();let y=z.current;if(y){let h=v.update.sessionUpdate;if(y.updateCount+=1,y.updateCount===1||y.lastUpdateType!==h||h==="tool_call"||h==="tool_call_update")q("acp.session_update",{runId:y.runId,cardId:y.cardId,sessionId:G,updateType:h,updateCount:y.updateCount,elapsedMs:Date.now()-y.startedAt});y.lastUpdateType=h}let I=V.current;if(I)await I.onSessionUpdate(v)},readTextFile:Y.readTextFile}),x),w=()=>$.kill();if(X.signal)X.signal.addEventListener("abort",w);let H=()=>{if(X.signal)X.signal.removeEventListener("abort",w)},B=async(A,v)=>{if(H(),$.kill(),f$(A))throw new H0(A.message??"Authentication required",v);if(A instanceof Error&&A.message==="ACP connection closed"){if(X.signal?.aborted)throw new R("ACP session cancelled: abort signal received");let y=await Promise.race([$.processCrashed,$.waitForExit,new Promise((I)=>setTimeout(()=>I({stderr:""}),500))]);throw new R(`Runtime process exited before completion: ${y.stderr?.trim()??""}`)}throw A},N;try{N=await D.initialize({protocolVersion:A0,clientCapabilities:mX,clientInfo:y$()})}catch(A){throw await B(A,[]),Error("unreachable")}try{b$(N.protocolVersion)}catch(A){throw H(),$.kill(),A}let O=N.authMethods?.map((A)=>A.id)??[],C;try{C=await D.newSession({cwd:X.spawn.cwd,mcpServers:X.mcpServers??[]})}catch(A){throw await B(A,O),Error("unreachable")}let P=C.sessionId;G=P;let j=nX(C),k=X.modelId??null,_=k?v$(k,j.models):null;if(_&&_!==j.currentModelId)if(j.modelConfigId)j=await WX({conn:D,sessionId:P,configId:j.modelConfigId,value:_,metadata:j,label:`${j.modelConfigId}=${_}`});else console.warn(`[acp] runtime did not advertise a model config option for ${_}; using agent default.`);for(let[A,v]of Object.entries(X.configValues??{}).sort(([y],[I])=>y.localeCompare(I))){if(A===j.modelConfigId)continue;if(!j.configOptions.some((y)=>y.id===A))continue;j=await WX({conn:D,sessionId:P,configId:A,value:v,metadata:j,label:`${A}=${String(v)}`})}H();let b=!1,d=async()=>{if(b)return;b=!0,$.kill(),await Promise.race([$.waitForExit,new Promise((A)=>setTimeout(A,2000))])},n=!1;return $.processCrashed.then(()=>{n=!0}),{sessionId:P,availableModels:j.models,currentModelId:j.currentModelId,availableConfigOptions:j.configOptions,isAlive:()=>!b&&!n,dispose:d,prompt:(A)=>x3({proc:$,conn:D,sessionId:P,activeAdapter:V,activeTrace:z,lastUpdate:J,collectStderrTail:K},A)}}async function x3(X,$){let{proc:Z,conn:Q,sessionId:W,activeAdapter:K,activeTrace:Y,lastUpdate:V}=X,z=Date.now(),J=$.heartbeatMs??W3,G=Y3(J),M={boardId:$.boardId,cardId:$.cardId,runId:$.runId},L=q$({ctx:M,appendText:$.appendText,appendToolActivity:$.appendToolActivity});K.current=L,Y.current={runId:$.runId,cardId:$.cardId,startedAt:z,updateCount:0,lastUpdateType:null},V.at=Date.now(),q("acp.prompt_started",{runId:$.runId,cardId:$.cardId,sessionId:W,heartbeatWindowMs:J});let x=!1,U=null,D=()=>Z.kill();$.signal.addEventListener("abort",D);try{let w=async()=>{let O=Math.min(K3,Math.max(50,Math.floor(J/2)));U=setInterval(()=>{let P=$.isAwaitingInput?.()??!1;if(P){V.at=Date.now();return}if(A$({nowMs:Date.now(),lastUpdateMs:V.at,windowMs:J,awaitingInput:P}))x=!0,q("acp.inactivity_timeout",{runId:$.runId,cardId:$.cardId,sessionId:W,windowMs:J,silentForMs:Date.now()-V.at}),Q.cancel({sessionId:W}).catch(()=>{return}),Z.kill()},O);let C=z3($.prompt.systemPrompt,$.prompt.messages);await Q.prompt({sessionId:W,prompt:C}),q("acp.prompt_resolved",{runId:$.runId,cardId:$.cardId,sessionId:W,elapsedMs:Date.now()-z}),L.flush({completeOpenToolCalls:!0})},H=Z.waitForExit.then((O)=>({kind:"exited",exit:O})),B=w().then(()=>({kind:"ok"})).catch(async(O)=>{if(O instanceof Error&&O.message==="ACP connection closed")return{kind:"crashed",exit:await Promise.race([Z.processCrashed,Z.waitForExit])};throw O}),N;try{N=await Promise.race([B,Z.processCrashed.then((O)=>({kind:"crashed",exit:O})),H])}catch(O){if(x)throw new u(G);throw O}if(x)throw new u(G);if(N.kind==="crashed")throw new R(`Runtime process exited before completion: ${N.exit.stderr.trim()}`);if(N.kind==="exited"){if($.signal.aborted)throw new R("ACP session cancelled: abort signal received");if(x)throw new u(G);throw new R(`Runtime process exited unexpectedly: ${N.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:L.getFinalText(),toolCallsExecuted:L.getToolCallCount(),stderrTail:X.collectStderrTail(),updateTypeCounts:L.getUpdateTypeCounts()}}finally{if(q("acp.prompt_finished",{runId:$.runId,cardId:$.cardId,sessionId:W,elapsedMs:Date.now()-z,timedOut:x,updateCount:Y.current?.updateCount??0}),U!==null)clearInterval(U);$.signal.removeEventListener("abort",D),L.flush({completeOpenToolCalls:!0}),K.current=null,Y.current=null}}var D3=30000;async function h$(X){let $=cX(X.spawn),Z=T$($.stdin),Q=E$($.stdout),W=R$(Z,Q),Y=new C$((J)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),W),V=()=>$.kill();if(X.signal)X.signal.addEventListener("abort",V);let z=null;try{let J=(async()=>{let M=await Y.initialize({protocolVersion:A0,clientCapabilities:mX,clientInfo:y$()});b$(M.protocolVersion);let L=M.authMethods?.map((N)=>N.id)??[],x;try{x=await Y.newSession({cwd:X.spawn.cwd,mcpServers:[]})}catch(N){if(f$(N))throw new H0(N.message??"Authentication required",L);throw N}let U=nX(x),D=X.modelId??null,w=D?v$(D,U.models):null;if(w&&w!==U.currentModelId)if(U.modelConfigId)U=await WX({conn:Y,sessionId:x.sessionId,configId:U.modelConfigId,value:w,metadata:U,label:`${U.modelConfigId}=${w}`});else console.warn(`[acp] runtime did not advertise a model config option for ${w}; discovering agent default models.`);for(let[N,O]of Object.entries(X.configValues??{}).sort(([C],[P])=>C.localeCompare(P))){if(N===U.modelConfigId)continue;if(!U.configOptions.some((C)=>C.id===N))continue;U=await WX({conn:Y,sessionId:x.sessionId,configId:N,value:O,metadata:U,label:`${N}=${String(O)}`})}let H=U.models??[],B=U.currentModelId;return Y.cancel({sessionId:x.sessionId}).catch(()=>{return}),{models:H,configOptions:U.configOptions,currentModelId:B}})(),G=new Promise((M,L)=>{z=setTimeout(()=>{L(new u)},D3)});return await Promise.race([J,G])}catch(J){if(J instanceof Error&&J.message==="ACP connection closed"){if(X.signal?.aborted)throw new R("ACP model discovery cancelled: abort signal received");throw new R("Runtime process exited during model discovery.")}throw J}finally{if(z)clearTimeout(z);if(X.signal)X.signal.removeEventListener("abort",V);$.kill()}}import w3 from"node:fs/promises";import KX from"node:os";async function I$(X){let $={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},Z;try{Z=await w3.readFile(X,"utf-8")}catch(Q){if(Q.code==="ENOENT")return structuredClone($);throw Q}return c0.parse(JSON.parse(Z))}function rX(X,$,Z){return{...X.defaultConfigValues??{},...$?.configValues??{},...Z?.configValues??{}}}async function X0(X){let $=X.configPath?await I$(X.configPath):await m(),Z=X.cardId?$.cardOverrides[X.cardId]:void 0;if(Z?.runtimeConfigId){let W=$.runtimes.find((K)=>K.id===Z.runtimeConfigId);if(W)return{entry:W,adapter:a(W),runFolder:Z.runFolder??W.runFolder??KX.homedir(),modelId:Z.modelId??W.defaultModelId??null,configValues:rX(W,void 0,Z)}}let Q=$.boardOverrides[X.boardId];if(Q?.runtimeConfigId){let W=$.runtimes.find((K)=>K.id===Q.runtimeConfigId);if(W)return{entry:W,adapter:a(W),runFolder:Q.runFolder??W.runFolder??KX.homedir(),modelId:Q.modelId??W.defaultModelId??null,configValues:rX(W,Q)}}if($.globalDefaultConfigId){let W=$.runtimes.find((K)=>K.id===$.globalDefaultConfigId);if(W)return{entry:W,adapter:a(W),runFolder:Z?.runFolder??Q?.runFolder??W.runFolder??KX.homedir(),modelId:Z?.modelId??Q?.modelId??W.defaultModelId??null,configValues:rX(W,Q,Z)}}throw new Y0}async function S$(X,$={}){let Q=($.configPath?await I$($.configPath):await m()).runtimes.find((W)=>W.id===X);if(!Q)return null;return{entry:Q,adapter:a(Q),runFolder:Q.runFolder??KX.homedir(),modelId:$.modelId??Q.defaultModelId??null,configValues:{...Q.defaultConfigValues??{},...$.configValues??{}}}}var g$=new Map;function sX(X,$){if(!X)return;g$.set(X,$)}function m$(X){if(!X)return!1;return g$.get(X)??!1}var j0=new Map,eX=new Set;function $1(X){j0.get(X)?.controller.abort()}function c$(X){for(let[$,Z]of j0){if(Z.frontendSessionId!==X)continue;Z.controller.abort(),j0.delete($)}}function l$(){for(let X of j0.values())X.controller.abort();j0.clear()}function X1(X,$){if($?.aborted)return!0;return X instanceof Error&&/abort signal received|session cancelled/i.test(X.message)}function p$(X,$,Z,Q){if((!$.availableModels||$.availableModels.length===0)&&$.availableConfigOptions.length===0)return;p((W)=>{let K=W.runtimes.find((Y)=>Y.id===X);if(K){if($.availableModels&&$.availableModels.length>0)K.discoveredModels=s0({adapterId:Z,models:$.availableModels,currentModelId:$.currentModelId??Q});if($.availableConfigOptions.length>0)K.discoveredConfigOptions=$.availableConfigOptions}}).catch(()=>{return})}function N3(X,$){return`${X}
|
|
937
937
|
|
|
938
938
|
Runtime run folder:
|
|
939
939
|
- Effective run folder: ${$}
|
|
@@ -943,4 +943,4 @@ Runtime run folder:
|
|
|
943
943
|
Connection: close\r
|
|
944
944
|
Content-Length: ${Buffer.byteLength(Z)}\r
|
|
945
945
|
\r
|
|
946
|
-
${Z}`),X.destroy()}function JZ(X,$){return new Promise((Z,Q)=>{let W=(Y)=>{X.off("listening",K),Q(Y)},K=()=>{X.off("error",W);let Y=X.address();if(!Y||typeof Y==="string"){Q(Error("Failed to read CLI bridge server address"));return}Z(Y.port)};X.once("error",W),X.once("listening",K),X.listen($,"127.0.0.1")})}function V2(X){return new Promise(($,Z)=>{X.close((Q)=>{if(Q)Z(Q);else $()})})}async function U2(X,$=G1()){let Z=new Map,Q=new Map,W=X.maxMessageSize??n3,K=!1,Y=(x)=>{let U=Q.get(x);if(U)clearTimeout(U);Q.delete(x)},V=(x)=>{Q.delete(x);let{activeRunIds:U}=X.registry.disconnect(x);X.onDisconnect(x,U)},z=(x,U)=>{let D={type:"cli_status",connected:!0,runtime:X.runtime,mcpReady:X.mcpReady(),error:U,capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()};if(x){let w=Z.get(x);if(w)L0(w,D);return}for(let w of Z.values())L0(w,D)},J=(x,U)=>{let D=U.sessionId.trim(),w=U.userId.trim();if(!D||!w){L0(x,{type:"cli_status",connected:!1,runtime:X.runtime,mcpReady:X.mcpReady(),error:"Missing frontend session or user id"}),x.close();return}Y(D);let H=Z.get(D);if(H&&H!==x)H.close();x.data.frontendSessionId=D,Z.set(D,x),X.registry.register({frontendSessionId:D,userId:w,tools:U.tools,send:(B)=>L0(x,B)}),z(D),X.onToolMetadata?.(D)},G=(x,U)=>{let D=X.registry.getUserId(x);if(!D)return;switch(U.type){case"bridge_ping":{let w=Z.get(x);if(w)L0(w,{type:"bridge_pong"});break}case"tool_metadata":X.registry.setMetadata(x,U.tools),X.onToolMetadata?.(x);break;case"tool_result":X.registry.handleToolResult(x,U);break;case"run_turn":q("bridge.run_received",{runId:U.run.runId,cardId:U.run.cardId,frontendSessionId:x}),X.registry.markRunActive(x,U.run.runId,U.run.cardId),X.onRunTurn(x,{...U.run,frontendSessionId:x,userId:D});break;case"cancel_run":if(X.registry.ownsRun(x,U.runId))X.onCancelRun(x,U.runId);break;case"runtime_rpc":X.onRuntimeRpc(x,U);break;case"browser_rpc":X.onBrowserRpc?.(x,Z.get(x)?.data.frontendOrigin??"",U);break;case"warmup_run":X.onWarmupRun(x,{...U,frontendSessionId:x},D);break;default:break}},M=(x,U)=>{let D=GX(x.headers.origin),w=z1(D),H={Vary:"Origin"};if(w&&D)H["Access-Control-Allow-Origin"]=D,H["Access-Control-Allow-Private-Network"]="true";if(x.method==="OPTIONS"){U.writeHead(204,{...H,"Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*","Access-Control-Max-Age":"600"}),U.end();return}if(x.method!=="GET"){U.writeHead(405,H),U.end();return}U.writeHead(200,{...H,"content-type":"application/json","cache-control":"no-store"}),U.end(JSON.stringify({ideawave:!0,runtime:X.runtime,mcpReady:X.mcpReady(),capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()}))},L=(x,U)=>{let D=GX(x.headers.origin),w=z1(D),H={Vary:"Origin"};if(w&&D)H["Access-Control-Allow-Origin"]=D,H["Access-Control-Allow-Private-Network"]="true";if(x.method==="OPTIONS"){U.writeHead(204,{...H,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"content-type","Access-Control-Max-Age":"600"}),U.end();return}if(!w){U.writeHead(403,H),U.end();return}if(x.method!=="POST"){U.writeHead(405,H),U.end();return}let B={...H,"content-type":"application/json"},N=(P,j)=>{U.writeHead(P,B),U.end(JSON.stringify(j))},O="",C=!1;x.on("data",(P)=>{if(O+=P.toString("utf8"),O.length>e3)C=!0,x.destroy()}),x.on("end",()=>{if(C){N(400,{ok:!1,error:"Request body too large"});return}let P;try{P=JSON.parse(O)}catch{N(400,{ok:!1,error:"Invalid JSON body"});return}let j=typeof P.url==="string"?P.url:"";if(!W2(j)){N(400,{ok:!1,error:"url must be an http(s) loopback or /static_boards/ page URL"});return}let k=(_,b)=>{let d=typeof _==="number"?_:Number.NaN;if(!Number.isFinite(d))return b;return Math.min(4000,Math.max(200,Math.round(d)))};K2({url:j,width:k(P.width,1440),height:k(P.height,900)}).then((_)=>N(200,{ok:!0,path:_.path,engine:_.engine})).catch((_)=>{let b=_ instanceof R0?503:_ instanceof jX?429:500;N(b,{ok:!1,..._ instanceof R0?{installing:!0}:{},error:_ instanceof Error?_.message:String(_)})})})};for(let x of $){let U=i3((H,B)=>{(async()=>{let N=new URL(H.url??"/","http://127.0.0.1").pathname;if(N===X2){M(H,B);return}if(N===s3){L(H,B);return}if(await X.onHttpRequest?.(H,B))return;B.writeHead(404,{"content-type":"text/plain"}),B.end("IdeaWave CLI bridge")})().catch((N)=>{if(B.headersSent){B.destroy(N instanceof Error?N:void 0);return}B.writeHead(500,{"content-type":"text/plain"}),B.end("IdeaWave CLI bridge request failed")})}),D=new o3({noServer:!0,maxPayload:W}),w=(H)=>{if(H.idleTimer)clearTimeout(H.idleTimer);H.idleTimer=setTimeout(()=>{H.close()},t3),H.idleTimer.unref?.()};D.on("connection",(H,B)=>{let N=H;N.data={id:d3(),frontendSessionId:null,frontendOrigin:new URL(GX(B.headers.origin)??G2).origin},N.idleTimer=null,w(N),N.on("ping",()=>w(N)),N.on("pong",()=>w(N)),N.on("error",()=>{if(N.idleTimer)clearTimeout(N.idleTimer);N.close()}),N.on("message",(O)=>{w(N);let C=YZ(O);if(W>0&&C.length>W)return;let P=g0(C);if(!P)return;let j=N.data.frontendSessionId;if(!j){if(P.type==="bridge_probe")L0(N,{type:"bridge_probe_ack",protocolVersion:P.protocolVersion});else if(P.type==="frontend_hello")J(N,P);return}G(j,P)}),N.on("close",()=>{if(N.idleTimer)clearTimeout(N.idleTimer);let O=N.data.frontendSessionId;if(!O)return;if(Z.get(O)!==N)return;if(Z.delete(O),Y(O),K)return;Q.set(O,setTimeout(()=>V(O),r3))})}),U.on("upgrade",(H,B,N)=>{let O=new URL(H.url??"/","http://127.0.0.1").pathname;if(X.onHttpUpgrade?.(H,B,N))return;if(O!==j1){J2(B,404,"Not Found");return}if(!z1(GX(H.headers.origin))){J2(B,403,"Forbidden");return}D.handleUpgrade(H,B,N,(C)=>{D.emit("connection",C,H)})});try{let H=await JZ(U,x);return{url:`ws://127.0.0.1:${H}${j1}`,port:H,sendStatus:z,close:async()=>{K=!0;for(let B of Q.values())clearTimeout(B);Q.clear();for(let B of D.clients){let N=B;if(N.idleTimer)clearTimeout(N.idleTimer);N.close()}D.close(),await V2(U).catch(()=>{return})}}}catch(H){if(D.close(),await V2(U).catch(()=>{return}),H?.code==="EADDRINUSE")continue;throw H}}throw Error(`No free IdeaWave CLI bridge port found in ${$[0]}-${$.at(-1)}`)}import{lstat as BZ,readFile as FZ}from"node:fs/promises";import OZ from"node:os";import y0 from"node:path";import{Server as kZ}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as qZ,ListToolsRequestSchema as _Z}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as jZ}from"node:crypto";import{createServer as GZ}from"node:http";import{StreamableHTTPServerTransport as zZ}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as w2}from"@modelcontextprotocol/sdk/types.js";var H2=new Set(["127.0.0.1","localhost","[::1]","::1"]);function VZ(X){let $=X.trim();if($.length===0)return null;if($.startsWith("[")){let K=$.indexOf("]");if(K===-1)return null;let Y=$.slice(0,K+1),V=$.slice(K+1);if(V.length===0)return{host:Y,port:null};if(!V.startsWith(":"))return null;let z=Number(V.slice(1));if(!Number.isInteger(z)||z<=0||z>65535)return null;return{host:Y,port:z}}let Z=$.lastIndexOf(":");if(Z===-1)return{host:$,port:null};let Q=$.slice(Z+1),W=Number(Q);if(!Number.isInteger(W)||W<=0||W>65535)return{host:$,port:null};return{host:$.slice(0,Z),port:W}}function x2(X){return H2.has(X)||H2.has(X.toLowerCase())}function D2(X,$){let Z=X.headers.host;if(typeof Z!=="string")return{ok:!1,status:403,reason:"missing-host"};let Q=VZ(Z);if(!Q)return{ok:!1,status:403,reason:"bad-host"};if(!x2(Q.host))return{ok:!1,status:403,reason:"non-loopback-host"};if(Q.port!==null&&Q.port!==$)return{ok:!1,status:403,reason:"host-port-mismatch"};let W=X.headers.origin;if(typeof W==="string"&&W.length>0){if(W!=="null"){let K;try{K=new URL(W)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!x2(K.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var N2="/mcp",UZ=43274,P2=16777216,HZ=1800000,xZ=300000,M2=200,DZ=-32700,Z0=-32600,U1=-32603;function l(X,$,Z,Q,W){X.statusCode=$,X.setHeader("content-type","application/json"),X.end(JSON.stringify({jsonrpc:"2.0",error:{code:Z,message:Q,...W?{data:W}:{}},id:null}))}class H1 extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class x1 extends Error{constructor(){super(`body exceeds ${P2} bytes`);this.name="BodyTooLargeError"}}async function wZ(X){if(X.method&&X.method!=="POST")return;let $=X.headers["content-type"];if(typeof $==="string"&&$.trim().length>0){if(!$.toLowerCase().includes("application/json"))throw new H1}let Z=0,Q=[];for await(let K of X){let Y=typeof K==="string"?Buffer.from(K):K;if(Z+=Y.byteLength,Z>P2)throw new x1;Q.push(Y)}if(Q.length===0)return;let W=Buffer.concat(Q).toString("utf8");if(W.length===0)return;return JSON.parse(W)}function NZ(X){if(Array.isArray(X))return X.some(w2);return w2(X)}function MZ(X){if(typeof X==="number")return X;let $=process.env.IDEAWAVE_MCP_PORT;if($&&$.trim().length>0){let Z=Number($);if(Number.isInteger(Z)&&Z>=0&&Z<65536)return Z}return UZ}async function PZ(X,$){let Z=(W)=>new Promise((K,Y)=>{let V=(J)=>{X.off("listening",z),Y(J)},z=()=>{X.off("error",V),K()};X.once("error",V),X.once("listening",z),X.listen(W,"127.0.0.1")});try{await Z($)}catch(W){if(W.code!=="EADDRINUSE"||$===0)throw W;console.warn(`[mcp] port ${$} in use, falling back to an OS-assigned port; external CLIs will need to re-paste the install command from Settings → External agents`),await Z(0)}let Q=X.address();if(Q==null||typeof Q==="string")throw Error("[mcp] failed to read bound address");return Q.port}function LZ(X,$){if($&&typeof $==="object"&&!Array.isArray($)){let Q=$.params;if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let W=Q.clientInfo;if(W&&typeof W==="object"&&!Array.isArray(W)){let K=W.name;if(typeof K==="string"&&K.trim().length>0)return K.trim()}}}let Z=X.headers["user-agent"];if(typeof Z==="string"&&Z.trim().length>0)return Z.trim();return null}async function L2(X){let $=new Map,Z=0;function Q(J){let G=$.get(J);if(G)G.lastActivity=Date.now()}async function W(J,G){$.delete(J),await G.transport.close().catch(()=>{return})}async function K(){let J=null,G=1/0;for(let[M,L]of $)if(L.lastActivity<G)G=L.lastActivity,J=M;if(J!==null){let M=$.get(J);if(M)console.warn(`[mcp] session cap of ${M2} reached; evicting ${J}`),await W(J,M)}}let Y=setInterval(()=>{let J=Date.now()-HZ;for(let[G,M]of $)if(M.lastActivity<J)console.log(`[mcp] sweeping idle session ${G}`),W(G,M)},xZ);Y.unref?.();let V=GZ((J,G)=>{(async()=>{let M;try{M=new URL(J.url??"/","http://127.0.0.1").pathname}catch{l(G,400,Z0,"bad-url");return}if(M!==N2){l(G,404,Z0,"not-found");return}let L=J.method??"POST";if(L!=="POST"&&L!=="GET"&&L!=="DELETE"){G.setHeader("Allow","GET, POST, DELETE"),l(G,405,Z0,"method-not-allowed");return}let x=D2(J,Z);if(!x.ok){l(G,x.status,Z0,"forbidden",{reason:x.reason});return}let U=J.headers["mcp-session-id"],D=typeof U==="string"?U:void 0;if(L==="GET"||L==="DELETE"){if(!D||!$.has(D)){l(G,400,Z0,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let B=$.get(D).transport;Q(D);try{await B.handleRequest(J,G)}catch(N){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",N),!G.headersSent)l(G,500,U1,"internal")}return}let w;try{w=await wZ(J)}catch(B){if(B instanceof H1){l(G,415,Z0,"expected-application-json");return}if(B instanceof x1){l(G,413,Z0,"body-too-large");return}l(G,400,DZ,"invalid-json");return}let H;if(D&&$.has(D))H=$.get(D).transport,Q(D);else if(!D&&w!==void 0&&NZ(w)){let B=J.headers["x-ideawave-user-id"],N=typeof B==="string"&&B.trim().length>0?B.trim():null,O=J.headers["x-ideawave-frontend-session-id"],C=typeof O==="string"&&O.trim().length>0?O.trim():null,P=J.headers["x-ideawave-tool-surface"],j=typeof P==="string"&&P.trim()==="read"?"read":"full",k=J.headers["x-ideawave-images-supported"],_=typeof k==="string"&&k.trim()==="1",b=J.headers["x-ideawave-card-id"],d=typeof b==="string"&&b.trim().length>0?b.trim():null,n=J.headers["x-ideawave-board-id"],A=typeof n==="string"&&n.trim().length>0?n.trim():null,v=J.headers["x-ideawave-run-folder"],y=typeof v==="string"&&v.trim().length>0?v.trim():null,I=LZ(J,w);if($.size>=M2)await K();let h=null,K0=new zZ({sessionIdGenerator:()=>jZ(),onsessioninitialized:(U0)=>{h=U0,$.set(U0,{transport:K0,lastActivity:Date.now()})},onsessionclosed:(U0)=>{$.delete(U0)}});K0.onclose=()=>{if(K0.sessionId)$.delete(K0.sessionId)};try{await X.buildServer({userId:N,frontendSessionId:C,boardId:A,toolSurface:j,imagesSupported:_,cardId:d,runFolder:y,clientHint:I}).connect(K0)}catch(U0){if(console.error("[mcp] buildServer/connect failed",U0),h)$.delete(h);await K0.close().catch(()=>{return}),l(G,500,U1,"server-init-failed");return}H=K0}else{l(G,400,Z0,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await H.handleRequest(J,G,w)}catch(B){if(console.error("[mcp] transport.handleRequest threw",B),!G.headersSent)l(G,500,U1,"internal")}})().catch((M)=>{console.error("[mcp] unhandled request handler error:",M)})});return Z=await PZ(V,MZ(X.port)),{url:`http://127.0.0.1:${Z}${N2}`,port:Z,close:async()=>{clearInterval(Y);for(let J of $.values())await J.transport.close().catch(()=>{return});$.clear(),await new Promise((J)=>V.close(()=>J()))}}}var AZ={name:"ideawave-board",version:"1.0.0"},zX="list_run_folder",UX="read_run_folder_file",O2=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",zX,UX]),k2=new Set(["inspect_diagram"]),CZ=[{name:zX,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:UX,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 D1(X){return{content:[{type:"text",text:X}]}}function RZ(X){return D1(JSON.stringify(X,null,2))}function B2(X){return{...D1(X),isError:!0}}async function fZ(X,$){if(!$||X.isError)return X;let Z=X.content.find((K)=>K.type==="text");if(!Z)return X;let Q;try{let K=JSON.parse(Z.text);if(typeof K.path!=="string")return X;Q=y0.resolve(K.path)}catch{return X}let W=y0.resolve(y0.join(OZ.tmpdir(),"ideawave-screenshots"));if(y0.dirname(Q)!==W||!/^board-[a-z0-9-]+\.png$/i.test(y0.basename(Q)))return X;try{if(!(await BZ(Q)).isFile())return X;let Y=await FZ(Q);if(Y.byteLength<1024||Y.byteLength>26214400||!Y.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return X;return{...X,content:[...X.content,{type:"image",data:Y.toString("base64"),mimeType:"image/png"}]}}catch{return X}}function yZ(X,$,Z="full",Q=!1){return X.getMetadata($).filter((W)=>{let K=$X(W.name);if(Z==="read"&&!O2.has(K))return!1;if(!Q&&k2.has(K))return!1;return!0}).map((W)=>({name:W.name,description:W.description,inputSchema:W.inputSchema}))}function bZ(X,$,Z={}){let Q=yZ(X,$,Z.toolSurface??"full",Z.imagesSupported??!1);return Z.includeRunFolderTools?[...Q,...CZ]:Q}function F2(X,$){if(!X||typeof X!=="object"||Array.isArray(X))return null;let Z=X[$];return typeof Z==="string"?Z:null}async function EZ(X,$,Z){if(Z&&Z.trim().length>0)return Z.trim();if(!X||!$)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await X0({boardId:X,cardId:$})).runFolder}async function TZ(X){let $=await EZ(X.boardId,X.cardId,X.runFolder);if(X.name===zX){let Z=F2(X.args,"path")??"",Q=await L$($,Z);return RZ(Q)}if(X.name===UX){let Z=F2(X.args,"path");if(!Z)return B2("read_run_folder_file requires a path.");return D1(await XX($,Z))}return B2(`Unknown local tool "${X.name}"`)}function vZ(X,$,Z,Q,W,K="full",Y=!1){let V=new kZ(AZ,{capabilities:{tools:{}}}),z=async()=>{if(Y)return!0;if(m$(Q))return!0;if(Z&&Q)try{return(await X0({boardId:Z,cardId:Q})).adapter.supportsImages===!0}catch{return!1}return!1};return V.setRequestHandler(_Z,async()=>({tools:bZ(X,$,{includeRunFolderTools:Boolean(W||Z&&Q),toolSurface:K,imagesSupported:await z()})})),V.setRequestHandler(qZ,async(J)=>{let{name:G,arguments:M}=J.params,L=$X(G),x=Date.now();q("mcp.tool_call_received",{frontendSessionId:$,cardId:Q,toolName:L});try{if(L===zX||L===UX)return await TZ({name:L,args:M,boardId:Z,cardId:Q,runFolder:W});if(K==="read"&&!O2.has(L))throw Error(`Tool "${G}" is not available in read-only mode`);if(k2.has(L)&&!await z())throw Error(`Tool "${G}" requires a runtime that supports image input`);let U=await X.callTool($,L,M??{},void 0,Q??void 0);if(q("mcp.tool_result_returned",{frontendSessionId:$,cardId:Q,toolName:L,elapsedMs:Date.now()-x}),U&&typeof U==="object"&&Array.isArray(U.content)){let D=U;return L==="screenshot_board"?await fZ(D,await z()):D}return{content:[{type:"text",text:typeof U==="string"?U:JSON.stringify(U)}]}}catch(U){return q("mcp.tool_result_returned",{frontendSessionId:$,cardId:Q,toolName:L,elapsedMs:Date.now()-x,hasError:!0}),{content:[{type:"text",text:U instanceof Error?U.message:"Tool call failed"}],isError:!0}}}),V}function q2(X,$){return L2({buildServer:(Z)=>vZ(X,Z.frontendSessionId,Z.boardId,Z.cardId,Z.runFolder,Z.toolSurface,Z.imagesSupported),port:$})}import HX from"node:fs/promises";import w1 from"node:os";import xX from"node:path";function _2(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function hZ(){let[X,$]=await Promise.all([m(),V$()]),Z=X.globalDefaultConfigId?X.runtimes.find((Q)=>Q.id===X.globalDefaultConfigId)??null:null;return{runtimes:X.runtimes,globalDefaultConfigId:X.globalDefaultConfigId,globalDefaultEffective:Z?{runFolder:Z.runFolder??w1.homedir(),modelId:Z.defaultModelId??null,configValues:Z.defaultConfigValues??{}}:null,knownAdapters:D0().map((Q)=>({id:Q.id,displayName:Q.displayName})),readiness:$}}async function IZ(X){try{let $=await X0({boardId:X.boardId,cardId:X.cardId});return{resolved:{configId:$.entry.id,adapterId:$.entry.kind==="registered"?$.entry.adapterId:null,displayName:$.entry.displayName,runFolder:$.runFolder,modelId:$.modelId,configValues:$.configValues}}}catch($){if($ instanceof Y0)return{resolved:null};throw $}}async function SZ(X){return p(($)=>{let Z=$.runtimes.find((K)=>K.kind==="registered"&&K.adapterId===X.adapterId);if(Z)return Z;let Q=D0().find((K)=>K.id===X.adapterId);if(!Q)throw Error(`Unknown adapterId: ${X.adapterId}`);let W={id:_2(),kind:"registered",adapterId:X.adapterId,displayName:Q.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return $.runtimes.push(W),W})}async function gZ(X){return p(($)=>{let Z={id:_2(),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 $.runtimes.push(Z),Z})}async function mZ(X){await p(($)=>{if($.runtimes=$.runtimes.filter((Z)=>Z.id!==X.runtimeConfigId),$.globalDefaultConfigId===X.runtimeConfigId)$.globalDefaultConfigId=null;for(let Z of Object.keys($.boardOverrides))if($.boardOverrides[Z].runtimeConfigId===X.runtimeConfigId)delete $.boardOverrides[Z];for(let Z of Object.keys($.cardOverrides))if($.cardOverrides[Z].runtimeConfigId===X.runtimeConfigId)delete $.cardOverrides[Z]})}async function cZ(X){await p(($)=>{let Z=$.runtimes.find((Q)=>Q.id===X.runtimeConfigId);if(!Z)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);if($.globalDefaultConfigId=X.runtimeConfigId,X.runFolder!==void 0)Z.runFolder=X.runFolder;if(X.modelId!==void 0)Z.defaultModelId=X.modelId;if(X.configValues!==void 0)Z.defaultConfigValues=X.configValues})}async function lZ(X){X.boardId,await p(($)=>{if(X.runtimeConfigId===null){delete $.cardOverrides[X.cardId];return}if(!$.runtimes.some((W)=>W.id===X.runtimeConfigId))throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let Q=$.cardOverrides[X.cardId];$.cardOverrides[X.cardId]={runtimeConfigId:X.runtimeConfigId,runFolder:X.runFolder!==void 0?X.runFolder:Q?.runFolder??null,modelId:X.modelId!==void 0?X.modelId:Q?.modelId??null,configValues:X.configValues!==void 0?X.configValues:Q?.configValues??{}}})}async function pZ(X){let Z=(await m()).runtimes.find((Y)=>Y.id===X.runtimeConfigId);if(!Z)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let Q=a(Z),W=await Q.resolveSpawnConfig(Z),K=Z.runFolder??w1.homedir();try{let Y=await h$({spawn:{...W,cwd:K},modelId:X.modelId??Z.defaultModelId??null,configValues:X.configValues??Z.defaultConfigValues??{}}),V=s0({adapterId:Q.id,models:Y.models,currentModelId:Y.currentModelId}),z=new Date().toISOString();return await p((J)=>{let G=J.runtimes.find((M)=>M.id===X.runtimeConfigId);if(G)G.discoveredModels=V,G.discoveredConfigOptions=Y.configOptions,G.discoveredAt=z}),{ok:!0,models:V,configOptions:Y.configOptions,currentModelId:Y.currentModelId}}catch(Y){if(Y instanceof H0)throw Error(`${Y.message}${Q.authHint?` ${Q.authHint}`:""}`);if(Y instanceof R||Y instanceof u)throw Error(Y.message);throw Y}}async function uZ(X){let $=w1.homedir(),Z=X.path?.trim()?X.path.trim():$,Q=xX.resolve(Z),W=!0;try{if(!(await HX.stat(Q)).isDirectory())Q=xX.dirname(Q)}catch{W=!1,Q=$}let K=[];try{K=(await HX.readdir(Q,{withFileTypes:!0})).filter((z)=>z.isDirectory()&&!z.name.startsWith(".")).map((z)=>({name:z.name,path:xX.join(Q,z.name)})).sort((z,J)=>z.name.localeCompare(J.name))}catch{K=[]}let Y=xX.dirname(Q);return{path:Q,parent:Y===Q?null:Y,home:$,exists:W,entries:K}}var A2={list:hZ,getEffectiveForCard:IZ,registerRegistered:SZ,registerCustom:gZ,unregister:mZ,setUserDefault:cZ,setCardOverride:lZ,refreshModels:pZ,browseFolder:uZ};var aZ=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function dZ(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function C2(){try{let X=await m();if(X.globalDefaultConfigId){if(X.runtimes.some((Z)=>Z.id===X.globalDefaultConfigId))return X.globalDefaultConfigId}for(let $ of aZ){if((await j$($.id))?.status!=="ready")continue;let Q=null;if(await p((W)=>{if(W.globalDefaultConfigId){if(W.runtimes.some((V)=>V.id===W.globalDefaultConfigId)){Q=W.globalDefaultConfigId;return}}let K=W.runtimes.find((Y)=>Y.kind==="registered"&&Y.adapterId===$.id);if(!K){let Y={id:dZ(),kind:"registered",adapterId:$.id,displayName:$.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};W.runtimes.push(Y),K=Y}W.globalDefaultConfigId=K.id,Q=K.id}),Q)return console.log(`[ideawave-cli] using agent runtime: ${$.displayName}`),Q}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 iZ=120000;function oZ(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class N1{sessions=new Map;createCallId;toolCallTimeoutMs;constructor(X={}){this.createCallId=X.createCallId??oZ,this.toolCallTimeoutMs=X.toolCallTimeoutMs??iZ}register(X){let $=this.sessions.get(X.frontendSessionId);if($){if($.userId!==X.userId)this.rejectPending($,"frontend session user changed"),$.activeRunIds.clear();this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:$.pendingToolCalls,activeRunIds:$.activeRunIds,activeRunCardIds:$.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,$="frontend session disconnected"){let Z=this.sessions.get(X);if(!Z)return{activeRunIds:[]};return this.sessions.delete(X),this.rejectPending(Z,$),{activeRunIds:Array.from(Z.activeRunIds)}}sessionCount(){return this.sessions.size}has(X){return this.sessions.has(X)}getUserId(X){return this.sessions.get(X)?.userId??null}setMetadata(X,$){let Z=this.sessions.get(X);if(Z)Z.tools=$}getMetadata(X){if(!X)return[];return this.sessions.get(X)?.tools??[]}sendToSession(X,$){let Z=this.sessions.get(X);if(!Z)return!1;return Z.send($),!0}callTool(X,$,Z,Q,W){if(!X)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let K=this.sessions.get(X);if(!K)return Promise.reject(Error(`Frontend session ${X} is not connected`));let Y=this.createCallId();return new Promise((V,z)=>{let J=Q??(W?this.getActiveRunIdForCard(K,W):this.getSoleActiveRunId(K)),G=W??(J?K.activeRunCardIds.get(J):void 0),M=Date.now(),L=setTimeout(()=>{K.pendingToolCalls.delete(Y),q("tool_queue.timeout",{frontendSessionId:X,runId:J,cardId:G,callId:Y,toolName:$,elapsedMs:Date.now()-M,queueDepth:K.pendingToolCalls.size}),z(Error(`Tool "${$}" timed out waiting for the frontend`))},this.toolCallTimeoutMs);K.pendingToolCalls.set(Y,{resolve:V,reject:z,timer:L,name:$,runId:J??null,cardId:G??null,startedAt:M}),q("tool_queue.forwarded_to_browser",{frontendSessionId:X,runId:J,cardId:G,callId:Y,toolName:$,queueDepth:K.pendingToolCalls.size}),K.send({type:"tool_call",callId:Y,name:$,args:Z,...J?{runId:J}:{},...G?{cardId:G}:{}})})}handleToolResult(X,$){let Z=this.sessions.get(X);if(!Z)return;let Q=Z.pendingToolCalls.get($.callId);if(!Q)return;if(Z.pendingToolCalls.delete($.callId),clearTimeout(Q.timer),q("tool_queue.result_received",{frontendSessionId:X,runId:Q.runId,cardId:Q.cardId,callId:$.callId,toolName:Q.name,elapsedMs:Date.now()-Q.startedAt,queueDepth:Z.pendingToolCalls.size,ok:$.ok}),$.ok){Q.resolve($.result);return}let W=$.result;if(W&&typeof W==="object"&&Array.isArray(W.content)){Q.resolve({...W,isError:!0});return}Q.reject(Error($.error??"Tool execution failed"))}markRunActive(X,$,Z){let Q=this.sessions.get(X);if(!Q)return;if(Q.activeRunIds.add($),Z)Q.activeRunCardIds.set($,Z)}markRunSettled(X,$){let Z=this.sessions.get(X);if(!Z)return;Z.activeRunIds.delete($),Z.activeRunCardIds.delete($)}ownsRun(X,$){return this.sessions.get(X)?.activeRunIds.has($)??!1}rejectPending(X,$){for(let Z of X.pendingToolCalls.values())clearTimeout(Z.timer),q("tool_queue.rejected",{frontendSessionId:X.frontendSessionId,runId:Z.runId,cardId:Z.cardId,toolName:Z.name,elapsedMs:Date.now()-Z.startedAt}),Z.reject(Error($));X.pendingToolCalls.clear()}getSoleActiveRunId(X){return X.activeRunIds.size===1?X.activeRunIds.values().next().value:void 0}getActiveRunIdForCard(X,$){let Z=[...X.activeRunCardIds.entries()].filter(([Q,W])=>X.activeRunIds.has(Q)&&W===$).map(([Q])=>Q);return Z.length===1?Z[0]:void 0}}function f2(){return"0.0.69".trim()?"0.0.69":"dev"}var nZ=process.argv.slice(2),P1=Y2(nZ,process.env);if(P1.allowRailwayPrPreviews)process.env[f0]="1";var W0=P1.cliArgs[0],{browserKitEnabled:E0,captureEngineEnabled:tZ}=P1;if(W0==="--help"||W0==="-h"||W0==="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(W0==="--version"||W0==="-v"||W0==="version")console.log(f2()),process.exit(0);if(W0)console.error(`Unknown command: ${W0}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var T0=new N1,z0=null,rZ=E0?{phase:"ready",message:"Local browser-kit proxy is ready"}:{phase:"idle"},B0=new r0;function Q0(X,$){T0.sendToSession(X,$)}async function sZ(X,$){try{let Z=A2[$.method],Q=await Z($.params);Q0(X,{type:"runtime_rpc_result",requestId:$.requestId,ok:!0,result:Q})}catch(Z){Q0(X,{type:"runtime_rpc_result",requestId:$.requestId,ok:!1,error:Z instanceof Error?Z.message:String(Z)})}}var v0=!1,b0=null;async function M1(){if(v0)return;if(b0)return b0;return b0=(async()=>{try{let X=await q2(T0);_1({...X,requestedPort:X.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${X.url}`);try{await p1({onStatusChange:($)=>{if(G$(),z0?.sendStatus(),$.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${$.packageName}: ${$.error??"unknown error"}`)}})}catch($){console.warn("[ideawave-cli] ACP bridge setup skipped:",$ instanceof Error?$.message:String($))}await C2(),v0=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),z0?.sendStatus()}catch(X){console.error("[ideawave-cli] failed to start agent host:",X),z0?.sendStatus(void 0,X instanceof Error?X.message:String(X))}finally{b0=null}})(),b0}if(process.env.APP_ENV!=="development"){let X=await z2();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(tZ)t$().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"}`)});z0=await U2({registry:T0,runtime:null,mcpReady:()=>v0,capabilities:E0?[A1]:[],cliVersion:f2(),browserRuntimeStatus:()=>rZ,onToolMetadata:(X)=>{console.log(`[ideawave-cli] session ${X} advertised ${T0.getMetadata(X).length} tools`),M1()},onRunTurn:(X,$)=>{console.log(`[ideawave-cli] running agent turn for card ${$.cardId} (session ${X})`),(async()=>{if(await M1(),!v0){Q0(X,{type:"run_settled",runId:$.runId,cardId:$.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"IdeaWave CLI agent host is not ready",partialText:null}});return}await u$($,(Z)=>Q0(X,Z))})().catch(()=>{return}).finally(()=>T0.markRunSettled(X,$.runId))},onCancelRun:(X,$)=>{$1($)},onRuntimeRpc:(X,$)=>{sZ(X,$)},onBrowserRpc:(X,$,Z)=>{if(!E0){Q0(X,{type:"browser_rpc_result",requestId:Z.requestId,ok:!1,error:"The development browser-kit proxy is not enabled"});return}B0.handleRpc(X,$,Z).then((Q)=>{Q0(X,{type:"browser_rpc_result",requestId:Z.requestId,ok:!0,result:Q})},(Q)=>{Q0(X,{type:"browser_rpc_result",requestId:Z.requestId,ok:!1,error:Q instanceof Error?Q.message:String(Q)})})},onHttpRequest:(X,$)=>E0?B0.handleHttpRequest(X,$):!1,onHttpUpgrade:(X,$,Z)=>E0?B0.handleUpgrade(X,$,Z):!1,onWarmupRun:(X,$,Z)=>{(async()=>{if(await M1(),!v0)return{status:"retryable",error:"agent host is not ready"};return a$({cardId:$.cardId,boardId:$.boardId,userId:Z,frontendSessionId:X})})().then((Q)=>{if(!$.warmupId)return;Q0(X,{type:"warmup_result",warmupId:$.warmupId,cardId:$.cardId,...Q})})},onDisconnect:(X,$)=>{B0.closeFrontendSession(X),c$(X);for(let Z of $)$1(Z);q("bridge.frontend_disconnected",{frontendSessionId:X,activeRuns:$.length}),F1(X).catch((Z)=>{console.warn(`[ideawave-cli] failed to evict sessions for ${X}:`,Z instanceof Error?Z.message:String(Z))}),console.log(`[ideawave-cli] browser session ${X} disconnected`)}});B0.setPort(z0.port);console.log(`[ideawave-cli] browser bridge listening on ${z0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var R2=!1;for(let X of["SIGINT","SIGTERM"])process.once(X,()=>{if(R2)return;R2=!0,l$(),(async()=>{await B0.close(),await e$(),await z0?.close().catch(()=>{return}),process.exit(0)})()});
|
|
946
|
+
${Z}`),X.destroy()}function JZ(X,$){return new Promise((Z,Q)=>{let W=(Y)=>{X.off("listening",K),Q(Y)},K=()=>{X.off("error",W);let Y=X.address();if(!Y||typeof Y==="string"){Q(Error("Failed to read CLI bridge server address"));return}Z(Y.port)};X.once("error",W),X.once("listening",K),X.listen($,"127.0.0.1")})}function V2(X){return new Promise(($,Z)=>{X.close((Q)=>{if(Q)Z(Q);else $()})})}async function U2(X,$=G1()){let Z=new Map,Q=new Map,W=X.maxMessageSize??n3,K=!1,Y=(x)=>{let U=Q.get(x);if(U)clearTimeout(U);Q.delete(x)},V=(x)=>{Q.delete(x);let{activeRunIds:U}=X.registry.disconnect(x);X.onDisconnect(x,U)},z=(x,U)=>{let D={type:"cli_status",connected:!0,runtime:X.runtime,mcpReady:X.mcpReady(),error:U,capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()};if(x){let w=Z.get(x);if(w)L0(w,D);return}for(let w of Z.values())L0(w,D)},J=(x,U)=>{let D=U.sessionId.trim(),w=U.userId.trim();if(!D||!w){L0(x,{type:"cli_status",connected:!1,runtime:X.runtime,mcpReady:X.mcpReady(),error:"Missing frontend session or user id"}),x.close();return}Y(D);let H=Z.get(D);if(H&&H!==x)H.close();x.data.frontendSessionId=D,Z.set(D,x),X.registry.register({frontendSessionId:D,userId:w,tools:U.tools,send:(B)=>L0(x,B)}),z(D),X.onToolMetadata?.(D)},G=(x,U)=>{let D=X.registry.getUserId(x);if(!D)return;switch(U.type){case"bridge_ping":{let w=Z.get(x);if(w)L0(w,{type:"bridge_pong"});break}case"tool_metadata":X.registry.setMetadata(x,U.tools),X.onToolMetadata?.(x);break;case"tool_result":X.registry.handleToolResult(x,U);break;case"run_turn":q("bridge.run_received",{runId:U.run.runId,cardId:U.run.cardId,frontendSessionId:x}),X.registry.markRunActive(x,U.run.runId,U.run.cardId),X.onRunTurn(x,{...U.run,frontendSessionId:x,userId:D});break;case"cancel_run":if(X.registry.ownsRun(x,U.runId))X.onCancelRun(x,U.runId);break;case"runtime_rpc":X.onRuntimeRpc(x,U);break;case"browser_rpc":X.onBrowserRpc?.(x,Z.get(x)?.data.frontendOrigin??"",U);break;case"warmup_run":X.onWarmupRun(x,{...U,frontendSessionId:x},D);break;default:break}},M=(x,U)=>{let D=GX(x.headers.origin),w=z1(D),H={Vary:"Origin"};if(w&&D)H["Access-Control-Allow-Origin"]=D,H["Access-Control-Allow-Private-Network"]="true";if(x.method==="OPTIONS"){U.writeHead(204,{...H,"Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*","Access-Control-Max-Age":"600"}),U.end();return}if(x.method!=="GET"){U.writeHead(405,H),U.end();return}U.writeHead(200,{...H,"content-type":"application/json","cache-control":"no-store"}),U.end(JSON.stringify({ideawave:!0,runtime:X.runtime,mcpReady:X.mcpReady(),capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()}))},L=(x,U)=>{let D=GX(x.headers.origin),w=z1(D),H={Vary:"Origin"};if(w&&D)H["Access-Control-Allow-Origin"]=D,H["Access-Control-Allow-Private-Network"]="true";if(x.method==="OPTIONS"){U.writeHead(204,{...H,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"content-type","Access-Control-Max-Age":"600"}),U.end();return}if(!w){U.writeHead(403,H),U.end();return}if(x.method!=="POST"){U.writeHead(405,H),U.end();return}let B={...H,"content-type":"application/json"},N=(P,j)=>{U.writeHead(P,B),U.end(JSON.stringify(j))},O="",C=!1;x.on("data",(P)=>{if(O+=P.toString("utf8"),O.length>e3)C=!0,x.destroy()}),x.on("end",()=>{if(C){N(400,{ok:!1,error:"Request body too large"});return}let P;try{P=JSON.parse(O)}catch{N(400,{ok:!1,error:"Invalid JSON body"});return}let j=typeof P.url==="string"?P.url:"";if(!W2(j)){N(400,{ok:!1,error:"url must be an http(s) loopback or /static_boards/ page URL"});return}let k=(_,b)=>{let d=typeof _==="number"?_:Number.NaN;if(!Number.isFinite(d))return b;return Math.min(4000,Math.max(200,Math.round(d)))};K2({url:j,width:k(P.width,1440),height:k(P.height,900)}).then((_)=>N(200,{ok:!0,path:_.path,engine:_.engine})).catch((_)=>{let b=_ instanceof R0?503:_ instanceof jX?429:500;N(b,{ok:!1,..._ instanceof R0?{installing:!0}:{},error:_ instanceof Error?_.message:String(_)})})})};for(let x of $){let U=i3((H,B)=>{(async()=>{let N=new URL(H.url??"/","http://127.0.0.1").pathname;if(N===X2){M(H,B);return}if(N===s3){L(H,B);return}if(await X.onHttpRequest?.(H,B))return;B.writeHead(404,{"content-type":"text/plain"}),B.end("IdeaWave CLI bridge")})().catch((N)=>{if(B.headersSent){B.destroy(N instanceof Error?N:void 0);return}B.writeHead(500,{"content-type":"text/plain"}),B.end("IdeaWave CLI bridge request failed")})}),D=new o3({noServer:!0,maxPayload:W}),w=(H)=>{if(H.idleTimer)clearTimeout(H.idleTimer);H.idleTimer=setTimeout(()=>{H.close()},t3),H.idleTimer.unref?.()};D.on("connection",(H,B)=>{let N=H;N.data={id:d3(),frontendSessionId:null,frontendOrigin:new URL(GX(B.headers.origin)??G2).origin},N.idleTimer=null,w(N),N.on("ping",()=>w(N)),N.on("pong",()=>w(N)),N.on("error",()=>{if(N.idleTimer)clearTimeout(N.idleTimer);N.close()}),N.on("message",(O)=>{w(N);let C=YZ(O);if(W>0&&C.length>W)return;let P=g0(C);if(!P)return;let j=N.data.frontendSessionId;if(!j){if(P.type==="bridge_probe")L0(N,{type:"bridge_probe_ack",protocolVersion:P.protocolVersion});else if(P.type==="frontend_hello")J(N,P);return}G(j,P)}),N.on("close",()=>{if(N.idleTimer)clearTimeout(N.idleTimer);let O=N.data.frontendSessionId;if(!O)return;if(Z.get(O)!==N)return;if(Z.delete(O),Y(O),K)return;Q.set(O,setTimeout(()=>V(O),r3))})}),U.on("upgrade",(H,B,N)=>{let O=new URL(H.url??"/","http://127.0.0.1").pathname;if(X.onHttpUpgrade?.(H,B,N))return;if(O!==j1){J2(B,404,"Not Found");return}if(!z1(GX(H.headers.origin))){J2(B,403,"Forbidden");return}D.handleUpgrade(H,B,N,(C)=>{D.emit("connection",C,H)})});try{let H=await JZ(U,x);return{url:`ws://127.0.0.1:${H}${j1}`,port:H,sendStatus:z,close:async()=>{K=!0;for(let B of Q.values())clearTimeout(B);Q.clear();for(let B of D.clients){let N=B;if(N.idleTimer)clearTimeout(N.idleTimer);N.close()}D.close(),await V2(U).catch(()=>{return})}}}catch(H){if(D.close(),await V2(U).catch(()=>{return}),H?.code==="EADDRINUSE")continue;throw H}}throw Error(`No free IdeaWave CLI bridge port found in ${$[0]}-${$.at(-1)}`)}import{lstat as BZ,readFile as FZ}from"node:fs/promises";import OZ from"node:os";import y0 from"node:path";import{Server as kZ}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as qZ,ListToolsRequestSchema as _Z}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as jZ}from"node:crypto";import{createServer as GZ}from"node:http";import{StreamableHTTPServerTransport as zZ}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as w2}from"@modelcontextprotocol/sdk/types.js";var H2=new Set(["127.0.0.1","localhost","[::1]","::1"]);function VZ(X){let $=X.trim();if($.length===0)return null;if($.startsWith("[")){let K=$.indexOf("]");if(K===-1)return null;let Y=$.slice(0,K+1),V=$.slice(K+1);if(V.length===0)return{host:Y,port:null};if(!V.startsWith(":"))return null;let z=Number(V.slice(1));if(!Number.isInteger(z)||z<=0||z>65535)return null;return{host:Y,port:z}}let Z=$.lastIndexOf(":");if(Z===-1)return{host:$,port:null};let Q=$.slice(Z+1),W=Number(Q);if(!Number.isInteger(W)||W<=0||W>65535)return{host:$,port:null};return{host:$.slice(0,Z),port:W}}function x2(X){return H2.has(X)||H2.has(X.toLowerCase())}function D2(X,$){let Z=X.headers.host;if(typeof Z!=="string")return{ok:!1,status:403,reason:"missing-host"};let Q=VZ(Z);if(!Q)return{ok:!1,status:403,reason:"bad-host"};if(!x2(Q.host))return{ok:!1,status:403,reason:"non-loopback-host"};if(Q.port!==null&&Q.port!==$)return{ok:!1,status:403,reason:"host-port-mismatch"};let W=X.headers.origin;if(typeof W==="string"&&W.length>0){if(W!=="null"){let K;try{K=new URL(W)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!x2(K.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var N2="/mcp",UZ=43274,P2=16777216,HZ=1800000,xZ=300000,M2=200,DZ=-32700,Z0=-32600,U1=-32603;function l(X,$,Z,Q,W){X.statusCode=$,X.setHeader("content-type","application/json"),X.end(JSON.stringify({jsonrpc:"2.0",error:{code:Z,message:Q,...W?{data:W}:{}},id:null}))}class H1 extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class x1 extends Error{constructor(){super(`body exceeds ${P2} bytes`);this.name="BodyTooLargeError"}}async function wZ(X){if(X.method&&X.method!=="POST")return;let $=X.headers["content-type"];if(typeof $==="string"&&$.trim().length>0){if(!$.toLowerCase().includes("application/json"))throw new H1}let Z=0,Q=[];for await(let K of X){let Y=typeof K==="string"?Buffer.from(K):K;if(Z+=Y.byteLength,Z>P2)throw new x1;Q.push(Y)}if(Q.length===0)return;let W=Buffer.concat(Q).toString("utf8");if(W.length===0)return;return JSON.parse(W)}function NZ(X){if(Array.isArray(X))return X.some(w2);return w2(X)}function MZ(X){if(typeof X==="number")return X;let $=process.env.IDEAWAVE_MCP_PORT;if($&&$.trim().length>0){let Z=Number($);if(Number.isInteger(Z)&&Z>=0&&Z<65536)return Z}return UZ}async function PZ(X,$){let Z=(W)=>new Promise((K,Y)=>{let V=(J)=>{X.off("listening",z),Y(J)},z=()=>{X.off("error",V),K()};X.once("error",V),X.once("listening",z),X.listen(W,"127.0.0.1")});try{await Z($)}catch(W){if(W.code!=="EADDRINUSE"||$===0)throw W;console.warn(`[mcp] port ${$} in use, falling back to an OS-assigned port; external CLIs will need to re-paste the install command from Settings → External agents`),await Z(0)}let Q=X.address();if(Q==null||typeof Q==="string")throw Error("[mcp] failed to read bound address");return Q.port}function LZ(X,$){if($&&typeof $==="object"&&!Array.isArray($)){let Q=$.params;if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let W=Q.clientInfo;if(W&&typeof W==="object"&&!Array.isArray(W)){let K=W.name;if(typeof K==="string"&&K.trim().length>0)return K.trim()}}}let Z=X.headers["user-agent"];if(typeof Z==="string"&&Z.trim().length>0)return Z.trim();return null}async function L2(X){let $=new Map,Z=0;function Q(J){let G=$.get(J);if(G)G.lastActivity=Date.now()}async function W(J,G){$.delete(J),await G.transport.close().catch(()=>{return})}async function K(){let J=null,G=1/0;for(let[M,L]of $)if(L.lastActivity<G)G=L.lastActivity,J=M;if(J!==null){let M=$.get(J);if(M)console.warn(`[mcp] session cap of ${M2} reached; evicting ${J}`),await W(J,M)}}let Y=setInterval(()=>{let J=Date.now()-HZ;for(let[G,M]of $)if(M.lastActivity<J)console.log(`[mcp] sweeping idle session ${G}`),W(G,M)},xZ);Y.unref?.();let V=GZ((J,G)=>{(async()=>{let M;try{M=new URL(J.url??"/","http://127.0.0.1").pathname}catch{l(G,400,Z0,"bad-url");return}if(M!==N2){l(G,404,Z0,"not-found");return}let L=J.method??"POST";if(L!=="POST"&&L!=="GET"&&L!=="DELETE"){G.setHeader("Allow","GET, POST, DELETE"),l(G,405,Z0,"method-not-allowed");return}let x=D2(J,Z);if(!x.ok){l(G,x.status,Z0,"forbidden",{reason:x.reason});return}let U=J.headers["mcp-session-id"],D=typeof U==="string"?U:void 0;if(L==="GET"||L==="DELETE"){if(!D||!$.has(D)){l(G,400,Z0,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let B=$.get(D).transport;Q(D);try{await B.handleRequest(J,G)}catch(N){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",N),!G.headersSent)l(G,500,U1,"internal")}return}let w;try{w=await wZ(J)}catch(B){if(B instanceof H1){l(G,415,Z0,"expected-application-json");return}if(B instanceof x1){l(G,413,Z0,"body-too-large");return}l(G,400,DZ,"invalid-json");return}let H;if(D&&$.has(D))H=$.get(D).transport,Q(D);else if(!D&&w!==void 0&&NZ(w)){let B=J.headers["x-ideawave-user-id"],N=typeof B==="string"&&B.trim().length>0?B.trim():null,O=J.headers["x-ideawave-frontend-session-id"],C=typeof O==="string"&&O.trim().length>0?O.trim():null,P=J.headers["x-ideawave-tool-surface"],j=typeof P==="string"&&P.trim()==="read"?"read":"full",k=J.headers["x-ideawave-images-supported"],_=typeof k==="string"&&k.trim()==="1",b=J.headers["x-ideawave-card-id"],d=typeof b==="string"&&b.trim().length>0?b.trim():null,n=J.headers["x-ideawave-board-id"],A=typeof n==="string"&&n.trim().length>0?n.trim():null,v=J.headers["x-ideawave-run-folder"],y=typeof v==="string"&&v.trim().length>0?v.trim():null,I=LZ(J,w);if($.size>=M2)await K();let h=null,K0=new zZ({sessionIdGenerator:()=>jZ(),onsessioninitialized:(U0)=>{h=U0,$.set(U0,{transport:K0,lastActivity:Date.now()})},onsessionclosed:(U0)=>{$.delete(U0)}});K0.onclose=()=>{if(K0.sessionId)$.delete(K0.sessionId)};try{await X.buildServer({userId:N,frontendSessionId:C,boardId:A,toolSurface:j,imagesSupported:_,cardId:d,runFolder:y,clientHint:I}).connect(K0)}catch(U0){if(console.error("[mcp] buildServer/connect failed",U0),h)$.delete(h);await K0.close().catch(()=>{return}),l(G,500,U1,"server-init-failed");return}H=K0}else{l(G,400,Z0,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await H.handleRequest(J,G,w)}catch(B){if(console.error("[mcp] transport.handleRequest threw",B),!G.headersSent)l(G,500,U1,"internal")}})().catch((M)=>{console.error("[mcp] unhandled request handler error:",M)})});return Z=await PZ(V,MZ(X.port)),{url:`http://127.0.0.1:${Z}${N2}`,port:Z,close:async()=>{clearInterval(Y);for(let J of $.values())await J.transport.close().catch(()=>{return});$.clear(),await new Promise((J)=>V.close(()=>J()))}}}var AZ={name:"ideawave-board",version:"1.0.0"},zX="list_run_folder",UX="read_run_folder_file",O2=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",zX,UX]),k2=new Set(["inspect_diagram"]),CZ=[{name:zX,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:UX,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 D1(X){return{content:[{type:"text",text:X}]}}function RZ(X){return D1(JSON.stringify(X,null,2))}function B2(X){return{...D1(X),isError:!0}}async function fZ(X,$){if(!$||X.isError)return X;let Z=X.content.find((K)=>K.type==="text");if(!Z)return X;let Q;try{let K=JSON.parse(Z.text);if(typeof K.path!=="string")return X;Q=y0.resolve(K.path)}catch{return X}let W=y0.resolve(y0.join(OZ.tmpdir(),"ideawave-screenshots"));if(y0.dirname(Q)!==W||!/^board-[a-z0-9-]+\.png$/i.test(y0.basename(Q)))return X;try{if(!(await BZ(Q)).isFile())return X;let Y=await FZ(Q);if(Y.byteLength<1024||Y.byteLength>26214400||!Y.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return X;return{...X,content:[...X.content,{type:"image",data:Y.toString("base64"),mimeType:"image/png"}]}}catch{return X}}function yZ(X,$,Z="full",Q=!1){return X.getMetadata($).filter((W)=>{let K=$X(W.name);if(Z==="read"&&!O2.has(K))return!1;if(!Q&&k2.has(K))return!1;return!0}).map((W)=>({name:W.name,description:W.description,inputSchema:W.inputSchema}))}function bZ(X,$,Z={}){let Q=yZ(X,$,Z.toolSurface??"full",Z.imagesSupported??!1);return Z.includeRunFolderTools?[...Q,...CZ]:Q}function F2(X,$){if(!X||typeof X!=="object"||Array.isArray(X))return null;let Z=X[$];return typeof Z==="string"?Z:null}async function EZ(X,$,Z){if(Z&&Z.trim().length>0)return Z.trim();if(!X||!$)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await X0({boardId:X,cardId:$})).runFolder}async function TZ(X){let $=await EZ(X.boardId,X.cardId,X.runFolder);if(X.name===zX){let Z=F2(X.args,"path")??"",Q=await L$($,Z);return RZ(Q)}if(X.name===UX){let Z=F2(X.args,"path");if(!Z)return B2("read_run_folder_file requires a path.");return D1(await XX($,Z))}return B2(`Unknown local tool "${X.name}"`)}function vZ(X,$,Z,Q,W,K="full",Y=!1){let V=new kZ(AZ,{capabilities:{tools:{}}}),z=async()=>{if(Y)return!0;if(m$(Q))return!0;if(Z&&Q)try{return(await X0({boardId:Z,cardId:Q})).adapter.supportsImages===!0}catch{return!1}return!1};return V.setRequestHandler(_Z,async()=>({tools:bZ(X,$,{includeRunFolderTools:Boolean(W||Z&&Q),toolSurface:K,imagesSupported:await z()})})),V.setRequestHandler(qZ,async(J)=>{let{name:G,arguments:M}=J.params,L=$X(G),x=Date.now();q("mcp.tool_call_received",{frontendSessionId:$,cardId:Q,toolName:L});try{if(L===zX||L===UX)return await TZ({name:L,args:M,boardId:Z,cardId:Q,runFolder:W});if(K==="read"&&!O2.has(L))throw Error(`Tool "${G}" is not available in read-only mode`);if(k2.has(L)&&!await z())throw Error(`Tool "${G}" requires a runtime that supports image input`);let U=await X.callTool($,L,M??{},void 0,Q??void 0);if(q("mcp.tool_result_returned",{frontendSessionId:$,cardId:Q,toolName:L,elapsedMs:Date.now()-x}),U&&typeof U==="object"&&Array.isArray(U.content)){let D=U;return L==="screenshot_board"?await fZ(D,await z()):D}return{content:[{type:"text",text:typeof U==="string"?U:JSON.stringify(U)}]}}catch(U){return q("mcp.tool_result_returned",{frontendSessionId:$,cardId:Q,toolName:L,elapsedMs:Date.now()-x,hasError:!0}),{content:[{type:"text",text:U instanceof Error?U.message:"Tool call failed"}],isError:!0}}}),V}function q2(X,$){return L2({buildServer:(Z)=>vZ(X,Z.frontendSessionId,Z.boardId,Z.cardId,Z.runFolder,Z.toolSurface,Z.imagesSupported),port:$})}import HX from"node:fs/promises";import w1 from"node:os";import xX from"node:path";function _2(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function hZ(){let[X,$]=await Promise.all([m(),V$()]),Z=X.globalDefaultConfigId?X.runtimes.find((Q)=>Q.id===X.globalDefaultConfigId)??null:null;return{runtimes:X.runtimes,globalDefaultConfigId:X.globalDefaultConfigId,globalDefaultEffective:Z?{runFolder:Z.runFolder??w1.homedir(),modelId:Z.defaultModelId??null,configValues:Z.defaultConfigValues??{}}:null,knownAdapters:D0().map((Q)=>({id:Q.id,displayName:Q.displayName})),readiness:$}}async function IZ(X){try{let $=await X0({boardId:X.boardId,cardId:X.cardId});return{resolved:{configId:$.entry.id,adapterId:$.entry.kind==="registered"?$.entry.adapterId:null,displayName:$.entry.displayName,runFolder:$.runFolder,modelId:$.modelId,configValues:$.configValues}}}catch($){if($ instanceof Y0)return{resolved:null};throw $}}async function SZ(X){return p(($)=>{let Z=$.runtimes.find((K)=>K.kind==="registered"&&K.adapterId===X.adapterId);if(Z)return Z;let Q=D0().find((K)=>K.id===X.adapterId);if(!Q)throw Error(`Unknown adapterId: ${X.adapterId}`);let W={id:_2(),kind:"registered",adapterId:X.adapterId,displayName:Q.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return $.runtimes.push(W),W})}async function gZ(X){return p(($)=>{let Z={id:_2(),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 $.runtimes.push(Z),Z})}async function mZ(X){await p(($)=>{if($.runtimes=$.runtimes.filter((Z)=>Z.id!==X.runtimeConfigId),$.globalDefaultConfigId===X.runtimeConfigId)$.globalDefaultConfigId=null;for(let Z of Object.keys($.boardOverrides))if($.boardOverrides[Z].runtimeConfigId===X.runtimeConfigId)delete $.boardOverrides[Z];for(let Z of Object.keys($.cardOverrides))if($.cardOverrides[Z].runtimeConfigId===X.runtimeConfigId)delete $.cardOverrides[Z]})}async function cZ(X){await p(($)=>{let Z=$.runtimes.find((Q)=>Q.id===X.runtimeConfigId);if(!Z)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);if($.globalDefaultConfigId=X.runtimeConfigId,X.runFolder!==void 0)Z.runFolder=X.runFolder;if(X.modelId!==void 0)Z.defaultModelId=X.modelId;if(X.configValues!==void 0)Z.defaultConfigValues=X.configValues})}async function lZ(X){X.boardId,await p(($)=>{if(X.runtimeConfigId===null){delete $.cardOverrides[X.cardId];return}if(!$.runtimes.some((W)=>W.id===X.runtimeConfigId))throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let Q=$.cardOverrides[X.cardId];$.cardOverrides[X.cardId]={runtimeConfigId:X.runtimeConfigId,runFolder:X.runFolder!==void 0?X.runFolder:Q?.runFolder??null,modelId:X.modelId!==void 0?X.modelId:Q?.modelId??null,configValues:X.configValues!==void 0?X.configValues:Q?.configValues??{}}})}async function pZ(X){let Z=(await m()).runtimes.find((Y)=>Y.id===X.runtimeConfigId);if(!Z)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let Q=a(Z),W=await Q.resolveSpawnConfig(Z),K=Z.runFolder??w1.homedir();try{let Y=await h$({spawn:{...W,cwd:K},modelId:X.modelId??Z.defaultModelId??null,configValues:X.configValues??Z.defaultConfigValues??{}}),V=s0({adapterId:Q.id,models:Y.models,currentModelId:Y.currentModelId}),z=new Date().toISOString();return await p((J)=>{let G=J.runtimes.find((M)=>M.id===X.runtimeConfigId);if(G)G.discoveredModels=V,G.discoveredConfigOptions=Y.configOptions,G.discoveredAt=z}),{ok:!0,models:V,configOptions:Y.configOptions,currentModelId:Y.currentModelId}}catch(Y){if(Y instanceof H0)throw Error(`${Y.message}${Q.authHint?` ${Q.authHint}`:""}`);if(Y instanceof R||Y instanceof u)throw Error(Y.message);throw Y}}async function uZ(X){let $=w1.homedir(),Z=X.path?.trim()?X.path.trim():$,Q=xX.resolve(Z),W=!0;try{if(!(await HX.stat(Q)).isDirectory())Q=xX.dirname(Q)}catch{W=!1,Q=$}let K=[];try{K=(await HX.readdir(Q,{withFileTypes:!0})).filter((z)=>z.isDirectory()&&!z.name.startsWith(".")).map((z)=>({name:z.name,path:xX.join(Q,z.name)})).sort((z,J)=>z.name.localeCompare(J.name))}catch{K=[]}let Y=xX.dirname(Q);return{path:Q,parent:Y===Q?null:Y,home:$,exists:W,entries:K}}var A2={list:hZ,getEffectiveForCard:IZ,registerRegistered:SZ,registerCustom:gZ,unregister:mZ,setUserDefault:cZ,setCardOverride:lZ,refreshModels:pZ,browseFolder:uZ};var aZ=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function dZ(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function C2(){try{let X=await m();if(X.globalDefaultConfigId){if(X.runtimes.some((Z)=>Z.id===X.globalDefaultConfigId))return X.globalDefaultConfigId}for(let $ of aZ){if((await j$($.id))?.status!=="ready")continue;let Q=null;if(await p((W)=>{if(W.globalDefaultConfigId){if(W.runtimes.some((V)=>V.id===W.globalDefaultConfigId)){Q=W.globalDefaultConfigId;return}}let K=W.runtimes.find((Y)=>Y.kind==="registered"&&Y.adapterId===$.id);if(!K){let Y={id:dZ(),kind:"registered",adapterId:$.id,displayName:$.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};W.runtimes.push(Y),K=Y}W.globalDefaultConfigId=K.id,Q=K.id}),Q)return console.log(`[ideawave-cli] using agent runtime: ${$.displayName}`),Q}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 iZ=120000;function oZ(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class N1{sessions=new Map;createCallId;toolCallTimeoutMs;constructor(X={}){this.createCallId=X.createCallId??oZ,this.toolCallTimeoutMs=X.toolCallTimeoutMs??iZ}register(X){let $=this.sessions.get(X.frontendSessionId);if($){if($.userId!==X.userId)this.rejectPending($,"frontend session user changed"),$.activeRunIds.clear();this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:$.pendingToolCalls,activeRunIds:$.activeRunIds,activeRunCardIds:$.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,$="frontend session disconnected"){let Z=this.sessions.get(X);if(!Z)return{activeRunIds:[]};return this.sessions.delete(X),this.rejectPending(Z,$),{activeRunIds:Array.from(Z.activeRunIds)}}sessionCount(){return this.sessions.size}has(X){return this.sessions.has(X)}getUserId(X){return this.sessions.get(X)?.userId??null}setMetadata(X,$){let Z=this.sessions.get(X);if(Z)Z.tools=$}getMetadata(X){if(!X)return[];return this.sessions.get(X)?.tools??[]}sendToSession(X,$){let Z=this.sessions.get(X);if(!Z)return!1;return Z.send($),!0}callTool(X,$,Z,Q,W){if(!X)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let K=this.sessions.get(X);if(!K)return Promise.reject(Error(`Frontend session ${X} is not connected`));let Y=this.createCallId();return new Promise((V,z)=>{let J=Q??(W?this.getActiveRunIdForCard(K,W):this.getSoleActiveRunId(K)),G=W??(J?K.activeRunCardIds.get(J):void 0),M=Date.now(),L=setTimeout(()=>{K.pendingToolCalls.delete(Y),q("tool_queue.timeout",{frontendSessionId:X,runId:J,cardId:G,callId:Y,toolName:$,elapsedMs:Date.now()-M,queueDepth:K.pendingToolCalls.size}),z(Error(`Tool "${$}" timed out waiting for the frontend`))},this.toolCallTimeoutMs);K.pendingToolCalls.set(Y,{resolve:V,reject:z,timer:L,name:$,runId:J??null,cardId:G??null,startedAt:M}),q("tool_queue.forwarded_to_browser",{frontendSessionId:X,runId:J,cardId:G,callId:Y,toolName:$,queueDepth:K.pendingToolCalls.size}),K.send({type:"tool_call",callId:Y,name:$,args:Z,...J?{runId:J}:{},...G?{cardId:G}:{}})})}handleToolResult(X,$){let Z=this.sessions.get(X);if(!Z)return;let Q=Z.pendingToolCalls.get($.callId);if(!Q)return;if(Z.pendingToolCalls.delete($.callId),clearTimeout(Q.timer),q("tool_queue.result_received",{frontendSessionId:X,runId:Q.runId,cardId:Q.cardId,callId:$.callId,toolName:Q.name,elapsedMs:Date.now()-Q.startedAt,queueDepth:Z.pendingToolCalls.size,ok:$.ok}),$.ok){Q.resolve($.result);return}let W=$.result;if(W&&typeof W==="object"&&Array.isArray(W.content)){Q.resolve({...W,isError:!0});return}Q.reject(Error($.error??"Tool execution failed"))}markRunActive(X,$,Z){let Q=this.sessions.get(X);if(!Q)return;if(Q.activeRunIds.add($),Z)Q.activeRunCardIds.set($,Z)}markRunSettled(X,$){let Z=this.sessions.get(X);if(!Z)return;Z.activeRunIds.delete($),Z.activeRunCardIds.delete($)}ownsRun(X,$){return this.sessions.get(X)?.activeRunIds.has($)??!1}rejectPending(X,$){for(let Z of X.pendingToolCalls.values())clearTimeout(Z.timer),q("tool_queue.rejected",{frontendSessionId:X.frontendSessionId,runId:Z.runId,cardId:Z.cardId,toolName:Z.name,elapsedMs:Date.now()-Z.startedAt}),Z.reject(Error($));X.pendingToolCalls.clear()}getSoleActiveRunId(X){return X.activeRunIds.size===1?X.activeRunIds.values().next().value:void 0}getActiveRunIdForCard(X,$){let Z=[...X.activeRunCardIds.entries()].filter(([Q,W])=>X.activeRunIds.has(Q)&&W===$).map(([Q])=>Q);return Z.length===1?Z[0]:void 0}}function f2(){return"0.0.70".trim()?"0.0.70":"dev"}var nZ=process.argv.slice(2),P1=Y2(nZ,process.env);if(P1.allowRailwayPrPreviews)process.env[f0]="1";var W0=P1.cliArgs[0],{browserKitEnabled:E0,captureEngineEnabled:tZ}=P1;if(W0==="--help"||W0==="-h"||W0==="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(W0==="--version"||W0==="-v"||W0==="version")console.log(f2()),process.exit(0);if(W0)console.error(`Unknown command: ${W0}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var T0=new N1,z0=null,rZ=E0?{phase:"ready",message:"Local browser-kit proxy is ready"}:{phase:"idle"},B0=new r0;function Q0(X,$){T0.sendToSession(X,$)}async function sZ(X,$){try{let Z=A2[$.method],Q=await Z($.params);Q0(X,{type:"runtime_rpc_result",requestId:$.requestId,ok:!0,result:Q})}catch(Z){Q0(X,{type:"runtime_rpc_result",requestId:$.requestId,ok:!1,error:Z instanceof Error?Z.message:String(Z)})}}var v0=!1,b0=null;async function M1(){if(v0)return;if(b0)return b0;return b0=(async()=>{try{let X=await q2(T0);_1({...X,requestedPort:X.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${X.url}`);try{await p1({onStatusChange:($)=>{if(G$(),z0?.sendStatus(),$.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${$.packageName}: ${$.error??"unknown error"}`)}})}catch($){console.warn("[ideawave-cli] ACP bridge setup skipped:",$ instanceof Error?$.message:String($))}await C2(),v0=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),z0?.sendStatus()}catch(X){console.error("[ideawave-cli] failed to start agent host:",X),z0?.sendStatus(void 0,X instanceof Error?X.message:String(X))}finally{b0=null}})(),b0}if(process.env.APP_ENV!=="development"){let X=await z2();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(tZ)t$().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"}`)});z0=await U2({registry:T0,runtime:null,mcpReady:()=>v0,capabilities:E0?[A1]:[],cliVersion:f2(),browserRuntimeStatus:()=>rZ,onToolMetadata:(X)=>{console.log(`[ideawave-cli] session ${X} advertised ${T0.getMetadata(X).length} tools`),M1()},onRunTurn:(X,$)=>{console.log(`[ideawave-cli] running agent turn for card ${$.cardId} (session ${X})`),(async()=>{if(await M1(),!v0){Q0(X,{type:"run_settled",runId:$.runId,cardId:$.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"IdeaWave CLI agent host is not ready",partialText:null}});return}await u$($,(Z)=>Q0(X,Z))})().catch(()=>{return}).finally(()=>T0.markRunSettled(X,$.runId))},onCancelRun:(X,$)=>{$1($)},onRuntimeRpc:(X,$)=>{sZ(X,$)},onBrowserRpc:(X,$,Z)=>{if(!E0){Q0(X,{type:"browser_rpc_result",requestId:Z.requestId,ok:!1,error:"The development browser-kit proxy is not enabled"});return}B0.handleRpc(X,$,Z).then((Q)=>{Q0(X,{type:"browser_rpc_result",requestId:Z.requestId,ok:!0,result:Q})},(Q)=>{Q0(X,{type:"browser_rpc_result",requestId:Z.requestId,ok:!1,error:Q instanceof Error?Q.message:String(Q)})})},onHttpRequest:(X,$)=>E0?B0.handleHttpRequest(X,$):!1,onHttpUpgrade:(X,$,Z)=>E0?B0.handleUpgrade(X,$,Z):!1,onWarmupRun:(X,$,Z)=>{(async()=>{if(await M1(),!v0)return{status:"retryable",error:"agent host is not ready"};return a$({cardId:$.cardId,boardId:$.boardId,userId:Z,frontendSessionId:X})})().then((Q)=>{if(!$.warmupId)return;Q0(X,{type:"warmup_result",warmupId:$.warmupId,cardId:$.cardId,...Q})})},onDisconnect:(X,$)=>{B0.closeFrontendSession(X),c$(X);for(let Z of $)$1(Z);q("bridge.frontend_disconnected",{frontendSessionId:X,activeRuns:$.length}),F1(X).catch((Z)=>{console.warn(`[ideawave-cli] failed to evict sessions for ${X}:`,Z instanceof Error?Z.message:String(Z))}),console.log(`[ideawave-cli] browser session ${X} disconnected`)}});B0.setPort(z0.port);console.log(`[ideawave-cli] browser bridge listening on ${z0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var R2=!1;for(let X of["SIGINT","SIGTERM"])process.once(X,()=>{if(R2)return;R2=!0,l$(),(async()=>{await B0.close(),await e$(),await z0?.close().catch(()=>{return}),process.exit(0)})()});
|