ideawave 0.0.43 → 0.0.44

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 +14 -14
  2. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -1,28 +1,28 @@
1
1
  #!/usr/bin/env node
2
- import{readFileSync as q2}from"node:fs";import{homedir as M2}from"node:os";import{join as N0}from"node:path";function N2(){let $=M2();switch(process.platform){case"win32":return process.env.APPDATA??N0($,"AppData","Roaming");case"darwin":return N0($,"Library","Application Support");default:return process.env.XDG_CONFIG_HOME??N0($,".config")}}function w$(){let $=process.env.IDEAWAVE_MCP_JSON_PATH;if($&&$.trim().length>0)return $;return N0(N2(),"ideawave","mcp.json")}var R$=null;function f$($){R$=$}var B2=86400000;function C2(){let $;try{$=q2(w$(),"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>B2)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 T$($,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 h0($={}){let Z=R$;if(Z)return T$(Z.url,$);let X=C2();if(!X)return null;return T$(X.url,$)}import{spawn as k2}from"node:child_process";import{closeSync as _2,existsSync as v$,mkdirSync as h$,openSync as A2,readFileSync as w2,renameSync as T2,rmSync as S$,statSync as R2,unlinkSync as f2,writeFileSync as E2}from"node:fs";import b$ from"node:os";import t from"node:path";import{execFile as P2}from"node:child_process";import{promisify as O2}from"node:util";import{execFile as F2}from"node:child_process";import{promisify as x2}from"node:util";var L2=x2(F2),S0=new Map,E$=5000;async function y$($,Z=L2){let X=S0.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}),j=Q.split(/\r?\n/).find((z)=>z.trim().length>0),W=j?j.trim():null;return S0.set($,{value:W,expiresAt:Date.now()+E$}),W}catch{return S0.set($,{value:null,expiresAt:Date.now()+E$}),null}}class W0 extends Error{code;constructor($,Z){super($);this.name="AcpError",this.code=Z}}class s extends W0{constructor($="No ACP runtime configured"){super($,"RUNTIME_NOT_CONFIGURED");this.name="RuntimeNotConfiguredError"}}class O extends W0{constructor($){super($,"RUNTIME_UNREACHABLE");this.name="RuntimeUnreachableError"}}class X0 extends W0{authMethods;constructor($,Z){super($,"AUTH_REQUIRED");this.name="AuthRequiredError",this.authMethods=Z}}class d extends W0{constructor($="ACP session timed out"){super($,"SESSION_TIMEOUT");this.name="SessionTimeoutError"}}var uZ=O2(P2);function A($,...Z){return y$($,...Z)}function b($){let Z={};for(let[X,J]of Object.entries(process.env))if(typeof J==="string")Z[X]=J;return{...Z,...$??{}}}var c0=[{adapterId:"claude-code",runtimeBinary:"claude",packageName:"@agentclientprotocol/claude-agent-acp",version:"0.50.0",warmupArgs:["--cli","--help"]},{adapterId:"codex",runtimeBinary:"codex",packageName:"@agentclientprotocol/codex-acp",version:"1.0.0",warmupArgs:["--version"]}],y2=1800000,m0=new Map;function l0(){if(process.env.IDEAWAVE_ACP_BRIDGE_CACHE_DIR)return process.env.IDEAWAVE_ACP_BRIDGE_CACHE_DIR;if(process.platform==="win32"){let $=process.env.LOCALAPPDATA??t.join(b$.homedir(),"AppData","Local");return t.join($,"ideawave","acp-bridges")}return t.join(process.env.XDG_CACHE_HOME??t.join(b$.homedir(),".cache"),"ideawave","acp-bridges")}function b2($){return $.replace(/^@/,"").replace(/[/\\]/g,"-")}function q0(){return t.join(l0(),"install-state.json")}function u0($){return t.join(l0(),`${b2($.packageName)}@${$.version}.install.lock`)}function p0(){return process.platform==="win32"?"npx.cmd":"npx"}function d0($){return`${$.packageName}@${$.version}`}function m$(){let $=q0();if(!v$($))return{};try{return JSON.parse(w2($,"utf8"))}catch{return{}}}function g0($,Z){let X=l0();h$(X,{recursive:!0});let J=m$();J.bridges={...J.bridges??{},[$.adapterId]:Z},E2(`${q0()}.tmp`,`${JSON.stringify(J,null,2)}
3
- `),T2(`${q0()}.tmp`,q0())}function g$($){return c0.find((Z)=>Z.packageName===$)??null}function I($,Z,X){return{adapterId:$.adapterId,packageName:$.packageName,version:$.version,status:Z,...X?{error:X}:{}}}function I$($,Z){return Z?.packageName===$.packageName&&Z.version===$.version}function c$($){try{return Date.now()-R2($).mtimeMs>y2}catch{return!1}}function I2($){let Z=u0($);if(!v$(Z))return!1;if(c$(Z))return S$(Z,{force:!0}),!1;return!0}function v2($){let Z=u0($);if(h$(t.dirname(Z),{recursive:!0}),c$(Z))S$(Z,{force:!0});try{let X=A2(Z,"wx");return _2(X),!0}catch{return!1}}function h2($){f2(u0($))}function a0($){let Z=m$().bridges?.[$.adapterId];if(I$($,Z)&&Z.status==="ready")return I($,"ready");if(m0.has($.adapterId)||I2($))return I($,"installing");if(I$($,Z)&&Z.status==="failed")return I($,"failed",Z.error);return I($,"missing")}function S2($){let Z=a0($);if(Z.status==="ready"||Z.status==="installing")return Z;if(!v2($))return I($,"installing");let X=I($,"installing");g0($,X);let J=()=>{},Q=new Promise((V)=>{J=V});m0.set($.adapterId,Q);let j=!1,W=(V)=>{if(j)return;j=!0;try{h2($)}catch{}g0($,V),m0.delete($.adapterId),J(V)},z;try{z=k2(p0(),["-y",d0($),...$.warmupArgs],{stdio:"ignore",windowsHide:!0})}catch(V){let H=I($,"failed",V instanceof Error?V.message:String(V));return W(H),H}return z.on("error",(V)=>{W(I($,"failed",V.message))}),z.on("close",(V)=>{if(V===0){W(I($,"ready"));return}W(I($,"failed",`npx warmup exited ${V??"null"}`))}),z.unref(),X}function J0($){let Z=g$($);return Z?a0(Z):null}async function l$(){let $=[];for(let Z of c0){if(!await A(Z.runtimeBinary)){$.push(I(Z,"not_needed"));continue}$.push(S2(Z))}return $.filter((Z)=>Z.status!=="not_needed")}function B0($){let Z=g$($);if(!Z)return null;if(a0(Z).status!=="ready")return null;return{command:p0(),args:["-y",d0(Z)],env:{}}}function i0($,Z){if($.command!==p0())return!1;let X=c0.find((J)=>$.args.includes(d0(J)));if(!X)return!1;return g0(X,I(X,"failed",Z)),!0}function m2($){if(!$)return null;let Z=$.indexOf("/");if(Z<=0)return null;return $.slice(0,Z)}function C0($){let Z=[...$.models];if($.adapterId!=="opencode"||Z.length===0)return Z;let X=m2($.currentModelId)??(Z.some((Q)=>Q.id.startsWith("opencode/"))?"opencode":null);if(!X)return Z;let J=Z.filter((Q)=>Q.id===$.currentModelId||Q.id.startsWith(`${X}/`));return J.length>0?J:Z}import{Readable as Z6,Writable as X6}from"node:stream";import{ClientSideConnection as $1,ndJsonStream as Z1}from"@agentclientprotocol/sdk";import a from"node:fs/promises";import y from"node:path";class V0 extends Error{constructor($){super($);this.name="PathTraversalError"}}class n0 extends Error{constructor($){super($);this.name="HiddenPathError"}}class s0 extends Error{constructor($){super($);this.name="RunFolderFileTooLargeError"}}class K0 extends Error{constructor($){super($);this.name="RunFolderBinaryFileError"}}var g2=new Set([".bzr",".cache",".claude",".config",".env",".git",".hg",".idea",".obsidian",".svn",".vscode","node_modules"]),u$=1e6,c2=4096,l2=new TextDecoder("utf-8",{fatal:!0});function u2($){return $.split(/[\\/]+/).filter((Z)=>Z.length>0)}function F0($){if(y.isAbsolute($))throw new V0("Absolute paths are not allowed");for(let Z of u2($)){if(Z===".")continue;if(Z==="..")throw new V0("Parent-directory traversal is not allowed");if(Z.startsWith(".")||g2.has(Z))throw new n0(`Path segment "${Z}" is hidden or configuration data`)}}function p2($){F0($);let Z=y.normalize($||".");return Z==="."?"":Z}function d2($,Z,X){let J=y.relative($,Z);if(J===".."||J.startsWith(`..${y.sep}`)||y.isAbsolute(J))throw new V0(`Path "${X}" resolves outside the run folder`);if(J.length>0)F0(J);return J}async function o0($,Z){F0(Z);let X=y.resolve($,Z||"."),J;try{J=await a.realpath(X)}catch(Q){if(Q.code!=="ENOENT")throw Q;let j=y.dirname(X),W=[y.basename(X)];while(j!==$&&j!==y.dirname(j))try{j=await a.realpath(j);break}catch(z){if(z.code!=="ENOENT")throw z;W.unshift(y.basename(j)),j=y.dirname(j)}J=y.join(j,...W)}return d2($,J,Z),J}async function a2($,Z){let X=await a.realpath($);return o0(X,Z)}function i2($){let Z=$.subarray(0,Math.min($.length,c2));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 x0($,Z){let X=await a2($,Z),J=await a.stat(X);if(!J.isFile())throw new K0(`Path "${Z}" is not a text file`);if(J.size>u$)throw new s0(`File "${Z}" is too large to read (${J.size} bytes, max ${u$} bytes)`);let Q=await a.readFile(X);if(i2(Q))throw new K0(`File "${Z}" appears to be binary, not text`);try{return l2.decode(Q)}catch{throw new K0(`File "${Z}" is not valid UTF-8 text`)}}function o2($){if($.isDirectory())return"directory";if($.isFile())return"file";if($.isSymbolicLink())return"symlink";return"other"}function p$($){return $.split(y.sep).join("/")}async function d$($,Z=""){let X=await a.realpath($),J=p2(Z),Q=await o0(X,J),j=await a.readdir(Q,{withFileTypes:!0}),W=[];for(let z of j){let V=J?y.join(J,z.name):z.name;try{F0(V);let H=await o0(X,V),U=await a.stat(H);W.push({name:z.name,path:p$(V),type:o2(z),size:z.isFile()?U.size:null})}catch{}}return W.sort((z,V)=>{if(z.type==="directory"&&V.type!=="directory")return-1;if(z.type!=="directory"&&V.type==="directory")return 1;return z.name.localeCompare(V.name)}),{path:p$(J),absolutePath:Q,entries:W}}var t0={fs:{readTextFile:!0,writeTextFile:!1},terminal:!1};function a$($){return{readTextFile:async(Z)=>{return{content:await x0($,Z.path)}}}}import{spawn as n2}from"node:child_process";function r0($){let Z=n2($.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,j=4096,W=[],z=0;Q.on("data",(Y)=>{W.push(Y),z+=Y.length;while(z>j*2&&W.length>1){let G=W.shift();if(G)z-=G.length}});let V=()=>{let Y=Buffer.concat(W).toString("utf8");return Y.length>j?Y.slice(-j):Y},H=!1,U=!1,N,D,M=new Promise((Y)=>{N=Y}),x=new Promise((Y)=>{D=Y}),B=(Y)=>{if(U)return;if(U=!0,N(Y),!H)D(Y)};return Z.on("exit",(Y,G)=>{B({code:Y,signal:G,stderr:V()})}),Z.on("error",(Y)=>{let G=V(),P=Y?.message??String(Y);B({code:null,signal:null,stderr:G?`${P}
4
- ${G}`:P})}),{stdin:X,stdout:J,stderr:Q,kill:(Y="SIGTERM")=>{if(H)return;H=!0;try{Z.kill(Y)}catch{}},waitForExit:M,processCrashed:x}}var s2=["mcp_ideawave_board_","ideawave_board_","ideawave-board_","ideawave-board.","ideawave.board."];function t2($){let Z=$.toLowerCase();for(let X of s2)if(Z.startsWith(X))return $.slice(X.length);if(/^mcp[-_.]/i.test($))return $.slice(4);return $}function L0($){return t2($.trim())}function e0($){let Z=L0($);if(!Z)return"Tool";if(!/[-_.]/.test(Z))return Z.charAt(0).toUpperCase()+Z.slice(1);let X=Z.replace(/[-_.]+/g," ").replace(/\s+/g," ").trim();if(!X)return"Tool";return X.charAt(0).toUpperCase()+X.slice(1)}function $$($){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"}function Z$($){if(typeof $!=="string")return null;let Z=$.trim();return Z?Z:null}function i$($){if(typeof $!=="string")return"Tool";let Z=$.trim();return Z?Z:"Tool"}function r2($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let X=$;for(let J of Z){let Q=X[J];if(typeof Q==="string"&&Q.trim())return Q.trim()}return null}function X$($,Z){let X=$.trim().toLowerCase();if(X==="skill"||X==="workflow"||X==="tool"||X==="invalid"){let J=r2(Z,["skillName","workflowName","toolName","name","title"]);if(J){let Q=X==="skill"?" skill":X==="workflow"?" workflow":"";return`${e0(J)}${Q}`}}if(X==="invalid")return"Tool call";return e0($)}var e2=33,o$=1600;function r($){if($.length<=o$)return $;return`${$.slice(0,o$-22)}
5
- ... truncated`}function O0($){let Z=$.replace(/\r\n?/g,`
6
- `),X=Z.trim();if(X.startsWith('"')&&X.endsWith('"')||X.startsWith("'")&&X.endsWith("'"))try{let Q=JSON.parse(X);if(typeof Q==="string")return Q.replace(/\r\n?/g,`
7
- `)}catch{return Z}if(!Z.includes("\\\""))return Z;let J=Z.replace(/\\r\\n/g,`
2
+ import{readFileSync as _2}from"node:fs";import{homedir as k2}from"node:os";import{join as x0}from"node:path";function O2(){let $=k2();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 b$(){let $=process.env.IDEAWAVE_MCP_JSON_PATH;if($&&$.trim().length>0)return $;return x0(O2(),"ideawave","mcp.json")}var I$=null;function h$($){I$=$}var A2=86400000;function w2(){let $;try{$=_2(b$(),"utf8")}catch{return null}let X;try{X=JSON.parse($)}catch{return null}if(typeof X.url!=="string")return null;if(typeof X.startedAt==="string"){let Z=Date.parse(X.startedAt);if(!Number.isNaN(Z)){if(Date.now()-Z>A2)return null}}if(typeof X.pid==="number"&&X.pid>0)try{process.kill(X.pid,0)}catch(Z){if(Z?.code!=="EPERM")return null}return{url:X.url}}function v$($,X={}){let Z=[];if(X.userId&&X.userId.trim().length>0)Z.push({name:"X-Ideawave-User-Id",value:X.userId.trim()});if(X.frontendSessionId&&X.frontendSessionId.trim().length>0)Z.push({name:"X-Ideawave-Frontend-Session-Id",value:X.frontendSessionId.trim()});if(X.toolSurface==="read")Z.push({name:"X-Ideawave-Tool-Surface",value:"read"});if(X.imagesSupported)Z.push({name:"X-Ideawave-Images-Supported",value:"1"});if(X.cardId&&X.cardId.trim().length>0)Z.push({name:"X-Ideawave-Card-Id",value:X.cardId.trim()});if(X.boardId&&X.boardId.trim().length>0)Z.push({name:"X-Ideawave-Board-Id",value:X.boardId.trim()});if(X.runFolder&&X.runFolder.trim().length>0)Z.push({name:"X-Ideawave-Run-Folder",value:X.runFolder.trim()});return{type:"http",name:"ideawave-board",url:$,headers:Z}}function u0($={}){let X=I$;if(X)return v$(X.url,$);let Z=w2();if(!Z)return null;return v$(Z.url,$)}import V0 from"node:fs/promises";import y2 from"node:path";import{z as q}from"zod";var S$=q.object({id:q.string(),name:q.string().nullable().default(null),description:q.string().nullable().default(null)}),c$=q.union([q.string(),q.boolean()]),T2=q.object({value:q.string(),name:q.string(),description:q.string().nullable().default(null),group:q.string().nullable().default(null),groupName:q.string().nullable().default(null)}),m$=q.object({id:q.string(),name:q.string(),category:q.string().nullable().default(null),description:q.string().nullable().default(null),type:q.enum(["select","boolean"]),currentValue:c$.nullable().default(null),options:q.array(T2).default([])}),p0=q.record(q.string(),c$).default({}),R2=q.discriminatedUnion("kind",[q.object({id:q.string(),kind:q.literal("registered"),adapterId:q.enum(["claude-code","opencode","codex","copilot"]),displayName:q.string(),runFolder:q.string().nullable(),defaultModelId:q.string().nullable().default(null),defaultConfigValues:p0,discoveredModels:q.array(S$).default([]),discoveredConfigOptions:q.array(m$).default([]),discoveredAt:q.string().nullable().default(null)}),q.object({id:q.string(),kind:q.literal("custom"),displayName:q.string(),command:q.string(),args:q.array(q.string()),env:q.record(q.string(),q.string()),runFolder:q.string().nullable(),defaultModelId:q.string().nullable().default(null),defaultConfigValues:p0,discoveredModels:q.array(S$).default([]),discoveredConfigOptions:q.array(m$).default([]),discoveredAt:q.string().nullable().default(null)})]),g$=q.object({runtimeConfigId:q.string(),runFolder:q.string().nullable(),modelId:q.string().nullable().default(null),configValues:p0}),C0=q.object({version:q.literal(1),globalDefaultConfigId:q.string().nullable(),runtimes:q.array(R2),boardOverrides:q.record(q.string(),g$).default({}),cardOverrides:q.record(q.string(),g$).default({})});import f2 from"node:os";import F0 from"node:path";function E2(){let $=f2.homedir();switch(process.platform){case"win32":return process.env.APPDATA??F0.join($,"AppData","Roaming");case"darwin":return F0.join($,"Library","Application Support");default:return process.env.XDG_CONFIG_HOME??F0.join($,".config")}}function P0(){let $=process.env.IDEAWAVE_RUNTIME_CONFIG_PATH;if($)return $;return F0.join(E2(),"ideawave","runtimes.json")}var b2={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},l$=new Map;function v2($){return l$.get($)??Promise.resolve()}function I2($,X){l$.set($,X)}async function h($){let X=$??P0(),Z;try{Z=await V0.readFile(X,"utf-8")}catch(Q){if(Q.code==="ENOENT")return structuredClone(b2);throw Q}return C0.parse(JSON.parse(Z))}async function g($,X){let Z=X??P0(),J=v2(Z).then(async()=>{let Q=await h(Z),j=structuredClone(Q),W=await $(j);return await h2(j,Z),W});return I2(Z,J.catch(()=>{return})),J}async function h2($,X){let Z=X??P0(),J=y2.dirname(Z);await V0.mkdir(J,{recursive:!0});let Q=`${Z}.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`,j=JSON.stringify($,null,2);await V0.writeFile(Q,j,"utf-8");try{await V0.rename(Q,Z)}catch(W){throw await V0.unlink(Q).catch(()=>{return}),W}}import{spawn as u2}from"node:child_process";import{closeSync as p2,existsSync as i$,mkdirSync as n$,openSync as a2,readFileSync as d2,renameSync as i2,rmSync as o$,statSync as n2,unlinkSync as o2,writeFileSync as s2}from"node:fs";import a$ from"node:os";import r from"node:path";import{execFile as c2}from"node:child_process";import{promisify as l2}from"node:util";import{execFile as S2}from"node:child_process";import{promisify as m2}from"node:util";var g2=m2(S2),a0=new Map,u$=5000;async function p$($,X=g2){let Z=a0.get($);if(Z&&Z.expiresAt>Date.now())return Z.value;let J=process.platform==="win32"?"where":"which";try{let{stdout:Q}=await X(J,[$],{timeout:2000}),j=Q.split(/\r?\n/).find((G)=>G.trim().length>0),W=j?j.trim():null;return a0.set($,{value:W,expiresAt:Date.now()+u$}),W}catch{return a0.set($,{value:null,expiresAt:Date.now()+u$}),null}}class Y0 extends Error{code;constructor($,X){super($);this.name="AcpError",this.code=X}}class t extends Y0{constructor($="No ACP runtime configured"){super($,"RUNTIME_NOT_CONFIGURED");this.name="RuntimeNotConfiguredError"}}class O extends Y0{constructor($){super($,"RUNTIME_UNREACHABLE");this.name="RuntimeUnreachableError"}}class J0 extends Y0{authMethods;constructor($,X){super($,"AUTH_REQUIRED");this.name="AuthRequiredError",this.authMethods=X}}class a extends Y0{constructor($="ACP session timed out"){super($,"SESSION_TIMEOUT");this.name="SessionTimeoutError"}}var zZ=l2(c2);function w($,...X){return p$($,...X)}function v($){let X={};for(let[Z,J]of Object.entries(process.env))if(typeof J==="string")X[Z]=J;return{...X,...$??{}}}var i0=[{adapterId:"claude-code",runtimeBinary:"claude",packageName:"@agentclientprotocol/claude-agent-acp",version:"0.50.0",warmupArgs:["--cli","--help"]},{adapterId:"codex",runtimeBinary:"codex",packageName:"@agentclientprotocol/codex-acp",version:"1.0.0",warmupArgs:["--version"]}],t2=1800000,L0=new Map;function n0(){if(process.env.IDEAWAVE_ACP_BRIDGE_CACHE_DIR)return process.env.IDEAWAVE_ACP_BRIDGE_CACHE_DIR;if(process.platform==="win32"){let $=process.env.LOCALAPPDATA??r.join(a$.homedir(),"AppData","Local");return r.join($,"ideawave","acp-bridges")}return r.join(process.env.XDG_CACHE_HOME??r.join(a$.homedir(),".cache"),"ideawave","acp-bridges")}function r2($){return $.replace(/^@/,"").replace(/[/\\]/g,"-")}function k0(){return r.join(n0(),"install-state.json")}function o0($){return r.join(n0(),`${r2($.packageName)}@${$.version}.install.lock`)}function s0(){return process.platform==="win32"?"npx.cmd":"npx"}function t0($){return`${$.packageName}@${$.version}`}function s$(){let $=k0();if(!i$($))return{};try{return JSON.parse(d2($,"utf8"))}catch{return{}}}function d0($,X){let Z=n0();n$(Z,{recursive:!0});let J=s$();J.bridges={...J.bridges??{},[$.adapterId]:X},s2(`${k0()}.tmp`,`${JSON.stringify(J,null,2)}
3
+ `),i2(`${k0()}.tmp`,k0())}function t$($){return i0.find((X)=>X.packageName===$)??null}function S($,X,Z){return{adapterId:$.adapterId,packageName:$.packageName,version:$.version,status:X,...Z?{error:Z}:{}}}function d$($,X){return X?.packageName===$.packageName&&X.version===$.version}function r$($){try{return Date.now()-n2($).mtimeMs>t2}catch{return!1}}function e2($){let X=o0($);if(!i$(X))return!1;if(r$(X))return o$(X,{force:!0}),!1;return!0}function $6($){let X=o0($);if(n$(r.dirname(X),{recursive:!0}),r$(X))o$(X,{force:!0});try{let Z=a2(X,"wx");return p2(Z),!0}catch{return!1}}function X6($){o2(o0($))}function r0($){let X=s$().bridges?.[$.adapterId];if(d$($,X)&&X.status==="ready")return S($,"ready");if(L0.has($.adapterId)||e2($))return S($,"installing");if(d$($,X)&&X.status==="failed")return S($,"failed",X.error);return S($,"missing")}function z0($,X){$?.onStatusChange?.(X)}function Z6($,X){let Z=r0($);if(Z.status==="ready")return z0(X,Z),Z;if(Z.status==="installing"){let K=L0.get($.adapterId);if(K&&X?.onStatusChange)K.then((H)=>z0(X,H));return z0(X,Z),Z}if(!$6($))return S($,"installing");let J=S($,"installing");d0($,J),z0(X,J);let Q=()=>{},j=new Promise((K)=>{Q=K});L0.set($.adapterId,j);let W=!1,G=(K)=>{if(W)return;W=!0;try{X6($)}catch{}d0($,K),z0(X,K),L0.delete($.adapterId),Q(K)},z;try{z=u2(s0(),["-y",t0($),...$.warmupArgs],{stdio:"ignore",windowsHide:!0})}catch(K){let H=S($,"failed",K instanceof Error?K.message:String(K));return G(H),H}return z.on("error",(K)=>{G(S($,"failed",K.message))}),z.on("close",(K)=>{if(K===0){G(S($,"ready"));return}G(S($,"failed",`npx warmup exited ${K??"null"}`))}),z.unref(),J}function Q0($){let X=t$($);return X?r0(X):null}async function e$($){let X=[];for(let Z of i0){if(!await w(Z.runtimeBinary)){X.push(S(Z,"not_needed"));continue}X.push(Z6(Z,$))}return X.filter((Z)=>Z.status!=="not_needed")}function O0($){let X=t$($);if(!X)return null;if(r0(X).status!=="ready")return null;return{command:s0(),args:["-y",t0(X)],env:{}}}function e0($,X){if($.command!==s0())return!1;let Z=i0.find((J)=>$.args.includes(t0(J)));if(!Z)return!1;return d0(Z,S(Z,"failed",X)),!0}var $1="claude",$$="@agentclientprotocol/claude-agent-acp",X1=["claude-agent-acp","claude-code-acp"],Z1="Install Claude Code from https://github.com/anthropics/claude-code",J1={id:"claude-code",displayName:"Claude Code",kind:"registered",supportsImages:!0,resolveSpawnConfig:async()=>{if(!await w($1))throw new O(`Claude Code CLI not found. ${Z1}`);let X=O0($$);if(X)return{command:X.command,args:X.args,env:v(X.env)};let Z=Q0($$),J=Z?.status==="installing";for(let j of X1){let W=await w(j);if(W&&!J&&Z?.status!=="failed")return{command:W,args:[],env:v()}}let Q=Z?.status==="failed"?`Claude Code ACP bridge install failed. ${Z.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 O(Q)},checkReadiness:async()=>{if(!await w($1))return{status:"not_installed",detail:Z1};let X=Q0($$);if(X?.status==="ready")return{status:"ready"};if(X?.status==="installing")return{status:"not_running",detail:"Installing Claude Code ACP bridge..."};if(X?.status==="failed")return{status:"not_running",detail:X.error??"Claude Code ACP bridge install failed. Restart IdeaWave CLI so it can warm the pinned bridge again."};for(let Z of X1)if(await w(Z))return{status:"ready"};return{status:"not_running",detail:"Installing Claude Code ACP bridge..."}},authHint:"Run `claude login` (or set ANTHROPIC_API_KEY)."};var Q1="codex",X$="@agentclientprotocol/codex-acp",j1="codex-acp",W1="Install Codex CLI from https://developers.openai.com/codex/cli",K1={id:"codex",displayName:"Codex",kind:"registered",resolveSpawnConfig:async()=>{if(!await w(Q1))throw new O(`Codex CLI not found. ${W1}`);let X=O0(X$);if(X)return{command:X.command,args:X.args,env:v(X.env)};let Z=Q0(X$),J=Z?.status==="installing",Q=await w(j1);if(Q&&!J&&Z?.status!=="failed")return{command:Q,args:[],env:v()};let j=Z?.status==="failed"?`Codex ACP bridge install failed. ${Z.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 O(j)},checkReadiness:async()=>{if(!await w(Q1))return{status:"not_installed",detail:W1};let X=Q0(X$);if(X?.status==="ready")return{status:"ready"};if(X?.status==="installing")return{status:"not_running",detail:"Installing Codex ACP bridge..."};if(X?.status==="failed")return{status:"not_running",detail:X.error??"Codex ACP bridge install failed. Restart IdeaWave CLI so it can warm the pinned bridge again."};if(await w(j1))return{status:"ready"};return{status:"not_running",detail:"Installing Codex ACP bridge..."}},authHint:"Run `codex login` (or set OPENAI_API_KEY)."};var V1="copilot",Y1="copilot-acp",z1="npm i -g @github/copilot",G1={id:"copilot",displayName:"GitHub Copilot",kind:"registered",resolveSpawnConfig:async()=>{let $=await w(V1);if($)return{command:$,args:["--acp"],env:v()};let X=await w(Y1);if(X)return{command:X,args:[],env:v()};throw new O(`Copilot not installed. Run: ${z1}`)},checkReadiness:async()=>{if(await w(V1))return{status:"ready"};if(await w(Y1))return{status:"ready"};return{status:"not_installed",detail:z1}},authHint:"Run `gh auth login` (or `copilot login`)."};import J6 from"node:fs/promises";function Q6($){return $.startsWith("/")||/^[a-zA-Z]:[\\/]/.test($)}async function H1($){if(Q6($))try{return await J6.access($),!0}catch{return!1}return await w($)!==null}var U1={id:"custom",displayName:"Custom ACP",kind:"custom",resolveSpawnConfig:async($)=>{if($.kind!=="custom")throw new O("customAdapter received non-custom entry");if(!await H1($.command))throw new O(`custom: command "${$.command}" not found`);return{command:$.command,args:$.args,env:v($.env)}},checkReadiness:async($)=>{if($.kind!=="custom")return{status:"unknown"};return await H1($.command)?{status:"ready"}:{status:"not_installed"}}};var D1="opencode",M1="Install OpenCode from https://opencode.ai",N1={id:"opencode",displayName:"OpenCode",kind:"registered",resolveSpawnConfig:async()=>{let $=await w(D1);if(!$)throw new O(`OpenCode not installed. ${M1}`);return{command:$,args:["acp"],env:v()}},checkReadiness:async()=>{if(!await w(D1))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 q1={"claude-code":J1,opencode:N1,codex:K1,copilot:G1};function c($){if($.kind==="custom")return U1;let X=q1[$.adapterId];if(!X)throw Error(`Unknown registered adapter: ${$.adapterId}`);return X}function j0(){return Object.values(q1)}var Z$=new Map,_0=new Map,j6=30000;function A0($,X){let Z=Z$.get($);if(Z&&Z.expiresAt>Date.now())return Promise.resolve(Z.value);let J=_0.get($);if(J)return J;let Q=X().then((j)=>{return Z$.set($,{value:j,expiresAt:Date.now()+j6}),j}).finally(()=>{_0.delete($)});return _0.set($,Q),Q}async function B1($){let X=await Promise.all(j0().map((j)=>A0(j.id,async()=>({adapterId:j.id,...await j.checkReadiness({id:"__probe__",kind:"registered",adapterId:j.id,displayName:j.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null})})))),J=(await h($)).runtimes.filter((j)=>j.kind==="custom"),Q=await Promise.all(J.map((j)=>A0(`custom:${j.id}`,async()=>({adapterId:j.id,...await c(j).checkReadiness(j)}))));return[...X,...Q]}async function x1($,X){let Z=j0().find((j)=>j.id===$);if(Z)return A0(Z.id,async()=>({adapterId:Z.id,...await Z.checkReadiness({id:"__probe__",kind:"registered",adapterId:Z.id,displayName:Z.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null})}));let Q=(await h(X)).runtimes.find((j)=>j.id===$);if(!Q||Q.kind!=="custom")return null;return A0(`custom:${Q.id}`,async()=>({adapterId:Q.id,...await c(Q).checkReadiness(Q)}))}function C1(){Z$.clear(),_0.clear()}function W6($){if(!$)return null;let X=$.indexOf("/");if(X<=0)return null;return $.slice(0,X)}function w0($){let X=[...$.models];if($.adapterId!=="opencode"||X.length===0)return X;let Z=W6($.currentModelId)??(X.some((Q)=>Q.id.startsWith("opencode/"))?"opencode":null);if(!Z)return X;let J=X.filter((Q)=>Q.id===$.currentModelId||Q.id.startsWith(`${Z}/`));return J.length>0?J:X}import{Readable as P6,Writable as L6}from"node:stream";import{ClientSideConnection as f1,ndJsonStream as E1}from"@agentclientprotocol/sdk";import d from"node:fs/promises";import b from"node:path";class H0 extends Error{constructor($){super($);this.name="PathTraversalError"}}class Q$ extends Error{constructor($){super($);this.name="HiddenPathError"}}class j$ extends Error{constructor($){super($);this.name="RunFolderFileTooLargeError"}}class G0 extends Error{constructor($){super($);this.name="RunFolderBinaryFileError"}}var K6=new Set([".bzr",".cache",".claude",".config",".env",".git",".hg",".idea",".obsidian",".svn",".vscode","node_modules"]),F1=1e6,V6=4096,Y6=new TextDecoder("utf-8",{fatal:!0});function z6($){return $.split(/[\\/]+/).filter((X)=>X.length>0)}function T0($){if(b.isAbsolute($))throw new H0("Absolute paths are not allowed");for(let X of z6($)){if(X===".")continue;if(X==="..")throw new H0("Parent-directory traversal is not allowed");if(X.startsWith(".")||K6.has(X))throw new Q$(`Path segment "${X}" is hidden or configuration data`)}}function G6($){T0($);let X=b.normalize($||".");return X==="."?"":X}function H6($,X,Z){let J=b.relative($,X);if(J===".."||J.startsWith(`..${b.sep}`)||b.isAbsolute(J))throw new H0(`Path "${Z}" resolves outside the run folder`);if(J.length>0)T0(J);return J}async function J$($,X){T0(X);let Z=b.resolve($,X||"."),J;try{J=await d.realpath(Z)}catch(Q){if(Q.code!=="ENOENT")throw Q;let j=b.dirname(Z),W=[b.basename(Z)];while(j!==$&&j!==b.dirname(j))try{j=await d.realpath(j);break}catch(G){if(G.code!=="ENOENT")throw G;W.unshift(b.basename(j)),j=b.dirname(j)}J=b.join(j,...W)}return H6($,J,X),J}async function U6($,X){let Z=await d.realpath($);return J$(Z,X)}function D6($){let X=$.subarray(0,Math.min($.length,V6));if(X.length===0)return!1;let Z=0;for(let J of X){if(J===0)return!0;let Q=J===9||J===10||J===12||J===13;if(J<32&&!Q)Z+=1}return Z/X.length>0.3}async function R0($,X){let Z=await U6($,X),J=await d.stat(Z);if(!J.isFile())throw new G0(`Path "${X}" is not a text file`);if(J.size>F1)throw new j$(`File "${X}" is too large to read (${J.size} bytes, max ${F1} bytes)`);let Q=await d.readFile(Z);if(D6(Q))throw new G0(`File "${X}" appears to be binary, not text`);try{return Y6.decode(Q)}catch{throw new G0(`File "${X}" is not valid UTF-8 text`)}}function M6($){if($.isDirectory())return"directory";if($.isFile())return"file";if($.isSymbolicLink())return"symlink";return"other"}function P1($){return $.split(b.sep).join("/")}async function L1($,X=""){let Z=await d.realpath($),J=G6(X),Q=await J$(Z,J),j=await d.readdir(Q,{withFileTypes:!0}),W=[];for(let G of j){let z=J?b.join(J,G.name):G.name;try{T0(z);let K=await J$(Z,z),H=await d.stat(K);W.push({name:G.name,path:P1(z),type:M6(G),size:G.isFile()?H.size:null})}catch{}}return W.sort((G,z)=>{if(G.type==="directory"&&z.type!=="directory")return-1;if(G.type!=="directory"&&z.type==="directory")return 1;return G.name.localeCompare(z.name)}),{path:P1(J),absolutePath:Q,entries:W}}var W$={fs:{readTextFile:!0,writeTextFile:!1},terminal:!1};function k1($){return{readTextFile:async(X)=>{return{content:await R0($,X.path)}}}}import{spawn as N6}from"node:child_process";function K$($){let X=N6($.command,$.args,{cwd:$.cwd,env:$.env,stdio:["pipe","pipe","pipe"]});if(!X.stdin||!X.stdout||!X.stderr)throw Error("Failed to allocate stdio streams for ACP subprocess");let{stdin:Z,stdout:J,stderr:Q}=X,j=4096,W=[],G=0;Q.on("data",(Y)=>{W.push(Y),G+=Y.length;while(G>j*2&&W.length>1){let D=W.shift();if(D)G-=D.length}});let z=()=>{let Y=Buffer.concat(W).toString("utf8");return Y.length>j?Y.slice(-j):Y},K=!1,H=!1,B,U,M=new Promise((Y)=>{B=Y}),N=new Promise((Y)=>{U=Y}),C=(Y)=>{if(H)return;if(H=!0,B(Y),!K)U(Y)};return X.on("exit",(Y,D)=>{C({code:Y,signal:D,stderr:z()})}),X.on("error",(Y)=>{let D=z(),x=Y?.message??String(Y);C({code:null,signal:null,stderr:D?`${x}
4
+ ${D}`:x})}),{stdin:Z,stdout:J,stderr:Q,kill:(Y="SIGTERM")=>{if(K)return;K=!0;try{X.kill(Y)}catch{}},waitForExit:M,processCrashed:N}}var q6=["mcp_ideawave_board_","ideawave_board_","ideawave-board_","ideawave-board.","ideawave.board."];function B6($){let X=$.toLowerCase();for(let Z of q6)if(X.startsWith(Z))return $.slice(Z.length);if(/^mcp[-_.]/i.test($))return $.slice(4);return $}function f0($){return B6($.trim())}function V$($){let X=f0($);if(!X)return"Tool";if(!/[-_.]/.test(X))return X.charAt(0).toUpperCase()+X.slice(1);let Z=X.replace(/[-_.]+/g," ").replace(/\s+/g," ").trim();if(!Z)return"Tool";return Z.charAt(0).toUpperCase()+Z.slice(1)}function Y$($){let X=$?.toLowerCase();if(X==="completed"||X==="complete"||X==="done"||X==="success"||X==="succeeded")return"completed";if(X==="failed"||X==="error"||X==="errored")return"failed";return"running"}function z$($){if(typeof $!=="string")return null;let X=$.trim();return X?X:null}function O1($){if(typeof $!=="string")return"Tool";let X=$.trim();return X?X:"Tool"}function x6($,X){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$;for(let J of X){let Q=Z[J];if(typeof Q==="string"&&Q.trim())return Q.trim()}return null}function G$($,X){let Z=$.trim().toLowerCase();if(Z==="skill"||Z==="workflow"||Z==="tool"||Z==="invalid"){let J=x6(X,["skillName","workflowName","toolName","name","title"]);if(J){let Q=Z==="skill"?" skill":Z==="workflow"?" workflow":"";return`${V$(J)}${Q}`}}if(Z==="invalid")return"Tool call";return V$($)}var C6=33,_1=1600;function e($){if($.length<=_1)return $;return`${$.slice(0,_1-22)}
5
+ ... truncated`}function y0($){let X=$.replace(/\r\n?/g,`
6
+ `),Z=X.trim();if(Z.startsWith('"')&&Z.endsWith('"')||Z.startsWith("'")&&Z.endsWith("'"))try{let Q=JSON.parse(Z);if(typeof Q==="string")return Q.replace(/\r\n?/g,`
7
+ `)}catch{return X}if(!X.includes("\\\""))return X;let J=X.replace(/\\r\\n/g,`
8
8
  `).replace(/\\n/g,`
9
9
  `).replace(/\\r/g,`
10
- `).replace(/\\t/g,"\t").replace(/\\"/g,'"');try{let Q=JSON.parse(J);if(Q!==null&&typeof Q==="object")return J}catch{return Z}return Z}function u($){if($===void 0||$===null)return null;if(typeof $==="string"){let Z=O0($).trim();return Z?r(Z):null}if(typeof $==="number"||typeof $==="boolean"||typeof $==="bigint")return String($);try{return r(JSON.stringify($,null,2))}catch{return r(O0(String($)))}}function $6($){if(!$||typeof $!=="object")return null;let Z=$;if(Z.type==="text"&&typeof Z.text==="string")return O0(Z.text);if(Z.type==="image")return"[image]";if(Z.type==="resource")return"[resource]";if(Z.type==="content"){let X=Z.content;if(X&&typeof X==="object"){let J=X;if(J.type==="text"&&typeof J.text==="string")return O0(J.text);if(J.type==="image")return"[image]";if(J.type==="resource")return"[resource]"}}if(Z.type==="diff")return`Diff: ${typeof Z.path==="string"?Z.path:"unknown file"}`;if(Z.type==="terminal")return`Terminal: ${typeof Z.terminalId==="string"?Z.terminalId:"terminal"}`;return u($)}function P0($){if(!Array.isArray($))return null;let Z=$.map($6).filter((X)=>Boolean(X?.trim()));if(Z.length===0)return null;return r(Z.join(`
10
+ `).replace(/\\t/g,"\t").replace(/\\"/g,'"');try{let Q=JSON.parse(J);if(Q!==null&&typeof Q==="object")return J}catch{return X}return X}function l($){if($===void 0||$===null)return null;if(typeof $==="string"){let X=y0($).trim();return X?e(X):null}if(typeof $==="number"||typeof $==="boolean"||typeof $==="bigint")return String($);try{return e(JSON.stringify($,null,2))}catch{return e(y0(String($)))}}function F6($){if(!$||typeof $!=="object")return null;let X=$;if(X.type==="text"&&typeof X.text==="string")return y0(X.text);if(X.type==="image")return"[image]";if(X.type==="resource")return"[resource]";if(X.type==="content"){let Z=X.content;if(Z&&typeof Z==="object"){let J=Z;if(J.type==="text"&&typeof J.text==="string")return y0(J.text);if(J.type==="image")return"[image]";if(J.type==="resource")return"[resource]"}}if(X.type==="diff")return`Diff: ${typeof X.path==="string"?X.path:"unknown file"}`;if(X.type==="terminal")return`Terminal: ${typeof X.terminalId==="string"?X.terminalId:"terminal"}`;return l($)}function E0($){if(!Array.isArray($))return null;let X=$.map(F6).filter((Z)=>Boolean(Z?.trim()));if(X.length===0)return null;return e(X.join(`
11
11
 
12
- `))}function J$($){if(!$||typeof $!=="object"||Array.isArray($))return u($);let Z=$,X=P0(Z.content);if(X)return X;for(let j of["output","result","text","message"]){let W=u(Z[j]);if(W)return W}let J=u(Z.stdout),Q=u(Z.stderr);if(J||Q)return r([J?`stdout:
12
+ `))}function H$($){if(!$||typeof $!=="object"||Array.isArray($))return l($);let X=$,Z=E0(X.content);if(Z)return Z;for(let j of["output","result","text","message"]){let W=l(X[j]);if(W)return W}let J=l(X.stdout),Q=l(X.stderr);if(J||Q)return e([J?`stdout:
13
13
  ${J}`:null,Q?`stderr:
14
14
  ${Q}`:null].filter(Boolean).join(`
15
15
 
16
- `));return u($)}function n$($,Z){if(!Z)return $;if(!$)return Z;if($===Z||$.endsWith(Z))return $;if(Z.startsWith($))return Z;return r(`${$}
16
+ `));return l($)}function A1($,X){if(!X)return $;if(!$)return X;if($===X||$.endsWith(X))return $;if(X.startsWith($))return X;return e(`${$}
17
17
 
18
- ${Z}`)}function Q$($){if(!Array.isArray($))return null;let Z=$.flatMap((X)=>{if(!X||typeof X!=="object")return[];let J=X;if(typeof J.path!=="string"||!J.path.trim())return[];let Q=typeof J.line==="number"?`:${J.line}`:"";return[`${J.path}${Q}`]});return Z.length>0?Z.slice(0,5):null}function s$($){let{ctx:Z,appendText:X,appendToolActivity:J}=$,Q=$.flushIntervalMs??e2,j="",W="",z=0,V=null,H={},U=new Map,N=(F)=>{if(U.set(F.toolCallId,F),!J)return;J({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,entry:F}).catch((K)=>{console.warn("[streamAdapter] appendToolActivity failed",K)})},D=(F)=>{let K=`${Z.runId}:thought`,L=U.get(K);if(!L||L.status!=="running")return;N({...L,status:"completed",completedAt:L.completedAt??F})},M=(F)=>{for(let K of U.values()){if(K.status!=="running"||K.rawTitle.toLowerCase()!=="toolsearch")continue;N({...K,status:"completed",completedAt:K.completedAt??F})}},x=(F)=>{for(let K of Array.from(U.values())){if(K.status!=="running")continue;if(K.kind==="thought"||K.rawTitle==="agent_thought")continue;N({...K,status:"completed",completedAt:K.completedAt??F})}},B="",Y=0,G=null,P=null,w=(F)=>{if(F===B)return;B=F,Y=Date.now(),X({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,text:F}).catch((K)=>{console.warn("[streamAdapter] appendText failed",K)})},k=()=>{if(G!==null)clearTimeout(G),G=null;if(P!==null){let F=P;P=null,w(F)}},_=(F)=>{let K=Date.now()-Y;if(K>=Q&&G===null){w(F);return}if(P=F,G===null){let L=Math.max(0,Q-K);G=setTimeout(()=>{G=null,k()},L)}};return{onSessionUpdate:async(F)=>{let K=F.update;switch(H[K.sessionUpdate]=(H[K.sessionUpdate]??0)+1,K.sessionUpdate){case"agent_message_chunk":{let L=new Date().toISOString();if(D(L),K.content.type==="text")j+=K.content.text,_(j);else{let T=`agent_message_chunk:${K.content.type}`;H[T]=(H[T]??0)+1}return}case"agent_thought_chunk":{if(K.content.type!=="text")return;W+=K.content.text;let L=new Date().toISOString(),T=`${Z.runId}:thought`,C=U.get(T);N({toolCallId:T,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:C?.startedAt??L,completedAt:null,contentPreview:r(W.trim())});return}case"user_message_chunk":return;case"tool_call":{z+=1;let L=i$(K.title),T=$$(K.status),C=new Date().toISOString();D(C),M(C),N({toolCallId:K.toolCallId,rawTitle:L,title:X$(L,K.rawInput),kind:Z$(K.kind),status:T,startedAt:C,completedAt:T==="running"?null:C,inputPreview:u(K.rawInput),outputPreview:J$(K.rawOutput),contentPreview:P0(K.content),locations:Q$(K.locations)});return}case"tool_call_update":{let L=U.get(K.toolCallId);if(!L){let Z0=i$(K.title),g=$$(K.status),l=new Date().toISOString();N({toolCallId:K.toolCallId,rawTitle:Z0,title:X$(Z0,K.rawInput),kind:Z$(K.kind),status:g,startedAt:l,completedAt:g==="running"?null:l,inputPreview:u(K.rawInput),outputPreview:J$(K.rawOutput),contentPreview:P0(K.content),locations:Q$(K.locations)});return}let T=K.status===void 0||K.status===null?L.status:$$(K.status),C=typeof K.title==="string"&&K.title.trim().length>0?K.title:L.rawTitle,R=typeof K.title==="string"&&K.title.trim().length>0,f=T==="running"?L.completedAt:L.completedAt??new Date().toISOString(),m=K.content===void 0?L.contentPreview:n$(L.contentPreview,P0(K.content)),n=K.rawOutput===void 0?L.outputPreview:n$(L.outputPreview,J$(K.rawOutput));N({...L,rawTitle:C,title:R?X$(C,K.rawInput):L.title,kind:K.kind===void 0?L.kind:Z$(K.kind),status:T,completedAt:f,inputPreview:K.rawInput===void 0?L.inputPreview:u(K.rawInput),outputPreview:n,contentPreview:m,locations:K.locations===void 0?L.locations:Q$(K.locations)});return}case"plan":V=K.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>j,getToolCallCount:()=>z,getLatestPlan:()=>V,getUpdateTypeCounts:()=>({...H}),flush:(F)=>{let K=new Date().toISOString();if(D(K),F?.completeOpenToolCalls)x(K);k()}}}var Y0=1,t$=-32000;function r$($){if($.awaitingInput)return!1;return $.nowMs-$.lastUpdateMs>$.windowMs}function X1($){if(!$||typeof $!=="object")return!1;return $.code===t$}var J6=300000,Q6=5000;function J1(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.43".trim()?"0.0.43":"dev"}}function Q1($){if($===Y0)return;throw new O(`Unsupported ACP protocol version ${$}; expected ${Y0}`)}function j1($){return Z6.toWeb($)}function W1($){return X6.toWeb($)}function j$($){return $!==null&&typeof $==="object"}function j6($){if(!Array.isArray($))return[];let Z=[];for(let X of $){if(!j$(X))continue;if(typeof X.group==="string"&&Array.isArray(X.options)){let J=typeof X.name==="string"?X.name:X.group;for(let Q of X.options){if(!j$(Q))continue;if(typeof Q.value!=="string"||typeof Q.name!=="string")continue;Z.push({value:Q.value,name:Q.name,description:typeof Q.description==="string"?Q.description:null,group:X.group,groupName:J})}continue}if(typeof X.value!=="string"||typeof X.name!=="string")continue;Z.push({value:X.value,name:X.name,description:typeof X.description==="string"?X.description:null,group:null,groupName:null})}return Z}function W6($){if(!j$($))return null;if(typeof $.id!=="string"||typeof $.name!=="string")return null;let Z=typeof $.category==="string"?$.category:null,X=typeof $.description==="string"?$.description:null;if($.type==="select"){let J=typeof $.currentValue==="string"?$.currentValue:null;return{id:$.id,name:$.name,category:Z,description:X,type:"select",currentValue:J,options:j6($.options)}}if($.type==="boolean"){let J=typeof $.currentValue==="boolean"?$.currentValue:typeof $.value==="boolean"?$.value:null;return{id:$.id,name:$.name,category:Z,description:X,type:"boolean",currentValue:J,options:[]}}return null}function W$($){let Z=($.configOptions??[]).map(W6).filter((z)=>z!==null),X=Z.find((z)=>z.type==="select"&&z.category==="model")??Z.find((z)=>z.type==="select"&&z.id==="model")??null,J=X?.options.map((z)=>({id:z.value,name:z.name,description:z.description??null})),Q=$.models?.availableModels?.map((z)=>({id:z.modelId,name:z.name??null,description:z.description??null})),j=J&&J.length>0?J:Q&&Q.length>0?Q:null,W=(typeof X?.currentValue==="string"?X.currentValue:null)??$.models?.currentModelId??null;return{models:j,currentModelId:W,configOptions:Z,modelConfigId:X?.id??null}}function K6($,Z){let X=[];if($.trim())X.push({type:"text",text:$});for(let J of Z)if(J.content.trim())X.push({type:"text",text:J.content});return X}function V6($){if(typeof $.value==="boolean")return{sessionId:$.sessionId,configId:$.configId,type:"boolean",value:$.value};return{sessionId:$.sessionId,configId:$.configId,value:$.value}}function Y6($,Z){let X=W$({configOptions:Z.configOptions});return{models:X.models??$.models,currentModelId:X.currentModelId??$.currentModelId,configOptions:X.configOptions,modelConfigId:X.modelConfigId??$.modelConfigId}}async function e$($){try{let Z=await $.conn.setSessionConfigOption(V6({sessionId:$.sessionId,configId:$.configId,value:$.value}));return Y6($.metadata,Z)}catch(Z){return console.warn(`[acp] setSessionConfigOption(${$.label}) failed; using agent default.`,Z instanceof Error?Z.message:Z),$.metadata}}async function K$($){let Z=r0($.spawn),X=[],J=0,Q=4096;Z.stderr.on("data",(C)=>{X.push(C),J+=C.length;while(J>Q*2&&X.length>1){let R=X.shift();if(R)J-=R.length}});let j=()=>{let C=Buffer.concat(X).toString("utf8");return C.length>Q?C.slice(-Q):C},W=a$($.spawn.cwd),z={current:null},V={at:Date.now()},H=W1(Z.stdin),U=j1(Z.stdout),N=Z1(H,U),M=new $1((C)=>({requestPermission:async(R)=>{let f=R.options,m=f?.find((n)=>n.kind==="allow_once")??f?.find((n)=>n.kind==="allow_always");if(m)return{outcome:{outcome:"selected",optionId:m.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(R)=>{V.at=Date.now();let f=z.current;if(f)await f.onSessionUpdate(R)},readTextFile:W.readTextFile}),N),x=()=>Z.kill();if($.signal)$.signal.addEventListener("abort",x);let B=()=>{if($.signal)$.signal.removeEventListener("abort",x)},Y=async(C,R)=>{if(B(),Z.kill(),X1(C))throw new X0(C.message??"Authentication required",R);if(C instanceof Error&&C.message==="ACP connection closed"){if($.signal?.aborted)throw new O("ACP session cancelled: abort signal received");let f=await Promise.race([Z.processCrashed,Z.waitForExit,new Promise((m)=>setTimeout(()=>m({stderr:""}),500))]);throw new O(`Runtime process exited before completion: ${f.stderr?.trim()??""}`)}throw C},G;try{G=await M.initialize({protocolVersion:Y0,clientCapabilities:t0,clientInfo:J1()})}catch(C){throw await Y(C,[]),Error("unreachable")}try{Q1(G.protocolVersion)}catch(C){throw B(),Z.kill(),C}let P=G.authMethods?.map((C)=>C.id)??[],w;try{w=await M.newSession({cwd:$.spawn.cwd,mcpServers:$.mcpServers??[]})}catch(C){throw await Y(C,P),Error("unreachable")}let k=w.sessionId,_=W$(w),F=$.modelId??null;if(F&&F!==_.currentModelId)if(_.modelConfigId){let C=_;if(_=await e$({conn:M,sessionId:k,configId:_.modelConfigId,value:F,metadata:_,label:`${_.modelConfigId}=${F}`}),_===C)try{await M.unstable_setSessionModel({sessionId:k,modelId:F})}catch(R){console.warn(`[acp] setSessionModel(${F}) failed; using agent default.`,R instanceof Error?R.message:R)}}else try{await M.unstable_setSessionModel({sessionId:k,modelId:F})}catch(C){console.warn(`[acp] setSessionModel(${F}) failed; using agent default.`,C instanceof Error?C.message:C)}for(let[C,R]of Object.entries($.configValues??{}).sort(([f],[m])=>f.localeCompare(m))){if(C===_.modelConfigId)continue;if(!_.configOptions.some((f)=>f.id===C))continue;_=await e$({conn:M,sessionId:k,configId:C,value:R,metadata:_,label:`${C}=${String(R)}`})}B();let K=!1,L=async()=>{if(K)return;K=!0,Z.kill(),await Promise.race([Z.waitForExit,new Promise((C)=>setTimeout(C,2000))])},T=!1;return Z.processCrashed.then(()=>{T=!0}),{sessionId:k,availableModels:_.models,currentModelId:_.currentModelId,availableConfigOptions:_.configOptions,isAlive:()=>!K&&!T,dispose:L,prompt:(C)=>G6({proc:Z,conn:M,sessionId:k,activeAdapter:z,lastUpdate:V,collectStderrTail:j},C)}}async function G6($,Z){let{proc:X,conn:J,sessionId:Q,activeAdapter:j,lastUpdate:W}=$,z={boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId},V=s$({ctx:z,appendText:Z.appendText,appendToolActivity:Z.appendToolActivity});j.current=V,W.at=Date.now();let H=!1,U=null,N=()=>X.kill();Z.signal.addEventListener("abort",N);try{let D=async()=>{let Y=Z.heartbeatMs??J6,G=Math.min(Q6,Math.max(50,Math.floor(Y/2)));U=setInterval(()=>{let w=Z.isAwaitingInput?.()??!1;if(w){W.at=Date.now();return}if(r$({nowMs:Date.now(),lastUpdateMs:W.at,windowMs:Y,awaitingInput:w}))H=!0,J.cancel({sessionId:Q}).catch(()=>{return}),X.kill()},G);let P=K6(Z.prompt.systemPrompt,Z.prompt.messages);await J.prompt({sessionId:Q,prompt:P}),V.flush({completeOpenToolCalls:!0})},M=X.waitForExit.then((Y)=>({kind:"exited",exit:Y})),x=D().then(()=>({kind:"ok"})).catch(async(Y)=>{if(Y instanceof Error&&Y.message==="ACP connection closed")return{kind:"crashed",exit:await Promise.race([X.processCrashed,X.waitForExit])};throw Y}),B;try{B=await Promise.race([x,X.processCrashed.then((Y)=>({kind:"crashed",exit:Y})),M])}catch(Y){if(H)throw new d;throw Y}if(H)throw new d;if(B.kind==="crashed")throw new O(`Runtime process exited before completion: ${B.exit.stderr.trim()}`);if(B.kind==="exited"){if(Z.signal.aborted)throw new O("ACP session cancelled: abort signal received");if(H)throw new d;throw new O(`Runtime process exited unexpectedly: ${B.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:V.getFinalText(),toolCallsExecuted:V.getToolCallCount(),stderrTail:$.collectStderrTail(),updateTypeCounts:V.getUpdateTypeCounts()}}finally{if(U!==null)clearInterval(U);Z.signal.removeEventListener("abort",N),V.flush({completeOpenToolCalls:!0}),j.current=null}}var z6=30000;async function K1($){let Z=r0($.spawn),X=W1(Z.stdin),J=j1(Z.stdout),Q=Z1(X,J),W=new $1((H)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),Q),z=()=>Z.kill();if($.signal)$.signal.addEventListener("abort",z);let V=null;try{let H=(async()=>{let N=await W.initialize({protocolVersion:Y0,clientCapabilities:t0,clientInfo:J1()});Q1(N.protocolVersion);let D=N.authMethods?.map((G)=>G.id)??[],M;try{M=await W.newSession({cwd:$.spawn.cwd,mcpServers:[]})}catch(G){if(X1(G))throw new X0(G.message??"Authentication required",D);throw G}let x=W$(M),B=x.models??[],Y=x.currentModelId;return W.cancel({sessionId:M.sessionId}).catch(()=>{return}),{models:B,configOptions:x.configOptions,currentModelId:Y}})(),U=new Promise((N,D)=>{V=setTimeout(()=>{D(new d)},z6)});return await Promise.race([H,U])}catch(H){if(H instanceof Error&&H.message==="ACP connection closed"){if($.signal?.aborted)throw new O("ACP model discovery cancelled: abort signal received");throw new O("Runtime process exited during model discovery.")}throw H}finally{if(V)clearTimeout(V);if($.signal)$.signal.removeEventListener("abort",z);Z.kill()}}var E=new Map,p=null;function k0($){$.then((Z)=>Z.dispose()).catch(()=>{return})}function H6(){if(p!==null)return;p=setInterval(()=>{let $=Date.now();for(let[Z,X]of E){if(X.inUse)continue;if($-X.lastUsed<600000)continue;E.delete(Z),k0(X.sessionPromise)}if(E.size===0&&p!==null)clearInterval(p),p=null},60000),p.unref?.()}function U6(){if(E.size<200)return;let $=null,Z=1/0;for(let[J,Q]of E){if(Q.inUse)continue;if(Q.lastUsed>=Z)continue;$=J,Z=Q.lastUsed}if(!$)return;let X=E.get($);if(!X)return;E.delete($),k0(X.sessionPromise)}function V$($,Z,X){return`${$}:${Z}:${X}`}async function Y$($){let Z=E.get($.key);if(Z)if(Z.fingerprint===$.fingerprint){Z.inUse=!0,Z.lastUsed=Date.now();try{let J=await Z.sessionPromise;if(J.isAlive())return J}catch{}E.delete($.key)}else E.delete($.key),k0(Z.sessionPromise);let X=$.open();U6(),E.set($.key,{key:$.key,fingerprint:$.fingerprint,sessionPromise:X,lastUsed:Date.now(),inUse:!0}),H6();try{return await X}catch(J){throw E.delete($.key),J}}function G$($,Z=!1){let X=E.get($);if(!X)return;if(Z){E.delete($),k0(X.sessionPromise);return}X.inUse=!1,X.lastUsed=Date.now()}async function D6(){let $=Array.from(E.values());if(E.clear(),p!==null)clearInterval(p),p=null;await Promise.all($.map((Z)=>Z.sessionPromise.then((X)=>X.dispose()).catch(()=>{return})))}function z$($){let Z=Object.entries($.configValues??{}),X=Z.length>0?JSON.stringify(Object.fromEntries(Z.sort(([J],[Q])=>J.localeCompare(Q)))):"";return[$.adapterId,$.configId??"",$.modelId??"",X,$.mcpUrl??"",$.runFolder??"",$.toolSurface??"full"].join(" ")}var V1=!1;function M6(){if(V1)return;V1=!0;let $=()=>{D6()};process.once("beforeExit",$),process.once("SIGTERM",$),process.once("SIGINT",$)}M6();import G0 from"node:fs/promises";import F6 from"node:path";import{z as q}from"zod";var Y1=q.object({id:q.string(),name:q.string().nullable().default(null),description:q.string().nullable().default(null)}),H1=q.union([q.string(),q.boolean()]),N6=q.object({value:q.string(),name:q.string(),description:q.string().nullable().default(null),group:q.string().nullable().default(null),groupName:q.string().nullable().default(null)}),G1=q.object({id:q.string(),name:q.string(),category:q.string().nullable().default(null),description:q.string().nullable().default(null),type:q.enum(["select","boolean"]),currentValue:H1.nullable().default(null),options:q.array(N6).default([])}),H$=q.record(q.string(),H1).default({}),q6=q.discriminatedUnion("kind",[q.object({id:q.string(),kind:q.literal("registered"),adapterId:q.enum(["claude-code","opencode","codex","copilot"]),displayName:q.string(),runFolder:q.string().nullable(),defaultModelId:q.string().nullable().default(null),defaultConfigValues:H$,discoveredModels:q.array(Y1).default([]),discoveredConfigOptions:q.array(G1).default([]),discoveredAt:q.string().nullable().default(null)}),q.object({id:q.string(),kind:q.literal("custom"),displayName:q.string(),command:q.string(),args:q.array(q.string()),env:q.record(q.string(),q.string()),runFolder:q.string().nullable(),defaultModelId:q.string().nullable().default(null),defaultConfigValues:H$,discoveredModels:q.array(Y1).default([]),discoveredConfigOptions:q.array(G1).default([]),discoveredAt:q.string().nullable().default(null)})]),z1=q.object({runtimeConfigId:q.string(),runFolder:q.string().nullable(),modelId:q.string().nullable().default(null),configValues:H$}),_0=q.object({version:q.literal(1),globalDefaultConfigId:q.string().nullable(),runtimes:q.array(q6),boardOverrides:q.record(q.string(),z1).default({}),cardOverrides:q.record(q.string(),z1).default({})});import B6 from"node:os";import A0 from"node:path";function C6(){let $=B6.homedir();switch(process.platform){case"win32":return process.env.APPDATA??A0.join($,"AppData","Roaming");case"darwin":return A0.join($,"Library","Application Support");default:return process.env.XDG_CONFIG_HOME??A0.join($,".config")}}function w0(){let $=process.env.IDEAWAVE_RUNTIME_CONFIG_PATH;if($)return $;return A0.join(C6(),"ideawave","runtimes.json")}var x6={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},U1=new Map;function L6($){return U1.get($)??Promise.resolve()}function P6($,Z){U1.set($,Z)}async function v($){let Z=$??w0(),X;try{X=await G0.readFile(Z,"utf-8")}catch(Q){if(Q.code==="ENOENT")return structuredClone(x6);throw Q}return _0.parse(JSON.parse(X))}async function S($,Z){let X=Z??w0(),J=L6(X).then(async()=>{let Q=await v(X),j=structuredClone(Q),W=await $(j);return await O6(j,X),W});return P6(X,J.catch(()=>{return})),J}async function O6($,Z){let X=Z??w0(),J=F6.dirname(X);await G0.mkdir(J,{recursive:!0});let Q=`${X}.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`,j=JSON.stringify($,null,2);await G0.writeFile(Q,j,"utf-8");try{await G0.rename(Q,X)}catch(W){throw await G0.unlink(Q).catch(()=>{return}),W}}import A6 from"node:fs/promises";import T0 from"node:os";var D1="claude",U$="@agentclientprotocol/claude-agent-acp",M1=["claude-agent-acp","claude-code-acp"],N1="Install Claude Code from https://github.com/anthropics/claude-code",q1={id:"claude-code",displayName:"Claude Code",kind:"registered",resolveSpawnConfig:async()=>{if(!await A(D1))throw new O(`Claude Code CLI not found. ${N1}`);let Z=B0(U$);if(Z)return{command:Z.command,args:Z.args,env:b(Z.env)};let X=J0(U$),J=X?.status==="installing";for(let j of M1){let W=await A(j);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 O(Q)},checkReadiness:async()=>{if(!await A(D1))return{status:"not_installed",detail:N1};let Z=J0(U$);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 M1)if(await A(X))return{status:"ready"};return{status:"not_running",detail:"Installing Claude Code ACP bridge..."}},authHint:"Run `claude login` (or set ANTHROPIC_API_KEY)."};var B1="codex",D$="@agentclientprotocol/codex-acp",C1="codex-acp",F1="Install Codex CLI from https://developers.openai.com/codex/cli",x1={id:"codex",displayName:"Codex",kind:"registered",resolveSpawnConfig:async()=>{if(!await A(B1))throw new O(`Codex CLI not found. ${F1}`);let Z=B0(D$);if(Z)return{command:Z.command,args:Z.args,env:b(Z.env)};let X=J0(D$),J=X?.status==="installing",Q=await A(C1);if(Q&&!J&&X?.status!=="failed")return{command:Q,args:[],env:b()};let j=X?.status==="failed"?`Codex ACP bridge install failed. ${X.error??"Restart IdeaWave CLI so it can warm the pinned bridge again."}`:"Codex ACP bridge is not ready. Keep IdeaWave CLI running and retry in a moment.";throw new O(j)},checkReadiness:async()=>{if(!await A(B1))return{status:"not_installed",detail:F1};let Z=J0(D$);if(Z?.status==="ready")return{status:"ready"};if(Z?.status==="installing")return{status:"not_running",detail:"Installing Codex ACP bridge..."};if(Z?.status==="failed")return{status:"not_running",detail:Z.error??"Codex ACP bridge install failed. Restart IdeaWave CLI so it can warm the pinned bridge again."};if(await A(C1))return{status:"ready"};return{status:"not_running",detail:"Installing Codex ACP bridge..."}},authHint:"Run `codex login` (or set OPENAI_API_KEY)."};var L1="copilot",P1="copilot-acp",O1="npm i -g @github/copilot",k1={id:"copilot",displayName:"GitHub Copilot",kind:"registered",resolveSpawnConfig:async()=>{let $=await A(L1);if($)return{command:$,args:["--acp"],env:b()};let Z=await A(P1);if(Z)return{command:Z,args:[],env:b()};throw new O(`Copilot not installed. Run: ${O1}`)},checkReadiness:async()=>{if(await A(L1))return{status:"ready"};if(await A(P1))return{status:"ready"};return{status:"not_installed",detail:O1}},authHint:"Run `gh auth login` (or `copilot login`)."};import k6 from"node:fs/promises";function _6($){return $.startsWith("/")||/^[a-zA-Z]:[\\/]/.test($)}async function _1($){if(_6($))try{return await k6.access($),!0}catch{return!1}return await A($)!==null}var A1={id:"custom",displayName:"Custom ACP",kind:"custom",resolveSpawnConfig:async($)=>{if($.kind!=="custom")throw new O("customAdapter received non-custom entry");if(!await _1($.command))throw new O(`custom: command "${$.command}" not found`);return{command:$.command,args:$.args,env:b($.env)}},checkReadiness:async($)=>{if($.kind!=="custom")return{status:"unknown"};return await _1($.command)?{status:"ready"}:{status:"not_installed"}}};var w1="opencode",T1="Install OpenCode from https://opencode.ai",R1={id:"opencode",displayName:"OpenCode",kind:"registered",resolveSpawnConfig:async()=>{let $=await A(w1);if(!$)throw new O(`OpenCode not installed. ${T1}`);return{command:$,args:["acp"],env:b()}},checkReadiness:async()=>{if(!await A(w1))return{status:"not_installed",detail:T1};return{status:"ready"}},authHint:"Run `opencode auth login <provider>` (or set the provider's API-key env var)."};var f1={"claude-code":q1,opencode:R1,codex:x1,copilot:k1};function c($){if($.kind==="custom")return A1;let Z=f1[$.adapterId];if(!Z)throw Error(`Unknown registered adapter: ${$.adapterId}`);return Z}function Q0(){return Object.values(f1)}async function E1($){let Z={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},X;try{X=await A6.readFile($,"utf-8")}catch(J){if(J.code==="ENOENT")return structuredClone(Z);throw J}return _0.parse(JSON.parse(X))}function M$($,Z,X){return{...$.defaultConfigValues??{},...Z?.configValues??{},...X?.configValues??{}}}async function e($){let Z=$.configPath?await E1($.configPath):await v(),X=$.cardId?Z.cardOverrides[$.cardId]:void 0;if(X?.runtimeConfigId){let Q=Z.runtimes.find((j)=>j.id===X.runtimeConfigId);if(Q)return{entry:Q,adapter:c(Q),runFolder:X.runFolder??Q.runFolder??T0.homedir(),modelId:X.modelId??Q.defaultModelId??null,configValues:M$(Q,void 0,X)}}let J=Z.boardOverrides[$.boardId];if(J?.runtimeConfigId){let Q=Z.runtimes.find((j)=>j.id===J.runtimeConfigId);if(Q)return{entry:Q,adapter:c(Q),runFolder:J.runFolder??Q.runFolder??T0.homedir(),modelId:J.modelId??Q.defaultModelId??null,configValues:M$(Q,J)}}if(Z.globalDefaultConfigId){let Q=Z.runtimes.find((j)=>j.id===Z.globalDefaultConfigId);if(Q)return{entry:Q,adapter:c(Q),runFolder:X?.runFolder??J?.runFolder??Q.runFolder??T0.homedir(),modelId:X?.modelId??J?.modelId??Q.defaultModelId??null,configValues:M$(Q,J,X)}}throw new s}async function y1($,Z={}){let J=(Z.configPath?await E1(Z.configPath):await v()).runtimes.find((Q)=>Q.id===$);if(!J)return null;return{entry:J,adapter:c(J),runFolder:J.runFolder??T0.homedir(),modelId:Z.modelId??J.defaultModelId??null,configValues:{...J.defaultConfigValues??{},...Z.configValues??{}}}}var $0=new Map,N$=new Set;function q$($){$0.get($)?.controller.abort()}function b1($){for(let[Z,X]of $0){if(X.frontendSessionId!==$)continue;X.controller.abort(),$0.delete(Z)}}function I1(){for(let $ of $0.values())$.controller.abort();$0.clear()}function v1($,Z){if(Z?.aborted)return!0;return $ instanceof Error&&/abort signal received|session cancelled/i.test($.message)}function h1($,Z,X,J){if((!Z.availableModels||Z.availableModels.length===0)&&Z.availableConfigOptions.length===0)return;S((Q)=>{let j=Q.runtimes.find((W)=>W.id===$);if(j){if(Z.availableModels&&Z.availableModels.length>0)j.discoveredModels=C0({adapterId:X,models:Z.availableModels,currentModelId:Z.currentModelId??J});if(Z.availableConfigOptions.length>0)j.discoveredConfigOptions=Z.availableConfigOptions}}).catch(()=>{return})}function w6($,Z){return`${$}
18
+ ${X}`)}function U$($){if(!Array.isArray($))return null;let X=$.flatMap((Z)=>{if(!Z||typeof Z!=="object")return[];let J=Z;if(typeof J.path!=="string"||!J.path.trim())return[];let Q=typeof J.line==="number"?`:${J.line}`:"";return[`${J.path}${Q}`]});return X.length>0?X.slice(0,5):null}function w1($){let{ctx:X,appendText:Z,appendToolActivity:J}=$,Q=$.flushIntervalMs??C6,j="",W="",G=0,z=null,K={},H=new Map,B=(P)=>{if(H.set(P.toolCallId,P),!J)return;J({boardId:X.boardId,cardId:X.cardId,runId:X.runId,entry:P}).catch((V)=>{console.warn("[streamAdapter] appendToolActivity failed",V)})},U=(P)=>{let V=`${X.runId}:thought`,F=H.get(V);if(!F||F.status!=="running")return;B({...F,status:"completed",completedAt:F.completedAt??P})},M=(P)=>{for(let V of H.values()){if(V.status!=="running"||V.rawTitle.toLowerCase()!=="toolsearch")continue;B({...V,status:"completed",completedAt:V.completedAt??P})}},N=(P)=>{for(let V of Array.from(H.values())){if(V.status!=="running")continue;if(V.kind==="thought"||V.rawTitle==="agent_thought")continue;B({...V,status:"completed",completedAt:V.completedAt??P})}},C="",Y=0,D=null,x=null,k=(P)=>{if(P===C)return;C=P,Y=Date.now(),Z({boardId:X.boardId,cardId:X.cardId,runId:X.runId,text:P}).catch((V)=>{console.warn("[streamAdapter] appendText failed",V)})},A=()=>{if(D!==null)clearTimeout(D),D=null;if(x!==null){let P=x;x=null,k(P)}},_=(P)=>{let V=Date.now()-Y;if(V>=Q&&D===null){k(P);return}if(x=P,D===null){let F=Math.max(0,Q-V);D=setTimeout(()=>{D=null,A()},F)}};return{onSessionUpdate:async(P)=>{let V=P.update;switch(K[V.sessionUpdate]=(K[V.sessionUpdate]??0)+1,V.sessionUpdate){case"agent_message_chunk":{let F=new Date().toISOString();if(U(F),V.content.type==="text")j+=V.content.text,_(j);else{let T=`agent_message_chunk:${V.content.type}`;K[T]=(K[T]??0)+1}return}case"agent_thought_chunk":{if(V.content.type!=="text")return;W+=V.content.text;let F=new Date().toISOString(),T=`${X.runId}:thought`,R=H.get(T);B({toolCallId:T,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:R?.startedAt??F,completedAt:null,contentPreview:e(W.trim())});return}case"user_message_chunk":return;case"tool_call":{G+=1;let F=O1(V.title),T=Y$(V.status),R=new Date().toISOString();U(R),M(R),B({toolCallId:V.toolCallId,rawTitle:F,title:G$(F,V.rawInput),kind:z$(V.kind),status:T,startedAt:R,completedAt:T==="running"?null:R,inputPreview:l(V.rawInput),outputPreview:H$(V.rawOutput),contentPreview:E0(V.content),locations:U$(V.locations)});return}case"tool_call_update":{let F=H.get(V.toolCallId);if(!F){let p=O1(V.title),B0=Y$(V.status),X0=new Date().toISOString();B({toolCallId:V.toolCallId,rawTitle:p,title:G$(p,V.rawInput),kind:z$(V.kind),status:B0,startedAt:X0,completedAt:B0==="running"?null:X0,inputPreview:l(V.rawInput),outputPreview:H$(V.rawOutput),contentPreview:E0(V.content),locations:U$(V.locations)});return}let T=V.status===void 0||V.status===null?F.status:Y$(V.status),R=typeof V.title==="string"&&V.title.trim().length>0?V.title:F.rawTitle,L=typeof V.title==="string"&&V.title.trim().length>0,f=T==="running"?F.completedAt:F.completedAt??new Date().toISOString(),E=V.content===void 0?F.contentPreview:A1(F.contentPreview,E0(V.content)),I=V.rawOutput===void 0?F.outputPreview:A1(F.outputPreview,H$(V.rawOutput));B({...F,rawTitle:R,title:L?G$(R,V.rawInput):F.title,kind:V.kind===void 0?F.kind:z$(V.kind),status:T,completedAt:f,inputPreview:V.rawInput===void 0?F.inputPreview:l(V.rawInput),outputPreview:I,contentPreview:E,locations:V.locations===void 0?F.locations:U$(V.locations)});return}case"plan":z=V.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>j,getToolCallCount:()=>G,getLatestPlan:()=>z,getUpdateTypeCounts:()=>({...K}),flush:(P)=>{let V=new Date().toISOString();if(U(V),P?.completeOpenToolCalls)N(V);A()}}}var U0=1,T1=-32000;function R1($){if($.awaitingInput)return!1;return $.nowMs-$.lastUpdateMs>$.windowMs}function y1($){if(!$||typeof $!=="object")return!1;return $.code===T1}var k6=300000,O6=5000;function b1(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.44".trim()?"0.0.44":"dev"}}function v1($){if($===U0)return;throw new O(`Unsupported ACP protocol version ${$}; expected ${U0}`)}function I1($){return P6.toWeb($)}function h1($){return L6.toWeb($)}function D$($){return $!==null&&typeof $==="object"}function _6($){if(!Array.isArray($))return[];let X=[];for(let Z of $){if(!D$(Z))continue;if(typeof Z.group==="string"&&Array.isArray(Z.options)){let J=typeof Z.name==="string"?Z.name:Z.group;for(let Q of Z.options){if(!D$(Q))continue;if(typeof Q.value!=="string"||typeof Q.name!=="string")continue;X.push({value:Q.value,name:Q.name,description:typeof Q.description==="string"?Q.description:null,group:Z.group,groupName:J})}continue}if(typeof Z.value!=="string"||typeof Z.name!=="string")continue;X.push({value:Z.value,name:Z.name,description:typeof Z.description==="string"?Z.description:null,group:null,groupName:null})}return X}function A6($){if(!D$($))return null;if(typeof $.id!=="string"||typeof $.name!=="string")return null;let X=typeof $.category==="string"?$.category:null,Z=typeof $.description==="string"?$.description:null;if($.type==="select"){let J=typeof $.currentValue==="string"?$.currentValue:null;return{id:$.id,name:$.name,category:X,description:Z,type:"select",currentValue:J,options:_6($.options)}}if($.type==="boolean"){let J=typeof $.currentValue==="boolean"?$.currentValue:typeof $.value==="boolean"?$.value:null;return{id:$.id,name:$.name,category:X,description:Z,type:"boolean",currentValue:J,options:[]}}return null}function M$($){let X=($.configOptions??[]).map(A6).filter((G)=>G!==null),Z=X.find((G)=>G.type==="select"&&G.category==="model")??X.find((G)=>G.type==="select"&&G.id==="model")??null,J=Z?.options.map((G)=>({id:G.value,name:G.name,description:G.description??null})),Q=w6($.models),j=J&&J.length>0?J:Q&&Q.length>0?Q:null,W=(typeof Z?.currentValue==="string"?Z.currentValue:null)??T6($.models)??null;return{models:j,currentModelId:W,configOptions:X,modelConfigId:Z?.id??null}}function w6($){if(!$||!Array.isArray($.availableModels))return null;let X=[];for(let Z of $.availableModels){if(typeof Z.modelId!=="string")continue;X.push({id:Z.modelId,name:typeof Z.name==="string"?Z.name:null,description:typeof Z.description==="string"?Z.description:null})}return X.length>0?X:null}function T6($){return typeof $?.currentModelId==="string"?$.currentModelId:null}function R6($,X){let Z=[];if($.trim())Z.push({type:"text",text:$});for(let J of X)if(J.content.trim())Z.push({type:"text",text:J.content});return Z}function f6($){if(typeof $.value==="boolean")return{sessionId:$.sessionId,configId:$.configId,type:"boolean",value:$.value};return{sessionId:$.sessionId,configId:$.configId,value:$.value}}function E6($,X){let Z=M$({configOptions:X.configOptions});return{models:Z.models??$.models,currentModelId:Z.currentModelId??$.currentModelId,configOptions:Z.configOptions,modelConfigId:Z.modelConfigId??$.modelConfigId}}function S1($,X){if($==="default")return null;if(!X||X.length===0)return $;let Z=X.find((K)=>K.id===$);if(Z)return Z.id;let J=$.toLowerCase(),Q=J.includes("opus")?"opus":J.includes("sonnet")?"sonnet":J.includes("haiku")?"haiku":null;if(!Q)return $;let j=(K)=>`${K.id} ${K.name??""} ${K.description??""}`.toLowerCase(),W=X.filter((K)=>j(K).includes(Q));if(W.length===0)return $;let z=(J.includes("1m")?W.find((K)=>j(K).includes("1m")):void 0)??W[0];return z?z.id:$}async function b0($){try{let X=await $.conn.setSessionConfigOption(f6({sessionId:$.sessionId,configId:$.configId,value:$.value}));return E6($.metadata,X)}catch(X){return console.warn(`[acp] setSessionConfigOption(${$.label}) failed; using agent default.`,X instanceof Error?X.message:X),$.metadata}}async function N$($){let X=K$($.spawn),Z=[],J=0,Q=4096;X.stderr.on("data",(L)=>{Z.push(L),J+=L.length;while(J>Q*2&&Z.length>1){let f=Z.shift();if(f)J-=f.length}});let j=()=>{let L=Buffer.concat(Z).toString("utf8");return L.length>Q?L.slice(-Q):L},W=k1($.spawn.cwd),G={current:null},z={at:Date.now()},K=h1(X.stdin),H=I1(X.stdout),B=E1(K,H),M=new f1((L)=>({requestPermission:async(f)=>{let E=f.options,I=E?.find((p)=>p.kind==="allow_once")??E?.find((p)=>p.kind==="allow_always");if(I)return{outcome:{outcome:"selected",optionId:I.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(f)=>{z.at=Date.now();let E=G.current;if(E)await E.onSessionUpdate(f)},readTextFile:W.readTextFile}),B),N=()=>X.kill();if($.signal)$.signal.addEventListener("abort",N);let C=()=>{if($.signal)$.signal.removeEventListener("abort",N)},Y=async(L,f)=>{if(C(),X.kill(),y1(L))throw new J0(L.message??"Authentication required",f);if(L instanceof Error&&L.message==="ACP connection closed"){if($.signal?.aborted)throw new O("ACP session cancelled: abort signal received");let E=await Promise.race([X.processCrashed,X.waitForExit,new Promise((I)=>setTimeout(()=>I({stderr:""}),500))]);throw new O(`Runtime process exited before completion: ${E.stderr?.trim()??""}`)}throw L},D;try{D=await M.initialize({protocolVersion:U0,clientCapabilities:W$,clientInfo:b1()})}catch(L){throw await Y(L,[]),Error("unreachable")}try{v1(D.protocolVersion)}catch(L){throw C(),X.kill(),L}let x=D.authMethods?.map((L)=>L.id)??[],k;try{k=await M.newSession({cwd:$.spawn.cwd,mcpServers:$.mcpServers??[]})}catch(L){throw await Y(L,x),Error("unreachable")}let A=k.sessionId,_=M$(k),P=$.modelId??null,V=P?S1(P,_.models):null;if(V&&V!==_.currentModelId)if(_.modelConfigId)_=await b0({conn:M,sessionId:A,configId:_.modelConfigId,value:V,metadata:_,label:`${_.modelConfigId}=${V}`});else console.warn(`[acp] runtime did not advertise a model config option for ${V}; using agent default.`);for(let[L,f]of Object.entries($.configValues??{}).sort(([E],[I])=>E.localeCompare(I))){if(L===_.modelConfigId)continue;if(!_.configOptions.some((E)=>E.id===L))continue;_=await b0({conn:M,sessionId:A,configId:L,value:f,metadata:_,label:`${L}=${String(f)}`})}C();let F=!1,T=async()=>{if(F)return;F=!0,X.kill(),await Promise.race([X.waitForExit,new Promise((L)=>setTimeout(L,2000))])},R=!1;return X.processCrashed.then(()=>{R=!0}),{sessionId:A,availableModels:_.models,currentModelId:_.currentModelId,availableConfigOptions:_.configOptions,isAlive:()=>!F&&!R,dispose:T,prompt:(L)=>y6({proc:X,conn:M,sessionId:A,activeAdapter:G,lastUpdate:z,collectStderrTail:j},L)}}async function y6($,X){let{proc:Z,conn:J,sessionId:Q,activeAdapter:j,lastUpdate:W}=$,G={boardId:X.boardId,cardId:X.cardId,runId:X.runId},z=w1({ctx:G,appendText:X.appendText,appendToolActivity:X.appendToolActivity});j.current=z,W.at=Date.now();let K=!1,H=null,B=()=>Z.kill();X.signal.addEventListener("abort",B);try{let U=async()=>{let Y=X.heartbeatMs??k6,D=Math.min(O6,Math.max(50,Math.floor(Y/2)));H=setInterval(()=>{let k=X.isAwaitingInput?.()??!1;if(k){W.at=Date.now();return}if(R1({nowMs:Date.now(),lastUpdateMs:W.at,windowMs:Y,awaitingInput:k}))K=!0,J.cancel({sessionId:Q}).catch(()=>{return}),Z.kill()},D);let x=R6(X.prompt.systemPrompt,X.prompt.messages);await J.prompt({sessionId:Q,prompt:x}),z.flush({completeOpenToolCalls:!0})},M=Z.waitForExit.then((Y)=>({kind:"exited",exit:Y})),N=U().then(()=>({kind:"ok"})).catch(async(Y)=>{if(Y instanceof Error&&Y.message==="ACP connection closed")return{kind:"crashed",exit:await Promise.race([Z.processCrashed,Z.waitForExit])};throw Y}),C;try{C=await Promise.race([N,Z.processCrashed.then((Y)=>({kind:"crashed",exit:Y})),M])}catch(Y){if(K)throw new a;throw Y}if(K)throw new a;if(C.kind==="crashed")throw new O(`Runtime process exited before completion: ${C.exit.stderr.trim()}`);if(C.kind==="exited"){if(X.signal.aborted)throw new O("ACP session cancelled: abort signal received");if(K)throw new a;throw new O(`Runtime process exited unexpectedly: ${C.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:z.getFinalText(),toolCallsExecuted:z.getToolCallCount(),stderrTail:$.collectStderrTail(),updateTypeCounts:z.getUpdateTypeCounts()}}finally{if(H!==null)clearInterval(H);X.signal.removeEventListener("abort",B),z.flush({completeOpenToolCalls:!0}),j.current=null}}var b6=30000;async function m1($){let X=K$($.spawn),Z=h1(X.stdin),J=I1(X.stdout),Q=E1(Z,J),W=new f1((K)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),Q),G=()=>X.kill();if($.signal)$.signal.addEventListener("abort",G);let z=null;try{let K=(async()=>{let B=await W.initialize({protocolVersion:U0,clientCapabilities:W$,clientInfo:b1()});v1(B.protocolVersion);let U=B.authMethods?.map((k)=>k.id)??[],M;try{M=await W.newSession({cwd:$.spawn.cwd,mcpServers:[]})}catch(k){if(y1(k))throw new J0(k.message??"Authentication required",U);throw k}let N=M$(M),C=$.modelId??null,Y=C?S1(C,N.models):null;if(Y&&Y!==N.currentModelId)if(N.modelConfigId)N=await b0({conn:W,sessionId:M.sessionId,configId:N.modelConfigId,value:Y,metadata:N,label:`${N.modelConfigId}=${Y}`});else console.warn(`[acp] runtime did not advertise a model config option for ${Y}; discovering agent default models.`);for(let[k,A]of Object.entries($.configValues??{}).sort(([_],[P])=>_.localeCompare(P))){if(k===N.modelConfigId)continue;if(!N.configOptions.some((_)=>_.id===k))continue;N=await b0({conn:W,sessionId:M.sessionId,configId:k,value:A,metadata:N,label:`${k}=${String(A)}`})}let D=N.models??[],x=N.currentModelId;return W.cancel({sessionId:M.sessionId}).catch(()=>{return}),{models:D,configOptions:N.configOptions,currentModelId:x}})(),H=new Promise((B,U)=>{z=setTimeout(()=>{U(new a)},b6)});return await Promise.race([K,H])}catch(K){if(K instanceof Error&&K.message==="ACP connection closed"){if($.signal?.aborted)throw new O("ACP model discovery cancelled: abort signal received");throw new O("Runtime process exited during model discovery.")}throw K}finally{if(z)clearTimeout(z);if($.signal)$.signal.removeEventListener("abort",G);X.kill()}}var y=new Map,u=null;function v0($){$.then((X)=>X.dispose()).catch(()=>{return})}function v6(){if(u!==null)return;u=setInterval(()=>{let $=Date.now();for(let[X,Z]of y){if(Z.inUse)continue;if($-Z.lastUsed<600000)continue;y.delete(X),v0(Z.sessionPromise)}if(y.size===0&&u!==null)clearInterval(u),u=null},60000),u.unref?.()}function I6(){if(y.size<200)return;let $=null,X=1/0;for(let[J,Q]of y){if(Q.inUse)continue;if(Q.lastUsed>=X)continue;$=J,X=Q.lastUsed}if(!$)return;let Z=y.get($);if(!Z)return;y.delete($),v0(Z.sessionPromise)}function q$($,X,Z){return`${$}:${X}:${Z}`}async function B$($){let X=y.get($.key);if(X)if(X.fingerprint===$.fingerprint){X.inUse=!0,X.lastUsed=Date.now();try{let J=await X.sessionPromise;if(J.isAlive())return J}catch{}y.delete($.key)}else y.delete($.key),v0(X.sessionPromise);let Z=$.open();I6(),y.set($.key,{key:$.key,fingerprint:$.fingerprint,sessionPromise:Z,lastUsed:Date.now(),inUse:!0}),v6();try{return await Z}catch(J){throw y.delete($.key),J}}function x$($,X=!1){let Z=y.get($);if(!Z)return;if(X){y.delete($),v0(Z.sessionPromise);return}Z.inUse=!1,Z.lastUsed=Date.now()}async function h6(){let $=Array.from(y.values());if(y.clear(),u!==null)clearInterval(u),u=null;await Promise.all($.map((X)=>X.sessionPromise.then((Z)=>Z.dispose()).catch(()=>{return})))}function C$($){let X=Object.entries($.configValues??{}),Z=X.length>0?JSON.stringify(Object.fromEntries(X.sort(([J],[Q])=>J.localeCompare(Q)))):"";return[$.adapterId,$.configId??"",$.modelId??"",Z,$.mcpUrl??"",$.runFolder??"",$.toolSurface??"full"].join(" ")}var g1=!1;function S6(){if(g1)return;g1=!0;let $=()=>{h6()};process.once("beforeExit",$),process.once("SIGTERM",$),process.once("SIGINT",$)}S6();import m6 from"node:fs/promises";import I0 from"node:os";async function c1($){let X={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},Z;try{Z=await m6.readFile($,"utf-8")}catch(J){if(J.code==="ENOENT")return structuredClone(X);throw J}return C0.parse(JSON.parse(Z))}function F$($,X,Z){return{...$.defaultConfigValues??{},...X?.configValues??{},...Z?.configValues??{}}}async function i($){let X=$.configPath?await c1($.configPath):await h(),Z=$.cardId?X.cardOverrides[$.cardId]:void 0;if(Z?.runtimeConfigId){let Q=X.runtimes.find((j)=>j.id===Z.runtimeConfigId);if(Q)return{entry:Q,adapter:c(Q),runFolder:Z.runFolder??Q.runFolder??I0.homedir(),modelId:Z.modelId??Q.defaultModelId??null,configValues:F$(Q,void 0,Z)}}let J=X.boardOverrides[$.boardId];if(J?.runtimeConfigId){let Q=X.runtimes.find((j)=>j.id===J.runtimeConfigId);if(Q)return{entry:Q,adapter:c(Q),runFolder:J.runFolder??Q.runFolder??I0.homedir(),modelId:J.modelId??Q.defaultModelId??null,configValues:F$(Q,J)}}if(X.globalDefaultConfigId){let Q=X.runtimes.find((j)=>j.id===X.globalDefaultConfigId);if(Q)return{entry:Q,adapter:c(Q),runFolder:Z?.runFolder??J?.runFolder??Q.runFolder??I0.homedir(),modelId:Z?.modelId??J?.modelId??Q.defaultModelId??null,configValues:F$(Q,J,Z)}}throw new t}async function l1($,X={}){let J=(X.configPath?await c1(X.configPath):await h()).runtimes.find((Q)=>Q.id===$);if(!J)return null;return{entry:J,adapter:c(J),runFolder:J.runFolder??I0.homedir(),modelId:X.modelId??J.defaultModelId??null,configValues:{...J.defaultConfigValues??{},...X.configValues??{}}}}var u1=new Map;function P$($,X){if(!$)return;u1.set($,X)}function p1($){if(!$)return!1;return u1.get($)??!1}var $0=new Map,L$=new Set;function k$($){$0.get($)?.controller.abort()}function a1($){for(let[X,Z]of $0){if(Z.frontendSessionId!==$)continue;Z.controller.abort(),$0.delete(X)}}function d1(){for(let $ of $0.values())$.controller.abort();$0.clear()}function i1($,X){if(X?.aborted)return!0;return $ instanceof Error&&/abort signal received|session cancelled/i.test($.message)}function n1($,X,Z,J){if((!X.availableModels||X.availableModels.length===0)&&X.availableConfigOptions.length===0)return;g((Q)=>{let j=Q.runtimes.find((W)=>W.id===$);if(j){if(X.availableModels&&X.availableModels.length>0)j.discoveredModels=w0({adapterId:Z,models:X.availableModels,currentModelId:X.currentModelId??J});if(X.availableConfigOptions.length>0)j.discoveredConfigOptions=X.availableConfigOptions}}).catch(()=>{return})}function g6($,X){return`${$}
19
19
 
20
20
  Runtime run folder:
21
- - Effective run folder: ${Z}
21
+ - Effective run folder: ${X}
22
22
  - When the user says "my folder", "current folder", or "run folder", they mean this selected runtime folder.
23
23
  - Use list_run_folder and read_run_folder_file for run-folder inspection. Do not use attached context-card tools for this unless the user asks about attached board context.
24
- - Filesystem access is read-only and limited to this folder. Hidden/config folders and outside-folder paths are unavailable.`}async function S1($,Z){let X=Date.now(),J=new AbortController;$0.set($.runId,{controller:J,frontendSessionId:$.frontendSessionId}),N$.add($.cardId);let Q=V$($.userId,$.frontendSessionId,$.cardId),j=!1,W=null;try{let V=($.runtimeConfigIdHint?await y1($.runtimeConfigIdHint,{modelId:$.modelHint??null}):null)??await e({boardId:$.boardId,cardId:$.cardId}),H=await V.adapter.resolveSpawnConfig(V.entry),U=$.toolSurface??"full";W=H;let N=h0({userId:$.userId,frontendSessionId:$.frontendSessionId,boardId:$.boardId,toolSurface:U,cardId:$.cardId,runFolder:V.runFolder}),D=N?[N]:[],M=$.modelHint??V.modelId,x=z$({adapterId:V.adapter.id,configId:V.entry.id,modelId:M,configValues:V.configValues,mcpUrl:N?.url??null,runFolder:V.runFolder,toolSurface:U}),B=await Y$({key:Q,fingerprint:x,open:()=>K$({spawn:{...H,cwd:V.runFolder},mcpServers:D,modelId:M,configValues:V.configValues,signal:J.signal})});h1(V.entry.id,B,V.adapter.id,M);let Y;try{Y=await B.prompt({runId:$.runId,boardId:$.boardId,cardId:$.cardId,prompt:{systemPrompt:w6($.systemPrompt,V.runFolder),messages:$.promptMessages.map((G)=>({role:G.role,content:G.content}))},signal:J.signal,appendText:async({text:G})=>{Z({type:"partial_text",runId:$.runId,cardId:$.cardId,text:G})},appendToolActivity:async({entry:G})=>{Z({type:"tool_activity",runId:$.runId,cardId:$.cardId,activity:G})}})}catch(G){if(!B.isAlive()||G instanceof O)j=!0;throw G}Z({type:"run_settled",runId:$.runId,cardId:$.cardId,result:{assistantContent:Y.finalText,model:Y.modelReported??null,latencyMs:Date.now()-X,errorText:null,partialText:null}})}catch(z){let V=z instanceof Error?z.message:"Agent run failed";if(z instanceof O&&W&&!v1(z,J.signal))i0(W,V);console.error(`[ideawave-cli] run ${$.runId} failed:`,V),Z({type:"run_settled",runId:$.runId,cardId:$.cardId,result:{assistantContent:"",model:null,latencyMs:Date.now()-X,errorText:V,partialText:null}})}finally{G$(Q,j),$0.delete($.runId),N$.delete($.cardId)}}async function m1($){if(N$.has($.cardId))return{status:"skipped"};let Z=V$($.userId,$.frontendSessionId,$.cardId),X=null;try{let J=await e({boardId:$.boardId,cardId:$.cardId}),Q=await J.adapter.resolveSpawnConfig(J.entry);X=Q;let j=h0({userId:$.userId,frontendSessionId:$.frontendSessionId,boardId:$.boardId,cardId:$.cardId,runFolder:J.runFolder}),W=j?[j]:[],z=z$({adapterId:J.adapter.id,configId:J.entry.id,modelId:J.modelId,configValues:J.configValues,mcpUrl:j?.url??null,runFolder:J.runFolder}),V=new AbortController,H=await Y$({key:Z,fingerprint:z,open:()=>K$({spawn:{...Q,cwd:J.runFolder},mcpServers:W,modelId:J.modelId,configValues:J.configValues,signal:V.signal})});return h1(J.entry.id,H,J.adapter.id,J.modelId),G$(Z,!1),console.log(`[ideawave-cli] warmed runtime for card ${$.cardId}`),{status:"ready"}}catch(J){if(J instanceof s)return{status:"skipped"};let Q=J instanceof Error?J.message:String(J);if(J instanceof O&&X&&!v1(J))i0(X,Q);if(J instanceof O&&/(not ready|installing|warming|retry in a moment)/i.test(Q))return{status:"retryable",error:Q};return console.warn(`[ideawave-cli] warmup failed for card ${$.cardId}:`,Q),{status:"failed",error:Q}}}import{randomUUID as f6}from"node:crypto";import{createServer as E6}from"node:http";import{WebSocket as i1,WebSocketServer as y6}from"ws";var B$="/cli-bridge",g1="/ping";function C$($=43275,Z=43277){let X=[];for(let J=$;J<=Z;J+=1)X.push(J);return X}function c1($=C$(),Z="127.0.0.1",X="/cli-bridge"){return $.map((J)=>`ws://${Z}:${J}${X}`)}var T6=new Set(["hello","frontend_hello","cli_status","browser_status","bridge_probe","bridge_probe_ack","bridge_ping","bridge_pong","tool_metadata","run_turn","cancel_run","tool_result","request_tool_metadata","tool_call","partial_text","tool_activity","run_settled","runtime_rpc","runtime_rpc_result","warmup_run","warmup_result"]);function R0($){try{let Z=JSON.parse($);if(Z&&typeof Z==="object"&&typeof Z.type==="string"&&T6.has(Z.type))return Z}catch{}return null}function f0($){return JSON.stringify($)}var R6=800;function l1({candidates:$,createWebSocket:Z,timeoutMs:X=R6,maxConcurrent:J=1,staggerMs:Q=0,setTimeoutFn:j=setTimeout,clearTimeoutFn:W=clearTimeout}){return new Promise((z,V)=>{let H=0,U=!1,N=null,D=new Map,M=Math.max(1,Math.floor(J)),x=()=>{if(N===null)return;W(N),N=null},B=(F)=>{let{socket:K,listeners:L,timer:T}=F;K.removeEventListener("open",L.open),K.removeEventListener("message",L.message),K.removeEventListener("error",L.error),K.removeEventListener("close",L.close),W(T),D.delete(K)},Y=(F)=>{x();for(let K of Array.from(D.values()))if(B(K),K.socket!==F)try{K.socket.close()}catch{}},G=()=>{if(U)return;if(H<$.length)return;if(D.size>0)return;if(N!==null)return;U=!0,V(Error("No IdeaWave CLI bridge is reachable"))},P=(F)=>{if(U)return;if(H>=$.length){G();return}if(D.size>=M)return;if(F<=0){x(),_();return}if(N!==null)return;N=j(()=>{N=null,_()},F)},w=()=>{if(U)return;if(D.size>=M)return;if(D.size===0||Q<=0||M===1){P(0);return}P(Q)},k=(F)=>{if(U)return;let K=D.get(F);if(!K)return;B(K);try{F.close()}catch{}w(),G()};function _(){if(U)return;if(D.size>=M)return;let F=$[H];if(H+=1,!F){G();return}let K;try{K=Z(F)}catch{w(),G();return}let L={open:()=>{if(U||!D.has(K))return;K.send(f0({type:"bridge_probe",protocolVersion:1}))},message:(C)=>{if(U||!D.has(K))return;if(R0(String(C?.data??""))?.type!=="bridge_probe_ack")return;U=!0,Y(K),z({url:F,socket:K})},error:()=>k(K),close:()=>k(K)};K.addEventListener("open",L.open),K.addEventListener("message",L.message),K.addEventListener("error",L.error),K.addEventListener("close",L.close);let T=j(()=>k(K),X);D.set(K,{url:F,socket:K,listeners:L,timer:T}),w()}_()})}var b6=0,I6=30000,v6=15000,h6="http://127.0.0.1";async function o1($=c1(),Z=(X)=>new i1(X,{headers:{origin:h6}})){try{let{url:X,socket:J}=await l1({candidates:$,createWebSocket:Z});try{J.close()}catch{}return X}catch{return null}}var S6=new Set(["https://ideawave-app-production.up.railway.app"]);function m6($){return $==="ideawave.app"||$.endsWith(".ideawave.app")}function g6(){let $=process.env.IDEAWAVE_CLI_ALLOWED_ORIGINS;if(!$)return c6;let Z=new Set;for(let X of $.split(",")){let J=X.trim();if(!J)continue;try{Z.add(new URL(J).origin)}catch{}}return Z}var c6=new Set;function u1($){if(!$)return!1;let Z;try{Z=new URL($)}catch{return!1}if(S6.has(Z.origin))return!0;if(g6().has(Z.origin))return!0;if(Z.protocol==="https:"&&m6(Z.hostname))return!0;if(Z.protocol!=="http:"&&Z.protocol!=="https:")return!1;return Z.hostname==="localhost"||Z.hostname==="127.0.0.1"||Z.hostname==="::1"}function j0($,Z){if($.readyState!==i1.OPEN)return;try{$.send(f0(Z))}catch{}}function l6($){if(typeof $==="string")return $;if(Buffer.isBuffer($))return $.toString("utf8");if(Array.isArray($))return Buffer.concat($).toString("utf8");return Buffer.from($).toString("utf8")}function p1($){if(typeof $==="string")return $;if(Array.isArray($))return $[0]??null;return null}function d1($,Z,X){$.write(`HTTP/1.1 ${Z} ${X}\r
24
+ - Filesystem access is read-only and limited to this folder. Hidden/config folders and outside-folder paths are unavailable.`}async function o1($,X){let Z=Date.now(),J=new AbortController;$0.set($.runId,{controller:J,frontendSessionId:$.frontendSessionId}),L$.add($.cardId);let Q=q$($.userId,$.frontendSessionId,$.cardId),j=!1,W=null;try{let z=($.runtimeConfigIdHint?await l1($.runtimeConfigIdHint,{modelId:$.modelHint??null}):null)??await i({boardId:$.boardId,cardId:$.cardId}),K=await z.adapter.resolveSpawnConfig(z.entry),H=$.toolSurface??"full",B=z.adapter.supportsImages===!0;W=K;let U=u0({userId:$.userId,frontendSessionId:$.frontendSessionId,boardId:$.boardId,toolSurface:H,imagesSupported:B,cardId:$.cardId,runFolder:z.runFolder}),M=U?[U]:[];P$($.cardId,B);let N=$.modelHint??z.modelId,C=C$({adapterId:z.adapter.id,configId:z.entry.id,modelId:N,configValues:z.configValues,mcpUrl:U?.url??null,runFolder:z.runFolder,toolSurface:H}),Y=await B$({key:Q,fingerprint:C,open:()=>N$({spawn:{...K,cwd:z.runFolder},mcpServers:M,modelId:N,configValues:z.configValues,signal:J.signal})});n1(z.entry.id,Y,z.adapter.id,N);let D;try{D=await Y.prompt({runId:$.runId,boardId:$.boardId,cardId:$.cardId,prompt:{systemPrompt:g6($.systemPrompt,z.runFolder),messages:$.promptMessages.map((x)=>({role:x.role,content:x.content}))},signal:J.signal,appendText:async({text:x})=>{X({type:"partial_text",runId:$.runId,cardId:$.cardId,text:x})},appendToolActivity:async({entry:x})=>{X({type:"tool_activity",runId:$.runId,cardId:$.cardId,activity:x})}})}catch(x){if(!Y.isAlive()||x instanceof O)j=!0;throw x}X({type:"run_settled",runId:$.runId,cardId:$.cardId,result:{assistantContent:D.finalText,model:D.modelReported??null,latencyMs:Date.now()-Z,errorText:null,partialText:null}})}catch(G){let z=G instanceof Error?G.message:"Agent run failed";if(G instanceof O&&W&&!i1(G,J.signal))e0(W,z);console.error(`[ideawave-cli] run ${$.runId} failed:`,z),X({type:"run_settled",runId:$.runId,cardId:$.cardId,result:{assistantContent:"",model:null,latencyMs:Date.now()-Z,errorText:z,partialText:null}})}finally{x$(Q,j),$0.delete($.runId),L$.delete($.cardId)}}async function s1($){if(L$.has($.cardId))return{status:"skipped"};let X=q$($.userId,$.frontendSessionId,$.cardId),Z=null;try{let J=await i({boardId:$.boardId,cardId:$.cardId}),Q=await J.adapter.resolveSpawnConfig(J.entry);Z=Q;let j=u0({userId:$.userId,frontendSessionId:$.frontendSessionId,boardId:$.boardId,cardId:$.cardId,runFolder:J.runFolder}),W=j?[j]:[];P$($.cardId,J.adapter.supportsImages===!0);let G=C$({adapterId:J.adapter.id,configId:J.entry.id,modelId:J.modelId,configValues:J.configValues,mcpUrl:j?.url??null,runFolder:J.runFolder}),z=new AbortController,K=await B$({key:X,fingerprint:G,open:()=>N$({spawn:{...Q,cwd:J.runFolder},mcpServers:W,modelId:J.modelId,configValues:J.configValues,signal:z.signal})});return n1(J.entry.id,K,J.adapter.id,J.modelId),x$(X,!1),console.log(`[ideawave-cli] warmed runtime for card ${$.cardId}`),{status:"ready"}}catch(J){if(J instanceof t)return{status:"skipped"};let Q=J instanceof Error?J.message:String(J);if(J instanceof O&&Z&&!i1(J))e0(Z,Q);if(J instanceof O&&/(not ready|installing|warming|retry in a moment)/i.test(Q))return{status:"retryable",error:Q};return console.warn(`[ideawave-cli] warmup failed for card ${$.cardId}:`,Q),{status:"failed",error:Q}}}import{randomUUID as u6}from"node:crypto";import{createServer as p6}from"node:http";import{WebSocket as Q2,WebSocketServer as a6}from"ws";var O$="/cli-bridge",t1="/ping";function _$($=43275,X=43277){let Z=[];for(let J=$;J<=X;J+=1)Z.push(J);return Z}function r1($=_$(),X="127.0.0.1",Z="/cli-bridge"){return $.map((J)=>`ws://${X}:${J}${Z}`)}var c6=new Set(["hello","frontend_hello","cli_status","browser_status","bridge_probe","bridge_probe_ack","bridge_ping","bridge_pong","tool_metadata","run_turn","cancel_run","tool_result","request_tool_metadata","tool_call","partial_text","tool_activity","run_settled","runtime_rpc","runtime_rpc_result","warmup_run","warmup_result"]);function h0($){try{let X=JSON.parse($);if(X&&typeof X==="object"&&typeof X.type==="string"&&c6.has(X.type))return X}catch{}return null}function S0($){return JSON.stringify($)}var l6=800;function e1({candidates:$,createWebSocket:X,timeoutMs:Z=l6,maxConcurrent:J=1,staggerMs:Q=0,setTimeoutFn:j=setTimeout,clearTimeoutFn:W=clearTimeout}){return new Promise((G,z)=>{let K=0,H=!1,B=null,U=new Map,M=Math.max(1,Math.floor(J)),N=()=>{if(B===null)return;W(B),B=null},C=(P)=>{let{socket:V,listeners:F,timer:T}=P;V.removeEventListener("open",F.open),V.removeEventListener("message",F.message),V.removeEventListener("error",F.error),V.removeEventListener("close",F.close),W(T),U.delete(V)},Y=(P)=>{N();for(let V of Array.from(U.values()))if(C(V),V.socket!==P)try{V.socket.close()}catch{}},D=()=>{if(H)return;if(K<$.length)return;if(U.size>0)return;if(B!==null)return;H=!0,z(Error("No IdeaWave CLI bridge is reachable"))},x=(P)=>{if(H)return;if(K>=$.length){D();return}if(U.size>=M)return;if(P<=0){N(),_();return}if(B!==null)return;B=j(()=>{B=null,_()},P)},k=()=>{if(H)return;if(U.size>=M)return;if(U.size===0||Q<=0||M===1){x(0);return}x(Q)},A=(P)=>{if(H)return;let V=U.get(P);if(!V)return;C(V);try{P.close()}catch{}k(),D()};function _(){if(H)return;if(U.size>=M)return;let P=$[K];if(K+=1,!P){D();return}let V;try{V=X(P)}catch{k(),D();return}let F={open:()=>{if(H||!U.has(V))return;V.send(S0({type:"bridge_probe",protocolVersion:1}))},message:(R)=>{if(H||!U.has(V))return;if(h0(String(R?.data??""))?.type!=="bridge_probe_ack")return;H=!0,Y(V),G({url:P,socket:V})},error:()=>A(V),close:()=>A(V)};V.addEventListener("open",F.open),V.addEventListener("message",F.message),V.addEventListener("error",F.error),V.addEventListener("close",F.close);let T=j(()=>A(V),Z);U.set(V,{url:P,socket:V,listeners:F,timer:T}),k()}_()})}var d6=0,i6=30000,n6=15000,o6="http://127.0.0.1";async function j2($=r1(),X=(Z)=>new Q2(Z,{headers:{origin:o6}})){try{let{url:Z,socket:J}=await e1({candidates:$,createWebSocket:X});try{J.close()}catch{}return Z}catch{return null}}var s6=new Set(["https://ideawave-app-production.up.railway.app"]);function t6($){return $==="ideawave.app"||$.endsWith(".ideawave.app")}function r6(){let $=process.env.IDEAWAVE_CLI_ALLOWED_ORIGINS;if(!$)return e6;let X=new Set;for(let Z of $.split(",")){let J=Z.trim();if(!J)continue;try{X.add(new URL(J).origin)}catch{}}return X}var e6=new Set;function $2($){if(!$)return!1;let X;try{X=new URL($)}catch{return!1}if(s6.has(X.origin))return!0;if(r6().has(X.origin))return!0;if(X.protocol==="https:"&&t6(X.hostname))return!0;if(X.protocol!=="http:"&&X.protocol!=="https:")return!1;return X.hostname==="localhost"||X.hostname==="127.0.0.1"||X.hostname==="::1"}function W0($,X){if($.readyState!==Q2.OPEN)return;try{$.send(S0(X))}catch{}}function $X($){if(typeof $==="string")return $;if(Buffer.isBuffer($))return $.toString("utf8");if(Array.isArray($))return Buffer.concat($).toString("utf8");return Buffer.from($).toString("utf8")}function X2($){if(typeof $==="string")return $;if(Array.isArray($))return $[0]??null;return null}function Z2($,X,Z){$.write(`HTTP/1.1 ${X} ${Z}\r
25
25
  Connection: close\r
26
- Content-Length: ${Buffer.byteLength(X)}\r
26
+ Content-Length: ${Buffer.byteLength(Z)}\r
27
27
  \r
28
- ${X}`),$.destroy()}function u6($,Z){return new Promise((X,J)=>{let Q=(W)=>{$.off("listening",j),J(W)},j=()=>{$.off("error",Q);let W=$.address();if(!W||typeof W==="string"){J(Error("Failed to read CLI bridge server address"));return}X(W.port)};$.once("error",Q),$.once("listening",j),$.listen(Z,"127.0.0.1")})}function a1($){return new Promise((Z,X)=>{$.close((J)=>{if(J)X(J);else Z()})})}async function n1($,Z=C$()){let X=new Map,J=new Map,Q=$.maxMessageSize??b6,j=!1,W=(D)=>{let M=J.get(D);if(M)clearTimeout(M);J.delete(D)},z=(D)=>{J.delete(D);let{activeRunIds:M}=$.registry.disconnect(D);$.onDisconnect(D,M)},V=(D,M)=>{let x={type:"cli_status",connected:!0,runtime:$.runtime,mcpReady:$.mcpReady(),error:M};if(D){let B=X.get(D);if(B)j0(B,x);return}for(let B of X.values())j0(B,x)},H=(D,M)=>{let x=M.sessionId.trim(),B=M.userId.trim();if(!x||!B){j0(D,{type:"cli_status",connected:!1,runtime:$.runtime,mcpReady:$.mcpReady(),error:"Missing frontend session or user id"}),D.close();return}W(x);let Y=X.get(x);if(Y&&Y!==D)Y.close();D.data.frontendSessionId=x,X.set(x,D),$.registry.register({frontendSessionId:x,userId:B,tools:M.tools,send:(G)=>j0(D,G)}),V(x),$.onToolMetadata?.(x)},U=(D,M)=>{let x=$.registry.getUserId(D);if(!x)return;switch(M.type){case"bridge_ping":{let B=X.get(D);if(B)j0(B,{type:"bridge_pong"});break}case"tool_metadata":$.registry.setMetadata(D,M.tools),$.onToolMetadata?.(D);break;case"tool_result":$.registry.handleToolResult(D,M);break;case"run_turn":$.registry.markRunActive(D,M.run.runId,M.run.cardId),$.onRunTurn(D,{...M.run,frontendSessionId:D,userId:x});break;case"cancel_run":if($.registry.ownsRun(D,M.runId))$.onCancelRun(D,M.runId);break;case"runtime_rpc":$.onRuntimeRpc(D,M);break;case"warmup_run":$.onWarmupRun(D,{...M,frontendSessionId:D},x);break;default:break}},N=(D,M)=>{let x=p1(D.headers.origin),B=u1(x),Y={Vary:"Origin"};if(B&&x)Y["Access-Control-Allow-Origin"]=x,Y["Access-Control-Allow-Private-Network"]="true";if(D.method==="OPTIONS"){M.writeHead(204,{...Y,"Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*","Access-Control-Max-Age":"600"}),M.end();return}if(D.method!=="GET"){M.writeHead(405,Y),M.end();return}M.writeHead(200,{...Y,"content-type":"application/json","cache-control":"no-store"}),M.end(JSON.stringify({ideawave:!0,runtime:$.runtime,mcpReady:$.mcpReady()}))};for(let D of Z){let M=E6((Y,G)=>{if(new URL(Y.url??"/","http://127.0.0.1").pathname===g1){N(Y,G);return}G.writeHead(404,{"content-type":"text/plain"}),G.end("IdeaWave CLI bridge")}),x=new y6({noServer:!0,maxPayload:Q}),B=(Y)=>{if(Y.idleTimer)clearTimeout(Y.idleTimer);Y.idleTimer=setTimeout(()=>{Y.close()},I6),Y.idleTimer.unref?.()};x.on("connection",(Y)=>{let G=Y;G.data={id:f6(),frontendSessionId:null},G.idleTimer=null,B(G),G.on("ping",()=>B(G)),G.on("pong",()=>B(G)),G.on("error",()=>{if(G.idleTimer)clearTimeout(G.idleTimer);G.close()}),G.on("message",(P)=>{B(G);let w=l6(P);if(Q>0&&w.length>Q)return;let k=R0(w);if(!k)return;let _=G.data.frontendSessionId;if(!_){if(k.type==="bridge_probe")j0(G,{type:"bridge_probe_ack",protocolVersion:k.protocolVersion});else if(k.type==="frontend_hello")H(G,k);return}U(_,k)}),G.on("close",()=>{if(G.idleTimer)clearTimeout(G.idleTimer);let P=G.data.frontendSessionId;if(!P)return;if(X.get(P)!==G)return;if(X.delete(P),W(P),j)return;J.set(P,setTimeout(()=>z(P),v6))})}),M.on("upgrade",(Y,G,P)=>{if(new URL(Y.url??"/","http://127.0.0.1").pathname!==B$){d1(G,404,"Not Found");return}if(!u1(p1(Y.headers.origin))){d1(G,403,"Forbidden");return}x.handleUpgrade(Y,G,P,(k)=>{x.emit("connection",k,Y)})});try{let Y=await u6(M,D);return{url:`ws://127.0.0.1:${Y}${B$}`,port:Y,sendStatus:V,close:async()=>{j=!0;for(let G of J.values())clearTimeout(G);J.clear();for(let G of x.clients){let P=G;if(P.idleTimer)clearTimeout(P.idleTimer);P.close()}x.close(),await a1(M).catch(()=>{return})}}}catch(Y){if(x.close(),await a1(M).catch(()=>{return}),Y?.code==="EADDRINUSE")continue;throw Y}}throw Error(`No free IdeaWave CLI bridge port found in ${Z[0]}-${Z.at(-1)}`)}import{Server as JZ}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as QZ,ListToolsRequestSchema as jZ}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as d6}from"node:crypto";import{createServer as a6}from"node:http";import{StreamableHTTPServerTransport as i6}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as e1}from"@modelcontextprotocol/sdk/types.js";var s1=new Set(["127.0.0.1","localhost","[::1]","::1"]);function p6($){let Z=$.trim();if(Z.length===0)return null;if(Z.startsWith("[")){let j=Z.indexOf("]");if(j===-1)return null;let W=Z.slice(0,j+1),z=Z.slice(j+1);if(z.length===0)return{host:W,port:null};if(!z.startsWith(":"))return null;let V=Number(z.slice(1));if(!Number.isInteger(V)||V<=0||V>65535)return null;return{host:W,port:V}}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 t1($){return s1.has($)||s1.has($.toLowerCase())}function r1($,Z){let X=$.headers.host;if(typeof X!=="string")return{ok:!1,status:403,reason:"missing-host"};let J=p6(X);if(!J)return{ok:!1,status:403,reason:"bad-host"};if(!t1(J.host))return{ok:!1,status:403,reason:"non-loopback-host"};if(J.port!==null&&J.port!==Z)return{ok:!1,status:403,reason:"host-port-mismatch"};let Q=$.headers.origin;if(typeof Q==="string"&&Q.length>0){if(Q!=="null"){let j;try{j=new URL(Q)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!t1(j.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var $2="/mcp",o6=43274,X2=16777216,n6=1800000,s6=300000,Z2=200,t6=-32700,i=-32600,F$=-32603;function h($,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 x$ extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class L$ extends Error{constructor(){super(`body exceeds ${X2} bytes`);this.name="BodyTooLargeError"}}async function r6($){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 x$}let X=0,J=[];for await(let j of $){let W=typeof j==="string"?Buffer.from(j):j;if(X+=W.byteLength,X>X2)throw new L$;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 e6($){if(Array.isArray($))return $.some(e1);return e1($)}function $Z($){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 o6}async function ZZ($,Z){let X=(Q)=>new Promise((j,W)=>{let z=(H)=>{$.off("listening",V),W(H)},V=()=>{$.off("error",z),j()};$.once("error",z),$.once("listening",V),$.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 XZ($,Z){if(Z&&typeof Z==="object"&&!Array.isArray(Z)){let J=Z.params;if(J&&typeof J==="object"&&!Array.isArray(J)){let Q=J.clientInfo;if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let j=Q.name;if(typeof j==="string"&&j.trim().length>0)return j.trim()}}}let X=$.headers["user-agent"];if(typeof X==="string"&&X.trim().length>0)return X.trim();return null}async function J2($){let Z=new Map,X=0;function J(H){let U=Z.get(H);if(U)U.lastActivity=Date.now()}async function Q(H,U){Z.delete(H),await U.transport.close().catch(()=>{return})}async function j(){let H=null,U=1/0;for(let[N,D]of Z)if(D.lastActivity<U)U=D.lastActivity,H=N;if(H!==null){let N=Z.get(H);if(N)console.warn(`[mcp] session cap of ${Z2} reached; evicting ${H}`),await Q(H,N)}}let W=setInterval(()=>{let H=Date.now()-n6;for(let[U,N]of Z)if(N.lastActivity<H)console.log(`[mcp] sweeping idle session ${U}`),Q(U,N)},s6);W.unref?.();let z=a6((H,U)=>{(async()=>{let N;try{N=new URL(H.url??"/","http://127.0.0.1").pathname}catch{h(U,400,i,"bad-url");return}if(N!==$2){h(U,404,i,"not-found");return}let D=H.method??"POST";if(D!=="POST"&&D!=="GET"&&D!=="DELETE"){U.setHeader("Allow","GET, POST, DELETE"),h(U,405,i,"method-not-allowed");return}let M=r1(H,X);if(!M.ok){h(U,M.status,i,"forbidden",{reason:M.reason});return}let x=H.headers["mcp-session-id"],B=typeof x==="string"?x:void 0;if(D==="GET"||D==="DELETE"){if(!B||!Z.has(B)){h(U,400,i,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let P=Z.get(B).transport;J(B);try{await P.handleRequest(H,U)}catch(w){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",w),!U.headersSent)h(U,500,F$,"internal")}return}let Y;try{Y=await r6(H)}catch(P){if(P instanceof x$){h(U,415,i,"expected-application-json");return}if(P instanceof L$){h(U,413,i,"body-too-large");return}h(U,400,t6,"invalid-json");return}let G;if(B&&Z.has(B))G=Z.get(B).transport,J(B);else if(!B&&Y!==void 0&&e6(Y)){let P=H.headers["x-ideawave-user-id"],w=typeof P==="string"&&P.trim().length>0?P.trim():null,k=H.headers["x-ideawave-frontend-session-id"],_=typeof k==="string"&&k.trim().length>0?k.trim():null,F=H.headers["x-ideawave-tool-surface"],K=typeof F==="string"&&F.trim()==="read"?"read":"full",L=H.headers["x-ideawave-card-id"],T=typeof L==="string"&&L.trim().length>0?L.trim():null,C=H.headers["x-ideawave-board-id"],R=typeof C==="string"&&C.trim().length>0?C.trim():null,f=H.headers["x-ideawave-run-folder"],m=typeof f==="string"&&f.trim().length>0?f.trim():null,n=XZ(H,Y);if(Z.size>=Z2)await j();let Z0=null,g=new i6({sessionIdGenerator:()=>d6(),onsessioninitialized:(l)=>{Z0=l,Z.set(l,{transport:g,lastActivity:Date.now()})},onsessionclosed:(l)=>{Z.delete(l)}});g.onclose=()=>{if(g.sessionId)Z.delete(g.sessionId)};try{await $.buildServer({userId:w,frontendSessionId:_,boardId:R,toolSurface:K,cardId:T,runFolder:m,clientHint:n}).connect(g)}catch(l){if(console.error("[mcp] buildServer/connect failed",l),Z0)Z.delete(Z0);await g.close().catch(()=>{return}),h(U,500,F$,"server-init-failed");return}G=g}else{h(U,400,i,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await G.handleRequest(H,U,Y)}catch(P){if(console.error("[mcp] transport.handleRequest threw",P),!U.headersSent)h(U,500,F$,"internal")}})().catch((N)=>{console.error("[mcp] unhandled request handler error:",N)})});return X=await ZZ(z,$Z($.port)),{url:`http://127.0.0.1:${X}${$2}`,port:X,close:async()=>{clearInterval(W);for(let H of Z.values())await H.transport.close().catch(()=>{return});Z.clear(),await new Promise((H)=>z.close(()=>H()))}}}var WZ={name:"ideawave-board",version:"1.0.0"},E0="list_run_folder",y0="read_run_folder_file",W2=new Set(["list_boards","get_board","list_nodes","list_edges","inspect_node","list_context_sources","read_context_card","read_context_file","read_context_image","list_context_folder","get_board_wiki","search_board","get_card_messages","list_agent_cards","inspect_neighbors",E0,y0]),KZ=[{name:E0,description:"List visible files and folders under the selected runtime run folder. Hidden/config folders are omitted.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Optional relative path inside the selected run folder. Defaults to the run-folder root."}},additionalProperties:!1}},{name:y0,description:"Read a text file inside the selected runtime run folder. Hidden/config paths and outside-folder paths are denied.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Relative path to a text file inside the selected run folder."}},required:["path"],additionalProperties:!1}}];function P$($){return{content:[{type:"text",text:$}]}}function VZ($){return P$(JSON.stringify($,null,2))}function Q2($){return{...P$($),isError:!0}}function YZ($,Z,X="full"){return $.getMetadata(Z).filter((J)=>X!=="read"||W2.has(L0(J.name))).map((J)=>({name:J.name,description:J.description,inputSchema:J.inputSchema}))}function GZ($,Z,X={}){let J=YZ($,Z,X.toolSurface??"full");return X.includeRunFolderTools?[...J,...KZ]:J}function j2($,Z){if(!$||typeof $!=="object"||Array.isArray($))return null;let X=$[Z];return typeof X==="string"?X:null}async function zZ($,Z,X){if(X&&X.trim().length>0)return X.trim();if(!$||!Z)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await e({boardId:$,cardId:Z})).runFolder}async function HZ($){let Z=await zZ($.boardId,$.cardId,$.runFolder);if($.name===E0){let X=j2($.args,"path")??"",J=await d$(Z,X);return VZ(J)}if($.name===y0){let X=j2($.args,"path");if(!X)return Q2("read_run_folder_file requires a path.");return P$(await x0(Z,X))}return Q2(`Unknown local tool "${$.name}"`)}function UZ($,Z,X,J,Q,j="full"){let W=new JZ(WZ,{capabilities:{tools:{}}});return W.setRequestHandler(jZ,async()=>({tools:GZ($,Z,{includeRunFolderTools:Boolean(Q||X&&J),toolSurface:j})})),W.setRequestHandler(QZ,async(z)=>{let{name:V,arguments:H}=z.params,U=L0(V);try{if(U===E0||U===y0)return await HZ({name:U,args:H,boardId:X,cardId:J,runFolder:Q});if(j==="read"&&!W2.has(U))throw Error(`Tool "${V}" is not available in read-only mode`);let N=await $.callTool(Z,U,H??{},void 0,J??void 0);if(N&&typeof N==="object"&&Array.isArray(N.content))return N;return{content:[{type:"text",text:typeof N==="string"?N:JSON.stringify(N)}]}}catch(N){return{content:[{type:"text",text:N instanceof Error?N.message:"Tool call failed"}],isError:!0}}}),W}function K2($,Z){return J2({buildServer:(X)=>UZ($,X.frontendSessionId,X.boardId,X.cardId,X.runFolder,X.toolSurface),port:Z})}import I0 from"node:fs/promises";import k$ from"node:os";import v0 from"node:path";var V2=new Map,O$=new Map,DZ=30000;function b0($,Z){let X=V2.get($);if(X&&X.expiresAt>Date.now())return Promise.resolve(X.value);let J=O$.get($);if(J)return J;let Q=Z().then((j)=>{return V2.set($,{value:j,expiresAt:Date.now()+DZ}),j}).finally(()=>{O$.delete($)});return O$.set($,Q),Q}async function Y2($){let Z=await Promise.all(Q0().map((j)=>b0(j.id,async()=>({adapterId:j.id,...await j.checkReadiness({id:"__probe__",kind:"registered",adapterId:j.id,displayName:j.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null})})))),J=(await v($)).runtimes.filter((j)=>j.kind==="custom"),Q=await Promise.all(J.map((j)=>b0(`custom:${j.id}`,async()=>({adapterId:j.id,...await c(j).checkReadiness(j)}))));return[...Z,...Q]}async function G2($,Z){let X=Q0().find((j)=>j.id===$);if(X)return b0(X.id,async()=>({adapterId:X.id,...await X.checkReadiness({id:"__probe__",kind:"registered",adapterId:X.id,displayName:X.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null})}));let Q=(await v(Z)).runtimes.find((j)=>j.id===$);if(!Q||Q.kind!=="custom")return null;return b0(`custom:${Q.id}`,async()=>({adapterId:Q.id,...await c(Q).checkReadiness(Q)}))}function z2(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function MZ(){let[$,Z]=await Promise.all([v(),Y2()]),X=$.globalDefaultConfigId?$.runtimes.find((J)=>J.id===$.globalDefaultConfigId)??null:null;return{runtimes:$.runtimes,globalDefaultConfigId:$.globalDefaultConfigId,globalDefaultEffective:X?{runFolder:X.runFolder??k$.homedir(),modelId:X.defaultModelId??null,configValues:X.defaultConfigValues??{}}:null,knownAdapters:Q0().map((J)=>({id:J.id,displayName:J.displayName})),readiness:Z}}async function NZ($){try{let Z=await e({boardId:$.boardId,cardId:$.cardId});return{resolved:{configId:Z.entry.id,adapterId:Z.entry.kind==="registered"?Z.entry.adapterId:null,displayName:Z.entry.displayName,runFolder:Z.runFolder,modelId:Z.modelId,configValues:Z.configValues}}}catch(Z){if(Z instanceof s)return{resolved:null};throw Z}}async function qZ($){return S((Z)=>{let X=Z.runtimes.find((j)=>j.kind==="registered"&&j.adapterId===$.adapterId);if(X)return X;let J=Q0().find((j)=>j.id===$.adapterId);if(!J)throw Error(`Unknown adapterId: ${$.adapterId}`);let Q={id:z2(),kind:"registered",adapterId:$.adapterId,displayName:J.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(Q),Q})}async function BZ($){return S((Z)=>{let X={id:z2(),kind:"custom",displayName:$.displayName,command:$.command,args:$.args,env:$.env,runFolder:$.runFolder,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(X),X})}async function CZ($){await S((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 FZ($){await S((Z)=>{let X=Z.runtimes.find((J)=>J.id===$.runtimeConfigId);if(!X)throw Error(`Runtime config not found: ${$.runtimeConfigId}`);if(Z.globalDefaultConfigId=$.runtimeConfigId,$.runFolder!==void 0)X.runFolder=$.runFolder;if($.modelId!==void 0)X.defaultModelId=$.modelId;if($.configValues!==void 0)X.defaultConfigValues=$.configValues})}async function xZ($){$.boardId,await S((Z)=>{if($.runtimeConfigId===null){delete Z.cardOverrides[$.cardId];return}if(!Z.runtimes.some((Q)=>Q.id===$.runtimeConfigId))throw Error(`Runtime config not found: ${$.runtimeConfigId}`);let J=Z.cardOverrides[$.cardId];Z.cardOverrides[$.cardId]={runtimeConfigId:$.runtimeConfigId,runFolder:$.runFolder!==void 0?$.runFolder:J?.runFolder??null,modelId:$.modelId!==void 0?$.modelId:J?.modelId??null,configValues:$.configValues!==void 0?$.configValues:J?.configValues??{}}})}async function LZ($){let X=(await v()).runtimes.find((W)=>W.id===$.runtimeConfigId);if(!X)throw Error(`Runtime config not found: ${$.runtimeConfigId}`);let J=c(X),Q=await J.resolveSpawnConfig(X),j=X.runFolder??k$.homedir();try{let W=await K1({spawn:{...Q,cwd:j}}),z=C0({adapterId:J.id,models:W.models,currentModelId:W.currentModelId}),V=new Date().toISOString();return await S((H)=>{let U=H.runtimes.find((N)=>N.id===$.runtimeConfigId);if(U)U.discoveredModels=z,U.discoveredConfigOptions=W.configOptions,U.discoveredAt=V}),{ok:!0,models:z,configOptions:W.configOptions,currentModelId:W.currentModelId}}catch(W){if(W instanceof X0)throw Error(`${W.message}${J.authHint?` ${J.authHint}`:""}`);if(W instanceof O||W instanceof d)throw Error(W.message);throw W}}async function PZ($){let Z=k$.homedir(),X=$.path?.trim()?$.path.trim():Z,J=v0.resolve(X),Q=!0;try{if(!(await I0.stat(J)).isDirectory())J=v0.dirname(J)}catch{Q=!1,J=Z}let j=[];try{j=(await I0.readdir(J,{withFileTypes:!0})).filter((V)=>V.isDirectory()&&!V.name.startsWith(".")).map((V)=>({name:V.name,path:v0.join(J,V.name)})).sort((V,H)=>V.name.localeCompare(H.name))}catch{j=[]}let W=v0.dirname(J);return{path:J,parent:W===J?null:W,home:Z,exists:Q,entries:j}}var H2={list:MZ,getEffectiveForCard:NZ,registerRegistered:qZ,registerCustom:BZ,unregister:CZ,setUserDefault:FZ,setCardOverride:xZ,refreshModels:LZ,browseFolder:PZ};var OZ=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function kZ(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function U2(){try{let $=await v();if($.globalDefaultConfigId){if($.runtimes.some((X)=>X.id===$.globalDefaultConfigId))return $.globalDefaultConfigId}for(let Z of OZ){if((await G2(Z.id))?.status!=="ready")continue;let J=null;if(await S((Q)=>{if(Q.globalDefaultConfigId){if(Q.runtimes.some((z)=>z.id===Q.globalDefaultConfigId)){J=Q.globalDefaultConfigId;return}}let j=Q.runtimes.find((W)=>W.kind==="registered"&&W.adapterId===Z.id);if(!j){let W={id:kZ(),kind:"registered",adapterId:Z.id,displayName:Z.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};Q.runtimes.push(W),j=W}Q.globalDefaultConfigId=j.id,J=j.id}),J)return console.log(`[ideawave-cli] using agent runtime: ${Z.displayName}`),J}return console.warn("[ideawave-cli] no agent runtime detected on PATH (tried claude, codex, gh copilot, opencode). Install one to run agents."),null}catch($){return console.warn("[ideawave-cli] runtime auto-seed failed",$),null}}function _Z(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class _${sessions=new Map;createCallId;toolCallTimeoutMs;constructor($={}){this.createCallId=$.createCallId??_Z,this.toolCallTimeoutMs=$.toolCallTimeoutMs??120000}register($){let Z=this.sessions.get($.frontendSessionId);if(Z){if(Z.userId!==$.userId)this.rejectPending(Z,"frontend session user changed"),Z.activeRunIds.clear();this.sessions.set($.frontendSessionId,{frontendSessionId:$.frontendSessionId,userId:$.userId,tools:$.tools,send:$.send,pendingToolCalls:Z.pendingToolCalls,activeRunIds:Z.activeRunIds,activeRunCardIds:Z.activeRunCardIds});return}this.sessions.set($.frontendSessionId,{frontendSessionId:$.frontendSessionId,userId:$.userId,tools:$.tools,send:$.send,pendingToolCalls:new Map,activeRunIds:new Set,activeRunCardIds:new Map})}disconnect($,Z="frontend session disconnected"){let X=this.sessions.get($);if(!X)return{activeRunIds:[]};return this.sessions.delete($),this.rejectPending(X,Z),{activeRunIds:Array.from(X.activeRunIds)}}sessionCount(){return this.sessions.size}has($){return this.sessions.has($)}getUserId($){return this.sessions.get($)?.userId??null}setMetadata($,Z){let X=this.sessions.get($);if(X)X.tools=Z}getMetadata($){if(!$)return[];return this.sessions.get($)?.tools??[]}sendToSession($,Z){let X=this.sessions.get($);if(!X)return!1;return X.send(Z),!0}callTool($,Z,X,J,Q){if(!$)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let j=this.sessions.get($);if(!j)return Promise.reject(Error(`Frontend session ${$} is not connected`));let W=this.createCallId();return new Promise((z,V)=>{let H=setTimeout(()=>{j.pendingToolCalls.delete(W),V(Error(`Tool "${Z}" timed out waiting for the frontend`))},this.toolCallTimeoutMs),U=J??(Q?this.getActiveRunIdForCard(j,Q):this.getSoleActiveRunId(j)),N=Q??(U?j.activeRunCardIds.get(U):void 0);j.pendingToolCalls.set(W,{resolve:z,reject:V,timer:H}),j.send({type:"tool_call",callId:W,name:Z,args:X,...U?{runId:U}:{},...N?{cardId:N}:{}})})}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 AZ(){return"0.0.43".trim()?"0.0.43":"dev"}var o=process.argv[2];if(o==="--help"||o==="-h"||o==="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(o==="--version"||o==="-v"||o==="version")console.log(AZ()),process.exit(0);if(o)console.error(`Unknown command: ${o}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var H0=new _$,M0=null;function U0($,Z){H0.sendToSession($,Z)}async function wZ($,Z){try{let X=H2[Z.method],J=await X(Z.params);U0($,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!0,result:J})}catch(X){U0($,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!1,error:X instanceof Error?X.message:String(X)})}}var D0=!1,z0=null;async function A$(){if(D0)return;if(z0)return z0;return z0=(async()=>{try{let $=await K2(H0);f$({...$,requestedPort:$.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${$.url}`);try{let Z=await l$();for(let X of Z)if(X.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${X.packageName}: ${X.error??"unknown error"}`)}catch(Z){console.warn("[ideawave-cli] ACP bridge setup skipped:",Z instanceof Error?Z.message:String(Z))}await U2(),D0=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),M0?.sendStatus()}catch($){console.error("[ideawave-cli] failed to start agent host:",$),M0?.sendStatus(void 0,$ instanceof Error?$.message:String($))}finally{z0=null}})(),z0}if(process.env.APP_ENV!=="development"){let $=await o1();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)}M0=await n1({registry:H0,runtime:null,mcpReady:()=>D0,onToolMetadata:($)=>{console.log(`[ideawave-cli] session ${$} advertised ${H0.getMetadata($).length} tools`),A$()},onRunTurn:($,Z)=>{console.log(`[ideawave-cli] running agent turn for card ${Z.cardId} (session ${$})`),(async()=>{if(await A$(),!D0){U0($,{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 S1(Z,(X)=>U0($,X))})().catch(()=>{return}).finally(()=>H0.markRunSettled($,Z.runId))},onCancelRun:($,Z)=>{q$(Z)},onRuntimeRpc:($,Z)=>{wZ($,Z)},onWarmupRun:($,Z,X)=>{(async()=>{if(await A$(),!D0)return{status:"retryable",error:"agent host is not ready"};return m1({cardId:Z.cardId,boardId:Z.boardId,userId:X,frontendSessionId:$})})().then((J)=>{if(!Z.warmupId)return;U0($,{type:"warmup_result",warmupId:Z.warmupId,cardId:Z.cardId,...J})})},onDisconnect:($,Z)=>{b1($);for(let X of Z)q$(X);console.log(`[ideawave-cli] browser session ${$} disconnected`)}});console.log(`[ideawave-cli] browser bridge listening on ${M0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var D2=!1;for(let $ of["SIGINT","SIGTERM"])process.once($,()=>{if(D2)return;D2=!0,I1(),(async()=>{await M0?.close().catch(()=>{return}),process.exit(0)})()});
28
+ ${Z}`),$.destroy()}function XX($,X){return new Promise((Z,J)=>{let Q=(W)=>{$.off("listening",j),J(W)},j=()=>{$.off("error",Q);let W=$.address();if(!W||typeof W==="string"){J(Error("Failed to read CLI bridge server address"));return}Z(W.port)};$.once("error",Q),$.once("listening",j),$.listen(X,"127.0.0.1")})}function J2($){return new Promise((X,Z)=>{$.close((J)=>{if(J)Z(J);else X()})})}async function W2($,X=_$()){let Z=new Map,J=new Map,Q=$.maxMessageSize??d6,j=!1,W=(U)=>{let M=J.get(U);if(M)clearTimeout(M);J.delete(U)},G=(U)=>{J.delete(U);let{activeRunIds:M}=$.registry.disconnect(U);$.onDisconnect(U,M)},z=(U,M)=>{let N={type:"cli_status",connected:!0,runtime:$.runtime,mcpReady:$.mcpReady(),error:M};if(U){let C=Z.get(U);if(C)W0(C,N);return}for(let C of Z.values())W0(C,N)},K=(U,M)=>{let N=M.sessionId.trim(),C=M.userId.trim();if(!N||!C){W0(U,{type:"cli_status",connected:!1,runtime:$.runtime,mcpReady:$.mcpReady(),error:"Missing frontend session or user id"}),U.close();return}W(N);let Y=Z.get(N);if(Y&&Y!==U)Y.close();U.data.frontendSessionId=N,Z.set(N,U),$.registry.register({frontendSessionId:N,userId:C,tools:M.tools,send:(D)=>W0(U,D)}),z(N),$.onToolMetadata?.(N)},H=(U,M)=>{let N=$.registry.getUserId(U);if(!N)return;switch(M.type){case"bridge_ping":{let C=Z.get(U);if(C)W0(C,{type:"bridge_pong"});break}case"tool_metadata":$.registry.setMetadata(U,M.tools),$.onToolMetadata?.(U);break;case"tool_result":$.registry.handleToolResult(U,M);break;case"run_turn":$.registry.markRunActive(U,M.run.runId,M.run.cardId),$.onRunTurn(U,{...M.run,frontendSessionId:U,userId:N});break;case"cancel_run":if($.registry.ownsRun(U,M.runId))$.onCancelRun(U,M.runId);break;case"runtime_rpc":$.onRuntimeRpc(U,M);break;case"warmup_run":$.onWarmupRun(U,{...M,frontendSessionId:U},N);break;default:break}},B=(U,M)=>{let N=X2(U.headers.origin),C=$2(N),Y={Vary:"Origin"};if(C&&N)Y["Access-Control-Allow-Origin"]=N,Y["Access-Control-Allow-Private-Network"]="true";if(U.method==="OPTIONS"){M.writeHead(204,{...Y,"Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*","Access-Control-Max-Age":"600"}),M.end();return}if(U.method!=="GET"){M.writeHead(405,Y),M.end();return}M.writeHead(200,{...Y,"content-type":"application/json","cache-control":"no-store"}),M.end(JSON.stringify({ideawave:!0,runtime:$.runtime,mcpReady:$.mcpReady()}))};for(let U of X){let M=p6((Y,D)=>{if(new URL(Y.url??"/","http://127.0.0.1").pathname===t1){B(Y,D);return}D.writeHead(404,{"content-type":"text/plain"}),D.end("IdeaWave CLI bridge")}),N=new a6({noServer:!0,maxPayload:Q}),C=(Y)=>{if(Y.idleTimer)clearTimeout(Y.idleTimer);Y.idleTimer=setTimeout(()=>{Y.close()},i6),Y.idleTimer.unref?.()};N.on("connection",(Y)=>{let D=Y;D.data={id:u6(),frontendSessionId:null},D.idleTimer=null,C(D),D.on("ping",()=>C(D)),D.on("pong",()=>C(D)),D.on("error",()=>{if(D.idleTimer)clearTimeout(D.idleTimer);D.close()}),D.on("message",(x)=>{C(D);let k=$X(x);if(Q>0&&k.length>Q)return;let A=h0(k);if(!A)return;let _=D.data.frontendSessionId;if(!_){if(A.type==="bridge_probe")W0(D,{type:"bridge_probe_ack",protocolVersion:A.protocolVersion});else if(A.type==="frontend_hello")K(D,A);return}H(_,A)}),D.on("close",()=>{if(D.idleTimer)clearTimeout(D.idleTimer);let x=D.data.frontendSessionId;if(!x)return;if(Z.get(x)!==D)return;if(Z.delete(x),W(x),j)return;J.set(x,setTimeout(()=>G(x),n6))})}),M.on("upgrade",(Y,D,x)=>{if(new URL(Y.url??"/","http://127.0.0.1").pathname!==O$){Z2(D,404,"Not Found");return}if(!$2(X2(Y.headers.origin))){Z2(D,403,"Forbidden");return}N.handleUpgrade(Y,D,x,(A)=>{N.emit("connection",A,Y)})});try{let Y=await XX(M,U);return{url:`ws://127.0.0.1:${Y}${O$}`,port:Y,sendStatus:z,close:async()=>{j=!0;for(let D of J.values())clearTimeout(D);J.clear();for(let D of N.clients){let x=D;if(x.idleTimer)clearTimeout(x.idleTimer);x.close()}N.close(),await J2(M).catch(()=>{return})}}}catch(Y){if(N.close(),await J2(M).catch(()=>{return}),Y?.code==="EADDRINUSE")continue;throw Y}}throw Error(`No free IdeaWave CLI bridge port found in ${X[0]}-${X.at(-1)}`)}import{Server as MX}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as NX,ListToolsRequestSchema as qX}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as JX}from"node:crypto";import{createServer as QX}from"node:http";import{StreamableHTTPServerTransport as jX}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as z2}from"@modelcontextprotocol/sdk/types.js";var K2=new Set(["127.0.0.1","localhost","[::1]","::1"]);function ZX($){let X=$.trim();if(X.length===0)return null;if(X.startsWith("[")){let j=X.indexOf("]");if(j===-1)return null;let W=X.slice(0,j+1),G=X.slice(j+1);if(G.length===0)return{host:W,port:null};if(!G.startsWith(":"))return null;let z=Number(G.slice(1));if(!Number.isInteger(z)||z<=0||z>65535)return null;return{host:W,port:z}}let Z=X.lastIndexOf(":");if(Z===-1)return{host:X,port:null};let J=X.slice(Z+1),Q=Number(J);if(!Number.isInteger(Q)||Q<=0||Q>65535)return{host:X,port:null};return{host:X.slice(0,Z),port:Q}}function V2($){return K2.has($)||K2.has($.toLowerCase())}function Y2($,X){let Z=$.headers.host;if(typeof Z!=="string")return{ok:!1,status:403,reason:"missing-host"};let J=ZX(Z);if(!J)return{ok:!1,status:403,reason:"bad-host"};if(!V2(J.host))return{ok:!1,status:403,reason:"non-loopback-host"};if(J.port!==null&&J.port!==X)return{ok:!1,status:403,reason:"host-port-mismatch"};let Q=$.headers.origin;if(typeof Q==="string"&&Q.length>0){if(Q!=="null"){let j;try{j=new URL(Q)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!V2(j.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var G2="/mcp",WX=43274,U2=16777216,KX=1800000,VX=300000,H2=200,YX=-32700,n=-32600,A$=-32603;function m($,X,Z,J,Q){$.statusCode=X,$.setHeader("content-type","application/json"),$.end(JSON.stringify({jsonrpc:"2.0",error:{code:Z,message:J,...Q?{data:Q}:{}},id:null}))}class w$ extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class T$ extends Error{constructor(){super(`body exceeds ${U2} bytes`);this.name="BodyTooLargeError"}}async function zX($){if($.method&&$.method!=="POST")return;let X=$.headers["content-type"];if(typeof X==="string"&&X.trim().length>0){if(!X.toLowerCase().includes("application/json"))throw new w$}let Z=0,J=[];for await(let j of $){let W=typeof j==="string"?Buffer.from(j):j;if(Z+=W.byteLength,Z>U2)throw new T$;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 GX($){if(Array.isArray($))return $.some(z2);return z2($)}function HX($){if(typeof $==="number")return $;let X=process.env.IDEAWAVE_MCP_PORT;if(X&&X.trim().length>0){let Z=Number(X);if(Number.isInteger(Z)&&Z>=0&&Z<65536)return Z}return WX}async function UX($,X){let Z=(Q)=>new Promise((j,W)=>{let G=(K)=>{$.off("listening",z),W(K)},z=()=>{$.off("error",G),j()};$.once("error",G),$.once("listening",z),$.listen(Q,"127.0.0.1")});try{await Z(X)}catch(Q){if(Q.code!=="EADDRINUSE"||X===0)throw Q;console.warn(`[mcp] port ${X} in use, falling back to an OS-assigned port; external CLIs will need to re-paste the install command from Settings → External agents`),await Z(0)}let J=$.address();if(J==null||typeof J==="string")throw Error("[mcp] failed to read bound address");return J.port}function DX($,X){if(X&&typeof X==="object"&&!Array.isArray(X)){let J=X.params;if(J&&typeof J==="object"&&!Array.isArray(J)){let Q=J.clientInfo;if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let j=Q.name;if(typeof j==="string"&&j.trim().length>0)return j.trim()}}}let Z=$.headers["user-agent"];if(typeof Z==="string"&&Z.trim().length>0)return Z.trim();return null}async function D2($){let X=new Map,Z=0;function J(K){let H=X.get(K);if(H)H.lastActivity=Date.now()}async function Q(K,H){X.delete(K),await H.transport.close().catch(()=>{return})}async function j(){let K=null,H=1/0;for(let[B,U]of X)if(U.lastActivity<H)H=U.lastActivity,K=B;if(K!==null){let B=X.get(K);if(B)console.warn(`[mcp] session cap of ${H2} reached; evicting ${K}`),await Q(K,B)}}let W=setInterval(()=>{let K=Date.now()-KX;for(let[H,B]of X)if(B.lastActivity<K)console.log(`[mcp] sweeping idle session ${H}`),Q(H,B)},VX);W.unref?.();let G=QX((K,H)=>{(async()=>{let B;try{B=new URL(K.url??"/","http://127.0.0.1").pathname}catch{m(H,400,n,"bad-url");return}if(B!==G2){m(H,404,n,"not-found");return}let U=K.method??"POST";if(U!=="POST"&&U!=="GET"&&U!=="DELETE"){H.setHeader("Allow","GET, POST, DELETE"),m(H,405,n,"method-not-allowed");return}let M=Y2(K,Z);if(!M.ok){m(H,M.status,n,"forbidden",{reason:M.reason});return}let N=K.headers["mcp-session-id"],C=typeof N==="string"?N:void 0;if(U==="GET"||U==="DELETE"){if(!C||!X.has(C)){m(H,400,n,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let x=X.get(C).transport;J(C);try{await x.handleRequest(K,H)}catch(k){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",k),!H.headersSent)m(H,500,A$,"internal")}return}let Y;try{Y=await zX(K)}catch(x){if(x instanceof w$){m(H,415,n,"expected-application-json");return}if(x instanceof T$){m(H,413,n,"body-too-large");return}m(H,400,YX,"invalid-json");return}let D;if(C&&X.has(C))D=X.get(C).transport,J(C);else if(!C&&Y!==void 0&&GX(Y)){let x=K.headers["x-ideawave-user-id"],k=typeof x==="string"&&x.trim().length>0?x.trim():null,A=K.headers["x-ideawave-frontend-session-id"],_=typeof A==="string"&&A.trim().length>0?A.trim():null,P=K.headers["x-ideawave-tool-surface"],V=typeof P==="string"&&P.trim()==="read"?"read":"full",F=K.headers["x-ideawave-images-supported"],T=typeof F==="string"&&F.trim()==="1",R=K.headers["x-ideawave-card-id"],L=typeof R==="string"&&R.trim().length>0?R.trim():null,f=K.headers["x-ideawave-board-id"],E=typeof f==="string"&&f.trim().length>0?f.trim():null,I=K.headers["x-ideawave-run-folder"],p=typeof I==="string"&&I.trim().length>0?I.trim():null,B0=DX(K,Y);if(X.size>=H2)await j();let X0=null,s=new jX({sessionIdGenerator:()=>JX(),onsessioninitialized:(Z0)=>{X0=Z0,X.set(Z0,{transport:s,lastActivity:Date.now()})},onsessionclosed:(Z0)=>{X.delete(Z0)}});s.onclose=()=>{if(s.sessionId)X.delete(s.sessionId)};try{await $.buildServer({userId:k,frontendSessionId:_,boardId:E,toolSurface:V,imagesSupported:T,cardId:L,runFolder:p,clientHint:B0}).connect(s)}catch(Z0){if(console.error("[mcp] buildServer/connect failed",Z0),X0)X.delete(X0);await s.close().catch(()=>{return}),m(H,500,A$,"server-init-failed");return}D=s}else{m(H,400,n,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await D.handleRequest(K,H,Y)}catch(x){if(console.error("[mcp] transport.handleRequest threw",x),!H.headersSent)m(H,500,A$,"internal")}})().catch((B)=>{console.error("[mcp] unhandled request handler error:",B)})});return Z=await UX(G,HX($.port)),{url:`http://127.0.0.1:${Z}${G2}`,port:Z,close:async()=>{clearInterval(W);for(let K of X.values())await K.transport.close().catch(()=>{return});X.clear(),await new Promise((K)=>G.close(()=>K()))}}}var BX={name:"ideawave-board",version:"1.0.0"},m0="list_run_folder",g0="read_run_folder_file",q2=new Set(["list_boards","get_board","list_nodes","list_edges","inspect_node","list_context_sources","read_context_card","read_context_file","read_context_image","list_context_folder","get_board_wiki","search_board","get_card_messages","list_agent_cards","inspect_neighbors",m0,g0]),B2=new Set(["inspect_diagram"]),xX=[{name:m0,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:g0,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 R$($){return{content:[{type:"text",text:$}]}}function CX($){return R$(JSON.stringify($,null,2))}function M2($){return{...R$($),isError:!0}}function FX($,X,Z="full",J=!1){return $.getMetadata(X).filter((Q)=>{let j=f0(Q.name);if(Z==="read"&&!q2.has(j))return!1;if(!J&&B2.has(j))return!1;return!0}).map((Q)=>({name:Q.name,description:Q.description,inputSchema:Q.inputSchema}))}function PX($,X,Z={}){let J=FX($,X,Z.toolSurface??"full",Z.imagesSupported??!1);return Z.includeRunFolderTools?[...J,...xX]:J}function N2($,X){if(!$||typeof $!=="object"||Array.isArray($))return null;let Z=$[X];return typeof Z==="string"?Z:null}async function LX($,X,Z){if(Z&&Z.trim().length>0)return Z.trim();if(!$||!X)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await i({boardId:$,cardId:X})).runFolder}async function kX($){let X=await LX($.boardId,$.cardId,$.runFolder);if($.name===m0){let Z=N2($.args,"path")??"",J=await L1(X,Z);return CX(J)}if($.name===g0){let Z=N2($.args,"path");if(!Z)return M2("read_run_folder_file requires a path.");return R$(await R0(X,Z))}return M2(`Unknown local tool "${$.name}"`)}function OX($,X,Z,J,Q,j="full",W=!1){let G=new MX(BX,{capabilities:{tools:{}}}),z=async()=>{if(W)return!0;if(p1(J))return!0;if(Z&&J)try{return(await i({boardId:Z,cardId:J})).adapter.supportsImages===!0}catch{return!1}return!1};return G.setRequestHandler(qX,async()=>({tools:PX($,X,{includeRunFolderTools:Boolean(Q||Z&&J),toolSurface:j,imagesSupported:await z()})})),G.setRequestHandler(NX,async(K)=>{let{name:H,arguments:B}=K.params,U=f0(H);try{if(U===m0||U===g0)return await kX({name:U,args:B,boardId:Z,cardId:J,runFolder:Q});if(j==="read"&&!q2.has(U))throw Error(`Tool "${H}" is not available in read-only mode`);if(B2.has(U)&&!await z())throw Error(`Tool "${H}" requires a runtime that supports image input`);let M=await $.callTool(X,U,B??{},void 0,J??void 0);if(M&&typeof M==="object"&&Array.isArray(M.content))return M;return{content:[{type:"text",text:typeof M==="string"?M:JSON.stringify(M)}]}}catch(M){return{content:[{type:"text",text:M instanceof Error?M.message:"Tool call failed"}],isError:!0}}}),G}function x2($,X){return D2({buildServer:(Z)=>OX($,Z.frontendSessionId,Z.boardId,Z.cardId,Z.runFolder,Z.toolSurface,Z.imagesSupported),port:X})}import c0 from"node:fs/promises";import f$ from"node:os";import l0 from"node:path";function C2(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function _X(){let[$,X]=await Promise.all([h(),B1()]),Z=$.globalDefaultConfigId?$.runtimes.find((J)=>J.id===$.globalDefaultConfigId)??null:null;return{runtimes:$.runtimes,globalDefaultConfigId:$.globalDefaultConfigId,globalDefaultEffective:Z?{runFolder:Z.runFolder??f$.homedir(),modelId:Z.defaultModelId??null,configValues:Z.defaultConfigValues??{}}:null,knownAdapters:j0().map((J)=>({id:J.id,displayName:J.displayName})),readiness:X}}async function AX($){try{let X=await i({boardId:$.boardId,cardId:$.cardId});return{resolved:{configId:X.entry.id,adapterId:X.entry.kind==="registered"?X.entry.adapterId:null,displayName:X.entry.displayName,runFolder:X.runFolder,modelId:X.modelId,configValues:X.configValues}}}catch(X){if(X instanceof t)return{resolved:null};throw X}}async function wX($){return g((X)=>{let Z=X.runtimes.find((j)=>j.kind==="registered"&&j.adapterId===$.adapterId);if(Z)return Z;let J=j0().find((j)=>j.id===$.adapterId);if(!J)throw Error(`Unknown adapterId: ${$.adapterId}`);let Q={id:C2(),kind:"registered",adapterId:$.adapterId,displayName:J.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return X.runtimes.push(Q),Q})}async function TX($){return g((X)=>{let Z={id:C2(),kind:"custom",displayName:$.displayName,command:$.command,args:$.args,env:$.env,runFolder:$.runFolder,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return X.runtimes.push(Z),Z})}async function RX($){await g((X)=>{if(X.runtimes=X.runtimes.filter((Z)=>Z.id!==$.runtimeConfigId),X.globalDefaultConfigId===$.runtimeConfigId)X.globalDefaultConfigId=null;for(let Z of Object.keys(X.boardOverrides))if(X.boardOverrides[Z].runtimeConfigId===$.runtimeConfigId)delete X.boardOverrides[Z];for(let Z of Object.keys(X.cardOverrides))if(X.cardOverrides[Z].runtimeConfigId===$.runtimeConfigId)delete X.cardOverrides[Z]})}async function fX($){await g((X)=>{let Z=X.runtimes.find((J)=>J.id===$.runtimeConfigId);if(!Z)throw Error(`Runtime config not found: ${$.runtimeConfigId}`);if(X.globalDefaultConfigId=$.runtimeConfigId,$.runFolder!==void 0)Z.runFolder=$.runFolder;if($.modelId!==void 0)Z.defaultModelId=$.modelId;if($.configValues!==void 0)Z.defaultConfigValues=$.configValues})}async function EX($){$.boardId,await g((X)=>{if($.runtimeConfigId===null){delete X.cardOverrides[$.cardId];return}if(!X.runtimes.some((Q)=>Q.id===$.runtimeConfigId))throw Error(`Runtime config not found: ${$.runtimeConfigId}`);let J=X.cardOverrides[$.cardId];X.cardOverrides[$.cardId]={runtimeConfigId:$.runtimeConfigId,runFolder:$.runFolder!==void 0?$.runFolder:J?.runFolder??null,modelId:$.modelId!==void 0?$.modelId:J?.modelId??null,configValues:$.configValues!==void 0?$.configValues:J?.configValues??{}}})}async function yX($){let Z=(await h()).runtimes.find((W)=>W.id===$.runtimeConfigId);if(!Z)throw Error(`Runtime config not found: ${$.runtimeConfigId}`);let J=c(Z),Q=await J.resolveSpawnConfig(Z),j=Z.runFolder??f$.homedir();try{let W=await m1({spawn:{...Q,cwd:j},modelId:$.modelId??Z.defaultModelId??null,configValues:$.configValues??Z.defaultConfigValues??{}}),G=w0({adapterId:J.id,models:W.models,currentModelId:W.currentModelId}),z=new Date().toISOString();return await g((K)=>{let H=K.runtimes.find((B)=>B.id===$.runtimeConfigId);if(H)H.discoveredModels=G,H.discoveredConfigOptions=W.configOptions,H.discoveredAt=z}),{ok:!0,models:G,configOptions:W.configOptions,currentModelId:W.currentModelId}}catch(W){if(W instanceof J0)throw Error(`${W.message}${J.authHint?` ${J.authHint}`:""}`);if(W instanceof O||W instanceof a)throw Error(W.message);throw W}}async function bX($){let X=f$.homedir(),Z=$.path?.trim()?$.path.trim():X,J=l0.resolve(Z),Q=!0;try{if(!(await c0.stat(J)).isDirectory())J=l0.dirname(J)}catch{Q=!1,J=X}let j=[];try{j=(await c0.readdir(J,{withFileTypes:!0})).filter((z)=>z.isDirectory()&&!z.name.startsWith(".")).map((z)=>({name:z.name,path:l0.join(J,z.name)})).sort((z,K)=>z.name.localeCompare(K.name))}catch{j=[]}let W=l0.dirname(J);return{path:J,parent:W===J?null:W,home:X,exists:Q,entries:j}}var F2={list:_X,getEffectiveForCard:AX,registerRegistered:wX,registerCustom:TX,unregister:RX,setUserDefault:fX,setCardOverride:EX,refreshModels:yX,browseFolder:bX};var vX=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function IX(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function P2(){try{let $=await h();if($.globalDefaultConfigId){if($.runtimes.some((Z)=>Z.id===$.globalDefaultConfigId))return $.globalDefaultConfigId}for(let X of vX){if((await x1(X.id))?.status!=="ready")continue;let J=null;if(await g((Q)=>{if(Q.globalDefaultConfigId){if(Q.runtimes.some((G)=>G.id===Q.globalDefaultConfigId)){J=Q.globalDefaultConfigId;return}}let j=Q.runtimes.find((W)=>W.kind==="registered"&&W.adapterId===X.id);if(!j){let W={id:IX(),kind:"registered",adapterId:X.id,displayName:X.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};Q.runtimes.push(W),j=W}Q.globalDefaultConfigId=j.id,J=j.id}),J)return console.log(`[ideawave-cli] using agent runtime: ${X.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 hX(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class E${sessions=new Map;createCallId;toolCallTimeoutMs;constructor($={}){this.createCallId=$.createCallId??hX,this.toolCallTimeoutMs=$.toolCallTimeoutMs??120000}register($){let X=this.sessions.get($.frontendSessionId);if(X){if(X.userId!==$.userId)this.rejectPending(X,"frontend session user changed"),X.activeRunIds.clear();this.sessions.set($.frontendSessionId,{frontendSessionId:$.frontendSessionId,userId:$.userId,tools:$.tools,send:$.send,pendingToolCalls:X.pendingToolCalls,activeRunIds:X.activeRunIds,activeRunCardIds:X.activeRunCardIds});return}this.sessions.set($.frontendSessionId,{frontendSessionId:$.frontendSessionId,userId:$.userId,tools:$.tools,send:$.send,pendingToolCalls:new Map,activeRunIds:new Set,activeRunCardIds:new Map})}disconnect($,X="frontend session disconnected"){let Z=this.sessions.get($);if(!Z)return{activeRunIds:[]};return this.sessions.delete($),this.rejectPending(Z,X),{activeRunIds:Array.from(Z.activeRunIds)}}sessionCount(){return this.sessions.size}has($){return this.sessions.has($)}getUserId($){return this.sessions.get($)?.userId??null}setMetadata($,X){let Z=this.sessions.get($);if(Z)Z.tools=X}getMetadata($){if(!$)return[];return this.sessions.get($)?.tools??[]}sendToSession($,X){let Z=this.sessions.get($);if(!Z)return!1;return Z.send(X),!0}callTool($,X,Z,J,Q){if(!$)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let j=this.sessions.get($);if(!j)return Promise.reject(Error(`Frontend session ${$} is not connected`));let W=this.createCallId();return new Promise((G,z)=>{let K=setTimeout(()=>{j.pendingToolCalls.delete(W),z(Error(`Tool "${X}" timed out waiting for the frontend`))},this.toolCallTimeoutMs),H=J??(Q?this.getActiveRunIdForCard(j,Q):this.getSoleActiveRunId(j)),B=Q??(H?j.activeRunCardIds.get(H):void 0);j.pendingToolCalls.set(W,{resolve:G,reject:z,timer:K}),j.send({type:"tool_call",callId:W,name:X,args:Z,...H?{runId:H}:{},...B?{cardId:B}:{}})})}handleToolResult($,X){let Z=this.sessions.get($);if(!Z)return;let J=Z.pendingToolCalls.get(X.callId);if(!J)return;if(Z.pendingToolCalls.delete(X.callId),clearTimeout(J.timer),X.ok)J.resolve(X.result);else J.reject(Error(X.error??"Tool execution failed"))}markRunActive($,X,Z){let J=this.sessions.get($);if(!J)return;if(J.activeRunIds.add(X),Z)J.activeRunCardIds.set(X,Z)}markRunSettled($,X){let Z=this.sessions.get($);if(!Z)return;Z.activeRunIds.delete(X),Z.activeRunCardIds.delete(X)}ownsRun($,X){return this.sessions.get($)?.activeRunIds.has(X)??!1}rejectPending($,X){for(let Z of $.pendingToolCalls.values())clearTimeout(Z.timer),Z.reject(Error(X));$.pendingToolCalls.clear()}getSoleActiveRunId($){return $.activeRunIds.size===1?$.activeRunIds.values().next().value:void 0}getActiveRunIdForCard($,X){let Z=[...$.activeRunCardIds.entries()].filter(([J,Q])=>$.activeRunIds.has(J)&&Q===X).map(([J])=>J);return Z.length===1?Z[0]:void 0}}function SX(){return"0.0.44".trim()?"0.0.44":"dev"}var o=process.argv[2];if(o==="--help"||o==="-h"||o==="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(o==="--version"||o==="-v"||o==="version")console.log(SX()),process.exit(0);if(o)console.error(`Unknown command: ${o}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var M0=new E$,K0=null;function N0($,X){M0.sendToSession($,X)}async function mX($,X){try{let Z=F2[X.method],J=await Z(X.params);N0($,{type:"runtime_rpc_result",requestId:X.requestId,ok:!0,result:J})}catch(Z){N0($,{type:"runtime_rpc_result",requestId:X.requestId,ok:!1,error:Z instanceof Error?Z.message:String(Z)})}}var q0=!1,D0=null;async function y$(){if(q0)return;if(D0)return D0;return D0=(async()=>{try{let $=await x2(M0);h$({...$,requestedPort:$.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${$.url}`);try{await e$({onStatusChange:(X)=>{if(C1(),K0?.sendStatus(),X.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${X.packageName}: ${X.error??"unknown error"}`)}})}catch(X){console.warn("[ideawave-cli] ACP bridge setup skipped:",X instanceof Error?X.message:String(X))}await P2(),q0=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),K0?.sendStatus()}catch($){console.error("[ideawave-cli] failed to start agent host:",$),K0?.sendStatus(void 0,$ instanceof Error?$.message:String($))}finally{D0=null}})(),D0}if(process.env.APP_ENV!=="development"){let $=await j2();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)}K0=await W2({registry:M0,runtime:null,mcpReady:()=>q0,onToolMetadata:($)=>{console.log(`[ideawave-cli] session ${$} advertised ${M0.getMetadata($).length} tools`),y$()},onRunTurn:($,X)=>{console.log(`[ideawave-cli] running agent turn for card ${X.cardId} (session ${$})`),(async()=>{if(await y$(),!q0){N0($,{type:"run_settled",runId:X.runId,cardId:X.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"IdeaWave CLI agent host is not ready",partialText:null}});return}await o1(X,(Z)=>N0($,Z))})().catch(()=>{return}).finally(()=>M0.markRunSettled($,X.runId))},onCancelRun:($,X)=>{k$(X)},onRuntimeRpc:($,X)=>{mX($,X)},onWarmupRun:($,X,Z)=>{(async()=>{if(await y$(),!q0)return{status:"retryable",error:"agent host is not ready"};return s1({cardId:X.cardId,boardId:X.boardId,userId:Z,frontendSessionId:$})})().then((J)=>{if(!X.warmupId)return;N0($,{type:"warmup_result",warmupId:X.warmupId,cardId:X.cardId,...J})})},onDisconnect:($,X)=>{a1($);for(let Z of X)k$(Z);console.log(`[ideawave-cli] browser session ${$} disconnected`)}});console.log(`[ideawave-cli] browser bridge listening on ${K0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var L2=!1;for(let $ of["SIGINT","SIGTERM"])process.once($,()=>{if(L2)return;L2=!0,d1(),(async()=>{await K0?.close().catch(()=>{return}),process.exit(0)})()});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ideawave",
3
- "version": "0.0.43",
3
+ "version": "0.0.44",
4
4
  "description": "IdeaWave CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -31,7 +31,7 @@
31
31
  ],
32
32
  "license": "UNLICENSED",
33
33
  "dependencies": {
34
- "@agentclientprotocol/sdk": "^0.22.1",
34
+ "@agentclientprotocol/sdk": "^0.25.1",
35
35
  "@modelcontextprotocol/sdk": "^1.29.0",
36
36
  "ws": "^8.21.0",
37
37
  "zod": "^4.3.6"