ideawave 0.0.95 → 0.0.96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.mjs +2 -2
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1060,7 +1060,7 @@ ${K}`:null].filter(Boolean).join(`
1060
1060
 
1061
1061
  ${Z}`)}function MX(X){if(!Array.isArray(X))return null;let Z=X.flatMap((W)=>{if(!W||typeof W!=="object")return[];let J=W;if(typeof J.path!=="string"||!J.path.trim())return[];let K=typeof J.line==="number"?`:${J.line}`:"";return[`${J.path}${K}`]});return Z.length>0?Z.slice(0,5):null}function H4(X){let{ctx:Z,appendText:W,appendToolActivity:J}=X,K=X.flushIntervalMs??I7,V="",j="",U=0,F=null,w=!1,q={},v=new Map,y=(b)=>{if(v.set(b.toolCallId,b),!J)return;J({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,entry:b}).catch((R)=>{console.warn("[streamAdapter] appendToolActivity failed",R)})},P=(b)=>{let R=`${Z.runId}:thought`,D=v.get(R);if(!D||D.status!=="running")return;y({...D,status:"completed",completedAt:D.completedAt??b})},O=(b)=>{for(let R of v.values()){if(R.status!=="running"||R.rawTitle.toLowerCase()!=="toolsearch")continue;y({...R,status:"completed",completedAt:R.completedAt??b})}},M=(b)=>{for(let R of Array.from(v.values())){if(R.status!=="running")continue;if(R.kind==="thought"||R.rawTitle==="agent_thought")continue;y({...R,status:"completed",completedAt:R.completedAt??b})}},h="",N=0,g=null,C=null,m=(b)=>{if(b===h)return;h=b,N=Date.now(),W({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,text:b}).catch((R)=>{console.warn("[streamAdapter] appendText failed",R)})},k=()=>{if(g!==null)clearTimeout(g),g=null;if(C!==null){let b=C;C=null,m(b)}},G=(b)=>{let R=Date.now()-N;if(R>=K&&g===null){m(b);return}if(C=b,g===null){let D=Math.max(0,K-R);g=setTimeout(()=>{g=null,k()},D)}};return{onSessionUpdate:async(b)=>{X.onAnyUpdate?.();let R=b.update;switch(q[R.sessionUpdate]=(q[R.sessionUpdate]??0)+1,R.sessionUpdate){case"agent_message_chunk":{let D=new Date().toISOString();if(P(D),R.content.type==="text"){if(R.content.text.length>0){if(w&&V.length>0&&!/\s$/.test(V)&&!/^\s/.test(R.content.text))V+=`
1062
1062
 
