ideawave 0.0.67 → 0.0.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -8
- package/dist/index.mjs +19 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,8 +11,8 @@ Then open [ideawave.app](https://ideawave.app), choose a board, and start an age
|
|
|
11
11
|
## Requirements
|
|
12
12
|
|
|
13
13
|
- Node.js 18 or newer
|
|
14
|
-
- Google Chrome for screenshot capture.
|
|
15
|
-
|
|
14
|
+
- Google Chrome for screenshot capture. Browser cards stay inside the app
|
|
15
|
+
iframe and use the CLI's local browser-kit proxy.
|
|
16
16
|
- At least one supported agent runtime installed and signed in:
|
|
17
17
|
- Claude Code
|
|
18
18
|
- Codex CLI
|
|
@@ -33,9 +33,8 @@ If a runtime appears unavailable, confirm its command is on your `PATH` and that
|
|
|
33
33
|
|
|
34
34
|
For supported runtimes, the CLI fetches small ACP bridge packages on first use. npm caches them, so later runs are fast. If npm's cache was cleared, keep the CLI running and retry after the bridge downloads again.
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
snapshots yet.
|
|
36
|
+
The CLI advertises the `browser-proxy-v5` capability so browser cards can route
|
|
37
|
+
pages and subresources through the local browser-kit proxy. The normal command
|
|
38
|
+
keeps screenshot capture available. `--dev` skips screenshot-engine setup and
|
|
39
|
+
allows Railway PR previews for browser-card development. Existing saved browser
|
|
40
|
+
snapshots remain readable, but browser-kit does not create new snapshots yet.
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
function y2(){let X=globalThis.performance?.now?.()??Date.now();return Math.round(X*10)/10}function q(X,$={}){if(typeof process<"u"&&process.env.IDEAWAVE_AGENT_RUNTIME_TRACE==="0")return;let Z=Object.fromEntries(Object.entries($).filter(([,Q])=>Q!==void 0));console.info("[agent-runtime-trace]",JSON.stringify({event:X,epochMs:Date.now(),monotonicMs:y2(),...typeof document>"u"?{}:{visibility:document.visibilityState},...Z}))}var R2=600000,b2=60000,L1=200,T2=2,y=new Map,i=null;function E2(X){X.then(($)=>$.dispose()).catch(()=>{return})}function v0(X){for(let $ of X.idleWaiters)$();X.idleWaiters.clear()}function t(X,$){if(y.get(X)!==$)return;y.delete(X),v0($),E2($.sessionPromise)}function v2(){if(i!==null)return;i=setInterval(()=>{let X=Date.now();for(let[$,Z]of y){if(Z.inUse)continue;if(X-Z.lastUsed<R2)continue;t($,Z)}if(y.size===0&&i!==null)clearInterval(i),i=null},b2),i.unref?.()}function h2(){if(y.size<L1)return;let X=null,$=1/0;for(let[Q,K]of y){if(K.inUse)continue;if(K.lastUsed>=$)continue;X=Q,$=K.lastUsed}if(!X)return;let Z=y.get(X);if(!Z)return;t(X,Z)}function I2(){let X=0;while(y.size>L1){let $=null,Z=null;for(let[Q,K]of y){if(K.inUse)continue;if(Z&&K.lastUsed>=Z.lastUsed)continue;$=Q,Z=K}if(!$||!Z)break;t($,Z),X+=1}if(X>0)q("session_pool.global_idle_trimmed",{evictedSessions:X,poolEntries:y.size})}function S2(X){let $=Array.from(y.entries()).filter(([,Q])=>Q.frontendSessionId===X&&!Q.inUse).sort(([,Q],[,K])=>Q.lastUsed-K.lastUsed),Z=$.length-T2;if(Z<=0)return;for(let[Q,K]of $.slice(0,Z))t(Q,K);q("session_pool.frontend_idle_trimmed",{frontendSessionId:X,evictedSessions:Z,poolEntries:y.size})}function DX(X,$,Z){return`${X}:${$}:${Z}`}async function h0(X){let $=y.get(X.key);if($){if($.inUse)return q("session_pool.wait_for_idle",{frontendSessionId:$.frontendSessionId,poolEntries:y.size}),await new Promise((Q)=>$.idleWaiters.add(Q)),h0(X);if($.fingerprint===X.fingerprint){$.inUse=!0,$.lastUsed=Date.now();try{let Q=await $.sessionPromise;if(Q.isAlive()){if($.frontendSessionId)q("session_pool.reuse",{frontendSessionId:$.frontendSessionId,poolEntries:y.size});return Q}}catch{}t(X.key,$)}else t(X.key,$)}let Z=X.open();if(h2(),y.set(X.key,{key:X.key,frontendSessionId:X.frontendSessionId??null,fingerprint:X.fingerprint,sessionPromise:Z,lastUsed:Date.now(),inUse:!0,idleWaiters:new Set}),v2(),X.frontendSessionId)q("session_pool.open",{frontendSessionId:X.frontendSessionId,poolEntries:y.size});try{return await Z}catch(Q){let K=y.get(X.key);if(K?.sessionPromise===Z)t(X.key,K);throw Q}}function NX(X,$=!1){let Z=y.get(X);if(!Z)return;if($){t(X,Z);return}if(Z.inUse=!1,Z.lastUsed=Date.now(),Z.frontendSessionId)S2(Z.frontendSessionId),q("session_pool.release",{frontendSessionId:Z.frontendSessionId,poolEntries:y.size});if(I2(),y.get(X)===Z)v0(Z)}async function P1(X){let $=Array.from(y.entries()).filter(([,Z])=>Z.frontendSessionId===X);for(let[Z,Q]of $)y.delete(Z),v0(Q);return await Promise.all($.map(([,Z])=>Z.sessionPromise.then((Q)=>Q.dispose()).catch(()=>{return}))),q("session_pool.frontend_evicted",{frontendSessionId:X,evictedSessions:$.length,poolEntries:y.size}),$.length}async function g2(){let X=Array.from(y.values());y.clear();for(let $ of X)v0($);if(i!==null)clearInterval(i),i=null;await Promise.all(X.map(($)=>$.sessionPromise.then((Z)=>Z.dispose()).catch(()=>{return})))}function wX(X){let $=Object.entries(X.configValues??{}),Z=$.length>0?JSON.stringify(Object.fromEntries($.sort(([Q],[K])=>Q.localeCompare(K)))):"";return[X.adapterId,X.configId??"",X.modelId??"",Z,X.mcpUrl??"",X.runFolder??"",X.toolSurface??"full"].join(" ")}var M1=!1;function m2(){if(M1)return;M1=!0;let X=()=>{g2()};process.once("beforeExit",X),process.once("SIGTERM",X),process.once("SIGINT",X)}m2();import{readFileSync as p2}from"node:fs";import{homedir as c2}from"node:os";import{join as I0}from"node:path";function l2(){let X=c2();switch(process.platform){case"win32":return process.env.APPDATA??I0(X,"AppData","Roaming");case"darwin":return I0(X,"Library","Application Support");default:return process.env.XDG_CONFIG_HOME??I0(X,".config")}}function F1(){let X=process.env.IDEAWAVE_MCP_JSON_PATH;if(X&&X.trim().length>0)return X;return I0(l2(),"ideawave","mcp.json")}var k1=null;function q1(X){k1=X}var u2=86400000;function a2(){let X;try{X=p2(F1(),"utf8")}catch{return null}let $;try{$=JSON.parse(X)}catch{return null}if(typeof $.url!=="string")return null;if(typeof $.startedAt==="string"){let Z=Date.parse($.startedAt);if(!Number.isNaN(Z)){if(Date.now()-Z>u2)return null}}if(typeof $.pid==="number"&&$.pid>0)try{process.kill($.pid,0)}catch(Z){if(Z?.code!=="EPERM")return null}return{url:$.url}}function O1(X,$={}){let Z=[];if($.userId&&$.userId.trim().length>0)Z.push({name:"X-Ideawave-User-Id",value:$.userId.trim()});if($.frontendSessionId&&$.frontendSessionId.trim().length>0)Z.push({name:"X-Ideawave-Frontend-Session-Id",value:$.frontendSessionId.trim()});if($.toolSurface==="read")Z.push({name:"X-Ideawave-Tool-Surface",value:"read"});if($.imagesSupported)Z.push({name:"X-Ideawave-Images-Supported",value:"1"});if($.cardId&&$.cardId.trim().length>0)Z.push({name:"X-Ideawave-Card-Id",value:$.cardId.trim()});if($.boardId&&$.boardId.trim().length>0)Z.push({name:"X-Ideawave-Board-Id",value:$.boardId.trim()});if($.runFolder&&$.runFolder.trim().length>0)Z.push({name:"X-Ideawave-Run-Folder",value:$.runFolder.trim()});return{type:"http",name:"ideawave-board",url:X,headers:Z}}function BX(X={}){let $=k1;if($)return O1($.url,X);let Z=a2();if(!Z)return null;return O1(Z.url,X)}var _1="browser-proxy-v5";var d2=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","browser_rpc","browser_rpc_result","warmup_run","warmup_result"]);function S0(X){try{let $=JSON.parse(X);if($&&typeof $==="object"&&typeof $.type==="string"&&d2.has($.type))return $}catch{}return null}function g0(X){return JSON.stringify(X)}import O0 from"node:fs/promises";import r2 from"node:path";import{z as F}from"zod";var A1=F.object({id:F.string(),name:F.string().nullable().default(null),description:F.string().nullable().default(null)}),y1=F.union([F.string(),F.boolean()]),i2=F.object({value:F.string(),name:F.string(),description:F.string().nullable().default(null),group:F.string().nullable().default(null),groupName:F.string().nullable().default(null)}),C1=F.object({id:F.string(),name:F.string(),category:F.string().nullable().default(null),description:F.string().nullable().default(null),type:F.enum(["select","boolean"]),currentValue:y1.nullable().default(null),options:F.array(i2).default([])}),MX=F.record(F.string(),y1).default({}),o2=F.discriminatedUnion("kind",[F.object({id:F.string(),kind:F.literal("registered"),adapterId:F.enum(["claude-code","opencode","codex","copilot"]),displayName:F.string(),runFolder:F.string().nullable(),defaultModelId:F.string().nullable().default(null),defaultConfigValues:MX,discoveredModels:F.array(A1).default([]),discoveredConfigOptions:F.array(C1).default([]),discoveredAt:F.string().nullable().default(null)}),F.object({id:F.string(),kind:F.literal("custom"),displayName:F.string(),command:F.string(),args:F.array(F.string()),env:F.record(F.string(),F.string()),runFolder:F.string().nullable(),defaultModelId:F.string().nullable().default(null),defaultConfigValues:MX,discoveredModels:F.array(A1).default([]),discoveredConfigOptions:F.array(C1).default([]),discoveredAt:F.string().nullable().default(null)})]),f1=F.object({runtimeConfigId:F.string(),runFolder:F.string().nullable(),modelId:F.string().nullable().default(null),configValues:MX}),m0=F.object({version:F.literal(1),globalDefaultConfigId:F.string().nullable(),runtimes:F.array(o2),boardOverrides:F.record(F.string(),f1).default({}),cardOverrides:F.record(F.string(),f1).default({})});import n2 from"node:os";import c0 from"node:path";function t2(){let X=n2.homedir();switch(process.platform){case"win32":return process.env.APPDATA??c0.join(X,"AppData","Roaming");case"darwin":return c0.join(X,"Library","Application Support");default:return process.env.XDG_CONFIG_HOME??c0.join(X,".config")}}function l0(){let X=process.env.IDEAWAVE_RUNTIME_CONFIG_PATH;if(X)return X;return c0.join(t2(),"ideawave","runtimes.json")}var s2={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},R1=new Map;function e2(X){return R1.get(X)??Promise.resolve()}function X6(X,$){R1.set(X,$)}async function m(X){let $=X??l0(),Z;try{Z=await O0.readFile($,"utf-8")}catch(K){if(K.code==="ENOENT")return structuredClone(s2);throw K}return m0.parse(JSON.parse(Z))}async function p(X,$){let Z=$??l0(),Q=e2(Z).then(async()=>{let K=await m(Z),J=structuredClone(K),Y=await X(J);return await $6(J,Z),Y});return X6(Z,Q.catch(()=>{return})),Q}async function $6(X,$){let Z=$??l0(),Q=r2.dirname(Z);await O0.mkdir(Q,{recursive:!0});let K=`${Z}.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`,J=JSON.stringify(X,null,2);await O0.writeFile(K,J,"utf-8");try{await O0.rename(K,Z)}catch(Y){throw await O0.unlink(K).catch(()=>{return}),Y}}import{spawn as z6}from"node:child_process";import{closeSync as U6,existsSync as h1,mkdirSync as I1,openSync as H6,readFileSync as x6,renameSync as D6,rmSync as S1,statSync as N6,unlinkSync as w6,writeFileSync as B6}from"node:fs";import E1 from"node:os";import W0 from"node:path";var Z6=/\.(?:cmd|bat)$/i;function Q6(X){return process.platform==="win32"&&Z6.test(X)}function p0(X){return Q6(X)?{shell:!0,windowsHide:!0}:{}}import{execFile as G6}from"node:child_process";import{promisify as V6}from"node:util";import{execFile as K6}from"node:child_process";import{promisify as J6}from"node:util";var Y6=J6(K6),LX=new Map,b1=5000,W6=/\.(?:cmd|bat|com|exe)$/i;function j6(X){let $=X.split(/\r?\n/).map((Z)=>Z.trim()).filter((Z)=>Z.length>0);if($.length===0)return null;if(process.platform!=="win32")return $[0]??null;return $.find((Z)=>W6.test(Z))??$[0]??null}async function T1(X,$=Y6){let Z=LX.get(X);if(Z&&Z.expiresAt>Date.now())return Z.value;let Q=process.platform==="win32"?"where":"which";try{let{stdout:K}=await $(Q,[X],{timeout:2000}),J=j6(K);return LX.set(X,{value:J,expiresAt:Date.now()+b1}),J}catch{return LX.set(X,{value:null,expiresAt:Date.now()+b1}),null}}class k0 extends Error{code;constructor(X,$){super(X);this.name="AcpError",this.code=$}}class Y0 extends k0{constructor(X="No ACP runtime configured"){super(X,"RUNTIME_NOT_CONFIGURED");this.name="RuntimeNotConfiguredError"}}class f extends k0{constructor(X){super(X,"RUNTIME_UNREACHABLE");this.name="RuntimeUnreachableError"}}class H0 extends k0{authMethods;constructor(X,$){super(X,"AUTH_REQUIRED");this.name="AuthRequiredError",this.authMethods=$}}class u extends k0{constructor(X="ACP session timed out"){super(X,"SESSION_TIMEOUT");this.name="SessionTimeoutError"}}var q4=V6(G6);function T(X,...$){return T1(X,...$)}function g(X){let $={};for(let[Z,Q]of Object.entries(process.env))if(typeof Q==="string")$[Z]=Q;return{...$,...X??{}}}var FX=[{adapterId:"claude-code",runtimeBinary:"claude",packageName:"@agentclientprotocol/claude-agent-acp",version:"0.61.0",warmupArgs:["--cli","--help"]},{adapterId:"codex",runtimeBinary:"codex",packageName:"@agentclientprotocol/codex-acp",version:"1.1.7",warmupArgs:["--version"]}],M6=1800000,u0=new Map;function OX(){if(process.env.IDEAWAVE_ACP_BRIDGE_CACHE_DIR)return process.env.IDEAWAVE_ACP_BRIDGE_CACHE_DIR;if(process.platform==="win32"){let X=process.env.LOCALAPPDATA??W0.join(E1.homedir(),"AppData","Local");return W0.join(X,"ideawave","acp-bridges")}return W0.join(process.env.XDG_CACHE_HOME??W0.join(E1.homedir(),".cache"),"ideawave","acp-bridges")}function L6(X){return X.replace(/^@/,"").replace(/[/\\]/g,"-")}function a0(){return W0.join(OX(),"install-state.json")}function kX(X){return W0.join(OX(),`${L6(X.packageName)}@${X.version}.install.lock`)}function qX(){return process.platform==="win32"?"npx.cmd":"npx"}function _X(X){return`${X.packageName}@${X.version}`}function g1(){let X=a0();if(!h1(X))return{};try{return JSON.parse(x6(X,"utf8"))}catch{return{}}}function PX(X,$){let Z=OX();I1(Z,{recursive:!0});let Q=g1();Q.bridges={...Q.bridges??{},[X.adapterId]:$},B6(`${a0()}.tmp`,`${JSON.stringify(Q,null,2)}
|
|
3
|
-
`),
|
|
2
|
+
function y2(){let X=globalThis.performance?.now?.()??Date.now();return Math.round(X*10)/10}function q(X,$={}){if(typeof process<"u"&&process.env.IDEAWAVE_AGENT_RUNTIME_TRACE==="0")return;let Z=Object.fromEntries(Object.entries($).filter(([,Q])=>Q!==void 0));console.info("[agent-runtime-trace]",JSON.stringify({event:X,epochMs:Date.now(),monotonicMs:y2(),...typeof document>"u"?{}:{visibility:document.visibilityState},...Z}))}var b2=600000,E2=60000,B1=200,T2=2,f=new Map,i=null;function v2(X){X.then(($)=>$.dispose()).catch(()=>{return})}function h0(X){for(let $ of X.idleWaiters)$();X.idleWaiters.clear()}function t(X,$){if(f.get(X)!==$)return;f.delete(X),h0($),v2($.sessionPromise)}function h2(){if(i!==null)return;i=setInterval(()=>{let X=Date.now();for(let[$,Z]of f){if(Z.inUse)continue;if(X-Z.lastUsed<b2)continue;t($,Z)}if(f.size===0&&i!==null)clearInterval(i),i=null},E2),i.unref?.()}function I2(){if(f.size<B1)return;let X=null,$=1/0;for(let[Q,W]of f){if(W.inUse)continue;if(W.lastUsed>=$)continue;X=Q,$=W.lastUsed}if(!X)return;let Z=f.get(X);if(!Z)return;t(X,Z)}function S2(){let X=0;while(f.size>B1){let $=null,Z=null;for(let[Q,W]of f){if(W.inUse)continue;if(Z&&W.lastUsed>=Z.lastUsed)continue;$=Q,Z=W}if(!$||!Z)break;t($,Z),X+=1}if(X>0)q("session_pool.global_idle_trimmed",{evictedSessions:X,poolEntries:f.size})}function g2(X){let $=Array.from(f.entries()).filter(([,Q])=>Q.frontendSessionId===X&&!Q.inUse).sort(([,Q],[,W])=>Q.lastUsed-W.lastUsed),Z=$.length-T2;if(Z<=0)return;for(let[Q,W]of $.slice(0,Z))t(Q,W);q("session_pool.frontend_idle_trimmed",{frontendSessionId:X,evictedSessions:Z,poolEntries:f.size})}function DX(X,$,Z){return`${X}:${$}:${Z}`}async function I0(X){let $=f.get(X.key);if($){if($.inUse)return q("session_pool.wait_for_idle",{frontendSessionId:$.frontendSessionId,poolEntries:f.size}),await new Promise((Q)=>$.idleWaiters.add(Q)),I0(X);if($.fingerprint===X.fingerprint){$.inUse=!0,$.lastUsed=Date.now();try{let Q=await $.sessionPromise;if(Q.isAlive()){if($.frontendSessionId)q("session_pool.reuse",{frontendSessionId:$.frontendSessionId,poolEntries:f.size});return Q}}catch{}t(X.key,$)}else t(X.key,$)}let Z=X.open();if(I2(),f.set(X.key,{key:X.key,frontendSessionId:X.frontendSessionId??null,fingerprint:X.fingerprint,sessionPromise:Z,lastUsed:Date.now(),inUse:!0,idleWaiters:new Set}),h2(),X.frontendSessionId)q("session_pool.open",{frontendSessionId:X.frontendSessionId,poolEntries:f.size});try{return await Z}catch(Q){let W=f.get(X.key);if(W?.sessionPromise===Z)t(X.key,W);throw Q}}function wX(X,$=!1){let Z=f.get(X);if(!Z)return;if($){t(X,Z);return}if(Z.inUse=!1,Z.lastUsed=Date.now(),Z.frontendSessionId)g2(Z.frontendSessionId),q("session_pool.release",{frontendSessionId:Z.frontendSessionId,poolEntries:f.size});if(S2(),f.get(X)===Z)h0(Z)}async function F1(X){let $=Array.from(f.entries()).filter(([,Z])=>Z.frontendSessionId===X);for(let[Z,Q]of $)f.delete(Z),h0(Q);return await Promise.all($.map(([,Z])=>Z.sessionPromise.then((Q)=>Q.dispose()).catch(()=>{return}))),q("session_pool.frontend_evicted",{frontendSessionId:X,evictedSessions:$.length,poolEntries:f.size}),$.length}async function m2(){let X=Array.from(f.values());f.clear();for(let $ of X)h0($);if(i!==null)clearInterval(i),i=null;await Promise.all(X.map(($)=>$.sessionPromise.then((Z)=>Z.dispose()).catch(()=>{return})))}function NX(X){let $=Object.entries(X.configValues??{}),Z=$.length>0?JSON.stringify(Object.fromEntries($.sort(([Q],[W])=>Q.localeCompare(W)))):"";return[X.adapterId,X.configId??"",X.modelId??"",Z,X.mcpUrl??"",X.runFolder??"",X.toolSurface??"full"].join(" ")}var L1=!1;function c2(){if(L1)return;L1=!0;let X=()=>{m2()};process.once("beforeExit",X),process.once("SIGTERM",X),process.once("SIGINT",X)}c2();import{readFileSync as u2}from"node:fs";import{homedir as l2}from"node:os";import{join as S0}from"node:path";function p2(){let X=l2();switch(process.platform){case"win32":return process.env.APPDATA??S0(X,"AppData","Roaming");case"darwin":return S0(X,"Library","Application Support");default:return process.env.XDG_CONFIG_HOME??S0(X,".config")}}function O1(){let X=process.env.IDEAWAVE_MCP_JSON_PATH;if(X&&X.trim().length>0)return X;return S0(p2(),"ideawave","mcp.json")}var q1=null;function _1(X){q1=X}var a2=86400000;function d2(){let X;try{X=u2(O1(),"utf8")}catch{return null}let $;try{$=JSON.parse(X)}catch{return null}if(typeof $.url!=="string")return null;if(typeof $.startedAt==="string"){let Z=Date.parse($.startedAt);if(!Number.isNaN(Z)){if(Date.now()-Z>a2)return null}}if(typeof $.pid==="number"&&$.pid>0)try{process.kill($.pid,0)}catch(Z){if(Z?.code!=="EPERM")return null}return{url:$.url}}function k1(X,$={}){let Z=[];if($.userId&&$.userId.trim().length>0)Z.push({name:"X-Ideawave-User-Id",value:$.userId.trim()});if($.frontendSessionId&&$.frontendSessionId.trim().length>0)Z.push({name:"X-Ideawave-Frontend-Session-Id",value:$.frontendSessionId.trim()});if($.toolSurface==="read")Z.push({name:"X-Ideawave-Tool-Surface",value:"read"});if($.imagesSupported)Z.push({name:"X-Ideawave-Images-Supported",value:"1"});if($.cardId&&$.cardId.trim().length>0)Z.push({name:"X-Ideawave-Card-Id",value:$.cardId.trim()});if($.boardId&&$.boardId.trim().length>0)Z.push({name:"X-Ideawave-Board-Id",value:$.boardId.trim()});if($.runFolder&&$.runFolder.trim().length>0)Z.push({name:"X-Ideawave-Run-Folder",value:$.runFolder.trim()});return{type:"http",name:"ideawave-board",url:X,headers:Z}}function MX(X={}){let $=q1;if($)return k1($.url,X);let Z=d2();if(!Z)return null;return k1(Z.url,X)}var A1="browser-proxy-v5";var i2=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","browser_rpc","browser_rpc_result","warmup_run","warmup_result"]);function g0(X){try{let $=JSON.parse(X);if($&&typeof $==="object"&&typeof $.type==="string"&&i2.has($.type))return $}catch{}return null}function m0(X){return JSON.stringify(X)}import F0 from"node:fs/promises";import s2 from"node:path";import{z as F}from"zod";var C1=F.object({id:F.string(),name:F.string().nullable().default(null),description:F.string().nullable().default(null)}),y1=F.union([F.string(),F.boolean()]),o2=F.object({value:F.string(),name:F.string(),description:F.string().nullable().default(null),group:F.string().nullable().default(null),groupName:F.string().nullable().default(null)}),R1=F.object({id:F.string(),name:F.string(),category:F.string().nullable().default(null),description:F.string().nullable().default(null),type:F.enum(["select","boolean"]),currentValue:y1.nullable().default(null),options:F.array(o2).default([])}),PX=F.record(F.string(),y1).default({}),n2=F.discriminatedUnion("kind",[F.object({id:F.string(),kind:F.literal("registered"),adapterId:F.enum(["claude-code","opencode","codex","copilot"]),displayName:F.string(),runFolder:F.string().nullable(),defaultModelId:F.string().nullable().default(null),defaultConfigValues:PX,discoveredModels:F.array(C1).default([]),discoveredConfigOptions:F.array(R1).default([]),discoveredAt:F.string().nullable().default(null)}),F.object({id:F.string(),kind:F.literal("custom"),displayName:F.string(),command:F.string(),args:F.array(F.string()),env:F.record(F.string(),F.string()),runFolder:F.string().nullable(),defaultModelId:F.string().nullable().default(null),defaultConfigValues:PX,discoveredModels:F.array(C1).default([]),discoveredConfigOptions:F.array(R1).default([]),discoveredAt:F.string().nullable().default(null)})]),f1=F.object({runtimeConfigId:F.string(),runFolder:F.string().nullable(),modelId:F.string().nullable().default(null),configValues:PX}),c0=F.object({version:F.literal(1),globalDefaultConfigId:F.string().nullable(),runtimes:F.array(n2),boardOverrides:F.record(F.string(),f1).default({}),cardOverrides:F.record(F.string(),f1).default({})});import t2 from"node:os";import l0 from"node:path";function r2(){let X=t2.homedir();switch(process.platform){case"win32":return process.env.APPDATA??l0.join(X,"AppData","Roaming");case"darwin":return l0.join(X,"Library","Application Support");default:return process.env.XDG_CONFIG_HOME??l0.join(X,".config")}}function p0(){let X=process.env.IDEAWAVE_RUNTIME_CONFIG_PATH;if(X)return X;return l0.join(r2(),"ideawave","runtimes.json")}var e2={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},b1=new Map;function X6(X){return b1.get(X)??Promise.resolve()}function $6(X,$){b1.set(X,$)}async function m(X){let $=X??p0(),Z;try{Z=await F0.readFile($,"utf-8")}catch(W){if(W.code==="ENOENT")return structuredClone(e2);throw W}return c0.parse(JSON.parse(Z))}async function p(X,$){let Z=$??p0(),Q=X6(Z).then(async()=>{let W=await m(Z),K=structuredClone(W),Y=await X(K);return await Z6(K,Z),Y});return $6(Z,Q.catch(()=>{return})),Q}async function Z6(X,$){let Z=$??p0(),Q=s2.dirname(Z);await F0.mkdir(Q,{recursive:!0});let W=`${Z}.tmp.${process.pid}.${Math.random().toString(36).slice(2)}`,K=JSON.stringify(X,null,2);await F0.writeFile(W,K,"utf-8");try{await F0.rename(W,Z)}catch(Y){throw await F0.unlink(W).catch(()=>{return}),Y}}import{spawn as U6}from"node:child_process";import{closeSync as H6,existsSync as I1,mkdirSync as S1,openSync as x6,readFileSync as D6,renameSync as w6,rmSync as g1,statSync as N6,unlinkSync as M6,writeFileSync as P6}from"node:fs";import v1 from"node:os";import J0 from"node:path";var Q6=/\.(?:cmd|bat)$/i;function W6(X){return process.platform==="win32"&&Q6.test(X)}function u0(X){return W6(X)?{shell:!0,windowsHide:!0}:{}}import{execFile as G6}from"node:child_process";import{promisify as z6}from"node:util";import{execFile as K6}from"node:child_process";import{promisify as Y6}from"node:util";var J6=Y6(K6),LX=new Map,E1=5000,V6=/\.(?:cmd|bat|com|exe)$/i;function j6(X){let $=X.split(/\r?\n/).map((Z)=>Z.trim()).filter((Z)=>Z.length>0);if($.length===0)return null;if(process.platform!=="win32")return $[0]??null;return $.find((Z)=>V6.test(Z))??$[0]??null}async function T1(X,$=J6){let Z=LX.get(X);if(Z&&Z.expiresAt>Date.now())return Z.value;let Q=process.platform==="win32"?"where":"which";try{let{stdout:W}=await $(Q,[X],{timeout:2000}),K=j6(W);return LX.set(X,{value:K,expiresAt:Date.now()+E1}),K}catch{return LX.set(X,{value:null,expiresAt:Date.now()+E1}),null}}class O0 extends Error{code;constructor(X,$){super(X);this.name="AcpError",this.code=$}}class Y0 extends O0{constructor(X="No ACP runtime configured"){super(X,"RUNTIME_NOT_CONFIGURED");this.name="RuntimeNotConfiguredError"}}class R extends O0{constructor(X){super(X,"RUNTIME_UNREACHABLE");this.name="RuntimeUnreachableError"}}class H0 extends O0{authMethods;constructor(X,$){super(X,"AUTH_REQUIRED");this.name="AuthRequiredError",this.authMethods=$}}class u extends O0{constructor(X="ACP session timed out"){super(X,"SESSION_TIMEOUT");this.name="SessionTimeoutError"}}var C4=z6(G6);function E(X,...$){return T1(X,...$)}function g(X){let $={};for(let[Z,Q]of Object.entries(process.env))if(typeof Q==="string")$[Z]=Q;return{...$,...X??{}}}var FX=[{adapterId:"claude-code",runtimeBinary:"claude",packageName:"@agentclientprotocol/claude-agent-acp",version:"0.61.0",warmupArgs:["--cli","--help"]},{adapterId:"codex",runtimeBinary:"codex",packageName:"@agentclientprotocol/codex-acp",version:"1.1.7",warmupArgs:["--version"]}],L6=1800000,a0=new Map;function OX(){if(process.env.IDEAWAVE_ACP_BRIDGE_CACHE_DIR)return process.env.IDEAWAVE_ACP_BRIDGE_CACHE_DIR;if(process.platform==="win32"){let X=process.env.LOCALAPPDATA??J0.join(v1.homedir(),"AppData","Local");return J0.join(X,"ideawave","acp-bridges")}return J0.join(process.env.XDG_CACHE_HOME??J0.join(v1.homedir(),".cache"),"ideawave","acp-bridges")}function B6(X){return X.replace(/^@/,"").replace(/[/\\]/g,"-")}function d0(){return J0.join(OX(),"install-state.json")}function kX(X){return J0.join(OX(),`${B6(X.packageName)}@${X.version}.install.lock`)}function qX(){return process.platform==="win32"?"npx.cmd":"npx"}function _X(X){return`${X.packageName}@${X.version}`}function m1(){let X=d0();if(!I1(X))return{};try{return JSON.parse(D6(X,"utf8"))}catch{return{}}}function BX(X,$){let Z=OX();S1(Z,{recursive:!0});let Q=m1();Q.bridges={...Q.bridges??{},[X.adapterId]:$},P6(`${d0()}.tmp`,`${JSON.stringify(Q,null,2)}
|
|
3
|
+
`),w6(`${d0()}.tmp`,d0())}function c1(X){return FX.find(($)=>$.packageName===X)??null}function c(X,$,Z){return{adapterId:X.adapterId,packageName:X.packageName,version:X.version,status:$,...Z?{error:Z}:{}}}function h1(X,$){return $?.packageName===X.packageName&&$.version===X.version}function l1(X){try{return Date.now()-N6(X).mtimeMs>L6}catch{return!1}}function F6(X){let $=kX(X);if(!I1($))return!1;if(l1($))return g1($,{force:!0}),!1;return!0}function O6(X){let $=kX(X);if(S1(J0.dirname($),{recursive:!0}),l1($))g1($,{force:!0});try{let Z=x6($,"wx");return H6(Z),!0}catch{return!1}}function k6(X){M6(kX(X))}function AX(X){let $=m1().bridges?.[X.adapterId];if(h1(X,$)&&$.status==="ready")return c(X,"ready");if(a0.has(X.adapterId)||F6(X))return c(X,"installing");if(h1(X,$)&&$.status==="failed")return c(X,"failed",$.error);return c(X,"missing")}function k0(X,$){X?.onStatusChange?.($)}function q6(X,$){let Z=AX(X);if(Z.status==="ready")return k0($,Z),Z;if(Z.status==="installing"){let J=a0.get(X.adapterId);if(J&&$?.onStatusChange)J.then((G)=>k0($,G));return k0($,Z),Z}if(!O6(X))return c(X,"installing");let Q=c(X,"installing");BX(X,Q),k0($,Q);let W=()=>{},K=new Promise((J)=>{W=J});a0.set(X.adapterId,K);let Y=!1,V=(J)=>{if(Y)return;Y=!0;try{k6(X)}catch{}BX(X,J),k0($,J),a0.delete(X.adapterId),W(J)},z;try{let J=qX();z=U6(J,["-y",_X(X),...X.warmupArgs],{stdio:"ignore",windowsHide:!0,...u0(J)})}catch(J){let G=c(X,"failed",J instanceof Error?J.message:String(J));return V(G),G}return z.on("error",(J)=>{V(c(X,"failed",J.message))}),z.on("close",(J)=>{if(J===0){V(c(X,"ready"));return}V(c(X,"failed",`npx warmup exited ${J??"null"}`))}),z.unref(),Q}function x0(X){let $=c1(X);return $?AX($):null}async function p1(X){let $=[];for(let Z of FX){if(!await E(Z.runtimeBinary)){$.push(c(Z,"not_needed"));continue}$.push(q6(Z,X))}return $.filter((Z)=>Z.status!=="not_needed")}function i0(X){let $=c1(X);if(!$)return null;if(AX($).status!=="ready")return null;return{command:qX(),args:["-y",_X($)],env:{}}}function CX(X,$){if(X.command!==qX())return!1;let Z=FX.find((Q)=>X.args.includes(_X(Q)));if(!Z)return!1;return BX(Z,c(Z,"failed",$)),!0}var u1="claude",RX="@agentclientprotocol/claude-agent-acp",a1=["claude-agent-acp","claude-code-acp"],d1="Install Claude Code from https://github.com/anthropics/claude-code",i1={id:"claude-code",displayName:"Claude Code",kind:"registered",supportsImages:!0,resolveSpawnConfig:async()=>{if(!await E(u1))throw new R(`Claude Code CLI not found. ${d1}`);let $=i0(RX);if($)return{command:$.command,args:$.args,env:g($.env)};let Z=x0(RX),Q=Z?.status==="installing";for(let K of a1){let Y=await E(K);if(Y&&!Q&&Z?.status!=="failed")return{command:Y,args:[],env:g()}}let W=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 R(W)},checkReadiness:async()=>{if(!await E(u1))return{status:"not_installed",detail:d1};let $=x0(RX);if($?.status==="ready")return{status:"ready"};if($?.status==="installing")return{status:"not_running",detail:"Installing Claude Code ACP bridge..."};if($?.status==="failed")return{status:"not_running",detail:$.error??"Claude Code ACP bridge install failed. Restart IdeaWave CLI so it can warm the pinned bridge again."};for(let Z of a1)if(await E(Z))return{status:"ready"};return{status:"not_running",detail:"Installing Claude Code ACP bridge..."}},authHint:"Run `claude login` (or set ANTHROPIC_API_KEY)."};var o1="codex",fX="@agentclientprotocol/codex-acp",n1="codex-acp",t1="Install Codex CLI from https://developers.openai.com/codex/cli",r1={id:"codex",displayName:"Codex",kind:"registered",resolveSpawnConfig:async()=>{if(!await E(o1))throw new R(`Codex CLI not found. ${t1}`);let $=i0(fX);if($)return{command:$.command,args:$.args,env:g($.env)};let Z=x0(fX),Q=Z?.status==="installing",W=await E(n1);if(W&&!Q&&Z?.status!=="failed")return{command:W,args:[],env:g()};let K=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 R(K)},checkReadiness:async()=>{if(!await E(o1))return{status:"not_installed",detail:t1};let $=x0(fX);if($?.status==="ready")return{status:"ready"};if($?.status==="installing")return{status:"not_running",detail:"Installing Codex ACP bridge..."};if($?.status==="failed")return{status:"not_running",detail:$.error??"Codex ACP bridge install failed. Restart IdeaWave CLI so it can warm the pinned bridge again."};if(await E(n1))return{status:"ready"};return{status:"not_running",detail:"Installing Codex ACP bridge..."}},authHint:"Run `codex login` (or set OPENAI_API_KEY)."};var s1="copilot",e1="copilot-acp",X$="npm i -g @github/copilot",$$={id:"copilot",displayName:"GitHub Copilot",kind:"registered",resolveSpawnConfig:async()=>{let X=await E(s1);if(X)return{command:X,args:["--acp"],env:g()};let $=await E(e1);if($)return{command:$,args:[],env:g()};throw new R(`Copilot not installed. Run: ${X$}`)},checkReadiness:async()=>{if(await E(s1))return{status:"ready"};if(await E(e1))return{status:"ready"};return{status:"not_installed",detail:X$}},authHint:"Run `gh auth login` (or `copilot login`)."};import _6 from"node:fs/promises";function A6(X){return X.startsWith("/")||/^[a-zA-Z]:[\\/]/.test(X)}async function Z$(X){if(A6(X))try{return await _6.access(X),!0}catch{return!1}return await E(X)!==null}var Q$={id:"custom",displayName:"Custom ACP",kind:"custom",resolveSpawnConfig:async(X)=>{if(X.kind!=="custom")throw new R("customAdapter received non-custom entry");if(!await Z$(X.command))throw new R(`custom: command "${X.command}" not found`);return{command:X.command,args:X.args,env:g(X.env)}},checkReadiness:async(X)=>{if(X.kind!=="custom")return{status:"unknown"};return await Z$(X.command)?{status:"ready"}:{status:"not_installed"}}};var W$="opencode",K$="Install OpenCode from https://opencode.ai",Y$={id:"opencode",displayName:"OpenCode",kind:"registered",resolveSpawnConfig:async()=>{let X=await E(W$);if(!X)throw new R(`OpenCode not installed. ${K$}`);return{command:X,args:["acp"],env:g()}},checkReadiness:async()=>{if(!await E(W$))return{status:"not_installed",detail:K$};return{status:"ready"}},authHint:"Run `opencode auth login <provider>` (or set the provider's API-key env var)."};var J$={"claude-code":i1,opencode:Y$,codex:r1,copilot:$$};function a(X){if(X.kind==="custom")return Q$;let $=J$[X.adapterId];if(!$)throw Error(`Unknown registered adapter: ${X.adapterId}`);return $}function D0(){return Object.values(J$)}var yX=new Map,o0=new Map,C6=30000;function n0(X,$){let Z=yX.get(X);if(Z&&Z.expiresAt>Date.now())return Promise.resolve(Z.value);let Q=o0.get(X);if(Q)return Q;let W=$().then((K)=>{return yX.set(X,{value:K,expiresAt:Date.now()+C6}),K}).finally(()=>{o0.delete(X)});return o0.set(X,W),W}async function V$(X){let $=await Promise.all(D0().map((K)=>n0(K.id,async()=>({adapterId:K.id,...await K.checkReadiness({id:"__probe__",kind:"registered",adapterId:K.id,displayName:K.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null})})))),Q=(await m(X)).runtimes.filter((K)=>K.kind==="custom"),W=await Promise.all(Q.map((K)=>n0(`custom:${K.id}`,async()=>({adapterId:K.id,...await a(K).checkReadiness(K)}))));return[...$,...W]}async function j$(X,$){let Z=D0().find((K)=>K.id===X);if(Z)return n0(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 W=(await m($)).runtimes.find((K)=>K.id===X);if(!W||W.kind!=="custom")return null;return n0(`custom:${W.id}`,async()=>({adapterId:W.id,...await a(W).checkReadiness(W)}))}function G$(){yX.clear(),o0.clear()}import{randomBytes as N$,randomUUID as x$}from"node:crypto";import{WebSocket as t0,WebSocketServer as f6}from"ws";function r(X){return JSON.stringify(X).replace(/</g,"\\u003c")}function R6(X){try{let $=new URL(X);if($.protocol!=="https:"||$.hostname!=="www.google.com"||$.username||$.password||$.pathname!=="/"&&$.pathname!=="/webhp")return null;return"https://www.google.com/search"}catch{return null}}function z$(X){let $=r(R6(X.sourceUrl));return`(() => {
|
|
4
4
|
"use strict";
|
|
5
5
|
let TOKEN = ${r(X.token)};
|
|
6
6
|
let SOURCE_URL = ${r(X.sourceUrl)};
|
|
@@ -396,12 +396,12 @@ function y2(){let X=globalThis.performance?.now?.()??Date.now();return Math.roun
|
|
|
396
396
|
if (BRIDGE_SCRIPT) BRIDGE_SCRIPT.remove();
|
|
397
397
|
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", state, { once: true });
|
|
398
398
|
else state();
|
|
399
|
-
})();`}function
|
|
399
|
+
})();`}function U$(X){return JSON.stringify(X).replace(/</g,"\\u003c")}function bX(X){return`(() => {
|
|
400
400
|
"use strict";
|
|
401
401
|
if (window.__browserKitHooked) return;
|
|
402
402
|
window.__browserKitHooked = true;
|
|
403
|
-
let REAL = ${
|
|
404
|
-
const PROXY_ORIGIN = ${
|
|
403
|
+
let REAL = ${U$(X.sourceUrl)};
|
|
404
|
+
const PROXY_ORIGIN = ${U$(X.proxyOrigin)};
|
|
405
405
|
const PREFIX = PROXY_ORIGIN + "/browser-kit/proxy/";
|
|
406
406
|
|
|
407
407
|
const currentRealUrl = () => {
|
|
@@ -785,7 +785,7 @@ function y2(){let X=globalThis.performance?.now?.()??Date.now();return Math.roun
|
|
|
785
785
|
};
|
|
786
786
|
addEventListener("popstate", notifyNavigation);
|
|
787
787
|
addEventListener("hashchange", notifyNavigation);
|
|
788
|
-
})();`}var
|
|
788
|
+
})();`}var H$=new Set(["content-security-policy","content-security-policy-report-only","x-frame-options","cross-origin-opener-policy","cross-origin-embedder-policy","cross-origin-resource-policy","content-encoding","content-length","transfer-encoding","set-cookie","strict-transport-security","report-to","nel","permissions-policy","x-content-type-options"]);function s(X,$,Z){if(!X)return X;let Q=X.trim();if(Q.startsWith(`${Z}/browser-kit/proxy/`)||Q.startsWith("/browser-kit/proxy/")||/^(data|blob|mailto|tel|javascript):/i.test(Q)||Q.startsWith("#"))return Q;try{let W=new URL(Q,$);if(W.protocol!=="http:"&&W.protocol!=="https:")return Q;return`${Z}/browser-kit/proxy/${W.href}`}catch{return Q}}function EX(X){let $=(Z)=>{let Q=Z.trim().replace(/^["']|["']$/g,"");if(!Q||Q.startsWith("data:"))return Z;return s(Q,X.baseUrl,X.proxyOrigin)};return X.css.replace(/url\(\s*([^)]+?)\s*\)/gi,(Z,Q)=>`url(${$(Q)})`).replace(/@import\s+(["'])([^"']+)\1/gi,(Z,Q,W)=>`@import ${Q}${$(W)}${Q}`)}function TX(X){let $=new URL(X.sourceUrl).origin,Z=X.html.replace(/<meta[^>]+http-equiv\s*=\s*["']?content-security-policy["']?[^>]*>/gi,"").replace(/\sintegrity\s*=\s*(["'])[^"']*\1/gi,"").replace(/(\b(?:href|src|action|poster)\s*=\s*["'])(https?:)\/\//gi,"$1/browser-kit/proxy/$2//").replace(/(\b(?:href|src|action|poster)\s*=\s*["'])\/\//gi,"$1/browser-kit/proxy/https://").replace(/(\b(?:href|action|poster)\s*=\s*["'])\/(?!\/|browser-kit\/proxy\/)/gi,`$1/browser-kit/proxy/${$}/`).replace(/(\bimport\s*\(\s*["'])\/(?!\/|browser-kit\/proxy\/)([^"']*)(["']\s*\))/g,`$1/browser-kit/proxy/${$}/$2$3`).replace(/(\bimport\s*\(\s*\\["'])\/(?!\/|browser-kit\/proxy\/)([^"'\\]*)(\\["']\s*\))/g,`$1/browser-kit/proxy/${$}/$2$3`);Z=Z.replace(/(<meta[^>]+http-equiv\s*=\s*["']?refresh["']?[^>]*content\s*=\s*["'][^"']*?url\s*=\s*)([^"'\s>]+)/gi,(Y,V,z)=>V+s(z,X.sourceUrl,X.proxyOrigin)),Z=Z.replace(/\bsrcset\s*=\s*["']([^"']*)["']/gi,(Y,V)=>{return`srcset="${V.split(",").map((J)=>{let G=J.trim().split(/\s+/),M=G.shift();if(!M)return"";return[/^https?:\/\//i.test(M)||M.startsWith("//")||M.startsWith("/")?s(M,X.sourceUrl,X.proxyOrigin):M,...G].join(" ")}).filter(Boolean).join(", ")}"`});let Q=bX({sourceUrl:X.sourceUrl,proxyOrigin:X.proxyOrigin}),W=z$({token:X.bridgeToken,sourceUrl:X.sourceUrl,revision:X.revision,navigateUrlPrefix:X.navigateUrlPrefix,parentOrigin:X.proxyOrigin}),K=`<base href="${X.proxyOrigin}/browser-kit/proxy/${X.sourceUrl}"><script data-browser-kit-runtime>${Q}</script><script data-ideawave-browser-bridge>${W}</script>`;if(/<head[^>]*>/i.test(Z))return Z.replace(/<head[^>]*>/i,(Y)=>Y+K);if(/<html[^>]*>/i.test(Z))return Z.replace(/<html[^>]*>/i,(Y)=>Y+K);return K+Z}function vX(){return`
|
|
789
789
|
self.addEventListener("install", (event) => event.waitUntil(self.skipWaiting()));
|
|
790
790
|
self.addEventListener("activate", (event) => event.waitUntil(self.clients.claim()));
|
|
791
791
|
|
|
@@ -873,7 +873,7 @@ self.addEventListener("fetch", (event) => {
|
|
|
873
873
|
return proxy(event, url.href);
|
|
874
874
|
})());
|
|
875
875
|
});
|
|
876
|
-
`}var y6=1800000,
|
|
876
|
+
`}var y6=1800000,w0="/browser-kit/proxy/",D$="__browser_kit_client_";function b6(X){let $=X??"";return $.startsWith("[")?$.slice(1,$.indexOf("]")):$.split(":")[0]??""}function w$(X){let $=new URL(X);if($.protocol!=="http:"&&$.protocol!=="https:")throw Error("Only HTTP(S) browser URLs are supported");return $.href}function E6(X){let $=new URL(X);if($.protocol!=="http:"&&$.protocol!=="https:")throw Error("Browser frontend origin is invalid");return $.origin}function hX(X){return JSON.stringify(X).replace(/</g,"\\u003c")}function T6(){return N$(12).toString("hex")}function v6(X){let $=new Headers;for(let[Z,Q]of Object.entries(X.headers))if(typeof Q==="string")$.set(Z,Q);else if(Array.isArray(Q))$.set(Z,Q.join(", "));return $}async function h6(X){if(X.method==="GET"||X.method==="HEAD")return;let $=[];for await(let Z of X)$.push(Buffer.isBuffer(Z)?Z:Buffer.from(Z));return $.length>0?Buffer.concat($):void 0}function I6(X){let $={};return X.forEach((Z,Q)=>{$[Q]=Z}),$}function S6(X,$){return`<!doctype html>
|
|
877
877
|
<html>
|
|
878
878
|
<head>
|
|
879
879
|
<meta charset="utf-8">
|
|
@@ -918,29 +918,29 @@ html,body,#view{border:0;margin:0;width:100%;height:100%;overflow:hidden;backgro
|
|
|
918
918
|
})();
|
|
919
919
|
</script>
|
|
920
920
|
</body>
|
|
921
|
-
</html>`}class t0{sessions=new Map;socketServer=new f6({noServer:!0});sweepTimer;port=null;constructor(){this.sweepTimer=setInterval(()=>this.sweep(),60000),this.sweepTimer.unref?.()}setPort(X){this.port=X}wrapperOrigin(X){if(!this.port)throw Error("Browser kit is not ready");return`http://${X.wrapperHost}.localhost:${this.port}`}result(X){let $=this.wrapperOrigin(X);return{proxySessionId:X.id,wrapperUrl:`${$}/browser-kit/wrapper?session=${encodeURIComponent(X.id)}`,bridgeToken:X.bridgeToken,navigateUrlPrefix:`${$}/browser-kit/navigate?session=${encodeURIComponent(X.id)}&url=`}}async handleRpc(X,$,Z){if(Z.method==="open_proxy_session"){let Q=Z.params;if(typeof Q.browserNodeId!=="string"||typeof Q.url!=="string")throw Error("Browser proxy session input is invalid");let K=D$(Q.url),J=b6($),Y=[...this.sessions.values()].find((z)=>z.frontendSessionId===X&&z.browserNodeId===Q.browserNodeId);if(Y){if(Y.frontendOrigin!==J)throw Error("Browser proxy session origin changed unexpectedly");return Y.currentUrl=K,Y.lastUsedAt=Date.now(),this.result(Y)}let j={id:H$(),frontendSessionId:X,frontendOrigin:J,browserNodeId:Q.browserNodeId,wrapperHost:`iw-browser-${T6()}`,bridgeToken:N$(24).toString("base64url"),currentUrl:K,lastUsedAt:Date.now(),cookies:new Map};return this.sessions.set(j.id,j),this.result(j)}if(Z.method==="close_proxy_session"){let Q=Z.params;if(typeof Q.proxySessionId!=="string")throw Error("Browser proxy session input is invalid");let K=this.sessions.get(Q.proxySessionId);if(K&&K.frontendSessionId!==X)throw Error("Browser proxy session belongs to another frontend session");if(K)this.sessions.delete(K.id);return{closed:!0}}if(Z.method==="build_snapshot")throw Error("Browser-kit snapshots are not available yet");throw Error("Unsupported browser-kit RPC operation")}closeFrontendSession(X){for(let $ of this.sessions.values())if($.frontendSessionId===X)this.sessions.delete($.id)}async close(){clearInterval(this.sweepTimer),this.sessions.clear(),this.socketServer.close()}sweep(){let X=Date.now()-y6;for(let $ of this.sessions.values())if($.lastUsedAt<X)this.sessions.delete($.id)}sessionForRequest(X){let $=R6(X.headers.host);return[...this.sessions.values()].find((Z)=>$===`${Z.wrapperHost}.localhost`)??null}storeCookies(X,$,Z){for(let Q of $){let[K="",...J]=Q.split(";"),Y=K.indexOf("=");if(Y<0)continue;let j=K.slice(0,Y).trim(),z=K.slice(Y+1).trim(),W=Z.toLowerCase();for(let B of J){let L=B.indexOf("="),x=(L<0?B:B.slice(0,L)).trim().toLowerCase(),U=L<0?"":B.slice(L+1).trim();if(x==="domain"&&U)W=U.replace(/^\./,"").toLowerCase()}if(!X.cookies.has(W))X.cookies.set(W,new Map);let V=X.cookies.get(W);if(!V)continue;if(z===""||/(^|;)\s*max-age=0/i.test(Q))V.delete(j);else V.set(j,z)}}storeClientCookies(X,$){if(!$)return;for(let Z of $.split(";")){let Q=Z.trim(),K=Q.indexOf("=");if(K<1)continue;let J=Q.slice(0,K);if(!J.startsWith(x$))continue;let Y=J.slice(x$.length).split(".");if(Y.length!==2)continue;try{let j=Buffer.from(Y[0]??"","base64url").toString(),z=Buffer.from(Y[1]??"","base64url").toString(),W=JSON.parse(decodeURIComponent(Q.slice(K+1))),V=new URL(j).hostname.toLowerCase();if(!z||W.name!==z||typeof W.value!=="string")continue;if(!X.cookies.has(V))X.cookies.set(V,new Map);let B=X.cookies.get(V);if(!B)continue;if(W.deleted===!0)B.delete(z);else B.set(z,W.value)}catch{}}}cookieHeader(X,$){let Z=$.toLowerCase(),Q=[];for(let[K,J]of X.cookies)if(Z===K||Z.endsWith(`.${K}`))for(let[Y,j]of J)Q.push(`${Y}=${j}`);return Q.join("; ")}async proxy(X,$,Z,Q){let K=Q.pathname.slice(N0.length)+Q.search+Q.hash;if(!/^https?:\/\//i.test(K)){$.writeHead(400,{"content-type":"text/plain"}),$.end(`Bad proxy target: ${K}`);return}let J=await v6(X),Y=X.method??"GET",j=K,z=J,W=null;this.storeClientCookies(Z,X.headers.cookie);for(let D=0;;D+=1){let N=new URL(j),H=E6(X);for(let G of["host","connection","origin","referer","cookie","accept-encoding"])H.delete(G);let P=this.cookieHeader(Z,N.hostname);if(P)H.set("cookie",P);H.set("referer",`${N.origin}/`);let w={method:Y,headers:H,redirect:"manual",...Y!=="GET"&&Y!=="HEAD"&&z?{body:z,duplex:"half"}:{}};try{W=await fetch(j,w)}catch(G){$.writeHead(502,{"content-type":"text/plain"}),$.end(`Proxy fetch error for ${j}: ${G instanceof Error?G.message:String(G)}`);return}let O=W.headers.getSetCookie,C=typeof O==="function"?O.call(W.headers):[];if(C.length>0)this.storeCookies(Z,C,N.hostname);let M=W.headers.get("location");if(W.status>=300&&W.status<400&&M&&D<15){if(j=new URL(M,j).href,W.status===303||Y==="POST"&&(W.status===301||W.status===302))Y="GET",z=void 0;continue}break}if(!W)throw Error("Browser proxy received no response");Z.lastUsedAt=Date.now();let V=new Headers;W.headers.forEach((D,N)=>{if(!U$.has(N.toLowerCase()))V.set(N,D)}),V.set("access-control-allow-origin","*"),V.set("access-control-allow-credentials","true");for(let D of["location","content-location"]){let N=V.get(D);if(N)V.set(D,s(N,j,this.wrapperOrigin(Z)))}let B=V.get("refresh");if(B){let D=B.toLowerCase().indexOf("url=");if(D>=0)V.set("refresh",B.slice(0,D+4)+s(B.slice(D+4).trim(),j,this.wrapperOrigin(Z)))}let L=V.get("link");if(L){let D=L.replace(/<([^>]+)>/g,(N,H)=>`<${s(H,j,this.wrapperOrigin(Z))}>`).replace(/;\s*integrity\s*=\s*(?:"[^"]*"|'[^']*'|[^;,\s]+)/gi,"");V.set("link",D)}let x=(W.headers.get("content-type")??"").toLowerCase(),U;if(x.includes("text/html")){let D=H$();U=EX({html:await W.text(),sourceUrl:j,proxyOrigin:this.wrapperOrigin(Z),bridgeToken:Z.bridgeToken,revision:D,navigateUrlPrefix:`${this.wrapperOrigin(Z)}/browser-kit/navigate?session=${encodeURIComponent(Z.id)}&url=`}),V.delete("etag"),V.delete("last-modified"),V.set("cache-control","no-store"),V.append("set-cookie",`__browser_kit_origin=${encodeURIComponent(new URL(j).origin)}; Path=/; SameSite=Lax`)}else if(x.includes("text/css"))U=TX({css:await W.text(),baseUrl:j,proxyOrigin:this.wrapperOrigin(Z)}),V.delete("etag"),V.delete("last-modified"),V.set("cache-control","no-store");else U=Buffer.from(await W.arrayBuffer());if($.writeHead(W.status,h6(V)),X.method==="HEAD")$.end();else $.end(U)}async handleHttpRequest(X,$){let Z=new URL(X.url??"/","http://localhost"),Q=Z.pathname.startsWith("/browser-kit/"),K=this.sessionForRequest(X);if(!K){if(!Q)return!1;return $.writeHead(404,{"content-type":"text/plain"}),$.end("Browser-kit session not found"),!0}if(K.lastUsedAt=Date.now(),!Q){let J=null,j=X.headers.referer?.match(/\/browser-kit\/proxy\/(https?:\/\/[^/?#]+)/i);if(j?.[1])J=j[1];if(!J){let W=X.headers.cookie?.match(/(?:^|;\s*)__browser_kit_origin=([^;]+)/);if(W?.[1])try{J=decodeURIComponent(W[1])}catch{}}if(!J)J=new URL(K.currentUrl).origin;let z=`${J}${Z.pathname}${Z.search}`;return $.writeHead(307,{location:`${this.wrapperOrigin(K)}${N0}${z}`,"cache-control":"no-store"}),$.end(),!0}if(Z.pathname==="/browser-kit/wrapper"){if(Z.searchParams.get("session")!==K.id||X.method!=="GET"&&X.method!=="HEAD")return $.writeHead(403),$.end(),!0;let J=I6(K,K.currentUrl);if($.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store","content-security-policy":`default-src 'self'; script-src 'self' 'unsafe-inline'; worker-src 'self'; style-src 'unsafe-inline'; frame-src 'self'; connect-src 'self'; frame-ancestors ${K.frontendOrigin}`,"access-control-allow-origin":K.frontendOrigin,vary:"Origin"}),X.method==="HEAD")$.end();else $.end(J);return!0}if(Z.pathname==="/browser-kit/sw.js")return $.writeHead(200,{"content-type":"text/javascript; charset=utf-8","service-worker-allowed":"/","cache-control":"no-store"}),$.end(vX()),!0;if(Z.pathname==="/browser-kit/navigate"){let J=Z.searchParams.get("url");if(!J)return $.writeHead(400),$.end(),!0;return K.currentUrl=D$(J),$.writeHead(307,{location:`${this.wrapperOrigin(K)}${N0}${K.currentUrl}`,"cache-control":"no-store"}),$.end(),!0}if(Z.pathname.startsWith(N0))return await this.proxy(X,$,K,Z),!0;return $.writeHead(404),$.end(),!0}handleUpgrade(X,$,Z){let Q=new URL(X.url??"/","http://localhost");if(!Q.pathname.startsWith(N0))return!1;let K=this.sessionForRequest(X);if(!K)return $.destroy(),!0;let J=Q.pathname.slice(N0.length)+Q.search+Q.hash;if(!/^wss?:\/\//i.test(J))return $.destroy(),!0;return this.socketServer.handleUpgrade(X,$,Z,(Y)=>{let j;try{let W=new URL(J),V={origin:W.origin},B=this.cookieHeader(K,W.hostname);if(B)V.cookie=B;j=new n0(J,{headers:V})}catch{Y.close(1011,"bad target");return}let z=[];j.binaryType="arraybuffer",j.on("open",()=>{for(let W of z)j.send(W);z.length=0}),Y.on("message",(W)=>{if(j.readyState===n0.OPEN)j.send(W);else z.push(W)}),j.on("message",(W)=>{if(Y.readyState===n0.OPEN)Y.send(W)}),Y.on("close",()=>j.close()),Y.on("error",()=>j.close()),j.on("close",(W,V)=>{if(Y.readyState===n0.OPEN)Y.close(W>=1000&&W<=4999?W:1000,V.toString())}),j.on("error",()=>Y.close(1011,"upstream error"))}),!0}}function S6(X){if(!X)return null;let $=X.indexOf("/");if($<=0)return null;return X.slice(0,$)}function r0(X){let $=[...X.models];if(X.adapterId!=="opencode"||$.length===0)return $;let Z=S6(X.currentModelId)??($.some((K)=>K.id.startsWith("opencode/"))?"opencode":null);if(!Z)return $;let Q=$.filter((K)=>K.id===X.currentModelId||K.id.startsWith(`${Z}/`));return Q.length>0?Q:$}import{Readable as X3,Writable as $3}from"node:stream";import{ClientSideConnection as A$,ndJsonStream as C$}from"@agentclientprotocol/sdk";import e from"node:fs/promises";import S from"node:path";class A0 extends Error{constructor(X){super(X);this.name="PathTraversalError"}}class SX extends Error{constructor(X){super(X);this.name="HiddenPathError"}}class gX extends Error{constructor(X){super(X);this.name="RunFolderFileTooLargeError"}}class _0 extends Error{constructor(X){super(X);this.name="RunFolderBinaryFileError"}}var g6=new Set([".bzr",".cache",".claude",".config",".env",".git",".hg",".idea",".obsidian",".svn",".vscode","node_modules"]),w$=1e6,m6=4096,c6=new TextDecoder("utf-8",{fatal:!0});function l6(X){return X.split(/[\\/]+/).filter(($)=>$.length>0)}function s0(X){if(S.isAbsolute(X))throw new A0("Absolute paths are not allowed");for(let $ of l6(X)){if($===".")continue;if($==="..")throw new A0("Parent-directory traversal is not allowed");if($.startsWith(".")||g6.has($))throw new SX(`Path segment "${$}" is hidden or configuration data`)}}function p6(X){s0(X);let $=S.normalize(X||".");return $==="."?"":$}function u6(X,$,Z){let Q=S.relative(X,$);if(Q===".."||Q.startsWith(`..${S.sep}`)||S.isAbsolute(Q))throw new A0(`Path "${Z}" resolves outside the run folder`);if(Q.length>0)s0(Q);return Q}async function IX(X,$){s0($);let Z=S.resolve(X,$||"."),Q;try{Q=await e.realpath(Z)}catch(K){if(K.code!=="ENOENT")throw K;let J=S.dirname(Z),Y=[S.basename(Z)];while(J!==X&&J!==S.dirname(J))try{J=await e.realpath(J);break}catch(j){if(j.code!=="ENOENT")throw j;Y.unshift(S.basename(J)),J=S.dirname(J)}Q=S.join(J,...Y)}return u6(X,Q,$),Q}async function a6(X,$){let Z=await e.realpath(X);return IX(Z,$)}function d6(X){let $=X.subarray(0,Math.min(X.length,m6));if($.length===0)return!1;let Z=0;for(let Q of $){if(Q===0)return!0;let K=Q===9||Q===10||Q===12||Q===13;if(Q<32&&!K)Z+=1}return Z/$.length>0.3}async function e0(X,$){let Z=await a6(X,$),Q=await e.stat(Z);if(!Q.isFile())throw new _0(`Path "${$}" is not a text file`);if(Q.size>w$)throw new gX(`File "${$}" is too large to read (${Q.size} bytes, max ${w$} bytes)`);let K=await e.readFile(Z);if(d6(K))throw new _0(`File "${$}" appears to be binary, not text`);try{return c6.decode(K)}catch{throw new _0(`File "${$}" is not valid UTF-8 text`)}}function i6(X){if(X.isDirectory())return"directory";if(X.isFile())return"file";if(X.isSymbolicLink())return"symlink";return"other"}function B$(X){return X.split(S.sep).join("/")}async function M$(X,$=""){let Z=await e.realpath(X),Q=p6($),K=await IX(Z,Q),J=await e.readdir(K,{withFileTypes:!0}),Y=[];for(let j of J){let z=Q?S.join(Q,j.name):j.name;try{s0(z);let W=await IX(Z,z),V=await e.stat(W);Y.push({name:j.name,path:B$(z),type:i6(j),size:j.isFile()?V.size:null})}catch{}}return Y.sort((j,z)=>{if(j.type==="directory"&&z.type!=="directory")return-1;if(j.type!=="directory"&&z.type==="directory")return 1;return j.name.localeCompare(z.name)}),{path:B$(Q),absolutePath:K,entries:Y}}var mX={fs:{readTextFile:!0,writeTextFile:!1},terminal:!1};function L$(X){return{readTextFile:async($)=>{return{content:await e0(X,$.path)}}}}import{spawn as o6}from"node:child_process";function cX(X){let $=o6(X.command,X.args,{cwd:X.cwd,env:X.env,stdio:["pipe","pipe","pipe"],...p0(X.command)});if(!$.stdin||!$.stdout||!$.stderr)throw Error("Failed to allocate stdio streams for ACP subprocess");let{stdin:Z,stdout:Q,stderr:K}=$,J=4096,Y=[],j=0;K.on("data",(N)=>{Y.push(N),j+=N.length;while(j>J*2&&Y.length>1){let H=Y.shift();if(H)j-=H.length}});let z=()=>{let N=Buffer.concat(Y).toString("utf8");return N.length>J?N.slice(-J):N},W=!1,V=!1,B,L,x=new Promise((N)=>{B=N}),U=new Promise((N)=>{L=N}),D=(N)=>{if(V)return;if(V=!0,B(N),!W)L(N)};return $.on("exit",(N,H)=>{D({code:N,signal:H,stderr:z()})}),$.on("error",(N)=>{let H=z(),P=N?.message??String(N);D({code:null,signal:null,stderr:H?`${P}
|
|
922
|
-
${H}`:
|
|
923
|
-
... truncated`}function
|
|
924
|
-
`),Z=$.trim();if(Z.startsWith('"')&&Z.endsWith('"')||Z.startsWith("'")&&Z.endsWith("'"))try{let
|
|
921
|
+
</html>`}class r0{sessions=new Map;socketServer=new f6({noServer:!0});sweepTimer;port=null;constructor(){this.sweepTimer=setInterval(()=>this.sweep(),60000),this.sweepTimer.unref?.()}setPort(X){this.port=X}wrapperOrigin(X){if(!this.port)throw Error("Browser kit is not ready");return`http://${X.wrapperHost}.localhost:${this.port}`}result(X){let $=this.wrapperOrigin(X);return{proxySessionId:X.id,wrapperUrl:`${$}/browser-kit/wrapper?session=${encodeURIComponent(X.id)}`,bridgeToken:X.bridgeToken,navigateUrlPrefix:`${$}/browser-kit/navigate?session=${encodeURIComponent(X.id)}&url=`}}async handleRpc(X,$,Z){if(Z.method==="open_proxy_session"){let Q=Z.params;if(typeof Q.browserNodeId!=="string"||typeof Q.url!=="string")throw Error("Browser proxy session input is invalid");let W=w$(Q.url),K=E6($),Y=[...this.sessions.values()].find((z)=>z.frontendSessionId===X&&z.browserNodeId===Q.browserNodeId);if(Y){if(Y.frontendOrigin!==K)throw Error("Browser proxy session origin changed unexpectedly");return Y.currentUrl=W,Y.lastUsedAt=Date.now(),this.result(Y)}let V={id:x$(),frontendSessionId:X,frontendOrigin:K,browserNodeId:Q.browserNodeId,wrapperHost:`iw-browser-${T6()}`,bridgeToken:N$(24).toString("base64url"),currentUrl:W,lastUsedAt:Date.now(),cookies:new Map};return this.sessions.set(V.id,V),this.result(V)}if(Z.method==="close_proxy_session"){let Q=Z.params;if(typeof Q.proxySessionId!=="string")throw Error("Browser proxy session input is invalid");let W=this.sessions.get(Q.proxySessionId);if(W&&W.frontendSessionId!==X)throw Error("Browser proxy session belongs to another frontend session");if(W)this.sessions.delete(W.id);return{closed:!0}}if(Z.method==="build_snapshot")throw Error("Browser-kit snapshots are not available yet");throw Error("Unsupported browser-kit RPC operation")}closeFrontendSession(X){for(let $ of this.sessions.values())if($.frontendSessionId===X)this.sessions.delete($.id)}async close(){clearInterval(this.sweepTimer),this.sessions.clear(),this.socketServer.close()}sweep(){let X=Date.now()-y6;for(let $ of this.sessions.values())if($.lastUsedAt<X)this.sessions.delete($.id)}sessionForRequest(X){let $=b6(X.headers.host);return[...this.sessions.values()].find((Z)=>$===`${Z.wrapperHost}.localhost`)??null}storeCookies(X,$,Z){for(let Q of $){let[W="",...K]=Q.split(";"),Y=W.indexOf("=");if(Y<0)continue;let V=W.slice(0,Y).trim(),z=W.slice(Y+1).trim(),J=Z.toLowerCase();for(let M of K){let L=M.indexOf("="),x=(L<0?M:M.slice(0,L)).trim().toLowerCase(),U=L<0?"":M.slice(L+1).trim();if(x==="domain"&&U)J=U.replace(/^\./,"").toLowerCase()}if(!X.cookies.has(J))X.cookies.set(J,new Map);let G=X.cookies.get(J);if(!G)continue;if(z===""||/(^|;)\s*max-age=0/i.test(Q))G.delete(V);else G.set(V,z)}}storeClientCookies(X,$){if(!$)return;for(let Z of $.split(";")){let Q=Z.trim(),W=Q.indexOf("=");if(W<1)continue;let K=Q.slice(0,W);if(!K.startsWith(D$))continue;let Y=K.slice(D$.length).split(".");if(Y.length!==2)continue;try{let V=Buffer.from(Y[0]??"","base64url").toString(),z=Buffer.from(Y[1]??"","base64url").toString(),J=JSON.parse(decodeURIComponent(Q.slice(W+1))),G=new URL(V).hostname.toLowerCase();if(!z||J.name!==z||typeof J.value!=="string")continue;if(!X.cookies.has(G))X.cookies.set(G,new Map);let M=X.cookies.get(G);if(!M)continue;if(J.deleted===!0)M.delete(z);else M.set(z,J.value)}catch{}}}cookieHeader(X,$){let Z=$.toLowerCase(),Q=[];for(let[W,K]of X.cookies)if(Z===W||Z.endsWith(`.${W}`))for(let[Y,V]of K)Q.push(`${Y}=${V}`);return Q.join("; ")}async proxy(X,$,Z,Q){let W=Q.pathname.slice(w0.length)+Q.search+Q.hash;if(!/^https?:\/\//i.test(W)){$.writeHead(400,{"content-type":"text/plain"}),$.end(`Bad proxy target: ${W}`);return}let K=await h6(X),Y=X.method??"GET",V=W,z=K,J=null;this.storeClientCookies(Z,X.headers.cookie);for(let D=0;;D+=1){let w=new URL(V),H=v6(X);for(let j of["host","connection","origin","referer","cookie","accept-encoding"])H.delete(j);let B=this.cookieHeader(Z,w.hostname);if(B)H.set("cookie",B);H.set("referer",`${w.origin}/`);let N={method:Y,headers:H,redirect:"manual",...Y!=="GET"&&Y!=="HEAD"&&z?{body:z,duplex:"half"}:{}};try{J=await fetch(V,N)}catch(j){$.writeHead(502,{"content-type":"text/plain"}),$.end(`Proxy fetch error for ${V}: ${j instanceof Error?j.message:String(j)}`);return}let O=J.headers.getSetCookie,C=typeof O==="function"?O.call(J.headers):[];if(C.length>0)this.storeCookies(Z,C,w.hostname);let P=J.headers.get("location");if(J.status>=300&&J.status<400&&P&&D<15){if(V=new URL(P,V).href,J.status===303||Y==="POST"&&(J.status===301||J.status===302))Y="GET",z=void 0;continue}break}if(!J)throw Error("Browser proxy received no response");Z.lastUsedAt=Date.now();let G=new Headers;J.headers.forEach((D,w)=>{if(!H$.has(w.toLowerCase()))G.set(w,D)}),G.set("access-control-allow-origin","*"),G.set("access-control-allow-credentials","true");for(let D of["location","content-location"]){let w=G.get(D);if(w)G.set(D,s(w,V,this.wrapperOrigin(Z)))}let M=G.get("refresh");if(M){let D=M.toLowerCase().indexOf("url=");if(D>=0)G.set("refresh",M.slice(0,D+4)+s(M.slice(D+4).trim(),V,this.wrapperOrigin(Z)))}let L=G.get("link");if(L){let D=L.replace(/<([^>]+)>/g,(w,H)=>`<${s(H,V,this.wrapperOrigin(Z))}>`).replace(/;\s*integrity\s*=\s*(?:"[^"]*"|'[^']*'|[^;,\s]+)/gi,"");G.set("link",D)}let x=(J.headers.get("content-type")??"").toLowerCase(),U;if(x.includes("text/html")){let D=x$();U=TX({html:await J.text(),sourceUrl:V,proxyOrigin:this.wrapperOrigin(Z),bridgeToken:Z.bridgeToken,revision:D,navigateUrlPrefix:`${this.wrapperOrigin(Z)}/browser-kit/navigate?session=${encodeURIComponent(Z.id)}&url=`}),G.delete("etag"),G.delete("last-modified"),G.set("cache-control","no-store"),G.append("set-cookie",`__browser_kit_origin=${encodeURIComponent(new URL(V).origin)}; Path=/; SameSite=Lax`)}else if(x.includes("text/css"))U=EX({css:await J.text(),baseUrl:V,proxyOrigin:this.wrapperOrigin(Z)}),G.delete("etag"),G.delete("last-modified"),G.set("cache-control","no-store");else U=Buffer.from(await J.arrayBuffer());if($.writeHead(J.status,I6(G)),X.method==="HEAD")$.end();else $.end(U)}async handleHttpRequest(X,$){let Z=new URL(X.url??"/","http://localhost"),Q=Z.pathname.startsWith("/browser-kit/"),W=this.sessionForRequest(X);if(!W){if(!Q)return!1;return $.writeHead(404,{"content-type":"text/plain"}),$.end("Browser-kit session not found"),!0}if(W.lastUsedAt=Date.now(),!Q){let K=null,V=X.headers.referer?.match(/\/browser-kit\/proxy\/(https?:\/\/[^/?#]+)/i);if(V?.[1])K=V[1];if(!K){let J=X.headers.cookie?.match(/(?:^|;\s*)__browser_kit_origin=([^;]+)/);if(J?.[1])try{K=decodeURIComponent(J[1])}catch{}}if(!K)K=new URL(W.currentUrl).origin;let z=`${K}${Z.pathname}${Z.search}`;return $.writeHead(307,{location:`${this.wrapperOrigin(W)}${w0}${z}`,"cache-control":"no-store"}),$.end(),!0}if(Z.pathname==="/browser-kit/wrapper"){if(Z.searchParams.get("session")!==W.id||X.method!=="GET"&&X.method!=="HEAD")return $.writeHead(403),$.end(),!0;let K=S6(W,W.currentUrl);if($.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store","content-security-policy":`default-src 'self'; script-src 'self' 'unsafe-inline'; worker-src 'self'; style-src 'unsafe-inline'; frame-src 'self'; connect-src 'self'; frame-ancestors ${W.frontendOrigin}`,"access-control-allow-origin":W.frontendOrigin,vary:"Origin"}),X.method==="HEAD")$.end();else $.end(K);return!0}if(Z.pathname==="/browser-kit/sw.js")return $.writeHead(200,{"content-type":"text/javascript; charset=utf-8","service-worker-allowed":"/","cache-control":"no-store"}),$.end(vX()),!0;if(Z.pathname==="/browser-kit/navigate"){let K=Z.searchParams.get("url");if(!K)return $.writeHead(400),$.end(),!0;return W.currentUrl=w$(K),$.writeHead(307,{location:`${this.wrapperOrigin(W)}${w0}${W.currentUrl}`,"cache-control":"no-store"}),$.end(),!0}if(Z.pathname.startsWith(w0))return await this.proxy(X,$,W,Z),!0;return $.writeHead(404),$.end(),!0}handleUpgrade(X,$,Z){let Q=new URL(X.url??"/","http://localhost");if(!Q.pathname.startsWith(w0))return!1;let W=this.sessionForRequest(X);if(!W)return $.destroy(),!0;let K=Q.pathname.slice(w0.length)+Q.search+Q.hash;if(!/^wss?:\/\//i.test(K))return $.destroy(),!0;return this.socketServer.handleUpgrade(X,$,Z,(Y)=>{let V;try{let J=new URL(K),G={origin:J.origin},M=this.cookieHeader(W,J.hostname);if(M)G.cookie=M;V=new t0(K,{headers:G})}catch{Y.close(1011,"bad target");return}let z=[];V.binaryType="arraybuffer",V.on("open",()=>{for(let J of z)V.send(J);z.length=0}),Y.on("message",(J)=>{if(V.readyState===t0.OPEN)V.send(J);else z.push(J)}),V.on("message",(J)=>{if(Y.readyState===t0.OPEN)Y.send(J)}),Y.on("close",()=>V.close()),Y.on("error",()=>V.close()),V.on("close",(J,G)=>{if(Y.readyState===t0.OPEN)Y.close(J>=1000&&J<=4999?J:1000,G.toString())}),V.on("error",()=>Y.close(1011,"upstream error"))}),!0}}function g6(X){if(!X)return null;let $=X.indexOf("/");if($<=0)return null;return X.slice(0,$)}function s0(X){let $=[...X.models];if(X.adapterId!=="opencode"||$.length===0)return $;let Z=g6(X.currentModelId)??($.some((W)=>W.id.startsWith("opencode/"))?"opencode":null);if(!Z)return $;let Q=$.filter((W)=>W.id===X.currentModelId||W.id.startsWith(`${Z}/`));return Q.length>0?Q:$}import{Readable as $3,Writable as Z3}from"node:stream";import{ClientSideConnection as C$,ndJsonStream as R$}from"@agentclientprotocol/sdk";import e from"node:fs/promises";import S from"node:path";class _0 extends Error{constructor(X){super(X);this.name="PathTraversalError"}}class SX extends Error{constructor(X){super(X);this.name="HiddenPathError"}}class gX extends Error{constructor(X){super(X);this.name="RunFolderFileTooLargeError"}}class q0 extends Error{constructor(X){super(X);this.name="RunFolderBinaryFileError"}}var m6=new Set([".bzr",".cache",".claude",".config",".env",".git",".hg",".idea",".obsidian",".svn",".vscode","node_modules"]),M$=1e6,c6=4096,l6=new TextDecoder("utf-8",{fatal:!0});function p6(X){return X.split(/[\\/]+/).filter(($)=>$.length>0)}function e0(X){if(S.isAbsolute(X))throw new _0("Absolute paths are not allowed");for(let $ of p6(X)){if($===".")continue;if($==="..")throw new _0("Parent-directory traversal is not allowed");if($.startsWith(".")||m6.has($))throw new SX(`Path segment "${$}" is hidden or configuration data`)}}function u6(X){e0(X);let $=S.normalize(X||".");return $==="."?"":$}function a6(X,$,Z){let Q=S.relative(X,$);if(Q===".."||Q.startsWith(`..${S.sep}`)||S.isAbsolute(Q))throw new _0(`Path "${Z}" resolves outside the run folder`);if(Q.length>0)e0(Q);return Q}async function IX(X,$){e0($);let Z=S.resolve(X,$||"."),Q;try{Q=await e.realpath(Z)}catch(W){if(W.code!=="ENOENT")throw W;let K=S.dirname(Z),Y=[S.basename(Z)];while(K!==X&&K!==S.dirname(K))try{K=await e.realpath(K);break}catch(V){if(V.code!=="ENOENT")throw V;Y.unshift(S.basename(K)),K=S.dirname(K)}Q=S.join(K,...Y)}return a6(X,Q,$),Q}async function d6(X,$){let Z=await e.realpath(X);return IX(Z,$)}function i6(X){let $=X.subarray(0,Math.min(X.length,c6));if($.length===0)return!1;let Z=0;for(let Q of $){if(Q===0)return!0;let W=Q===9||Q===10||Q===12||Q===13;if(Q<32&&!W)Z+=1}return Z/$.length>0.3}async function XX(X,$){let Z=await d6(X,$),Q=await e.stat(Z);if(!Q.isFile())throw new q0(`Path "${$}" is not a text file`);if(Q.size>M$)throw new gX(`File "${$}" is too large to read (${Q.size} bytes, max ${M$} bytes)`);let W=await e.readFile(Z);if(i6(W))throw new q0(`File "${$}" appears to be binary, not text`);try{return l6.decode(W)}catch{throw new q0(`File "${$}" is not valid UTF-8 text`)}}function o6(X){if(X.isDirectory())return"directory";if(X.isFile())return"file";if(X.isSymbolicLink())return"symlink";return"other"}function P$(X){return X.split(S.sep).join("/")}async function L$(X,$=""){let Z=await e.realpath(X),Q=u6($),W=await IX(Z,Q),K=await e.readdir(W,{withFileTypes:!0}),Y=[];for(let V of K){let z=Q?S.join(Q,V.name):V.name;try{e0(z);let J=await IX(Z,z),G=await e.stat(J);Y.push({name:V.name,path:P$(z),type:o6(V),size:V.isFile()?G.size:null})}catch{}}return Y.sort((V,z)=>{if(V.type==="directory"&&z.type!=="directory")return-1;if(V.type!=="directory"&&z.type==="directory")return 1;return V.name.localeCompare(z.name)}),{path:P$(Q),absolutePath:W,entries:Y}}var mX={fs:{readTextFile:!0,writeTextFile:!1},terminal:!1};function B$(X){return{readTextFile:async($)=>{return{content:await XX(X,$.path)}}}}import{spawn as n6}from"node:child_process";function cX(X){let $=n6(X.command,X.args,{cwd:X.cwd,env:X.env,stdio:["pipe","pipe","pipe"],...u0(X.command)});if(!$.stdin||!$.stdout||!$.stderr)throw Error("Failed to allocate stdio streams for ACP subprocess");let{stdin:Z,stdout:Q,stderr:W}=$,K=4096,Y=[],V=0;W.on("data",(w)=>{Y.push(w),V+=w.length;while(V>K*2&&Y.length>1){let H=Y.shift();if(H)V-=H.length}});let z=()=>{let w=Buffer.concat(Y).toString("utf8");return w.length>K?w.slice(-K):w},J=!1,G=!1,M,L,x=new Promise((w)=>{M=w}),U=new Promise((w)=>{L=w}),D=(w)=>{if(G)return;if(G=!0,M(w),!J)L(w)};return $.on("exit",(w,H)=>{D({code:w,signal:H,stderr:z()})}),$.on("error",(w)=>{let H=z(),B=w?.message??String(w);D({code:null,signal:null,stderr:H?`${B}
|
|
922
|
+
${H}`:B})}),{stdin:Z,stdout:Q,stderr:W,kill:(w="SIGTERM")=>{if(J)return;J=!0;try{$.kill(w)}catch{}},waitForExit:x,processCrashed:U}}var t6=["mcp_ideawave_board_","ideawave_board_","ideawave-board_","ideawave-board.","ideawave.board."];function r6(X){let $=X.toLowerCase();for(let Z of t6)if($.startsWith(Z))return X.slice(Z.length);if(/^mcp[-_.]/i.test(X))return X.slice(4);return X}function $X(X){return r6(X.trim())}function lX(X){let $=$X(X);if(!$)return"Tool";if(!/[-_.]/.test($))return $.charAt(0).toUpperCase()+$.slice(1);let Z=$.replace(/[-_.]+/g," ").replace(/\s+/g," ").trim();if(!Z)return"Tool";return Z.charAt(0).toUpperCase()+Z.slice(1)}function pX(X){let $=X?.toLowerCase();if($==="completed"||$==="complete"||$==="done"||$==="success"||$==="succeeded")return"completed";if($==="failed"||$==="error"||$==="errored")return"failed";return"running"}function uX(X){if(typeof X!=="string")return null;let $=X.trim();return $?$:null}function F$(X){if(typeof X!=="string")return"Tool";let $=X.trim();return $?$:"Tool"}function s6(X,$){if(!X||typeof X!=="object"||Array.isArray(X))return null;let Z=X;for(let Q of $){let W=Z[Q];if(typeof W==="string"&&W.trim())return W.trim()}return null}function aX(X,$){let Z=X.trim().toLowerCase();if(Z==="skill"||Z==="workflow"||Z==="tool"||Z==="invalid"){let Q=s6($,["skillName","workflowName","toolName","name","title"]);if(Q){let W=Z==="skill"?" skill":Z==="workflow"?" workflow":"";return`${lX(Q)}${W}`}}if(Z==="invalid")return"Tool call";return lX(X)}var e6=33,O$=1600;function V0(X){if(X.length<=O$)return X;return`${X.slice(0,O$-22)}
|
|
923
|
+
... truncated`}function QX(X){let $=X.replace(/\r\n?/g,`
|
|
924
|
+
`),Z=$.trim();if(Z.startsWith('"')&&Z.endsWith('"')||Z.startsWith("'")&&Z.endsWith("'"))try{let W=JSON.parse(Z);if(typeof W==="string")return W.replace(/\r\n?/g,`
|
|
925
925
|
`)}catch{return $}if(!$.includes("\\\""))return $;let Q=$.replace(/\\r\\n/g,`
|
|
926
926
|
`).replace(/\\n/g,`
|
|
927
927
|
`).replace(/\\r/g,`
|
|
928
|
-
`).replace(/\\t/g,"\t").replace(/\\"/g,'"');try{let
|
|
928
|
+
`).replace(/\\t/g,"\t").replace(/\\"/g,'"');try{let W=JSON.parse(Q);if(W!==null&&typeof W==="object")return Q}catch{return $}return $}function o(X){if(X===void 0||X===null)return null;if(typeof X==="string"){let $=QX(X).trim();return $?V0($):null}if(typeof X==="number"||typeof X==="boolean"||typeof X==="bigint")return String(X);try{return V0(JSON.stringify(X,null,2))}catch{return V0(QX(String(X)))}}function X3(X){if(!X||typeof X!=="object")return null;let $=X;if($.type==="text"&&typeof $.text==="string")return QX($.text);if($.type==="image")return"[image]";if($.type==="resource")return"[resource]";if($.type==="content"){let Z=$.content;if(Z&&typeof Z==="object"){let Q=Z;if(Q.type==="text"&&typeof Q.text==="string")return QX(Q.text);if(Q.type==="image")return"[image]";if(Q.type==="resource")return"[resource]"}}if($.type==="diff")return`Diff: ${typeof $.path==="string"?$.path:"unknown file"}`;if($.type==="terminal")return`Terminal: ${typeof $.terminalId==="string"?$.terminalId:"terminal"}`;return o(X)}function ZX(X){if(!Array.isArray(X))return null;let $=X.map(X3).filter((Z)=>Boolean(Z?.trim()));if($.length===0)return null;return V0($.join(`
|
|
929
929
|
|
|
930
|
-
`))}function dX(X){if(!X||typeof X!=="object"||Array.isArray(X))return o(X);let $=X,Z
|
|
931
|
-
${Q}`:null,
|
|
932
|
-
${
|
|
930
|
+
`))}function dX(X){if(!X||typeof X!=="object"||Array.isArray(X))return o(X);let $=X,Z=ZX($.content);if(Z)return Z;for(let K of["output","result","text","message"]){let Y=o($[K]);if(Y)return Y}let Q=o($.stdout),W=o($.stderr);if(Q||W)return V0([Q?`stdout:
|
|
931
|
+
${Q}`:null,W?`stderr:
|
|
932
|
+
${W}`:null].filter(Boolean).join(`
|
|
933
933
|
|
|
934
|
-
`));return o(X)}function
|
|
934
|
+
`));return o(X)}function k$(X,$){if(!$)return X;if(!X)return $;if(X===$||X.endsWith($))return X;if($.startsWith(X))return $;return V0(`${X}
|
|
935
935
|
|
|
936
|
-
${$}`)}function iX(X){if(!Array.isArray(X))return null;let $=X.flatMap((Z)=>{if(!Z||typeof Z!=="object")return[];let Q=Z;if(typeof Q.path!=="string"||!Q.path.trim())return[];let K=typeof Q.line==="number"?`:${Q.line}`:"";return[`${Q.path}${K}`]});return $.length>0?$.slice(0,5):null}function k$(X){let{ctx:$,appendText:Z,appendToolActivity:Q}=X,K=X.flushIntervalMs??s6,J="",Y="",j=0,z=null,W={},V=new Map,B=(M)=>{if(V.set(M.toolCallId,M),!Q)return;Q({boardId:$.boardId,cardId:$.cardId,runId:$.runId,entry:M}).catch((G)=>{console.warn("[streamAdapter] appendToolActivity failed",G)})},L=(M)=>{let G=`${$.runId}:thought`,k=V.get(G);if(!k||k.status!=="running")return;B({...k,status:"completed",completedAt:k.completedAt??M})},x=(M)=>{for(let G of V.values()){if(G.status!=="running"||G.rawTitle.toLowerCase()!=="toolsearch")continue;B({...G,status:"completed",completedAt:G.completedAt??M})}},U=(M)=>{for(let G of Array.from(V.values())){if(G.status!=="running")continue;if(G.kind==="thought"||G.rawTitle==="agent_thought")continue;B({...G,status:"completed",completedAt:G.completedAt??M})}},D="",N=0,H=null,P=null,w=(M)=>{if(M===D)return;D=M,N=Date.now(),Z({boardId:$.boardId,cardId:$.cardId,runId:$.runId,text:M}).catch((G)=>{console.warn("[streamAdapter] appendText failed",G)})},O=()=>{if(H!==null)clearTimeout(H),H=null;if(P!==null){let M=P;P=null,w(M)}},C=(M)=>{let G=Date.now()-N;if(G>=K&&H===null){w(M);return}if(P=M,H===null){let k=Math.max(0,K-G);H=setTimeout(()=>{H=null,O()},k)}};return{onSessionUpdate:async(M)=>{let G=M.update;switch(W[G.sessionUpdate]=(W[G.sessionUpdate]??0)+1,G.sessionUpdate){case"agent_message_chunk":{let k=new Date().toISOString();if(L(k),G.content.type==="text")J+=G.content.text,C(J);else{let _=`agent_message_chunk:${G.content.type}`;W[_]=(W[_]??0)+1}return}case"agent_thought_chunk":{if(G.content.type!=="text")return;Y+=G.content.text;let k=new Date().toISOString(),_=`${$.runId}:thought`,b=V.get(_);B({toolCallId:_,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:b?.startedAt??k,completedAt:null,contentPreview:j0(Y.trim())});return}case"user_message_chunk":return;case"tool_call":{j+=1;let k=P$(G.title),_=pX(G.status),b=new Date().toISOString();L(b),x(b),B({toolCallId:G.toolCallId,rawTitle:k,title:aX(k,G.rawInput),kind:uX(G.kind),status:_,startedAt:b,completedAt:_==="running"?null:b,inputPreview:o(G.rawInput),outputPreview:dX(G.rawOutput),contentPreview:$X(G.content),locations:iX(G.locations)});return}case"tool_call_update":{let k=V.get(G.toolCallId);if(!k){let R=P$(G.title),I=pX(G.status),h=new Date().toISOString();B({toolCallId:G.toolCallId,rawTitle:R,title:aX(R,G.rawInput),kind:uX(G.kind),status:I,startedAt:h,completedAt:I==="running"?null:h,inputPreview:o(G.rawInput),outputPreview:dX(G.rawOutput),contentPreview:$X(G.content),locations:iX(G.locations)});return}let _=G.status===void 0||G.status===null?k.status:pX(G.status),b=typeof G.title==="string"&&G.title.trim().length>0?G.title:k.rawTitle,d=typeof G.title==="string"&&G.title.trim().length>0,n=_==="running"?k.completedAt:k.completedAt??new Date().toISOString(),A=G.content===void 0?k.contentPreview:O$(k.contentPreview,$X(G.content)),v=G.rawOutput===void 0?k.outputPreview:O$(k.outputPreview,dX(G.rawOutput));B({...k,rawTitle:b,title:d?aX(b,G.rawInput):k.title,kind:G.kind===void 0?k.kind:uX(G.kind),status:_,completedAt:n,inputPreview:G.rawInput===void 0?k.inputPreview:o(G.rawInput),outputPreview:v,contentPreview:A,locations:G.locations===void 0?k.locations:iX(G.locations)});return}case"plan":z=G.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>J,getToolCallCount:()=>j,getLatestPlan:()=>z,getUpdateTypeCounts:()=>({...W}),flush:(M)=>{let G=new Date().toISOString();if(L(G),M?.completeOpenToolCalls)U(G);O()}}}var C0=1,q$=-32000;function _$(X){if(X.awaitingInput)return!1;return X.nowMs-X.lastUpdateMs>=X.windowMs}function f$(X){if(!X||typeof X!=="object")return!1;return X.code===q$}var Z3=60000,Q3=Z3,K3=5000;function J3(X){let $=Math.max(1,Math.round(X/1000));return`Runtime has not responded for ${$} ${$===1?"second":"seconds"}. Retry the agent run.`}function y$(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.67".trim()?"0.0.67":"dev"}}function R$(X){if(X===C0)return;throw new f(`Unsupported ACP protocol version ${X}; expected ${C0}`)}function b$(X){return X3.toWeb(X)}function T$(X){return $3.toWeb(X)}function oX(X){return X!==null&&typeof X==="object"}function Y3(X){if(!Array.isArray(X))return[];let $=[];for(let Z of X){if(!oX(Z))continue;if(typeof Z.group==="string"&&Array.isArray(Z.options)){let Q=typeof Z.name==="string"?Z.name:Z.group;for(let K of Z.options){if(!oX(K))continue;if(typeof K.value!=="string"||typeof K.name!=="string")continue;$.push({value:K.value,name:K.name,description:typeof K.description==="string"?K.description:null,group:Z.group,groupName:Q})}continue}if(typeof Z.value!=="string"||typeof Z.name!=="string")continue;$.push({value:Z.value,name:Z.name,description:typeof Z.description==="string"?Z.description:null,group:null,groupName:null})}return $}function W3(X){if(!oX(X))return null;if(typeof X.id!=="string"||typeof X.name!=="string")return null;let $=typeof X.category==="string"?X.category:null,Z=typeof X.description==="string"?X.description:null;if(X.type==="select"){let Q=typeof X.currentValue==="string"?X.currentValue:null;return{id:X.id,name:X.name,category:$,description:Z,type:"select",currentValue:Q,options:Y3(X.options)}}if(X.type==="boolean"){let Q=typeof X.currentValue==="boolean"?X.currentValue:typeof X.value==="boolean"?X.value:null;return{id:X.id,name:X.name,category:$,description:Z,type:"boolean",currentValue:Q,options:[]}}return null}function nX(X){let $=(X.configOptions??[]).map(W3).filter((j)=>j!==null),Z=$.find((j)=>j.type==="select"&&j.category==="model")??$.find((j)=>j.type==="select"&&j.id==="model")??null,Q=Z?.options.map((j)=>({id:j.value,name:j.name,description:j.description??null})),K=j3(X.models),J=Q&&Q.length>0?Q:K&&K.length>0?K:null,Y=(typeof Z?.currentValue==="string"?Z.currentValue:null)??G3(X.models)??null;return{models:J,currentModelId:Y,configOptions:$,modelConfigId:Z?.id??null}}function j3(X){if(!X||!Array.isArray(X.availableModels))return null;let $=[];for(let Z of X.availableModels){if(typeof Z.modelId!=="string")continue;$.push({id:Z.modelId,name:typeof Z.name==="string"?Z.name:null,description:typeof Z.description==="string"?Z.description:null})}return $.length>0?$:null}function G3(X){return typeof X?.currentModelId==="string"?X.currentModelId:null}function V3(X,$){let Z=[];if(X.trim())Z.push({type:"text",text:X});for(let Q of $)if(Q.content.trim())Z.push({type:"text",text:Q.content});return Z}function z3(X){if(typeof X.value==="boolean")return{sessionId:X.sessionId,configId:X.configId,type:"boolean",value:X.value};return{sessionId:X.sessionId,configId:X.configId,value:X.value}}function U3(X,$){let Z=nX({configOptions:$.configOptions});return{models:Z.models??X.models,currentModelId:Z.currentModelId??X.currentModelId,configOptions:Z.configOptions,modelConfigId:Z.modelConfigId??X.modelConfigId}}function E$(X,$){if(X==="default")return null;if(!$||$.length===0)return X;let Z=$.find((W)=>W.id===X);if(Z)return Z.id;let Q=X.toLowerCase(),K=Q.includes("opus")?"opus":Q.includes("sonnet")?"sonnet":Q.includes("haiku")?"haiku":null;if(!K)return X;let J=(W)=>`${W.id} ${W.name??""} ${W.description??""}`.toLowerCase(),Y=$.filter((W)=>J(W).includes(K));if(Y.length===0)return X;let z=(Q.includes("1m")?Y.find((W)=>J(W).includes("1m")):void 0)??Y[0];return z?z.id:X}async function QX(X){try{let $=await X.conn.setSessionConfigOption(z3({sessionId:X.sessionId,configId:X.configId,value:X.value}));return U3(X.metadata,$)}catch($){return console.warn(`[acp] setSessionConfigOption(${X.label}) failed; using agent default.`,$ instanceof Error?$.message:$),X.metadata}}async function tX(X){let $=cX(X.spawn),Z=[],Q=0,K=4096;$.stderr.on("data",(A)=>{Z.push(A),Q+=A.length;while(Q>K*2&&Z.length>1){let v=Z.shift();if(v)Q-=v.length}});let J=()=>{let A=Buffer.concat(Z).toString("utf8");return A.length>K?A.slice(-K):A},Y=L$(X.spawn.cwd),j={current:null},z={current:null},W={at:Date.now()},V=null,B=T$($.stdin),L=b$($.stdout),x=C$(B,L),D=new A$((A)=>({requestPermission:async(v)=>{let R=v.options,I=R?.find((h)=>h.kind==="allow_once")??R?.find((h)=>h.kind==="allow_always");if(I)return{outcome:{outcome:"selected",optionId:I.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(v)=>{W.at=Date.now();let R=z.current;if(R){let h=v.update.sessionUpdate;if(R.updateCount+=1,R.updateCount===1||R.lastUpdateType!==h||h==="tool_call"||h==="tool_call_update")q("acp.session_update",{runId:R.runId,cardId:R.cardId,sessionId:V,updateType:h,updateCount:R.updateCount,elapsedMs:Date.now()-R.startedAt});R.lastUpdateType=h}let I=j.current;if(I)await I.onSessionUpdate(v)},readTextFile:Y.readTextFile}),x),N=()=>$.kill();if(X.signal)X.signal.addEventListener("abort",N);let H=()=>{if(X.signal)X.signal.removeEventListener("abort",N)},P=async(A,v)=>{if(H(),$.kill(),f$(A))throw new H0(A.message??"Authentication required",v);if(A instanceof Error&&A.message==="ACP connection closed"){if(X.signal?.aborted)throw new f("ACP session cancelled: abort signal received");let R=await Promise.race([$.processCrashed,$.waitForExit,new Promise((I)=>setTimeout(()=>I({stderr:""}),500))]);throw new f(`Runtime process exited before completion: ${R.stderr?.trim()??""}`)}throw A},w;try{w=await D.initialize({protocolVersion:C0,clientCapabilities:mX,clientInfo:y$()})}catch(A){throw await P(A,[]),Error("unreachable")}try{R$(w.protocolVersion)}catch(A){throw H(),$.kill(),A}let O=w.authMethods?.map((A)=>A.id)??[],C;try{C=await D.newSession({cwd:X.spawn.cwd,mcpServers:X.mcpServers??[]})}catch(A){throw await P(A,O),Error("unreachable")}let M=C.sessionId;V=M;let G=nX(C),k=X.modelId??null,_=k?E$(k,G.models):null;if(_&&_!==G.currentModelId)if(G.modelConfigId)G=await QX({conn:D,sessionId:M,configId:G.modelConfigId,value:_,metadata:G,label:`${G.modelConfigId}=${_}`});else console.warn(`[acp] runtime did not advertise a model config option for ${_}; using agent default.`);for(let[A,v]of Object.entries(X.configValues??{}).sort(([R],[I])=>R.localeCompare(I))){if(A===G.modelConfigId)continue;if(!G.configOptions.some((R)=>R.id===A))continue;G=await QX({conn:D,sessionId:M,configId:A,value:v,metadata:G,label:`${A}=${String(v)}`})}H();let b=!1,d=async()=>{if(b)return;b=!0,$.kill(),await Promise.race([$.waitForExit,new Promise((A)=>setTimeout(A,2000))])},n=!1;return $.processCrashed.then(()=>{n=!0}),{sessionId:M,availableModels:G.models,currentModelId:G.currentModelId,availableConfigOptions:G.configOptions,isAlive:()=>!b&&!n,dispose:d,prompt:(A)=>H3({proc:$,conn:D,sessionId:M,activeAdapter:j,activeTrace:z,lastUpdate:W,collectStderrTail:J},A)}}async function H3(X,$){let{proc:Z,conn:Q,sessionId:K,activeAdapter:J,activeTrace:Y,lastUpdate:j}=X,z=Date.now(),W=$.heartbeatMs??Q3,V=J3(W),B={boardId:$.boardId,cardId:$.cardId,runId:$.runId},L=k$({ctx:B,appendText:$.appendText,appendToolActivity:$.appendToolActivity});J.current=L,Y.current={runId:$.runId,cardId:$.cardId,startedAt:z,updateCount:0,lastUpdateType:null},j.at=Date.now(),q("acp.prompt_started",{runId:$.runId,cardId:$.cardId,sessionId:K,heartbeatWindowMs:W});let x=!1,U=null,D=()=>Z.kill();$.signal.addEventListener("abort",D);try{let N=async()=>{let O=Math.min(K3,Math.max(50,Math.floor(W/2)));U=setInterval(()=>{let M=$.isAwaitingInput?.()??!1;if(M){j.at=Date.now();return}if(_$({nowMs:Date.now(),lastUpdateMs:j.at,windowMs:W,awaitingInput:M}))x=!0,q("acp.inactivity_timeout",{runId:$.runId,cardId:$.cardId,sessionId:K,windowMs:W,silentForMs:Date.now()-j.at}),Q.cancel({sessionId:K}).catch(()=>{return}),Z.kill()},O);let C=V3($.prompt.systemPrompt,$.prompt.messages);await Q.prompt({sessionId:K,prompt:C}),q("acp.prompt_resolved",{runId:$.runId,cardId:$.cardId,sessionId:K,elapsedMs:Date.now()-z}),L.flush({completeOpenToolCalls:!0})},H=Z.waitForExit.then((O)=>({kind:"exited",exit:O})),P=N().then(()=>({kind:"ok"})).catch(async(O)=>{if(O instanceof Error&&O.message==="ACP connection closed")return{kind:"crashed",exit:await Promise.race([Z.processCrashed,Z.waitForExit])};throw O}),w;try{w=await Promise.race([P,Z.processCrashed.then((O)=>({kind:"crashed",exit:O})),H])}catch(O){if(x)throw new u(V);throw O}if(x)throw new u(V);if(w.kind==="crashed")throw new f(`Runtime process exited before completion: ${w.exit.stderr.trim()}`);if(w.kind==="exited"){if($.signal.aborted)throw new f("ACP session cancelled: abort signal received");if(x)throw new u(V);throw new f(`Runtime process exited unexpectedly: ${w.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:L.getFinalText(),toolCallsExecuted:L.getToolCallCount(),stderrTail:X.collectStderrTail(),updateTypeCounts:L.getUpdateTypeCounts()}}finally{if(q("acp.prompt_finished",{runId:$.runId,cardId:$.cardId,sessionId:K,elapsedMs:Date.now()-z,timedOut:x,updateCount:Y.current?.updateCount??0}),U!==null)clearInterval(U);$.signal.removeEventListener("abort",D),L.flush({completeOpenToolCalls:!0}),J.current=null,Y.current=null}}var x3=30000;async function v$(X){let $=cX(X.spawn),Z=T$($.stdin),Q=b$($.stdout),K=C$(Z,Q),Y=new A$((W)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),K),j=()=>$.kill();if(X.signal)X.signal.addEventListener("abort",j);let z=null;try{let W=(async()=>{let B=await Y.initialize({protocolVersion:C0,clientCapabilities:mX,clientInfo:y$()});R$(B.protocolVersion);let L=B.authMethods?.map((w)=>w.id)??[],x;try{x=await Y.newSession({cwd:X.spawn.cwd,mcpServers:[]})}catch(w){if(f$(w))throw new H0(w.message??"Authentication required",L);throw w}let U=nX(x),D=X.modelId??null,N=D?E$(D,U.models):null;if(N&&N!==U.currentModelId)if(U.modelConfigId)U=await QX({conn:Y,sessionId:x.sessionId,configId:U.modelConfigId,value:N,metadata:U,label:`${U.modelConfigId}=${N}`});else console.warn(`[acp] runtime did not advertise a model config option for ${N}; discovering agent default models.`);for(let[w,O]of Object.entries(X.configValues??{}).sort(([C],[M])=>C.localeCompare(M))){if(w===U.modelConfigId)continue;if(!U.configOptions.some((C)=>C.id===w))continue;U=await QX({conn:Y,sessionId:x.sessionId,configId:w,value:O,metadata:U,label:`${w}=${String(O)}`})}let H=U.models??[],P=U.currentModelId;return Y.cancel({sessionId:x.sessionId}).catch(()=>{return}),{models:H,configOptions:U.configOptions,currentModelId:P}})(),V=new Promise((B,L)=>{z=setTimeout(()=>{L(new u)},x3)});return await Promise.race([W,V])}catch(W){if(W instanceof Error&&W.message==="ACP connection closed"){if(X.signal?.aborted)throw new f("ACP model discovery cancelled: abort signal received");throw new f("Runtime process exited during model discovery.")}throw W}finally{if(z)clearTimeout(z);if(X.signal)X.signal.removeEventListener("abort",j);$.kill()}}import D3 from"node:fs/promises";import KX from"node:os";async function h$(X){let $={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},Z;try{Z=await D3.readFile(X,"utf-8")}catch(Q){if(Q.code==="ENOENT")return structuredClone($);throw Q}return m0.parse(JSON.parse(Z))}function rX(X,$,Z){return{...X.defaultConfigValues??{},...$?.configValues??{},...Z?.configValues??{}}}async function X0(X){let $=X.configPath?await h$(X.configPath):await m(),Z=X.cardId?$.cardOverrides[X.cardId]:void 0;if(Z?.runtimeConfigId){let K=$.runtimes.find((J)=>J.id===Z.runtimeConfigId);if(K)return{entry:K,adapter:a(K),runFolder:Z.runFolder??K.runFolder??KX.homedir(),modelId:Z.modelId??K.defaultModelId??null,configValues:rX(K,void 0,Z)}}let Q=$.boardOverrides[X.boardId];if(Q?.runtimeConfigId){let K=$.runtimes.find((J)=>J.id===Q.runtimeConfigId);if(K)return{entry:K,adapter:a(K),runFolder:Q.runFolder??K.runFolder??KX.homedir(),modelId:Q.modelId??K.defaultModelId??null,configValues:rX(K,Q)}}if($.globalDefaultConfigId){let K=$.runtimes.find((J)=>J.id===$.globalDefaultConfigId);if(K)return{entry:K,adapter:a(K),runFolder:Z?.runFolder??Q?.runFolder??K.runFolder??KX.homedir(),modelId:Z?.modelId??Q?.modelId??K.defaultModelId??null,configValues:rX(K,Q,Z)}}throw new Y0}async function I$(X,$={}){let Q=($.configPath?await h$($.configPath):await m()).runtimes.find((K)=>K.id===X);if(!Q)return null;return{entry:Q,adapter:a(Q),runFolder:Q.runFolder??KX.homedir(),modelId:$.modelId??Q.defaultModelId??null,configValues:{...Q.defaultConfigValues??{},...$.configValues??{}}}}var S$=new Map;function sX(X,$){if(!X)return;S$.set(X,$)}function g$(X){if(!X)return!1;return S$.get(X)??!1}var G0=new Map,eX=new Set;function $1(X){G0.get(X)?.controller.abort()}function m$(X){for(let[$,Z]of G0){if(Z.frontendSessionId!==X)continue;Z.controller.abort(),G0.delete($)}}function c$(){for(let X of G0.values())X.controller.abort();G0.clear()}function X1(X,$){if($?.aborted)return!0;return X instanceof Error&&/abort signal received|session cancelled/i.test(X.message)}function l$(X,$,Z,Q){if((!$.availableModels||$.availableModels.length===0)&&$.availableConfigOptions.length===0)return;p((K)=>{let J=K.runtimes.find((Y)=>Y.id===X);if(J){if($.availableModels&&$.availableModels.length>0)J.discoveredModels=r0({adapterId:Z,models:$.availableModels,currentModelId:$.currentModelId??Q});if($.availableConfigOptions.length>0)J.discoveredConfigOptions=$.availableConfigOptions}}).catch(()=>{return})}function N3(X,$){return`${X}
|
|
936
|
+
${$}`)}function iX(X){if(!Array.isArray(X))return null;let $=X.flatMap((Z)=>{if(!Z||typeof Z!=="object")return[];let Q=Z;if(typeof Q.path!=="string"||!Q.path.trim())return[];let W=typeof Q.line==="number"?`:${Q.line}`:"";return[`${Q.path}${W}`]});return $.length>0?$.slice(0,5):null}function q$(X){let{ctx:$,appendText:Z,appendToolActivity:Q}=X,W=X.flushIntervalMs??e6,K="",Y="",V=0,z=null,J={},G=new Map,M=(P)=>{if(G.set(P.toolCallId,P),!Q)return;Q({boardId:$.boardId,cardId:$.cardId,runId:$.runId,entry:P}).catch((j)=>{console.warn("[streamAdapter] appendToolActivity failed",j)})},L=(P)=>{let j=`${$.runId}:thought`,k=G.get(j);if(!k||k.status!=="running")return;M({...k,status:"completed",completedAt:k.completedAt??P})},x=(P)=>{for(let j of G.values()){if(j.status!=="running"||j.rawTitle.toLowerCase()!=="toolsearch")continue;M({...j,status:"completed",completedAt:j.completedAt??P})}},U=(P)=>{for(let j of Array.from(G.values())){if(j.status!=="running")continue;if(j.kind==="thought"||j.rawTitle==="agent_thought")continue;M({...j,status:"completed",completedAt:j.completedAt??P})}},D="",w=0,H=null,B=null,N=(P)=>{if(P===D)return;D=P,w=Date.now(),Z({boardId:$.boardId,cardId:$.cardId,runId:$.runId,text:P}).catch((j)=>{console.warn("[streamAdapter] appendText failed",j)})},O=()=>{if(H!==null)clearTimeout(H),H=null;if(B!==null){let P=B;B=null,N(P)}},C=(P)=>{let j=Date.now()-w;if(j>=W&&H===null){N(P);return}if(B=P,H===null){let k=Math.max(0,W-j);H=setTimeout(()=>{H=null,O()},k)}};return{onSessionUpdate:async(P)=>{let j=P.update;switch(J[j.sessionUpdate]=(J[j.sessionUpdate]??0)+1,j.sessionUpdate){case"agent_message_chunk":{let k=new Date().toISOString();if(L(k),j.content.type==="text")K+=j.content.text,C(K);else{let _=`agent_message_chunk:${j.content.type}`;J[_]=(J[_]??0)+1}return}case"agent_thought_chunk":{if(j.content.type!=="text")return;Y+=j.content.text;let k=new Date().toISOString(),_=`${$.runId}:thought`,b=G.get(_);M({toolCallId:_,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:b?.startedAt??k,completedAt:null,contentPreview:V0(Y.trim())});return}case"user_message_chunk":return;case"tool_call":{V+=1;let k=F$(j.title),_=pX(j.status),b=new Date().toISOString();L(b),x(b),M({toolCallId:j.toolCallId,rawTitle:k,title:aX(k,j.rawInput),kind:uX(j.kind),status:_,startedAt:b,completedAt:_==="running"?null:b,inputPreview:o(j.rawInput),outputPreview:dX(j.rawOutput),contentPreview:ZX(j.content),locations:iX(j.locations)});return}case"tool_call_update":{let k=G.get(j.toolCallId);if(!k){let y=F$(j.title),I=pX(j.status),h=new Date().toISOString();M({toolCallId:j.toolCallId,rawTitle:y,title:aX(y,j.rawInput),kind:uX(j.kind),status:I,startedAt:h,completedAt:I==="running"?null:h,inputPreview:o(j.rawInput),outputPreview:dX(j.rawOutput),contentPreview:ZX(j.content),locations:iX(j.locations)});return}let _=j.status===void 0||j.status===null?k.status:pX(j.status),b=typeof j.title==="string"&&j.title.trim().length>0?j.title:k.rawTitle,d=typeof j.title==="string"&&j.title.trim().length>0,n=_==="running"?k.completedAt:k.completedAt??new Date().toISOString(),A=j.content===void 0?k.contentPreview:k$(k.contentPreview,ZX(j.content)),v=j.rawOutput===void 0?k.outputPreview:k$(k.outputPreview,dX(j.rawOutput));M({...k,rawTitle:b,title:d?aX(b,j.rawInput):k.title,kind:j.kind===void 0?k.kind:uX(j.kind),status:_,completedAt:n,inputPreview:j.rawInput===void 0?k.inputPreview:o(j.rawInput),outputPreview:v,contentPreview:A,locations:j.locations===void 0?k.locations:iX(j.locations)});return}case"plan":z=j.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>K,getToolCallCount:()=>V,getLatestPlan:()=>z,getUpdateTypeCounts:()=>({...J}),flush:(P)=>{let j=new Date().toISOString();if(L(j),P?.completeOpenToolCalls)U(j);O()}}}var A0=1,_$=-32000;function A$(X){if(X.awaitingInput)return!1;return X.nowMs-X.lastUpdateMs>=X.windowMs}function f$(X){if(!X||typeof X!=="object")return!1;return X.code===_$}var Q3=60000,W3=Q3,K3=5000;function Y3(X){let $=Math.max(1,Math.round(X/1000));return`Runtime has not responded for ${$} ${$===1?"second":"seconds"}. Retry the agent run.`}function y$(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.68".trim()?"0.0.68":"dev"}}function b$(X){if(X===A0)return;throw new R(`Unsupported ACP protocol version ${X}; expected ${A0}`)}function E$(X){return $3.toWeb(X)}function T$(X){return Z3.toWeb(X)}function oX(X){return X!==null&&typeof X==="object"}function J3(X){if(!Array.isArray(X))return[];let $=[];for(let Z of X){if(!oX(Z))continue;if(typeof Z.group==="string"&&Array.isArray(Z.options)){let Q=typeof Z.name==="string"?Z.name:Z.group;for(let W of Z.options){if(!oX(W))continue;if(typeof W.value!=="string"||typeof W.name!=="string")continue;$.push({value:W.value,name:W.name,description:typeof W.description==="string"?W.description:null,group:Z.group,groupName:Q})}continue}if(typeof Z.value!=="string"||typeof Z.name!=="string")continue;$.push({value:Z.value,name:Z.name,description:typeof Z.description==="string"?Z.description:null,group:null,groupName:null})}return $}function V3(X){if(!oX(X))return null;if(typeof X.id!=="string"||typeof X.name!=="string")return null;let $=typeof X.category==="string"?X.category:null,Z=typeof X.description==="string"?X.description:null;if(X.type==="select"){let Q=typeof X.currentValue==="string"?X.currentValue:null;return{id:X.id,name:X.name,category:$,description:Z,type:"select",currentValue:Q,options:J3(X.options)}}if(X.type==="boolean"){let Q=typeof X.currentValue==="boolean"?X.currentValue:typeof X.value==="boolean"?X.value:null;return{id:X.id,name:X.name,category:$,description:Z,type:"boolean",currentValue:Q,options:[]}}return null}function nX(X){let $=(X.configOptions??[]).map(V3).filter((V)=>V!==null),Z=$.find((V)=>V.type==="select"&&V.category==="model")??$.find((V)=>V.type==="select"&&V.id==="model")??null,Q=Z?.options.map((V)=>({id:V.value,name:V.name,description:V.description??null})),W=j3(X.models),K=Q&&Q.length>0?Q:W&&W.length>0?W:null,Y=(typeof Z?.currentValue==="string"?Z.currentValue:null)??G3(X.models)??null;return{models:K,currentModelId:Y,configOptions:$,modelConfigId:Z?.id??null}}function j3(X){if(!X||!Array.isArray(X.availableModels))return null;let $=[];for(let Z of X.availableModels){if(typeof Z.modelId!=="string")continue;$.push({id:Z.modelId,name:typeof Z.name==="string"?Z.name:null,description:typeof Z.description==="string"?Z.description:null})}return $.length>0?$:null}function G3(X){return typeof X?.currentModelId==="string"?X.currentModelId:null}function z3(X,$){let Z=[];if(X.trim())Z.push({type:"text",text:X});for(let Q of $)if(Q.content.trim())Z.push({type:"text",text:Q.content});return Z}function U3(X){if(typeof X.value==="boolean")return{sessionId:X.sessionId,configId:X.configId,type:"boolean",value:X.value};return{sessionId:X.sessionId,configId:X.configId,value:X.value}}function H3(X,$){let Z=nX({configOptions:$.configOptions});return{models:Z.models??X.models,currentModelId:Z.currentModelId??X.currentModelId,configOptions:Z.configOptions,modelConfigId:Z.modelConfigId??X.modelConfigId}}function v$(X,$){if(X==="default")return null;if(!$||$.length===0)return X;let Z=$.find((J)=>J.id===X);if(Z)return Z.id;let Q=X.toLowerCase(),W=Q.includes("opus")?"opus":Q.includes("sonnet")?"sonnet":Q.includes("haiku")?"haiku":null;if(!W)return X;let K=(J)=>`${J.id} ${J.name??""} ${J.description??""}`.toLowerCase(),Y=$.filter((J)=>K(J).includes(W));if(Y.length===0)return X;let z=(Q.includes("1m")?Y.find((J)=>K(J).includes("1m")):void 0)??Y[0];return z?z.id:X}async function WX(X){try{let $=await X.conn.setSessionConfigOption(U3({sessionId:X.sessionId,configId:X.configId,value:X.value}));return H3(X.metadata,$)}catch($){return console.warn(`[acp] setSessionConfigOption(${X.label}) failed; using agent default.`,$ instanceof Error?$.message:$),X.metadata}}async function tX(X){let $=cX(X.spawn),Z=[],Q=0,W=4096;$.stderr.on("data",(A)=>{Z.push(A),Q+=A.length;while(Q>W*2&&Z.length>1){let v=Z.shift();if(v)Q-=v.length}});let K=()=>{let A=Buffer.concat(Z).toString("utf8");return A.length>W?A.slice(-W):A},Y=B$(X.spawn.cwd),V={current:null},z={current:null},J={at:Date.now()},G=null,M=T$($.stdin),L=E$($.stdout),x=R$(M,L),D=new C$((A)=>({requestPermission:async(v)=>{let y=v.options,I=y?.find((h)=>h.kind==="allow_once")??y?.find((h)=>h.kind==="allow_always");if(I)return{outcome:{outcome:"selected",optionId:I.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(v)=>{J.at=Date.now();let y=z.current;if(y){let h=v.update.sessionUpdate;if(y.updateCount+=1,y.updateCount===1||y.lastUpdateType!==h||h==="tool_call"||h==="tool_call_update")q("acp.session_update",{runId:y.runId,cardId:y.cardId,sessionId:G,updateType:h,updateCount:y.updateCount,elapsedMs:Date.now()-y.startedAt});y.lastUpdateType=h}let I=V.current;if(I)await I.onSessionUpdate(v)},readTextFile:Y.readTextFile}),x),w=()=>$.kill();if(X.signal)X.signal.addEventListener("abort",w);let H=()=>{if(X.signal)X.signal.removeEventListener("abort",w)},B=async(A,v)=>{if(H(),$.kill(),f$(A))throw new H0(A.message??"Authentication required",v);if(A instanceof Error&&A.message==="ACP connection closed"){if(X.signal?.aborted)throw new R("ACP session cancelled: abort signal received");let y=await Promise.race([$.processCrashed,$.waitForExit,new Promise((I)=>setTimeout(()=>I({stderr:""}),500))]);throw new R(`Runtime process exited before completion: ${y.stderr?.trim()??""}`)}throw A},N;try{N=await D.initialize({protocolVersion:A0,clientCapabilities:mX,clientInfo:y$()})}catch(A){throw await B(A,[]),Error("unreachable")}try{b$(N.protocolVersion)}catch(A){throw H(),$.kill(),A}let O=N.authMethods?.map((A)=>A.id)??[],C;try{C=await D.newSession({cwd:X.spawn.cwd,mcpServers:X.mcpServers??[]})}catch(A){throw await B(A,O),Error("unreachable")}let P=C.sessionId;G=P;let j=nX(C),k=X.modelId??null,_=k?v$(k,j.models):null;if(_&&_!==j.currentModelId)if(j.modelConfigId)j=await WX({conn:D,sessionId:P,configId:j.modelConfigId,value:_,metadata:j,label:`${j.modelConfigId}=${_}`});else console.warn(`[acp] runtime did not advertise a model config option for ${_}; using agent default.`);for(let[A,v]of Object.entries(X.configValues??{}).sort(([y],[I])=>y.localeCompare(I))){if(A===j.modelConfigId)continue;if(!j.configOptions.some((y)=>y.id===A))continue;j=await WX({conn:D,sessionId:P,configId:A,value:v,metadata:j,label:`${A}=${String(v)}`})}H();let b=!1,d=async()=>{if(b)return;b=!0,$.kill(),await Promise.race([$.waitForExit,new Promise((A)=>setTimeout(A,2000))])},n=!1;return $.processCrashed.then(()=>{n=!0}),{sessionId:P,availableModels:j.models,currentModelId:j.currentModelId,availableConfigOptions:j.configOptions,isAlive:()=>!b&&!n,dispose:d,prompt:(A)=>x3({proc:$,conn:D,sessionId:P,activeAdapter:V,activeTrace:z,lastUpdate:J,collectStderrTail:K},A)}}async function x3(X,$){let{proc:Z,conn:Q,sessionId:W,activeAdapter:K,activeTrace:Y,lastUpdate:V}=X,z=Date.now(),J=$.heartbeatMs??W3,G=Y3(J),M={boardId:$.boardId,cardId:$.cardId,runId:$.runId},L=q$({ctx:M,appendText:$.appendText,appendToolActivity:$.appendToolActivity});K.current=L,Y.current={runId:$.runId,cardId:$.cardId,startedAt:z,updateCount:0,lastUpdateType:null},V.at=Date.now(),q("acp.prompt_started",{runId:$.runId,cardId:$.cardId,sessionId:W,heartbeatWindowMs:J});let x=!1,U=null,D=()=>Z.kill();$.signal.addEventListener("abort",D);try{let w=async()=>{let O=Math.min(K3,Math.max(50,Math.floor(J/2)));U=setInterval(()=>{let P=$.isAwaitingInput?.()??!1;if(P){V.at=Date.now();return}if(A$({nowMs:Date.now(),lastUpdateMs:V.at,windowMs:J,awaitingInput:P}))x=!0,q("acp.inactivity_timeout",{runId:$.runId,cardId:$.cardId,sessionId:W,windowMs:J,silentForMs:Date.now()-V.at}),Q.cancel({sessionId:W}).catch(()=>{return}),Z.kill()},O);let C=z3($.prompt.systemPrompt,$.prompt.messages);await Q.prompt({sessionId:W,prompt:C}),q("acp.prompt_resolved",{runId:$.runId,cardId:$.cardId,sessionId:W,elapsedMs:Date.now()-z}),L.flush({completeOpenToolCalls:!0})},H=Z.waitForExit.then((O)=>({kind:"exited",exit:O})),B=w().then(()=>({kind:"ok"})).catch(async(O)=>{if(O instanceof Error&&O.message==="ACP connection closed")return{kind:"crashed",exit:await Promise.race([Z.processCrashed,Z.waitForExit])};throw O}),N;try{N=await Promise.race([B,Z.processCrashed.then((O)=>({kind:"crashed",exit:O})),H])}catch(O){if(x)throw new u(G);throw O}if(x)throw new u(G);if(N.kind==="crashed")throw new R(`Runtime process exited before completion: ${N.exit.stderr.trim()}`);if(N.kind==="exited"){if($.signal.aborted)throw new R("ACP session cancelled: abort signal received");if(x)throw new u(G);throw new R(`Runtime process exited unexpectedly: ${N.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:L.getFinalText(),toolCallsExecuted:L.getToolCallCount(),stderrTail:X.collectStderrTail(),updateTypeCounts:L.getUpdateTypeCounts()}}finally{if(q("acp.prompt_finished",{runId:$.runId,cardId:$.cardId,sessionId:W,elapsedMs:Date.now()-z,timedOut:x,updateCount:Y.current?.updateCount??0}),U!==null)clearInterval(U);$.signal.removeEventListener("abort",D),L.flush({completeOpenToolCalls:!0}),K.current=null,Y.current=null}}var D3=30000;async function h$(X){let $=cX(X.spawn),Z=T$($.stdin),Q=E$($.stdout),W=R$(Z,Q),Y=new C$((J)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),W),V=()=>$.kill();if(X.signal)X.signal.addEventListener("abort",V);let z=null;try{let J=(async()=>{let M=await Y.initialize({protocolVersion:A0,clientCapabilities:mX,clientInfo:y$()});b$(M.protocolVersion);let L=M.authMethods?.map((N)=>N.id)??[],x;try{x=await Y.newSession({cwd:X.spawn.cwd,mcpServers:[]})}catch(N){if(f$(N))throw new H0(N.message??"Authentication required",L);throw N}let U=nX(x),D=X.modelId??null,w=D?v$(D,U.models):null;if(w&&w!==U.currentModelId)if(U.modelConfigId)U=await WX({conn:Y,sessionId:x.sessionId,configId:U.modelConfigId,value:w,metadata:U,label:`${U.modelConfigId}=${w}`});else console.warn(`[acp] runtime did not advertise a model config option for ${w}; discovering agent default models.`);for(let[N,O]of Object.entries(X.configValues??{}).sort(([C],[P])=>C.localeCompare(P))){if(N===U.modelConfigId)continue;if(!U.configOptions.some((C)=>C.id===N))continue;U=await WX({conn:Y,sessionId:x.sessionId,configId:N,value:O,metadata:U,label:`${N}=${String(O)}`})}let H=U.models??[],B=U.currentModelId;return Y.cancel({sessionId:x.sessionId}).catch(()=>{return}),{models:H,configOptions:U.configOptions,currentModelId:B}})(),G=new Promise((M,L)=>{z=setTimeout(()=>{L(new u)},D3)});return await Promise.race([J,G])}catch(J){if(J instanceof Error&&J.message==="ACP connection closed"){if(X.signal?.aborted)throw new R("ACP model discovery cancelled: abort signal received");throw new R("Runtime process exited during model discovery.")}throw J}finally{if(z)clearTimeout(z);if(X.signal)X.signal.removeEventListener("abort",V);$.kill()}}import w3 from"node:fs/promises";import KX from"node:os";async function I$(X){let $={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},Z;try{Z=await w3.readFile(X,"utf-8")}catch(Q){if(Q.code==="ENOENT")return structuredClone($);throw Q}return c0.parse(JSON.parse(Z))}function rX(X,$,Z){return{...X.defaultConfigValues??{},...$?.configValues??{},...Z?.configValues??{}}}async function X0(X){let $=X.configPath?await I$(X.configPath):await m(),Z=X.cardId?$.cardOverrides[X.cardId]:void 0;if(Z?.runtimeConfigId){let W=$.runtimes.find((K)=>K.id===Z.runtimeConfigId);if(W)return{entry:W,adapter:a(W),runFolder:Z.runFolder??W.runFolder??KX.homedir(),modelId:Z.modelId??W.defaultModelId??null,configValues:rX(W,void 0,Z)}}let Q=$.boardOverrides[X.boardId];if(Q?.runtimeConfigId){let W=$.runtimes.find((K)=>K.id===Q.runtimeConfigId);if(W)return{entry:W,adapter:a(W),runFolder:Q.runFolder??W.runFolder??KX.homedir(),modelId:Q.modelId??W.defaultModelId??null,configValues:rX(W,Q)}}if($.globalDefaultConfigId){let W=$.runtimes.find((K)=>K.id===$.globalDefaultConfigId);if(W)return{entry:W,adapter:a(W),runFolder:Z?.runFolder??Q?.runFolder??W.runFolder??KX.homedir(),modelId:Z?.modelId??Q?.modelId??W.defaultModelId??null,configValues:rX(W,Q,Z)}}throw new Y0}async function S$(X,$={}){let Q=($.configPath?await I$($.configPath):await m()).runtimes.find((W)=>W.id===X);if(!Q)return null;return{entry:Q,adapter:a(Q),runFolder:Q.runFolder??KX.homedir(),modelId:$.modelId??Q.defaultModelId??null,configValues:{...Q.defaultConfigValues??{},...$.configValues??{}}}}var g$=new Map;function sX(X,$){if(!X)return;g$.set(X,$)}function m$(X){if(!X)return!1;return g$.get(X)??!1}var j0=new Map,eX=new Set;function $1(X){j0.get(X)?.controller.abort()}function c$(X){for(let[$,Z]of j0){if(Z.frontendSessionId!==X)continue;Z.controller.abort(),j0.delete($)}}function l$(){for(let X of j0.values())X.controller.abort();j0.clear()}function X1(X,$){if($?.aborted)return!0;return X instanceof Error&&/abort signal received|session cancelled/i.test(X.message)}function p$(X,$,Z,Q){if((!$.availableModels||$.availableModels.length===0)&&$.availableConfigOptions.length===0)return;p((W)=>{let K=W.runtimes.find((Y)=>Y.id===X);if(K){if($.availableModels&&$.availableModels.length>0)K.discoveredModels=s0({adapterId:Z,models:$.availableModels,currentModelId:$.currentModelId??Q});if($.availableConfigOptions.length>0)K.discoveredConfigOptions=$.availableConfigOptions}}).catch(()=>{return})}function N3(X,$){return`${X}
|
|
937
937
|
|
|
938
938
|
Runtime run folder:
|
|
939
939
|
- Effective run folder: ${$}
|
|
940
940
|
- When the user says "my folder", "current folder", or "run folder", they mean this selected runtime folder.
|
|
941
941
|
- 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.
|
|
942
|
-
- Filesystem access is read-only and limited to this folder. Hidden/config folders and outside-folder paths are unavailable.`}async function p$(X,$){let Z=Date.now(),Q=new AbortController;G0.set(X.runId,{controller:Q,frontendSessionId:X.frontendSessionId}),eX.add(X.cardId),q("cli.run_started",{runId:X.runId,cardId:X.cardId,frontendSessionId:X.frontendSessionId});let K=DX(X.userId,X.frontendSessionId,X.cardId),J=!1,Y=null;try{let z=(X.runtimeConfigIdHint?await I$(X.runtimeConfigIdHint,{modelId:X.modelHint??null}):null)??await X0({boardId:X.boardId,cardId:X.cardId}),W=await z.adapter.resolveSpawnConfig(z.entry),V=X.toolSurface??"full",B=z.adapter.supportsImages===!0;Y=W;let L=BX({userId:X.userId,frontendSessionId:X.frontendSessionId,boardId:X.boardId,toolSurface:V,imagesSupported:B,cardId:X.cardId,runFolder:z.runFolder}),x=L?[L]:[];sX(X.cardId,B);let U=X.modelHint??z.modelId,D=wX({adapterId:z.adapter.id,configId:z.entry.id,modelId:U,configValues:z.configValues,mcpUrl:L?.url??null,runFolder:z.runFolder,toolSurface:V});q("cli.session_acquire_started",{runId:X.runId,cardId:X.cardId,frontendSessionId:X.frontendSessionId});let N=await h0({key:K,frontendSessionId:X.frontendSessionId,fingerprint:D,open:()=>tX({spawn:{...W,cwd:z.runFolder},mcpServers:x,modelId:U,configValues:z.configValues,signal:Q.signal})});q("cli.session_acquired",{runId:X.runId,cardId:X.cardId,frontendSessionId:X.frontendSessionId,elapsedMs:Date.now()-Z}),l$(z.entry.id,N,z.adapter.id,U);let H;try{let P=0,w="";q("cli.prompt_started",{runId:X.runId,cardId:X.cardId,elapsedMs:Date.now()-Z}),H=await N.prompt({runId:X.runId,boardId:X.boardId,cardId:X.cardId,prompt:{systemPrompt:N3(X.systemPrompt,z.runFolder),messages:X.promptMessages.map((O)=>({role:O.role,content:O.content}))},signal:Q.signal,appendText:async({text:O})=>{if(P+=1,P===1)q("cli.first_partial_text_forwarded",{runId:X.runId,cardId:X.cardId,elapsedMs:Date.now()-Z,textLength:O.length});$({type:"partial_text",runId:X.runId,cardId:X.cardId,text:O})},appendToolActivity:async({entry:O})=>{let C=`${O.toolCallId}:${O.status}`;if(C!==w)w=C,q("cli.tool_activity_forwarded",{runId:X.runId,cardId:X.cardId,toolCallId:O.toolCallId,toolStatus:O.status,elapsedMs:Date.now()-Z});$({type:"tool_activity",runId:X.runId,cardId:X.cardId,activity:O})}})}catch(P){if(!N.isAlive()||P instanceof f||P instanceof u)J=!0;throw P}$({type:"run_settled",runId:X.runId,cardId:X.cardId,result:{assistantContent:H.finalText,model:H.modelReported??null,latencyMs:Date.now()-Z,errorText:null,partialText:null}}),q("cli.run_settled",{runId:X.runId,cardId:X.cardId,elapsedMs:Date.now()-Z,hasError:!1})}catch(j){let z=j instanceof Error?j.message:"Agent run failed";if(j instanceof f&&Y&&!X1(j,Q.signal))CX(Y,z);if(!X1(j,Q.signal))console.error(`[ideawave-cli] run ${X.runId} failed:`,z);$({type:"run_settled",runId:X.runId,cardId:X.cardId,result:{assistantContent:"",model:null,latencyMs:Date.now()-Z,errorText:z,partialText:null}}),q("cli.run_settled",{runId:X.runId,cardId:X.cardId,elapsedMs:Date.now()-Z,hasError:!0,errorName:j instanceof Error?j.name:"unknown"})}finally{NX(K,J),G0.delete(X.runId),eX.delete(X.cardId),q("cli.run_released",{runId:X.runId,cardId:X.cardId,elapsedMs:Date.now()-Z,sessionDead:J})}}async function u$(X){if(eX.has(X.cardId))return{status:"skipped"};let $=DX(X.userId,X.frontendSessionId,X.cardId),Z=null;try{let Q=await X0({boardId:X.boardId,cardId:X.cardId}),K=await Q.adapter.resolveSpawnConfig(Q.entry);Z=K;let J=BX({userId:X.userId,frontendSessionId:X.frontendSessionId,boardId:X.boardId,cardId:X.cardId,runFolder:Q.runFolder}),Y=J?[J]:[];sX(X.cardId,Q.adapter.supportsImages===!0);let j=wX({adapterId:Q.adapter.id,configId:Q.entry.id,modelId:Q.modelId,configValues:Q.configValues,mcpUrl:J?.url??null,runFolder:Q.runFolder}),z=new AbortController,W=await h0({key:$,frontendSessionId:X.frontendSessionId,fingerprint:j,open:()=>tX({spawn:{...K,cwd:Q.runFolder},mcpServers:Y,modelId:Q.modelId,configValues:Q.configValues,signal:z.signal})});return l$(Q.entry.id,W,Q.adapter.id,Q.modelId),NX($,!1),console.log(`[ideawave-cli] warmed runtime for card ${X.cardId}`),{status:"ready"}}catch(Q){if(Q instanceof Y0)return{status:"skipped"};let K=Q instanceof Error?Q.message:String(Q);if(Q instanceof f&&Z&&!X1(Q))CX(Z,K);if(Q instanceof f&&/(not ready|installing|warming|retry in a moment)/i.test(K))return{status:"retryable",error:K};return console.warn(`[ideawave-cli] warmup failed for card ${X.cardId}:`,K),{status:"failed",error:K}}}import{chromium as y3}from"playwright-core";import{spawn as w3}from"node:child_process";import{existsSync as f0,readFileSync as B3}from"node:fs";import{createRequire as a$}from"node:module";import JX from"node:os";import E from"node:path";var $0={phase:"checking"},w0=null,Z1=0,M3=60000,L3=["install","--only-shell","chromium"];class y0 extends Error{constructor(){super("The lightweight screenshot engine is being installed in the background. Live browsing remains available; retry the screenshot shortly.");this.name="CaptureEngineInstallingError"}}class d$ extends Error{constructor(X){super(X?`The screenshot engine could not be installed: ${X}`:"The screenshot engine is unavailable. Retry after checking network access and disk space.");this.name="CaptureEngineUnavailableError"}}function P3(X){return X.phase==="failed"?new d$(X.error):new y0}function B0(){return{...$0}}function F3(X){let $=X.exists??f0;for(let[Z,Q]of[[X.override,"explicit"],[X.managedShell,"headless-shell"],[X.system,"system-chromium"]])if(Z&&$(Z))return{path:Z,engine:Q};return null}function i$(X,$){let Z=[],Q=$.IDEAWAVE_CAPTURE_EXECUTABLE_PATH??$.IDEAWAVE_CHROMIUM_PATH;if(Q)Z.push(Q);if(X==="win32"){let K=$.ProgramFiles??"C:\\Program Files",J=$["ProgramFiles(x86)"]??"C:\\Program Files (x86)";if(Z.push(E.win32.join(K,"Google\\Chrome\\Application\\chrome.exe"),E.win32.join(J,"Google\\Chrome\\Application\\chrome.exe")),$.LOCALAPPDATA)Z.push(E.win32.join($.LOCALAPPDATA,"Google\\Chrome\\Application\\chrome.exe"));Z.push(E.win32.join(J,"Microsoft\\Edge\\Application\\msedge.exe"),E.win32.join(K,"Microsoft\\Edge\\Application\\msedge.exe"))}else if(X==="darwin")Z.push("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge","/Applications/Chromium.app/Contents/MacOS/Chromium","google-chrome","chromium");else Z.push("google-chrome","google-chrome-stable","chromium","chromium-browser","msedge");return Z}function O3(X){let $=(process.env.PATH??"").split(E.delimiter),Z=process.platform==="win32"?[".exe",".cmd",".bat",""]:[""];for(let Q of $){if(!Q)continue;for(let K of Z){let J=E.join(Q,`${X}${K}`);if(f0(J))return J}}return null}function k3(){let X=new Set([process.env.IDEAWAVE_CAPTURE_EXECUTABLE_PATH,process.env.IDEAWAVE_CHROMIUM_PATH]);for(let $ of i$(process.platform,process.env)){if(X.has($))continue;if(E.isAbsolute($)){if(f0($))return $}else{let Z=O3($);if(Z)return Z}}return null}function q3(){try{let X=a$(import.meta.url);return E.dirname(X.resolve("playwright-core/package.json"))}catch{return null}}function _3(X){let $=process.env.PLAYWRIGHT_BROWSERS_PATH?.trim();if($==="0")return E.join(X,".local-browsers");if($)return $.startsWith("~")?E.join(JX.homedir(),$.slice(1)):E.resolve($);if(process.platform==="win32")return E.join(process.env.LOCALAPPDATA??E.join(JX.homedir(),"AppData","Local"),"ms-playwright");if(process.platform==="darwin")return E.join(JX.homedir(),"Library","Caches","ms-playwright");return E.join(JX.homedir(),".cache","ms-playwright")}function A3(){if(process.platform==="win32")return"win64";if(process.platform==="darwin")return process.arch==="arm64"?"mac-arm64":"mac-x64";return process.arch==="arm64"?"linux-arm64":"linux64"}function Q1(){let X=q3();if(!X)return null;try{let Z=JSON.parse(B3(E.join(X,"browsers.json"),"utf8")).browsers?.find((j)=>j.name==="chromium-headless-shell");if(!Z?.revision)return null;let Q=A3(),K=Z.revisionOverrides?.[Q]??Z.revision,J=E.join(_3(X),`chromium_headless_shell-${K}`),Y=process.platform==="win32"?["chrome-headless-shell-win64/chrome-headless-shell.exe","chrome-headless-shell-win32/chrome-headless-shell.exe"]:process.platform==="darwin"?[`chrome-headless-shell-${Q}/chrome-headless-shell`,"chrome-headless-shell-mac-x64/chrome-headless-shell","chrome-headless-shell-mac-arm64/chrome-headless-shell"]:[`chrome-headless-shell-${Q}/chrome-headless-shell`,"chrome-headless-shell-linux64/chrome-headless-shell"];for(let j of Y){let z=E.join(J,...j.split("/"));if(f0(z))return z}}catch{return null}return null}function C3(){let X=process.env.IDEAWAVE_CAPTURE_EXECUTABLE_PATH??process.env.IDEAWAVE_CHROMIUM_PATH;return X&&f0(X)?X:null}function o$(){return F3({override:C3(),managedShell:Q1(),system:k3()})}function f3(){let $=a$(import.meta.url).resolve("playwright-core/package.json"),Z=E.join(E.dirname($),"cli.js");return new Promise((Q,K)=>{let J=w3(process.execPath,[Z,...L3],{stdio:"ignore",windowsHide:!0});J.once("error",K),J.once("exit",(Y)=>{if(Y===0)Q();else K(Error(`Playwright headless-shell installer exited with code ${Y}`))})})}function K1(X){let $=Q1();if($)return $0={phase:"ready",engine:"headless-shell",executablePath:$},Promise.resolve(B0());if(w0)return w0;if(Z1>0&&Date.now()-Z1<M3)return Promise.resolve(B0());return $0=X?{phase:"ready",engine:X.engine,executablePath:X.path,installingManagedShell:!0}:{phase:"installing",installingManagedShell:!0},w0=(async()=>{try{await f3();let Z=Q1();if(!Z)throw Error("Headless Shell finished installing but its executable was not found");$0={phase:"ready",engine:"headless-shell",executablePath:Z}}catch(Z){Z1=Date.now(),$0=X?{phase:"ready",engine:X.engine,executablePath:X.path,error:Z instanceof Error?Z.message:String(Z)}:{phase:"failed",error:Z instanceof Error?Z.message:String(Z)}}finally{w0=null}return B0()})(),w0}function n$(){let X=o$();if(X?.engine==="explicit"||X?.engine==="headless-shell")return $0={phase:"ready",engine:X.engine,executablePath:X.path},Promise.resolve(B0());return K1(X)}async function t$(){let X=o$();if(X){if($0={phase:"ready",engine:X.engine,executablePath:X.path,...X.engine==="system-chromium"&&w0?{installingManagedShell:!0}:{}},X.engine==="system-chromium")K1(X);return X.path}throw K1(null),P3($0)}var R3=60000,b3=16,V0=null,YX=null,M0=null,J1=Promise.resolve(),WX=0,Y1=0,T3=0;class jX extends Error{constructor(){super("The capture queue is busy; retry shortly.");this.name="CaptureQueueFullError"}}function W1(){if(M0)clearTimeout(M0);M0=null}async function j1(){W1();let X=V0;if(V0=null,YX=null,X)await X.close().catch(()=>{return})}function E3(X=R3){W1(),M0=setTimeout(()=>{if(M0=null,Y1===0&&WX===0)j1()},X),M0.unref?.()}async function v3(){let X=await t$();if(V0?.isConnected()&&YX===X)return V0;await j1();let $=await y3.launch({headless:!0,executablePath:X,handleSIGHUP:!1,handleSIGINT:!1,handleSIGTERM:!1});return T3+=1,V0=$,YX=X,$.on("disconnected",()=>{if(V0===$)V0=null,YX=null}),$}function r$(X,$){if(WX>=b3)return Promise.reject(new jX);WX+=1;let Z,Q,K=new Promise((J,Y)=>{Z=J,Q=Y});return J1=J1.then(async()=>{WX-=1,Y1+=1,W1();let J=null,Y;try{J=await(await v3()).newContext(X.context);let z=await J.newPage();Y={ok:!0,value:await $(z)}}catch(j){Y={ok:!1,error:j}}finally{if(J)await J.close().catch(()=>{return});Y1-=1,E3()}if(Y.ok)Z(Y.value);else Q(Y.error)}),K}async function s$(){await J1.catch(()=>{return}),await j1()}import{randomUUID as u3}from"node:crypto";import{createServer as a3}from"node:http";import{WebSocket as W2,WebSocketServer as d3}from"ws";var G1="/cli-bridge",e$="/ping";function V1(X=43275,$=43277){let Z=[];for(let Q=X;Q<=$;Q+=1)Z.push(Q);return Z}function X2(X=V1(),$="127.0.0.1",Z="/cli-bridge"){return X.map((Q)=>`ws://${$}:${Q}${Z}`)}var h3=800;function $2({candidates:X,createWebSocket:$,timeoutMs:Z=h3,maxConcurrent:Q=1,staggerMs:K=0,setTimeoutFn:J=setTimeout,clearTimeoutFn:Y=clearTimeout}){return new Promise((j,z)=>{let W=0,V=!1,B=null,L=new Map,x=Math.max(1,Math.floor(Q)),U=()=>{if(B===null)return;Y(B),B=null},D=(M)=>{let{socket:G,listeners:k,timer:_}=M;G.removeEventListener("open",k.open),G.removeEventListener("message",k.message),G.removeEventListener("error",k.error),G.removeEventListener("close",k.close),Y(_),L.delete(G)},N=(M)=>{U();for(let G of Array.from(L.values()))if(D(G),G.socket!==M)try{G.socket.close()}catch{}},H=()=>{if(V)return;if(W<X.length)return;if(L.size>0)return;if(B!==null)return;V=!0,z(Error("No IdeaWave CLI bridge is reachable"))},P=(M)=>{if(V)return;if(W>=X.length){H();return}if(L.size>=x)return;if(M<=0){U(),C();return}if(B!==null)return;B=J(()=>{B=null,C()},M)},w=()=>{if(V)return;if(L.size>=x)return;if(L.size===0||K<=0||x===1){P(0);return}P(K)},O=(M)=>{if(V)return;let G=L.get(M);if(!G)return;D(G);try{M.close()}catch{}w(),H()};function C(){if(V)return;if(L.size>=x)return;let M=X[W];if(W+=1,!M){H();return}let G;try{G=$(M)}catch{w(),H();return}let k={open:()=>{if(V||!L.has(G))return;G.send(g0({type:"bridge_probe",protocolVersion:1}))},message:(b)=>{if(V||!L.has(G))return;if(S0(String(b?.data??""))?.type!=="bridge_probe_ack")return;V=!0,N(G),j({url:M,socket:G})},error:()=>O(G),close:()=>O(G)};G.addEventListener("open",k.open),G.addEventListener("message",k.message),G.addEventListener("error",k.error),G.addEventListener("close",k.close);let _=J(()=>O(G),Z);L.set(G,{url:M,socket:G,listeners:k,timer:_}),w()}C()})}import{randomBytes as I3}from"node:crypto";import{mkdir as S3,writeFile as g3}from"node:fs/promises";import m3 from"node:os";import Z2 from"node:path";var c3=30000,l3=1024;function Q2(X){let $;try{$=new URL(X)}catch{return!1}if($.protocol!=="http:"&&$.protocol!=="https:")return!1;let Z=$.hostname.toLowerCase().replace(/^\[|\]$/g,"");if(Z==="localhost"||Z==="127.0.0.1"||Z==="::1")return!0;let K=Z==="ideawave.app"||Z.endsWith(".ideawave.app");return $.protocol==="https:"&&K&&$.pathname.startsWith("/static_boards/")}async function p3(X,$){let Z=Z2.join(m3.tmpdir(),"ideawave-screenshots");await S3(Z,{recursive:!0});let Q=Z2.join(Z,`board-${Date.now()}-${I3(4).toString("hex")}.png`);return await g3(Q,X),{path:Q,engine:$}}async function K2(X){let $=X.timeoutMs??c3;return r$({context:{viewport:{width:X.width,height:X.height},deviceScaleFactor:1}},async(Z)=>{Z.setDefaultTimeout($),Z.setDefaultNavigationTimeout($);let Q=await Z.goto(X.url,{waitUntil:"networkidle",timeout:$});if(!Q?.ok())throw Error(`Static board responded with HTTP ${Q?.status()??"unknown"}; request a fresh one-time token before retrying`);await Z.locator('[data-ideawave-static-board-ready="true"]').waitFor({state:"attached",timeout:$}),await Z.evaluate(async()=>{if(document.fonts?.ready)await document.fonts.ready});let K=await Z.screenshot({type:"png",animations:"disabled",caret:"hide",scale:"css"});if(K.byteLength<l3)throw Error("Headless Shell returned an empty screenshot");return p3(Buffer.from(K),B0().engine??"system-chromium")})}var i3=0,o3=30000,n3=15000,t3="/screenshot",r3=65536,j2="http://127.0.0.1",VX="IDEAWAVE_CLI_ALLOW_RAILWAY_PR_PREVIEWS";async function G2(X=X2(),$=(Z)=>new W2(Z,{headers:{origin:j2}})){try{let{url:Z,socket:Q}=await $2({candidates:X,createWebSocket:$});try{Q.close()}catch{}return Z}catch{return null}}var s3=new Set(["https://ideawave-app-production.up.railway.app"]);function e3(X){return X==="ideawave.app"||X.endsWith(".ideawave.app")}function XZ(X){return X==="1"||X?.toLowerCase()==="true"}function $Z(X){return/^ideawave-app-ideawave-app-pr-\d+\.up\.railway\.app$/i.test(X)}function ZZ(){let X=process.env.IDEAWAVE_CLI_ALLOWED_ORIGINS;if(!X)return QZ;let $=new Set;for(let Z of X.split(",")){let Q=Z.trim();if(!Q)continue;try{$.add(new URL(Q).origin)}catch{}}return $}var QZ=new Set;function z1(X){if(!X)return!1;let $;try{$=new URL(X)}catch{return!1}if(s3.has($.origin))return!0;if(ZZ().has($.origin))return!0;if($.protocol==="https:"&&XZ(process.env[VX])&&$Z($.hostname))return!0;if($.protocol==="https:"&&e3($.hostname))return!0;if($.protocol!=="http:"&&$.protocol!=="https:")return!1;return $.hostname==="localhost"||$.hostname==="127.0.0.1"||$.hostname==="::1"}function L0(X,$){if(X.readyState!==W2.OPEN)return;try{X.send(g0($))}catch{}}function KZ(X){if(typeof X==="string")return X;if(Buffer.isBuffer(X))return X.toString("utf8");if(Array.isArray(X))return Buffer.concat(X).toString("utf8");return Buffer.from(X).toString("utf8")}function GX(X){if(typeof X==="string")return X;if(Array.isArray(X))return X[0]??null;return null}function J2(X,$,Z){X.write(`HTTP/1.1 ${$} ${Z}\r
|
|
942
|
+
- Filesystem access is read-only and limited to this folder. Hidden/config folders and outside-folder paths are unavailable.`}async function u$(X,$){let Z=Date.now(),Q=new AbortController;j0.set(X.runId,{controller:Q,frontendSessionId:X.frontendSessionId}),eX.add(X.cardId),q("cli.run_started",{runId:X.runId,cardId:X.cardId,frontendSessionId:X.frontendSessionId});let W=DX(X.userId,X.frontendSessionId,X.cardId),K=!1,Y=null;try{let z=(X.runtimeConfigIdHint?await S$(X.runtimeConfigIdHint,{modelId:X.modelHint??null}):null)??await X0({boardId:X.boardId,cardId:X.cardId}),J=await z.adapter.resolveSpawnConfig(z.entry),G=X.toolSurface??"full",M=z.adapter.supportsImages===!0;Y=J;let L=MX({userId:X.userId,frontendSessionId:X.frontendSessionId,boardId:X.boardId,toolSurface:G,imagesSupported:M,cardId:X.cardId,runFolder:z.runFolder}),x=L?[L]:[];sX(X.cardId,M);let U=X.modelHint??z.modelId,D=NX({adapterId:z.adapter.id,configId:z.entry.id,modelId:U,configValues:z.configValues,mcpUrl:L?.url??null,runFolder:z.runFolder,toolSurface:G});q("cli.session_acquire_started",{runId:X.runId,cardId:X.cardId,frontendSessionId:X.frontendSessionId});let w=await I0({key:W,frontendSessionId:X.frontendSessionId,fingerprint:D,open:()=>tX({spawn:{...J,cwd:z.runFolder},mcpServers:x,modelId:U,configValues:z.configValues,signal:Q.signal})});q("cli.session_acquired",{runId:X.runId,cardId:X.cardId,frontendSessionId:X.frontendSessionId,elapsedMs:Date.now()-Z}),p$(z.entry.id,w,z.adapter.id,U);let H;try{let B=0,N="";q("cli.prompt_started",{runId:X.runId,cardId:X.cardId,elapsedMs:Date.now()-Z}),H=await w.prompt({runId:X.runId,boardId:X.boardId,cardId:X.cardId,prompt:{systemPrompt:N3(X.systemPrompt,z.runFolder),messages:X.promptMessages.map((O)=>({role:O.role,content:O.content}))},signal:Q.signal,appendText:async({text:O})=>{if(B+=1,B===1)q("cli.first_partial_text_forwarded",{runId:X.runId,cardId:X.cardId,elapsedMs:Date.now()-Z,textLength:O.length});$({type:"partial_text",runId:X.runId,cardId:X.cardId,text:O})},appendToolActivity:async({entry:O})=>{let C=`${O.toolCallId}:${O.status}`;if(C!==N)N=C,q("cli.tool_activity_forwarded",{runId:X.runId,cardId:X.cardId,toolCallId:O.toolCallId,toolStatus:O.status,elapsedMs:Date.now()-Z});$({type:"tool_activity",runId:X.runId,cardId:X.cardId,activity:O})}})}catch(B){if(!w.isAlive()||B instanceof R||B instanceof u)K=!0;throw B}$({type:"run_settled",runId:X.runId,cardId:X.cardId,result:{assistantContent:H.finalText,model:H.modelReported??null,latencyMs:Date.now()-Z,errorText:null,partialText:null}}),q("cli.run_settled",{runId:X.runId,cardId:X.cardId,elapsedMs:Date.now()-Z,hasError:!1})}catch(V){let z=V instanceof Error?V.message:"Agent run failed";if(V instanceof R&&Y&&!X1(V,Q.signal))CX(Y,z);if(!X1(V,Q.signal))console.error(`[ideawave-cli] run ${X.runId} failed:`,z);$({type:"run_settled",runId:X.runId,cardId:X.cardId,result:{assistantContent:"",model:null,latencyMs:Date.now()-Z,errorText:z,partialText:null}}),q("cli.run_settled",{runId:X.runId,cardId:X.cardId,elapsedMs:Date.now()-Z,hasError:!0,errorName:V instanceof Error?V.name:"unknown"})}finally{wX(W,K),j0.delete(X.runId),eX.delete(X.cardId),q("cli.run_released",{runId:X.runId,cardId:X.cardId,elapsedMs:Date.now()-Z,sessionDead:K})}}async function a$(X){if(eX.has(X.cardId))return{status:"skipped"};let $=DX(X.userId,X.frontendSessionId,X.cardId),Z=null;try{let Q=await X0({boardId:X.boardId,cardId:X.cardId}),W=await Q.adapter.resolveSpawnConfig(Q.entry);Z=W;let K=MX({userId:X.userId,frontendSessionId:X.frontendSessionId,boardId:X.boardId,cardId:X.cardId,runFolder:Q.runFolder}),Y=K?[K]:[];sX(X.cardId,Q.adapter.supportsImages===!0);let V=NX({adapterId:Q.adapter.id,configId:Q.entry.id,modelId:Q.modelId,configValues:Q.configValues,mcpUrl:K?.url??null,runFolder:Q.runFolder}),z=new AbortController,J=await I0({key:$,frontendSessionId:X.frontendSessionId,fingerprint:V,open:()=>tX({spawn:{...W,cwd:Q.runFolder},mcpServers:Y,modelId:Q.modelId,configValues:Q.configValues,signal:z.signal})});return p$(Q.entry.id,J,Q.adapter.id,Q.modelId),wX($,!1),console.log(`[ideawave-cli] warmed runtime for card ${X.cardId}`),{status:"ready"}}catch(Q){if(Q instanceof Y0)return{status:"skipped"};let W=Q instanceof Error?Q.message:String(Q);if(Q instanceof R&&Z&&!X1(Q))CX(Z,W);if(Q instanceof R&&/(not ready|installing|warming|retry in a moment)/i.test(W))return{status:"retryable",error:W};return console.warn(`[ideawave-cli] warmup failed for card ${X.cardId}:`,W),{status:"failed",error:W}}}import{chromium as y3}from"playwright-core";import{spawn as M3}from"node:child_process";import{existsSync as C0,readFileSync as P3}from"node:fs";import{createRequire as d$}from"node:module";import YX from"node:os";import T from"node:path";var $0={phase:"checking"},N0=null,Z1=0,L3=60000,B3=["install","--only-shell","chromium"];class R0 extends Error{constructor(){super("The lightweight screenshot engine is being installed in the background. Live browsing remains available; retry the screenshot shortly.");this.name="CaptureEngineInstallingError"}}class i$ extends Error{constructor(X){super(X?`The screenshot engine could not be installed: ${X}`:"The screenshot engine is unavailable. Retry after checking network access and disk space.");this.name="CaptureEngineUnavailableError"}}function F3(X){return X.phase==="failed"?new i$(X.error):new R0}function M0(){return{...$0}}function O3(X){let $=X.exists??C0;for(let[Z,Q]of[[X.override,"explicit"],[X.managedShell,"headless-shell"],[X.system,"system-chromium"]])if(Z&&$(Z))return{path:Z,engine:Q};return null}function o$(X,$){let Z=[],Q=$.IDEAWAVE_CAPTURE_EXECUTABLE_PATH??$.IDEAWAVE_CHROMIUM_PATH;if(Q)Z.push(Q);if(X==="win32"){let W=$.ProgramFiles??"C:\\Program Files",K=$["ProgramFiles(x86)"]??"C:\\Program Files (x86)";if(Z.push(T.win32.join(W,"Google\\Chrome\\Application\\chrome.exe"),T.win32.join(K,"Google\\Chrome\\Application\\chrome.exe")),$.LOCALAPPDATA)Z.push(T.win32.join($.LOCALAPPDATA,"Google\\Chrome\\Application\\chrome.exe"));Z.push(T.win32.join(K,"Microsoft\\Edge\\Application\\msedge.exe"),T.win32.join(W,"Microsoft\\Edge\\Application\\msedge.exe"))}else if(X==="darwin")Z.push("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge","/Applications/Chromium.app/Contents/MacOS/Chromium","google-chrome","chromium");else Z.push("google-chrome","google-chrome-stable","chromium","chromium-browser","msedge");return Z}function k3(X){let $=(process.env.PATH??"").split(T.delimiter),Z=process.platform==="win32"?[".exe",".cmd",".bat",""]:[""];for(let Q of $){if(!Q)continue;for(let W of Z){let K=T.join(Q,`${X}${W}`);if(C0(K))return K}}return null}function q3(){let X=new Set([process.env.IDEAWAVE_CAPTURE_EXECUTABLE_PATH,process.env.IDEAWAVE_CHROMIUM_PATH]);for(let $ of o$(process.platform,process.env)){if(X.has($))continue;if(T.isAbsolute($)){if(C0($))return $}else{let Z=k3($);if(Z)return Z}}return null}function _3(){try{let X=d$(import.meta.url);return T.dirname(X.resolve("playwright-core/package.json"))}catch{return null}}function A3(X){let $=process.env.PLAYWRIGHT_BROWSERS_PATH?.trim();if($==="0")return T.join(X,".local-browsers");if($)return $.startsWith("~")?T.join(YX.homedir(),$.slice(1)):T.resolve($);if(process.platform==="win32")return T.join(process.env.LOCALAPPDATA??T.join(YX.homedir(),"AppData","Local"),"ms-playwright");if(process.platform==="darwin")return T.join(YX.homedir(),"Library","Caches","ms-playwright");return T.join(YX.homedir(),".cache","ms-playwright")}function C3(){if(process.platform==="win32")return"win64";if(process.platform==="darwin")return process.arch==="arm64"?"mac-arm64":"mac-x64";return process.arch==="arm64"?"linux-arm64":"linux64"}function Q1(){let X=_3();if(!X)return null;try{let Z=JSON.parse(P3(T.join(X,"browsers.json"),"utf8")).browsers?.find((V)=>V.name==="chromium-headless-shell");if(!Z?.revision)return null;let Q=C3(),W=Z.revisionOverrides?.[Q]??Z.revision,K=T.join(A3(X),`chromium_headless_shell-${W}`),Y=process.platform==="win32"?["chrome-headless-shell-win64/chrome-headless-shell.exe","chrome-headless-shell-win32/chrome-headless-shell.exe"]:process.platform==="darwin"?[`chrome-headless-shell-${Q}/chrome-headless-shell`,"chrome-headless-shell-mac-x64/chrome-headless-shell","chrome-headless-shell-mac-arm64/chrome-headless-shell"]:[`chrome-headless-shell-${Q}/chrome-headless-shell`,"chrome-headless-shell-linux64/chrome-headless-shell"];for(let V of Y){let z=T.join(K,...V.split("/"));if(C0(z))return z}}catch{return null}return null}function R3(){let X=process.env.IDEAWAVE_CAPTURE_EXECUTABLE_PATH??process.env.IDEAWAVE_CHROMIUM_PATH;return X&&C0(X)?X:null}function n$(){return O3({override:R3(),managedShell:Q1(),system:q3()})}function f3(){let $=d$(import.meta.url).resolve("playwright-core/package.json"),Z=T.join(T.dirname($),"cli.js");return new Promise((Q,W)=>{let K=M3(process.execPath,[Z,...B3],{stdio:"ignore",windowsHide:!0});K.once("error",W),K.once("exit",(Y)=>{if(Y===0)Q();else W(Error(`Playwright headless-shell installer exited with code ${Y}`))})})}function W1(X){let $=Q1();if($)return $0={phase:"ready",engine:"headless-shell",executablePath:$},Promise.resolve(M0());if(N0)return N0;if(Z1>0&&Date.now()-Z1<L3)return Promise.resolve(M0());return $0=X?{phase:"ready",engine:X.engine,executablePath:X.path,installingManagedShell:!0}:{phase:"installing",installingManagedShell:!0},N0=(async()=>{try{await f3();let Z=Q1();if(!Z)throw Error("Headless Shell finished installing but its executable was not found");$0={phase:"ready",engine:"headless-shell",executablePath:Z}}catch(Z){Z1=Date.now(),$0=X?{phase:"ready",engine:X.engine,executablePath:X.path,error:Z instanceof Error?Z.message:String(Z)}:{phase:"failed",error:Z instanceof Error?Z.message:String(Z)}}finally{N0=null}return M0()})(),N0}function t$(){let X=n$();if(X?.engine==="explicit"||X?.engine==="headless-shell")return $0={phase:"ready",engine:X.engine,executablePath:X.path},Promise.resolve(M0());return W1(X)}async function r$(){let X=n$();if(X){if($0={phase:"ready",engine:X.engine,executablePath:X.path,...X.engine==="system-chromium"&&N0?{installingManagedShell:!0}:{}},X.engine==="system-chromium")W1(X);return X.path}throw W1(null),F3($0)}var b3=60000,E3=16,G0=null,JX=null,P0=null,K1=Promise.resolve(),VX=0,Y1=0,T3=0;class jX extends Error{constructor(){super("The capture queue is busy; retry shortly.");this.name="CaptureQueueFullError"}}function J1(){if(P0)clearTimeout(P0);P0=null}async function V1(){J1();let X=G0;if(G0=null,JX=null,X)await X.close().catch(()=>{return})}function v3(X=b3){J1(),P0=setTimeout(()=>{if(P0=null,Y1===0&&VX===0)V1()},X),P0.unref?.()}async function h3(){let X=await r$();if(G0?.isConnected()&&JX===X)return G0;await V1();let $=await y3.launch({headless:!0,executablePath:X,handleSIGHUP:!1,handleSIGINT:!1,handleSIGTERM:!1});return T3+=1,G0=$,JX=X,$.on("disconnected",()=>{if(G0===$)G0=null,JX=null}),$}function s$(X,$){if(VX>=E3)return Promise.reject(new jX);VX+=1;let Z,Q,W=new Promise((K,Y)=>{Z=K,Q=Y});return K1=K1.then(async()=>{VX-=1,Y1+=1,J1();let K=null,Y;try{K=await(await h3()).newContext(X.context);let z=await K.newPage();Y={ok:!0,value:await $(z)}}catch(V){Y={ok:!1,error:V}}finally{if(K)await K.close().catch(()=>{return});Y1-=1,v3()}if(Y.ok)Z(Y.value);else Q(Y.error)}),W}async function e$(){await K1.catch(()=>{return}),await V1()}import{randomUUID as d3}from"node:crypto";import{createServer as i3}from"node:http";import{WebSocket as j2,WebSocketServer as o3}from"ws";var j1="/cli-bridge",X2="/ping";function G1(X=43275,$=43277){let Z=[];for(let Q=X;Q<=$;Q+=1)Z.push(Q);return Z}function $2(X=G1(),$="127.0.0.1",Z="/cli-bridge"){return X.map((Q)=>`ws://${$}:${Q}${Z}`)}var I3=800;function Z2({candidates:X,createWebSocket:$,timeoutMs:Z=I3,maxConcurrent:Q=1,staggerMs:W=0,setTimeoutFn:K=setTimeout,clearTimeoutFn:Y=clearTimeout}){return new Promise((V,z)=>{let J=0,G=!1,M=null,L=new Map,x=Math.max(1,Math.floor(Q)),U=()=>{if(M===null)return;Y(M),M=null},D=(P)=>{let{socket:j,listeners:k,timer:_}=P;j.removeEventListener("open",k.open),j.removeEventListener("message",k.message),j.removeEventListener("error",k.error),j.removeEventListener("close",k.close),Y(_),L.delete(j)},w=(P)=>{U();for(let j of Array.from(L.values()))if(D(j),j.socket!==P)try{j.socket.close()}catch{}},H=()=>{if(G)return;if(J<X.length)return;if(L.size>0)return;if(M!==null)return;G=!0,z(Error("No IdeaWave CLI bridge is reachable"))},B=(P)=>{if(G)return;if(J>=X.length){H();return}if(L.size>=x)return;if(P<=0){U(),C();return}if(M!==null)return;M=K(()=>{M=null,C()},P)},N=()=>{if(G)return;if(L.size>=x)return;if(L.size===0||W<=0||x===1){B(0);return}B(W)},O=(P)=>{if(G)return;let j=L.get(P);if(!j)return;D(j);try{P.close()}catch{}N(),H()};function C(){if(G)return;if(L.size>=x)return;let P=X[J];if(J+=1,!P){H();return}let j;try{j=$(P)}catch{N(),H();return}let k={open:()=>{if(G||!L.has(j))return;j.send(m0({type:"bridge_probe",protocolVersion:1}))},message:(b)=>{if(G||!L.has(j))return;if(g0(String(b?.data??""))?.type!=="bridge_probe_ack")return;G=!0,w(j),V({url:P,socket:j})},error:()=>O(j),close:()=>O(j)};j.addEventListener("open",k.open),j.addEventListener("message",k.message),j.addEventListener("error",k.error),j.addEventListener("close",k.close);let _=K(()=>O(j),Z);L.set(j,{url:P,socket:j,listeners:k,timer:_}),N()}C()})}import{randomBytes as S3}from"node:crypto";import{mkdir as g3,writeFile as m3}from"node:fs/promises";import c3 from"node:os";import Q2 from"node:path";var l3=30000,p3=1024;function W2(X){let $;try{$=new URL(X)}catch{return!1}if($.protocol!=="http:"&&$.protocol!=="https:")return!1;let Z=$.hostname.toLowerCase().replace(/^\[|\]$/g,"");if(Z==="localhost"||Z==="127.0.0.1"||Z==="::1")return!0;let W=Z==="ideawave.app"||Z.endsWith(".ideawave.app");return $.protocol==="https:"&&W&&$.pathname.startsWith("/static_boards/")}async function u3(X,$){let Z=Q2.join(c3.tmpdir(),"ideawave-screenshots");await g3(Z,{recursive:!0});let Q=Q2.join(Z,`board-${Date.now()}-${S3(4).toString("hex")}.png`);return await m3(Q,X),{path:Q,engine:$}}async function K2(X){let $=X.timeoutMs??l3;return s$({context:{viewport:{width:X.width,height:X.height},deviceScaleFactor:1}},async(Z)=>{Z.setDefaultTimeout($),Z.setDefaultNavigationTimeout($);let Q=await Z.goto(X.url,{waitUntil:"networkidle",timeout:$});if(!Q?.ok())throw Error(`Static board responded with HTTP ${Q?.status()??"unknown"}; request a fresh one-time token before retrying`);await Z.locator('[data-ideawave-static-board-ready="true"]').waitFor({state:"attached",timeout:$}),await Z.evaluate(async()=>{if(document.fonts?.ready)await document.fonts.ready});let W=await Z.screenshot({type:"png",animations:"disabled",caret:"hide",scale:"css"});if(W.byteLength<p3)throw Error("Headless Shell returned an empty screenshot");return u3(Buffer.from(W),M0().engine??"system-chromium")})}var f0="IDEAWAVE_CLI_ALLOW_RAILWAY_PR_PREVIEWS";function a3(X){return X==="1"||X?.toLowerCase()==="true"}function Y2(X,$){let Q=X.includes("--dev")||a3($.IDEAWAVE_CLI_ALLOW_RAILWAY_PR_PREVIEWS),W=$.APP_ENV==="development"||Q;return{cliArgs:X.filter((K)=>K!=="--dev"),browserKitEnabled:!0,captureEngineEnabled:!W,allowRailwayPrPreviews:Q}}var n3=0,t3=30000,r3=15000,s3="/screenshot",e3=65536,G2="http://127.0.0.1";async function z2(X=$2(),$=(Z)=>new j2(Z,{headers:{origin:G2}})){try{let{url:Z,socket:Q}=await Z2({candidates:X,createWebSocket:$});try{Q.close()}catch{}return Z}catch{return null}}var XZ=new Set(["https://ideawave-app-production.up.railway.app"]);function $Z(X){return X==="ideawave.app"||X.endsWith(".ideawave.app")}function ZZ(X){return X==="1"||X?.toLowerCase()==="true"}function QZ(X){return/^ideawave-app-ideawave-app-pr-\d+\.up\.railway\.app$/i.test(X)}function WZ(){let X=process.env.IDEAWAVE_CLI_ALLOWED_ORIGINS;if(!X)return KZ;let $=new Set;for(let Z of X.split(",")){let Q=Z.trim();if(!Q)continue;try{$.add(new URL(Q).origin)}catch{}}return $}var KZ=new Set;function z1(X){if(!X)return!1;let $;try{$=new URL(X)}catch{return!1}if(XZ.has($.origin))return!0;if(WZ().has($.origin))return!0;if($.protocol==="https:"&&ZZ(process.env[f0])&&QZ($.hostname))return!0;if($.protocol==="https:"&&$Z($.hostname))return!0;if($.protocol!=="http:"&&$.protocol!=="https:")return!1;return $.hostname==="localhost"||$.hostname==="127.0.0.1"||$.hostname==="::1"}function L0(X,$){if(X.readyState!==j2.OPEN)return;try{X.send(m0($))}catch{}}function YZ(X){if(typeof X==="string")return X;if(Buffer.isBuffer(X))return X.toString("utf8");if(Array.isArray(X))return Buffer.concat(X).toString("utf8");return Buffer.from(X).toString("utf8")}function GX(X){if(typeof X==="string")return X;if(Array.isArray(X))return X[0]??null;return null}function J2(X,$,Z){X.write(`HTTP/1.1 ${$} ${Z}\r
|
|
943
943
|
Connection: close\r
|
|
944
944
|
Content-Length: ${Buffer.byteLength(Z)}\r
|
|
945
945
|
\r
|
|
946
|
-
${Z}`),X.destroy()}function JZ(X,$){return new Promise((Z,Q)=>{let K=(Y)=>{X.off("listening",J),Q(Y)},J=()=>{X.off("error",K);let Y=X.address();if(!Y||typeof Y==="string"){Q(Error("Failed to read CLI bridge server address"));return}Z(Y.port)};X.once("error",K),X.once("listening",J),X.listen($,"127.0.0.1")})}function Y2(X){return new Promise(($,Z)=>{X.close((Q)=>{if(Q)Z(Q);else $()})})}async function V2(X,$=V1()){let Z=new Map,Q=new Map,K=X.maxMessageSize??i3,J=!1,Y=(x)=>{let U=Q.get(x);if(U)clearTimeout(U);Q.delete(x)},j=(x)=>{Q.delete(x);let{activeRunIds:U}=X.registry.disconnect(x);X.onDisconnect(x,U)},z=(x,U)=>{let D={type:"cli_status",connected:!0,runtime:X.runtime,mcpReady:X.mcpReady(),error:U,capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()};if(x){let N=Z.get(x);if(N)L0(N,D);return}for(let N of Z.values())L0(N,D)},W=(x,U)=>{let D=U.sessionId.trim(),N=U.userId.trim();if(!D||!N){L0(x,{type:"cli_status",connected:!1,runtime:X.runtime,mcpReady:X.mcpReady(),error:"Missing frontend session or user id"}),x.close();return}Y(D);let H=Z.get(D);if(H&&H!==x)H.close();x.data.frontendSessionId=D,Z.set(D,x),X.registry.register({frontendSessionId:D,userId:N,tools:U.tools,send:(P)=>L0(x,P)}),z(D),X.onToolMetadata?.(D)},V=(x,U)=>{let D=X.registry.getUserId(x);if(!D)return;switch(U.type){case"bridge_ping":{let N=Z.get(x);if(N)L0(N,{type:"bridge_pong"});break}case"tool_metadata":X.registry.setMetadata(x,U.tools),X.onToolMetadata?.(x);break;case"tool_result":X.registry.handleToolResult(x,U);break;case"run_turn":q("bridge.run_received",{runId:U.run.runId,cardId:U.run.cardId,frontendSessionId:x}),X.registry.markRunActive(x,U.run.runId,U.run.cardId),X.onRunTurn(x,{...U.run,frontendSessionId:x,userId:D});break;case"cancel_run":if(X.registry.ownsRun(x,U.runId))X.onCancelRun(x,U.runId);break;case"runtime_rpc":X.onRuntimeRpc(x,U);break;case"browser_rpc":X.onBrowserRpc?.(x,Z.get(x)?.data.frontendOrigin??"",U);break;case"warmup_run":X.onWarmupRun(x,{...U,frontendSessionId:x},D);break;default:break}},B=(x,U)=>{let D=GX(x.headers.origin),N=z1(D),H={Vary:"Origin"};if(N&&D)H["Access-Control-Allow-Origin"]=D,H["Access-Control-Allow-Private-Network"]="true";if(x.method==="OPTIONS"){U.writeHead(204,{...H,"Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*","Access-Control-Max-Age":"600"}),U.end();return}if(x.method!=="GET"){U.writeHead(405,H),U.end();return}U.writeHead(200,{...H,"content-type":"application/json","cache-control":"no-store"}),U.end(JSON.stringify({ideawave:!0,runtime:X.runtime,mcpReady:X.mcpReady(),capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()}))},L=(x,U)=>{let D=GX(x.headers.origin),N=z1(D),H={Vary:"Origin"};if(N&&D)H["Access-Control-Allow-Origin"]=D,H["Access-Control-Allow-Private-Network"]="true";if(x.method==="OPTIONS"){U.writeHead(204,{...H,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"content-type","Access-Control-Max-Age":"600"}),U.end();return}if(!N){U.writeHead(403,H),U.end();return}if(x.method!=="POST"){U.writeHead(405,H),U.end();return}let P={...H,"content-type":"application/json"},w=(M,G)=>{U.writeHead(M,P),U.end(JSON.stringify(G))},O="",C=!1;x.on("data",(M)=>{if(O+=M.toString("utf8"),O.length>r3)C=!0,x.destroy()}),x.on("end",()=>{if(C){w(400,{ok:!1,error:"Request body too large"});return}let M;try{M=JSON.parse(O)}catch{w(400,{ok:!1,error:"Invalid JSON body"});return}let G=typeof M.url==="string"?M.url:"";if(!Q2(G)){w(400,{ok:!1,error:"url must be an http(s) loopback or /static_boards/ page URL"});return}let k=(_,b)=>{let d=typeof _==="number"?_:Number.NaN;if(!Number.isFinite(d))return b;return Math.min(4000,Math.max(200,Math.round(d)))};K2({url:G,width:k(M.width,1440),height:k(M.height,900)}).then((_)=>w(200,{ok:!0,path:_.path,engine:_.engine})).catch((_)=>{let b=_ instanceof y0?503:_ instanceof jX?429:500;w(b,{ok:!1,..._ instanceof y0?{installing:!0}:{},error:_ instanceof Error?_.message:String(_)})})})};for(let x of $){let U=a3((H,P)=>{(async()=>{let w=new URL(H.url??"/","http://127.0.0.1").pathname;if(w===e$){B(H,P);return}if(w===t3){L(H,P);return}if(await X.onHttpRequest?.(H,P))return;P.writeHead(404,{"content-type":"text/plain"}),P.end("IdeaWave CLI bridge")})().catch((w)=>{if(P.headersSent){P.destroy(w instanceof Error?w:void 0);return}P.writeHead(500,{"content-type":"text/plain"}),P.end("IdeaWave CLI bridge request failed")})}),D=new d3({noServer:!0,maxPayload:K}),N=(H)=>{if(H.idleTimer)clearTimeout(H.idleTimer);H.idleTimer=setTimeout(()=>{H.close()},o3),H.idleTimer.unref?.()};D.on("connection",(H,P)=>{let w=H;w.data={id:u3(),frontendSessionId:null,frontendOrigin:new URL(GX(P.headers.origin)??j2).origin},w.idleTimer=null,N(w),w.on("ping",()=>N(w)),w.on("pong",()=>N(w)),w.on("error",()=>{if(w.idleTimer)clearTimeout(w.idleTimer);w.close()}),w.on("message",(O)=>{N(w);let C=KZ(O);if(K>0&&C.length>K)return;let M=S0(C);if(!M)return;let G=w.data.frontendSessionId;if(!G){if(M.type==="bridge_probe")L0(w,{type:"bridge_probe_ack",protocolVersion:M.protocolVersion});else if(M.type==="frontend_hello")W(w,M);return}V(G,M)}),w.on("close",()=>{if(w.idleTimer)clearTimeout(w.idleTimer);let O=w.data.frontendSessionId;if(!O)return;if(Z.get(O)!==w)return;if(Z.delete(O),Y(O),J)return;Q.set(O,setTimeout(()=>j(O),n3))})}),U.on("upgrade",(H,P,w)=>{let O=new URL(H.url??"/","http://127.0.0.1").pathname;if(X.onHttpUpgrade?.(H,P,w))return;if(O!==G1){J2(P,404,"Not Found");return}if(!z1(GX(H.headers.origin))){J2(P,403,"Forbidden");return}D.handleUpgrade(H,P,w,(C)=>{D.emit("connection",C,H)})});try{let H=await JZ(U,x);return{url:`ws://127.0.0.1:${H}${G1}`,port:H,sendStatus:z,close:async()=>{J=!0;for(let P of Q.values())clearTimeout(P);Q.clear();for(let P of D.clients){let w=P;if(w.idleTimer)clearTimeout(w.idleTimer);w.close()}D.close(),await Y2(U).catch(()=>{return})}}}catch(H){if(D.close(),await Y2(U).catch(()=>{return}),H?.code==="EADDRINUSE")continue;throw H}}throw Error(`No free IdeaWave CLI bridge port found in ${$[0]}-${$.at(-1)}`)}import{lstat as MZ,readFile as LZ}from"node:fs/promises";import PZ from"node:os";import R0 from"node:path";import{Server as FZ}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as OZ,ListToolsRequestSchema as kZ}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as WZ}from"node:crypto";import{createServer as jZ}from"node:http";import{StreamableHTTPServerTransport as GZ}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as x2}from"@modelcontextprotocol/sdk/types.js";var z2=new Set(["127.0.0.1","localhost","[::1]","::1"]);function YZ(X){let $=X.trim();if($.length===0)return null;if($.startsWith("[")){let J=$.indexOf("]");if(J===-1)return null;let Y=$.slice(0,J+1),j=$.slice(J+1);if(j.length===0)return{host:Y,port:null};if(!j.startsWith(":"))return null;let z=Number(j.slice(1));if(!Number.isInteger(z)||z<=0||z>65535)return null;return{host:Y,port:z}}let Z=$.lastIndexOf(":");if(Z===-1)return{host:$,port:null};let Q=$.slice(Z+1),K=Number(Q);if(!Number.isInteger(K)||K<=0||K>65535)return{host:$,port:null};return{host:$.slice(0,Z),port:K}}function U2(X){return z2.has(X)||z2.has(X.toLowerCase())}function H2(X,$){let Z=X.headers.host;if(typeof Z!=="string")return{ok:!1,status:403,reason:"missing-host"};let Q=YZ(Z);if(!Q)return{ok:!1,status:403,reason:"bad-host"};if(!U2(Q.host))return{ok:!1,status:403,reason:"non-loopback-host"};if(Q.port!==null&&Q.port!==$)return{ok:!1,status:403,reason:"host-port-mismatch"};let K=X.headers.origin;if(typeof K==="string"&&K.length>0){if(K!=="null"){let J;try{J=new URL(K)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!U2(J.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var D2="/mcp",VZ=43274,w2=16777216,zZ=1800000,UZ=300000,N2=200,HZ=-32700,Z0=-32600,U1=-32603;function l(X,$,Z,Q,K){X.statusCode=$,X.setHeader("content-type","application/json"),X.end(JSON.stringify({jsonrpc:"2.0",error:{code:Z,message:Q,...K?{data:K}:{}},id:null}))}class H1 extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class x1 extends Error{constructor(){super(`body exceeds ${w2} bytes`);this.name="BodyTooLargeError"}}async function xZ(X){if(X.method&&X.method!=="POST")return;let $=X.headers["content-type"];if(typeof $==="string"&&$.trim().length>0){if(!$.toLowerCase().includes("application/json"))throw new H1}let Z=0,Q=[];for await(let J of X){let Y=typeof J==="string"?Buffer.from(J):J;if(Z+=Y.byteLength,Z>w2)throw new x1;Q.push(Y)}if(Q.length===0)return;let K=Buffer.concat(Q).toString("utf8");if(K.length===0)return;return JSON.parse(K)}function DZ(X){if(Array.isArray(X))return X.some(x2);return x2(X)}function NZ(X){if(typeof X==="number")return X;let $=process.env.IDEAWAVE_MCP_PORT;if($&&$.trim().length>0){let Z=Number($);if(Number.isInteger(Z)&&Z>=0&&Z<65536)return Z}return VZ}async function wZ(X,$){let Z=(K)=>new Promise((J,Y)=>{let j=(W)=>{X.off("listening",z),Y(W)},z=()=>{X.off("error",j),J()};X.once("error",j),X.once("listening",z),X.listen(K,"127.0.0.1")});try{await Z($)}catch(K){if(K.code!=="EADDRINUSE"||$===0)throw K;console.warn(`[mcp] port ${$} in use, falling back to an OS-assigned port; external CLIs will need to re-paste the install command from Settings → External agents`),await Z(0)}let Q=X.address();if(Q==null||typeof Q==="string")throw Error("[mcp] failed to read bound address");return Q.port}function BZ(X,$){if($&&typeof $==="object"&&!Array.isArray($)){let Q=$.params;if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let K=Q.clientInfo;if(K&&typeof K==="object"&&!Array.isArray(K)){let J=K.name;if(typeof J==="string"&&J.trim().length>0)return J.trim()}}}let Z=X.headers["user-agent"];if(typeof Z==="string"&&Z.trim().length>0)return Z.trim();return null}async function B2(X){let $=new Map,Z=0;function Q(W){let V=$.get(W);if(V)V.lastActivity=Date.now()}async function K(W,V){$.delete(W),await V.transport.close().catch(()=>{return})}async function J(){let W=null,V=1/0;for(let[B,L]of $)if(L.lastActivity<V)V=L.lastActivity,W=B;if(W!==null){let B=$.get(W);if(B)console.warn(`[mcp] session cap of ${N2} reached; evicting ${W}`),await K(W,B)}}let Y=setInterval(()=>{let W=Date.now()-zZ;for(let[V,B]of $)if(B.lastActivity<W)console.log(`[mcp] sweeping idle session ${V}`),K(V,B)},UZ);Y.unref?.();let j=jZ((W,V)=>{(async()=>{let B;try{B=new URL(W.url??"/","http://127.0.0.1").pathname}catch{l(V,400,Z0,"bad-url");return}if(B!==D2){l(V,404,Z0,"not-found");return}let L=W.method??"POST";if(L!=="POST"&&L!=="GET"&&L!=="DELETE"){V.setHeader("Allow","GET, POST, DELETE"),l(V,405,Z0,"method-not-allowed");return}let x=H2(W,Z);if(!x.ok){l(V,x.status,Z0,"forbidden",{reason:x.reason});return}let U=W.headers["mcp-session-id"],D=typeof U==="string"?U:void 0;if(L==="GET"||L==="DELETE"){if(!D||!$.has(D)){l(V,400,Z0,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let P=$.get(D).transport;Q(D);try{await P.handleRequest(W,V)}catch(w){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",w),!V.headersSent)l(V,500,U1,"internal")}return}let N;try{N=await xZ(W)}catch(P){if(P instanceof H1){l(V,415,Z0,"expected-application-json");return}if(P instanceof x1){l(V,413,Z0,"body-too-large");return}l(V,400,HZ,"invalid-json");return}let H;if(D&&$.has(D))H=$.get(D).transport,Q(D);else if(!D&&N!==void 0&&DZ(N)){let P=W.headers["x-ideawave-user-id"],w=typeof P==="string"&&P.trim().length>0?P.trim():null,O=W.headers["x-ideawave-frontend-session-id"],C=typeof O==="string"&&O.trim().length>0?O.trim():null,M=W.headers["x-ideawave-tool-surface"],G=typeof M==="string"&&M.trim()==="read"?"read":"full",k=W.headers["x-ideawave-images-supported"],_=typeof k==="string"&&k.trim()==="1",b=W.headers["x-ideawave-card-id"],d=typeof b==="string"&&b.trim().length>0?b.trim():null,n=W.headers["x-ideawave-board-id"],A=typeof n==="string"&&n.trim().length>0?n.trim():null,v=W.headers["x-ideawave-run-folder"],R=typeof v==="string"&&v.trim().length>0?v.trim():null,I=BZ(W,N);if($.size>=N2)await J();let h=null,J0=new GZ({sessionIdGenerator:()=>WZ(),onsessioninitialized:(U0)=>{h=U0,$.set(U0,{transport:J0,lastActivity:Date.now()})},onsessionclosed:(U0)=>{$.delete(U0)}});J0.onclose=()=>{if(J0.sessionId)$.delete(J0.sessionId)};try{await X.buildServer({userId:w,frontendSessionId:C,boardId:A,toolSurface:G,imagesSupported:_,cardId:d,runFolder:R,clientHint:I}).connect(J0)}catch(U0){if(console.error("[mcp] buildServer/connect failed",U0),h)$.delete(h);await J0.close().catch(()=>{return}),l(V,500,U1,"server-init-failed");return}H=J0}else{l(V,400,Z0,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await H.handleRequest(W,V,N)}catch(P){if(console.error("[mcp] transport.handleRequest threw",P),!V.headersSent)l(V,500,U1,"internal")}})().catch((B)=>{console.error("[mcp] unhandled request handler error:",B)})});return Z=await wZ(j,NZ(X.port)),{url:`http://127.0.0.1:${Z}${D2}`,port:Z,close:async()=>{clearInterval(Y);for(let W of $.values())await W.transport.close().catch(()=>{return});$.clear(),await new Promise((W)=>j.close(()=>W()))}}}var qZ={name:"ideawave-board",version:"1.0.0"},zX="list_run_folder",UX="read_run_folder_file",P2=new Set(["list_boards","get_board","screenshot_board","list_nodes","list_edges","inspect_node","list_context_sources","read_context_card","read_context_file","read_context_image","list_context_folder","get_board_wiki","search_board","get_card_messages","list_agent_cards","inspect_neighbors",zX,UX]),F2=new Set(["inspect_diagram"]),_Z=[{name:zX,description:"List visible files and folders under the selected runtime run folder. Hidden/config folders are omitted.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Optional relative path inside the selected run folder. Defaults to the run-folder root."}},additionalProperties:!1}},{name:UX,description:"Read a text file inside the selected runtime run folder. Hidden/config paths and outside-folder paths are denied.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Relative path to a text file inside the selected run folder."}},required:["path"],additionalProperties:!1}}];function D1(X){return{content:[{type:"text",text:X}]}}function AZ(X){return D1(JSON.stringify(X,null,2))}function M2(X){return{...D1(X),isError:!0}}async function CZ(X,$){if(!$||X.isError)return X;let Z=X.content.find((J)=>J.type==="text");if(!Z)return X;let Q;try{let J=JSON.parse(Z.text);if(typeof J.path!=="string")return X;Q=R0.resolve(J.path)}catch{return X}let K=R0.resolve(R0.join(PZ.tmpdir(),"ideawave-screenshots"));if(R0.dirname(Q)!==K||!/^board-[a-z0-9-]+\.png$/i.test(R0.basename(Q)))return X;try{if(!(await MZ(Q)).isFile())return X;let Y=await LZ(Q);if(Y.byteLength<1024||Y.byteLength>26214400||!Y.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return X;return{...X,content:[...X.content,{type:"image",data:Y.toString("base64"),mimeType:"image/png"}]}}catch{return X}}function fZ(X,$,Z="full",Q=!1){return X.getMetadata($).filter((K)=>{let J=XX(K.name);if(Z==="read"&&!P2.has(J))return!1;if(!Q&&F2.has(J))return!1;return!0}).map((K)=>({name:K.name,description:K.description,inputSchema:K.inputSchema}))}function yZ(X,$,Z={}){let Q=fZ(X,$,Z.toolSurface??"full",Z.imagesSupported??!1);return Z.includeRunFolderTools?[...Q,..._Z]:Q}function L2(X,$){if(!X||typeof X!=="object"||Array.isArray(X))return null;let Z=X[$];return typeof Z==="string"?Z:null}async function RZ(X,$,Z){if(Z&&Z.trim().length>0)return Z.trim();if(!X||!$)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await X0({boardId:X,cardId:$})).runFolder}async function bZ(X){let $=await RZ(X.boardId,X.cardId,X.runFolder);if(X.name===zX){let Z=L2(X.args,"path")??"",Q=await M$($,Z);return AZ(Q)}if(X.name===UX){let Z=L2(X.args,"path");if(!Z)return M2("read_run_folder_file requires a path.");return D1(await e0($,Z))}return M2(`Unknown local tool "${X.name}"`)}function TZ(X,$,Z,Q,K,J="full",Y=!1){let j=new FZ(qZ,{capabilities:{tools:{}}}),z=async()=>{if(Y)return!0;if(g$(Q))return!0;if(Z&&Q)try{return(await X0({boardId:Z,cardId:Q})).adapter.supportsImages===!0}catch{return!1}return!1};return j.setRequestHandler(kZ,async()=>({tools:yZ(X,$,{includeRunFolderTools:Boolean(K||Z&&Q),toolSurface:J,imagesSupported:await z()})})),j.setRequestHandler(OZ,async(W)=>{let{name:V,arguments:B}=W.params,L=XX(V),x=Date.now();q("mcp.tool_call_received",{frontendSessionId:$,cardId:Q,toolName:L});try{if(L===zX||L===UX)return await bZ({name:L,args:B,boardId:Z,cardId:Q,runFolder:K});if(J==="read"&&!P2.has(L))throw Error(`Tool "${V}" is not available in read-only mode`);if(F2.has(L)&&!await z())throw Error(`Tool "${V}" requires a runtime that supports image input`);let U=await X.callTool($,L,B??{},void 0,Q??void 0);if(q("mcp.tool_result_returned",{frontendSessionId:$,cardId:Q,toolName:L,elapsedMs:Date.now()-x}),U&&typeof U==="object"&&Array.isArray(U.content)){let D=U;return L==="screenshot_board"?await CZ(D,await z()):D}return{content:[{type:"text",text:typeof U==="string"?U:JSON.stringify(U)}]}}catch(U){return q("mcp.tool_result_returned",{frontendSessionId:$,cardId:Q,toolName:L,elapsedMs:Date.now()-x,hasError:!0}),{content:[{type:"text",text:U instanceof Error?U.message:"Tool call failed"}],isError:!0}}}),j}function O2(X,$){return B2({buildServer:(Z)=>TZ(X,Z.frontendSessionId,Z.boardId,Z.cardId,Z.runFolder,Z.toolSurface,Z.imagesSupported),port:$})}import HX from"node:fs/promises";import N1 from"node:os";import xX from"node:path";function k2(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function EZ(){let[X,$]=await Promise.all([m(),W$()]),Z=X.globalDefaultConfigId?X.runtimes.find((Q)=>Q.id===X.globalDefaultConfigId)??null:null;return{runtimes:X.runtimes,globalDefaultConfigId:X.globalDefaultConfigId,globalDefaultEffective:Z?{runFolder:Z.runFolder??N1.homedir(),modelId:Z.defaultModelId??null,configValues:Z.defaultConfigValues??{}}:null,knownAdapters:D0().map((Q)=>({id:Q.id,displayName:Q.displayName})),readiness:$}}async function vZ(X){try{let $=await X0({boardId:X.boardId,cardId:X.cardId});return{resolved:{configId:$.entry.id,adapterId:$.entry.kind==="registered"?$.entry.adapterId:null,displayName:$.entry.displayName,runFolder:$.runFolder,modelId:$.modelId,configValues:$.configValues}}}catch($){if($ instanceof Y0)return{resolved:null};throw $}}async function hZ(X){return p(($)=>{let Z=$.runtimes.find((J)=>J.kind==="registered"&&J.adapterId===X.adapterId);if(Z)return Z;let Q=D0().find((J)=>J.id===X.adapterId);if(!Q)throw Error(`Unknown adapterId: ${X.adapterId}`);let K={id:k2(),kind:"registered",adapterId:X.adapterId,displayName:Q.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return $.runtimes.push(K),K})}async function IZ(X){return p(($)=>{let Z={id:k2(),kind:"custom",displayName:X.displayName,command:X.command,args:X.args,env:X.env,runFolder:X.runFolder,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return $.runtimes.push(Z),Z})}async function SZ(X){await p(($)=>{if($.runtimes=$.runtimes.filter((Z)=>Z.id!==X.runtimeConfigId),$.globalDefaultConfigId===X.runtimeConfigId)$.globalDefaultConfigId=null;for(let Z of Object.keys($.boardOverrides))if($.boardOverrides[Z].runtimeConfigId===X.runtimeConfigId)delete $.boardOverrides[Z];for(let Z of Object.keys($.cardOverrides))if($.cardOverrides[Z].runtimeConfigId===X.runtimeConfigId)delete $.cardOverrides[Z]})}async function gZ(X){await p(($)=>{let Z=$.runtimes.find((Q)=>Q.id===X.runtimeConfigId);if(!Z)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);if($.globalDefaultConfigId=X.runtimeConfigId,X.runFolder!==void 0)Z.runFolder=X.runFolder;if(X.modelId!==void 0)Z.defaultModelId=X.modelId;if(X.configValues!==void 0)Z.defaultConfigValues=X.configValues})}async function mZ(X){X.boardId,await p(($)=>{if(X.runtimeConfigId===null){delete $.cardOverrides[X.cardId];return}if(!$.runtimes.some((K)=>K.id===X.runtimeConfigId))throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let Q=$.cardOverrides[X.cardId];$.cardOverrides[X.cardId]={runtimeConfigId:X.runtimeConfigId,runFolder:X.runFolder!==void 0?X.runFolder:Q?.runFolder??null,modelId:X.modelId!==void 0?X.modelId:Q?.modelId??null,configValues:X.configValues!==void 0?X.configValues:Q?.configValues??{}}})}async function cZ(X){let Z=(await m()).runtimes.find((Y)=>Y.id===X.runtimeConfigId);if(!Z)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let Q=a(Z),K=await Q.resolveSpawnConfig(Z),J=Z.runFolder??N1.homedir();try{let Y=await v$({spawn:{...K,cwd:J},modelId:X.modelId??Z.defaultModelId??null,configValues:X.configValues??Z.defaultConfigValues??{}}),j=r0({adapterId:Q.id,models:Y.models,currentModelId:Y.currentModelId}),z=new Date().toISOString();return await p((W)=>{let V=W.runtimes.find((B)=>B.id===X.runtimeConfigId);if(V)V.discoveredModels=j,V.discoveredConfigOptions=Y.configOptions,V.discoveredAt=z}),{ok:!0,models:j,configOptions:Y.configOptions,currentModelId:Y.currentModelId}}catch(Y){if(Y instanceof H0)throw Error(`${Y.message}${Q.authHint?` ${Q.authHint}`:""}`);if(Y instanceof f||Y instanceof u)throw Error(Y.message);throw Y}}async function lZ(X){let $=N1.homedir(),Z=X.path?.trim()?X.path.trim():$,Q=xX.resolve(Z),K=!0;try{if(!(await HX.stat(Q)).isDirectory())Q=xX.dirname(Q)}catch{K=!1,Q=$}let J=[];try{J=(await HX.readdir(Q,{withFileTypes:!0})).filter((z)=>z.isDirectory()&&!z.name.startsWith(".")).map((z)=>({name:z.name,path:xX.join(Q,z.name)})).sort((z,W)=>z.name.localeCompare(W.name))}catch{J=[]}let Y=xX.dirname(Q);return{path:Q,parent:Y===Q?null:Y,home:$,exists:K,entries:J}}var q2={list:EZ,getEffectiveForCard:vZ,registerRegistered:hZ,registerCustom:IZ,unregister:SZ,setUserDefault:gZ,setCardOverride:mZ,refreshModels:cZ,browseFolder:lZ};var pZ=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function uZ(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function _2(){try{let X=await m();if(X.globalDefaultConfigId){if(X.runtimes.some((Z)=>Z.id===X.globalDefaultConfigId))return X.globalDefaultConfigId}for(let $ of pZ){if((await j$($.id))?.status!=="ready")continue;let Q=null;if(await p((K)=>{if(K.globalDefaultConfigId){if(K.runtimes.some((j)=>j.id===K.globalDefaultConfigId)){Q=K.globalDefaultConfigId;return}}let J=K.runtimes.find((Y)=>Y.kind==="registered"&&Y.adapterId===$.id);if(!J){let Y={id:uZ(),kind:"registered",adapterId:$.id,displayName:$.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};K.runtimes.push(Y),J=Y}K.globalDefaultConfigId=J.id,Q=J.id}),Q)return console.log(`[ideawave-cli] using agent runtime: ${$.displayName}`),Q}return console.warn("[ideawave-cli] no agent runtime detected on PATH (tried claude, codex, gh copilot, opencode). Install one to run agents."),null}catch(X){return console.warn("[ideawave-cli] runtime auto-seed failed",X),null}}var aZ=120000;function dZ(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class w1{sessions=new Map;createCallId;toolCallTimeoutMs;constructor(X={}){this.createCallId=X.createCallId??dZ,this.toolCallTimeoutMs=X.toolCallTimeoutMs??aZ}register(X){let $=this.sessions.get(X.frontendSessionId);if($){if($.userId!==X.userId)this.rejectPending($,"frontend session user changed"),$.activeRunIds.clear();this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:$.pendingToolCalls,activeRunIds:$.activeRunIds,activeRunCardIds:$.activeRunCardIds});return}this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:new Map,activeRunIds:new Set,activeRunCardIds:new Map})}disconnect(X,$="frontend session disconnected"){let Z=this.sessions.get(X);if(!Z)return{activeRunIds:[]};return this.sessions.delete(X),this.rejectPending(Z,$),{activeRunIds:Array.from(Z.activeRunIds)}}sessionCount(){return this.sessions.size}has(X){return this.sessions.has(X)}getUserId(X){return this.sessions.get(X)?.userId??null}setMetadata(X,$){let Z=this.sessions.get(X);if(Z)Z.tools=$}getMetadata(X){if(!X)return[];return this.sessions.get(X)?.tools??[]}sendToSession(X,$){let Z=this.sessions.get(X);if(!Z)return!1;return Z.send($),!0}callTool(X,$,Z,Q,K){if(!X)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let J=this.sessions.get(X);if(!J)return Promise.reject(Error(`Frontend session ${X} is not connected`));let Y=this.createCallId();return new Promise((j,z)=>{let W=Q??(K?this.getActiveRunIdForCard(J,K):this.getSoleActiveRunId(J)),V=K??(W?J.activeRunCardIds.get(W):void 0),B=Date.now(),L=setTimeout(()=>{J.pendingToolCalls.delete(Y),q("tool_queue.timeout",{frontendSessionId:X,runId:W,cardId:V,callId:Y,toolName:$,elapsedMs:Date.now()-B,queueDepth:J.pendingToolCalls.size}),z(Error(`Tool "${$}" timed out waiting for the frontend`))},this.toolCallTimeoutMs);J.pendingToolCalls.set(Y,{resolve:j,reject:z,timer:L,name:$,runId:W??null,cardId:V??null,startedAt:B}),q("tool_queue.forwarded_to_browser",{frontendSessionId:X,runId:W,cardId:V,callId:Y,toolName:$,queueDepth:J.pendingToolCalls.size}),J.send({type:"tool_call",callId:Y,name:$,args:Z,...W?{runId:W}:{},...V?{cardId:V}:{}})})}handleToolResult(X,$){let Z=this.sessions.get(X);if(!Z)return;let Q=Z.pendingToolCalls.get($.callId);if(!Q)return;if(Z.pendingToolCalls.delete($.callId),clearTimeout(Q.timer),q("tool_queue.result_received",{frontendSessionId:X,runId:Q.runId,cardId:Q.cardId,callId:$.callId,toolName:Q.name,elapsedMs:Date.now()-Q.startedAt,queueDepth:Z.pendingToolCalls.size,ok:$.ok}),$.ok){Q.resolve($.result);return}let K=$.result;if(K&&typeof K==="object"&&Array.isArray(K.content)){Q.resolve({...K,isError:!0});return}Q.reject(Error($.error??"Tool execution failed"))}markRunActive(X,$,Z){let Q=this.sessions.get(X);if(!Q)return;if(Q.activeRunIds.add($),Z)Q.activeRunCardIds.set($,Z)}markRunSettled(X,$){let Z=this.sessions.get(X);if(!Z)return;Z.activeRunIds.delete($),Z.activeRunCardIds.delete($)}ownsRun(X,$){return this.sessions.get(X)?.activeRunIds.has($)??!1}rejectPending(X,$){for(let Z of X.pendingToolCalls.values())clearTimeout(Z.timer),q("tool_queue.rejected",{frontendSessionId:X.frontendSessionId,runId:Z.runId,cardId:Z.cardId,toolName:Z.name,elapsedMs:Date.now()-Z.startedAt}),Z.reject(Error($));X.pendingToolCalls.clear()}getSoleActiveRunId(X){return X.activeRunIds.size===1?X.activeRunIds.values().next().value:void 0}getActiveRunIdForCard(X,$){let Z=[...X.activeRunCardIds.entries()].filter(([Q,K])=>X.activeRunIds.has(Q)&&K===$).map(([Q])=>Q);return Z.length===1?Z[0]:void 0}}function C2(){return"0.0.67".trim()?"0.0.67":"dev"}var iZ=process.argv.slice(2),f2=[];for(let X of iZ){if(X==="--dev"){process.env[VX]="1";continue}f2.push(X)}var K0=f2[0],P0=process.env.APP_ENV==="development"||process.env[VX]==="1";if(K0==="--help"||K0==="-h"||K0==="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(K0==="--version"||K0==="-v"||K0==="version")console.log(C2()),process.exit(0);if(K0)console.error(`Unknown command: ${K0}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var T0=new w1,z0=null,oZ=P0?{phase:"ready",message:"Local browser-kit proxy is ready"}:{phase:"idle"},F0=new t0;function Q0(X,$){T0.sendToSession(X,$)}async function nZ(X,$){try{let Z=q2[$.method],Q=await Z($.params);Q0(X,{type:"runtime_rpc_result",requestId:$.requestId,ok:!0,result:Q})}catch(Z){Q0(X,{type:"runtime_rpc_result",requestId:$.requestId,ok:!1,error:Z instanceof Error?Z.message:String(Z)})}}var E0=!1,b0=null;async function B1(){if(E0)return;if(b0)return b0;return b0=(async()=>{try{let X=await O2(T0);q1({...X,requestedPort:X.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${X.url}`);try{await l1({onStatusChange:($)=>{if(G$(),z0?.sendStatus(),$.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${$.packageName}: ${$.error??"unknown error"}`)}})}catch($){console.warn("[ideawave-cli] ACP bridge setup skipped:",$ instanceof Error?$.message:String($))}await _2(),E0=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),z0?.sendStatus()}catch(X){console.error("[ideawave-cli] failed to start agent host:",X),z0?.sendStatus(void 0,X instanceof Error?X.message:String(X))}finally{b0=null}})(),b0}if(process.env.APP_ENV!=="development"){let X=await G2();if(X)console.error(`[ideawave-cli] An IdeaWave CLI is already running at ${X}.`),console.error("[ideawave-cli] Only one CLI per machine is supported — it already serves every browser tab. Exiting."),process.exit(0)}if(!P0)n$().then((X)=>{if(X.phase==="ready")console.log("[ideawave-cli] screenshot engine ready");else if(X.phase==="failed")console.warn(`[ideawave-cli] screenshot engine setup failed: ${X.error??"unknown error"}`)});z0=await V2({registry:T0,runtime:null,mcpReady:()=>E0,capabilities:P0?[_1]:[],cliVersion:C2(),browserRuntimeStatus:()=>oZ,onToolMetadata:(X)=>{console.log(`[ideawave-cli] session ${X} advertised ${T0.getMetadata(X).length} tools`),B1()},onRunTurn:(X,$)=>{console.log(`[ideawave-cli] running agent turn for card ${$.cardId} (session ${X})`),(async()=>{if(await B1(),!E0){Q0(X,{type:"run_settled",runId:$.runId,cardId:$.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"IdeaWave CLI agent host is not ready",partialText:null}});return}await p$($,(Z)=>Q0(X,Z))})().catch(()=>{return}).finally(()=>T0.markRunSettled(X,$.runId))},onCancelRun:(X,$)=>{$1($)},onRuntimeRpc:(X,$)=>{nZ(X,$)},onBrowserRpc:(X,$,Z)=>{if(!P0){Q0(X,{type:"browser_rpc_result",requestId:Z.requestId,ok:!1,error:"The development browser-kit proxy is not enabled"});return}F0.handleRpc(X,$,Z).then((Q)=>{Q0(X,{type:"browser_rpc_result",requestId:Z.requestId,ok:!0,result:Q})},(Q)=>{Q0(X,{type:"browser_rpc_result",requestId:Z.requestId,ok:!1,error:Q instanceof Error?Q.message:String(Q)})})},onHttpRequest:(X,$)=>P0?F0.handleHttpRequest(X,$):!1,onHttpUpgrade:(X,$,Z)=>P0?F0.handleUpgrade(X,$,Z):!1,onWarmupRun:(X,$,Z)=>{(async()=>{if(await B1(),!E0)return{status:"retryable",error:"agent host is not ready"};return u$({cardId:$.cardId,boardId:$.boardId,userId:Z,frontendSessionId:X})})().then((Q)=>{if(!$.warmupId)return;Q0(X,{type:"warmup_result",warmupId:$.warmupId,cardId:$.cardId,...Q})})},onDisconnect:(X,$)=>{F0.closeFrontendSession(X),m$(X);for(let Z of $)$1(Z);q("bridge.frontend_disconnected",{frontendSessionId:X,activeRuns:$.length}),P1(X).catch((Z)=>{console.warn(`[ideawave-cli] failed to evict sessions for ${X}:`,Z instanceof Error?Z.message:String(Z))}),console.log(`[ideawave-cli] browser session ${X} disconnected`)}});F0.setPort(z0.port);console.log(`[ideawave-cli] browser bridge listening on ${z0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var A2=!1;for(let X of["SIGINT","SIGTERM"])process.once(X,()=>{if(A2)return;A2=!0,c$(),(async()=>{await F0.close(),await s$(),await z0?.close().catch(()=>{return}),process.exit(0)})()});
|
|
946
|
+
${Z}`),X.destroy()}function JZ(X,$){return new Promise((Z,Q)=>{let W=(Y)=>{X.off("listening",K),Q(Y)},K=()=>{X.off("error",W);let Y=X.address();if(!Y||typeof Y==="string"){Q(Error("Failed to read CLI bridge server address"));return}Z(Y.port)};X.once("error",W),X.once("listening",K),X.listen($,"127.0.0.1")})}function V2(X){return new Promise(($,Z)=>{X.close((Q)=>{if(Q)Z(Q);else $()})})}async function U2(X,$=G1()){let Z=new Map,Q=new Map,W=X.maxMessageSize??n3,K=!1,Y=(x)=>{let U=Q.get(x);if(U)clearTimeout(U);Q.delete(x)},V=(x)=>{Q.delete(x);let{activeRunIds:U}=X.registry.disconnect(x);X.onDisconnect(x,U)},z=(x,U)=>{let D={type:"cli_status",connected:!0,runtime:X.runtime,mcpReady:X.mcpReady(),error:U,capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()};if(x){let w=Z.get(x);if(w)L0(w,D);return}for(let w of Z.values())L0(w,D)},J=(x,U)=>{let D=U.sessionId.trim(),w=U.userId.trim();if(!D||!w){L0(x,{type:"cli_status",connected:!1,runtime:X.runtime,mcpReady:X.mcpReady(),error:"Missing frontend session or user id"}),x.close();return}Y(D);let H=Z.get(D);if(H&&H!==x)H.close();x.data.frontendSessionId=D,Z.set(D,x),X.registry.register({frontendSessionId:D,userId:w,tools:U.tools,send:(B)=>L0(x,B)}),z(D),X.onToolMetadata?.(D)},G=(x,U)=>{let D=X.registry.getUserId(x);if(!D)return;switch(U.type){case"bridge_ping":{let w=Z.get(x);if(w)L0(w,{type:"bridge_pong"});break}case"tool_metadata":X.registry.setMetadata(x,U.tools),X.onToolMetadata?.(x);break;case"tool_result":X.registry.handleToolResult(x,U);break;case"run_turn":q("bridge.run_received",{runId:U.run.runId,cardId:U.run.cardId,frontendSessionId:x}),X.registry.markRunActive(x,U.run.runId,U.run.cardId),X.onRunTurn(x,{...U.run,frontendSessionId:x,userId:D});break;case"cancel_run":if(X.registry.ownsRun(x,U.runId))X.onCancelRun(x,U.runId);break;case"runtime_rpc":X.onRuntimeRpc(x,U);break;case"browser_rpc":X.onBrowserRpc?.(x,Z.get(x)?.data.frontendOrigin??"",U);break;case"warmup_run":X.onWarmupRun(x,{...U,frontendSessionId:x},D);break;default:break}},M=(x,U)=>{let D=GX(x.headers.origin),w=z1(D),H={Vary:"Origin"};if(w&&D)H["Access-Control-Allow-Origin"]=D,H["Access-Control-Allow-Private-Network"]="true";if(x.method==="OPTIONS"){U.writeHead(204,{...H,"Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*","Access-Control-Max-Age":"600"}),U.end();return}if(x.method!=="GET"){U.writeHead(405,H),U.end();return}U.writeHead(200,{...H,"content-type":"application/json","cache-control":"no-store"}),U.end(JSON.stringify({ideawave:!0,runtime:X.runtime,mcpReady:X.mcpReady(),capabilities:X.capabilities??[],cliVersion:X.cliVersion,browserRuntime:X.browserRuntimeStatus?.()}))},L=(x,U)=>{let D=GX(x.headers.origin),w=z1(D),H={Vary:"Origin"};if(w&&D)H["Access-Control-Allow-Origin"]=D,H["Access-Control-Allow-Private-Network"]="true";if(x.method==="OPTIONS"){U.writeHead(204,{...H,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"content-type","Access-Control-Max-Age":"600"}),U.end();return}if(!w){U.writeHead(403,H),U.end();return}if(x.method!=="POST"){U.writeHead(405,H),U.end();return}let B={...H,"content-type":"application/json"},N=(P,j)=>{U.writeHead(P,B),U.end(JSON.stringify(j))},O="",C=!1;x.on("data",(P)=>{if(O+=P.toString("utf8"),O.length>e3)C=!0,x.destroy()}),x.on("end",()=>{if(C){N(400,{ok:!1,error:"Request body too large"});return}let P;try{P=JSON.parse(O)}catch{N(400,{ok:!1,error:"Invalid JSON body"});return}let j=typeof P.url==="string"?P.url:"";if(!W2(j)){N(400,{ok:!1,error:"url must be an http(s) loopback or /static_boards/ page URL"});return}let k=(_,b)=>{let d=typeof _==="number"?_:Number.NaN;if(!Number.isFinite(d))return b;return Math.min(4000,Math.max(200,Math.round(d)))};K2({url:j,width:k(P.width,1440),height:k(P.height,900)}).then((_)=>N(200,{ok:!0,path:_.path,engine:_.engine})).catch((_)=>{let b=_ instanceof R0?503:_ instanceof jX?429:500;N(b,{ok:!1,..._ instanceof R0?{installing:!0}:{},error:_ instanceof Error?_.message:String(_)})})})};for(let x of $){let U=i3((H,B)=>{(async()=>{let N=new URL(H.url??"/","http://127.0.0.1").pathname;if(N===X2){M(H,B);return}if(N===s3){L(H,B);return}if(await X.onHttpRequest?.(H,B))return;B.writeHead(404,{"content-type":"text/plain"}),B.end("IdeaWave CLI bridge")})().catch((N)=>{if(B.headersSent){B.destroy(N instanceof Error?N:void 0);return}B.writeHead(500,{"content-type":"text/plain"}),B.end("IdeaWave CLI bridge request failed")})}),D=new o3({noServer:!0,maxPayload:W}),w=(H)=>{if(H.idleTimer)clearTimeout(H.idleTimer);H.idleTimer=setTimeout(()=>{H.close()},t3),H.idleTimer.unref?.()};D.on("connection",(H,B)=>{let N=H;N.data={id:d3(),frontendSessionId:null,frontendOrigin:new URL(GX(B.headers.origin)??G2).origin},N.idleTimer=null,w(N),N.on("ping",()=>w(N)),N.on("pong",()=>w(N)),N.on("error",()=>{if(N.idleTimer)clearTimeout(N.idleTimer);N.close()}),N.on("message",(O)=>{w(N);let C=YZ(O);if(W>0&&C.length>W)return;let P=g0(C);if(!P)return;let j=N.data.frontendSessionId;if(!j){if(P.type==="bridge_probe")L0(N,{type:"bridge_probe_ack",protocolVersion:P.protocolVersion});else if(P.type==="frontend_hello")J(N,P);return}G(j,P)}),N.on("close",()=>{if(N.idleTimer)clearTimeout(N.idleTimer);let O=N.data.frontendSessionId;if(!O)return;if(Z.get(O)!==N)return;if(Z.delete(O),Y(O),K)return;Q.set(O,setTimeout(()=>V(O),r3))})}),U.on("upgrade",(H,B,N)=>{let O=new URL(H.url??"/","http://127.0.0.1").pathname;if(X.onHttpUpgrade?.(H,B,N))return;if(O!==j1){J2(B,404,"Not Found");return}if(!z1(GX(H.headers.origin))){J2(B,403,"Forbidden");return}D.handleUpgrade(H,B,N,(C)=>{D.emit("connection",C,H)})});try{let H=await JZ(U,x);return{url:`ws://127.0.0.1:${H}${j1}`,port:H,sendStatus:z,close:async()=>{K=!0;for(let B of Q.values())clearTimeout(B);Q.clear();for(let B of D.clients){let N=B;if(N.idleTimer)clearTimeout(N.idleTimer);N.close()}D.close(),await V2(U).catch(()=>{return})}}}catch(H){if(D.close(),await V2(U).catch(()=>{return}),H?.code==="EADDRINUSE")continue;throw H}}throw Error(`No free IdeaWave CLI bridge port found in ${$[0]}-${$.at(-1)}`)}import{lstat as BZ,readFile as FZ}from"node:fs/promises";import OZ from"node:os";import y0 from"node:path";import{Server as kZ}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as qZ,ListToolsRequestSchema as _Z}from"@modelcontextprotocol/sdk/types.js";import{randomUUID as jZ}from"node:crypto";import{createServer as GZ}from"node:http";import{StreamableHTTPServerTransport as zZ}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as w2}from"@modelcontextprotocol/sdk/types.js";var H2=new Set(["127.0.0.1","localhost","[::1]","::1"]);function VZ(X){let $=X.trim();if($.length===0)return null;if($.startsWith("[")){let K=$.indexOf("]");if(K===-1)return null;let Y=$.slice(0,K+1),V=$.slice(K+1);if(V.length===0)return{host:Y,port:null};if(!V.startsWith(":"))return null;let z=Number(V.slice(1));if(!Number.isInteger(z)||z<=0||z>65535)return null;return{host:Y,port:z}}let Z=$.lastIndexOf(":");if(Z===-1)return{host:$,port:null};let Q=$.slice(Z+1),W=Number(Q);if(!Number.isInteger(W)||W<=0||W>65535)return{host:$,port:null};return{host:$.slice(0,Z),port:W}}function x2(X){return H2.has(X)||H2.has(X.toLowerCase())}function D2(X,$){let Z=X.headers.host;if(typeof Z!=="string")return{ok:!1,status:403,reason:"missing-host"};let Q=VZ(Z);if(!Q)return{ok:!1,status:403,reason:"bad-host"};if(!x2(Q.host))return{ok:!1,status:403,reason:"non-loopback-host"};if(Q.port!==null&&Q.port!==$)return{ok:!1,status:403,reason:"host-port-mismatch"};let W=X.headers.origin;if(typeof W==="string"&&W.length>0){if(W!=="null"){let K;try{K=new URL(W)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!x2(K.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var N2="/mcp",UZ=43274,P2=16777216,HZ=1800000,xZ=300000,M2=200,DZ=-32700,Z0=-32600,U1=-32603;function l(X,$,Z,Q,W){X.statusCode=$,X.setHeader("content-type","application/json"),X.end(JSON.stringify({jsonrpc:"2.0",error:{code:Z,message:Q,...W?{data:W}:{}},id:null}))}class H1 extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class x1 extends Error{constructor(){super(`body exceeds ${P2} bytes`);this.name="BodyTooLargeError"}}async function wZ(X){if(X.method&&X.method!=="POST")return;let $=X.headers["content-type"];if(typeof $==="string"&&$.trim().length>0){if(!$.toLowerCase().includes("application/json"))throw new H1}let Z=0,Q=[];for await(let K of X){let Y=typeof K==="string"?Buffer.from(K):K;if(Z+=Y.byteLength,Z>P2)throw new x1;Q.push(Y)}if(Q.length===0)return;let W=Buffer.concat(Q).toString("utf8");if(W.length===0)return;return JSON.parse(W)}function NZ(X){if(Array.isArray(X))return X.some(w2);return w2(X)}function MZ(X){if(typeof X==="number")return X;let $=process.env.IDEAWAVE_MCP_PORT;if($&&$.trim().length>0){let Z=Number($);if(Number.isInteger(Z)&&Z>=0&&Z<65536)return Z}return UZ}async function PZ(X,$){let Z=(W)=>new Promise((K,Y)=>{let V=(J)=>{X.off("listening",z),Y(J)},z=()=>{X.off("error",V),K()};X.once("error",V),X.once("listening",z),X.listen(W,"127.0.0.1")});try{await Z($)}catch(W){if(W.code!=="EADDRINUSE"||$===0)throw W;console.warn(`[mcp] port ${$} in use, falling back to an OS-assigned port; external CLIs will need to re-paste the install command from Settings → External agents`),await Z(0)}let Q=X.address();if(Q==null||typeof Q==="string")throw Error("[mcp] failed to read bound address");return Q.port}function LZ(X,$){if($&&typeof $==="object"&&!Array.isArray($)){let Q=$.params;if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let W=Q.clientInfo;if(W&&typeof W==="object"&&!Array.isArray(W)){let K=W.name;if(typeof K==="string"&&K.trim().length>0)return K.trim()}}}let Z=X.headers["user-agent"];if(typeof Z==="string"&&Z.trim().length>0)return Z.trim();return null}async function L2(X){let $=new Map,Z=0;function Q(J){let G=$.get(J);if(G)G.lastActivity=Date.now()}async function W(J,G){$.delete(J),await G.transport.close().catch(()=>{return})}async function K(){let J=null,G=1/0;for(let[M,L]of $)if(L.lastActivity<G)G=L.lastActivity,J=M;if(J!==null){let M=$.get(J);if(M)console.warn(`[mcp] session cap of ${M2} reached; evicting ${J}`),await W(J,M)}}let Y=setInterval(()=>{let J=Date.now()-HZ;for(let[G,M]of $)if(M.lastActivity<J)console.log(`[mcp] sweeping idle session ${G}`),W(G,M)},xZ);Y.unref?.();let V=GZ((J,G)=>{(async()=>{let M;try{M=new URL(J.url??"/","http://127.0.0.1").pathname}catch{l(G,400,Z0,"bad-url");return}if(M!==N2){l(G,404,Z0,"not-found");return}let L=J.method??"POST";if(L!=="POST"&&L!=="GET"&&L!=="DELETE"){G.setHeader("Allow","GET, POST, DELETE"),l(G,405,Z0,"method-not-allowed");return}let x=D2(J,Z);if(!x.ok){l(G,x.status,Z0,"forbidden",{reason:x.reason});return}let U=J.headers["mcp-session-id"],D=typeof U==="string"?U:void 0;if(L==="GET"||L==="DELETE"){if(!D||!$.has(D)){l(G,400,Z0,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let B=$.get(D).transport;Q(D);try{await B.handleRequest(J,G)}catch(N){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",N),!G.headersSent)l(G,500,U1,"internal")}return}let w;try{w=await wZ(J)}catch(B){if(B instanceof H1){l(G,415,Z0,"expected-application-json");return}if(B instanceof x1){l(G,413,Z0,"body-too-large");return}l(G,400,DZ,"invalid-json");return}let H;if(D&&$.has(D))H=$.get(D).transport,Q(D);else if(!D&&w!==void 0&&NZ(w)){let B=J.headers["x-ideawave-user-id"],N=typeof B==="string"&&B.trim().length>0?B.trim():null,O=J.headers["x-ideawave-frontend-session-id"],C=typeof O==="string"&&O.trim().length>0?O.trim():null,P=J.headers["x-ideawave-tool-surface"],j=typeof P==="string"&&P.trim()==="read"?"read":"full",k=J.headers["x-ideawave-images-supported"],_=typeof k==="string"&&k.trim()==="1",b=J.headers["x-ideawave-card-id"],d=typeof b==="string"&&b.trim().length>0?b.trim():null,n=J.headers["x-ideawave-board-id"],A=typeof n==="string"&&n.trim().length>0?n.trim():null,v=J.headers["x-ideawave-run-folder"],y=typeof v==="string"&&v.trim().length>0?v.trim():null,I=LZ(J,w);if($.size>=M2)await K();let h=null,K0=new zZ({sessionIdGenerator:()=>jZ(),onsessioninitialized:(U0)=>{h=U0,$.set(U0,{transport:K0,lastActivity:Date.now()})},onsessionclosed:(U0)=>{$.delete(U0)}});K0.onclose=()=>{if(K0.sessionId)$.delete(K0.sessionId)};try{await X.buildServer({userId:N,frontendSessionId:C,boardId:A,toolSurface:j,imagesSupported:_,cardId:d,runFolder:y,clientHint:I}).connect(K0)}catch(U0){if(console.error("[mcp] buildServer/connect failed",U0),h)$.delete(h);await K0.close().catch(()=>{return}),l(G,500,U1,"server-init-failed");return}H=K0}else{l(G,400,Z0,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await H.handleRequest(J,G,w)}catch(B){if(console.error("[mcp] transport.handleRequest threw",B),!G.headersSent)l(G,500,U1,"internal")}})().catch((M)=>{console.error("[mcp] unhandled request handler error:",M)})});return Z=await PZ(V,MZ(X.port)),{url:`http://127.0.0.1:${Z}${N2}`,port:Z,close:async()=>{clearInterval(Y);for(let J of $.values())await J.transport.close().catch(()=>{return});$.clear(),await new Promise((J)=>V.close(()=>J()))}}}var AZ={name:"ideawave-board",version:"1.0.0"},zX="list_run_folder",UX="read_run_folder_file",O2=new Set(["list_boards","get_board","screenshot_board","list_nodes","list_edges","inspect_node","list_context_sources","read_context_card","read_context_file","read_context_image","list_context_folder","get_board_wiki","search_board","get_card_messages","list_agent_cards","inspect_neighbors",zX,UX]),k2=new Set(["inspect_diagram"]),CZ=[{name:zX,description:"List visible files and folders under the selected runtime run folder. Hidden/config folders are omitted.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Optional relative path inside the selected run folder. Defaults to the run-folder root."}},additionalProperties:!1}},{name:UX,description:"Read a text file inside the selected runtime run folder. Hidden/config paths and outside-folder paths are denied.",inputSchema:{type:"object",properties:{path:{type:"string",description:"Relative path to a text file inside the selected run folder."}},required:["path"],additionalProperties:!1}}];function D1(X){return{content:[{type:"text",text:X}]}}function RZ(X){return D1(JSON.stringify(X,null,2))}function B2(X){return{...D1(X),isError:!0}}async function fZ(X,$){if(!$||X.isError)return X;let Z=X.content.find((K)=>K.type==="text");if(!Z)return X;let Q;try{let K=JSON.parse(Z.text);if(typeof K.path!=="string")return X;Q=y0.resolve(K.path)}catch{return X}let W=y0.resolve(y0.join(OZ.tmpdir(),"ideawave-screenshots"));if(y0.dirname(Q)!==W||!/^board-[a-z0-9-]+\.png$/i.test(y0.basename(Q)))return X;try{if(!(await BZ(Q)).isFile())return X;let Y=await FZ(Q);if(Y.byteLength<1024||Y.byteLength>26214400||!Y.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return X;return{...X,content:[...X.content,{type:"image",data:Y.toString("base64"),mimeType:"image/png"}]}}catch{return X}}function yZ(X,$,Z="full",Q=!1){return X.getMetadata($).filter((W)=>{let K=$X(W.name);if(Z==="read"&&!O2.has(K))return!1;if(!Q&&k2.has(K))return!1;return!0}).map((W)=>({name:W.name,description:W.description,inputSchema:W.inputSchema}))}function bZ(X,$,Z={}){let Q=yZ(X,$,Z.toolSurface??"full",Z.imagesSupported??!1);return Z.includeRunFolderTools?[...Q,...CZ]:Q}function F2(X,$){if(!X||typeof X!=="object"||Array.isArray(X))return null;let Z=X[$];return typeof Z==="string"?Z:null}async function EZ(X,$,Z){if(Z&&Z.trim().length>0)return Z.trim();if(!X||!$)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await X0({boardId:X,cardId:$})).runFolder}async function TZ(X){let $=await EZ(X.boardId,X.cardId,X.runFolder);if(X.name===zX){let Z=F2(X.args,"path")??"",Q=await L$($,Z);return RZ(Q)}if(X.name===UX){let Z=F2(X.args,"path");if(!Z)return B2("read_run_folder_file requires a path.");return D1(await XX($,Z))}return B2(`Unknown local tool "${X.name}"`)}function vZ(X,$,Z,Q,W,K="full",Y=!1){let V=new kZ(AZ,{capabilities:{tools:{}}}),z=async()=>{if(Y)return!0;if(m$(Q))return!0;if(Z&&Q)try{return(await X0({boardId:Z,cardId:Q})).adapter.supportsImages===!0}catch{return!1}return!1};return V.setRequestHandler(_Z,async()=>({tools:bZ(X,$,{includeRunFolderTools:Boolean(W||Z&&Q),toolSurface:K,imagesSupported:await z()})})),V.setRequestHandler(qZ,async(J)=>{let{name:G,arguments:M}=J.params,L=$X(G),x=Date.now();q("mcp.tool_call_received",{frontendSessionId:$,cardId:Q,toolName:L});try{if(L===zX||L===UX)return await TZ({name:L,args:M,boardId:Z,cardId:Q,runFolder:W});if(K==="read"&&!O2.has(L))throw Error(`Tool "${G}" is not available in read-only mode`);if(k2.has(L)&&!await z())throw Error(`Tool "${G}" requires a runtime that supports image input`);let U=await X.callTool($,L,M??{},void 0,Q??void 0);if(q("mcp.tool_result_returned",{frontendSessionId:$,cardId:Q,toolName:L,elapsedMs:Date.now()-x}),U&&typeof U==="object"&&Array.isArray(U.content)){let D=U;return L==="screenshot_board"?await fZ(D,await z()):D}return{content:[{type:"text",text:typeof U==="string"?U:JSON.stringify(U)}]}}catch(U){return q("mcp.tool_result_returned",{frontendSessionId:$,cardId:Q,toolName:L,elapsedMs:Date.now()-x,hasError:!0}),{content:[{type:"text",text:U instanceof Error?U.message:"Tool call failed"}],isError:!0}}}),V}function q2(X,$){return L2({buildServer:(Z)=>vZ(X,Z.frontendSessionId,Z.boardId,Z.cardId,Z.runFolder,Z.toolSurface,Z.imagesSupported),port:$})}import HX from"node:fs/promises";import w1 from"node:os";import xX from"node:path";function _2(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function hZ(){let[X,$]=await Promise.all([m(),V$()]),Z=X.globalDefaultConfigId?X.runtimes.find((Q)=>Q.id===X.globalDefaultConfigId)??null:null;return{runtimes:X.runtimes,globalDefaultConfigId:X.globalDefaultConfigId,globalDefaultEffective:Z?{runFolder:Z.runFolder??w1.homedir(),modelId:Z.defaultModelId??null,configValues:Z.defaultConfigValues??{}}:null,knownAdapters:D0().map((Q)=>({id:Q.id,displayName:Q.displayName})),readiness:$}}async function IZ(X){try{let $=await X0({boardId:X.boardId,cardId:X.cardId});return{resolved:{configId:$.entry.id,adapterId:$.entry.kind==="registered"?$.entry.adapterId:null,displayName:$.entry.displayName,runFolder:$.runFolder,modelId:$.modelId,configValues:$.configValues}}}catch($){if($ instanceof Y0)return{resolved:null};throw $}}async function SZ(X){return p(($)=>{let Z=$.runtimes.find((K)=>K.kind==="registered"&&K.adapterId===X.adapterId);if(Z)return Z;let Q=D0().find((K)=>K.id===X.adapterId);if(!Q)throw Error(`Unknown adapterId: ${X.adapterId}`);let W={id:_2(),kind:"registered",adapterId:X.adapterId,displayName:Q.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return $.runtimes.push(W),W})}async function gZ(X){return p(($)=>{let Z={id:_2(),kind:"custom",displayName:X.displayName,command:X.command,args:X.args,env:X.env,runFolder:X.runFolder,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return $.runtimes.push(Z),Z})}async function mZ(X){await p(($)=>{if($.runtimes=$.runtimes.filter((Z)=>Z.id!==X.runtimeConfigId),$.globalDefaultConfigId===X.runtimeConfigId)$.globalDefaultConfigId=null;for(let Z of Object.keys($.boardOverrides))if($.boardOverrides[Z].runtimeConfigId===X.runtimeConfigId)delete $.boardOverrides[Z];for(let Z of Object.keys($.cardOverrides))if($.cardOverrides[Z].runtimeConfigId===X.runtimeConfigId)delete $.cardOverrides[Z]})}async function cZ(X){await p(($)=>{let Z=$.runtimes.find((Q)=>Q.id===X.runtimeConfigId);if(!Z)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);if($.globalDefaultConfigId=X.runtimeConfigId,X.runFolder!==void 0)Z.runFolder=X.runFolder;if(X.modelId!==void 0)Z.defaultModelId=X.modelId;if(X.configValues!==void 0)Z.defaultConfigValues=X.configValues})}async function lZ(X){X.boardId,await p(($)=>{if(X.runtimeConfigId===null){delete $.cardOverrides[X.cardId];return}if(!$.runtimes.some((W)=>W.id===X.runtimeConfigId))throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let Q=$.cardOverrides[X.cardId];$.cardOverrides[X.cardId]={runtimeConfigId:X.runtimeConfigId,runFolder:X.runFolder!==void 0?X.runFolder:Q?.runFolder??null,modelId:X.modelId!==void 0?X.modelId:Q?.modelId??null,configValues:X.configValues!==void 0?X.configValues:Q?.configValues??{}}})}async function pZ(X){let Z=(await m()).runtimes.find((Y)=>Y.id===X.runtimeConfigId);if(!Z)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let Q=a(Z),W=await Q.resolveSpawnConfig(Z),K=Z.runFolder??w1.homedir();try{let Y=await h$({spawn:{...W,cwd:K},modelId:X.modelId??Z.defaultModelId??null,configValues:X.configValues??Z.defaultConfigValues??{}}),V=s0({adapterId:Q.id,models:Y.models,currentModelId:Y.currentModelId}),z=new Date().toISOString();return await p((J)=>{let G=J.runtimes.find((M)=>M.id===X.runtimeConfigId);if(G)G.discoveredModels=V,G.discoveredConfigOptions=Y.configOptions,G.discoveredAt=z}),{ok:!0,models:V,configOptions:Y.configOptions,currentModelId:Y.currentModelId}}catch(Y){if(Y instanceof H0)throw Error(`${Y.message}${Q.authHint?` ${Q.authHint}`:""}`);if(Y instanceof R||Y instanceof u)throw Error(Y.message);throw Y}}async function uZ(X){let $=w1.homedir(),Z=X.path?.trim()?X.path.trim():$,Q=xX.resolve(Z),W=!0;try{if(!(await HX.stat(Q)).isDirectory())Q=xX.dirname(Q)}catch{W=!1,Q=$}let K=[];try{K=(await HX.readdir(Q,{withFileTypes:!0})).filter((z)=>z.isDirectory()&&!z.name.startsWith(".")).map((z)=>({name:z.name,path:xX.join(Q,z.name)})).sort((z,J)=>z.name.localeCompare(J.name))}catch{K=[]}let Y=xX.dirname(Q);return{path:Q,parent:Y===Q?null:Y,home:$,exists:W,entries:K}}var A2={list:hZ,getEffectiveForCard:IZ,registerRegistered:SZ,registerCustom:gZ,unregister:mZ,setUserDefault:cZ,setCardOverride:lZ,refreshModels:pZ,browseFolder:uZ};var aZ=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function dZ(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function C2(){try{let X=await m();if(X.globalDefaultConfigId){if(X.runtimes.some((Z)=>Z.id===X.globalDefaultConfigId))return X.globalDefaultConfigId}for(let $ of aZ){if((await j$($.id))?.status!=="ready")continue;let Q=null;if(await p((W)=>{if(W.globalDefaultConfigId){if(W.runtimes.some((V)=>V.id===W.globalDefaultConfigId)){Q=W.globalDefaultConfigId;return}}let K=W.runtimes.find((Y)=>Y.kind==="registered"&&Y.adapterId===$.id);if(!K){let Y={id:dZ(),kind:"registered",adapterId:$.id,displayName:$.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};W.runtimes.push(Y),K=Y}W.globalDefaultConfigId=K.id,Q=K.id}),Q)return console.log(`[ideawave-cli] using agent runtime: ${$.displayName}`),Q}return console.warn("[ideawave-cli] no agent runtime detected on PATH (tried claude, codex, gh copilot, opencode). Install one to run agents."),null}catch(X){return console.warn("[ideawave-cli] runtime auto-seed failed",X),null}}var iZ=120000;function oZ(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class N1{sessions=new Map;createCallId;toolCallTimeoutMs;constructor(X={}){this.createCallId=X.createCallId??oZ,this.toolCallTimeoutMs=X.toolCallTimeoutMs??iZ}register(X){let $=this.sessions.get(X.frontendSessionId);if($){if($.userId!==X.userId)this.rejectPending($,"frontend session user changed"),$.activeRunIds.clear();this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:$.pendingToolCalls,activeRunIds:$.activeRunIds,activeRunCardIds:$.activeRunCardIds});return}this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:new Map,activeRunIds:new Set,activeRunCardIds:new Map})}disconnect(X,$="frontend session disconnected"){let Z=this.sessions.get(X);if(!Z)return{activeRunIds:[]};return this.sessions.delete(X),this.rejectPending(Z,$),{activeRunIds:Array.from(Z.activeRunIds)}}sessionCount(){return this.sessions.size}has(X){return this.sessions.has(X)}getUserId(X){return this.sessions.get(X)?.userId??null}setMetadata(X,$){let Z=this.sessions.get(X);if(Z)Z.tools=$}getMetadata(X){if(!X)return[];return this.sessions.get(X)?.tools??[]}sendToSession(X,$){let Z=this.sessions.get(X);if(!Z)return!1;return Z.send($),!0}callTool(X,$,Z,Q,W){if(!X)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let K=this.sessions.get(X);if(!K)return Promise.reject(Error(`Frontend session ${X} is not connected`));let Y=this.createCallId();return new Promise((V,z)=>{let J=Q??(W?this.getActiveRunIdForCard(K,W):this.getSoleActiveRunId(K)),G=W??(J?K.activeRunCardIds.get(J):void 0),M=Date.now(),L=setTimeout(()=>{K.pendingToolCalls.delete(Y),q("tool_queue.timeout",{frontendSessionId:X,runId:J,cardId:G,callId:Y,toolName:$,elapsedMs:Date.now()-M,queueDepth:K.pendingToolCalls.size}),z(Error(`Tool "${$}" timed out waiting for the frontend`))},this.toolCallTimeoutMs);K.pendingToolCalls.set(Y,{resolve:V,reject:z,timer:L,name:$,runId:J??null,cardId:G??null,startedAt:M}),q("tool_queue.forwarded_to_browser",{frontendSessionId:X,runId:J,cardId:G,callId:Y,toolName:$,queueDepth:K.pendingToolCalls.size}),K.send({type:"tool_call",callId:Y,name:$,args:Z,...J?{runId:J}:{},...G?{cardId:G}:{}})})}handleToolResult(X,$){let Z=this.sessions.get(X);if(!Z)return;let Q=Z.pendingToolCalls.get($.callId);if(!Q)return;if(Z.pendingToolCalls.delete($.callId),clearTimeout(Q.timer),q("tool_queue.result_received",{frontendSessionId:X,runId:Q.runId,cardId:Q.cardId,callId:$.callId,toolName:Q.name,elapsedMs:Date.now()-Q.startedAt,queueDepth:Z.pendingToolCalls.size,ok:$.ok}),$.ok){Q.resolve($.result);return}let W=$.result;if(W&&typeof W==="object"&&Array.isArray(W.content)){Q.resolve({...W,isError:!0});return}Q.reject(Error($.error??"Tool execution failed"))}markRunActive(X,$,Z){let Q=this.sessions.get(X);if(!Q)return;if(Q.activeRunIds.add($),Z)Q.activeRunCardIds.set($,Z)}markRunSettled(X,$){let Z=this.sessions.get(X);if(!Z)return;Z.activeRunIds.delete($),Z.activeRunCardIds.delete($)}ownsRun(X,$){return this.sessions.get(X)?.activeRunIds.has($)??!1}rejectPending(X,$){for(let Z of X.pendingToolCalls.values())clearTimeout(Z.timer),q("tool_queue.rejected",{frontendSessionId:X.frontendSessionId,runId:Z.runId,cardId:Z.cardId,toolName:Z.name,elapsedMs:Date.now()-Z.startedAt}),Z.reject(Error($));X.pendingToolCalls.clear()}getSoleActiveRunId(X){return X.activeRunIds.size===1?X.activeRunIds.values().next().value:void 0}getActiveRunIdForCard(X,$){let Z=[...X.activeRunCardIds.entries()].filter(([Q,W])=>X.activeRunIds.has(Q)&&W===$).map(([Q])=>Q);return Z.length===1?Z[0]:void 0}}function f2(){return"0.0.68".trim()?"0.0.68":"dev"}var nZ=process.argv.slice(2),P1=Y2(nZ,process.env);if(P1.allowRailwayPrPreviews)process.env[f0]="1";var W0=P1.cliArgs[0],{browserKitEnabled:E0,captureEngineEnabled:tZ}=P1;if(W0==="--help"||W0==="-h"||W0==="help")console.log("ideawave — host the local bridge for a running ideawave.app session."),console.log(""),console.log("Usage:"),console.log(" ideawave Serve the browser bridge and MCP forwarder."),console.log(" ideawave --version Print the CLI version."),process.exit(0);if(W0==="--version"||W0==="-v"||W0==="version")console.log(f2()),process.exit(0);if(W0)console.error(`Unknown command: ${W0}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var T0=new N1,z0=null,rZ=E0?{phase:"ready",message:"Local browser-kit proxy is ready"}:{phase:"idle"},B0=new r0;function Q0(X,$){T0.sendToSession(X,$)}async function sZ(X,$){try{let Z=A2[$.method],Q=await Z($.params);Q0(X,{type:"runtime_rpc_result",requestId:$.requestId,ok:!0,result:Q})}catch(Z){Q0(X,{type:"runtime_rpc_result",requestId:$.requestId,ok:!1,error:Z instanceof Error?Z.message:String(Z)})}}var v0=!1,b0=null;async function M1(){if(v0)return;if(b0)return b0;return b0=(async()=>{try{let X=await q2(T0);_1({...X,requestedPort:X.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${X.url}`);try{await p1({onStatusChange:($)=>{if(G$(),z0?.sendStatus(),$.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${$.packageName}: ${$.error??"unknown error"}`)}})}catch($){console.warn("[ideawave-cli] ACP bridge setup skipped:",$ instanceof Error?$.message:String($))}await C2(),v0=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),z0?.sendStatus()}catch(X){console.error("[ideawave-cli] failed to start agent host:",X),z0?.sendStatus(void 0,X instanceof Error?X.message:String(X))}finally{b0=null}})(),b0}if(process.env.APP_ENV!=="development"){let X=await z2();if(X)console.error(`[ideawave-cli] An IdeaWave CLI is already running at ${X}.`),console.error("[ideawave-cli] Only one CLI per machine is supported — it already serves every browser tab. Exiting."),process.exit(0)}if(tZ)t$().then((X)=>{if(X.phase==="ready")console.log("[ideawave-cli] screenshot engine ready");else if(X.phase==="failed")console.warn(`[ideawave-cli] screenshot engine setup failed: ${X.error??"unknown error"}`)});z0=await U2({registry:T0,runtime:null,mcpReady:()=>v0,capabilities:E0?[A1]:[],cliVersion:f2(),browserRuntimeStatus:()=>rZ,onToolMetadata:(X)=>{console.log(`[ideawave-cli] session ${X} advertised ${T0.getMetadata(X).length} tools`),M1()},onRunTurn:(X,$)=>{console.log(`[ideawave-cli] running agent turn for card ${$.cardId} (session ${X})`),(async()=>{if(await M1(),!v0){Q0(X,{type:"run_settled",runId:$.runId,cardId:$.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"IdeaWave CLI agent host is not ready",partialText:null}});return}await u$($,(Z)=>Q0(X,Z))})().catch(()=>{return}).finally(()=>T0.markRunSettled(X,$.runId))},onCancelRun:(X,$)=>{$1($)},onRuntimeRpc:(X,$)=>{sZ(X,$)},onBrowserRpc:(X,$,Z)=>{if(!E0){Q0(X,{type:"browser_rpc_result",requestId:Z.requestId,ok:!1,error:"The development browser-kit proxy is not enabled"});return}B0.handleRpc(X,$,Z).then((Q)=>{Q0(X,{type:"browser_rpc_result",requestId:Z.requestId,ok:!0,result:Q})},(Q)=>{Q0(X,{type:"browser_rpc_result",requestId:Z.requestId,ok:!1,error:Q instanceof Error?Q.message:String(Q)})})},onHttpRequest:(X,$)=>E0?B0.handleHttpRequest(X,$):!1,onHttpUpgrade:(X,$,Z)=>E0?B0.handleUpgrade(X,$,Z):!1,onWarmupRun:(X,$,Z)=>{(async()=>{if(await M1(),!v0)return{status:"retryable",error:"agent host is not ready"};return a$({cardId:$.cardId,boardId:$.boardId,userId:Z,frontendSessionId:X})})().then((Q)=>{if(!$.warmupId)return;Q0(X,{type:"warmup_result",warmupId:$.warmupId,cardId:$.cardId,...Q})})},onDisconnect:(X,$)=>{B0.closeFrontendSession(X),c$(X);for(let Z of $)$1(Z);q("bridge.frontend_disconnected",{frontendSessionId:X,activeRuns:$.length}),F1(X).catch((Z)=>{console.warn(`[ideawave-cli] failed to evict sessions for ${X}:`,Z instanceof Error?Z.message:String(Z))}),console.log(`[ideawave-cli] browser session ${X} disconnected`)}});B0.setPort(z0.port);console.log(`[ideawave-cli] browser bridge listening on ${z0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var R2=!1;for(let X of["SIGINT","SIGTERM"])process.once(X,()=>{if(R2)return;R2=!0,l$(),(async()=>{await B0.close(),await e$(),await z0?.close().catch(()=>{return}),process.exit(0)})()});
|