ideawave 0.0.100 → 0.0.101
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/dist/index.mjs +2 -2
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1140,7 +1140,7 @@ ${Y}`:null].filter(Boolean).join(`
|
|
|
1140
1140
|
|
|
1141
1141
|
${Z}`)}function oX(X){if(!Array.isArray(X))return null;let Z=X.flatMap((W)=>{if(!W||typeof W!=="object")return[];let Q=W;if(typeof Q.path!=="string"||!Q.path.trim())return[];let Y=typeof Q.line==="number"?`:${Q.line}`:"";return[`${Q.path}${Y}`]});return Z.length>0?Z.slice(0,5):null}function T4(X){let{ctx:Z,appendText:W,appendToolActivity:Q}=X,Y=X.flushIntervalMs??EW,z="",j="",F=0,L=null,U=!1,w={},P=new Map,C=(x)=>{if(P.set(x.toolCallId,x),!Q)return;Q({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,entry:x}).catch((b)=>{console.warn("[streamAdapter] appendToolActivity failed",b)})},h=(x)=>{let b=`${Z.runId}:thought`,y=P.get(b);if(!y||y.status!=="running")return;C({...y,status:"completed",completedAt:y.completedAt??x})},D=(x)=>{for(let b of P.values()){if(b.status!=="running"||b.rawTitle.toLowerCase()!=="toolsearch")continue;C({...b,status:"completed",completedAt:b.completedAt??x})}},G=(x)=>{for(let b of Array.from(P.values())){if(b.status!=="running")continue;if(b.kind==="thought"||b.rawTitle==="agent_thought")continue;C({...b,status:"completed",completedAt:b.completedAt??x})}},N="",v=0,O=null,M=null,g=(x)=>{if(x===N)return;N=x,v=Date.now(),W({boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId,text:x}).catch((b)=>{console.warn("[streamAdapter] appendText failed",b)})},$=()=>{if(O!==null)clearTimeout(O),O=null;if(M!==null){let x=M;M=null,g(x)}},A=(x)=>{let b=Date.now()-v;if(b>=Y&&O===null){g(x);return}if(M=x,O===null){let y=Math.max(0,Y-b);O=setTimeout(()=>{O=null,$()},y)}};return{onSessionUpdate:async(x)=>{X.onAnyUpdate?.();let b=x.update;switch(w[b.sessionUpdate]=(w[b.sessionUpdate]??0)+1,b.sessionUpdate){case"agent_message_chunk":{let y=new Date().toISOString();if(h(y),b.content.type==="text"){if(b.content.text.length>0){if(U&&z.length>0&&!/\s$/.test(z)&&!/^\s/.test(b.content.text))z+=`
|
|
1142
1142
|
|
|
1143
|
-
`;z+=b.content.text,U=!1,A(z)}}else{let _=`agent_message_chunk:${b.content.type}`;w[_]=(w[_]??0)+1}return}case"agent_thought_chunk":{if(b.content.type!=="text")return;j+=b.content.text;let y=new Date().toISOString(),_=`${Z.runId}:thought`,I=P.get(_);C({toolCallId:_,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:I?.startedAt??y,completedAt:null,contentPreview:p0(j.trim())});return}case"user_message_chunk":return;case"tool_call":{F+=1,U=z.length>0;let y=S4(b.title),_=iX(b.status),I=new Date().toISOString();h(I),D(I),C({toolCallId:b.toolCallId,rawTitle:y,title:rX(y,b.rawInput),kind:pX(b.kind),status:_,startedAt:I,completedAt:_==="running"?null:I,inputPreview:D0(b.rawInput),outputPreview:sX(b.rawOutput),contentPreview:_2(b.content),locations:oX(b.locations)});return}case"tool_call_update":{let y=P.get(b.toolCallId);if(!y){let C0=S4(b.title),n=iX(b.status),S=new Date().toISOString();C({toolCallId:b.toolCallId,rawTitle:C0,title:rX(C0,b.rawInput),kind:pX(b.kind),status:n,startedAt:S,completedAt:n==="running"?null:S,inputPreview:D0(b.rawInput),outputPreview:sX(b.rawOutput),contentPreview:_2(b.content),locations:oX(b.locations)});return}let _=b.status===void 0||b.status===null?y.status:iX(b.status),I=typeof b.title==="string"&&b.title.trim().length>0?b.title:y.rawTitle,l=typeof b.title==="string"&&b.title.trim().length>0,k=_==="running"?y.completedAt:y.completedAt??new Date().toISOString(),r=b.content===void 0?y.contentPreview:I4(y.contentPreview,_2(b.content)),W0=b.rawOutput===void 0?y.outputPreview:I4(y.outputPreview,sX(b.rawOutput));C({...y,rawTitle:I,title:l?rX(I,b.rawInput):y.title,kind:b.kind===void 0?y.kind:pX(b.kind),status:_,completedAt:k,inputPreview:b.rawInput===void 0?y.inputPreview:D0(b.rawInput),outputPreview:W0,contentPreview:r,locations:b.locations===void 0?y.locations:oX(b.locations)});return}case"plan":L=b.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>z,getToolCallCount:()=>F,getLatestPlan:()=>L,getUpdateTypeCounts:()=>({...w}),flush:(x)=>{let b=new Date().toISOString();if(h(b),x?.completeOpenToolCalls)G(b);$()}}}var mW=new Set(["ECONNRESET","EPIPE"]);function S2(X){if(!X||typeof X!=="object")return!1;if(X instanceof Error&&X.message==="ACP connection closed")return!0;let Z="code"in X?X.code:void 0;return typeof Z==="string"&&mW.has(Z)}var T1=1,l4=-32000;function _0(X){return typeof X==="number"&&Number.isSafeInteger(X)&&X>=0?X:null}function _W(X){if(!X)return{status:"unreported"};let Z=_0(X.totalTokens),W=_0(X.inputTokens),Q=_0(X.outputTokens);if(Z===null||W===null||Q===null)return{status:"unreported"};let Y=_0(X.thoughtTokens),z=_0(X.cachedReadTokens),j=_0(X.cachedWriteTokens);return{status:"reported",totalTokens:Z,inputTokens:W,outputTokens:Q,...Y===null?{}:{thoughtTokens:Y},...z===null?{}:{cachedReadTokens:z},...j===null?{}:{cachedWriteTokens:j}}}function kW(X){if(!X)return null;if(typeof X.amount!=="number"||!Number.isFinite(X.amount)||X.amount<0||typeof X.currency!=="string"||X.currency.trim().length===0)return null;return{amount:X.amount,currency:X.currency}}function SW(X){let Z=_0(X.used),W=_0(X.size);return Z===null||W===null?null:{usedTokens:Z,windowTokens:W}}function AW(X){let Z=X.latestCost;if(!Z)return{status:"unreported",reason:"omitted"};let W=X.baselineCost;if(!W){if(X.zeroBaseline)return{status:"reported",amount:Z.amount,currency:Z.currency};return{status:"unreported",reason:"baseline_unavailable"}}if(W.currency!==Z.currency)return{status:"unreported",reason:"currency_mismatch"};if(Z.amount<W.amount)return{status:"unreported",reason:"counter_reset"};return{status:"reported",amount:Z.amount-W.amount,currency:Z.currency}}function u4(){return{lastCumulativeCost:null,promptsStarted:0}}function c4(X){let Z={baselineCost:X.lastCumulativeCost?{...X.lastCumulativeCost}:null,zeroBaseline:X.promptsStarted===0&&X.lastCumulativeCost===null,latestCost:null,latestContext:null,finalizedUsage:null};return X.promptsStarted+=1,Z}function d4(X,Z,W){let Q=SW(W),Y=kW(W.cost);if(Z&&Q)Z.latestContext=Q;if(Y){if(Z)Z.latestCost=Y;X.lastCumulativeCost=Y}return{context:Q,cumulativeCost:Y}}function A2(X,Z,W){if(Z.finalizedUsage)return Z.finalizedUsage;let Q={tokens:_W(X?.usage),context:Z.latestContext?{status:"reported",...Z.latestContext}:{status:"unreported"},cost:AW(Z)};if(Z.finalizedUsage=Q,!Z.latestCost)W.lastCumulativeCost=null;return Q}function U1(X){return{tokenUsageStatus:X?.tokens.status??"unreported",...X?.tokens.status==="reported"?{totalTokens:X.tokens.totalTokens,inputTokens:X.tokens.inputTokens,outputTokens:X.tokens.outputTokens,thoughtTokens:X.tokens.thoughtTokens,cachedReadTokens:X.tokens.cachedReadTokens,cachedWriteTokens:X.tokens.cachedWriteTokens}:{},contextUsageStatus:X?.context.status??"unreported",...X?.context.status==="reported"?{contextUsedTokens:X.context.usedTokens,contextWindowTokens:X.context.windowTokens}:{},costUsageStatus:X?.cost.status??"unreported",...X?.cost.status==="reported"?{costAmount:X.cost.amount,costCurrency:X.cost.currency}:{costUnreportedReason:X?.cost.reason??"omitted"}}}function a4(X){if(X.awaitingInput)return!1;return X.nowMs-X.lastUpdateMs>=X.windowMs}function o4(X){if(!X||typeof X!=="object")return!1;return X.code===l4}var lW=300000,uW=lW,cW=5000;function dW(X){let Z=Math.max(1,Math.round(X/1000));return`Runtime has not responded for ${Z} ${Z===1?"second":"seconds"}. Retry the agent run.`}function n4(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.100".trim()?"0.0.100":"dev"}}function t4(X){if(X===T1)return;throw new u(`Unsupported ACP protocol version ${X}; expected ${T1}`)}function e4(X){return(X??[]).flatMap((Z)=>{if(!Z||typeof Z!=="object")return[];let W=Z.name;return typeof W==="string"&&W.trim()?[W.trim()]:[]})}function aW(X,Z,W,Q){let Y=X,z=e4(Z),F=[Y.toolCall.name,Y.toolCall.title].filter((L)=>typeof L==="string").some((L)=>i4(L,z));if(W==="codex"&&Y._meta?.is_mcp_tool_approval===!0){if(F)return!0;if(typeof Y.toolCall.toolCallId!=="string")return!1;let L=Q.get(Y.toolCall.toolCallId);return Boolean(L&&i4(L,z))}if(F)return!0;return W==="claude-code"&&Y.toolCall.kind==="fetch"}function i4(X,Z){return Z.some((W)=>{return[...new Set([W,W.replace(/-/g,"_"),W.replace(/[^a-zA-Z0-9_-]/g,"_")])].some((Y)=>X.startsWith(`mcp__${Y}__`)||X.startsWith(`mcp.${Y}.`))})}function X8(X){return IW.toWeb(X)}function Z8(X){return TW.toWeb(X)}function I2(X){return X!==null&&typeof X==="object"}function iW(X){if(!Array.isArray(X))return[];let Z=[];for(let W of X){if(!I2(W))continue;if(typeof W.group==="string"&&Array.isArray(W.options)){let Q=typeof W.name==="string"?W.name:W.group;for(let Y of W.options){if(!I2(Y))continue;if(typeof Y.value!=="string"||typeof Y.name!=="string")continue;Z.push({value:Y.value,name:Y.name,description:typeof Y.description==="string"?Y.description:null,group:W.group,groupName:Q})}continue}if(typeof W.value!=="string"||typeof W.name!=="string")continue;Z.push({value:W.value,name:W.name,description:typeof W.description==="string"?W.description:null,group:null,groupName:null})}return Z}function pW(X){if(!I2(X))return null;if(typeof X.id!=="string"||typeof X.name!=="string")return null;let Z=typeof X.category==="string"?X.category:null,W=typeof X.description==="string"?X.description:null;if(X.type==="select"){let Q=typeof X.currentValue==="string"?X.currentValue:null;return{id:X.id,name:X.name,category:Z,description:W,type:"select",currentValue:Q,options:iW(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:Z,description:W,type:"boolean",currentValue:Q,options:[]}}return null}function nX(X){let Z=(X.configOptions??[]).map(pW).filter((F)=>F!==null),W=Z.find((F)=>F.type==="select"&&F.category==="model")??Z.find((F)=>F.type==="select"&&F.id==="model")??null,Q=W?.options.map((F)=>({id:F.value,name:F.name,description:F.description??null})),Y=rW(X.models),z=Q&&Q.length>0?Q:Y&&Y.length>0?Y:null,j=(typeof W?.currentValue==="string"?W.currentValue:null)??sW(X.models)??null;return{models:z,currentModelId:j,configOptions:Z,modelConfigId:W?.id??null}}function rW(X){if(!X||!Array.isArray(X.availableModels))return null;let Z=[];for(let W of X.availableModels){if(typeof W.modelId!=="string")continue;Z.push({id:W.modelId,name:typeof W.name==="string"?W.name:null,description:typeof W.description==="string"?W.description:null})}return Z.length>0?Z:null}function sW(X){return typeof X?.currentModelId==="string"?X.currentModelId:null}function oW(X,Z){let W=[];if(X.trim())W.push({type:"text",text:X});for(let Q of Z)if(Q.content.trim())W.push({type:"text",text:Q.content});return W}var nW=500;function W8(X){return new Promise((Z)=>{let W=setTimeout(()=>Z({code:null,signal:null,stderr:""}),nW);X.then((Q)=>{clearTimeout(W),Z(Q)})})}function Q8(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 J8(X,Z){let W=nX({configOptions:Z.configOptions});return{models:W.models??X.models,currentModelId:W.currentModelId??X.currentModelId,configOptions:W.configOptions,modelConfigId:W.modelConfigId??X.modelConfigId}}function Y8(X,Z){if(X==="default")return null;if(!Z||Z.length===0)return X;let W=Z.find((U)=>U.id===X);if(W)return W.id;let Q=X.toLowerCase(),Y=Q.includes("opus")?"opus":Q.includes("sonnet")?"sonnet":Q.includes("haiku")?"haiku":null;if(!Y)return X;let z=(U)=>`${U.id} ${U.name??""} ${U.description??""}`.toLowerCase(),j=Z.filter((U)=>z(U).includes(Y));if(j.length===0)return X;let L=(Q.includes("1m")?j.find((U)=>z(U).includes("1m")):void 0)??j[0];return L?L.id:X}async function T2(X){try{let Z=await X.conn.setSessionConfigOption(Q8({sessionId:X.sessionId,configId:X.configId,value:X.value}));return J8(X.metadata,Z)}catch(Z){return console.warn(`[acp] setSessionConfigOption(${X.label}) failed; using agent default.`,Z instanceof Error?Z.message:Z),X.metadata}}function p4(X){let Z=X.id.toLowerCase().replace(/[_\s-]+/g,"");return X.category?.toLowerCase().replace(/[_\s-]+/g,"")==="mode"||Z==="mode"||Z==="permissionmode"}function tW(X){if(X.type!=="select")return null;return X.options.find(({value:W})=>{return W.toLowerCase().replace(/[_\s-]+/g,"")==="readonly"})?.value??null}async function l2(X){let Z=X.isolateAmbientToolSources&&X.adapterId==="codex";if(Z&&e4(X.mcpServers).length===0)throw new u("An isolated Codex session requires an explicit IdeaWave MCP server");let W=dX(Z?{...X.spawn,env:{...X.spawn.env,INITIAL_AGENT_MODE:"read-only",DISABLE_MCP_CONFIG_FILTERING:"true"}}:X.spawn),Q=[],Y=0,z=4096;W.stderr.on("data",(S)=>{Q.push(S),Y+=S.length;while(Y>z*2&&Q.length>1){let d=Q.shift();if(d)Y-=d.length}});let j=()=>{let S=Buffer.concat(Q).toString("utf8");return S.length>z?S.slice(-z):S},F=k4(X.spawn.cwd),L={current:null},U={current:null},w=u4(),P={at:Date.now()},C=new Map,h=null,D=Z8(W.stdin),G=X8(W.stdout),N=s4(D,G),O=new r4((S)=>({requestPermission:async(d)=>{if(X.isolateAmbientToolSources&&!aW(d,X.mcpServers,X.adapterId,C))return{outcome:{outcome:"cancelled"}};let T=d.options,t=T?.find(($0)=>$0.kind==="allow_once")??T?.find(($0)=>$0.kind==="allow_always");if(t)return{outcome:{outcome:"selected",optionId:t.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(d)=>{if(P.at=Date.now(),X.isolateAmbientToolSources&&X.adapterId==="codex"&&(d.update.sessionUpdate==="tool_call"||d.update.sessionUpdate==="tool_call_update")){let z0=d.update;if(typeof z0.toolCallId==="string"&&typeof z0.title==="string")C.set(z0.toolCallId,z0.title)}let T=U.current,t=d.update.sessionUpdate;if(t==="usage_update"){let z0=d4(w,T?.promptUsage??null,d.update);m("acp.usage_update",{runId:T?.runId,cardId:T?.cardId,sessionId:h,attributedToActivePrompt:T!==null,contextUsageStatus:z0.context?"reported":"unreported",contextUsedTokens:z0.context?.usedTokens,contextWindowTokens:z0.context?.windowTokens,cumulativeCostStatus:z0.cumulativeCost?"reported":"unreported",cumulativeCostAmount:z0.cumulativeCost?.amount,cumulativeCostCurrency:z0.cumulativeCost?.currency})}if(T){if(T.updateCount+=1,T.updateCount===1||T.lastUpdateType!==t||t==="tool_call"||t==="tool_call_update")m("acp.session_update",{runId:T.runId,cardId:T.cardId,sessionId:h,updateType:t,updateCount:T.updateCount,elapsedMs:Date.now()-T.startedAt});T.lastUpdateType=t}let $0=L.current;if($0)await $0.onSessionUpdate(d)},readTextFile:X.isolateAmbientToolSources?async()=>{throw Error("Filesystem reads are unavailable in this isolated session")}:F.readTextFile}),N),M=()=>W.kill();if(X.signal)X.signal.addEventListener("abort",M);let g=()=>{if(X.signal)X.signal.removeEventListener("abort",M)},$=(S)=>{throw g(),W.kill(),new u(S)},A=(S,d)=>{let T=d instanceof Error?d.message:I2(d)&&typeof d.message==="string"?d.message:String(d);return $(`Isolated Codex runtime advertised ${S} but rejected it: ${T}`)},x=async(S,d)=>{if(g(),W.kill(),o4(S))throw new Z1(S.message??"Authentication required",d);if(S2(S)){if(X.signal?.aborted)throw new u("ACP session cancelled: abort signal received");let T=await W8(W.waitForExit);throw new u(`Runtime process exited before completion: ${T.stderr?.trim()??""}`)}throw S},b;try{b=await O.initialize({protocolVersion:T1,clientCapabilities:X.isolateAmbientToolSources?_4:cX,clientInfo:n4()})}catch(S){throw await x(S,[]),Error("unreachable")}try{t4(b.protocolVersion)}catch(S){throw g(),W.kill(),S}let y=b.authMethods?.map((S)=>S.id)??[],_;try{_=await O.newSession({cwd:X.spawn.cwd,mcpServers:X.mcpServers??[],...X.isolateAmbientToolSources&&X.adapterId==="claude-code"?{_meta:{disableBuiltInTools:!0,claudeCode:{options:{settingSources:[],tools:X.allowNativeWebTools===!1?[]:["WebSearch","WebFetch"]}}}}:{}})}catch(S){throw await x(S,y),Error("unreachable")}let I=_.sessionId;h=I;let l=nX(_),k=X.modelId??null,r=k?Y8(k,l.models):null;if(r&&r!==l.currentModelId)if(l.modelConfigId)l=await T2({conn:O,sessionId:I,configId:l.modelConfigId,value:r,metadata:l,label:`${l.modelConfigId}=${r}`});else console.warn(`[acp] runtime did not advertise a model config option for ${r}; using agent default.`);for(let[S,d]of Object.entries(X.configValues??{}).sort(([T],[t])=>T.localeCompare(t))){if(S===l.modelConfigId)continue;let T=l.configOptions.find((t)=>t.id===S);if(!T)continue;if(Z&&p4(T))continue;l=await T2({conn:O,sessionId:I,configId:S,value:d,metadata:l,label:`${S}=${String(d)}`})}if(Z){let S=l.configOptions.find(p4),d=S?tW(S):null;if(S&&d)try{let T=await O.setSessionConfigOption(Q8({sessionId:I,configId:S.id,value:d}));l=J8(l,T)}catch(T){A(`${S.id}=${d}`,T)}else{let T=_.modes?.availableModes.find((t)=>t.id.toLowerCase().replace(/[_\s-]+/g,"")==="readonly");if(!T)$("Isolated Codex runtime did not advertise an enforceable read-only config option or legacy mode");else try{await O.setSessionMode({sessionId:I,modeId:T.id})}catch(t){A(`legacy mode=${T.id}`,t)}}}g();let W0=!1,C0=async()=>{if(W0)return;W0=!0,W.kill(),await Promise.race([W.waitForExit,new Promise((S)=>setTimeout(S,2000))])},n=!1;return W.processCrashed.then(()=>{n=!0}),{sessionId:I,availableModels:l.models,currentModelId:l.currentModelId,availableConfigOptions:l.configOptions,isAlive:()=>!W0&&!n,dispose:C0,prompt:(S)=>{return C.clear(),eW({proc:W,conn:O,sessionId:I,activeAdapter:L,activeTrace:U,usageState:w,lastUpdate:P,collectStderrTail:j},S)}}}async function eW(X,Z){let{proc:W,conn:Q,sessionId:Y,activeAdapter:z,activeTrace:j,usageState:F,lastUpdate:L}=X,U=Date.now(),w=Z.heartbeatMs??uW,P=dW(w),C={boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId},h=T4({ctx:C,appendText:Z.appendText,appendToolActivity:Z.appendToolActivity,onAnyUpdate:Z.onAnyUpdate}),D=c4(F),G=null,N=null;z.current=h,j.current={runId:Z.runId,cardId:Z.cardId,startedAt:U,updateCount:0,lastUpdateType:null,promptUsage:D},L.at=Date.now(),m("acp.prompt_started",{runId:Z.runId,cardId:Z.cardId,sessionId:Y,heartbeatWindowMs:w});let v=!1,O=null,M=()=>W.kill();Z.signal.addEventListener("abort",M);try{let g=async()=>{let b=Math.min(cW,Math.max(50,Math.floor(w/2)));O=setInterval(()=>{let _=Z.isAwaitingInput?.()??!1;if(_){L.at=Date.now();return}if(a4({nowMs:Date.now(),lastUpdateMs:L.at,windowMs:w,awaitingInput:_}))v=!0,m("acp.inactivity_timeout",{runId:Z.runId,cardId:Z.cardId,sessionId:Y,windowMs:w,silentForMs:Date.now()-L.at}),Q.cancel({sessionId:Y}).catch(()=>{return}),W.kill()},b);let y=oW(Z.prompt.systemPrompt,Z.prompt.messages);G=await Q.prompt({sessionId:Y,prompt:y}),N=A2(G,D,F),m("acp.prompt_resolved",{runId:Z.runId,cardId:Z.cardId,sessionId:Y,elapsedMs:Date.now()-U,...U1(N)}),h.flush({completeOpenToolCalls:!0})},$=W.waitForExit.then((b)=>({kind:"exited",exit:b})),A=g().then(()=>({kind:"ok"})).catch(async(b)=>{if(S2(b))return W.kill(),{kind:"crashed",exit:await W8(W.waitForExit)};throw b}),x;try{x=await Promise.race([A,W.processCrashed.then((b)=>({kind:"crashed",exit:b})),$])}catch(b){if(v)throw new x0(P);throw b}if(v)throw new x0(P);if(x.kind!=="ok"&&Z.signal.aborted)throw new u("ACP session cancelled: abort signal received");if(x.kind==="crashed")throw new u(`Runtime process exited before completion: ${x.exit.stderr.trim()}`);if(x.kind==="exited"){if(v)throw new x0(P);throw new u(`Runtime process exited unexpectedly: ${x.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:h.getFinalText(),toolCallsExecuted:h.getToolCallCount(),stderrTail:X.collectStderrTail(),updateTypeCounts:h.getUpdateTypeCounts(),usage:N??A2(G,D,F)}}finally{let g=N??A2(G,D,F);if(m("acp.prompt_finished",{runId:Z.runId,cardId:Z.cardId,sessionId:Y,elapsedMs:Date.now()-U,timedOut:v,updateCount:j.current?.updateCount??0,...U1(g)}),O!==null)clearInterval(O);Z.signal.removeEventListener("abort",M),h.flush({completeOpenToolCalls:!0}),z.current=null,j.current=null}}var XQ=30000;async function z8(X){let Z=dX(X.spawn),W=Z8(Z.stdin),Q=X8(Z.stdout),Y=s4(W,Q),j=new r4((U)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),Y),F=()=>Z.kill();if(X.signal)X.signal.addEventListener("abort",F);let L=null;try{let U=(async()=>{let P=await j.initialize({protocolVersion:T1,clientCapabilities:cX,clientInfo:n4()});t4(P.protocolVersion);let C=P.authMethods?.map((M)=>M.id)??[],h;try{h=await j.newSession({cwd:X.spawn.cwd,mcpServers:[]})}catch(M){if(o4(M))throw new Z1(M.message??"Authentication required",C);throw M}let D=nX(h),G=X.modelId??null,N=G?Y8(G,D.models):null;if(N&&N!==D.currentModelId)if(D.modelConfigId)D=await T2({conn:j,sessionId:h.sessionId,configId:D.modelConfigId,value:N,metadata:D,label:`${D.modelConfigId}=${N}`});else console.warn(`[acp] runtime did not advertise a model config option for ${N}; discovering agent default models.`);for(let[M,g]of Object.entries(X.configValues??{}).sort(([$],[A])=>$.localeCompare(A))){if(M===D.modelConfigId)continue;if(!D.configOptions.some(($)=>$.id===M))continue;D=await T2({conn:j,sessionId:h.sessionId,configId:M,value:g,metadata:D,label:`${M}=${String(g)}`})}let v=D.models??[],O=D.currentModelId;return j.cancel({sessionId:h.sessionId}).catch(()=>{return}),{models:v,configOptions:D.configOptions,currentModelId:O}})(),w=new Promise((P,C)=>{L=setTimeout(()=>{C(new x0)},XQ)});return await Promise.race([U,w])}catch(U){if(S2(U)){if(X.signal?.aborted)throw new u("ACP model discovery cancelled: abort signal received");throw new u("Runtime process exited during model discovery.")}throw U}finally{if(L)clearTimeout(L);if(X.signal)X.signal.removeEventListener("abort",F);Z.kill()}}import ZQ from"node:fs/promises";import u2 from"node:os";async function V8(X){let Z={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},W;try{W=await ZQ.readFile(X,"utf-8")}catch(Q){if(Q.code==="ENOENT")return structuredClone(Z);throw Q}return Z2.parse(JSON.parse(W))}function tX(X,Z,W){return{...X.defaultConfigValues??{},...Z?.configValues??{},...W?.configValues??{}}}async function k0(X){let Z=X.configPath?await V8(X.configPath):await F0(),W=X.cardId?Z.cardOverrides[X.cardId]:void 0;if(W?.runtimeConfigId){let Y=Z.runtimes.find((z)=>z.id===W.runtimeConfigId);if(Y)return{entry:Y,adapter:O0(Y),runFolder:W.runFolder??Y.runFolder??u2.homedir(),modelId:W.modelId??Y.defaultModelId??null,configValues:tX(Y,void 0,W)}}let Q=Z.boardOverrides[X.boardId];if(Q?.runtimeConfigId){let Y=Z.runtimes.find((z)=>z.id===Q.runtimeConfigId);if(Y)return{entry:Y,adapter:O0(Y),runFolder:Q.runFolder??Y.runFolder??u2.homedir(),modelId:Q.modelId??Y.defaultModelId??null,configValues:tX(Y,Q)}}if(Z.globalDefaultConfigId){let Y=Z.runtimes.find((z)=>z.id===Z.globalDefaultConfigId);if(Y)return{entry:Y,adapter:O0(Y),runFolder:W?.runFolder??Q?.runFolder??Y.runFolder??u2.homedir(),modelId:W?.modelId??Q?.modelId??Y.defaultModelId??null,configValues:tX(Y,Q,W)}}throw new h0}async function eX(X,Z={}){let Q=(Z.configPath?await V8(Z.configPath):await F0()).runtimes.find((Y)=>Y.id===X);if(!Q)return null;return{entry:Q,adapter:O0(Q),runFolder:Q.runFolder??u2.homedir(),modelId:Z.modelId??Q.defaultModelId??null,configValues:{...Q.defaultConfigValues??{},...Z.configValues??{}}}}var X3=new Map;function Z3(X,Z){X3.set(X,Z)}function W3(X){X3.delete(X)}function j8(X){if(!X)return null;return X3.get(X)??null}import{lstat as RQ,readFile as vQ}from"node:fs/promises";import CQ from"node:os";import u1 from"node:path";import{Server as fQ}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as yQ,ListToolsRequestSchema as hQ}from"@modelcontextprotocol/sdk/types.js";import{z as i}from"zod";var K0={maxSteps:12,maxParticipants:4,maxChannels:2,maxHandoffsPerChannel:12,maxTotalDispatches:24},l1=["ideate_create_note","ideate_create_code","ideate_create_shape","ideate_create_browser","ideate_create_image_context_card","ideate_add_browser_note","ideate_add_board_callout","ideate_create_diagram","ideate_create_edge","ideate_update_note","ideate_update_code","ideate_update_shape","ideate_update_diagram","ideate_update_edge","ideate_delete_node","ideate_delete_edge"],WQ=`
|
|
1143
|
+
`;z+=b.content.text,U=!1,A(z)}}else{let _=`agent_message_chunk:${b.content.type}`;w[_]=(w[_]??0)+1}return}case"agent_thought_chunk":{if(b.content.type!=="text")return;j+=b.content.text;let y=new Date().toISOString(),_=`${Z.runId}:thought`,I=P.get(_);C({toolCallId:_,rawTitle:"agent_thought",title:"Thought",kind:"thought",status:"running",startedAt:I?.startedAt??y,completedAt:null,contentPreview:p0(j.trim())});return}case"user_message_chunk":return;case"tool_call":{F+=1,U=z.length>0;let y=S4(b.title),_=iX(b.status),I=new Date().toISOString();h(I),D(I),C({toolCallId:b.toolCallId,rawTitle:y,title:rX(y,b.rawInput),kind:pX(b.kind),status:_,startedAt:I,completedAt:_==="running"?null:I,inputPreview:D0(b.rawInput),outputPreview:sX(b.rawOutput),contentPreview:_2(b.content),locations:oX(b.locations)});return}case"tool_call_update":{let y=P.get(b.toolCallId);if(!y){let C0=S4(b.title),n=iX(b.status),S=new Date().toISOString();C({toolCallId:b.toolCallId,rawTitle:C0,title:rX(C0,b.rawInput),kind:pX(b.kind),status:n,startedAt:S,completedAt:n==="running"?null:S,inputPreview:D0(b.rawInput),outputPreview:sX(b.rawOutput),contentPreview:_2(b.content),locations:oX(b.locations)});return}let _=b.status===void 0||b.status===null?y.status:iX(b.status),I=typeof b.title==="string"&&b.title.trim().length>0?b.title:y.rawTitle,l=typeof b.title==="string"&&b.title.trim().length>0,k=_==="running"?y.completedAt:y.completedAt??new Date().toISOString(),r=b.content===void 0?y.contentPreview:I4(y.contentPreview,_2(b.content)),W0=b.rawOutput===void 0?y.outputPreview:I4(y.outputPreview,sX(b.rawOutput));C({...y,rawTitle:I,title:l?rX(I,b.rawInput):y.title,kind:b.kind===void 0?y.kind:pX(b.kind),status:_,completedAt:k,inputPreview:b.rawInput===void 0?y.inputPreview:D0(b.rawInput),outputPreview:W0,contentPreview:r,locations:b.locations===void 0?y.locations:oX(b.locations)});return}case"plan":L=b.entries;return;case"available_commands_update":return;case"current_mode_update":return;default:return}},getFinalText:()=>z,getToolCallCount:()=>F,getLatestPlan:()=>L,getUpdateTypeCounts:()=>({...w}),flush:(x)=>{let b=new Date().toISOString();if(h(b),x?.completeOpenToolCalls)G(b);$()}}}var mW=new Set(["ECONNRESET","EPIPE"]);function S2(X){if(!X||typeof X!=="object")return!1;if(X instanceof Error&&X.message==="ACP connection closed")return!0;let Z="code"in X?X.code:void 0;return typeof Z==="string"&&mW.has(Z)}var T1=1,l4=-32000;function _0(X){return typeof X==="number"&&Number.isSafeInteger(X)&&X>=0?X:null}function _W(X){if(!X)return{status:"unreported"};let Z=_0(X.totalTokens),W=_0(X.inputTokens),Q=_0(X.outputTokens);if(Z===null||W===null||Q===null)return{status:"unreported"};let Y=_0(X.thoughtTokens),z=_0(X.cachedReadTokens),j=_0(X.cachedWriteTokens);return{status:"reported",totalTokens:Z,inputTokens:W,outputTokens:Q,...Y===null?{}:{thoughtTokens:Y},...z===null?{}:{cachedReadTokens:z},...j===null?{}:{cachedWriteTokens:j}}}function kW(X){if(!X)return null;if(typeof X.amount!=="number"||!Number.isFinite(X.amount)||X.amount<0||typeof X.currency!=="string"||X.currency.trim().length===0)return null;return{amount:X.amount,currency:X.currency}}function SW(X){let Z=_0(X.used),W=_0(X.size);return Z===null||W===null?null:{usedTokens:Z,windowTokens:W}}function AW(X){let Z=X.latestCost;if(!Z)return{status:"unreported",reason:"omitted"};let W=X.baselineCost;if(!W){if(X.zeroBaseline)return{status:"reported",amount:Z.amount,currency:Z.currency};return{status:"unreported",reason:"baseline_unavailable"}}if(W.currency!==Z.currency)return{status:"unreported",reason:"currency_mismatch"};if(Z.amount<W.amount)return{status:"unreported",reason:"counter_reset"};return{status:"reported",amount:Z.amount-W.amount,currency:Z.currency}}function u4(){return{lastCumulativeCost:null,promptsStarted:0}}function c4(X){let Z={baselineCost:X.lastCumulativeCost?{...X.lastCumulativeCost}:null,zeroBaseline:X.promptsStarted===0&&X.lastCumulativeCost===null,latestCost:null,latestContext:null,finalizedUsage:null};return X.promptsStarted+=1,Z}function d4(X,Z,W){let Q=SW(W),Y=kW(W.cost);if(Z&&Q)Z.latestContext=Q;if(Y){if(Z)Z.latestCost=Y;X.lastCumulativeCost=Y}return{context:Q,cumulativeCost:Y}}function A2(X,Z,W){if(Z.finalizedUsage)return Z.finalizedUsage;let Q={tokens:_W(X?.usage),context:Z.latestContext?{status:"reported",...Z.latestContext}:{status:"unreported"},cost:AW(Z)};if(Z.finalizedUsage=Q,!Z.latestCost)W.lastCumulativeCost=null;return Q}function U1(X){return{tokenUsageStatus:X?.tokens.status??"unreported",...X?.tokens.status==="reported"?{totalTokens:X.tokens.totalTokens,inputTokens:X.tokens.inputTokens,outputTokens:X.tokens.outputTokens,thoughtTokens:X.tokens.thoughtTokens,cachedReadTokens:X.tokens.cachedReadTokens,cachedWriteTokens:X.tokens.cachedWriteTokens}:{},contextUsageStatus:X?.context.status??"unreported",...X?.context.status==="reported"?{contextUsedTokens:X.context.usedTokens,contextWindowTokens:X.context.windowTokens}:{},costUsageStatus:X?.cost.status??"unreported",...X?.cost.status==="reported"?{costAmount:X.cost.amount,costCurrency:X.cost.currency}:{costUnreportedReason:X?.cost.reason??"omitted"}}}function a4(X){if(X.awaitingInput)return!1;return X.nowMs-X.lastUpdateMs>=X.windowMs}function o4(X){if(!X||typeof X!=="object")return!1;return X.code===l4}var lW=300000,uW=lW,cW=5000;function dW(X){let Z=Math.max(1,Math.round(X/1000));return`Runtime has not responded for ${Z} ${Z===1?"second":"seconds"}. Retry the agent run.`}function n4(){return{name:"ideawave-cli",title:"IdeaWave CLI",version:"0.0.101".trim()?"0.0.101":"dev"}}function t4(X){if(X===T1)return;throw new u(`Unsupported ACP protocol version ${X}; expected ${T1}`)}function e4(X){return(X??[]).flatMap((Z)=>{if(!Z||typeof Z!=="object")return[];let W=Z.name;return typeof W==="string"&&W.trim()?[W.trim()]:[]})}function aW(X,Z,W,Q){let Y=X,z=e4(Z),F=[Y.toolCall.name,Y.toolCall.title].filter((L)=>typeof L==="string").some((L)=>i4(L,z));if(W==="codex"&&Y._meta?.is_mcp_tool_approval===!0){if(F)return!0;if(typeof Y.toolCall.toolCallId!=="string")return!1;let L=Q.get(Y.toolCall.toolCallId);return Boolean(L&&i4(L,z))}if(F)return!0;return W==="claude-code"&&Y.toolCall.kind==="fetch"}function i4(X,Z){return Z.some((W)=>{return[...new Set([W,W.replace(/-/g,"_"),W.replace(/[^a-zA-Z0-9_-]/g,"_")])].some((Y)=>X.startsWith(`mcp__${Y}__`)||X.startsWith(`mcp.${Y}.`))})}function X8(X){return IW.toWeb(X)}function Z8(X){return TW.toWeb(X)}function I2(X){return X!==null&&typeof X==="object"}function iW(X){if(!Array.isArray(X))return[];let Z=[];for(let W of X){if(!I2(W))continue;if(typeof W.group==="string"&&Array.isArray(W.options)){let Q=typeof W.name==="string"?W.name:W.group;for(let Y of W.options){if(!I2(Y))continue;if(typeof Y.value!=="string"||typeof Y.name!=="string")continue;Z.push({value:Y.value,name:Y.name,description:typeof Y.description==="string"?Y.description:null,group:W.group,groupName:Q})}continue}if(typeof W.value!=="string"||typeof W.name!=="string")continue;Z.push({value:W.value,name:W.name,description:typeof W.description==="string"?W.description:null,group:null,groupName:null})}return Z}function pW(X){if(!I2(X))return null;if(typeof X.id!=="string"||typeof X.name!=="string")return null;let Z=typeof X.category==="string"?X.category:null,W=typeof X.description==="string"?X.description:null;if(X.type==="select"){let Q=typeof X.currentValue==="string"?X.currentValue:null;return{id:X.id,name:X.name,category:Z,description:W,type:"select",currentValue:Q,options:iW(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:Z,description:W,type:"boolean",currentValue:Q,options:[]}}return null}function nX(X){let Z=(X.configOptions??[]).map(pW).filter((F)=>F!==null),W=Z.find((F)=>F.type==="select"&&F.category==="model")??Z.find((F)=>F.type==="select"&&F.id==="model")??null,Q=W?.options.map((F)=>({id:F.value,name:F.name,description:F.description??null})),Y=rW(X.models),z=Q&&Q.length>0?Q:Y&&Y.length>0?Y:null,j=(typeof W?.currentValue==="string"?W.currentValue:null)??sW(X.models)??null;return{models:z,currentModelId:j,configOptions:Z,modelConfigId:W?.id??null}}function rW(X){if(!X||!Array.isArray(X.availableModels))return null;let Z=[];for(let W of X.availableModels){if(typeof W.modelId!=="string")continue;Z.push({id:W.modelId,name:typeof W.name==="string"?W.name:null,description:typeof W.description==="string"?W.description:null})}return Z.length>0?Z:null}function sW(X){return typeof X?.currentModelId==="string"?X.currentModelId:null}function oW(X,Z){let W=[];if(X.trim())W.push({type:"text",text:X});for(let Q of Z)if(Q.content.trim())W.push({type:"text",text:Q.content});return W}var nW=500;function W8(X){return new Promise((Z)=>{let W=setTimeout(()=>Z({code:null,signal:null,stderr:""}),nW);X.then((Q)=>{clearTimeout(W),Z(Q)})})}function Q8(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 J8(X,Z){let W=nX({configOptions:Z.configOptions});return{models:W.models??X.models,currentModelId:W.currentModelId??X.currentModelId,configOptions:W.configOptions,modelConfigId:W.modelConfigId??X.modelConfigId}}function Y8(X,Z){if(X==="default")return null;if(!Z||Z.length===0)return X;let W=Z.find((U)=>U.id===X);if(W)return W.id;let Q=X.toLowerCase(),Y=Q.includes("opus")?"opus":Q.includes("sonnet")?"sonnet":Q.includes("haiku")?"haiku":null;if(!Y)return X;let z=(U)=>`${U.id} ${U.name??""} ${U.description??""}`.toLowerCase(),j=Z.filter((U)=>z(U).includes(Y));if(j.length===0)return X;let L=(Q.includes("1m")?j.find((U)=>z(U).includes("1m")):void 0)??j[0];return L?L.id:X}async function T2(X){try{let Z=await X.conn.setSessionConfigOption(Q8({sessionId:X.sessionId,configId:X.configId,value:X.value}));return J8(X.metadata,Z)}catch(Z){return console.warn(`[acp] setSessionConfigOption(${X.label}) failed; using agent default.`,Z instanceof Error?Z.message:Z),X.metadata}}function p4(X){let Z=X.id.toLowerCase().replace(/[_\s-]+/g,"");return X.category?.toLowerCase().replace(/[_\s-]+/g,"")==="mode"||Z==="mode"||Z==="permissionmode"}function tW(X){if(X.type!=="select")return null;return X.options.find(({value:W})=>{return W.toLowerCase().replace(/[_\s-]+/g,"")==="readonly"})?.value??null}async function l2(X){let Z=X.isolateAmbientToolSources&&X.adapterId==="codex";if(Z&&e4(X.mcpServers).length===0)throw new u("An isolated Codex session requires an explicit IdeaWave MCP server");let W=dX(Z?{...X.spawn,env:{...X.spawn.env,INITIAL_AGENT_MODE:"read-only",DISABLE_MCP_CONFIG_FILTERING:"true"}}:X.spawn),Q=[],Y=0,z=4096;W.stderr.on("data",(S)=>{Q.push(S),Y+=S.length;while(Y>z*2&&Q.length>1){let d=Q.shift();if(d)Y-=d.length}});let j=()=>{let S=Buffer.concat(Q).toString("utf8");return S.length>z?S.slice(-z):S},F=k4(X.spawn.cwd),L={current:null},U={current:null},w=u4(),P={at:Date.now()},C=new Map,h=null,D=Z8(W.stdin),G=X8(W.stdout),N=s4(D,G),O=new r4((S)=>({requestPermission:async(d)=>{if(X.isolateAmbientToolSources&&!aW(d,X.mcpServers,X.adapterId,C))return{outcome:{outcome:"cancelled"}};let T=d.options,t=T?.find(($0)=>$0.kind==="allow_once")??T?.find(($0)=>$0.kind==="allow_always");if(t)return{outcome:{outcome:"selected",optionId:t.optionId}};return{outcome:{outcome:"cancelled"}}},sessionUpdate:async(d)=>{if(P.at=Date.now(),X.isolateAmbientToolSources&&X.adapterId==="codex"&&(d.update.sessionUpdate==="tool_call"||d.update.sessionUpdate==="tool_call_update")){let z0=d.update;if(typeof z0.toolCallId==="string"&&typeof z0.title==="string")C.set(z0.toolCallId,z0.title)}let T=U.current,t=d.update.sessionUpdate;if(t==="usage_update"){let z0=d4(w,T?.promptUsage??null,d.update);m("acp.usage_update",{runId:T?.runId,cardId:T?.cardId,sessionId:h,attributedToActivePrompt:T!==null,contextUsageStatus:z0.context?"reported":"unreported",contextUsedTokens:z0.context?.usedTokens,contextWindowTokens:z0.context?.windowTokens,cumulativeCostStatus:z0.cumulativeCost?"reported":"unreported",cumulativeCostAmount:z0.cumulativeCost?.amount,cumulativeCostCurrency:z0.cumulativeCost?.currency})}if(T){if(T.updateCount+=1,T.updateCount===1||T.lastUpdateType!==t||t==="tool_call"||t==="tool_call_update")m("acp.session_update",{runId:T.runId,cardId:T.cardId,sessionId:h,updateType:t,updateCount:T.updateCount,elapsedMs:Date.now()-T.startedAt});T.lastUpdateType=t}let $0=L.current;if($0)await $0.onSessionUpdate(d)},readTextFile:X.isolateAmbientToolSources?async()=>{throw Error("Filesystem reads are unavailable in this isolated session")}:F.readTextFile}),N),M=()=>W.kill();if(X.signal)X.signal.addEventListener("abort",M);let g=()=>{if(X.signal)X.signal.removeEventListener("abort",M)},$=(S)=>{throw g(),W.kill(),new u(S)},A=(S,d)=>{let T=d instanceof Error?d.message:I2(d)&&typeof d.message==="string"?d.message:String(d);return $(`Isolated Codex runtime advertised ${S} but rejected it: ${T}`)},x=async(S,d)=>{if(g(),W.kill(),o4(S))throw new Z1(S.message??"Authentication required",d);if(S2(S)){if(X.signal?.aborted)throw new u("ACP session cancelled: abort signal received");let T=await W8(W.waitForExit);throw new u(`Runtime process exited before completion: ${T.stderr?.trim()??""}`)}throw S},b;try{b=await O.initialize({protocolVersion:T1,clientCapabilities:X.isolateAmbientToolSources?_4:cX,clientInfo:n4()})}catch(S){throw await x(S,[]),Error("unreachable")}try{t4(b.protocolVersion)}catch(S){throw g(),W.kill(),S}let y=b.authMethods?.map((S)=>S.id)??[],_;try{_=await O.newSession({cwd:X.spawn.cwd,mcpServers:X.mcpServers??[],...X.isolateAmbientToolSources&&X.adapterId==="claude-code"?{_meta:{disableBuiltInTools:!0,claudeCode:{options:{settingSources:[],tools:X.allowNativeWebTools===!1?[]:["WebSearch","WebFetch"]}}}}:{}})}catch(S){throw await x(S,y),Error("unreachable")}let I=_.sessionId;h=I;let l=nX(_),k=X.modelId??null,r=k?Y8(k,l.models):null;if(r&&r!==l.currentModelId)if(l.modelConfigId)l=await T2({conn:O,sessionId:I,configId:l.modelConfigId,value:r,metadata:l,label:`${l.modelConfigId}=${r}`});else console.warn(`[acp] runtime did not advertise a model config option for ${r}; using agent default.`);for(let[S,d]of Object.entries(X.configValues??{}).sort(([T],[t])=>T.localeCompare(t))){if(S===l.modelConfigId)continue;let T=l.configOptions.find((t)=>t.id===S);if(!T)continue;if(Z&&p4(T))continue;l=await T2({conn:O,sessionId:I,configId:S,value:d,metadata:l,label:`${S}=${String(d)}`})}if(Z){let S=l.configOptions.find(p4),d=S?tW(S):null;if(S&&d)try{let T=await O.setSessionConfigOption(Q8({sessionId:I,configId:S.id,value:d}));l=J8(l,T)}catch(T){A(`${S.id}=${d}`,T)}else{let T=_.modes?.availableModes.find((t)=>t.id.toLowerCase().replace(/[_\s-]+/g,"")==="readonly");if(!T)$("Isolated Codex runtime did not advertise an enforceable read-only config option or legacy mode");else try{await O.setSessionMode({sessionId:I,modeId:T.id})}catch(t){A(`legacy mode=${T.id}`,t)}}}g();let W0=!1,C0=async()=>{if(W0)return;W0=!0,W.kill(),await Promise.race([W.waitForExit,new Promise((S)=>setTimeout(S,2000))])},n=!1;return W.processCrashed.then(()=>{n=!0}),{sessionId:I,availableModels:l.models,currentModelId:l.currentModelId,availableConfigOptions:l.configOptions,isAlive:()=>!W0&&!n,dispose:C0,prompt:(S)=>{return C.clear(),eW({proc:W,conn:O,sessionId:I,activeAdapter:L,activeTrace:U,usageState:w,lastUpdate:P,collectStderrTail:j},S)}}}async function eW(X,Z){let{proc:W,conn:Q,sessionId:Y,activeAdapter:z,activeTrace:j,usageState:F,lastUpdate:L}=X,U=Date.now(),w=Z.heartbeatMs??uW,P=dW(w),C={boardId:Z.boardId,cardId:Z.cardId,runId:Z.runId},h=T4({ctx:C,appendText:Z.appendText,appendToolActivity:Z.appendToolActivity,onAnyUpdate:Z.onAnyUpdate}),D=c4(F),G=null,N=null;z.current=h,j.current={runId:Z.runId,cardId:Z.cardId,startedAt:U,updateCount:0,lastUpdateType:null,promptUsage:D},L.at=Date.now(),m("acp.prompt_started",{runId:Z.runId,cardId:Z.cardId,sessionId:Y,heartbeatWindowMs:w});let v=!1,O=null,M=()=>W.kill();Z.signal.addEventListener("abort",M);try{let g=async()=>{let b=Math.min(cW,Math.max(50,Math.floor(w/2)));O=setInterval(()=>{let _=Z.isAwaitingInput?.()??!1;if(_){L.at=Date.now();return}if(a4({nowMs:Date.now(),lastUpdateMs:L.at,windowMs:w,awaitingInput:_}))v=!0,m("acp.inactivity_timeout",{runId:Z.runId,cardId:Z.cardId,sessionId:Y,windowMs:w,silentForMs:Date.now()-L.at}),Q.cancel({sessionId:Y}).catch(()=>{return}),W.kill()},b);let y=oW(Z.prompt.systemPrompt,Z.prompt.messages);G=await Q.prompt({sessionId:Y,prompt:y}),N=A2(G,D,F),m("acp.prompt_resolved",{runId:Z.runId,cardId:Z.cardId,sessionId:Y,elapsedMs:Date.now()-U,...U1(N)}),h.flush({completeOpenToolCalls:!0})},$=W.waitForExit.then((b)=>({kind:"exited",exit:b})),A=g().then(()=>({kind:"ok"})).catch(async(b)=>{if(S2(b))return W.kill(),{kind:"crashed",exit:await W8(W.waitForExit)};throw b}),x;try{x=await Promise.race([A,W.processCrashed.then((b)=>({kind:"crashed",exit:b})),$])}catch(b){if(v)throw new x0(P);throw b}if(v)throw new x0(P);if(x.kind!=="ok"&&Z.signal.aborted)throw new u("ACP session cancelled: abort signal received");if(x.kind==="crashed")throw new u(`Runtime process exited before completion: ${x.exit.stderr.trim()}`);if(x.kind==="exited"){if(v)throw new x0(P);throw new u(`Runtime process exited unexpectedly: ${x.exit.stderr.trim()}`)}return{modelReported:"unknown",finalText:h.getFinalText(),toolCallsExecuted:h.getToolCallCount(),stderrTail:X.collectStderrTail(),updateTypeCounts:h.getUpdateTypeCounts(),usage:N??A2(G,D,F)}}finally{let g=N??A2(G,D,F);if(m("acp.prompt_finished",{runId:Z.runId,cardId:Z.cardId,sessionId:Y,elapsedMs:Date.now()-U,timedOut:v,updateCount:j.current?.updateCount??0,...U1(g)}),O!==null)clearInterval(O);Z.signal.removeEventListener("abort",M),h.flush({completeOpenToolCalls:!0}),z.current=null,j.current=null}}var XQ=30000;async function z8(X){let Z=dX(X.spawn),W=Z8(Z.stdin),Q=X8(Z.stdout),Y=s4(W,Q),j=new r4((U)=>({requestPermission:async()=>({outcome:{outcome:"cancelled"}}),sessionUpdate:async()=>{return},readTextFile:async()=>({content:""})}),Y),F=()=>Z.kill();if(X.signal)X.signal.addEventListener("abort",F);let L=null;try{let U=(async()=>{let P=await j.initialize({protocolVersion:T1,clientCapabilities:cX,clientInfo:n4()});t4(P.protocolVersion);let C=P.authMethods?.map((M)=>M.id)??[],h;try{h=await j.newSession({cwd:X.spawn.cwd,mcpServers:[]})}catch(M){if(o4(M))throw new Z1(M.message??"Authentication required",C);throw M}let D=nX(h),G=X.modelId??null,N=G?Y8(G,D.models):null;if(N&&N!==D.currentModelId)if(D.modelConfigId)D=await T2({conn:j,sessionId:h.sessionId,configId:D.modelConfigId,value:N,metadata:D,label:`${D.modelConfigId}=${N}`});else console.warn(`[acp] runtime did not advertise a model config option for ${N}; discovering agent default models.`);for(let[M,g]of Object.entries(X.configValues??{}).sort(([$],[A])=>$.localeCompare(A))){if(M===D.modelConfigId)continue;if(!D.configOptions.some(($)=>$.id===M))continue;D=await T2({conn:j,sessionId:h.sessionId,configId:M,value:g,metadata:D,label:`${M}=${String(g)}`})}let v=D.models??[],O=D.currentModelId;return j.cancel({sessionId:h.sessionId}).catch(()=>{return}),{models:v,configOptions:D.configOptions,currentModelId:O}})(),w=new Promise((P,C)=>{L=setTimeout(()=>{C(new x0)},XQ)});return await Promise.race([U,w])}catch(U){if(S2(U)){if(X.signal?.aborted)throw new u("ACP model discovery cancelled: abort signal received");throw new u("Runtime process exited during model discovery.")}throw U}finally{if(L)clearTimeout(L);if(X.signal)X.signal.removeEventListener("abort",F);Z.kill()}}import ZQ from"node:fs/promises";import u2 from"node:os";async function V8(X){let Z={version:1,globalDefaultConfigId:null,runtimes:[],boardOverrides:{},cardOverrides:{}},W;try{W=await ZQ.readFile(X,"utf-8")}catch(Q){if(Q.code==="ENOENT")return structuredClone(Z);throw Q}return Z2.parse(JSON.parse(W))}function tX(X,Z,W){return{...X.defaultConfigValues??{},...Z?.configValues??{},...W?.configValues??{}}}async function k0(X){let Z=X.configPath?await V8(X.configPath):await F0(),W=X.cardId?Z.cardOverrides[X.cardId]:void 0;if(W?.runtimeConfigId){let Y=Z.runtimes.find((z)=>z.id===W.runtimeConfigId);if(Y)return{entry:Y,adapter:O0(Y),runFolder:W.runFolder??Y.runFolder??u2.homedir(),modelId:W.modelId??Y.defaultModelId??null,configValues:tX(Y,void 0,W)}}let Q=Z.boardOverrides[X.boardId];if(Q?.runtimeConfigId){let Y=Z.runtimes.find((z)=>z.id===Q.runtimeConfigId);if(Y)return{entry:Y,adapter:O0(Y),runFolder:Q.runFolder??Y.runFolder??u2.homedir(),modelId:Q.modelId??Y.defaultModelId??null,configValues:tX(Y,Q)}}if(Z.globalDefaultConfigId){let Y=Z.runtimes.find((z)=>z.id===Z.globalDefaultConfigId);if(Y)return{entry:Y,adapter:O0(Y),runFolder:W?.runFolder??Q?.runFolder??Y.runFolder??u2.homedir(),modelId:W?.modelId??Q?.modelId??Y.defaultModelId??null,configValues:tX(Y,Q,W)}}throw new h0}async function eX(X,Z={}){let Q=(Z.configPath?await V8(Z.configPath):await F0()).runtimes.find((Y)=>Y.id===X);if(!Q)return null;return{entry:Q,adapter:O0(Q),runFolder:Q.runFolder??u2.homedir(),modelId:Z.modelId??Q.defaultModelId??null,configValues:{...Q.defaultConfigValues??{},...Z.configValues??{}}}}var X3=new Map;function Z3(X,Z){X3.set(X,Z)}function W3(X){X3.delete(X)}function j8(X){if(!X)return null;return X3.get(X)??null}import{lstat as RQ,readFile as vQ}from"node:fs/promises";import CQ from"node:os";import u1 from"node:path";import{Server as fQ}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as yQ,ListToolsRequestSchema as hQ}from"@modelcontextprotocol/sdk/types.js";import{z as i}from"zod";var K0={maxSteps:12,maxParticipants:4,maxChannels:2,maxHandoffsPerChannel:12,maxTotalDispatches:24},l1=["ideate_create_note","ideate_create_code","ideate_create_shape","ideate_create_browser","ideate_create_image_context_card","ideate_add_browser_note","ideate_add_board_callout","ideate_create_diagram","ideate_create_edge","ideate_update_note","ideate_update_code","ideate_update_shape","ideate_update_diagram","ideate_update_edge","ideate_delete_node","ideate_delete_edge"],WQ=`
|
|
1144
1144
|
<!-- ideawave:mutation-tool=`,QQ=" -->",zj=new RegExp(`${WQ.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}(?<tool>${l1.join("|")})${QQ.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}$`);var r0=i.string().trim().min(1).max(80),H8=i.string().trim().min(1).max(240).regex(/^(node|edge|diagram|browser|browser-annotation|comment|spatial-group|create):/),K8={type:"string",minLength:1,maxLength:240,pattern:"^(node|edge|diagram|browser|browser-annotation|comment|spatial-group|create):",description:"Exact lease key. A new artifact uses create:<runId>:<clientKey>, where clientKey exactly matches this step. An existing artifact uses its frozen UUID-backed node:, edge:, browser:, or diagram: key. External-only research declares no invented resource key."},Vj={type:"object",description:`A bounded acyclic Ideate plan with at most ${K0.maxSteps} total steps. Each new visible artifact gets one step and one exact create lease.`,properties:{summary:{type:"string",minLength:1,maxLength:1500},semanticAnchorId:{type:"string",minLength:1,maxLength:160},participants:{type:"array",maxItems:K0.maxParticipants,items:{type:"object",properties:{clientKey:{type:"string",minLength:1,maxLength:80},label:{type:"string",minLength:1,maxLength:40},responsibility:{type:"string",minLength:1,maxLength:1000}},required:["clientKey","label","responsibility"],additionalProperties:!1}},collaborationChannels:{type:"array",maxItems:K0.maxChannels,items:{type:"object",properties:{clientKey:{type:"string",minLength:1,maxLength:80},protocol:{type:"string",enum:["handoff","turn-taking","request-response","barrier"]},participantKeys:{type:"array",minItems:2,maxItems:4,items:{type:"string",minLength:1,maxLength:80}},resourceScope:{type:"array",maxItems:40,items:K8},maxHandoffs:{type:"integer",minimum:1,maximum:K0.maxHandoffsPerChannel},maxDurationMs:{type:"integer",minimum:1000,maximum:1800000},completion:{type:"string",enum:["all-done","accepted","coordinator-decides"]}},required:["clientKey","protocol","participantKeys","resourceScope","maxHandoffs","maxDurationMs","completion"],additionalProperties:!1}},steps:{type:"array",minItems:1,maxItems:K0.maxSteps,description:`HARD LIMIT: 1-${K0.maxSteps} total steps. Count plan.steps before submitting. If a draft is larger, combine related work and retry the same plan tool immediately; never silently truncate required outcomes.`,items:{type:"object",properties:{clientKey:{type:"string",minLength:1,maxLength:80,description:"Stable step key. For a create step, this exact value is the final segment of its create lease and the worker create call clientKey."},participantKey:{type:"string",minLength:1,maxLength:80},channelKeys:{type:"array",maxItems:2,items:{type:"string",minLength:1,maxLength:80}},label:{type:"string",minLength:1,maxLength:80},kind:{type:"string",enum:["read","browser","write","synthesis"]},prompt:{type:"string",minLength:1,maxLength:4000},mutationTool:{type:"string",enum:l1,description:"Required exactly once for each fresh write step. This is the one fenced mutation capability its worker receives."},dependsOn:{type:"array",maxItems:K0.maxSteps,items:{type:"string",minLength:1,maxLength:80}},resources:{type:"array",maxItems:40,items:{type:"object",properties:{key:K8,mode:{type:"string",enum:["read","write"]}},required:["key","mode"],additionalProperties:!1}}},required:["clientKey","label","kind","prompt","dependsOn","resources"],additionalProperties:!1}}},required:["summary","steps"],additionalProperties:!1};var jj=i.object({summary:i.string().trim().min(1).max(1500),semanticAnchorId:i.string().trim().min(1).max(160).optional(),participants:i.array(i.object({clientKey:r0,label:i.string().trim().min(1).max(40),responsibility:i.string().trim().min(1).max(1000)}).strict()).max(K0.maxParticipants).optional(),collaborationChannels:i.array(i.object({clientKey:r0,protocol:i.enum(["handoff","turn-taking","request-response","barrier"]),participantKeys:i.array(r0).min(2).max(4),resourceScope:i.array(H8).max(40),maxHandoffs:i.number().int().min(1).max(K0.maxHandoffsPerChannel),maxDurationMs:i.number().int().min(1000).max(1800000),completion:i.enum(["all-done","accepted","coordinator-decides"])}).strict()).max(K0.maxChannels).optional(),steps:i.array(i.object({clientKey:r0,participantKey:r0.optional(),channelKeys:i.array(r0).max(2).optional(),label:i.string().trim().min(1).max(80),kind:i.enum(["read","browser","write","synthesis"]),prompt:i.string().trim().min(1).max(4000),mutationTool:i.enum(l1).optional(),dependsOn:i.array(r0).max(K0.maxSteps),resources:i.array(i.object({key:H8,mode:i.enum(["read","write"])}).strict()).max(40)}).strict()).min(1).max(K0.maxSteps,{error:`Plan exceeds the hard ${K0.maxSteps}-step limit. Combine related work into ${K0.maxSteps} or fewer steps and retry the same plan tool immediately; do not drop required outcomes.`})}).strict();var U8=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"]),JQ=["screenshot_board","inspect_diagram","ask_user_question","create_agent_card","append_user_message","spawn_child_agents"],YQ=new Set(JQ),Bj=new Set([...U8].filter((X)=>!YQ.has(X)));var Q3={coordinator:["inspect_ideate_context","get_ideate_run_status","screenshot_ideate_context","search_board","list_nodes","submit_ideate_plan","revise_ideate_plan","get_question_ui_guide","ask_ideate_question","complete_ideate_run","start_board_walkthrough"],worker:["get_ideate_run_status","get_ideate_worker_context","screenshot_ideate_context","get_board","list_nodes","inspect_node","inspect_diagram","list_context_sources","read_context_card","read_context_file","read_context_image","list_context_folder","get_board_wiki","search_board","read_diagram_guide","inspect_browser","list_browser_images","locate_browser_element","list_agent_cards","get_card_messages","inspect_table","get_table_schema","read_table","query_table","export_table_csv",...l1]},zQ=new Set(["inspect_board_region","inspect_neighbors","list_edges","start_board_walkthrough"]),F8=new Set(Q3.coordinator),c2=new Set(Q3.worker);var wj=Q3.worker.filter((X)=>X.startsWith("ideate_"));var VQ=new Set([...F8,...c2,"set_ideate_placement"].filter((X)=>X.startsWith("ideate_")||X.includes("ideate_")));function L8(X,Z,W){if(Z==="full")return!VQ.has(X);if(Z==="read")return U8.has(X);if(Z==="ideate-coordinator")return F8.has(X);if(zQ.has(X))return!1;return c2.has(X)&&Array.isArray(W)&&W.includes(X)}import{randomUUID as HQ}from"node:crypto";import{createServer as KQ}from"node:http";import{StreamableHTTPServerTransport as UQ}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{isInitializeRequest as P8}from"@modelcontextprotocol/sdk/types.js";var B8=new Set(["127.0.0.1","localhost","[::1]","::1"]);function jQ(X){let Z=X.trim();if(Z.length===0)return null;if(Z.startsWith("[")){let z=Z.indexOf("]");if(z===-1)return null;let j=Z.slice(0,z+1),F=Z.slice(z+1);if(F.length===0)return{host:j,port:null};if(!F.startsWith(":"))return null;let L=Number(F.slice(1));if(!Number.isInteger(L)||L<=0||L>65535)return null;return{host:j,port:L}}let W=Z.lastIndexOf(":");if(W===-1)return{host:Z,port:null};let Q=Z.slice(W+1),Y=Number(Q);if(!Number.isInteger(Y)||Y<=0||Y>65535)return{host:Z,port:null};return{host:Z.slice(0,W),port:Y}}function w8(X){return B8.has(X)||B8.has(X.toLowerCase())}function q8(X,Z){let W=X.headers.host;if(typeof W!=="string")return{ok:!1,status:403,reason:"missing-host"};let Q=jQ(W);if(!Q)return{ok:!1,status:403,reason:"bad-host"};if(!w8(Q.host))return{ok:!1,status:403,reason:"non-loopback-host"};if(Q.port!==null&&Q.port!==Z)return{ok:!1,status:403,reason:"host-port-mismatch"};let Y=X.headers.origin;if(typeof Y==="string"&&Y.length>0){if(Y!=="null"){let z;try{z=new URL(Y)}catch{return{ok:!1,status:403,reason:"bad-origin"}}if(!w8(z.hostname))return{ok:!1,status:403,reason:"non-loopback-origin"}}}return{ok:!0}}var b8="/mcp",FQ=43274,O8=16777216,LQ=1800000,BQ=300000,x8=200,wQ=-32700,S0=-32600,J3=-32603;function w0(X,Z,W,Q,Y){X.statusCode=Z,X.setHeader("content-type","application/json"),X.end(JSON.stringify({jsonrpc:"2.0",error:{code:W,message:Q,...Y?{data:Y}:{}},id:null}))}class Y3 extends Error{constructor(){super("expected application/json");this.name="BadContentTypeError"}}class z3 extends Error{constructor(){super(`body exceeds ${O8} bytes`);this.name="BodyTooLargeError"}}async function qQ(X){if(X.method&&X.method!=="POST")return;let Z=X.headers["content-type"];if(typeof Z==="string"&&Z.trim().length>0){if(!Z.toLowerCase().includes("application/json"))throw new Y3}let W=0,Q=[];for await(let z of X){let j=typeof z==="string"?Buffer.from(z):z;if(W+=j.byteLength,W>O8)throw new z3;Q.push(j)}if(Q.length===0)return;let Y=Buffer.concat(Q).toString("utf8");if(Y.length===0)return;return JSON.parse(Y)}function PQ(X){if(Array.isArray(X))return X.some(P8);return P8(X)}function bQ(X){if(typeof X==="number")return X;let Z=process.env.IDEAWAVE_MCP_PORT;if(Z&&Z.trim().length>0){let W=Number(Z);if(Number.isInteger(W)&&W>=0&&W<65536)return W}return FQ}async function xQ(X,Z){let W=(Y)=>new Promise((z,j)=>{let F=(U)=>{X.off("listening",L),j(U)},L=()=>{X.off("error",F),z()};X.once("error",F),X.once("listening",L),X.listen(Y,"127.0.0.1")});try{await W(Z)}catch(Y){if(Y.code!=="EADDRINUSE"||Z===0)throw Y;console.warn(`[mcp] port ${Z} in use, falling back to an OS-assigned port; external CLIs will need to re-paste the install command from Settings → External agents`),await W(0)}let Q=X.address();if(Q==null||typeof Q==="string")throw Error("[mcp] failed to read bound address");return Q.port}function OQ(X,Z){if(Z&&typeof Z==="object"&&!Array.isArray(Z)){let Q=Z.params;if(Q&&typeof Q==="object"&&!Array.isArray(Q)){let Y=Q.clientInfo;if(Y&&typeof Y==="object"&&!Array.isArray(Y)){let z=Y.name;if(typeof z==="string"&&z.trim().length>0)return z.trim()}}}let W=X.headers["user-agent"];if(typeof W==="string"&&W.trim().length>0)return W.trim();return null}async function R8(X){let Z=new Map,W=0;function Q(U){let w=Z.get(U);if(w)w.lastActivity=Date.now()}async function Y(U,w){Z.delete(U),await w.transport.close().catch(()=>{return})}async function z(){let U=null,w=1/0;for(let[P,C]of Z)if(C.lastActivity<w)w=C.lastActivity,U=P;if(U!==null){let P=Z.get(U);if(P)console.warn(`[mcp] session cap of ${x8} reached; evicting ${U}`),await Y(U,P)}}let j=setInterval(()=>{let U=Date.now()-LQ;for(let[w,P]of Z)if(P.lastActivity<U)console.log(`[mcp] sweeping idle session ${w}`),Y(w,P)},BQ);j.unref?.();let F=KQ((U,w)=>{(async()=>{let P;try{P=new URL(U.url??"/","http://127.0.0.1").pathname}catch{w0(w,400,S0,"bad-url");return}if(P!==b8){w0(w,404,S0,"not-found");return}let C=U.method??"POST";if(C!=="POST"&&C!=="GET"&&C!=="DELETE"){w.setHeader("Allow","GET, POST, DELETE"),w0(w,405,S0,"method-not-allowed");return}let h=q8(U,W);if(!h.ok){w0(w,h.status,S0,"forbidden",{reason:h.reason});return}let D=U.headers["mcp-session-id"],G=typeof D==="string"?D:void 0;if(C==="GET"||C==="DELETE"){if(!G||!Z.has(G)){w0(w,400,S0,"no-session",{hint:"Open a POST initialize first to receive an Mcp-Session-Id."});return}let O=Z.get(G).transport;Q(G);try{await O.handleRequest(U,w)}catch(M){if(console.error("[mcp] transport.handleRequest (GET/DELETE) threw",M),!w.headersSent)w0(w,500,J3,"internal")}return}let N;try{N=await qQ(U)}catch(O){if(O instanceof Y3){w0(w,415,S0,"expected-application-json");return}if(O instanceof z3){w0(w,413,S0,"body-too-large");return}w0(w,400,wQ,"invalid-json");return}let v;if(G&&Z.has(G))v=Z.get(G).transport,Q(G);else if(!G&&N!==void 0&&PQ(N)){let O=U.headers["x-ideawave-user-id"],M=typeof O==="string"&&O.trim().length>0?O.trim():null,g=U.headers["x-ideawave-frontend-session-id"],$=typeof g==="string"&&g.trim().length>0?g.trim():null,A=U.headers["x-ideawave-tool-surface"],x=typeof A==="string"?A.trim():"full",b=x==="read"||x==="ideate-coordinator"||x==="ideate-worker"?x:"full",y=U.headers["x-ideawave-images-supported"],_=typeof y==="string"&&y.trim()==="1",I=U.headers["x-ideawave-card-id"],l=typeof I==="string"&&I.trim().length>0?I.trim():null,k=U.headers["x-ideawave-execution-kind"],r=U.headers["x-ideawave-execution-id"],W0=typeof k==="string"?k.trim():"",C0=typeof r==="string"?r.trim():"",S=C0&&new Set(["agent-card","ideate-coordinator","ideate-step","ideate-participant","board-insight","board-auto-title"]).has(W0)?{kind:W0,id:C0}:null,d=U.headers["x-ideawave-ideate-claims"],T=null;if(typeof d==="string"&&d.length>0)try{T=JSON.parse(d)}catch{T=null}let t=U.headers["x-ideawave-board-id"],$0=typeof t==="string"&&t.trim().length>0?t.trim():null,z0=U.headers["x-ideawave-run-folder"],x9=typeof z0==="string"&&z0.trim().length>0?z0.trim():null,WX=U.headers["x-ideawave-pool-session-id"],O9=typeof WX==="string"&&WX.trim().length>0?WX.trim():null,R9=OQ(U,N);if(Z.size>=x8)await z();let QX=null,l0=new UQ({sessionIdGenerator:()=>HQ(),onsessioninitialized:(X1)=>{QX=X1,Z.set(X1,{transport:l0,lastActivity:Date.now()})},onsessionclosed:(X1)=>{Z.delete(X1)}});l0.onclose=()=>{if(l0.sessionId)Z.delete(l0.sessionId)};try{await X.buildServer({userId:M,frontendSessionId:$,boardId:$0,toolSurface:b,imagesSupported:_,cardId:l,executionTarget:S,ideateClaims:T,runFolder:x9,poolSessionId:O9,clientHint:R9}).connect(l0)}catch(X1){if(console.error("[mcp] buildServer/connect failed",X1),QX)Z.delete(QX);await l0.close().catch(()=>{return}),w0(w,500,J3,"server-init-failed");return}v=l0}else{w0(w,400,S0,"no-session",{hint:"Non-initialize requests must include a valid Mcp-Session-Id header obtained from a prior initialize."});return}try{await v.handleRequest(U,w,N)}catch(O){if(console.error("[mcp] transport.handleRequest threw",O),!w.headersSent)w0(w,500,J3,"internal")}})().catch((P)=>{console.error("[mcp] unhandled request handler error:",P)})});return W=await xQ(F,bQ(X.port)),{url:`http://127.0.0.1:${W}${b8}`,port:W,close:async()=>{clearInterval(j);for(let U of Z.values())await U.transport.close().catch(()=>{return});Z.clear(),await new Promise((U)=>F.close(()=>U()))}}}var v8=new Map;function V3(X,Z){if(!X)return;v8.set(X,Z)}function C8(X){if(!X)return!1;return v8.get(X)??!1}var MQ={name:"ideawave-board",version:"1.0.0"},d2="list_run_folder",a2="read_run_folder_file",h8=new Set(["inspect_diagram"]),c1=new Map;function NQ(X,Z){let W=new Set(X.map(({name:Y})=>K1(Y)).filter((Y)=>c2.has(Y))),Q=new Set(Z.map((Y)=>K1(Y)));return W.size===Q.size&&[...W].every((Y)=>Q.has(Y))}function DQ(X,Z){if(!X)return;let W=c1.get(X);if(!W)return;for(let Q of W.waiters){if(!NQ(Z,Q.expectedWorkerTools))continue;W.waiters.delete(Q),Q.resolve(!0)}}async function M8(X){let Z=c1.get(X.poolSessionId);if(!Z)return!1;let W=X.timeoutMs??750;return new Promise((Q)=>{let Y=!1,z=(L)=>{if(Y)return;Y=!0,clearTimeout(F),Z.waiters.delete(j),Q(L)},j={expectedWorkerTools:X.expectedWorkerTools,resolve:z},F=setTimeout(()=>z(!1),W);F.unref?.(),Z.waiters.add(j),Z.server.sendToolListChanged().catch(()=>z(!1))})}function j3(X,Z,W){if(X===d2||X===a2)return Z==="full"||Z==="read";return L8(X,Z,W)}var $Q=[{name:d2,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:a2,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 H3(X){return{content:[{type:"text",text:X}]}}function GQ(X){return H3(JSON.stringify(X,null,2))}function f8(X){return{...H3(X),isError:!0}}async function EQ(X,Z){if(!Z||X.isError)return X;let W=X.content.find((z)=>z.type==="text");if(!W)return X;let Q;try{let z=JSON.parse(W.text);if(typeof z.path!=="string")return X;Q=u1.resolve(z.path)}catch{return X}let Y=u1.resolve(u1.join(CQ.tmpdir(),"ideawave-screenshots"));if(u1.dirname(Q)!==Y||!/^board-[a-z0-9-]+\.png$/i.test(u1.basename(Q)))return X;try{if(!(await RQ(Q)).isFile())return X;let j=await vQ(Q);if(j.byteLength<1024||j.byteLength>26214400||!j.subarray(0,8).equals(Buffer.from([137,80,78,71,13,10,26,10])))return X;return{...X,content:[...X.content,{type:"image",data:j.toString("base64"),mimeType:"image/png"}]}}catch{return X}}function gQ(X,Z,W="full",Q=!1,Y){return X.getMetadata(Z).filter((z)=>{let j=K1(z.name);if(!j3(j,W,Y))return!1;if(!Q&&h8.has(j))return!1;return!0}).map((z)=>({name:z.name,description:z.description,inputSchema:z.inputSchema}))}function mQ(X,Z,W={}){let Q=gQ(X,Z,W.toolSurface??"full",W.imagesSupported??!1,W.workerToolNames);if(!W.includeRunFolderTools)return Q;let Y=W.toolSurface??"full",z=$Q.filter((j)=>j3(j.name,Y,W.workerToolNames));return[...Q,...z]}function y8(X,Z){if(!X||typeof X!=="object"||Array.isArray(X))return null;let W=X[Z];return typeof W==="string"?W:null}async function _Q(X,Z,W){if(W&&W.trim().length>0)return W.trim();if(!X||!Z)throw Error("Run-folder tools require an active IdeaWave board and card.");return(await k0({boardId:X,cardId:Z})).runFolder}async function kQ(X){let Z=await _Q(X.boardId,X.cardId,X.runFolder);if(X.name===d2){let W=y8(X.args,"path")??"",Q=await m4(Z,W);return GQ(Q)}if(X.name===a2){let W=y8(X.args,"path");if(!W)return f8("read_run_folder_file requires a path.");return H3(await m2(Z,W))}return f8(`Unknown local tool "${X.name}"`)}function SQ(X,Z,W,Q,Y,z="full",j=!1,F=null,L=null,U=null){let w=new fQ(MQ,{capabilities:{tools:{listChanged:!0}}});if(U){let h={server:w,waiters:new Set};c1.set(U,h),w.onclose=()=>{if(c1.get(U)!==h)return;c1.delete(U);for(let D of h.waiters)D.resolve(!1);h.waiters.clear()}}let P=()=>{let h=j8(U);return{cardId:h?.cardId??Q,executionTarget:h?.executionTarget??F,ideateClaims:h?.ideateClaims??L}},C=async()=>{if(j)return!0;let h=P().cardId;if(C8(h))return!0;if(W&&h)try{return(await k0({boardId:W,cardId:h})).adapter.supportsImages===!0}catch{return!1}return!1};return w.setRequestHandler(hQ,async()=>{let h=mQ(X,Z,{includeRunFolderTools:z!=="ideate-coordinator"&&Boolean(Y||W&&Q),toolSurface:z,imagesSupported:await C(),workerToolNames:P().ideateClaims?.workerToolNames??null});return DQ(U,h),{tools:h}}),w.setRequestHandler(yQ,async(h)=>{let{name:D,arguments:G}=h.params,N=K1(D),v=Date.now(),O=P();m("mcp.tool_call_received",{frontendSessionId:Z,cardId:O.cardId,toolName:N});try{if(!j3(N,z,O.ideateClaims?.workerToolNames))throw Error(`Tool "${D}" is not available on the ${z} surface`);if(N===d2||N===a2)return await kQ({name:N,args:G,boardId:W,cardId:O.cardId,runFolder:Y});if(h8.has(N)&&!await C())throw Error(`Tool "${D}" requires a runtime that supports image input`);let M=await X.callTool(Z,N,G??{},O.ideateClaims?.runId,O.cardId??void 0,O.executionTarget??void 0,O.ideateClaims??void 0,z);if(m("mcp.tool_result_returned",{frontendSessionId:Z,cardId:O.cardId,toolName:N,elapsedMs:Date.now()-v}),M&&typeof M==="object"&&Array.isArray(M.content)){let g=M;return N==="screenshot_board"||N==="screenshot_ideate_context"?await EQ(g,await C()):g}return{content:[{type:"text",text:typeof M==="string"?M:JSON.stringify(M)}]}}catch(M){return m("mcp.tool_result_returned",{frontendSessionId:Z,cardId:O.cardId,toolName:N,elapsedMs:Date.now()-v,hasError:!0}),{content:[{type:"text",text:M instanceof Error?M.message:"Tool call failed"}],isError:!0}}}),w}function N8(X,Z){return R8({buildServer:(W)=>SQ(X,W.frontendSessionId,W.boardId,W.cardId,W.runFolder,W.toolSurface,W.imagesSupported,W.executionTarget,W.ideateClaims,W.poolSessionId),port:Z})}var s0=new Map,K3=new Set;function U3(X){s0.get(X)?.controller.abort()}function $8(X){for(let[Z,W]of s0){if(W.frontendSessionId!==X)continue;W.controller.abort(),s0.delete(Z)}}function G8(){for(let X of s0.values())X.controller.abort();s0.clear()}function d1(X,Z){if(Z?.aborted)return!0;return X instanceof Error&&/abort signal received|session cancelled/i.test(X.message)}var D8=200;async function F3(X){try{return await X.open()}catch(Z){if(!(Z instanceof u)||d1(Z,X.signal))throw Z;if(m("cli.session_open_retry",{operation:X.operation,delayMs:D8,errorText:Z.message}),await new Promise((W)=>{setTimeout(W,D8)}),X.signal?.aborted)throw Z;return X.open()}}function L3(X,Z,W,Q){if((!Z.availableModels||Z.availableModels.length===0)&&Z.availableConfigOptions.length===0)return;q0((Y)=>{let z=Y.runtimes.find((j)=>j.id===X);if(z){if(Z.availableModels&&Z.availableModels.length>0)z.discoveredModels=E2({adapterId:W,models:Z.availableModels,currentModelId:Z.currentModelId??Q});if(Z.availableConfigOptions.length>0)z.discoveredConfigOptions=Z.availableConfigOptions}}).catch(()=>{return})}function AQ(X,Z,W){if(W==="ideate-coordinator"||W==="ideate-worker")return X;return`${X}
|
|
1145
1145
|
|
|
1146
1146
|
Runtime run folder:
|
|
@@ -1151,4 +1151,4 @@ Runtime run folder:
|
|
|
1151
1151
|
Connection: close\r
|
|
1152
1152
|
Content-Length: ${Buffer.byteLength(W)}\r
|
|
1153
1153
|
\r
|
|
1154
|
-
${W}`),X.destroy()}function GJ(X,Z){return new Promise((W,Q)=>{let Y=(j)=>{X.off("listening",z),Q(j)},z=()=>{X.off("error",Y);let j=X.address();if(!j||typeof j==="string"){Q(Error("Failed to read CLI bridge server address"));return}W(j.port)};X.once("error",Y),X.once("listening",z),X.listen(Z,"127.0.0.1")})}function H9(X){return new Promise((Z,W)=>{X.close((Q)=>{if(Q)W(Q);else Z()})})}async function F9(X,Z=C3()){let W=new Map,Q=new Map,Y=X.maxMessageSize??PJ,z=X.cliInstanceId??Y9(),j=X.nativePingIntervalMs??OJ,F=X.idleTimeoutMs??bJ,L=X.disconnectGraceMs??xJ,U=!1,w=(v)=>{let O=Q.get(v);if(O)clearTimeout(O);Q.delete(v)},P=(v)=>{Q.delete(v);let{activeRunIds:O}=X.registry.disconnect(v);X.onDisconnect(v,O)},C=(v,O,M)=>{let g={type:"cli_status",connected:!0,runtime:X.runtime,mcpReady:X.mcpReady(),error:O,capabilities:X.capabilities??[],cliVersion:X.cliVersion,cliInstanceId:z,...M===void 0?{}:{sessionResumed:M},browserRuntime:X.browserRuntimeStatus?.()};if(v){let $=W.get(v);if($)n0($,g);return}for(let $ of W.values())n0($,g)},h=(v,O)=>{let M=O.sessionId.trim(),g=O.userId.trim();if(!M||!g){n0(v,{type:"cli_status",connected:!1,runtime:X.runtime,mcpReady:X.mcpReady(),error:"Missing frontend session or user id"}),v.close();return}let $=W.get(M),A=X.registry.register({frontendSessionId:M,userId:g,tools:O.tools,send:(x)=>n0(v,x)});if(!A.accepted){n0(v,{type:"cli_status",connected:!1,runtime:X.runtime,mcpReady:X.mcpReady(),error:"Frontend session belongs to another user. Reload the board and reconnect."}),v.close(1008,"Frontend session identity mismatch");return}if(w(M),v.data.frontendSessionId=M,v.idleTimer)clearTimeout(v.idleTimer);if(v.idleTimer=null,W.set(M,v),$&&$!==v)$.close();C(M,void 0,A.sessionResumed),X.onToolMetadata?.(M)},D=(v,O)=>{let M=X.registry.getUserId(v);if(!M)return;let g=($)=>{let A=$J($),x=X.registry.acceptInboundRequest(v,A);if(x!=="capacity")X.registry.sendToSession(v,{type:"delivery_ack",messageId:A});return x};switch(O.type){case"bridge_ping":{let $=W.get(v);if($)n0($,{type:"bridge_pong"});break}case"delivery_ack":X.registry.handleDeliveryAck(v,O.messageId);break;case"tool_metadata":X.registry.setMetadata(v,O.tools),X.onToolMetadata?.(v);break;case"tool_result":X.registry.handleToolResult(v,O);break;case"run_turn":{let $=g(O);if($==="duplicate"||$==="cancelled")break;if($==="capacity"){X.registry.sendToSession(v,{type:"run_settled",runId:O.run.runId,cardId:O.run.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"CLI request queue is full. Retry this run.",partialText:null}});break}m("bridge.run_received",{runId:O.run.runId,cardId:O.run.cardId,frontendSessionId:v}),X.registry.markRunActive(v,O.run.runId,O.run.cardId),X.onRunTurn(v,{...O.run,frontendSessionId:v,userId:M})}break;case"cancel_run":{if(X.registry.cancelInboundRequest(v,z9(O))!=="capacity")X.registry.sendToSession(v,{type:"delivery_ack",messageId:V9(O)});if(X.registry.ownsRun(v,O.runId))X.onCancelRun(v,O.runId)}break;case"runtime_rpc":{let $=g(O);if($==="duplicate"||$==="cancelled")break;if($==="capacity"){X.registry.sendToSession(v,{type:"runtime_rpc_result",requestId:O.requestId,ok:!1,error:"CLI request queue is full. Retry this operation."});break}X.onRuntimeRpc(v,O)}break;case"browser_rpc":{let $=g(O);if($==="duplicate"||$==="cancelled")break;if($==="capacity"){X.registry.sendToSession(v,{type:"browser_rpc_result",requestId:O.requestId,ok:!1,error:"CLI request queue is full. Retry this operation."});break}X.onBrowserRpc?.(v,W.get(v)?.data.frontendOrigin??"",O)}break;case"browser_rpc_cancel":{if(X.registry.cancelInboundRequest(v,z9(O))!=="capacity")X.registry.sendToSession(v,{type:"delivery_ack",messageId:V9(O)});X.onBrowserRpcCancel?.(v,O)}break;case"warmup_run":X.onWarmupRun(v,{...O,frontendSessionId:v},M);break;default:break}},G=(v,O)=>{let M=e2(v.headers.origin),g=f3(M),$={Vary:"Origin"};if(g&&M)$["Access-Control-Allow-Origin"]=M,$["Access-Control-Allow-Private-Network"]="true";if(v.method==="OPTIONS"){O.writeHead(204,{...$,"Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*","Access-Control-Max-Age":"600"}),O.end();return}if(v.method!=="GET"){O.writeHead(405,$),O.end();return}O.writeHead(200,{...$,"content-type":"application/json","cache-control":"no-store"}),O.end(JSON.stringify({ideawave:!0,runtime:X.runtime,mcpReady:X.mcpReady(),capabilities:X.capabilities??[],cliVersion:X.cliVersion,cliInstanceId:z,browserRuntime:X.browserRuntimeStatus?.()}))},N=(v,O)=>{let M=e2(v.headers.origin),g=f3(M),$={Vary:"Origin"};if(g&&M)$["Access-Control-Allow-Origin"]=M,$["Access-Control-Allow-Private-Network"]="true";if(v.method==="OPTIONS"){O.writeHead(204,{...$,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"content-type","Access-Control-Max-Age":"600"}),O.end();return}if(!g){O.writeHead(403,$),O.end();return}if(v.method!=="POST"){O.writeHead(405,$),O.end();return}let A={...$,"content-type":"application/json"},x=(_,I)=>{O.writeHead(_,A),O.end(JSON.stringify(I))},b="",y=!1;v.on("data",(_)=>{if(b+=_.toString("utf8"),b.length>vJ)y=!0,v.destroy()}),v.on("end",()=>{if(y){x(400,{ok:!1,error:"Request body too large"});return}let _;try{_=JSON.parse(b)}catch{x(400,{ok:!1,error:"Invalid JSON body"});return}let I=typeof _.url==="string"?_.url:"";if(!W9(I)){x(400,{ok:!1,error:"url must be an http(s) loopback or /static_boards/ page URL"});return}let l=(k,r)=>{let W0=typeof k==="number"?k:Number.NaN;if(!Number.isFinite(W0))return r;return Math.min(4000,Math.max(200,Math.round(W0)))};Q9({url:I,width:l(_.width,1440),height:l(_.height,900)}).then((k)=>x(200,{ok:!0,path:k.path,engine:k.engine})).catch((k)=>{let r=k instanceof i1?503:k instanceof t2?429:500;x(r,{ok:!1,...k instanceof i1?{installing:!0}:{},error:k instanceof Error?k.message:String(k)})})})};for(let v of Z){let O=wJ((x,b)=>{(async()=>{let y=new URL(x.url??"/","http://127.0.0.1").pathname;if(y===o8){G(x,b);return}if(y===RJ){N(x,b);return}if(await X.onHttpRequest?.(x,b))return;b.writeHead(404,{"content-type":"text/plain"}),b.end("IdeaWave CLI bridge")})().catch((y)=>{if(b.headersSent){b.destroy(y instanceof Error?y:void 0);return}b.writeHead(500,{"content-type":"text/plain"}),b.end("IdeaWave CLI bridge request failed")})}),M=new qJ({noServer:!0,maxPayload:Y}),g=(x)=>{if(x.idleTimer)clearTimeout(x.idleTimer);x.idleTimer=setTimeout(()=>{x.close()},F),x.idleTimer.unref?.()},$=(x)=>{if(x.nativePingTimer)clearInterval(x.nativePingTimer);x.nativePingTimer=null,x.awaitingNativePong=!1,x.nativePongMisses=0},A=(x)=>{$(x),x.nativePingTimer=setInterval(()=>{if(x.readyState!==y3.OPEN)return;if(x.awaitingNativePong){if(x.nativePongMisses+=1,x.nativePongMisses>=2){x.terminate();return}}x.awaitingNativePong=!0;try{x.ping()}catch{x.terminate()}},j),x.nativePingTimer.unref?.()};M.on("connection",(x,b)=>{let y=x;y.data={id:Y9(),frontendSessionId:null,frontendOrigin:new URL(e2(b.headers.origin)??K9).origin},y.idleTimer=null,y.nativePingTimer=null,y.awaitingNativePong=!1,y.nativePongMisses=0,g(y),A(y),y.on("ping",()=>{if(!y.data.frontendSessionId)g(y)}),y.on("pong",()=>{if(y.awaitingNativePong=!1,y.nativePongMisses=0,!y.data.frontendSessionId)g(y)}),y.on("error",()=>{if(y.idleTimer)clearTimeout(y.idleTimer);$(y),y.close()}),y.on("message",(_)=>{if(!y.data.frontendSessionId)g(y);let I=DJ(_);if(Y>0&&I.length>Y)return;let l=p2(I);if(!l)return;let k=y.data.frontendSessionId;if(!k){if(l.type==="bridge_probe")n0(y,{type:"bridge_probe_ack",protocolVersion:l.protocolVersion});else if(l.type==="frontend_hello")h(y,l);return}D(k,l)}),y.on("close",()=>{if(y.idleTimer)clearTimeout(y.idleTimer);$(y);let _=y.data.frontendSessionId;if(!_)return;if(W.get(_)!==y)return;if(W.delete(_),w(_),U)return;Q.set(_,setTimeout(()=>P(_),L))})}),O.on("upgrade",(x,b,y)=>{let _=new URL(x.url??"/","http://127.0.0.1").pathname;if(X.onHttpUpgrade?.(x,b,y))return;if(_!==v3){j9(b,404,"Not Found");return}if(!f3(e2(x.headers.origin))){j9(b,403,"Forbidden");return}M.handleUpgrade(x,b,y,(I)=>{M.emit("connection",I,x)})});try{let x=await GJ(O,v);return{url:`ws://127.0.0.1:${x}${v3}`,port:x,sendStatus:C,close:async()=>{U=!0;for(let b of Q.values())clearTimeout(b);Q.clear();for(let b of M.clients){let y=b;if(y.idleTimer)clearTimeout(y.idleTimer);$(y),y.close()}M.close(),await H9(O).catch(()=>{return})}}}catch(x){if(M.close(),await H9(O).catch(()=>{return}),x?.code==="EADDRINUSE")continue;throw x}}throw Error(`No free IdeaWave CLI bridge port found in ${Z[0]}-${Z.at(-1)}`)}import XX from"node:fs/promises";import h3 from"node:os";import ZX from"node:path";function L9(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function EJ(){let[X,Z]=await Promise.all([F0(),x6()]),W=X.globalDefaultConfigId?X.runtimes.find((Q)=>Q.id===X.globalDefaultConfigId)??null:null;return{runtimes:X.runtimes,globalDefaultConfigId:X.globalDefaultConfigId,globalDefaultEffective:W?{runFolder:W.runFolder??h3.homedir(),modelId:W.defaultModelId??null,configValues:W.defaultConfigValues??{}}:null,knownAdapters:Q1().map((Q)=>({id:Q.id,displayName:Q.displayName})),readiness:Z}}async function gJ(X){try{let Z=await k0({boardId:X.boardId,cardId:X.cardId});return{resolved:{configId:Z.entry.id,adapterId:Z.entry.kind==="registered"?Z.entry.adapterId:null,displayName:Z.entry.displayName,runFolder:Z.runFolder,modelId:Z.modelId,configValues:Z.configValues}}}catch(Z){if(Z instanceof h0)return{resolved:null};throw Z}}async function mJ(X){return q0((Z)=>{let W=Z.runtimes.find((z)=>z.kind==="registered"&&z.adapterId===X.adapterId);if(W)return W;let Q=Q1().find((z)=>z.id===X.adapterId);if(!Q)throw Error(`Unknown adapterId: ${X.adapterId}`);let Y={id:L9(),kind:"registered",adapterId:X.adapterId,displayName:Q.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(Y),Y})}async function _J(X){return q0((Z)=>{let W={id:L9(),kind:"custom",displayName:X.displayName,command:X.command,args:X.args,env:X.env,runFolder:X.runFolder,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(W),W})}async function kJ(X){await q0((Z)=>{if(Z.runtimes=Z.runtimes.filter((W)=>W.id!==X.runtimeConfigId),Z.globalDefaultConfigId===X.runtimeConfigId)Z.globalDefaultConfigId=null;for(let W of Object.keys(Z.boardOverrides))if(Z.boardOverrides[W].runtimeConfigId===X.runtimeConfigId)delete Z.boardOverrides[W];for(let W of Object.keys(Z.cardOverrides))if(Z.cardOverrides[W].runtimeConfigId===X.runtimeConfigId)delete Z.cardOverrides[W]})}async function SJ(X){await q0((Z)=>{let W=Z.runtimes.find((Q)=>Q.id===X.runtimeConfigId);if(!W)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);if(Z.globalDefaultConfigId=X.runtimeConfigId,X.runFolder!==void 0)W.runFolder=X.runFolder;if(X.modelId!==void 0)W.defaultModelId=X.modelId;if(X.configValues!==void 0)W.defaultConfigValues=X.configValues})}async function AJ(X){X.boardId,await q0((Z)=>{if(X.runtimeConfigId===null){delete Z.cardOverrides[X.cardId];return}if(!Z.runtimes.some((Y)=>Y.id===X.runtimeConfigId))throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let Q=Z.cardOverrides[X.cardId];Z.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 IJ(X){let W=(await F0()).runtimes.find((j)=>j.id===X.runtimeConfigId);if(!W)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let Q=O0(W),Y=await Q.resolveSpawnConfig(W),z=W.runFolder??h3.homedir();try{let j=await z8({spawn:{...Y,cwd:z},modelId:X.modelId??W.defaultModelId??null,configValues:X.configValues??W.defaultConfigValues??{}}),F=E2({adapterId:Q.id,models:j.models,currentModelId:j.currentModelId}),L=new Date().toISOString();return await q0((U)=>{let w=U.runtimes.find((P)=>P.id===X.runtimeConfigId);if(w)w.discoveredModels=F,w.discoveredConfigOptions=j.configOptions,w.discoveredAt=L}),{ok:!0,models:F,configOptions:j.configOptions,currentModelId:j.currentModelId}}catch(j){if(j instanceof Z1)throw Error(`${j.message}${Q.authHint?` ${Q.authHint}`:""}`);if(j instanceof u||j instanceof x0)throw Error(j.message);throw j}}async function TJ(X){let Z=h3.homedir(),W=X.path?.trim()?X.path.trim():Z,Q=ZX.resolve(W),Y=!0;try{if(!(await XX.stat(Q)).isDirectory())Q=ZX.dirname(Q)}catch{Y=!1,Q=Z}let z=[];try{z=(await XX.readdir(Q,{withFileTypes:!0})).filter((L)=>L.isDirectory()&&!L.name.startsWith(".")).map((L)=>({name:L.name,path:ZX.join(Q,L.name)})).sort((L,U)=>L.name.localeCompare(U.name))}catch{z=[]}let j=ZX.dirname(Q);return{path:Q,parent:j===Q?null:j,home:Z,exists:Y,entries:z}}var B9={list:EJ,getEffectiveForCard:gJ,registerRegistered:mJ,registerCustom:_J,unregister:kJ,setUserDefault:SJ,setCardOverride:AJ,refreshModels:IJ,browseFolder:TJ};var lJ=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function uJ(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function w9(){try{let X=await F0();if(X.globalDefaultConfigId){if(X.runtimes.some((W)=>W.id===X.globalDefaultConfigId))return X.globalDefaultConfigId}for(let Z of lJ){if((await O6(Z.id))?.status!=="ready")continue;let Q=null;if(await q0((Y)=>{if(Y.globalDefaultConfigId){if(Y.runtimes.some((F)=>F.id===Y.globalDefaultConfigId)){Q=Y.globalDefaultConfigId;return}}let z=Y.runtimes.find((j)=>j.kind==="registered"&&j.adapterId===Z.id);if(!z){let j={id:uJ(),kind:"registered",adapterId:Z.id,displayName:Z.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};Y.runtimes.push(j),z=j}Y.globalDefaultConfigId=z.id,Q=z.id}),Q)return console.log(`[ideawave-cli] using agent runtime: ${Z.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 cJ=240000,dJ=256,aJ=33554432,iJ=128,pJ=512,rJ=t8,sJ=65536;function oJ(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class M3{sessions=new Map;createCallId;toolCallTimeoutMs;maxPendingDeliveries;maxPendingDeliveryBytes;maxAcceptedInboundRequests;maxCancellationTombstones;cancellationTombstoneTtlMs;terminalReservationBytes;constructor(X={}){this.createCallId=X.createCallId??oJ,this.toolCallTimeoutMs=X.toolCallTimeoutMs??cJ,this.maxPendingDeliveries=X.maxPendingDeliveries??dJ,this.maxPendingDeliveryBytes=X.maxPendingDeliveryBytes??aJ,this.maxAcceptedInboundRequests=X.maxAcceptedInboundRequests??iJ,this.maxCancellationTombstones=X.maxCancellationTombstones??pJ,this.cancellationTombstoneTtlMs=X.cancellationTombstoneTtlMs??rJ,this.terminalReservationBytes=X.terminalReservationBytes??sJ}register(X){let Z=this.sessions.get(X.frontendSessionId);if(Z){let W=Z.userId===X.userId;if(!W)return{accepted:!1,sessionResumed:!1};return this.pruneCancellationTombstones(Z),this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:Z.pendingToolCalls,pendingDeliveries:Z.pendingDeliveries,acceptedInboundRequests:Z.acceptedInboundRequests,cancelledInboundRequests:Z.cancelledInboundRequests,cancellationOverflowUntil:Z.cancellationOverflowUntil,activeRunIds:Z.activeRunIds,activeRunCardIds:Z.activeRunCardIds}),this.replayPendingDeliveries(X.frontendSessionId),{accepted:!0,sessionResumed:W}}return this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:new Map,pendingDeliveries:new Map,acceptedInboundRequests:new Map,cancelledInboundRequests:new Map,cancellationOverflowUntil:null,activeRunIds:new Set,activeRunCardIds:new Map}),{accepted:!0,sessionResumed:!1}}disconnect(X,Z="frontend session disconnected"){let W=this.sessions.get(X);if(!W)return{activeRunIds:[]};return this.sessions.delete(X),this.rejectPending(W,Z),{activeRunIds:Array.from(W.activeRunIds)}}sessionCount(){return this.sessions.size}has(X){return this.sessions.has(X)}getUserId(X){return this.sessions.get(X)?.userId??null}setMetadata(X,Z){let W=this.sessions.get(X);if(W)W.tools=Z}getMetadata(X){if(!X)return[];return this.sessions.get(X)?.tools??[]}acceptInboundRequest(X,Z){let W=this.sessions.get(X);if(!W)return"capacity";if(this.pruneCancellationTombstones(W),W.cancelledInboundRequests.has(Z))return"cancelled";if(W.acceptedInboundRequests.has(Z))return"duplicate";if(W.cancellationOverflowUntil!==null&&(Z.startsWith("run_turn:")||Z.startsWith("browser_rpc:")))return"capacity";if(W.acceptedInboundRequests.size>=this.maxAcceptedInboundRequests||W.pendingDeliveries.size+W.acceptedInboundRequests.size>=this.maxPendingDeliveries||this.pendingDeliveryBytes(W)+this.outstandingTerminalReservationBytes(W)+this.terminalReservationBytes>this.maxPendingDeliveryBytes)return"capacity";return W.acceptedInboundRequests.set(Z,{terminalReservation:!0,terminalReservationBytes:this.terminalReservationBytes}),"accepted"}cancelInboundRequest(X,Z){let W=this.sessions.get(X);if(!W)return"capacity";this.pruneCancellationTombstones(W);let Q=Date.now()+this.cancellationTombstoneTtlMs;if(W.cancelledInboundRequests.has(Z))return W.cancelledInboundRequests.set(Z,Q),"duplicate";if(W.cancelledInboundRequests.size>=this.maxCancellationTombstones)return W.cancellationOverflowUntil=Math.max(W.cancellationOverflowUntil??0,Q),"capacity";return W.cancelledInboundRequests.set(Z,Q),"accepted"}sendToSession(X,Z){let W=this.sessions.get(X);if(!W)return!1;let Q=this.toReliableMessage(Z);if(Q){let Y=this.getReliableMessageId(Q),z=Buffer.byteLength(JSON.stringify(Q),"utf8"),j=W.pendingDeliveries.get(Y),F=this.pendingDeliveryBytes(W),L=W.pendingDeliveries.size+(j?0:1),U=F-(j?.byteLength??0)+z,w=this.inboundRequestIdForTerminalDelivery(Y),P=w?W.acceptedInboundRequests.get(w):void 0,C=Boolean(P?.terminalReservation),h=[...W.acceptedInboundRequests.values()].filter((G)=>G.terminalReservation).length-(C?1:0),D=this.outstandingTerminalReservationBytes(W)-(C?P?.terminalReservationBytes??0:0);if(C&&(L+h>this.maxPendingDeliveries||U+D>this.maxPendingDeliveryBytes))Q=this.compactTerminalFailure(Q),z=Buffer.byteLength(JSON.stringify(Q),"utf8"),U=F-(j?.byteLength??0)+z;if(L+h>this.maxPendingDeliveries||U+D>this.maxPendingDeliveryBytes)return m("bridge.delivery_rejected",{frontendSessionId:X,messageId:Y,messageType:Q.type,byteLength:z,reason:"capacity"}),!1;if(W.pendingDeliveries.set(Y,{message:Q,queuedAt:Date.now(),byteLength:z}),P)P.terminalReservation=!1;return m("bridge.delivery_queued",{frontendSessionId:X,messageId:Y,messageType:Q.type,queueDepth:W.pendingDeliveries.size}),W.send(Q),!0}return W.send(Z),!0}handleDeliveryAck(X,Z){let W=this.sessions.get(X);if(!W)return;let Q=W.pendingDeliveries.get(Z);if(Q)W.pendingDeliveries.delete(Z),m("bridge.delivery_acknowledged",{frontendSessionId:X,messageId:Z,messageType:Q.message.type,elapsedMs:Date.now()-Q.queuedAt,queueDepth:W.pendingDeliveries.size});let Y=this.inboundRequestIdForTerminalDelivery(Z);if(Y)W.acceptedInboundRequests.delete(Y)}callTool(X,Z,W,Q,Y,z,j,F){if(!X)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let L=this.sessions.get(X);if(!L)return Promise.reject(Error(`Frontend session ${X} is not connected`));let U=this.createCallId();return new Promise((w,P)=>{let C=Q??(Y?this.getActiveRunIdForCard(L,Y):this.getSoleActiveRunId(L)),h=Y??(C?L.activeRunCardIds.get(C):void 0),D=Date.now(),G=setTimeout(()=>{L.pendingToolCalls.delete(U),L.pendingDeliveries.delete(U),m("tool_queue.timeout",{frontendSessionId:X,runId:C,cardId:h,callId:U,toolName:Z,elapsedMs:Date.now()-D,queueDepth:L.pendingToolCalls.size}),P(Error(`Tool "${Z}" timed out waiting for the frontend`))},this.toolCallTimeoutMs);if(L.pendingToolCalls.set(U,{resolve:w,reject:P,timer:G,name:Z,runId:C??null,cardId:h??null,startedAt:D}),m("tool_queue.forwarded_to_browser",{frontendSessionId:X,runId:C,cardId:h,callId:U,toolName:Z,queueDepth:L.pendingToolCalls.size}),!this.sendToSession(X,{type:"tool_call",callId:U,messageId:U,name:Z,args:W,...C?{runId:C}:{},...h?{cardId:h}:{},...z?{executionTarget:z}:{},...j?{ideateClaims:j}:{},...F?{toolSurface:F}:{}}))L.pendingToolCalls.delete(U),clearTimeout(G),P(Error("Frontend delivery capacity reached"))})}handleToolResult(X,Z){let W=this.sessions.get(X);if(!W)return;let Q=W.pendingToolCalls.get(Z.callId);if(!Q){W.pendingDeliveries.delete(Z.callId),W.send({type:"delivery_ack",messageId:Z.callId});return}W.pendingToolCalls.delete(Z.callId),W.pendingDeliveries.delete(Z.callId),clearTimeout(Q.timer),W.send({type:"delivery_ack",messageId:Z.callId});let Y=Z.ok?"":Z.error??Z.result?.content?.find(({text:F})=>typeof F==="string")?.text??"Tool execution failed",z=/network|fetch|connection|offline/i.test(Y)?"network":/timeout|timed out/i.test(Y)?"timeout":/unauthor|forbidden|permission/i.test(Y)?"authorization":/conflict|revision|lease|fence/i.test(Y)?"conflict":/invalid|missing|required|schema/i.test(Y)?"validation":"unknown";if(m("tool_queue.result_received",{frontendSessionId:X,runId:Q.runId,cardId:Q.cardId,callId:Z.callId,toolName:Q.name,elapsedMs:Date.now()-Q.startedAt,queueDepth:W.pendingToolCalls.size,ok:Z.ok,...Z.ok?{}:{errorCategory:z}}),Z.ok){Q.resolve(Z.result);return}let j=Z.result;if(j&&typeof j==="object"&&Array.isArray(j.content)){Q.resolve({...j,isError:!0});return}Q.reject(Error(Z.error??"Tool execution failed"))}markRunActive(X,Z,W){let Q=this.sessions.get(X);if(!Q)return;if(Q.activeRunIds.add(Z),W)Q.activeRunCardIds.set(Z,W)}markRunSettled(X,Z){let W=this.sessions.get(X);if(!W)return;W.activeRunIds.delete(Z),W.activeRunCardIds.delete(Z)}ownsRun(X,Z){return this.sessions.get(X)?.activeRunIds.has(Z)??!1}rejectPending(X,Z){for(let W of X.pendingToolCalls.values())clearTimeout(W.timer),m("tool_queue.rejected",{frontendSessionId:X.frontendSessionId,runId:W.runId,cardId:W.cardId,toolName:W.name,elapsedMs:Date.now()-W.startedAt}),W.reject(Error(Z));X.pendingToolCalls.clear()}replayPendingDeliveries(X){let Z=this.sessions.get(X);if(!Z)return;for(let[W,Q]of Z.pendingDeliveries)m("bridge.delivery_replayed",{frontendSessionId:X,messageId:W,messageType:Q.message.type,elapsedMs:Date.now()-Q.queuedAt,queueDepth:Z.pendingDeliveries.size}),Z.send(Q.message)}pruneCancellationTombstones(X){let Z=Date.now();for(let[W,Q]of X.cancelledInboundRequests)if(Q<=Z)X.cancelledInboundRequests.delete(W);if(X.cancellationOverflowUntil!==null&&X.cancellationOverflowUntil<=Z)X.cancellationOverflowUntil=null}pendingDeliveryBytes(X){let Z=0;for(let W of X.pendingDeliveries.values())Z+=W.byteLength;return Z}outstandingTerminalReservationBytes(X){let Z=0;for(let W of X.acceptedInboundRequests.values())if(W.terminalReservation)Z+=W.terminalReservationBytes;return Z}compactTerminalFailure(X){switch(X.type){case"run_settled":return{...X,result:{assistantContent:"",model:null,latencyMs:X.result.latencyMs,errorText:"CLI terminal response exceeded the reliable bridge limit. Continue the paused run after reconnecting.",partialText:null}};case"runtime_rpc_result":return{...X,ok:!1,error:"CLI terminal response exceeded the reliable bridge limit. Continue the paused run after reconnecting.",result:void 0};case"browser_rpc_result":return{...X,ok:!1,error:"CLI terminal response exceeded the reliable bridge limit. Continue the paused run after reconnecting.",result:void 0};case"tool_call":return X}}inboundRequestIdForTerminalDelivery(X){if(X.startsWith("run_settled:"))return`run_turn:${X.slice(12)}`;if(X.startsWith("runtime_rpc_result:"))return`runtime_rpc:${X.slice(19)}`;if(X.startsWith("browser_rpc_result:"))return`browser_rpc:${X.slice(19)}`;return null}toReliableMessage(X){switch(X.type){case"tool_call":return{...X,messageId:X.messageId??X.callId};case"run_settled":return{...X,messageId:X.messageId??`run_settled:${X.runId}`};case"runtime_rpc_result":return{...X,messageId:X.messageId??`runtime_rpc_result:${X.requestId}`};case"browser_rpc_result":return{...X,messageId:X.messageId??`browser_rpc_result:${X.requestId}`};default:return null}}getReliableMessageId(X){if(!X.messageId)throw Error(`Reliable relay message ${X.type} is missing messageId`);return X.messageId}getSoleActiveRunId(X){return X.activeRunIds.size===1?X.activeRunIds.values().next().value:void 0}getActiveRunIdForCard(X,Z){let W=[...X.activeRunCardIds.entries()].filter(([Q,Y])=>X.activeRunIds.has(Q)&&Y===Z).map(([Q])=>Q);return W.length===1?W[0]:void 0}}function b9(){return"0.0.100".trim()?"0.0.100":"dev"}var nJ=process.argv.slice(2),D3=J9(nJ,process.env);if(D3.allowRailwayPrPreviews)process.env[p1]="1";var T0=D3.cliArgs[0],{browserKitEnabled:s1,captureEngineEnabled:tJ}=D3;if(T0==="--help"||T0==="-h"||T0==="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(T0==="--version"||T0==="-v"||T0==="version")console.log(b9()),process.exit(0);if(T0)console.error(`Unknown command: ${T0}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var o1=new M3,e0=null,eJ=s1?{phase:"ready",message:"Local browser-kit proxy is ready"}:{phase:"idle"},w1=new G2,t0=new Map;function q9(X,Z){return`${X}:${Z}`}function I0(X,Z){let W=o1.sendToSession(X,Z);if(!W)m("bridge.delivery_rejected_by_registry",{frontendSessionId:X,messageType:Z.type});return W}async function XY(X,Z){try{let W=B9[Z.method],Q=await W(Z.params);I0(X,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!0,result:Q})}catch(W){I0(X,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!1,error:W instanceof Error?W.message:String(W)})}}var n1=!1,r1=null;async function N3(){if(n1)return;if(r1)return r1;return r1=(async()=>{try{let X=await N8(o1);A3({...X,requestedPort:X.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${X.url}`);try{await X6({onStatusChange:(Z)=>{if(R6(),e0?.sendStatus(),Z.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${Z.packageName}: ${Z.error??"unknown error"}`)}})}catch(Z){console.warn("[ideawave-cli] ACP bridge setup skipped:",Z instanceof Error?Z.message:String(Z))}await w9(),n1=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),e0?.sendStatus()}catch(X){console.error("[ideawave-cli] failed to start agent host:",X),e0?.sendStatus(void 0,X instanceof Error?X.message:String(X))}finally{r1=null}})(),r1}if(process.env.APP_ENV!=="development"){let X=await U9();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(tJ)i8().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"}`)});e0=await F9({registry:o1,runtime:null,mcpReady:()=>n1,capabilities:l8(s1),cliVersion:b9(),browserRuntimeStatus:()=>eJ,onToolMetadata:(X)=>{console.log(`[ideawave-cli] session ${X} advertised ${o1.getMetadata(X).length} tools`),N3()},onRunTurn:(X,Z)=>{console.log(`[ideawave-cli] running agent turn for card ${Z.cardId} (session ${X})`),(async()=>{if(await N3(),!n1){I0(X,{type:"run_settled",runId:Z.runId,cardId:Z.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"IdeaWave CLI agent host is not ready",partialText:null}});return}await g8(Z,(W)=>I0(X,W))})().catch(()=>{return}).finally(()=>o1.markRunSettled(X,Z.runId))},onCancelRun:(X,Z)=>{U3(Z)},onRuntimeRpc:(X,Z)=>{XY(X,Z)},onBrowserRpc:(X,Z,W)=>{if(!s1){I0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!1,error:"The development browser-kit proxy is not enabled"});return}let Q=q9(X,W.requestId);t0.get(Q)?.abort();let Y=new AbortController;t0.set(Q,Y),w1.handleRpc(X,Z,W,{signal:Y.signal}).then((z)=>{I0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!0,result:z})},(z)=>{I0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!1,error:IX(z)})}).finally(()=>{if(t0.get(Q)===Y)t0.delete(Q)})},onBrowserRpcCancel:(X,Z)=>{t0.get(q9(X,Z.requestId))?.abort()},onHttpRequest:(X,Z)=>s1?w1.handleHttpRequest(X,Z):!1,onHttpUpgrade:(X,Z,W)=>s1?w1.handleUpgrade(X,Z,W):!1,onWarmupRun:(X,Z,W)=>{(async()=>{if(await N3(),!n1)return{status:"retryable",error:"agent host is not ready"};if(Z.ideate)return B3({boardId:Z.boardId,userId:W,frontendSessionId:X,surface:Z.ideate.surface,runtimeConfigId:Z.ideate.runtimeConfigId,modelId:Z.ideate.modelId});return m8({cardId:Z.cardId,boardId:Z.boardId,userId:W,frontendSessionId:X})})().then((Q)=>{if(!Z.warmupId)return;I0(X,{type:"warmup_result",warmupId:Z.warmupId,cardId:Z.cardId,...Q})})},onDisconnect:(X,Z)=>{for(let[W,Q]of t0){if(!W.startsWith(`${X}:`))continue;Q.abort(),t0.delete(W)}w1.closeFrontendSession(X),$8(X);for(let W of Z)U3(W);m("bridge.frontend_disconnected",{frontendSessionId:X,activeRuns:Z.length}),g3(X).catch((W)=>{console.warn(`[ideawave-cli] failed to evict sessions for ${X}:`,W instanceof Error?W.message:String(W))}),console.log(`[ideawave-cli] browser session ${X} disconnected`)}});w1.setPort(e0.port);console.log(`[ideawave-cli] browser bridge listening on ${e0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var P9=!1;for(let X of["SIGINT","SIGTERM"])process.once(X,()=>{if(P9)return;P9=!0,G8(),(async()=>{await w1.close(),await s8(),await e0?.close().catch(()=>{return}),process.exit(0)})()});
|
|
1154
|
+
${W}`),X.destroy()}function GJ(X,Z){return new Promise((W,Q)=>{let Y=(j)=>{X.off("listening",z),Q(j)},z=()=>{X.off("error",Y);let j=X.address();if(!j||typeof j==="string"){Q(Error("Failed to read CLI bridge server address"));return}W(j.port)};X.once("error",Y),X.once("listening",z),X.listen(Z,"127.0.0.1")})}function H9(X){return new Promise((Z,W)=>{X.close((Q)=>{if(Q)W(Q);else Z()})})}async function F9(X,Z=C3()){let W=new Map,Q=new Map,Y=X.maxMessageSize??PJ,z=X.cliInstanceId??Y9(),j=X.nativePingIntervalMs??OJ,F=X.idleTimeoutMs??bJ,L=X.disconnectGraceMs??xJ,U=!1,w=(v)=>{let O=Q.get(v);if(O)clearTimeout(O);Q.delete(v)},P=(v)=>{Q.delete(v);let{activeRunIds:O}=X.registry.disconnect(v);X.onDisconnect(v,O)},C=(v,O,M)=>{let g={type:"cli_status",connected:!0,runtime:X.runtime,mcpReady:X.mcpReady(),error:O,capabilities:X.capabilities??[],cliVersion:X.cliVersion,cliInstanceId:z,...M===void 0?{}:{sessionResumed:M},browserRuntime:X.browserRuntimeStatus?.()};if(v){let $=W.get(v);if($)n0($,g);return}for(let $ of W.values())n0($,g)},h=(v,O)=>{let M=O.sessionId.trim(),g=O.userId.trim();if(!M||!g){n0(v,{type:"cli_status",connected:!1,runtime:X.runtime,mcpReady:X.mcpReady(),error:"Missing frontend session or user id"}),v.close();return}let $=W.get(M),A=X.registry.register({frontendSessionId:M,userId:g,tools:O.tools,send:(x)=>n0(v,x)});if(!A.accepted){n0(v,{type:"cli_status",connected:!1,runtime:X.runtime,mcpReady:X.mcpReady(),error:"Frontend session belongs to another user. Reload the board and reconnect."}),v.close(1008,"Frontend session identity mismatch");return}if(w(M),v.data.frontendSessionId=M,v.idleTimer)clearTimeout(v.idleTimer);if(v.idleTimer=null,W.set(M,v),$&&$!==v)$.close();C(M,void 0,A.sessionResumed),X.onToolMetadata?.(M)},D=(v,O)=>{let M=X.registry.getUserId(v);if(!M)return;let g=($)=>{let A=$J($),x=X.registry.acceptInboundRequest(v,A);if(x!=="capacity")X.registry.sendToSession(v,{type:"delivery_ack",messageId:A});return x};switch(O.type){case"bridge_ping":{let $=W.get(v);if($)n0($,{type:"bridge_pong"});break}case"delivery_ack":X.registry.handleDeliveryAck(v,O.messageId);break;case"tool_metadata":X.registry.setMetadata(v,O.tools),X.onToolMetadata?.(v);break;case"tool_result":X.registry.handleToolResult(v,O);break;case"run_turn":{let $=g(O);if($==="duplicate"||$==="cancelled")break;if($==="capacity"){X.registry.sendToSession(v,{type:"run_settled",runId:O.run.runId,cardId:O.run.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"CLI request queue is full. Retry this run.",partialText:null}});break}m("bridge.run_received",{runId:O.run.runId,cardId:O.run.cardId,frontendSessionId:v}),X.registry.markRunActive(v,O.run.runId,O.run.cardId),X.onRunTurn(v,{...O.run,frontendSessionId:v,userId:M})}break;case"cancel_run":{if(X.registry.cancelInboundRequest(v,z9(O))!=="capacity")X.registry.sendToSession(v,{type:"delivery_ack",messageId:V9(O)});if(X.registry.ownsRun(v,O.runId))X.onCancelRun(v,O.runId)}break;case"runtime_rpc":{let $=g(O);if($==="duplicate"||$==="cancelled")break;if($==="capacity"){X.registry.sendToSession(v,{type:"runtime_rpc_result",requestId:O.requestId,ok:!1,error:"CLI request queue is full. Retry this operation."});break}X.onRuntimeRpc(v,O)}break;case"browser_rpc":{let $=g(O);if($==="duplicate"||$==="cancelled")break;if($==="capacity"){X.registry.sendToSession(v,{type:"browser_rpc_result",requestId:O.requestId,ok:!1,error:"CLI request queue is full. Retry this operation."});break}X.onBrowserRpc?.(v,W.get(v)?.data.frontendOrigin??"",O)}break;case"browser_rpc_cancel":{if(X.registry.cancelInboundRequest(v,z9(O))!=="capacity")X.registry.sendToSession(v,{type:"delivery_ack",messageId:V9(O)});X.onBrowserRpcCancel?.(v,O)}break;case"warmup_run":X.onWarmupRun(v,{...O,frontendSessionId:v},M);break;default:break}},G=(v,O)=>{let M=e2(v.headers.origin),g=f3(M),$={Vary:"Origin"};if(g&&M)$["Access-Control-Allow-Origin"]=M,$["Access-Control-Allow-Private-Network"]="true";if(v.method==="OPTIONS"){O.writeHead(204,{...$,"Access-Control-Allow-Methods":"GET, OPTIONS","Access-Control-Allow-Headers":"*","Access-Control-Max-Age":"600"}),O.end();return}if(v.method!=="GET"){O.writeHead(405,$),O.end();return}O.writeHead(200,{...$,"content-type":"application/json","cache-control":"no-store"}),O.end(JSON.stringify({ideawave:!0,runtime:X.runtime,mcpReady:X.mcpReady(),capabilities:X.capabilities??[],cliVersion:X.cliVersion,cliInstanceId:z,browserRuntime:X.browserRuntimeStatus?.()}))},N=(v,O)=>{let M=e2(v.headers.origin),g=f3(M),$={Vary:"Origin"};if(g&&M)$["Access-Control-Allow-Origin"]=M,$["Access-Control-Allow-Private-Network"]="true";if(v.method==="OPTIONS"){O.writeHead(204,{...$,"Access-Control-Allow-Methods":"POST, OPTIONS","Access-Control-Allow-Headers":"content-type","Access-Control-Max-Age":"600"}),O.end();return}if(!g){O.writeHead(403,$),O.end();return}if(v.method!=="POST"){O.writeHead(405,$),O.end();return}let A={...$,"content-type":"application/json"},x=(_,I)=>{O.writeHead(_,A),O.end(JSON.stringify(I))},b="",y=!1;v.on("data",(_)=>{if(b+=_.toString("utf8"),b.length>vJ)y=!0,v.destroy()}),v.on("end",()=>{if(y){x(400,{ok:!1,error:"Request body too large"});return}let _;try{_=JSON.parse(b)}catch{x(400,{ok:!1,error:"Invalid JSON body"});return}let I=typeof _.url==="string"?_.url:"";if(!W9(I)){x(400,{ok:!1,error:"url must be an http(s) loopback or /static_boards/ page URL"});return}let l=(k,r)=>{let W0=typeof k==="number"?k:Number.NaN;if(!Number.isFinite(W0))return r;return Math.min(4000,Math.max(200,Math.round(W0)))};Q9({url:I,width:l(_.width,1440),height:l(_.height,900)}).then((k)=>x(200,{ok:!0,path:k.path,engine:k.engine})).catch((k)=>{let r=k instanceof i1?503:k instanceof t2?429:500;x(r,{ok:!1,...k instanceof i1?{installing:!0}:{},error:k instanceof Error?k.message:String(k)})})})};for(let v of Z){let O=wJ((x,b)=>{(async()=>{let y=new URL(x.url??"/","http://127.0.0.1").pathname;if(y===o8){G(x,b);return}if(y===RJ){N(x,b);return}if(await X.onHttpRequest?.(x,b))return;b.writeHead(404,{"content-type":"text/plain"}),b.end("IdeaWave CLI bridge")})().catch((y)=>{if(b.headersSent){b.destroy(y instanceof Error?y:void 0);return}b.writeHead(500,{"content-type":"text/plain"}),b.end("IdeaWave CLI bridge request failed")})}),M=new qJ({noServer:!0,maxPayload:Y}),g=(x)=>{if(x.idleTimer)clearTimeout(x.idleTimer);x.idleTimer=setTimeout(()=>{x.close()},F),x.idleTimer.unref?.()},$=(x)=>{if(x.nativePingTimer)clearInterval(x.nativePingTimer);x.nativePingTimer=null,x.awaitingNativePong=!1,x.nativePongMisses=0},A=(x)=>{$(x),x.nativePingTimer=setInterval(()=>{if(x.readyState!==y3.OPEN)return;if(x.awaitingNativePong){if(x.nativePongMisses+=1,x.nativePongMisses>=2){x.terminate();return}}x.awaitingNativePong=!0;try{x.ping()}catch{x.terminate()}},j),x.nativePingTimer.unref?.()};M.on("connection",(x,b)=>{let y=x;y.data={id:Y9(),frontendSessionId:null,frontendOrigin:new URL(e2(b.headers.origin)??K9).origin},y.idleTimer=null,y.nativePingTimer=null,y.awaitingNativePong=!1,y.nativePongMisses=0,g(y),A(y),y.on("ping",()=>{if(!y.data.frontendSessionId)g(y)}),y.on("pong",()=>{if(y.awaitingNativePong=!1,y.nativePongMisses=0,!y.data.frontendSessionId)g(y)}),y.on("error",()=>{if(y.idleTimer)clearTimeout(y.idleTimer);$(y),y.close()}),y.on("message",(_)=>{if(!y.data.frontendSessionId)g(y);let I=DJ(_);if(Y>0&&I.length>Y)return;let l=p2(I);if(!l)return;let k=y.data.frontendSessionId;if(!k){if(l.type==="bridge_probe")n0(y,{type:"bridge_probe_ack",protocolVersion:l.protocolVersion});else if(l.type==="frontend_hello")h(y,l);return}D(k,l)}),y.on("close",()=>{if(y.idleTimer)clearTimeout(y.idleTimer);$(y);let _=y.data.frontendSessionId;if(!_)return;if(W.get(_)!==y)return;if(W.delete(_),w(_),U)return;Q.set(_,setTimeout(()=>P(_),L))})}),O.on("upgrade",(x,b,y)=>{let _=new URL(x.url??"/","http://127.0.0.1").pathname;if(X.onHttpUpgrade?.(x,b,y))return;if(_!==v3){j9(b,404,"Not Found");return}if(!f3(e2(x.headers.origin))){j9(b,403,"Forbidden");return}M.handleUpgrade(x,b,y,(I)=>{M.emit("connection",I,x)})});try{let x=await GJ(O,v);return{url:`ws://127.0.0.1:${x}${v3}`,port:x,sendStatus:C,close:async()=>{U=!0;for(let b of Q.values())clearTimeout(b);Q.clear();for(let b of M.clients){let y=b;if(y.idleTimer)clearTimeout(y.idleTimer);$(y),y.close()}M.close(),await H9(O).catch(()=>{return})}}}catch(x){if(M.close(),await H9(O).catch(()=>{return}),x?.code==="EADDRINUSE")continue;throw x}}throw Error(`No free IdeaWave CLI bridge port found in ${Z[0]}-${Z.at(-1)}`)}import XX from"node:fs/promises";import h3 from"node:os";import ZX from"node:path";function L9(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function EJ(){let[X,Z]=await Promise.all([F0(),x6()]),W=X.globalDefaultConfigId?X.runtimes.find((Q)=>Q.id===X.globalDefaultConfigId)??null:null;return{runtimes:X.runtimes,globalDefaultConfigId:X.globalDefaultConfigId,globalDefaultEffective:W?{runFolder:W.runFolder??h3.homedir(),modelId:W.defaultModelId??null,configValues:W.defaultConfigValues??{}}:null,knownAdapters:Q1().map((Q)=>({id:Q.id,displayName:Q.displayName})),readiness:Z}}async function gJ(X){try{let Z=await k0({boardId:X.boardId,cardId:X.cardId});return{resolved:{configId:Z.entry.id,adapterId:Z.entry.kind==="registered"?Z.entry.adapterId:null,displayName:Z.entry.displayName,runFolder:Z.runFolder,modelId:Z.modelId,configValues:Z.configValues}}}catch(Z){if(Z instanceof h0)return{resolved:null};throw Z}}async function mJ(X){return q0((Z)=>{let W=Z.runtimes.find((z)=>z.kind==="registered"&&z.adapterId===X.adapterId);if(W)return W;let Q=Q1().find((z)=>z.id===X.adapterId);if(!Q)throw Error(`Unknown adapterId: ${X.adapterId}`);let Y={id:L9(),kind:"registered",adapterId:X.adapterId,displayName:Q.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(Y),Y})}async function _J(X){return q0((Z)=>{let W={id:L9(),kind:"custom",displayName:X.displayName,command:X.command,args:X.args,env:X.env,runFolder:X.runFolder,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};return Z.runtimes.push(W),W})}async function kJ(X){await q0((Z)=>{if(Z.runtimes=Z.runtimes.filter((W)=>W.id!==X.runtimeConfigId),Z.globalDefaultConfigId===X.runtimeConfigId)Z.globalDefaultConfigId=null;for(let W of Object.keys(Z.boardOverrides))if(Z.boardOverrides[W].runtimeConfigId===X.runtimeConfigId)delete Z.boardOverrides[W];for(let W of Object.keys(Z.cardOverrides))if(Z.cardOverrides[W].runtimeConfigId===X.runtimeConfigId)delete Z.cardOverrides[W]})}async function SJ(X){await q0((Z)=>{let W=Z.runtimes.find((Q)=>Q.id===X.runtimeConfigId);if(!W)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);if(Z.globalDefaultConfigId=X.runtimeConfigId,X.runFolder!==void 0)W.runFolder=X.runFolder;if(X.modelId!==void 0)W.defaultModelId=X.modelId;if(X.configValues!==void 0)W.defaultConfigValues=X.configValues})}async function AJ(X){X.boardId,await q0((Z)=>{if(X.runtimeConfigId===null){delete Z.cardOverrides[X.cardId];return}if(!Z.runtimes.some((Y)=>Y.id===X.runtimeConfigId))throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let Q=Z.cardOverrides[X.cardId];Z.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 IJ(X){let W=(await F0()).runtimes.find((j)=>j.id===X.runtimeConfigId);if(!W)throw Error(`Runtime config not found: ${X.runtimeConfigId}`);let Q=O0(W),Y=await Q.resolveSpawnConfig(W),z=W.runFolder??h3.homedir();try{let j=await z8({spawn:{...Y,cwd:z},modelId:X.modelId??W.defaultModelId??null,configValues:X.configValues??W.defaultConfigValues??{}}),F=E2({adapterId:Q.id,models:j.models,currentModelId:j.currentModelId}),L=new Date().toISOString();return await q0((U)=>{let w=U.runtimes.find((P)=>P.id===X.runtimeConfigId);if(w)w.discoveredModels=F,w.discoveredConfigOptions=j.configOptions,w.discoveredAt=L}),{ok:!0,models:F,configOptions:j.configOptions,currentModelId:j.currentModelId}}catch(j){if(j instanceof Z1)throw Error(`${j.message}${Q.authHint?` ${Q.authHint}`:""}`);if(j instanceof u||j instanceof x0)throw Error(j.message);throw j}}async function TJ(X){let Z=h3.homedir(),W=X.path?.trim()?X.path.trim():Z,Q=ZX.resolve(W),Y=!0;try{if(!(await XX.stat(Q)).isDirectory())Q=ZX.dirname(Q)}catch{Y=!1,Q=Z}let z=[];try{z=(await XX.readdir(Q,{withFileTypes:!0})).filter((L)=>L.isDirectory()&&!L.name.startsWith(".")).map((L)=>({name:L.name,path:ZX.join(Q,L.name)})).sort((L,U)=>L.name.localeCompare(U.name))}catch{z=[]}let j=ZX.dirname(Q);return{path:Q,parent:j===Q?null:j,home:Z,exists:Y,entries:z}}var B9={list:EJ,getEffectiveForCard:gJ,registerRegistered:mJ,registerCustom:_J,unregister:kJ,setUserDefault:SJ,setCardOverride:AJ,refreshModels:IJ,browseFolder:TJ};var lJ=[{id:"claude-code",displayName:"Claude Code"},{id:"codex",displayName:"Codex"},{id:"copilot",displayName:"Copilot"},{id:"opencode",displayName:"OpenCode"}];function uJ(){return`cfg_${crypto.randomUUID().replace(/-/g,"").slice(0,16)}`}async function w9(){try{let X=await F0();if(X.globalDefaultConfigId){if(X.runtimes.some((W)=>W.id===X.globalDefaultConfigId))return X.globalDefaultConfigId}for(let Z of lJ){if((await O6(Z.id))?.status!=="ready")continue;let Q=null;if(await q0((Y)=>{if(Y.globalDefaultConfigId){if(Y.runtimes.some((F)=>F.id===Y.globalDefaultConfigId)){Q=Y.globalDefaultConfigId;return}}let z=Y.runtimes.find((j)=>j.kind==="registered"&&j.adapterId===Z.id);if(!z){let j={id:uJ(),kind:"registered",adapterId:Z.id,displayName:Z.displayName,runFolder:null,defaultModelId:null,defaultConfigValues:{},discoveredModels:[],discoveredConfigOptions:[],discoveredAt:null};Y.runtimes.push(j),z=j}Y.globalDefaultConfigId=z.id,Q=z.id}),Q)return console.log(`[ideawave-cli] using agent runtime: ${Z.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 cJ=240000,dJ=256,aJ=33554432,iJ=128,pJ=512,rJ=t8,sJ=65536;function oJ(){if(typeof crypto<"u"&&"randomUUID"in crypto)return`call_${crypto.randomUUID()}`;return`call_${Date.now()}_${Math.random().toString(16).slice(2)}`}class M3{sessions=new Map;createCallId;toolCallTimeoutMs;maxPendingDeliveries;maxPendingDeliveryBytes;maxAcceptedInboundRequests;maxCancellationTombstones;cancellationTombstoneTtlMs;terminalReservationBytes;constructor(X={}){this.createCallId=X.createCallId??oJ,this.toolCallTimeoutMs=X.toolCallTimeoutMs??cJ,this.maxPendingDeliveries=X.maxPendingDeliveries??dJ,this.maxPendingDeliveryBytes=X.maxPendingDeliveryBytes??aJ,this.maxAcceptedInboundRequests=X.maxAcceptedInboundRequests??iJ,this.maxCancellationTombstones=X.maxCancellationTombstones??pJ,this.cancellationTombstoneTtlMs=X.cancellationTombstoneTtlMs??rJ,this.terminalReservationBytes=X.terminalReservationBytes??sJ}register(X){let Z=this.sessions.get(X.frontendSessionId);if(Z){let W=Z.userId===X.userId;if(!W)return{accepted:!1,sessionResumed:!1};return this.pruneCancellationTombstones(Z),this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:Z.pendingToolCalls,pendingDeliveries:Z.pendingDeliveries,acceptedInboundRequests:Z.acceptedInboundRequests,cancelledInboundRequests:Z.cancelledInboundRequests,cancellationOverflowUntil:Z.cancellationOverflowUntil,activeRunIds:Z.activeRunIds,activeRunCardIds:Z.activeRunCardIds}),this.replayPendingDeliveries(X.frontendSessionId),{accepted:!0,sessionResumed:W}}return this.sessions.set(X.frontendSessionId,{frontendSessionId:X.frontendSessionId,userId:X.userId,tools:X.tools,send:X.send,pendingToolCalls:new Map,pendingDeliveries:new Map,acceptedInboundRequests:new Map,cancelledInboundRequests:new Map,cancellationOverflowUntil:null,activeRunIds:new Set,activeRunCardIds:new Map}),{accepted:!0,sessionResumed:!1}}disconnect(X,Z="frontend session disconnected"){let W=this.sessions.get(X);if(!W)return{activeRunIds:[]};return this.sessions.delete(X),this.rejectPending(W,Z),{activeRunIds:Array.from(W.activeRunIds)}}sessionCount(){return this.sessions.size}has(X){return this.sessions.has(X)}getUserId(X){return this.sessions.get(X)?.userId??null}setMetadata(X,Z){let W=this.sessions.get(X);if(W)W.tools=Z}getMetadata(X){if(!X)return[];return this.sessions.get(X)?.tools??[]}acceptInboundRequest(X,Z){let W=this.sessions.get(X);if(!W)return"capacity";if(this.pruneCancellationTombstones(W),W.cancelledInboundRequests.has(Z))return"cancelled";if(W.acceptedInboundRequests.has(Z))return"duplicate";if(W.cancellationOverflowUntil!==null&&(Z.startsWith("run_turn:")||Z.startsWith("browser_rpc:")))return"capacity";if(W.acceptedInboundRequests.size>=this.maxAcceptedInboundRequests||W.pendingDeliveries.size+W.acceptedInboundRequests.size>=this.maxPendingDeliveries||this.pendingDeliveryBytes(W)+this.outstandingTerminalReservationBytes(W)+this.terminalReservationBytes>this.maxPendingDeliveryBytes)return"capacity";return W.acceptedInboundRequests.set(Z,{terminalReservation:!0,terminalReservationBytes:this.terminalReservationBytes}),"accepted"}cancelInboundRequest(X,Z){let W=this.sessions.get(X);if(!W)return"capacity";this.pruneCancellationTombstones(W);let Q=Date.now()+this.cancellationTombstoneTtlMs;if(W.cancelledInboundRequests.has(Z))return W.cancelledInboundRequests.set(Z,Q),"duplicate";if(W.cancelledInboundRequests.size>=this.maxCancellationTombstones)return W.cancellationOverflowUntil=Math.max(W.cancellationOverflowUntil??0,Q),"capacity";return W.cancelledInboundRequests.set(Z,Q),"accepted"}sendToSession(X,Z){let W=this.sessions.get(X);if(!W)return!1;let Q=this.toReliableMessage(Z);if(Q){let Y=this.getReliableMessageId(Q),z=Buffer.byteLength(JSON.stringify(Q),"utf8"),j=W.pendingDeliveries.get(Y),F=this.pendingDeliveryBytes(W),L=W.pendingDeliveries.size+(j?0:1),U=F-(j?.byteLength??0)+z,w=this.inboundRequestIdForTerminalDelivery(Y),P=w?W.acceptedInboundRequests.get(w):void 0,C=Boolean(P?.terminalReservation),h=[...W.acceptedInboundRequests.values()].filter((G)=>G.terminalReservation).length-(C?1:0),D=this.outstandingTerminalReservationBytes(W)-(C?P?.terminalReservationBytes??0:0);if(C&&(L+h>this.maxPendingDeliveries||U+D>this.maxPendingDeliveryBytes))Q=this.compactTerminalFailure(Q),z=Buffer.byteLength(JSON.stringify(Q),"utf8"),U=F-(j?.byteLength??0)+z;if(L+h>this.maxPendingDeliveries||U+D>this.maxPendingDeliveryBytes)return m("bridge.delivery_rejected",{frontendSessionId:X,messageId:Y,messageType:Q.type,byteLength:z,reason:"capacity"}),!1;if(W.pendingDeliveries.set(Y,{message:Q,queuedAt:Date.now(),byteLength:z}),P)P.terminalReservation=!1;return m("bridge.delivery_queued",{frontendSessionId:X,messageId:Y,messageType:Q.type,queueDepth:W.pendingDeliveries.size}),W.send(Q),!0}return W.send(Z),!0}handleDeliveryAck(X,Z){let W=this.sessions.get(X);if(!W)return;let Q=W.pendingDeliveries.get(Z);if(Q)W.pendingDeliveries.delete(Z),m("bridge.delivery_acknowledged",{frontendSessionId:X,messageId:Z,messageType:Q.message.type,elapsedMs:Date.now()-Q.queuedAt,queueDepth:W.pendingDeliveries.size});let Y=this.inboundRequestIdForTerminalDelivery(Z);if(Y)W.acceptedInboundRequests.delete(Y)}callTool(X,Z,W,Q,Y,z,j,F){if(!X)return Promise.reject(Error("MCP tool call is missing a frontend session id"));let L=this.sessions.get(X);if(!L)return Promise.reject(Error(`Frontend session ${X} is not connected`));let U=this.createCallId();return new Promise((w,P)=>{let C=Q??(Y?this.getActiveRunIdForCard(L,Y):this.getSoleActiveRunId(L)),h=Y??(C?L.activeRunCardIds.get(C):void 0),D=Date.now(),G=setTimeout(()=>{L.pendingToolCalls.delete(U),L.pendingDeliveries.delete(U),m("tool_queue.timeout",{frontendSessionId:X,runId:C,cardId:h,callId:U,toolName:Z,elapsedMs:Date.now()-D,queueDepth:L.pendingToolCalls.size}),P(Error(`Tool "${Z}" timed out waiting for the frontend`))},this.toolCallTimeoutMs);if(L.pendingToolCalls.set(U,{resolve:w,reject:P,timer:G,name:Z,runId:C??null,cardId:h??null,startedAt:D}),m("tool_queue.forwarded_to_browser",{frontendSessionId:X,runId:C,cardId:h,callId:U,toolName:Z,queueDepth:L.pendingToolCalls.size}),!this.sendToSession(X,{type:"tool_call",callId:U,messageId:U,name:Z,args:W,...C?{runId:C}:{},...h?{cardId:h}:{},...z?{executionTarget:z}:{},...j?{ideateClaims:j}:{},...F?{toolSurface:F}:{}}))L.pendingToolCalls.delete(U),clearTimeout(G),P(Error("Frontend delivery capacity reached"))})}handleToolResult(X,Z){let W=this.sessions.get(X);if(!W)return;let Q=W.pendingToolCalls.get(Z.callId);if(!Q){W.pendingDeliveries.delete(Z.callId),W.send({type:"delivery_ack",messageId:Z.callId});return}W.pendingToolCalls.delete(Z.callId),W.pendingDeliveries.delete(Z.callId),clearTimeout(Q.timer),W.send({type:"delivery_ack",messageId:Z.callId});let Y=Z.ok?"":Z.error??Z.result?.content?.find(({text:F})=>typeof F==="string")?.text??"Tool execution failed",z=/network|fetch|connection|offline/i.test(Y)?"network":/timeout|timed out/i.test(Y)?"timeout":/unauthor|forbidden|permission/i.test(Y)?"authorization":/conflict|revision|lease|fence/i.test(Y)?"conflict":/invalid|missing|required|schema/i.test(Y)?"validation":"unknown";if(m("tool_queue.result_received",{frontendSessionId:X,runId:Q.runId,cardId:Q.cardId,callId:Z.callId,toolName:Q.name,elapsedMs:Date.now()-Q.startedAt,queueDepth:W.pendingToolCalls.size,ok:Z.ok,...Z.ok?{}:{errorCategory:z}}),Z.ok){Q.resolve(Z.result);return}let j=Z.result;if(j&&typeof j==="object"&&Array.isArray(j.content)){Q.resolve({...j,isError:!0});return}Q.reject(Error(Z.error??"Tool execution failed"))}markRunActive(X,Z,W){let Q=this.sessions.get(X);if(!Q)return;if(Q.activeRunIds.add(Z),W)Q.activeRunCardIds.set(Z,W)}markRunSettled(X,Z){let W=this.sessions.get(X);if(!W)return;W.activeRunIds.delete(Z),W.activeRunCardIds.delete(Z)}ownsRun(X,Z){return this.sessions.get(X)?.activeRunIds.has(Z)??!1}rejectPending(X,Z){for(let W of X.pendingToolCalls.values())clearTimeout(W.timer),m("tool_queue.rejected",{frontendSessionId:X.frontendSessionId,runId:W.runId,cardId:W.cardId,toolName:W.name,elapsedMs:Date.now()-W.startedAt}),W.reject(Error(Z));X.pendingToolCalls.clear()}replayPendingDeliveries(X){let Z=this.sessions.get(X);if(!Z)return;for(let[W,Q]of Z.pendingDeliveries)m("bridge.delivery_replayed",{frontendSessionId:X,messageId:W,messageType:Q.message.type,elapsedMs:Date.now()-Q.queuedAt,queueDepth:Z.pendingDeliveries.size}),Z.send(Q.message)}pruneCancellationTombstones(X){let Z=Date.now();for(let[W,Q]of X.cancelledInboundRequests)if(Q<=Z)X.cancelledInboundRequests.delete(W);if(X.cancellationOverflowUntil!==null&&X.cancellationOverflowUntil<=Z)X.cancellationOverflowUntil=null}pendingDeliveryBytes(X){let Z=0;for(let W of X.pendingDeliveries.values())Z+=W.byteLength;return Z}outstandingTerminalReservationBytes(X){let Z=0;for(let W of X.acceptedInboundRequests.values())if(W.terminalReservation)Z+=W.terminalReservationBytes;return Z}compactTerminalFailure(X){switch(X.type){case"run_settled":return{...X,result:{assistantContent:"",model:null,latencyMs:X.result.latencyMs,errorText:"CLI terminal response exceeded the reliable bridge limit. Continue the paused run after reconnecting.",partialText:null}};case"runtime_rpc_result":return{...X,ok:!1,error:"CLI terminal response exceeded the reliable bridge limit. Continue the paused run after reconnecting.",result:void 0};case"browser_rpc_result":return{...X,ok:!1,error:"CLI terminal response exceeded the reliable bridge limit. Continue the paused run after reconnecting.",result:void 0};case"tool_call":return X}}inboundRequestIdForTerminalDelivery(X){if(X.startsWith("run_settled:"))return`run_turn:${X.slice(12)}`;if(X.startsWith("runtime_rpc_result:"))return`runtime_rpc:${X.slice(19)}`;if(X.startsWith("browser_rpc_result:"))return`browser_rpc:${X.slice(19)}`;return null}toReliableMessage(X){switch(X.type){case"tool_call":return{...X,messageId:X.messageId??X.callId};case"run_settled":return{...X,messageId:X.messageId??`run_settled:${X.runId}`};case"runtime_rpc_result":return{...X,messageId:X.messageId??`runtime_rpc_result:${X.requestId}`};case"browser_rpc_result":return{...X,messageId:X.messageId??`browser_rpc_result:${X.requestId}`};default:return null}}getReliableMessageId(X){if(!X.messageId)throw Error(`Reliable relay message ${X.type} is missing messageId`);return X.messageId}getSoleActiveRunId(X){return X.activeRunIds.size===1?X.activeRunIds.values().next().value:void 0}getActiveRunIdForCard(X,Z){let W=[...X.activeRunCardIds.entries()].filter(([Q,Y])=>X.activeRunIds.has(Q)&&Y===Z).map(([Q])=>Q);return W.length===1?W[0]:void 0}}function b9(){return"0.0.101".trim()?"0.0.101":"dev"}var nJ=process.argv.slice(2),D3=J9(nJ,process.env);if(D3.allowRailwayPrPreviews)process.env[p1]="1";var T0=D3.cliArgs[0],{browserKitEnabled:s1,captureEngineEnabled:tJ}=D3;if(T0==="--help"||T0==="-h"||T0==="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(T0==="--version"||T0==="-v"||T0==="version")console.log(b9()),process.exit(0);if(T0)console.error(`Unknown command: ${T0}`),console.error("Run `ideawave --help` for usage."),process.exit(1);var o1=new M3,e0=null,eJ=s1?{phase:"ready",message:"Local browser-kit proxy is ready"}:{phase:"idle"},w1=new G2,t0=new Map;function q9(X,Z){return`${X}:${Z}`}function I0(X,Z){let W=o1.sendToSession(X,Z);if(!W)m("bridge.delivery_rejected_by_registry",{frontendSessionId:X,messageType:Z.type});return W}async function XY(X,Z){try{let W=B9[Z.method],Q=await W(Z.params);I0(X,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!0,result:Q})}catch(W){I0(X,{type:"runtime_rpc_result",requestId:Z.requestId,ok:!1,error:W instanceof Error?W.message:String(W)})}}var n1=!1,r1=null;async function N3(){if(n1)return;if(r1)return r1;return r1=(async()=>{try{let X=await N8(o1);A3({...X,requestedPort:X.port}),console.log(`[ideawave-cli] MCP endpoint for the agent: ${X.url}`);try{await X6({onStatusChange:(Z)=>{if(R6(),e0?.sendStatus(),Z.status==="failed")console.warn(`[ideawave-cli] ACP bridge setup failed for ${Z.packageName}: ${Z.error??"unknown error"}`)}})}catch(Z){console.warn("[ideawave-cli] ACP bridge setup skipped:",Z instanceof Error?Z.message:String(Z))}await w9(),n1=!0,console.log("[ideawave-cli] ready — agent runs will drive the board."),e0?.sendStatus()}catch(X){console.error("[ideawave-cli] failed to start agent host:",X),e0?.sendStatus(void 0,X instanceof Error?X.message:String(X))}finally{r1=null}})(),r1}if(process.env.APP_ENV!=="development"){let X=await U9();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(tJ)i8().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"}`)});e0=await F9({registry:o1,runtime:null,mcpReady:()=>n1,capabilities:l8(s1),cliVersion:b9(),browserRuntimeStatus:()=>eJ,onToolMetadata:(X)=>{console.log(`[ideawave-cli] session ${X} advertised ${o1.getMetadata(X).length} tools`),N3()},onRunTurn:(X,Z)=>{console.log(`[ideawave-cli] running agent turn for card ${Z.cardId} (session ${X})`),(async()=>{if(await N3(),!n1){I0(X,{type:"run_settled",runId:Z.runId,cardId:Z.cardId,result:{assistantContent:"",model:null,latencyMs:0,errorText:"IdeaWave CLI agent host is not ready",partialText:null}});return}await g8(Z,(W)=>I0(X,W))})().catch(()=>{return}).finally(()=>o1.markRunSettled(X,Z.runId))},onCancelRun:(X,Z)=>{U3(Z)},onRuntimeRpc:(X,Z)=>{XY(X,Z)},onBrowserRpc:(X,Z,W)=>{if(!s1){I0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!1,error:"The development browser-kit proxy is not enabled"});return}let Q=q9(X,W.requestId);t0.get(Q)?.abort();let Y=new AbortController;t0.set(Q,Y),w1.handleRpc(X,Z,W,{signal:Y.signal}).then((z)=>{I0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!0,result:z})},(z)=>{I0(X,{type:"browser_rpc_result",requestId:W.requestId,ok:!1,error:IX(z)})}).finally(()=>{if(t0.get(Q)===Y)t0.delete(Q)})},onBrowserRpcCancel:(X,Z)=>{t0.get(q9(X,Z.requestId))?.abort()},onHttpRequest:(X,Z)=>s1?w1.handleHttpRequest(X,Z):!1,onHttpUpgrade:(X,Z,W)=>s1?w1.handleUpgrade(X,Z,W):!1,onWarmupRun:(X,Z,W)=>{(async()=>{if(await N3(),!n1)return{status:"retryable",error:"agent host is not ready"};if(Z.ideate)return B3({boardId:Z.boardId,userId:W,frontendSessionId:X,surface:Z.ideate.surface,runtimeConfigId:Z.ideate.runtimeConfigId,modelId:Z.ideate.modelId});return m8({cardId:Z.cardId,boardId:Z.boardId,userId:W,frontendSessionId:X})})().then((Q)=>{if(!Z.warmupId)return;I0(X,{type:"warmup_result",warmupId:Z.warmupId,cardId:Z.cardId,...Q})})},onDisconnect:(X,Z)=>{for(let[W,Q]of t0){if(!W.startsWith(`${X}:`))continue;Q.abort(),t0.delete(W)}w1.closeFrontendSession(X),$8(X);for(let W of Z)U3(W);m("bridge.frontend_disconnected",{frontendSessionId:X,activeRuns:Z.length}),g3(X).catch((W)=>{console.warn(`[ideawave-cli] failed to evict sessions for ${X}:`,W instanceof Error?W.message:String(W))}),console.log(`[ideawave-cli] browser session ${X} disconnected`)}});w1.setPort(e0.port);console.log(`[ideawave-cli] browser bridge listening on ${e0.url}`);console.log("[ideawave-cli] waiting for ideawave.app browser sessions…");var P9=!1;for(let X of["SIGINT","SIGTERM"])process.once(X,()=>{if(P9)return;P9=!0,G8(),(async()=>{await w1.close(),await s8(),await e0?.close().catch(()=>{return}),process.exit(0)})()});
|