ideawave 0.0.20 → 0.0.21

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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import{readFileSync as o1}from"node:fs";import{homedir as d1}from"node:os";import{join as x0}from"node:path";function n1(){let $=d1();switch(process.platform){case"win32":return process.env.APPDATA??x0($,"AppData","Roaming");case"darwin":return x0($,"Library","Application Support");default:return process.env.XDG_CONFIG_HOME??x0($,".config")}}function z$(){let $=process.env.IDEAWAVE_MCP_JSON_PATH;if($&&$.trim().length>0)return $;return x0(n1(),"ideawave","mcp.json")}var H$=null;function U$($){H$=$}var s1=86400000;function t1(){let $;try{$=o1(z$(),"utf8")}catch{return null}let Z;try{Z=JSON.parse($)}catch{return null}if(typeof Z.url!=="string")return null;if(typeof Z.startedAt==="string"){let X=Date.parse(Z.startedAt);if(!Number.isNaN(X)){if(Date.now()-X>s1)return null}}if(typeof Z.pid==="number"&&Z.pid>0)try{process.kill(Z.pid,0)}catch(X){if(X?.code!=="EPERM")return null}return{url:Z.url}}function B$($,Z={}){let X=[];if(Z.userId&&Z.userId.trim().length>0)X.push({name:"X-Ideawave-User-Id",value:Z.userId.trim()});if(Z.frontendSessionId&&Z.frontendSessionId.trim().length>0)X.push({name:"X-Ideawave-Frontend-Session-Id",value:Z.frontendSessionId.trim()});if(Z.toolSurface==="read")X.push({name:"X-Ideawave-Tool-Surface",value:"read"});if(Z.cardId&&Z.cardId.trim().length>0)X.push({name:"X-Ideawave-Card-Id",value:Z.cardId.trim()});if(Z.boardId&&Z.boardId.trim().length>0)X.push({name:"X-Ideawave-Board-Id",value:Z.boardId.trim()});if(Z.runFolder&&Z.runFolder.trim().length>0)X.push({name:"X-Ideawave-Run-Folder",value:Z.runFolder.trim()});return{type:"http",name:"ideawave-board",url:$,headers:X}}function T0($={}){let Z=H$;if(Z)return B$(Z.url,$);let X=t1();if(!X)return null;return B$(X.url,$)}import{spawn as J2}from"node:child_process";import{closeSync as Q2,existsSync as q$,mkdirSync as w$,openSync as V2,readFileSync as j2,renameSync as W2,rmSync as L$,statSync as G2,unlinkSync as K2,writeFileSync as M2}from"node:fs";import k$ from"node:os";import d from"node:path";import{execFile as Z2}from"node:child_process";import{promisify as X2}from"node:util";import{execFile as r1}from"node:child_process";import{promisify as e1}from"node:util";var $2=e1(r1),b0=new Map,N$=5000;async function C$($,Z=$2){let X=b0.get($);if(X&&X.expiresAt>Date.now())return X.value;let J=process.platform==="win32"?"where":"which";try{let{stdout:Q}=await Z(J,[$],{timeout:2000}),V=Q.split(/\r?\n/).find((Y)=>Y.trim().length>0),W=V?V.trim():null;return b0.set($,{value:W,expiresAt:Date.now()+N$}),W}catch{return b0.set($,{value:null,expiresAt:Date.now()+N$}),null}}class J0 extends Error{code;constructor($,Z){super($);this.name="AcpError",this.code=Z}}class a extends J0{constructor($="No ACP runtime configured"){super($,"RUNTIME_NOT_CONFIGURED");this.name="RuntimeNotConfiguredError"}}class L extends J0{constructor($){super($,"RUNTIME_UNREACHABLE");this.name="RuntimeUnreachableError"}}class r extends J0{authMethods;constructor($,Z){super($,"AUTH_REQUIRED");this.name="AuthRequiredError",this.authMethods=Z}}class i extends J0{constructor($="ACP session timed out"){super($,"SESSION_TIMEOUT");this.name="SessionTimeoutError"}}var M6=X2(Z2);function O($,...Z){return C$($,...Z)}function b($){let Z={};for(let[X,J]of Object.entries(process.env))if(typeof J==="string")Z[X]=J;return{...Z,...$??{}}}var y0=[{adapterId:"claude-code",runtimeBinary:"claude",packageName:"@agentclientprotocol/claude-agent-acp",version:"0.39.0",warmupArgs:["--cli","--help"]},{adapterId:"codex",runtimeBinary:"codex",packageName:"@zed-industries/codex-acp",version:"0.15.0",warmupArgs:["--help"]}],Y2=1800000,v0=new Map;function I0(){if(process.env.IDEAWAVE_ACP_BRIDGE_CACHE_DIR)return process.env.IDEAWAVE_ACP_BRIDGE_CACHE_DIR;if(process.platform==="win32"){let $=process.env.LOCALAPPDATA??d.join(k$.homedir(),"AppData","Local");return d.join($,"ideawave","acp-bridges")}return d.join(process.env.XDG_CACHE_HOME??d.join(k$.homedir(),".cache"),"ideawave","acp-bridges")}function D2($){return $.replace(/^@/,"").replace(/[/\\]/g,"-")}function z0(){return d.join(I0(),"install-state.json")}function g0($){return d.join(I0(),`${D2($.packageName)}@${$.version}.install.lock`)}function h0(){return process.platform==="win32"?"npx.cmd":"npx"}function m0($){return`${$.packageName}@${$.version}`}function F$(){let $=z0();if(!q$($))return{};try{return JSON.parse(j2($,"utf8"))}catch{return{}}}function E0($,Z){let X=I0();w$(X,{recursive:!0});let J=F$();J.bridges={...J.bridges??{},[$.adapterId]:Z},M2(`${z0()}.tmp`,`${JSON.stringify(J,null,2)}
3
3
  `),W2(`${z0()}.tmp`,z0())}function _$($){return y0.find((Z)=>Z.packageName===$)??null}function E($,Z,X){return{adapterId:$.adapterId,packageName:$.packageName,version:$.version,status:Z,...X?{error:X}:{}}}function P$($,Z){return Z?.packageName===$.packageName&&Z.version===$.version}function O$($){try{return Date.now()-G2($).mtimeMs>Y2}catch{return!1}}function x2($){let Z=g0($);if(!q$(Z))return!1;if(O$(Z))return L$(Z,{force:!0}),!1;return!0}function z2($){let Z=g0($);if(w$(d.dirname(Z),{recursive:!0}),O$(Z))L$(Z,{force:!0});try{let X=V2(Z,"wx");return Q2(X),!0}catch{return!1}}function B2($){K2(g0($))}function S0($){let Z=F$().bridges?.[$.adapterId];if(P$($,Z)&&Z.status==="ready")return E($,"ready");if(v0.has($.adapterId)||x2($))return E($,"installing");if(P$($,Z)&&Z.status==="failed")return E($,"failed",Z.error);return E($,"missing")}function H2($){let Z=S0($);if(Z.status==="ready"||Z.status==="installing")return Z;if(!z2($))return E($,"installing");let X=E($,"installing");E0($,X);let J=()=>{},Q=new Promise((G)=>{J=G});v0.set($.adapterId,Q);let V=!1,W=(G)=>{if(V)return;V=!0;try{B2($)}catch{}E0($,G),v0.delete($.adapterId),J(G)},Y;try{Y=J2(h0(),["-y",m0($),...$.warmupArgs],{stdio:"ignore",windowsHide:!0})}catch(G){let K=E($,"failed",G instanceof Error?G.message:String(G));return W(K),K}return Y.on("error",(G)=>{W(E($,"failed",G.message))}),Y.on("close",(G)=>{if(G===0){W(E($,"ready"));return}W(E($,"failed",`npx warmup exited ${G??"null"}`))}),Y.unref(),X}function e($){let Z=_$($);return Z?S0(Z):null}async function f$(){let $=[];for(let Z of y0){if(!await O(Z.runtimeBinary)){$.push(E(Z,"not_needed"));continue}$.push(H2(Z))}return $.filter((Z)=>Z.status!=="not_needed")}function B0($){let Z=_$($);if(!Z)return null;if(S0(Z).status!=="ready")return null;return{command:h0(),args:["-y",m0(Z)],env:{}}}function c0($,Z){if($.command!==h0())return!1;let X=y0.find((J)=>$.args.includes(m0(J)));if(!X)return!1;return E0(X,E(X,"failed",Z)),!0}import{Readable as A2,Writable as R2}from"node:stream";import{ClientSideConnection as I$,ndJsonStream as g$}from"@agentclientprotocol/sdk";import c from"node:fs/promises";import T from"node:path";class V0 extends Error{constructor($){super($);this.name="PathTraversalError"}}class u0 extends Error{constructor($){super($);this.name="HiddenPathError"}}class p0 extends Error{constructor($){super($);this.name="RunFolderFileTooLargeError"}}class Q0 extends Error{constructor($){super($);this.name="RunFolderBinaryFileError"}}var U2=new Set([".bzr",".cache",".claude",".config",".env",".git",".hg",".idea",".obsidian",".svn",".vscode","node_modules"]),A$=1e6,N2=4096,C2=new TextDecoder("utf-8",{fatal:!0});function k2($){return $.split(/[\\/]+/).filter((Z)=>Z.length>0)}function H0($){if(T.isAbsolute($))throw new V0("Absolute paths are not allowed");for(let Z of k2($)){if(Z===".")continue;if(Z==="..")throw new V0("Parent-directory traversal is not allowed");if(Z.startsWith(".")||U2.has(Z))throw new u0(`Path segment "${Z}" is hidden or configuration data`)}}function P2($){H0($);let Z=T.normalize($||".");return Z==="."?"":Z}function q2($,Z,X){let J=T.relative($,Z);if(J===".."||J.startsWith(`..${T.sep}`)||T.isAbsolute(J))throw new V0(`Path "${X}" resolves outside the run folder`);if(J.length>0)H0(J);return J}async function l0($,Z){H0(Z);let X=T.resolve($,Z||"."),J;try{J=await c.realpath(X)}catch(Q){if(Q.code!=="ENOENT")throw Q;let V=T.dirname(X),W=[T.basename(X)];while(V!==$&&V!==T.dirname(V))try{V=await c.realpath(V);break}catch(Y){if(Y.code!=="ENOENT")throw Y;W.unshift(T.basename(V)),V=T.dirname(V)}J=T.join(V,...W)}return q2($,J,Z),J}async function w2($,Z){let X=await c.realpath($);return l0(X,Z)}function L2($){let Z=$.subarray(0,Math.min($.length,N2));if(Z.length===0)return!1;let X=0;for(let J of Z){if(J===0)return!0;let Q=J===9||J===10||J===12||J===13;if(J<32&&!Q)X+=1}return X/Z.length>0.3}async function U0($,Z){let X=await w2($,Z),J=await c.stat(X);if(!J.isFile())throw new Q0(`Path "${Z}" is not a text file`);if(J.size>A$)throw new p0(`File "${Z}" is too large to read (${J.size} bytes, max ${A$} bytes)`);let Q=await c.readFile(X);if(L2(Q))throw new Q0(`File "${Z}" appears to be binary, not text`);try{return C2.decode(Q)}catch{throw new Q0(`File "${Z}" is not valid UTF-8 text`)}}function F2($){if($.isDirectory())return"directory";if($.isFile())return"file";if($.isSymbolicLink())return"symlink";return"other"}function R$($){return $.split(T.sep).join("/")}async function T$($,Z=""){let X=await c.realpath($),J=P2(Z),Q=await l0(X,J),V=await c.readdir(Q,{withFileTypes:!0}),W=[];for(let Y of V){let G=J?T.join(J,Y.name):Y.name;try{H0(G);let K=await l0(X,G),j=await c.stat(K);W.push({name:Y.name,path:R$(G),type:F2(Y),size:Y.isFile()?j.size:null})}catch{}}return W.sort((Y,G)=>{if(Y.type==="directory"&&G.type!=="directory")return-1;if(Y.type!=="directory"&&G.type==="directory")return 1;return Y.name.localeCompare(G.name)}),{path:R$(J),absolutePath:Q,entries:W}}var a0={fs:{readTextFile:!0,writeTextFile:!1},terminal:!1};function b$($){return{readTextFile:async(Z)=>{return{content:await U0($,Z.path)}}}}import{spawn as _2}from"node:child_process";function i0($){let Z=_2($.command,$.args,{cwd:$.cwd,env:$.env,stdio:["pipe","pipe","pipe"]});if(!Z.stdin||!Z.stdout||!Z.stderr)throw Error("Failed to allocate stdio streams for ACP subprocess");let{stdin:X,stdout:J,stderr:Q}=Z,V=4096,W=[],Y=0;Q.on("data",(x)=>{W.push(x),Y+=x.length;while(Y>V*2&&W.length>1){let N=W.shift();if(N)Y-=N.length}});let G=()=>{let x=Buffer.concat(W).toString("utf8");return x.length>V?x.slice(-V):x},K=!1,j=!1,M,z,U=new Promise((x)=>{M=x}),H=new Promise((x)=>{z=x}),D=(x)=>{if(j)return;if(j=!0,M(x),!K)z(x)};return Z.on("exit",(x,N)=>{D({code:x,signal:N,stderr:G()})}),Z.on("error",(x)=>{let N=G(),C=x?.message??String(x);D({code:null,signal:null,stderr:N?`${C}
4
- ${N}`:C})}),{stdin:X,stdout:J,stderr:Q,kill:(x="SIGTERM")=>{if(K)return;K=!0;try{Z.kill(x)}catch{}},waitForExit:U,processCrashed:H}}function d0($){let Z=$?.toLowerCase();if(Z==="completed"||Z==="complete"||Z==="done"||Z==="success"||Z==="succeeded")return"completed";if(Z==="failed"||Z==="error"||Z==="errored")return"failed";return"running"}var O2={delete_node:"Delete card",delete_nodes:"Delete cards",create_code_card:"Create code card",update_code_card:"Update code card",create_note_card:"Create note",update_note_card:"Update note",create_edge:"Create connection",update_edge:"Update connection",delete_edge:"Delete connection",create_flowchart:"Create flowchart",create_agent_card:"Spawn sub-agent",spawn_child_agents:"Spawn sub-agents",list_nodes:"Read board",list_edges:"Read connections",read_file:"Read file"};function n0($){let Z=O2[$];if(Z)return Z;let X=$.replaceAll(/[_-]+/g," ").trim().split(/\s+/);if(X.length>1&&X[0].toLowerCase()==="mcp")X.shift();if(X.length===0)return $;return X.map((J,Q)=>Q===0?J.charAt(0).toUpperCase()+J.slice(1):J).join(" ")}var f2=33;function v$($){let{ctx:Z,appendText:X,appendToolActivity:J}=$,Q=$.flushIntervalMs??f2,V="",W=0,Y=null,G={},K=new Map,j=(w)=>{if(K.set(w.toolCallId,w),!J)return;J({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,entry:w}).catch((B)=>{console.warn("[streamAdapter] appendToolActivity failed",B)})},M=(w)=>{for(let B of K.values()){if(B.status!=="running"||B.rawTitle.toLowerCase()!=="toolsearch")continue;j({...B,status:"completed",completedAt:B.completedAt??w})}},z="",U=0,H=null,D=null,x=(w)=>{if(w===z)return;z=w,U=Date.now(),X({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,text:w}).catch((B)=>{console.warn("[streamAdapter] appendText failed",B)})},N=()=>{if(H!==null)clearTimeout(H),H=null;if(D!==null){let w=D;D=null,x(w)}},C=(w)=>{let B=Date.now()-U;if(B>=Q&&H===null){x(w);return}if(D=w,H===null){let _=Math.max(0,Q-B);H=setTimeout(()=>{H=null,N()},_)}};return{onSessionUpdate:async(w)=>{let B=w.update;switch(G[B.sessionUpdate]=(G[B.sessionUpdate]??0)+1,B.sessionUpdate){case"agent_message_chunk":{if(B.content.type==="text")V+=B.content.text,C(V);else{let _=`agent_message_chunk:${B.content.type}`;G[_]=(G[_]??0)+1}return}case"agent_thought_chunk":return;case"user_message_chunk":return;case"tool_call":{W+=1;let _=typeof B.title==="string"&&B.title.length>0?B.title:"tool",F=d0(B.status),k=new Date().toISOString();M(k),j({toolCallId:B.toolCallId,rawTitle:_,title:n0(_),kind:typeof B.kind==="string"?B.kind:null,status:F,startedAt:k,completedAt:F==="running"?null:k});return}case"tool_call_update":{let _=K.get(B.toolCallId);if(!_){let g=typeof B.title==="string"&&B.title.length>0?B.title:"tool",q=d0(B.status),R=new Date().toISOString();j({toolCallId:B.toolCallId,rawTitle:g,title:n0(g),kind:typeof B.kind==="string"?B.kind:null,status:q,startedAt:R,completedAt:q==="running"?null:R});return}let F=B.status===void 0||B.status===null?_.status:d0(B.status),k=typeof B.title==="string"&&B.title.length>0?B.title:_.rawTitle,f=F==="running"?_.completedAt:_.completedAt??new Date().toISOString();j({..._,rawTitle:k,title:n0(k),kind:typeof B.kind==="string"?B.kind:_.kind,status:F,completedAt:f});return}case"plan":Y=B.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>V,getToolCallCount:()=>W,getLatestPlan:()=>Y,getUpdateTypeCounts:()=>({...G}),flush:N}}var j0=1,E$=-32000;function y$($){if($.awaitingInput)return!1;return $.nowMs-$.lastUpdateMs>$.windowMs}function h$($){if(!$||typeof $!=="object")return!1;return $.code===E$}var T2=300000,b2=90000,v2=5000;function m$(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.20".trim()?"0.0.20":"dev"}}function S$($){if($===j0)return;throw new L(`Unsupported ACP protocol version ${$}; expected ${j0}`)}function c$($){return A2.toWeb($)}function l$($){return R2.toWeb($)}function u$($){let Z=$.configOptions?.find((J)=>J.type==="select"&&(J.category==="model"||J.id==="model"));if(Z&&Array.isArray(Z.options)){let J=[];for(let Q of Z.options)if(Q&&typeof Q==="object"&&"group"in Q){let V=Q.options;if(Array.isArray(V)){for(let W of V)if(W&&typeof W.value==="string"&&typeof W.name==="string")J.push({id:W.value,name:W.name,description:typeof W.description==="string"?W.description:null})}}else if(Q&&typeof Q.value==="string"&&typeof Q.name==="string")J.push({id:Q.value,name:Q.name,description:typeof Q.description==="string"?Q.description:null});if(J.length>0)return J}let X=$.models?.availableModels?.map((J)=>({id:J.modelId,name:J.name??null,description:J.description??null}));return X&&X.length>0?X:null}function E2($,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}async function o0($){let Z=i0($.spawn),X=[],J=0,Q=4096;Z.stderr.on("data",(q)=>{X.push(q),J+=q.length;while(J>Q*2&&X.length>1){let R=X.shift();if(R)J-=R.length}});let V=()=>{let q=Buffer.concat(X).toString("utf8");return q.length>Q?q.slice(-Q):q},W=b$($.spawn.cwd),Y={current:null},G={at:Date.now()},K=l$(Z.stdin),j=c$(Z.stdout),M=g$(K,j),U=new I$((q)=>({requestPermission:async(R)=>{let v=R.options,s=v?.find((X0)=>X0.kind==="allow_once")??v?.find((X0)=>X0.kind==="allow_always");if(s)return{outcome:{outcome:"selected",optionId:s.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(R)=>{G.at=Date.now();let v=Y.current;if(v)await v.onSessionUpdate(R)},readTextFile:W.readTextFile}),M),H=()=>Z.kill();if($.signal)$.signal.addEventListener("abort",H);let D=()=>{if($.signal)$.signal.removeEventListener("abort",H)},x=async(q,R)=>{if(D(),Z.kill(),h$(q))throw new r(q.message??"Authentication required",R);if(q instanceof Error&&q.message==="ACP connection closed"){if($.signal?.aborted)throw new L("ACP session cancelled: abort signal received");let v=await Promise.race([Z.processCrashed,Z.waitForExit,new Promise((s)=>setTimeout(()=>s({stderr:""}),500))]);throw new L(`Runtime process exited before completion: ${v.stderr?.trim()??""}`)}throw q},N;try{N=await U.initialize({protocolVersion:j0,clientCapabilities:a0,clientInfo:m$()})}catch(q){throw await x(q,[]),Error("unreachable")}try{S$(N.protocolVersion)}catch(q){throw D(),Z.kill(),q}let C=N.authMethods?.map((q)=>q.id)??[],w;try{w=await U.newSession({cwd:$.spawn.cwd,mcpServers:$.mcpServers??[]})}catch(q){throw await x(q,C),Error("unreachable")}let B=w.sessionId,_=u$(w),F=$.modelId??w.models?.currentModelId??null;if(F)try{await U.unstable_setSessionModel({sessionId:B,modelId:F})}catch(q){console.warn(`[acp] setSessionModel(${F}) failed; using agent default.`,q instanceof Error?q.message:q)}D();let k=!1,f=async()=>{if(k)return;k=!0,Z.kill(),await Promise.race([Z.waitForExit,new Promise((q)=>setTimeout(q,2000))])},g=!1;return Z.processCrashed.then(()=>{g=!0}),{sessionId:B,availableModels:_,isAlive:()=>!k&&!g,dispose:f,prompt:(q)=>y2({proc:Z,conn:U,sessionId:B,activeAdapter:Y,lastUpdate:G,collectStderrTail:V},q)}}async function y2($,Z){let{proc:X,conn:J,sessionId:Q,activeAdapter:V,lastUpdate:W}=$,Y={boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId},G=v$({ctx:Y,appendText:Z.appendText,appendToolActivity:Z.appendToolActivity});V.current=G,W.at=Date.now();let K=!1,j=null,M=null,z=()=>X.kill();Z.signal.addEventListener("abort",z);let U=Z.timeoutMs??T2;try{let H=async()=>{let C=Z.heartbeatMs??b2,w=Math.min(v2,Math.max(50,Math.floor(C/2)));M=setInterval(()=>{let _=Z.isAwaitingInput?.()??!1;if(_){W.at=Date.now();return}if(y$({nowMs:Date.now(),lastUpdateMs:W.at,windowMs:C,awaitingInput:_}))K=!0,J.cancel({sessionId:Q}).catch(()=>{return}),X.kill()},w);let B=E2(Z.prompt.systemPrompt,Z.prompt.messages);await J.prompt({sessionId:Q,prompt:B}),G.flush()},D=X.waitForExit.then((C)=>({kind:"exited",exit:C})),x=H().then(()=>({kind:"ok"})).catch(async(C)=>{if(C instanceof Error&&C.message==="ACP connection closed")return{kind:"crashed",exit:await Promise.race([X.processCrashed,X.waitForExit])};throw C}),N=await Promise.race([x,X.processCrashed.then((C)=>({kind:"crashed",exit:C})),D,new Promise((C,w)=>{let B=()=>{j=setTimeout(()=>{if(Z.isAwaitingInput?.()){B();return}w({kind:"timeout"})},U)};B()}).catch((C)=>C)]);if(N.kind==="crashed")throw new L(`Runtime process exited before completion: ${N.exit.stderr.trim()}`);if(N.kind==="exited"){if(Z.signal.aborted)throw new L("ACP session cancelled: abort signal received");if(K)throw new i;throw new L(`Runtime process exited unexpectedly: ${N.exit.stderr.trim()}`)}if(N.kind==="timeout"||K)throw new i;return{modelReported:"unknown",finalText:G.getFinalText(),toolCallsExecuted:G.getToolCallCount(),stderrTail:$.collectStderrTail(),updateTypeCounts:G.getUpdateTypeCounts()}}finally{if(j!==null)clearTimeout(j);if(M!==null)clearInterval(M);Z.signal.removeEventListener("abort",z),G.flush(),V.current=null}}var I2=30000;async function p$($){let Z=i0($.spawn),X=l$(Z.stdin),J=c$(Z.stdout),Q=g$(X,J),W=new I$((K)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),Q),Y=()=>Z.kill();if($.signal)$.signal.addEventListener("abort",Y);let G=null;try{let K=(async()=>{let M=await W.initialize({protocolVersion:j0,clientCapabilities:a0,clientInfo:m$()});S$(M.protocolVersion);let z=M.authMethods?.map((x)=>x.id)??[],U;try{U=await W.newSession({cwd:$.spawn.cwd,mcpServers:[]})}catch(x){if(h$(x))throw new r(x.message??"Authentication required",z);throw x}let H=u$(U)??[],D=U.models?.currentModelId??null;return W.cancel({sessionId:U.sessionId}).catch(()=>{return}),{models:H,currentModelId:D}})(),j=new Promise((M,z)=>{G=setTimeout(()=>{z(new i)},I2)});return await Promise.race([K,j])}catch(K){if(K instanceof Error&&K.message==="ACP connection closed")throw new L("Runtime process exited during model discovery.");throw K}finally{if(G)clearTimeout(G);if($.signal)$.signal.removeEventListener("abort",Y);Z.kill()}}var A=new Map,S=null;function N0($){$.then((Z)=>Z.dispose()).catch(()=>{return})}function g2(){if(S!==null)return;S=setInterval(()=>{let $=Date.now();for(let[Z,X]of A){if(X.inUse)continue;if($-X.lastUsed<600000)continue;A.delete(Z),N0(X.sessionPromise)}if(A.size===0&&S!==null)clearInterval(S),S=null},60000),S.unref?.()}function h2(){if(A.size<200)return;let $=null,Z=1/0;for(let[J,Q]of A){if(Q.inUse)continue;if(Q.lastUsed>=Z)continue;$=J,Z=Q.lastUsed}if(!$)return;let X=A.get($);if(!X)return;A.delete($),N0(X.sessionPromise)}function s0($,Z,X){return`${$}:${Z}:${X}`}async function t0($){let Z=A.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{}A.delete($.key)}else A.delete($.key),N0(Z.sessionPromise);let X=$.open();h2(),A.set($.key,{key:$.key,fingerprint:$.fingerprint,sessionPromise:X,lastUsed:Date.now(),inUse:!0}),g2();try{return await X}catch(J){throw A.delete($.key),J}}function r0($,Z=!1){let X=A.get($);if(!X)return;if(Z){A.delete($),N0(X.sessionPromise);return}X.inUse=!1,X.lastUsed=Date.now()}async function m2(){let $=Array.from(A.values());if(A.clear(),S!==null)clearInterval(S),S=null;await Promise.all($.map((Z)=>Z.sessionPromise.then((X)=>X.dispose()).catch(()=>{return})))}function e0($){return[$.adapterId,$.configId??"",$.modelId??"",$.mcpUrl??"",$.runFolder??"",$.toolSurface??"full"].join(" ")}var a$=!1;function S2(){if(a$)return;a$=!0;let $=()=>{m2()};process.once("beforeExit",$),process.once("SIGTERM",$),process.once("SIGINT",$)}S2();import W0 from"node:fs/promises";import p2 from"node:path";import{z as P}from"zod";var i$=P.object({id:P.string(),name:P.string().nullable().default(null),description:P.string().nullable().default(null)}),c2=P.discriminatedUnion("kind",[P.object({id:P.string(),kind:P.literal("registered"),adapterId:P.enum(["claude-code","opencode","codex","copilot"]),displayName:P.string(),runFolder:P.string().nullable(),defaultModelId:P.string().nullable().default(null),discoveredModels:P.array(i$).default([]),discoveredAt:P.string().nullable().default(null)}),P.object({id:P.string(),kind:P.literal("custom"),displayName:P.string(),command:P.string(),args:P.array(P.string()),env:P.record(P.string(),P.string()),runFolder:P.string().nullable(),defaultModelId:P.string().nullable().default(null),discoveredModels:P.array(i$).default([]),discoveredAt:P.string().nullable().default(null)})]),d$=P.object({runtimeConfigId:P.string(),runFolder:P.string().nullable(),modelId:P.string().nullable().default(null)}),C0=P.object({version:P.literal(1),globalDefaultConfigId:P.string().nullable(),runtimes:P.array(c2),boardOverrides:P.record(P.string(),d$).default({}),cardOverrides:P.record(P.string(),d$).default({})});import l2 from"node:os";import k0 from"node:path";function u2(){let $=l2.homedir();switch(process.platform){case"win32":return process.env.APPDATA??k0.join($,"AppData","Roaming");case"darwin":return k0.join($,"Library","Application Support");default:return process.env.XDG_CONFIG_HOME??k0.join($,".config")}}function P0(){let $=process.env.IDEAWAVE_RUNTIME_CONFIG_PATH;if($)return $;return k0.join(u2(),"ideawave","runtimes.json")}var a2={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},n$=new Map;function i2($){return n$.get($)??Promise.resolve()}function d2($,Z){n$.set($,Z)}async function y($){let Z=$??P0(),X;try{X=await W0.readFile(Z,"utf-8")}catch(Q){if(Q.code==="ENOENT")return structuredClone(a2);throw Q}return C0.parse(JSON.parse(X))}async function h($,Z){let X=Z??P0(),J=i2(X).then(async()=>{let Q=await y(X),V=structuredClone(Q),W=await $(V);return await n2(V,X),W});return d2(X,J.catch(()=>{return})),J}async function n2($,Z){let X=Z??P0(),J=p2.dirname(X);await W0.mkdir(J,{recursive:!0});let Q=`${X}.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`,V=JSON.stringify($,null,2);await W0.writeFile(Q,V,"utf-8");try{await W0.rename(Q,X)}catch(W){throw await W0.unlink(Q).catch(()=>{return}),W}}import t2 from"node:fs/promises";import q0 from"node:os";var o$="claude",$$="@agentclientprotocol/claude-agent-acp",s$=["claude-agent-acp","claude-code-acp"],t$="Install Claude Code from https://github.com/anthropics/claude-code",r$={id:"claude-code",displayName:"Claude Code",kind:"registered",resolveSpawnConfig:async()=>{if(!await O(o$))throw new L(`Claude Code CLI not found. ${t$}`);let Z=B0($$);if(Z)return{command:Z.command,args:Z.args,env:b(Z.env)};let X=e($$),J=X?.status==="installing";for(let V of s$){let W=await O(V);if(W&&!J&&X?.status!=="failed")return{command:W,args:[],env:b()}}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 L(Q)},checkReadiness:async()=>{if(!await O(o$))return{status:"not_installed",detail:t$};let Z=e($$);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 s$)if(await O(X))return{status:"ready"};return{status:"not_running",detail:"Installing Claude Code ACP bridge..."}},authHint:"Run `claude login` (or set ANTHROPIC_API_KEY)."};var e$="codex",Z$="@zed-industries/codex-acp",$1="codex-acp",Z1="Install Codex CLI from https://developers.openai.com/codex/cli",X1={id:"codex",displayName:"Codex",kind:"registered",resolveSpawnConfig:async()=>{if(!await O(e$))throw new L(`Codex CLI not found. ${Z1}`);let Z=B0(Z$);if(Z)return{command:Z.command,args:Z.args,env:b(Z.env)};let X=e(Z$),J=X?.status==="installing",Q=await O($1);if(Q&&!J&&X?.status!=="failed")return{command:Q,args:[],env:b()};let V=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 L(V)},checkReadiness:async()=>{if(!await O(e$))return{status:"not_installed",detail:Z1};let Z=e(Z$);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 O($1))return{status:"ready"};return{status:"not_running",detail:"Installing Codex ACP bridge..."}},authHint:"Run `codex login` (or set OPENAI_API_KEY)."};var J1="copilot",Q1="copilot-acp",V1="npm i -g @github/copilot",j1={id:"copilot",displayName:"GitHub Copilot",kind:"registered",resolveSpawnConfig:async()=>{let $=await O(J1);if($)return{command:$,args:["--acp"],env:b()};let Z=await O(Q1);if(Z)return{command:Z,args:[],env:b()};throw new L(`Copilot not installed. Run: ${V1}`)},checkReadiness:async()=>{if(await O(J1))return{status:"ready"};if(await O(Q1))return{status:"ready"};return{status:"not_installed",detail:V1}},authHint:"Run `gh auth login` (or `copilot login`)."};import o2 from"node:fs/promises";function s2($){return $.startsWith("/")||/^[a-zA-Z]:[\\/]/.test($)}async function W1($){if(s2($))try{return await o2.access($),!0}catch{return!1}return await O($)!==null}var G1={id:"custom",displayName:"Custom ACP",kind:"custom",resolveSpawnConfig:async($)=>{if($.kind!=="custom")throw new L("customAdapter received non-custom entry");if(!await W1($.command))throw new L(`custom: command "${$.command}" not found`);return{command:$.command,args:$.args,env:b($.env)}},checkReadiness:async($)=>{if($.kind!=="custom")return{status:"unknown"};return await W1($.command)?{status:"ready"}:{status:"not_installed"}}};var K1="opencode",M1="Install OpenCode from https://opencode.ai",Y1={id:"opencode",displayName:"OpenCode",kind:"registered",resolveSpawnConfig:async()=>{let $=await O(K1);if(!$)throw new L(`OpenCode not installed. ${M1}`);return{command:$,args:["acp"],env:b()}},checkReadiness:async()=>{if(!await O(K1))return{status:"not_installed",detail:M1};return{status:"ready"}},authHint:"Run `opencode auth login <provider>` (or set the provider's API-key env var)."};var D1={"claude-code":r$,opencode:Y1,codex:X1,copilot:j1};function m($){if($.kind==="custom")return G1;let Z=D1[$.adapterId];if(!Z)throw Error(`Unknown registered adapter: ${$.adapterId}`);return Z}function $0(){return Object.values(D1)}async function x1($){let Z={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},X;try{X=await t2.readFile($,"utf-8")}catch(J){if(J.code==="ENOENT")return structuredClone(Z);throw J}return C0.parse(JSON.parse(X))}async function n($){let Z=$.configPath?await x1($.configPath):await y(),X=$.cardId?Z.cardOverrides[$.cardId]:void 0;if(X?.runtimeConfigId){let Q=Z.runtimes.find((V)=>V.id===X.runtimeConfigId);if(Q)return{entry:Q,adapter:m(Q),runFolder:X.runFolder??Q.runFolder??q0.homedir(),modelId:X.modelId??Q.defaultModelId??null}}let J=Z.boardOverrides[$.boardId];if(J?.runtimeConfigId){let Q=Z.runtimes.find((V)=>V.id===J.runtimeConfigId);if(Q)return{entry:Q,adapter:m(Q),runFolder:J.runFolder??Q.runFolder??q0.homedir(),modelId:J.modelId??Q.defaultModelId??null}}if(Z.globalDefaultConfigId){let Q=Z.runtimes.find((V)=>V.id===Z.globalDefaultConfigId);if(Q)return{entry:Q,adapter:m(Q),runFolder:X?.runFolder??J?.runFolder??Q.runFolder??q0.homedir(),modelId:X?.modelId??J?.modelId??Q.defaultModelId??null}}throw new a}async function z1($,Z={}){let J=(Z.configPath?await x1(Z.configPath):await y()).runtimes.find((Q)=>Q.id===$);if(!J)return null;return{entry:J,adapter:m(J),runFolder:J.runFolder??q0.homedir(),modelId:Z.modelId??J.defaultModelId??null}}var o=new Map,X$=new Set;function J$($){o.get($)?.controller.abort()}function B1($){for(let[Z,X]of o){if(X.frontendSessionId!==$)continue;X.controller.abort(),o.delete(Z)}}function H1(){for(let $ of o.values())$.controller.abort();o.clear()}function U1($,Z){if(!Z.availableModels||Z.availableModels.length===0)return;h((X)=>{let J=X.runtimes.find((Q)=>Q.id===$);if(J)J.discoveredModels=Z.availableModels??[]}).catch(()=>{return})}function r2($,Z){return`${$}
4
+ ${N}`:C})}),{stdin:X,stdout:J,stderr:Q,kill:(x="SIGTERM")=>{if(K)return;K=!0;try{Z.kill(x)}catch{}},waitForExit:U,processCrashed:H}}function d0($){let Z=$?.toLowerCase();if(Z==="completed"||Z==="complete"||Z==="done"||Z==="success"||Z==="succeeded")return"completed";if(Z==="failed"||Z==="error"||Z==="errored")return"failed";return"running"}var O2={delete_node:"Delete card",delete_nodes:"Delete cards",create_code_card:"Create code card",update_code_card:"Update code card",create_note_card:"Create note",update_note_card:"Update note",create_edge:"Create connection",update_edge:"Update connection",delete_edge:"Delete connection",create_flowchart:"Create flowchart",create_agent_card:"Spawn sub-agent",spawn_child_agents:"Spawn sub-agents",list_nodes:"Read board",list_edges:"Read connections",read_file:"Read file"};function n0($){let Z=O2[$];if(Z)return Z;let X=$.replaceAll(/[_-]+/g," ").trim().split(/\s+/);if(X.length>1&&X[0].toLowerCase()==="mcp")X.shift();if(X.length===0)return $;return X.map((J,Q)=>Q===0?J.charAt(0).toUpperCase()+J.slice(1):J).join(" ")}var f2=33;function v$($){let{ctx:Z,appendText:X,appendToolActivity:J}=$,Q=$.flushIntervalMs??f2,V="",W=0,Y=null,G={},K=new Map,j=(w)=>{if(K.set(w.toolCallId,w),!J)return;J({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,entry:w}).catch((B)=>{console.warn("[streamAdapter] appendToolActivity failed",B)})},M=(w)=>{for(let B of K.values()){if(B.status!=="running"||B.rawTitle.toLowerCase()!=="toolsearch")continue;j({...B,status:"completed",completedAt:B.completedAt??w})}},z="",U=0,H=null,D=null,x=(w)=>{if(w===z)return;z=w,U=Date.now(),X({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,text:w}).catch((B)=>{console.warn("[streamAdapter] appendText failed",B)})},N=()=>{if(H!==null)clearTimeout(H),H=null;if(D!==null){let w=D;D=null,x(w)}},C=(w)=>{let B=Date.now()-U;if(B>=Q&&H===null){x(w);return}if(D=w,H===null){let _=Math.max(0,Q-B);H=setTimeout(()=>{H=null,N()},_)}};return{onSessionUpdate:async(w)=>{let B=w.update;switch(G[B.sessionUpdate]=(G[B.sessionUpdate]??0)+1,B.sessionUpdate){case"agent_message_chunk":{if(B.content.type==="text")V+=B.content.text,C(V);else{let _=`agent_message_chunk:${B.content.type}`;G[_]=(G[_]??0)+1}return}case"agent_thought_chunk":return;case"user_message_chunk":return;case"tool_call":{W+=1;let _=typeof B.title==="string"&&B.title.length>0?B.title:"tool",F=d0(B.status),k=new Date().toISOString();M(k),j({toolCallId:B.toolCallId,rawTitle:_,title:n0(_),kind:typeof B.kind==="string"?B.kind:null,status:F,startedAt:k,completedAt:F==="running"?null:k});return}case"tool_call_update":{let _=K.get(B.toolCallId);if(!_){let g=typeof B.title==="string"&&B.title.length>0?B.title:"tool",q=d0(B.status),R=new Date().toISOString();j({toolCallId:B.toolCallId,rawTitle:g,title:n0(g),kind:typeof B.kind==="string"?B.kind:null,status:q,startedAt:R,completedAt:q==="running"?null:R});return}let F=B.status===void 0||B.status===null?_.status:d0(B.status),k=typeof B.title==="string"&&B.title.length>0?B.title:_.rawTitle,f=F==="running"?_.completedAt:_.completedAt??new Date().toISOString();j({..._,rawTitle:k,title:n0(k),kind:typeof B.kind==="string"?B.kind:_.kind,status:F,completedAt:f});return}case"plan":Y=B.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>V,getToolCallCount:()=>W,getLatestPlan:()=>Y,getUpdateTypeCounts:()=>({...G}),flush:N}}var j0=1,E$=-32000;function y$($){if($.awaitingInput)return!1;return $.nowMs-$.lastUpdateMs>$.windowMs}function h$($){if(!$||typeof $!=="object")return!1;return $.code===E$}var T2=300000,b2=90000,v2=5000;function m$(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.21".trim()?"0.0.21":"dev"}}function S$($){if($===j0)return;throw new L(`Unsupported ACP protocol version ${$}; expected ${j0}`)}function c$($){return A2.toWeb($)}function l$($){return R2.toWeb($)}function u$($){let Z=$.configOptions?.find((J)=>J.type==="select"&&(J.category==="model"||J.id==="model"));if(Z&&Array.isArray(Z.options)){let J=[];for(let Q of Z.options)if(Q&&typeof Q==="object"&&"group"in Q){let V=Q.options;if(Array.isArray(V)){for(let W of V)if(W&&typeof W.value==="string"&&typeof W.name==="string")J.push({id:W.value,name:W.name,description:typeof W.description==="string"?W.description:null})}}else if(Q&&typeof Q.value==="string"&&typeof Q.name==="string")J.push({id:Q.value,name:Q.name,description:typeof Q.description==="string"?Q.description:null});if(J.length>0)return J}let X=$.models?.availableModels?.map((J)=>({id:J.modelId,name:J.name??null,description:J.description??null}));return X&&X.length>0?X:null}function E2($,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}async function o0($){let Z=i0($.spawn),X=[],J=0,Q=4096;Z.stderr.on("data",(q)=>{X.push(q),J+=q.length;while(J>Q*2&&X.length>1){let R=X.shift();if(R)J-=R.length}});let V=()=>{let q=Buffer.concat(X).toString("utf8");return q.length>Q?q.slice(-Q):q},W=b$($.spawn.cwd),Y={current:null},G={at:Date.now()},K=l$(Z.stdin),j=c$(Z.stdout),M=g$(K,j),U=new I$((q)=>({requestPermission:async(R)=>{let v=R.options,s=v?.find((X0)=>X0.kind==="allow_once")??v?.find((X0)=>X0.kind==="allow_always");if(s)return{outcome:{outcome:"selected",optionId:s.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(R)=>{G.at=Date.now();let v=Y.current;if(v)await v.onSessionUpdate(R)},readTextFile:W.readTextFile}),M),H=()=>Z.kill();if($.signal)$.signal.addEventListener("abort",H);let D=()=>{if($.signal)$.signal.removeEventListener("abort",H)},x=async(q,R)=>{if(D(),Z.kill(),h$(q))throw new r(q.message??"Authentication required",R);if(q instanceof Error&&q.message==="ACP connection closed"){if($.signal?.aborted)throw new L("ACP session cancelled: abort signal received");let v=await Promise.race([Z.processCrashed,Z.waitForExit,new Promise((s)=>setTimeout(()=>s({stderr:""}),500))]);throw new L(`Runtime process exited before completion: ${v.stderr?.trim()??""}`)}throw q},N;try{N=await U.initialize({protocolVersion:j0,clientCapabilities:a0,clientInfo:m$()})}catch(q){throw await x(q,[]),Error("unreachable")}try{S$(N.protocolVersion)}catch(q){throw D(),Z.kill(),q}let C=N.authMethods?.map((q)=>q.id)??[],w;try{w=await U.newSession({cwd:$.spawn.cwd,mcpServers:$.mcpServers??[]})}catch(q){throw await x(q,C),Error("unreachable")}let B=w.sessionId,_=u$(w),F=$.modelId??w.models?.currentModelId??null;if(F)try{await U.unstable_setSessionModel({sessionId:B,modelId:F})}catch(q){console.warn(`[acp] setSessionModel(${F}) failed; using agent default.`,q instanceof Error?q.message:q)}D();let k=!1,f=async()=>{if(k)return;k=!0,Z.kill(),await Promise.race([Z.waitForExit,new Promise((q)=>setTimeout(q,2000))])},g=!1;return Z.processCrashed.then(()=>{g=!0}),{sessionId:B,availableModels:_,isAlive:()=>!k&&!g,dispose:f,prompt:(q)=>y2({proc:Z,conn:U,sessionId:B,activeAdapter:Y,lastUpdate:G,collectStderrTail:V},q)}}async function y2($,Z){let{proc:X,conn:J,sessionId:Q,activeAdapter:V,lastUpdate:W}=$,Y={boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId},G=v$({ctx:Y,appendText:Z.appendText,appendToolActivity:Z.appendToolActivity});V.current=G,W.at=Date.now();let K=!1,j=null,M=null,z=()=>X.kill();Z.signal.addEventListener("abort",z);let U=Z.timeoutMs??T2;try{let H=async()=>{let C=Z.heartbeatMs??b2,w=Math.min(v2,Math.max(50,Math.floor(C/2)));M=setInterval(()=>{let _=Z.isAwaitingInput?.()??!1;if(_){W.at=Date.now();return}if(y$({nowMs:Date.now(),lastUpdateMs:W.at,windowMs:C,awaitingInput:_}))K=!0,J.cancel({sessionId:Q}).catch(()=>{return}),X.kill()},w);let B=E2(Z.prompt.systemPrompt,Z.prompt.messages);await J.prompt({sessionId:Q,prompt:B}),G.flush()},D=X.waitForExit.then((C)=>({kind:"exited",exit:C})),x=H().then(()=>({kind:"ok"})).catch(async(C)=>{if(C instanceof Error&&C.message==="ACP connection closed")return{kind:"crashed",exit:await Promise.race([X.processCrashed,X.waitForExit])};throw C}),N=await Promise.race([x,X.processCrashed.then((C)=>({kind:"crashed",exit:C})),D,new Promise((C,w)=>{let B=()=>{j=setTimeout(()=>{if(Z.isAwaitingInput?.()){B();return}w({kind:"timeout"})},U)};B()}).catch((C)=>C)]);if(N.kind==="crashed")throw new L(`Runtime process exited before completion: ${N.exit.stderr.trim()}`);if(N.kind==="exited"){if(Z.signal.aborted)throw new L("ACP session cancelled: abort signal received");if(K)throw new i;throw new L(`Runtime process exited unexpectedly: ${N.exit.stderr.trim()}`)}if(N.kind==="timeout"||K)throw new i;return{modelReported:"unknown",finalText:G.getFinalText(),toolCallsExecuted:G.getToolCallCount(),stderrTail:$.collectStderrTail(),updateTypeCounts:G.getUpdateTypeCounts()}}finally{if(j!==null)clearTimeout(j);if(M!==null)clearInterval(M);Z.signal.removeEventListener("abort",z),G.flush(),V.current=null}}var I2=30000;async function p$($){let Z=i0($.spawn),X=l$(Z.stdin),J=c$(Z.stdout),Q=g$(X,J),W=new I$((K)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),Q),Y=()=>Z.kill();if($.signal)$.signal.addEventListener("abort",Y);let G=null;try{let K=(async()=>{let M=await W.initialize({protocolVersion:j0,clientCapabilities:a0,clientInfo:m$()});S$(M.protocolVersion);let z=M.authMethods?.map((x)=>x.id)??[],U;try{U=await W.newSession({cwd:$.spawn.cwd,mcpServers:[]})}catch(x){if(h$(x))throw new r(x.message??"Authentication required",z);throw x}let H=u$(U)??[],D=U.models?.currentModelId??null;return W.cancel({sessionId:U.sessionId}).catch(()=>{return}),{models:H,currentModelId:D}})(),j=new Promise((M,z)=>{G=setTimeout(()=>{z(new i)},I2)});return await Promise.race([K,j])}catch(K){if(K instanceof Error&&K.message==="ACP connection closed")throw new L("Runtime process exited during model discovery.");throw K}finally{if(G)clearTimeout(G);if($.signal)$.signal.removeEventListener("abort",Y);Z.kill()}}var A=new Map,S=null;function N0($){$.then((Z)=>Z.dispose()).catch(()=>{return})}function g2(){if(S!==null)return;S=setInterval(()=>{let $=Date.now();for(let[Z,X]of A){if(X.inUse)continue;if($-X.lastUsed<600000)continue;A.delete(Z),N0(X.sessionPromise)}if(A.size===0&&S!==null)clearInterval(S),S=null},60000),S.unref?.()}function h2(){if(A.size<200)return;let $=null,Z=1/0;for(let[J,Q]of A){if(Q.inUse)continue;if(Q.lastUsed>=Z)continue;$=J,Z=Q.lastUsed}if(!$)return;let X=A.get($);if(!X)return;A.delete($),N0(X.sessionPromise)}function s0($,Z,X){return`${$}:${Z}:${X}`}async function t0($){let Z=A.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{}A.delete($.key)}else A.delete($.key),N0(Z.sessionPromise);let X=$.open();h2(),A.set($.key,{key:$.key,fingerprint:$.fingerprint,sessionPromise:X,lastUsed:Date.now(),inUse:!0}),g2();try{return await X}catch(J){throw A.delete($.key),J}}function r0($,Z=!1){let X=A.get($);if(!X)return;if(Z){A.delete($),N0(X.sessionPromise);return}X.inUse=!1,X.lastUsed=Date.now()}async function m2(){let $=Array.from(A.values());if(A.clear(),S!==null)clearInterval(S),S=null;await Promise.all($.map((Z)=>Z.sessionPromise.then((X)=>X.dispose()).catch(()=>{return})))}function e0($){return[$.adapterId,$.configId??"",$.modelId??"",$.mcpUrl??"",$.runFolder??"",$.toolSurface??"full"].join(" ")}var a$=!1;function S2(){if(a$)return;a$=!0;let $=()=>{m2()};process.once("beforeExit",$),process.once("SIGTERM",$),process.once("SIGINT",$)}S2();import W0 from"node:fs/promises";import p2 from"node:path";import{z as P}from"zod";var i$=P.object({id:P.string(),name:P.string().nullable().default(null),description:P.string().nullable().default(null)}),c2=P.discriminatedUnion("kind",[P.object({id:P.string(),kind:P.literal("registered"),adapterId:P.enum(["claude-code","opencode","codex","copilot"]),displayName:P.string(),runFolder:P.string().nullable(),defaultModelId:P.string().nullable().default(null),discoveredModels:P.array(i$).default([]),discoveredAt:P.string().nullable().default(null)}),P.object({id:P.string(),kind:P.literal("custom"),displayName:P.string(),command:P.string(),args:P.array(P.string()),env:P.record(P.string(),P.string()),runFolder:P.string().nullable(),defaultModelId:P.string().nullable().default(null),discoveredModels:P.array(i$).default([]),discoveredAt:P.string().nullable().default(null)})]),d$=P.object({runtimeConfigId:P.string(),runFolder:P.string().nullable(),modelId:P.string().nullable().default(null)}),C0=P.object({version:P.literal(1),globalDefaultConfigId:P.string().nullable(),runtimes:P.array(c2),boardOverrides:P.record(P.string(),d$).default({}),cardOverrides:P.record(P.string(),d$).default({})});import l2 from"node:os";import k0 from"node:path";function u2(){let $=l2.homedir();switch(process.platform){case"win32":return process.env.APPDATA??k0.join($,"AppData","Roaming");case"darwin":return k0.join($,"Library","Application Support");default:return process.env.XDG_CONFIG_HOME??k0.join($,".config")}}function P0(){let $=process.env.IDEAWAVE_RUNTIME_CONFIG_PATH;if($)return $;return k0.join(u2(),"ideawave","runtimes.json")}var a2={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},n$=new Map;function i2($){return n$.get($)??Promise.resolve()}function d2($,Z){n$.set($,Z)}async function y($){let Z=$??P0(),X;try{X=await W0.readFile(Z,"utf-8")}catch(Q){if(Q.code==="ENOENT")return structuredClone(a2);throw Q}return C0.parse(JSON.parse(X))}async function h($,Z){let X=Z??P0(),J=i2(X).then(async()=>{let Q=await y(X),V=structuredClone(Q),W=await $(V);return await n2(V,X),W});return d2(X,J.catch(()=>{return})),J}async function n2($,Z){let X=Z??P0(),J=p2.dirname(X);await W0.mkdir(J,{recursive:!0});let Q=`${X}.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`,V=JSON.stringify($,null,2);await W0.writeFile(Q,V,"utf-8");try{await W0.rename(Q,X)}catch(W){throw await W0.unlink(Q).catch(()=>{return}),W}}import t2 from"node:fs/promises";import q0 from"node:os";var o$="claude",$$="@agentclientprotocol/claude-agent-acp",s$=["claude-agent-acp","claude-code-acp"],t$="Install Claude Code from https://github.com/anthropics/claude-code",r$={id:"claude-code",displayName:"Claude Code",kind:"registered",resolveSpawnConfig:async()=>{if(!await O(o$))throw new L(`Claude Code CLI not found. ${t$}`);let Z=B0($$);if(Z)return{command:Z.command,args:Z.args,env:b(Z.env)};let X=e($$),J=X?.status==="installing";for(let V of s$){let W=await O(V);if(W&&!J&&X?.status!=="failed")return{command:W,args:[],env:b()}}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 L(Q)},checkReadiness:async()=>{if(!await O(o$))return{status:"not_installed",detail:t$};let Z=e($$);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 s$)if(await O(X))return{status:"ready"};return{status:"not_running",detail:"Installing Claude Code ACP bridge..."}},authHint:"Run `claude login` (or set ANTHROPIC_API_KEY)."};var e$="codex",Z$="@zed-industries/codex-acp",$1="codex-acp",Z1="Install Codex CLI from https://developers.openai.com/codex/cli",X1={id:"codex",displayName:"Codex",kind:"registered",resolveSpawnConfig:async()=>{if(!await O(e$))throw new L(`Codex CLI not found. ${Z1}`);let Z=B0(Z$);if(Z)return{command:Z.command,args:Z.args,env:b(Z.env)};let X=e(Z$),J=X?.status==="installing",Q=await O($1);if(Q&&!J&&X?.status!=="failed")return{command:Q,args:[],env:b()};let V=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 L(V)},checkReadiness:async()=>{if(!await O(e$))return{status:"not_installed",detail:Z1};let Z=e(Z$);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 O($1))return{status:"ready"};return{status:"not_running",detail:"Installing Codex ACP bridge..."}},authHint:"Run `codex login` (or set OPENAI_API_KEY)."};var J1="copilot",Q1="copilot-acp",V1="npm i -g @github/copilot",j1={id:"copilot",displayName:"GitHub Copilot",kind:"registered",resolveSpawnConfig:async()=>{let $=await O(J1);if($)return{command:$,args:["--acp"],env:b()};let Z=await O(Q1);if(Z)return{command:Z,args:[],env:b()};throw new L(`Copilot not installed. Run: ${V1}`)},checkReadiness:async()=>{if(await O(J1))return{status:"ready"};if(await O(Q1))return{status:"ready"};return{status:"not_installed",detail:V1}},authHint:"Run `gh auth login` (or `copilot login`)."};import o2 from"node:fs/promises";function s2($){return $.startsWith("/")||/^[a-zA-Z]:[\\/]/.test($)}async function W1($){if(s2($))try{return await o2.access($),!0}catch{return!1}return await O($)!==null}var G1={id:"custom",displayName:"Custom ACP",kind:"custom",resolveSpawnConfig:async($)=>{if($.kind!=="custom")throw new L("customAdapter received non-custom entry");if(!await W1($.command))throw new L(`custom: command "${$.command}" not found`);return{command:$.command,args:$.args,env:b($.env)}},checkReadiness:async($)=>{if($.kind!=="custom")return{status:"unknown"};return await W1($.command)?{status:"ready"}:{status:"not_installed"}}};var K1="opencode",M1="Install OpenCode from https://opencode.ai",Y1={id:"opencode",displayName:"OpenCode",kind:"registered",resolveSpawnConfig:async()=>{let $=await O(K1);if(!$)throw new L(`OpenCode not installed. ${M1}`);return{command:$,args:["acp"],env:b()}},checkReadiness:async()=>{if(!await O(K1))return{status:"not_installed",detail:M1};return{status:"ready"}},authHint:"Run `opencode auth login <provider>` (or set the provider's API-key env var)."};var D1={"claude-code":r$,opencode:Y1,codex:X1,copilot:j1};function m($){if($.kind==="custom")return G1;let Z=D1[$.adapterId];if(!Z)throw Error(`Unknown registered adapter: ${$.adapterId}`);return Z}function $0(){return Object.values(D1)}async function x1($){let Z={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},X;try{X=await t2.readFile($,"utf-8")}catch(J){if(J.code==="ENOENT")return structuredClone(Z);throw J}return C0.parse(JSON.parse(X))}async function n($){let Z=$.configPath?await x1($.configPath):await y(),X=$.cardId?Z.cardOverrides[$.cardId]:void 0;if(X?.runtimeConfigId){let Q=Z.runtimes.find((V)=>V.id===X.runtimeConfigId);if(Q)return{entry:Q,adapter:m(Q),runFolder:X.runFolder??Q.runFolder??q0.homedir(),modelId:X.modelId??Q.defaultModelId??null}}let J=Z.boardOverrides[$.boardId];if(J?.runtimeConfigId){let Q=Z.runtimes.find((V)=>V.id===J.runtimeConfigId);if(Q)return{entry:Q,adapter:m(Q),runFolder:J.runFolder??Q.runFolder??q0.homedir(),modelId:J.modelId??Q.defaultModelId??null}}if(Z.globalDefaultConfigId){let Q=Z.runtimes.find((V)=>V.id===Z.globalDefaultConfigId);if(Q)return{entry:Q,adapter:m(Q),runFolder:X?.runFolder??J?.runFolder??Q.runFolder??q0.homedir(),modelId:X?.modelId??J?.modelId??Q.defaultModelId??null}}throw new a}async function z1($,Z={}){let J=(Z.configPath?await x1(Z.configPath):await y()).runtimes.find((Q)=>Q.id===$);if(!J)return null;return{entry:J,adapter:m(J),runFolder:J.runFolder??q0.homedir(),modelId:Z.modelId??J.defaultModelId??null}}var o=new Map,X$=new Set;function J$($){o.get($)?.controller.abort()}function B1($){for(let[Z,X]of o){if(X.frontendSessionId!==$)continue;X.controller.abort(),o.delete(Z)}}function H1(){for(let $ of o.values())$.controller.abort();o.clear()}function U1($,Z){if(!Z.availableModels||Z.availableModels.length===0)return;h((X)=>{let J=X.runtimes.find((Q)=>Q.id===$);if(J)J.discoveredModels=Z.availableModels??[]}).catch(()=>{return})}function r2($,Z){return`${$}
5
5
 
6
6
  Runtime run folder:
7
7
  - Effective run folder: ${Z}
@@ -11,4 +11,4 @@ Runtime run folder:
11
11
  Connection: close\r
12
12
  Content-Length: ${Buffer.byteLength(X)}\r
13
13
  \r
14
- ${X}`),$.destroy()}function M3($,Z){return new Promise((X,J)=>{let Q=(W)=>{$.off("listening",V),J(W)},V=()=>{$.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",V),$.listen(Z,"127.0.0.1")})}function L1($){return new Promise((Z,X)=>{$.close((J)=>{if(J)X(J);else Z()})})}async function O1($,Z=V$()){let X=new Map,J=new Map,Q=!1,V=(j)=>{let M=J.get(j);if(M)clearTimeout(M);J.delete(j)},W=(j)=>{J.delete(j);let{activeRunIds:M}=$.registry.disconnect(j);$.onDisconnect(j,M)},Y=(j,M)=>{let z={type:"cli_status",connected:!0,runtime:$.runtime,mcpReady:$.mcpReady(),error:M};if(j){let U=X.get(j);if(U)Z0(U,z);return}for(let U of X.values())Z0(U,z)},G=(j,M)=>{let z=M.sessionId.trim(),U=M.userId.trim();if(!z||!U){Z0(j,{type:"cli_status",connected:!1,runtime:$.runtime,mcpReady:$.mcpReady(),error:"Missing frontend session or user id"}),j.close();return}V(z);let H=X.get(z);if(H&&H!==j)H.close();j.data.frontendSessionId=z,X.set(z,j),$.registry.register({frontendSessionId:z,userId:U,tools:M.tools,send:(D)=>Z0(j,D)}),Y(z),$.onToolMetadata?.(z)},K=(j,M)=>{let z=$.registry.getUserId(j);if(!z)return;switch(M.type){case"bridge_ping":{let U=X.get(j);if(U)Z0(U,{type:"bridge_pong"});break}case"tool_metadata":$.registry.setMetadata(j,M.tools),$.onToolMetadata?.(j);break;case"tool_result":$.registry.handleToolResult(j,M);break;case"run_turn":$.registry.markRunActive(j,M.run.runId,M.run.cardId),$.onRunTurn(j,{...M.run,frontendSessionId:j,userId:z});break;case"cancel_run":if($.registry.ownsRun(j,M.runId))$.onCancelRun(j,M.runId);break;case"runtime_rpc":$.onRuntimeRpc(j,M);break;case"warmup_run":$.onWarmupRun(j,{...M,frontendSessionId:j},z);break;default:break}};for(let j of Z){let M=X3((H,D)=>{D.writeHead(404,{"content-type":"text/plain"}),D.end("IdeaWave CLI bridge")}),z=new J3({noServer:!0,maxPayload:q1}),U=(H)=>{if(H.idleTimer)clearTimeout(H.idleTimer);H.idleTimer=setTimeout(()=>{H.close()},Q3),H.idleTimer.unref?.()};z.on("connection",(H)=>{let D=H;D.data={id:Z3(),frontendSessionId:null},D.idleTimer=null,U(D),D.on("ping",()=>U(D)),D.on("pong",()=>U(D)),D.on("message",(x)=>{U(D);let N=G3(x);if(N.length>q1)return;let C=w0(N);if(!C)return;let w=D.data.frontendSessionId;if(!w){if(C.type==="bridge_probe")Z0(D,{type:"bridge_probe_ack",protocolVersion:C.protocolVersion});else if(C.type==="frontend_hello")G(D,C);return}K(w,C)}),D.on("close",()=>{if(D.idleTimer)clearTimeout(D.idleTimer);let x=D.data.frontendSessionId;if(!x)return;if(X.get(x)!==D)return;if(X.delete(x),V(x),Q)return;J.set(x,setTimeout(()=>W(x),V3))})}),M.on("upgrade",(H,D,x)=>{if(new URL(H.url??"/","http://127.0.0.1").pathname!==Q$){w1(D,404,"Not Found");return}if(!W3(K3(H.headers.origin))){w1(D,403,"Forbidden");return}z.handleUpgrade(H,D,x,(C)=>{z.emit("connection",C,H)})});try{let H=await M3(M,j);return{url:`ws://127.0.0.1:${H}${Q$}`,port:H,sendStatus:Y,close:async()=>{Q=!0;for(let D of J.values())clearTimeout(D);J.clear();for(let D of z.clients){let x=D;if(x.idleTimer)clearTimeout(x.idleTimer);x.close()}z.close(),await L1(M).catch(()=>{return})}}}catch(H){if(z.close(),await L1(M).catch(()=>{return}),H?.code==="EADDRINUSE")continue;throw H}}throw Error(`No free IdeaWave CLI bridge port found in ${Z[0]}-${Z.at(-1)}`)}import{Server as L3}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as F3,ListToolsRequestSchema as _3}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as D3}from"node:crypto";import{createServer as x3}from"node:http";import{StreamableHTTPServerTransport as z3}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as T1}from"@modelcontextprotocol/sdk/types.js";var f1=new Set(["127.0.0.1","localhost","[::1]","::1"]);function Y3($){let Z=$.trim();if(Z.length===0)return null;if(Z.startsWith("[")){let V=Z.indexOf("]");if(V===-1)return null;let W=Z.slice(0,V+1),Y=Z.slice(V+1);if(Y.length===0)return{host:W,port:null};if(!Y.startsWith(":"))return null;let G=Number(Y.slice(1));if(!Number.isInteger(G)||G<=0||G>65535)return null;return{host:W,port:G}}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 A1($){return f1.has($)||f1.has($.toLowerCase())}function R1($,Z){let X=$.headers.host;if(typeof X!=="string")return{ok:!1,status:403,reason:"missing-host"};let J=Y3(X);if(!J)return{ok:!1,status:403,reason:"bad-host"};if(!A1(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 V;try{V=new URL(Q)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!A1(V.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var b1="/mcp",B3=43274,E1=16777216,H3=1800000,U3=300000,v1=200,N3=-32700,l=-32600,j$=-32603;function I($,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 W$ extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class G$ extends Error{constructor(){super(`body exceeds ${E1} bytes`);this.name="BodyTooLargeError"}}async function C3($){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 W$}let X=0,J=[];for await(let V of $){let W=typeof V==="string"?Buffer.from(V):V;if(X+=W.byteLength,X>E1)throw new G$;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 k3($){if(Array.isArray($))return $.some(T1);return T1($)}function P3($){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 B3}async function q3($,Z){let X=(Q)=>new Promise((V,W)=>{let Y=(K)=>{$.off("listening",G),W(K)},G=()=>{$.off("error",Y),V()};$.once("error",Y),$.once("listening",G),$.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 w3($,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 V=Q.name;if(typeof V==="string"&&V.trim().length>0)return V.trim()}}}let X=$.headers["user-agent"];if(typeof X==="string"&&X.trim().length>0)return X.trim();return null}async function y1($){let Z=new Map,X=0;function J(K){let j=Z.get(K);if(j)j.lastActivity=Date.now()}async function Q(K,j){Z.delete(K),await j.transport.close().catch(()=>{return})}async function V(){let K=null,j=1/0;for(let[M,z]of Z)if(z.lastActivity<j)j=z.lastActivity,K=M;if(K!==null){let M=Z.get(K);if(M)console.warn(`[mcp] session cap of ${v1} reached; evicting ${K}`),await Q(K,M)}}let W=setInterval(()=>{let K=Date.now()-H3;for(let[j,M]of Z)if(M.lastActivity<K)console.log(`[mcp] sweeping idle session ${j}`),Q(j,M)},U3);W.unref?.();let Y=x3((K,j)=>{(async()=>{let M;try{M=new URL(K.url??"/","http://127.0.0.1").pathname}catch{I(j,400,l,"bad-url");return}if(M!==b1){I(j,404,l,"not-found");return}let z=K.method??"POST";if(z!=="POST"&&z!=="GET"&&z!=="DELETE"){j.setHeader("Allow","GET, POST, DELETE"),I(j,405,l,"method-not-allowed");return}let U=R1(K,X);if(!U.ok){I(j,U.status,l,"forbidden",{reason:U.reason});return}let H=K.headers["mcp-session-id"],D=typeof H==="string"?H:void 0;if(z==="GET"||z==="DELETE"){if(!D||!Z.has(D)){I(j,400,l,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let C=Z.get(D).transport;J(D);try{await C.handleRequest(K,j)}catch(w){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",w),!j.headersSent)I(j,500,j$,"internal")}return}let x;try{x=await C3(K)}catch(C){if(C instanceof W$){I(j,415,l,"expected-application-json");return}if(C instanceof G$){I(j,413,l,"body-too-large");return}I(j,400,N3,"invalid-json");return}let N;if(D&&Z.has(D))N=Z.get(D).transport,J(D);else if(!D&&x!==void 0&&k3(x)){let C=K.headers["x-ideawave-user-id"],w=typeof C==="string"&&C.trim().length>0?C.trim():null,B=K.headers["x-ideawave-frontend-session-id"],_=typeof B==="string"&&B.trim().length>0?B.trim():null,F=K.headers["x-ideawave-tool-surface"],k=typeof F==="string"&&F.trim()==="read"?"read":"full",f=K.headers["x-ideawave-card-id"],g=typeof f==="string"&&f.trim().length>0?f.trim():null,q=K.headers["x-ideawave-board-id"],R=typeof q==="string"&&q.trim().length>0?q.trim():null,v=K.headers["x-ideawave-run-folder"],s=typeof v==="string"&&v.trim().length>0?v.trim():null,X0=w3(K,x);if(Z.size>=v1)await V();let R0=null,p=new z3({sessionIdGenerator:()=>D3(),onsessioninitialized:(t)=>{R0=t,Z.set(t,{transport:p,lastActivity:Date.now()})},onsessionclosed:(t)=>{Z.delete(t)}});p.onclose=()=>{if(p.sessionId)Z.delete(p.sessionId)};try{await $.buildServer({userId:w,frontendSessionId:_,boardId:R,toolSurface:k,cardId:g,runFolder:s,clientHint:X0}).connect(p)}catch(t){if(console.error("[mcp] buildServer/connect failed",t),R0)Z.delete(R0);await p.close().catch(()=>{return}),I(j,500,j$,"server-init-failed");return}N=p}else{I(j,400,l,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await N.handleRequest(K,j,x)}catch(C){if(console.error("[mcp] transport.handleRequest threw",C),!j.headersSent)I(j,500,j$,"internal")}})().catch((M)=>{console.error("[mcp] unhandled request handler error:",M)})});return X=await q3(Y,P3($.port)),{url:`http://127.0.0.1:${X}${b1}`,port:X,close:async()=>{clearInterval(W);for(let K of Z.values())await K.transport.close().catch(()=>{return});Z.clear(),await new Promise((K)=>Y.close(()=>K()))}}}var O3={name:"ideawave-board",version:"1.0.0"},F0="list_run_folder",_0="read_run_folder_file",h1=new Set(["list_boards","get_board","list_nodes","list_edges","inspect_node","list_context_sources","read_context_card","read_context_file","list_context_folder","get_board_wiki","search_board","get_card_messages","list_agent_cards","inspect_neighbors",F0,_0]),f3=[{name:F0,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:_0,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 K$($){return{content:[{type:"text",text:$}]}}function A3($){return K$(JSON.stringify($,null,2))}function I1($){return{...K$($),isError:!0}}function R3($,Z,X="full"){return $.getMetadata(Z).filter((J)=>X!=="read"||h1.has(J.name)).map((J)=>({name:J.name,description:J.description,inputSchema:J.inputSchema}))}function T3($,Z,X={}){let J=R3($,Z,X.toolSurface??"full");return X.includeRunFolderTools?[...J,...f3]:J}function g1($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let X=$[Z];return typeof X==="string"?X:null}async function b3($,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 n({boardId:$,cardId:Z})).runFolder}async function v3($){let Z=await b3($.boardId,$.cardId,$.runFolder);if($.name===F0){let X=g1($.args,"path")??"",J=await T$(Z,X);return A3(J)}if($.name===_0){let X=g1($.args,"path");if(!X)return I1("read_run_folder_file requires a path.");return K$(await U0(Z,X))}return I1(`Unknown local tool "${$.name}"`)}function E3($,Z,X,J,Q,V="full"){let W=new L3(O3,{capabilities:{tools:{}}});return W.setRequestHandler(_3,async()=>({tools:T3($,Z,{includeRunFolderTools:Boolean(Q||X&&J),toolSurface:V})})),W.setRequestHandler(F3,async(Y)=>{let{name:G,arguments:K}=Y.params;try{if(G===F0||G===_0)return await v3({name:G,args:K,boardId:X,cardId:J,runFolder:Q});if(V==="read"&&!h1.has(G))throw Error(`Tool "${G}" is not available in read-only mode`);let j=await $.callTool(Z,G,K??{},void 0,J??void 0);if(j&&typeof j==="object"&&Array.isArray(j.content))return j;return{content:[{type:"text",text:typeof j==="string"?j:JSON.stringify(j)}]}}catch(j){return{content:[{type:"text",text:j instanceof Error?j.message:"Tool call failed"}],isError:!0}}}),W}function m1($,Z){return y1({buildServer:(X)=>E3($,X.frontendSessionId,X.boardId,X.cardId,X.runFolder,X.toolSurface),port:Z})}import f0 from"node:fs/promises";import Y$ from"node:os";import A0 from"node:path";var S1=new Map,M$=new Map,y3=30000;function O0($,Z){let X=S1.get($);if(X&&X.expiresAt>Date.now())return Promise.resolve(X.value);let J=M$.get($);if(J)return J;let Q=Z().then((V)=>{return S1.set($,{value:V,expiresAt:Date.now()+y3}),V}).finally(()=>{M$.delete($)});return M$.set($,Q),Q}async function c1($){let Z=await Promise.all($0().map((V)=>O0(V.id,async()=>({adapterId:V.id,...await V.checkReadiness({id:"__probe__",kind:"registered",adapterId:V.id,displayName:V.displayName,runFolder:null,defaultModelId:null,discoveredModels:[],discoveredAt:null})})))),J=(await y($)).runtimes.filter((V)=>V.kind==="custom"),Q=await Promise.all(J.map((V)=>O0(`custom:${V.id}`,async()=>({adapterId:V.id,...await m(V).checkReadiness(V)}))));return[...Z,...Q]}async function l1($,Z){let X=$0().find((V)=>V.id===$);if(X)return O0(X.id,async()=>({adapterId:X.id,...await X.checkReadiness({id:"__probe__",kind:"registered",adapterId:X.id,displayName:X.displayName,runFolder:null,defaultModelId:null,discoveredModels:[],discoveredAt:null})}));let Q=(await y(Z)).runtimes.find((V)=>V.id===$);if(!Q||Q.kind!=="custom")return null;return O0(`custom:${Q.id}`,async()=>({adapterId:Q.id,...await m(Q).checkReadiness(Q)}))}function u1(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function I3(){let[$,Z]=await Promise.all([y(),c1()]),X=$.globalDefaultConfigId?$.runtimes.find((J)=>J.id===$.globalDefaultConfigId)??null:null;return{runtimes:$.runtimes,globalDefaultConfigId:$.globalDefaultConfigId,globalDefaultEffective:X?{runFolder:X.runFolder??Y$.homedir(),modelId:X.defaultModelId??null}:null,knownAdapters:$0().map((J)=>({id:J.id,displayName:J.displayName})),readiness:Z}}async function g3($){try{let Z=await n({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}}}catch(Z){if(Z instanceof a)return{resolved:null};throw Z}}async function h3($){return h((Z)=>{let X=Z.runtimes.find((V)=>V.kind==="registered"&&V.adapterId===$.adapterId);if(X)return X;let J=$0().find((V)=>V.id===$.adapterId);if(!J)throw Error(`Unknown adapterId: ${$.adapterId}`);let Q={id:u1(),kind:"registered",adapterId:$.adapterId,displayName:J.displayName,runFolder:null,defaultModelId:null,discoveredModels:[],discoveredAt:null};return Z.runtimes.push(Q),Q})}async function m3($){return h((Z)=>{let X={id:u1(),kind:"custom",displayName:$.displayName,command:$.command,args:$.args,env:$.env,runFolder:$.runFolder,defaultModelId:null,discoveredModels:[],discoveredAt:null};return Z.runtimes.push(X),X})}async function S3($){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 c3($){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})}async function l3($){$.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}})}async function u3($){let X=(await y()).runtimes.find((W)=>W.id===$.runtimeConfigId);if(!X)throw Error(`Runtime config not found: ${$.runtimeConfigId}`);let J=m(X),Q=await J.resolveSpawnConfig(X),V=X.runFolder??Y$.homedir();try{let W=await p$({spawn:{...Q,cwd:V}}),Y=new Date().toISOString();return await h((G)=>{let K=G.runtimes.find((j)=>j.id===$.runtimeConfigId);if(K)K.discoveredModels=W.models,K.discoveredAt=Y}),{ok:!0,models:W.models,currentModelId:W.currentModelId}}catch(W){if(W instanceof r)throw Error(`${W.message}${J.authHint?` ${J.authHint}`:""}`);if(W instanceof L||W instanceof i)throw Error(W.message);throw W}}async function p3($){let Z=Y$.homedir(),X=$.path?.trim()?$.path.trim():Z,J=A0.resolve(X),Q=!0;try{if(!(await f0.stat(J)).isDirectory())J=A0.dirname(J)}catch{Q=!1,J=Z}let V=[];try{V=(await f0.readdir(J,{withFileTypes:!0})).filter((G)=>G.isDirectory()&&!G.name.startsWith(".")).map((G)=>({name:G.name,path:A0.join(J,G.name)})).sort((G,K)=>G.name.localeCompare(K.name))}catch{V=[]}let W=A0.dirname(J);return{path:J,parent:W===J?null:W,home:Z,exists:Q,entries:V}}var p1={list:I3,getEffectiveForCard:g3,registerRegistered:h3,registerCustom:m3,unregister:S3,setUserDefault:c3,setCardOverride:l3,refreshModels:u3,browseFolder:p3};var a3=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function i3(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function a1(){try{let $=await y();if($.globalDefaultConfigId){if($.runtimes.some((X)=>X.id===$.globalDefaultConfigId))return $.globalDefaultConfigId}for(let Z of a3){if((await l1(Z.id))?.status!=="ready")continue;let J=null;if(await h((Q)=>{if(Q.globalDefaultConfigId){if(Q.runtimes.some((Y)=>Y.id===Q.globalDefaultConfigId)){J=Q.globalDefaultConfigId;return}}let V=Q.runtimes.find((W)=>W.kind==="registered"&&W.adapterId===Z.id);if(!V){let W={id:i3(),kind:"registered",adapterId:Z.id,displayName:Z.displayName,runFolder:null,defaultModelId:null,discoveredModels:[],discoveredAt:null};Q.runtimes.push(W),V=W}Q.globalDefaultConfigId=V.id,J=V.id}),J)return console.log(`[ideawave-cli] using agent runtime: ${Z.displayName}`),J}return console.warn("[ideawave-cli] no agent runtime detected on PATH (tried claude, codex, gh copilot, opencode). Install one to run agents."),null}catch($){return console.warn("[ideawave-cli] runtime auto-seed failed",$),null}}function d3(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class D${sessions=new Map;createCallId;toolCallTimeoutMs;constructor($={}){this.createCallId=$.createCallId??d3,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 V=this.sessions.get($);if(!V)return Promise.reject(Error(`Frontend session ${$} is not connected`));let W=this.createCallId();return new Promise((Y,G)=>{let K=setTimeout(()=>{V.pendingToolCalls.delete(W),G(Error(`Tool "${Z}" timed out waiting for the frontend`))},this.toolCallTimeoutMs),j=J??(Q?this.getActiveRunIdForCard(V,Q):this.getSoleActiveRunId(V)),M=Q??(j?V.activeRunCardIds.get(j):void 0);V.pendingToolCalls.set(W,{resolve:Y,reject:G,timer:K}),V.send({type:"tool_call",callId:W,name:Z,args:X,...j?{runId:j}:{},...M?{cardId:M}:{}})})}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 n3(){return"0.0.20".trim()?"0.0.20":"dev"}var u=process.argv[2];if(u==="--help"||u==="-h"||u==="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(u==="--version"||u==="-v"||u==="version")console.log(n3()),process.exit(0);if(u)console.error(`Unknown command: ${u}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var K0=new D$,D0=null;function M0($,Z){K0.sendToSession($,Z)}async function o3($,Z){try{let X=p1[Z.method],J=await X(Z.params);M0($,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!0,result:J})}catch(X){M0($,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!1,error:X instanceof Error?X.message:String(X)})}}var Y0=!1,G0=null;async function x$(){if(Y0)return;if(G0)return G0;return G0=(async()=>{try{let $=await m1(K0);U$({...$,requestedPort:$.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${$.url}`);try{let Z=await f$();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 a1(),Y0=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),D0?.sendStatus()}catch($){console.error("[ideawave-cli] failed to start agent host:",$),D0?.sendStatus(void 0,$ instanceof Error?$.message:String($))}finally{G0=null}})(),G0}if(process.env.APP_ENV!=="development"){let $=await _1();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)}D0=await O1({registry:K0,runtime:null,mcpReady:()=>Y0,onToolMetadata:($)=>{console.log(`[ideawave-cli] session ${$} advertised ${K0.getMetadata($).length} tools`),x$()},onRunTurn:($,Z)=>{console.log(`[ideawave-cli] running agent turn for card ${Z.cardId} (session ${$})`),(async()=>{if(await x$(),!Y0){M0($,{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 N1(Z,(X)=>M0($,X))})().catch(()=>{return}).finally(()=>K0.markRunSettled($,Z.runId))},onCancelRun:($,Z)=>{J$(Z)},onRuntimeRpc:($,Z)=>{o3($,Z)},onWarmupRun:($,Z,X)=>{(async()=>{if(await x$(),!Y0)return{status:"retryable",error:"agent host is not ready"};return C1({cardId:Z.cardId,boardId:Z.boardId,userId:X,frontendSessionId:$})})().then((J)=>{if(!Z.warmupId)return;M0($,{type:"warmup_result",warmupId:Z.warmupId,cardId:Z.cardId,...J})})},onDisconnect:($,Z)=>{B1($);for(let X of Z)J$(X);console.log(`[ideawave-cli] browser session ${$} disconnected`)}});console.log(`[ideawave-cli] browser bridge listening on ${D0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var i1=!1;for(let $ of["SIGINT","SIGTERM"])process.once($,()=>{if(i1)return;i1=!0,H1(),(async()=>{await D0?.close().catch(()=>{return}),process.exit(0)})()});
14
+ ${X}`),$.destroy()}function M3($,Z){return new Promise((X,J)=>{let Q=(W)=>{$.off("listening",V),J(W)},V=()=>{$.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",V),$.listen(Z,"127.0.0.1")})}function L1($){return new Promise((Z,X)=>{$.close((J)=>{if(J)X(J);else Z()})})}async function O1($,Z=V$()){let X=new Map,J=new Map,Q=!1,V=(j)=>{let M=J.get(j);if(M)clearTimeout(M);J.delete(j)},W=(j)=>{J.delete(j);let{activeRunIds:M}=$.registry.disconnect(j);$.onDisconnect(j,M)},Y=(j,M)=>{let z={type:"cli_status",connected:!0,runtime:$.runtime,mcpReady:$.mcpReady(),error:M};if(j){let U=X.get(j);if(U)Z0(U,z);return}for(let U of X.values())Z0(U,z)},G=(j,M)=>{let z=M.sessionId.trim(),U=M.userId.trim();if(!z||!U){Z0(j,{type:"cli_status",connected:!1,runtime:$.runtime,mcpReady:$.mcpReady(),error:"Missing frontend session or user id"}),j.close();return}V(z);let H=X.get(z);if(H&&H!==j)H.close();j.data.frontendSessionId=z,X.set(z,j),$.registry.register({frontendSessionId:z,userId:U,tools:M.tools,send:(D)=>Z0(j,D)}),Y(z),$.onToolMetadata?.(z)},K=(j,M)=>{let z=$.registry.getUserId(j);if(!z)return;switch(M.type){case"bridge_ping":{let U=X.get(j);if(U)Z0(U,{type:"bridge_pong"});break}case"tool_metadata":$.registry.setMetadata(j,M.tools),$.onToolMetadata?.(j);break;case"tool_result":$.registry.handleToolResult(j,M);break;case"run_turn":$.registry.markRunActive(j,M.run.runId,M.run.cardId),$.onRunTurn(j,{...M.run,frontendSessionId:j,userId:z});break;case"cancel_run":if($.registry.ownsRun(j,M.runId))$.onCancelRun(j,M.runId);break;case"runtime_rpc":$.onRuntimeRpc(j,M);break;case"warmup_run":$.onWarmupRun(j,{...M,frontendSessionId:j},z);break;default:break}};for(let j of Z){let M=X3((H,D)=>{D.writeHead(404,{"content-type":"text/plain"}),D.end("IdeaWave CLI bridge")}),z=new J3({noServer:!0,maxPayload:q1}),U=(H)=>{if(H.idleTimer)clearTimeout(H.idleTimer);H.idleTimer=setTimeout(()=>{H.close()},Q3),H.idleTimer.unref?.()};z.on("connection",(H)=>{let D=H;D.data={id:Z3(),frontendSessionId:null},D.idleTimer=null,U(D),D.on("ping",()=>U(D)),D.on("pong",()=>U(D)),D.on("message",(x)=>{U(D);let N=G3(x);if(N.length>q1)return;let C=w0(N);if(!C)return;let w=D.data.frontendSessionId;if(!w){if(C.type==="bridge_probe")Z0(D,{type:"bridge_probe_ack",protocolVersion:C.protocolVersion});else if(C.type==="frontend_hello")G(D,C);return}K(w,C)}),D.on("close",()=>{if(D.idleTimer)clearTimeout(D.idleTimer);let x=D.data.frontendSessionId;if(!x)return;if(X.get(x)!==D)return;if(X.delete(x),V(x),Q)return;J.set(x,setTimeout(()=>W(x),V3))})}),M.on("upgrade",(H,D,x)=>{if(new URL(H.url??"/","http://127.0.0.1").pathname!==Q$){w1(D,404,"Not Found");return}if(!W3(K3(H.headers.origin))){w1(D,403,"Forbidden");return}z.handleUpgrade(H,D,x,(C)=>{z.emit("connection",C,H)})});try{let H=await M3(M,j);return{url:`ws://127.0.0.1:${H}${Q$}`,port:H,sendStatus:Y,close:async()=>{Q=!0;for(let D of J.values())clearTimeout(D);J.clear();for(let D of z.clients){let x=D;if(x.idleTimer)clearTimeout(x.idleTimer);x.close()}z.close(),await L1(M).catch(()=>{return})}}}catch(H){if(z.close(),await L1(M).catch(()=>{return}),H?.code==="EADDRINUSE")continue;throw H}}throw Error(`No free IdeaWave CLI bridge port found in ${Z[0]}-${Z.at(-1)}`)}import{Server as L3}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as F3,ListToolsRequestSchema as _3}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as D3}from"node:crypto";import{createServer as x3}from"node:http";import{StreamableHTTPServerTransport as z3}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as T1}from"@modelcontextprotocol/sdk/types.js";var f1=new Set(["127.0.0.1","localhost","[::1]","::1"]);function Y3($){let Z=$.trim();if(Z.length===0)return null;if(Z.startsWith("[")){let V=Z.indexOf("]");if(V===-1)return null;let W=Z.slice(0,V+1),Y=Z.slice(V+1);if(Y.length===0)return{host:W,port:null};if(!Y.startsWith(":"))return null;let G=Number(Y.slice(1));if(!Number.isInteger(G)||G<=0||G>65535)return null;return{host:W,port:G}}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 A1($){return f1.has($)||f1.has($.toLowerCase())}function R1($,Z){let X=$.headers.host;if(typeof X!=="string")return{ok:!1,status:403,reason:"missing-host"};let J=Y3(X);if(!J)return{ok:!1,status:403,reason:"bad-host"};if(!A1(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 V;try{V=new URL(Q)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!A1(V.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var b1="/mcp",B3=43274,E1=16777216,H3=1800000,U3=300000,v1=200,N3=-32700,l=-32600,j$=-32603;function I($,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 W$ extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class G$ extends Error{constructor(){super(`body exceeds ${E1} bytes`);this.name="BodyTooLargeError"}}async function C3($){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 W$}let X=0,J=[];for await(let V of $){let W=typeof V==="string"?Buffer.from(V):V;if(X+=W.byteLength,X>E1)throw new G$;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 k3($){if(Array.isArray($))return $.some(T1);return T1($)}function P3($){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 B3}async function q3($,Z){let X=(Q)=>new Promise((V,W)=>{let Y=(K)=>{$.off("listening",G),W(K)},G=()=>{$.off("error",Y),V()};$.once("error",Y),$.once("listening",G),$.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 w3($,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 V=Q.name;if(typeof V==="string"&&V.trim().length>0)return V.trim()}}}let X=$.headers["user-agent"];if(typeof X==="string"&&X.trim().length>0)return X.trim();return null}async function y1($){let Z=new Map,X=0;function J(K){let j=Z.get(K);if(j)j.lastActivity=Date.now()}async function Q(K,j){Z.delete(K),await j.transport.close().catch(()=>{return})}async function V(){let K=null,j=1/0;for(let[M,z]of Z)if(z.lastActivity<j)j=z.lastActivity,K=M;if(K!==null){let M=Z.get(K);if(M)console.warn(`[mcp] session cap of ${v1} reached; evicting ${K}`),await Q(K,M)}}let W=setInterval(()=>{let K=Date.now()-H3;for(let[j,M]of Z)if(M.lastActivity<K)console.log(`[mcp] sweeping idle session ${j}`),Q(j,M)},U3);W.unref?.();let Y=x3((K,j)=>{(async()=>{let M;try{M=new URL(K.url??"/","http://127.0.0.1").pathname}catch{I(j,400,l,"bad-url");return}if(M!==b1){I(j,404,l,"not-found");return}let z=K.method??"POST";if(z!=="POST"&&z!=="GET"&&z!=="DELETE"){j.setHeader("Allow","GET, POST, DELETE"),I(j,405,l,"method-not-allowed");return}let U=R1(K,X);if(!U.ok){I(j,U.status,l,"forbidden",{reason:U.reason});return}let H=K.headers["mcp-session-id"],D=typeof H==="string"?H:void 0;if(z==="GET"||z==="DELETE"){if(!D||!Z.has(D)){I(j,400,l,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let C=Z.get(D).transport;J(D);try{await C.handleRequest(K,j)}catch(w){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",w),!j.headersSent)I(j,500,j$,"internal")}return}let x;try{x=await C3(K)}catch(C){if(C instanceof W$){I(j,415,l,"expected-application-json");return}if(C instanceof G$){I(j,413,l,"body-too-large");return}I(j,400,N3,"invalid-json");return}let N;if(D&&Z.has(D))N=Z.get(D).transport,J(D);else if(!D&&x!==void 0&&k3(x)){let C=K.headers["x-ideawave-user-id"],w=typeof C==="string"&&C.trim().length>0?C.trim():null,B=K.headers["x-ideawave-frontend-session-id"],_=typeof B==="string"&&B.trim().length>0?B.trim():null,F=K.headers["x-ideawave-tool-surface"],k=typeof F==="string"&&F.trim()==="read"?"read":"full",f=K.headers["x-ideawave-card-id"],g=typeof f==="string"&&f.trim().length>0?f.trim():null,q=K.headers["x-ideawave-board-id"],R=typeof q==="string"&&q.trim().length>0?q.trim():null,v=K.headers["x-ideawave-run-folder"],s=typeof v==="string"&&v.trim().length>0?v.trim():null,X0=w3(K,x);if(Z.size>=v1)await V();let R0=null,p=new z3({sessionIdGenerator:()=>D3(),onsessioninitialized:(t)=>{R0=t,Z.set(t,{transport:p,lastActivity:Date.now()})},onsessionclosed:(t)=>{Z.delete(t)}});p.onclose=()=>{if(p.sessionId)Z.delete(p.sessionId)};try{await $.buildServer({userId:w,frontendSessionId:_,boardId:R,toolSurface:k,cardId:g,runFolder:s,clientHint:X0}).connect(p)}catch(t){if(console.error("[mcp] buildServer/connect failed",t),R0)Z.delete(R0);await p.close().catch(()=>{return}),I(j,500,j$,"server-init-failed");return}N=p}else{I(j,400,l,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await N.handleRequest(K,j,x)}catch(C){if(console.error("[mcp] transport.handleRequest threw",C),!j.headersSent)I(j,500,j$,"internal")}})().catch((M)=>{console.error("[mcp] unhandled request handler error:",M)})});return X=await q3(Y,P3($.port)),{url:`http://127.0.0.1:${X}${b1}`,port:X,close:async()=>{clearInterval(W);for(let K of Z.values())await K.transport.close().catch(()=>{return});Z.clear(),await new Promise((K)=>Y.close(()=>K()))}}}var O3={name:"ideawave-board",version:"1.0.0"},F0="list_run_folder",_0="read_run_folder_file",h1=new Set(["list_boards","get_board","list_nodes","list_edges","inspect_node","list_context_sources","read_context_card","read_context_file","list_context_folder","get_board_wiki","search_board","get_card_messages","list_agent_cards","inspect_neighbors",F0,_0]),f3=[{name:F0,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:_0,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 K$($){return{content:[{type:"text",text:$}]}}function A3($){return K$(JSON.stringify($,null,2))}function I1($){return{...K$($),isError:!0}}function R3($,Z,X="full"){return $.getMetadata(Z).filter((J)=>X!=="read"||h1.has(J.name)).map((J)=>({name:J.name,description:J.description,inputSchema:J.inputSchema}))}function T3($,Z,X={}){let J=R3($,Z,X.toolSurface??"full");return X.includeRunFolderTools?[...J,...f3]:J}function g1($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let X=$[Z];return typeof X==="string"?X:null}async function b3($,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 n({boardId:$,cardId:Z})).runFolder}async function v3($){let Z=await b3($.boardId,$.cardId,$.runFolder);if($.name===F0){let X=g1($.args,"path")??"",J=await T$(Z,X);return A3(J)}if($.name===_0){let X=g1($.args,"path");if(!X)return I1("read_run_folder_file requires a path.");return K$(await U0(Z,X))}return I1(`Unknown local tool "${$.name}"`)}function E3($,Z,X,J,Q,V="full"){let W=new L3(O3,{capabilities:{tools:{}}});return W.setRequestHandler(_3,async()=>({tools:T3($,Z,{includeRunFolderTools:Boolean(Q||X&&J),toolSurface:V})})),W.setRequestHandler(F3,async(Y)=>{let{name:G,arguments:K}=Y.params;try{if(G===F0||G===_0)return await v3({name:G,args:K,boardId:X,cardId:J,runFolder:Q});if(V==="read"&&!h1.has(G))throw Error(`Tool "${G}" is not available in read-only mode`);let j=await $.callTool(Z,G,K??{},void 0,J??void 0);if(j&&typeof j==="object"&&Array.isArray(j.content))return j;return{content:[{type:"text",text:typeof j==="string"?j:JSON.stringify(j)}]}}catch(j){return{content:[{type:"text",text:j instanceof Error?j.message:"Tool call failed"}],isError:!0}}}),W}function m1($,Z){return y1({buildServer:(X)=>E3($,X.frontendSessionId,X.boardId,X.cardId,X.runFolder,X.toolSurface),port:Z})}import f0 from"node:fs/promises";import Y$ from"node:os";import A0 from"node:path";var S1=new Map,M$=new Map,y3=30000;function O0($,Z){let X=S1.get($);if(X&&X.expiresAt>Date.now())return Promise.resolve(X.value);let J=M$.get($);if(J)return J;let Q=Z().then((V)=>{return S1.set($,{value:V,expiresAt:Date.now()+y3}),V}).finally(()=>{M$.delete($)});return M$.set($,Q),Q}async function c1($){let Z=await Promise.all($0().map((V)=>O0(V.id,async()=>({adapterId:V.id,...await V.checkReadiness({id:"__probe__",kind:"registered",adapterId:V.id,displayName:V.displayName,runFolder:null,defaultModelId:null,discoveredModels:[],discoveredAt:null})})))),J=(await y($)).runtimes.filter((V)=>V.kind==="custom"),Q=await Promise.all(J.map((V)=>O0(`custom:${V.id}`,async()=>({adapterId:V.id,...await m(V).checkReadiness(V)}))));return[...Z,...Q]}async function l1($,Z){let X=$0().find((V)=>V.id===$);if(X)return O0(X.id,async()=>({adapterId:X.id,...await X.checkReadiness({id:"__probe__",kind:"registered",adapterId:X.id,displayName:X.displayName,runFolder:null,defaultModelId:null,discoveredModels:[],discoveredAt:null})}));let Q=(await y(Z)).runtimes.find((V)=>V.id===$);if(!Q||Q.kind!=="custom")return null;return O0(`custom:${Q.id}`,async()=>({adapterId:Q.id,...await m(Q).checkReadiness(Q)}))}function u1(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function I3(){let[$,Z]=await Promise.all([y(),c1()]),X=$.globalDefaultConfigId?$.runtimes.find((J)=>J.id===$.globalDefaultConfigId)??null:null;return{runtimes:$.runtimes,globalDefaultConfigId:$.globalDefaultConfigId,globalDefaultEffective:X?{runFolder:X.runFolder??Y$.homedir(),modelId:X.defaultModelId??null}:null,knownAdapters:$0().map((J)=>({id:J.id,displayName:J.displayName})),readiness:Z}}async function g3($){try{let Z=await n({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}}}catch(Z){if(Z instanceof a)return{resolved:null};throw Z}}async function h3($){return h((Z)=>{let X=Z.runtimes.find((V)=>V.kind==="registered"&&V.adapterId===$.adapterId);if(X)return X;let J=$0().find((V)=>V.id===$.adapterId);if(!J)throw Error(`Unknown adapterId: ${$.adapterId}`);let Q={id:u1(),kind:"registered",adapterId:$.adapterId,displayName:J.displayName,runFolder:null,defaultModelId:null,discoveredModels:[],discoveredAt:null};return Z.runtimes.push(Q),Q})}async function m3($){return h((Z)=>{let X={id:u1(),kind:"custom",displayName:$.displayName,command:$.command,args:$.args,env:$.env,runFolder:$.runFolder,defaultModelId:null,discoveredModels:[],discoveredAt:null};return Z.runtimes.push(X),X})}async function S3($){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 c3($){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})}async function l3($){$.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}})}async function u3($){let X=(await y()).runtimes.find((W)=>W.id===$.runtimeConfigId);if(!X)throw Error(`Runtime config not found: ${$.runtimeConfigId}`);let J=m(X),Q=await J.resolveSpawnConfig(X),V=X.runFolder??Y$.homedir();try{let W=await p$({spawn:{...Q,cwd:V}}),Y=new Date().toISOString();return await h((G)=>{let K=G.runtimes.find((j)=>j.id===$.runtimeConfigId);if(K)K.discoveredModels=W.models,K.discoveredAt=Y}),{ok:!0,models:W.models,currentModelId:W.currentModelId}}catch(W){if(W instanceof r)throw Error(`${W.message}${J.authHint?` ${J.authHint}`:""}`);if(W instanceof L||W instanceof i)throw Error(W.message);throw W}}async function p3($){let Z=Y$.homedir(),X=$.path?.trim()?$.path.trim():Z,J=A0.resolve(X),Q=!0;try{if(!(await f0.stat(J)).isDirectory())J=A0.dirname(J)}catch{Q=!1,J=Z}let V=[];try{V=(await f0.readdir(J,{withFileTypes:!0})).filter((G)=>G.isDirectory()&&!G.name.startsWith(".")).map((G)=>({name:G.name,path:A0.join(J,G.name)})).sort((G,K)=>G.name.localeCompare(K.name))}catch{V=[]}let W=A0.dirname(J);return{path:J,parent:W===J?null:W,home:Z,exists:Q,entries:V}}var p1={list:I3,getEffectiveForCard:g3,registerRegistered:h3,registerCustom:m3,unregister:S3,setUserDefault:c3,setCardOverride:l3,refreshModels:u3,browseFolder:p3};var a3=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function i3(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function a1(){try{let $=await y();if($.globalDefaultConfigId){if($.runtimes.some((X)=>X.id===$.globalDefaultConfigId))return $.globalDefaultConfigId}for(let Z of a3){if((await l1(Z.id))?.status!=="ready")continue;let J=null;if(await h((Q)=>{if(Q.globalDefaultConfigId){if(Q.runtimes.some((Y)=>Y.id===Q.globalDefaultConfigId)){J=Q.globalDefaultConfigId;return}}let V=Q.runtimes.find((W)=>W.kind==="registered"&&W.adapterId===Z.id);if(!V){let W={id:i3(),kind:"registered",adapterId:Z.id,displayName:Z.displayName,runFolder:null,defaultModelId:null,discoveredModels:[],discoveredAt:null};Q.runtimes.push(W),V=W}Q.globalDefaultConfigId=V.id,J=V.id}),J)return console.log(`[ideawave-cli] using agent runtime: ${Z.displayName}`),J}return console.warn("[ideawave-cli] no agent runtime detected on PATH (tried claude, codex, gh copilot, opencode). Install one to run agents."),null}catch($){return console.warn("[ideawave-cli] runtime auto-seed failed",$),null}}function d3(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class D${sessions=new Map;createCallId;toolCallTimeoutMs;constructor($={}){this.createCallId=$.createCallId??d3,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 V=this.sessions.get($);if(!V)return Promise.reject(Error(`Frontend session ${$} is not connected`));let W=this.createCallId();return new Promise((Y,G)=>{let K=setTimeout(()=>{V.pendingToolCalls.delete(W),G(Error(`Tool "${Z}" timed out waiting for the frontend`))},this.toolCallTimeoutMs),j=J??(Q?this.getActiveRunIdForCard(V,Q):this.getSoleActiveRunId(V)),M=Q??(j?V.activeRunCardIds.get(j):void 0);V.pendingToolCalls.set(W,{resolve:Y,reject:G,timer:K}),V.send({type:"tool_call",callId:W,name:Z,args:X,...j?{runId:j}:{},...M?{cardId:M}:{}})})}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 n3(){return"0.0.21".trim()?"0.0.21":"dev"}var u=process.argv[2];if(u==="--help"||u==="-h"||u==="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(u==="--version"||u==="-v"||u==="version")console.log(n3()),process.exit(0);if(u)console.error(`Unknown command: ${u}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var K0=new D$,D0=null;function M0($,Z){K0.sendToSession($,Z)}async function o3($,Z){try{let X=p1[Z.method],J=await X(Z.params);M0($,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!0,result:J})}catch(X){M0($,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!1,error:X instanceof Error?X.message:String(X)})}}var Y0=!1,G0=null;async function x$(){if(Y0)return;if(G0)return G0;return G0=(async()=>{try{let $=await m1(K0);U$({...$,requestedPort:$.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${$.url}`);try{let Z=await f$();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 a1(),Y0=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),D0?.sendStatus()}catch($){console.error("[ideawave-cli] failed to start agent host:",$),D0?.sendStatus(void 0,$ instanceof Error?$.message:String($))}finally{G0=null}})(),G0}if(process.env.APP_ENV!=="development"){let $=await _1();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)}D0=await O1({registry:K0,runtime:null,mcpReady:()=>Y0,onToolMetadata:($)=>{console.log(`[ideawave-cli] session ${$} advertised ${K0.getMetadata($).length} tools`),x$()},onRunTurn:($,Z)=>{console.log(`[ideawave-cli] running agent turn for card ${Z.cardId} (session ${$})`),(async()=>{if(await x$(),!Y0){M0($,{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 N1(Z,(X)=>M0($,X))})().catch(()=>{return}).finally(()=>K0.markRunSettled($,Z.runId))},onCancelRun:($,Z)=>{J$(Z)},onRuntimeRpc:($,Z)=>{o3($,Z)},onWarmupRun:($,Z,X)=>{(async()=>{if(await x$(),!Y0)return{status:"retryable",error:"agent host is not ready"};return C1({cardId:Z.cardId,boardId:Z.boardId,userId:X,frontendSessionId:$})})().then((J)=>{if(!Z.warmupId)return;M0($,{type:"warmup_result",warmupId:Z.warmupId,cardId:Z.cardId,...J})})},onDisconnect:($,Z)=>{B1($);for(let X of Z)J$(X);console.log(`[ideawave-cli] browser session ${$} disconnected`)}});console.log(`[ideawave-cli] browser bridge listening on ${D0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var i1=!1;for(let $ of["SIGINT","SIGTERM"])process.once($,()=>{if(i1)return;i1=!0,H1(),(async()=>{await D0?.close().catch(()=>{return}),process.exit(0)})()});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ideawave",
3
- "version": "0.0.20",
3
+ "version": "0.0.21",
4
4
  "description": "IdeaWave CLI",
5
5
  "type": "module",
6
6
  "bin": {