ideawave 0.0.30 → 0.0.32

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
@@ -15,7 +15,7 @@ ${Q}`:null].filter(Boolean).join(`
15
15
 
16
16
  `));return u($)}function s$($,Z){if(!Z)return $;if(!$)return Z;if($===Z||$.endsWith(Z))return $;if(Z.startsWith($))return Z;return r(`${$}
17
17
 
18
- ${Z}`)}function Q$($){if(!Array.isArray($))return null;let Z=$.flatMap((X)=>{if(!X||typeof X!=="object")return[];let J=X;if(typeof J.path!=="string"||!J.path.trim())return[];let Q=typeof J.line==="number"?`:${J.line}`:"";return[`${J.path}${Q}`]});return Z.length>0?Z.slice(0,5):null}function o$($){let{ctx:Z,appendText:X,appendToolActivity:J}=$,Q=$.flushIntervalMs??s2,j="",W="",G=0,Y=null,z={},H=new Map,V=(F)=>{if(H.set(F.toolCallId,F),!J)return;J({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,entry:F}).catch((K)=>{console.warn("[streamAdapter] appendToolActivity failed",K)})},D=(F)=>{let K=`${Z.runId}:thought`,k=H.get(K);if(!k||k.status!=="running")return;V({...k,status:"completed",completedAt:k.completedAt??F})},q=(F)=>{for(let K of H.values()){if(K.status!=="running"||K.rawTitle.toLowerCase()!=="toolsearch")continue;V({...K,status:"completed",completedAt:K.completedAt??F})}},C=(F)=>{for(let K of Array.from(H.values())){if(K.status!=="running")continue;if(K.kind==="thought"||K.rawTitle==="agent_thought")continue;V({...K,status:"completed",completedAt:K.completedAt??F})}},N="",M=0,B=null,L=null,A=(F)=>{if(F===N)return;N=F,M=Date.now(),X({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,text:F}).catch((K)=>{console.warn("[streamAdapter] appendText failed",K)})},O=()=>{if(B!==null)clearTimeout(B),B=null;if(L!==null){let F=L;L=null,A(F)}},_=(F)=>{let K=Date.now()-M;if(K>=Q&&B===null){A(F);return}if(L=F,B===null){let k=Math.max(0,Q-K);B=setTimeout(()=>{B=null,O()},k)}};return{onSessionUpdate:async(F)=>{let K=F.update;switch(z[K.sessionUpdate]=(z[K.sessionUpdate]??0)+1,K.sessionUpdate){case"agent_message_chunk":{let k=new Date().toISOString();if(D(k),K.content.type==="text")j+=K.content.text,_(j);else{let w=`agent_message_chunk:${K.content.type}`;z[w]=(z[w]??0)+1}return}case"agent_thought_chunk":{if(K.content.type!=="text")return;W+=K.content.text;let k=new Date().toISOString(),w=`${Z.runId}:thought`,x=H.get(w);V({toolCallId:w,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:x?.startedAt??k,completedAt:null,contentPreview:r(W.trim())});return}case"user_message_chunk":return;case"tool_call":{G+=1;let k=i$(K.title),w=$$(K.status),x=new Date().toISOString();D(x),q(x),V({toolCallId:K.toolCallId,rawTitle:k,title:X$(k,K.rawInput),kind:Z$(K.kind),status:w,startedAt:x,completedAt:w==="running"?null:x,inputPreview:u(K.rawInput),outputPreview:J$(K.rawOutput),contentPreview:P0(K.content),locations:Q$(K.locations)});return}case"tool_call_update":{let k=H.get(K.toolCallId);if(!k){let Z0=i$(K.title),m=$$(K.status),l=new Date().toISOString();V({toolCallId:K.toolCallId,rawTitle:Z0,title:X$(Z0,K.rawInput),kind:Z$(K.kind),status:m,startedAt:l,completedAt:m==="running"?null:l,inputPreview:u(K.rawInput),outputPreview:J$(K.rawOutput),contentPreview:P0(K.content),locations:Q$(K.locations)});return}let w=K.status===void 0||K.status===null?k.status:$$(K.status),x=typeof K.title==="string"&&K.title.trim().length>0?K.title:k.rawTitle,R=typeof K.title==="string"&&K.title.trim().length>0,b=w==="running"?k.completedAt:k.completedAt??new Date().toISOString(),S=K.content===void 0?k.contentPreview:s$(k.contentPreview,P0(K.content)),n=K.rawOutput===void 0?k.outputPreview:s$(k.outputPreview,J$(K.rawOutput));V({...k,rawTitle:x,title:R?X$(x,K.rawInput):k.title,kind:K.kind===void 0?k.kind:Z$(K.kind),status:w,completedAt:b,inputPreview:K.rawInput===void 0?k.inputPreview:u(K.rawInput),outputPreview:n,contentPreview:S,locations:K.locations===void 0?k.locations:Q$(K.locations)});return}case"plan":Y=K.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>j,getToolCallCount:()=>G,getLatestPlan:()=>Y,getUpdateTypeCounts:()=>({...z}),flush:(F)=>{let K=new Date().toISOString();if(D(K),F?.completeOpenToolCalls)C(K);O()}}}var Y0=1,t$=-32000;function r$($){if($.awaitingInput)return!1;return $.nowMs-$.lastUpdateMs>$.windowMs}function X1($){if(!$||typeof $!=="object")return!1;return $.code===t$}var e2=300000,$3=5000;function J1(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.30".trim()?"0.0.30":"dev"}}function Q1($){if($===Y0)return;throw new P(`Unsupported ACP protocol version ${$}; expected ${Y0}`)}function j1($){return t2.toWeb($)}function W1($){return r2.toWeb($)}function j$($){return $!==null&&typeof $==="object"}function Z3($){if(!Array.isArray($))return[];let Z=[];for(let X of $){if(!j$(X))continue;if(typeof X.group==="string"&&Array.isArray(X.options)){let J=typeof X.name==="string"?X.name:X.group;for(let Q of X.options){if(!j$(Q))continue;if(typeof Q.value!=="string"||typeof Q.name!=="string")continue;Z.push({value:Q.value,name:Q.name,description:typeof Q.description==="string"?Q.description:null,group:X.group,groupName:J})}continue}if(typeof X.value!=="string"||typeof X.name!=="string")continue;Z.push({value:X.value,name:X.name,description:typeof X.description==="string"?X.description:null,group:null,groupName:null})}return Z}function X3($){if(!j$($))return null;if(typeof $.id!=="string"||typeof $.name!=="string")return null;let Z=typeof $.category==="string"?$.category:null,X=typeof $.description==="string"?$.description:null;if($.type==="select"){let J=typeof $.currentValue==="string"?$.currentValue:null;return{id:$.id,name:$.name,category:Z,description:X,type:"select",currentValue:J,options:Z3($.options)}}if($.type==="boolean"){let J=typeof $.currentValue==="boolean"?$.currentValue:typeof $.value==="boolean"?$.value:null;return{id:$.id,name:$.name,category:Z,description:X,type:"boolean",currentValue:J,options:[]}}return null}function W$($){let Z=($.configOptions??[]).map(X3).filter((G)=>G!==null),X=Z.find((G)=>G.type==="select"&&G.category==="model")??Z.find((G)=>G.type==="select"&&G.id==="model")??null,J=X?.options.map((G)=>({id:G.value,name:G.name,description:G.description??null})),Q=$.models?.availableModels?.map((G)=>({id:G.modelId,name:G.name??null,description:G.description??null})),j=J&&J.length>0?J:Q&&Q.length>0?Q:null,W=(typeof X?.currentValue==="string"?X.currentValue:null)??$.models?.currentModelId??null;return{models:j,currentModelId:W,configOptions:Z,modelConfigId:X?.id??null}}function J3($,Z){let X=[];if($.trim())X.push({type:"text",text:$});for(let J of Z)if(J.content.trim())X.push({type:"text",text:J.content});return X}function Q3($){if(typeof $.value==="boolean")return{sessionId:$.sessionId,configId:$.configId,type:"boolean",value:$.value};return{sessionId:$.sessionId,configId:$.configId,value:$.value}}function j3($,Z){let X=W$({configOptions:Z.configOptions});return{models:X.models??$.models,currentModelId:X.currentModelId??$.currentModelId,configOptions:X.configOptions,modelConfigId:X.modelConfigId??$.modelConfigId}}async function e$($){try{let Z=await $.conn.setSessionConfigOption(Q3({sessionId:$.sessionId,configId:$.configId,value:$.value}));return j3($.metadata,Z)}catch(Z){return console.warn(`[acp] setSessionConfigOption(${$.label}) failed; using agent default.`,Z instanceof Error?Z.message:Z),$.metadata}}async function K$($){let Z=r0($.spawn),X=[],J=0,Q=4096;Z.stderr.on("data",(x)=>{X.push(x),J+=x.length;while(J>Q*2&&X.length>1){let R=X.shift();if(R)J-=R.length}});let j=()=>{let x=Buffer.concat(X).toString("utf8");return x.length>Q?x.slice(-Q):x},W=d$($.spawn.cwd),G={current:null},Y={at:Date.now()},z=W1(Z.stdin),H=j1(Z.stdout),V=Z1(z,H),q=new $1((x)=>({requestPermission:async(R)=>{let b=R.options,S=b?.find((n)=>n.kind==="allow_once")??b?.find((n)=>n.kind==="allow_always");if(S)return{outcome:{outcome:"selected",optionId:S.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(R)=>{Y.at=Date.now();let b=G.current;if(b)await b.onSessionUpdate(R)},readTextFile:W.readTextFile}),V),C=()=>Z.kill();if($.signal)$.signal.addEventListener("abort",C);let N=()=>{if($.signal)$.signal.removeEventListener("abort",C)},M=async(x,R)=>{if(N(),Z.kill(),X1(x))throw new X0(x.message??"Authentication required",R);if(x instanceof Error&&x.message==="ACP connection closed"){if($.signal?.aborted)throw new P("ACP session cancelled: abort signal received");let b=await Promise.race([Z.processCrashed,Z.waitForExit,new Promise((S)=>setTimeout(()=>S({stderr:""}),500))]);throw new P(`Runtime process exited before completion: ${b.stderr?.trim()??""}`)}throw x},B;try{B=await q.initialize({protocolVersion:Y0,clientCapabilities:t0,clientInfo:J1()})}catch(x){throw await M(x,[]),Error("unreachable")}try{Q1(B.protocolVersion)}catch(x){throw N(),Z.kill(),x}let L=B.authMethods?.map((x)=>x.id)??[],A;try{A=await q.newSession({cwd:$.spawn.cwd,mcpServers:$.mcpServers??[]})}catch(x){throw await M(x,L),Error("unreachable")}let O=A.sessionId,_=W$(A),F=$.modelId??null;if(F&&F!==_.currentModelId)if(_.modelConfigId){let x=_;if(_=await e$({conn:q,sessionId:O,configId:_.modelConfigId,value:F,metadata:_,label:`${_.modelConfigId}=${F}`}),_===x)try{await q.unstable_setSessionModel({sessionId:O,modelId:F})}catch(R){console.warn(`[acp] setSessionModel(${F}) failed; using agent default.`,R instanceof Error?R.message:R)}}else try{await q.unstable_setSessionModel({sessionId:O,modelId:F})}catch(x){console.warn(`[acp] setSessionModel(${F}) failed; using agent default.`,x instanceof Error?x.message:x)}for(let[x,R]of Object.entries($.configValues??{}).sort(([b],[S])=>b.localeCompare(S))){if(x===_.modelConfigId)continue;if(!_.configOptions.some((b)=>b.id===x))continue;_=await e$({conn:q,sessionId:O,configId:x,value:R,metadata:_,label:`${x}=${String(R)}`})}N();let K=!1,k=async()=>{if(K)return;K=!0,Z.kill(),await Promise.race([Z.waitForExit,new Promise((x)=>setTimeout(x,2000))])},w=!1;return Z.processCrashed.then(()=>{w=!0}),{sessionId:O,availableModels:_.models,currentModelId:_.currentModelId,availableConfigOptions:_.configOptions,isAlive:()=>!K&&!w,dispose:k,prompt:(x)=>W3({proc:Z,conn:q,sessionId:O,activeAdapter:G,lastUpdate:Y,collectStderrTail:j},x)}}async function W3($,Z){let{proc:X,conn:J,sessionId:Q,activeAdapter:j,lastUpdate:W}=$,G={boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId},Y=o$({ctx:G,appendText:Z.appendText,appendToolActivity:Z.appendToolActivity});j.current=Y,W.at=Date.now();let z=!1,H=null,V=()=>X.kill();Z.signal.addEventListener("abort",V);try{let D=async()=>{let M=Z.heartbeatMs??e2,B=Math.min($3,Math.max(50,Math.floor(M/2)));H=setInterval(()=>{let A=Z.isAwaitingInput?.()??!1;if(A){W.at=Date.now();return}if(r$({nowMs:Date.now(),lastUpdateMs:W.at,windowMs:M,awaitingInput:A}))z=!0,J.cancel({sessionId:Q}).catch(()=>{return}),X.kill()},B);let L=J3(Z.prompt.systemPrompt,Z.prompt.messages);await J.prompt({sessionId:Q,prompt:L}),Y.flush({completeOpenToolCalls:!0})},q=X.waitForExit.then((M)=>({kind:"exited",exit:M})),C=D().then(()=>({kind:"ok"})).catch(async(M)=>{if(M instanceof Error&&M.message==="ACP connection closed")return{kind:"crashed",exit:await Promise.race([X.processCrashed,X.waitForExit])};throw M}),N=await Promise.race([C,X.processCrashed.then((M)=>({kind:"crashed",exit:M})),q]);if(z)throw new o;if(N.kind==="crashed")throw new P(`Runtime process exited before completion: ${N.exit.stderr.trim()}`);if(N.kind==="exited"){if(Z.signal.aborted)throw new P("ACP session cancelled: abort signal received");if(z)throw new o;throw new P(`Runtime process exited unexpectedly: ${N.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:Y.getFinalText(),toolCallsExecuted:Y.getToolCallCount(),stderrTail:$.collectStderrTail(),updateTypeCounts:Y.getUpdateTypeCounts()}}finally{if(H!==null)clearInterval(H);Z.signal.removeEventListener("abort",V),Y.flush(),j.current=null}}var K3=30000;async function K1($){let Z=r0($.spawn),X=W1(Z.stdin),J=j1(Z.stdout),Q=Z1(X,J),W=new $1((z)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),Q),G=()=>Z.kill();if($.signal)$.signal.addEventListener("abort",G);let Y=null;try{let z=(async()=>{let V=await W.initialize({protocolVersion:Y0,clientCapabilities:t0,clientInfo:J1()});Q1(V.protocolVersion);let D=V.authMethods?.map((B)=>B.id)??[],q;try{q=await W.newSession({cwd:$.spawn.cwd,mcpServers:[]})}catch(B){if(X1(B))throw new X0(B.message??"Authentication required",D);throw B}let C=W$(q),N=C.models??[],M=C.currentModelId;return W.cancel({sessionId:q.sessionId}).catch(()=>{return}),{models:N,configOptions:C.configOptions,currentModelId:M}})(),H=new Promise((V,D)=>{Y=setTimeout(()=>{D(new o)},K3)});return await Promise.race([z,H])}catch(z){if(z instanceof Error&&z.message==="ACP connection closed"){if($.signal?.aborted)throw new P("ACP model discovery cancelled: abort signal received");throw new P("Runtime process exited during model discovery.")}throw z}finally{if(Y)clearTimeout(Y);if($.signal)$.signal.removeEventListener("abort",G);Z.kill()}}var E=new Map,p=null;function A0($){$.then((Z)=>Z.dispose()).catch(()=>{return})}function V3(){if(p!==null)return;p=setInterval(()=>{let $=Date.now();for(let[Z,X]of E){if(X.inUse)continue;if($-X.lastUsed<600000)continue;E.delete(Z),A0(X.sessionPromise)}if(E.size===0&&p!==null)clearInterval(p),p=null},60000),p.unref?.()}function Y3(){if(E.size<200)return;let $=null,Z=1/0;for(let[J,Q]of E){if(Q.inUse)continue;if(Q.lastUsed>=Z)continue;$=J,Z=Q.lastUsed}if(!$)return;let X=E.get($);if(!X)return;E.delete($),A0(X.sessionPromise)}function V$($,Z,X){return`${$}:${Z}:${X}`}async function Y$($){let Z=E.get($.key);if(Z)if(Z.fingerprint===$.fingerprint){Z.inUse=!0,Z.lastUsed=Date.now();try{let J=await Z.sessionPromise;if(J.isAlive())return J}catch{}E.delete($.key)}else E.delete($.key),A0(Z.sessionPromise);let X=$.open();Y3(),E.set($.key,{key:$.key,fingerprint:$.fingerprint,sessionPromise:X,lastUsed:Date.now(),inUse:!0}),V3();try{return await X}catch(J){throw E.delete($.key),J}}function M$($,Z=!1){let X=E.get($);if(!X)return;if(Z){E.delete($),A0(X.sessionPromise);return}X.inUse=!1,X.lastUsed=Date.now()}async function M3(){let $=Array.from(E.values());if(E.clear(),p!==null)clearInterval(p),p=null;await Promise.all($.map((Z)=>Z.sessionPromise.then((X)=>X.dispose()).catch(()=>{return})))}function G$($){let Z=Object.entries($.configValues??{}),X=Z.length>0?JSON.stringify(Object.fromEntries(Z.sort(([J],[Q])=>J.localeCompare(Q)))):"";return[$.adapterId,$.configId??"",$.modelId??"",X,$.mcpUrl??"",$.runFolder??"",$.toolSurface??"full"].join(" ")}var V1=!1;function G3(){if(V1)return;V1=!0;let $=()=>{M3()};process.once("beforeExit",$),process.once("SIGTERM",$),process.once("SIGINT",$)}G3();import M0 from"node:fs/promises";import U3 from"node:path";import{z as U}from"zod";var Y1=U.object({id:U.string(),name:U.string().nullable().default(null),description:U.string().nullable().default(null)}),z1=U.union([U.string(),U.boolean()]),z3=U.object({value:U.string(),name:U.string(),description:U.string().nullable().default(null),group:U.string().nullable().default(null),groupName:U.string().nullable().default(null)}),M1=U.object({id:U.string(),name:U.string(),category:U.string().nullable().default(null),description:U.string().nullable().default(null),type:U.enum(["select","boolean"]),currentValue:z1.nullable().default(null),options:U.array(z3).default([])}),z$=U.record(U.string(),z1).default({}),H3=U.discriminatedUnion("kind",[U.object({id:U.string(),kind:U.literal("registered"),adapterId:U.enum(["claude-code","opencode","codex","copilot"]),displayName:U.string(),runFolder:U.string().nullable(),defaultModelId:U.string().nullable().default(null),defaultConfigValues:z$,discoveredModels:U.array(Y1).default([]),discoveredConfigOptions:U.array(M1).default([]),discoveredAt:U.string().nullable().default(null)}),U.object({id:U.string(),kind:U.literal("custom"),displayName:U.string(),command:U.string(),args:U.array(U.string()),env:U.record(U.string(),U.string()),runFolder:U.string().nullable(),defaultModelId:U.string().nullable().default(null),defaultConfigValues:z$,discoveredModels:U.array(Y1).default([]),discoveredConfigOptions:U.array(M1).default([]),discoveredAt:U.string().nullable().default(null)})]),G1=U.object({runtimeConfigId:U.string(),runFolder:U.string().nullable(),modelId:U.string().nullable().default(null),configValues:z$}),_0=U.object({version:U.literal(1),globalDefaultConfigId:U.string().nullable(),runtimes:U.array(H3),boardOverrides:U.record(U.string(),G1).default({}),cardOverrides:U.record(U.string(),G1).default({})});import D3 from"node:os";import f0 from"node:path";function B3(){let $=D3.homedir();switch(process.platform){case"win32":return process.env.APPDATA??f0.join($,"AppData","Roaming");case"darwin":return f0.join($,"Library","Application Support");default:return process.env.XDG_CONFIG_HOME??f0.join($,".config")}}function O0(){let $=process.env.IDEAWAVE_RUNTIME_CONFIG_PATH;if($)return $;return f0.join(B3(),"ideawave","runtimes.json")}var N3={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},H1=new Map;function q3($){return H1.get($)??Promise.resolve()}function x3($,Z){H1.set($,Z)}async function v($){let Z=$??O0(),X;try{X=await M0.readFile(Z,"utf-8")}catch(Q){if(Q.code==="ENOENT")return structuredClone(N3);throw Q}return _0.parse(JSON.parse(X))}async function h($,Z){let X=Z??O0(),J=q3(X).then(async()=>{let Q=await v(X),j=structuredClone(Q),W=await $(j);return await F3(j,X),W});return x3(X,J.catch(()=>{return})),J}async function F3($,Z){let X=Z??O0(),J=U3.dirname(X);await M0.mkdir(J,{recursive:!0});let Q=`${X}.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`,j=JSON.stringify($,null,2);await M0.writeFile(Q,j,"utf-8");try{await M0.rename(Q,X)}catch(W){throw await M0.unlink(Q).catch(()=>{return}),W}}import P3 from"node:fs/promises";import w0 from"node:os";var D1="claude",H$="@agentclientprotocol/claude-agent-acp",B1=["claude-agent-acp","claude-code-acp"],U1="Install Claude Code from https://github.com/anthropics/claude-code",N1={id:"claude-code",displayName:"Claude Code",kind:"registered",resolveSpawnConfig:async()=>{if(!await f(D1))throw new P(`Claude Code CLI not found. ${U1}`);let Z=q0(H$);if(Z)return{command:Z.command,args:Z.args,env:y(Z.env)};let X=J0(H$),J=X?.status==="installing";for(let j of B1){let W=await f(j);if(W&&!J&&X?.status!=="failed")return{command:W,args:[],env:y()}}let Q=X?.status==="failed"?`Claude Code ACP bridge install failed. ${X.error??"Restart IdeaWave CLI so it can warm the pinned bridge again."}`:"Claude Code ACP bridge is not ready. Keep IdeaWave CLI running and retry in a moment.";throw new P(Q)},checkReadiness:async()=>{if(!await f(D1))return{status:"not_installed",detail:U1};let Z=J0(H$);if(Z?.status==="ready")return{status:"ready"};if(Z?.status==="installing")return{status:"not_running",detail:"Installing Claude Code ACP bridge..."};if(Z?.status==="failed")return{status:"not_running",detail:Z.error??"Claude Code ACP bridge install failed. Restart IdeaWave CLI so it can warm the pinned bridge again."};for(let X of B1)if(await f(X))return{status:"ready"};return{status:"not_running",detail:"Installing Claude Code ACP bridge..."}},authHint:"Run `claude login` (or set ANTHROPIC_API_KEY)."};var q1="codex",D$="@zed-industries/codex-acp",x1="codex-acp",F1="Install Codex CLI from https://developers.openai.com/codex/cli",k1={id:"codex",displayName:"Codex",kind:"registered",resolveSpawnConfig:async()=>{if(!await f(q1))throw new P(`Codex CLI not found. ${F1}`);let Z=q0(D$);if(Z)return{command:Z.command,args:Z.args,env:y(Z.env)};let X=J0(D$),J=X?.status==="installing",Q=await f(x1);if(Q&&!J&&X?.status!=="failed")return{command:Q,args:[],env:y()};let j=X?.status==="failed"?`Codex ACP bridge install failed. ${X.error??"Restart IdeaWave CLI so it can warm the pinned bridge again."}`:"Codex ACP bridge is not ready. Keep IdeaWave CLI running and retry in a moment.";throw new P(j)},checkReadiness:async()=>{if(!await f(q1))return{status:"not_installed",detail:F1};let Z=J0(D$);if(Z?.status==="ready")return{status:"ready"};if(Z?.status==="installing")return{status:"not_running",detail:"Installing Codex ACP bridge..."};if(Z?.status==="failed")return{status:"not_running",detail:Z.error??"Codex ACP bridge install failed. Restart IdeaWave CLI so it can warm the pinned bridge again."};if(await f(x1))return{status:"ready"};return{status:"not_running",detail:"Installing Codex ACP bridge..."}},authHint:"Run `codex login` (or set OPENAI_API_KEY)."};var C1="copilot",P1="copilot-acp",L1="npm i -g @github/copilot",A1={id:"copilot",displayName:"GitHub Copilot",kind:"registered",resolveSpawnConfig:async()=>{let $=await f(C1);if($)return{command:$,args:["--acp"],env:y()};let Z=await f(P1);if(Z)return{command:Z,args:[],env:y()};throw new P(`Copilot not installed. Run: ${L1}`)},checkReadiness:async()=>{if(await f(C1))return{status:"ready"};if(await f(P1))return{status:"ready"};return{status:"not_installed",detail:L1}},authHint:"Run `gh auth login` (or `copilot login`)."};import k3 from"node:fs/promises";function C3($){return $.startsWith("/")||/^[a-zA-Z]:[\\/]/.test($)}async function _1($){if(C3($))try{return await k3.access($),!0}catch{return!1}return await f($)!==null}var f1={id:"custom",displayName:"Custom ACP",kind:"custom",resolveSpawnConfig:async($)=>{if($.kind!=="custom")throw new P("customAdapter received non-custom entry");if(!await _1($.command))throw new P(`custom: command "${$.command}" not found`);return{command:$.command,args:$.args,env:y($.env)}},checkReadiness:async($)=>{if($.kind!=="custom")return{status:"unknown"};return await _1($.command)?{status:"ready"}:{status:"not_installed"}}};var O1="opencode",w1="Install OpenCode from https://opencode.ai",R1={id:"opencode",displayName:"OpenCode",kind:"registered",resolveSpawnConfig:async()=>{let $=await f(O1);if(!$)throw new P(`OpenCode not installed. ${w1}`);return{command:$,args:["acp"],env:y()}},checkReadiness:async()=>{if(!await f(O1))return{status:"not_installed",detail:w1};return{status:"ready"}},authHint:"Run `opencode auth login <provider>` (or set the provider's API-key env var)."};var b1={"claude-code":N1,opencode:R1,codex:k1,copilot:A1};function c($){if($.kind==="custom")return f1;let Z=b1[$.adapterId];if(!Z)throw Error(`Unknown registered adapter: ${$.adapterId}`);return Z}function Q0(){return Object.values(b1)}async function E1($){let Z={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},X;try{X=await P3.readFile($,"utf-8")}catch(J){if(J.code==="ENOENT")return structuredClone(Z);throw J}return _0.parse(JSON.parse(X))}function B$($,Z,X){return{...$.defaultConfigValues??{},...Z?.configValues??{},...X?.configValues??{}}}async function e($){let Z=$.configPath?await E1($.configPath):await v(),X=$.cardId?Z.cardOverrides[$.cardId]:void 0;if(X?.runtimeConfigId){let Q=Z.runtimes.find((j)=>j.id===X.runtimeConfigId);if(Q)return{entry:Q,adapter:c(Q),runFolder:X.runFolder??Q.runFolder??w0.homedir(),modelId:X.modelId??Q.defaultModelId??null,configValues:B$(Q,void 0,X)}}let J=Z.boardOverrides[$.boardId];if(J?.runtimeConfigId){let Q=Z.runtimes.find((j)=>j.id===J.runtimeConfigId);if(Q)return{entry:Q,adapter:c(Q),runFolder:J.runFolder??Q.runFolder??w0.homedir(),modelId:J.modelId??Q.defaultModelId??null,configValues:B$(Q,J)}}if(Z.globalDefaultConfigId){let Q=Z.runtimes.find((j)=>j.id===Z.globalDefaultConfigId);if(Q)return{entry:Q,adapter:c(Q),runFolder:X?.runFolder??J?.runFolder??Q.runFolder??w0.homedir(),modelId:X?.modelId??J?.modelId??Q.defaultModelId??null,configValues:B$(Q,J,X)}}throw new s}async function T1($,Z={}){let J=(Z.configPath?await E1(Z.configPath):await v()).runtimes.find((Q)=>Q.id===$);if(!J)return null;return{entry:J,adapter:c(J),runFolder:J.runFolder??w0.homedir(),modelId:Z.modelId??J.defaultModelId??null,configValues:{...J.defaultConfigValues??{},...Z.configValues??{}}}}var $0=new Map,U$=new Set;function N$($){$0.get($)?.controller.abort()}function y1($){for(let[Z,X]of $0){if(X.frontendSessionId!==$)continue;X.controller.abort(),$0.delete(Z)}}function I1(){for(let $ of $0.values())$.controller.abort();$0.clear()}function v1($,Z,X,J){if((!Z.availableModels||Z.availableModels.length===0)&&Z.availableConfigOptions.length===0)return;h((Q)=>{let j=Q.runtimes.find((W)=>W.id===$);if(j){if(Z.availableModels&&Z.availableModels.length>0)j.discoveredModels=x0({adapterId:X,models:Z.availableModels,currentModelId:Z.currentModelId??J});if(Z.availableConfigOptions.length>0)j.discoveredConfigOptions=Z.availableConfigOptions}}).catch(()=>{return})}function L3($,Z){return`${$}
18
+ ${Z}`)}function Q$($){if(!Array.isArray($))return null;let Z=$.flatMap((X)=>{if(!X||typeof X!=="object")return[];let J=X;if(typeof J.path!=="string"||!J.path.trim())return[];let Q=typeof J.line==="number"?`:${J.line}`:"";return[`${J.path}${Q}`]});return Z.length>0?Z.slice(0,5):null}function o$($){let{ctx:Z,appendText:X,appendToolActivity:J}=$,Q=$.flushIntervalMs??s2,j="",W="",G=0,Y=null,z={},H=new Map,V=(F)=>{if(H.set(F.toolCallId,F),!J)return;J({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,entry:F}).catch((K)=>{console.warn("[streamAdapter] appendToolActivity failed",K)})},D=(F)=>{let K=`${Z.runId}:thought`,k=H.get(K);if(!k||k.status!=="running")return;V({...k,status:"completed",completedAt:k.completedAt??F})},q=(F)=>{for(let K of H.values()){if(K.status!=="running"||K.rawTitle.toLowerCase()!=="toolsearch")continue;V({...K,status:"completed",completedAt:K.completedAt??F})}},C=(F)=>{for(let K of Array.from(H.values())){if(K.status!=="running")continue;if(K.kind==="thought"||K.rawTitle==="agent_thought")continue;V({...K,status:"completed",completedAt:K.completedAt??F})}},N="",M=0,B=null,L=null,A=(F)=>{if(F===N)return;N=F,M=Date.now(),X({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,text:F}).catch((K)=>{console.warn("[streamAdapter] appendText failed",K)})},O=()=>{if(B!==null)clearTimeout(B),B=null;if(L!==null){let F=L;L=null,A(F)}},_=(F)=>{let K=Date.now()-M;if(K>=Q&&B===null){A(F);return}if(L=F,B===null){let k=Math.max(0,Q-K);B=setTimeout(()=>{B=null,O()},k)}};return{onSessionUpdate:async(F)=>{let K=F.update;switch(z[K.sessionUpdate]=(z[K.sessionUpdate]??0)+1,K.sessionUpdate){case"agent_message_chunk":{let k=new Date().toISOString();if(D(k),K.content.type==="text")j+=K.content.text,_(j);else{let w=`agent_message_chunk:${K.content.type}`;z[w]=(z[w]??0)+1}return}case"agent_thought_chunk":{if(K.content.type!=="text")return;W+=K.content.text;let k=new Date().toISOString(),w=`${Z.runId}:thought`,x=H.get(w);V({toolCallId:w,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:x?.startedAt??k,completedAt:null,contentPreview:r(W.trim())});return}case"user_message_chunk":return;case"tool_call":{G+=1;let k=i$(K.title),w=$$(K.status),x=new Date().toISOString();D(x),q(x),V({toolCallId:K.toolCallId,rawTitle:k,title:X$(k,K.rawInput),kind:Z$(K.kind),status:w,startedAt:x,completedAt:w==="running"?null:x,inputPreview:u(K.rawInput),outputPreview:J$(K.rawOutput),contentPreview:P0(K.content),locations:Q$(K.locations)});return}case"tool_call_update":{let k=H.get(K.toolCallId);if(!k){let Z0=i$(K.title),m=$$(K.status),l=new Date().toISOString();V({toolCallId:K.toolCallId,rawTitle:Z0,title:X$(Z0,K.rawInput),kind:Z$(K.kind),status:m,startedAt:l,completedAt:m==="running"?null:l,inputPreview:u(K.rawInput),outputPreview:J$(K.rawOutput),contentPreview:P0(K.content),locations:Q$(K.locations)});return}let w=K.status===void 0||K.status===null?k.status:$$(K.status),x=typeof K.title==="string"&&K.title.trim().length>0?K.title:k.rawTitle,R=typeof K.title==="string"&&K.title.trim().length>0,b=w==="running"?k.completedAt:k.completedAt??new Date().toISOString(),S=K.content===void 0?k.contentPreview:s$(k.contentPreview,P0(K.content)),n=K.rawOutput===void 0?k.outputPreview:s$(k.outputPreview,J$(K.rawOutput));V({...k,rawTitle:x,title:R?X$(x,K.rawInput):k.title,kind:K.kind===void 0?k.kind:Z$(K.kind),status:w,completedAt:b,inputPreview:K.rawInput===void 0?k.inputPreview:u(K.rawInput),outputPreview:n,contentPreview:S,locations:K.locations===void 0?k.locations:Q$(K.locations)});return}case"plan":Y=K.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>j,getToolCallCount:()=>G,getLatestPlan:()=>Y,getUpdateTypeCounts:()=>({...z}),flush:(F)=>{let K=new Date().toISOString();if(D(K),F?.completeOpenToolCalls)C(K);O()}}}var Y0=1,t$=-32000;function r$($){if($.awaitingInput)return!1;return $.nowMs-$.lastUpdateMs>$.windowMs}function X1($){if(!$||typeof $!=="object")return!1;return $.code===t$}var e2=300000,$3=5000;function J1(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.32".trim()?"0.0.32":"dev"}}function Q1($){if($===Y0)return;throw new P(`Unsupported ACP protocol version ${$}; expected ${Y0}`)}function j1($){return t2.toWeb($)}function W1($){return r2.toWeb($)}function j$($){return $!==null&&typeof $==="object"}function Z3($){if(!Array.isArray($))return[];let Z=[];for(let X of $){if(!j$(X))continue;if(typeof X.group==="string"&&Array.isArray(X.options)){let J=typeof X.name==="string"?X.name:X.group;for(let Q of X.options){if(!j$(Q))continue;if(typeof Q.value!=="string"||typeof Q.name!=="string")continue;Z.push({value:Q.value,name:Q.name,description:typeof Q.description==="string"?Q.description:null,group:X.group,groupName:J})}continue}if(typeof X.value!=="string"||typeof X.name!=="string")continue;Z.push({value:X.value,name:X.name,description:typeof X.description==="string"?X.description:null,group:null,groupName:null})}return Z}function X3($){if(!j$($))return null;if(typeof $.id!=="string"||typeof $.name!=="string")return null;let Z=typeof $.category==="string"?$.category:null,X=typeof $.description==="string"?$.description:null;if($.type==="select"){let J=typeof $.currentValue==="string"?$.currentValue:null;return{id:$.id,name:$.name,category:Z,description:X,type:"select",currentValue:J,options:Z3($.options)}}if($.type==="boolean"){let J=typeof $.currentValue==="boolean"?$.currentValue:typeof $.value==="boolean"?$.value:null;return{id:$.id,name:$.name,category:Z,description:X,type:"boolean",currentValue:J,options:[]}}return null}function W$($){let Z=($.configOptions??[]).map(X3).filter((G)=>G!==null),X=Z.find((G)=>G.type==="select"&&G.category==="model")??Z.find((G)=>G.type==="select"&&G.id==="model")??null,J=X?.options.map((G)=>({id:G.value,name:G.name,description:G.description??null})),Q=$.models?.availableModels?.map((G)=>({id:G.modelId,name:G.name??null,description:G.description??null})),j=J&&J.length>0?J:Q&&Q.length>0?Q:null,W=(typeof X?.currentValue==="string"?X.currentValue:null)??$.models?.currentModelId??null;return{models:j,currentModelId:W,configOptions:Z,modelConfigId:X?.id??null}}function J3($,Z){let X=[];if($.trim())X.push({type:"text",text:$});for(let J of Z)if(J.content.trim())X.push({type:"text",text:J.content});return X}function Q3($){if(typeof $.value==="boolean")return{sessionId:$.sessionId,configId:$.configId,type:"boolean",value:$.value};return{sessionId:$.sessionId,configId:$.configId,value:$.value}}function j3($,Z){let X=W$({configOptions:Z.configOptions});return{models:X.models??$.models,currentModelId:X.currentModelId??$.currentModelId,configOptions:X.configOptions,modelConfigId:X.modelConfigId??$.modelConfigId}}async function e$($){try{let Z=await $.conn.setSessionConfigOption(Q3({sessionId:$.sessionId,configId:$.configId,value:$.value}));return j3($.metadata,Z)}catch(Z){return console.warn(`[acp] setSessionConfigOption(${$.label}) failed; using agent default.`,Z instanceof Error?Z.message:Z),$.metadata}}async function K$($){let Z=r0($.spawn),X=[],J=0,Q=4096;Z.stderr.on("data",(x)=>{X.push(x),J+=x.length;while(J>Q*2&&X.length>1){let R=X.shift();if(R)J-=R.length}});let j=()=>{let x=Buffer.concat(X).toString("utf8");return x.length>Q?x.slice(-Q):x},W=d$($.spawn.cwd),G={current:null},Y={at:Date.now()},z=W1(Z.stdin),H=j1(Z.stdout),V=Z1(z,H),q=new $1((x)=>({requestPermission:async(R)=>{let b=R.options,S=b?.find((n)=>n.kind==="allow_once")??b?.find((n)=>n.kind==="allow_always");if(S)return{outcome:{outcome:"selected",optionId:S.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(R)=>{Y.at=Date.now();let b=G.current;if(b)await b.onSessionUpdate(R)},readTextFile:W.readTextFile}),V),C=()=>Z.kill();if($.signal)$.signal.addEventListener("abort",C);let N=()=>{if($.signal)$.signal.removeEventListener("abort",C)},M=async(x,R)=>{if(N(),Z.kill(),X1(x))throw new X0(x.message??"Authentication required",R);if(x instanceof Error&&x.message==="ACP connection closed"){if($.signal?.aborted)throw new P("ACP session cancelled: abort signal received");let b=await Promise.race([Z.processCrashed,Z.waitForExit,new Promise((S)=>setTimeout(()=>S({stderr:""}),500))]);throw new P(`Runtime process exited before completion: ${b.stderr?.trim()??""}`)}throw x},B;try{B=await q.initialize({protocolVersion:Y0,clientCapabilities:t0,clientInfo:J1()})}catch(x){throw await M(x,[]),Error("unreachable")}try{Q1(B.protocolVersion)}catch(x){throw N(),Z.kill(),x}let L=B.authMethods?.map((x)=>x.id)??[],A;try{A=await q.newSession({cwd:$.spawn.cwd,mcpServers:$.mcpServers??[]})}catch(x){throw await M(x,L),Error("unreachable")}let O=A.sessionId,_=W$(A),F=$.modelId??null;if(F&&F!==_.currentModelId)if(_.modelConfigId){let x=_;if(_=await e$({conn:q,sessionId:O,configId:_.modelConfigId,value:F,metadata:_,label:`${_.modelConfigId}=${F}`}),_===x)try{await q.unstable_setSessionModel({sessionId:O,modelId:F})}catch(R){console.warn(`[acp] setSessionModel(${F}) failed; using agent default.`,R instanceof Error?R.message:R)}}else try{await q.unstable_setSessionModel({sessionId:O,modelId:F})}catch(x){console.warn(`[acp] setSessionModel(${F}) failed; using agent default.`,x instanceof Error?x.message:x)}for(let[x,R]of Object.entries($.configValues??{}).sort(([b],[S])=>b.localeCompare(S))){if(x===_.modelConfigId)continue;if(!_.configOptions.some((b)=>b.id===x))continue;_=await e$({conn:q,sessionId:O,configId:x,value:R,metadata:_,label:`${x}=${String(R)}`})}N();let K=!1,k=async()=>{if(K)return;K=!0,Z.kill(),await Promise.race([Z.waitForExit,new Promise((x)=>setTimeout(x,2000))])},w=!1;return Z.processCrashed.then(()=>{w=!0}),{sessionId:O,availableModels:_.models,currentModelId:_.currentModelId,availableConfigOptions:_.configOptions,isAlive:()=>!K&&!w,dispose:k,prompt:(x)=>W3({proc:Z,conn:q,sessionId:O,activeAdapter:G,lastUpdate:Y,collectStderrTail:j},x)}}async function W3($,Z){let{proc:X,conn:J,sessionId:Q,activeAdapter:j,lastUpdate:W}=$,G={boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId},Y=o$({ctx:G,appendText:Z.appendText,appendToolActivity:Z.appendToolActivity});j.current=Y,W.at=Date.now();let z=!1,H=null,V=()=>X.kill();Z.signal.addEventListener("abort",V);try{let D=async()=>{let M=Z.heartbeatMs??e2,B=Math.min($3,Math.max(50,Math.floor(M/2)));H=setInterval(()=>{let A=Z.isAwaitingInput?.()??!1;if(A){W.at=Date.now();return}if(r$({nowMs:Date.now(),lastUpdateMs:W.at,windowMs:M,awaitingInput:A}))z=!0,J.cancel({sessionId:Q}).catch(()=>{return}),X.kill()},B);let L=J3(Z.prompt.systemPrompt,Z.prompt.messages);await J.prompt({sessionId:Q,prompt:L}),Y.flush({completeOpenToolCalls:!0})},q=X.waitForExit.then((M)=>({kind:"exited",exit:M})),C=D().then(()=>({kind:"ok"})).catch(async(M)=>{if(M instanceof Error&&M.message==="ACP connection closed")return{kind:"crashed",exit:await Promise.race([X.processCrashed,X.waitForExit])};throw M}),N=await Promise.race([C,X.processCrashed.then((M)=>({kind:"crashed",exit:M})),q]);if(z)throw new o;if(N.kind==="crashed")throw new P(`Runtime process exited before completion: ${N.exit.stderr.trim()}`);if(N.kind==="exited"){if(Z.signal.aborted)throw new P("ACP session cancelled: abort signal received");if(z)throw new o;throw new P(`Runtime process exited unexpectedly: ${N.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:Y.getFinalText(),toolCallsExecuted:Y.getToolCallCount(),stderrTail:$.collectStderrTail(),updateTypeCounts:Y.getUpdateTypeCounts()}}finally{if(H!==null)clearInterval(H);Z.signal.removeEventListener("abort",V),Y.flush(),j.current=null}}var K3=30000;async function K1($){let Z=r0($.spawn),X=W1(Z.stdin),J=j1(Z.stdout),Q=Z1(X,J),W=new $1((z)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),Q),G=()=>Z.kill();if($.signal)$.signal.addEventListener("abort",G);let Y=null;try{let z=(async()=>{let V=await W.initialize({protocolVersion:Y0,clientCapabilities:t0,clientInfo:J1()});Q1(V.protocolVersion);let D=V.authMethods?.map((B)=>B.id)??[],q;try{q=await W.newSession({cwd:$.spawn.cwd,mcpServers:[]})}catch(B){if(X1(B))throw new X0(B.message??"Authentication required",D);throw B}let C=W$(q),N=C.models??[],M=C.currentModelId;return W.cancel({sessionId:q.sessionId}).catch(()=>{return}),{models:N,configOptions:C.configOptions,currentModelId:M}})(),H=new Promise((V,D)=>{Y=setTimeout(()=>{D(new o)},K3)});return await Promise.race([z,H])}catch(z){if(z instanceof Error&&z.message==="ACP connection closed"){if($.signal?.aborted)throw new P("ACP model discovery cancelled: abort signal received");throw new P("Runtime process exited during model discovery.")}throw z}finally{if(Y)clearTimeout(Y);if($.signal)$.signal.removeEventListener("abort",G);Z.kill()}}var E=new Map,p=null;function A0($){$.then((Z)=>Z.dispose()).catch(()=>{return})}function V3(){if(p!==null)return;p=setInterval(()=>{let $=Date.now();for(let[Z,X]of E){if(X.inUse)continue;if($-X.lastUsed<600000)continue;E.delete(Z),A0(X.sessionPromise)}if(E.size===0&&p!==null)clearInterval(p),p=null},60000),p.unref?.()}function Y3(){if(E.size<200)return;let $=null,Z=1/0;for(let[J,Q]of E){if(Q.inUse)continue;if(Q.lastUsed>=Z)continue;$=J,Z=Q.lastUsed}if(!$)return;let X=E.get($);if(!X)return;E.delete($),A0(X.sessionPromise)}function V$($,Z,X){return`${$}:${Z}:${X}`}async function Y$($){let Z=E.get($.key);if(Z)if(Z.fingerprint===$.fingerprint){Z.inUse=!0,Z.lastUsed=Date.now();try{let J=await Z.sessionPromise;if(J.isAlive())return J}catch{}E.delete($.key)}else E.delete($.key),A0(Z.sessionPromise);let X=$.open();Y3(),E.set($.key,{key:$.key,fingerprint:$.fingerprint,sessionPromise:X,lastUsed:Date.now(),inUse:!0}),V3();try{return await X}catch(J){throw E.delete($.key),J}}function M$($,Z=!1){let X=E.get($);if(!X)return;if(Z){E.delete($),A0(X.sessionPromise);return}X.inUse=!1,X.lastUsed=Date.now()}async function M3(){let $=Array.from(E.values());if(E.clear(),p!==null)clearInterval(p),p=null;await Promise.all($.map((Z)=>Z.sessionPromise.then((X)=>X.dispose()).catch(()=>{return})))}function G$($){let Z=Object.entries($.configValues??{}),X=Z.length>0?JSON.stringify(Object.fromEntries(Z.sort(([J],[Q])=>J.localeCompare(Q)))):"";return[$.adapterId,$.configId??"",$.modelId??"",X,$.mcpUrl??"",$.runFolder??"",$.toolSurface??"full"].join(" ")}var V1=!1;function G3(){if(V1)return;V1=!0;let $=()=>{M3()};process.once("beforeExit",$),process.once("SIGTERM",$),process.once("SIGINT",$)}G3();import M0 from"node:fs/promises";import U3 from"node:path";import{z as U}from"zod";var Y1=U.object({id:U.string(),name:U.string().nullable().default(null),description:U.string().nullable().default(null)}),z1=U.union([U.string(),U.boolean()]),z3=U.object({value:U.string(),name:U.string(),description:U.string().nullable().default(null),group:U.string().nullable().default(null),groupName:U.string().nullable().default(null)}),M1=U.object({id:U.string(),name:U.string(),category:U.string().nullable().default(null),description:U.string().nullable().default(null),type:U.enum(["select","boolean"]),currentValue:z1.nullable().default(null),options:U.array(z3).default([])}),z$=U.record(U.string(),z1).default({}),H3=U.discriminatedUnion("kind",[U.object({id:U.string(),kind:U.literal("registered"),adapterId:U.enum(["claude-code","opencode","codex","copilot"]),displayName:U.string(),runFolder:U.string().nullable(),defaultModelId:U.string().nullable().default(null),defaultConfigValues:z$,discoveredModels:U.array(Y1).default([]),discoveredConfigOptions:U.array(M1).default([]),discoveredAt:U.string().nullable().default(null)}),U.object({id:U.string(),kind:U.literal("custom"),displayName:U.string(),command:U.string(),args:U.array(U.string()),env:U.record(U.string(),U.string()),runFolder:U.string().nullable(),defaultModelId:U.string().nullable().default(null),defaultConfigValues:z$,discoveredModels:U.array(Y1).default([]),discoveredConfigOptions:U.array(M1).default([]),discoveredAt:U.string().nullable().default(null)})]),G1=U.object({runtimeConfigId:U.string(),runFolder:U.string().nullable(),modelId:U.string().nullable().default(null),configValues:z$}),_0=U.object({version:U.literal(1),globalDefaultConfigId:U.string().nullable(),runtimes:U.array(H3),boardOverrides:U.record(U.string(),G1).default({}),cardOverrides:U.record(U.string(),G1).default({})});import D3 from"node:os";import f0 from"node:path";function B3(){let $=D3.homedir();switch(process.platform){case"win32":return process.env.APPDATA??f0.join($,"AppData","Roaming");case"darwin":return f0.join($,"Library","Application Support");default:return process.env.XDG_CONFIG_HOME??f0.join($,".config")}}function O0(){let $=process.env.IDEAWAVE_RUNTIME_CONFIG_PATH;if($)return $;return f0.join(B3(),"ideawave","runtimes.json")}var N3={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},H1=new Map;function q3($){return H1.get($)??Promise.resolve()}function x3($,Z){H1.set($,Z)}async function v($){let Z=$??O0(),X;try{X=await M0.readFile(Z,"utf-8")}catch(Q){if(Q.code==="ENOENT")return structuredClone(N3);throw Q}return _0.parse(JSON.parse(X))}async function h($,Z){let X=Z??O0(),J=q3(X).then(async()=>{let Q=await v(X),j=structuredClone(Q),W=await $(j);return await F3(j,X),W});return x3(X,J.catch(()=>{return})),J}async function F3($,Z){let X=Z??O0(),J=U3.dirname(X);await M0.mkdir(J,{recursive:!0});let Q=`${X}.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`,j=JSON.stringify($,null,2);await M0.writeFile(Q,j,"utf-8");try{await M0.rename(Q,X)}catch(W){throw await M0.unlink(Q).catch(()=>{return}),W}}import P3 from"node:fs/promises";import w0 from"node:os";var D1="claude",H$="@agentclientprotocol/claude-agent-acp",B1=["claude-agent-acp","claude-code-acp"],U1="Install Claude Code from https://github.com/anthropics/claude-code",N1={id:"claude-code",displayName:"Claude Code",kind:"registered",resolveSpawnConfig:async()=>{if(!await f(D1))throw new P(`Claude Code CLI not found. ${U1}`);let Z=q0(H$);if(Z)return{command:Z.command,args:Z.args,env:y(Z.env)};let X=J0(H$),J=X?.status==="installing";for(let j of B1){let W=await f(j);if(W&&!J&&X?.status!=="failed")return{command:W,args:[],env:y()}}let Q=X?.status==="failed"?`Claude Code ACP bridge install failed. ${X.error??"Restart IdeaWave CLI so it can warm the pinned bridge again."}`:"Claude Code ACP bridge is not ready. Keep IdeaWave CLI running and retry in a moment.";throw new P(Q)},checkReadiness:async()=>{if(!await f(D1))return{status:"not_installed",detail:U1};let Z=J0(H$);if(Z?.status==="ready")return{status:"ready"};if(Z?.status==="installing")return{status:"not_running",detail:"Installing Claude Code ACP bridge..."};if(Z?.status==="failed")return{status:"not_running",detail:Z.error??"Claude Code ACP bridge install failed. Restart IdeaWave CLI so it can warm the pinned bridge again."};for(let X of B1)if(await f(X))return{status:"ready"};return{status:"not_running",detail:"Installing Claude Code ACP bridge..."}},authHint:"Run `claude login` (or set ANTHROPIC_API_KEY)."};var q1="codex",D$="@zed-industries/codex-acp",x1="codex-acp",F1="Install Codex CLI from https://developers.openai.com/codex/cli",k1={id:"codex",displayName:"Codex",kind:"registered",resolveSpawnConfig:async()=>{if(!await f(q1))throw new P(`Codex CLI not found. ${F1}`);let Z=q0(D$);if(Z)return{command:Z.command,args:Z.args,env:y(Z.env)};let X=J0(D$),J=X?.status==="installing",Q=await f(x1);if(Q&&!J&&X?.status!=="failed")return{command:Q,args:[],env:y()};let j=X?.status==="failed"?`Codex ACP bridge install failed. ${X.error??"Restart IdeaWave CLI so it can warm the pinned bridge again."}`:"Codex ACP bridge is not ready. Keep IdeaWave CLI running and retry in a moment.";throw new P(j)},checkReadiness:async()=>{if(!await f(q1))return{status:"not_installed",detail:F1};let Z=J0(D$);if(Z?.status==="ready")return{status:"ready"};if(Z?.status==="installing")return{status:"not_running",detail:"Installing Codex ACP bridge..."};if(Z?.status==="failed")return{status:"not_running",detail:Z.error??"Codex ACP bridge install failed. Restart IdeaWave CLI so it can warm the pinned bridge again."};if(await f(x1))return{status:"ready"};return{status:"not_running",detail:"Installing Codex ACP bridge..."}},authHint:"Run `codex login` (or set OPENAI_API_KEY)."};var C1="copilot",P1="copilot-acp",L1="npm i -g @github/copilot",A1={id:"copilot",displayName:"GitHub Copilot",kind:"registered",resolveSpawnConfig:async()=>{let $=await f(C1);if($)return{command:$,args:["--acp"],env:y()};let Z=await f(P1);if(Z)return{command:Z,args:[],env:y()};throw new P(`Copilot not installed. Run: ${L1}`)},checkReadiness:async()=>{if(await f(C1))return{status:"ready"};if(await f(P1))return{status:"ready"};return{status:"not_installed",detail:L1}},authHint:"Run `gh auth login` (or `copilot login`)."};import k3 from"node:fs/promises";function C3($){return $.startsWith("/")||/^[a-zA-Z]:[\\/]/.test($)}async function _1($){if(C3($))try{return await k3.access($),!0}catch{return!1}return await f($)!==null}var f1={id:"custom",displayName:"Custom ACP",kind:"custom",resolveSpawnConfig:async($)=>{if($.kind!=="custom")throw new P("customAdapter received non-custom entry");if(!await _1($.command))throw new P(`custom: command "${$.command}" not found`);return{command:$.command,args:$.args,env:y($.env)}},checkReadiness:async($)=>{if($.kind!=="custom")return{status:"unknown"};return await _1($.command)?{status:"ready"}:{status:"not_installed"}}};var O1="opencode",w1="Install OpenCode from https://opencode.ai",R1={id:"opencode",displayName:"OpenCode",kind:"registered",resolveSpawnConfig:async()=>{let $=await f(O1);if(!$)throw new P(`OpenCode not installed. ${w1}`);return{command:$,args:["acp"],env:y()}},checkReadiness:async()=>{if(!await f(O1))return{status:"not_installed",detail:w1};return{status:"ready"}},authHint:"Run `opencode auth login <provider>` (or set the provider's API-key env var)."};var b1={"claude-code":N1,opencode:R1,codex:k1,copilot:A1};function c($){if($.kind==="custom")return f1;let Z=b1[$.adapterId];if(!Z)throw Error(`Unknown registered adapter: ${$.adapterId}`);return Z}function Q0(){return Object.values(b1)}async function E1($){let Z={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},X;try{X=await P3.readFile($,"utf-8")}catch(J){if(J.code==="ENOENT")return structuredClone(Z);throw J}return _0.parse(JSON.parse(X))}function B$($,Z,X){return{...$.defaultConfigValues??{},...Z?.configValues??{},...X?.configValues??{}}}async function e($){let Z=$.configPath?await E1($.configPath):await v(),X=$.cardId?Z.cardOverrides[$.cardId]:void 0;if(X?.runtimeConfigId){let Q=Z.runtimes.find((j)=>j.id===X.runtimeConfigId);if(Q)return{entry:Q,adapter:c(Q),runFolder:X.runFolder??Q.runFolder??w0.homedir(),modelId:X.modelId??Q.defaultModelId??null,configValues:B$(Q,void 0,X)}}let J=Z.boardOverrides[$.boardId];if(J?.runtimeConfigId){let Q=Z.runtimes.find((j)=>j.id===J.runtimeConfigId);if(Q)return{entry:Q,adapter:c(Q),runFolder:J.runFolder??Q.runFolder??w0.homedir(),modelId:J.modelId??Q.defaultModelId??null,configValues:B$(Q,J)}}if(Z.globalDefaultConfigId){let Q=Z.runtimes.find((j)=>j.id===Z.globalDefaultConfigId);if(Q)return{entry:Q,adapter:c(Q),runFolder:X?.runFolder??J?.runFolder??Q.runFolder??w0.homedir(),modelId:X?.modelId??J?.modelId??Q.defaultModelId??null,configValues:B$(Q,J,X)}}throw new s}async function T1($,Z={}){let J=(Z.configPath?await E1(Z.configPath):await v()).runtimes.find((Q)=>Q.id===$);if(!J)return null;return{entry:J,adapter:c(J),runFolder:J.runFolder??w0.homedir(),modelId:Z.modelId??J.defaultModelId??null,configValues:{...J.defaultConfigValues??{},...Z.configValues??{}}}}var $0=new Map,U$=new Set;function N$($){$0.get($)?.controller.abort()}function y1($){for(let[Z,X]of $0){if(X.frontendSessionId!==$)continue;X.controller.abort(),$0.delete(Z)}}function I1(){for(let $ of $0.values())$.controller.abort();$0.clear()}function v1($,Z,X,J){if((!Z.availableModels||Z.availableModels.length===0)&&Z.availableConfigOptions.length===0)return;h((Q)=>{let j=Q.runtimes.find((W)=>W.id===$);if(j){if(Z.availableModels&&Z.availableModels.length>0)j.discoveredModels=x0({adapterId:X,models:Z.availableModels,currentModelId:Z.currentModelId??J});if(Z.availableConfigOptions.length>0)j.discoveredConfigOptions=Z.availableConfigOptions}}).catch(()=>{return})}function L3($,Z){return`${$}
19
19
 
20
20
  Runtime run folder:
21
21
  - Effective run folder: ${Z}
@@ -25,4 +25,4 @@ Runtime run folder:
25
25
  Connection: close\r
26
26
  Content-Length: ${Buffer.byteLength(X)}\r
27
27
  \r
28
- ${X}`),$.destroy()}function c3($,Z){return new Promise((X,J)=>{let Q=(W)=>{$.off("listening",j),J(W)},j=()=>{$.off("error",Q);let W=$.address();if(!W||typeof W==="string"){J(Error("Failed to read CLI bridge server address"));return}X(W.port)};$.once("error",Q),$.once("listening",j),$.listen(Z,"127.0.0.1")})}function l1($){return new Promise((Z,X)=>{$.close((J)=>{if(J)X(J);else Z()})})}async function a1($,Z=x$()){let X=new Map,J=new Map,Q=$.maxMessageSize??R3,j=!1,W=(V)=>{let D=J.get(V);if(D)clearTimeout(D);J.delete(V)},G=(V)=>{J.delete(V);let{activeRunIds:D}=$.registry.disconnect(V);$.onDisconnect(V,D)},Y=(V,D)=>{let q={type:"cli_status",connected:!0,runtime:$.runtime,mcpReady:$.mcpReady(),error:D};if(V){let C=X.get(V);if(C)j0(C,q);return}for(let C of X.values())j0(C,q)},z=(V,D)=>{let q=D.sessionId.trim(),C=D.userId.trim();if(!q||!C){j0(V,{type:"cli_status",connected:!1,runtime:$.runtime,mcpReady:$.mcpReady(),error:"Missing frontend session or user id"}),V.close();return}W(q);let N=X.get(q);if(N&&N!==V)N.close();V.data.frontendSessionId=q,X.set(q,V),$.registry.register({frontendSessionId:q,userId:C,tools:D.tools,send:(M)=>j0(V,M)}),Y(q),$.onToolMetadata?.(q)},H=(V,D)=>{let q=$.registry.getUserId(V);if(!q)return;switch(D.type){case"bridge_ping":{let C=X.get(V);if(C)j0(C,{type:"bridge_pong"});break}case"tool_metadata":$.registry.setMetadata(V,D.tools),$.onToolMetadata?.(V);break;case"tool_result":$.registry.handleToolResult(V,D);break;case"run_turn":$.registry.markRunActive(V,D.run.runId,D.run.cardId),$.onRunTurn(V,{...D.run,frontendSessionId:V,userId:q});break;case"cancel_run":if($.registry.ownsRun(V,D.runId))$.onCancelRun(V,D.runId);break;case"runtime_rpc":$.onRuntimeRpc(V,D);break;case"warmup_run":$.onWarmupRun(V,{...D,frontendSessionId:V},q);break;default:break}};for(let V of Z){let D=O3((N,M)=>{M.writeHead(404,{"content-type":"text/plain"}),M.end("IdeaWave CLI bridge")}),q=new w3({noServer:!0,maxPayload:Q}),C=(N)=>{if(N.idleTimer)clearTimeout(N.idleTimer);N.idleTimer=setTimeout(()=>{N.close()},b3),N.idleTimer.unref?.()};q.on("connection",(N)=>{let M=N;M.data={id:f3(),frontendSessionId:null},M.idleTimer=null,C(M),M.on("ping",()=>C(M)),M.on("pong",()=>C(M)),M.on("error",()=>{if(M.idleTimer)clearTimeout(M.idleTimer);M.close()}),M.on("message",(B)=>{C(M);let L=S3(B);if(Q>0&&L.length>Q)return;let A=R0(L);if(!A)return;let O=M.data.frontendSessionId;if(!O){if(A.type==="bridge_probe")j0(M,{type:"bridge_probe_ack",protocolVersion:A.protocolVersion});else if(A.type==="frontend_hello")z(M,A);return}H(O,A)}),M.on("close",()=>{if(M.idleTimer)clearTimeout(M.idleTimer);let B=M.data.frontendSessionId;if(!B)return;if(X.get(B)!==M)return;if(X.delete(B),W(B),j)return;J.set(B,setTimeout(()=>G(B),E3))})}),D.on("upgrade",(N,M,B)=>{if(new URL(N.url??"/","http://127.0.0.1").pathname!==q$){c1(M,404,"Not Found");return}if(!h3(m3(N.headers.origin))){c1(M,403,"Forbidden");return}q.handleUpgrade(N,M,B,(A)=>{q.emit("connection",A,N)})});try{let N=await c3(D,V);return{url:`ws://127.0.0.1:${N}${q$}`,port:N,sendStatus:Y,close:async()=>{j=!0;for(let M of J.values())clearTimeout(M);J.clear();for(let M of q.clients){let B=M;if(B.idleTimer)clearTimeout(B.idleTimer);B.close()}q.close(),await l1(D).catch(()=>{return})}}}catch(N){if(q.close(),await l1(D).catch(()=>{return}),N?.code==="EADDRINUSE")continue;throw N}}throw Error(`No free IdeaWave CLI bridge port found in ${Z[0]}-${Z.at(-1)}`)}import{Server as Z6}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as X6,ListToolsRequestSchema as J6}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as u3}from"node:crypto";import{createServer as p3}from"node:http";import{StreamableHTTPServerTransport as a3}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as s1}from"@modelcontextprotocol/sdk/types.js";var d1=new Set(["127.0.0.1","localhost","[::1]","::1"]);function l3($){let Z=$.trim();if(Z.length===0)return null;if(Z.startsWith("[")){let j=Z.indexOf("]");if(j===-1)return null;let W=Z.slice(0,j+1),G=Z.slice(j+1);if(G.length===0)return{host:W,port:null};if(!G.startsWith(":"))return null;let Y=Number(G.slice(1));if(!Number.isInteger(Y)||Y<=0||Y>65535)return null;return{host:W,port:Y}}let X=Z.lastIndexOf(":");if(X===-1)return{host:Z,port:null};let J=Z.slice(X+1),Q=Number(J);if(!Number.isInteger(Q)||Q<=0||Q>65535)return{host:Z,port:null};return{host:Z.slice(0,X),port:Q}}function i1($){return d1.has($)||d1.has($.toLowerCase())}function n1($,Z){let X=$.headers.host;if(typeof X!=="string")return{ok:!1,status:403,reason:"missing-host"};let J=l3(X);if(!J)return{ok:!1,status:403,reason:"bad-host"};if(!i1(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 Q=$.headers.origin;if(typeof Q==="string"&&Q.length>0){if(Q!=="null"){let j;try{j=new URL(Q)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!i1(j.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var o1="/mcp",d3=43274,r1=16777216,i3=1800000,n3=300000,t1=200,s3=-32700,d=-32600,F$=-32603;function g($,Z,X,J,Q){$.statusCode=Z,$.setHeader("content-type","application/json"),$.end(JSON.stringify({jsonrpc:"2.0",error:{code:X,message:J,...Q?{data:Q}:{}},id:null}))}class k$ extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class C$ extends Error{constructor(){super(`body exceeds ${r1} bytes`);this.name="BodyTooLargeError"}}async function o3($){if($.method&&$.method!=="POST")return;let Z=$.headers["content-type"];if(typeof Z==="string"&&Z.trim().length>0){if(!Z.toLowerCase().includes("application/json"))throw new k$}let X=0,J=[];for await(let j of $){let W=typeof j==="string"?Buffer.from(j):j;if(X+=W.byteLength,X>r1)throw new C$;J.push(W)}if(J.length===0)return;let Q=Buffer.concat(J).toString("utf8");if(Q.length===0)return;return JSON.parse(Q)}function t3($){if(Array.isArray($))return $.some(s1);return s1($)}function r3($){if(typeof $==="number")return $;let Z=process.env.IDEAWAVE_MCP_PORT;if(Z&&Z.trim().length>0){let X=Number(Z);if(Number.isInteger(X)&&X>=0&&X<65536)return X}return d3}async function e3($,Z){let X=(Q)=>new Promise((j,W)=>{let G=(z)=>{$.off("listening",Y),W(z)},Y=()=>{$.off("error",G),j()};$.once("error",G),$.once("listening",Y),$.listen(Q,"127.0.0.1")});try{await X(Z)}catch(Q){if(Q.code!=="EADDRINUSE"||Z===0)throw Q;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 X(0)}let J=$.address();if(J==null||typeof J==="string")throw Error("[mcp] failed to read bound address");return J.port}function $6($,Z){if(Z&&typeof Z==="object"&&!Array.isArray(Z)){let J=Z.params;if(J&&typeof J==="object"&&!Array.isArray(J)){let Q=J.clientInfo;if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let j=Q.name;if(typeof j==="string"&&j.trim().length>0)return j.trim()}}}let X=$.headers["user-agent"];if(typeof X==="string"&&X.trim().length>0)return X.trim();return null}async function e1($){let Z=new Map,X=0;function J(z){let H=Z.get(z);if(H)H.lastActivity=Date.now()}async function Q(z,H){Z.delete(z),await H.transport.close().catch(()=>{return})}async function j(){let z=null,H=1/0;for(let[V,D]of Z)if(D.lastActivity<H)H=D.lastActivity,z=V;if(z!==null){let V=Z.get(z);if(V)console.warn(`[mcp] session cap of ${t1} reached; evicting ${z}`),await Q(z,V)}}let W=setInterval(()=>{let z=Date.now()-i3;for(let[H,V]of Z)if(V.lastActivity<z)console.log(`[mcp] sweeping idle session ${H}`),Q(H,V)},n3);W.unref?.();let G=p3((z,H)=>{(async()=>{let V;try{V=new URL(z.url??"/","http://127.0.0.1").pathname}catch{g(H,400,d,"bad-url");return}if(V!==o1){g(H,404,d,"not-found");return}let D=z.method??"POST";if(D!=="POST"&&D!=="GET"&&D!=="DELETE"){H.setHeader("Allow","GET, POST, DELETE"),g(H,405,d,"method-not-allowed");return}let q=n1(z,X);if(!q.ok){g(H,q.status,d,"forbidden",{reason:q.reason});return}let C=z.headers["mcp-session-id"],N=typeof C==="string"?C:void 0;if(D==="GET"||D==="DELETE"){if(!N||!Z.has(N)){g(H,400,d,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let L=Z.get(N).transport;J(N);try{await L.handleRequest(z,H)}catch(A){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",A),!H.headersSent)g(H,500,F$,"internal")}return}let M;try{M=await o3(z)}catch(L){if(L instanceof k$){g(H,415,d,"expected-application-json");return}if(L instanceof C$){g(H,413,d,"body-too-large");return}g(H,400,s3,"invalid-json");return}let B;if(N&&Z.has(N))B=Z.get(N).transport,J(N);else if(!N&&M!==void 0&&t3(M)){let L=z.headers["x-ideawave-user-id"],A=typeof L==="string"&&L.trim().length>0?L.trim():null,O=z.headers["x-ideawave-frontend-session-id"],_=typeof O==="string"&&O.trim().length>0?O.trim():null,F=z.headers["x-ideawave-tool-surface"],K=typeof F==="string"&&F.trim()==="read"?"read":"full",k=z.headers["x-ideawave-card-id"],w=typeof k==="string"&&k.trim().length>0?k.trim():null,x=z.headers["x-ideawave-board-id"],R=typeof x==="string"&&x.trim().length>0?x.trim():null,b=z.headers["x-ideawave-run-folder"],S=typeof b==="string"&&b.trim().length>0?b.trim():null,n=$6(z,M);if(Z.size>=t1)await j();let Z0=null,m=new a3({sessionIdGenerator:()=>u3(),onsessioninitialized:(l)=>{Z0=l,Z.set(l,{transport:m,lastActivity:Date.now()})},onsessionclosed:(l)=>{Z.delete(l)}});m.onclose=()=>{if(m.sessionId)Z.delete(m.sessionId)};try{await $.buildServer({userId:A,frontendSessionId:_,boardId:R,toolSurface:K,cardId:w,runFolder:S,clientHint:n}).connect(m)}catch(l){if(console.error("[mcp] buildServer/connect failed",l),Z0)Z.delete(Z0);await m.close().catch(()=>{return}),g(H,500,F$,"server-init-failed");return}B=m}else{g(H,400,d,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await B.handleRequest(z,H,M)}catch(L){if(console.error("[mcp] transport.handleRequest threw",L),!H.headersSent)g(H,500,F$,"internal")}})().catch((V)=>{console.error("[mcp] unhandled request handler error:",V)})});return X=await e3(G,r3($.port)),{url:`http://127.0.0.1:${X}${o1}`,port:X,close:async()=>{clearInterval(W);for(let z of Z.values())await z.transport.close().catch(()=>{return});Z.clear(),await new Promise((z)=>G.close(()=>z()))}}}var Q6={name:"ideawave-board",version:"1.0.0"},E0="list_run_folder",T0="read_run_folder_file",X2=new Set(["list_boards","get_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",E0,T0]),j6=[{name:E0,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:T0,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 P$($){return{content:[{type:"text",text:$}]}}function W6($){return P$(JSON.stringify($,null,2))}function $2($){return{...P$($),isError:!0}}function K6($,Z,X="full"){return $.getMetadata(Z).filter((J)=>X!=="read"||X2.has(C0(J.name))).map((J)=>({name:J.name,description:J.description,inputSchema:J.inputSchema}))}function V6($,Z,X={}){let J=K6($,Z,X.toolSurface??"full");return X.includeRunFolderTools?[...J,...j6]:J}function Z2($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let X=$[Z];return typeof X==="string"?X:null}async function Y6($,Z,X){if(X&&X.trim().length>0)return X.trim();if(!$||!Z)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await e({boardId:$,cardId:Z})).runFolder}async function M6($){let Z=await Y6($.boardId,$.cardId,$.runFolder);if($.name===E0){let X=Z2($.args,"path")??"",J=await a$(Z,X);return W6(J)}if($.name===T0){let X=Z2($.args,"path");if(!X)return $2("read_run_folder_file requires a path.");return P$(await k0(Z,X))}return $2(`Unknown local tool "${$.name}"`)}function G6($,Z,X,J,Q,j="full"){let W=new Z6(Q6,{capabilities:{tools:{}}});return W.setRequestHandler(J6,async()=>({tools:V6($,Z,{includeRunFolderTools:Boolean(Q||X&&J),toolSurface:j})})),W.setRequestHandler(X6,async(G)=>{let{name:Y,arguments:z}=G.params,H=C0(Y);try{if(H===E0||H===T0)return await M6({name:H,args:z,boardId:X,cardId:J,runFolder:Q});if(j==="read"&&!X2.has(H))throw Error(`Tool "${Y}" is not available in read-only mode`);let V=await $.callTool(Z,H,z??{},void 0,J??void 0);if(V&&typeof V==="object"&&Array.isArray(V.content))return V;return{content:[{type:"text",text:typeof V==="string"?V:JSON.stringify(V)}]}}catch(V){return{content:[{type:"text",text:V instanceof Error?V.message:"Tool call failed"}],isError:!0}}}),W}function J2($,Z){return e1({buildServer:(X)=>G6($,X.frontendSessionId,X.boardId,X.cardId,X.runFolder,X.toolSurface),port:Z})}import I0 from"node:fs/promises";import A$ from"node:os";import v0 from"node:path";var Q2=new Map,L$=new Map,z6=30000;function y0($,Z){let X=Q2.get($);if(X&&X.expiresAt>Date.now())return Promise.resolve(X.value);let J=L$.get($);if(J)return J;let Q=Z().then((j)=>{return Q2.set($,{value:j,expiresAt:Date.now()+z6}),j}).finally(()=>{L$.delete($)});return L$.set($,Q),Q}async function j2($){let Z=await Promise.all(Q0().map((j)=>y0(j.id,async()=>({adapterId:j.id,...await j.checkReadiness({id:"__probe__",kind:"registered",adapterId:j.id,displayName:j.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null})})))),J=(await v($)).runtimes.filter((j)=>j.kind==="custom"),Q=await Promise.all(J.map((j)=>y0(`custom:${j.id}`,async()=>({adapterId:j.id,...await c(j).checkReadiness(j)}))));return[...Z,...Q]}async function W2($,Z){let X=Q0().find((j)=>j.id===$);if(X)return y0(X.id,async()=>({adapterId:X.id,...await X.checkReadiness({id:"__probe__",kind:"registered",adapterId:X.id,displayName:X.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null})}));let Q=(await v(Z)).runtimes.find((j)=>j.id===$);if(!Q||Q.kind!=="custom")return null;return y0(`custom:${Q.id}`,async()=>({adapterId:Q.id,...await c(Q).checkReadiness(Q)}))}function K2(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function H6(){let[$,Z]=await Promise.all([v(),j2()]),X=$.globalDefaultConfigId?$.runtimes.find((J)=>J.id===$.globalDefaultConfigId)??null:null;return{runtimes:$.runtimes,globalDefaultConfigId:$.globalDefaultConfigId,globalDefaultEffective:X?{runFolder:X.runFolder??A$.homedir(),modelId:X.defaultModelId??null,configValues:X.defaultConfigValues??{}}:null,knownAdapters:Q0().map((J)=>({id:J.id,displayName:J.displayName})),readiness:Z}}async function D6($){try{let Z=await e({boardId:$.boardId,cardId:$.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 s)return{resolved:null};throw Z}}async function B6($){return h((Z)=>{let X=Z.runtimes.find((j)=>j.kind==="registered"&&j.adapterId===$.adapterId);if(X)return X;let J=Q0().find((j)=>j.id===$.adapterId);if(!J)throw Error(`Unknown adapterId: ${$.adapterId}`);let Q={id:K2(),kind:"registered",adapterId:$.adapterId,displayName:J.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(Q),Q})}async function U6($){return h((Z)=>{let X={id:K2(),kind:"custom",displayName:$.displayName,command:$.command,args:$.args,env:$.env,runFolder:$.runFolder,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(X),X})}async function N6($){await h((Z)=>{if(Z.runtimes=Z.runtimes.filter((X)=>X.id!==$.runtimeConfigId),Z.globalDefaultConfigId===$.runtimeConfigId)Z.globalDefaultConfigId=null;for(let X of Object.keys(Z.boardOverrides))if(Z.boardOverrides[X].runtimeConfigId===$.runtimeConfigId)delete Z.boardOverrides[X];for(let X of Object.keys(Z.cardOverrides))if(Z.cardOverrides[X].runtimeConfigId===$.runtimeConfigId)delete Z.cardOverrides[X]})}async function q6($){await h((Z)=>{let X=Z.runtimes.find((J)=>J.id===$.runtimeConfigId);if(!X)throw Error(`Runtime config not found: ${$.runtimeConfigId}`);if(Z.globalDefaultConfigId=$.runtimeConfigId,$.runFolder!==void 0)X.runFolder=$.runFolder;if($.modelId!==void 0)X.defaultModelId=$.modelId;if($.configValues!==void 0)X.defaultConfigValues=$.configValues})}async function x6($){$.boardId,await h((Z)=>{if($.runtimeConfigId===null){delete Z.cardOverrides[$.cardId];return}if(!Z.runtimes.some((Q)=>Q.id===$.runtimeConfigId))throw Error(`Runtime config not found: ${$.runtimeConfigId}`);let J=Z.cardOverrides[$.cardId];Z.cardOverrides[$.cardId]={runtimeConfigId:$.runtimeConfigId,runFolder:$.runFolder!==void 0?$.runFolder:J?.runFolder??null,modelId:$.modelId!==void 0?$.modelId:J?.modelId??null,configValues:$.configValues!==void 0?$.configValues:J?.configValues??{}}})}async function F6($){let X=(await v()).runtimes.find((W)=>W.id===$.runtimeConfigId);if(!X)throw Error(`Runtime config not found: ${$.runtimeConfigId}`);let J=c(X),Q=await J.resolveSpawnConfig(X),j=X.runFolder??A$.homedir();try{let W=await K1({spawn:{...Q,cwd:j}}),G=x0({adapterId:J.id,models:W.models,currentModelId:W.currentModelId}),Y=new Date().toISOString();return await h((z)=>{let H=z.runtimes.find((V)=>V.id===$.runtimeConfigId);if(H)H.discoveredModels=G,H.discoveredConfigOptions=W.configOptions,H.discoveredAt=Y}),{ok:!0,models:G,configOptions:W.configOptions,currentModelId:W.currentModelId}}catch(W){if(W instanceof X0)throw Error(`${W.message}${J.authHint?` ${J.authHint}`:""}`);if(W instanceof P||W instanceof o)throw Error(W.message);throw W}}async function k6($){let Z=A$.homedir(),X=$.path?.trim()?$.path.trim():Z,J=v0.resolve(X),Q=!0;try{if(!(await I0.stat(J)).isDirectory())J=v0.dirname(J)}catch{Q=!1,J=Z}let j=[];try{j=(await I0.readdir(J,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()&&!Y.name.startsWith(".")).map((Y)=>({name:Y.name,path:v0.join(J,Y.name)})).sort((Y,z)=>Y.name.localeCompare(z.name))}catch{j=[]}let W=v0.dirname(J);return{path:J,parent:W===J?null:W,home:Z,exists:Q,entries:j}}var V2={list:H6,getEffectiveForCard:D6,registerRegistered:B6,registerCustom:U6,unregister:N6,setUserDefault:q6,setCardOverride:x6,refreshModels:F6,browseFolder:k6};var C6=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function P6(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function Y2(){try{let $=await v();if($.globalDefaultConfigId){if($.runtimes.some((X)=>X.id===$.globalDefaultConfigId))return $.globalDefaultConfigId}for(let Z of C6){if((await W2(Z.id))?.status!=="ready")continue;let J=null;if(await h((Q)=>{if(Q.globalDefaultConfigId){if(Q.runtimes.some((G)=>G.id===Q.globalDefaultConfigId)){J=Q.globalDefaultConfigId;return}}let j=Q.runtimes.find((W)=>W.kind==="registered"&&W.adapterId===Z.id);if(!j){let W={id:P6(),kind:"registered",adapterId:Z.id,displayName:Z.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};Q.runtimes.push(W),j=W}Q.globalDefaultConfigId=j.id,J=j.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($){return console.warn("[ideawave-cli] runtime auto-seed failed",$),null}}function L6(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class _${sessions=new Map;createCallId;toolCallTimeoutMs;constructor($={}){this.createCallId=$.createCallId??L6,this.toolCallTimeoutMs=$.toolCallTimeoutMs??120000}register($){let Z=this.sessions.get($.frontendSessionId);if(Z){if(Z.userId!==$.userId)this.rejectPending(Z,"frontend session user changed"),Z.activeRunIds.clear();this.sessions.set($.frontendSessionId,{frontendSessionId:$.frontendSessionId,userId:$.userId,tools:$.tools,send:$.send,pendingToolCalls:Z.pendingToolCalls,activeRunIds:Z.activeRunIds,activeRunCardIds:Z.activeRunCardIds});return}this.sessions.set($.frontendSessionId,{frontendSessionId:$.frontendSessionId,userId:$.userId,tools:$.tools,send:$.send,pendingToolCalls:new Map,activeRunIds:new Set,activeRunCardIds:new Map})}disconnect($,Z="frontend session disconnected"){let X=this.sessions.get($);if(!X)return{activeRunIds:[]};return this.sessions.delete($),this.rejectPending(X,Z),{activeRunIds:Array.from(X.activeRunIds)}}sessionCount(){return this.sessions.size}has($){return this.sessions.has($)}getUserId($){return this.sessions.get($)?.userId??null}setMetadata($,Z){let X=this.sessions.get($);if(X)X.tools=Z}getMetadata($){if(!$)return[];return this.sessions.get($)?.tools??[]}sendToSession($,Z){let X=this.sessions.get($);if(!X)return!1;return X.send(Z),!0}callTool($,Z,X,J,Q){if(!$)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let j=this.sessions.get($);if(!j)return Promise.reject(Error(`Frontend session ${$} is not connected`));let W=this.createCallId();return new Promise((G,Y)=>{let z=setTimeout(()=>{j.pendingToolCalls.delete(W),Y(Error(`Tool "${Z}" timed out waiting for the frontend`))},this.toolCallTimeoutMs),H=J??(Q?this.getActiveRunIdForCard(j,Q):this.getSoleActiveRunId(j)),V=Q??(H?j.activeRunCardIds.get(H):void 0);j.pendingToolCalls.set(W,{resolve:G,reject:Y,timer:z}),j.send({type:"tool_call",callId:W,name:Z,args:X,...H?{runId:H}:{},...V?{cardId:V}:{}})})}handleToolResult($,Z){let X=this.sessions.get($);if(!X)return;let J=X.pendingToolCalls.get(Z.callId);if(!J)return;if(X.pendingToolCalls.delete(Z.callId),clearTimeout(J.timer),Z.ok)J.resolve(Z.result);else J.reject(Error(Z.error??"Tool execution failed"))}markRunActive($,Z,X){let J=this.sessions.get($);if(!J)return;if(J.activeRunIds.add(Z),X)J.activeRunCardIds.set(Z,X)}markRunSettled($,Z){let X=this.sessions.get($);if(!X)return;X.activeRunIds.delete(Z),X.activeRunCardIds.delete(Z)}ownsRun($,Z){return this.sessions.get($)?.activeRunIds.has(Z)??!1}rejectPending($,Z){for(let X of $.pendingToolCalls.values())clearTimeout(X.timer),X.reject(Error(Z));$.pendingToolCalls.clear()}getSoleActiveRunId($){return $.activeRunIds.size===1?$.activeRunIds.values().next().value:void 0}getActiveRunIdForCard($,Z){let X=[...$.activeRunCardIds.entries()].filter(([J,Q])=>$.activeRunIds.has(J)&&Q===Z).map(([J])=>J);return X.length===1?X[0]:void 0}}function A6(){return"0.0.30".trim()?"0.0.30":"dev"}var i=process.argv[2];if(i==="--help"||i==="-h"||i==="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(i==="--version"||i==="-v"||i==="version")console.log(A6()),process.exit(0);if(i)console.error(`Unknown command: ${i}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var z0=new _$,B0=null;function H0($,Z){z0.sendToSession($,Z)}async function _6($,Z){try{let X=V2[Z.method],J=await X(Z.params);H0($,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!0,result:J})}catch(X){H0($,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!1,error:X instanceof Error?X.message:String(X)})}}var D0=!1,G0=null;async function f$(){if(D0)return;if(G0)return G0;return G0=(async()=>{try{let $=await J2(z0);b$({...$,requestedPort:$.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${$.url}`);try{let Z=await l$();for(let X of Z)if(X.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${X.packageName}: ${X.error??"unknown error"}`)}catch(Z){console.warn("[ideawave-cli] ACP bridge setup skipped:",Z instanceof Error?Z.message:String(Z))}await Y2(),D0=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),B0?.sendStatus()}catch($){console.error("[ideawave-cli] failed to start agent host:",$),B0?.sendStatus(void 0,$ instanceof Error?$.message:String($))}finally{G0=null}})(),G0}if(process.env.APP_ENV!=="development"){let $=await p1();if($)console.error(`[ideawave-cli] An IdeaWave CLI is already running at ${$}.`),console.error("[ideawave-cli] Only one CLI per machine is supported — it already serves every browser tab. Exiting."),process.exit(0)}B0=await a1({registry:z0,runtime:null,mcpReady:()=>D0,onToolMetadata:($)=>{console.log(`[ideawave-cli] session ${$} advertised ${z0.getMetadata($).length} tools`),f$()},onRunTurn:($,Z)=>{console.log(`[ideawave-cli] running agent turn for card ${Z.cardId} (session ${$})`),(async()=>{if(await f$(),!D0){H0($,{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 g1(Z,(X)=>H0($,X))})().catch(()=>{return}).finally(()=>z0.markRunSettled($,Z.runId))},onCancelRun:($,Z)=>{N$(Z)},onRuntimeRpc:($,Z)=>{_6($,Z)},onWarmupRun:($,Z,X)=>{(async()=>{if(await f$(),!D0)return{status:"retryable",error:"agent host is not ready"};return h1({cardId:Z.cardId,boardId:Z.boardId,userId:X,frontendSessionId:$})})().then((J)=>{if(!Z.warmupId)return;H0($,{type:"warmup_result",warmupId:Z.warmupId,cardId:Z.cardId,...J})})},onDisconnect:($,Z)=>{y1($);for(let X of Z)N$(X);console.log(`[ideawave-cli] browser session ${$} disconnected`)}});console.log(`[ideawave-cli] browser bridge listening on ${B0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var M2=!1;for(let $ of["SIGINT","SIGTERM"])process.once($,()=>{if(M2)return;M2=!0,I1(),(async()=>{await B0?.close().catch(()=>{return}),process.exit(0)})()});
28
+ ${X}`),$.destroy()}function c3($,Z){return new Promise((X,J)=>{let Q=(W)=>{$.off("listening",j),J(W)},j=()=>{$.off("error",Q);let W=$.address();if(!W||typeof W==="string"){J(Error("Failed to read CLI bridge server address"));return}X(W.port)};$.once("error",Q),$.once("listening",j),$.listen(Z,"127.0.0.1")})}function l1($){return new Promise((Z,X)=>{$.close((J)=>{if(J)X(J);else Z()})})}async function a1($,Z=x$()){let X=new Map,J=new Map,Q=$.maxMessageSize??R3,j=!1,W=(V)=>{let D=J.get(V);if(D)clearTimeout(D);J.delete(V)},G=(V)=>{J.delete(V);let{activeRunIds:D}=$.registry.disconnect(V);$.onDisconnect(V,D)},Y=(V,D)=>{let q={type:"cli_status",connected:!0,runtime:$.runtime,mcpReady:$.mcpReady(),error:D};if(V){let C=X.get(V);if(C)j0(C,q);return}for(let C of X.values())j0(C,q)},z=(V,D)=>{let q=D.sessionId.trim(),C=D.userId.trim();if(!q||!C){j0(V,{type:"cli_status",connected:!1,runtime:$.runtime,mcpReady:$.mcpReady(),error:"Missing frontend session or user id"}),V.close();return}W(q);let N=X.get(q);if(N&&N!==V)N.close();V.data.frontendSessionId=q,X.set(q,V),$.registry.register({frontendSessionId:q,userId:C,tools:D.tools,send:(M)=>j0(V,M)}),Y(q),$.onToolMetadata?.(q)},H=(V,D)=>{let q=$.registry.getUserId(V);if(!q)return;switch(D.type){case"bridge_ping":{let C=X.get(V);if(C)j0(C,{type:"bridge_pong"});break}case"tool_metadata":$.registry.setMetadata(V,D.tools),$.onToolMetadata?.(V);break;case"tool_result":$.registry.handleToolResult(V,D);break;case"run_turn":$.registry.markRunActive(V,D.run.runId,D.run.cardId),$.onRunTurn(V,{...D.run,frontendSessionId:V,userId:q});break;case"cancel_run":if($.registry.ownsRun(V,D.runId))$.onCancelRun(V,D.runId);break;case"runtime_rpc":$.onRuntimeRpc(V,D);break;case"warmup_run":$.onWarmupRun(V,{...D,frontendSessionId:V},q);break;default:break}};for(let V of Z){let D=O3((N,M)=>{M.writeHead(404,{"content-type":"text/plain"}),M.end("IdeaWave CLI bridge")}),q=new w3({noServer:!0,maxPayload:Q}),C=(N)=>{if(N.idleTimer)clearTimeout(N.idleTimer);N.idleTimer=setTimeout(()=>{N.close()},b3),N.idleTimer.unref?.()};q.on("connection",(N)=>{let M=N;M.data={id:f3(),frontendSessionId:null},M.idleTimer=null,C(M),M.on("ping",()=>C(M)),M.on("pong",()=>C(M)),M.on("error",()=>{if(M.idleTimer)clearTimeout(M.idleTimer);M.close()}),M.on("message",(B)=>{C(M);let L=S3(B);if(Q>0&&L.length>Q)return;let A=R0(L);if(!A)return;let O=M.data.frontendSessionId;if(!O){if(A.type==="bridge_probe")j0(M,{type:"bridge_probe_ack",protocolVersion:A.protocolVersion});else if(A.type==="frontend_hello")z(M,A);return}H(O,A)}),M.on("close",()=>{if(M.idleTimer)clearTimeout(M.idleTimer);let B=M.data.frontendSessionId;if(!B)return;if(X.get(B)!==M)return;if(X.delete(B),W(B),j)return;J.set(B,setTimeout(()=>G(B),E3))})}),D.on("upgrade",(N,M,B)=>{if(new URL(N.url??"/","http://127.0.0.1").pathname!==q$){c1(M,404,"Not Found");return}if(!h3(m3(N.headers.origin))){c1(M,403,"Forbidden");return}q.handleUpgrade(N,M,B,(A)=>{q.emit("connection",A,N)})});try{let N=await c3(D,V);return{url:`ws://127.0.0.1:${N}${q$}`,port:N,sendStatus:Y,close:async()=>{j=!0;for(let M of J.values())clearTimeout(M);J.clear();for(let M of q.clients){let B=M;if(B.idleTimer)clearTimeout(B.idleTimer);B.close()}q.close(),await l1(D).catch(()=>{return})}}}catch(N){if(q.close(),await l1(D).catch(()=>{return}),N?.code==="EADDRINUSE")continue;throw N}}throw Error(`No free IdeaWave CLI bridge port found in ${Z[0]}-${Z.at(-1)}`)}import{Server as Z6}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as X6,ListToolsRequestSchema as J6}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as u3}from"node:crypto";import{createServer as p3}from"node:http";import{StreamableHTTPServerTransport as a3}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as s1}from"@modelcontextprotocol/sdk/types.js";var d1=new Set(["127.0.0.1","localhost","[::1]","::1"]);function l3($){let Z=$.trim();if(Z.length===0)return null;if(Z.startsWith("[")){let j=Z.indexOf("]");if(j===-1)return null;let W=Z.slice(0,j+1),G=Z.slice(j+1);if(G.length===0)return{host:W,port:null};if(!G.startsWith(":"))return null;let Y=Number(G.slice(1));if(!Number.isInteger(Y)||Y<=0||Y>65535)return null;return{host:W,port:Y}}let X=Z.lastIndexOf(":");if(X===-1)return{host:Z,port:null};let J=Z.slice(X+1),Q=Number(J);if(!Number.isInteger(Q)||Q<=0||Q>65535)return{host:Z,port:null};return{host:Z.slice(0,X),port:Q}}function i1($){return d1.has($)||d1.has($.toLowerCase())}function n1($,Z){let X=$.headers.host;if(typeof X!=="string")return{ok:!1,status:403,reason:"missing-host"};let J=l3(X);if(!J)return{ok:!1,status:403,reason:"bad-host"};if(!i1(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 Q=$.headers.origin;if(typeof Q==="string"&&Q.length>0){if(Q!=="null"){let j;try{j=new URL(Q)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!i1(j.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var o1="/mcp",d3=43274,r1=16777216,i3=1800000,n3=300000,t1=200,s3=-32700,d=-32600,F$=-32603;function g($,Z,X,J,Q){$.statusCode=Z,$.setHeader("content-type","application/json"),$.end(JSON.stringify({jsonrpc:"2.0",error:{code:X,message:J,...Q?{data:Q}:{}},id:null}))}class k$ extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class C$ extends Error{constructor(){super(`body exceeds ${r1} bytes`);this.name="BodyTooLargeError"}}async function o3($){if($.method&&$.method!=="POST")return;let Z=$.headers["content-type"];if(typeof Z==="string"&&Z.trim().length>0){if(!Z.toLowerCase().includes("application/json"))throw new k$}let X=0,J=[];for await(let j of $){let W=typeof j==="string"?Buffer.from(j):j;if(X+=W.byteLength,X>r1)throw new C$;J.push(W)}if(J.length===0)return;let Q=Buffer.concat(J).toString("utf8");if(Q.length===0)return;return JSON.parse(Q)}function t3($){if(Array.isArray($))return $.some(s1);return s1($)}function r3($){if(typeof $==="number")return $;let Z=process.env.IDEAWAVE_MCP_PORT;if(Z&&Z.trim().length>0){let X=Number(Z);if(Number.isInteger(X)&&X>=0&&X<65536)return X}return d3}async function e3($,Z){let X=(Q)=>new Promise((j,W)=>{let G=(z)=>{$.off("listening",Y),W(z)},Y=()=>{$.off("error",G),j()};$.once("error",G),$.once("listening",Y),$.listen(Q,"127.0.0.1")});try{await X(Z)}catch(Q){if(Q.code!=="EADDRINUSE"||Z===0)throw Q;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 X(0)}let J=$.address();if(J==null||typeof J==="string")throw Error("[mcp] failed to read bound address");return J.port}function $6($,Z){if(Z&&typeof Z==="object"&&!Array.isArray(Z)){let J=Z.params;if(J&&typeof J==="object"&&!Array.isArray(J)){let Q=J.clientInfo;if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let j=Q.name;if(typeof j==="string"&&j.trim().length>0)return j.trim()}}}let X=$.headers["user-agent"];if(typeof X==="string"&&X.trim().length>0)return X.trim();return null}async function e1($){let Z=new Map,X=0;function J(z){let H=Z.get(z);if(H)H.lastActivity=Date.now()}async function Q(z,H){Z.delete(z),await H.transport.close().catch(()=>{return})}async function j(){let z=null,H=1/0;for(let[V,D]of Z)if(D.lastActivity<H)H=D.lastActivity,z=V;if(z!==null){let V=Z.get(z);if(V)console.warn(`[mcp] session cap of ${t1} reached; evicting ${z}`),await Q(z,V)}}let W=setInterval(()=>{let z=Date.now()-i3;for(let[H,V]of Z)if(V.lastActivity<z)console.log(`[mcp] sweeping idle session ${H}`),Q(H,V)},n3);W.unref?.();let G=p3((z,H)=>{(async()=>{let V;try{V=new URL(z.url??"/","http://127.0.0.1").pathname}catch{g(H,400,d,"bad-url");return}if(V!==o1){g(H,404,d,"not-found");return}let D=z.method??"POST";if(D!=="POST"&&D!=="GET"&&D!=="DELETE"){H.setHeader("Allow","GET, POST, DELETE"),g(H,405,d,"method-not-allowed");return}let q=n1(z,X);if(!q.ok){g(H,q.status,d,"forbidden",{reason:q.reason});return}let C=z.headers["mcp-session-id"],N=typeof C==="string"?C:void 0;if(D==="GET"||D==="DELETE"){if(!N||!Z.has(N)){g(H,400,d,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let L=Z.get(N).transport;J(N);try{await L.handleRequest(z,H)}catch(A){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",A),!H.headersSent)g(H,500,F$,"internal")}return}let M;try{M=await o3(z)}catch(L){if(L instanceof k$){g(H,415,d,"expected-application-json");return}if(L instanceof C$){g(H,413,d,"body-too-large");return}g(H,400,s3,"invalid-json");return}let B;if(N&&Z.has(N))B=Z.get(N).transport,J(N);else if(!N&&M!==void 0&&t3(M)){let L=z.headers["x-ideawave-user-id"],A=typeof L==="string"&&L.trim().length>0?L.trim():null,O=z.headers["x-ideawave-frontend-session-id"],_=typeof O==="string"&&O.trim().length>0?O.trim():null,F=z.headers["x-ideawave-tool-surface"],K=typeof F==="string"&&F.trim()==="read"?"read":"full",k=z.headers["x-ideawave-card-id"],w=typeof k==="string"&&k.trim().length>0?k.trim():null,x=z.headers["x-ideawave-board-id"],R=typeof x==="string"&&x.trim().length>0?x.trim():null,b=z.headers["x-ideawave-run-folder"],S=typeof b==="string"&&b.trim().length>0?b.trim():null,n=$6(z,M);if(Z.size>=t1)await j();let Z0=null,m=new a3({sessionIdGenerator:()=>u3(),onsessioninitialized:(l)=>{Z0=l,Z.set(l,{transport:m,lastActivity:Date.now()})},onsessionclosed:(l)=>{Z.delete(l)}});m.onclose=()=>{if(m.sessionId)Z.delete(m.sessionId)};try{await $.buildServer({userId:A,frontendSessionId:_,boardId:R,toolSurface:K,cardId:w,runFolder:S,clientHint:n}).connect(m)}catch(l){if(console.error("[mcp] buildServer/connect failed",l),Z0)Z.delete(Z0);await m.close().catch(()=>{return}),g(H,500,F$,"server-init-failed");return}B=m}else{g(H,400,d,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await B.handleRequest(z,H,M)}catch(L){if(console.error("[mcp] transport.handleRequest threw",L),!H.headersSent)g(H,500,F$,"internal")}})().catch((V)=>{console.error("[mcp] unhandled request handler error:",V)})});return X=await e3(G,r3($.port)),{url:`http://127.0.0.1:${X}${o1}`,port:X,close:async()=>{clearInterval(W);for(let z of Z.values())await z.transport.close().catch(()=>{return});Z.clear(),await new Promise((z)=>G.close(()=>z()))}}}var Q6={name:"ideawave-board",version:"1.0.0"},E0="list_run_folder",T0="read_run_folder_file",X2=new Set(["list_boards","get_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",E0,T0]),j6=[{name:E0,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:T0,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 P$($){return{content:[{type:"text",text:$}]}}function W6($){return P$(JSON.stringify($,null,2))}function $2($){return{...P$($),isError:!0}}function K6($,Z,X="full"){return $.getMetadata(Z).filter((J)=>X!=="read"||X2.has(C0(J.name))).map((J)=>({name:J.name,description:J.description,inputSchema:J.inputSchema}))}function V6($,Z,X={}){let J=K6($,Z,X.toolSurface??"full");return X.includeRunFolderTools?[...J,...j6]:J}function Z2($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let X=$[Z];return typeof X==="string"?X:null}async function Y6($,Z,X){if(X&&X.trim().length>0)return X.trim();if(!$||!Z)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await e({boardId:$,cardId:Z})).runFolder}async function M6($){let Z=await Y6($.boardId,$.cardId,$.runFolder);if($.name===E0){let X=Z2($.args,"path")??"",J=await a$(Z,X);return W6(J)}if($.name===T0){let X=Z2($.args,"path");if(!X)return $2("read_run_folder_file requires a path.");return P$(await k0(Z,X))}return $2(`Unknown local tool "${$.name}"`)}function G6($,Z,X,J,Q,j="full"){let W=new Z6(Q6,{capabilities:{tools:{}}});return W.setRequestHandler(J6,async()=>({tools:V6($,Z,{includeRunFolderTools:Boolean(Q||X&&J),toolSurface:j})})),W.setRequestHandler(X6,async(G)=>{let{name:Y,arguments:z}=G.params,H=C0(Y);try{if(H===E0||H===T0)return await M6({name:H,args:z,boardId:X,cardId:J,runFolder:Q});if(j==="read"&&!X2.has(H))throw Error(`Tool "${Y}" is not available in read-only mode`);let V=await $.callTool(Z,H,z??{},void 0,J??void 0);if(V&&typeof V==="object"&&Array.isArray(V.content))return V;return{content:[{type:"text",text:typeof V==="string"?V:JSON.stringify(V)}]}}catch(V){return{content:[{type:"text",text:V instanceof Error?V.message:"Tool call failed"}],isError:!0}}}),W}function J2($,Z){return e1({buildServer:(X)=>G6($,X.frontendSessionId,X.boardId,X.cardId,X.runFolder,X.toolSurface),port:Z})}import I0 from"node:fs/promises";import A$ from"node:os";import v0 from"node:path";var Q2=new Map,L$=new Map,z6=30000;function y0($,Z){let X=Q2.get($);if(X&&X.expiresAt>Date.now())return Promise.resolve(X.value);let J=L$.get($);if(J)return J;let Q=Z().then((j)=>{return Q2.set($,{value:j,expiresAt:Date.now()+z6}),j}).finally(()=>{L$.delete($)});return L$.set($,Q),Q}async function j2($){let Z=await Promise.all(Q0().map((j)=>y0(j.id,async()=>({adapterId:j.id,...await j.checkReadiness({id:"__probe__",kind:"registered",adapterId:j.id,displayName:j.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null})})))),J=(await v($)).runtimes.filter((j)=>j.kind==="custom"),Q=await Promise.all(J.map((j)=>y0(`custom:${j.id}`,async()=>({adapterId:j.id,...await c(j).checkReadiness(j)}))));return[...Z,...Q]}async function W2($,Z){let X=Q0().find((j)=>j.id===$);if(X)return y0(X.id,async()=>({adapterId:X.id,...await X.checkReadiness({id:"__probe__",kind:"registered",adapterId:X.id,displayName:X.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null})}));let Q=(await v(Z)).runtimes.find((j)=>j.id===$);if(!Q||Q.kind!=="custom")return null;return y0(`custom:${Q.id}`,async()=>({adapterId:Q.id,...await c(Q).checkReadiness(Q)}))}function K2(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function H6(){let[$,Z]=await Promise.all([v(),j2()]),X=$.globalDefaultConfigId?$.runtimes.find((J)=>J.id===$.globalDefaultConfigId)??null:null;return{runtimes:$.runtimes,globalDefaultConfigId:$.globalDefaultConfigId,globalDefaultEffective:X?{runFolder:X.runFolder??A$.homedir(),modelId:X.defaultModelId??null,configValues:X.defaultConfigValues??{}}:null,knownAdapters:Q0().map((J)=>({id:J.id,displayName:J.displayName})),readiness:Z}}async function D6($){try{let Z=await e({boardId:$.boardId,cardId:$.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 s)return{resolved:null};throw Z}}async function B6($){return h((Z)=>{let X=Z.runtimes.find((j)=>j.kind==="registered"&&j.adapterId===$.adapterId);if(X)return X;let J=Q0().find((j)=>j.id===$.adapterId);if(!J)throw Error(`Unknown adapterId: ${$.adapterId}`);let Q={id:K2(),kind:"registered",adapterId:$.adapterId,displayName:J.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(Q),Q})}async function U6($){return h((Z)=>{let X={id:K2(),kind:"custom",displayName:$.displayName,command:$.command,args:$.args,env:$.env,runFolder:$.runFolder,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(X),X})}async function N6($){await h((Z)=>{if(Z.runtimes=Z.runtimes.filter((X)=>X.id!==$.runtimeConfigId),Z.globalDefaultConfigId===$.runtimeConfigId)Z.globalDefaultConfigId=null;for(let X of Object.keys(Z.boardOverrides))if(Z.boardOverrides[X].runtimeConfigId===$.runtimeConfigId)delete Z.boardOverrides[X];for(let X of Object.keys(Z.cardOverrides))if(Z.cardOverrides[X].runtimeConfigId===$.runtimeConfigId)delete Z.cardOverrides[X]})}async function q6($){await h((Z)=>{let X=Z.runtimes.find((J)=>J.id===$.runtimeConfigId);if(!X)throw Error(`Runtime config not found: ${$.runtimeConfigId}`);if(Z.globalDefaultConfigId=$.runtimeConfigId,$.runFolder!==void 0)X.runFolder=$.runFolder;if($.modelId!==void 0)X.defaultModelId=$.modelId;if($.configValues!==void 0)X.defaultConfigValues=$.configValues})}async function x6($){$.boardId,await h((Z)=>{if($.runtimeConfigId===null){delete Z.cardOverrides[$.cardId];return}if(!Z.runtimes.some((Q)=>Q.id===$.runtimeConfigId))throw Error(`Runtime config not found: ${$.runtimeConfigId}`);let J=Z.cardOverrides[$.cardId];Z.cardOverrides[$.cardId]={runtimeConfigId:$.runtimeConfigId,runFolder:$.runFolder!==void 0?$.runFolder:J?.runFolder??null,modelId:$.modelId!==void 0?$.modelId:J?.modelId??null,configValues:$.configValues!==void 0?$.configValues:J?.configValues??{}}})}async function F6($){let X=(await v()).runtimes.find((W)=>W.id===$.runtimeConfigId);if(!X)throw Error(`Runtime config not found: ${$.runtimeConfigId}`);let J=c(X),Q=await J.resolveSpawnConfig(X),j=X.runFolder??A$.homedir();try{let W=await K1({spawn:{...Q,cwd:j}}),G=x0({adapterId:J.id,models:W.models,currentModelId:W.currentModelId}),Y=new Date().toISOString();return await h((z)=>{let H=z.runtimes.find((V)=>V.id===$.runtimeConfigId);if(H)H.discoveredModels=G,H.discoveredConfigOptions=W.configOptions,H.discoveredAt=Y}),{ok:!0,models:G,configOptions:W.configOptions,currentModelId:W.currentModelId}}catch(W){if(W instanceof X0)throw Error(`${W.message}${J.authHint?` ${J.authHint}`:""}`);if(W instanceof P||W instanceof o)throw Error(W.message);throw W}}async function k6($){let Z=A$.homedir(),X=$.path?.trim()?$.path.trim():Z,J=v0.resolve(X),Q=!0;try{if(!(await I0.stat(J)).isDirectory())J=v0.dirname(J)}catch{Q=!1,J=Z}let j=[];try{j=(await I0.readdir(J,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()&&!Y.name.startsWith(".")).map((Y)=>({name:Y.name,path:v0.join(J,Y.name)})).sort((Y,z)=>Y.name.localeCompare(z.name))}catch{j=[]}let W=v0.dirname(J);return{path:J,parent:W===J?null:W,home:Z,exists:Q,entries:j}}var V2={list:H6,getEffectiveForCard:D6,registerRegistered:B6,registerCustom:U6,unregister:N6,setUserDefault:q6,setCardOverride:x6,refreshModels:F6,browseFolder:k6};var C6=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function P6(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function Y2(){try{let $=await v();if($.globalDefaultConfigId){if($.runtimes.some((X)=>X.id===$.globalDefaultConfigId))return $.globalDefaultConfigId}for(let Z of C6){if((await W2(Z.id))?.status!=="ready")continue;let J=null;if(await h((Q)=>{if(Q.globalDefaultConfigId){if(Q.runtimes.some((G)=>G.id===Q.globalDefaultConfigId)){J=Q.globalDefaultConfigId;return}}let j=Q.runtimes.find((W)=>W.kind==="registered"&&W.adapterId===Z.id);if(!j){let W={id:P6(),kind:"registered",adapterId:Z.id,displayName:Z.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};Q.runtimes.push(W),j=W}Q.globalDefaultConfigId=j.id,J=j.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($){return console.warn("[ideawave-cli] runtime auto-seed failed",$),null}}function L6(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class _${sessions=new Map;createCallId;toolCallTimeoutMs;constructor($={}){this.createCallId=$.createCallId??L6,this.toolCallTimeoutMs=$.toolCallTimeoutMs??120000}register($){let Z=this.sessions.get($.frontendSessionId);if(Z){if(Z.userId!==$.userId)this.rejectPending(Z,"frontend session user changed"),Z.activeRunIds.clear();this.sessions.set($.frontendSessionId,{frontendSessionId:$.frontendSessionId,userId:$.userId,tools:$.tools,send:$.send,pendingToolCalls:Z.pendingToolCalls,activeRunIds:Z.activeRunIds,activeRunCardIds:Z.activeRunCardIds});return}this.sessions.set($.frontendSessionId,{frontendSessionId:$.frontendSessionId,userId:$.userId,tools:$.tools,send:$.send,pendingToolCalls:new Map,activeRunIds:new Set,activeRunCardIds:new Map})}disconnect($,Z="frontend session disconnected"){let X=this.sessions.get($);if(!X)return{activeRunIds:[]};return this.sessions.delete($),this.rejectPending(X,Z),{activeRunIds:Array.from(X.activeRunIds)}}sessionCount(){return this.sessions.size}has($){return this.sessions.has($)}getUserId($){return this.sessions.get($)?.userId??null}setMetadata($,Z){let X=this.sessions.get($);if(X)X.tools=Z}getMetadata($){if(!$)return[];return this.sessions.get($)?.tools??[]}sendToSession($,Z){let X=this.sessions.get($);if(!X)return!1;return X.send(Z),!0}callTool($,Z,X,J,Q){if(!$)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let j=this.sessions.get($);if(!j)return Promise.reject(Error(`Frontend session ${$} is not connected`));let W=this.createCallId();return new Promise((G,Y)=>{let z=setTimeout(()=>{j.pendingToolCalls.delete(W),Y(Error(`Tool "${Z}" timed out waiting for the frontend`))},this.toolCallTimeoutMs),H=J??(Q?this.getActiveRunIdForCard(j,Q):this.getSoleActiveRunId(j)),V=Q??(H?j.activeRunCardIds.get(H):void 0);j.pendingToolCalls.set(W,{resolve:G,reject:Y,timer:z}),j.send({type:"tool_call",callId:W,name:Z,args:X,...H?{runId:H}:{},...V?{cardId:V}:{}})})}handleToolResult($,Z){let X=this.sessions.get($);if(!X)return;let J=X.pendingToolCalls.get(Z.callId);if(!J)return;if(X.pendingToolCalls.delete(Z.callId),clearTimeout(J.timer),Z.ok)J.resolve(Z.result);else J.reject(Error(Z.error??"Tool execution failed"))}markRunActive($,Z,X){let J=this.sessions.get($);if(!J)return;if(J.activeRunIds.add(Z),X)J.activeRunCardIds.set(Z,X)}markRunSettled($,Z){let X=this.sessions.get($);if(!X)return;X.activeRunIds.delete(Z),X.activeRunCardIds.delete(Z)}ownsRun($,Z){return this.sessions.get($)?.activeRunIds.has(Z)??!1}rejectPending($,Z){for(let X of $.pendingToolCalls.values())clearTimeout(X.timer),X.reject(Error(Z));$.pendingToolCalls.clear()}getSoleActiveRunId($){return $.activeRunIds.size===1?$.activeRunIds.values().next().value:void 0}getActiveRunIdForCard($,Z){let X=[...$.activeRunCardIds.entries()].filter(([J,Q])=>$.activeRunIds.has(J)&&Q===Z).map(([J])=>J);return X.length===1?X[0]:void 0}}function A6(){return"0.0.32".trim()?"0.0.32":"dev"}var i=process.argv[2];if(i==="--help"||i==="-h"||i==="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(i==="--version"||i==="-v"||i==="version")console.log(A6()),process.exit(0);if(i)console.error(`Unknown command: ${i}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var z0=new _$,B0=null;function H0($,Z){z0.sendToSession($,Z)}async function _6($,Z){try{let X=V2[Z.method],J=await X(Z.params);H0($,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!0,result:J})}catch(X){H0($,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!1,error:X instanceof Error?X.message:String(X)})}}var D0=!1,G0=null;async function f$(){if(D0)return;if(G0)return G0;return G0=(async()=>{try{let $=await J2(z0);b$({...$,requestedPort:$.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${$.url}`);try{let Z=await l$();for(let X of Z)if(X.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${X.packageName}: ${X.error??"unknown error"}`)}catch(Z){console.warn("[ideawave-cli] ACP bridge setup skipped:",Z instanceof Error?Z.message:String(Z))}await Y2(),D0=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),B0?.sendStatus()}catch($){console.error("[ideawave-cli] failed to start agent host:",$),B0?.sendStatus(void 0,$ instanceof Error?$.message:String($))}finally{G0=null}})(),G0}if(process.env.APP_ENV!=="development"){let $=await p1();if($)console.error(`[ideawave-cli] An IdeaWave CLI is already running at ${$}.`),console.error("[ideawave-cli] Only one CLI per machine is supported — it already serves every browser tab. Exiting."),process.exit(0)}B0=await a1({registry:z0,runtime:null,mcpReady:()=>D0,onToolMetadata:($)=>{console.log(`[ideawave-cli] session ${$} advertised ${z0.getMetadata($).length} tools`),f$()},onRunTurn:($,Z)=>{console.log(`[ideawave-cli] running agent turn for card ${Z.cardId} (session ${$})`),(async()=>{if(await f$(),!D0){H0($,{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 g1(Z,(X)=>H0($,X))})().catch(()=>{return}).finally(()=>z0.markRunSettled($,Z.runId))},onCancelRun:($,Z)=>{N$(Z)},onRuntimeRpc:($,Z)=>{_6($,Z)},onWarmupRun:($,Z,X)=>{(async()=>{if(await f$(),!D0)return{status:"retryable",error:"agent host is not ready"};return h1({cardId:Z.cardId,boardId:Z.boardId,userId:X,frontendSessionId:$})})().then((J)=>{if(!Z.warmupId)return;H0($,{type:"warmup_result",warmupId:Z.warmupId,cardId:Z.cardId,...J})})},onDisconnect:($,Z)=>{y1($);for(let X of Z)N$(X);console.log(`[ideawave-cli] browser session ${$} disconnected`)}});console.log(`[ideawave-cli] browser bridge listening on ${B0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var M2=!1;for(let $ of["SIGINT","SIGTERM"])process.once($,()=>{if(M2)return;M2=!0,I1(),(async()=>{await B0?.close().catch(()=>{return}),process.exit(0)})()});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ideawave",
3
- "version": "0.0.30",
3
+ "version": "0.0.32",
4
4
  "description": "IdeaWave CLI",
5
5
  "type": "module",
6
6
  "bin": {