1063
- `;V+=R.content.text,w=!1,G(V)}}else{let T=`agent_message_chunk:${R.content.type}`;q[T]=(q[T]??0)+1}return}case"agent_thought_chunk":{if(R.content.type!=="text")return;j+=R.content.text;let D=new Date().toISOString(),T=`${Z.runId}:thought`,I=v.get(T);y({toolCallId:T,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:I?.startedAt??D,completedAt:null,contentPreview:k0(j.trim())});return}case"user_message_chunk":return;case"tool_call":{U+=1,w=V.length>0;let D=Y4(R.title),T=RX(R.status),I=new Date().toISOString();P(I),O(I),y({toolCallId:R.toolCallId,rawTitle:D,title:CX(D,R.rawInput),kind:fX(R.kind),status:T,startedAt:I,completedAt:T==="running"?null:I,inputPreview:v0(R.rawInput),outputPreview:hX(R.rawOutput),contentPreview:B2(R.content),locations:MX(R.locations)});return}case"tool_call_update":{let D=v.get(R.toolCallId);if(!D){let Z0=Y4(R.title),W0=RX(R.status),N1=new Date().toISOString();y({toolCallId:R.toolCallId,rawTitle:Z0,title:CX(Z0,R.rawInput),kind:fX(R.kind),status:W0,startedAt:N1,completedAt:W0==="running"?null:N1,inputPreview:v0(R.rawInput),outputPreview:hX(R.rawOutput),contentPreview:B2(R.content),locations:MX(R.locations)});return}let T=R.status===void 0||R.status===null?D.status:RX(R.status),I=typeof R.title==="string"&&R.title.trim().length>0?R.title:D.rawTitle,q0=typeof R.title==="string"&&R.title.trim().length>0,S=T==="running"?D.completedAt:D.completedAt??new Date().toISOString(),s=R.content===void 0?D.contentPreview:j4(D.contentPreview,B2(R.content)),c=R.rawOutput===void 0?D.outputPreview:j4(D.outputPreview,hX(R.rawOutput));y({...D,rawTitle:I,title:q0?CX(I,R.rawInput):D.title,kind:R.kind===void 0?D.kind:fX(R.kind),status:T,completedAt:S,inputPreview:R.rawInput===void 0?D.inputPreview:v0(R.rawInput),outputPreview:c,contentPreview:s,locations:R.locations===void 0?D.locations:MX(R.locations)});return}case"plan":F=R.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>V,getToolCallCount:()=>U,getLatestPlan:()=>F,getUpdateTypeCounts:()=>({...q}),flush:(b)=>{let R=new Date().toISOString();if(P(R),b?.completeOpenToolCalls)M(R);k()}}}var l7=new Set(["ECONNRESET","EPIPE"]);function L2(X){if(!X||typeof X!=="object")return!1;if(X instanceof Error&&X.message==="ACP connection closed")return!0;let Z="code"in X?X.code:void 0;return typeof Z==="string"&&l7.has(Z)}var b1=1,w4=-32000;function U4(X){if(X.awaitingInput)return!1;return X.nowMs-X.lastUpdateMs>=X.windowMs}function q4(X){if(!X||typeof X!=="object")return!1;return X.code===w4}var T7=300000,c7=T7,a7=5000;function d7(X){let Z=Math.max(1,Math.round(X/1000));return`Runtime has not responded for ${Z} ${Z===1?"second":"seconds"}. Retry the agent run.`}function L4(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.95".trim()?"0.0.95":"dev"}}function P4(X){if(X===b1)return;throw new l(`Unsupported ACP protocol version ${X}; expected ${b1}`)}function x4(X){return u7.toWeb(X)}function b4(X){return A7.toWeb(X)}function NX(X){return X!==null&&typeof X==="object"}function i7(X){if(!Array.isArray(X))return[];let Z=[];for(let W of X){if(!NX(W))continue;if(typeof W.group==="string"&&Array.isArray(W.options)){let J=typeof W.name==="string"?W.name:W.group;for(let K of W.options){if(!NX(K))continue;if(typeof K.value!=="string"||typeof K.name!=="string")continue;Z.push({value:K.value,name:K.name,description:typeof K.description==="string"?K.description:null,group:W.group,groupName:J})}continue}if(typeof W.value!=="string"||typeof W.name!=="string")continue;Z.push({value:W.value,name:W.name,description:typeof W.description==="string"?W.description:null,group:null,groupName:null})}return Z}function p7(X){if(!NX(X))return null;if(typeof X.id!=="string"||typeof X.name!=="string")return null;let Z=typeof X.category==="string"?X.category:null,W=typeof X.description==="string"?X.description:null;if(X.type==="select"){let J=typeof X.currentValue==="string"?X.currentValue:null;return{id:X.id,name:X.name,category:Z,description:W,type:"select",currentValue:J,options:i7(X.options)}}if(X.type==="boolean"){let J=typeof X.currentValue==="boolean"?X.currentValue:typeof X.value==="boolean"?X.value:null;return{id:X.id,name:X.name,category:Z,description:W,type:"boolean",currentValue:J,options:[]}}return null}function gX(X){let Z=(X.configOptions??[]).map(p7).filter((U)=>U!==null),W=Z.find((U)=>U.type==="select"&&U.category==="model")??Z.find((U)=>U.type==="select"&&U.id==="model")??null,J=W?.options.map((U)=>({id:U.value,name:U.name,description:U.description??null})),K=s7(X.models),V=J&&J.length>0?J:K&&K.length>0?K:null,j=(typeof W?.currentValue==="string"?W.currentValue:null)??r7(X.models)??null;return{models:V,currentModelId:j,configOptions:Z,modelConfigId:W?.id??null}}function s7(X){if(!X||!Array.isArray(X.availableModels))return null;let Z=[];for(let W of X.availableModels){if(typeof W.modelId!=="string")continue;Z.push({id:W.modelId,name:typeof W.name==="string"?W.name:null,description:typeof W.description==="string"?W.description:null})}return Z.length>0?Z:null}function r7(X){return typeof X?.currentModelId==="string"?X.currentModelId:null}function o7(X,Z){let W=[];if(X.trim())W.push({type:"text",text:X});for(let J of Z)if(J.content.trim())W.push({type:"text",text:J.content});return W}var n7=500;function v4(X){return new Promise((Z)=>{let W=setTimeout(()=>Z({code:null,signal:null,stderr:""}),n7);X.then((J)=>{clearTimeout(W),Z(J)})})}function t7(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 e7(X,Z){let W=gX({configOptions:Z.configOptions});return{models:W.models??X.models,currentModelId:W.currentModelId??X.currentModelId,configOptions:W.configOptions,modelConfigId:W.modelConfigId??X.modelConfigId}}function y4(X,Z){if(X==="default")return null;if(!Z||Z.length===0)return X;let W=Z.find((w)=>w.id===X);if(W)return W.id;let J=X.toLowerCase(),K=J.includes("opus")?"opus":J.includes("sonnet")?"sonnet":J.includes("haiku")?"haiku":null;if(!K)return X;let V=(w)=>`${w.id} ${w.name??""} ${w.description??""}`.toLowerCase(),j=Z.filter((w)=>V(w).includes(K));if(j.length===0)return X;let F=(J.includes("1m")?j.find((w)=>V(w).includes("1m")):void 0)??j[0];return F?F.id:X}async function P2(X){try{let Z=await X.conn.setSessionConfigOption(t7({sessionId:X.sessionId,configId:X.configId,value:X.value}));return e7(X.metadata,Z)}catch(Z){return console.warn(`[acp] setSessionConfigOption(${X.label}) failed; using agent default.`,Z instanceof Error?Z.message:Z),X.metadata}}async function x2(X){let Z=yX(X.spawn),W=[],J=0,K=4096;Z.stderr.on("data",(S)=>{W.push(S),J+=S.length;while(J>K*2&&W.length>1){let s=W.shift();if(s)J-=s.length}});let V=()=>{let S=Buffer.concat(W).toString("utf8");return S.length>K?S.slice(-K):S},j=V4(X.spawn.cwd),U={current:null},F={current:null},w={at:Date.now()},q=null,v=b4(Z.stdin),y=x4(Z.stdout),P=B4(v,y),M=new F4((S)=>({requestPermission:async(s)=>{let c=s.options,Z0=c?.find((W0)=>W0.kind==="allow_once")??c?.find((W0)=>W0.kind==="allow_always");if(Z0)return{outcome:{outcome:"selected",optionId:Z0.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(s)=>{w.at=Date.now();let c=F.current;if(c){let W0=s.update.sessionUpdate;if(c.updateCount+=1,c.updateCount===1||c.lastUpdateType!==W0||W0==="tool_call"||W0==="tool_call_update")E("acp.session_update",{runId:c.runId,cardId:c.cardId,sessionId:q,updateType:W0,updateCount:c.updateCount,elapsedMs:Date.now()-c.startedAt});c.lastUpdateType=W0}let Z0=U.current;if(Z0)await Z0.onSessionUpdate(s)},readTextFile:j.readTextFile}),P),h=()=>Z.kill();if(X.signal)X.signal.addEventListener("abort",h);let N=()=>{if(X.signal)X.signal.removeEventListener("abort",h)},g=async(S,s)=>{if(N(),Z.kill(),q4(S))throw new u0(S.message??"Authentication required",s);if(L2(S)){if(X.signal?.aborted)throw new l("ACP session cancelled: abort signal received");let c=await v4(Z.waitForExit);throw new l(`Runtime process exited before completion: ${c.stderr?.trim()??""}`)}throw S},C;try{C=await M.initialize({protocolVersion:b1,clientCapabilities:vX,clientInfo:L4()})}catch(S){throw await g(S,[]),Error("unreachable")}try{P4(C.protocolVersion)}catch(S){throw N(),Z.kill(),S}let m=C.authMethods?.map((S)=>S.id)??[],k;try{k=await M.newSession({cwd:X.spawn.cwd,mcpServers:X.mcpServers??[],...X.isolateAmbientToolSources?{_meta:{claudeCode:{options:{settingSources:[]}}}}:{}})}catch(S){throw await g(S,m),Error("unreachable")}let G=k.sessionId;q=G;let b=gX(k),R=X.modelId??null,D=R?y4(R,b.models):null;if(D&&D!==b.currentModelId)if(b.modelConfigId)b=await P2({conn:M,sessionId:G,configId:b.modelConfigId,value:D,metadata:b,label:`${b.modelConfigId}=${D}`});else console.warn(`[acp] runtime did not advertise a model config option for ${D}; using agent default.`);for(let[S,s]of Object.entries(X.configValues??{}).sort(([c],[Z0])=>c.localeCompare(Z0))){if(S===b.modelConfigId)continue;if(!b.configOptions.some((c)=>c.id===S))continue;b=await P2({conn:M,sessionId:G,configId:S,value:s,metadata:b,label:`${S}=${String(s)}`})}N();let T=!1,I=async()=>{if(T)return;T=!0,Z.kill(),await Promise.race([Z.waitForExit,new Promise((S)=>setTimeout(S,2000))])},q0=!1;return Z.processCrashed.then(()=>{q0=!0}),{sessionId:G,availableModels:b.models,currentModelId:b.currentModelId,availableConfigOptions:b.configOptions,isAlive:()=>!T&&!q0,dispose:I,prompt:(S)=>XW({proc:Z,conn:M,sessionId:G,activeAdapter:U,activeTrace:F,lastUpdate:w,collectStderrTail:V},S)}}async function XW(X,Z){let{proc:W,conn:J,sessionId:K,activeAdapter:V,activeTrace:j,lastUpdate:U}=X,F=Date.now(),w=Z.heartbeatMs??c7,q=d7(w),v={boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId},y=H4({ctx:v,appendText:Z.appendText,appendToolActivity:Z.appendToolActivity,onAnyUpdate:Z.onAnyUpdate});V.current=y,j.current={runId:Z.runId,cardId:Z.cardId,startedAt:F,updateCount:0,lastUpdateType:null},U.at=Date.now(),E("acp.prompt_started",{runId:Z.runId,cardId:Z.cardId,sessionId:K,heartbeatWindowMs:w});let P=!1,O=null,M=()=>W.kill();Z.signal.addEventListener("abort",M);try{let h=async()=>{let m=Math.min(a7,Math.max(50,Math.floor(w/2)));O=setInterval(()=>{let G=Z.isAwaitingInput?.()??!1;if(G){U.at=Date.now();return}if(U4({nowMs:Date.now(),lastUpdateMs:U.at,windowMs:w,awaitingInput:G}))P=!0,E("acp.inactivity_timeout",{runId:Z.runId,cardId:Z.cardId,sessionId:K,windowMs:w,silentForMs:Date.now()-U.at}),J.cancel({sessionId:K}).catch(()=>{return}),W.kill()},m);let k=o7(Z.prompt.systemPrompt,Z.prompt.messages);await J.prompt({sessionId:K,prompt:k}),E("acp.prompt_resolved",{runId:Z.runId,cardId:Z.cardId,sessionId:K,elapsedMs:Date.now()-F}),y.flush({completeOpenToolCalls:!0})},N=W.waitForExit.then((m)=>({kind:"exited",exit:m})),g=h().then(()=>({kind:"ok"})).catch(async(m)=>{if(L2(m))return W.kill(),{kind:"crashed",exit:await v4(W.waitForExit)};throw m}),C;try{C=await Promise.race([g,W.processCrashed.then((m)=>({kind:"crashed",exit:m})),N])}catch(m){if(P)throw new w0(q);throw m}if(P)throw new w0(q);if(C.kind!=="ok"&&Z.signal.aborted)throw new l("ACP session cancelled: abort signal received");if(C.kind==="crashed")throw new l(`Runtime process exited before completion: ${C.exit.stderr.trim()}`);if(C.kind==="exited"){if(P)throw new w0(q);throw new l(`Runtime process exited unexpectedly: ${C.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:y.getFinalText(),toolCallsExecuted:y.getToolCallCount(),stderrTail:X.collectStderrTail(),updateTypeCounts:y.getUpdateTypeCounts()}}finally{if(E("acp.prompt_finished",{runId:Z.runId,cardId:Z.cardId,sessionId:K,elapsedMs:Date.now()-F,timedOut:P,updateCount:j.current?.updateCount??0}),O!==null)clearInterval(O);Z.signal.removeEventListener("abort",M),y.flush({completeOpenToolCalls:!0}),V.current=null,j.current=null}}var ZW=30000;async function O4(X){let Z=yX(X.spawn),W=b4(Z.stdin),J=x4(Z.stdout),K=B4(W,J),j=new F4((w)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),K),U=()=>Z.kill();if(X.signal)X.signal.addEventListener("abort",U);let F=null;try{let w=(async()=>{let v=await j.initialize({protocolVersion:b1,clientCapabilities:vX,clientInfo:L4()});P4(v.protocolVersion);let y=v.authMethods?.map((C)=>C.id)??[],P;try{P=await j.newSession({cwd:X.spawn.cwd,mcpServers:[]})}catch(C){if(q4(C))throw new u0(C.message??"Authentication required",y);throw C}let O=gX(P),M=X.modelId??null,h=M?y4(M,O.models):null;if(h&&h!==O.currentModelId)if(O.modelConfigId)O=await P2({conn:j,sessionId:P.sessionId,configId:O.modelConfigId,value:h,metadata:O,label:`${O.modelConfigId}=${h}`});else console.warn(`[acp] runtime did not advertise a model config option for ${h}; discovering agent default models.`);for(let[C,m]of Object.entries(X.configValues??{}).sort(([k],[G])=>k.localeCompare(G))){if(C===O.modelConfigId)continue;if(!O.configOptions.some((k)=>k.id===C))continue;O=await P2({conn:j,sessionId:P.sessionId,configId:C,value:m,metadata:O,label:`${C}=${String(m)}`})}let N=O.models??[],g=O.currentModelId;return j.cancel({sessionId:P.sessionId}).catch(()=>{return}),{models:N,configOptions:O.configOptions,currentModelId:g}})(),q=new Promise((v,y)=>{F=setTimeout(()=>{y(new w0)},ZW)});return await Promise.race([w,q])}catch(w){if(L2(w)){if(X.signal?.aborted)throw new l("ACP model discovery cancelled: abort signal received");throw new l("Runtime process exited during model discovery.")}throw w}finally{if(F)clearTimeout(F);if(X.signal)X.signal.removeEventListener("abort",U);Z.kill()}}import WW from"node:fs/promises";import b2 from"node:os";async function R4(X){let Z={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},W;try{W=await WW.readFile(X,"utf-8")}catch(J){if(J.code==="ENOENT")return structuredClone(Z);throw J}return E1.parse(JSON.parse(W))}function DX(X,Z,W){return{...X.defaultConfigValues??{},...Z?.configValues??{},...W?.configValues??{}}}async function C0(X){let Z=X.configPath?await R4(X.configPath):await J0(),W=X.cardId?Z.cardOverrides[X.cardId]:void 0;if(W?.runtimeConfigId){let K=Z.runtimes.find((V)=>V.id===W.runtimeConfigId);if(K)return{entry:K,adapter:U0(K),runFolder:W.runFolder??K.runFolder??b2.homedir(),modelId:W.modelId??K.defaultModelId??null,configValues:DX(K,void 0,W)}}let J=Z.boardOverrides[X.boardId];if(J?.runtimeConfigId){let K=Z.runtimes.find((V)=>V.id===J.runtimeConfigId);if(K)return{entry:K,adapter:U0(K),runFolder:J.runFolder??K.runFolder??b2.homedir(),modelId:J.modelId??K.defaultModelId??null,configValues:DX(K,J)}}if(Z.globalDefaultConfigId){let K=Z.runtimes.find((V)=>V.id===Z.globalDefaultConfigId);if(K)return{entry:K,adapter:U0(K),runFolder:W?.runFolder??J?.runFolder??K.runFolder??b2.homedir(),modelId:W?.modelId??J?.modelId??K.defaultModelId??null,configValues:DX(K,J,W)}}throw new x0}async function $X(X,Z={}){let J=(Z.configPath?await R4(Z.configPath):await J0()).runtimes.find((K)=>K.id===X);if(!J)return null;return{entry:J,adapter:U0(J),runFolder:J.runFolder??b2.homedir(),modelId:Z.modelId??J.defaultModelId??null,configValues:{...J.defaultConfigValues??{},...Z.configValues??{}}}}var GX=new Map;function f4(X,Z){GX.set(X,Z)}function C4(X){GX.delete(X)}function h4(X){if(!X)return null;return GX.get(X)??null}var M4=new Map;function mX(X,Z){if(!X)return;M4.set(X,Z)}function N4(X){if(!X)return!1;return M4.get(X)??!1}var _0=new Map,EX=new Set;function _X(X){_0.get(X)?.controller.abort()}function g4(X){for(let[Z,W]of _0){if(W.frontendSessionId!==X)continue;W.controller.abort(),_0.delete(Z)}}function D4(){for(let X of _0.values())X.controller.abort();_0.clear()}function IX(X,Z){if(Z?.aborted)return!0;return X instanceof Error&&/abort signal received|session cancelled/i.test(X.message)}function SX(X,Z,W,J){if((!Z.availableModels||Z.availableModels.length===0)&&Z.availableConfigOptions.length===0)return;z0((K)=>{let V=K.runtimes.find((j)=>j.id===X);if(V){if(Z.availableModels&&Z.availableModels.length>0)V.discoveredModels=H2({adapterId:W,models:Z.availableModels,currentModelId:Z.currentModelId??J});if(Z.availableConfigOptions.length>0)V.discoveredConfigOptions=Z.availableConfigOptions}}).catch(()=>{return})}function QW(X,Z){return`${X}
1063
+ `;V+=R.content.text,w=!1,G(V)}}else{let T=`agent_message_chunk:${R.content.type}`;q[T]=(q[T]??0)+1}return}case"agent_thought_chunk":{if(R.content.type!=="text")return;j+=R.content.text;let D=new Date().toISOString(),T=`${Z.runId}:thought`,I=v.get(T);y({toolCallId:T,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:I?.startedAt??D,completedAt:null,contentPreview:k0(j.trim())});return}case"user_message_chunk":return;case"tool_call":{U+=1,w=V.length>0;let D=Y4(R.title),T=RX(R.status),I=new Date().toISOString();P(I),O(I),y({toolCallId:R.toolCallId,rawTitle:D,title:CX(D,R.rawInput),kind:fX(R.kind),status:T,startedAt:I,completedAt:T==="running"?null:I,inputPreview:v0(R.rawInput),outputPreview:hX(R.rawOutput),contentPreview:B2(R.content),locations:MX(R.locations)});return}case"tool_call_update":{let D=v.get(R.toolCallId);if(!D){let Z0=Y4(R.title),W0=RX(R.status),N1=new Date().toISOString();y({toolCallId:R.toolCallId,rawTitle:Z0,title:CX(Z0,R.rawInput),kind:fX(R.kind),status:W0,startedAt:N1,completedAt:W0==="running"?null:N1,inputPreview:v0(R.rawInput),outputPreview:hX(R.rawOutput),contentPreview:B2(R.content),locations:MX(R.locations)});return}let T=R.status===void 0||R.status===null?D.status:RX(R.status),I=typeof R.title==="string"&&R.title.trim().length>0?R.title:D.rawTitle,q0=typeof R.title==="string"&&R.title.trim().length>0,S=T==="running"?D.completedAt:D.completedAt??new Date().toISOString(),s=R.content===void 0?D.contentPreview:j4(D.contentPreview,B2(R.content)),c=R.rawOutput===void 0?D.outputPreview:j4(D.outputPreview,hX(R.rawOutput));y({...D,rawTitle:I,title:q0?CX(I,R.rawInput):D.title,kind:R.kind===void 0?D.kind:fX(R.kind),status:T,completedAt:S,inputPreview:R.rawInput===void 0?D.inputPreview:v0(R.rawInput),outputPreview:c,contentPreview:s,locations:R.locations===void 0?D.locations:MX(R.locations)});return}case"plan":F=R.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>V,getToolCallCount:()=>U,getLatestPlan:()=>F,getUpdateTypeCounts:()=>({...q}),flush:(b)=>{let R=new Date().toISOString();if(P(R),b?.completeOpenToolCalls)M(R);k()}}}var l7=new Set(["ECONNRESET","EPIPE"]);function L2(X){if(!X||typeof X!=="object")return!1;if(X instanceof Error&&X.message==="ACP connection closed")return!0;let Z="code"in X?X.code:void 0;return typeof Z==="string"&&l7.has(Z)}var b1=1,w4=-32000;function U4(X){if(X.awaitingInput)return!1;return X.nowMs-X.lastUpdateMs>=X.windowMs}function q4(X){if(!X||typeof X!=="object")return!1;return X.code===w4}var T7=300000,c7=T7,a7=5000;function d7(X){let Z=Math.max(1,Math.round(X/1000));return`Runtime has not responded for ${Z} ${Z===1?"second":"seconds"}. Retry the agent run.`}function L4(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.96".trim()?"0.0.96":"dev"}}function P4(X){if(X===b1)return;throw new l(`Unsupported ACP protocol version ${X}; expected ${b1}`)}function x4(X){return u7.toWeb(X)}function b4(X){return A7.toWeb(X)}function NX(X){return X!==null&&typeof X==="object"}function i7(X){if(!Array.isArray(X))return[];let Z=[];for(let W of X){if(!NX(W))continue;if(typeof W.group==="string"&&Array.isArray(W.options)){let J=typeof W.name==="string"?W.name:W.group;for(let K of W.options){if(!NX(K))continue;if(typeof K.value!=="string"||typeof K.name!=="string")continue;Z.push({value:K.value,name:K.name,description:typeof K.description==="string"?K.description:null,group:W.group,groupName:J})}continue}if(typeof W.value!=="string"||typeof W.name!=="string")continue;Z.push({value:W.value,name:W.name,description:typeof W.description==="string"?W.description:null,group:null,groupName:null})}return Z}function p7(X){if(!NX(X))return null;if(typeof X.id!=="string"||typeof X.name!=="string")return null;let Z=typeof X.category==="string"?X.category:null,W=typeof X.description==="string"?X.description:null;if(X.type==="select"){let J=typeof X.currentValue==="string"?X.currentValue:null;return{id:X.id,name:X.name,category:Z,description:W,type:"select",currentValue:J,options:i7(X.options)}}if(X.type==="boolean"){let J=typeof X.currentValue==="boolean"?X.currentValue:typeof X.value==="boolean"?X.value:null;return{id:X.id,name:X.name,category:Z,description:W,type:"boolean",currentValue:J,options:[]}}return null}function gX(X){let Z=(X.configOptions??[]).map(p7).filter((U)=>U!==null),W=Z.find((U)=>U.type==="select"&&U.category==="model")??Z.find((U)=>U.type==="select"&&U.id==="model")??null,J=W?.options.map((U)=>({id:U.value,name:U.name,description:U.description??null})),K=s7(X.models),V=J&&J.length>0?J:K&&K.length>0?K:null,j=(typeof W?.currentValue==="string"?W.currentValue:null)??r7(X.models)??null;return{models:V,currentModelId:j,configOptions:Z,modelConfigId:W?.id??null}}function s7(X){if(!X||!Array.isArray(X.availableModels))return null;let Z=[];for(let W of X.availableModels){if(typeof W.modelId!=="string")continue;Z.push({id:W.modelId,name:typeof W.name==="string"?W.name:null,description:typeof W.description==="string"?W.description:null})}return Z.length>0?Z:null}function r7(X){return typeof X?.currentModelId==="string"?X.currentModelId:null}function o7(X,Z){let W=[];if(X.trim())W.push({type:"text",text:X});for(let J of Z)if(J.content.trim())W.push({type:"text",text:J.content});return W}var n7=500;function v4(X){return new Promise((Z)=>{let W=setTimeout(()=>Z({code:null,signal:null,stderr:""}),n7);X.then((J)=>{clearTimeout(W),Z(J)})})}function t7(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 e7(X,Z){let W=gX({configOptions:Z.configOptions});return{models:W.models??X.models,currentModelId:W.currentModelId??X.currentModelId,configOptions:W.configOptions,modelConfigId:W.modelConfigId??X.modelConfigId}}function y4(X,Z){if(X==="default")return null;if(!Z||Z.length===0)return X;let W=Z.find((w)=>w.id===X);if(W)return W.id;let J=X.toLowerCase(),K=J.includes("opus")?"opus":J.includes("sonnet")?"sonnet":J.includes("haiku")?"haiku":null;if(!K)return X;let V=(w)=>`${w.id} ${w.name??""} ${w.description??""}`.toLowerCase(),j=Z.filter((w)=>V(w).includes(K));if(j.length===0)return X;let F=(J.includes("1m")?j.find((w)=>V(w).includes("1m")):void 0)??j[0];return F?F.id:X}async function P2(X){try{let Z=await X.conn.setSessionConfigOption(t7({sessionId:X.sessionId,configId:X.configId,value:X.value}));return e7(X.metadata,Z)}catch(Z){return console.warn(`[acp] setSessionConfigOption(${X.label}) failed; using agent default.`,Z instanceof Error?Z.message:Z),X.metadata}}async function x2(X){let Z=yX(X.spawn),W=[],J=0,K=4096;Z.stderr.on("data",(S)=>{W.push(S),J+=S.length;while(J>K*2&&W.length>1){let s=W.shift();if(s)J-=s.length}});let V=()=>{let S=Buffer.concat(W).toString("utf8");return S.length>K?S.slice(-K):S},j=V4(X.spawn.cwd),U={current:null},F={current:null},w={at:Date.now()},q=null,v=b4(Z.stdin),y=x4(Z.stdout),P=B4(v,y),M=new F4((S)=>({requestPermission:async(s)=>{let c=s.options,Z0=c?.find((W0)=>W0.kind==="allow_once")??c?.find((W0)=>W0.kind==="allow_always");if(Z0)return{outcome:{outcome:"selected",optionId:Z0.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(s)=>{w.at=Date.now();let c=F.current;if(c){let W0=s.update.sessionUpdate;if(c.updateCount+=1,c.updateCount===1||c.lastUpdateType!==W0||W0==="tool_call"||W0==="tool_call_update")E("acp.session_update",{runId:c.runId,cardId:c.cardId,sessionId:q,updateType:W0,updateCount:c.updateCount,elapsedMs:Date.now()-c.startedAt});c.lastUpdateType=W0}let Z0=U.current;if(Z0)await Z0.onSessionUpdate(s)},readTextFile:j.readTextFile}),P),h=()=>Z.kill();if(X.signal)X.signal.addEventListener("abort",h);let N=()=>{if(X.signal)X.signal.removeEventListener("abort",h)},g=async(S,s)=>{if(N(),Z.kill(),q4(S))throw new u0(S.message??"Authentication required",s);if(L2(S)){if(X.signal?.aborted)throw new l("ACP session cancelled: abort signal received");let c=await v4(Z.waitForExit);throw new l(`Runtime process exited before completion: ${c.stderr?.trim()??""}`)}throw S},C;try{C=await M.initialize({protocolVersion:b1,clientCapabilities:vX,clientInfo:L4()})}catch(S){throw await g(S,[]),Error("unreachable")}try{P4(C.protocolVersion)}catch(S){throw N(),Z.kill(),S}let m=C.authMethods?.map((S)=>S.id)??[],k;try{k=await M.newSession({cwd:X.spawn.cwd,mcpServers:X.mcpServers??[],...X.isolateAmbientToolSources?{_meta:{claudeCode:{options:{settingSources:[]}}}}:{}})}catch(S){throw await g(S,m),Error("unreachable")}let G=k.sessionId;q=G;let b=gX(k),R=X.modelId??null,D=R?y4(R,b.models):null;if(D&&D!==b.currentModelId)if(b.modelConfigId)b=await P2({conn:M,sessionId:G,configId:b.modelConfigId,value:D,metadata:b,label:`${b.modelConfigId}=${D}`});else console.warn(`[acp] runtime did not advertise a model config option for ${D}; using agent default.`);for(let[S,s]of Object.entries(X.configValues??{}).sort(([c],[Z0])=>c.localeCompare(Z0))){if(S===b.modelConfigId)continue;if(!b.configOptions.some((c)=>c.id===S))continue;b=await P2({conn:M,sessionId:G,configId:S,value:s,metadata:b,label:`${S}=${String(s)}`})}N();let T=!1,I=async()=>{if(T)return;T=!0,Z.kill(),await Promise.race([Z.waitForExit,new Promise((S)=>setTimeout(S,2000))])},q0=!1;return Z.processCrashed.then(()=>{q0=!0}),{sessionId:G,availableModels:b.models,currentModelId:b.currentModelId,availableConfigOptions:b.configOptions,isAlive:()=>!T&&!q0,dispose:I,prompt:(S)=>XW({proc:Z,conn:M,sessionId:G,activeAdapter:U,activeTrace:F,lastUpdate:w,collectStderrTail:V},S)}}async function XW(X,Z){let{proc:W,conn:J,sessionId:K,activeAdapter:V,activeTrace:j,lastUpdate:U}=X,F=Date.now(),w=Z.heartbeatMs??c7,q=d7(w),v={boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId},y=H4({ctx:v,appendText:Z.appendText,appendToolActivity:Z.appendToolActivity,onAnyUpdate:Z.onAnyUpdate});V.current=y,j.current={runId:Z.runId,cardId:Z.cardId,startedAt:F,updateCount:0,lastUpdateType:null},U.at=Date.now(),E("acp.prompt_started",{runId:Z.runId,cardId:Z.cardId,sessionId:K,heartbeatWindowMs:w});let P=!1,O=null,M=()=>W.kill();Z.signal.addEventListener("abort",M);try{let h=async()=>{let m=Math.min(a7,Math.max(50,Math.floor(w/2)));O=setInterval(()=>{let G=Z.isAwaitingInput?.()??!1;if(G){U.at=Date.now();return}if(U4({nowMs:Date.now(),lastUpdateMs:U.at,windowMs:w,awaitingInput:G}))P=!0,E("acp.inactivity_timeout",{runId:Z.runId,cardId:Z.cardId,sessionId:K,windowMs:w,silentForMs:Date.now()-U.at}),J.cancel({sessionId:K}).catch(()=>{return}),W.kill()},m);let k=o7(Z.prompt.systemPrompt,Z.prompt.messages);await J.prompt({sessionId:K,prompt:k}),E("acp.prompt_resolved",{runId:Z.runId,cardId:Z.cardId,sessionId:K,elapsedMs:Date.now()-F}),y.flush({completeOpenToolCalls:!0})},N=W.waitForExit.then((m)=>({kind:"exited",exit:m})),g=h().then(()=>({kind:"ok"})).catch(async(m)=>{if(L2(m))return W.kill(),{kind:"crashed",exit:await v4(W.waitForExit)};throw m}),C;try{C=await Promise.race([g,W.processCrashed.then((m)=>({kind:"crashed",exit:m})),N])}catch(m){if(P)throw new w0(q);throw m}if(P)throw new w0(q);if(C.kind!=="ok"&&Z.signal.aborted)throw new l("ACP session cancelled: abort signal received");if(C.kind==="crashed")throw new l(`Runtime process exited before completion: ${C.exit.stderr.trim()}`);if(C.kind==="exited"){if(P)throw new w0(q);throw new l(`Runtime process exited unexpectedly: ${C.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:y.getFinalText(),toolCallsExecuted:y.getToolCallCount(),stderrTail:X.collectStderrTail(),updateTypeCounts:y.getUpdateTypeCounts()}}finally{if(E("acp.prompt_finished",{runId:Z.runId,cardId:Z.cardId,sessionId:K,elapsedMs:Date.now()-F,timedOut:P,updateCount:j.current?.updateCount??0}),O!==null)clearInterval(O);Z.signal.removeEventListener("abort",M),y.flush({completeOpenToolCalls:!0}),V.current=null,j.current=null}}var ZW=30000;async function O4(X){let Z=yX(X.spawn),W=b4(Z.stdin),J=x4(Z.stdout),K=B4(W,J),j=new F4((w)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),K),U=()=>Z.kill();if(X.signal)X.signal.addEventListener("abort",U);let F=null;try{let w=(async()=>{let v=await j.initialize({protocolVersion:b1,clientCapabilities:vX,clientInfo:L4()});P4(v.protocolVersion);let y=v.authMethods?.map((C)=>C.id)??[],P;try{P=await j.newSession({cwd:X.spawn.cwd,mcpServers:[]})}catch(C){if(q4(C))throw new u0(C.message??"Authentication required",y);throw C}let O=gX(P),M=X.modelId??null,h=M?y4(M,O.models):null;if(h&&h!==O.currentModelId)if(O.modelConfigId)O=await P2({conn:j,sessionId:P.sessionId,configId:O.modelConfigId,value:h,metadata:O,label:`${O.modelConfigId}=${h}`});else console.warn(`[acp] runtime did not advertise a model config option for ${h}; discovering agent default models.`);for(let[C,m]of Object.entries(X.configValues??{}).sort(([k],[G])=>k.localeCompare(G))){if(C===O.modelConfigId)continue;if(!O.configOptions.some((k)=>k.id===C))continue;O=await P2({conn:j,sessionId:P.sessionId,configId:C,value:m,metadata:O,label:`${C}=${String(m)}`})}let N=O.models??[],g=O.currentModelId;return j.cancel({sessionId:P.sessionId}).catch(()=>{return}),{models:N,configOptions:O.configOptions,currentModelId:g}})(),q=new Promise((v,y)=>{F=setTimeout(()=>{y(new w0)},ZW)});return await Promise.race([w,q])}catch(w){if(L2(w)){if(X.signal?.aborted)throw new l("ACP model discovery cancelled: abort signal received");throw new l("Runtime process exited during model discovery.")}throw w}finally{if(F)clearTimeout(F);if(X.signal)X.signal.removeEventListener("abort",U);Z.kill()}}import WW from"node:fs/promises";import b2 from"node:os";async function R4(X){let Z={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},W;try{W=await WW.readFile(X,"utf-8")}catch(J){if(J.code==="ENOENT")return structuredClone(Z);throw J}return E1.parse(JSON.parse(W))}function DX(X,Z,W){return{...X.defaultConfigValues??{},...Z?.configValues??{},...W?.configValues??{}}}async function C0(X){let Z=X.configPath?await R4(X.configPath):await J0(),W=X.cardId?Z.cardOverrides[X.cardId]:void 0;if(W?.runtimeConfigId){let K=Z.runtimes.find((V)=>V.id===W.runtimeConfigId);if(K)return{entry:K,adapter:U0(K),runFolder:W.runFolder??K.runFolder??b2.homedir(),modelId:W.modelId??K.defaultModelId??null,configValues:DX(K,void 0,W)}}let J=Z.boardOverrides[X.boardId];if(J?.runtimeConfigId){let K=Z.runtimes.find((V)=>V.id===J.runtimeConfigId);if(K)return{entry:K,adapter:U0(K),runFolder:J.runFolder??K.runFolder??b2.homedir(),modelId:J.modelId??K.defaultModelId??null,configValues:DX(K,J)}}if(Z.globalDefaultConfigId){let K=Z.runtimes.find((V)=>V.id===Z.globalDefaultConfigId);if(K)return{entry:K,adapter:U0(K),runFolder:W?.runFolder??J?.runFolder??K.runFolder??b2.homedir(),modelId:W?.modelId??J?.modelId??K.defaultModelId??null,configValues:DX(K,J,W)}}throw new x0}async function $X(X,Z={}){let J=(Z.configPath?await R4(Z.configPath):await J0()).runtimes.find((K)=>K.id===X);if(!J)return null;return{entry:J,adapter:U0(J),runFolder:J.runFolder??b2.homedir(),modelId:Z.modelId??J.defaultModelId??null,configValues:{...J.defaultConfigValues??{},...Z.configValues??{}}}}var GX=new Map;function f4(X,Z){GX.set(X,Z)}function C4(X){GX.delete(X)}function h4(X){if(!X)return null;return GX.get(X)??null}var M4=new Map;function mX(X,Z){if(!X)return;M4.set(X,Z)}function N4(X){if(!X)return!1;return M4.get(X)??!1}var _0=new Map,EX=new Set;function _X(X){_0.get(X)?.controller.abort()}function g4(X){for(let[Z,W]of _0){if(W.frontendSessionId!==X)continue;W.controller.abort(),_0.delete(Z)}}function D4(){for(let X of _0.values())X.controller.abort();_0.clear()}function IX(X,Z){if(Z?.aborted)return!0;return X instanceof Error&&/abort signal received|session cancelled/i.test(X.message)}function SX(X,Z,W,J){if((!Z.availableModels||Z.availableModels.length===0)&&Z.availableConfigOptions.length===0)return;z0((K)=>{let V=K.runtimes.find((j)=>j.id===X);if(V){if(Z.availableModels&&Z.availableModels.length>0)V.discoveredModels=H2({adapterId:W,models:Z.availableModels,currentModelId:Z.currentModelId??J});if(Z.availableConfigOptions.length>0)V.discoveredConfigOptions=Z.availableConfigOptions}}).catch(()=>{return})}function QW(X,Z){return`${X}
1064
1064
 
1065
1065
  Runtime run folder:
1066
1066
  - Effective run folder: ${Z}
@@ -1070,4 +1070,4 @@ Runtime run folder:
1070
1070
  Connection: close\r
1071
1071
  Content-Length: ${Buffer.byteLength(W)}\r
1072
1072
  \r
1073
- ${W}`),X.destroy()}function rW(X,Z){return new Promise((W,J)=>{let K=(j)=>{X.off("listening",V),J(j)},V=()=>{X.off("error",K);let j=X.address();if(!j||typeof j==="string"){J(Error("Failed to read CLI bridge server address"));return}W(j.port)};X.once("error",K),X.once("listening",V),X.listen(Z,"127.0.0.1")})}function W8(X){return new Promise((Z,W)=>{X.close((J)=>{if(J)W(J);else Z()})})}async function V8(X,Z=sX()){let W=new Map,J=new Map,K=X.maxMessageSize??IW,V=!1,j=(P)=>{let O=J.get(P);if(O)clearTimeout(O);J.delete(P)},U=(P)=>{J.delete(P);let{activeRunIds:O}=X.registry.disconnect(P);X.onDisconnect(P,O)},F=(P,O)=>{let M={type:"cli_status",connected:!0,runtime:X.runtime,mcpReady:X.mcpReady(),error:O,capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()};if(P){let h=W.get(P);if(h)o0(h,M);return}for(let h of W.values())o0(h,M)},w=(P,O)=>{let M=O.sessionId.trim(),h=O.userId.trim();if(!M||!h){o0(P,{type:"cli_status",connected:!1,runtime:X.runtime,mcpReady:X.mcpReady(),error:"Missing frontend session or user id"}),P.close();return}j(M);let N=W.get(M);if(N&&N!==P)N.close();P.data.frontendSessionId=M,W.set(M,P),X.registry.register({frontendSessionId:M,userId:h,tools:O.tools,send:(g)=>o0(P,g)}),F(M),X.onToolMetadata?.(M)},q=(P,O)=>{let M=X.registry.getUserId(P);if(!M)return;switch(O.type){case"bridge_ping":{let h=W.get(P);if(h)o0(h,{type:"bridge_pong"});break}case"tool_metadata":X.registry.setMetadata(P,O.tools),X.onToolMetadata?.(P);break;case"tool_result":X.registry.handleToolResult(P,O);break;case"run_turn":E("bridge.run_received",{runId:O.run.runId,cardId:O.run.cardId,frontendSessionId:P}),X.registry.markRunActive(P,O.run.runId,O.run.cardId),X.onRunTurn(P,{...O.run,frontendSessionId:P,userId:M});break;case"cancel_run":if(X.registry.ownsRun(P,O.runId))X.onCancelRun(P,O.runId);break;case"runtime_rpc":X.onRuntimeRpc(P,O);break;case"browser_rpc":X.onBrowserRpc?.(P,W.get(P)?.data.frontendOrigin??"",O);break;case"warmup_run":X.onWarmupRun(P,{...O,frontendSessionId:P},M);break;default:break}},v=(P,O)=>{let M=h2(P.headers.origin),h=rX(M),N={Vary:"Origin"};if(h&&M)N["Access-Control-Allow-Origin"]=M,N["Access-Control-Allow-Private-Network"]="true";if(P.method==="OPTIONS"){O.writeHead(204,{...N,"Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*","Access-Control-Max-Age":"600"}),O.end();return}if(P.method!=="GET"){O.writeHead(405,N),O.end();return}O.writeHead(200,{...N,"content-type":"application/json","cache-control":"no-store"}),O.end(JSON.stringify({ideawave:!0,runtime:X.runtime,mcpReady:X.mcpReady(),capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()}))},y=(P,O)=>{let M=h2(P.headers.origin),h=rX(M),N={Vary:"Origin"};if(h&&M)N["Access-Control-Allow-Origin"]=M,N["Access-Control-Allow-Private-Network"]="true";if(P.method==="OPTIONS"){O.writeHead(204,{...N,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"content-type","Access-Control-Max-Age":"600"}),O.end();return}if(!h){O.writeHead(403,N),O.end();return}if(P.method!=="POST"){O.writeHead(405,N),O.end();return}let g={...N,"content-type":"application/json"},C=(G,b)=>{O.writeHead(G,g),O.end(JSON.stringify(b))},m="",k=!1;P.on("data",(G)=>{if(m+=G.toString("utf8"),m.length>AW)k=!0,P.destroy()}),P.on("end",()=>{if(k){C(400,{ok:!1,error:"Request body too large"});return}let G;try{G=JSON.parse(m)}catch{C(400,{ok:!1,error:"Invalid JSON body"});return}let b=typeof G.url==="string"?G.url:"";if(!t4(b)){C(400,{ok:!1,error:"url must be an http(s) loopback or /static_boards/ page URL"});return}let R=(D,T)=>{let I=typeof D==="number"?D:Number.NaN;if(!Number.isFinite(I))return T;return Math.min(4000,Math.max(200,Math.round(I)))};e4({url:b,width:R(G.width,1440),height:R(G.height,900)}).then((D)=>C(200,{ok:!0,path:D.path,engine:D.engine})).catch((D)=>{let T=D instanceof y1?503:D instanceof C2?429:500;C(T,{ok:!1,...D instanceof y1?{installing:!0}:{},error:D instanceof Error?D.message:String(D)})})})};for(let P of Z){let O=kW((N,g)=>{(async()=>{let C=new URL(N.url??"/","http://127.0.0.1").pathname;if(C===s4){v(N,g);return}if(C===uW){y(N,g);return}if(await X.onHttpRequest?.(N,g))return;g.writeHead(404,{"content-type":"text/plain"}),g.end("IdeaWave CLI bridge")})().catch((C)=>{if(g.headersSent){g.destroy(C instanceof Error?C:void 0);return}g.writeHead(500,{"content-type":"text/plain"}),g.end("IdeaWave CLI bridge request failed")})}),M=new _W({noServer:!0,maxPayload:K}),h=(N)=>{if(N.idleTimer)clearTimeout(N.idleTimer);N.idleTimer=setTimeout(()=>{N.close()},SW),N.idleTimer.unref?.()};M.on("connection",(N,g)=>{let C=N;C.data={id:EW(),frontendSessionId:null,frontendOrigin:new URL(h2(g.headers.origin)??J8).origin},C.idleTimer=null,h(C),C.on("ping",()=>h(C)),C.on("pong",()=>h(C)),C.on("error",()=>{if(C.idleTimer)clearTimeout(C.idleTimer);C.close()}),C.on("message",(m)=>{h(C);let k=sW(m);if(K>0&&k.length>K)return;let G=v2(k);if(!G)return;let b=C.data.frontendSessionId;if(!b){if(G.type==="bridge_probe")o0(C,{type:"bridge_probe_ack",protocolVersion:G.protocolVersion});else if(G.type==="frontend_hello")w(C,G);return}q(b,G)}),C.on("close",()=>{if(C.idleTimer)clearTimeout(C.idleTimer);let m=C.data.frontendSessionId;if(!m)return;if(W.get(m)!==C)return;if(W.delete(m),j(m),V)return;J.set(m,setTimeout(()=>U(m),lW))})}),O.on("upgrade",(N,g,C)=>{let m=new URL(N.url??"/","http://127.0.0.1").pathname;if(X.onHttpUpgrade?.(N,g,C))return;if(m!==pX){Z8(g,404,"Not Found");return}if(!rX(h2(N.headers.origin))){Z8(g,403,"Forbidden");return}M.handleUpgrade(N,g,C,(k)=>{M.emit("connection",k,N)})});try{let N=await rW(O,P);return{url:`ws://127.0.0.1:${N}${pX}`,port:N,sendStatus:F,close:async()=>{V=!0;for(let g of J.values())clearTimeout(g);J.clear();for(let g of M.clients){let C=g;if(C.idleTimer)clearTimeout(C.idleTimer);C.close()}M.close(),await W8(O).catch(()=>{return})}}}catch(N){if(M.close(),await W8(O).catch(()=>{return}),N?.code==="EADDRINUSE")continue;throw N}}throw Error(`No free IdeaWave CLI bridge port found in ${Z[0]}-${Z.at(-1)}`)}import{lstat as UQ,readFile as FQ}from"node:fs/promises";import BQ from"node:os";import R1 from"node:path";import{Server as qQ}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as LQ,ListToolsRequestSchema as PQ}from"@modelcontextprotocol/sdk/types.js";var Y8=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"]),oW=["screenshot_board","inspect_diagram","ask_user_question","create_agent_card","append_user_message","spawn_child_agents"],nW=new Set(oW),AY=new Set([...Y8].filter((X)=>!nW.has(X)));var z8=new Set(["inspect_ideate_context","get_ideate_run_status","screenshot_ideate_context","submit_ideate_plan","revise_ideate_plan","set_ideate_placement","ask_ideate_question","complete_ideate_run","start_board_walkthrough"]),j8=new Set(["inspect_ideate_context","get_ideate_run_status","get_ideate_worker_context","screenshot_ideate_context","get_board","list_nodes","list_edges","inspect_node","inspect_board_region","inspect_diagram","list_context_sources","read_context_card","read_context_file","read_context_image","list_context_folder","get_board_wiki","search_board","inspect_neighbors","read_diagram_guide","inspect_browser","locate_browser_element","list_agent_cards","get_card_messages","inspect_table","get_table_schema","read_table","query_table","export_table_csv","start_board_walkthrough","ideate_create_note","ideate_create_code","ideate_create_shape","ideate_create_browser","ideate_add_browser_note","ideate_add_board_callout","ideate_create_diagram","ideate_create_edge","ideate_update_note","ideate_update_code","ideate_update_shape","ideate_update_diagram","ideate_update_edge","ideate_delete_node","ideate_delete_edge"]),tW=new Set([...z8,...j8].filter((X)=>X.startsWith("ideate_")||X.includes("ideate_")));function H8(X,Z){if(Z==="full")return!tW.has(X);if(Z==="read")return Y8.has(X);if(Z==="ideate-coordinator")return z8.has(X);return j8.has(X)}import{randomUUID as XQ}from"node:crypto";import{createServer as ZQ}from"node:http";import{StreamableHTTPServerTransport as WQ}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as B8}from"@modelcontextprotocol/sdk/types.js";var w8=new Set(["127.0.0.1","localhost","[::1]","::1"]);function eW(X){let Z=X.trim();if(Z.length===0)return null;if(Z.startsWith("[")){let V=Z.indexOf("]");if(V===-1)return null;let j=Z.slice(0,V+1),U=Z.slice(V+1);if(U.length===0)return{host:j,port:null};if(!U.startsWith(":"))return null;let F=Number(U.slice(1));if(!Number.isInteger(F)||F<=0||F>65535)return null;return{host:j,port:F}}let W=Z.lastIndexOf(":");if(W===-1)return{host:Z,port:null};let J=Z.slice(W+1),K=Number(J);if(!Number.isInteger(K)||K<=0||K>65535)return{host:Z,port:null};return{host:Z.slice(0,W),port:K}}function U8(X){return w8.has(X)||w8.has(X.toLowerCase())}function F8(X,Z){let W=X.headers.host;if(typeof W!=="string")return{ok:!1,status:403,reason:"missing-host"};let J=eW(W);if(!J)return{ok:!1,status:403,reason:"bad-host"};if(!U8(J.host))return{ok:!1,status:403,reason:"non-loopback-host"};if(J.port!==null&&J.port!==Z)return{ok:!1,status:403,reason:"host-port-mismatch"};let K=X.headers.origin;if(typeof K==="string"&&K.length>0){if(K!=="null"){let V;try{V=new URL(K)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!U8(V.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var q8="/mcp",QQ=43274,P8=16777216,JQ=1800000,KQ=300000,L8=200,VQ=-32700,M0=-32600,oX=-32603;function Y0(X,Z,W,J,K){X.statusCode=Z,X.setHeader("content-type","application/json"),X.end(JSON.stringify({jsonrpc:"2.0",error:{code:W,message:J,...K?{data:K}:{}},id:null}))}class nX extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class tX extends Error{constructor(){super(`body exceeds ${P8} bytes`);this.name="BodyTooLargeError"}}async function YQ(X){if(X.method&&X.method!=="POST")return;let Z=X.headers["content-type"];if(typeof Z==="string"&&Z.trim().length>0){if(!Z.toLowerCase().includes("application/json"))throw new nX}let W=0,J=[];for await(let V of X){let j=typeof V==="string"?Buffer.from(V):V;if(W+=j.byteLength,W>P8)throw new tX;J.push(j)}if(J.length===0)return;let K=Buffer.concat(J).toString("utf8");if(K.length===0)return;return JSON.parse(K)}function zQ(X){if(Array.isArray(X))return X.some(B8);return B8(X)}function jQ(X){if(typeof X==="number")return X;let Z=process.env.IDEAWAVE_MCP_PORT;if(Z&&Z.trim().length>0){let W=Number(Z);if(Number.isInteger(W)&&W>=0&&W<65536)return W}return QQ}async function HQ(X,Z){let W=(K)=>new Promise((V,j)=>{let U=(w)=>{X.off("listening",F),j(w)},F=()=>{X.off("error",U),V()};X.once("error",U),X.once("listening",F),X.listen(K,"127.0.0.1")});try{await W(Z)}catch(K){if(K.code!=="EADDRINUSE"||Z===0)throw K;console.warn(`[mcp] port ${Z} in use, falling back to an OS-assigned port; external CLIs will need to re-paste the install command from Settings → External agents`),await W(0)}let J=X.address();if(J==null||typeof J==="string")throw Error("[mcp] failed to read bound address");return J.port}function wQ(X,Z){if(Z&&typeof Z==="object"&&!Array.isArray(Z)){let J=Z.params;if(J&&typeof J==="object"&&!Array.isArray(J)){let K=J.clientInfo;if(K&&typeof K==="object"&&!Array.isArray(K)){let V=K.name;if(typeof V==="string"&&V.trim().length>0)return V.trim()}}}let W=X.headers["user-agent"];if(typeof W==="string"&&W.trim().length>0)return W.trim();return null}async function x8(X){let Z=new Map,W=0;function J(w){let q=Z.get(w);if(q)q.lastActivity=Date.now()}async function K(w,q){Z.delete(w),await q.transport.close().catch(()=>{return})}async function V(){let w=null,q=1/0;for(let[v,y]of Z)if(y.lastActivity<q)q=y.lastActivity,w=v;if(w!==null){let v=Z.get(w);if(v)console.warn(`[mcp] session cap of ${L8} reached; evicting ${w}`),await K(w,v)}}let j=setInterval(()=>{let w=Date.now()-JQ;for(let[q,v]of Z)if(v.lastActivity<w)console.log(`[mcp] sweeping idle session ${q}`),K(q,v)},KQ);j.unref?.();let U=ZQ((w,q)=>{(async()=>{let v;try{v=new URL(w.url??"/","http://127.0.0.1").pathname}catch{Y0(q,400,M0,"bad-url");return}if(v!==q8){Y0(q,404,M0,"not-found");return}let y=w.method??"POST";if(y!=="POST"&&y!=="GET"&&y!=="DELETE"){q.setHeader("Allow","GET, POST, DELETE"),Y0(q,405,M0,"method-not-allowed");return}let P=F8(w,W);if(!P.ok){Y0(q,P.status,M0,"forbidden",{reason:P.reason});return}let O=w.headers["mcp-session-id"],M=typeof O==="string"?O:void 0;if(y==="GET"||y==="DELETE"){if(!M||!Z.has(M)){Y0(q,400,M0,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let g=Z.get(M).transport;J(M);try{await g.handleRequest(w,q)}catch(C){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",C),!q.headersSent)Y0(q,500,oX,"internal")}return}let h;try{h=await YQ(w)}catch(g){if(g instanceof nX){Y0(q,415,M0,"expected-application-json");return}if(g instanceof tX){Y0(q,413,M0,"body-too-large");return}Y0(q,400,VQ,"invalid-json");return}let N;if(M&&Z.has(M))N=Z.get(M).transport,J(M);else if(!M&&h!==void 0&&zQ(h)){let g=w.headers["x-ideawave-user-id"],C=typeof g==="string"&&g.trim().length>0?g.trim():null,m=w.headers["x-ideawave-frontend-session-id"],k=typeof m==="string"&&m.trim().length>0?m.trim():null,G=w.headers["x-ideawave-tool-surface"],b=typeof G==="string"?G.trim():"full",R=b==="read"||b==="ideate-coordinator"||b==="ideate-worker"?b:"full",D=w.headers["x-ideawave-images-supported"],T=typeof D==="string"&&D.trim()==="1",I=w.headers["x-ideawave-card-id"],q0=typeof I==="string"&&I.trim().length>0?I.trim():null,S=w.headers["x-ideawave-execution-kind"],s=w.headers["x-ideawave-execution-id"],c=typeof S==="string"?S.trim():"",Z0=typeof s==="string"?s.trim():"",N1=Z0&&new Set(["agent-card","ideate-coordinator","ideate-step","ideate-participant","board-insight","board-auto-title"]).has(c)?{kind:c,id:Z0}:null,$2=w.headers["x-ideawave-ideate-claims"],G2=null;if(typeof $2==="string"&&$2.length>0)try{G2=JSON.parse($2)}catch{G2=null}let m2=w.headers["x-ideawave-board-id"],g8=typeof m2==="string"&&m2.trim().length>0?m2.trim():null,E2=w.headers["x-ideawave-run-folder"],D8=typeof E2==="string"&&E2.trim().length>0?E2.trim():null,k2=w.headers["x-ideawave-pool-session-id"],$8=typeof k2==="string"&&k2.trim().length>0?k2.trim():null,G8=wQ(w,h);if(Z.size>=L8)await V();let _2=null,D0=new WQ({sessionIdGenerator:()=>XQ(),onsessioninitialized:(l0)=>{_2=l0,Z.set(l0,{transport:D0,lastActivity:Date.now()})},onsessionclosed:(l0)=>{Z.delete(l0)}});D0.onclose=()=>{if(D0.sessionId)Z.delete(D0.sessionId)};try{await X.buildServer({userId:C,frontendSessionId:k,boardId:g8,toolSurface:R,imagesSupported:T,cardId:q0,executionTarget:N1,ideateClaims:G2,runFolder:D8,poolSessionId:$8,clientHint:G8}).connect(D0)}catch(l0){if(console.error("[mcp] buildServer/connect failed",l0),_2)Z.delete(_2);await D0.close().catch(()=>{return}),Y0(q,500,oX,"server-init-failed");return}N=D0}else{Y0(q,400,M0,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await N.handleRequest(w,q,h)}catch(g){if(console.error("[mcp] transport.handleRequest threw",g),!q.headersSent)Y0(q,500,oX,"internal")}})().catch((v)=>{console.error("[mcp] unhandled request handler error:",v)})});return W=await HQ(U,jQ(X.port)),{url:`http://127.0.0.1:${W}${q8}`,port:W,close:async()=>{clearInterval(j);for(let w of Z.values())await w.transport.close().catch(()=>{return});Z.clear(),await new Promise((w)=>U.close(()=>w()))}}}var xQ={name:"ideawave-board",version:"1.0.0"},M2="list_run_folder",N2="read_run_folder_file",y8=new Set(["inspect_diagram"]);function O8(X,Z){if(X===M2||X===N2)return Z!=="ideate-coordinator";return H8(X,Z)}var bQ=[{name:M2,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:N2,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 eX(X){return{content:[{type:"text",text:X}]}}function vQ(X){return eX(JSON.stringify(X,null,2))}function b8(X){return{...eX(X),isError:!0}}async function yQ(X,Z){if(!Z||X.isError)return X;let W=X.content.find((V)=>V.type==="text");if(!W)return X;let J;try{let V=JSON.parse(W.text);if(typeof V.path!=="string")return X;J=R1.resolve(V.path)}catch{return X}let K=R1.resolve(R1.join(BQ.tmpdir(),"ideawave-screenshots"));if(R1.dirname(J)!==K||!/^board-[a-z0-9-]+\.png$/i.test(R1.basename(J)))return X;try{if(!(await UQ(J)).isFile())return X;let j=await FQ(J);if(j.byteLength<1024||j.byteLength>26214400||!j.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return X;return{...X,content:[...X.content,{type:"image",data:j.toString("base64"),mimeType:"image/png"}]}}catch{return X}}function OQ(X,Z,W="full",J=!1){return X.getMetadata(Z).filter((K)=>{let V=F2(K.name);if(!O8(V,W))return!1;if(!J&&y8.has(V))return!1;return!0}).map((K)=>({name:K.name,description:K.description,inputSchema:K.inputSchema}))}function RQ(X,Z,W={}){let J=OQ(X,Z,W.toolSurface??"full",W.imagesSupported??!1);return W.includeRunFolderTools?[...J,...bQ]:J}function v8(X,Z){if(!X||typeof X!=="object"||Array.isArray(X))return null;let W=X[Z];return typeof W==="string"?W:null}async function fQ(X,Z,W){if(W&&W.trim().length>0)return W.trim();if(!X||!Z)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await C0({boardId:X,cardId:Z})).runFolder}async function CQ(X){let Z=await fQ(X.boardId,X.cardId,X.runFolder);if(X.name===M2){let W=v8(X.args,"path")??"",J=await K4(Z,W);return vQ(J)}if(X.name===N2){let W=v8(X.args,"path");if(!W)return b8("read_run_folder_file requires a path.");return eX(await U2(Z,W))}return b8(`Unknown local tool "${X.name}"`)}function hQ(X,Z,W,J,K,V="full",j=!1,U=null,F=null,w=null){let q=new qQ(xQ,{capabilities:{tools:{}}}),v=()=>{let P=h4(w);return{cardId:P?.cardId??J,executionTarget:P?.executionTarget??U,ideateClaims:P?.ideateClaims??F}},y=async()=>{if(j)return!0;let P=v().cardId;if(N4(P))return!0;if(W&&P)try{return(await C0({boardId:W,cardId:P})).adapter.supportsImages===!0}catch{return!1}return!1};return q.setRequestHandler(PQ,async()=>({tools:RQ(X,Z,{includeRunFolderTools:V!=="ideate-coordinator"&&Boolean(K||W&&J),toolSurface:V,imagesSupported:await y()})})),q.setRequestHandler(LQ,async(P)=>{let{name:O,arguments:M}=P.params,h=F2(O),N=Date.now(),g=v();E("mcp.tool_call_received",{frontendSessionId:Z,cardId:g.cardId,toolName:h});try{if(!O8(h,V))throw Error(`Tool "${O}" is not available on the ${V} surface`);if(h===M2||h===N2)return await CQ({name:h,args:M,boardId:W,cardId:g.cardId,runFolder:K});if(y8.has(h)&&!await y())throw Error(`Tool "${O}" requires a runtime that supports image input`);let C=await X.callTool(Z,h,M??{},g.ideateClaims?.runId,g.cardId??void 0,g.executionTarget??void 0,g.ideateClaims??void 0,V);if(E("mcp.tool_result_returned",{frontendSessionId:Z,cardId:g.cardId,toolName:h,elapsedMs:Date.now()-N}),C&&typeof C==="object"&&Array.isArray(C.content)){let m=C;return h==="screenshot_board"||h==="screenshot_ideate_context"?await yQ(m,await y()):m}return{content:[{type:"text",text:typeof C==="string"?C:JSON.stringify(C)}]}}catch(C){return E("mcp.tool_result_returned",{frontendSessionId:Z,cardId:g.cardId,toolName:h,elapsedMs:Date.now()-N,hasError:!0}),{content:[{type:"text",text:C instanceof Error?C.message:"Tool call failed"}],isError:!0}}}),q}function R8(X,Z){return x8({buildServer:(W)=>hQ(X,W.frontendSessionId,W.boardId,W.cardId,W.runFolder,W.toolSurface,W.imagesSupported,W.executionTarget,W.ideateClaims,W.poolSessionId),port:Z})}import g2 from"node:fs/promises";import X3 from"node:os";import D2 from"node:path";function f8(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function MQ(){let[X,Z]=await Promise.all([J0(),p3()]),W=X.globalDefaultConfigId?X.runtimes.find((J)=>J.id===X.globalDefaultConfigId)??null:null;return{runtimes:X.runtimes,globalDefaultConfigId:X.globalDefaultConfigId,globalDefaultEffective:W?{runFolder:W.runFolder??X3.homedir(),modelId:W.defaultModelId??null,configValues:W.defaultConfigValues??{}}:null,knownAdapters:T0().map((J)=>({id:J.id,displayName:J.displayName})),readiness:Z}}async function NQ(X){try{let Z=await C0({boardId:X.boardId,cardId:X.cardId});return{resolved:{configId:Z.entry.id,adapterId:Z.entry.kind==="registered"?Z.entry.adapterId:null,displayName:Z.entry.displayName,runFolder:Z.runFolder,modelId:Z.modelId,configValues:Z.configValues}}}catch(Z){if(Z instanceof x0)return{resolved:null};throw Z}}async function gQ(X){return z0((Z)=>{let W=Z.runtimes.find((V)=>V.kind==="registered"&&V.adapterId===X.adapterId);if(W)return W;let J=T0().find((V)=>V.id===X.adapterId);if(!J)throw Error(`Unknown adapterId: ${X.adapterId}`);let K={id:f8(),kind:"registered",adapterId:X.adapterId,displayName:J.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(K),K})}async function DQ(X){return z0((Z)=>{let W={id:f8(),kind:"custom",displayName:X.displayName,command:X.command,args:X.args,env:X.env,runFolder:X.runFolder,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(W),W})}async function $Q(X){await z0((Z)=>{if(Z.runtimes=Z.runtimes.filter((W)=>W.id!==X.runtimeConfigId),Z.globalDefaultConfigId===X.runtimeConfigId)Z.globalDefaultConfigId=null;for(let W of Object.keys(Z.boardOverrides))if(Z.boardOverrides[W].runtimeConfigId===X.runtimeConfigId)delete Z.boardOverrides[W];for(let W of Object.keys(Z.cardOverrides))if(Z.cardOverrides[W].runtimeConfigId===X.runtimeConfigId)delete Z.cardOverrides[W]})}async function GQ(X){await z0((Z)=>{let W=Z.runtimes.find((J)=>J.id===X.runtimeConfigId);if(!W)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);if(Z.globalDefaultConfigId=X.runtimeConfigId,X.runFolder!==void 0)W.runFolder=X.runFolder;if(X.modelId!==void 0)W.defaultModelId=X.modelId;if(X.configValues!==void 0)W.defaultConfigValues=X.configValues})}async function mQ(X){X.boardId,await z0((Z)=>{if(X.runtimeConfigId===null){delete Z.cardOverrides[X.cardId];return}if(!Z.runtimes.some((K)=>K.id===X.runtimeConfigId))throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let J=Z.cardOverrides[X.cardId];Z.cardOverrides[X.cardId]={runtimeConfigId:X.runtimeConfigId,runFolder:X.runFolder!==void 0?X.runFolder:J?.runFolder??null,modelId:X.modelId!==void 0?X.modelId:J?.modelId??null,configValues:X.configValues!==void 0?X.configValues:J?.configValues??{}}})}async function EQ(X){let W=(await J0()).runtimes.find((j)=>j.id===X.runtimeConfigId);if(!W)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let J=U0(W),K=await J.resolveSpawnConfig(W),V=W.runFolder??X3.homedir();try{let j=await O4({spawn:{...K,cwd:V},modelId:X.modelId??W.defaultModelId??null,configValues:X.configValues??W.defaultConfigValues??{}}),U=H2({adapterId:J.id,models:j.models,currentModelId:j.currentModelId}),F=new Date().toISOString();return await z0((w)=>{let q=w.runtimes.find((v)=>v.id===X.runtimeConfigId);if(q)q.discoveredModels=U,q.discoveredConfigOptions=j.configOptions,q.discoveredAt=F}),{ok:!0,models:U,configOptions:j.configOptions,currentModelId:j.currentModelId}}catch(j){if(j instanceof u0)throw Error(`${j.message}${J.authHint?` ${J.authHint}`:""}`);if(j instanceof l||j instanceof w0)throw Error(j.message);throw j}}async function kQ(X){let Z=X3.homedir(),W=X.path?.trim()?X.path.trim():Z,J=D2.resolve(W),K=!0;try{if(!(await g2.stat(J)).isDirectory())J=D2.dirname(J)}catch{K=!1,J=Z}let V=[];try{V=(await g2.readdir(J,{withFileTypes:!0})).filter((F)=>F.isDirectory()&&!F.name.startsWith(".")).map((F)=>({name:F.name,path:D2.join(J,F.name)})).sort((F,w)=>F.name.localeCompare(w.name))}catch{V=[]}let j=D2.dirname(J);return{path:J,parent:j===J?null:j,home:Z,exists:K,entries:V}}var C8={list:MQ,getEffectiveForCard:NQ,registerRegistered:gQ,registerCustom:DQ,unregister:$Q,setUserDefault:GQ,setCardOverride:mQ,refreshModels:EQ,browseFolder:kQ};var _Q=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function IQ(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function h8(){try{let X=await J0();if(X.globalDefaultConfigId){if(X.runtimes.some((W)=>W.id===X.globalDefaultConfigId))return X.globalDefaultConfigId}for(let Z of _Q){if((await s3(Z.id))?.status!=="ready")continue;let J=null;if(await z0((K)=>{if(K.globalDefaultConfigId){if(K.runtimes.some((U)=>U.id===K.globalDefaultConfigId)){J=K.globalDefaultConfigId;return}}let V=K.runtimes.find((j)=>j.kind==="registered"&&j.adapterId===Z.id);if(!V){let j={id:IQ(),kind:"registered",adapterId:Z.id,displayName:Z.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};K.runtimes.push(j),V=j}K.globalDefaultConfigId=V.id,J=V.id}),J)return console.log(`[ideawave-cli] using agent runtime: ${Z.displayName}`),J}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 SQ=240000;function lQ(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class Z3{sessions=new Map;createCallId;toolCallTimeoutMs;constructor(X={}){this.createCallId=X.createCallId??lQ,this.toolCallTimeoutMs=X.toolCallTimeoutMs??SQ}register(X){let Z=this.sessions.get(X.frontendSessionId);if(Z){if(Z.userId!==X.userId)this.rejectPending(Z,"frontend session user changed"),Z.activeRunIds.clear();this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:Z.pendingToolCalls,activeRunIds:Z.activeRunIds,activeRunCardIds:Z.activeRunCardIds});return}this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:new Map,activeRunIds:new Set,activeRunCardIds:new Map})}disconnect(X,Z="frontend session disconnected"){let W=this.sessions.get(X);if(!W)return{activeRunIds:[]};return this.sessions.delete(X),this.rejectPending(W,Z),{activeRunIds:Array.from(W.activeRunIds)}}sessionCount(){return this.sessions.size}has(X){return this.sessions.has(X)}getUserId(X){return this.sessions.get(X)?.userId??null}setMetadata(X,Z){let W=this.sessions.get(X);if(W)W.tools=Z}getMetadata(X){if(!X)return[];return this.sessions.get(X)?.tools??[]}sendToSession(X,Z){let W=this.sessions.get(X);if(!W)return!1;return W.send(Z),!0}callTool(X,Z,W,J,K,V,j,U){if(!X)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let F=this.sessions.get(X);if(!F)return Promise.reject(Error(`Frontend session ${X} is not connected`));let w=this.createCallId();return new Promise((q,v)=>{let y=J??(K?this.getActiveRunIdForCard(F,K):this.getSoleActiveRunId(F)),P=K??(y?F.activeRunCardIds.get(y):void 0),O=Date.now(),M=setTimeout(()=>{F.pendingToolCalls.delete(w),E("tool_queue.timeout",{frontendSessionId:X,runId:y,cardId:P,callId:w,toolName:Z,elapsedMs:Date.now()-O,queueDepth:F.pendingToolCalls.size}),v(Error(`Tool "${Z}" timed out waiting for the frontend`))},this.toolCallTimeoutMs);F.pendingToolCalls.set(w,{resolve:q,reject:v,timer:M,name:Z,runId:y??null,cardId:P??null,startedAt:O}),E("tool_queue.forwarded_to_browser",{frontendSessionId:X,runId:y,cardId:P,callId:w,toolName:Z,queueDepth:F.pendingToolCalls.size}),F.send({type:"tool_call",callId:w,name:Z,args:W,...y?{runId:y}:{},...P?{cardId:P}:{},...V?{executionTarget:V}:{},...j?{ideateClaims:j}:{},...U?{toolSurface:U}:{}})})}handleToolResult(X,Z){let W=this.sessions.get(X);if(!W)return;let J=W.pendingToolCalls.get(Z.callId);if(!J)return;W.pendingToolCalls.delete(Z.callId),clearTimeout(J.timer);let K=Z.ok?"":Z.error??Z.result?.content?.find(({text:U})=>typeof U==="string")?.text??"Tool execution failed",V=/network|fetch|connection|offline/i.test(K)?"network":/timeout|timed out/i.test(K)?"timeout":/unauthor|forbidden|permission/i.test(K)?"authorization":/conflict|revision|lease|fence/i.test(K)?"conflict":/invalid|missing|required|schema/i.test(K)?"validation":"unknown";if(E("tool_queue.result_received",{frontendSessionId:X,runId:J.runId,cardId:J.cardId,callId:Z.callId,toolName:J.name,elapsedMs:Date.now()-J.startedAt,queueDepth:W.pendingToolCalls.size,ok:Z.ok,...Z.ok?{}:{errorCategory:V}}),Z.ok){J.resolve(Z.result);return}let j=Z.result;if(j&&typeof j==="object"&&Array.isArray(j.content)){J.resolve({...j,isError:!0});return}J.reject(Error(Z.error??"Tool execution failed"))}markRunActive(X,Z,W){let J=this.sessions.get(X);if(!J)return;if(J.activeRunIds.add(Z),W)J.activeRunCardIds.set(Z,W)}markRunSettled(X,Z){let W=this.sessions.get(X);if(!W)return;W.activeRunIds.delete(Z),W.activeRunCardIds.delete(Z)}ownsRun(X,Z){return this.sessions.get(X)?.activeRunIds.has(Z)??!1}rejectPending(X,Z){for(let W of X.pendingToolCalls.values())clearTimeout(W.timer),E("tool_queue.rejected",{frontendSessionId:X.frontendSessionId,runId:W.runId,cardId:W.cardId,toolName:W.name,elapsedMs:Date.now()-W.startedAt}),W.reject(Error(Z));X.pendingToolCalls.clear()}getSoleActiveRunId(X){return X.activeRunIds.size===1?X.activeRunIds.values().next().value:void 0}getActiveRunIdForCard(X,Z){let W=[...X.activeRunCardIds.entries()].filter(([J,K])=>X.activeRunIds.has(J)&&K===Z).map(([J])=>J);return W.length===1?W[0]:void 0}}function N8(){return"0.0.95".trim()?"0.0.95":"dev"}var uQ=process.argv.slice(2),Q3=X8(uQ,process.env);if(Q3.allowRailwayPrPreviews)process.env[O1]="1";var g0=Q3.cliArgs[0],{browserKitEnabled:C1,captureEngineEnabled:AQ}=Q3;if(g0==="--help"||g0==="-h"||g0==="help")console.log("ideawave — host the local bridge for a running ideawave.app session."),console.log(""),console.log("Usage:"),console.log(" ideawave Serve the browser bridge and MCP forwarder."),console.log(" ideawave --version Print the CLI version."),process.exit(0);if(g0==="--version"||g0==="-v"||g0==="version")console.log(N8()),process.exit(0);if(g0)console.error(`Unknown command: ${g0}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var h1=new Z3,S0=null,TQ=C1?{phase:"ready",message:"Local browser-kit proxy is ready"}:{phase:"idle"},n0=new j2;function N0(X,Z){h1.sendToSession(X,Z)}async function cQ(X,Z){try{let W=C8[Z.method],J=await W(Z.params);N0(X,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!0,result:J})}catch(W){N0(X,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!1,error:W instanceof Error?W.message:String(W)})}}var M1=!1,f1=null;async function W3(){if(M1)return;if(f1)return f1;return f1=(async()=>{try{let X=await R8(h1);U3({...X,requestedPort:X.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${X.url}`);try{await N3({onStatusChange:(Z)=>{if(r3(),S0?.sendStatus(),Z.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${Z.packageName}: ${Z.error??"unknown error"}`)}})}catch(Z){console.warn("[ideawave-cli] ACP bridge setup skipped:",Z instanceof Error?Z.message:String(Z))}await h8(),M1=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),S0?.sendStatus()}catch(X){console.error("[ideawave-cli] failed to start agent host:",X),S0?.sendStatus(void 0,X instanceof Error?X.message:String(X))}finally{f1=null}})(),f1}if(process.env.APP_ENV!=="development"){let X=await K8();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(AQ)a4().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"}`)});S0=await V8({registry:h1,runtime:null,mcpReady:()=>M1,capabilities:l4(C1),cliVersion:N8(),browserRuntimeStatus:()=>TQ,onToolMetadata:(X)=>{console.log(`[ideawave-cli] session ${X} advertised ${h1.getMetadata(X).length} tools`),W3()},onRunTurn:(X,Z)=>{console.log(`[ideawave-cli] running agent turn for card ${Z.cardId} (session ${X})`),(async()=>{if(await W3(),!M1){N0(X,{type:"run_settled",runId:Z.runId,cardId:Z.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"IdeaWave CLI agent host is not ready",partialText:null}});return}await G4(Z,(W)=>N0(X,W))})().catch(()=>{return}).finally(()=>h1.markRunSettled(X,Z.runId))},onCancelRun:(X,Z)=>{_X(Z)},onRuntimeRpc:(X,Z)=>{cQ(X,Z)},onBrowserRpc:(X,Z,W)=>{if(!C1){N0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!1,error:"The development browser-kit proxy is not enabled"});return}n0.handleRpc(X,Z,W).then((J)=>{N0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!0,result:J})},(J)=>{N0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!1,error:J instanceof Error?J.message:String(J)})})},onHttpRequest:(X,Z)=>C1?n0.handleHttpRequest(X,Z):!1,onHttpUpgrade:(X,Z,W)=>C1?n0.handleUpgrade(X,Z,W):!1,onWarmupRun:(X,Z,W)=>{(async()=>{if(await W3(),!M1)return{status:"retryable",error:"agent host is not ready"};if(Z.ideate)return lX({boardId:Z.boardId,userId:W,frontendSessionId:X,surface:Z.ideate.surface,runtimeConfigId:Z.ideate.runtimeConfigId,modelId:Z.ideate.modelId});return m4({cardId:Z.cardId,boardId:Z.boardId,userId:W,frontendSessionId:X})})().then((J)=>{if(!Z.warmupId)return;N0(X,{type:"warmup_result",warmupId:Z.warmupId,cardId:Z.cardId,...J})})},onDisconnect:(X,Z)=>{n0.closeFrontendSession(X),g4(X);for(let W of Z)_X(W);E("bridge.frontend_disconnected",{frontendSessionId:X,activeRuns:Z.length}),Y3(X).catch((W)=>{console.warn(`[ideawave-cli] failed to evict sessions for ${X}:`,W instanceof Error?W.message:String(W))}),console.log(`[ideawave-cli] browser session ${X} disconnected`)}});n0.setPort(S0.port);console.log(`[ideawave-cli] browser bridge listening on ${S0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var M8=!1;for(let X of["SIGINT","SIGTERM"])process.once(X,()=>{if(M8)return;M8=!0,D4(),(async()=>{await n0.close(),await p4(),await S0?.close().catch(()=>{return}),process.exit(0)})()});
1073
+ ${W}`),X.destroy()}function rW(X,Z){return new Promise((W,J)=>{let K=(j)=>{X.off("listening",V),J(j)},V=()=>{X.off("error",K);let j=X.address();if(!j||typeof j==="string"){J(Error("Failed to read CLI bridge server address"));return}W(j.port)};X.once("error",K),X.once("listening",V),X.listen(Z,"127.0.0.1")})}function W8(X){return new Promise((Z,W)=>{X.close((J)=>{if(J)W(J);else Z()})})}async function V8(X,Z=sX()){let W=new Map,J=new Map,K=X.maxMessageSize??IW,V=!1,j=(P)=>{let O=J.get(P);if(O)clearTimeout(O);J.delete(P)},U=(P)=>{J.delete(P);let{activeRunIds:O}=X.registry.disconnect(P);X.onDisconnect(P,O)},F=(P,O)=>{let M={type:"cli_status",connected:!0,runtime:X.runtime,mcpReady:X.mcpReady(),error:O,capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()};if(P){let h=W.get(P);if(h)o0(h,M);return}for(let h of W.values())o0(h,M)},w=(P,O)=>{let M=O.sessionId.trim(),h=O.userId.trim();if(!M||!h){o0(P,{type:"cli_status",connected:!1,runtime:X.runtime,mcpReady:X.mcpReady(),error:"Missing frontend session or user id"}),P.close();return}j(M);let N=W.get(M);if(N&&N!==P)N.close();P.data.frontendSessionId=M,W.set(M,P),X.registry.register({frontendSessionId:M,userId:h,tools:O.tools,send:(g)=>o0(P,g)}),F(M),X.onToolMetadata?.(M)},q=(P,O)=>{let M=X.registry.getUserId(P);if(!M)return;switch(O.type){case"bridge_ping":{let h=W.get(P);if(h)o0(h,{type:"bridge_pong"});break}case"tool_metadata":X.registry.setMetadata(P,O.tools),X.onToolMetadata?.(P);break;case"tool_result":X.registry.handleToolResult(P,O);break;case"run_turn":E("bridge.run_received",{runId:O.run.runId,cardId:O.run.cardId,frontendSessionId:P}),X.registry.markRunActive(P,O.run.runId,O.run.cardId),X.onRunTurn(P,{...O.run,frontendSessionId:P,userId:M});break;case"cancel_run":if(X.registry.ownsRun(P,O.runId))X.onCancelRun(P,O.runId);break;case"runtime_rpc":X.onRuntimeRpc(P,O);break;case"browser_rpc":X.onBrowserRpc?.(P,W.get(P)?.data.frontendOrigin??"",O);break;case"warmup_run":X.onWarmupRun(P,{...O,frontendSessionId:P},M);break;default:break}},v=(P,O)=>{let M=h2(P.headers.origin),h=rX(M),N={Vary:"Origin"};if(h&&M)N["Access-Control-Allow-Origin"]=M,N["Access-Control-Allow-Private-Network"]="true";if(P.method==="OPTIONS"){O.writeHead(204,{...N,"Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*","Access-Control-Max-Age":"600"}),O.end();return}if(P.method!=="GET"){O.writeHead(405,N),O.end();return}O.writeHead(200,{...N,"content-type":"application/json","cache-control":"no-store"}),O.end(JSON.stringify({ideawave:!0,runtime:X.runtime,mcpReady:X.mcpReady(),capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()}))},y=(P,O)=>{let M=h2(P.headers.origin),h=rX(M),N={Vary:"Origin"};if(h&&M)N["Access-Control-Allow-Origin"]=M,N["Access-Control-Allow-Private-Network"]="true";if(P.method==="OPTIONS"){O.writeHead(204,{...N,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"content-type","Access-Control-Max-Age":"600"}),O.end();return}if(!h){O.writeHead(403,N),O.end();return}if(P.method!=="POST"){O.writeHead(405,N),O.end();return}let g={...N,"content-type":"application/json"},C=(G,b)=>{O.writeHead(G,g),O.end(JSON.stringify(b))},m="",k=!1;P.on("data",(G)=>{if(m+=G.toString("utf8"),m.length>AW)k=!0,P.destroy()}),P.on("end",()=>{if(k){C(400,{ok:!1,error:"Request body too large"});return}let G;try{G=JSON.parse(m)}catch{C(400,{ok:!1,error:"Invalid JSON body"});return}let b=typeof G.url==="string"?G.url:"";if(!t4(b)){C(400,{ok:!1,error:"url must be an http(s) loopback or /static_boards/ page URL"});return}let R=(D,T)=>{let I=typeof D==="number"?D:Number.NaN;if(!Number.isFinite(I))return T;return Math.min(4000,Math.max(200,Math.round(I)))};e4({url:b,width:R(G.width,1440),height:R(G.height,900)}).then((D)=>C(200,{ok:!0,path:D.path,engine:D.engine})).catch((D)=>{let T=D instanceof y1?503:D instanceof C2?429:500;C(T,{ok:!1,...D instanceof y1?{installing:!0}:{},error:D instanceof Error?D.message:String(D)})})})};for(let P of Z){let O=kW((N,g)=>{(async()=>{let C=new URL(N.url??"/","http://127.0.0.1").pathname;if(C===s4){v(N,g);return}if(C===uW){y(N,g);return}if(await X.onHttpRequest?.(N,g))return;g.writeHead(404,{"content-type":"text/plain"}),g.end("IdeaWave CLI bridge")})().catch((C)=>{if(g.headersSent){g.destroy(C instanceof Error?C:void 0);return}g.writeHead(500,{"content-type":"text/plain"}),g.end("IdeaWave CLI bridge request failed")})}),M=new _W({noServer:!0,maxPayload:K}),h=(N)=>{if(N.idleTimer)clearTimeout(N.idleTimer);N.idleTimer=setTimeout(()=>{N.close()},SW),N.idleTimer.unref?.()};M.on("connection",(N,g)=>{let C=N;C.data={id:EW(),frontendSessionId:null,frontendOrigin:new URL(h2(g.headers.origin)??J8).origin},C.idleTimer=null,h(C),C.on("ping",()=>h(C)),C.on("pong",()=>h(C)),C.on("error",()=>{if(C.idleTimer)clearTimeout(C.idleTimer);C.close()}),C.on("message",(m)=>{h(C);let k=sW(m);if(K>0&&k.length>K)return;let G=v2(k);if(!G)return;let b=C.data.frontendSessionId;if(!b){if(G.type==="bridge_probe")o0(C,{type:"bridge_probe_ack",protocolVersion:G.protocolVersion});else if(G.type==="frontend_hello")w(C,G);return}q(b,G)}),C.on("close",()=>{if(C.idleTimer)clearTimeout(C.idleTimer);let m=C.data.frontendSessionId;if(!m)return;if(W.get(m)!==C)return;if(W.delete(m),j(m),V)return;J.set(m,setTimeout(()=>U(m),lW))})}),O.on("upgrade",(N,g,C)=>{let m=new URL(N.url??"/","http://127.0.0.1").pathname;if(X.onHttpUpgrade?.(N,g,C))return;if(m!==pX){Z8(g,404,"Not Found");return}if(!rX(h2(N.headers.origin))){Z8(g,403,"Forbidden");return}M.handleUpgrade(N,g,C,(k)=>{M.emit("connection",k,N)})});try{let N=await rW(O,P);return{url:`ws://127.0.0.1:${N}${pX}`,port:N,sendStatus:F,close:async()=>{V=!0;for(let g of J.values())clearTimeout(g);J.clear();for(let g of M.clients){let C=g;if(C.idleTimer)clearTimeout(C.idleTimer);C.close()}M.close(),await W8(O).catch(()=>{return})}}}catch(N){if(M.close(),await W8(O).catch(()=>{return}),N?.code==="EADDRINUSE")continue;throw N}}throw Error(`No free IdeaWave CLI bridge port found in ${Z[0]}-${Z.at(-1)}`)}import{lstat as UQ,readFile as FQ}from"node:fs/promises";import BQ from"node:os";import R1 from"node:path";import{Server as qQ}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as LQ,ListToolsRequestSchema as PQ}from"@modelcontextprotocol/sdk/types.js";var Y8=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"]),oW=["screenshot_board","inspect_diagram","ask_user_question","create_agent_card","append_user_message","spawn_child_agents"],nW=new Set(oW),AY=new Set([...Y8].filter((X)=>!nW.has(X)));var z8=new Set(["inspect_ideate_context","get_ideate_run_status","screenshot_ideate_context","submit_ideate_plan","revise_ideate_plan","set_ideate_placement","ask_ideate_question","complete_ideate_run","start_board_walkthrough"]),j8=new Set(["inspect_ideate_context","get_ideate_run_status","get_ideate_worker_context","screenshot_ideate_context","get_board","list_nodes","list_edges","inspect_node","inspect_board_region","inspect_diagram","list_context_sources","read_context_card","read_context_file","read_context_image","list_context_folder","get_board_wiki","search_board","inspect_neighbors","read_diagram_guide","inspect_browser","locate_browser_element","list_agent_cards","get_card_messages","inspect_table","get_table_schema","read_table","query_table","export_table_csv","start_board_walkthrough","ideate_create_note","ideate_create_code","ideate_create_shape","ideate_create_browser","ideate_add_browser_note","ideate_add_board_callout","ideate_create_diagram","ideate_create_edge","ideate_update_note","ideate_update_code","ideate_update_shape","ideate_update_diagram","ideate_update_edge","ideate_delete_node","ideate_delete_edge"]),tW=new Set([...z8,...j8].filter((X)=>X.startsWith("ideate_")||X.includes("ideate_")));function H8(X,Z){if(Z==="full")return!tW.has(X);if(Z==="read")return Y8.has(X);if(Z==="ideate-coordinator")return z8.has(X);return j8.has(X)}import{randomUUID as XQ}from"node:crypto";import{createServer as ZQ}from"node:http";import{StreamableHTTPServerTransport as WQ}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as B8}from"@modelcontextprotocol/sdk/types.js";var w8=new Set(["127.0.0.1","localhost","[::1]","::1"]);function eW(X){let Z=X.trim();if(Z.length===0)return null;if(Z.startsWith("[")){let V=Z.indexOf("]");if(V===-1)return null;let j=Z.slice(0,V+1),U=Z.slice(V+1);if(U.length===0)return{host:j,port:null};if(!U.startsWith(":"))return null;let F=Number(U.slice(1));if(!Number.isInteger(F)||F<=0||F>65535)return null;return{host:j,port:F}}let W=Z.lastIndexOf(":");if(W===-1)return{host:Z,port:null};let J=Z.slice(W+1),K=Number(J);if(!Number.isInteger(K)||K<=0||K>65535)return{host:Z,port:null};return{host:Z.slice(0,W),port:K}}function U8(X){return w8.has(X)||w8.has(X.toLowerCase())}function F8(X,Z){let W=X.headers.host;if(typeof W!=="string")return{ok:!1,status:403,reason:"missing-host"};let J=eW(W);if(!J)return{ok:!1,status:403,reason:"bad-host"};if(!U8(J.host))return{ok:!1,status:403,reason:"non-loopback-host"};if(J.port!==null&&J.port!==Z)return{ok:!1,status:403,reason:"host-port-mismatch"};let K=X.headers.origin;if(typeof K==="string"&&K.length>0){if(K!=="null"){let V;try{V=new URL(K)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!U8(V.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var q8="/mcp",QQ=43274,P8=16777216,JQ=1800000,KQ=300000,L8=200,VQ=-32700,M0=-32600,oX=-32603;function Y0(X,Z,W,J,K){X.statusCode=Z,X.setHeader("content-type","application/json"),X.end(JSON.stringify({jsonrpc:"2.0",error:{code:W,message:J,...K?{data:K}:{}},id:null}))}class nX extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class tX extends Error{constructor(){super(`body exceeds ${P8} bytes`);this.name="BodyTooLargeError"}}async function YQ(X){if(X.method&&X.method!=="POST")return;let Z=X.headers["content-type"];if(typeof Z==="string"&&Z.trim().length>0){if(!Z.toLowerCase().includes("application/json"))throw new nX}let W=0,J=[];for await(let V of X){let j=typeof V==="string"?Buffer.from(V):V;if(W+=j.byteLength,W>P8)throw new tX;J.push(j)}if(J.length===0)return;let K=Buffer.concat(J).toString("utf8");if(K.length===0)return;return JSON.parse(K)}function zQ(X){if(Array.isArray(X))return X.some(B8);return B8(X)}function jQ(X){if(typeof X==="number")return X;let Z=process.env.IDEAWAVE_MCP_PORT;if(Z&&Z.trim().length>0){let W=Number(Z);if(Number.isInteger(W)&&W>=0&&W<65536)return W}return QQ}async function HQ(X,Z){let W=(K)=>new Promise((V,j)=>{let U=(w)=>{X.off("listening",F),j(w)},F=()=>{X.off("error",U),V()};X.once("error",U),X.once("listening",F),X.listen(K,"127.0.0.1")});try{await W(Z)}catch(K){if(K.code!=="EADDRINUSE"||Z===0)throw K;console.warn(`[mcp] port ${Z} in use, falling back to an OS-assigned port; external CLIs will need to re-paste the install command from Settings → External agents`),await W(0)}let J=X.address();if(J==null||typeof J==="string")throw Error("[mcp] failed to read bound address");return J.port}function wQ(X,Z){if(Z&&typeof Z==="object"&&!Array.isArray(Z)){let J=Z.params;if(J&&typeof J==="object"&&!Array.isArray(J)){let K=J.clientInfo;if(K&&typeof K==="object"&&!Array.isArray(K)){let V=K.name;if(typeof V==="string"&&V.trim().length>0)return V.trim()}}}let W=X.headers["user-agent"];if(typeof W==="string"&&W.trim().length>0)return W.trim();return null}async function x8(X){let Z=new Map,W=0;function J(w){let q=Z.get(w);if(q)q.lastActivity=Date.now()}async function K(w,q){Z.delete(w),await q.transport.close().catch(()=>{return})}async function V(){let w=null,q=1/0;for(let[v,y]of Z)if(y.lastActivity<q)q=y.lastActivity,w=v;if(w!==null){let v=Z.get(w);if(v)console.warn(`[mcp] session cap of ${L8} reached; evicting ${w}`),await K(w,v)}}let j=setInterval(()=>{let w=Date.now()-JQ;for(let[q,v]of Z)if(v.lastActivity<w)console.log(`[mcp] sweeping idle session ${q}`),K(q,v)},KQ);j.unref?.();let U=ZQ((w,q)=>{(async()=>{let v;try{v=new URL(w.url??"/","http://127.0.0.1").pathname}catch{Y0(q,400,M0,"bad-url");return}if(v!==q8){Y0(q,404,M0,"not-found");return}let y=w.method??"POST";if(y!=="POST"&&y!=="GET"&&y!=="DELETE"){q.setHeader("Allow","GET, POST, DELETE"),Y0(q,405,M0,"method-not-allowed");return}let P=F8(w,W);if(!P.ok){Y0(q,P.status,M0,"forbidden",{reason:P.reason});return}let O=w.headers["mcp-session-id"],M=typeof O==="string"?O:void 0;if(y==="GET"||y==="DELETE"){if(!M||!Z.has(M)){Y0(q,400,M0,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let g=Z.get(M).transport;J(M);try{await g.handleRequest(w,q)}catch(C){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",C),!q.headersSent)Y0(q,500,oX,"internal")}return}let h;try{h=await YQ(w)}catch(g){if(g instanceof nX){Y0(q,415,M0,"expected-application-json");return}if(g instanceof tX){Y0(q,413,M0,"body-too-large");return}Y0(q,400,VQ,"invalid-json");return}let N;if(M&&Z.has(M))N=Z.get(M).transport,J(M);else if(!M&&h!==void 0&&zQ(h)){let g=w.headers["x-ideawave-user-id"],C=typeof g==="string"&&g.trim().length>0?g.trim():null,m=w.headers["x-ideawave-frontend-session-id"],k=typeof m==="string"&&m.trim().length>0?m.trim():null,G=w.headers["x-ideawave-tool-surface"],b=typeof G==="string"?G.trim():"full",R=b==="read"||b==="ideate-coordinator"||b==="ideate-worker"?b:"full",D=w.headers["x-ideawave-images-supported"],T=typeof D==="string"&&D.trim()==="1",I=w.headers["x-ideawave-card-id"],q0=typeof I==="string"&&I.trim().length>0?I.trim():null,S=w.headers["x-ideawave-execution-kind"],s=w.headers["x-ideawave-execution-id"],c=typeof S==="string"?S.trim():"",Z0=typeof s==="string"?s.trim():"",N1=Z0&&new Set(["agent-card","ideate-coordinator","ideate-step","ideate-participant","board-insight","board-auto-title"]).has(c)?{kind:c,id:Z0}:null,$2=w.headers["x-ideawave-ideate-claims"],G2=null;if(typeof $2==="string"&&$2.length>0)try{G2=JSON.parse($2)}catch{G2=null}let m2=w.headers["x-ideawave-board-id"],g8=typeof m2==="string"&&m2.trim().length>0?m2.trim():null,E2=w.headers["x-ideawave-run-folder"],D8=typeof E2==="string"&&E2.trim().length>0?E2.trim():null,k2=w.headers["x-ideawave-pool-session-id"],$8=typeof k2==="string"&&k2.trim().length>0?k2.trim():null,G8=wQ(w,h);if(Z.size>=L8)await V();let _2=null,D0=new WQ({sessionIdGenerator:()=>XQ(),onsessioninitialized:(l0)=>{_2=l0,Z.set(l0,{transport:D0,lastActivity:Date.now()})},onsessionclosed:(l0)=>{Z.delete(l0)}});D0.onclose=()=>{if(D0.sessionId)Z.delete(D0.sessionId)};try{await X.buildServer({userId:C,frontendSessionId:k,boardId:g8,toolSurface:R,imagesSupported:T,cardId:q0,executionTarget:N1,ideateClaims:G2,runFolder:D8,poolSessionId:$8,clientHint:G8}).connect(D0)}catch(l0){if(console.error("[mcp] buildServer/connect failed",l0),_2)Z.delete(_2);await D0.close().catch(()=>{return}),Y0(q,500,oX,"server-init-failed");return}N=D0}else{Y0(q,400,M0,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await N.handleRequest(w,q,h)}catch(g){if(console.error("[mcp] transport.handleRequest threw",g),!q.headersSent)Y0(q,500,oX,"internal")}})().catch((v)=>{console.error("[mcp] unhandled request handler error:",v)})});return W=await HQ(U,jQ(X.port)),{url:`http://127.0.0.1:${W}${q8}`,port:W,close:async()=>{clearInterval(j);for(let w of Z.values())await w.transport.close().catch(()=>{return});Z.clear(),await new Promise((w)=>U.close(()=>w()))}}}var xQ={name:"ideawave-board",version:"1.0.0"},M2="list_run_folder",N2="read_run_folder_file",y8=new Set(["inspect_diagram"]);function O8(X,Z){if(X===M2||X===N2)return Z!=="ideate-coordinator";return H8(X,Z)}var bQ=[{name:M2,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:N2,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 eX(X){return{content:[{type:"text",text:X}]}}function vQ(X){return eX(JSON.stringify(X,null,2))}function b8(X){return{...eX(X),isError:!0}}async function yQ(X,Z){if(!Z||X.isError)return X;let W=X.content.find((V)=>V.type==="text");if(!W)return X;let J;try{let V=JSON.parse(W.text);if(typeof V.path!=="string")return X;J=R1.resolve(V.path)}catch{return X}let K=R1.resolve(R1.join(BQ.tmpdir(),"ideawave-screenshots"));if(R1.dirname(J)!==K||!/^board-[a-z0-9-]+\.png$/i.test(R1.basename(J)))return X;try{if(!(await UQ(J)).isFile())return X;let j=await FQ(J);if(j.byteLength<1024||j.byteLength>26214400||!j.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return X;return{...X,content:[...X.content,{type:"image",data:j.toString("base64"),mimeType:"image/png"}]}}catch{return X}}function OQ(X,Z,W="full",J=!1){return X.getMetadata(Z).filter((K)=>{let V=F2(K.name);if(!O8(V,W))return!1;if(!J&&y8.has(V))return!1;return!0}).map((K)=>({name:K.name,description:K.description,inputSchema:K.inputSchema}))}function RQ(X,Z,W={}){let J=OQ(X,Z,W.toolSurface??"full",W.imagesSupported??!1);return W.includeRunFolderTools?[...J,...bQ]:J}function v8(X,Z){if(!X||typeof X!=="object"||Array.isArray(X))return null;let W=X[Z];return typeof W==="string"?W:null}async function fQ(X,Z,W){if(W&&W.trim().length>0)return W.trim();if(!X||!Z)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await C0({boardId:X,cardId:Z})).runFolder}async function CQ(X){let Z=await fQ(X.boardId,X.cardId,X.runFolder);if(X.name===M2){let W=v8(X.args,"path")??"",J=await K4(Z,W);return vQ(J)}if(X.name===N2){let W=v8(X.args,"path");if(!W)return b8("read_run_folder_file requires a path.");return eX(await U2(Z,W))}return b8(`Unknown local tool "${X.name}"`)}function hQ(X,Z,W,J,K,V="full",j=!1,U=null,F=null,w=null){let q=new qQ(xQ,{capabilities:{tools:{}}}),v=()=>{let P=h4(w);return{cardId:P?.cardId??J,executionTarget:P?.executionTarget??U,ideateClaims:P?.ideateClaims??F}},y=async()=>{if(j)return!0;let P=v().cardId;if(N4(P))return!0;if(W&&P)try{return(await C0({boardId:W,cardId:P})).adapter.supportsImages===!0}catch{return!1}return!1};return q.setRequestHandler(PQ,async()=>({tools:RQ(X,Z,{includeRunFolderTools:V!=="ideate-coordinator"&&Boolean(K||W&&J),toolSurface:V,imagesSupported:await y()})})),q.setRequestHandler(LQ,async(P)=>{let{name:O,arguments:M}=P.params,h=F2(O),N=Date.now(),g=v();E("mcp.tool_call_received",{frontendSessionId:Z,cardId:g.cardId,toolName:h});try{if(!O8(h,V))throw Error(`Tool "${O}" is not available on the ${V} surface`);if(h===M2||h===N2)return await CQ({name:h,args:M,boardId:W,cardId:g.cardId,runFolder:K});if(y8.has(h)&&!await y())throw Error(`Tool "${O}" requires a runtime that supports image input`);let C=await X.callTool(Z,h,M??{},g.ideateClaims?.runId,g.cardId??void 0,g.executionTarget??void 0,g.ideateClaims??void 0,V);if(E("mcp.tool_result_returned",{frontendSessionId:Z,cardId:g.cardId,toolName:h,elapsedMs:Date.now()-N}),C&&typeof C==="object"&&Array.isArray(C.content)){let m=C;return h==="screenshot_board"||h==="screenshot_ideate_context"?await yQ(m,await y()):m}return{content:[{type:"text",text:typeof C==="string"?C:JSON.stringify(C)}]}}catch(C){return E("mcp.tool_result_returned",{frontendSessionId:Z,cardId:g.cardId,toolName:h,elapsedMs:Date.now()-N,hasError:!0}),{content:[{type:"text",text:C instanceof Error?C.message:"Tool call failed"}],isError:!0}}}),q}function R8(X,Z){return x8({buildServer:(W)=>hQ(X,W.frontendSessionId,W.boardId,W.cardId,W.runFolder,W.toolSurface,W.imagesSupported,W.executionTarget,W.ideateClaims,W.poolSessionId),port:Z})}import g2 from"node:fs/promises";import X3 from"node:os";import D2 from"node:path";function f8(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function MQ(){let[X,Z]=await Promise.all([J0(),p3()]),W=X.globalDefaultConfigId?X.runtimes.find((J)=>J.id===X.globalDefaultConfigId)??null:null;return{runtimes:X.runtimes,globalDefaultConfigId:X.globalDefaultConfigId,globalDefaultEffective:W?{runFolder:W.runFolder??X3.homedir(),modelId:W.defaultModelId??null,configValues:W.defaultConfigValues??{}}:null,knownAdapters:T0().map((J)=>({id:J.id,displayName:J.displayName})),readiness:Z}}async function NQ(X){try{let Z=await C0({boardId:X.boardId,cardId:X.cardId});return{resolved:{configId:Z.entry.id,adapterId:Z.entry.kind==="registered"?Z.entry.adapterId:null,displayName:Z.entry.displayName,runFolder:Z.runFolder,modelId:Z.modelId,configValues:Z.configValues}}}catch(Z){if(Z instanceof x0)return{resolved:null};throw Z}}async function gQ(X){return z0((Z)=>{let W=Z.runtimes.find((V)=>V.kind==="registered"&&V.adapterId===X.adapterId);if(W)return W;let J=T0().find((V)=>V.id===X.adapterId);if(!J)throw Error(`Unknown adapterId: ${X.adapterId}`);let K={id:f8(),kind:"registered",adapterId:X.adapterId,displayName:J.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(K),K})}async function DQ(X){return z0((Z)=>{let W={id:f8(),kind:"custom",displayName:X.displayName,command:X.command,args:X.args,env:X.env,runFolder:X.runFolder,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(W),W})}async function $Q(X){await z0((Z)=>{if(Z.runtimes=Z.runtimes.filter((W)=>W.id!==X.runtimeConfigId),Z.globalDefaultConfigId===X.runtimeConfigId)Z.globalDefaultConfigId=null;for(let W of Object.keys(Z.boardOverrides))if(Z.boardOverrides[W].runtimeConfigId===X.runtimeConfigId)delete Z.boardOverrides[W];for(let W of Object.keys(Z.cardOverrides))if(Z.cardOverrides[W].runtimeConfigId===X.runtimeConfigId)delete Z.cardOverrides[W]})}async function GQ(X){await z0((Z)=>{let W=Z.runtimes.find((J)=>J.id===X.runtimeConfigId);if(!W)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);if(Z.globalDefaultConfigId=X.runtimeConfigId,X.runFolder!==void 0)W.runFolder=X.runFolder;if(X.modelId!==void 0)W.defaultModelId=X.modelId;if(X.configValues!==void 0)W.defaultConfigValues=X.configValues})}async function mQ(X){X.boardId,await z0((Z)=>{if(X.runtimeConfigId===null){delete Z.cardOverrides[X.cardId];return}if(!Z.runtimes.some((K)=>K.id===X.runtimeConfigId))throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let J=Z.cardOverrides[X.cardId];Z.cardOverrides[X.cardId]={runtimeConfigId:X.runtimeConfigId,runFolder:X.runFolder!==void 0?X.runFolder:J?.runFolder??null,modelId:X.modelId!==void 0?X.modelId:J?.modelId??null,configValues:X.configValues!==void 0?X.configValues:J?.configValues??{}}})}async function EQ(X){let W=(await J0()).runtimes.find((j)=>j.id===X.runtimeConfigId);if(!W)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let J=U0(W),K=await J.resolveSpawnConfig(W),V=W.runFolder??X3.homedir();try{let j=await O4({spawn:{...K,cwd:V},modelId:X.modelId??W.defaultModelId??null,configValues:X.configValues??W.defaultConfigValues??{}}),U=H2({adapterId:J.id,models:j.models,currentModelId:j.currentModelId}),F=new Date().toISOString();return await z0((w)=>{let q=w.runtimes.find((v)=>v.id===X.runtimeConfigId);if(q)q.discoveredModels=U,q.discoveredConfigOptions=j.configOptions,q.discoveredAt=F}),{ok:!0,models:U,configOptions:j.configOptions,currentModelId:j.currentModelId}}catch(j){if(j instanceof u0)throw Error(`${j.message}${J.authHint?` ${J.authHint}`:""}`);if(j instanceof l||j instanceof w0)throw Error(j.message);throw j}}async function kQ(X){let Z=X3.homedir(),W=X.path?.trim()?X.path.trim():Z,J=D2.resolve(W),K=!0;try{if(!(await g2.stat(J)).isDirectory())J=D2.dirname(J)}catch{K=!1,J=Z}let V=[];try{V=(await g2.readdir(J,{withFileTypes:!0})).filter((F)=>F.isDirectory()&&!F.name.startsWith(".")).map((F)=>({name:F.name,path:D2.join(J,F.name)})).sort((F,w)=>F.name.localeCompare(w.name))}catch{V=[]}let j=D2.dirname(J);return{path:J,parent:j===J?null:j,home:Z,exists:K,entries:V}}var C8={list:MQ,getEffectiveForCard:NQ,registerRegistered:gQ,registerCustom:DQ,unregister:$Q,setUserDefault:GQ,setCardOverride:mQ,refreshModels:EQ,browseFolder:kQ};var _Q=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function IQ(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function h8(){try{let X=await J0();if(X.globalDefaultConfigId){if(X.runtimes.some((W)=>W.id===X.globalDefaultConfigId))return X.globalDefaultConfigId}for(let Z of _Q){if((await s3(Z.id))?.status!=="ready")continue;let J=null;if(await z0((K)=>{if(K.globalDefaultConfigId){if(K.runtimes.some((U)=>U.id===K.globalDefaultConfigId)){J=K.globalDefaultConfigId;return}}let V=K.runtimes.find((j)=>j.kind==="registered"&&j.adapterId===Z.id);if(!V){let j={id:IQ(),kind:"registered",adapterId:Z.id,displayName:Z.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};K.runtimes.push(j),V=j}K.globalDefaultConfigId=V.id,J=V.id}),J)return console.log(`[ideawave-cli] using agent runtime: ${Z.displayName}`),J}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 SQ=240000;function lQ(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class Z3{sessions=new Map;createCallId;toolCallTimeoutMs;constructor(X={}){this.createCallId=X.createCallId??lQ,this.toolCallTimeoutMs=X.toolCallTimeoutMs??SQ}register(X){let Z=this.sessions.get(X.frontendSessionId);if(Z){if(Z.userId!==X.userId)this.rejectPending(Z,"frontend session user changed"),Z.activeRunIds.clear();this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:Z.pendingToolCalls,activeRunIds:Z.activeRunIds,activeRunCardIds:Z.activeRunCardIds});return}this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:new Map,activeRunIds:new Set,activeRunCardIds:new Map})}disconnect(X,Z="frontend session disconnected"){let W=this.sessions.get(X);if(!W)return{activeRunIds:[]};return this.sessions.delete(X),this.rejectPending(W,Z),{activeRunIds:Array.from(W.activeRunIds)}}sessionCount(){return this.sessions.size}has(X){return this.sessions.has(X)}getUserId(X){return this.sessions.get(X)?.userId??null}setMetadata(X,Z){let W=this.sessions.get(X);if(W)W.tools=Z}getMetadata(X){if(!X)return[];return this.sessions.get(X)?.tools??[]}sendToSession(X,Z){let W=this.sessions.get(X);if(!W)return!1;return W.send(Z),!0}callTool(X,Z,W,J,K,V,j,U){if(!X)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let F=this.sessions.get(X);if(!F)return Promise.reject(Error(`Frontend session ${X} is not connected`));let w=this.createCallId();return new Promise((q,v)=>{let y=J??(K?this.getActiveRunIdForCard(F,K):this.getSoleActiveRunId(F)),P=K??(y?F.activeRunCardIds.get(y):void 0),O=Date.now(),M=setTimeout(()=>{F.pendingToolCalls.delete(w),E("tool_queue.timeout",{frontendSessionId:X,runId:y,cardId:P,callId:w,toolName:Z,elapsedMs:Date.now()-O,queueDepth:F.pendingToolCalls.size}),v(Error(`Tool "${Z}" timed out waiting for the frontend`))},this.toolCallTimeoutMs);F.pendingToolCalls.set(w,{resolve:q,reject:v,timer:M,name:Z,runId:y??null,cardId:P??null,startedAt:O}),E("tool_queue.forwarded_to_browser",{frontendSessionId:X,runId:y,cardId:P,callId:w,toolName:Z,queueDepth:F.pendingToolCalls.size}),F.send({type:"tool_call",callId:w,name:Z,args:W,...y?{runId:y}:{},...P?{cardId:P}:{},...V?{executionTarget:V}:{},...j?{ideateClaims:j}:{},...U?{toolSurface:U}:{}})})}handleToolResult(X,Z){let W=this.sessions.get(X);if(!W)return;let J=W.pendingToolCalls.get(Z.callId);if(!J)return;W.pendingToolCalls.delete(Z.callId),clearTimeout(J.timer);let K=Z.ok?"":Z.error??Z.result?.content?.find(({text:U})=>typeof U==="string")?.text??"Tool execution failed",V=/network|fetch|connection|offline/i.test(K)?"network":/timeout|timed out/i.test(K)?"timeout":/unauthor|forbidden|permission/i.test(K)?"authorization":/conflict|revision|lease|fence/i.test(K)?"conflict":/invalid|missing|required|schema/i.test(K)?"validation":"unknown";if(E("tool_queue.result_received",{frontendSessionId:X,runId:J.runId,cardId:J.cardId,callId:Z.callId,toolName:J.name,elapsedMs:Date.now()-J.startedAt,queueDepth:W.pendingToolCalls.size,ok:Z.ok,...Z.ok?{}:{errorCategory:V}}),Z.ok){J.resolve(Z.result);return}let j=Z.result;if(j&&typeof j==="object"&&Array.isArray(j.content)){J.resolve({...j,isError:!0});return}J.reject(Error(Z.error??"Tool execution failed"))}markRunActive(X,Z,W){let J=this.sessions.get(X);if(!J)return;if(J.activeRunIds.add(Z),W)J.activeRunCardIds.set(Z,W)}markRunSettled(X,Z){let W=this.sessions.get(X);if(!W)return;W.activeRunIds.delete(Z),W.activeRunCardIds.delete(Z)}ownsRun(X,Z){return this.sessions.get(X)?.activeRunIds.has(Z)??!1}rejectPending(X,Z){for(let W of X.pendingToolCalls.values())clearTimeout(W.timer),E("tool_queue.rejected",{frontendSessionId:X.frontendSessionId,runId:W.runId,cardId:W.cardId,toolName:W.name,elapsedMs:Date.now()-W.startedAt}),W.reject(Error(Z));X.pendingToolCalls.clear()}getSoleActiveRunId(X){return X.activeRunIds.size===1?X.activeRunIds.values().next().value:void 0}getActiveRunIdForCard(X,Z){let W=[...X.activeRunCardIds.entries()].filter(([J,K])=>X.activeRunIds.has(J)&&K===Z).map(([J])=>J);return W.length===1?W[0]:void 0}}function N8(){return"0.0.96".trim()?"0.0.96":"dev"}var uQ=process.argv.slice(2),Q3=X8(uQ,process.env);if(Q3.allowRailwayPrPreviews)process.env[O1]="1";var g0=Q3.cliArgs[0],{browserKitEnabled:C1,captureEngineEnabled:AQ}=Q3;if(g0==="--help"||g0==="-h"||g0==="help")console.log("ideawave — host the local bridge for a running ideawave.app session."),console.log(""),console.log("Usage:"),console.log(" ideawave Serve the browser bridge and MCP forwarder."),console.log(" ideawave --version Print the CLI version."),process.exit(0);if(g0==="--version"||g0==="-v"||g0==="version")console.log(N8()),process.exit(0);if(g0)console.error(`Unknown command: ${g0}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var h1=new Z3,S0=null,TQ=C1?{phase:"ready",message:"Local browser-kit proxy is ready"}:{phase:"idle"},n0=new j2;function N0(X,Z){h1.sendToSession(X,Z)}async function cQ(X,Z){try{let W=C8[Z.method],J=await W(Z.params);N0(X,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!0,result:J})}catch(W){N0(X,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!1,error:W instanceof Error?W.message:String(W)})}}var M1=!1,f1=null;async function W3(){if(M1)return;if(f1)return f1;return f1=(async()=>{try{let X=await R8(h1);U3({...X,requestedPort:X.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${X.url}`);try{await N3({onStatusChange:(Z)=>{if(r3(),S0?.sendStatus(),Z.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${Z.packageName}: ${Z.error??"unknown error"}`)}})}catch(Z){console.warn("[ideawave-cli] ACP bridge setup skipped:",Z instanceof Error?Z.message:String(Z))}await h8(),M1=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),S0?.sendStatus()}catch(X){console.error("[ideawave-cli] failed to start agent host:",X),S0?.sendStatus(void 0,X instanceof Error?X.message:String(X))}finally{f1=null}})(),f1}if(process.env.APP_ENV!=="development"){let X=await K8();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(AQ)a4().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"}`)});S0=await V8({registry:h1,runtime:null,mcpReady:()=>M1,capabilities:l4(C1),cliVersion:N8(),browserRuntimeStatus:()=>TQ,onToolMetadata:(X)=>{console.log(`[ideawave-cli] session ${X} advertised ${h1.getMetadata(X).length} tools`),W3()},onRunTurn:(X,Z)=>{console.log(`[ideawave-cli] running agent turn for card ${Z.cardId} (session ${X})`),(async()=>{if(await W3(),!M1){N0(X,{type:"run_settled",runId:Z.runId,cardId:Z.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"IdeaWave CLI agent host is not ready",partialText:null}});return}await G4(Z,(W)=>N0(X,W))})().catch(()=>{return}).finally(()=>h1.markRunSettled(X,Z.runId))},onCancelRun:(X,Z)=>{_X(Z)},onRuntimeRpc:(X,Z)=>{cQ(X,Z)},onBrowserRpc:(X,Z,W)=>{if(!C1){N0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!1,error:"The development browser-kit proxy is not enabled"});return}n0.handleRpc(X,Z,W).then((J)=>{N0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!0,result:J})},(J)=>{N0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!1,error:J instanceof Error?J.message:String(J)})})},onHttpRequest:(X,Z)=>C1?n0.handleHttpRequest(X,Z):!1,onHttpUpgrade:(X,Z,W)=>C1?n0.handleUpgrade(X,Z,W):!1,onWarmupRun:(X,Z,W)=>{(async()=>{if(await W3(),!M1)return{status:"retryable",error:"agent host is not ready"};if(Z.ideate)return lX({boardId:Z.boardId,userId:W,frontendSessionId:X,surface:Z.ideate.surface,runtimeConfigId:Z.ideate.runtimeConfigId,modelId:Z.ideate.modelId});return m4({cardId:Z.cardId,boardId:Z.boardId,userId:W,frontendSessionId:X})})().then((J)=>{if(!Z.warmupId)return;N0(X,{type:"warmup_result",warmupId:Z.warmupId,cardId:Z.cardId,...J})})},onDisconnect:(X,Z)=>{n0.closeFrontendSession(X),g4(X);for(let W of Z)_X(W);E("bridge.frontend_disconnected",{frontendSessionId:X,activeRuns:Z.length}),Y3(X).catch((W)=>{console.warn(`[ideawave-cli] failed to evict sessions for ${X}:`,W instanceof Error?W.message:String(W))}),console.log(`[ideawave-cli] browser session ${X} disconnected`)}});n0.setPort(S0.port);console.log(`[ideawave-cli] browser bridge listening on ${S0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var M8=!1;for(let X of["SIGINT","SIGTERM"])process.once(X,()=>{if(M8)return;M8=!0,D4(),(async()=>{await n0.close(),await p4(),await S0?.close().catch(()=>{return}),process.exit(0)})()});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ideawave",
3
- "version": "0.0.95",
3
+ "version": "0.0.96",
4
4
  "description": "IdeaWave CLI",
5
5
  "type": "module",
6
6
  "bin": {